1 #include <deal.II/base/tensor.h> 2 #include <deal.II/base/table.h> 4 #include <deal.II/base/qprojector.h> 6 #include <deal.II/lac/full_matrix.templates.h> 9 #include <deal.II/fe/fe_values.h> 11 #include <deal.II/dofs/dof_handler.h> 12 #include <deal.II/dofs/dof_tools.h> 14 #include <deal.II/lac/vector.h> 16 #include "ADTypes.hpp" 18 #include "solution/local_solution.hpp" 19 #include "weak_dg.hpp" 21 #define KOPRIVA_METRICS_VOL 22 #define KOPRIVA_METRICS_FACE 23 #define KOPRIVA_METRICS_BOUNDARY 27 template <
typename real,
int dim>
using Coord = std::array<real, dim>;
29 template <
typename real,
int dim>
using CoordGrad = std::array<dealii::Tensor<1, dim, real>, dim>;
31 template <
typename real,
int nstate>
using State = std::array<real, nstate>;
33 template <
typename real,
int dim,
int nstate>
using DirectionalState = std::array<dealii::Tensor<1, dim, real>, nstate>;
39 template <
typename number>
40 void gauss_jordan(dealii::FullMatrix<number> &input_matrix) {
41 Assert(!input_matrix.empty(), dealii::ExcMessage(
"Empty matrix"))
42 Assert(input_matrix.n_cols() == input_matrix.n_rows(), dealii::ExcMessage(
"Non quadratic matrix"));
45 const size_t N = input_matrix.n();
50 number diagonal_sum = 0;
51 for (
size_t i = 0; i < N; ++i) diagonal_sum = diagonal_sum + abs(input_matrix(i, i));
52 const number typical_diagonal_element = diagonal_sum / N;
53 (void)typical_diagonal_element;
56 std::vector<size_t> p(N);
57 for (
size_t i = 0; i < N; ++i) p[i] = i;
59 for (
size_t j = 0; j < N; ++j) {
62 number max_pivot = abs(input_matrix(j, j));
64 for (
size_t i = j + 1; i < N; ++i) {
65 if (abs(input_matrix(i, j)) > max_pivot) {
66 max_pivot = abs(input_matrix(i, j));
71 Assert(max_pivot > 1.e-16 * typical_diagonal_element, dealii::ExcMessage(
"Non regular matrix"));
75 for (
size_t k = 0; k < N; ++k) std::swap(input_matrix(j, k), input_matrix(r, k));
77 std::swap(p[j], p[r]);
81 const number hr = number(1.) / input_matrix(j, j);
82 input_matrix(j, j) = hr;
83 for (
size_t k = 0; k < N; ++k) {
85 for (
size_t i = 0; i < N; ++i) {
87 input_matrix(i, k) -= input_matrix(i, j) * input_matrix(j, k) * hr;
90 for (
size_t i = 0; i < N; ++i) {
91 input_matrix(i, j) *= hr;
92 input_matrix(j, i) *= -hr;
94 input_matrix(j, j) = hr;
97 std::vector<number> hv(N);
98 for (
size_t i = 0; i < N; ++i) {
99 for (
size_t k = 0; k < N; ++k) hv[p[k]] = input_matrix(i, k);
100 for (
size_t k = 0; k < N; ++k) input_matrix(i, k) = hv[k];
107 template <
typename real>
108 double getValue(
const real &x) {
109 if constexpr (std::is_same<real, double>::value) {
112 return getValue(x.value());
120 template <
int dim,
typename real1,
typename real2>
121 dealii::Tensor<1, dim, real1> vmult(
const dealii::Tensor<2, dim, real1> A,
const dealii::Tensor<1, dim, real2> x) {
122 dealii::Tensor<1, dim, real1> y;
123 for (
int row = 0; row < dim; ++row) {
125 for (
int col = 0; col < dim; ++col) {
126 y[row] += A[row][col] * x[col];
137 template <
int dim,
typename real1>
138 real1 norm(
const dealii::Tensor<1, dim, real1> x) {
140 for (
int row = 0; row < dim; ++row) {
141 val += x[row] * x[row];
151 void automatic_differentiation_indexing_1(
152 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R,
153 const unsigned int n_soln_dofs,
const unsigned int n_metric_dofs,
154 unsigned int &w_start,
unsigned int &w_end,
155 unsigned int &x_start,
unsigned int &x_end)
161 if (compute_d2R || (compute_dRdW && compute_dRdX)) {
163 w_end = w_start + n_soln_dofs;
165 x_end = x_start + n_metric_dofs;
166 }
else if (compute_dRdW) {
168 w_end = w_start + n_soln_dofs;
171 }
else if (compute_dRdX) {
175 x_end = x_start + n_metric_dofs;
177 std::cout <<
"Called the derivative version of the residual without requesting the derivative" << std::endl;
186 void automatic_differentiation_indexing_2(
187 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R,
188 const unsigned int n_soln_dofs_int,
const unsigned int n_soln_dofs_ext,
const unsigned int n_metric_dofs,
189 unsigned int &w_int_start,
unsigned int &w_int_end,
unsigned int &w_ext_start,
unsigned int &w_ext_end,
190 unsigned int &x_int_start,
unsigned int &x_int_end,
unsigned int &x_ext_start,
unsigned int &x_ext_end)
193 w_int_start = 0; w_int_end = 0; w_ext_start = 0; w_ext_end = 0;
194 x_int_start = 0; x_int_end = 0; x_ext_start = 0; x_ext_end = 0;
195 if (compute_d2R || (compute_dRdW && compute_dRdX)) {
197 w_int_end = w_int_start + n_soln_dofs_int;
198 w_ext_start = w_int_end;
199 w_ext_end = w_ext_start + n_soln_dofs_ext;
200 x_int_start = w_ext_end;
201 x_int_end = x_int_start + n_metric_dofs;
202 x_ext_start = x_int_end;
203 x_ext_end = x_ext_start + n_metric_dofs;
204 }
else if (compute_dRdW) {
206 w_int_end = w_int_start + n_soln_dofs_int;
207 w_ext_start = w_int_end;
208 w_ext_end = w_ext_start + n_soln_dofs_ext;
209 x_int_start = w_ext_end;
210 x_int_end = x_int_start + 0;
211 x_ext_start = x_int_end;
212 x_ext_end = x_ext_start + 0;
213 }
else if (compute_dRdX) {
215 w_int_end = w_int_start + 0;
216 w_ext_start = w_int_end;
217 w_ext_end = w_ext_start + 0;
218 x_int_start = w_ext_end;
219 x_int_end = x_int_start + n_metric_dofs;
220 x_ext_start = x_int_end;
221 x_ext_end = x_ext_start + n_metric_dofs;
223 std::cout <<
"Called the derivative version of the residual without requesting the derivative" << std::endl;
227 template <
int dim,
typename real>
228 bool check_same_coords (
229 const std::vector<dealii::Point<dim>> &unit_quad_pts_int,
230 const std::vector<dealii::Point<dim>> &unit_quad_pts_ext,
233 const double tolerance)
235 assert(unit_quad_pts_int.size() == unit_quad_pts_ext.size());
236 const unsigned int nquad = unit_quad_pts_int.size();
237 std::vector<Coord<real,dim>> coords_int = metric_int.
evaluate_values(unit_quad_pts_int);
238 std::vector<Coord<real,dim>> coords_ext = metric_ext.
evaluate_values(unit_quad_pts_ext);
241 for (
unsigned int iquad = 0; iquad < nquad; ++iquad) {
242 for (
int d=0; d<dim; ++d) {
243 real abs_diff = abs(coords_int[iquad][d] - coords_ext[iquad][d]);
244 if (abs_diff > tolerance) {
245 real rel_diff = abs_diff / coords_int[iquad][d];
246 if (rel_diff > tolerance) {
252 std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1);
253 std::cout <<
"coords_int ";
254 for (
int d=0;d<dim;++d) {
255 std::cout << coords_int[iquad][d] <<
" ";
257 std::cout << std::endl;
258 std::cout <<
"coords_ext ";
259 for (
int d=0;d<dim;++d) {
260 std::cout << coords_ext[iquad][d] <<
" ";
262 std::cout << std::endl;
268 template <
int dim,
typename real>
269 std::vector<dealii::Tensor<2,dim,real>> evaluate_metric_jacobian (
270 const std::vector<dealii::Point<dim>> &points,
273 const unsigned int n_dofs = metric_solution.
finite_element.dofs_per_cell;
275 const unsigned int n_pts = points.size();
277 AssertDimension(n_dofs, metric_solution.
coefficients.size());
281 std::vector<dealii::Tensor<2,dim,real>> metric_jacobian(n_pts);
283 for (
unsigned int ipoint=0; ipoint<n_pts; ++ipoint) {
284 for (
int row=0;row<dim;++row) {
285 for (
int col=0;col<dim;++col) {
286 metric_jacobian[ipoint][row][col] = coords_gradients[ipoint][row][col];
290 return metric_jacobian;
293 template <
int dim,
typename real>
294 std::vector <real> determinant_ArrayTensor(std::vector<CoordGrad<real,dim>> &coords_gradients)
296 const unsigned int n = coords_gradients.size();
297 std::vector <real> determinants(n);
298 for (
unsigned int i=0; i<n; ++i) {
299 if constexpr(dim==1) {
300 determinants[i] = coords_gradients[i][0][0];
302 if constexpr(dim==2) {
303 determinants[i] = coords_gradients[i][0][0] * coords_gradients[i][1][1] - coords_gradients[i][0][1] * coords_gradients[i][1][0];
305 if constexpr(dim==3) {
306 determinants[i] = +coords_gradients[i][0][0] * (coords_gradients[i][1][1] * coords_gradients[i][2][2] - coords_gradients[i][1][2] * coords_gradients[i][2][1])
307 -coords_gradients[i][0][1] * (coords_gradients[i][1][0] * coords_gradients[i][2][2] - coords_gradients[i][1][2] * coords_gradients[i][2][0])
308 +coords_gradients[i][0][2] * (coords_gradients[i][1][0] * coords_gradients[i][2][1] - coords_gradients[i][1][1] * coords_gradients[i][2][0]);
314 template <
int dim,
typename real>
315 void evaluate_covariant_metric_jacobian (
316 const dealii::Quadrature<dim> &quadrature,
318 std::vector<dealii::Tensor<2,dim,real>> &covariant_metric_jacobian,
319 std::vector<real> &jacobian_determinants)
321 const dealii::FiniteElement<dim> &fe_lagrange_grid = metric_solution.
finite_element.base_element(0);
323 const std::vector< dealii::Point<dim,double> > &unit_grid_pts = fe_lagrange_grid.get_unit_support_points();
324 std::vector<Coord<real, dim>> coords = metric_solution.
evaluate_values(unit_grid_pts);
327 const std::vector< dealii::Point<dim,double> > &unit_quad_pts = quadrature.get_points();
330 const unsigned int n_grid_pts = unit_grid_pts.size();
331 const unsigned int n_quad_pts = unit_quad_pts.size();
333 jacobian_determinants = determinant_ArrayTensor<dim,real>(quad_pts_coords_gradients);
335 if constexpr (dim==1) {
336 for (
unsigned int iquad = 0; iquad<n_quad_pts; ++iquad) {
337 const real invJ = 1.0/jacobian_determinants[iquad];
338 covariant_metric_jacobian[iquad][0][0] = invJ;
342 if constexpr (dim==2) {
347 std::vector<dealii::Tensor<2,dim,real>> dphys_dref_quad(n_quad_pts);
350 for (
unsigned int iquad = 0; iquad<n_quad_pts; ++iquad) {
352 dphys_dref_quad[iquad] = 0.0;
354 const dealii::Point<dim,double> &quad_point = unit_quad_pts[iquad];
356 for (
unsigned int igrid = 0; igrid<n_grid_pts; ++igrid) {
358 const dealii::Tensor<1,dim,double> shape_grad = fe_lagrange_grid.shape_grad(igrid, quad_point);
360 for(
int dphys=0; dphys<dim; dphys++) {
361 for(
int dref=0; dref<dim; dref++) {
362 dphys_dref_quad[iquad][dphys][dref] += coords[igrid][dphys] * shape_grad[dref];
369 for (
unsigned int iquad = 0; iquad<n_quad_pts; ++iquad) {
371 const real invJ = 1.0/jacobian_determinants[iquad];
373 covariant_metric_jacobian[iquad] = 0.0;
377 covariant_metric_jacobian[iquad][0][0] = dphys_dref_quad[iquad][1][1] * invJ;
378 covariant_metric_jacobian[iquad][0][1] = -dphys_dref_quad[iquad][1][0] * invJ;
379 covariant_metric_jacobian[iquad][1][0] = -dphys_dref_quad[iquad][0][1] * invJ;
380 covariant_metric_jacobian[iquad][1][1] = dphys_dref_quad[iquad][0][0] * invJ;
385 if constexpr (dim == 3) {
388 std::vector<real> Ta(n_grid_pts);
389 std::vector<real> Tb(n_grid_pts);
390 std::vector<real> Tc(n_grid_pts);
392 std::vector<real> Td(n_grid_pts);
393 std::vector<real> Te(n_grid_pts);
394 std::vector<real> Tf(n_grid_pts);
396 std::vector<real> Tg(n_grid_pts);
397 std::vector<real> Th(n_grid_pts);
398 std::vector<real> Ti(n_grid_pts);
400 for(
unsigned int igrid=0; igrid<n_grid_pts; igrid++) {
401 Ta[igrid] = 0.5*(coords_gradients[igrid][1][1] * coords[igrid][2] - coords_gradients[igrid][2][1] * coords[igrid][1]);
402 Tb[igrid] = 0.5*(coords_gradients[igrid][1][2] * coords[igrid][2] - coords_gradients[igrid][2][2] * coords[igrid][1]);
403 Tc[igrid] = 0.5*(coords_gradients[igrid][1][0] * coords[igrid][2] - coords_gradients[igrid][2][0] * coords[igrid][1]);
405 Td[igrid] = 0.5*(coords_gradients[igrid][2][1] * coords[igrid][0] - coords_gradients[igrid][0][1] * coords[igrid][2]);
406 Te[igrid] = 0.5*(coords_gradients[igrid][2][2] * coords[igrid][0] - coords_gradients[igrid][0][2] * coords[igrid][2]);
407 Tf[igrid] = 0.5*(coords_gradients[igrid][2][0] * coords[igrid][0] - coords_gradients[igrid][0][0] * coords[igrid][2]);
409 Tg[igrid] = 0.5*(coords_gradients[igrid][0][1] * coords[igrid][1] - coords_gradients[igrid][1][1] * coords[igrid][0]);
410 Th[igrid] = 0.5*(coords_gradients[igrid][0][2] * coords[igrid][1] - coords_gradients[igrid][1][2] * coords[igrid][0]);
411 Ti[igrid] = 0.5*(coords_gradients[igrid][0][0] * coords[igrid][1] - coords_gradients[igrid][1][0] * coords[igrid][0]);
414 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++) {
416 covariant_metric_jacobian[iquad] = 0.0;
418 const dealii::Point<dim,double> &quad_point = unit_quad_pts[iquad];
420 for(
unsigned int igrid=0; igrid<n_grid_pts; igrid++) {
422 const dealii::Tensor<1,dim,double> shape_grad = fe_lagrange_grid.shape_grad(igrid, quad_point);
424 covariant_metric_jacobian[iquad][0][0] += shape_grad[2] * Ta[igrid] - shape_grad[1] * Tb[igrid];
425 covariant_metric_jacobian[iquad][1][0] += shape_grad[2] * Td[igrid] - shape_grad[1] * Te[igrid];
426 covariant_metric_jacobian[iquad][2][0] += shape_grad[2] * Tg[igrid] - shape_grad[1] * Th[igrid];
428 covariant_metric_jacobian[iquad][0][1] += shape_grad[0] * Tb[igrid] - shape_grad[2] * Tc[igrid];
429 covariant_metric_jacobian[iquad][1][1] += shape_grad[0] * Te[igrid] - shape_grad[2] * Tf[igrid];
430 covariant_metric_jacobian[iquad][2][1] += shape_grad[0] * Th[igrid] - shape_grad[2] * Ti[igrid];
432 covariant_metric_jacobian[iquad][0][2] += shape_grad[1] * Tc[igrid] - shape_grad[0] * Ta[igrid];
433 covariant_metric_jacobian[iquad][1][2] += shape_grad[1] * Tf[igrid] - shape_grad[0] * Td[igrid];
434 covariant_metric_jacobian[iquad][2][2] += shape_grad[1] * Ti[igrid] - shape_grad[0] * Tg[igrid];
437 const real invJ = 1.0/jacobian_determinants[iquad];
438 covariant_metric_jacobian[iquad] *= invJ;
449 template <
int dim,
int nstate,
typename real,
typename MeshType>
452 const unsigned int degree,
453 const unsigned int max_degree_input,
454 const unsigned int grid_degree_input,
455 const std::shared_ptr<Triangulation> triangulation_input)
456 :
DGBaseState<dim,nstate,real,MeshType>::
DGBaseState(parameters_input, degree, max_degree_input, grid_degree_input, triangulation_input)
459 template <
int dim,
int nstate,
typename real,
typename MeshType>
461 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
462 const dealii::types::global_dof_index current_cell_index,
463 const dealii::FEValues<dim,dim> &fe_values_vol,
464 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_int,
465 const std::vector<dealii::types::global_dof_index> &,
468 dealii::Vector<real> &,
469 const dealii::FEValues<dim,dim> &)
471 using State = State<real, nstate>;
472 using DirectionalState = DirectionalState<real, dim, nstate>;
474 (void) current_cell_index;
476 const unsigned int n_quad_pts = fe_values_vol.n_quadrature_points;
477 const unsigned int n_soln_dofs_int = fe_values_vol.dofs_per_cell;
479 AssertDimension (n_soln_dofs_int, soln_dof_indices_int.size());
481 const std::vector<real> &JxW = fe_values_vol.get_JxW_values ();
483 real cell_volume_estimate = 0.0;
484 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
485 cell_volume_estimate = cell_volume_estimate + JxW[iquad];
489 std::vector<State> soln_at_q(n_quad_pts);
490 std::vector<State> source_at_q;
491 std::vector<State> physical_source_at_q;
492 std::vector<DirectionalState> soln_grad_at_q(n_quad_pts);
493 std::vector<DirectionalState> conv_phys_flux_at_q(n_quad_pts);
494 std::vector<DirectionalState> diss_phys_flux_at_q(n_quad_pts);
496 std::vector< real > soln_coeff(n_soln_dofs_int);
497 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
501 typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
504 std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
505 artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
507 std::vector<real> artificial_diss_coeff_at_q(n_quad_pts);
508 real max_artificial_diss = 0.0;
509 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
510 artificial_diss_coeff_at_q[iquad] = 0.0;
513 const dealii::Point<dim,real> point = fe_values_vol.get_quadrature().point(iquad);
514 for (
unsigned int idof=0; idof<n_dofs_arti_diss; ++idof) {
515 const unsigned int index = dof_indices_artificial_dissipation[idof];
518 max_artificial_diss = std::max(artificial_diss_coeff_at_q[iquad], max_artificial_diss);
522 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
523 for (
int istate=0; istate<
nstate; istate++) {
525 soln_at_q[iquad][istate] = 0;
526 soln_grad_at_q[iquad][istate] = 0;
530 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
531 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
532 const unsigned int istate = fe_values_vol.get_fe().system_to_component_index(idof).first;
533 soln_at_q[iquad][istate] += soln_coeff[idof] * fe_values_vol.shape_value_component(idof, iquad, istate);
534 soln_grad_at_q[iquad][istate] += soln_coeff[idof] * fe_values_vol.shape_grad_component(idof, iquad, istate);
538 const unsigned int cell_index = fe_values_vol.get_cell()->active_cell_index();
539 const unsigned int cell_degree = fe_values_vol.get_fe().tensor_degree();
540 const real diameter = fe_values_vol.get_cell()->diameter();
541 const real cell_diameter = cell_volume / std::pow(diameter,dim-1);
544 const real cell_radius = 0.5 * cell_diameter;
549 template <
int dim,
int nstate,
typename real2>
550 void compute_br2_correction(
551 const dealii::FESystem<dim,dim> &fe_soln,
553 const std::vector<State<real2, nstate>> &lifting_op_R_rhs,
554 std::vector<State<real2, nstate>> &soln_grad_correction
557 const unsigned int n_faces = std::pow(2,dim);
558 const double br2_factor = n_faces * 1.01;
562 const dealii::FiniteElement<dim> &base_fe = fe_soln.get_sub_fe(0,1);
563 const unsigned int n_base_dofs = base_fe.n_dofs_per_cell();
567 const int degree = base_fe.tensor_degree();
568 dealii::QGauss<dim> vol_quad(degree+1);
569 const unsigned int n_vol_quad = vol_quad.size();
571 if (n_base_dofs != n_vol_quad) std::abort();
574 const std::vector<dealii::Point<dim,double>> &vol_unit_quad_pts = vol_quad.get_points();
575 using Tensor2D = dealii::Tensor<2,dim,real2>;
576 std::vector<Tensor2D> volume_metric_jac = evaluate_metric_jacobian (vol_unit_quad_pts, metric_solution);
579 dealii::FullMatrix<double> vandermonde_inverse(n_base_dofs, n_vol_quad);
581 for (
unsigned int idof_base=0; idof_base<n_base_dofs; ++idof_base) {
582 for (
unsigned int iquad=0; iquad<n_vol_quad; ++iquad) {
583 vandermonde_inverse[idof_base][iquad] = base_fe.shape_value(idof_base, vol_quad.point(iquad));
586 gauss_jordan(vandermonde_inverse);
588 std::vector< std::array<real2,nstate> > vandermonde_inv_rhs(n_vol_quad);
589 for (
unsigned int kquad=0; kquad<n_vol_quad; ++kquad) {
590 for (
int s=0; s<
nstate; s++) {
591 vandermonde_inv_rhs[kquad][s] = 0.0;
592 for (
unsigned int jdof_base=0; jdof_base<n_base_dofs; ++jdof_base) {
593 vandermonde_inv_rhs[kquad][s] += vandermonde_inverse[kquad][jdof_base] * lifting_op_R_rhs[jdof_base][s];
597 for (
unsigned int kquad=0; kquad<n_vol_quad; ++kquad) {
598 for (
int s=0; s<
nstate; s++) {
599 vandermonde_inv_rhs[kquad][s] /= dealii::determinant(volume_metric_jac[kquad]) * vol_quad.weight(kquad);
602 for (
unsigned int idof_base=0; idof_base<n_base_dofs; ++idof_base) {
603 for (
int s=0; s<
nstate; s++) {
604 soln_grad_correction[idof_base][s] = 0.0;
605 for (
unsigned int kquad=0; kquad<n_vol_quad; ++kquad) {
606 soln_grad_correction[idof_base][s] += vandermonde_inverse[kquad][idof_base] * vandermonde_inv_rhs[kquad][s];
608 soln_grad_correction[idof_base][s] *= br2_factor;
614 template <
int dim,
int nstate,
typename real2>
615 void correct_the_gradient(
616 const std::vector<State<real2, nstate>> &soln_grad_corr,
617 const dealii::FESystem<dim,dim> &fe_soln,
618 const std::vector<DirectionalState<real2, dim, nstate>> &soln_jump,
619 const dealii::FullMatrix<double> &interpolation_operator,
620 const std::array<dealii::FullMatrix<real2>,dim> &gradient_operator,
621 std::vector<DirectionalState<real2, dim, nstate>> &soln_grad)
624 (void) soln_grad_corr;
625 (void) interpolation_operator;
626 (void) gradient_operator;
627 const unsigned int n_quad = soln_grad.size();
628 const unsigned int n_soln_dofs = fe_soln.dofs_per_cell;
630 for (
unsigned int iquad=0; iquad<n_quad; ++iquad) {
631 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
632 const unsigned int istate = fe_soln.system_to_component_index(idof).first;
633 const unsigned int idof_base = fe_soln.system_to_component_index(idof).second;
636 for (
int d=0;d<dim;++d) {
638 soln_grad[iquad][istate][d] += soln_grad_corr[idof_base][istate] * interpolation_operator[idof][iquad];
645 template <
int dim,
int nstate,
typename real,
typename MeshType>
646 template <
typename real2>
648 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
649 const dealii::types::global_dof_index current_cell_index,
652 const std::vector< real > &local_dual,
653 const unsigned int face_number,
654 const unsigned int boundary_id,
658 const dealii::FEFaceValuesBase<dim,dim> &fe_values_boundary,
660 const dealii::Quadrature<dim-1> &quadrature,
661 std::vector<real2> &rhs,
662 real2 &dual_dot_residual,
663 const bool compute_metric_derivatives)
665 const unsigned int n_soln_dofs = local_solution.
finite_element.dofs_per_cell;
666 const unsigned int n_metric_dofs = local_metric.
finite_element.dofs_per_cell;
667 const unsigned int n_quad_pts = fe_values_boundary.n_quadrature_points;
669 dual_dot_residual = 0.0;
670 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
674 using State = State<real2, nstate>;
675 using DirectionalState = DirectionalState<real2, dim, nstate>;
677 const dealii::Quadrature<dim> face_quadrature
678 = dealii::QProjector<dim>::project_to_face(
679 dealii::ReferenceCell::get_hypercube(dim),
682 const std::vector<dealii::Point<dim,real>> &unit_quad_pts = face_quadrature.get_points();
683 std::vector<dealii::Point<dim,real2>> real_quad_pts(unit_quad_pts.size());
685 std::vector<dealii::Tensor<2,dim,real2>> metric_jacobian = evaluate_metric_jacobian (unit_quad_pts, local_metric);
686 std::vector<real2> jac_det(n_quad_pts);
687 std::vector<real2> surface_jac_det(n_quad_pts);
688 std::vector<dealii::Tensor<2,dim,real2>> jac_inv_tran(n_quad_pts);
690 const dealii::Tensor<1,dim,real> unit_normal = dealii::GeometryInfo<dim>::unit_normal_vector[face_number];
691 std::vector<dealii::Tensor<1,dim,real2>> phys_unit_normal(n_quad_pts);
693 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
694 if (compute_metric_derivatives) {
695 for (
int d=0;d<dim;++d) { real_quad_pts[iquad][d] = 0;}
696 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
697 const int iaxis = local_metric.
finite_element.system_to_component_index(idof).first;
698 real_quad_pts[iquad][iaxis] += local_metric.
coefficients[idof] * local_metric.
finite_element.shape_value(idof,unit_quad_pts[iquad]);
701 const real2 jacobian_determinant = dealii::determinant(metric_jacobian[iquad]);
702 const dealii::Tensor<2,dim,real2> jacobian_transpose_inverse = dealii::transpose(dealii::invert(metric_jacobian[iquad]));
704 jac_det[iquad] = jacobian_determinant;
705 jac_inv_tran[iquad] = jacobian_transpose_inverse;
707 const dealii::Tensor<1,dim,real2> normal = vmult(jacobian_transpose_inverse, unit_normal);
708 const real2 area =
norm(normal);
710 surface_jac_det[iquad] =
norm(normal)*jac_det[iquad];
714 for (
int d=0;d<dim;++d) {
715 phys_unit_normal[iquad][d] = normal[d] / area;
724 real_quad_pts[iquad] = fe_values_boundary.quadrature_point(iquad);
725 surface_jac_det[iquad] = fe_values_boundary.JxW(iquad) / face_quadrature.weight(iquad);
726 phys_unit_normal[iquad] = fe_values_boundary.normal_vector(iquad);
730 #ifdef KOPRIVA_METRICS_BOUNDARY 731 auto old_jac_det = jac_det;
732 auto old_jac_inv_tran = jac_inv_tran;
734 if constexpr (dim != 1) {
735 evaluate_covariant_metric_jacobian<dim,real2> ( face_quadrature, local_metric, jac_inv_tran, jac_det);
739 std::vector<real2> faceJxW(n_quad_pts);
741 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
742 if (compute_metric_derivatives) {
743 const dealii::Tensor<1,dim,real2> normal = vmult(jac_inv_tran[iquad], unit_normal);
744 const real2 area =
norm(normal);
746 surface_jac_det[iquad] =
norm(normal)*jac_det[iquad];
750 for (
int d=0;d<dim;++d) {
751 phys_unit_normal[iquad][d] = normal[d] / area;
755 faceJxW[iquad] = surface_jac_det[iquad] * face_quadrature.weight(iquad);
758 dealii::FullMatrix<real> interpolation_operator(n_soln_dofs,n_quad_pts);
759 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
760 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
761 interpolation_operator[idof][iquad] = local_solution.
finite_element.shape_value(idof,unit_quad_pts[iquad]);
764 std::array<dealii::FullMatrix<real2>,dim> gradient_operator;
765 for (
int d=0;d<dim;++d) {
766 gradient_operator[d].reinit(dealii::TableIndices<2>(n_soln_dofs, n_quad_pts));
768 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
769 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
770 if (compute_metric_derivatives) {
771 const dealii::Tensor<1,dim,real> ref_shape_grad = local_solution.
finite_element.shape_grad(idof,unit_quad_pts[iquad]);
772 const dealii::Tensor<1,dim,real2> phys_shape_grad = vmult(jac_inv_tran[iquad], ref_shape_grad);
773 for (
int d=0;d<dim;++d) {
774 gradient_operator[d][idof][iquad] = phys_shape_grad[d];
783 for (
int d=0;d<dim;++d) {
784 const unsigned int istate = local_solution.
finite_element.system_to_component_index(idof).first;
785 gradient_operator[d][idof][iquad] = fe_values_boundary.shape_grad_component(idof, iquad, istate)[d];
792 std::vector<State> soln_int = local_solution.
evaluate_values(unit_quad_pts);
793 std::vector<State> soln_ext(n_quad_pts);
794 std::vector<DirectionalState> soln_grad_int(n_quad_pts), soln_grad_ext(n_quad_pts);
796 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
798 for (
int istate=0; istate<
nstate; istate++) {
799 soln_grad_int[iquad][istate] = 0;
801 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
802 const int istate = fe_values_boundary.get_fe().system_to_component_index(idof).first;
803 for (
int d=0;d<dim;++d) {
804 soln_grad_int[iquad][istate][d] += local_solution.
coefficients[idof] * gradient_operator[d][idof][iquad];
809 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
810 const dealii::Tensor<1,dim,real2> normal_int = phys_unit_normal[iquad];
811 physics.
boundary_face_values (boundary_id, real_quad_pts[iquad], normal_int, soln_int[iquad], soln_grad_int[iquad], soln_ext[iquad], soln_grad_ext[iquad]);
815 const dealii::FiniteElement<dim> &base_fe_int = local_solution.
finite_element.get_sub_fe(0,1);
816 const unsigned int n_base_dofs_int = base_fe_int.n_dofs_per_cell();
818 std::vector<DirectionalState > soln_grad_correction_int(n_base_dofs_int);
823 std::vector<DirectionalState> soln_jump_int(n_quad_pts);
824 std::vector<DirectionalState> soln_jump_ext(n_quad_pts);
825 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
826 for (
int s=0; s<
nstate; s++) {
827 for (
int d=0; d<dim; d++) {
828 soln_jump_int[iquad][s][d] = (soln_int[iquad][s] - soln_ext[iquad][s]) * (phys_unit_normal[iquad][d]);
829 soln_jump_ext[iquad][s][d] = (soln_ext[iquad][s] - soln_int[iquad][s]) * (-phys_unit_normal[iquad][d]);
834 std::vector<State> lifting_op_R_rhs_int(n_base_dofs_int);
835 for (
unsigned int idof_base=0; idof_base<n_base_dofs_int; ++idof_base) {
836 for (
int s=0; s<
nstate; s++) {
838 const unsigned int idof = local_solution.
finite_element.component_to_system_index(s, idof_base);
839 lifting_op_R_rhs_int[idof_base][s] = 0.0;
841 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
843 for (
int d=0; d<dim; ++d) {
845 const double basis_average = interpolation_operator[idof][iquad];
846 lifting_op_R_rhs_int[idof_base][s] -= soln_jump_int[iquad][s][d] * basis_average * faceJxW[iquad];
852 std::vector<State> soln_grad_corr_int(n_base_dofs_int);
853 compute_br2_correction<dim,nstate,real2>(local_solution.
finite_element, local_metric, lifting_op_R_rhs_int, soln_grad_corr_int);
855 correct_the_gradient<dim,nstate,real2>( soln_grad_corr_int, local_solution.
finite_element, soln_jump_int, interpolation_operator, gradient_operator, soln_grad_int);
857 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
858 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
859 const unsigned int istate = local_solution.
finite_element.system_to_component_index(idof).first;
860 const unsigned int idof_base = local_solution.
finite_element.system_to_component_index(idof).second;
863 for (
int d=0;d<dim;++d) {
868 soln_grad_ext[iquad][istate][d] = soln_grad_int[iquad][istate][d];
871 physics.
boundary_face_values (boundary_id, real_quad_pts[iquad], phys_unit_normal[iquad], soln_int[iquad], soln_grad_int[iquad], soln_ext[iquad], soln_grad_ext[iquad]);
877 std::vector<State> conv_num_flux_dot_n(n_quad_pts);
878 std::vector<State> diss_soln_num_flux(n_quad_pts);
879 std::vector<DirectionalState> diss_flux_jump_int(n_quad_pts);
880 std::vector<State> diss_auxi_num_flux_dot_n(n_quad_pts);
889 (void) artificial_diss_coeff;
891 typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
894 std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
895 artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
897 std::vector<real> artificial_diss_coeff_at_q(n_quad_pts);
898 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
899 artificial_diss_coeff_at_q[iquad] = 0.0;
901 const dealii::Point<dim,real> point = unit_quad_pts[iquad];
902 for (
unsigned int idof=0; idof<n_dofs_arti_diss; ++idof) {
903 const unsigned int index = dof_indices_artificial_dissipation[idof];
907 artificial_diss_coeff_at_q[iquad] = 0.0;
910 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
912 const dealii::Tensor<1,dim,real2> normal_int = phys_unit_normal[iquad];
926 conv_num_flux_dot_n[iquad] = conv_num_flux.
evaluate_flux(soln_int[iquad], soln_ext[iquad], normal_int);
928 diss_soln_num_flux[iquad] = diss_num_flux.
evaluate_solution_flux(soln_ext[iquad], soln_ext[iquad], normal_int);
930 DirectionalState diss_soln_jump_int;
931 for (
int s=0; s<
nstate; s++) {
932 for (
int d=0; d<dim; d++) {
933 diss_soln_jump_int[s][d] = (diss_soln_num_flux[iquad][s] - soln_int[iquad][s]) * normal_int[d];
936 diss_flux_jump_int[iquad] = physics.
dissipative_flux (soln_int[iquad], diss_soln_jump_int, current_cell_index);
940 for (
int s=0; s<
nstate; s++) {
941 diss_flux_jump_int[iquad][s] += artificial_diss_flux_jump_int[s];
950 artificial_diss_coeff_at_q[iquad],
951 artificial_diss_coeff_at_q[iquad],
952 soln_int[iquad], soln_ext[iquad],
953 soln_grad_int[iquad], soln_grad_ext[iquad],
954 normal_int, penalty,
true);
958 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
962 const unsigned int istate = fe_values_boundary.get_fe().system_to_component_index(itest).first;
964 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
966 const real2 JxW_iquad = faceJxW[iquad];
968 rhs_val = rhs_val - interpolation_operator[itest][iquad] * conv_num_flux_dot_n[iquad][istate] * JxW_iquad;
970 rhs_val = rhs_val - interpolation_operator[itest][iquad] * diss_auxi_num_flux_dot_n[iquad][istate] * JxW_iquad;
971 for (
int d=0;d<dim;++d) {
972 rhs_val = rhs_val + gradient_operator[d][itest][iquad] * diss_flux_jump_int[iquad][istate][d] * JxW_iquad;
977 rhs[itest] = rhs_val;
978 dual_dot_residual += local_dual[itest]*rhs_val;
983 template <
int dim,
int nstate,
typename real,
typename MeshType>
985 typename dealii::DoFHandler<dim>::active_cell_iterator ,
986 const dealii::types::global_dof_index current_cell_index,
987 const unsigned int face_number,
988 const unsigned int boundary_id,
989 const dealii::FEFaceValuesBase<dim,dim> &fe_values_boundary,
991 const dealii::FESystem<dim,dim> &fe_soln,
992 const dealii::Quadrature<dim-1> &quadrature,
993 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
994 const std::vector<dealii::types::global_dof_index> &soln_dof_indices,
995 dealii::Vector<real> &local_rhs_cell,
996 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
998 (void) current_cell_index;
1001 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
1002 const unsigned int n_soln_dofs = fe_values_boundary.dofs_per_cell;
1003 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
1005 (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R;
1006 const bool compute_metric_derivatives =
true;
1007 AssertDimension (n_soln_dofs, soln_dof_indices.size());
1009 std::vector< adtype > soln_coeff(n_soln_dofs);
1010 std::vector< adtype > coords_coeff(n_metric_dofs);
1012 unsigned int w_start, w_end, x_start, x_end;
1013 automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R,
1014 n_soln_dofs, n_metric_dofs,
1015 w_start, w_end, x_start, x_end );
1017 unsigned int i_derivative = 0;
1018 const unsigned int n_total_indep = x_end;
1020 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
1021 const real val = this->
solution(soln_dof_indices[idof]);
1022 soln_coeff[idof] = val;
1023 soln_coeff[idof].val() = val;
1025 if (compute_dRdW || compute_d2R) soln_coeff[idof].diff(i_derivative, n_total_indep);
1026 if (compute_d2R) soln_coeff[idof].val().diff(i_derivative, n_total_indep);
1028 if (compute_dRdW || compute_d2R) i_derivative++;
1030 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1031 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices[idof]];
1032 coords_coeff[idof] = val;
1033 coords_coeff[idof].val() = val;
1035 if (compute_dRdX || compute_d2R) coords_coeff[idof].diff(i_derivative, n_total_indep);
1036 if (compute_d2R) coords_coeff[idof].val().diff(i_derivative, n_total_indep);
1038 if (compute_dRdX || compute_d2R) i_derivative++;
1041 AssertDimension(i_derivative, n_total_indep);
1043 std::vector<real> local_dual(n_soln_dofs);
1044 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1045 local_dual[itest] = this->
dual[soln_dof_indices[itest]];
1052 std::vector<adtype> rhs(n_soln_dofs);
1053 adtype dual_dot_residual;
1072 compute_metric_derivatives);
1074 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1075 local_rhs_cell[itest] += rhs[itest].val().val();
1078 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1080 std::vector<real> residual_derivatives(n_soln_dofs);
1081 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
1082 const unsigned int i_dx = idof+w_start;
1083 residual_derivatives[idof] = rhs[itest].dx(i_dx).val();
1084 AssertIsFinite(residual_derivatives[idof]);
1086 const bool elide_zero_values =
false;
1087 this->
system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives, elide_zero_values);
1090 std::vector<real> residual_derivatives(n_metric_dofs);
1091 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1092 const unsigned int i_dx = idof+x_start;
1093 residual_derivatives[idof] = rhs[itest].dx(i_dx).val();
1095 this->
dRdXv.add(soln_dof_indices[itest], metric_dof_indices, residual_derivatives);
1101 std::vector<real> dWidW(n_soln_dofs);
1102 std::vector<real> dWidX(n_metric_dofs);
1103 std::vector<real> dXidX(n_metric_dofs);
1104 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
1106 const unsigned int i_dx = idof+w_start;
1107 const FadType dWi = dual_dot_residual.dx(i_dx);
1109 for (
unsigned int jdof=0; jdof<n_soln_dofs; ++jdof) {
1110 const unsigned int j_dx = jdof+w_start;
1111 dWidW[jdof] = dWi.dx(j_dx);
1113 this->
d2RdWdW.add(soln_dof_indices[idof], soln_dof_indices, dWidW);
1115 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
1116 const unsigned int j_dx = jdof+x_start;
1117 dWidX[jdof] = dWi.dx(j_dx);
1119 this->
d2RdWdX.add(soln_dof_indices[idof], metric_dof_indices, dWidX);
1121 for (
unsigned int idof=0; idof<n_metric_dofs; ++idof) {
1123 const unsigned int i_dx = idof+x_start;
1124 const FadType dXi = dual_dot_residual.dx(i_dx);
1126 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
1127 const unsigned int j_dx = jdof+x_start;
1128 dXidX[jdof] = dXi.dx(j_dx);
1130 this->
d2RdXdX.add(metric_dof_indices[idof], metric_dof_indices, dXidX);
1136 template <
int dim,
int nstate,
typename real,
typename MeshType>
1137 template <
typename adtype>
1139 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1140 const dealii::types::global_dof_index current_cell_index,
1141 const unsigned int face_number,
1142 const unsigned int boundary_id,
1143 const dealii::FEFaceValuesBase<dim,dim> &fe_values_boundary,
1145 const dealii::FESystem<dim,dim> &fe_soln,
1146 const dealii::Quadrature<dim-1> &quadrature,
1147 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
1148 const std::vector<dealii::types::global_dof_index> &soln_dof_indices,
1152 dealii::Vector<real> &local_rhs_cell,
1153 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
1155 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
1156 const unsigned int n_soln_dofs = fe_values_boundary.dofs_per_cell;
1157 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
1159 (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R;
1160 const bool compute_metric_derivatives =
true;
1161 AssertDimension (n_soln_dofs, soln_dof_indices.size());
1166 unsigned int w_start, w_end, x_start, x_end;
1167 automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R,
1168 n_soln_dofs, n_metric_dofs,
1169 w_start, w_end, x_start, x_end );
1171 using TH = codi::TapeHelper<adtype>;
1173 adtype::getGlobalTape();
1174 if (compute_dRdW || compute_dRdX || compute_d2R) {
1175 th.startRecording();
1177 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
1178 const real val = this->
solution(soln_dof_indices[idof]);
1179 local_solution.coefficients[idof] = val;
1181 if (compute_dRdW || compute_d2R) {
1182 th.registerInput(local_solution.coefficients[idof]);
1184 adtype::getGlobalTape().deactivateValue(local_solution.coefficients[idof]);
1187 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1188 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices[idof]];
1191 if (compute_dRdX || compute_d2R) {
1194 adtype::getGlobalTape().deactivateValue(local_metric.
coefficients[idof]);
1198 std::vector<real> local_dual(n_soln_dofs);
1199 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1200 local_dual[itest] = this->
dual[soln_dof_indices[itest]];
1203 std::vector<adtype> rhs(n_soln_dofs);
1204 adtype dual_dot_residual;
1221 compute_metric_derivatives);
1223 if (compute_dRdW || compute_dRdX) {
1224 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1225 th.registerOutput(rhs[itest]);
1227 }
else if (compute_d2R) {
1228 th.registerOutput(dual_dot_residual);
1230 if (compute_dRdW || compute_dRdX || compute_d2R) {
1234 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1235 local_rhs_cell(itest) += getValue<adtype>(rhs[itest]);
1236 AssertIsFinite(local_rhs_cell(itest));
1240 typename TH::JacobianType& jac = th.createJacobian();
1241 th.evalJacobian(jac);
1242 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1244 std::vector<real> residual_derivatives(n_soln_dofs);
1245 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
1246 const unsigned int i_dx = idof+w_start;
1247 residual_derivatives[idof] = jac(itest,i_dx);
1248 AssertIsFinite(residual_derivatives[idof]);
1250 const bool elide_zero_values =
false;
1251 this->
system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives, elide_zero_values);
1253 th.deleteJacobian(jac);
1258 typename TH::JacobianType& jac = th.createJacobian();
1259 th.evalJacobian(jac);
1260 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1261 std::vector<real> residual_derivatives(n_metric_dofs);
1262 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1263 const unsigned int i_dx = idof+x_start;
1264 residual_derivatives[idof] = jac(itest,i_dx);
1266 this->
dRdXv.add(soln_dof_indices[itest], metric_dof_indices, residual_derivatives);
1268 th.deleteJacobian(jac);
1273 typename TH::HessianType& hes = th.createHessian();
1274 th.evalHessian(hes);
1276 int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs : 0;
1278 std::vector<real> dWidW(n_soln_dofs);
1279 std::vector<real> dWidX(n_metric_dofs);
1280 std::vector<real> dXidX(n_metric_dofs);
1282 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
1284 const unsigned int i_dx = idof+w_start;
1286 for (
unsigned int jdof=0; jdof<n_soln_dofs; ++jdof) {
1287 const unsigned int j_dx = jdof+w_start;
1288 dWidW[jdof] = hes(i_dependent,i_dx,j_dx);
1290 this->
d2RdWdW.add(soln_dof_indices[idof], soln_dof_indices, dWidW);
1292 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
1293 const unsigned int j_dx = jdof+x_start;
1294 dWidX[jdof] = hes(i_dependent,i_dx,j_dx);
1296 this->
d2RdWdX.add(soln_dof_indices[idof], metric_dof_indices, dWidX);
1299 for (
unsigned int idof=0; idof<n_metric_dofs; ++idof) {
1301 const unsigned int i_dx = idof+x_start;
1303 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
1304 const unsigned int j_dx = jdof+x_start;
1305 dXidX[jdof] = hes(i_dependent,i_dx,j_dx);
1307 this->
d2RdXdX.add(metric_dof_indices[idof], metric_dof_indices, dXidX);
1310 th.deleteHessian(hes);
1312 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
1313 adtype::getGlobalTape().deactivateValue(local_solution.coefficients[idof]);
1315 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1316 adtype::getGlobalTape().deactivateValue(local_metric.
coefficients[idof]);
1321 template <
int dim,
int nstate,
typename real,
typename MeshType>
1323 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1324 const dealii::types::global_dof_index current_cell_index,
1325 const unsigned int face_number,
1326 const unsigned int boundary_id,
1327 const dealii::FEFaceValuesBase<dim,dim> &fe_values_boundary,
1329 const dealii::FESystem<dim,dim> &fe_soln,
1330 const dealii::Quadrature<dim-1> &quadrature,
1331 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
1332 const std::vector<dealii::types::global_dof_index> &soln_dof_indices,
1336 dealii::Vector<real> &local_rhs_cell,
1337 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
1339 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
1340 const unsigned int n_soln_dofs = fe_values_boundary.dofs_per_cell;
1341 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
1343 (void) compute_dRdW;
1344 (void) compute_dRdX;
1347 const bool compute_metric_derivatives =
true;
1348 AssertDimension (n_soln_dofs, soln_dof_indices.size());
1353 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
1354 const real val = this->
solution(soln_dof_indices[idof]);
1355 local_solution.coefficients[idof] = val;
1357 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1358 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices[idof]];
1362 std::vector<real> local_dual(n_soln_dofs);
1363 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1364 local_dual[itest] = this->
dual[soln_dof_indices[itest]];
1367 std::vector<real> rhs(n_soln_dofs);
1368 real dual_dot_residual;
1385 compute_metric_derivatives);
1387 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1388 local_rhs_cell(itest) += getValue<real>(rhs[itest]);
1389 AssertIsFinite(local_rhs_cell(itest));
1395 template <
int dim,
int nstate,
typename real,
typename MeshType>
1397 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1398 const dealii::types::global_dof_index current_cell_index,
1399 const unsigned int face_number,
1400 const unsigned int boundary_id,
1401 const dealii::FEFaceValuesBase<dim,dim> &fe_values_boundary,
1403 const dealii::FESystem<dim,dim> &fe_soln,
1404 const dealii::Quadrature<dim-1> &quadrature,
1405 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
1406 const std::vector<dealii::types::global_dof_index> &soln_dof_indices,
1407 dealii::Vector<real> &local_rhs_cell,
1408 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
1410 (void) current_cell_index;
1412 assemble_boundary_codi_taped_derivatives<codi_HessianComputationType>(
1427 compute_dRdW, compute_dRdX, compute_d2R);
1428 }
else if (compute_dRdW || compute_dRdX) {
1429 assemble_boundary_codi_taped_derivatives<codi_JacobianComputationType>(
1444 compute_dRdW, compute_dRdX, compute_d2R);
1461 compute_dRdW, compute_dRdX, compute_d2R);
1469 dealii::Quadrature<dim> project_face_quadrature(
1470 const dealii::Quadrature<dim - 1> &face_quadrature_lower_dim,
const std::pair<unsigned int, int> face_subface_pair,
1471 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set) {
1472 dealii::Quadrature<dim> face_quadrature;
1474 if constexpr (dim == 3) {
1475 const dealii::Quadrature<dim> all_faces_quad =
1476 face_subface_pair.second == -1 ? dealii::QProjector<dim>::project_to_all_faces(
1477 dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim)
1478 : dealii::QProjector<dim>::project_to_all_subfaces(
1479 dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim);
1480 const unsigned int n_face_quad_pts = face_quadrature_lower_dim.size();
1481 std::vector<dealii::Point<dim>> points(n_face_quad_pts);
1482 std::vector<double> weights(n_face_quad_pts);
1483 for (
unsigned int iquad = 0; iquad < n_face_quad_pts; ++iquad) {
1484 points[iquad] = all_faces_quad.point(iquad + face_data_set);
1485 weights[iquad] = all_faces_quad.weight(iquad + face_data_set);
1487 face_quadrature = dealii::Quadrature<dim>(points, weights);
1490 (void) face_data_set;
1491 if (face_subface_pair.second == -1) {
1492 face_quadrature = dealii::QProjector<dim>::project_to_face(
1493 dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim, face_subface_pair.first);
1495 face_quadrature = dealii::QProjector<dim>::project_to_subface(
1496 dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim, face_subface_pair.first,
1497 face_subface_pair.second, dealii::RefinementCase<dim - 1>::isotropic_refinement);
1500 return face_quadrature;
1503 template <
int dim,
int nstate,
typename real,
typename MeshType>
1504 template <
typename real2>
1506 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1507 const dealii::types::global_dof_index current_cell_index,
1508 const dealii::types::global_dof_index neighbor_cell_index,
1513 const std::vector< double > &dual_int,
1514 const std::vector< double > &dual_ext,
1515 const std::pair<unsigned int, int> face_subface_int,
1516 const std::pair<unsigned int, int> face_subface_ext,
1517 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_int,
1518 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_ext,
1522 const dealii::FEFaceValuesBase<dim,dim> &fe_values_int,
1523 const dealii::FEFaceValuesBase<dim,dim> &fe_values_ext,
1525 const dealii::Quadrature<dim-1> &face_quadrature,
1526 std::vector<real2> &rhs_int,
1527 std::vector<real2> &rhs_ext,
1528 real2 &dual_dot_residual,
1529 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
1531 (void) compute_dRdW;
1532 const unsigned int n_soln_dofs_int = soln_int.
finite_element.dofs_per_cell;
1533 const unsigned int n_soln_dofs_ext = soln_ext.
finite_element.dofs_per_cell;
1534 const unsigned int n_face_quad_pts = face_quadrature.size();
1536 dual_dot_residual = 0.0;
1537 for (
unsigned int itest=0; itest<n_soln_dofs_int; ++itest) {
1538 rhs_int[itest] = 0.0;
1540 for (
unsigned int itest=0; itest<n_soln_dofs_ext; ++itest) {
1541 rhs_ext[itest] = 0.0;
1544 using State = State<real2, nstate>;
1545 using DirectionalState = DirectionalState<real2, dim, nstate>;
1546 using Tensor1D = dealii::Tensor<1,dim,real2>;
1547 using Tensor2D = dealii::Tensor<2,dim,real2>;
1549 dealii::Quadrature<dim> face_quadrature_int = project_face_quadrature<dim>(face_quadrature, face_subface_int, face_data_set_int);
1550 dealii::Quadrature<dim> face_quadrature_ext = project_face_quadrature<dim>(face_quadrature, face_subface_ext, face_data_set_ext);
1552 (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R;
1553 const bool compute_metric_derivatives =
true;
1555 const std::vector<dealii::Point<dim,double>> &unit_quad_pts_int = face_quadrature_int.get_points();
1556 const std::vector<dealii::Point<dim,double>> &unit_quad_pts_ext = face_quadrature_ext.get_points();
1561 std::vector<Tensor2D> metric_jac_int = evaluate_metric_jacobian (unit_quad_pts_int, metric_int);
1562 std::vector<Tensor2D> metric_jac_ext = evaluate_metric_jacobian (unit_quad_pts_ext, metric_ext);
1564 const dealii::Tensor<1,dim,real> unit_normal_int = dealii::GeometryInfo<dim>::unit_normal_vector[face_subface_int.first];
1565 const dealii::Tensor<1,dim,real> unit_normal_ext = dealii::GeometryInfo<dim>::unit_normal_vector[face_subface_ext.first];
1586 (void) artificial_diss_coeff_int;
1587 (void) artificial_diss_coeff_ext;
1588 typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
1591 std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
1592 artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
1594 std::vector<real> artificial_diss_coeff_at_q(n_face_quad_pts);
1595 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1596 artificial_diss_coeff_at_q[iquad] = 0.0;
1599 const dealii::Point<dim,real> point = unit_quad_pts_int[iquad];
1600 for (
unsigned int idof=0; idof<n_dofs_arti_diss; ++idof) {
1601 const unsigned int index = dof_indices_artificial_dissipation[idof];
1605 artificial_diss_coeff_at_q[iquad] = 0.0;
1608 std::vector<real2> jacobian_determinant_int(n_face_quad_pts);
1609 std::vector<real2> jacobian_determinant_ext(n_face_quad_pts);
1610 std::vector<Tensor2D> jacobian_transpose_inverse_int(n_face_quad_pts);
1611 std::vector<Tensor2D> jacobian_transpose_inverse_ext(n_face_quad_pts);
1613 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1614 if (compute_metric_derivatives) {
1615 jacobian_determinant_int[iquad] = dealii::determinant(metric_jac_int[iquad]);
1616 jacobian_determinant_ext[iquad] = dealii::determinant(metric_jac_ext[iquad]);
1618 jacobian_transpose_inverse_int[iquad] = dealii::transpose(dealii::invert(metric_jac_int[iquad]));
1619 jacobian_transpose_inverse_ext[iquad] = dealii::transpose(dealii::invert(metric_jac_ext[iquad]));
1623 #ifdef KOPRIVA_METRICS_FACE 1624 auto old_jacobian_determinant_int = jacobian_determinant_int;
1625 auto old_jacobian_determinant_ext = jacobian_determinant_ext;
1626 auto old_jacobian_transpose_inverse_int = jacobian_transpose_inverse_int;
1627 auto old_jacobian_transpose_inverse_ext = jacobian_transpose_inverse_ext;
1629 if constexpr (dim != 1) {
1630 evaluate_covariant_metric_jacobian<dim,real2> ( face_quadrature_int, metric_int, jacobian_transpose_inverse_int, jacobian_determinant_int);
1631 evaluate_covariant_metric_jacobian<dim,real2> ( face_quadrature_ext, metric_ext, jacobian_transpose_inverse_ext, jacobian_determinant_ext);
1637 check_same_coords<dim,real2>(unit_quad_pts_int, unit_quad_pts_ext, metric_int, metric_ext, 1e-10);
1641 std::vector<Tensor1D> phys_unit_normal_int(n_face_quad_pts), phys_unit_normal_ext(n_face_quad_pts);
1642 std::vector<real2> surface_jac_det(n_face_quad_pts);
1643 std::vector<real2> faceJxW(n_face_quad_pts);
1645 dealii::FullMatrix<real> interpolation_operator_int(n_soln_dofs_int, n_face_quad_pts);
1646 dealii::FullMatrix<real> interpolation_operator_ext(n_soln_dofs_ext, n_face_quad_pts);
1647 std::array<dealii::FullMatrix<real2>,dim> gradient_operator_int, gradient_operator_ext;
1648 for (
int d=0;d<dim;++d) {
1649 gradient_operator_int[d].reinit(dealii::TableIndices<2>(n_soln_dofs_int, n_face_quad_pts));
1650 gradient_operator_ext[d].reinit(dealii::TableIndices<2>(n_soln_dofs_ext, n_face_quad_pts));
1653 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1655 real2 surface_jac_det_int, surface_jac_det_ext;
1657 if (compute_metric_derivatives) {
1659 const real2 jac_det_int = jacobian_determinant_int[iquad];
1660 const real2 jac_det_ext = jacobian_determinant_ext[iquad];
1662 const Tensor2D jac_inv_tran_int = jacobian_transpose_inverse_int[iquad];
1663 const Tensor2D jac_inv_tran_ext = jacobian_transpose_inverse_ext[iquad];
1665 const Tensor1D normal_int = vmult(jac_inv_tran_int, unit_normal_int);
1666 const Tensor1D normal_ext = vmult(jac_inv_tran_ext, unit_normal_ext);
1667 const real2 area_int =
norm(normal_int);
1668 const real2 area_ext =
norm(normal_ext);
1674 for (
int d=0;d<dim;++d) {
1675 phys_unit_normal_int[iquad][d] = normal_int[d] / area_int;
1677 for (
int d=0;d<dim;++d) {
1678 phys_unit_normal_ext[iquad][d] = normal_ext[d] / area_ext;
1681 surface_jac_det_int = area_int*jac_det_int;
1682 surface_jac_det_ext = area_ext*jac_det_ext;
1685 if (std::is_same<double,real2>::value) {
1686 bool valid_metrics =
true;
1695 if (face_subface_int.second == -1 && face_subface_ext.second == -1) {
1698 pcout <<
"iquad " << iquad <<
" Non-matching surface jacobians, int = " 1699 << surface_jac_det_int <<
", ext = " << surface_jac_det_ext <<
", diff = " 1700 << abs(surface_jac_det_int-surface_jac_det_ext) << std::endl;
1703 valid_metrics =
false;
1706 real2 diff_norm = 0;
1707 for (
int d=0;d<dim;++d) {
1708 const real2 diff = phys_unit_normal_int[iquad][d]+phys_unit_normal_ext[iquad][d];
1709 diff_norm += diff*diff;
1711 diff_norm = sqrt(diff_norm);
1712 if (diff_norm > 1e-10) {
1713 std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1);
1714 std::cout <<
"Non-matching normals. Error norm: " << diff_norm << std::endl;
1715 for (
int d=0;d<dim;++d) {
1717 std::cout <<
" normal_int["<<d<<
"] : " << phys_unit_normal_int[iquad][d]
1718 <<
" normal_ext["<<d<<
"] : " << phys_unit_normal_ext[iquad][d]
1721 valid_metrics =
false;
1723 if (!valid_metrics) {
1735 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
1736 interpolation_operator_int[idof][iquad] = soln_int.
finite_element.shape_value(idof,unit_quad_pts_int[iquad]);
1737 dealii::Tensor<1,dim,real> ref_shape_grad = soln_int.
finite_element.shape_grad(idof,unit_quad_pts_int[iquad]);
1738 const Tensor1D phys_shape_grad = vmult(jac_inv_tran_int, ref_shape_grad);
1739 for (
int d=0;d<dim;++d) {
1740 gradient_operator_int[d][idof][iquad] = phys_shape_grad[d];
1743 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
1744 interpolation_operator_ext[idof][iquad] = soln_ext.
finite_element.shape_value(idof,unit_quad_pts_ext[iquad]);
1745 dealii::Tensor<1,dim,real> ref_shape_grad = soln_ext.
finite_element.shape_grad(idof,unit_quad_pts_ext[iquad]);
1746 const Tensor1D phys_shape_grad = vmult(jac_inv_tran_ext, ref_shape_grad);
1747 for (
int d=0;d<dim;++d) {
1748 gradient_operator_ext[d][idof][iquad] = phys_shape_grad[d];
1753 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
1754 interpolation_operator_int[idof][iquad] = soln_int.
finite_element.shape_value(idof,unit_quad_pts_int[iquad]);
1756 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
1757 interpolation_operator_ext[idof][iquad] = soln_ext.
finite_element.shape_value(idof,unit_quad_pts_ext[iquad]);
1759 for (
int d=0;d<dim;++d) {
1760 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
1761 const unsigned int istate = soln_int.
finite_element.system_to_component_index(idof).first;
1762 gradient_operator_int[d][idof][iquad] = fe_values_int.shape_grad_component(idof, iquad, istate)[d];
1764 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
1765 const unsigned int istate = soln_ext.
finite_element.system_to_component_index(idof).first;
1766 gradient_operator_ext[d][idof][iquad] = fe_values_ext.shape_grad_component(idof, iquad, istate)[d];
1769 surface_jac_det_int = fe_values_int.JxW(iquad)/face_quadrature_int.weight(iquad);
1770 surface_jac_det_ext = fe_values_ext.JxW(iquad)/face_quadrature_ext.weight(iquad);
1772 phys_unit_normal_int[iquad] = fe_values_int.normal_vector(iquad);
1773 phys_unit_normal_ext[iquad] = -phys_unit_normal_int[iquad];
1781 if ( surface_jac_det_int > surface_jac_det_ext) {
1784 surface_jac_det[iquad] = surface_jac_det_ext;
1789 surface_jac_det[iquad] = surface_jac_det_int;
1793 faceJxW[iquad] = surface_jac_det[iquad] * face_quadrature_int.weight(iquad);
1798 std::vector<State> soln_int_at_q = soln_int.
evaluate_values(unit_quad_pts_int);
1799 std::vector<State> soln_ext_at_q = soln_ext.
evaluate_values(unit_quad_pts_ext);
1802 std::vector<DirectionalState> soln_grad_int(n_face_quad_pts), soln_grad_ext(n_face_quad_pts);
1803 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1805 for (
int istate=0; istate<
nstate; istate++) {
1806 soln_grad_int[iquad][istate] = 0;
1807 soln_grad_ext[iquad][istate] = 0;
1810 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
1811 const unsigned int istate = soln_int.
finite_element.system_to_component_index(idof).first;
1812 for (
int d=0;d<dim;++d) {
1813 soln_grad_int[iquad][istate][d] += soln_int.
coefficients[idof] * gradient_operator_int[d][idof][iquad];
1816 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
1817 const unsigned int istate = soln_ext.
finite_element.system_to_component_index(idof).first;
1818 for (
int d=0;d<dim;++d) {
1819 soln_grad_ext[iquad][istate][d] += soln_ext.
coefficients[idof] * gradient_operator_ext[d][idof][iquad];
1829 const dealii::FiniteElement<dim> &base_fe_int = soln_int.
finite_element.get_sub_fe(0,1);
1830 const dealii::FiniteElement<dim> &base_fe_ext = soln_ext.
finite_element.get_sub_fe(0,1);
1831 const unsigned int n_base_dofs_int = base_fe_int.n_dofs_per_cell();
1832 const unsigned int n_base_dofs_ext = base_fe_ext.n_dofs_per_cell();
1835 std::vector<DirectionalState> soln_jump_int(n_face_quad_pts);
1836 std::vector<DirectionalState> soln_jump_ext(n_face_quad_pts);
1837 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1838 for (
int s=0; s<
nstate; s++) {
1839 for (
int d=0; d<dim; d++) {
1840 soln_jump_int[iquad][s][d] = (soln_int_at_q[iquad][s] - soln_ext_at_q[iquad][s]) * phys_unit_normal_int[iquad][d];
1841 soln_jump_ext[iquad][s][d] = (soln_ext_at_q[iquad][s] - soln_int_at_q[iquad][s]) * (-phys_unit_normal_int[iquad][d]);
1848 std::vector<State> lifting_op_R_rhs_int(n_base_dofs_int);
1849 for (
unsigned int idof_base=0; idof_base<n_base_dofs_int; ++idof_base) {
1850 for (
int s=0; s<
nstate; s++) {
1852 const unsigned int idof = soln_int.
finite_element.component_to_system_index(s, idof_base);
1853 lifting_op_R_rhs_int[idof_base][s] = 0.0;
1855 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1857 for (
int d=0; d<dim; ++d) {
1859 const double basis_average = 0.5 * (interpolation_operator_int[idof][iquad] + 0.0);
1860 lifting_op_R_rhs_int[idof_base][s] -= soln_jump_int[iquad][s][d] * basis_average * faceJxW[iquad];
1867 std::vector<State> lifting_op_R_rhs_ext(n_base_dofs_ext);
1868 for (
unsigned int idof_base=0; idof_base<n_base_dofs_ext; ++idof_base) {
1869 for (
int s=0; s<
nstate; s++) {
1871 const unsigned int idof = soln_ext.
finite_element.component_to_system_index(s, idof_base);
1872 lifting_op_R_rhs_ext[idof_base][s] = 0.0;
1874 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1876 for (
int d=0; d<dim; ++d) {
1878 const double basis_average = 0.5 * ( 0.0 + interpolation_operator_ext[idof][iquad] );
1879 lifting_op_R_rhs_ext[idof_base][s] -= soln_jump_ext[iquad][s][d] * basis_average * faceJxW[iquad];
1886 std::vector<State> soln_grad_corr_int(n_base_dofs_int), soln_grad_corr_ext(n_base_dofs_ext);
1887 compute_br2_correction<dim,nstate,real2>(soln_int.
finite_element, metric_int, lifting_op_R_rhs_int, soln_grad_corr_int);
1888 compute_br2_correction<dim,nstate,real2>(soln_ext.
finite_element, metric_ext, lifting_op_R_rhs_ext, soln_grad_corr_ext);
1890 correct_the_gradient<dim,nstate,real2>( soln_grad_corr_int, soln_int.
finite_element, soln_jump_int, interpolation_operator_int, gradient_operator_int, soln_grad_int);
1891 correct_the_gradient<dim,nstate,real2>( soln_grad_corr_ext, soln_ext.
finite_element, soln_jump_ext, interpolation_operator_ext, gradient_operator_ext, soln_grad_ext);
1896 State conv_num_flux_dot_n;
1897 State diss_soln_num_flux;
1898 State diss_auxi_num_flux_dot_n;
1900 DirectionalState diss_flux_jump_int;
1901 DirectionalState diss_flux_jump_ext;
1903 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1906 conv_num_flux_dot_n = conv_num_flux.
evaluate_flux(soln_int_at_q[iquad], soln_ext_at_q[iquad], phys_unit_normal_int[iquad]);
1907 diss_soln_num_flux = diss_num_flux.
evaluate_solution_flux(soln_int_at_q[iquad], soln_ext_at_q[iquad], phys_unit_normal_int[iquad]);
1909 DirectionalState diss_soln_jump_int, diss_soln_jump_ext;
1910 for (
int s=0; s<
nstate; s++) {
1911 for (
int d=0; d<dim; d++) {
1912 diss_soln_jump_int[s][d] = (diss_soln_num_flux[s] - soln_int_at_q[iquad][s]) * phys_unit_normal_int[iquad][d];
1913 diss_soln_jump_ext[s][d] = (diss_soln_num_flux[s] - soln_ext_at_q[iquad][s]) * phys_unit_normal_ext[iquad][d];
1916 diss_flux_jump_int = physics.
dissipative_flux (soln_int_at_q[iquad], diss_soln_jump_int, current_cell_index);
1917 diss_flux_jump_ext = physics.
dissipative_flux (soln_ext_at_q[iquad], diss_soln_jump_ext, neighbor_cell_index);
1922 for (
int s=0; s<
nstate; s++) {
1923 diss_flux_jump_int[s] += artificial_diss_flux_jump_int[s];
1924 diss_flux_jump_ext[s] += artificial_diss_flux_jump_ext[s];
1931 neighbor_cell_index,
1932 artificial_diss_coeff_at_q[iquad],
1933 artificial_diss_coeff_at_q[iquad],
1934 soln_int_at_q[iquad], soln_ext_at_q[iquad],
1935 soln_grad_int[iquad], soln_grad_ext[iquad],
1936 phys_unit_normal_int[iquad], penalty);
1939 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
1941 const unsigned int istate = soln_int.
finite_element.system_to_component_index(itest_int).first;
1943 const real2 JxW_iquad = faceJxW[iquad];
1945 rhs = rhs - interpolation_operator_int[itest_int][iquad] * conv_num_flux_dot_n[istate] * JxW_iquad;
1947 rhs = rhs - interpolation_operator_int[itest_int][iquad] * diss_auxi_num_flux_dot_n[istate] * JxW_iquad;
1948 for (
int d=0;d<dim;++d) {
1949 rhs = rhs + gradient_operator_int[d][itest_int][iquad] * diss_flux_jump_int[istate][d] * JxW_iquad;
1952 rhs_int[itest_int] += rhs;
1953 dual_dot_residual += dual_int[itest_int]*rhs;
1957 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
1959 const unsigned int istate = soln_ext.
finite_element.system_to_component_index(itest_ext).first;
1961 const real2 JxW_iquad = faceJxW[iquad];
1963 rhs = rhs - interpolation_operator_ext[itest_ext][iquad] * (-conv_num_flux_dot_n[istate]) * JxW_iquad;
1965 rhs = rhs - interpolation_operator_ext[itest_ext][iquad] * (-diss_auxi_num_flux_dot_n[istate]) * JxW_iquad;
1966 for (
int d=0;d<dim;++d) {
1967 rhs = rhs + gradient_operator_ext[d][itest_ext][iquad] * diss_flux_jump_ext[istate][d] * JxW_iquad;
1970 rhs_ext[itest_ext] += rhs;
1971 dual_dot_residual += dual_ext[itest_ext]*rhs;
1978 template <
int dim,
int nstate,
typename real,
typename MeshType>
1980 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1981 const dealii::types::global_dof_index current_cell_index,
1982 const dealii::types::global_dof_index neighbor_cell_index,
1983 const std::pair<unsigned int, int> face_subface_int,
1984 const std::pair<unsigned int, int> face_subface_ext,
1985 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_int,
1986 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_ext,
1987 const dealii::FEFaceValuesBase<dim,dim> &fe_values_int,
1988 const dealii::FEFaceValuesBase<dim,dim> &fe_values_ext,
1990 const dealii::FESystem<dim,dim> &soln_int.finite_element,
1991 const dealii::FESystem<dim,dim> &soln_ext.finite_element,
1992 const dealii::Quadrature<dim-1> &face_quadrature,
1993 const std::vector<dealii::types::global_dof_index> &metric_dof_indices_int,
1994 const std::vector<dealii::types::global_dof_index> &metric_dof_indices_ext,
1995 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_int,
1996 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_ext,
1997 dealii::Vector<real> &local_rhs_int_cell,
1998 dealii::Vector<real> &local_rhs_ext_cell,
1999 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
2001 (void) current_cell_index;
2002 (void) neighbor_cell_index;
2004 using ADArray = std::array<adtype,nstate>;
2005 using ADArrayTensor1 = std::array< dealii::Tensor<1,dim,adtype>,
nstate >;
2007 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
2008 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
2009 const unsigned int n_soln_dofs_int = soln_int.finite_element.dofs_per_cell;
2010 const unsigned int n_soln_dofs_ext = soln_ext.finite_element.dofs_per_cell;
2012 AssertDimension (n_soln_dofs_int, soln_dof_indices_int.size());
2013 AssertDimension (n_soln_dofs_ext, soln_dof_indices_ext.size());
2015 std::vector< adtype > coords_coeff_int(n_metric_dofs);
2016 std::vector< adtype > coords_coeff_ext(n_metric_dofs);
2017 std::vector< adtype > soln_int.coefficients(n_soln_dofs_int);
2018 std::vector< adtype > soln_ext.coefficients(n_soln_dofs_ext);
2021 unsigned int w_int_start, w_int_end, w_ext_start, w_ext_end,
2022 x_int_start, x_int_end, x_ext_start, x_ext_end;
2023 automatic_differentiation_indexing_2(
2024 compute_dRdW, compute_dRdX, compute_d2R,
2025 n_soln_dofs_int, n_soln_dofs_ext, n_metric_dofs,
2026 w_int_start, w_int_end, w_ext_start, w_ext_end,
2027 x_int_start, x_int_end, x_ext_start, x_ext_end);
2029 const unsigned int n_total_indep = x_ext_end;
2030 unsigned int i_derivative = 0;
2032 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
2033 const real val = this->
solution(soln_dof_indices_int[idof]);
2034 soln_int.coefficients[idof] = val;
2035 soln_int.coefficients[idof].val() = val;
2037 if (compute_dRdW || compute_d2R) soln_int.coefficients[idof].diff(i_derivative, n_total_indep);
2038 if (compute_d2R) soln_int.coefficients[idof].val().diff(i_derivative, n_total_indep);
2039 if (compute_dRdW || compute_d2R) i_derivative++;
2041 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
2042 const real val = this->
solution(soln_dof_indices_ext[idof]);
2043 soln_ext.coefficients[idof] = val;
2044 soln_ext.coefficients[idof].val() = val;
2046 if (compute_dRdW || compute_d2R) soln_ext.coefficients[idof].diff(i_derivative, n_total_indep);
2047 if (compute_d2R) soln_ext.coefficients[idof].val().diff(i_derivative, n_total_indep);
2048 if (compute_dRdW || compute_d2R) i_derivative++;
2050 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2051 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices_int[idof]];
2052 coords_coeff_int[idof] = val;
2053 coords_coeff_int[idof].val() = val;
2055 if (compute_dRdX || compute_d2R) coords_coeff_int[idof].diff(i_derivative, n_total_indep);
2056 if (compute_d2R) coords_coeff_int[idof].val().diff(i_derivative, n_total_indep);
2057 if (compute_dRdX || compute_d2R) i_derivative++;
2059 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2060 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices_ext[idof]];
2061 coords_coeff_ext[idof] = val;
2062 coords_coeff_ext[idof].val() = val;
2064 if (compute_dRdX || compute_d2R) coords_coeff_ext[idof].diff(i_derivative, n_total_indep);
2065 if (compute_d2R) coords_coeff_ext[idof].val().diff(i_derivative, n_total_indep);
2066 if (compute_dRdX || compute_d2R) i_derivative++;
2068 AssertDimension(i_derivative, n_total_indep);
2070 std::vector<double> dual_int(n_soln_dofs_int);
2071 std::vector<double> dual_ext(n_soln_dofs_ext);
2073 for (
unsigned int itest=0; itest<n_soln_dofs_int; ++itest) {
2074 const unsigned int global_residual_row = soln_dof_indices_int[itest];
2075 dual_int[itest] = this->
dual[global_residual_row];
2077 for (
unsigned int itest=0; itest<n_soln_dofs_ext; ++itest) {
2078 const unsigned int global_residual_row = soln_dof_indices_ext[itest];
2079 dual_ext[itest] = this->
dual[global_residual_row];
2082 std::vector<adtype> rhs_int(n_soln_dofs_int);
2083 std::vector<adtype> rhs_ext(n_soln_dofs_ext);
2084 adtype dual_dot_residual;
2092 neighbor_cell_index,
2093 soln_int.coefficients,
2094 soln_ext.coefficients,
2109 soln_int.finite_element,
2110 soln_ext.finite_element,
2112 face_quadrature_int,
2113 face_quadrature_ext,
2117 compute_dRdW, compute_dRdX, compute_d2R);
2119 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
2120 local_rhs_int_cell[itest_int] += rhs_int[itest_int].val().val();
2122 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
2123 local_rhs_ext_cell[itest_ext] += rhs_ext[itest_ext].val().val();
2127 std::vector<real> residual_derivatives(n_soln_dofs_int);
2128 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
2130 residual_derivatives.resize(n_soln_dofs_int);
2131 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
2132 const unsigned int i_dx = idof+w_int_start;
2133 residual_derivatives[idof] = rhs_int[itest_int].dx(i_dx).val();
2135 const bool elide_zero_values =
false;
2136 this->
system_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_int, residual_derivatives, elide_zero_values);
2139 residual_derivatives.resize(n_soln_dofs_ext);
2140 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
2141 const unsigned int i_dx = idof+w_ext_start;
2142 residual_derivatives[idof] = rhs_int[itest_int].dx(i_dx).val();
2144 this->
system_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_ext, residual_derivatives, elide_zero_values);
2147 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
2149 residual_derivatives.resize(n_soln_dofs_int);
2150 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
2151 const unsigned int i_dx = idof+w_int_start;
2152 residual_derivatives[idof] = rhs_ext[itest_ext].dx(i_dx).val();
2154 const bool elide_zero_values =
false;
2155 this->
system_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_int, residual_derivatives, elide_zero_values);
2158 residual_derivatives.resize(n_soln_dofs_ext);
2159 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
2160 const unsigned int i_dx = idof+w_ext_start;
2161 residual_derivatives[idof] = rhs_ext[itest_ext].dx(i_dx).val();
2163 this->
system_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_ext, residual_derivatives, elide_zero_values);
2167 std::vector<real> residual_derivatives(n_metric_dofs);
2168 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
2170 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2171 const unsigned int i_dx = idof+x_int_start;
2172 residual_derivatives[idof] = rhs_int[itest_int].dx(i_dx).val();
2174 this->
dRdXv.add(soln_dof_indices_int[itest_int], metric_dof_indices_int, residual_derivatives);
2177 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2178 const unsigned int i_dx = idof+x_ext_start;
2179 residual_derivatives[idof] = rhs_int[itest_int].dx(i_dx).val();
2181 this->
dRdXv.add(soln_dof_indices_int[itest_int], metric_dof_indices_ext, residual_derivatives);
2183 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
2185 std::vector<real> residual_derivatives(n_metric_dofs);
2186 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2187 const unsigned int i_dx = idof+x_int_start;
2188 residual_derivatives[idof] = rhs_ext[itest_ext].dx(i_dx).val();
2190 this->
dRdXv.add(soln_dof_indices_ext[itest_ext], metric_dof_indices_int, residual_derivatives);
2194 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2195 const unsigned int i_dx = idof+x_ext_start;
2196 residual_derivatives[idof] = rhs_ext[itest_ext].dx(i_dx).val();
2198 this->
dRdXv.add(soln_dof_indices_ext[itest_ext], metric_dof_indices_ext, residual_derivatives);
2203 std::vector<real> dWidWint(n_soln_dofs_int);
2204 std::vector<real> dWidWext(n_soln_dofs_ext);
2205 std::vector<real> dWidX(n_metric_dofs);
2206 std::vector<real> dXidX(n_metric_dofs);
2208 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
2210 const unsigned int i_dx = idof+w_int_start;
2211 const FadType dWi = dual_dot_residual.dx(i_dx);
2214 for (
unsigned int jdof=0; jdof<n_soln_dofs_int; ++jdof) {
2215 const unsigned int j_dx = jdof+w_int_start;
2216 dWidWint[jdof] = dWi.dx(j_dx);
2218 this->
d2RdWdW.add(soln_dof_indices_int[idof], soln_dof_indices_int, dWidWint);
2221 for (
unsigned int jdof=0; jdof<n_soln_dofs_ext; ++jdof) {
2222 const unsigned int j_dx = jdof+w_ext_start;
2223 dWidWext[jdof] = dWi.dx(j_dx);
2225 this->
d2RdWdW.add(soln_dof_indices_int[idof], soln_dof_indices_ext, dWidWext);
2228 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2229 const unsigned int j_dx = jdof+x_int_start;
2230 dWidX[jdof] = dWi.dx(j_dx);
2232 this->
d2RdWdX.add(soln_dof_indices_int[idof], metric_dof_indices_int, dWidX);
2235 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2236 const unsigned int j_dx = jdof+x_ext_start;
2237 dWidX[jdof] = dWi.dx(j_dx);
2239 this->
d2RdWdX.add(soln_dof_indices_int[idof], metric_dof_indices_ext, dWidX);
2242 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
2244 const unsigned int i_dx = idof+w_ext_start;
2245 const FadType dWi = dual_dot_residual.dx(i_dx);
2248 for (
unsigned int jdof=0; jdof<n_soln_dofs_int; ++jdof) {
2249 const unsigned int j_dx = jdof+w_int_start;
2250 dWidWint[jdof] = dWi.dx(j_dx);
2252 this->
d2RdWdW.add(soln_dof_indices_ext[idof], soln_dof_indices_int, dWidWint);
2255 for (
unsigned int jdof=0; jdof<n_soln_dofs_ext; ++jdof) {
2256 const unsigned int j_dx = jdof+w_ext_start;
2257 dWidWext[jdof] = dWi.dx(j_dx);
2259 this->
d2RdWdW.add(soln_dof_indices_ext[idof], soln_dof_indices_ext, dWidWext);
2262 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2263 const unsigned int j_dx = jdof+x_int_start;
2264 dWidX[jdof] = dWi.dx(j_dx);
2266 this->
d2RdWdX.add(soln_dof_indices_ext[idof], metric_dof_indices_int, dWidX);
2269 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2270 const unsigned int j_dx = jdof+x_ext_start;
2271 dWidX[jdof] = dWi.dx(j_dx);
2273 this->
d2RdWdX.add(soln_dof_indices_ext[idof], metric_dof_indices_ext, dWidX);
2277 for (
unsigned int idof=0; idof<n_metric_dofs; ++idof) {
2279 const unsigned int i_dx = idof+x_int_start;
2280 const FadType dWi = dual_dot_residual.dx(i_dx);
2283 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2284 const unsigned int j_dx = jdof+x_int_start;
2285 dWidX[jdof] = dWi.dx(j_dx);
2287 this->
d2RdXdX.add(metric_dof_indices_int[idof], metric_dof_indices_int, dWidX);
2290 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2291 const unsigned int j_dx = jdof+x_ext_start;
2292 dWidX[jdof] = dWi.dx(j_dx);
2294 this->
d2RdXdX.add(metric_dof_indices_int[idof], metric_dof_indices_ext, dWidX);
2297 for (
unsigned int idof=0; idof<n_metric_dofs; ++idof) {
2299 const unsigned int i_dx = idof+x_ext_start;
2300 const FadType dWi = dual_dot_residual.dx(i_dx);
2303 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2304 const unsigned int j_dx = jdof+x_int_start;
2305 dWidX[jdof] = dWi.dx(j_dx);
2307 this->
d2RdXdX.add(metric_dof_indices_ext[idof], metric_dof_indices_int, dWidX);
2310 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2311 const unsigned int j_dx = jdof+x_ext_start;
2312 dWidX[jdof] = dWi.dx(j_dx);
2314 this->
d2RdXdX.add(metric_dof_indices_ext[idof], metric_dof_indices_ext, dWidX);
2321 template <
int dim,
int nstate,
typename real,
typename MeshType>
2322 template <
typename adtype>
2324 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
2325 const dealii::types::global_dof_index current_cell_index,
2326 const dealii::types::global_dof_index neighbor_cell_index,
2327 const std::pair<unsigned int, int> face_subface_int,
2328 const std::pair<unsigned int, int> face_subface_ext,
2329 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_int,
2330 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_ext,
2331 const dealii::FEFaceValuesBase<dim,dim> &fe_values_int,
2332 const dealii::FEFaceValuesBase<dim,dim> &fe_values_ext,
2334 const dealii::FESystem<dim,dim> &fe_int,
2335 const dealii::FESystem<dim,dim> &fe_ext,
2336 const dealii::Quadrature<dim-1> &face_quadrature,
2337 const std::vector<dealii::types::global_dof_index> &metric_dof_indices_int,
2338 const std::vector<dealii::types::global_dof_index> &metric_dof_indices_ext,
2339 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_int,
2340 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_ext,
2344 dealii::Vector<real> &local_rhs_int_cell,
2345 dealii::Vector<real> &local_rhs_ext_cell,
2346 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
2348 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
2349 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
2350 const unsigned int n_soln_dofs_int = fe_int.dofs_per_cell;
2351 const unsigned int n_soln_dofs_ext = fe_ext.dofs_per_cell;
2353 AssertDimension (n_soln_dofs_int, soln_dof_indices_int.size());
2354 AssertDimension (n_soln_dofs_ext, soln_dof_indices_ext.size());
2362 unsigned int w_int_start, w_int_end, w_ext_start, w_ext_end,
2363 x_int_start, x_int_end, x_ext_start, x_ext_end;
2364 automatic_differentiation_indexing_2(
2365 compute_dRdW, compute_dRdX, compute_d2R,
2366 n_soln_dofs_int, n_soln_dofs_ext, n_metric_dofs,
2367 w_int_start, w_int_end, w_ext_start, w_ext_end,
2368 x_int_start, x_int_end, x_ext_start, x_ext_end);
2370 using TH = codi::TapeHelper<adtype>;
2372 adtype::getGlobalTape();
2373 if (compute_dRdW || compute_dRdX || compute_d2R) {
2374 th.startRecording();
2376 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
2377 const real val = this->
solution(soln_dof_indices_int[idof]);
2378 soln_int.coefficients[idof] = val;
2379 if (compute_dRdW || compute_d2R) {
2380 th.registerInput(soln_int.coefficients[idof]);
2382 adtype::getGlobalTape().deactivateValue(soln_int.coefficients[idof]);
2385 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
2386 const real val = this->
solution(soln_dof_indices_ext[idof]);
2388 if (compute_dRdW || compute_d2R) {
2391 adtype::getGlobalTape().deactivateValue(soln_ext.
coefficients[idof]);
2394 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2395 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices_int[idof]];
2397 if (compute_dRdX || compute_d2R) {
2400 adtype::getGlobalTape().deactivateValue(metric_int.
coefficients[idof]);
2403 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2404 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices_ext[idof]];
2406 if (compute_dRdX || compute_d2R) {
2409 adtype::getGlobalTape().deactivateValue(metric_ext.
coefficients[idof]);
2413 std::vector<double> dual_int(n_soln_dofs_int);
2414 std::vector<double> dual_ext(n_soln_dofs_ext);
2416 for (
unsigned int itest=0; itest<n_soln_dofs_int; ++itest) {
2417 const unsigned int global_residual_row = soln_dof_indices_int[itest];
2418 dual_int[itest] = this->
dual[global_residual_row];
2420 for (
unsigned int itest=0; itest<n_soln_dofs_ext; ++itest) {
2421 const unsigned int global_residual_row = soln_dof_indices_ext[itest];
2422 dual_ext[itest] = this->
dual[global_residual_row];
2425 std::vector<adtype> rhs_int(n_soln_dofs_int);
2426 std::vector<adtype> rhs_ext(n_soln_dofs_ext);
2427 adtype dual_dot_residual;
2432 neighbor_cell_index,
2433 soln_int, soln_ext, metric_int, metric_ext,
2450 compute_dRdW, compute_dRdX, compute_d2R);
2452 if (compute_dRdW || compute_dRdX) {
2453 for (
unsigned int itest=0; itest<n_soln_dofs_int; ++itest) {
2454 th.registerOutput(rhs_int[itest]);
2456 for (
unsigned int itest=0; itest<n_soln_dofs_ext; ++itest) {
2457 th.registerOutput(rhs_ext[itest]);
2459 }
else if (compute_d2R) {
2460 th.registerOutput(dual_dot_residual);
2462 if (compute_dRdW || compute_dRdX || compute_d2R) {
2467 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
2468 local_rhs_int_cell[itest_int] += getValue<adtype>(rhs_int[itest_int]);
2470 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
2471 local_rhs_ext_cell[itest_ext] += getValue<adtype>(rhs_ext[itest_ext]);
2474 if (compute_dRdW || compute_dRdX) {
2475 typename TH::JacobianType& jac = th.createJacobian();
2476 th.evalJacobian(jac);
2479 std::vector<real> residual_derivatives(n_soln_dofs_int);
2481 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
2482 int i_dependent = itest_int;
2485 residual_derivatives.resize(n_soln_dofs_int);
2486 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
2487 const unsigned int i_dx = idof+w_int_start;
2488 residual_derivatives[idof] = jac(i_dependent,i_dx);
2490 const bool elide_zero_values =
false;
2491 this->
system_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_int, residual_derivatives, elide_zero_values);
2494 residual_derivatives.resize(n_soln_dofs_ext);
2495 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
2496 const unsigned int i_dx = idof+w_ext_start;
2497 residual_derivatives[idof] = jac(i_dependent,i_dx);
2499 this->
system_matrix.add(soln_dof_indices_int[itest_int], soln_dof_indices_ext, residual_derivatives, elide_zero_values);
2502 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
2504 int i_dependent = n_soln_dofs_int + itest_ext;
2507 residual_derivatives.resize(n_soln_dofs_int);
2508 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
2509 const unsigned int i_dx = idof+w_int_start;
2510 residual_derivatives[idof] = jac(i_dependent,i_dx);
2512 const bool elide_zero_values =
false;
2513 this->
system_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_int, residual_derivatives, elide_zero_values);
2516 residual_derivatives.resize(n_soln_dofs_ext);
2517 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
2518 const unsigned int i_dx = idof+w_ext_start;
2519 residual_derivatives[idof] = jac(i_dependent,i_dx);
2521 this->
system_matrix.add(soln_dof_indices_ext[itest_ext], soln_dof_indices_ext, residual_derivatives, elide_zero_values);
2526 std::vector<real> residual_derivatives(n_metric_dofs);
2528 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
2530 int i_dependent = itest_int;
2533 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2534 const unsigned int i_dx = idof+x_int_start;
2535 residual_derivatives[idof] = jac(i_dependent,i_dx);
2537 this->
dRdXv.add(soln_dof_indices_int[itest_int], metric_dof_indices_int, residual_derivatives);
2540 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2541 const unsigned int i_dx = idof+x_ext_start;
2542 residual_derivatives[idof] = jac(i_dependent,i_dx);
2544 this->
dRdXv.add(soln_dof_indices_int[itest_int], metric_dof_indices_ext, residual_derivatives);
2547 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
2549 int i_dependent = n_soln_dofs_int + itest_ext;
2552 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2553 const unsigned int i_dx = idof+x_int_start;
2554 residual_derivatives[idof] = jac(i_dependent,i_dx);
2556 this->
dRdXv.add(soln_dof_indices_ext[itest_ext], metric_dof_indices_int, residual_derivatives);
2559 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2560 const unsigned int i_dx = idof+x_ext_start;
2561 residual_derivatives[idof] = jac(i_dependent,i_dx);
2563 this->
dRdXv.add(soln_dof_indices_ext[itest_ext], metric_dof_indices_ext, residual_derivatives);
2567 th.deleteJacobian(jac);
2571 typename TH::HessianType& hes = th.createHessian();
2572 th.evalHessian(hes);
2574 std::vector<real> dWidW(n_soln_dofs_int);
2575 std::vector<real> dWidX(n_metric_dofs);
2576 std::vector<real> dXidX(n_metric_dofs);
2578 int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs_int + n_soln_dofs_ext : 0;
2580 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
2582 const unsigned int i_dx = idof+w_int_start;
2585 for (
unsigned int jdof=0; jdof<n_soln_dofs_int; ++jdof) {
2586 const unsigned int j_dx = jdof+w_int_start;
2587 dWidW[jdof] = hes(i_dependent,i_dx,j_dx);
2589 this->
d2RdWdW.add(soln_dof_indices_int[idof], soln_dof_indices_int, dWidW);
2592 for (
unsigned int jdof=0; jdof<n_soln_dofs_ext; ++jdof) {
2593 const unsigned int j_dx = jdof+w_ext_start;
2594 dWidW[jdof] = hes(i_dependent,i_dx,j_dx);
2596 this->
d2RdWdW.add(soln_dof_indices_int[idof], soln_dof_indices_ext, dWidW);
2599 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2600 const unsigned int j_dx = jdof+x_int_start;
2601 dWidX[jdof] = hes(i_dependent,i_dx,j_dx);
2603 this->
d2RdWdX.add(soln_dof_indices_int[idof], metric_dof_indices_int, dWidX);
2606 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2607 const unsigned int j_dx = jdof+x_ext_start;
2608 dWidX[jdof] = hes(i_dependent,i_dx,j_dx);
2610 this->
d2RdWdX.add(soln_dof_indices_int[idof], metric_dof_indices_ext, dWidX);
2613 for (
unsigned int idof=0; idof<n_metric_dofs; ++idof) {
2615 const unsigned int i_dx = idof+x_int_start;
2618 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2619 const unsigned int j_dx = jdof+x_int_start;
2620 dXidX[jdof] = hes(i_dependent,i_dx,j_dx);
2622 this->
d2RdXdX.add(metric_dof_indices_int[idof], metric_dof_indices_int, dXidX);
2625 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2626 const unsigned int j_dx = jdof+x_ext_start;
2627 dXidX[jdof] = hes(i_dependent,i_dx,j_dx);
2629 this->
d2RdXdX.add(metric_dof_indices_int[idof], metric_dof_indices_ext, dXidX);
2632 dWidW.resize(n_soln_dofs_ext);
2634 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
2636 const unsigned int i_dx = idof+w_ext_start;
2639 for (
unsigned int jdof=0; jdof<n_soln_dofs_int; ++jdof) {
2640 const unsigned int j_dx = jdof+w_int_start;
2641 dWidW[jdof] = hes(i_dependent,i_dx,j_dx);
2643 this->
d2RdWdW.add(soln_dof_indices_ext[idof], soln_dof_indices_int, dWidW);
2646 for (
unsigned int jdof=0; jdof<n_soln_dofs_ext; ++jdof) {
2647 const unsigned int j_dx = jdof+w_ext_start;
2648 dWidW[jdof] = hes(i_dependent,i_dx,j_dx);
2650 this->
d2RdWdW.add(soln_dof_indices_ext[idof], soln_dof_indices_ext, dWidW);
2653 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2654 const unsigned int j_dx = jdof+x_int_start;
2655 dWidX[jdof] = hes(i_dependent,i_dx,j_dx);
2657 this->
d2RdWdX.add(soln_dof_indices_ext[idof], metric_dof_indices_int, dWidX);
2660 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2661 const unsigned int j_dx = jdof+x_ext_start;
2662 dWidX[jdof] = hes(i_dependent,i_dx,j_dx);
2664 this->
d2RdWdX.add(soln_dof_indices_ext[idof], metric_dof_indices_ext, dWidX);
2667 for (
unsigned int idof=0; idof<n_metric_dofs; ++idof) {
2669 const unsigned int i_dx = idof+x_ext_start;
2672 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2673 const unsigned int j_dx = jdof+x_int_start;
2674 dXidX[jdof] = hes(i_dependent,i_dx,j_dx);
2676 this->
d2RdXdX.add(metric_dof_indices_ext[idof], metric_dof_indices_int, dXidX);
2678 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
2679 const unsigned int j_dx = jdof+x_ext_start;
2680 dXidX[jdof] = hes(i_dependent,i_dx,j_dx);
2682 this->
d2RdXdX.add(metric_dof_indices_ext[idof], metric_dof_indices_ext, dXidX);
2685 th.deleteHessian(hes);
2688 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
2689 adtype::getGlobalTape().deactivateValue(soln_int.coefficients[idof]);
2691 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
2692 adtype::getGlobalTape().deactivateValue(soln_ext.
coefficients[idof]);
2694 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2695 adtype::getGlobalTape().deactivateValue(metric_int.
coefficients[idof]);
2697 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2698 adtype::getGlobalTape().deactivateValue(metric_ext.
coefficients[idof]);
2703 template <
int dim,
int nstate,
typename real,
typename MeshType>
2705 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
2706 const dealii::types::global_dof_index current_cell_index,
2707 const dealii::types::global_dof_index neighbor_cell_index,
2708 const std::pair<unsigned int, int> face_subface_int,
2709 const std::pair<unsigned int, int> face_subface_ext,
2710 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_int,
2711 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_ext,
2712 const dealii::FEFaceValuesBase<dim,dim> &fe_values_int,
2713 const dealii::FEFaceValuesBase<dim,dim> &fe_values_ext,
2715 const dealii::FESystem<dim,dim> &fe_int,
2716 const dealii::FESystem<dim,dim> &fe_ext,
2717 const dealii::Quadrature<dim-1> &face_quadrature,
2718 const std::vector<dealii::types::global_dof_index> &metric_dof_indices_int,
2719 const std::vector<dealii::types::global_dof_index> &metric_dof_indices_ext,
2720 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_int,
2721 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_ext,
2725 dealii::Vector<real> &local_rhs_int_cell,
2726 dealii::Vector<real> &local_rhs_ext_cell,
2727 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
2729 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
2730 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
2731 const unsigned int n_soln_dofs_int = fe_int.dofs_per_cell;
2732 const unsigned int n_soln_dofs_ext = fe_ext.dofs_per_cell;
2734 AssertDimension (n_soln_dofs_int, soln_dof_indices_int.size());
2735 AssertDimension (n_soln_dofs_ext, soln_dof_indices_ext.size());
2742 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
2743 const real val = this->
solution(soln_dof_indices_int[idof]);
2744 soln_int.coefficients[idof] = val;
2746 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
2747 const real val = this->
solution(soln_dof_indices_ext[idof]);
2750 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2751 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices_int[idof]];
2754 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
2755 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices_ext[idof]];
2759 std::vector<double> dual_int(n_soln_dofs_int);
2760 std::vector<double> dual_ext(n_soln_dofs_ext);
2762 for (
unsigned int itest=0; itest<n_soln_dofs_int; ++itest) {
2763 const unsigned int global_residual_row = soln_dof_indices_int[itest];
2764 dual_int[itest] = this->
dual[global_residual_row];
2766 for (
unsigned int itest=0; itest<n_soln_dofs_ext; ++itest) {
2767 const unsigned int global_residual_row = soln_dof_indices_ext[itest];
2768 dual_ext[itest] = this->
dual[global_residual_row];
2771 std::vector<real> rhs_int(n_soln_dofs_int);
2772 std::vector<real> rhs_ext(n_soln_dofs_ext);
2773 real dual_dot_residual;
2778 neighbor_cell_index,
2779 soln_int, soln_ext, metric_int, metric_ext,
2796 compute_dRdW, compute_dRdX, compute_d2R);
2798 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
2799 local_rhs_int_cell[itest_int] += getValue<real>(rhs_int[itest_int]);
2801 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
2802 local_rhs_ext_cell[itest_ext] += getValue<real>(rhs_ext[itest_ext]);
2808 template <
int dim,
int nstate,
typename real,
typename MeshType>
2809 template <
typename real2>
2811 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
2812 const dealii::types::global_dof_index current_cell_index,
2815 const std::vector<real> &local_dual,
2816 const dealii::Quadrature<dim> &quadrature,
2818 std::vector<real2> &rhs, real2 &dual_dot_residual,
2819 const bool compute_metric_derivatives,
2820 const dealii::FEValues<dim,dim> &fe_values_vol)
2822 (void) current_cell_index;
2823 using State = State<real2, nstate>;
2824 using DirectionalState = DirectionalState<real2, dim, nstate>;
2825 using Tensor2D = dealii::Tensor<2,dim,real2>;
2827 const unsigned int n_quad_pts = quadrature.size();
2828 const unsigned int n_soln_dofs = local_solution.
finite_element.dofs_per_cell;
2830 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
2833 dual_dot_residual = 0.0;
2835 const std::vector<dealii::Point<dim>> &points = quadrature.get_points ();
2837 const unsigned int n_metric_dofs = local_metric.
finite_element.dofs_per_cell;
2840 std::vector<Tensor2D> metric_jacobian;
2841 if (compute_metric_derivatives) metric_jacobian = evaluate_metric_jacobian ( points, local_metric);
2842 std::vector<real2> jac_det(n_quad_pts);
2843 std::vector<Tensor2D> jac_inv_tran(n_quad_pts);
2844 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2846 if (compute_metric_derivatives) {
2847 const real2 jacobian_determinant = dealii::determinant(metric_jacobian[iquad]);
2848 jac_det[iquad] = jacobian_determinant;
2850 const Tensor2D jacobian_transpose_inverse = dealii::transpose(dealii::invert(metric_jacobian[iquad]));
2851 jac_inv_tran[iquad] = jacobian_transpose_inverse;
2853 jac_det[iquad] = fe_values_vol.JxW(iquad) / quadrature.weight(iquad);
2856 #ifdef KOPRIVA_METRICS_VOL 2857 auto old_jac_inv_tran = jac_inv_tran;
2858 auto old_jac_det = jac_det;
2859 if constexpr (dim != 1) {
2860 evaluate_covariant_metric_jacobian<dim,real2> ( quadrature, local_metric, jac_inv_tran, jac_det);
2862 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2863 if (abs(old_jac_det[iquad] - jac_det[iquad])/abs(old_jac_det[iquad]) > 1e-10) {
2864 std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1);
2865 std::cout <<
"Not the same jac det, iquad " << iquad << std::endl;
2866 std::cout << old_jac_det[iquad] << std::endl;
2867 std::cout << jac_det[iquad] << std::endl;
2873 const std::vector<dealii::Point<dim,double>> &unit_quad_pts = quadrature.get_points();
2874 dealii::FullMatrix<real> interpolation_operator(n_soln_dofs,n_quad_pts);
2875 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
2876 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2877 interpolation_operator[idof][iquad] = local_solution.
finite_element.shape_value(idof,unit_quad_pts[iquad]);
2886 std::array<dealii::FullMatrix<real2>,dim> gradient_operator;
2887 for (
int d=0;d<dim;++d) {
2888 gradient_operator[d].reinit(dealii::TableIndices<2>(n_soln_dofs, n_quad_pts));
2890 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
2891 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2892 if (compute_metric_derivatives) {
2894 const dealii::Tensor<1,dim,real2> ref_shape_grad = local_solution.
finite_element.shape_grad(idof,points[iquad]);
2895 dealii::Tensor<1,dim,real2> phys_shape_grad;
2896 for (
int dr=0;dr<dim;++dr) {
2897 phys_shape_grad[dr] = 0.0;
2898 for (
int dc=0;dc<dim;++dc) {
2899 phys_shape_grad[dr] += jac_inv_tran[iquad][dr][dc] * ref_shape_grad[dc];
2902 for (
int d=0;d<dim;++d) {
2903 gradient_operator[d][idof][iquad] = phys_shape_grad[d];
2912 for (
int d=0;d<dim;++d) {
2913 const unsigned int istate = local_solution.
finite_element.system_to_component_index(idof).first;
2914 gradient_operator[d][idof][iquad] = fe_values_vol.shape_grad_component(idof, iquad, istate)[d];
2937 (void) artificial_diss_coeff;
2939 typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
2942 std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
2943 artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
2960 std::vector<real2> artificial_diss_coeff_at_q(n_quad_pts);
2962 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad)
2964 artificial_diss_coeff_at_q[iquad] = arti_diss;
2980 std::vector<State> soln_at_q(n_quad_pts);
2981 std::vector<DirectionalState> soln_grad_at_q(n_quad_pts);
2983 std::vector<DirectionalState> conv_phys_flux_at_q(n_quad_pts);
2984 std::vector<DirectionalState> diss_phys_flux_at_q(n_quad_pts);
2985 std::vector<State> source_at_q;
2986 std::vector<State> physical_source_at_q;
2988 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2989 for (
int istate=0; istate<
nstate; istate++) {
2990 soln_at_q[iquad][istate] = 0;
2991 soln_grad_at_q[iquad][istate] = 0;
2993 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
2994 const unsigned int istate = local_solution.
finite_element.system_to_component_index(idof).first;
2995 soln_at_q[iquad][istate] += local_solution.
coefficients[idof] * interpolation_operator[idof][iquad];
2996 for (
int d=0;d<dim;++d) {
2997 soln_grad_at_q[iquad][istate][d] += local_solution.
coefficients[idof] * gradient_operator[d][idof][iquad];
3000 conv_phys_flux_at_q[iquad] = physics.
convective_flux (soln_at_q[iquad]);
3001 diss_phys_flux_at_q[iquad] = physics.
dissipative_flux (soln_at_q[iquad], soln_grad_at_q[iquad], current_cell_index);
3004 physical_source_at_q.resize(n_quad_pts);
3005 dealii::Point<dim,real2> ad_points;
3006 for (
int d=0;d<dim;++d) { ad_points[d] = 0.0;}
3007 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
3008 const int iaxis = local_metric.
finite_element.system_to_component_index(idof).first;
3011 physical_source_at_q[iquad] = physics.
physical_source_term (ad_points, soln_at_q[iquad], soln_grad_at_q[iquad], current_cell_index);
3015 DirectionalState artificial_diss_phys_flux_at_q;
3017 artificial_diss_phys_flux_at_q = this->
artificial_dissip->calc_artificial_dissipation_flux(soln_at_q[iquad], soln_grad_at_q[iquad],artificial_diss_coeff_at_q[iquad]);
3018 for (
int s=0; s<
nstate; s++) {
3019 diss_phys_flux_at_q[iquad][s] += artificial_diss_phys_flux_at_q[s];
3024 source_at_q.resize(n_quad_pts);
3025 dealii::Point<dim,real2> ad_point;
3026 for (
int d=0;d<dim;++d) { ad_point[d] = 0.0;}
3027 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
3028 const int iaxis = local_metric.
finite_element.system_to_component_index(idof).first;
3031 source_at_q[iquad] = physics.
source_term (ad_point, soln_at_q[iquad], this->
current_time, current_cell_index);
3043 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3045 const unsigned int istate = local_solution.
finite_element.system_to_component_index(itest).first;
3047 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
3049 const real2 JxW_iquad = jac_det[iquad] * quadrature.weight(iquad);
3051 for (
int d=0;d<dim;++d) {
3053 rhs[itest] = rhs[itest] + gradient_operator[d][itest][iquad] * conv_phys_flux_at_q[iquad][istate][d] * JxW_iquad;
3056 rhs[itest] = rhs[itest] + gradient_operator[d][itest][iquad] * diss_phys_flux_at_q[iquad][istate][d] * JxW_iquad;
3060 rhs[itest] = rhs[itest] + interpolation_operator[itest][iquad]* physical_source_at_q[iquad][istate] * JxW_iquad;
3064 rhs[itest] = rhs[itest] + interpolation_operator[itest][iquad]* source_at_q[iquad][istate] * JxW_iquad;
3067 dual_dot_residual += local_dual[itest]*rhs[itest];
3072 template <
int dim,
int nstate,
typename real,
typename MeshType>
3074 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3075 const dealii::types::global_dof_index current_cell_index,
3076 const dealii::FEValues<dim,dim> &fe_values_vol,
3077 const dealii::FESystem<dim,dim> &fe_soln,
3078 const dealii::Quadrature<dim> &quadrature,
3079 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
3080 const std::vector<dealii::types::global_dof_index> &soln_dof_indices,
3081 dealii::Vector<real> &local_rhs_cell,
3082 const dealii::FEValues<dim,dim> &,
3083 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3085 (void) current_cell_index;
3087 using ADArray = std::array<FadFadType,nstate>;
3088 using ADArrayTensor1 = std::array< dealii::Tensor<1,dim,FadFadType>,
nstate >;
3090 const unsigned int n_soln_dofs = fe_soln.dofs_per_cell;
3092 AssertDimension (n_soln_dofs, soln_dof_indices.size());
3094 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
3095 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
3097 std::vector<FadFadType> coords_coeff(n_metric_dofs);
3098 std::vector<FadFadType> soln_coeff(n_soln_dofs);
3100 std::vector<real> local_dual(n_soln_dofs);
3101 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3102 const unsigned int global_residual_row = soln_dof_indices[itest];
3103 local_dual[itest] = this->
dual[global_residual_row];
3106 (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R;
3107 const bool compute_metric_derivatives =
true;
3109 unsigned int w_start, w_end, x_start, x_end;
3110 automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R,
3111 n_soln_dofs, n_metric_dofs,
3112 w_start, w_end, x_start, x_end );
3114 unsigned int i_derivative = 0;
3115 const unsigned int n_total_indep = x_end;
3117 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
3118 const real val = this->
solution(soln_dof_indices[idof]);
3119 soln_coeff[idof] = val;
3120 soln_coeff[idof].val() = val;
3122 if (compute_dRdW || compute_d2R) soln_coeff[idof].diff(i_derivative, n_total_indep);
3123 if (compute_d2R) soln_coeff[idof].val().diff(i_derivative, n_total_indep);
3125 if (compute_dRdW || compute_d2R) i_derivative++;
3127 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
3128 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices[idof]];
3129 coords_coeff[idof] = val;
3130 coords_coeff[idof].val() = val;
3132 if (compute_dRdX || compute_d2R) coords_coeff[idof].diff(i_derivative, n_total_indep);
3133 if (compute_d2R) coords_coeff[idof].val().diff(i_derivative, n_total_indep);
3135 if (compute_dRdX || compute_d2R) i_derivative++;
3138 AssertDimension(i_derivative, n_total_indep);
3141 std::vector<FadFadType> rhs(n_soln_dofs);
3142 assemble_volume_term<FadFadType>(
3145 soln_coeff, coords_coeff, local_dual,
3146 fe_soln, fe_metric, quadrature,
3148 rhs, dual_dot_residual,
3149 compute_metric_derivatives, fe_values_vol);
3159 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3162 std::vector<real> residual_derivatives(n_soln_dofs);
3163 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
3164 const unsigned int i_dx = idof+w_start;
3165 residual_derivatives[idof] = rhs[itest].dx(i_dx).val();
3166 AssertIsFinite(residual_derivatives[idof]);
3168 const bool elide_zero_values =
false;
3169 this->
system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives, elide_zero_values);
3172 std::vector<real> residual_derivatives(n_metric_dofs);
3173 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
3174 const unsigned int i_dx = idof+x_start;
3175 residual_derivatives[idof] = rhs[itest].dx(i_dx).val();
3177 this->
dRdXv.add(soln_dof_indices[itest], metric_dof_indices, residual_derivatives);
3184 local_rhs_cell(itest) += rhs[itest].val().val();
3185 AssertIsFinite(local_rhs_cell(itest));
3192 std::vector<real> dWidW(n_soln_dofs);
3193 std::vector<real> dWidX(n_metric_dofs);
3194 std::vector<real> dXidX(n_metric_dofs);
3196 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
3198 const unsigned int i_dx = idof+w_start;
3199 const FadType dWi = dual_dot_residual.dx(i_dx);
3201 for (
unsigned int jdof=0; jdof<n_soln_dofs; ++jdof) {
3202 const unsigned int j_dx = jdof+w_start;
3203 dWidW[jdof] = dWi.dx(j_dx);
3205 this->
d2RdWdW.add(soln_dof_indices[idof], soln_dof_indices, dWidW);
3207 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
3208 const unsigned int j_dx = jdof+x_start;
3209 dWidX[jdof] = dWi.dx(j_dx);
3211 this->
d2RdWdX.add(soln_dof_indices[idof], metric_dof_indices, dWidX);
3214 for (
unsigned int idof=0; idof<n_metric_dofs; ++idof) {
3216 const unsigned int i_dx = idof+x_start;
3217 const FadType dXi = dual_dot_residual.dx(i_dx);
3219 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
3220 const unsigned int j_dx = jdof+x_start;
3221 dXidX[jdof] = dXi.dx(j_dx);
3223 this->
d2RdXdX.add(metric_dof_indices[idof], metric_dof_indices, dXidX);
3230 template <
int dim,
int nstate,
typename real,
typename MeshType>
3231 template <
typename real2>
3233 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3234 const dealii::types::global_dof_index current_cell_index,
3235 const dealii::FEValues<dim,dim> &fe_values_vol,
3236 const dealii::FESystem<dim,dim> &fe_soln,
3237 const dealii::Quadrature<dim> &quadrature,
3238 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
3239 const std::vector<dealii::types::global_dof_index> &soln_dof_indices,
3240 dealii::Vector<real> &local_rhs_cell,
3241 const dealii::FEValues<dim,dim> &fe_values_lagrange,
3243 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3245 (void) fe_values_lagrange;
3247 using adtype = real2;
3249 const unsigned int n_soln_dofs = fe_soln.dofs_per_cell;
3251 AssertDimension (n_soln_dofs, soln_dof_indices.size());
3253 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
3254 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
3259 std::vector<real> local_dual(n_soln_dofs);
3260 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3261 const unsigned int global_residual_row = soln_dof_indices[itest];
3262 local_dual[itest] = this->
dual[global_residual_row];
3265 (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R;
3266 const bool compute_metric_derivatives =
true;
3268 unsigned int w_start, w_end, x_start, x_end;
3269 automatic_differentiation_indexing_1( compute_dRdW, compute_dRdX, compute_d2R,
3270 n_soln_dofs, n_metric_dofs,
3271 w_start, w_end, x_start, x_end );
3273 using TH = codi::TapeHelper<adtype>;
3275 adtype::getGlobalTape();
3276 if (compute_dRdW || compute_dRdX || compute_d2R) {
3277 th.startRecording();
3279 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
3280 const real val = this->
solution(soln_dof_indices[idof]);
3283 if (compute_dRdW || compute_d2R) {
3286 adtype::getGlobalTape().deactivateValue(local_solution.
coefficients[idof]);
3289 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
3290 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices[idof]];
3293 if (compute_dRdX || compute_d2R) {
3296 adtype::getGlobalTape().deactivateValue(local_metric.
coefficients[idof]);
3300 adtype dual_dot_residual = 0.0;
3301 std::vector<adtype> rhs(n_soln_dofs);
3302 assemble_volume_term<adtype>(
3305 local_solution, local_metric,
3309 rhs, dual_dot_residual,
3310 compute_metric_derivatives, fe_values_vol);
3312 if (compute_dRdW || compute_dRdX) {
3313 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3314 th.registerOutput(rhs[itest]);
3316 }
else if (compute_d2R) {
3317 th.registerOutput(dual_dot_residual);
3319 if (compute_dRdW || compute_dRdX || compute_d2R) {
3323 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3324 local_rhs_cell(itest) += getValue<adtype>(rhs[itest]);
3325 AssertIsFinite(local_rhs_cell(itest));
3329 typename TH::JacobianType& jac = th.createJacobian();
3330 th.evalJacobian(jac);
3331 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3333 std::vector<real> residual_derivatives(n_soln_dofs);
3334 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
3335 const unsigned int i_dx = idof+w_start;
3336 residual_derivatives[idof] = jac(itest,i_dx);
3337 AssertIsFinite(residual_derivatives[idof]);
3339 const bool elide_zero_values =
false;
3340 this->
system_matrix.add(soln_dof_indices[itest], soln_dof_indices, residual_derivatives, elide_zero_values);
3342 th.deleteJacobian(jac);
3347 typename TH::JacobianType& jac = th.createJacobian();
3348 th.evalJacobian(jac);
3349 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3350 std::vector<real> residual_derivatives(n_metric_dofs);
3351 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
3352 const unsigned int i_dx = idof+x_start;
3353 residual_derivatives[idof] = jac(itest,i_dx);
3355 this->
dRdXv.add(soln_dof_indices[itest], metric_dof_indices, residual_derivatives);
3357 th.deleteJacobian(jac);
3362 typename TH::HessianType& hes = th.createHessian();
3363 th.evalHessian(hes);
3365 int i_dependent = (compute_dRdW || compute_dRdX) ? n_soln_dofs : 0;
3367 std::vector<real> dWidW(n_soln_dofs);
3368 std::vector<real> dWidX(n_metric_dofs);
3369 std::vector<real> dXidX(n_metric_dofs);
3371 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
3373 const unsigned int i_dx = idof+w_start;
3375 for (
unsigned int jdof=0; jdof<n_soln_dofs; ++jdof) {
3376 const unsigned int j_dx = jdof+w_start;
3377 dWidW[jdof] = hes(i_dependent,i_dx,j_dx);
3379 this->
d2RdWdW.add(soln_dof_indices[idof], soln_dof_indices, dWidW);
3381 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
3382 const unsigned int j_dx = jdof+x_start;
3383 dWidX[jdof] = hes(i_dependent,i_dx,j_dx);
3385 this->
d2RdWdX.add(soln_dof_indices[idof], metric_dof_indices, dWidX);
3388 for (
unsigned int idof=0; idof<n_metric_dofs; ++idof) {
3390 const unsigned int i_dx = idof+x_start;
3392 for (
unsigned int jdof=0; jdof<n_metric_dofs; ++jdof) {
3393 const unsigned int j_dx = jdof+x_start;
3394 dXidX[jdof] = hes(i_dependent,i_dx,j_dx);
3396 this->
d2RdXdX.add(metric_dof_indices[idof], metric_dof_indices, dXidX);
3399 th.deleteHessian(hes);
3402 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
3403 adtype::getGlobalTape().deactivateValue(local_solution.coefficients[idof]);
3405 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
3406 adtype::getGlobalTape().deactivateValue(local_metric.coefficients[idof]);
3411 template <
int dim,
int nstate,
typename real,
typename MeshType>
3413 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3414 const dealii::types::global_dof_index current_cell_index,
3415 const dealii::FEValues<dim,dim> &fe_values_vol,
3416 const dealii::FESystem<dim,dim> &fe_soln,
3417 const dealii::Quadrature<dim> &quadrature,
3418 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
3419 const std::vector<dealii::types::global_dof_index> &soln_dof_indices,
3420 dealii::Vector<real> &local_rhs_cell,
3421 const dealii::FEValues<dim,dim> &fe_values_lagrange,
3423 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3425 (void) fe_values_lagrange;
3426 (void) compute_dRdW;
3427 (void) compute_dRdX;
3429 assert( !compute_dRdW && !compute_dRdX && !compute_d2R);
3430 (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R;
3431 const bool compute_metric_derivatives =
true;
3433 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
3434 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
3435 const unsigned int n_soln_dofs = fe_soln.dofs_per_cell;
3437 AssertDimension (n_soln_dofs, soln_dof_indices.size());
3442 std::vector<real> local_dual(n_soln_dofs);
3443 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3444 const unsigned int global_residual_row = soln_dof_indices[itest];
3445 local_dual[itest] = this->
dual[global_residual_row];
3448 for (
unsigned int idof = 0; idof < n_soln_dofs; ++idof) {
3449 const real val = this->
solution(soln_dof_indices[idof]);
3450 local_solution.coefficients[idof] = val;
3452 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
3453 const real val = this->
high_order_grid->volume_nodes[metric_dof_indices[idof]];
3457 double dual_dot_residual = 0.0;
3458 std::vector<double> rhs(n_soln_dofs);
3459 assemble_volume_term<double>(
3462 local_solution, local_metric, local_dual,
3465 rhs, dual_dot_residual,
3466 compute_metric_derivatives, fe_values_vol);
3468 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
3469 local_rhs_cell(itest) += getValue<double>(rhs[itest]);
3470 AssertIsFinite(local_rhs_cell(itest));
3474 template <
int dim,
int nstate,
typename real,
typename MeshType>
3476 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3477 const dealii::types::global_dof_index current_cell_index,
3478 const dealii::FEValues<dim,dim> &fe_values_vol,
3479 const dealii::FESystem<dim,dim> &fe_soln,
3480 const dealii::Quadrature<dim> &quadrature,
3481 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
3482 const std::vector<dealii::types::global_dof_index> &soln_dof_indices,
3483 dealii::Vector<real> &local_rhs_cell,
3484 const dealii::FEValues<dim,dim> &fe_values_lagrange,
3485 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3487 (void) current_cell_index;
3488 (void) fe_values_lagrange;
3490 assemble_volume_codi_taped_derivatives<codi_HessianComputationType>(
3494 fe_soln, quadrature,
3495 metric_dof_indices, soln_dof_indices,
3499 compute_dRdW, compute_dRdX, compute_d2R);
3500 }
else if (compute_dRdW || compute_dRdX) {
3501 assemble_volume_codi_taped_derivatives<codi_JacobianComputationType>(
3505 fe_soln, quadrature,
3506 metric_dof_indices, soln_dof_indices,
3510 compute_dRdW, compute_dRdX, compute_d2R);
3516 fe_soln, quadrature,
3517 metric_dof_indices, soln_dof_indices,
3521 compute_dRdW, compute_dRdX, compute_d2R);
3525 template <
int dim,
int nstate,
typename real,
typename MeshType>
3527 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3528 const dealii::types::global_dof_index current_cell_index,
3529 const dealii::types::global_dof_index neighbor_cell_index,
3530 const std::pair<unsigned int, int> face_subface_int,
3531 const std::pair<unsigned int, int> face_subface_ext,
3532 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_int,
3533 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_ext,
3534 const dealii::FEFaceValuesBase<dim,dim> &fe_values_int,
3535 const dealii::FEFaceValuesBase<dim,dim> &fe_values_ext,
3537 const dealii::FESystem<dim,dim> &fe_int,
3538 const dealii::FESystem<dim,dim> &fe_ext,
3539 const dealii::Quadrature<dim-1> &face_quadrature,
3540 const std::vector<dealii::types::global_dof_index> &metric_dof_indices_int,
3541 const std::vector<dealii::types::global_dof_index> &metric_dof_indices_ext,
3542 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_int,
3543 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_ext,
3544 dealii::Vector<real> &local_rhs_int_cell,
3545 dealii::Vector<real> &local_rhs_ext_cell,
3546 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3548 (void) current_cell_index;
3549 (void) neighbor_cell_index;
3551 assemble_face_codi_taped_derivatives<codi_HessianComputationType>(
3554 neighbor_cell_index,
3565 metric_dof_indices_int,
3566 metric_dof_indices_ext,
3567 soln_dof_indices_int,
3568 soln_dof_indices_ext,
3574 compute_dRdW, compute_dRdX, compute_d2R);
3575 }
else if (compute_dRdW || compute_dRdX) {
3576 assemble_face_codi_taped_derivatives<codi_JacobianComputationType>(
3579 neighbor_cell_index,
3590 metric_dof_indices_int,
3591 metric_dof_indices_ext,
3592 soln_dof_indices_int,
3593 soln_dof_indices_ext,
3599 compute_dRdW, compute_dRdX, compute_d2R);
3604 neighbor_cell_index,
3615 metric_dof_indices_int,
3616 metric_dof_indices_ext,
3617 soln_dof_indices_int,
3618 soln_dof_indices_ext,
3624 compute_dRdW, compute_dRdX, compute_d2R);
3630 template <
int dim,
int nstate,
typename real,
typename MeshType>
3632 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3633 const dealii::types::global_dof_index current_cell_index,
3634 const std::vector<dealii::types::global_dof_index> &cell_dofs_indices,
3635 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
3636 const unsigned int poly_degree,
3637 const unsigned int grid_degree,
3645 std::array<std::vector<real>,dim> &,
3646 dealii::hp::FEValues<dim,dim> &fe_values_collection_volume,
3647 dealii::hp::FEValues<dim,dim> &fe_values_collection_volume_lagrange,
3648 const dealii::FESystem<dim,dim> ¤t_fe_ref,
3649 dealii::Vector<real> &local_rhs_int_cell,
3650 std::vector<dealii::Tensor<1,dim,real>> &,
3652 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3655 const int i_fele = cell->active_fe_index();
3656 const int i_quad = i_fele;
3657 const int i_mapp = 0;
3658 fe_values_collection_volume.reinit (cell, i_quad, i_mapp, i_fele);
3659 dealii::TriaIterator<dealii::CellAccessor<dim,dim>> cell_iterator =
static_cast<dealii::TriaIterator<dealii::CellAccessor<dim,dim>
> > (cell);
3660 fe_values_collection_volume_lagrange.reinit (cell_iterator, i_quad, i_mapp, i_fele);
3662 const dealii::FEValues<dim,dim> &fe_values_volume = fe_values_collection_volume.get_present_fe_values();
3663 const dealii::FEValues<dim,dim> &fe_values_lagrange = fe_values_collection_volume_lagrange.get_present_fe_values();
3671 poly_degree, grid_degree,
3673 fe_values_lagrange);
3675 local_rhs_int_cell*=0.0;
3681 metric_dof_indices, cell_dofs_indices,
3682 local_rhs_int_cell, fe_values_lagrange,
3683 compute_dRdW, compute_dRdX, compute_d2R);
3686 template <
int dim,
int nstate,
typename real,
typename MeshType>
3688 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3689 const dealii::types::global_dof_index current_cell_index,
3690 const unsigned int iface,
3691 const unsigned int boundary_id,
3693 const std::vector<dealii::types::global_dof_index> &cell_dofs_indices,
3694 const std::vector<dealii::types::global_dof_index> &metric_dof_indices,
3695 const unsigned int ,
3696 const unsigned int ,
3704 std::array<std::vector<real>,dim> &,
3705 dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_int,
3706 const dealii::FESystem<dim,dim> ¤t_fe_ref,
3707 dealii::Vector<real> &local_rhs_int_cell,
3708 std::vector<dealii::Tensor<1,dim,real>> &,
3710 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3713 const int i_fele = cell->active_fe_index();
3714 const int i_quad = i_fele;
3715 const int i_mapp = 0;
3717 fe_values_collection_face_int.reinit (cell, iface, i_quad, i_mapp, i_fele);
3718 const dealii::FEFaceValues<dim,dim> &fe_values_face_int = fe_values_collection_face_int.get_present_fe_values();
3723 iface, boundary_id, fe_values_face_int, penalty,
3724 current_fe_ref, face_quadrature,
3725 metric_dof_indices, cell_dofs_indices, local_rhs_int_cell,
3726 compute_dRdW, compute_dRdX, compute_d2R);
3729 template <
int dim,
int nstate,
typename real,
typename MeshType>
3731 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3732 typename dealii::DoFHandler<dim>::active_cell_iterator neighbor_cell,
3733 const dealii::types::global_dof_index current_cell_index,
3734 const dealii::types::global_dof_index neighbor_cell_index,
3735 const unsigned int iface,
3736 const unsigned int neighbor_iface,
3738 const std::vector<dealii::types::global_dof_index> ¤t_dofs_indices,
3739 const std::vector<dealii::types::global_dof_index> &neighbor_dofs_indices,
3740 const std::vector<dealii::types::global_dof_index> ¤t_metric_dofs_indices,
3741 const std::vector<dealii::types::global_dof_index> &neighbor_metric_dofs_indices,
3742 const unsigned int ,
3743 const unsigned int ,
3744 const unsigned int ,
3745 const unsigned int ,
3756 std::array<std::vector<real>,dim> &,
3757 dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_int,
3758 dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_ext,
3759 dealii::Vector<real> ¤t_cell_rhs,
3760 dealii::Vector<real> &neighbor_cell_rhs,
3761 std::vector<dealii::Tensor<1,dim,real>> &,
3762 dealii::LinearAlgebra::distributed::Vector<double> &rhs,
3763 std::array<dealii::LinearAlgebra::distributed::Vector<double>,dim> &,
3765 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3768 const int i_fele = cell->active_fe_index();
3769 const int i_quad = i_fele;
3770 const int i_mapp = 0;
3771 const int i_fele_n = neighbor_cell->active_fe_index(), i_quad_n = i_fele_n, i_mapp_n = 0;
3773 fe_values_collection_face_int.reinit (cell, iface, i_quad, i_mapp, i_fele);
3774 fe_values_collection_face_ext.reinit (neighbor_cell, neighbor_iface, i_quad_n, i_mapp_n, i_fele_n);
3777 const dealii::FEFaceValues<dim,dim> &fe_values_face_int = fe_values_collection_face_int.get_present_fe_values();
3778 const dealii::FEFaceValues<dim,dim> &fe_values_face_ext = fe_values_collection_face_ext.get_present_fe_values();
3779 const dealii::Quadrature<dim-1> &used_face_quadrature = this->
face_quadrature_collection[(i_quad_n > i_quad) ? i_quad_n : i_quad];
3781 std::pair<unsigned int, int> face_subface_int = std::make_pair(iface, -1);
3782 std::pair<unsigned int, int> face_subface_ext = std::make_pair(neighbor_iface, -1);
3783 const auto face_data_set_int = dealii::QProjector<dim>::DataSetDescriptor::face (
3784 dealii::ReferenceCell::get_hypercube(dim),
3786 cell->face_orientation(iface),
3787 cell->face_flip(iface),
3788 cell->face_rotation(iface),
3789 used_face_quadrature.size());
3790 const auto face_data_set_ext = dealii::QProjector<dim>::DataSetDescriptor::face (
3791 dealii::ReferenceCell::get_hypercube(dim),
3793 neighbor_cell->face_orientation(neighbor_iface),
3794 neighbor_cell->face_flip(neighbor_iface),
3795 neighbor_cell->face_rotation(neighbor_iface),
3796 used_face_quadrature.size());
3801 neighbor_cell_index,
3802 face_subface_int, face_subface_ext,
3805 fe_values_face_int, fe_values_face_ext,
3808 used_face_quadrature,
3809 current_metric_dofs_indices, neighbor_metric_dofs_indices,
3810 current_dofs_indices, neighbor_dofs_indices,
3811 current_cell_rhs, neighbor_cell_rhs,
3812 compute_dRdW, compute_dRdX, compute_d2R);
3815 const unsigned int n_dofs_neigh_cell = this->
fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell();
3816 for (
unsigned int i=0; i<n_dofs_neigh_cell; ++i) {
3817 rhs[neighbor_dofs_indices[i]] += neighbor_cell_rhs[i];
3821 template <
int dim,
int nstate,
typename real,
typename MeshType>
3823 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
3824 typename dealii::DoFHandler<dim>::active_cell_iterator neighbor_cell,
3825 const dealii::types::global_dof_index current_cell_index,
3826 const dealii::types::global_dof_index neighbor_cell_index,
3827 const unsigned int iface,
3828 const unsigned int neighbor_iface,
3829 const unsigned int neighbor_i_subface,
3831 const std::vector<dealii::types::global_dof_index> ¤t_dofs_indices,
3832 const std::vector<dealii::types::global_dof_index> &neighbor_dofs_indices,
3833 const std::vector<dealii::types::global_dof_index> ¤t_metric_dofs_indices,
3834 const std::vector<dealii::types::global_dof_index> &neighbor_metric_dofs_indices,
3835 const unsigned int ,
3836 const unsigned int ,
3837 const unsigned int ,
3838 const unsigned int ,
3849 std::array<std::vector<real>,dim> &,
3850 dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_int,
3851 dealii::hp::FESubfaceValues<dim,dim> &fe_values_collection_subface,
3852 dealii::Vector<real> ¤t_cell_rhs,
3853 dealii::Vector<real> &neighbor_cell_rhs,
3854 std::vector<dealii::Tensor<1,dim,real>> &,
3855 dealii::LinearAlgebra::distributed::Vector<double> &rhs,
3856 std::array<dealii::LinearAlgebra::distributed::Vector<double>,dim> &,
3858 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
3861 const int i_fele = cell->active_fe_index();
3862 const int i_quad = i_fele;
3863 const int i_mapp = 0;
3864 const int i_fele_n = neighbor_cell->active_fe_index(), i_quad_n = i_fele_n, i_mapp_n = 0;
3866 fe_values_collection_face_int.reinit (cell, iface, i_quad, i_mapp, i_fele);
3867 fe_values_collection_subface.reinit (neighbor_cell, neighbor_iface, neighbor_i_subface, i_quad_n, i_mapp_n, i_fele_n);
3869 const dealii::FEFaceValues<dim,dim> &fe_values_face_int = fe_values_collection_face_int.get_present_fe_values();
3870 const dealii::FESubfaceValues<dim,dim> &fe_values_face_ext = fe_values_collection_subface.get_present_fe_values();
3871 const dealii::Quadrature<dim-1> &used_face_quadrature = this->
face_quadrature_collection[(i_quad_n > i_quad) ? i_quad_n : i_quad];
3872 std::pair<unsigned int, int> face_subface_int = std::make_pair(iface, -1);
3873 std::pair<unsigned int, int> face_subface_ext = std::make_pair(neighbor_iface, (
int)neighbor_i_subface);
3875 const auto face_data_set_int = dealii::QProjector<dim>::DataSetDescriptor::face(
3876 dealii::ReferenceCell::get_hypercube(dim),
3878 cell->face_orientation(iface),
3879 cell->face_flip(iface),
3880 cell->face_rotation(iface),
3881 used_face_quadrature.size());
3882 const auto face_data_set_ext = dealii::QProjector<dim>::DataSetDescriptor::subface (
3883 dealii::ReferenceCell::get_hypercube(dim),
3886 neighbor_cell->face_orientation(neighbor_iface),
3887 neighbor_cell->face_flip(neighbor_iface),
3888 neighbor_cell->face_rotation(neighbor_iface),
3889 used_face_quadrature.size(),
3890 neighbor_cell->subface_case(neighbor_iface));
3895 neighbor_cell_index,
3896 face_subface_int, face_subface_ext,
3899 fe_values_face_int, fe_values_face_ext,
3902 used_face_quadrature,
3903 current_metric_dofs_indices, neighbor_metric_dofs_indices,
3904 current_dofs_indices, neighbor_dofs_indices,
3905 current_cell_rhs, neighbor_cell_rhs,
3906 compute_dRdW, compute_dRdX, compute_d2R);
3909 const unsigned int n_dofs_neigh_cell = this->
fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell();
3910 for (
unsigned int i=0; i<n_dofs_neigh_cell; ++i) {
3911 rhs[neighbor_dofs_indices[i]] += neighbor_cell_rhs[i];
3916 template <
int dim,
int nstate,
typename real,
typename MeshType>
3922 template <
int dim,
int nstate,
typename real,
typename MeshType>
real2 discontinuity_sensor(const dealii::Quadrature< dim > &volume_quadrature, const std::vector< real2 > &soln_coeff_high, const dealii::FiniteElement< dim, dim > &fe_high, const std::vector< real2 > &jac_det)
void assemble_face_term_derivatives(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const std::pair< unsigned int, int > face_subface_int, const std::pair< unsigned int, int > face_subface_ext, const typename dealii::QProjector< dim >::DataSetDescriptor face_data_set_int, const typename dealii::QProjector< dim >::DataSetDescriptor face_data_set_ext, const dealii::FEFaceValuesBase< dim, dim > &, const dealii::FEFaceValuesBase< dim, dim > &, const real penalty, const dealii::FESystem< dim, dim > &fe_int, const dealii::FESystem< dim, dim > &fe_ext, const dealii::Quadrature< dim-1 > &face_quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices_int, const std::vector< dealii::types::global_dof_index > &metric_dof_indices_ext, const std::vector< dealii::types::global_dof_index > &soln_dof_indices_int, const std::vector< dealii::types::global_dof_index > &soln_dof_indices_ext, dealii::Vector< real > &local_rhs_int_cell, dealii::Vector< real > &local_rhs_ext_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Evaluate the integral over the internal cell edges and its specified derivatives. ...
dealii::Vector< double > artificial_dissipation_coeffs
Artificial dissipation in each cell.
Sacado::Fad::DFad< FadType > FadFadType
Sacado AD type that allows 2nd derivatives.
dealii::LinearAlgebra::distributed::Vector< double > artificial_dissipation_c0
Artificial dissipation coefficients.
virtual std::array< real, nstate > evaluate_solution_flux(const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const dealii::Tensor< 1, dim, real > &normal_int) const =0
Solution flux at the interface.
Sacado::Fad::DFad< double > FadType
Sacado AD type for first derivatives.
dealii::TrilinosWrappers::SparseMatrix dRdXv
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
dealii::LinearAlgebra::distributed::Vector< real > dual
Current optimization dual variables corresponding to the residual constraints also known as the adjoi...
Class to store local solution coefficients and provide evaluation functions.
double matching_surface_jac_det_tolerance
std::shared_ptr< Triangulation > triangulation
Mesh.
Base class of numerical flux associated with dissipation.
Files for the baseline physics.
ManufacturedSolutionParam manufactured_solution_param
Associated manufactured solution parameters.
void assemble_boundary_term(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const LocalSolution< real2, dim, nstate > &local_solution, const LocalSolution< real2, dim, dim > &local_metric, const std::vector< real > &local_dual, const unsigned int face_number, const unsigned int boundary_id, const Physics::PhysicsBase< dim, nstate, real2 > &physics, const NumericalFlux::NumericalFluxConvective< dim, nstate, real2 > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nstate, real2 > &diss_num_flux, const dealii::FEFaceValuesBase< dim, dim > &fe_values_boundary, const real penalty, const dealii::Quadrature< dim-1 > &quadrature, std::vector< real2 > &rhs, real2 &dual_dot_residual, const bool compute_metric_derivatives)
Main function responsible for evaluating the boundary integral and the specified derivatives.
virtual void boundary_face_values(const int, const dealii::Point< dim, real > &, const dealii::Tensor< 1, dim, real > &, const std::array< real, nstate > &, const std::array< dealii::Tensor< 1, dim, real >, nstate > &, std::array< real, nstate > &, std::array< dealii::Tensor< 1, dim, real >, nstate > &) const =0
Evaluates boundary values and gradients on the other side of the face.
DGWeak class templated on the number of state variables.
dealii::TrilinosWrappers::SparseMatrix d2RdWdW
MPI_Comm mpi_communicator
MPI communicator.
dealii::Vector< double > max_dt_cell
Time it takes for the maximum wavespeed to cross the cell domain.
Main parameter class that contains the various other sub-parameter classes.
std::vector< std::array< real, n_components > > evaluate_values(const std::vector< dealii::Point< dim >> &unit_points) const
Obtain values at unit points.
void assemble_auxiliary_residual()
Assembles the auxiliary equations' residuals and solves for the auxiliary variables.
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution.
virtual void assemble_volume_term_derivatives(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const dealii::FEValues< dim, dim > &, const dealii::FESystem< dim, dim > &fe, const dealii::Quadrature< dim > &quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const std::vector< dealii::types::global_dof_index > &soln_dof_indices, dealii::Vector< real > &local_rhs_cell, const dealii::FEValues< dim, dim > &, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Evaluate the integral over the cell volume and the specified derivatives.
ManufacturedConvergenceStudyParam manufactured_convergence_study_param
Contains parameters for manufactured convergence study.
void allocate_dual_vector()
Allocate the dual vector for optimization.
const int nstate
Number of state variables.
dealii::DoFHandler< dim > dof_handler_artificial_dissipation
Degrees of freedom handler for C0 artificial dissipation.
void assemble_face_residual(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const std::pair< unsigned int, int > face_subface_int, const std::pair< unsigned int, int > face_subface_ext, const typename dealii::QProjector< dim >::DataSetDescriptor face_data_set_int, const typename dealii::QProjector< dim >::DataSetDescriptor face_data_set_ext, const dealii::FEFaceValuesBase< dim, dim > &, const dealii::FEFaceValuesBase< dim, dim > &, const real penalty, const dealii::FESystem< dim, dim > &fe_int, const dealii::FESystem< dim, dim > &fe_ext, const dealii::Quadrature< dim-1 > &face_quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices_int, const std::vector< dealii::types::global_dof_index > &metric_dof_indices_ext, const std::vector< dealii::types::global_dof_index > &soln_dof_indices_int, const std::vector< dealii::types::global_dof_index > &soln_dof_indices_ext, const Physics::PhysicsBase< dim, nstate, real > &physics, const NumericalFlux::NumericalFluxConvective< dim, nstate, real > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nstate, real > &diss_num_flux, dealii::Vector< real > &local_rhs_int_cell, dealii::Vector< real > &local_rhs_ext_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Evaluate the integral over the internal face.
void assemble_volume_term_and_build_operators(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const std::vector< dealii::types::global_dof_index > &cell_dofs_indices, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const unsigned int poly_degree, const unsigned int grid_degree, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &, OPERATOR::metric_operators< real, dim, 2 *dim > &, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &, std::array< std::vector< real >, dim > &, dealii::hp::FEValues< dim, dim > &fe_values_collection_volume, dealii::hp::FEValues< dim, dim > &fe_values_collection_volume_lagrange, const dealii::FESystem< dim, dim > ¤t_fe_ref, dealii::Vector< real > &local_rhs_int_cell, std::vector< dealii::Tensor< 1, dim, real >> &, const bool, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Builds the necessary fe values and assembles volume residual.
dealii::IndexSet locally_owned_dofs
Locally own degrees of freedom.
DissipativeNumericalFlux
Possible dissipative numerical flux types.
dealii::hp::QCollection< dim-1 > face_quadrature_collection
Quadrature used to evaluate face integrals.
virtual std::array< dealii::Tensor< 1, dim, real >, nstate > convective_flux(const std::array< real, nstate > &solution) const =0
Convective fluxes that will be differentiated once in space.
virtual std::array< real, nstate > evaluate_auxiliary_flux(const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const real artificial_diss_coeff_int, const real artificial_diss_coeff_ext, const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_int, const std::array< dealii::Tensor< 1, dim, real >, nstate > &soln_grad_ext, const dealii::Tensor< 1, dim, real > &normal_int, const real &penalty, const bool on_boundary=false) const =0
Auxiliary flux at the interface.
std::vector< std::array< dealii::Tensor< 1, dim, real >, n_components > > evaluate_reference_gradients(const std::vector< dealii::Point< dim >> &unit_points) const
Base metric operators class that stores functions used in both the volume and on surface.
void assemble_volume_term(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const LocalSolution< real2, dim, nstate > &local_solution, const LocalSolution< real2, dim, dim > &local_metric, const std::vector< real > &local_dual, const dealii::Quadrature< dim > &quadrature, const Physics::PhysicsBase< dim, nstate, real2 > &physics, std::vector< real2 > &rhs, real2 &dual_dot_residual, const bool compute_metric_derivatives, const dealii::FEValues< dim, dim > &fe_values_vol)
Main function responsible for evaluating the integral over the cell volume and the specified derivati...
real current_time
The current time set in set_current_time()
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
void assemble_face_codi_taped_derivatives(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const std::pair< unsigned int, int > face_subface_int, const std::pair< unsigned int, int > face_subface_ext, const typename dealii::QProjector< dim >::DataSetDescriptor face_data_set_int, const typename dealii::QProjector< dim >::DataSetDescriptor face_data_set_ext, const dealii::FEFaceValuesBase< dim, dim > &, const dealii::FEFaceValuesBase< dim, dim > &, const real penalty, const dealii::FESystem< dim, dim > &fe_int, const dealii::FESystem< dim, dim > &fe_ext, const dealii::Quadrature< dim-1 > &face_quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices_int, const std::vector< dealii::types::global_dof_index > &metric_dof_indices_ext, const std::vector< dealii::types::global_dof_index > &soln_dof_indices_int, const std::vector< dealii::types::global_dof_index > &soln_dof_indices_ext, const Physics::PhysicsBase< dim, nstate, adtype > &physics, const NumericalFlux::NumericalFluxConvective< dim, nstate, adtype > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nstate, adtype > &diss_num_flux, dealii::Vector< real > &local_rhs_int_cell, dealii::Vector< real > &local_rhs_ext_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Preparation of CoDiPack taping for internal cell faces integrals, and derivative evaluation.
dealii::IndexSet ghost_dofs
Locally relevant ghost degrees of freedom.
The mapping shape functions evaluated at the desired nodes (facet set included in volume grid nodes f...
Base class of numerical flux associated with convection.
bool use_manufactured_source_term
Uses non-zero source term based on the manufactured solution and the PDE.
std::shared_ptr< ArtificialDissipationBase< dim, nstate > > artificial_dissip
Link to Artificial dissipation class (with three dissipation types, depending on the input)...
void assemble_boundary_codi_taped_derivatives(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const unsigned int face_number, const unsigned int boundary_id, const dealii::FEFaceValuesBase< dim, dim > &fe_values_boundary, const real penalty, const dealii::FESystem< dim, dim > &fe_soln, const dealii::Quadrature< dim-1 > &quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const std::vector< dealii::types::global_dof_index > &soln_dof_indices, const Physics::PhysicsBase< dim, nstate, adtype > &physics, const NumericalFlux::NumericalFluxConvective< dim, nstate, adtype > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nstate, adtype > &diss_num_flux, dealii::Vector< real > &local_rhs_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Preparation of CoDiPack taping for boundary integral, and derivative evaluation.
std::shared_ptr< HighOrderGrid< dim, real, MeshType > > high_order_grid
High order grid that will provide the MappingFEField.
real evaluate_CFL(std::vector< std::array< real, nstate > > soln_at_q, const real artificial_dissipation, const real cell_diameter, const unsigned int cell_degree)
Evaluate the time it takes for the maximum wavespeed to cross the cell domain.
void assemble_volume_residual(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const dealii::FEValues< dim, dim > &fe_values_vol, const dealii::FESystem< dim, dim > &fe_soln, const dealii::Quadrature< dim > &quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const std::vector< dealii::types::global_dof_index > &soln_dof_indices, dealii::Vector< real > &local_rhs_cell, const dealii::FEValues< dim, dim > &fe_values_lagrange, const Physics::PhysicsBase< dim, nstate, real > &physics, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Evaluate the integral over the cell volume.
virtual std::array< real, nstate > source_term(const dealii::Point< dim, real > &pos, const std::array< real, nstate > &solution, const real current_time, const dealii::types::global_dof_index cell_index) const =0
Artificial dissipative fluxes that will be differentiated ONCE in space.
std::vector< real > coefficients
Solution coefficients in the finite element basis.
void assemble_subface_term_and_build_operators(typename dealii::DoFHandler< dim >::active_cell_iterator cell, typename dealii::DoFHandler< dim >::active_cell_iterator neighbor_cell, const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const unsigned int iface, const unsigned int neighbor_iface, const unsigned int neighbor_i_subface, const real penalty, const std::vector< dealii::types::global_dof_index > ¤t_dofs_indices, const std::vector< dealii::types::global_dof_index > &neighbor_dofs_indices, const std::vector< dealii::types::global_dof_index > ¤t_metric_dofs_indices, const std::vector< dealii::types::global_dof_index > &neighbor_metric_dofs_indices, const unsigned int, const unsigned int, const unsigned int, const unsigned int, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &, OPERATOR::metric_operators< real, dim, 2 *dim > &, OPERATOR::metric_operators< real, dim, 2 *dim > &, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &, std::array< std::vector< real >, dim > &, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_int, dealii::hp::FESubfaceValues< dim, dim > &fe_values_collection_subface, dealii::Vector< real > ¤t_cell_rhs, dealii::Vector< real > &neighbor_cell_rhs, std::vector< dealii::Tensor< 1, dim, real >> &, dealii::LinearAlgebra::distributed::Vector< double > &rhs, std::array< dealii::LinearAlgebra::distributed::Vector< double >, dim > &, const bool, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Builds the necessary fe values and assembles subface residual.
dealii::TrilinosWrappers::SparseMatrix d2RdWdX
void assemble_face_term(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const LocalSolution< real2, dim, nstate > &soln_int, const LocalSolution< real2, dim, nstate > &soln_ext, const LocalSolution< real2, dim, dim > &metric_int, const LocalSolution< real2, dim, dim > &metric_ext, const std::vector< double > &dual_int, const std::vector< double > &dual_ext, const std::pair< unsigned int, int > face_subface_int, const std::pair< unsigned int, int > face_subface_ext, const typename dealii::QProjector< dim >::DataSetDescriptor face_data_set_int, const typename dealii::QProjector< dim >::DataSetDescriptor face_data_set_ext, const Physics::PhysicsBase< dim, nstate, real2 > &physics, const NumericalFlux::NumericalFluxConvective< dim, nstate, real2 > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nstate, real2 > &diss_num_flux, const dealii::FEFaceValuesBase< dim, dim > &fe_values_int, const dealii::FEFaceValuesBase< dim, dim > &fe_values_ext, const real penalty, const dealii::Quadrature< dim-1 > &face_quadrature, std::vector< real2 > &rhs_int, std::vector< real2 > &rhs_ext, real2 &dual_dot_residual, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Main function responsible for evaluating the internal face integral and the specified derivatives...
virtual std::array< real, nstate > physical_source_term(const dealii::Point< dim, real > &pos, const std::array< real, nstate > &solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const dealii::types::global_dof_index cell_index) const
Physical source term that does require differentiation.
DGWeak(const Parameters::AllParameters *const parameters_input, const unsigned int degree, const unsigned int max_degree_input, const unsigned int grid_degree_input, const std::shared_ptr< Triangulation > triangulation_input)
Constructor.
void assemble_face_term_and_build_operators(typename dealii::DoFHandler< dim >::active_cell_iterator cell, typename dealii::DoFHandler< dim >::active_cell_iterator neighbor_cell, const dealii::types::global_dof_index current_cell_index, const dealii::types::global_dof_index neighbor_cell_index, const unsigned int iface, const unsigned int neighbor_iface, const real penalty, const std::vector< dealii::types::global_dof_index > ¤t_dofs_indices, const std::vector< dealii::types::global_dof_index > &neighbor_dofs_indices, const std::vector< dealii::types::global_dof_index > ¤t_metric_dofs_indices, const std::vector< dealii::types::global_dof_index > &neighbor_metric_dofs_indices, const unsigned int, const unsigned int, const unsigned int, const unsigned int, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &, OPERATOR::metric_operators< real, dim, 2 *dim > &, OPERATOR::metric_operators< real, dim, 2 *dim > &, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &, std::array< std::vector< real >, dim > &, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_int, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_ext, dealii::Vector< real > ¤t_cell_rhs, dealii::Vector< real > &neighbor_cell_rhs, std::vector< dealii::Tensor< 1, dim, real >> &, dealii::LinearAlgebra::distributed::Vector< double > &rhs, std::array< dealii::LinearAlgebra::distributed::Vector< double >, dim > &, const bool, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Builds the necessary fe values and assembles face residual.
const bool has_nonzero_physical_source
Flag to signal that physical source term is non-zero.
void assemble_boundary_residual(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const unsigned int face_number, const unsigned int boundary_id, const dealii::FEFaceValuesBase< dim, dim > &fe_values_boundary, const real penalty, const dealii::FESystem< dim, dim > &fe_soln, const dealii::Quadrature< dim-1 > &quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const std::vector< dealii::types::global_dof_index > &soln_dof_indices, const Physics::PhysicsBase< dim, nstate, real > &physics, const NumericalFlux::NumericalFluxConvective< dim, nstate, real > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nstate, real > &diss_num_flux, dealii::Vector< real > &local_rhs_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Evaluate the integral over the boundary.
Abstract class templated on the number of state variables.
const dealii::FESystem< dim, dim > & finite_element
Reference to the finite element system used to represent the solution.
void assemble_volume_codi_taped_derivatives(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const dealii::FEValues< dim, dim > &fe_values_vol, const dealii::FESystem< dim, dim > &fe_soln, const dealii::Quadrature< dim > &quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const std::vector< dealii::types::global_dof_index > &soln_dof_indices, dealii::Vector< real > &local_rhs_cell, const dealii::FEValues< dim, dim > &fe_values_lagrange, const Physics::PhysicsBase< dim, nstate, real2 > &physics, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Preparation of CoDiPack taping for volume integral, and derivative evaluation.
bool add_artificial_dissipation
Flag to add artificial dissipation from Persson's shock capturing paper.
dealii::TrilinosWrappers::SparseMatrix system_matrix
DissipativeNumericalFlux diss_num_flux_type
Store diffusive flux type.
dealii::Vector< double > cell_volume
Time it takes for the maximum wavespeed to cross the cell domain.
std::array< real, nstate > evaluate_flux(const std::array< real, nstate > &soln_int, const std::array< real, nstate > &soln_ext, const dealii::Tensor< 1, dim, real > &normal1) const
Returns the convective numerical flux at an interface.
void assemble_volume_term_explicit(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const dealii::FEValues< dim, dim > &fe_values_volume, const std::vector< dealii::types::global_dof_index > ¤t_dofs_indices, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const unsigned int poly_degree, const unsigned int grid_degree, dealii::Vector< real > ¤t_cell_rhs, const dealii::FEValues< dim, dim > &fe_values_lagrange)
Evaluate the integral over the cell volume.
void assemble_boundary_term_and_build_operators(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const unsigned int iface, const unsigned int boundary_id, const real penalty, const std::vector< dealii::types::global_dof_index > &cell_dofs_indices, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const unsigned int poly_degree, const unsigned int grid_degree, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::basis_functions< dim, 2 *dim, real > &, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &, OPERATOR::metric_operators< real, dim, 2 *dim > &, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &, std::array< std::vector< real >, dim > &, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_int, const dealii::FESystem< dim, dim > ¤t_fe_ref, dealii::Vector< real > &local_rhs_int_cell, std::vector< dealii::Tensor< 1, dim, real >> &, const bool, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Builds the necessary fe values and assembles boundary residual.
bool use_periodic_bc
Flag to use periodic BC.
void assemble_boundary_term_derivatives(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const unsigned int face_number, const unsigned int boundary_id, const dealii::FEFaceValuesBase< dim, dim > &fe_values_boundary, const real penalty, const dealii::FESystem< dim, dim > &fe, const dealii::Quadrature< dim-1 > &quadrature, const std::vector< dealii::types::global_dof_index > &metric_dof_indices, const std::vector< dealii::types::global_dof_index > &soln_dof_indices, dealii::Vector< real > &local_rhs_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
Evaluate the integral over the cell edges that are on domain boundaries and the specified derivatives...
dealii::TrilinosWrappers::SparseMatrix d2RdXdX
real1 norm(const dealii::Tensor< 1, dim, real1 > x)
Returns norm of dealii::Tensor<1,dim,real>
dealii::hp::QCollection< dim > volume_quadrature_collection
Finite Element Collection to represent the high-order grid.
ArtificialDissipationParam artificial_dissipation_param
Contains parameters for artificial dissipation.
virtual std::array< dealii::Tensor< 1, dim, real >, nstate > dissipative_flux(const std::array< real, nstate > &solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &solution_gradient, const dealii::types::global_dof_index cell_index) const =0
Dissipative fluxes that will be differentiated ONCE in space.
const dealii::hp::FECollection< dim > fe_collection
Finite Element Collection for p-finite-element to represent the solution.
Projection operator corresponding to basis functions onto M-norm (L2).
Local stiffness matrix without jacobian dependence.
const dealii::FE_Q< dim > fe_q_artificial_dissipation
Continuous distribution of artificial dissipation.