/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/model/numflux.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/model/numflux.hh Source File
DiFfRG
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,
34 "Internal error: template parameter M must be the same as Model. "
35 "Do not explicitly specify the M template parameter.");
36 using Components = typename M::Components;
37
38 std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(0)> F_s{};
39 std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(0)> F_n{};
40 asImp().flux(F_s, p, sol_s);
41 asImp().flux(F_n, p, sol_n);
42
43 const auto &u_s = get<0>(sol_s);
44 const auto &u_n = get<0>(sol_n);
45
46 // A lengthy calculation for the diffusion
47 // we use FD here, as nested AD calculations would be quite the hassle
50 std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(0)> dflux_s{};
51 std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(0)> dflux_n{};
52 for (uint i = 0; i < Model::Components::count_fe_functions(0); ++i) {
53 auto du = 1e-5 * (0.5 * (abs(u_s[i]) + abs(u_n[i])) + 1e-9);
54 du_s[i] += du;
55 du_n[i] += du;
56 asImp().flux(dflux_s, p, Solutions_s::as(std::tuple_cat(std::tie(du_s), tuple_tail(sol_s))));
57 asImp().flux(dflux_n, p, Solutions_n::as(std::tuple_cat(std::tie(du_n), tuple_tail(sol_n))));
58 du_s[i] = u_s[i];
59 du_n[i] = u_n[i];
60
61 const auto alpha = max(abs(dot<dim, NumberType>(dflux_s[i], normal) - dot<dim, NumberType>(F_s[i], normal)),
62 abs(dot<dim, NumberType>(dflux_n[i], normal) - dot<dim, NumberType>(F_n[i], normal))) /
63 du;
64
65 for (uint d = 0; d < dim; ++d)
66 NF[i][d] = 0.5 * (F_s[i][d] + F_n[i][d]) - 0.5 * alpha * (u_n[i] - u_s[i]);
67 }
68 }
69 };
70
71 constexpr uint from_right = 0;
72 constexpr uint from_left = 1;
73
74 template <typename... T> struct UpDownFlux {
75 template <uint i> using value = typename std::tuple_element<i, std::tuple<T...>>::type;
76 };
77 template <int... n> struct FlowDirections {
78 static constexpr std::array<int, sizeof...(n)> value{{n...}};
79 static constexpr int size = sizeof...(n);
80 };
81 template <int... n> struct UpDown {
82 static constexpr std::array<int, sizeof...(n)> value{{n...}};
83 static constexpr int size = sizeof...(n);
84 };
85 template <typename Model, typename... Collections> class LDGUpDownFluxes
86 {
87 Model &asImp() { return static_cast<Model &>(*this); }
88 const Model &asImp() const { return static_cast<const Model &>(*this); }
89 template <int i> using C = typename std::tuple_element<i, std::tuple<Collections...>>::type;
90
91 public:
92 template <uint dependent, int dim, typename NumberType, typename Solutions_s, typename Solutions_n,
93 typename M = Model>
94 void ldg_numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(dependent)> &NF,
95 const Tensor<1, dim> &normal, const Point<dim> &p, const Solutions_s &u_s,
96 const Solutions_n &u_n) const
97 {
98 static_assert(std::is_same<M, Model>::value,
99 "Internal error: template parameter M must be the same as Model. "
100 "Do not explicitly specify the M template parameter.");
101 static_assert(dependent >= 1, "ldg_numflux requires dependent >= 1 (use numflux for dependent == 0).");
102
103 using Dirs = typename C<dependent - 1>::template value<0>;
104 using UD = typename C<dependent - 1>::template value<1>;
105 static_assert(Dirs::size == UD::size && UD::size >= M::Components::count_fe_functions(dependent),
106 "LDG numflux: FlowDirections::size and UpDown::size must both be >= count_fe_functions(dependent).");
107 using Components = typename M::Components;
108
109 Tensor<1, dim> t;
110 for (uint i = 0; i < dim; ++i)
111 t[i] = -1.;
112
113 std::array<std::array<Tensor<1, dim, NumberType>, Components::count_fe_functions(dependent)>, 2> F;
114 // normals are facing outwards! Therefore, the first case is the one where the normal points to the left
115 // (smaller field values), the second case is the one where the normal points to the right (larger field
116 // values).
117 if (scalar_product(t, normal) >= 0) {
118 // F[0] takes the flux from the right (inside the cell), F[1] takes the flux from the left (the other cell)
119 asImp().template ldg_flux<dependent>(F[0], p, u_s);
120 asImp().template ldg_flux<dependent>(F[1], p, u_n);
121 } else {
122 // F[0] takes the flux from the right (the other cell), F[1] takes the flux from the left (inside the cell)
123 asImp().template ldg_flux<dependent>(F[0], p, u_n);
124 asImp().template ldg_flux<dependent>(F[1], p, u_s);
125 }
126
127 for (uint i = 0; i < Components::count_fe_functions(dependent); ++i)
128 NF[i][Dirs::value[i]] = F[UD::value[i]][i][Dirs::value[i]];
129 }
130 };
131
132 template <typename Model> class NoNumFlux
133 {
134 public:
135 template <int dim, typename NumberType, typename Solutions_s, typename Solutions_n, typename M = Model>
136 void numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(0)> &,
137 const Tensor<1, dim> &, const Point<dim> &, const Solutions_s &, const Solutions_n &) const
138 {
139 static_assert(std::is_same<M, Model>::value,
140 "Internal error: template parameter M must be the same as Model. "
141 "Do not explicitly specify the M template parameter.");
142 }
143 };
144
145 template <typename Model> class FlowBoundaries
146 {
147 Model &asImp() { return static_cast<Model &>(*this); }
148 const Model &asImp() const { return static_cast<const Model &>(*this); }
149
150 public:
151 template <int dim, typename NumberType, typename Solutions, typename M = Model>
152 void boundary_numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(0)> &F,
153 const Tensor<1, dim> & /*normal*/, const Point<dim> &p, const Solutions &sol) const
154 {
155 static_assert(std::is_same<M, Model>::value,
156 "Internal error: template parameter M must be the same as Model. "
157 "Do not explicitly specify the M template parameter.");
158 asImp().flux(F, p, sol);
159 }
160
161 template <uint dependent, int dim, typename NumberType, typename Solutions, typename M = Model>
162 void
163 ldg_boundary_numflux(std::array<Tensor<1, dim, NumberType>, M::Components::count_fe_functions(dependent)> &BNF,
164 const Tensor<1, dim> & /*normal*/, const Point<dim> &p, const Solutions &u) const
165 {
166 static_assert(std::is_same<M, Model>::value,
167 "Internal error: template parameter M must be the same as Model. "
168 "Do not explicitly specify the M template parameter.");
169 asImp().template ldg_flux<dependent>(BNF, p, u);
170 }
171 };
172 } // namespace def
173} // namespace DiFfRG
Definition numflux.hh:146
const Model & asImp() const
Definition numflux.hh:148
Model & asImp()
Definition numflux.hh:147
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:163
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:152
Definition numflux.hh:86
typename std::tuple_element< i, std::tuple< Collections... > >::type C
Definition numflux.hh:89
const Model & asImp() const
Definition numflux.hh:88
Model & asImp()
Definition numflux.hh:87
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:94
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:133
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:136
constexpr uint from_right
Definition numflux.hh:71
constexpr uint from_left
Definition numflux.hh:72
Definition complex_math.hh:10
constexpr auto tuple_tail(const std::tuple< Head, Tail... > &t)
Definition tuples.hh:223
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:211
constexpr auto & get(named_tuple< tuple_type, strSet > &ob)
get a reference to the element with the given name
Definition tuples.hh:111
std::array< NT, n > vector_to_array(const Vector &v)
Definition tuples.hh:204
unsigned int uint
Definition utils.hh:24
Definition complex_math.hh:19
Definition numflux.hh:77
static constexpr int size
Definition numflux.hh:79
static constexpr std::array< int, sizeof...(n)> value
Definition numflux.hh:78
Definition numflux.hh:74
typename std::tuple_element< i, std::tuple< T... > >::type value
Definition numflux.hh:75
Definition numflux.hh:81
static constexpr int size
Definition numflux.hh:83
static constexpr std::array< int, sizeof...(n)> value
Definition numflux.hh:82