DiFfRG
Loading...
Searching...
No Matches
numflux.hh
Go to the documentation of this file.
1#pragma once
2
3// standard library
4#include <array>
5
6// external libraries
7#include <deal.II/base/point.h>
8#include <deal.II/base/tensor.h>
9#include <deal.II/lac/vector.h>
10
11// DiFfRG
13
14namespace DiFfRG
15{
16 namespace def
17 {
18 using namespace dealii;
19
20 template <typename Model> class LLFFlux
21 {
22 Model &asImp() { return static_cast<Model &>(*this); }
23 const Model &asImp() const { return static_cast<const Model &>(*this); }
24
25 public:
26 template <int dim, typename NumberType, typename Solutions_s, typename Solutions_n, typename M = Model>
27 void numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(0)> &NF,
28 const Tensor<1, dim> &normal, const Point<dim> &p, const Solutions_s &sol_s,
29 const Solutions_n &sol_n) const
30 {
31 using std::max, std::abs;
32 using namespace autodiff;
33 static_assert(std::is_same<M, Model>::value, "The call of this method should not have touched M.");
34 using Components = typename M::Components;
35
36 std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(0)> F_s{};
37 std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(0)> F_n{};
38 asImp().flux(F_s, p, sol_s);
39 asImp().flux(F_n, p, sol_n);
40
41 const auto &u_s = std::get<0>(sol_s);
42 const auto &u_n = std::get<0>(sol_n);
43
44 // A lengthy calculation for the diffusion
45 // we use FD here, as nested AD calculations would be quite the hassle
48 std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(0)> dflux_s{};
49 std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(0)> dflux_n{};
50 for (uint i = 0; i < Model::Components::count_fe_functions(0); ++i) {
51 auto du = 1e-5 * (0.5 * (abs(u_s[i]) + abs(u_n[i])) + 1e-9);
52 du_s[i] += du;
53 du_n[i] += du;
54 asImp().flux(dflux_s, p, Solutions_s::as(std::tuple_cat(std::tie(du_s), tuple_tail(sol_s))));
55 asImp().flux(dflux_n, p, Solutions_n::as(std::tuple_cat(std::tie(du_n), tuple_tail(sol_n))));
56 du_s[i] = u_s[i];
57 du_n[i] = u_n[i];
58
59 const auto alpha = max(abs(dot<dim, NumberType>(dflux_s[i], normal) - dot<dim, NumberType>(F_s[i], normal)),
60 abs(dot<dim, NumberType>(dflux_n[i], normal) - dot<dim, NumberType>(F_n[i], normal))) /
61 du;
62
63 for (uint d = 0; d < dim; ++d)
64 NF[i][d] = 0.5 * (F_s[i][d] + F_n[i][d]) - 0.5 * alpha * (u_n[i] - u_s[i]);
65 }
66 }
67 };
68
69 constexpr uint from_right = 0;
70 constexpr uint from_left = 1;
71
72 template <typename... T> struct UpDownFlux {
73 template <uint i> using value = typename std::tuple_element<i, std::tuple<T...>>::type;
74 };
75 template <int... n> struct FlowDirections {
76 static constexpr std::array<int, sizeof...(n)> value{{n...}};
77 static constexpr int size = sizeof...(n);
78 };
79 template <int... n> struct UpDown {
80 static constexpr std::array<int, sizeof...(n)> value{{n...}};
81 static constexpr int size = sizeof...(n);
82 };
83 template <typename Model, typename... Collections> class LDGUpDownFluxes
84 {
85 Model &asImp() { return static_cast<Model &>(*this); }
86 const Model &asImp() const { return static_cast<const Model &>(*this); }
87 template <int i> using C = typename std::tuple_element<i, std::tuple<Collections...>>::type;
88
89 public:
90 template <uint dependent, int dim, typename NumberType, typename Solutions_s, typename Solutions_n,
91 typename M = Model>
92 void ldg_numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(dependent)> &NF,
93 const Tensor<1, dim> &normal, const Point<dim> &p, const Solutions_s &u_s,
94 const Solutions_n &u_n) const
95 {
96 static_assert(std::is_same<M, Model>::value, "The call of this method should not have touched M.");
97 static_assert(dependent >= 1, "This is LDG, not DG.");
98
99 using Dirs = typename C<dependent - 1>::template value<0>;
100 using UD = typename C<dependent - 1>::template value<1>;
101 static_assert(Dirs::size == UD::size && UD::size >= M::Components::count_fe_functions(dependent),
102 "Mismatch in array sizes.");
103 using Components = typename M::Components;
104
105 Tensor<1, dim> t;
106 for (uint i = 0; i < dim; ++i)
107 t[i] = -1.;
108
109 std::array<std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(dependent)>, 2> F;
110 // normals are facing outwards! Therefore, the first case is the one where the normal points to the left
111 // (smaller field values), the second case is the one where the normal points to the right (larger field
112 // values).
113 if (scalar_product(t, normal) >= 0) {
114 // F[0] takes the flux from the right (inside the cell), F[1] takes the flux from the left (the other cell)
115 asImp().template ldg_flux<dependent>(F[0], p, u_s);
116 asImp().template ldg_flux<dependent>(F[1], p, u_n);
117 } else {
118 // F[0] takes the flux from the right (the other cell), F[1] takes the flux from the left (inside the cell)
119 asImp().template ldg_flux<dependent>(F[0], p, u_n);
120 asImp().template ldg_flux<dependent>(F[1], p, u_s);
121 }
122
123 for (uint i = 0; i < Components::count_fe_functions(dependent); ++i)
124 NF[i][Dirs::value[i]] = F[UD::value[i]][i][Dirs::value[i]];
125 }
126 };
127
128 template <typename Model> class NoNumFlux
129 {
130 public:
131 template <int dim, typename NumberType, typename Solutions_s, typename Solutions_n, typename M = Model>
132 void numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(0)> &,
133 const Tensor<1, dim> &, const Point<dim> &, const Solutions_s &, const Solutions_n &) const
134 {
135 static_assert(std::is_same<M, Model>::value, "The call of this method should not have touched M.");
136 }
137 };
138
139 template <typename Model> class FlowBoundaries
140 {
141 Model &asImp() { return static_cast<Model &>(*this); }
142 const Model &asImp() const { return static_cast<const Model &>(*this); }
143
144 public:
145 template <int dim, typename NumberType, typename Solutions, typename M = Model>
146 void boundary_numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(0)> &F,
147 const Tensor<1, dim> & /*normal*/, const Point<dim> &p, const Solutions &sol) const
148 {
149 static_assert(std::is_same<M, Model>::value, "The call of this method should not have touched M.");
150 asImp().flux(F, p, sol);
151 }
152
153 template <uint dependent, int dim, typename NumberType, typename Solutions, typename M = Model>
154 void
155 ldg_boundary_numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(dependent)> &BNF,
156 const Tensor<1, dim> & /*normal*/, const Point<dim> &p, const Solutions &u) const
157 {
158 static_assert(std::is_same<M, Model>::value, "The call of this method should not have touched M.");
159 asImp().template ldg_flux<dependent>(BNF, p, u);
160 }
161 };
162 } // namespace def
163} // namespace DiFfRG
Definition numflux.hh:140
const Model & asImp() const
Definition numflux.hh:142
Model & asImp()
Definition numflux.hh:141
void ldg_boundary_numflux(std::array< Tensor< 1, dim, NumberType >, M::Components::count_fe_functions(dependent)> &BNF, const Tensor< 1, dim > &, const Point< dim > &p, const Solutions &u) const
Definition numflux.hh:155
void boundary_numflux(std::array< Tensor< 1, dim, NumberType >, M::Components::count_fe_functions(0)> &F, const Tensor< 1, dim > &, const Point< dim > &p, const Solutions &sol) const
Definition numflux.hh:146
Definition numflux.hh:84
typename std::tuple_element< i, std::tuple< Collections... > >::type C
Definition numflux.hh:87
const Model & asImp() const
Definition numflux.hh:86
Model & asImp()
Definition numflux.hh:85
void ldg_numflux(std::array< Tensor< 1, dim, NumberType >, M::Components::count_fe_functions(dependent)> &NF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Solutions_s &u_s, const Solutions_n &u_n) const
Definition numflux.hh:92
Definition numflux.hh:21
const Model & asImp() const
Definition numflux.hh:23
void numflux(std::array< Tensor< 1, dim, NumberType >, M::Components::count_fe_functions(0)> &NF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Solutions_s &sol_s, const Solutions_n &sol_n) const
Definition numflux.hh:27
Model & asImp()
Definition numflux.hh:22
Definition numflux.hh:129
void numflux(std::array< Tensor< 1, dim, NumberType >, M::Components::count_fe_functions(0)> &, const Tensor< 1, dim > &, const Point< dim > &, const Solutions_s &, const Solutions_n &) const
Definition numflux.hh:132
constexpr uint from_right
Definition numflux.hh:69
constexpr uint from_left
Definition numflux.hh:70
Definition complex_math.hh:14
constexpr auto tuple_tail(const std::tuple< Head, Tail... > &t)
Definition tuples.hh:222
NT dot(const A1 &a1, const A2 &a2)
A dot product which takes the dot product between a1 and a2, assuming each has n entries which can be...
Definition math.hh:203
std::array< NT, n > vector_to_array(const Vector &v)
Definition tuples.hh:203
unsigned int uint
Definition utils.hh:22
Definition complex_math.hh:59
constexpr auto & get(DiFfRG::named_tuple< tuple_type, strs... > &ob)
Definition tuples.hh:119
Definition numflux.hh:75
static constexpr int size
Definition numflux.hh:77
static constexpr std::array< int, sizeof...(n)> value
Definition numflux.hh:76
Definition numflux.hh:72
typename std::tuple_element< i, std::tuple< T... > >::type value
Definition numflux.hh:73
Definition numflux.hh:79
static constexpr int size
Definition numflux.hh:81
static constexpr std::array< int, sizeof...(n)> value
Definition numflux.hh:80