DiFfRG
Loading...
Searching...
No Matches
ad.hh
Go to the documentation of this file.
1#pragma once
2
3// DiFfRG
6
7// external libraries
8#include <autodiff/forward/dual.hpp>
9#include <autodiff/forward/real.hpp>
10#include <deal.II/base/point.h>
11#include <deal.II/base/tensor.h>
12#include <deal.II/lac/full_matrix.h>
13#include <deal.II/lac/vector.h>
14#include <tbb/tbb.h>
15
16namespace DiFfRG
17{
18 namespace def
19 {
20 using namespace dealii;
21
22 namespace internal
23 {
24 template <typename AD_type> struct AD_tools;
25
26 template <> struct AD_tools<autodiff::dual> {
27 template <uint n, typename Vector> static std::array<autodiff::dual, n> vector_to_AD(const Vector &v)
28 {
29 std::array<autodiff::dual, n> x;
30 for (uint i = 0; i < n; ++i) {
31 x[i] = v[i];
32 }
33 return x;
34 }
35
36 template <uint n, int dim, int r, typename NT>
37 static std::array<dealii::Tensor<r, dim, autodiff::dual>, n>
38 ten_to_AD(const std::vector<dealii::Tensor<r, dim, NT>> &v)
39 {
40 static_assert(r >= 1 && r <= 2, "Only rank 1 and 2 tensors are supported.");
41 std::array<dealii::Tensor<r, dim, autodiff::dual>, n> x;
42 for (uint i = 0; i < n; ++i) {
43 if constexpr (r == 1)
44 for (uint d = 0; d < dim; ++d)
45 x[i][d] = v[i][d];
46 else if constexpr (r == 2)
47 for (uint d1 = 0; d1 < dim; ++d1)
48 for (uint d2 = 0; d2 < dim; ++d2) {
49 x[i][d1][d2] = v[i][d1][d2];
50 }
51 }
52 return x;
53 }
54 };
55
56 template <> struct AD_tools<autodiff::real> {
57 template <uint n, typename Vector> static std::array<autodiff::real, n> vector_to_AD(const Vector &v)
58 {
59 std::array<autodiff::real, n> x;
60 for (uint i = 0; i < n; ++i) {
61 x[i] = v[i];
62 }
63 return x;
64 }
65
66 template <uint n, int dim, int r, typename NT>
67 static std::array<dealii::Tensor<r, dim, autodiff::real>, n>
68 ten_to_AD(const std::vector<dealii::Tensor<r, dim, NT>> &v)
69 {
70 static_assert(r >= 1 && r <= 2, "Only rank 1 and 2 tensors are supported.");
71 std::array<dealii::Tensor<r, dim, autodiff::real>, n> x;
72 for (uint i = 0; i < n; ++i) {
73 if constexpr (r == 1)
74 for (uint d = 0; d < dim; ++d)
75 x[i][d] = v[i][d];
76 else if constexpr (r == 2)
77 for (uint d1 = 0; d1 < dim; ++d1)
78 for (uint d2 = 0; d2 < dim; ++d2) {
79 x[i][d1][d2] = v[i][d1][d2];
80 }
81 }
82 return x;
83 }
84 };
85 } // namespace internal
86
87 template <typename Model, typename AD_type = autodiff::real> class ADjacobian_flux
88 {
89 Model &asImp() { return static_cast<Model &>(*this); }
90 const Model &asImp() const { return static_cast<const Model &>(*this); }
92
93 public:
94 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
95 void jacobian_flux_grad(SimpleMatrix<Tensor<1, dim, Tensor<1, dim, NT>>, n_to, n_from> &jF, const Point<dim> &p,
96 const Vector &sol) const
97 {
98 using Components = typename Model::Components;
99 static_assert(n_to == Components::count_fe_functions());
100 static_assert(n_from == Components::count_fe_functions());
101
102 const auto &u = std::get<tup_idx>(sol);
103 const auto _du = AD_tools::template ten_to_AD<n_from>(u);
104 tbb::parallel_for(
105 tbb::blocked_range2d<uint>(0, Components::count_fe_functions(), 0, dim),
106 [&](const tbb::blocked_range2d<uint> &r) {
107 auto du = _du;
108 for (uint j = r.rows().begin(); j < r.rows().end(); ++j) {
109 for (uint d = r.cols().begin(); d < r.cols().end(); ++d) {
110 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
111 // take derivative with respect to jth variable
112 seed(du[j][d]);
113 asImp().flux(res, p,
114 Vector::as(std::tuple_cat(tuple_first<tup_idx>(sol), std::tie(du),
115 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
116 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
117 for (uint dd = 0; dd < dim; ++dd) {
118 jF(i, j)[dd][d] = grad(res[i][dd]);
119 }
120 }
121 unseed(du[j][d]);
122 }
123 }
124 });
125 }
126
127 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
128 void jacobian_flux_hess(SimpleMatrix<Tensor<1, dim, Tensor<2, dim, NT>>, n_to, n_from> &jF, const Point<dim> &p,
129 const Vector &sol) const
130 {
131 using Components = typename Model::Components;
132 static_assert(n_to == Components::count_fe_functions());
133 static_assert(n_from == Components::count_fe_functions());
134
135 const auto &u = std::get<tup_idx>(sol);
136 const auto _du = AD_tools::template ten_to_AD<n_from>(u);
137 tbb::parallel_for(
138 tbb::blocked_range3d<uint>(0, Components::count_fe_functions(), 0, dim, 0, dim),
139 [&](const tbb::blocked_range3d<uint> &r) {
140 auto du = _du;
141 for (uint j = r.pages().begin(); j < r.pages().end(); ++j) {
142 for (uint d1 = r.rows().begin(); d1 < r.rows().end(); ++d1)
143 for (uint d2 = r.cols().begin(); d2 < r.cols().end(); ++d2) {
144 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
145 // take derivative with respect to jth variable
146 seed(du[j][d1][d2]);
147 asImp().flux(res, p,
148 Vector::as(std::tuple_cat(tuple_first<tup_idx>(sol), std::tie(du),
149 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
150 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
151 for (uint d = 0; d < dim; ++d) {
152 jF(i, j)[d][d1][d2] = grad(res[i][d]);
153 }
154 }
155 unseed(du[j][d1][d2]);
156 }
157 }
158 });
159 }
160
161 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
162 void jacobian_flux_extr(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &jF, const Point<dim> &p,
163 const Vector &sol) const
164 {
165 using Components = typename Model::Components;
166 static_assert(n_to == Components::count_fe_functions());
167 static_assert(n_from == Components::count_extractors());
168
169 const auto &e = std::get<tup_idx>(sol);
170 auto de = AD_tools::template vector_to_AD<n_from>(e);
171 for (uint j = 0; j < Components::count_extractors(); ++j) {
172 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
173 // take derivative with respect to jth variable
174 seed(de[j]);
175 asImp().flux(res, p,
176 Vector::as(std::tuple_cat(tuple_first<tup_idx>(sol), std::tie(de),
177 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
178 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
179 for (uint d = 0; d < dim; ++d) {
180 jF(i, j)[d] = grad(res[i][d]);
181 }
182 }
183 unseed(de[j]);
184 }
185 }
186
187 template <uint from, uint to, uint n_from, uint n_to, int dim, typename NT, typename Vector>
188 void jacobian_flux(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &jF, const Point<dim> &p,
189 const Vector &sol) const
190 {
191 using Components = typename Model::Components;
192 static_assert(n_to == Components::count_fe_functions(to));
193 static_assert(n_from == Components::count_fe_functions(from));
194
195 if constexpr (to == 0) {
196 const auto &u = std::get<from>(sol);
197 const auto _du = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(u);
198 tbb::parallel_for(tbb::blocked_range<uint>(0, Components::count_fe_functions(from)),
199 [&](const tbb::blocked_range<uint> &r) {
200 auto du = _du;
201 for (uint j = r.begin(); j < r.end(); ++j) {
202 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
203 // take derivative with respect to jth variable
204 seed(du[j]);
205 asImp().flux(
206 res, p,
207 Vector::as(std::tuple_cat(tuple_first<from>(sol), std::tie(du),
208 tuple_last<std::tuple_size_v<Vector> - from - 1>(sol))));
209 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
210 for (uint d = 0; d < dim; ++d) {
211 jF(i, j)[d] = grad(res[i][d]);
212 }
213 }
214 unseed(du[j]);
215 }
216 });
217 } else {
218 auto du = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(sol);
219 for (uint j = 0; j < Components::count_fe_functions(from); ++j) {
220 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
221 // take derivative with respect to jth variable
222 seed(du[j]);
223 asImp().template ldg_flux<to>(res, p, du);
224 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
225 for (uint d = 0; d < dim; ++d) {
226 jF(i, j)[d] = grad(res[i][d]);
227 }
228 }
229 unseed(du[j]);
230 }
231 }
232 }
233 };
234
235 template <typename Model, typename AD_type = autodiff::real> class ADjacobian_source
236 {
237 Model &asImp() { return static_cast<Model &>(*this); }
238 const Model &asImp() const { return static_cast<const Model &>(*this); }
240
241 public:
242 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
243 void jacobian_source_grad(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &jS, const Point<dim> &p,
244 const Vector &sol) const
245 {
246 using Components = typename Model::Components;
247 static_assert(n_to == Components::count_fe_functions());
248 static_assert(n_from == Components::count_fe_functions());
249
250 const auto &u = std::get<tup_idx>(sol);
251 const auto _du = AD_tools::template ten_to_AD<n_from>(u);
252 tbb::parallel_for(
253 tbb::blocked_range2d<uint>(0, Components::count_fe_functions(), 0, dim),
254 [&](const tbb::blocked_range2d<uint> &r) {
255 auto du = _du;
256 for (uint j = r.rows().begin(); j < r.rows().end(); ++j) {
257 for (uint d = r.cols().begin(); d < r.cols().end(); ++d) {
258 std::array<AD_type, Components::count_fe_functions()> res{{}};
259 // take derivative with respect to jth variable
260 seed(du[j][d]);
261 asImp().source(res, p,
262 Vector::as(std::tuple_cat(tuple_first<tup_idx>(sol), std::tie(du),
263 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
264 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
265 jS(i, j)[d] = grad(res[i]);
266 }
267 unseed(du[j][d]);
268 }
269 }
270 });
271 }
272
273 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
274 void jacobian_source_hess(SimpleMatrix<Tensor<2, dim, NT>, n_to, n_from> &jS, const Point<dim> &p,
275 const Vector &sol) const
276 {
277 using Components = typename Model::Components;
278 static_assert(n_to == Components::count_fe_functions());
279 static_assert(n_from == Components::count_fe_functions());
280
281 const auto &u = std::get<tup_idx>(sol);
282 const auto _du = AD_tools::template ten_to_AD<n_from>(u);
283 tbb::parallel_for(tbb::blocked_range3d<uint>(0, Components::count_fe_functions(), 0, dim, 0, dim),
284 [&](const tbb::blocked_range3d<uint> &r) {
285 auto du = _du;
286 for (uint j = r.pages().begin(); j < r.pages().end(); ++j) {
287 for (uint d1 = r.rows().begin(); d1 < r.rows().end(); ++d1) {
288 for (uint d2 = r.cols().begin(); d2 < r.cols().end(); ++d2) {
289 std::array<AD_type, Components::count_fe_functions()> res{{}};
290 // take derivative with respect to jth variable
291 seed(du[j][d1][d2]);
292 asImp().source(res, p,
293 Vector::as(std::tuple_cat(
294 tuple_first<tup_idx>(sol), std::tie(du),
295 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
296 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
297 jS(i, j)[d1][d2] = grad(res[i]);
298 }
299 unseed(du[j][d1][d2]);
300 }
301 }
302 }
303 });
304 }
305
306 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
307 void jacobian_source_extr(SimpleMatrix<NT, n_to, n_from> &jS, const Point<dim> &p, const Vector &sol) const
308 {
309 using Components = typename Model::Components;
310 static_assert(n_to == Components::count_fe_functions());
311 static_assert(n_from == Components::count_extractors());
312
313 const auto &e = std::get<tup_idx>(sol);
314 auto de = AD_tools::template vector_to_AD<n_from>(e);
315 for (uint j = 0; j < n_from; ++j) {
316 std::array<AD_type, Components::count_fe_functions()> res{{}};
317 // take derivative with respect to jth variable
318 seed(de[j]);
319 asImp().source(res, p,
320 Vector::as(std::tuple_cat(tuple_first<tup_idx>(sol), std::tie(de),
321 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
322 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
323 jS(i, j) = grad(res[i]);
324 }
325 unseed(de[j]);
326 }
327 }
328
329 template <uint from, uint to, uint n_from, uint n_to, int dim, typename NT, typename Vector>
330 void jacobian_source(SimpleMatrix<NT, n_to, n_from> &jS, const Point<dim> &p, const Vector &sol) const
331 {
332 using Components = typename Model::Components;
333 static_assert(n_to == Components::count_fe_functions(to));
334 static_assert(n_from == Components::count_fe_functions(from));
335
336 if constexpr (to == 0) {
337 const auto &u = std::get<from>(sol);
338 const auto _du = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(u);
339 tbb::parallel_for(tbb::blocked_range<uint>(0, Components::count_fe_functions(from)),
340 [&](const tbb::blocked_range<uint> &r) {
341 auto du = _du;
342 for (uint j = r.begin(); j < r.end(); ++j) {
343 std::array<AD_type, Components::count_fe_functions(to)> res{{}};
344 // take derivative with respect to jth variable
345 seed(du[j]);
346 asImp().source(
347 res, p,
348 Vector::as(std::tuple_cat(tuple_first<from>(sol), std::tie(du),
349 tuple_last<std::tuple_size_v<Vector> - from - 1>(sol))));
350 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
351 jS(i, j) = grad(res[i]);
352 }
353 unseed(du[j]);
354 }
355 });
356 } else {
357 auto du = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(sol);
358 for (uint j = 0; j < Components::count_fe_functions(from); ++j) {
359 std::array<AD_type, Components::count_fe_functions(to)> res{{}};
360 // take derivative with respect to jth variable
361 seed(du[j]);
362 asImp().template ldg_source<to>(res, p, du);
363 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
364 jS(i, j) = grad(res[i]);
365 }
366 unseed(du[j]);
367 }
368 }
369 }
370 };
371
372 template <typename Model, typename AD_type = autodiff::real> class ADjacobian_numflux
373 {
374 Model &asImp() { return static_cast<Model &>(*this); }
375 const Model &asImp() const { return static_cast<const Model &>(*this); }
377
378 public:
379 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
380 void jacobian_numflux_grad(std::array<SimpleMatrix<Tensor<1, dim, Tensor<1, dim, NT>>, n_to, n_from>, 2> &jNF,
381 const Tensor<1, dim> &normal, const Point<dim> &p, const Vector_s &sol_s,
382 const Vector_n &sol_n) const
383 {
384 using Components = typename Model::Components;
385 static_assert(n_to == Components::count_fe_functions());
386 static_assert(n_from == Components::count_fe_functions());
387
388 const auto &u_s = std::get<tup_idx>(sol_s);
389 const auto &u_n = std::get<tup_idx>(sol_n);
390
391 auto du_s = AD_tools::template ten_to_AD<n_from>(u_s);
392 for (uint j = 0; j < Components::count_fe_functions(); ++j) {
393 for (uint d = 0; d < dim; ++d) {
394 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
395 // take derivative with respect to jth variable
396 seed(du_s[j][d]);
397 asImp().numflux(res, normal, p,
398 Vector_s::as(std::tuple_cat(tuple_first<tup_idx>(sol_s), std::tie(du_s),
399 tuple_last<std::tuple_size_v<Vector_s> - tup_idx - 1>(sol_s))),
400 sol_n);
401 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
402 for (uint dd = 0; dd < dim; ++dd) {
403 jNF[0](i, j)[dd][d] = grad(res[i][dd]);
404 }
405 }
406 unseed(du_s[j][d]);
407 }
408 }
409 auto du_n = AD_tools::template ten_to_AD<n_from>(u_n);
410 for (uint j = 0; j < Components::count_fe_functions(); ++j) {
411 for (uint d = 0; d < dim; ++d) {
412 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
413 // take derivative with respect to jth variable
414 seed(du_n[j][d]);
415 asImp().numflux(res, normal, p, sol_s,
416 Vector_n::as(std::tuple_cat(tuple_first<tup_idx>(sol_n), std::tie(du_n),
417 tuple_last<std::tuple_size_v<Vector_n> - tup_idx - 1>(sol_n))));
418 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
419 for (uint dd = 0; dd < dim; ++dd) {
420 jNF[1](i, j)[dd][d] = grad(res[i][dd]);
421 }
422 }
423 unseed(du_n[j][d]);
424 }
425 }
426 }
427
428 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
429 void jacobian_numflux_hess(std::array<SimpleMatrix<Tensor<1, dim, Tensor<2, dim, NT>>, n_to, n_from>, 2> &jNF,
430 const Tensor<1, dim> &normal, const Point<dim> &p, const Vector_s &sol_s,
431 const Vector_n &sol_n) const
432 {
433 using Components = typename Model::Components;
434 static_assert(n_to == Components::count_fe_functions());
435 static_assert(n_from == Components::count_fe_functions());
436
437 const auto &u_s = std::get<tup_idx>(sol_s);
438 const auto &u_n = std::get<tup_idx>(sol_n);
439
440 auto du_s = AD_tools::template ten_to_AD<n_from>(u_s);
441 for (uint j = 0; j < Components::count_fe_functions(); ++j) {
442 for (uint d1 = 0; d1 < dim; ++d1)
443 for (uint d2 = 0; d2 < dim; ++d2) {
444 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
445 // take derivative with respect to jth variable
446 seed(du_s[j][d1][d2]);
447 asImp().numflux(
448 res, normal, p,
449 Vector_s::as(std::tuple_cat(tuple_first<tup_idx>(sol_s), std::tie(du_s),
450 tuple_last<std::tuple_size_v<Vector_s> - tup_idx - 1>(sol_s))),
451 sol_n);
452 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
453 for (uint d = 0; d < dim; ++d) {
454 jNF[0](i, j)[d][d1][d2] = grad(res[i][d]);
455 }
456 }
457 unseed(du_s[j][d1][d2]);
458 }
459 }
460 auto du_n = AD_tools::template ten_to_AD<n_from>(u_n);
461 for (uint j = 0; j < Components::count_fe_functions(); ++j) {
462 for (uint d1 = 0; d1 < dim; ++d1)
463 for (uint d2 = 0; d2 < dim; ++d2) {
464 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
465 // take derivative with respect to jth variable
466 seed(du_n[j][d1][d2]);
467 asImp().numflux(
468 res, normal, p, sol_s,
469 Vector_n::as(std::tuple_cat(tuple_first<tup_idx>(sol_n), std::tie(du_n),
470 tuple_last<std::tuple_size_v<Vector_n> - tup_idx - 1>(sol_n))));
471 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
472 for (uint d = 0; d < dim; ++d) {
473 jNF[1](i, j)[d][d1][d2] = grad(res[i][d]);
474 }
475 }
476 unseed(du_n[j][d1][d2]);
477 }
478 }
479 }
480
481 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
482 void jacobian_numflux_extr(std::array<SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from>, 2> &jNF,
483 const Tensor<1, dim> &normal, const Point<dim> &p, const Vector_s &sol_s,
484 const Vector_n &sol_n) const
485 {
486 using Components = typename Model::Components;
487 static_assert(n_to == Components::count_fe_functions());
488 static_assert(n_from == Components::count_extractors());
489
490 const auto &e = std::get<tup_idx>(sol_s);
491 auto de = AD_tools::template vector_to_AD<n_from>(e);
492 for (uint j = 0; j < n_from; ++j) {
493 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res_s{{}};
494 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res_n{{}};
495 // take derivative with respect to jth variable
496 seed(de[j]);
497 asImp().numflux(res_s, normal, p,
498 Vector_s::as(std::tuple_cat(tuple_first<tup_idx>(sol_s), std::tie(de),
499 tuple_last<std::tuple_size_v<Vector_s> - tup_idx - 1>(sol_s))),
500 sol_n);
501 asImp().numflux(res_n, normal, p, sol_s,
502 Vector_n::as(std::tuple_cat(tuple_first<tup_idx>(sol_n), std::tie(de),
503 tuple_last<std::tuple_size_v<Vector_n> - tup_idx - 1>(sol_n))));
504 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
505 for (uint d = 0; d < dim; ++d) {
506 jNF[0](i, j)[d] = grad(res_s[i][d]);
507 jNF[1](i, j)[d] = grad(res_n[i][d]);
508 }
509 }
510 unseed(de[j]);
511 }
512 }
513
514 template <uint from, uint to, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
515 void jacobian_numflux(std::array<SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from>, 2> &jNF,
516 const Tensor<1, dim> &normal, const Point<dim> &p, const Vector_s &sol_s,
517 const Vector_n &sol_n) const
518 {
519 using Components = typename Model::Components;
520 static_assert(n_to == Components::count_fe_functions(to));
521 static_assert(n_from == Components::count_fe_functions(from));
522
523 if constexpr (to == 0) {
524 const auto &u_s = std::get<from>(sol_s);
525 const auto &u_n = std::get<from>(sol_n);
526
527 auto du_s = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(u_s);
528 for (uint j = 0; j < Components::count_fe_functions(from); ++j) {
529 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
530 // take derivative with respect to jth variable
531 seed(du_s[j]);
532 asImp().numflux(res, normal, p,
533 Vector_s::as(std::tuple_cat(tuple_first<from>(sol_s), std::tie(du_s),
534 tuple_last<std::tuple_size_v<Vector_s> - from - 1>(sol_s))),
535 sol_n);
536 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
537 for (uint d = 0; d < dim; ++d) {
538 jNF[0](i, j)[d] = grad(res[i][d]);
539 }
540 }
541 unseed(du_s[j]);
542 }
543 auto du_n = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(u_n);
544 for (uint j = 0; j < Components::count_fe_functions(from); ++j) {
545 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
546 // take derivative with respect to jth variable
547 seed(du_n[j]);
548 asImp().numflux(res, normal, p, sol_s,
549 Vector_n::as(std::tuple_cat(tuple_first<from>(sol_n), std::tie(du_n),
550 tuple_last<std::tuple_size_v<Vector_n> - from - 1>(sol_n))));
551 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
552 for (uint d = 0; d < dim; ++d) {
553 jNF[1](i, j)[d] = grad(res[i][d]);
554 }
555 }
556 unseed(du_n[j]);
557 }
558 } else {
559 auto du_s = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(sol_s);
560 for (uint j = 0; j < Components::count_fe_functions(from); ++j) {
561 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
562 // take derivative with respect to jth variable
563 seed(du_s[j]);
564 asImp().template ldg_numflux<to>(res, normal, p, du_s, sol_n);
565 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
566 for (uint d = 0; d < dim; ++d) {
567 jNF[0](i, j)[d] = grad(res[i][d]);
568 }
569 }
570 unseed(du_s[j]);
571 }
572 auto du_n = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(sol_n);
573 for (uint j = 0; j < Components::count_fe_functions(from); ++j) {
574 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
575 // take derivative with respect to jth variable
576 seed(du_n[j]);
577 asImp().template ldg_numflux<to>(res, normal, p, sol_s, du_n);
578 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
579 for (uint d = 0; d < dim; ++d) {
580 jNF[1](i, j)[d] = grad(res[i][d]);
581 }
582 }
583 unseed(du_n[j]);
584 }
585 }
586 }
587 };
588
589 template <typename Model, typename AD_type = autodiff::real> class ADjacobian_boundary_numflux
590 {
591 Model &asImp() { return static_cast<Model &>(*this); }
592 const Model &asImp() const { return static_cast<const Model &>(*this); }
594
595 public:
596 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
597 void jacobian_boundary_numflux_grad(SimpleMatrix<Tensor<1, dim, Tensor<1, dim, NT>>, n_to, n_from> &jBNF,
598 const Tensor<1, dim> &normal, const Point<dim> &p, const Vector &sol) const
599 {
600 using Components = typename Model::Components;
601 static_assert(n_to == Components::count_fe_functions());
602 static_assert(n_from == Components::count_fe_functions());
603
604 const auto &u = std::get<tup_idx>(sol);
605 auto du = AD_tools::template ten_to_AD<n_from>(u);
606 for (uint j = 0; j < Components::count_fe_functions(); ++j) {
607 for (uint d = 0; d < dim; ++d) {
608 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
609 // take derivative with respect to jth variable
610 seed(du[j][d]);
611 asImp().boundary_numflux(
612 res, normal, p,
613 Vector::as(std::tuple_cat(tuple_first<tup_idx>(sol), std::tie(du),
614 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
615 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
616 for (uint dd = 0; dd < dim; ++dd) {
617 jBNF(i, j)[dd][d] = grad(res[i][dd]);
618 }
619 }
620 unseed(du[j][d]);
621 }
622 }
623 }
624
625 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
626 void jacobian_boundary_numflux_hess(SimpleMatrix<Tensor<1, dim, Tensor<2, dim, NT>>, n_to, n_from> &jBNF,
627 const Tensor<1, dim> &normal, const Point<dim> &p, const Vector &sol) const
628 {
629 using Components = typename Model::Components;
630 static_assert(n_to == Components::count_fe_functions());
631 static_assert(n_from == Components::count_fe_functions());
632
633 const auto &u = std::get<tup_idx>(sol);
634 auto du = AD_tools::template ten_to_AD<n_from>(u);
635 for (uint j = 0; j < Components::count_fe_functions(); ++j) {
636 for (uint d1 = 0; d1 < dim; ++d1)
637 for (uint d2 = 0; d2 < dim; ++d2) {
638 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
639 // take derivative with respect to jth variable
640 seed(du[j][d1][d2]);
641 asImp().boundary_numflux(
642 res, normal, p,
643 Vector::as(std::tuple_cat(tuple_first<tup_idx>(sol), std::tie(du),
644 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
645 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
646 for (uint d = 0; d < dim; ++d) {
647 jBNF(i, j)[d][d1][d2] = grad(res[i][d]);
648 }
649 }
650 unseed(du[j][d1][d2]);
651 }
652 }
653 }
654
655 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
656 void jacobian_boundary_numflux_extr(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &jBNF,
657 const Tensor<1, dim> &normal, const Point<dim> &p, const Vector &sol) const
658 {
659 using Components = typename Model::Components;
660 static_assert(n_to == Components::count_fe_functions());
661 static_assert(n_from == Components::count_extractors());
662
663 const auto &e = std::get<tup_idx>(sol);
664 auto de = AD_tools::template vector_to_AD<n_from>(e);
665 for (uint j = 0; j < n_from; ++j) {
666 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions()> res{{}};
667 // take derivative with respect to jth variable
668 seed(de[j]);
669 asImp().boundary_numflux(
670 res, normal, p,
671 Vector::as(std::tuple_cat(tuple_first<tup_idx>(sol), std::tie(de),
672 tuple_last<std::tuple_size_v<Vector> - tup_idx - 1>(sol))));
673 for (uint i = 0; i < Components::count_fe_functions(); ++i) {
674 for (uint d = 0; d < dim; ++d) {
675 jBNF(i, j)[d] = grad(res[i][d]);
676 }
677 }
678 unseed(de[j]);
679 }
680 }
681
682 template <uint from, uint to, uint n_from, uint n_to, int dim, typename NT, typename Vector>
683 void jacobian_boundary_numflux(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &jBNF, const Tensor<1, dim> &normal,
684 const Point<dim> &p, const Vector &sol) const
685 {
686 using Components = typename Model::Components;
687 static_assert(n_to == Components::count_fe_functions(to));
688 static_assert(n_from == Components::count_fe_functions(from));
689
690 if constexpr (to == 0) {
691 const auto &u = std::get<from>(sol);
692 auto du = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(u);
693 for (uint j = 0; j < Components::count_fe_functions(from); ++j) {
694 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
695 // take derivative with respect to jth variable
696 seed(du[j]);
697 asImp().boundary_numflux(res, normal, p,
698 Vector::as(std::tuple_cat(tuple_first<from>(sol), std::tie(du),
699 tuple_last<std::tuple_size_v<Vector> - from - 1>(sol))));
700 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
701 for (uint d = 0; d < dim; ++d) {
702 jBNF(i, j)[d] = grad(res[i][d]);
703 }
704 }
705 unseed(du[j]);
706 }
707 } else {
708 auto du = AD_tools::template vector_to_AD<Components::count_fe_functions(from)>(sol);
709 for (uint j = 0; j < Components::count_fe_functions(from); ++j) {
710 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
711 // take derivative with respect to jth variable
712 seed(du[j]);
713 asImp().template ldg_boundary_numflux<to>(res, normal, p, du);
714 for (uint i = 0; i < Components::count_fe_functions(to); ++i) {
715 for (uint d = 0; d < dim; ++d) {
716 jBNF(i, j)[d] = grad(res[i][d]);
717 }
718 }
719 unseed(du[j]);
720 }
721 }
722 }
723 };
724
725 template <typename Model, typename AD_type = autodiff::real> class ADjacobian_mass
726 {
727 Model &asImp() { return static_cast<Model &>(*this); }
728 const Model &asImp() const { return static_cast<const Model &>(*this); }
730
731 public:
732 template <uint dot, uint n_from, uint n_to, int dim, typename NT, typename Vector>
733 void jacobian_mass(SimpleMatrix<NT, n_to, n_from> &jM, const Point<dim> &p, const Vector &u,
734 const Vector &u_dot) const
735 {
736 using Components = typename Model::Components;
737 static_assert(n_from == Components::count_fe_functions() && n_to == Components::count_fe_functions());
738
739 if constexpr (dot == 0) {
740 auto du = AD_tools::template vector_to_AD<Components::count_fe_functions(0)>(u);
741 for (uint j = 0; j < Components::count_fe_functions(0); ++j) {
742 std::array<AD_type, Components::count_fe_functions(0)> res{{}};
743 // take derivative with respect to jth variable
744 seed(du[j]);
745 asImp().mass(res, p, du, u_dot);
746 for (uint i = 0; i < Components::count_fe_functions(0); ++i) {
747 jM(i, j) = grad(res[i]);
748 }
749 unseed(du[j]);
750 }
751 } else {
752 auto du_dot = AD_tools::template vector_to_AD<Components::count_fe_functions(0)>(u_dot);
753 for (uint j = 0; j < Components::count_fe_functions(0); ++j) {
754 std::array<AD_type, Components::count_fe_functions(0)> res{{}};
755 // take derivative with respect to jth variable
756 seed(du_dot[j]);
757 asImp().mass(res, p, u, du_dot);
758 for (uint i = 0; i < Components::count_fe_functions(0); ++i) {
759 jM(i, j) = grad(res[i]);
760 }
761 unseed(du_dot[j]);
762 }
763 }
764 }
765 };
766
767 template <typename Model, typename AD_type = autodiff::real> class ADjacobian_variables
768 {
769 Model &asImp() { return static_cast<Model &>(*this); }
770 const Model &asImp() const { return static_cast<const Model &>(*this); }
772
773 public:
774 template <uint to, typename NT, typename Solution>
775 void jacobian_variables(FullMatrix<NT> &jac, const Solution &sol) const
776 {
777 const auto &variables = std::get<0>(sol);
778 const auto &extractors = std::get<1>(sol);
779 if constexpr (to == 0) {
780 AssertThrow(jac.m() == variables.size() && jac.n() == variables.size(),
781 ExcMessage("Assure that the jacobian has the right dimension!"));
782 } else if constexpr (to == 1) {
783 AssertThrow(jac.m() == variables.size() && jac.n() == extractors.size(),
784 ExcMessage("Assure that the jacobian has the right dimension!"));
785 }
786
787 if constexpr (to == 0) {
788 auto du = AD_tools::template vector_to_AD<Model::Components::count_variables()>(variables);
789 for (uint j = 0; j < Model::Components::count_variables(); ++j) {
790 std::array<AD_type, Model::Components::count_variables()> res{{}};
791 // take derivative with respect to jth variable
792 seed(du[j]);
793 asImp().dt_variables(res,
794 Solution::as(std::tuple_cat(tuple_first<to>(sol), std::tie(du),
795 tuple_last<std::tuple_size_v<Solution> - to - 1>(sol))));
796 for (uint i = 0; i < Model::Components::count_variables(); ++i) {
797 jac(i, j) = grad(res[i]);
798 }
799 unseed(du[j]);
800 }
801 } else if constexpr (to == 1) {
802 auto du = AD_tools::template vector_to_AD<Model::Components::count_extractors()>(extractors);
803 for (uint j = 0; j < Model::Components::count_extractors(); ++j) {
804 std::array<AD_type, Model::Components::count_variables()> res{{}};
805 // take derivative with respect to jth variable
806 seed(du[j]);
807 asImp().dt_variables(res,
808 Solution::as(std::tuple_cat(tuple_first<to>(sol), std::tie(du),
809 tuple_last<std::tuple_size_v<Solution> - to - 1>(sol))));
810 for (uint i = 0; i < Model::Components::count_extractors(); ++i) {
811 jac(i, j) = grad(res[i]);
812 }
813 unseed(du[j]);
814 }
815 }
816 }
817 };
818
819 template <typename Model, typename AD_type = autodiff::real> class ADjacobian_extractors
820 {
821 Model &asImp() { return static_cast<Model &>(*this); }
822 const Model &asImp() const { return static_cast<const Model &>(*this); }
824
825 public:
826 template <uint to, int dim, typename NT, typename Solution>
827 void jacobian_extractors(FullMatrix<NT> &jac, const Point<dim> &x, const Solution &sol) const
828 {
829 static_assert(std::is_same_v<NT, double>, "Only double is supported for now!");
830 const auto &fe_functions = std::get<0>(sol);
831 const auto &fe_derivatives = std::get<1>(sol);
832 const auto &fe_hessians = std::get<2>(sol);
833
834 if constexpr (to == 0) {
835 AssertThrow(jac.m() == Model::Components::count_extractors() && jac.n() == fe_functions.size(),
836 ExcMessage("Assure that the jacobian has the right dimension!"));
837 } else if constexpr (to == 1) {
838 AssertThrow(jac.m() == Model::Components::count_extractors() && jac.n() == fe_derivatives.size() * dim,
839 ExcMessage("Assure that the jacobian has the right dimension!"));
840 } else if constexpr (to == 2) {
841 AssertThrow(jac.m() == Model::Components::count_extractors() && jac.n() == fe_derivatives.size() * dim * dim,
842 ExcMessage("Assure that the jacobian has the right dimension!"));
843 }
844
845 if constexpr (to == 0) {
846 auto du = AD_tools::template vector_to_AD<Model::Components::count_fe_functions()>(fe_functions);
847 for (uint j = 0; j < Model::Components::count_fe_functions(); ++j) {
848 std::array<AD_type, Model::Components::count_extractors()> res{{}};
849 // take derivative with respect to jth variable
850 seed(du[j]);
851 asImp().extract(res, x,
852 Solution::as(std::tuple_cat(tuple_first<to>(sol), std::tie(du),
853 tuple_last<std::tuple_size_v<Solution> - to - 1>(sol))));
854 for (uint i = 0; i < Model::Components::count_extractors(); ++i) {
855 jac(i, j) = grad(res[i]);
856 }
857 unseed(du[j]);
858 }
859 } else if constexpr (to == 1) {
860 auto du = AD_tools::template ten_to_AD<Model::Components::count_fe_functions()>(fe_derivatives);
861 for (uint j = 0; j < Model::Components::count_fe_functions(); ++j) {
862 for (uint d1 = 0; d1 < dim; ++d1) {
863 std::array<AD_type, Model::Components::count_extractors()> res{{}};
864 // take derivative with respect to jth variable
865 seed(du[j][d1]);
866 asImp().extract(res, x,
867 Solution::as(std::tuple_cat(tuple_first<to>(sol), std::tie(du),
868 tuple_last<std::tuple_size_v<Solution> - to - 1>(sol))));
869 for (uint i = 0; i < Model::Components::count_extractors(); ++i) {
870 jac(i, j * dim + d1) = grad(res[i]);
871 }
872 unseed(du[j][d1]);
873 }
874 }
875 } else if constexpr (to == 2) {
876 auto du = AD_tools::template ten_to_AD<Model::Components::count_fe_functions()>(fe_hessians);
877 for (uint j = 0; j < Model::Components::count_fe_functions(); ++j) {
878 for (uint d1 = 0; d1 < dim; ++d1)
879 for (uint d2 = 0; d2 < dim; ++d2) {
880 std::array<AD_type, Model::Components::count_extractors()> res{{}};
881 // take derivative with respect to jth variable
882 seed(du[j][d1][d2]);
883 asImp().extract(res, x,
884 Solution::as(std::tuple_cat(tuple_first<to>(sol), std::tie(du),
885 tuple_last<std::tuple_size_v<Solution> - to - 1>(sol))));
886 for (uint i = 0; i < Model::Components::count_extractors(); ++i) {
887 jac(i, j * dim * dim + d1 * dim + d2) = grad(res[i]);
888 }
889 unseed(du[j][d1][d2]);
890 }
891 }
892 }
893 }
894 };
895
896 template <typename Model>
897 class AD_real : public ADjacobian_flux<Model, autodiff::real>,
898 public ADjacobian_source<Model, autodiff::real>,
899 public ADjacobian_numflux<Model, autodiff::real>,
900 public ADjacobian_boundary_numflux<Model, autodiff::real>,
901 public ADjacobian_mass<Model, autodiff::real>,
902 public ADjacobian_variables<Model, autodiff::real>,
903 public ADjacobian_extractors<Model, autodiff::real>
904 {
905 };
906
907 template <typename Model>
908 class AD_dual : public ADjacobian_flux<Model, autodiff::dual>,
909 public ADjacobian_source<Model, autodiff::dual>,
910 public ADjacobian_numflux<Model, autodiff::dual>,
911 public ADjacobian_boundary_numflux<Model, autodiff::dual>,
912 public ADjacobian_mass<Model, autodiff::dual>,
913 public ADjacobian_variables<Model, autodiff::dual>,
914 public ADjacobian_extractors<Model, autodiff::dual>
915 {
916 };
917
918 template <typename Model> using AD = AD_real<Model>;
919
920 template <typename Model>
921 class FE_AD : public ADjacobian_flux<Model, autodiff::real>,
922 public ADjacobian_source<Model, autodiff::real>,
923 public ADjacobian_numflux<Model, autodiff::real>,
924 public ADjacobian_boundary_numflux<Model, autodiff::real>,
925 public ADjacobian_mass<Model, autodiff::real>
926 {
927 public:
928 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
929 void jacobian_flux_extr(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &, const Point<dim> &,
930 const Vector &) const
931 {
932 }
933 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
934 void jacobian_source_extr(SimpleMatrix<NT, n_to, n_from> &, const Point<dim> &, const Vector &) const
935 {
936 }
937 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
938 void jacobian_numflux_extr(std::array<SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from>, 2> &,
939 const Tensor<1, dim> &, const Point<dim> &, const Vector_s &, const Vector_n &) const
940 {
941 }
942 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
943 void jacobian_boundary_numflux_extr(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &, const Tensor<1, dim> &,
944 const Point<dim> &, const Vector &) const
945 {
946 }
947 template <uint to, int dim, typename NT, typename Solution>
948 void jacobian_extractors(FullMatrix<NT> &, const Point<dim> &, const Solution &) const
949 {
950 }
951 template <uint to, typename NT, typename Solution>
952 void jacobian_variables(FullMatrix<NT> &, const Solution &) const
953 {
954 }
955 };
956
958 {
959 public:
960 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
961 void jacobian_flux_grad(SimpleMatrix<Tensor<1, dim, Tensor<1, dim, NT>>, n_to, n_from> &, const Point<dim> &,
962 const Vector &) const
963 {
964 }
965 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
966 void jacobian_flux_hess(SimpleMatrix<Tensor<1, dim, Tensor<2, dim, NT>>, n_to, n_from> &, const Point<dim> &,
967 const Vector &) const
968 {
969 }
970 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
971 void jacobian_flux_extr(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &, const Point<dim> &,
972 const Vector &) const
973 {
974 }
975 template <uint from, uint to, uint n_from, uint n_to, int dim, typename NT, typename Vector>
976 void jacobian_flux(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &, const Point<dim> &, const Vector &) const
977 {
978 }
979 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
980 void jacobian_source_grad(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &, const Point<dim> &,
981 const Vector &) const
982 {
983 }
984 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
985 void jacobian_source_hess(SimpleMatrix<Tensor<2, dim, NT>, n_to, n_from> &, const Point<dim> &,
986 const Vector &) const
987 {
988 }
989 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
990 void jacobian_source_extr(SimpleMatrix<NT, n_to, n_from> &, const Point<dim> &, const Vector &) const
991 {
992 }
993 template <uint from, uint to, uint n_from, uint n_to, int dim, typename NT, typename Vector>
994 void jacobian_source(SimpleMatrix<NT, n_to, n_from> &, const Point<dim> &, const Vector &) const
995 {
996 }
997 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
998 void jacobian_numflux_grad(std::array<SimpleMatrix<Tensor<1, dim, Tensor<1, dim, NT>>, n_to, n_from>, 2> &,
999 const Tensor<1, dim> &, const Point<dim> &, const Vector_s &, const Vector_n &) const
1000 {
1001 }
1002 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
1003 void jacobian_numflux_hess(std::array<SimpleMatrix<Tensor<1, dim, Tensor<2, dim, NT>>, n_to, n_from>, 2> &,
1004 const Tensor<1, dim> &, const Point<dim> &, const Vector_s &, const Vector_n &) const
1005 {
1006 }
1007 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
1008 void jacobian_numflux_extr(std::array<SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from>, 2> &,
1009 const Tensor<1, dim> &, const Point<dim> &, const Vector_s &, const Vector_n &) const
1010 {
1011 }
1012 template <uint from, uint to, uint n_from, uint n_to, int dim, typename NT, typename Vector_s, typename Vector_n>
1013 void jacobian_numflux(std::array<SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from>, 2> &, const Tensor<1, dim> &,
1014 const Point<dim> &, const Vector_s &, const Vector_n &) const
1015 {
1016 }
1017 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
1018 void jacobian_boundary_numflux_grad(SimpleMatrix<Tensor<1, dim, Tensor<1, dim, NT>>, n_to, n_from> &,
1019 const Tensor<1, dim> &, const Point<dim> &, const Vector &) const
1020 {
1021 }
1022 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
1023 void jacobian_boundary_numflux_hess(SimpleMatrix<Tensor<1, dim, Tensor<2, dim, NT>>, n_to, n_from> &,
1024 const Tensor<1, dim> &, const Point<dim> &, const Vector &) const
1025 {
1026 }
1027 template <uint tup_idx, uint n_from, uint n_to, int dim, typename NT, typename Vector>
1028 void jacobian_boundary_numflux_extr(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &, const Tensor<1, dim> &,
1029 const Point<dim> &, const Vector &) const
1030 {
1031 }
1032 template <uint from, uint to, uint n_from, uint n_to, int dim, typename NT, typename Vector>
1033 void jacobian_boundary_numflux(SimpleMatrix<Tensor<1, dim, NT>, n_to, n_from> &, const Tensor<1, dim> &,
1034 const Point<dim> &, const Vector &) const
1035 {
1036 }
1037 template <uint dot, uint n_from, uint n_to, int dim, typename NT, typename Vector>
1038 void jacobian_mass(SimpleMatrix<NT, n_to, n_from> &, const Point<dim> &, const Vector &, const Vector &) const
1039 {
1040 }
1041
1042 template <uint to, int dim, typename NT, typename Solution>
1043 void jacobian_extractors(FullMatrix<NT> &, const Point<dim> &, const Solution &) const
1044 {
1045 }
1046 template <uint to, typename NT, typename Solution>
1047 void jacobian_variables(FullMatrix<NT> &, const Solution &) const
1048 {
1049 }
1050 };
1051
1052 } // namespace def
1053} // namespace DiFfRG
A simple NxM-matrix class, which is used for cell-wise Jacobians.
Definition tuples.hh:153
Definition ad.hh:915
Definition ad.hh:904
void jacobian_boundary_numflux_grad(SimpleMatrix< Tensor< 1, dim, Tensor< 1, dim, NT > >, n_to, n_from > &jBNF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:597
void jacobian_boundary_numflux_hess(SimpleMatrix< Tensor< 1, dim, Tensor< 2, dim, NT > >, n_to, n_from > &jBNF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:626
const Model & asImp() const
Definition ad.hh:592
void jacobian_boundary_numflux_extr(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &jBNF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:656
Model & asImp()
Definition ad.hh:591
void jacobian_boundary_numflux(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &jBNF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:683
Model & asImp()
Definition ad.hh:821
void jacobian_extractors(FullMatrix< NT > &jac, const Point< dim > &x, const Solution &sol) const
Definition ad.hh:827
const Model & asImp() const
Definition ad.hh:822
Definition ad.hh:88
void jacobian_flux_grad(SimpleMatrix< Tensor< 1, dim, Tensor< 1, dim, NT > >, n_to, n_from > &jF, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:95
void jacobian_flux_extr(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &jF, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:162
void jacobian_flux(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &jF, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:188
void jacobian_flux_hess(SimpleMatrix< Tensor< 1, dim, Tensor< 2, dim, NT > >, n_to, n_from > &jF, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:128
const Model & asImp() const
Definition ad.hh:90
Model & asImp()
Definition ad.hh:89
Definition ad.hh:726
void jacobian_mass(SimpleMatrix< NT, n_to, n_from > &jM, const Point< dim > &p, const Vector &u, const Vector &u_dot) const
Definition ad.hh:733
Model & asImp()
Definition ad.hh:727
const Model & asImp() const
Definition ad.hh:728
const Model & asImp() const
Definition ad.hh:375
void jacobian_numflux_extr(std::array< SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from >, 2 > &jNF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Vector_s &sol_s, const Vector_n &sol_n) const
Definition ad.hh:482
Model & asImp()
Definition ad.hh:374
void jacobian_numflux(std::array< SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from >, 2 > &jNF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Vector_s &sol_s, const Vector_n &sol_n) const
Definition ad.hh:515
void jacobian_numflux_grad(std::array< SimpleMatrix< Tensor< 1, dim, Tensor< 1, dim, NT > >, n_to, n_from >, 2 > &jNF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Vector_s &sol_s, const Vector_n &sol_n) const
Definition ad.hh:380
void jacobian_numflux_hess(std::array< SimpleMatrix< Tensor< 1, dim, Tensor< 2, dim, NT > >, n_to, n_from >, 2 > &jNF, const Tensor< 1, dim > &normal, const Point< dim > &p, const Vector_s &sol_s, const Vector_n &sol_n) const
Definition ad.hh:429
Definition ad.hh:236
void jacobian_source_grad(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &jS, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:243
void jacobian_source(SimpleMatrix< NT, n_to, n_from > &jS, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:330
Model & asImp()
Definition ad.hh:237
void jacobian_source_extr(SimpleMatrix< NT, n_to, n_from > &jS, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:307
const Model & asImp() const
Definition ad.hh:238
void jacobian_source_hess(SimpleMatrix< Tensor< 2, dim, NT >, n_to, n_from > &jS, const Point< dim > &p, const Vector &sol) const
Definition ad.hh:274
Model & asImp()
Definition ad.hh:769
void jacobian_variables(FullMatrix< NT > &jac, const Solution &sol) const
Definition ad.hh:775
const Model & asImp() const
Definition ad.hh:770
Definition ad.hh:926
void jacobian_boundary_numflux_extr(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector &) const
Definition ad.hh:943
void jacobian_extractors(FullMatrix< NT > &, const Point< dim > &, const Solution &) const
Definition ad.hh:948
void jacobian_flux_extr(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:929
void jacobian_variables(FullMatrix< NT > &, const Solution &) const
Definition ad.hh:952
void jacobian_source_extr(SimpleMatrix< NT, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:934
void jacobian_numflux_extr(std::array< SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from >, 2 > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector_s &, const Vector_n &) const
Definition ad.hh:938
Definition ad.hh:958
void jacobian_boundary_numflux_hess(SimpleMatrix< Tensor< 1, dim, Tensor< 2, dim, NT > >, n_to, n_from > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector &) const
Definition ad.hh:1023
void jacobian_boundary_numflux(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector &) const
Definition ad.hh:1033
void jacobian_flux_hess(SimpleMatrix< Tensor< 1, dim, Tensor< 2, dim, NT > >, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:966
void jacobian_mass(SimpleMatrix< NT, n_to, n_from > &, const Point< dim > &, const Vector &, const Vector &) const
Definition ad.hh:1038
void jacobian_numflux_hess(std::array< SimpleMatrix< Tensor< 1, dim, Tensor< 2, dim, NT > >, n_to, n_from >, 2 > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector_s &, const Vector_n &) const
Definition ad.hh:1003
void jacobian_source(SimpleMatrix< NT, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:994
void jacobian_source_grad(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:980
void jacobian_variables(FullMatrix< NT > &, const Solution &) const
Definition ad.hh:1047
void jacobian_source_hess(SimpleMatrix< Tensor< 2, dim, NT >, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:985
void jacobian_boundary_numflux_extr(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector &) const
Definition ad.hh:1028
void jacobian_flux_extr(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:971
void jacobian_extractors(FullMatrix< NT > &, const Point< dim > &, const Solution &) const
Definition ad.hh:1043
void jacobian_numflux_grad(std::array< SimpleMatrix< Tensor< 1, dim, Tensor< 1, dim, NT > >, n_to, n_from >, 2 > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector_s &, const Vector_n &) const
Definition ad.hh:998
void jacobian_flux_grad(SimpleMatrix< Tensor< 1, dim, Tensor< 1, dim, NT > >, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:961
void jacobian_source_extr(SimpleMatrix< NT, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:990
void jacobian_numflux_extr(std::array< SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from >, 2 > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector_s &, const Vector_n &) const
Definition ad.hh:1008
void jacobian_flux(SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from > &, const Point< dim > &, const Vector &) const
Definition ad.hh:976
void jacobian_boundary_numflux_grad(SimpleMatrix< Tensor< 1, dim, Tensor< 1, dim, NT > >, n_to, n_from > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector &) const
Definition ad.hh:1018
void jacobian_numflux(std::array< SimpleMatrix< Tensor< 1, dim, NT >, n_to, n_from >, 2 > &, const Tensor< 1, dim > &, const Point< dim > &, const Vector_s &, const Vector_n &) const
Definition ad.hh:1013
Definition complex_math.hh:14
constexpr auto tuple_first(const std::tuple< Head, Tail... > &t)
Definition tuples.hh:247
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
AUTODIFF_DEVICE_FUNC auto real(const autodiff::Real< N, T > &a)
Definition complex_math.hh:148
unsigned int uint
Definition utils.hh:22
constexpr auto tuple_last(const std::tuple< Head, Tail... > &t)
Definition tuples.hh:233
Definition complex_math.hh:59
constexpr auto & get(DiFfRG::named_tuple< tuple_type, strs... > &ob)
Definition tuples.hh:119
static std::array< dealii::Tensor< r, dim, autodiff::dual >, n > ten_to_AD(const std::vector< dealii::Tensor< r, dim, NT > > &v)
Definition ad.hh:38
static std::array< autodiff::dual, n > vector_to_AD(const Vector &v)
Definition ad.hh:27
static std::array< autodiff::real, n > vector_to_AD(const Vector &v)
Definition ad.hh:57
static std::array< dealii::Tensor< r, dim, autodiff::real >, n > ten_to_AD(const std::vector< dealii::Tensor< r, dim, NT > > &v)
Definition ad.hh:68