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 26 template <
typename real,
int dim>
using Coord = std::array<real, dim>;
28 template <
typename real,
int dim>
using CoordGrad = std::array<dealii::Tensor<1, dim, real>, dim>;
30 template <
typename real,
int nstate>
using State = std::array<real, nstate>;
32 template <
typename real,
int dim,
int nstate>
using DirectionalState = std::array<dealii::Tensor<1, dim, real>, nstate>;
38 template <
typename number>
39 void gauss_jordan(dealii::FullMatrix<number> &input_matrix) {
40 Assert(!input_matrix.empty(), dealii::ExcMessage(
"Empty matrix"))
41 Assert(input_matrix.n_cols() == input_matrix.n_rows(), dealii::ExcMessage(
"Non quadratic matrix"));
44 const size_t N = input_matrix.n();
49 number diagonal_sum = 0;
50 for (
size_t i = 0; i < N; ++i) diagonal_sum = diagonal_sum + abs(input_matrix(i, i));
51 const number typical_diagonal_element = diagonal_sum / N;
52 (void)typical_diagonal_element;
55 std::vector<size_t> p(N);
56 for (
size_t i = 0; i < N; ++i) p[i] = i;
58 for (
size_t j = 0; j < N; ++j) {
61 number max_pivot = abs(input_matrix(j, j));
63 for (
size_t i = j + 1; i < N; ++i) {
64 if (abs(input_matrix(i, j)) > max_pivot) {
65 max_pivot = abs(input_matrix(i, j));
70 Assert(max_pivot > 1.e-16 * typical_diagonal_element, dealii::ExcMessage(
"Non regular matrix"));
74 for (
size_t k = 0; k < N; ++k) std::swap(input_matrix(j, k), input_matrix(r, k));
76 std::swap(p[j], p[r]);
80 const number hr = number(1.) / input_matrix(j, j);
81 input_matrix(j, j) = hr;
82 for (
size_t k = 0; k < N; ++k) {
84 for (
size_t i = 0; i < N; ++i) {
86 input_matrix(i, k) -= input_matrix(i, j) * input_matrix(j, k) * hr;
89 for (
size_t i = 0; i < N; ++i) {
90 input_matrix(i, j) *= hr;
91 input_matrix(j, i) *= -hr;
93 input_matrix(j, j) = hr;
96 std::vector<number> hv(N);
97 for (
size_t i = 0; i < N; ++i) {
98 for (
size_t k = 0; k < N; ++k) hv[p[k]] = input_matrix(i, k);
99 for (
size_t k = 0; k < N; ++k) input_matrix(i, k) = hv[k];
106 template <
typename real>
107 double getValue(
const real &x) {
108 if constexpr (std::is_same<real, double>::value) {
111 return getValue(x.value());
119 template <
int dim,
typename real1,
typename real2>
120 dealii::Tensor<1, dim, real1> vmult(
const dealii::Tensor<2, dim, real1> A,
const dealii::Tensor<1, dim, real2> x) {
121 dealii::Tensor<1, dim, real1> y;
122 for (
int row = 0; row < dim; ++row) {
124 for (
int col = 0; col < dim; ++col) {
125 y[row] += A[row][col] * x[col];
136 template <
int dim,
typename real1>
137 real1 norm(
const dealii::Tensor<1, dim, real1> x) {
139 for (
int row = 0; row < dim; ++row) {
140 val += x[row] * x[row];
145 template <
int dim,
int nspecies,
typename real>
146 bool check_same_coords (
147 const std::vector<dealii::Point<dim>> &unit_quad_pts_int,
148 const std::vector<dealii::Point<dim>> &unit_quad_pts_ext,
151 const double tolerance)
153 assert(unit_quad_pts_int.size() == unit_quad_pts_ext.size());
154 const unsigned int nquad = unit_quad_pts_int.size();
155 std::vector<Coord<real,dim>> coords_int = metric_int.
evaluate_values(unit_quad_pts_int);
156 std::vector<Coord<real,dim>> coords_ext = metric_ext.
evaluate_values(unit_quad_pts_ext);
159 for (
unsigned int iquad = 0; iquad < nquad; ++iquad) {
160 for (
int d=0; d<dim; ++d) {
161 real abs_diff = abs(coords_int[iquad][d] - coords_ext[iquad][d]);
162 if (abs_diff > tolerance) {
163 real rel_diff = abs_diff / coords_int[iquad][d];
164 if (rel_diff > tolerance) {
170 std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1);
171 std::cout <<
"coords_int ";
172 for (
int d=0;d<dim;++d) {
173 std::cout << coords_int[iquad][d] <<
" ";
175 std::cout << std::endl;
176 std::cout <<
"coords_ext ";
177 for (
int d=0;d<dim;++d) {
178 std::cout << coords_ext[iquad][d] <<
" ";
180 std::cout << std::endl;
186 template <
int dim,
int nspecies,
typename real>
187 std::vector<dealii::Tensor<2,dim,real>> evaluate_metric_jacobian (
188 const std::vector<dealii::Point<dim>> &points,
191 const unsigned int n_dofs = metric_solution.
finite_element.dofs_per_cell;
193 const unsigned int n_pts = points.size();
195 AssertDimension(n_dofs, metric_solution.
coefficients.size());
199 std::vector<dealii::Tensor<2,dim,real>> metric_jacobian(n_pts);
201 for (
unsigned int ipoint=0; ipoint<n_pts; ++ipoint) {
202 for (
int row=0;row<dim;++row) {
203 for (
int col=0;col<dim;++col) {
204 metric_jacobian[ipoint][row][col] = coords_gradients[ipoint][row][col];
208 return metric_jacobian;
211 template <
int dim,
int nspecies,
typename real>
212 std::vector <real> determinant_ArrayTensor(std::vector<CoordGrad<real,dim>> &coords_gradients)
214 const unsigned int n = coords_gradients.size();
215 std::vector <real> determinants(n);
216 for (
unsigned int i=0; i<n; ++i) {
217 if constexpr(dim==1) {
218 determinants[i] = coords_gradients[i][0][0];
220 if constexpr(dim==2) {
221 determinants[i] = coords_gradients[i][0][0] * coords_gradients[i][1][1] - coords_gradients[i][0][1] * coords_gradients[i][1][0];
223 if constexpr(dim==3) {
224 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])
225 -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])
226 +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]);
232 template <
int dim,
int nspecies,
typename real>
233 void evaluate_covariant_metric_jacobian (
234 const dealii::Quadrature<dim> &quadrature,
236 std::vector<dealii::Tensor<2,dim,real>> &covariant_metric_jacobian,
237 std::vector<real> &jacobian_determinants)
239 const dealii::FiniteElement<dim> &fe_lagrange_grid = metric_solution.
finite_element.base_element(0);
241 const std::vector< dealii::Point<dim,double> > &unit_grid_pts = fe_lagrange_grid.get_unit_support_points();
242 std::vector<Coord<real, dim>> coords = metric_solution.
evaluate_values(unit_grid_pts);
245 const std::vector< dealii::Point<dim,double> > &unit_quad_pts = quadrature.get_points();
248 const unsigned int n_grid_pts = unit_grid_pts.size();
249 const unsigned int n_quad_pts = unit_quad_pts.size();
251 jacobian_determinants = determinant_ArrayTensor<dim,nspecies,real>(quad_pts_coords_gradients);
253 if constexpr (dim==1) {
254 for (
unsigned int iquad = 0; iquad<n_quad_pts; ++iquad) {
255 const real invJ = 1.0/jacobian_determinants[iquad];
256 covariant_metric_jacobian[iquad][0][0] = invJ;
260 if constexpr (dim==2) {
265 std::vector<dealii::Tensor<2,dim,real>> dphys_dref_quad(n_quad_pts);
268 for (
unsigned int iquad = 0; iquad<n_quad_pts; ++iquad) {
270 dphys_dref_quad[iquad] = 0.0;
272 const dealii::Point<dim,double> &quad_point = unit_quad_pts[iquad];
274 for (
unsigned int igrid = 0; igrid<n_grid_pts; ++igrid) {
276 const dealii::Tensor<1,dim,double> shape_grad = fe_lagrange_grid.shape_grad(igrid, quad_point);
278 for(
int dphys=0; dphys<dim; dphys++) {
279 for(
int dref=0; dref<dim; dref++) {
280 dphys_dref_quad[iquad][dphys][dref] += coords[igrid][dphys] * shape_grad[dref];
287 for (
unsigned int iquad = 0; iquad<n_quad_pts; ++iquad) {
289 const real invJ = 1.0/jacobian_determinants[iquad];
291 covariant_metric_jacobian[iquad] = 0.0;
295 covariant_metric_jacobian[iquad][0][0] = dphys_dref_quad[iquad][1][1] * invJ;
296 covariant_metric_jacobian[iquad][0][1] = -dphys_dref_quad[iquad][1][0] * invJ;
297 covariant_metric_jacobian[iquad][1][0] = -dphys_dref_quad[iquad][0][1] * invJ;
298 covariant_metric_jacobian[iquad][1][1] = dphys_dref_quad[iquad][0][0] * invJ;
303 if constexpr (dim == 3) {
306 std::vector<real> Ta(n_grid_pts);
307 std::vector<real> Tb(n_grid_pts);
308 std::vector<real> Tc(n_grid_pts);
310 std::vector<real> Td(n_grid_pts);
311 std::vector<real> Te(n_grid_pts);
312 std::vector<real> Tf(n_grid_pts);
314 std::vector<real> Tg(n_grid_pts);
315 std::vector<real> Th(n_grid_pts);
316 std::vector<real> Ti(n_grid_pts);
318 for(
unsigned int igrid=0; igrid<n_grid_pts; igrid++) {
319 Ta[igrid] = 0.5*(coords_gradients[igrid][1][1] * coords[igrid][2] - coords_gradients[igrid][2][1] * coords[igrid][1]);
320 Tb[igrid] = 0.5*(coords_gradients[igrid][1][2] * coords[igrid][2] - coords_gradients[igrid][2][2] * coords[igrid][1]);
321 Tc[igrid] = 0.5*(coords_gradients[igrid][1][0] * coords[igrid][2] - coords_gradients[igrid][2][0] * coords[igrid][1]);
323 Td[igrid] = 0.5*(coords_gradients[igrid][2][1] * coords[igrid][0] - coords_gradients[igrid][0][1] * coords[igrid][2]);
324 Te[igrid] = 0.5*(coords_gradients[igrid][2][2] * coords[igrid][0] - coords_gradients[igrid][0][2] * coords[igrid][2]);
325 Tf[igrid] = 0.5*(coords_gradients[igrid][2][0] * coords[igrid][0] - coords_gradients[igrid][0][0] * coords[igrid][2]);
327 Tg[igrid] = 0.5*(coords_gradients[igrid][0][1] * coords[igrid][1] - coords_gradients[igrid][1][1] * coords[igrid][0]);
328 Th[igrid] = 0.5*(coords_gradients[igrid][0][2] * coords[igrid][1] - coords_gradients[igrid][1][2] * coords[igrid][0]);
329 Ti[igrid] = 0.5*(coords_gradients[igrid][0][0] * coords[igrid][1] - coords_gradients[igrid][1][0] * coords[igrid][0]);
332 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++) {
334 covariant_metric_jacobian[iquad] = 0.0;
336 const dealii::Point<dim,double> &quad_point = unit_quad_pts[iquad];
338 for(
unsigned int igrid=0; igrid<n_grid_pts; igrid++) {
340 const dealii::Tensor<1,dim,double> shape_grad = fe_lagrange_grid.shape_grad(igrid, quad_point);
342 covariant_metric_jacobian[iquad][0][0] += shape_grad[2] * Ta[igrid] - shape_grad[1] * Tb[igrid];
343 covariant_metric_jacobian[iquad][1][0] += shape_grad[2] * Td[igrid] - shape_grad[1] * Te[igrid];
344 covariant_metric_jacobian[iquad][2][0] += shape_grad[2] * Tg[igrid] - shape_grad[1] * Th[igrid];
346 covariant_metric_jacobian[iquad][0][1] += shape_grad[0] * Tb[igrid] - shape_grad[2] * Tc[igrid];
347 covariant_metric_jacobian[iquad][1][1] += shape_grad[0] * Te[igrid] - shape_grad[2] * Tf[igrid];
348 covariant_metric_jacobian[iquad][2][1] += shape_grad[0] * Th[igrid] - shape_grad[2] * Ti[igrid];
350 covariant_metric_jacobian[iquad][0][2] += shape_grad[1] * Tc[igrid] - shape_grad[0] * Ta[igrid];
351 covariant_metric_jacobian[iquad][1][2] += shape_grad[1] * Tf[igrid] - shape_grad[0] * Td[igrid];
352 covariant_metric_jacobian[iquad][2][2] += shape_grad[1] * Ti[igrid] - shape_grad[0] * Tg[igrid];
355 const real invJ = 1.0/jacobian_determinants[iquad];
356 covariant_metric_jacobian[iquad] *= invJ;
367 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
370 const unsigned int degree,
371 const unsigned int max_degree_input,
372 const unsigned int grid_degree_input,
373 const std::shared_ptr<Triangulation> triangulation_input)
374 :
DGBaseState<dim,nspecies,nstate,real,MeshType>(parameters_input, degree, max_degree_input, grid_degree_input, triangulation_input)
377 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
379 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
380 const dealii::types::global_dof_index current_cell_index,
381 const dealii::FEValues<dim,dim> &fe_values_vol,
382 const std::vector<dealii::types::global_dof_index> &soln_dof_indices_int,
383 const std::vector<dealii::types::global_dof_index> &,
386 dealii::Vector<real> &,
387 const dealii::FEValues<dim,dim> &)
389 using State = State<real, nstate>;
390 using DirectionalState = DirectionalState<real, dim, nstate>;
392 (void) current_cell_index;
394 const unsigned int n_quad_pts = fe_values_vol.n_quadrature_points;
395 const unsigned int n_soln_dofs_int = fe_values_vol.dofs_per_cell;
397 AssertDimension (n_soln_dofs_int, soln_dof_indices_int.size());
399 const std::vector<real> &JxW = fe_values_vol.get_JxW_values ();
401 real cell_volume_estimate = 0.0;
402 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
403 cell_volume_estimate = cell_volume_estimate + JxW[iquad];
407 std::vector<State> soln_at_q(n_quad_pts);
408 std::vector<State> source_at_q;
409 std::vector<State> physical_source_at_q;
410 std::vector<DirectionalState> soln_grad_at_q(n_quad_pts);
411 std::vector<DirectionalState> conv_phys_flux_at_q(n_quad_pts);
412 std::vector<DirectionalState> diss_phys_flux_at_q(n_quad_pts);
414 std::vector< real > soln_coeff(n_soln_dofs_int);
415 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
416 soln_coeff[idof] = this->
solution(soln_dof_indices_int[idof]);
419 typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
422 std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
423 artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
425 std::vector<real> artificial_diss_coeff_at_q(n_quad_pts);
426 real max_artificial_diss = 0.0;
427 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
428 artificial_diss_coeff_at_q[iquad] = 0.0;
431 const dealii::Point<dim,real> point = fe_values_vol.get_quadrature().point(iquad);
432 for (
unsigned int idof=0; idof<n_dofs_arti_diss; ++idof) {
433 const unsigned int index = dof_indices_artificial_dissipation[idof];
436 max_artificial_diss = std::max(artificial_diss_coeff_at_q[iquad], max_artificial_diss);
440 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
441 for (
int istate=0; istate<
nstate; istate++) {
443 soln_at_q[iquad][istate] = 0;
444 soln_grad_at_q[iquad][istate] = 0;
448 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
449 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
450 const unsigned int istate = fe_values_vol.get_fe().system_to_component_index(idof).first;
451 soln_at_q[iquad][istate] += soln_coeff[idof] * fe_values_vol.shape_value_component(idof, iquad, istate);
452 soln_grad_at_q[iquad][istate] += soln_coeff[idof] * fe_values_vol.shape_grad_component(idof, iquad, istate);
456 const unsigned int cell_index = fe_values_vol.get_cell()->active_cell_index();
457 const unsigned int cell_degree = fe_values_vol.get_fe().tensor_degree();
458 const real diameter = fe_values_vol.get_cell()->diameter();
459 const real cell_diameter = cell_volume / std::pow(diameter,dim-1);
462 const real cell_radius = 0.5 * cell_diameter;
467 template <
int dim,
int nspecies,
int nstate,
typename real2>
468 void compute_br2_correction(
469 const dealii::FESystem<dim,dim> &fe_soln,
471 const std::vector<State<real2, nstate>> &lifting_op_R_rhs,
472 std::vector<State<real2, nstate>> &soln_grad_correction
475 const unsigned int n_faces = std::pow(2,dim);
476 const double br2_factor = n_faces * 1.01;
480 const dealii::FiniteElement<dim> &base_fe = fe_soln.get_sub_fe(0,1);
481 const unsigned int n_base_dofs = base_fe.n_dofs_per_cell();
485 const int degree = base_fe.tensor_degree();
486 dealii::QGauss<dim> vol_quad(degree+1);
487 const unsigned int n_vol_quad = vol_quad.size();
489 if (n_base_dofs != n_vol_quad) std::abort();
492 const std::vector<dealii::Point<dim,double>> &vol_unit_quad_pts = vol_quad.get_points();
493 using Tensor2D = dealii::Tensor<2,dim,real2>;
494 std::vector<Tensor2D> volume_metric_jac = evaluate_metric_jacobian (vol_unit_quad_pts, metric_solution);
497 dealii::FullMatrix<double> vandermonde_inverse(n_base_dofs, n_vol_quad);
499 for (
unsigned int idof_base=0; idof_base<n_base_dofs; ++idof_base) {
500 for (
unsigned int iquad=0; iquad<n_vol_quad; ++iquad) {
501 vandermonde_inverse[idof_base][iquad] = base_fe.shape_value(idof_base, vol_quad.point(iquad));
504 gauss_jordan(vandermonde_inverse);
506 std::vector< std::array<real2,nstate> > vandermonde_inv_rhs(n_vol_quad);
507 for (
unsigned int kquad=0; kquad<n_vol_quad; ++kquad) {
508 for (
int s=0; s<
nstate; s++) {
509 vandermonde_inv_rhs[kquad][s] = 0.0;
510 for (
unsigned int jdof_base=0; jdof_base<n_base_dofs; ++jdof_base) {
511 vandermonde_inv_rhs[kquad][s] += vandermonde_inverse[kquad][jdof_base] * lifting_op_R_rhs[jdof_base][s];
515 for (
unsigned int kquad=0; kquad<n_vol_quad; ++kquad) {
516 for (
int s=0; s<
nstate; s++) {
517 vandermonde_inv_rhs[kquad][s] /= dealii::determinant(volume_metric_jac[kquad]) * vol_quad.weight(kquad);
520 for (
unsigned int idof_base=0; idof_base<n_base_dofs; ++idof_base) {
521 for (
int s=0; s<
nstate; s++) {
522 soln_grad_correction[idof_base][s] = 0.0;
523 for (
unsigned int kquad=0; kquad<n_vol_quad; ++kquad) {
524 soln_grad_correction[idof_base][s] += vandermonde_inverse[kquad][idof_base] * vandermonde_inv_rhs[kquad][s];
526 soln_grad_correction[idof_base][s] *= br2_factor;
532 template <
int dim,
int nspecies,
int nstate,
typename real2>
533 void correct_the_gradient(
534 const std::vector<State<real2, nstate>> &soln_grad_corr,
535 const dealii::FESystem<dim,dim> &fe_soln,
536 const std::vector<DirectionalState<real2, dim, nstate>> &soln_jump,
537 const dealii::FullMatrix<double> &interpolation_operator,
538 const std::array<dealii::FullMatrix<real2>,dim> &gradient_operator,
539 std::vector<DirectionalState<real2, dim, nstate>> &soln_grad)
542 (void) soln_grad_corr;
543 (void) interpolation_operator;
544 (void) gradient_operator;
545 const unsigned int n_quad = soln_grad.size();
546 const unsigned int n_soln_dofs = fe_soln.dofs_per_cell;
548 for (
unsigned int iquad=0; iquad<n_quad; ++iquad) {
549 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
550 const unsigned int istate = fe_soln.system_to_component_index(idof).first;
551 const unsigned int idof_base = fe_soln.system_to_component_index(idof).second;
554 for (
int d=0;d<dim;++d) {
556 soln_grad[iquad][istate][d] += soln_grad_corr[idof_base][istate] * interpolation_operator[idof][iquad];
563 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
564 template <
typename real2>
566 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
567 const dealii::types::global_dof_index current_cell_index,
570 const std::vector< real > &local_dual,
571 const unsigned int face_number,
572 const unsigned int boundary_id,
576 const dealii::FEFaceValuesBase<dim,dim> &fe_values_boundary,
578 const dealii::Quadrature<dim-1> &quadrature,
579 std::vector<real2> &rhs,
580 real2 &dual_dot_residual,
581 const bool compute_metric_derivatives)
583 const unsigned int n_soln_dofs = local_solution.
finite_element.dofs_per_cell;
584 const unsigned int n_metric_dofs = local_metric.
finite_element.dofs_per_cell;
585 const unsigned int n_quad_pts = fe_values_boundary.n_quadrature_points;
587 dual_dot_residual = 0.0;
588 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
592 using State = State<real2, nstate>;
593 using DirectionalState = DirectionalState<real2, dim, nstate>;
595 const dealii::Quadrature<dim> face_quadrature
596 = dealii::QProjector<dim>::project_to_face(
597 dealii::ReferenceCell::get_hypercube(dim),
600 const std::vector<dealii::Point<dim,real>> &unit_quad_pts = face_quadrature.get_points();
601 std::vector<dealii::Point<dim,real2>> real_quad_pts(unit_quad_pts.size());
603 std::vector<dealii::Tensor<2,dim,real2>> metric_jacobian = evaluate_metric_jacobian (unit_quad_pts, local_metric);
604 std::vector<real2> jac_det(n_quad_pts);
605 std::vector<real2> surface_jac_det(n_quad_pts);
606 std::vector<dealii::Tensor<2,dim,real2>> jac_inv_tran(n_quad_pts);
608 const dealii::Tensor<1,dim,real> unit_normal = dealii::GeometryInfo<dim>::unit_normal_vector[face_number];
609 std::vector<dealii::Tensor<1,dim,real2>> phys_unit_normal(n_quad_pts);
611 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
612 if (compute_metric_derivatives) {
613 for (
int d=0;d<dim;++d) { real_quad_pts[iquad][d] = 0;}
614 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
615 const int iaxis = local_metric.
finite_element.system_to_component_index(idof).first;
616 real_quad_pts[iquad][iaxis] += local_metric.
coefficients[idof] * local_metric.
finite_element.shape_value(idof,unit_quad_pts[iquad]);
619 const real2 jacobian_determinant = dealii::determinant(metric_jacobian[iquad]);
620 const dealii::Tensor<2,dim,real2> jacobian_transpose_inverse = dealii::transpose(dealii::invert(metric_jacobian[iquad]));
622 jac_det[iquad] = jacobian_determinant;
623 jac_inv_tran[iquad] = jacobian_transpose_inverse;
625 const dealii::Tensor<1,dim,real2> normal = vmult(jacobian_transpose_inverse, unit_normal);
626 const real2 area =
norm(normal);
628 surface_jac_det[iquad] =
norm(normal)*jac_det[iquad];
632 for (
int d=0;d<dim;++d) {
633 phys_unit_normal[iquad][d] = normal[d] / area;
642 real_quad_pts[iquad] = fe_values_boundary.quadrature_point(iquad);
643 surface_jac_det[iquad] = fe_values_boundary.JxW(iquad) / face_quadrature.weight(iquad);
644 phys_unit_normal[iquad] = fe_values_boundary.normal_vector(iquad);
647 #ifdef KOPRIVA_METRICS_BOUNDARY 648 auto old_jac_det = jac_det;
649 auto old_jac_inv_tran = jac_inv_tran;
651 if constexpr (dim != 1) {
652 evaluate_covariant_metric_jacobian<dim,nspecies,real2> ( face_quadrature, local_metric, jac_inv_tran, jac_det);
656 std::vector<real2> faceJxW(n_quad_pts);
658 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
659 if (compute_metric_derivatives) {
660 const dealii::Tensor<1,dim,real2> normal = vmult(jac_inv_tran[iquad], unit_normal);
661 const real2 area =
norm(normal);
663 surface_jac_det[iquad] =
norm(normal)*jac_det[iquad];
667 for (
int d=0;d<dim;++d) {
668 phys_unit_normal[iquad][d] = normal[d] / area;
672 faceJxW[iquad] = surface_jac_det[iquad] * face_quadrature.weight(iquad);
675 dealii::FullMatrix<real> interpolation_operator(n_soln_dofs,n_quad_pts);
676 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
677 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
678 interpolation_operator[idof][iquad] = local_solution.
finite_element.shape_value(idof,unit_quad_pts[iquad]);
681 std::array<dealii::FullMatrix<real2>,dim> gradient_operator;
682 for (
int d=0;d<dim;++d) {
683 gradient_operator[d].reinit(dealii::TableIndices<2>(n_soln_dofs, n_quad_pts));
685 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
686 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
687 if (compute_metric_derivatives) {
688 const dealii::Tensor<1,dim,real> ref_shape_grad = local_solution.
finite_element.shape_grad(idof,unit_quad_pts[iquad]);
689 const dealii::Tensor<1,dim,real2> phys_shape_grad = vmult(jac_inv_tran[iquad], ref_shape_grad);
690 for (
int d=0;d<dim;++d) {
691 gradient_operator[d][idof][iquad] = phys_shape_grad[d];
700 for (
int d=0;d<dim;++d) {
701 const unsigned int istate = local_solution.
finite_element.system_to_component_index(idof).first;
702 gradient_operator[d][idof][iquad] = fe_values_boundary.shape_grad_component(idof, iquad, istate)[d];
708 std::vector<State> soln_int = local_solution.
evaluate_values(unit_quad_pts);
709 std::vector<State> soln_ext(n_quad_pts), soln_ext_viscous_flux(n_quad_pts);
710 std::vector<DirectionalState> soln_grad_int(n_quad_pts), soln_grad_ext(n_quad_pts), soln_grad_ext_viscous_flux(n_quad_pts);
712 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
714 for (
int istate=0; istate<
nstate; istate++) {
715 soln_grad_int[iquad][istate] = 0;
717 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
718 const int istate = fe_values_boundary.get_fe().system_to_component_index(idof).first;
719 for (
int d=0;d<dim;++d) {
720 soln_grad_int[iquad][istate][d] += local_solution.
coefficients[idof] * gradient_operator[d][idof][iquad];
725 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
726 const dealii::Tensor<1,dim,real2> normal_int = phys_unit_normal[iquad];
727 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]);
728 physics.
boundary_face_values_viscous_flux (boundary_id, real_quad_pts[iquad], normal_int, soln_int[iquad], soln_grad_int[iquad], soln_int[iquad], soln_grad_int[iquad], soln_ext_viscous_flux[iquad], soln_grad_ext_viscous_flux[iquad]);
732 const dealii::FiniteElement<dim> &base_fe_int = local_solution.
finite_element.get_sub_fe(0,1);
733 const unsigned int n_base_dofs_int = base_fe_int.n_dofs_per_cell();
735 std::vector<DirectionalState > soln_grad_correction_int(n_base_dofs_int);
740 std::vector<DirectionalState> soln_jump_int(n_quad_pts);
741 std::vector<DirectionalState> soln_jump_ext(n_quad_pts);
742 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
743 for (
int s=0; s<
nstate; s++) {
744 for (
int d=0; d<dim; d++) {
745 soln_jump_int[iquad][s][d] = (soln_int[iquad][s] - soln_ext[iquad][s]) * (phys_unit_normal[iquad][d]);
746 soln_jump_ext[iquad][s][d] = (soln_ext[iquad][s] - soln_int[iquad][s]) * (-phys_unit_normal[iquad][d]);
751 std::vector<State> lifting_op_R_rhs_int(n_base_dofs_int);
752 for (
unsigned int idof_base=0; idof_base<n_base_dofs_int; ++idof_base) {
753 for (
int s=0; s<
nstate; s++) {
755 const unsigned int idof = local_solution.
finite_element.component_to_system_index(s, idof_base);
756 lifting_op_R_rhs_int[idof_base][s] = 0.0;
758 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
760 for (
int d=0; d<dim; ++d) {
761 const double basis_average = interpolation_operator[idof][iquad];
762 lifting_op_R_rhs_int[idof_base][s] -= soln_jump_int[iquad][s][d] * basis_average * faceJxW[iquad];
768 std::vector<State> soln_grad_corr_int(n_base_dofs_int);
769 compute_br2_correction<dim,nspecies,nstate,real2>(local_solution.
finite_element, local_metric, lifting_op_R_rhs_int, soln_grad_corr_int);
771 correct_the_gradient<dim,nspecies,nstate,real2>( soln_grad_corr_int, local_solution.
finite_element, soln_jump_int, interpolation_operator, gradient_operator, soln_grad_int);
773 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
774 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
775 const unsigned int istate = local_solution.
finite_element.system_to_component_index(idof).first;
776 const unsigned int idof_base = local_solution.
finite_element.system_to_component_index(idof).second;
779 for (
int d=0;d<dim;++d) {
784 soln_grad_ext[iquad][istate][d] = soln_grad_int[iquad][istate][d];
787 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]);
793 std::vector<State> conv_num_flux_dot_n(n_quad_pts);
794 std::vector<State> diss_soln_num_flux(n_quad_pts);
795 std::vector<DirectionalState> diss_flux_jump_int(n_quad_pts);
796 std::vector<State> diss_auxi_num_flux_dot_n(n_quad_pts);
805 (void) artificial_diss_coeff;
807 typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
810 std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
811 artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
813 std::vector<real> artificial_diss_coeff_at_q(n_quad_pts);
814 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
815 artificial_diss_coeff_at_q[iquad] = 0.0;
817 const dealii::Point<dim,real> point = unit_quad_pts[iquad];
818 for (
unsigned int idof=0; idof<n_dofs_arti_diss; ++idof) {
819 const unsigned int index = dof_indices_artificial_dissipation[idof];
823 artificial_diss_coeff_at_q[iquad] = 0.0;
826 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
828 const dealii::Tensor<1,dim,real2> normal_int = phys_unit_normal[iquad];
842 conv_num_flux_dot_n[iquad] = conv_num_flux.
evaluate_flux(soln_int[iquad], soln_ext[iquad], normal_int);
844 diss_soln_num_flux[iquad] = diss_num_flux.
evaluate_solution_flux(soln_ext_viscous_flux[iquad], soln_ext_viscous_flux[iquad], normal_int);
846 DirectionalState diss_soln_jump_int;
847 for (
int s=0; s<
nstate; s++) {
848 for (
int d=0; d<dim; d++) {
849 diss_soln_jump_int[s][d] = (diss_soln_num_flux[iquad][s] - soln_int[iquad][s]) * normal_int[d];
852 diss_flux_jump_int[iquad] = physics.
dissipative_flux (soln_int[iquad], diss_soln_jump_int, current_cell_index);
855 const DirectionalState artificial_diss_flux_jump_int = this->
artificial_dissip->calc_artificial_dissipation_flux(soln_int[iquad], diss_soln_jump_int, artificial_diss_coeff_at_q[iquad]);
856 for (
int s=0; s<
nstate; s++) {
857 diss_flux_jump_int[iquad][s] += artificial_diss_flux_jump_int[s];
864 artificial_diss_coeff_at_q[iquad],
865 artificial_diss_coeff_at_q[iquad],
866 soln_int[iquad], soln_ext_viscous_flux[iquad],
867 soln_grad_int[iquad], soln_grad_ext_viscous_flux[iquad],
868 soln_int[iquad], soln_ext_viscous_flux[iquad],
869 soln_grad_int[iquad], soln_grad_ext_viscous_flux[iquad],
870 normal_int, penalty,
true, boundary_id);
874 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
878 const unsigned int istate = fe_values_boundary.get_fe().system_to_component_index(itest).first;
880 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
882 const real2 JxW_iquad = faceJxW[iquad];
884 rhs_val = rhs_val - interpolation_operator[itest][iquad] * conv_num_flux_dot_n[iquad][istate] * JxW_iquad;
886 rhs_val = rhs_val - interpolation_operator[itest][iquad] * diss_auxi_num_flux_dot_n[iquad][istate] * JxW_iquad;
887 for (
int d=0;d<dim;++d) {
888 rhs_val = rhs_val + gradient_operator[d][itest][iquad] * diss_flux_jump_int[iquad][istate][d] * JxW_iquad;
893 rhs[itest] = rhs_val;
894 dual_dot_residual += local_dual[itest]*rhs_val;
900 dealii::Quadrature<dim> project_face_quadrature(
901 const dealii::Quadrature<dim - 1> &face_quadrature_lower_dim,
const std::pair<unsigned int, int> face_subface_pair,
902 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set) {
903 dealii::Quadrature<dim> face_quadrature;
905 if constexpr (dim == 3) {
906 const dealii::Quadrature<dim> all_faces_quad =
907 face_subface_pair.second == -1 ? dealii::QProjector<dim>::project_to_all_faces(
908 dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim)
909 : dealii::QProjector<dim>::project_to_all_subfaces(
910 dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim);
911 const unsigned int n_face_quad_pts = face_quadrature_lower_dim.size();
912 std::vector<dealii::Point<dim>> points(n_face_quad_pts);
913 std::vector<double> weights(n_face_quad_pts);
914 for (
unsigned int iquad = 0; iquad < n_face_quad_pts; ++iquad) {
915 points[iquad] = all_faces_quad.point(iquad + face_data_set);
916 weights[iquad] = all_faces_quad.weight(iquad + face_data_set);
918 face_quadrature = dealii::Quadrature<dim>(points, weights);
921 (void) face_data_set;
922 if (face_subface_pair.second == -1) {
923 face_quadrature = dealii::QProjector<dim>::project_to_face(
924 dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim, face_subface_pair.first);
926 face_quadrature = dealii::QProjector<dim>::project_to_subface(
927 dealii::ReferenceCell::get_hypercube(dim), face_quadrature_lower_dim, face_subface_pair.first,
928 face_subface_pair.second, dealii::RefinementCase<dim - 1>::isotropic_refinement);
931 return face_quadrature;
934 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
935 template <
typename real2>
937 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
938 typename dealii::DoFHandler<dim>::active_cell_iterator ,
939 const dealii::types::global_dof_index current_cell_index,
940 const dealii::types::global_dof_index neighbor_cell_index,
945 const std::vector< double > &dual_int,
946 const std::vector< double > &dual_ext,
947 const std::pair<unsigned int, int> face_subface_int,
948 const std::pair<unsigned int, int> face_subface_ext,
949 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_int,
950 const typename dealii::QProjector<dim>::DataSetDescriptor face_data_set_ext,
954 const dealii::FEFaceValuesBase<dim,dim> &fe_values_int,
955 const dealii::FEFaceValuesBase<dim,dim> &fe_values_ext,
957 const dealii::Quadrature<dim-1> &face_quadrature,
958 std::vector<real2> &rhs_int,
959 std::vector<real2> &rhs_ext,
960 real2 &dual_dot_residual,
961 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R)
964 const unsigned int n_soln_dofs_int = soln_int.
finite_element.dofs_per_cell;
965 const unsigned int n_soln_dofs_ext = soln_ext.
finite_element.dofs_per_cell;
966 const unsigned int n_face_quad_pts = face_quadrature.size();
968 dual_dot_residual = 0.0;
969 for (
unsigned int itest=0; itest<n_soln_dofs_int; ++itest) {
970 rhs_int[itest] = 0.0;
972 for (
unsigned int itest=0; itest<n_soln_dofs_ext; ++itest) {
973 rhs_ext[itest] = 0.0;
976 using State = State<real2, nstate>;
977 using DirectionalState = DirectionalState<real2, dim, nstate>;
978 using Tensor1D = dealii::Tensor<1,dim,real2>;
979 using Tensor2D = dealii::Tensor<2,dim,real2>;
981 dealii::Quadrature<dim> face_quadrature_int = project_face_quadrature<dim>(face_quadrature, face_subface_int, face_data_set_int);
982 dealii::Quadrature<dim> face_quadrature_ext = project_face_quadrature<dim>(face_quadrature, face_subface_ext, face_data_set_ext);
984 (void) compute_dRdW; (void) compute_dRdX; (void) compute_d2R;
985 const bool compute_metric_derivatives =
true;
987 const std::vector<dealii::Point<dim,double>> &unit_quad_pts_int = face_quadrature_int.get_points();
988 const std::vector<dealii::Point<dim,double>> &unit_quad_pts_ext = face_quadrature_ext.get_points();
993 std::vector<Tensor2D> metric_jac_int = evaluate_metric_jacobian (unit_quad_pts_int, metric_int);
994 std::vector<Tensor2D> metric_jac_ext = evaluate_metric_jacobian (unit_quad_pts_ext, metric_ext);
996 const dealii::Tensor<1,dim,real> unit_normal_int = dealii::GeometryInfo<dim>::unit_normal_vector[face_subface_int.first];
997 const dealii::Tensor<1,dim,real> unit_normal_ext = dealii::GeometryInfo<dim>::unit_normal_vector[face_subface_ext.first];
1020 (void) artificial_diss_coeff_int;
1021 (void) artificial_diss_coeff_ext;
1022 typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
1025 std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
1026 artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
1028 std::vector<real> artificial_diss_coeff_at_q(n_face_quad_pts);
1029 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1030 artificial_diss_coeff_at_q[iquad] = 0.0;
1033 const dealii::Point<dim,real> point = unit_quad_pts_int[iquad];
1034 for (
unsigned int idof=0; idof<n_dofs_arti_diss; ++idof) {
1035 const unsigned int index = dof_indices_artificial_dissipation[idof];
1039 artificial_diss_coeff_at_q[iquad] = 0.0;
1042 std::vector<real2> jacobian_determinant_int(n_face_quad_pts);
1043 std::vector<real2> jacobian_determinant_ext(n_face_quad_pts);
1044 std::vector<Tensor2D> jacobian_transpose_inverse_int(n_face_quad_pts);
1045 std::vector<Tensor2D> jacobian_transpose_inverse_ext(n_face_quad_pts);
1047 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1048 if (compute_metric_derivatives) {
1049 jacobian_determinant_int[iquad] = dealii::determinant(metric_jac_int[iquad]);
1050 jacobian_determinant_ext[iquad] = dealii::determinant(metric_jac_ext[iquad]);
1052 jacobian_transpose_inverse_int[iquad] = dealii::transpose(dealii::invert(metric_jac_int[iquad]));
1053 jacobian_transpose_inverse_ext[iquad] = dealii::transpose(dealii::invert(metric_jac_ext[iquad]));
1057 #ifdef KOPRIVA_METRICS_FACE 1058 auto old_jacobian_determinant_int = jacobian_determinant_int;
1059 auto old_jacobian_determinant_ext = jacobian_determinant_ext;
1060 auto old_jacobian_transpose_inverse_int = jacobian_transpose_inverse_int;
1061 auto old_jacobian_transpose_inverse_ext = jacobian_transpose_inverse_ext;
1063 if constexpr (dim != 1) {
1064 evaluate_covariant_metric_jacobian<dim,nspecies,real2> ( face_quadrature_int, metric_int, jacobian_transpose_inverse_int, jacobian_determinant_int);
1065 evaluate_covariant_metric_jacobian<dim,nspecies,real2> ( face_quadrature_ext, metric_ext, jacobian_transpose_inverse_ext, jacobian_determinant_ext);
1070 check_same_coords<dim,nspecies,real2>(unit_quad_pts_int, unit_quad_pts_ext, metric_int, metric_ext, 1e-10);
1074 std::vector<Tensor1D> phys_unit_normal_int(n_face_quad_pts), phys_unit_normal_ext(n_face_quad_pts);
1075 std::vector<real2> surface_jac_det(n_face_quad_pts);
1076 std::vector<real2> faceJxW(n_face_quad_pts);
1078 dealii::FullMatrix<real> interpolation_operator_int(n_soln_dofs_int, n_face_quad_pts);
1079 dealii::FullMatrix<real> interpolation_operator_ext(n_soln_dofs_ext, n_face_quad_pts);
1080 std::array<dealii::FullMatrix<real2>,dim> gradient_operator_int, gradient_operator_ext;
1081 for (
int d=0;d<dim;++d) {
1082 gradient_operator_int[d].reinit(dealii::TableIndices<2>(n_soln_dofs_int, n_face_quad_pts));
1083 gradient_operator_ext[d].reinit(dealii::TableIndices<2>(n_soln_dofs_ext, n_face_quad_pts));
1086 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1088 real2 surface_jac_det_int, surface_jac_det_ext;
1090 if (compute_metric_derivatives) {
1092 const real2 jac_det_int = jacobian_determinant_int[iquad];
1093 const real2 jac_det_ext = jacobian_determinant_ext[iquad];
1095 const Tensor2D jac_inv_tran_int = jacobian_transpose_inverse_int[iquad];
1096 const Tensor2D jac_inv_tran_ext = jacobian_transpose_inverse_ext[iquad];
1098 const Tensor1D normal_int = vmult(jac_inv_tran_int, unit_normal_int);
1099 const Tensor1D normal_ext = vmult(jac_inv_tran_ext, unit_normal_ext);
1100 const real2 area_int =
norm(normal_int);
1101 const real2 area_ext =
norm(normal_ext);
1106 for (
int d=0;d<dim;++d) {
1107 phys_unit_normal_int[iquad][d] = normal_int[d] / area_int;
1109 for (
int d=0;d<dim;++d) {
1110 phys_unit_normal_ext[iquad][d] = normal_ext[d] / area_ext;
1113 surface_jac_det_int = area_int*jac_det_int;
1114 surface_jac_det_ext = area_ext*jac_det_ext;
1117 if (std::is_same<double,real2>::value) {
1118 bool valid_metrics =
true;
1127 if (face_subface_int.second == -1 && face_subface_ext.second == -1) {
1130 pcout <<
"iquad " << iquad <<
" Non-matching surface jacobians, int = " 1131 << surface_jac_det_int <<
", ext = " << surface_jac_det_ext <<
", diff = " 1132 << abs(surface_jac_det_int-surface_jac_det_ext) << std::endl;
1135 valid_metrics =
false;
1138 real2 diff_norm = 0;
1139 for (
int d=0;d<dim;++d) {
1140 const real2 diff = phys_unit_normal_int[iquad][d]+phys_unit_normal_ext[iquad][d];
1141 diff_norm += diff*diff;
1143 diff_norm = sqrt(diff_norm);
1144 if (diff_norm > 1e-10) {
1145 std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1);
1146 std::cout <<
"Non-matching normals. Error norm: " << diff_norm << std::endl;
1147 for (
int d=0;d<dim;++d) {
1149 std::cout <<
" normal_int["<<d<<
"] : " << phys_unit_normal_int[iquad][d]
1150 <<
" normal_ext["<<d<<
"] : " << phys_unit_normal_ext[iquad][d]
1153 valid_metrics =
false;
1155 if (!valid_metrics) {
1167 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
1168 interpolation_operator_int[idof][iquad] = soln_int.
finite_element.shape_value(idof,unit_quad_pts_int[iquad]);
1169 dealii::Tensor<1,dim,real> ref_shape_grad = soln_int.
finite_element.shape_grad(idof,unit_quad_pts_int[iquad]);
1170 const Tensor1D phys_shape_grad = vmult(jac_inv_tran_int, ref_shape_grad);
1171 for (
int d=0;d<dim;++d) {
1172 gradient_operator_int[d][idof][iquad] = phys_shape_grad[d];
1175 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
1176 interpolation_operator_ext[idof][iquad] = soln_ext.
finite_element.shape_value(idof,unit_quad_pts_ext[iquad]);
1177 dealii::Tensor<1,dim,real> ref_shape_grad = soln_ext.
finite_element.shape_grad(idof,unit_quad_pts_ext[iquad]);
1178 const Tensor1D phys_shape_grad = vmult(jac_inv_tran_ext, ref_shape_grad);
1179 for (
int d=0;d<dim;++d) {
1180 gradient_operator_ext[d][idof][iquad] = phys_shape_grad[d];
1185 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
1186 interpolation_operator_int[idof][iquad] = soln_int.
finite_element.shape_value(idof,unit_quad_pts_int[iquad]);
1188 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
1189 interpolation_operator_ext[idof][iquad] = soln_ext.
finite_element.shape_value(idof,unit_quad_pts_ext[iquad]);
1191 for (
int d=0;d<dim;++d) {
1192 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
1193 const unsigned int istate = soln_int.
finite_element.system_to_component_index(idof).first;
1194 gradient_operator_int[d][idof][iquad] = fe_values_int.shape_grad_component(idof, iquad, istate)[d];
1196 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
1197 const unsigned int istate = soln_ext.
finite_element.system_to_component_index(idof).first;
1198 gradient_operator_ext[d][idof][iquad] = fe_values_ext.shape_grad_component(idof, iquad, istate)[d];
1201 surface_jac_det_int = fe_values_int.JxW(iquad)/face_quadrature_int.weight(iquad);
1202 surface_jac_det_ext = fe_values_ext.JxW(iquad)/face_quadrature_ext.weight(iquad);
1204 phys_unit_normal_int[iquad] = fe_values_int.normal_vector(iquad);
1205 phys_unit_normal_ext[iquad] = -phys_unit_normal_int[iquad];
1214 if ( surface_jac_det_int > surface_jac_det_ext) {
1217 surface_jac_det[iquad] = surface_jac_det_ext;
1222 surface_jac_det[iquad] = surface_jac_det_int;
1226 faceJxW[iquad] = surface_jac_det[iquad] * face_quadrature_int.weight(iquad);
1230 std::vector<State> soln_int_at_q = soln_int.
evaluate_values(unit_quad_pts_int);
1231 std::vector<State> soln_ext_at_q = soln_ext.
evaluate_values(unit_quad_pts_ext);
1234 std::vector<DirectionalState> soln_grad_int(n_face_quad_pts), soln_grad_ext(n_face_quad_pts);
1235 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1237 for (
int istate=0; istate<
nstate; istate++) {
1238 soln_grad_int[iquad][istate] = 0;
1239 soln_grad_ext[iquad][istate] = 0;
1242 for (
unsigned int idof=0; idof<n_soln_dofs_int; ++idof) {
1243 const unsigned int istate = soln_int.
finite_element.system_to_component_index(idof).first;
1244 for (
int d=0;d<dim;++d) {
1245 soln_grad_int[iquad][istate][d] += soln_int.
coefficients[idof] * gradient_operator_int[d][idof][iquad];
1248 for (
unsigned int idof=0; idof<n_soln_dofs_ext; ++idof) {
1249 const unsigned int istate = soln_ext.
finite_element.system_to_component_index(idof).first;
1250 for (
int d=0;d<dim;++d) {
1251 soln_grad_ext[iquad][istate][d] += soln_ext.
coefficients[idof] * gradient_operator_ext[d][idof][iquad];
1261 const dealii::FiniteElement<dim> &base_fe_int = soln_int.
finite_element.get_sub_fe(0,1);
1262 const dealii::FiniteElement<dim> &base_fe_ext = soln_ext.
finite_element.get_sub_fe(0,1);
1263 const unsigned int n_base_dofs_int = base_fe_int.n_dofs_per_cell();
1264 const unsigned int n_base_dofs_ext = base_fe_ext.n_dofs_per_cell();
1267 std::vector<DirectionalState> soln_jump_int(n_face_quad_pts);
1268 std::vector<DirectionalState> soln_jump_ext(n_face_quad_pts);
1269 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1270 for (
int s=0; s<
nstate; s++) {
1271 for (
int d=0; d<dim; d++) {
1272 soln_jump_int[iquad][s][d] = (soln_int_at_q[iquad][s] - soln_ext_at_q[iquad][s]) * phys_unit_normal_int[iquad][d];
1273 soln_jump_ext[iquad][s][d] = (soln_ext_at_q[iquad][s] - soln_int_at_q[iquad][s]) * (-phys_unit_normal_int[iquad][d]);
1280 std::vector<State> lifting_op_R_rhs_int(n_base_dofs_int);
1281 for (
unsigned int idof_base=0; idof_base<n_base_dofs_int; ++idof_base) {
1282 for (
int s=0; s<
nstate; s++) {
1284 const unsigned int idof = soln_int.
finite_element.component_to_system_index(s, idof_base);
1285 lifting_op_R_rhs_int[idof_base][s] = 0.0;
1287 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1289 for (
int d=0; d<dim; ++d) {
1290 const double basis_average = 0.5 * (interpolation_operator_int[idof][iquad] + 0.0);
1291 lifting_op_R_rhs_int[idof_base][s] -= soln_jump_int[iquad][s][d] * basis_average * faceJxW[iquad];
1298 std::vector<State> lifting_op_R_rhs_ext(n_base_dofs_ext);
1299 for (
unsigned int idof_base=0; idof_base<n_base_dofs_ext; ++idof_base) {
1300 for (
int s=0; s<
nstate; s++) {
1302 const unsigned int idof = soln_ext.
finite_element.component_to_system_index(s, idof_base);
1303 lifting_op_R_rhs_ext[idof_base][s] = 0.0;
1305 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1307 for (
int d=0; d<dim; ++d) {
1308 const double basis_average = 0.5 * ( 0.0 + interpolation_operator_ext[idof][iquad] );
1309 lifting_op_R_rhs_ext[idof_base][s] -= soln_jump_ext[iquad][s][d] * basis_average * faceJxW[iquad];
1316 std::vector<State> soln_grad_corr_int(n_base_dofs_int), soln_grad_corr_ext(n_base_dofs_ext);
1317 compute_br2_correction<dim,nspecies,nstate,real2>(soln_int.
finite_element, metric_int, lifting_op_R_rhs_int, soln_grad_corr_int);
1318 compute_br2_correction<dim,nspecies,nstate,real2>(soln_ext.
finite_element, metric_ext, lifting_op_R_rhs_ext, soln_grad_corr_ext);
1320 correct_the_gradient<dim,nspecies,nstate,real2>( soln_grad_corr_int, soln_int.
finite_element, soln_jump_int, interpolation_operator_int, gradient_operator_int, soln_grad_int);
1321 correct_the_gradient<dim,nspecies,nstate,real2>( soln_grad_corr_ext, soln_ext.
finite_element, soln_jump_ext, interpolation_operator_ext, gradient_operator_ext, soln_grad_ext);
1326 State conv_num_flux_dot_n;
1327 State diss_soln_num_flux;
1328 State diss_auxi_num_flux_dot_n;
1330 DirectionalState diss_flux_jump_int;
1331 DirectionalState diss_flux_jump_ext;
1333 for (
unsigned int iquad=0; iquad<n_face_quad_pts; ++iquad) {
1336 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]);
1337 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]);
1339 DirectionalState diss_soln_jump_int, diss_soln_jump_ext;
1340 for (
int s=0; s<
nstate; s++) {
1341 for (
int d=0; d<dim; d++) {
1342 diss_soln_jump_int[s][d] = (diss_soln_num_flux[s] - soln_int_at_q[iquad][s]) * phys_unit_normal_int[iquad][d];
1343 diss_soln_jump_ext[s][d] = (diss_soln_num_flux[s] - soln_ext_at_q[iquad][s]) * phys_unit_normal_ext[iquad][d];
1346 diss_flux_jump_int = physics.
dissipative_flux (soln_int_at_q[iquad], diss_soln_jump_int, current_cell_index);
1347 diss_flux_jump_ext = physics.
dissipative_flux (soln_ext_at_q[iquad], diss_soln_jump_ext, neighbor_cell_index);
1352 for (
int s=0; s<
nstate; s++) {
1353 diss_flux_jump_int[s] += artificial_diss_flux_jump_int[s];
1354 diss_flux_jump_ext[s] += artificial_diss_flux_jump_ext[s];
1361 neighbor_cell_index,
1362 artificial_diss_coeff_at_q[iquad],
1363 artificial_diss_coeff_at_q[iquad],
1364 soln_int_at_q[iquad], soln_ext_at_q[iquad],
1365 soln_grad_int[iquad], soln_grad_ext[iquad],
1366 soln_int_at_q[iquad], soln_ext_at_q[iquad],
1367 soln_grad_int[iquad], soln_grad_ext[iquad],
1368 phys_unit_normal_int[iquad], penalty,
false);
1371 for (
unsigned int itest_int=0; itest_int<n_soln_dofs_int; ++itest_int) {
1373 const unsigned int istate = soln_int.
finite_element.system_to_component_index(itest_int).first;
1375 const real2 JxW_iquad = faceJxW[iquad];
1377 rhs = rhs - interpolation_operator_int[itest_int][iquad] * conv_num_flux_dot_n[istate] * JxW_iquad;
1379 rhs = rhs - interpolation_operator_int[itest_int][iquad] * diss_auxi_num_flux_dot_n[istate] * JxW_iquad;
1380 for (
int d=0;d<dim;++d) {
1381 rhs = rhs + gradient_operator_int[d][itest_int][iquad] * diss_flux_jump_int[istate][d] * JxW_iquad;
1384 rhs_int[itest_int] += rhs;
1385 dual_dot_residual += dual_int[itest_int]*rhs;
1389 for (
unsigned int itest_ext=0; itest_ext<n_soln_dofs_ext; ++itest_ext) {
1391 const unsigned int istate = soln_ext.
finite_element.system_to_component_index(itest_ext).first;
1393 const real2 JxW_iquad = faceJxW[iquad];
1395 rhs = rhs - interpolation_operator_ext[itest_ext][iquad] * (-conv_num_flux_dot_n[istate]) * JxW_iquad;
1397 rhs = rhs - interpolation_operator_ext[itest_ext][iquad] * (-diss_auxi_num_flux_dot_n[istate]) * JxW_iquad;
1398 for (
int d=0;d<dim;++d) {
1399 rhs = rhs + gradient_operator_ext[d][itest_ext][iquad] * diss_flux_jump_ext[istate][d] * JxW_iquad;
1402 rhs_ext[itest_ext] += rhs;
1403 dual_dot_residual += dual_ext[itest_ext]*rhs;
1410 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
1411 template <
typename real2>
1413 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1414 const dealii::types::global_dof_index current_cell_index,
1417 const std::vector<real> &local_dual,
1418 const dealii::Quadrature<dim> &quadrature,
1420 std::vector<real2> &rhs, real2 &dual_dot_residual,
1421 const bool compute_metric_derivatives,
1422 const dealii::FEValues<dim,dim> &fe_values_vol)
1424 (void) current_cell_index;
1425 using State = State<real2, nstate>;
1426 using DirectionalState = DirectionalState<real2, dim, nstate>;
1427 using Tensor2D = dealii::Tensor<2,dim,real2>;
1429 const unsigned int n_quad_pts = quadrature.size();
1430 const unsigned int n_soln_dofs = local_solution.
finite_element.dofs_per_cell;
1432 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1435 dual_dot_residual = 0.0;
1437 const std::vector<dealii::Point<dim>> &points = quadrature.get_points ();
1439 const unsigned int n_metric_dofs = local_metric.
finite_element.dofs_per_cell;
1442 std::vector<Tensor2D> metric_jacobian;
1443 if (compute_metric_derivatives) metric_jacobian = evaluate_metric_jacobian ( points, local_metric);
1444 std::vector<real2> jac_det(n_quad_pts);
1445 std::vector<Tensor2D> jac_inv_tran(n_quad_pts);
1446 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
1448 if (compute_metric_derivatives) {
1449 const real2 jacobian_determinant = dealii::determinant(metric_jacobian[iquad]);
1450 jac_det[iquad] = jacobian_determinant;
1452 const Tensor2D jacobian_transpose_inverse = dealii::transpose(dealii::invert(metric_jacobian[iquad]));
1453 jac_inv_tran[iquad] = jacobian_transpose_inverse;
1455 jac_det[iquad] = fe_values_vol.JxW(iquad) / quadrature.weight(iquad);
1458 #ifdef KOPRIVA_METRICS_VOL 1459 auto old_jac_inv_tran = jac_inv_tran;
1460 auto old_jac_det = jac_det;
1461 if constexpr (dim != 1) {
1462 evaluate_covariant_metric_jacobian<dim,nspecies,real2> ( quadrature, local_metric, jac_inv_tran, jac_det);
1464 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
1465 if (abs(old_jac_det[iquad] - jac_det[iquad])/abs(old_jac_det[iquad]) > 1e-10) {
1466 std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 1);
1467 std::cout <<
"Not the same jac det, iquad " << iquad << std::endl;
1468 std::cout << old_jac_det[iquad] << std::endl;
1469 std::cout << jac_det[iquad] << std::endl;
1475 const std::vector<dealii::Point<dim,double>> &unit_quad_pts = quadrature.get_points();
1476 dealii::FullMatrix<real> interpolation_operator(n_soln_dofs,n_quad_pts);
1477 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
1478 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
1479 interpolation_operator[idof][iquad] = local_solution.
finite_element.shape_value(idof,unit_quad_pts[iquad]);
1488 std::array<dealii::FullMatrix<real2>,dim> gradient_operator;
1489 for (
int d=0;d<dim;++d) {
1490 gradient_operator[d].reinit(dealii::TableIndices<2>(n_soln_dofs, n_quad_pts));
1492 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
1493 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
1494 if (compute_metric_derivatives) {
1496 const dealii::Tensor<1,dim,real2> ref_shape_grad = local_solution.
finite_element.shape_grad(idof,points[iquad]);
1497 dealii::Tensor<1,dim,real2> phys_shape_grad;
1498 for (
int dr=0;dr<dim;++dr) {
1499 phys_shape_grad[dr] = 0.0;
1500 for (
int dc=0;dc<dim;++dc) {
1501 phys_shape_grad[dr] += jac_inv_tran[iquad][dr][dc] * ref_shape_grad[dc];
1504 for (
int d=0;d<dim;++d) {
1505 gradient_operator[d][idof][iquad] = phys_shape_grad[d];
1514 for (
int d=0;d<dim;++d) {
1515 const unsigned int istate = local_solution.
finite_element.system_to_component_index(idof).first;
1516 gradient_operator[d][idof][iquad] = fe_values_vol.shape_grad_component(idof, iquad, istate)[d];
1539 (void) artificial_diss_coeff;
1541 typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
1544 std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
1545 artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
1562 std::vector<real2> artificial_diss_coeff_at_q(n_quad_pts);
1564 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad)
1566 artificial_diss_coeff_at_q[iquad] = arti_diss;
1582 std::vector<State> soln_at_q(n_quad_pts);
1583 std::vector<DirectionalState> soln_grad_at_q(n_quad_pts);
1585 std::vector<DirectionalState> conv_phys_flux_at_q(n_quad_pts);
1586 std::vector<DirectionalState> diss_phys_flux_at_q(n_quad_pts);
1587 std::vector<State> source_at_q;
1588 std::vector<State> physical_source_at_q;
1590 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
1591 for (
int istate=0; istate<
nstate; istate++) {
1592 soln_at_q[iquad][istate] = 0;
1593 soln_grad_at_q[iquad][istate] = 0;
1595 for (
unsigned int idof=0; idof<n_soln_dofs; ++idof) {
1596 const unsigned int istate = local_solution.
finite_element.system_to_component_index(idof).first;
1597 soln_at_q[iquad][istate] += local_solution.
coefficients[idof] * interpolation_operator[idof][iquad];
1598 for (
int d=0;d<dim;++d) {
1599 soln_grad_at_q[iquad][istate][d] += local_solution.
coefficients[idof] * gradient_operator[d][idof][iquad];
1602 conv_phys_flux_at_q[iquad] = physics.
convective_flux (soln_at_q[iquad]);
1603 diss_phys_flux_at_q[iquad] = physics.
dissipative_flux (soln_at_q[iquad], soln_grad_at_q[iquad], current_cell_index);
1606 physical_source_at_q.resize(n_quad_pts);
1607 dealii::Point<dim,real2> ad_points;
1608 for (
int d=0;d<dim;++d) { ad_points[d] = 0.0;}
1609 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1610 const int iaxis = local_metric.
finite_element.system_to_component_index(idof).first;
1613 physical_source_at_q[iquad] = physics.
physical_source_term (ad_points, soln_at_q[iquad], soln_grad_at_q[iquad], current_cell_index);
1617 const DirectionalState 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]);
1618 for (
int s=0; s<
nstate; s++) {
1619 diss_phys_flux_at_q[iquad][s] += artificial_diss_phys_flux_at_q[s];
1624 source_at_q.resize(n_quad_pts);
1625 dealii::Point<dim,real2> ad_point;
1626 for (
int d=0;d<dim;++d) { ad_point[d] = 0.0;}
1627 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1628 const int iaxis = local_metric.
finite_element.system_to_component_index(idof).first;
1631 source_at_q[iquad] = physics.
source_term (ad_point, soln_at_q[iquad], this->
current_time, current_cell_index);
1643 for (
unsigned int itest=0; itest<n_soln_dofs; ++itest) {
1645 const unsigned int istate = local_solution.
finite_element.system_to_component_index(itest).first;
1647 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
1649 const real2 JxW_iquad = jac_det[iquad] * quadrature.weight(iquad);
1651 for (
int d=0;d<dim;++d) {
1653 rhs[itest] = rhs[itest] + gradient_operator[d][itest][iquad] * conv_phys_flux_at_q[iquad][istate][d] * JxW_iquad;
1656 rhs[itest] = rhs[itest] + gradient_operator[d][itest][iquad] * diss_phys_flux_at_q[iquad][istate][d] * JxW_iquad;
1660 rhs[itest] = rhs[itest] + interpolation_operator[itest][iquad]* physical_source_at_q[iquad][istate] * JxW_iquad;
1664 rhs[itest] = rhs[itest] + interpolation_operator[itest][iquad]* source_at_q[iquad][istate] * JxW_iquad;
1667 dual_dot_residual += local_dual[itest]*rhs[itest];
1672 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
1673 template <
typename adtype>
1675 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1676 const dealii::types::global_dof_index current_cell_index,
1677 const std::vector<adtype> &soln_coeffs,
1678 const dealii::Tensor<1,dim,std::vector<adtype>> &,
1679 const std::vector<adtype> &metric_coeffs,
1680 const std::vector<real> &local_dual,
1681 const std::vector<dealii::types::global_dof_index> &soln_dofs_indices,
1682 const std::vector<dealii::types::global_dof_index> &metric_dofs_indices,
1683 const unsigned int poly_degree,
1684 const unsigned int grid_degree,
1693 std::array<std::vector<adtype>,dim> &,
1694 dealii::hp::FEValues<dim,dim> &fe_values_collection_volume,
1695 dealii::hp::FEValues<dim,dim> &fe_values_collection_volume_lagrange,
1696 const dealii::FESystem<dim,dim> &fe_soln,
1697 std::vector<adtype> &rhs,
1698 dealii::Tensor<1,dim,std::vector<adtype>> &,
1700 adtype &dual_dot_residual)
1703 const int i_fele = cell->active_fe_index();
1704 const int i_quad = i_fele;
1705 const int i_mapp = 0;
1706 fe_values_collection_volume.reinit (cell, i_quad, i_mapp, i_fele);
1707 dealii::TriaIterator<dealii::CellAccessor<dim, dim>> cell_iterator =
static_cast<dealii::TriaIterator<dealii::CellAccessor<dim, dim>
> > (cell);
1708 fe_values_collection_volume_lagrange.reinit (cell_iterator, i_quad, i_mapp, i_fele);
1710 const dealii::FEValues<dim,dim> &fe_values_vol = fe_values_collection_volume.get_present_fe_values();
1711 const dealii::FEValues<dim,dim> &fe_values_lagrange = fe_values_collection_volume_lagrange.get_present_fe_values();
1713 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
1714 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
1715 const unsigned int n_soln_dofs = fe_soln.dofs_per_cell;
1717 dealii::Vector<real> local_rhs_dummy (n_soln_dofs);
1724 metric_dofs_indices,
1725 poly_degree, grid_degree,
1727 fe_values_lagrange);
1733 for(
unsigned int i=0; i<n_soln_dofs; ++i)
1737 for(
unsigned int i=0; i<n_metric_dofs; ++i)
1742 const bool compute_metric_derivatives =
true;
1744 assemble_volume_term<adtype>(
1747 local_solution, local_metric,
1751 rhs, dual_dot_residual,
1752 compute_metric_derivatives, fe_values_vol);
1755 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
1756 template <
typename adtype>
1758 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1759 const dealii::types::global_dof_index current_cell_index,
1760 const std::vector<adtype> &soln_coeffs,
1761 const dealii::Tensor<1,dim,std::vector<adtype>> &,
1762 const std::vector<adtype> &metric_coeffs,
1763 const std::vector< real > &local_dual,
1764 const unsigned int face_number,
1765 const unsigned int boundary_id,
1769 const unsigned int ,
1770 const unsigned int ,
1776 std::array<std::vector<adtype>,dim> &,
1777 dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_int,
1778 const dealii::FESystem<dim,dim> &fe_soln,
1780 std::vector<adtype> &rhs,
1781 dealii::Tensor<1,dim,std::vector<adtype>> &,
1783 adtype &dual_dot_residual)
1786 const int i_fele = cell->active_fe_index();
1787 const int i_quad = i_fele;
1788 const int i_mapp = 0;
1790 fe_values_collection_face_int.reinit (cell, face_number, i_quad, i_mapp, i_fele);
1791 const dealii::FEFaceValues<dim,dim> &fe_values_boundary = fe_values_collection_face_int.get_present_fe_values();
1794 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
1795 const unsigned int n_soln_dofs = fe_values_boundary.dofs_per_cell;
1796 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
1799 for(
unsigned int i=0; i<n_soln_dofs; ++i)
1803 for(
unsigned int i=0; i<n_metric_dofs; ++i)
1808 const bool compute_metric_derivatives =
true;
1810 assemble_boundary_term<adtype>(
1826 compute_metric_derivatives);
1829 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
1830 template <
typename adtype>
1832 typename dealii::DoFHandler<dim>::active_cell_iterator cell,
1833 typename dealii::DoFHandler<dim>::active_cell_iterator neighbor_cell,
1834 const dealii::types::global_dof_index current_cell_index,
1835 const dealii::types::global_dof_index neighbor_cell_index,
1836 const unsigned int iface,
1837 const unsigned int neighbor_iface,
1838 const std::vector<adtype> &soln_int,
1839 const std::vector<adtype> &soln_ext,
1840 const dealii::Tensor<1,dim,std::vector<adtype>> &,
1841 const dealii::Tensor<1,dim,std::vector<adtype>> &,
1842 const std::vector<adtype> &metric_int,
1843 const std::vector<adtype> &metric_ext,
1844 const std::vector< double > &dual_int,
1845 const std::vector< double > &dual_ext,
1846 const unsigned int ,
1847 const unsigned int ,
1848 const unsigned int ,
1849 const unsigned int ,
1860 std::array<std::vector<adtype>,dim> &,
1864 dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_int,
1865 dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_ext,
1866 dealii::hp::FESubfaceValues<dim,dim> &fe_values_collection_subface,
1867 const dealii::FESystem<dim,dim> &fe_int,
1868 const dealii::FESystem<dim,dim> &fe_ext,
1870 std::vector<adtype> &rhs_int,
1871 std::vector<adtype> &rhs_ext,
1872 dealii::Tensor<1,dim,std::vector<adtype>> &,
1873 dealii::Tensor<1,dim,std::vector<adtype>> &,
1875 adtype &dual_dot_residual,
1876 const bool compute_dRdW,
const bool compute_dRdX,
const bool compute_d2R,
1877 const bool is_a_subface,
1878 const unsigned int neighbor_i_subface)
1880 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
1881 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
1882 const unsigned int n_soln_dofs_int = fe_int.dofs_per_cell;
1883 const unsigned int n_soln_dofs_ext = fe_ext.dofs_per_cell;
1885 const int i_fele = cell->active_fe_index();
1886 const int i_quad = i_fele;
1887 const int i_mapp = 0;
1888 const int i_fele_n = neighbor_cell->active_fe_index();
1889 const int i_quad_n = i_fele_n;
1890 const int i_mapp_n = 0;
1892 fe_values_collection_face_int.reinit (cell, iface, i_quad, i_mapp, i_fele);
1893 const dealii::FEFaceValues<dim,dim> &fe_values_face_int = fe_values_collection_face_int.get_present_fe_values();
1894 const dealii::Quadrature<dim-1> &face_quadrature = this->
face_quadrature_collection[(i_quad_n > i_quad) ? i_quad_n : i_quad];
1901 for (
unsigned int idof = 0; idof < n_soln_dofs_int; ++idof) {
1902 local_soln_int.coefficients[idof] = soln_int[idof];
1904 for (
unsigned int idof = 0; idof < n_soln_dofs_ext; ++idof) {
1907 for (
unsigned int idof = 0; idof < n_metric_dofs; ++idof) {
1908 local_metric_int.
coefficients[idof] = metric_int[idof];
1909 local_metric_ext.
coefficients[idof] = metric_ext[idof];
1912 std::pair<unsigned int, int> face_subface_int = std::make_pair(iface, -1);
1914 const auto face_data_set_int = dealii::QProjector<dim>::DataSetDescriptor::face(
1915 dealii::ReferenceCell::get_hypercube(dim),
1917 cell->face_orientation(iface),
1918 cell->face_flip(iface),
1919 cell->face_rotation(iface),
1920 face_quadrature.size());
1924 fe_values_collection_subface.reinit (neighbor_cell, neighbor_iface, neighbor_i_subface, i_quad_n, i_mapp_n, i_fele_n);
1925 const dealii::FESubfaceValues<dim,dim> &fe_values_face_ext = fe_values_collection_subface.get_present_fe_values();
1926 std::pair<unsigned int, int> face_subface_ext = std::make_pair(neighbor_iface, (
int)neighbor_i_subface);
1927 const auto face_data_set_ext = dealii::QProjector<dim>::DataSetDescriptor::subface (
1928 dealii::ReferenceCell::get_hypercube(dim),
1931 neighbor_cell->face_orientation(neighbor_iface),
1932 neighbor_cell->face_flip(neighbor_iface),
1933 neighbor_cell->face_rotation(neighbor_iface),
1934 face_quadrature.size(),
1935 neighbor_cell->subface_case(neighbor_iface));
1936 assemble_face_term<adtype>(
1940 neighbor_cell_index,
1941 local_soln_int, local_soln_ext, local_metric_int, local_metric_ext,
1958 compute_dRdW, compute_dRdX, compute_d2R);
1962 fe_values_collection_face_ext.reinit (neighbor_cell, neighbor_iface, i_quad_n, i_mapp_n, i_fele_n);
1963 const dealii::FEFaceValues<dim,dim> &fe_values_face_ext = fe_values_collection_face_ext.get_present_fe_values();
1964 std::pair<unsigned int, int> face_subface_ext = std::make_pair(neighbor_iface, -1);
1965 const auto face_data_set_ext = dealii::QProjector<dim>::DataSetDescriptor::face (
1966 dealii::ReferenceCell::get_hypercube(dim),
1968 neighbor_cell->face_orientation(neighbor_iface),
1969 neighbor_cell->face_flip(neighbor_iface),
1970 neighbor_cell->face_rotation(neighbor_iface),
1971 face_quadrature.size());
1972 assemble_face_term<adtype>(
1976 neighbor_cell_index,
1977 local_soln_int, local_soln_ext, local_metric_int, local_metric_ext,
1994 compute_dRdW, compute_dRdX, compute_d2R);
1999 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
2005 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
2012 #if PHILIP_SPECIES==1 2014 #define POSSIBLE_NSTATE (1)(2)(3)(4)(5)(6) 2021 #define INSTANTIATE_TRIA(r, data, nstate) \ 2022 template class DGWeak <PHILIP_DIM, PHILIP_SPECIES, nstate, double, dealii::Triangulation<PHILIP_DIM>>; \ 2023 template class DGWeak <PHILIP_DIM, PHILIP_SPECIES, nstate, double, dealii::parallel::shared::Triangulation<PHILIP_DIM>>; 2024 BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_TRIA, _, POSSIBLE_NSTATE)
2027 #define INSTANTIATE_DISTRIBUTED(r, data, nstate) \ 2028 template class DGWeak <PHILIP_DIM, PHILIP_SPECIES, nstate, double, dealii::parallel::distributed::Triangulation<PHILIP_DIM>>; 2030 BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_DISTRIBUTED, _, POSSIBLE_NSTATE)
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.
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.
dealii::LinearAlgebra::distributed::Vector< double > artificial_dissipation_c0
Artificial dissipation coefficients.
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.
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.
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
Class to store local solution coefficients and provide evaluation functions.
double matching_surface_jac_det_tolerance
const dealii::FE_Q< dim > fe_q_artificial_dissipation
Continuous distribution of artificial dissipation.
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.
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
dealii::IndexSet ghost_dofs
Locally relevant ghost degrees of freedom.
std::shared_ptr< ArtificialDissipationBase< dim, nspecies, nstate > > artificial_dissip
Link to Artificial dissipation class (with three dissipation types, depending on the input)...
dealii::hp::QCollection< dim-1 > face_quadrature_collection
Quadrature used to evaluate face integrals.
Base class of numerical flux associated with dissipation.
Files for the baseline physics.
const bool has_nonzero_physical_source
Flag to signal that physical source term is non-zero.
dealii::DoFHandler< dim > dof_handler_artificial_dissipation
Degrees of freedom handler for C0 artificial dissipation.
ManufacturedSolutionParam manufactured_solution_param
Associated manufactured solution parameters.
std::shared_ptr< HighOrderGrid< dim, real, MeshType > > high_order_grid
High order grid that will provide the MappingFEField.
const int nstate
Number of state variables.
DGWeak class templated on the number of state variables.
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.
dealii::hp::QCollection< dim > volume_quadrature_collection
Finite Element Collection to represent the high-order grid.
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 std::array< real, nstate > &filtered_soln_int, const std::array< real, nstate > &filtered_soln_ext, const std::array< dealii::Tensor< 1, dim, real >, nstate > &filtered_soln_grad_int, const std::array< dealii::Tensor< 1, dim, real >, nstate > &filtered_soln_grad_ext_, const dealii::Tensor< 1, dim, real > &normal_int, const real &penalty, const bool on_boundary, const int boundary_type=0) const =0
Auxiliary flux at the interface.
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.
Main parameter class that contains the various other sub-parameter classes.
ManufacturedConvergenceStudyParam manufactured_convergence_study_param
Contains parameters for manufactured convergence study.
dealii::Vector< double > cell_volume
Time it takes for the maximum wavespeed to cross the cell domain.
DissipativeNumericalFlux
Possible dissipative numerical flux types.
void assemble_auxiliary_residual(const bool, const bool, const bool)
Assembles the auxiliary equations' residuals and solves for the auxiliary variables.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
virtual void boundary_face_values_viscous_flux(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 > &, 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
Evaluates boundary values and gradients on the other side of the face for the viscous flux...
MPI_Comm mpi_communicator
MPI communicator.
dealii::IndexSet locally_owned_dofs
Locally own degrees of freedom.
Base metric operators class that stores functions used in both the volume and on surface.
void assemble_boundary_term_and_build_operators_ad_templated(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const std::vector< adtype > &soln_coeffs, const dealii::Tensor< 1, dim, std::vector< adtype >> &, const std::vector< adtype > &metric_coeffs, const std::vector< real > &local_dual, const unsigned int face_number, const unsigned int boundary_id, const Physics::PhysicsBase< dim, nspecies, nstate, adtype > &physics, const NumericalFlux::NumericalFluxConvective< dim, nspecies, nstate, adtype > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nspecies, nstate, adtype > &diss_num_flux, const unsigned int, const unsigned int, OPERATOR::basis_functions< dim, 2 *dim > &, OPERATOR::basis_functions< dim, 2 *dim > &, OPERATOR::vol_projection_operator< dim, 2 *dim > &, OPERATOR::metric_operators< adtype, dim, 2 *dim > &, OPERATOR::mapping_shape_functions< dim, 2 *dim > &, std::array< std::vector< adtype >, dim > &, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_int, const dealii::FESystem< dim, dim > &fe_soln, const real penalty, std::vector< adtype > &rhs, dealii::Tensor< 1, dim, std::vector< adtype >> &, const bool, adtype &dual_dot_residual)
Calls the function to assemble boundary residual.
std::vector< std::array< dealii::Tensor< 1, dim, real >, n_components > > evaluate_reference_gradients(const std::vector< dealii::Point< dim >> &unit_points) const
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.
dealii::Vector< double > max_dt_cell
Time it takes for the maximum wavespeed to cross the cell domain.
bool use_manufactured_source_term
Uses non-zero source term based on the manufactured solution and the PDE.
bool check_same_coords_in_weak_dg
void assemble_volume_term_and_build_operators_ad_templated(typename dealii::DoFHandler< dim >::active_cell_iterator cell, const dealii::types::global_dof_index current_cell_index, const std::vector< adtype > &soln_coeffs, const dealii::Tensor< 1, dim, std::vector< adtype >> &, const std::vector< adtype > &metric_coeffs, const std::vector< real > &local_dual, const std::vector< dealii::types::global_dof_index > &soln_dofs_indices, const std::vector< dealii::types::global_dof_index > &metric_dofs_indices, const unsigned int poly_degree, const unsigned int grid_degree, const Physics::PhysicsBase< dim, nspecies, nstate, adtype > &physics, OPERATOR::basis_functions< dim, 2 *dim > &, OPERATOR::basis_functions< dim, 2 *dim > &, OPERATOR::local_basis_stiffness< dim, 2 *dim > &, OPERATOR::vol_projection_operator< dim, 2 *dim > &, OPERATOR::vol_projection_operator< dim, 2 *dim > &, OPERATOR::metric_operators< adtype, dim, 2 *dim > &, OPERATOR::mapping_shape_functions< dim, 2 *dim > &, std::array< std::vector< adtype >, 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 > &fe_soln, std::vector< adtype > &rhs, dealii::Tensor< 1, dim, std::vector< adtype >> &, const bool, adtype &dual_dot_residual)
Calls the function to assemble volume residual.
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 > &, 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
Evaluates boundary values and gradients on the other side of the face for the convective flux...
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, nspecies, nstate > &local_solution, const LocalSolution< real2, dim, nspecies, dim > &local_metric, const std::vector< real > &local_dual, const unsigned int face_number, const unsigned int boundary_id, const Physics::PhysicsBase< dim, nspecies, nstate, real2 > &physics, const NumericalFlux::NumericalFluxConvective< dim, nspecies, nstate, real2 > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nspecies, 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.
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)
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution.
Abstract class templated on the number of state variables.
dealii::LinearAlgebra::distributed::Vector< real > dual
Current optimization dual variables corresponding to the residual constraints also known as the adjoi...
dealii::Vector< double > artificial_dissipation_coeffs
Artificial dissipation in each cell.
real current_time
The current time set in set_current_time()
const dealii::FESystem< dim, dim > & finite_element
Reference to the finite element system used to represent the solution.
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, nspecies, nstate > &local_solution, const LocalSolution< real2, dim, nspecies, dim > &local_metric, const std::vector< real > &local_dual, const dealii::Quadrature< dim > &quadrature, const Physics::PhysicsBase< dim, nspecies, 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...
bool add_artificial_dissipation
Flag to add artificial dissipation from Persson's shock capturing paper.
void allocate_dual_vector(const bool compute_d2R)
Allocate the dual vector for optimization.
DissipativeNumericalFlux diss_num_flux_type
Store diffusive flux type.
void assemble_face_term_and_build_operators_ad_templated(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 std::vector< adtype > &soln_coeff_int, const std::vector< adtype > &soln_coeff_ext, const dealii::Tensor< 1, dim, std::vector< adtype >> &, const dealii::Tensor< 1, dim, std::vector< adtype >> &, const std::vector< adtype > &metric_coeff_int, const std::vector< adtype > &metric_coeff_ext, const std::vector< double > &dual_int, const std::vector< double > &dual_ext, const unsigned int, const unsigned int, const unsigned int, const unsigned int, OPERATOR::basis_functions< dim, 2 *dim > &, OPERATOR::basis_functions< dim, 2 *dim > &, OPERATOR::basis_functions< dim, 2 *dim > &, OPERATOR::basis_functions< dim, 2 *dim > &, OPERATOR::local_basis_stiffness< dim, 2 *dim > &, OPERATOR::vol_projection_operator< dim, 2 *dim > &, OPERATOR::vol_projection_operator< dim, 2 *dim > &, OPERATOR::metric_operators< adtype, dim, 2 *dim > &, OPERATOR::metric_operators< adtype, dim, 2 *dim > &, OPERATOR::mapping_shape_functions< dim, 2 *dim > &, std::array< std::vector< adtype >, dim > &, const Physics::PhysicsBase< dim, nspecies, nstate, adtype > &physics, const NumericalFlux::NumericalFluxConvective< dim, nspecies, nstate, adtype > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nspecies, nstate, adtype > &diss_num_flux, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_int, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_ext, dealii::hp::FESubfaceValues< dim, dim > &fe_values_collection_subface, const dealii::FESystem< dim, dim > &fe_int, const dealii::FESystem< dim, dim > &fe_ext, const real penalty, std::vector< adtype > &rhs_int, std::vector< adtype > &rhs_ext, dealii::Tensor< 1, dim, std::vector< adtype >> &, dealii::Tensor< 1, dim, std::vector< adtype >> &, const bool, adtype &dual_dot_residual, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, const bool is_a_subface, const unsigned int neighbor_i_subface)
Calls the function to assemble face residual.
std::shared_ptr< Triangulation > triangulation
Mesh.
void assemble_face_term(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 LocalSolution< real2, dim, nspecies, nstate > &soln_int, const LocalSolution< real2, dim, nspecies, nstate > &soln_ext, const LocalSolution< real2, dim, nspecies, dim > &metric_int, const LocalSolution< real2, dim, nspecies, 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, nspecies, nstate, real2 > &physics, const NumericalFlux::NumericalFluxConvective< dim, nspecies, nstate, real2 > &conv_num_flux, const NumericalFlux::NumericalFluxDissipative< dim, nspecies, 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...
real1 norm(const dealii::Tensor< 1, dim, real1 > x)
Returns norm of dealii::Tensor<1,dim,real>
std::vector< real > coefficients
Solution coefficients in the finite element basis.
ArtificialDissipationParam artificial_dissipation_param
Contains parameters for artificial dissipation.
std::vector< std::array< real, n_components > > evaluate_values(const std::vector< dealii::Point< dim >> &unit_points) const
Obtain values at unit points.
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 std::array< real, nstate > &filtered_solution, const std::array< dealii::Tensor< 1, dim, real >, nstate > &filtered_solution_gradient, const dealii::types::global_dof_index cell_index)
Dissipative fluxes that will be differentiated ONCE in space.
Projection operator corresponding to basis functions onto M-norm (L2).
Local stiffness matrix without jacobian dependence.
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.