/home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/FV/assembler/flux_jacobian_hessian.hh Source File#

DiFfRG: /home/runner/work/DiFfRG_current/DiFfRG_current/DiFfRG/include/DiFfRG/discretization/FV/assembler/flux_jacobian_hessian.hh Source File
DiFfRG
Discretization Framework for functional Renormalization Group flows
flux_jacobian_hessian.hh
Go to the documentation of this file.
1#pragma once
2
3#include <array>
4#include <autodiff/forward/real/real.hpp>
5#include <cstddef>
6#include <deal.II/base/point.h>
7#include <deal.II/base/tensor.h>
8#include <tuple>
9
11
12namespace DiFfRG
13{
14 namespace FV
15 {
16 namespace KurganovTadmor
17 {
18 namespace internal
19 {
20 template <typename NumberType, size_t n_components>
21 using JacobianMatrix = std::array<std::array<NumberType, n_components>, n_components>;
22
23 template <typename NumberType, int dim, size_t n_components>
25 std::array<std::array<std::array<std::array<NumberType, n_components>, n_components>, n_components>, dim>;
26
32 template <typename NumberType, int dim, size_t n_components>
34 std::array<std::array<dealii::Tensor<2, dim, NumberType>, n_components>, n_components>;
35
36 template <typename NumberType, int dim, size_t n_components>
37 using MixedHessianTensor = std::array<HessianTensor<NumberType, dim, n_components>, dim>;
38
39 template <typename NumberType, int dim, size_t n_components> struct FluxDerivativeData {
40 std::array<dealii::Tensor<1, dim, NumberType>, n_components> F{};
41 std::array<JacobianMatrix<NumberType, n_components>, dim> J{};
45 };
46
53 template <typename Model, typename NumberType, int dim, size_t n_components, typename ExtractorArray,
54 typename VariableVector>
55 FluxDerivativeData<NumberType, dim, n_components>
56 compute_flux_derivatives_ad(const std::array<NumberType, n_components> &u,
57 const std::array<dealii::Tensor<1, dim, NumberType>, n_components> &grad_u,
58 const dealii::Point<dim> &x_q, const double cell_width,
59 const ExtractorArray &extractors, const VariableVector &variables,
60 const Model &model)
61 {
62 using ADNumberType = autodiff::Real<2, NumberType>;
63 using autodiff::detail::derivative;
64 using autodiff::detail::seed;
65
66 auto unseed = [](ADNumberType &x) { seed<1>(x, NumberType(0)); };
67
68 std::array<ADNumberType, n_components> u_AD{};
69 std::array<dealii::Tensor<1, dim, ADNumberType>, n_components> grad_u_AD{};
70 for (size_t c = 0; c < n_components; ++c) {
71 u_AD[c] = ADNumberType(u[c]);
72 for (size_t d = 0; d < dim; ++d)
73 grad_u_AD[c][d] = ADNumberType(grad_u[c][d]);
74 }
75
78 std::array<dealii::Tensor<1, dim, ADNumberType>, n_components> F_AD{};
79
80 model.flux(F_AD, x_q, flux_tie(u_AD, grad_u_AD, extractors, variables, cell_width));
81 for (size_t i = 0; i < n_components; ++i)
82 for (size_t d_out = 0; d_out < dim; ++d_out)
83 result.F[i][d_out] = F_AD[i][d_out].val();
84
85 // Diagonal u passes provide J and the diagonal u-Hessian.
86 for (size_t j = 0; j < n_components; ++j) {
87 seed<1>(u_AD[j], NumberType(1));
88 F_AD = {};
89 model.flux(F_AD, x_q, flux_tie(u_AD, grad_u_AD, extractors, variables, cell_width));
90 for (size_t i = 0; i < n_components; ++i)
91 for (size_t d_out = 0; d_out < dim; ++d_out) {
92 result.J[d_out][i][j] = derivative<1>(F_AD[i][d_out]);
93 result.H[d_out][i][j][j] = derivative<2>(F_AD[i][d_out]);
94 }
95 unseed(u_AD[j]);
96 }
97
98 // Off-diagonal u-Hessian entries via polarization.
99 for (size_t j = 0; j < n_components; ++j)
100 for (size_t c = j + 1; c < n_components; ++c) {
101 seed<1>(u_AD[j], NumberType(1));
102 seed<1>(u_AD[c], NumberType(1));
103 F_AD = {};
104 model.flux(F_AD, x_q, flux_tie(u_AD, grad_u_AD, extractors, variables, cell_width));
105 for (size_t i = 0; i < n_components; ++i)
106 for (size_t d_out = 0; d_out < dim; ++d_out) {
107 const NumberType cross =
108 (derivative<2>(F_AD[i][d_out]) - result.H[d_out][i][j][j] - result.H[d_out][i][c][c]) /
109 NumberType(2);
110 result.H[d_out][i][j][c] = result.H[d_out][i][c][j] = cross;
111 }
112 unseed(u_AD[j]);
113 unseed(u_AD[c]);
114 }
115
116 // Gradient diagonal passes provide dF/dgrad(u) and the diagonal terms used by mixed polarization.
117 for (size_t c = 0; c < n_components; ++c)
118 for (size_t d_in = 0; d_in < dim; ++d_in) {
119 seed<1>(grad_u_AD[c][d_in], NumberType(1));
120 F_AD = {};
121 model.flux(F_AD, x_q, flux_tie(u_AD, grad_u_AD, extractors, variables, cell_width));
122 for (size_t i = 0; i < n_components; ++i)
123 for (size_t d_out = 0; d_out < dim; ++d_out) {
124 result.grad_J[i][c][d_out][d_in] = derivative<1>(F_AD[i][d_out]);
125 grad_diagonal_H[i][c][d_out][d_in] = derivative<2>(F_AD[i][d_out]);
126 }
127 unseed(grad_u_AD[c][d_in]);
128 }
129
130 // Mixed d2F/(du_j dgrad(u_c)_d_in) entries via polarization.
131 for (size_t j = 0; j < n_components; ++j)
132 for (size_t c = 0; c < n_components; ++c)
133 for (size_t d_in = 0; d_in < dim; ++d_in) {
134 seed<1>(u_AD[j], NumberType(1));
135 seed<1>(grad_u_AD[c][d_in], NumberType(1));
136 F_AD = {};
137 model.flux(F_AD, x_q, flux_tie(u_AD, grad_u_AD, extractors, variables, cell_width));
138 for (size_t i = 0; i < n_components; ++i)
139 for (size_t d_out = 0; d_out < dim; ++d_out)
140 result.mixed_H[d_in][d_out][i][j][c] = (derivative<2>(F_AD[i][d_out]) - result.H[d_out][i][j][j] -
141 grad_diagonal_H[i][c][d_out][d_in]) /
142 NumberType(2);
143 unseed(u_AD[j]);
144 unseed(grad_u_AD[c][d_in]);
145 }
146
147 return result;
148 }
149
156 template <typename Model, typename NumberType, int dim, size_t n_components, typename ExtractorArray,
157 typename VariableVector>
158 auto compute_flux_jacobian_and_hessian(const std::array<NumberType, n_components> &u,
159 const dealii::Point<dim> &x_q, const double cell_width,
160 const ExtractorArray &extractors, const VariableVector &variables,
161 const Model &model)
162 {
163 const std::array<dealii::Tensor<1, dim, NumberType>, n_components> grad_u{};
165 u, grad_u, x_q, cell_width, extractors, variables, model);
166 return std::make_tuple(derivatives.F, derivatives.J, derivatives.H);
167 }
168
169 } // namespace internal
170 } // namespace KurganovTadmor
171 } // namespace FV
172} // namespace DiFfRG
auto flux_tie(T &&...t)
The named tuple handed to model.flux().
Definition flux_ties.hh:36
FluxDerivativeData< NumberType, dim, n_components > compute_flux_derivatives_ad(const std::array< NumberType, n_components > &u, const std::array< dealii::Tensor< 1, dim, NumberType >, n_components > &grad_u, const dealii::Point< dim > &x_q, const double cell_width, const ExtractorArray &extractors, const VariableVector &variables, const Model &model)
Compute F, dF/du, d2F/du2, dF/dgrad(u), and d2F/(du dgrad(u)) with second-order forward AD.
Definition flux_jacobian_hessian.hh:56
std::array< std::array< std::array< std::array< NumberType, n_components >, n_components >, n_components >, dim > HessianTensor
Definition flux_jacobian_hessian.hh:24
std::array< std::array< NumberType, n_components >, n_components > JacobianMatrix
Definition flux_jacobian_hessian.hh:21
std::array< std::array< dealii::Tensor< 2, dim, NumberType >, n_components >, n_components > FluxGradientJacobian
Derivative of every flux component/direction with respect to every component/direction of grad(u).
Definition flux_jacobian_hessian.hh:33
auto compute_flux_jacobian_and_hessian(const std::array< NumberType, n_components > &u, const dealii::Point< dim > &x_q, const double cell_width, const ExtractorArray &extractors, const VariableVector &variables, const Model &model)
Backward-compatible state-only view of the full AD derivative extraction.
Definition flux_jacobian_hessian.hh:158
std::array< HessianTensor< NumberType, dim, n_components >, dim > MixedHessianTensor
Definition flux_jacobian_hessian.hh:37
Definition complex_math.hh:10
Definition flux_jacobian_hessian.hh:39
MixedHessianTensor< NumberType, dim, n_components > mixed_H
Definition flux_jacobian_hessian.hh:44
FluxGradientJacobian< NumberType, dim, n_components > grad_J
Definition flux_jacobian_hessian.hh:43
HessianTensor< NumberType, dim, n_components > H
Definition flux_jacobian_hessian.hh:42
std::array< JacobianMatrix< NumberType, n_components >, dim > J
Definition flux_jacobian_hessian.hh:41
std::array< dealii::Tensor< 1, dim, NumberType >, n_components > F
Definition flux_jacobian_hessian.hh:40