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>
20 using namespace dealii;
27 template <u
int n,
typename Vector>
static std::array<autodiff::dual, n>
vector_to_AD(
const Vector &v)
29 std::array<autodiff::dual, n> x;
30 for (
uint i = 0; i < n; ++i) {
36 template <u
int 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)
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) {
44 for (
uint d = 0; d < dim; ++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];
57 template <u
int n,
typename Vector>
static std::array<autodiff::real, n>
vector_to_AD(
const Vector &v)
59 std::array<autodiff::real, n> x;
60 for (
uint i = 0; i < n; ++i) {
66 template <u
int 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)
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) {
74 for (
uint d = 0; d < dim; ++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];
87 template <
typename Model,
typename AD_type = autodiff::real>
class ADjacobian_flux
89 Model &
asImp() {
return static_cast<Model &
>(*this); }
90 const Model &
asImp()
const {
return static_cast<const Model &
>(*this); }
94 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
96 const Vector &sol)
const
98 using Components =
typename Model::Components;
99 static_assert(n_to == Components::count_fe_functions());
100 static_assert(n_from == Components::count_fe_functions());
103 const auto _du = AD_tools::template ten_to_AD<n_from>(u);
105 tbb::blocked_range2d<uint>(0, Components::count_fe_functions(), 0, dim),
106 [&](
const tbb::blocked_range2d<uint> &r) {
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{{}};
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]);
127 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
129 const Vector &sol)
const
131 using Components =
typename Model::Components;
132 static_assert(n_to == Components::count_fe_functions());
133 static_assert(n_from == Components::count_fe_functions());
136 const auto _du = AD_tools::template ten_to_AD<n_from>(u);
138 tbb::blocked_range3d<uint>(0, Components::count_fe_functions(), 0, dim, 0, dim),
139 [&](
const tbb::blocked_range3d<uint> &r) {
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{{}};
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]);
155 unseed(du[j][d1][d2]);
161 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
163 const Vector &sol)
const
165 using Components =
typename Model::Components;
166 static_assert(n_to == Components::count_fe_functions());
167 static_assert(n_from == Components::count_extractors());
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{{}};
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]);
187 template <u
int from, u
int to, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
189 const Vector &sol)
const
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));
195 if constexpr (to == 0) {
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) {
201 for (
uint j = r.begin(); j < r.end(); ++j) {
202 std::array<Tensor<1, dim, AD_type>, Components::count_fe_functions(to)> res{{}};
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]);
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{{}};
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]);
237 Model &
asImp() {
return static_cast<Model &
>(*this); }
238 const Model &
asImp()
const {
return static_cast<const Model &
>(*this); }
242 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
244 const Vector &sol)
const
246 using Components =
typename Model::Components;
247 static_assert(n_to == Components::count_fe_functions());
248 static_assert(n_from == Components::count_fe_functions());
251 const auto _du = AD_tools::template ten_to_AD<n_from>(u);
253 tbb::blocked_range2d<uint>(0, Components::count_fe_functions(), 0, dim),
254 [&](
const tbb::blocked_range2d<uint> &r) {
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{{}};
261 asImp().source(res, p,
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]);
273 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
275 const Vector &sol)
const
277 using Components =
typename Model::Components;
278 static_assert(n_to == Components::count_fe_functions());
279 static_assert(n_from == Components::count_fe_functions());
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) {
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{{}};
292 asImp().source(res, p,
293 Vector::as(std::tuple_cat(
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]);
299 unseed(du[j][d1][d2]);
306 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
309 using Components =
typename Model::Components;
310 static_assert(n_to == Components::count_fe_functions());
311 static_assert(n_from == Components::count_extractors());
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{{}};
319 asImp().source(res, p,
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]);
329 template <u
int from, u
int to, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
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));
336 if constexpr (to == 0) {
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) {
342 for (
uint j = r.begin(); j < r.end(); ++j) {
343 std::array<AD_type, Components::count_fe_functions(to)> res{{}};
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]);
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{{}};
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]);
374 Model &
asImp() {
return static_cast<Model &
>(*this); }
375 const Model &
asImp()
const {
return static_cast<const Model &
>(*this); }
379 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
381 const Tensor<1, dim> &normal,
const Point<dim> &p,
const Vector_s &sol_s,
382 const Vector_n &sol_n)
const
384 using Components =
typename Model::Components;
385 static_assert(n_to == Components::count_fe_functions());
386 static_assert(n_from == Components::count_fe_functions());
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{{}};
397 asImp().numflux(res, normal, p,
399 tuple_last<std::tuple_size_v<Vector_s> - tup_idx - 1>(sol_s))),
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]);
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{{}};
415 asImp().numflux(res, normal, p, sol_s,
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]);
428 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
430 const Tensor<1, dim> &normal,
const Point<dim> &p,
const Vector_s &sol_s,
431 const Vector_n &sol_n)
const
433 using Components =
typename Model::Components;
434 static_assert(n_to == Components::count_fe_functions());
435 static_assert(n_from == Components::count_fe_functions());
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{{}};
446 seed(du_s[j][d1][d2]);
450 tuple_last<std::tuple_size_v<Vector_s> - tup_idx - 1>(sol_s))),
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]);
457 unseed(du_s[j][d1][d2]);
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{{}};
466 seed(du_n[j][d1][d2]);
468 res, normal, p, sol_s,
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]);
476 unseed(du_n[j][d1][d2]);
481 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
483 const Tensor<1, dim> &normal,
const Point<dim> &p,
const Vector_s &sol_s,
484 const Vector_n &sol_n)
const
486 using Components =
typename Model::Components;
487 static_assert(n_to == Components::count_fe_functions());
488 static_assert(n_from == Components::count_extractors());
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{{}};
497 asImp().numflux(res_s, normal, p,
499 tuple_last<std::tuple_size_v<Vector_s> - tup_idx - 1>(sol_s))),
501 asImp().numflux(res_n, normal, p, sol_s,
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]);
514 template <u
int from, u
int to, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
516 const Tensor<1, dim> &normal,
const Point<dim> &p,
const Vector_s &sol_s,
517 const Vector_n &sol_n)
const
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));
523 if constexpr (to == 0) {
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{{}};
532 asImp().numflux(res, normal, p,
534 tuple_last<std::tuple_size_v<Vector_s> - from - 1>(sol_s))),
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]);
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{{}};
548 asImp().numflux(res, normal, p, sol_s,
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]);
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{{}};
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]);
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{{}};
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]);
591 Model &
asImp() {
return static_cast<Model &
>(*this); }
592 const Model &
asImp()
const {
return static_cast<const Model &
>(*this); }
596 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
598 const Tensor<1, dim> &normal,
const Point<dim> &p,
const Vector &sol)
const
600 using Components =
typename Model::Components;
601 static_assert(n_to == Components::count_fe_functions());
602 static_assert(n_from == Components::count_fe_functions());
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{{}};
611 asImp().boundary_numflux(
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]);
625 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
627 const Tensor<1, dim> &normal,
const Point<dim> &p,
const Vector &sol)
const
629 using Components =
typename Model::Components;
630 static_assert(n_to == Components::count_fe_functions());
631 static_assert(n_from == Components::count_fe_functions());
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{{}};
641 asImp().boundary_numflux(
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]);
650 unseed(du[j][d1][d2]);
655 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
657 const Tensor<1, dim> &normal,
const Point<dim> &p,
const Vector &sol)
const
659 using Components =
typename Model::Components;
660 static_assert(n_to == Components::count_fe_functions());
661 static_assert(n_from == Components::count_extractors());
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{{}};
669 asImp().boundary_numflux(
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]);
682 template <u
int from, u
int to, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
684 const Point<dim> &p,
const Vector &sol)
const
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));
690 if constexpr (to == 0) {
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{{}};
697 asImp().boundary_numflux(res, normal, p,
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]);
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{{}};
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]);
727 Model &
asImp() {
return static_cast<Model &
>(*this); }
728 const Model &
asImp()
const {
return static_cast<const Model &
>(*this); }
732 template <u
int dot, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
734 const Vector &u_dot)
const
736 using Components =
typename Model::Components;
737 static_assert(n_from == Components::count_fe_functions() && n_to == Components::count_fe_functions());
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{{}};
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]);
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{{}};
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]);
769 Model &
asImp() {
return static_cast<Model &
>(*this); }
770 const Model &
asImp()
const {
return static_cast<const Model &
>(*this); }
774 template <u
int to,
typename NT,
typename Solution>
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!"));
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{{}};
793 asImp().dt_variables(res,
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]);
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{{}};
807 asImp().dt_variables(res,
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]);
821 Model &
asImp() {
return static_cast<Model &
>(*this); }
822 const Model &
asImp()
const {
return static_cast<const Model &
>(*this); }
826 template <u
int to,
int dim,
typename NT,
typename Solution>
829 static_assert(std::is_same_v<NT, double>,
"Only double is supported for now!");
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!"));
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{{}};
851 asImp().extract(res, x,
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]);
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{{}};
866 asImp().extract(res, x,
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]);
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{{}};
883 asImp().extract(res, x,
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]);
889 unseed(du[j][d1][d2]);
896 template <
typename Model>
907 template <
typename Model>
920 template <
typename Model>
928 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
930 const Vector &)
const
933 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
937 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
939 const Tensor<1, dim> &,
const Point<dim> &,
const Vector_s &,
const Vector_n &)
const
942 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
944 const Point<dim> &,
const Vector &)
const
947 template <u
int to,
int dim,
typename NT,
typename Solution>
951 template <u
int to,
typename NT,
typename Solution>
960 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
962 const Vector &)
const
965 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
967 const Vector &)
const
970 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
972 const Vector &)
const
975 template <u
int from, u
int to, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
979 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
981 const Vector &)
const
984 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
986 const Vector &)
const
989 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
993 template <u
int from, u
int to, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
997 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
999 const Tensor<1, dim> &,
const Point<dim> &,
const Vector_s &,
const Vector_n &)
const
1002 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
1004 const Tensor<1, dim> &,
const Point<dim> &,
const Vector_s &,
const Vector_n &)
const
1007 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
1009 const Tensor<1, dim> &,
const Point<dim> &,
const Vector_s &,
const Vector_n &)
const
1012 template <u
int from, u
int to, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector_s,
typename Vector_n>
1014 const Point<dim> &,
const Vector_s &,
const Vector_n &)
const
1017 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
1019 const Tensor<1, dim> &,
const Point<dim> &,
const Vector &)
const
1022 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
1024 const Tensor<1, dim> &,
const Point<dim> &,
const Vector &)
const
1027 template <u
int tup_
idx, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
1029 const Point<dim> &,
const Vector &)
const
1032 template <u
int from, u
int to, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
1034 const Point<dim> &,
const Vector &)
const
1037 template <u
int dot, u
int n_from, u
int n_to,
int dim,
typename NT,
typename Vector>
1042 template <u
int to,
int dim,
typename NT,
typename Solution>
1046 template <u
int to,
typename NT,
typename Solution>
A simple NxM-matrix class, which is used for cell-wise Jacobians.
Definition tuples.hh:153
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
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
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
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
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
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