[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
dg_base.cpp
1 #include<limits>
2 #include<fstream>
3 #include <deal.II/base/parameter_handler.h>
4 #include <deal.II/base/tensor.h>
5 
6 #include <deal.II/base/qprojector.h>
7 
8 #include <deal.II/grid/tria.h>
9 #include <deal.II/distributed/shared_tria.h>
10 #include <deal.II/distributed/tria.h>
11 
12 #include <deal.II/grid/grid_generator.h>
13 #include <deal.II/grid/grid_refinement.h>
14 
15 #include <deal.II/dofs/dof_handler.h>
16 #include <deal.II/dofs/dof_tools.h>
17 #include <deal.II/dofs/dof_renumbering.h>
18 
19 #include <deal.II/dofs/dof_accessor.h>
20 
21 #include <deal.II/lac/vector.h>
22 #include <deal.II/lac/dynamic_sparsity_pattern.h>
23 #include <deal.II/lac/sparse_matrix.h>
24 
25 #include <deal.II/fe/fe_dgq.h>
26 
27 //#include <deal.II/fe/mapping_q1.h> // Might need mapping_q
28 #include <deal.II/fe/mapping_q.h> // Might need mapping_q
29 #include <deal.II/fe/mapping_q_generic.h>
30 #include <deal.II/fe/mapping_manifold.h>
31 #include <deal.II/fe/mapping_fe_field.h>
32 
33 // Finally, we take our exact solution from the library as well as volume_quadrature
34 // and additional tools.
35 #include <EpetraExt_Transpose_RowMatrix.h>
36 #include <deal.II/distributed/grid_refinement.h>
37 #include <deal.II/dofs/dof_renumbering.h>
38 #include <deal.II/grid/grid_refinement.h>
39 #include <deal.II/numerics/data_out.h>
40 #include <deal.II/numerics/data_out_dof_data.h>
41 #include <deal.II/numerics/data_out_faces.h>
42 #include <deal.II/numerics/derivative_approximation.h>
43 #include <deal.II/numerics/vector_tools.h>
44 #include <deal.II/numerics/vector_tools.templates.h>
45 
46 #include "dg_base.hpp"
47 #include "global_counter.hpp"
48 #include "post_processor/physics_post_processor.h"
49 
50 unsigned int n_vmult;
51 unsigned int dRdW_form;
52 unsigned int dRdW_mult;
53 unsigned int dRdX_mult;
54 unsigned int d2R_mult;
55 
56 
57 namespace PHiLiP {
58 
59 template <int dim, typename real, typename MeshType>
61  const int nstate_input,
62  const Parameters::AllParameters *const parameters_input,
63  const unsigned int degree,
64  const unsigned int max_degree_input,
65  const unsigned int grid_degree_input,
66  const std::shared_ptr<Triangulation> triangulation_input)
67  : DGBase<dim,real,MeshType>(nstate_input, parameters_input, degree, max_degree_input, grid_degree_input, triangulation_input, this->create_collection_tuple(max_degree_input, nstate_input, parameters_input))
68 { }
69 
70 template <int dim, typename real, typename MeshType>
72  const int nstate_input,
73  const Parameters::AllParameters *const parameters_input,
74  const unsigned int degree,
75  const unsigned int max_degree_input,
76  const unsigned int grid_degree_input,
77  const std::shared_ptr<Triangulation> triangulation_input,
78  const MassiveCollectionTuple collection_tuple)
79  : all_parameters(parameters_input)
80  , nstate(nstate_input)
81  , initial_degree(degree)
82  , max_degree(max_degree_input)
83  , max_grid_degree(grid_degree_input)
84  , triangulation(triangulation_input)
85  , fe_collection(std::get<0>(collection_tuple))
86  , volume_quadrature_collection(std::get<1>(collection_tuple))
87  , face_quadrature_collection(std::get<2>(collection_tuple))
88  , fe_collection_lagrange(std::get<3>(collection_tuple))
89  , oneD_fe_collection(std::get<4>(collection_tuple))
90  , oneD_fe_collection_1state(std::get<5>(collection_tuple))
91  , oneD_fe_collection_flux(std::get<6>(collection_tuple))
92  , oneD_quadrature_collection(std::get<7>(collection_tuple))
94  , dof_handler(*triangulation, true)
95  , high_order_grid(std::make_shared<HighOrderGrid<dim,real,MeshType>>(grid_degree_input, triangulation, all_parameters->check_valid_metric_Jacobian, all_parameters->do_renumber_dofs, all_parameters->output_high_order_grid))
98  , mpi_communicator(MPI_COMM_WORLD)
99  , pcout(std::cout, dealii::Utilities::MPI::this_mpi_process(mpi_communicator)==0)
102 {
103 
106 
107  set_all_cells_fe_degree(degree);
108 
109 }
110 
111 template <int dim, typename real, typename MeshType>
113 {
114  high_order_grid->reinit();
115 
118 }
119 
120 template <int dim, typename real, typename MeshType>
122 {
123  high_order_grid = new_high_order_grid;
124  triangulation = high_order_grid->triangulation;
128 }
129 
130 
131 template <int dim, typename real, typename MeshType>
132 std::tuple<
133  //dealii::hp::MappingCollection<dim>, // Mapping
134  dealii::hp::FECollection<dim>, // Solution FE
135  dealii::hp::QCollection<dim>, // Volume quadrature
136  dealii::hp::QCollection<dim-1>, // Face quadrature
137  dealii::hp::FECollection<dim>, // Lagrange polynomials for strong form
138  dealii::hp::FECollection<1>, // Solution FE 1D
139  dealii::hp::FECollection<1>, // Solution FE 1D for a single state
140  dealii::hp::FECollection<1>, // Collocated flux basis 1D for Strong
141  dealii::hp::QCollection<1> >// 1D quadrature for strong form
143  const unsigned int max_degree,
144  const int nstate,
145  const Parameters::AllParameters *const parameters_input) const
146 {
147  dealii::hp::FECollection<dim> fe_coll;
148  dealii::hp::FECollection<1> fe_coll_1D;
149  dealii::hp::FECollection<1> fe_coll_1D_1state;
150  dealii::hp::QCollection<dim> volume_quad_coll;
151  dealii::hp::QCollection<dim-1> face_quad_coll;
152  dealii::hp::QCollection<1> oneD_quad_coll;
153 
154  dealii::hp::FECollection<dim> fe_coll_lagr;
155  dealii::hp::FECollection<1> fe_coll_lagr_1D;
156 
157  const unsigned int overintegration = parameters_input->overintegration;
158  using FluxNodes = Parameters::AllParameters::FluxNodes;
159  const FluxNodes flux_nodes_type = parameters_input->flux_nodes_type;
160 
161  // for p=0, we use a p=1 FE for collocation, since there's no p=0 quadrature for Gauss Lobatto (GLL)
162  if (flux_nodes_type==FluxNodes::GLL)
163  {
164  int degree = 1;
165  const unsigned int integration_strength = degree+1+overintegration;
166 
167  const dealii::FE_DGQ<dim> fe_dg(degree);
168  const dealii::FESystem<dim,dim> fe_system(fe_dg, nstate);
169  fe_coll.push_back (fe_system);
170 
171  const dealii::FE_DGQ<1> fe_dg_1D(degree);
172  const dealii::FESystem<1,1> fe_system_1D(fe_dg_1D, nstate);
173  fe_coll_1D.push_back (fe_system_1D);
174  const dealii::FESystem<1,1> fe_system_1D_1state(fe_dg_1D, 1);
175  fe_coll_1D_1state.push_back (fe_system_1D_1state);
176 
177  dealii::Quadrature<1> oneD_quad(integration_strength);
178  dealii::Quadrature<dim> volume_quad(integration_strength);
179  dealii::Quadrature<dim-1> face_quad(integration_strength); //removed const
180 
181  dealii::QGaussLobatto<1> oneD_quad_Gauss_Lobatto (integration_strength);
182  dealii::QGaussLobatto<dim> vol_quad_Gauss_Lobatto (integration_strength);
183  oneD_quad = oneD_quad_Gauss_Lobatto;
184  volume_quad = vol_quad_Gauss_Lobatto;
185 
186  if(dim == 1) {
187  dealii::QGauss<dim-1> face_quad_Gauss_Legendre (integration_strength);
188  face_quad = face_quad_Gauss_Legendre;
189  } else {
190  dealii::QGaussLobatto<dim-1> face_quad_Gauss_Lobatto (integration_strength);
191  face_quad = face_quad_Gauss_Lobatto;
192  }
193 
194  volume_quad_coll.push_back (volume_quad);
195  face_quad_coll.push_back (face_quad);
196  oneD_quad_coll.push_back (oneD_quad);
197 
198  dealii::FE_DGQArbitraryNodes<dim,dim> lagrange_poly(oneD_quad);
199  fe_coll_lagr.push_back (lagrange_poly);
200 
201  dealii::FE_DGQArbitraryNodes<1,1> lagrange_poly_1D(oneD_quad);
202  fe_coll_lagr_1D.push_back (lagrange_poly_1D);
203  }
204 
205  int minimum_degree = (flux_nodes_type==FluxNodes::GLL) ? 1 : 0;
206  for (unsigned int degree=minimum_degree; degree<=max_degree; ++degree) {
207 
208  // Solution FECollection
209  const dealii::FE_DGQ<dim> fe_dg(degree);
210  const dealii::FESystem<dim,dim> fe_system(fe_dg, nstate);
211  fe_coll.push_back (fe_system);
212 
213  const dealii::FE_DGQ<1> fe_dg_1D(degree);
214  const dealii::FESystem<1,1> fe_system_1D(fe_dg_1D, nstate);
215  fe_coll_1D.push_back (fe_system_1D);
216  const dealii::FESystem<1,1> fe_system_1D_1state(fe_dg_1D, 1);
217  fe_coll_1D_1state.push_back (fe_system_1D_1state);
218 
219  const unsigned int integration_strength = degree+1+overintegration;
220 
221  dealii::Quadrature<1> oneD_quad(integration_strength);
222  dealii::Quadrature<dim> volume_quad(integration_strength);
223  dealii::Quadrature<dim-1> face_quad(integration_strength); //removed const
224 
225  if (flux_nodes_type==FluxNodes::GLL) {
226  dealii::QGaussLobatto<1> oneD_quad_Gauss_Lobatto (integration_strength);
227  dealii::QGaussLobatto<dim> vol_quad_Gauss_Lobatto (integration_strength);
228  oneD_quad = oneD_quad_Gauss_Lobatto;
229  volume_quad = vol_quad_Gauss_Lobatto;
230 
231  if(dim == 1)
232  {
233  dealii::QGauss<dim-1> face_quad_Gauss_Legendre (integration_strength);
234  face_quad = face_quad_Gauss_Legendre;
235  }
236  else
237  {
238  dealii::QGaussLobatto<dim-1> face_quad_Gauss_Lobatto (integration_strength);
239  face_quad = face_quad_Gauss_Lobatto;
240  }
241  } else if(flux_nodes_type==FluxNodes::GL) {
242  dealii::QGauss<1> oneD_quad_Gauss_Legendre (integration_strength);
243  dealii::QGauss<dim> vol_quad_Gauss_Legendre (integration_strength);
244  dealii::QGauss<dim-1> face_quad_Gauss_Legendre (integration_strength);
245  oneD_quad = oneD_quad_Gauss_Legendre;
246  volume_quad = vol_quad_Gauss_Legendre;
247  face_quad = face_quad_Gauss_Legendre;
248  }
249 
250  volume_quad_coll.push_back (volume_quad);
251  face_quad_coll.push_back (face_quad);
252  oneD_quad_coll.push_back (oneD_quad);
253 
254  dealii::FE_DGQArbitraryNodes<dim,dim> lagrange_poly(oneD_quad);
255  fe_coll_lagr.push_back (lagrange_poly);
256 
257  dealii::FE_DGQArbitraryNodes<1,1> lagrange_poly_1d(oneD_quad);
258  fe_coll_lagr_1D.push_back (lagrange_poly_1d);
259  }
260  return std::make_tuple(fe_coll, volume_quad_coll, face_quad_coll, fe_coll_lagr, fe_coll_1D, fe_coll_1D_1state, fe_coll_lagr_1D, oneD_quad_coll);
261 }
262 
263 
264 template <int dim, typename real, typename MeshType>
265 void DGBase<dim,real,MeshType>::time_scale_solution_update ( dealii::LinearAlgebra::distributed::Vector<double> &solution_update, const real CFL ) const
266 {
267  std::vector<dealii::types::global_dof_index> dofs_indices;
268 
269  for (auto cell = dof_handler.begin_active(); cell != dof_handler.end(); ++cell) {
270 
271  if (!cell->is_locally_owned()) continue;
272 
273 
274  const int i_fele = cell->active_fe_index();
275  const dealii::FESystem<dim,dim> &fe_ref = fe_collection[i_fele];
276  const unsigned int n_dofs_cell = fe_ref.n_dofs_per_cell();
277 
278  dofs_indices.resize(n_dofs_cell);
279  cell->get_dof_indices (dofs_indices);
280 
281  const dealii::types::global_dof_index cell_index = cell->active_cell_index();
282 
283  const real dt = CFL * max_dt_cell[cell_index];
284  for (unsigned int idof = 0; idof < n_dofs_cell; ++idof) {
285  const dealii::types::global_dof_index dof_index = dofs_indices[idof];
286  solution_update[dof_index] *= dt;
287  }
288  }
289 }
290 
291 
292 template <int dim, typename real, typename MeshType>
293 void DGBase<dim,real,MeshType>::set_all_cells_fe_degree ( const unsigned int degree )
294 {
295  triangulation->prepare_coarsening_and_refinement();
296  for (auto cell = dof_handler.begin_active(); cell != dof_handler.end(); ++cell)
297  {
298  if (cell->is_locally_owned()) cell->set_future_fe_index (degree);
299  }
300 
301  triangulation->execute_coarsening_and_refinement();
302 }
303 
304 template <int dim, typename real, typename MeshType>
306 {
307  unsigned int max_fe_degree = 0;
308 
309  for(auto cell = dof_handler.begin_active(); cell != dof_handler.end(); ++cell)
310  if(cell->is_locally_owned() && cell->active_fe_index() > max_fe_degree)
311  max_fe_degree = cell->active_fe_index();
312 
313  return dealii::Utilities::MPI::max(max_fe_degree, MPI_COMM_WORLD);
314 }
315 
316 template <int dim, typename real, typename MeshType>
318 {
319  unsigned int min_fe_degree = max_degree;
320 
321  for(auto cell = dof_handler.begin_active(); cell != dof_handler.end(); ++cell)
322  if(cell->is_locally_owned() && cell->active_fe_index() < min_fe_degree)
323  min_fe_degree = cell->active_fe_index();
324 
325  return dealii::Utilities::MPI::min(min_fe_degree, MPI_COMM_WORLD);
326 }
327 
328 template <int dim, typename real, typename MeshType>
329 dealii::Point<dim> DGBase<dim,real,MeshType>::coordinates_of_highest_refined_cell(bool check_for_p_refined_cell)
330 {
331  const int iproc = dealii::Utilities::MPI::this_mpi_process(mpi_communicator);
332  const dealii::Point<dim> unit_vertex = dealii::GeometryInfo<dim>::unit_cell_vertex(0);
333  double current_cell_diameter;
334  double min_diameter_local = high_order_grid->dof_handler_grid.begin_active()->diameter();
335  int max_cell_polynomial_order = 0;
336  int current_cell_polynomial_order = 0;
337  dealii::Point<dim> refined_cell_coord;
338 
339  if(check_for_p_refined_cell)
340  {
341  for (const auto &cell : dof_handler.active_cell_iterators())
342  {
343  if(!cell->is_locally_owned()) continue;
344  current_cell_polynomial_order = cell->active_fe_index();
345  if ((current_cell_polynomial_order > max_cell_polynomial_order) && (cell->is_locally_owned()))
346  {
347  max_cell_polynomial_order = current_cell_polynomial_order;
348  refined_cell_coord = cell->center();
349  }
350  }
351  }
352  else
353  {
354  for (const auto &cell : high_order_grid->dof_handler_grid.active_cell_iterators())
355  {
356  if(!cell->is_locally_owned()) continue;
357  current_cell_diameter = cell->diameter(); // For future dealii version: current_cell_diameter = cell->diameter(*(mapping_fe_field));
358  if ((min_diameter_local > current_cell_diameter) && (cell->is_locally_owned()))
359  {
360  min_diameter_local = current_cell_diameter;
361  refined_cell_coord = high_order_grid->mapping_fe_field->transform_unit_to_real_cell(cell, unit_vertex);
362  }
363  }
364  }
365 
366  dealii::Utilities::MPI::MinMaxAvg indexstore;
367  int processor_containing_refined_cell;
368 
369  if(check_for_p_refined_cell)
370  {
371  indexstore = dealii::Utilities::MPI::min_max_avg(max_cell_polynomial_order, mpi_communicator);
372  processor_containing_refined_cell = indexstore.max_index;
373  }
374  else
375  {
376  indexstore = dealii::Utilities::MPI::min_max_avg(min_diameter_local, mpi_communicator);
377  processor_containing_refined_cell = indexstore.min_index;
378  }
379 
380  double global_point[dim];
381 
382  if (iproc == processor_containing_refined_cell)
383  {
384  for (int i=0; i<dim; i++)
385  global_point[i] = refined_cell_coord[i];
386  }
387 
388  MPI_Bcast(global_point, dim, MPI_DOUBLE, processor_containing_refined_cell, mpi_communicator); // Update values in all processors
389 
390  for (int i=0; i<dim; i++)
391  refined_cell_coord[i] = global_point[i];
392 
393  return refined_cell_coord;
394  }
395 
396 template <int dim, typename real, typename MeshType>
397 template<typename DoFCellAccessorType>
399  const DoFCellAccessorType &cell,
400  const int iface,
401  const dealii::hp::FECollection<dim> fe_collection) const
402 {
403 
404  const unsigned int fe_index = cell->active_fe_index();
405  const unsigned int degree = fe_collection[fe_index].tensor_degree();
406  const unsigned int degsq = (degree == 0) ? 1 : degree * (degree+1);
407 
408  const unsigned int normal_direction = dealii::GeometryInfo<dim>::unit_normal_direction[iface];
409  const real vol_div_facearea = cell->extent_in_direction(normal_direction);
410 
411  const real penalty = degsq / vol_div_facearea * this->all_parameters->sipg_penalty_factor;// * 20;
412 
413  return penalty;
414 }
415 
416 template <int dim, typename real, typename MeshType>
417 template<typename DoFCellAccessorType1, typename DoFCellAccessorType2>
419  const DoFCellAccessorType1 &current_cell,
420  const DoFCellAccessorType2 &neighbor_cell) const
421 {
422  if (neighbor_cell->has_children()) {
423  // Only happens in 1D where neither faces have children, but neighbor has some children
424  // Can't do the computation now since we need to query the children's DoF
425  AssertDimension(dim,1);
426  return false;
427  } else if (neighbor_cell->is_ghost()) {
428  // In the case the neighbor is a ghost cell, we let the processor with the lower rank do the work on that face
429  // We cannot use the cell->index() because the index is relative to the distributed triangulation
430  // Therefore, the cell index of a ghost cell might be different to the physical cell index even if they refer to the same cell
431  return (current_cell->subdomain_id() < neighbor_cell->subdomain_id());
432  //return true;
433  } else {
434  // Locally owned neighbor cell
435  Assert(neighbor_cell->is_locally_owned(), dealii::ExcMessage("If not ghost, neighbor should be locally owned."));
436 
437  if (current_cell->index() < neighbor_cell->index()) {
438  // Cell with lower index does work
439  return true;
440  } else if (neighbor_cell->index() == current_cell->index()) {
441  // If both cells have same index
442  // See https://www.dealii.org/developer/doxygen/deal.II/classTriaAccessorBase.html#a695efcbe84fefef3e4c93ee7bdb446ad
443  // then cell at the lower level does the work
444  return (current_cell->level() < neighbor_cell->level());
445  }
446  return false;
447  }
448  Assert(0==1, dealii::ExcMessage("Should not have reached here. Somehow another possible case has not been considered when two cells have the same coarseness."));
449  return false;
450 }
451 
452 template <int dim, typename real, typename MeshType>
453 template<typename DoFCellAccessorType1, typename DoFCellAccessorType2>
455  const DoFCellAccessorType1 &current_cell,
456  const DoFCellAccessorType2 &current_metric_cell,
457  const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R,
458  dealii::hp::FEValues<dim,dim> &fe_values_collection_volume,
459  dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_int,
460  dealii::hp::FEFaceValues<dim,dim> &fe_values_collection_face_ext,
461  dealii::hp::FESubfaceValues<dim,dim> &fe_values_collection_subface,
462  dealii::hp::FEValues<dim,dim> &fe_values_collection_volume_lagrange,
468  OPERATOR::vol_projection_operator<dim,2*dim,real> &soln_basis_projection_oper_int,
469  OPERATOR::vol_projection_operator<dim,2*dim,real> &soln_basis_projection_oper_ext,
471  const bool compute_auxiliary_right_hand_side,
472  dealii::LinearAlgebra::distributed::Vector<double> &rhs,
473  std::array<dealii::LinearAlgebra::distributed::Vector<double>,dim> &rhs_aux)
474 {
475  std::vector<dealii::types::global_dof_index> current_dofs_indices;
476  std::vector<dealii::types::global_dof_index> neighbor_dofs_indices;
477 
478  // Current reference element related to this physical cell
479  const int i_fele = current_cell->active_fe_index();
480 
481  const dealii::FESystem<dim,dim> &current_fe_ref = fe_collection[i_fele];
482  const unsigned int n_dofs_curr_cell = current_fe_ref.n_dofs_per_cell();
483 
484  // Local vector contribution from each cell
485  dealii::Vector<real> current_cell_rhs (n_dofs_curr_cell); // Defaults to 0.0 initialization
486  // Local vector contribution from each cell for Auxiliary equations
487  std::vector<dealii::Tensor<1,dim,double>> current_cell_rhs_aux (n_dofs_curr_cell);// Defaults to 0.0 initialization
488 
489  // Obtain the mapping from local dof indices to global dof indices
490  current_dofs_indices.resize(n_dofs_curr_cell);
491  current_cell->get_dof_indices (current_dofs_indices);
492 
493  const unsigned int grid_degree = this->high_order_grid->fe_system.tensor_degree();
494  const unsigned int poly_degree = i_fele;
495 
496  const unsigned int n_metric_dofs_cell = high_order_grid->fe_system.dofs_per_cell;
497  std::vector<dealii::types::global_dof_index> current_metric_dofs_indices(n_metric_dofs_cell);
498  std::vector<dealii::types::global_dof_index> neighbor_metric_dofs_indices(n_metric_dofs_cell);
499  current_metric_cell->get_dof_indices (current_metric_dofs_indices);
500 
501  const dealii::types::global_dof_index current_cell_index = current_cell->active_cell_index();
502 
503  std::array<std::vector<real>,dim> mapping_support_points;
504  //if have source term need to store vol flux nodes.
506  //for boundary conditions not periodic we need surface flux nodes
507  //should change this flag to something like if have face on boundary not periodic in the future
508  const bool store_surf_flux_nodes = (all_parameters->use_periodic_bc) ? false : true;
509  OPERATOR::metric_operators<real,dim,2*dim> metric_oper_int(nstate, poly_degree, grid_degree,
510  store_vol_flux_nodes,
511  store_surf_flux_nodes);
512 
513  //flag to terminate if strong form and implicit
514  if((this->all_parameters->use_weak_form==false)
515  && (this->all_parameters->ode_solver_param.ode_solver_type
516  == Parameters::ODESolverParam::ODESolverEnum::implicit_solver))
517  {
518  pcout<<"ERROR: Implicit does not currently work for strong form. Aborting..."<<std::endl;
519  std::abort();
520  }
521 
522 
524  current_cell,
525  current_cell_index,
526  current_dofs_indices,
527  current_metric_dofs_indices,
528  poly_degree,
529  grid_degree,
530  soln_basis_int,
531  flux_basis_int,
532  flux_basis_stiffness,
533  soln_basis_projection_oper_int,
534  soln_basis_projection_oper_ext,
535  metric_oper_int,
536  mapping_basis,
537  mapping_support_points,
538  fe_values_collection_volume,
539  fe_values_collection_volume_lagrange,
540  current_fe_ref,
541  current_cell_rhs,
542  current_cell_rhs_aux,
543  compute_auxiliary_right_hand_side,
544  compute_dRdW, compute_dRdX, compute_d2R);
545 
546  (void) fe_values_collection_face_int;
547  (void) fe_values_collection_face_ext;
548  (void) fe_values_collection_subface;
549  for (unsigned int iface=0; iface < dealii::GeometryInfo<dim>::faces_per_cell; ++iface) {
550 
551  auto current_face = current_cell->face(iface);
552 
553  // CASE 1: FACE AT BOUNDARY
554  if ((current_face->at_boundary() && !current_cell->has_periodic_neighbor(iface)))
555  {
556  const real penalty = evaluate_penalty_scaling (current_cell, iface, fe_collection);
557 
558  const unsigned int boundary_id = current_face->boundary_id();
559 
561  current_cell,
562  current_cell_index,
563  iface,
564  boundary_id,
565  penalty,
566  current_dofs_indices,
567  current_metric_dofs_indices,
568  poly_degree,
569  grid_degree,
570  soln_basis_int,
571  flux_basis_int,
572  flux_basis_stiffness,
573  soln_basis_projection_oper_int,
574  soln_basis_projection_oper_ext,
575  metric_oper_int,
576  mapping_basis,
577  mapping_support_points,
578  fe_values_collection_face_int,
579  current_fe_ref,
580  current_cell_rhs,
581  current_cell_rhs_aux,
582  compute_auxiliary_right_hand_side,
583  compute_dRdW, compute_dRdX, compute_d2R);
584 
585  }
586  // CASE 2: PERIODIC BOUNDARY CONDITIONS
587  // NOTE: Periodicity is not adapted for hp adaptivity yet. this needs to be figured out in the future
588  else if (current_face->at_boundary() && current_cell->has_periodic_neighbor(iface))
589  {
590 
591  const auto neighbor_cell = current_cell->periodic_neighbor(iface);
592 
593  if (!current_cell->periodic_neighbor_is_coarser(iface) && current_cell_should_do_the_work(current_cell, neighbor_cell))
594  {
595  Assert (current_cell->periodic_neighbor(iface).state() == dealii::IteratorState::valid, dealii::ExcInternalError());
596 
597  const unsigned int n_dofs_neigh_cell = fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell();
598  dealii::Vector<real> neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization
599 
600  // Obtain the mapping from local dof indices to global dof indices for neighbor cell
601  neighbor_dofs_indices.resize(n_dofs_neigh_cell);
602  neighbor_cell->get_dof_indices (neighbor_dofs_indices);
603 
604  // Corresponding face of the neighbor.
605  const unsigned int neighbor_iface = current_cell->periodic_neighbor_of_periodic_neighbor(iface);
606 
607  const int i_fele_n = neighbor_cell->active_fe_index();
608 
609  // Compute penalty.
610  const real penalty1 = evaluate_penalty_scaling (current_cell, iface, fe_collection);
611  const real penalty2 = evaluate_penalty_scaling (neighbor_cell, neighbor_iface, fe_collection);
612  const real penalty = 0.5 * (penalty1 + penalty2);
613 
614  const dealii::types::global_dof_index neighbor_cell_index = neighbor_cell->active_cell_index();
615  const auto metric_neighbor_cell = current_metric_cell->periodic_neighbor(iface);
616  metric_neighbor_cell->get_dof_indices(neighbor_metric_dofs_indices);
617 
618  const unsigned int poly_degree_ext = i_fele_n;
619  const unsigned int grid_degree_ext = this->high_order_grid->fe_system.tensor_degree();
620  //constructor doesn't build anything
621  OPERATOR::metric_operators<real,dim,2*dim> metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext,
622  store_vol_flux_nodes,
623  store_surf_flux_nodes);
624 
626  current_cell,
627  neighbor_cell,
628  current_cell_index,
629  neighbor_cell_index,
630  iface,
631  neighbor_iface,
632  penalty,
633  current_dofs_indices,
634  neighbor_dofs_indices,
635  current_metric_dofs_indices,
636  neighbor_metric_dofs_indices,
637  poly_degree,
638  poly_degree_ext,
639  grid_degree,
640  grid_degree_ext,
641  soln_basis_int,
642  soln_basis_ext,
643  flux_basis_int,
644  flux_basis_ext,
645  flux_basis_stiffness,
646  soln_basis_projection_oper_int,
647  soln_basis_projection_oper_ext,
648  metric_oper_int,
649  metric_oper_ext,
650  mapping_basis,
651  mapping_support_points,
652  fe_values_collection_face_int,
653  fe_values_collection_face_ext,
654  current_cell_rhs,
655  neighbor_cell_rhs,
656  current_cell_rhs_aux,
657  rhs,
658  rhs_aux,
659  compute_auxiliary_right_hand_side,
660  compute_dRdW, compute_dRdX, compute_d2R);
661  }
662  }
663  // CASE 3: NEIGHBOUR IS FINER
664  // Occurs if the face has children
665  else if (current_cell->face(iface)->has_children())
666  {
667  // Do nothing.
668  // The face contribution from the current cell will appear then the finer neighbor cell is assembled.
669  }
670  // CASE 4: NEIGHBOR IS COARSER
671  // Assemble face residual.
672  else if (current_cell->neighbor(iface)->face(current_cell->neighbor_face_no(iface))->has_children())
673  {
674  Assert (current_cell->neighbor(iface).state() == dealii::IteratorState::valid, dealii::ExcInternalError());
675  Assert (!(current_cell->neighbor(iface)->has_children()), dealii::ExcInternalError());
676 
677  // Obtain cell neighbour
678  const auto neighbor_cell = current_cell->neighbor(iface);
679  const unsigned int neighbor_iface = current_cell->neighbor_face_no(iface);
680 
681  // Find corresponding subface
682  unsigned int neighbor_i_subface = 0;
683  unsigned int n_subface = dealii::GeometryInfo<dim>::n_subfaces(neighbor_cell->subface_case(neighbor_iface));
684 
685  for (; neighbor_i_subface < n_subface; ++neighbor_i_subface) {
686  if (neighbor_cell->neighbor_child_on_subface (neighbor_iface, neighbor_i_subface) == current_cell) {
687  break;
688  }
689  }
690  Assert(neighbor_i_subface != n_subface, dealii::ExcInternalError());
691 
692  const int i_fele_n = neighbor_cell->active_fe_index();//, i_quad_n = i_fele_n, i_mapp_n = 0;
693 
694  const unsigned int n_dofs_neigh_cell = fe_collection[i_fele_n].n_dofs_per_cell();
695  dealii::Vector<real> neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization
696 
697  // Obtain the mapping from local dof indices to global dof indices for neighbor cell
698  neighbor_dofs_indices.resize(n_dofs_neigh_cell);
699  neighbor_cell->get_dof_indices (neighbor_dofs_indices);
700 
701  const real penalty1 = evaluate_penalty_scaling (current_cell, iface, fe_collection);
702  const real penalty2 = evaluate_penalty_scaling (neighbor_cell, neighbor_iface, fe_collection);
703  const real penalty = 0.5 * (penalty1 + penalty2);
704 
705  const dealii::types::global_dof_index neighbor_cell_index = neighbor_cell->active_cell_index();
706  const auto metric_neighbor_cell = current_metric_cell->neighbor(iface);
707  metric_neighbor_cell->get_dof_indices(neighbor_metric_dofs_indices);
708 
709  const unsigned int poly_degree_ext = i_fele_n;
710  const unsigned int grid_degree_ext = this->high_order_grid->fe_system.tensor_degree();
711  //Check if the poly degree or mapping changed order, in which case, then we re-compute the corresponding basis
712  OPERATOR::metric_operators<real,dim,2*dim> metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext,
713  store_vol_flux_nodes,
714  store_surf_flux_nodes);
715 
717  current_cell,
718  neighbor_cell,
719  current_cell_index,
720  neighbor_cell_index,
721  iface,
722  neighbor_iface,
723  neighbor_i_subface,
724  penalty,
725  current_dofs_indices,
726  neighbor_dofs_indices,
727  current_metric_dofs_indices,
728  neighbor_metric_dofs_indices,
729  poly_degree,
730  poly_degree_ext,
731  grid_degree,
732  grid_degree_ext,
733  soln_basis_int,
734  soln_basis_ext,
735  flux_basis_int,
736  flux_basis_ext,
737  flux_basis_stiffness,
738  soln_basis_projection_oper_int,
739  soln_basis_projection_oper_ext,
740  metric_oper_int,
741  metric_oper_ext,
742  mapping_basis,
743  mapping_support_points,
744  fe_values_collection_face_int,
745  fe_values_collection_subface,
746  current_cell_rhs,
747  neighbor_cell_rhs,
748  current_cell_rhs_aux,
749  rhs,
750  rhs_aux,
751  compute_auxiliary_right_hand_side,
752  compute_dRdW, compute_dRdX, compute_d2R);
753  }
754  // CASE 5: NEIGHBOR CELL HAS SAME COARSENESS
755  // Therefore, we need to choose one of them to do the work
756  else if (current_cell_should_do_the_work(current_cell, current_cell->neighbor(iface)))
757  {
758  Assert (current_cell->neighbor(iface).state() == dealii::IteratorState::valid, dealii::ExcInternalError());
759 
760  const auto neighbor_cell = current_cell->neighbor_or_periodic_neighbor(iface);
761  // Corresponding face of the neighbor.
762  // e.g. The 4th face of the current cell might correspond to the 3rd face of the neighbor
763  const unsigned int neighbor_iface = current_cell->neighbor_of_neighbor(iface);
764 
765  // Get information about neighbor cell
766  const unsigned int n_dofs_neigh_cell = fe_collection[neighbor_cell->active_fe_index()].n_dofs_per_cell();
767 
768  // Local rhs contribution from neighbor
769  dealii::Vector<real> neighbor_cell_rhs (n_dofs_neigh_cell); // Defaults to 0.0 initialization
770 
771  // Obtain the mapping from local dof indices to global dof indices for neighbor cell
772  neighbor_dofs_indices.resize(n_dofs_neigh_cell);
773  neighbor_cell->get_dof_indices (neighbor_dofs_indices);
774 
775  const int i_fele_n = neighbor_cell->active_fe_index();
776 
777  // Compute penalty.
778  const real penalty1 = evaluate_penalty_scaling (current_cell, iface, fe_collection);
779  const real penalty2 = evaluate_penalty_scaling (neighbor_cell, neighbor_iface, fe_collection);
780  const real penalty = 0.5 * (penalty1 + penalty2);
781 
782  const dealii::types::global_dof_index neighbor_cell_index = neighbor_cell->active_cell_index();
783  const auto metric_neighbor_cell = current_metric_cell->neighbor_or_periodic_neighbor(iface);
784  metric_neighbor_cell->get_dof_indices(neighbor_metric_dofs_indices);
785 
786  const unsigned int poly_degree_ext = i_fele_n;
787  // In future high_order_grids dof object/metric_cell should store the cell's fe degree.
788  // For now high_order_grid only handles all cells of same grid degree.
789  const unsigned int grid_degree_ext = this->high_order_grid->fe_system.tensor_degree();
790  //Check if the poly degree or mapping changed order, in which case, then we re-compute the corresponding basis
791  OPERATOR::metric_operators<real,dim,2*dim> metric_oper_ext(nstate, poly_degree_ext, grid_degree_ext,
792  store_vol_flux_nodes,
793  store_surf_flux_nodes);
794 
796  current_cell,
797  neighbor_cell,
798  current_cell_index,
799  neighbor_cell_index,
800  iface,
801  neighbor_iface,
802  penalty,
803  current_dofs_indices,
804  neighbor_dofs_indices,
805  current_metric_dofs_indices,
806  neighbor_metric_dofs_indices,
807  poly_degree,
808  poly_degree_ext,
809  grid_degree,
810  grid_degree_ext,
811  soln_basis_int,
812  soln_basis_ext,
813  flux_basis_int,
814  flux_basis_ext,
815  flux_basis_stiffness,
816  soln_basis_projection_oper_int,
817  soln_basis_projection_oper_ext,
818  metric_oper_int,
819  metric_oper_ext,
820  mapping_basis,
821  mapping_support_points,
822  fe_values_collection_face_int,
823  fe_values_collection_face_ext,
824  current_cell_rhs,
825  neighbor_cell_rhs,
826  current_cell_rhs_aux,
827  rhs,
828  rhs_aux,
829  compute_auxiliary_right_hand_side,
830  compute_dRdW, compute_dRdX, compute_d2R);
831  }
832  else {
833  // Should be faces where the neighbor cell has the same coarseness
834  // but will be evaluated when we visit the other cell.
835  }
836  } // end of face loop
837 
838  if(compute_auxiliary_right_hand_side) {
839  // Add local contribution from current cell to global vector
840  for (unsigned int i=0; i<n_dofs_curr_cell; ++i) {
841  for(int idim=0; idim<dim; idim++){
842  rhs_aux[idim][current_dofs_indices[i]] += current_cell_rhs_aux[i][idim];
843  }
844  }
845  }
846  else {
847  // Add local contribution from current cell to global vector
848  for (unsigned int i=0; i<n_dofs_curr_cell; ++i) {
849  rhs[current_dofs_indices[i]] += current_cell_rhs[i];
850  }
851  }
852 }
853 
854 template <int dim, typename real, typename MeshType>
855 void DGBase<dim,real,MeshType>::set_dual(const dealii::LinearAlgebra::distributed::Vector<real> &dual_input)
856 {
857  dual = dual_input;
858 }
859 
860 template <int dim, typename real, typename MeshType>
862 {
863  const auto mapping = (*(high_order_grid->mapping_fe_field));
864  dealii::hp::MappingCollection<dim> mapping_collection(mapping);
865  const dealii::UpdateFlags update_flags = dealii::update_values | dealii::update_JxW_values;
866  dealii::hp::FEValues<dim,dim> fe_values_collection_volume (mapping_collection, fe_collection, volume_quadrature_collection, update_flags);
867 
868  std::vector< double > soln_coeff_high;
869  std::vector<dealii::types::global_dof_index> dof_indices;
870 
871  const unsigned int n_dofs_arti_diss = fe_q_artificial_dissipation.dofs_per_cell;
872  std::vector<dealii::types::global_dof_index> dof_indices_artificial_dissipation(n_dofs_arti_diss);
873 
874  if (freeze_artificial_dissipation) return;
876  for (auto cell : dof_handler.active_cell_iterators()) {
877  if (!(cell->is_locally_owned() || cell->is_ghost())) continue;
878 
879  dealii::types::global_dof_index cell_index = cell->active_cell_index();
880  artificial_dissipation_coeffs[cell_index] = 0.0;
881  artificial_dissipation_se[cell_index] = 0.0;
882  //artificial_dissipation_coeffs[cell_index] = 1e-2;
883  //artificial_dissipation_se[cell_index] = 0.0;
884  //continue;
885 
886  const int i_fele = cell->active_fe_index();
887  const int i_quad = i_fele;
888  const int i_mapp = 0;
889 
890  const dealii::FESystem<dim,dim> &fe_high = fe_collection[i_fele];
891  const unsigned int degree = fe_high.tensor_degree();
892 
893  if (degree == 0) continue;
894 
895  const unsigned int nstate = fe_high.components;
896  const unsigned int n_dofs_high = fe_high.dofs_per_cell;
897 
898  fe_values_collection_volume.reinit (cell, i_quad, i_mapp, i_fele);
899  const dealii::FEValues<dim,dim> &fe_values_volume = fe_values_collection_volume.get_present_fe_values();
900 
901  dof_indices.resize(n_dofs_high);
902  cell->get_dof_indices (dof_indices);
903 
904  soln_coeff_high.resize(n_dofs_high);
905  for (unsigned int idof=0; idof<n_dofs_high; ++idof) {
906  soln_coeff_high[idof] = solution[dof_indices[idof]];
907  }
908 
909  // Lower degree basis.
910  const unsigned int lower_degree = degree-1;
911  const dealii::FE_DGQLegendre<dim> fe_dgq_lower(lower_degree);
912  const dealii::FESystem<dim,dim> fe_lower(fe_dgq_lower, nstate);
913 
914  // Projection quadrature.
915  const dealii::QGauss<dim> projection_quadrature(degree+5);
916  std::vector< double > soln_coeff_lower = project_function<dim,double>( soln_coeff_high, fe_high, fe_lower, projection_quadrature);
917 
918  // Quadrature used for solution difference.
919  const dealii::Quadrature<dim> &quadrature = fe_values_volume.get_quadrature();
920  const std::vector<dealii::Point<dim,double>> &unit_quad_pts = quadrature.get_points();
921 
922  const unsigned int n_quad_pts = quadrature.size();
923  const unsigned int n_dofs_lower = fe_lower.dofs_per_cell;
924 
925  double element_volume = 0.0;
926  double error = 0.0;
927  double soln_norm = 0.0;
928  std::vector<double> soln_high(nstate);
929  std::vector<double> soln_lower(nstate);
930  for (unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
931  for (unsigned int s=0; s<nstate; ++s) {
932  soln_high[s] = 0.0;
933  soln_lower[s] = 0.0;
934  }
935  // Interpolate solution
936  for (unsigned int idof=0; idof<n_dofs_high; ++idof) {
937  const unsigned int istate = fe_high.system_to_component_index(idof).first;
938  soln_high[istate] += soln_coeff_high[idof] * fe_high.shape_value_component(idof,unit_quad_pts[iquad],istate);
939  }
940  // Interpolate low order solution
941  for (unsigned int idof=0; idof<n_dofs_lower; ++idof) {
942  const unsigned int istate = fe_lower.system_to_component_index(idof).first;
943  soln_lower[istate] += soln_coeff_lower[idof] * fe_lower.shape_value_component(idof,unit_quad_pts[iquad],istate);
944  }
945  // Quadrature
946  element_volume += fe_values_volume.JxW(iquad);
947  // Only integrate over the first state variable.
948  for (unsigned int s=0; s<1/*nstate*/; ++s)
949  {
950  error += (soln_high[s] - soln_lower[s]) * (soln_high[s] - soln_lower[s]) * fe_values_volume.JxW(iquad);
951  soln_norm += soln_high[s] * soln_high[s] * fe_values_volume.JxW(iquad);
952  }
953  }
954 
955  //std::cout << " error: " << error
956  // << " soln_norm: " << soln_norm << std::endl;
957  //if (error < 1e-12) continue;
958  if (soln_norm < 1e-12)
959  {
960  continue;
961  }
962 
963  double S_e, s_e;
964  S_e = sqrt(error / soln_norm);
965  s_e = log10(S_e);
966 
967  //const double mu_scale = 1.0;
968  //const double s_0 = log10(0.1) - 4.25*log10(degree);
969  //const double s_0 = -0.5 - 4.25*log10(degree);
970  //const double kappa = 1.0;
971 
973  //const double s_0 = - 4.25*log10(degree);
974  const double s_0 = -0.00 - 4.00*log10(degree);
976  const double low = s_0 - kappa;
977  const double upp = s_0 + kappa;
978 
979  const double diameter = std::pow(element_volume, 1.0/dim);
980  const double eps_0 = mu_scale * diameter / (double)degree;
981 
982  //std::cout << " lower < s_e < upp " << low << " < " << s_e << " < " << upp << " ? " << std::endl;
983 
984  if ( s_e < low) continue;
985 
986  if ( s_e > upp) {
987  artificial_dissipation_coeffs[cell_index] += eps_0;
989  {
991  }
992  continue;
993  }
994 
995  const double PI = 4*atan(1);
996  double eps = 1.0 + sin(PI * (s_e - s_0) * 0.5 / kappa);
997  eps *= eps_0 * 0.5;
998 
1000  {
1002  }
1003 
1004 
1005  artificial_dissipation_coeffs[cell_index] += eps;
1006  artificial_dissipation_se[cell_index] = s_e;
1007 
1008  typename dealii::DoFHandler<dim>::active_cell_iterator artificial_dissipation_cell(
1009  triangulation.get(), cell->level(), cell->index(), &dof_handler_artificial_dissipation);
1010 
1011  dof_indices_artificial_dissipation.resize(n_dofs_arti_diss);
1012  artificial_dissipation_cell->get_dof_indices (dof_indices_artificial_dissipation);
1013  for (unsigned int idof=0; idof<n_dofs_arti_diss; ++idof) {
1014  const unsigned int index = dof_indices_artificial_dissipation[idof];
1015  artificial_dissipation_c0[index] = std::max(artificial_dissipation_c0[index], eps);
1016  }
1017 
1018  //const unsigned int dofs_per_face = fe_q_artificial_dissipation.n_dofs_per_face();
1019  //for (unsigned int iface=0; iface < dealii::GeometryInfo<dim>::faces_per_cell; ++iface) {
1020  // const auto face = cell->face(iface);
1021  // if (face->at_boundary()) {
1022  // for (unsigned int idof_face=0; idof_face<dofs_per_face; ++idof_face) {
1023  // unsigned int idof_cell = fe_q_artificial_dissipation.face_to_cell_index(idof_face, iface);
1024  // const dealii::types::global_dof_index index = dof_indices_artificial_dissipation[idof_cell];
1025  // artificial_dissipation_c0[index] = 0.0;
1026  // }
1027  // }
1028  //}
1029  }
1030  dealii::IndexSet boundary_dofs(dof_handler_artificial_dissipation.n_dofs());
1031  dealii::DoFTools::extract_boundary_dofs(dof_handler_artificial_dissipation,
1032  dealii::ComponentMask(),
1033  boundary_dofs);
1034  for (unsigned int i = 0; i < dof_handler_artificial_dissipation.n_dofs(); ++i) {
1035  if (boundary_dofs.is_element(i)) {
1036  artificial_dissipation_c0[i] = 0.0;
1037  }
1038  }
1039  // artificial_dissipation_c0 *= 0.0;
1040  // artificial_dissipation_c0.add(1e-1);
1041  artificial_dissipation_c0.update_ghost_values();
1042 }
1043 
1044 template <int dim, typename real, typename MeshType>
1046  const unsigned int poly_degree_int,
1047  const unsigned int poly_degree_ext,
1048  const unsigned int /*grid_degree*/,
1054  OPERATOR::vol_projection_operator<dim,2*dim,real> &soln_basis_projection_oper_int,
1055  OPERATOR::vol_projection_operator<dim,2*dim,real> &soln_basis_projection_oper_ext,
1057 {
1058  soln_basis_int.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree_int], oneD_quadrature_collection[poly_degree_int]);
1059  soln_basis_int.build_1D_gradient_operator(oneD_fe_collection_1state[poly_degree_int], oneD_quadrature_collection[poly_degree_int]);
1062 
1063  soln_basis_ext.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree_ext], oneD_quadrature_collection[poly_degree_ext]);
1064  soln_basis_ext.build_1D_gradient_operator(oneD_fe_collection_1state[poly_degree_ext], oneD_quadrature_collection[poly_degree_ext]);
1067 
1068  flux_basis_int.build_1D_volume_operator(oneD_fe_collection_flux[poly_degree_int], oneD_quadrature_collection[poly_degree_int]);
1069  flux_basis_int.build_1D_gradient_operator(oneD_fe_collection_flux[poly_degree_int], oneD_quadrature_collection[poly_degree_int]);
1072 
1073  flux_basis_ext.build_1D_volume_operator(oneD_fe_collection_flux[poly_degree_ext], oneD_quadrature_collection[poly_degree_ext]);
1074  flux_basis_ext.build_1D_gradient_operator(oneD_fe_collection_flux[poly_degree_ext], oneD_quadrature_collection[poly_degree_ext]);
1077 
1078  //flux basis stiffness operator for skew-symmetric form
1079  flux_basis_stiffness.build_1D_volume_operator(oneD_fe_collection_flux[poly_degree_int], oneD_quadrature_collection[poly_degree_int]);
1080 
1081  //basis functions projection operator
1082  soln_basis_projection_oper_int.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree_int], oneD_quadrature_collection[poly_degree_int]);
1083  soln_basis_projection_oper_ext.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree_int], oneD_quadrature_collection[poly_degree_int]);
1084 
1085  //We only need to compute the most recent mapping basis since we compute interior before looping faces
1086  mapping_basis.build_1D_shape_functions_at_grid_nodes(high_order_grid->oneD_fe_system, high_order_grid->oneD_grid_nodes);
1088 }
1089 
1090 template <int dim, typename real, typename MeshType>
1091 void DGBase<dim,real,MeshType>::assemble_residual (const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, const double CFL_mass)
1092 {
1093  dealii::deal_II_exceptions::disable_abort_on_exception(); // Allows us to catch negative Jacobians.
1094  Assert( !(compute_dRdW && compute_dRdX)
1095  && !(compute_dRdW && compute_d2R)
1096  && !(compute_dRdX && compute_d2R)
1097  , dealii::ExcMessage("Can only do one at a time compute_dRdW or compute_dRdX or compute_d2R"));
1098 
1100  //pcout << "Assembling DG residual...";
1101  if (compute_dRdW) {
1102  pcout << " with dRdW...";
1103 
1104  auto diff_sol = solution;
1105  diff_sol -= solution_dRdW;
1106  const double l2_norm_sol = diff_sol.l2_norm();
1107 
1108  if (l2_norm_sol == 0.0) {
1109 
1110  auto diff_node = high_order_grid->volume_nodes;
1111  diff_node -= volume_nodes_dRdW;
1112  const double l2_norm_node = diff_node.l2_norm();
1113 
1114  if (l2_norm_node == 0.0) {
1115  if (CFL_mass_dRdW == CFL_mass) {
1116  pcout << " which is already assembled..." << std::endl;
1117  return;
1118  }
1119  }
1120  }
1121  {
1122  int n_stencil = 1 + std::pow(2,dim);
1123  int n_dofs_cell = nstate*std::pow(max_degree+1,dim);
1124  n_vmult += n_stencil*n_dofs_cell;
1125  dRdW_form += 1;
1126  }
1128  volume_nodes_dRdW = high_order_grid->volume_nodes;
1129  CFL_mass_dRdW = CFL_mass;
1130 
1131  system_matrix = 0;
1132  }
1133  if (compute_dRdX) {
1134  pcout << " with dRdX...";
1135 
1136  auto diff_sol = solution;
1137  diff_sol -= solution_dRdX;
1138  const double l2_norm_sol = diff_sol.l2_norm();
1139 
1140  if (l2_norm_sol == 0.0) {
1141 
1142  auto diff_node = high_order_grid->volume_nodes;
1143  diff_node -= volume_nodes_dRdX;
1144  const double l2_norm_node = diff_node.l2_norm();
1145 
1146  if (l2_norm_node == 0.0) {
1147  pcout << " which is already assembled..." << std::endl;
1148  return;
1149  }
1150  }
1152  volume_nodes_dRdX = high_order_grid->volume_nodes;
1153 
1154  if ( dRdXv.m() != solution.size() || dRdXv.n() != high_order_grid->volume_nodes.size()) {
1155 
1156  allocate_dRdX();
1157  }
1158  dRdXv = 0;
1159  }
1160  if (compute_d2R) {
1161  pcout << " with d2RdWdW, d2RdWdX, d2RdXdX...";
1162  auto diff_sol = solution;
1163  diff_sol -= solution_d2R;
1164  const double l2_norm_sol = diff_sol.l2_norm();
1165 
1166  if (l2_norm_sol == 0.0) {
1167 
1168  auto diff_node = high_order_grid->volume_nodes;
1169  diff_node -= volume_nodes_d2R;
1170  const double l2_norm_node = diff_node.l2_norm();
1171 
1172  if (l2_norm_node == 0.0) {
1173 
1174  auto diff_dual = dual;
1175  diff_dual -= dual_d2R;
1176  const double l2_norm_dual = diff_dual.l2_norm();
1177  if (l2_norm_dual == 0.0) {
1178  pcout << " which is already assembled..." << std::endl;
1179  return;
1180  }
1181  }
1182  }
1184  volume_nodes_d2R = high_order_grid->volume_nodes;
1185  dual_d2R = dual;
1186 
1187  if ( d2RdWdW.m() != solution.size()
1188  || d2RdWdX.m() != solution.size()
1189  || d2RdWdX.n() != high_order_grid->volume_nodes.size()
1190  || d2RdXdX.m() != high_order_grid->volume_nodes.size()) {
1191 
1193  }
1194  d2RdWdW = 0;
1195  d2RdWdX = 0;
1196  d2RdXdX = 0;
1197  }
1198  right_hand_side = 0;
1199 
1200 
1201  //const dealii::MappingManifold<dim,dim> mapping;
1202  //const dealii::MappingQ<dim,dim> mapping(10);//;max_degree+1);
1203  //const dealii::MappingQ<dim,dim> mapping(high_order_grid->max_degree);
1204  //const dealii::MappingQGeneric<dim,dim> mapping(high_order_grid->max_degree);
1205  const auto mapping = (*(high_order_grid->mapping_fe_field));
1206 
1207  dealii::hp::MappingCollection<dim> mapping_collection(mapping);
1208 
1209  dealii::hp::FEValues<dim,dim> fe_values_collection_volume (mapping_collection, fe_collection, volume_quadrature_collection, this->volume_update_flags);
1210  dealii::hp::FEFaceValues<dim,dim> fe_values_collection_face_int (mapping_collection, fe_collection, face_quadrature_collection, this->face_update_flags);
1211  dealii::hp::FEFaceValues<dim,dim> fe_values_collection_face_ext (mapping_collection, fe_collection, face_quadrature_collection, this->neighbor_face_update_flags);
1212  dealii::hp::FESubfaceValues<dim,dim> fe_values_collection_subface (mapping_collection, fe_collection, face_quadrature_collection, this->face_update_flags);
1213 
1214  dealii::hp::FEValues<dim,dim> fe_values_collection_volume_lagrange (mapping_collection, fe_collection_lagrange, volume_quadrature_collection, this->volume_update_flags);
1215 
1216  const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree();
1217  OPERATOR::basis_functions<dim,2*dim,real> soln_basis_int(1, max_degree, init_grid_degree);
1218  OPERATOR::basis_functions<dim,2*dim,real> soln_basis_ext(1, max_degree, init_grid_degree);
1219  OPERATOR::basis_functions<dim,2*dim,real> flux_basis_int(1, max_degree, init_grid_degree);
1220  OPERATOR::basis_functions<dim,2*dim,real> flux_basis_ext(1, max_degree, init_grid_degree);
1221  OPERATOR::local_basis_stiffness<dim,2*dim,real> flux_basis_stiffness(1, max_degree, init_grid_degree, true);
1222  OPERATOR::vol_projection_operator<dim,2*dim,real> soln_basis_projection_oper_int(1, max_degree, init_grid_degree);
1223  OPERATOR::vol_projection_operator<dim,2*dim,real> soln_basis_projection_oper_ext(1, max_degree, init_grid_degree);
1224  OPERATOR::mapping_shape_functions<dim,2*dim,real> mapping_basis(1, init_grid_degree, init_grid_degree);
1225 
1227  max_degree, max_degree, init_grid_degree,
1228  soln_basis_int, soln_basis_ext,
1229  flux_basis_int, flux_basis_ext,
1230  flux_basis_stiffness,
1231  soln_basis_projection_oper_int, soln_basis_projection_oper_ext,
1232  mapping_basis);
1233 
1234  solution.update_ghost_values();
1235 
1236 
1237  int assembly_error = 0;
1238  try {
1239 
1240  // update artificial dissipation discontinuity sensor only if using artificial dissipation
1242 
1243  // updates model variables only if there is a model
1244  if(all_parameters->pde_type == Parameters::AllParameters::PartialDifferentialEquation::physics_model) update_model_variables();
1245 
1246  // assembles and solves for auxiliary variable if necessary.
1248 
1249  dealii::Timer timer;
1251  timer.start();
1252  }
1253 
1254  auto metric_cell = high_order_grid->dof_handler_grid.begin_active();
1255  for (auto soln_cell = dof_handler.begin_active(); soln_cell != dof_handler.end(); ++soln_cell, ++metric_cell) {
1256  if (!soln_cell->is_locally_owned()) continue;
1257 
1258  // Add right-hand side contributions this cell can compute
1260  soln_cell,
1261  metric_cell,
1262  compute_dRdW, compute_dRdX, compute_d2R,
1263  fe_values_collection_volume,
1264  fe_values_collection_face_int,
1265  fe_values_collection_face_ext,
1266  fe_values_collection_subface,
1267  fe_values_collection_volume_lagrange,
1268  soln_basis_int,
1269  soln_basis_ext,
1270  flux_basis_int,
1271  flux_basis_ext,
1272  flux_basis_stiffness,
1273  soln_basis_projection_oper_int,
1274  soln_basis_projection_oper_ext,
1275  mapping_basis,
1276  false,
1279  } // end of cell loop
1280 
1282  timer.stop();
1283  assemble_residual_time += timer.cpu_time();
1284  }
1285  } catch(...) {
1286  assembly_error = 1;
1287  }
1288  const int mpi_assembly_error = dealii::Utilities::MPI::sum(assembly_error, mpi_communicator);
1289 
1290 
1291  if (mpi_assembly_error != 0) {
1292  std::cout << "Invalid residual assembly encountered..."
1293  << " Filling up RHS with 1s. " << std::endl;
1294  right_hand_side *= 0.0;
1295  right_hand_side.add(1.0);
1296  if (compute_dRdW) {
1297  std::cout << " Filling up Jacobian with mass matrix. " << std::endl;
1298  const bool do_inverse_mass_matrix = false;
1299  evaluate_mass_matrices (do_inverse_mass_matrix);
1300  system_matrix.copy_from(global_mass_matrix);
1301  }
1302  //if (compute_dRdX) {
1303  // dRdXv.trilinos_matrix().
1304  //}
1305  //if (compute_d2R) {
1306  // d2RdWdW = 0;
1307  // d2RdWdX = 0;
1308  // d2RdXdX = 0;
1309  //}
1310  }
1311 
1312  right_hand_side.compress(dealii::VectorOperation::add);
1313  right_hand_side.update_ghost_values();
1314  if ( compute_dRdW ) {
1315  system_matrix.compress(dealii::VectorOperation::add);
1316 
1317  if (global_mass_matrix.m() != system_matrix.m()) {
1318  const bool do_inverse_mass_matrix = false;
1319  evaluate_mass_matrices (do_inverse_mass_matrix);
1320  }
1321  if (CFL_mass != 0.0) {
1322  time_scaled_mass_matrices(CFL_mass);
1324  }
1325 
1326  Epetra_CrsMatrix *input_matrix = const_cast<Epetra_CrsMatrix *>(&(system_matrix.trilinos_matrix()));
1327  Epetra_CrsMatrix *output_matrix;
1328  epetra_rowmatrixtransposer_dRdW = std::make_unique<Epetra_RowMatrixTransposer> ( input_matrix );
1329  const bool make_data_contiguous = true;
1330  int error_transpose = epetra_rowmatrixtransposer_dRdW->CreateTranspose( make_data_contiguous, output_matrix);
1331  if (error_transpose) {
1332  std::cout << "Failed to create dRdW transpose... Aborting" << std::endl;
1333  //std::abort();
1334  }
1335  bool copy_values = true;
1336  system_matrix_transpose.reinit(*output_matrix, copy_values);
1337  delete(output_matrix);
1338 
1339  }
1340  if ( compute_dRdX ) dRdXv.compress(dealii::VectorOperation::add);
1341  if ( compute_d2R ) {
1342  d2RdWdW.compress(dealii::VectorOperation::add);
1343  d2RdXdX.compress(dealii::VectorOperation::add);
1344  d2RdWdX.compress(dealii::VectorOperation::add);
1345  }
1346  //if ( compute_dRdW ) system_matrix.compress(dealii::VectorOperation::insert);
1347  //system_matrix.print(std::cout);
1348 
1349 } // end of assemble_system_explicit ()
1350 
1351 template <int dim, typename real, typename MeshType>
1353 {
1354  pcout << "Evaluating residual Linf-norm..." << std::endl;
1355  const auto mapping = (*(high_order_grid->mapping_fe_field));
1356  dealii::hp::MappingCollection<dim> mapping_collection(mapping);
1357 
1358  double residual_linf_norm = 0.0;
1359  std::vector<dealii::types::global_dof_index> dofs_indices;
1360  const dealii::UpdateFlags update_flags = dealii::update_values | dealii::update_JxW_values;
1361  dealii::hp::FEValues<dim,dim> fe_values_collection_volume (mapping_collection,
1362  fe_collection,
1364  update_flags);
1365 
1366  // Obtain the mapping from local dof indices to global dof indices
1367  for (const auto& cell : dof_handler.active_cell_iterators()) {
1368  if (!cell->is_locally_owned()) continue;
1369 
1370  const int i_fele = cell->active_fe_index();
1371  const int i_quad = i_fele;
1372  const int i_mapp = 0;
1373 
1374  fe_values_collection_volume.reinit (cell, i_quad, i_mapp, i_fele);
1375  const dealii::FEValues<dim,dim> &fe_values_vol = fe_values_collection_volume.get_present_fe_values();
1376 
1377  const dealii::FESystem<dim,dim> &fe_ref = fe_collection[i_fele];
1378  const unsigned int n_dofs = fe_ref.n_dofs_per_cell();
1379  const unsigned int n_quad = fe_values_vol.n_quadrature_points;
1380 
1381  dofs_indices.resize(n_dofs);
1382  cell->get_dof_indices (dofs_indices);
1383 
1384  for (unsigned int iquad = 0; iquad < n_quad; ++iquad) {
1385  double residual_val = 0.0;
1386  for (unsigned int idof = 0; idof < n_dofs; ++idof) {
1387  const unsigned int istate = fe_values_vol.get_fe().system_to_component_index(idof).first;
1388  residual_val += right_hand_side[dofs_indices[idof]] * fe_values_vol.shape_value_component(idof, iquad, istate);
1389  }
1390  residual_linf_norm = std::max(std::abs(residual_val), residual_val);
1391  }
1392 
1393  }
1394  const double mpi_residual_linf_norm = dealii::Utilities::MPI::max(residual_linf_norm, mpi_communicator);
1395  return mpi_residual_linf_norm;
1396 }
1397 
1398 
1399 template <int dim, typename real, typename MeshType>
1401 {
1402 
1403  //return get_residual_linfnorm ();
1404  //return right_hand_side.l2_norm();
1405  //return right_hand_side.l2_norm() / right_hand_side.size();
1406  //auto scaled_residual = right_hand_side;
1407  //global_mass_matrix.vmult(scaled_residual, right_hand_side);
1408  //return scaled_residual.l2_norm();
1409  //pcout << "Evaluating residual L2-norm..." << std::endl;
1410 
1411  const auto mapping = (*(high_order_grid->mapping_fe_field));
1412  dealii::hp::MappingCollection<dim> mapping_collection(mapping);
1413 
1414  double residual_l2_norm = 0.0;
1415  double domain_volume = 0.0;
1416  std::vector<dealii::types::global_dof_index> dofs_indices;
1417  const dealii::UpdateFlags update_flags = dealii::update_values | dealii::update_JxW_values;
1418  dealii::hp::FEValues<dim,dim> fe_values_collection_volume (mapping_collection,
1419  fe_collection,
1421  update_flags);
1422 
1423  // Obtain the mapping from local dof indices to global dof indices
1424  for (const auto& cell : dof_handler.active_cell_iterators()) {
1425  if (!cell->is_locally_owned()) continue;
1426 
1427  const int i_fele = cell->active_fe_index();
1428  const int i_quad = i_fele;
1429  const int i_mapp = 0;
1430 
1431  fe_values_collection_volume.reinit (cell, i_quad, i_mapp, i_fele);
1432  const dealii::FEValues<dim,dim> &fe_values_vol = fe_values_collection_volume.get_present_fe_values();
1433 
1434  const dealii::FESystem<dim,dim> &fe_ref = fe_collection[i_fele];
1435  const unsigned int n_dofs = fe_ref.n_dofs_per_cell();
1436  const unsigned int n_quad = fe_values_vol.n_quadrature_points;
1437 
1438  dofs_indices.resize(n_dofs);
1439  cell->get_dof_indices (dofs_indices);
1440 
1441  for (unsigned int iquad = 0; iquad < n_quad; ++iquad) {
1442  double residual_val = 0.0;
1443  for (unsigned int idof = 0; idof < n_dofs; ++idof) {
1444  const unsigned int istate = fe_values_vol.get_fe().system_to_component_index(idof).first;
1445  residual_val += right_hand_side[dofs_indices[idof]] * fe_values_vol.shape_value_component(idof, iquad, istate);
1446  }
1447  residual_l2_norm += residual_val*residual_val * fe_values_vol.JxW(iquad);
1448  domain_volume += fe_values_vol.JxW(iquad);
1449  }
1450 
1451  }
1452  const double mpi_residual_l2_norm = dealii::Utilities::MPI::sum(residual_l2_norm, mpi_communicator);
1453  const double mpi_domain_volume = dealii::Utilities::MPI::sum(domain_volume, mpi_communicator);
1454  return std::sqrt(mpi_residual_l2_norm) / mpi_domain_volume;
1455 }
1456 
1457 template <int dim, typename real, typename MeshType>
1459 {
1460  return dof_handler.n_dofs();
1461 }
1462 
1463 
1464 #if PHILIP_DIM > 1
1465 template <int dim, typename DoFHandlerType = dealii::DoFHandler<dim>>
1466 class DataOutEulerFaces : public dealii::DataOutFaces<dim, DoFHandlerType>
1467 {
1468  static const unsigned int dimension = DoFHandlerType::dimension;
1469  static const unsigned int space_dimension = DoFHandlerType::space_dimension;
1470  using cell_iterator = typename dealii::DataOut_DoFData<DoFHandlerType, dimension - 1, dimension>::cell_iterator;
1471 
1472  using FaceDescriptor = typename std::pair<cell_iterator, unsigned int>;
1483  virtual FaceDescriptor first_face() override;
1484 
1506  virtual FaceDescriptor next_face(const FaceDescriptor &face) override;
1507 
1508 };
1509 
1510 template <int dim, typename DoFHandlerType>
1511 typename DataOutEulerFaces<dim, DoFHandlerType>::FaceDescriptor
1512 DataOutEulerFaces<dim, DoFHandlerType>::first_face()
1513 {
1514  // simply find first active cell with a face on the boundary
1515  typename dealii::Triangulation<dimension, space_dimension>::active_cell_iterator
1516  cell = this->triangulation->begin_active();
1517  for (; cell != this->triangulation->end(); ++cell)
1518  if (cell->is_locally_owned())
1519  for (const unsigned int f : dealii::GeometryInfo<dimension>::face_indices())
1520  if (cell->face(f)->at_boundary())
1521  if (cell->face(f)->boundary_id() == 1001)
1522  return FaceDescriptor(cell, f);
1523 
1524  // just return an invalid descriptor if we haven't found a locally
1525  // owned face. this can happen in parallel where all boundary
1526  // faces are owned by other processors
1527  return FaceDescriptor();
1528 }
1529 
1530 template <int dim, typename DoFHandlerType>
1531 typename DataOutEulerFaces<dim, DoFHandlerType>::FaceDescriptor
1532 DataOutEulerFaces<dim, DoFHandlerType>::next_face(const FaceDescriptor &old_face)
1533 {
1534  FaceDescriptor face = old_face;
1535 
1536  // first check whether the present cell has more faces on the boundary. since
1537  // we started with this face, its cell must clearly be locally owned
1538  Assert(face.first->is_locally_owned(), dealii::ExcInternalError());
1539  for (unsigned int f = face.second + 1; f < dealii::GeometryInfo<dimension>::faces_per_cell; ++f)
1540  if (face.first->face(f)->at_boundary())
1541  if (face.first->face(f)->boundary_id() == 1001) {
1542  // yup, that is so, so return it
1543  face.second = f;
1544  return face;
1545  }
1546 
1547  // otherwise find the next active cell that has a face on the boundary
1548 
1549  // convert the iterator to an active_iterator and advance this to the next
1550  // active cell
1551  typename dealii::Triangulation<dimension, space_dimension>::active_cell_iterator
1552  active_cell = face.first;
1553 
1554  // increase face pointer by one
1555  ++active_cell;
1556 
1557  // while there are active cells
1558  while (active_cell != this->triangulation->end()) {
1559  // check all the faces of this active cell. but skip it altogether
1560  // if it isn't locally owned
1561  if (active_cell->is_locally_owned())
1562  for (const unsigned int f : dealii::GeometryInfo<dimension>::face_indices())
1563  if (active_cell->face(f)->at_boundary())
1564  if (active_cell->face(f)->boundary_id() == 1001) {
1565  face.first = active_cell;
1566  face.second = f;
1567  return face;
1568  }
1569 
1570  // the present cell had no faces on the boundary (or was not locally
1571  // owned), so check next cell
1572  ++active_cell;
1573  }
1574 
1575  // we fell off the edge, so return with invalid pointer
1576  face.first = this->triangulation->end();
1577  face.second = 0;
1578  return face;
1579 }
1580 
1581 template <int dim>
1582 class NormalPostprocessor : public dealii::DataPostprocessorVector<dim>
1583 {
1584 public:
1585  NormalPostprocessor ()
1586  : dealii::DataPostprocessorVector<dim> ("normal", dealii::update_normal_vectors)
1587  {}
1588  virtual void
1589  evaluate_vector_field (const dealii::DataPostprocessorInputs::Vector<dim> &input_data, std::vector<dealii::Vector<double>> &computed_quantities) const override
1590  {
1591  // ensure that there really are as many output slots
1592  // as there are points at which DataOut provides the
1593  // gradients:
1594  AssertDimension (input_data.normals.size(), computed_quantities.size());
1595  // then loop over all of these inputs:
1596  for (unsigned int p=0; p<input_data.solution_gradients.size(); ++p) {
1597  // ensure that each output slot has exactly 'dim'
1598  // components (as should be expected, given that we
1599  // want to create vector-valued outputs), and copy the
1600  // gradients of the solution at the evaluation points
1601  // into the output slots:
1602  AssertDimension (computed_quantities[p].size(), dim);
1603  for (unsigned int d=0; d<dim; ++d)
1604  computed_quantities[p][d] = input_data.normals[p][d];
1605  }
1606  }
1607  virtual void
1608  evaluate_scalar_field (const dealii::DataPostprocessorInputs::Scalar<dim> &input_data, std::vector<dealii::Vector<double> > &computed_quantities) const override
1609  {
1610  // ensure that there really are as many output slots
1611  // as there are points at which DataOut provides the
1612  // gradients:
1613  AssertDimension (input_data.normals.size(), computed_quantities.size());
1614  // then loop over all of these inputs:
1615  for (unsigned int p=0; p<input_data.solution_gradients.size(); ++p) {
1616  // ensure that each output slot has exactly 'dim'
1617  // components (as should be expected, given that we
1618  // want to create vector-valued outputs), and copy the
1619  // gradients of the solution at the evaluation points
1620  // into the output slots:
1621  AssertDimension (computed_quantities[p].size(), dim);
1622  for (unsigned int d=0; d<dim; ++d)
1623  computed_quantities[p][d] = input_data.normals[p][d];
1624  }
1625  }
1626 };
1627 
1628 
1629 
1630 template <int dim, typename real, typename MeshType>
1631 void DGBase<dim,real,MeshType>::output_face_results_vtk (const unsigned int cycle, const double current_time)// const
1632 {
1633 
1634  DataOutEulerFaces<dim, dealii::DoFHandler<dim>> data_out;
1635 
1636  data_out.attach_dof_handler (dof_handler);
1637 
1638  std::vector<std::string> position_names;
1639  for(int d=0;d<dim;++d) {
1640  if (d==0) position_names.push_back("x");
1641  if (d==1) position_names.push_back("y");
1642  if (d==2) position_names.push_back("z");
1643  }
1644  std::vector<dealii::DataComponentInterpretation::DataComponentInterpretation> data_component_interpretation(dim, dealii::DataComponentInterpretation::component_is_scalar);
1645  data_out.add_data_vector (high_order_grid->dof_handler_grid, high_order_grid->volume_nodes, position_names, data_component_interpretation);
1646 
1647  dealii::Vector<float> subdomain(triangulation->n_active_cells());
1648  for (unsigned int i = 0; i < subdomain.size(); ++i) {
1649  subdomain(i) = triangulation->locally_owned_subdomain();
1650  }
1651  const std::string name = "subdomain";
1652  data_out.add_data_vector(subdomain, name, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim-1,dim>::DataVectorType::type_cell_data);
1653 
1655  data_out.add_data_vector(artificial_dissipation_coeffs, std::string("artificial_dissipation_coeffs"), dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim-1,dim>::DataVectorType::type_cell_data);
1656  data_out.add_data_vector(artificial_dissipation_se, std::string("artificial_dissipation_se"), dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim-1,dim>::DataVectorType::type_cell_data);
1657  data_out.add_data_vector(dof_handler_artificial_dissipation, artificial_dissipation_c0, std::string("artificial_dissipation_c0"));
1658  }
1659 
1660  data_out.add_data_vector(max_dt_cell, std::string("max_dt_cell"), dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim-1,dim>::DataVectorType::type_cell_data);
1661 
1662  data_out.add_data_vector(cell_volume, std::string("cell_volume"), dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim-1,dim>::DataVectorType::type_cell_data);
1663 
1664 
1665  // Let the physics post-processor determine what to output.
1666  const std::unique_ptr< dealii::DataPostprocessor<dim> > post_processor = Postprocess::PostprocessorFactory<dim>::create_Postprocessor(all_parameters);
1667  data_out.add_data_vector (solution, *post_processor);
1668 
1669  NormalPostprocessor<dim> normals_post_processor;
1670  data_out.add_data_vector (solution, normals_post_processor);
1671 
1672  // Output the polynomial degree in each cell
1673  std::vector<unsigned int> active_fe_indices;
1674  dof_handler.get_active_fe_indices(active_fe_indices);
1675  dealii::Vector<double> active_fe_indices_dealiivector(active_fe_indices.begin(), active_fe_indices.end());
1676  dealii::Vector<double> cell_poly_degree = active_fe_indices_dealiivector;
1677 
1678  data_out.add_data_vector (active_fe_indices_dealiivector, "PolynomialDegree", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim-1,dim>::DataVectorType::type_cell_data);
1679 
1680  // Output absolute value of the residual so that we can visualize it on a logscale.
1681  std::vector<std::string> residual_names;
1682  for(int s=0;s<nstate;++s) {
1683  std::string varname = "residual" + dealii::Utilities::int_to_string(s,1);
1684  residual_names.push_back(varname);
1685  }
1686  auto residual = right_hand_side;
1687  for (auto &&rhs_value : residual) {
1688  if (std::signbit(rhs_value)) rhs_value = -rhs_value;
1689  if (rhs_value == 0.0) rhs_value = std::numeric_limits<double>::min();
1690  }
1691  residual.update_ghost_values();
1692  data_out.add_data_vector (residual, residual_names, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim-1,dim>::DataVectorType::type_dof_data);
1693 
1694  //for(int s=0;s<nstate;++s) {
1695  // residual_names[s] = "scaled_" + residual_names[s];
1696  //}
1697  //global_mass_matrix.vmult(residual, right_hand_side);
1698  //for (auto &&rhs_value : residual) {
1699  // if (std::signbit(rhs_value)) rhs_value = -rhs_value;
1700  // if (rhs_value == 0.0) rhs_value = std::numeric_limits<double>::min();
1701  //}
1702  //residual.update_ghost_values();
1703  //data_out.add_data_vector (residual, residual_names, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim-1,dim>::DataVectorType::type_dof_data);
1704 
1705 
1706  //typename dealii::DataOut<dim,dealii::DoFHandler<dim>>::CurvedCellRegion curved = dealii::DataOut<dim,dealii::DoFHandler<dim>>::CurvedCellRegion::curved_inner_cells;
1707  //typename dealii::DataOut<dim>::CurvedCellRegion curved = dealii::DataOut<dim>::CurvedCellRegion::curved_boundary;
1708  //typename dealii::DataOut<dim>::CurvedCellRegion curved = dealii::DataOut<dim>::CurvedCellRegion::no_curved_cells;
1709 
1710  const dealii::Mapping<dim> &mapping = (*(high_order_grid->mapping_fe_field));
1711  const int grid_degree = high_order_grid->max_degree;
1712  //const int n_subdivisions = max_degree+1;//+30; // if write_higher_order_cells, n_subdivisions represents the order of the cell
1713  //const int n_subdivisions = 1;//+30; // if write_higher_order_cells, n_subdivisions represents the order of the cell
1714  const int n_subdivisions = grid_degree;
1715  data_out.build_patches(mapping, n_subdivisions);
1716  //const bool write_higher_order_cells = (dim>1 && max_degree > 1) ? true : false;
1717  const bool write_higher_order_cells = false;//(dim>1 && grid_degree > 1) ? true : false;
1718  dealii::DataOutBase::VtkFlags vtkflags(current_time,cycle,true,dealii::DataOutBase::VtkFlags::ZlibCompressionLevel::best_compression,write_higher_order_cells);
1719  data_out.set_flags(vtkflags);
1720 
1721  const int iproc = dealii::Utilities::MPI::this_mpi_process(mpi_communicator);
1722  std::string filename = this->all_parameters->solution_vtk_files_directory_name + "/" + "surface_solution-" + dealii::Utilities::int_to_string(dim, 1) +"D_maxpoly"+dealii::Utilities::int_to_string(max_degree, 2)+"-";
1723  filename += dealii::Utilities::int_to_string(cycle, 4) + ".";
1724  filename += dealii::Utilities::int_to_string(iproc, 4);
1725  filename += ".vtu";
1726  std::ofstream output(filename);
1727  data_out.write_vtu(output);
1728  //std::cout << "Writing out file: " << filename << std::endl;
1729 
1730  if (iproc == 0) {
1731  std::vector<std::string> filenames;
1732  for (unsigned int iproc = 0; iproc < dealii::Utilities::MPI::n_mpi_processes(mpi_communicator); ++iproc) {
1733  std::string fn = "surface_solution-" + dealii::Utilities::int_to_string(dim, 1) +"D_maxpoly"+dealii::Utilities::int_to_string(max_degree, 2)+"-";
1734  fn += dealii::Utilities::int_to_string(cycle, 4) + ".";
1735  fn += dealii::Utilities::int_to_string(iproc, 4);
1736  fn += ".vtu";
1737  filenames.push_back(fn);
1738  }
1739  std::string master_fn = this->all_parameters->solution_vtk_files_directory_name + "/" + "surface_solution-" + dealii::Utilities::int_to_string(dim, 1) +"D_maxpoly"+dealii::Utilities::int_to_string(max_degree, 2)+"-";
1740  master_fn += dealii::Utilities::int_to_string(cycle, 4) + ".pvtu";
1741  std::ofstream master_output(master_fn);
1742  data_out.write_pvtu_record(master_output, filenames);
1743  }
1744 
1745 }
1746 #endif
1747 
1748 template <int dim, typename real, typename MeshType>
1749 void DGBase<dim,real,MeshType>::output_results_vtk (const unsigned int cycle, const double current_time)// const
1750 {
1751 #if PHILIP_DIM>1
1752  if(this->all_parameters->output_face_results_vtk) output_face_results_vtk (cycle, current_time);
1753 #endif
1754 
1755  const bool enable_higher_order_vtk_output = this->all_parameters->enable_higher_order_vtk_output;
1756  dealii::DataOut<dim, dealii::DoFHandler<dim>> data_out;
1757 
1758  data_out.attach_dof_handler (dof_handler);
1759 
1760  std::vector<std::string> position_names;
1761  for(int d=0;d<dim;++d) {
1762  if (d==0) position_names.push_back("x");
1763  if (d==1) position_names.push_back("y");
1764  if (d==2) position_names.push_back("z");
1765  }
1766  std::vector<dealii::DataComponentInterpretation::DataComponentInterpretation> data_component_interpretation(dim, dealii::DataComponentInterpretation::component_is_scalar);
1767  data_out.add_data_vector (high_order_grid->dof_handler_grid, high_order_grid->volume_nodes, position_names, data_component_interpretation);
1768 
1769  dealii::Vector<float> subdomain(triangulation->n_active_cells());
1770  for (unsigned int i = 0; i < subdomain.size(); ++i) {
1771  subdomain(i) = triangulation->locally_owned_subdomain();
1772  }
1773  data_out.add_data_vector(subdomain, "subdomain", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
1774 
1776  data_out.add_data_vector(artificial_dissipation_coeffs, "artificial_dissipation_coeffs", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
1777  data_out.add_data_vector(artificial_dissipation_se, "artificial_dissipation_se", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
1778  data_out.add_data_vector(dof_handler_artificial_dissipation, artificial_dissipation_c0, "artificial_dissipation_c0");
1779  }
1780 
1781  data_out.add_data_vector(max_dt_cell, "max_dt_cell", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
1782 
1783  data_out.add_data_vector(reduced_mesh_weights, "reduced_mesh_weights", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
1784 
1785  data_out.add_data_vector(cell_volume, "cell_volume", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
1786 
1787 
1788  // Let the physics post-processor determine what to output.
1789  const std::unique_ptr< dealii::DataPostprocessor<dim> > post_processor = Postprocess::PostprocessorFactory<dim>::create_Postprocessor(all_parameters);
1790  data_out.add_data_vector (solution, *post_processor);
1791 
1792  // Output the polynomial degree in each cell
1793  std::vector<unsigned int> active_fe_indices;
1794  dof_handler.get_active_fe_indices(active_fe_indices);
1795  dealii::Vector<double> active_fe_indices_dealiivector(active_fe_indices.begin(), active_fe_indices.end());
1796  dealii::Vector<double> cell_poly_degree = active_fe_indices_dealiivector;
1797 
1798  data_out.add_data_vector (active_fe_indices_dealiivector, "PolynomialDegree", dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_cell_data);
1799 
1800  // Output absolute value of the residual so that we can visualize it on a logscale.
1801  std::vector<std::string> residual_names;
1802  for(int s=0;s<nstate;++s) {
1803  std::string varname = "residual" + dealii::Utilities::int_to_string(s,1);
1804  residual_names.push_back(varname);
1805  }
1806  auto residual = right_hand_side;
1807  for (auto &&rhs_value : residual) {
1808  if (std::signbit(rhs_value)) rhs_value = -rhs_value;
1809  if (rhs_value == 0.0) rhs_value = std::numeric_limits<double>::min();
1810  }
1811  residual.update_ghost_values();
1812  data_out.add_data_vector (residual, residual_names, dealii::DataOut_DoFData<dealii::DoFHandler<dim>,dim>::DataVectorType::type_dof_data);
1813 
1814  typename dealii::DataOut<dim,dealii::DoFHandler<dim>>::CurvedCellRegion curved = dealii::DataOut<dim,dealii::DoFHandler<dim>>::CurvedCellRegion::curved_inner_cells;
1815  //typename dealii::DataOut<dim>::CurvedCellRegion curved = dealii::DataOut<dim>::CurvedCellRegion::curved_boundary;
1816  //typename dealii::DataOut<dim>::CurvedCellRegion curved = dealii::DataOut<dim>::CurvedCellRegion::no_curved_cells;
1817 
1818  const dealii::Mapping<dim> &mapping = (*(high_order_grid->mapping_fe_field));
1819  const unsigned int grid_degree = high_order_grid->max_degree;
1820  // If higher-order vtk output is not enabled, passing 0 will be interpreted as DataOutInterface::default_subdivisions
1821  const int n_subdivisions = (enable_higher_order_vtk_output) ? std::max(grid_degree,get_max_fe_degree()) : 0;
1822  data_out.build_patches(mapping, n_subdivisions, curved);
1823  const bool write_higher_order_cells = (n_subdivisions>1 && dim>1) ? true : false;
1824  dealii::DataOutBase::VtkFlags vtkflags(current_time,cycle,true,dealii::DataOutBase::VtkFlags::ZlibCompressionLevel::best_compression,write_higher_order_cells);
1825  data_out.set_flags(vtkflags);
1826 
1827  const int iproc = dealii::Utilities::MPI::this_mpi_process(mpi_communicator);
1828  std::string filename = this->all_parameters->solution_vtk_files_directory_name + "/" + "solution-" + dealii::Utilities::int_to_string(dim, 1) +"D_maxpoly"+dealii::Utilities::int_to_string(max_degree, 2)+"-";
1829  filename += dealii::Utilities::int_to_string(cycle, 4) + ".";
1830  filename += dealii::Utilities::int_to_string(iproc, 4);
1831  filename += ".vtu";
1832  std::ofstream output(filename);
1833  data_out.write_vtu(output);
1834  //std::cout << "Writing out file: " << filename << std::endl;
1835 
1836  if (iproc == 0) {
1837  std::vector<std::string> filenames;
1838  for (unsigned int iproc = 0; iproc < dealii::Utilities::MPI::n_mpi_processes(mpi_communicator); ++iproc) {
1839  std::string fn = "solution-" + dealii::Utilities::int_to_string(dim, 1) +"D_maxpoly"+dealii::Utilities::int_to_string(max_degree, 2)+"-";
1840  fn += dealii::Utilities::int_to_string(cycle, 4) + ".";
1841  fn += dealii::Utilities::int_to_string(iproc, 4);
1842  fn += ".vtu";
1843  filenames.push_back(fn);
1844  }
1845  std::string master_fn = this->all_parameters->solution_vtk_files_directory_name + "/" + "solution-" + dealii::Utilities::int_to_string(dim, 1) +"D_maxpoly"+dealii::Utilities::int_to_string(max_degree, 2)+"-";
1846  master_fn += dealii::Utilities::int_to_string(cycle, 4) + ".pvtu";
1847  std::ofstream master_output(master_fn);
1848  data_out.write_pvtu_record(master_output, filenames);
1849  }
1850 
1851 }
1852 
1853 template <int dim, typename real, typename MeshType>
1855 {
1856  for (int idim=0; idim<dim; idim++) {
1858  auxiliary_right_hand_side[idim].add(1.0);
1859 
1861  auxiliary_solution[idim] *= 0.0;
1862  }
1863 }
1864 
1865 template <int dim, typename real, typename MeshType>
1867  const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)
1868 {
1869  pcout << "Allocating DG system and initializing FEValues" << std::endl;
1870  // This function allocates all the necessary memory to the
1871  // system matrices and vectors.
1872 
1873  dof_handler.distribute_dofs(fe_collection);
1874  //This Cuthill_McKee renumbering for dof_handlr uses a lot of memory in 3D, is there another way?
1875  using RenumberDofsType = Parameters::AllParameters::RenumberDofsType;
1876  if(all_parameters->do_renumber_dofs && all_parameters->renumber_dofs_type == RenumberDofsType::CuthillMckee ){
1877  dealii::DoFRenumbering::Cuthill_McKee(dof_handler,true);
1878  }
1879  //const bool reversed_numbering = true;
1880  //dealii::DoFRenumbering::Cuthill_McKee(dof_handler, reversed_numbering);
1881  //const bool reversed_numbering = false;
1882  //const bool use_constraints = false;
1883  //dealii::DoFRenumbering::boost::minimum_degree(dof_handler, reversed_numbering, use_constraints);
1884  //dealii::DoFRenumbering::boost::king_ordering(dof_handler, reversed_numbering, use_constraints);
1885 
1886  // Solution and RHS
1887  locally_owned_dofs = dof_handler.locally_owned_dofs();
1888  dealii::DoFTools::extract_locally_relevant_dofs(dof_handler, ghost_dofs);
1890  ghost_dofs.subtract_set(locally_owned_dofs);
1891  //dealii::DoFTools::extract_locally_relevant_dofs(dof_handler, locally_relevant_dofs);
1892 
1894 
1895  // Allocates artificial dissipation variables when required.
1897 
1898  max_dt_cell.reinit(triangulation->n_active_cells());
1899  cell_volume.reinit(triangulation->n_active_cells());
1900 
1901  reduced_mesh_weights.reinit(triangulation->n_active_cells());
1902 
1903  // allocates model variables only if there is a model
1904  if(all_parameters->pde_type == Parameters::AllParameters::PartialDifferentialEquation::physics_model) allocate_model_variables();
1905 
1907  solution *= 0.0;
1908  solution.add(std::numeric_limits<real>::lowest());
1909  //right_hand_side.reinit(locally_owned_dofs, mpi_communicator);
1911  right_hand_side.add(1.0); // Avoid 0 initial residual for output and logarithmic visualization.
1912 
1914 
1915  // Set use_auxiliary_eq flag
1917 
1918  // Allocate for auxiliary equation only.
1920 
1921  // Set the assemble resiudla time to 0 for clock_t type
1922  assemble_residual_time = 0.0;
1923 
1924  // System matrix allocation
1925  if (compute_dRdW || compute_dRdX || compute_d2R) {
1926  dealii::DynamicSparsityPattern dsp(locally_relevant_dofs);
1927  dealii::DoFTools::make_flux_sparsity_pattern(dof_handler, dsp);
1928  dealii::SparsityTools::distribute_sparsity_pattern(dsp, dof_handler.locally_owned_dofs(), mpi_communicator, locally_relevant_dofs);
1929 
1930  sparsity_pattern.copy_from(dsp);
1931 
1933  }
1934 
1935  // Make sure that derivatives are cleared when reallocating DG objects.
1936  // The call to assemble the derivatives will reallocate those derivatives
1937  // if they are ever needed.
1938  system_matrix_transpose.clear();
1939  dRdXv.clear();
1940  d2RdWdX.clear();
1941  d2RdWdW.clear();
1942  d2RdXdX.clear();
1943 
1944  if (compute_dRdW) {
1945  solution_dRdW.reinit(solution);
1946  solution_dRdW *= 0.0;
1947  volume_nodes_dRdW.reinit(high_order_grid->volume_nodes);
1948  volume_nodes_dRdW *= 0.0;
1949  }
1950 
1951  CFL_mass_dRdW = 0.0;
1952 
1953  if (compute_dRdX) {
1954  solution_dRdX.reinit(solution);
1955  solution_dRdX *= 0.0;
1956  volume_nodes_dRdX.reinit(high_order_grid->volume_nodes);
1957  volume_nodes_dRdX *= 0.0;
1958  }
1959 
1960  if (compute_d2R) {
1961  solution_d2R.reinit(solution);
1962  solution_d2R *= 0.0;
1963  volume_nodes_d2R.reinit(high_order_grid->volume_nodes);
1964  volume_nodes_d2R *= 0.0;
1965  dual_d2R.reinit(dual);
1966  dual_d2R *= 0.0;
1967  }
1968 }
1969 
1970 template <int dim, typename real, typename MeshType>
1972 {
1973  const dealii::IndexSet locally_owned_dofs_artificial_dissipation = dof_handler_artificial_dissipation.locally_owned_dofs();
1974 
1975  dealii::IndexSet ghost_dofs_artificial_dissipation;
1976  dealii::IndexSet locally_relevant_dofs_artificial_dissipation;
1977  dealii::DoFTools::extract_locally_relevant_dofs(dof_handler_artificial_dissipation, ghost_dofs_artificial_dissipation);
1978  locally_relevant_dofs_artificial_dissipation = ghost_dofs_artificial_dissipation;
1979  ghost_dofs_artificial_dissipation.subtract_set(locally_owned_dofs_artificial_dissipation);
1980 
1981  artificial_dissipation_c0.reinit(locally_owned_dofs_artificial_dissipation, ghost_dofs_artificial_dissipation, mpi_communicator);
1982  artificial_dissipation_c0.update_ghost_values();
1983 
1984  artificial_dissipation_coeffs.reinit(triangulation->n_active_cells());
1985  artificial_dissipation_se.reinit(triangulation->n_active_cells());
1986 }
1987 
1988 
1989 template <int dim, typename real, typename MeshType>
1991 {
1992  locally_owned_dofs = dof_handler.locally_owned_dofs();
1993  {
1994  dealii::SparsityPattern sparsity_pattern_d2RdWdX = get_d2RdWdX_sparsity_pattern ();
1995  const dealii::IndexSet &row_parallel_partitioning_d2RdWdX = locally_owned_dofs;
1996  const dealii::IndexSet &col_parallel_partitioning_d2RdWdX = high_order_grid->locally_owned_dofs_grid;
1997  d2RdWdX.reinit(row_parallel_partitioning_d2RdWdX, col_parallel_partitioning_d2RdWdX, sparsity_pattern_d2RdWdX, mpi_communicator);
1998  }
1999 
2000  {
2001  dealii::SparsityPattern sparsity_pattern_d2RdWdW = get_d2RdWdW_sparsity_pattern ();
2002  const dealii::IndexSet &row_parallel_partitioning_d2RdWdW = locally_owned_dofs;
2003  const dealii::IndexSet &col_parallel_partitioning_d2RdWdW = locally_owned_dofs;
2004  d2RdWdW.reinit(row_parallel_partitioning_d2RdWdW, col_parallel_partitioning_d2RdWdW, sparsity_pattern_d2RdWdW, mpi_communicator);
2005  }
2006 
2007  {
2008  dealii::SparsityPattern sparsity_pattern_d2RdXdX = get_d2RdXdX_sparsity_pattern ();
2009  const dealii::IndexSet &row_parallel_partitioning_d2RdXdX = high_order_grid->locally_owned_dofs_grid;
2010  const dealii::IndexSet &col_parallel_partitioning_d2RdXdX = high_order_grid->locally_owned_dofs_grid;
2011  d2RdXdX.reinit(row_parallel_partitioning_d2RdXdX, col_parallel_partitioning_d2RdXdX, sparsity_pattern_d2RdXdX, mpi_communicator);
2012  }
2013 }
2014 
2015 template <int dim, typename real, typename MeshType>
2017 {
2018  // dRdXv matrix allocation
2019  dealii::SparsityPattern dRdXv_sparsity_pattern = get_dRdX_sparsity_pattern ();
2020  const dealii::IndexSet &row_parallel_partitioning = locally_owned_dofs;
2021  const dealii::IndexSet &col_parallel_partitioning = high_order_grid->locally_owned_dofs_grid;
2022  dRdXv.reinit(row_parallel_partitioning, col_parallel_partitioning, dRdXv_sparsity_pattern, MPI_COMM_WORLD);
2023 }
2024 
2025 template <int dim, typename real, typename MeshType>
2027  const bool Cartesian_element,
2028  const unsigned int poly_degree, const unsigned int grid_degree,
2031  OPERATOR::local_mass<dim,2*dim,real> &reference_mass_matrix,
2035 {
2037  const FR_enum FR_Type = this->all_parameters->flux_reconstruction_type;
2038 
2040  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2041 
2042  // Note the fe_collection passed for metric mapping operators has to be COLLOCATED ON GRID NODES
2044 
2045  if(Cartesian_element || this->all_parameters->use_weight_adjusted_mass){//then we can factor out det of Jac and rapidly simplify
2046  reference_mass_matrix.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2047  }
2048  if(grid_degree > 1 || !Cartesian_element){//then we need to construct dim matrices on the fly
2050  }
2051  if((FR_Type != FR_enum::cDG && Cartesian_element) || (FR_Type != FR_enum::cDG && this->all_parameters->use_weight_adjusted_mass)){
2052  reference_FR.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2053  }
2054  if((use_auxiliary_eq && FR_Type_Aux != FR_Aux_enum::kDG && Cartesian_element) || (FR_Type_Aux != FR_Aux_enum::kDG && this->all_parameters->use_weight_adjusted_mass)){
2055  reference_FR_aux.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2056  }
2057  if(((FR_Type != FR_enum::cDG) ||
2058  (use_auxiliary_eq && FR_Type_Aux != FR_Aux_enum::kDG) ) && (grid_degree > 1 || !Cartesian_element)){
2060  }
2061 }
2062 
2063 template <int dim, typename real, typename MeshType>
2064 void DGBase<dim,real,MeshType>::evaluate_mass_matrices (bool do_inverse_mass_matrix)
2065 {
2067  const FR_enum FR_Type = this->all_parameters->flux_reconstruction_type;
2068 
2070  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2071 
2072  // flag for energy tests
2073  const bool use_energy = this->all_parameters->use_energy;
2074 
2075  // Mass matrix sparsity pattern
2076  dealii::DynamicSparsityPattern dsp(dof_handler.n_dofs());
2077  std::vector<dealii::types::global_dof_index> dofs_indices;
2078  for (auto cell = dof_handler.begin_active(); cell!=dof_handler.end(); ++cell) {
2079 
2080  if (!cell->is_locally_owned()) continue;
2081 
2082  const unsigned int fe_index_curr_cell = cell->active_fe_index();
2083 
2084  // Current reference element related to this physical cell
2085  const dealii::FESystem<dim,dim> &current_fe_ref = fe_collection[fe_index_curr_cell];
2086  const unsigned int n_dofs_cell = current_fe_ref.n_dofs_per_cell();
2087 
2088  dofs_indices.resize(n_dofs_cell);
2089  cell->get_dof_indices (dofs_indices);
2090  for (unsigned int itest=0; itest<n_dofs_cell; ++itest) {
2091  for (unsigned int itrial=0; itrial<n_dofs_cell; ++itrial) {
2092  dsp.add(dofs_indices[itest], dofs_indices[itrial]);
2093  }
2094  }
2095  }
2096  // Initialize global matrices to 0.
2097  dealii::SparsityTools::distribute_sparsity_pattern(dsp, dof_handler.locally_owned_dofs(), mpi_communicator, locally_owned_dofs);
2098  mass_sparsity_pattern.copy_from(dsp);
2099  if (do_inverse_mass_matrix) {
2101  if (use_auxiliary_eq){
2103  }
2104  if (use_energy){//for split form get energy
2106  if (use_auxiliary_eq){
2108  }
2109  }
2110  } else {
2112  if (use_auxiliary_eq){
2114  }
2115  }
2116 
2117  // setup 1D operators for ONE STATE. We loop over states in assembly for speedup.
2118  const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree();
2119  OPERATOR::mapping_shape_functions<dim,2*dim,real> mapping_basis(1, max_degree, init_grid_degree);//first set at max degree
2120  OPERATOR::basis_functions<dim,2*dim,real> basis(1, max_degree, init_grid_degree);
2121  OPERATOR::local_mass<dim,2*dim,real> reference_mass_matrix(1, max_degree, init_grid_degree);//first set at max degree
2122  OPERATOR::local_Flux_Reconstruction_operator<dim,2*dim,real> reference_FR(1, max_degree, init_grid_degree, FR_Type);
2123  OPERATOR::local_Flux_Reconstruction_operator_aux<dim,2*dim,real> reference_FR_aux(1, max_degree, init_grid_degree, FR_Type_Aux);
2124  OPERATOR::derivative_p<dim,2*dim,real> deriv_p(1, max_degree, init_grid_degree);
2125 
2126  auto first_cell = dof_handler.begin_active();
2127  const bool Cartesian_first_element = (first_cell->manifold_id() == dealii::numbers::flat_manifold_id);
2128 
2129  reinit_operators_for_mass_matrix(Cartesian_first_element, max_degree, init_grid_degree, mapping_basis, basis, reference_mass_matrix, reference_FR, reference_FR_aux, deriv_p);
2130 
2131  //Loop over cells and set the matrices.
2132  auto metric_cell = high_order_grid->dof_handler_grid.begin_active();
2133  for (auto cell = dof_handler.begin_active(); cell!=dof_handler.end(); ++cell, ++metric_cell) {
2134 
2135  if (!cell->is_locally_owned()) continue;
2136 
2137  const bool Cartesian_element = (cell->manifold_id() == dealii::numbers::flat_manifold_id);
2138 
2139  const unsigned int fe_index_curr_cell = cell->active_fe_index();
2140  const unsigned int curr_grid_degree = high_order_grid->fe_system.tensor_degree();//in the future the metric cell's should store a local grid degree. currently high_order_grid dof_handler_grid doesn't have that capability
2141 
2142  //Check if need to recompute the 1D basis for the current degree (if different than previous cell)
2143  //That is, if the poly_degree, manifold type, or grid degree is different than previous reference operator
2144  if((fe_index_curr_cell != mapping_basis.current_degree) ||
2145  (curr_grid_degree != mapping_basis.current_grid_degree))
2146  {
2147  reinit_operators_for_mass_matrix(Cartesian_element, fe_index_curr_cell, curr_grid_degree, mapping_basis, basis, reference_mass_matrix, reference_FR, reference_FR_aux, deriv_p);
2148 
2149  mapping_basis.current_degree = fe_index_curr_cell;
2150  basis.current_degree = fe_index_curr_cell;
2151  reference_mass_matrix.current_degree = fe_index_curr_cell;
2152  reference_FR.current_degree = fe_index_curr_cell;
2153  reference_FR_aux.current_degree = fe_index_curr_cell;
2154  deriv_p.current_degree = fe_index_curr_cell;
2155  }
2156 
2157  // Current reference element related to this physical cell
2158  const unsigned int n_dofs_cell = fe_collection[fe_index_curr_cell].n_dofs_per_cell();
2159  const unsigned int n_quad_pts = volume_quadrature_collection[fe_index_curr_cell].size();
2160 
2161  //setup metric cell
2162  const dealii::FESystem<dim> &fe_metric = high_order_grid->fe_system;
2163  const unsigned int n_metric_dofs = high_order_grid->fe_system.dofs_per_cell;
2164  const unsigned int n_grid_nodes = n_metric_dofs/dim;
2165  std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
2166  metric_cell->get_dof_indices (metric_dof_indices);
2167  // get mapping_support points
2168  std::array<std::vector<real>,dim> mapping_support_points;
2169  for(int idim=0; idim<dim; idim++){
2170  mapping_support_points[idim].resize(n_metric_dofs/dim);
2171  }
2172  const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(curr_grid_degree);
2173  for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
2174  const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]);
2175  const unsigned int istate = fe_metric.system_to_component_index(idof).first;
2176  const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
2177  const unsigned int igrid_node = index_renumbering[ishape];
2178  mapping_support_points[istate][igrid_node] = val;
2179  }
2180 
2181  //get determinant of Jacobian
2182  OPERATOR::metric_operators<real, dim, 2*dim> metric_oper(nstate, fe_index_curr_cell, curr_grid_degree);
2184  n_quad_pts, n_grid_nodes,
2185  mapping_support_points,
2186  mapping_basis);
2187 
2188  //Get dofs indices to set local matrices in global.
2189  dofs_indices.resize(n_dofs_cell);
2190  cell->get_dof_indices (dofs_indices);
2191  //Compute local matrices and set them in the global system.
2193  Cartesian_element,
2194  do_inverse_mass_matrix,
2195  fe_index_curr_cell,
2196  curr_grid_degree,
2197  n_quad_pts,
2198  n_dofs_cell,
2199  dofs_indices,
2200  metric_oper,
2201  basis,
2202  reference_mass_matrix,
2203  reference_FR,
2204  reference_FR_aux,
2205  deriv_p);
2206  }//end of cell loop
2207 
2208  //Compress global matrices.
2209  if (do_inverse_mass_matrix) {
2210  global_inverse_mass_matrix.compress(dealii::VectorOperation::insert);
2211  if (use_auxiliary_eq){
2212  global_inverse_mass_matrix_auxiliary.compress(dealii::VectorOperation::insert);
2213  }
2214  if (use_energy){//for split form energy
2215  global_mass_matrix.compress(dealii::VectorOperation::insert);
2216  if (use_auxiliary_eq){
2217  global_mass_matrix_auxiliary.compress(dealii::VectorOperation::insert);
2218  }
2219  }
2220  } else {
2221  global_mass_matrix.compress(dealii::VectorOperation::insert);
2222  if (use_auxiliary_eq){
2223  global_mass_matrix_auxiliary.compress(dealii::VectorOperation::insert);
2224  }
2225  }
2226 }
2227 
2228 template<int dim, typename real, typename MeshType>
2230  const bool Cartesian_element,
2231  const bool do_inverse_mass_matrix,
2232  const unsigned int poly_degree,
2233  const unsigned int /*curr_grid_degree*/,
2234  const unsigned int n_quad_pts,
2235  const unsigned int n_dofs_cell,
2236  const std::vector<dealii::types::global_dof_index> dofs_indices,
2239  OPERATOR::local_mass<dim,2*dim,real> &reference_mass_matrix,
2243 {
2245  const FR_enum FR_Type = this->all_parameters->flux_reconstruction_type;
2246 
2248  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2249 
2250  dealii::FullMatrix<real> local_mass_matrix(n_dofs_cell);
2251  dealii::FullMatrix<real> local_mass_matrix_inv(n_dofs_cell);
2252  dealii::FullMatrix<real> local_mass_matrix_aux(n_dofs_cell);
2253  dealii::FullMatrix<real> local_mass_matrix_aux_inv(n_dofs_cell);
2254 
2255  for(int istate=0; istate<nstate; istate++){
2256  const unsigned int n_shape_fns = n_dofs_cell / nstate;
2257  dealii::FullMatrix<real> local_mass_matrix_state(n_shape_fns);
2258  dealii::FullMatrix<real> local_mass_matrix_inv_state(n_shape_fns);
2259  dealii::FullMatrix<real> local_mass_matrix_aux_state(n_shape_fns);
2260  dealii::FullMatrix<real> local_mass_matrix_aux_inv_state(n_shape_fns);
2261  // compute mass matrix and inverse the standard way
2262  if(this->all_parameters->use_weight_adjusted_mass == false){
2263  //check if Cartesian grid because we can factor out determinant of Jacobian
2264  if(Cartesian_element){
2265  local_mass_matrix_state.add(metric_oper.det_Jac_vol[0],
2266  reference_mass_matrix.tensor_product_state(
2267  1,
2268  reference_mass_matrix.oneD_vol_operator,
2269  reference_mass_matrix.oneD_vol_operator,
2270  reference_mass_matrix.oneD_vol_operator));
2271  if(use_auxiliary_eq){
2272  local_mass_matrix_aux_state.add(1.0, local_mass_matrix_state);
2273  }
2274  if(FR_Type != FR_enum::cDG){
2275  local_mass_matrix_state.add(metric_oper.det_Jac_vol[0],
2277  reference_mass_matrix.oneD_vol_operator,
2278  1,
2279  n_shape_fns));
2280  }
2281  if(use_auxiliary_eq){
2282  if(FR_Type_Aux != FR_Aux_enum::kDG){
2283  local_mass_matrix_aux_state.add(metric_oper.det_Jac_vol[0],
2284  reference_FR_aux.build_dim_Flux_Reconstruction_operator(
2285  reference_mass_matrix.oneD_vol_operator,
2286  1,
2287  n_shape_fns));
2288  }
2289  }
2290  if(do_inverse_mass_matrix){
2291  local_mass_matrix_inv_state.invert(local_mass_matrix_state);
2292  if(use_auxiliary_eq)
2293  local_mass_matrix_aux_inv_state.invert(local_mass_matrix_aux_state);
2294  }
2295  }
2296  //if not a linear grid, we have to build the dim matrices on the fly
2297  else{
2298  //quadrature weights
2299  const std::vector<real> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2300  local_mass_matrix_state = reference_mass_matrix.build_dim_mass_matrix(
2301  1,
2302  n_shape_fns, n_quad_pts,
2303  basis,
2304  metric_oper.det_Jac_vol,
2305  quad_weights);
2306 
2307  if(use_auxiliary_eq) local_mass_matrix_aux_state.add(1.0, local_mass_matrix_state);
2308 
2309  if(FR_Type != FR_enum::cDG){
2310  dealii::FullMatrix<real> local_FR(n_shape_fns);
2311  local_FR = reference_FR.build_dim_Flux_Reconstruction_operator_directly(
2312  1,
2313  n_shape_fns,
2314  deriv_p.oneD_vol_operator,
2315  local_mass_matrix_state);
2316  local_mass_matrix_state.add(1.0, local_FR);
2317  }
2318  if(use_auxiliary_eq){
2319  if(FR_Type_Aux != FR_Aux_enum::kDG){
2320  dealii::FullMatrix<real> local_FR_aux(n_shape_fns);
2321  local_FR_aux = reference_FR_aux.build_dim_Flux_Reconstruction_operator_directly(
2322  1,
2323  n_shape_fns,
2324  deriv_p.oneD_vol_operator,
2325  local_mass_matrix_aux_state);
2326  local_mass_matrix_aux_state.add(1.0, local_FR_aux);
2327  }
2328  }
2329  }
2330  if(do_inverse_mass_matrix){
2331  local_mass_matrix_inv_state.invert(local_mass_matrix_state);
2332  if(use_auxiliary_eq)
2333  local_mass_matrix_aux_inv_state.invert(local_mass_matrix_aux_state);
2334  }
2335  }
2336  else{//do weight adjusted inverse
2337  //Weight-adjusted framework based off Cicchino, Alexander, and Sivakumaran Nadarajah. "Nonlinearly Stable Split Forms for the Weight-Adjusted Flux Reconstruction High-Order Method: Curvilinear Numerical Validation." AIAA SCITECH 2022 Forum. 2022 for FR. For a DG background please refer to Chan, Jesse, and Lucas C. Wilcox. "On discretely entropy stable weight-adjusted discontinuous Galerkin methods: curvilinear meshes." Journal of Computational Physics 378 (2019): 366-393. Section 4.1.
2338  //quadrature weights
2339  const std::vector<real> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2340  std::vector<real> J_inv(n_quad_pts);
2341  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2342  J_inv[iquad] = 1.0 / metric_oper.det_Jac_vol[iquad];
2343  }
2344  dealii::FullMatrix<real> local_weighted_mass_matrix(n_shape_fns);
2345  dealii::FullMatrix<real> local_weighted_mass_matrix_aux(n_shape_fns);
2346  local_weighted_mass_matrix = reference_mass_matrix.build_dim_mass_matrix(
2347  1,
2348  n_shape_fns, n_quad_pts,
2349  basis,
2350  J_inv,
2351  quad_weights);
2352  if(use_auxiliary_eq)
2353  local_weighted_mass_matrix_aux.add(1.0, local_weighted_mass_matrix);
2354 
2355  if(FR_Type != FR_enum::cDG){
2356  dealii::FullMatrix<real> local_FR(n_shape_fns);
2357  local_FR = reference_FR.build_dim_Flux_Reconstruction_operator_directly(
2358  1,
2359  n_shape_fns,
2360  deriv_p.oneD_vol_operator,
2361  local_weighted_mass_matrix);
2362  local_weighted_mass_matrix.add(1.0, local_FR);
2363  }
2364  //auxiliary weighted not correct and not yet implemented properly...
2365  if(use_auxiliary_eq){
2366  if(FR_Type_Aux != FR_Aux_enum::kDG){
2367  dealii::FullMatrix<real> local_FR_aux(n_shape_fns);
2368  local_FR_aux = reference_FR_aux.build_dim_Flux_Reconstruction_operator_directly(
2369  1,
2370  n_shape_fns,
2371  deriv_p.oneD_vol_operator,
2372  local_mass_matrix);
2373  local_weighted_mass_matrix_aux.add(1.0, local_FR_aux);
2374  }
2375  }
2376  dealii::FullMatrix<real> ref_mass_dim(n_shape_fns);
2377  ref_mass_dim = reference_mass_matrix.tensor_product_state(
2378  1,
2379  reference_mass_matrix.oneD_vol_operator,
2380  reference_mass_matrix.oneD_vol_operator,
2381  reference_mass_matrix.oneD_vol_operator);
2382  if(FR_Type != FR_enum::cDG){
2383  dealii::FullMatrix<real> local_FR(n_shape_fns);
2384  local_FR = reference_FR.build_dim_Flux_Reconstruction_operator(
2385  reference_mass_matrix.oneD_vol_operator,
2386  1,
2387  n_shape_fns);
2388  ref_mass_dim.add(1.0, local_FR);
2389  }
2390  dealii::FullMatrix<real> ref_mass_dim_inv(n_shape_fns);
2391  ref_mass_dim_inv.invert(ref_mass_dim);
2392  dealii::FullMatrix<real> temp(n_shape_fns);
2393  ref_mass_dim_inv.mmult(temp, local_weighted_mass_matrix);
2394  temp.mmult(local_mass_matrix_inv_state, ref_mass_dim_inv);
2395  local_mass_matrix_state.invert(local_mass_matrix_inv_state);
2396  if(use_auxiliary_eq){
2397  dealii::FullMatrix<real> temp2(n_shape_fns);
2398  ref_mass_dim_inv.mmult(temp2, local_weighted_mass_matrix_aux);
2399  temp2.mmult(local_mass_matrix_aux_inv_state, ref_mass_dim_inv);
2400  local_mass_matrix_aux_state.invert(local_mass_matrix_aux_inv_state);
2401  }
2402  }
2403  //write the ONE state, dim sized mass matrices using symmetry into nstate, dim sized mass matrices.
2404  for(unsigned int test_shape=0; test_shape<n_shape_fns; test_shape++){
2405 
2406  const unsigned int test_index = istate * n_shape_fns + test_shape;
2407 
2408  for(unsigned int trial_shape=test_shape; trial_shape<n_shape_fns; trial_shape++){
2409  const unsigned int trial_index = istate * n_shape_fns + trial_shape;
2410  local_mass_matrix[test_index][trial_index] = local_mass_matrix_state[test_shape][trial_shape];
2411  local_mass_matrix[trial_index][test_index] = local_mass_matrix_state[test_shape][trial_shape];
2412 
2413  local_mass_matrix_inv[test_index][trial_index] = local_mass_matrix_inv_state[test_shape][trial_shape];
2414  local_mass_matrix_inv[trial_index][test_index] = local_mass_matrix_inv_state[test_shape][trial_shape];
2415 
2416  if(use_auxiliary_eq){
2417  local_mass_matrix_aux[test_index][trial_index] = local_mass_matrix_aux_state[test_shape][trial_shape];
2418  local_mass_matrix_aux[trial_index][test_index] = local_mass_matrix_aux_state[test_shape][trial_shape];
2419 
2420  local_mass_matrix_aux_inv[test_index][trial_index] = local_mass_matrix_aux_inv_state[test_shape][trial_shape];
2421  local_mass_matrix_aux_inv[trial_index][test_index] = local_mass_matrix_aux_inv_state[test_shape][trial_shape];
2422  }
2423  }
2424  }
2425  }
2426 
2427  //set in global matrices
2428  if (do_inverse_mass_matrix) {
2429  //set the global inverse mass matrix
2430  global_inverse_mass_matrix.set(dofs_indices, local_mass_matrix_inv);
2431  //set the global inverse mass matrix for auxiliary equations
2432  if(use_auxiliary_eq){
2433  global_inverse_mass_matrix_auxiliary.set(dofs_indices, local_mass_matrix_aux_inv);
2434  }
2435  //If an energy test, we also need to store the mass matrix to compute energy/entropy and conservation.
2436  if (this->all_parameters->use_energy){//for split form energy
2437  global_mass_matrix.set(dofs_indices, local_mass_matrix);
2438  if(use_auxiliary_eq){
2439  global_mass_matrix_auxiliary.set(dofs_indices, local_mass_matrix_aux);
2440  }
2441  }
2442  } else {
2443  //only store global mass matrix
2444  global_mass_matrix.set(dofs_indices, local_mass_matrix);
2445  if(use_auxiliary_eq){
2446  global_mass_matrix_auxiliary.set(dofs_indices, local_mass_matrix_aux);
2447  }
2448  }
2449 }
2450 
2451 template<int dim, typename real, typename MeshType>
2453  const dealii::LinearAlgebra::distributed::Vector<double> &input_vector,
2454  dealii::LinearAlgebra::distributed::Vector<double> &output_vector,
2455  const bool use_auxiliary_eq)
2456 {
2459  const FR_enum FR_Type = this->all_parameters->flux_reconstruction_type;
2460  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2461 
2462  const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree();
2463  OPERATOR::mapping_shape_functions<dim,2*dim,real> mapping_basis(1, init_grid_degree, init_grid_degree);
2464 
2465  OPERATOR::FR_mass_inv<dim,2*dim,real> mass_inv(1, max_degree, init_grid_degree, FR_Type);
2466  OPERATOR::FR_mass_inv_aux<dim,2*dim,real> mass_inv_aux(1, max_degree, init_grid_degree, FR_Type_Aux);
2467 
2468  OPERATOR::vol_projection_operator_FR<dim,2*dim,real> projection_oper(1, max_degree, init_grid_degree, FR_Type, true);
2469  OPERATOR::vol_projection_operator_FR_aux<dim,2*dim,real> projection_oper_aux(1, max_degree, init_grid_degree, FR_Type_Aux, true);
2470 
2472 
2473  const unsigned int grid_degree = this->high_order_grid->fe_system.tensor_degree();
2474  const dealii::FESystem<dim> &fe_metric = high_order_grid->fe_system;
2475  const unsigned int n_metric_dofs = high_order_grid->fe_system.dofs_per_cell;
2476  auto metric_cell = high_order_grid->dof_handler_grid.begin_active();
2477 
2478  auto first_cell = dof_handler.begin_active();
2479  const bool Cartesian_first_element = (first_cell->manifold_id() == dealii::numbers::flat_manifold_id) ? true : false;
2480 
2481  if(Cartesian_first_element){//then we can factor out det of Jac and rapidly simplify
2482  if(use_auxiliary_eq){
2483  mass_inv_aux.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2484  }
2485  else{
2487  }
2488  }
2489  else{//we always use weight-adjusted for curvilinear based off the projection operator
2490  if(use_auxiliary_eq){
2491  projection_oper_aux.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2492  }
2493  else{
2494  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2495  }
2496  }
2497 
2498  dealii::Timer timer;
2500  timer.start();
2501  }
2502 
2503  for (auto soln_cell = dof_handler.begin_active(); soln_cell != dof_handler.end(); ++soln_cell, ++metric_cell) {
2504  if (!soln_cell->is_locally_owned()) continue;
2505 
2506  const unsigned int poly_degree = soln_cell->active_fe_index();
2507  const unsigned int n_dofs_cell = fe_collection[poly_degree].n_dofs_per_cell();
2508  std::vector<dealii::types::global_dof_index> current_dofs_indices;
2509  current_dofs_indices.resize(n_dofs_cell);
2510  soln_cell->get_dof_indices (current_dofs_indices);
2511 
2512  const bool Cartesian_element = (soln_cell->manifold_id() == dealii::numbers::flat_manifold_id);
2513 
2514  // if poly degree, the element manifold type, or grid degree changed for this cell, reinitialize the reference operator
2515  if((poly_degree != mass_inv.current_degree && Cartesian_element && !use_auxiliary_eq) ||
2516  (poly_degree != projection_oper.current_degree && (grid_degree > 1 || Cartesian_element) && !use_auxiliary_eq))
2517  {
2519  if(Cartesian_element){//then we can factor out det of Jac and rapidly simplify
2521  if(use_auxiliary_eq){
2522  mass_inv_aux.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2523  }
2524  }
2525  else{//we always use weight-adjusted for curvilinear based off the projection operator
2526  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2527  if(use_auxiliary_eq){
2528  projection_oper_aux.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2529  }
2530  }
2531  }
2532 
2533  // get mapping support points and determinant of Jacobian
2534  // setup metric cell
2535  std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
2536  metric_cell->get_dof_indices (metric_dof_indices);
2537  // get mapping_support points
2538  std::array<std::vector<real>,dim> mapping_support_points;
2539  for(int idim=0; idim<dim; idim++){
2540  mapping_support_points[idim].resize(n_metric_dofs/dim);
2541  }
2542  const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(grid_degree);
2543  for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
2544  const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]);
2545  const unsigned int istate = fe_metric.system_to_component_index(idof).first;
2546  const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
2547  const unsigned int igrid_node = index_renumbering[ishape];
2548  mapping_support_points[istate][igrid_node] = val;
2549  }
2550  //get determinant of Jacobian
2551  const unsigned int n_quad_pts = volume_quadrature_collection[poly_degree].size();
2552  const unsigned int n_grid_nodes = n_metric_dofs / dim;
2553  //get determinant of Jacobian
2554  OPERATOR::metric_operators<real, dim, 2*dim> metric_oper(1, poly_degree, grid_degree);
2556  n_quad_pts, n_grid_nodes,
2557  mapping_support_points,
2558  mapping_basis);
2559  //solve mass inverse times input vector for each state independently
2560  for(int istate=0; istate<nstate; istate++){
2561  const unsigned int n_shape_fns = n_dofs_cell / nstate;
2562  std::vector<real> local_input_vector(n_shape_fns);
2563  std::vector<real> local_output_vector(n_shape_fns);
2564 
2565  for(unsigned int ishape=0; ishape<n_shape_fns; ishape++){
2566  const unsigned int idof = istate * n_shape_fns + ishape;
2567  local_input_vector[ishape] = input_vector[current_dofs_indices[idof]];
2568  }
2569 
2570  if(Cartesian_element){
2571  if(use_auxiliary_eq){
2572  mass_inv_aux.matrix_vector_mult_1D(local_input_vector, local_output_vector,
2573  mass_inv_aux.oneD_vol_operator,
2574  false, 1.0 / metric_oper.det_Jac_vol[0]);
2575  }
2576  else{
2577  mass_inv.matrix_vector_mult_1D(local_input_vector, local_output_vector,
2578  mass_inv.oneD_vol_operator,
2579  false, 1.0 / metric_oper.det_Jac_vol[0]);
2580  }
2581  }
2582  else{
2583  if(use_auxiliary_eq){
2584  std::vector<real> projection_of_input(n_quad_pts);
2585  projection_oper_aux.matrix_vector_mult_1D(local_input_vector, projection_of_input,
2586  projection_oper_aux.oneD_transpose_vol_operator);
2587  const std::vector<double> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2588  std::vector<real> JxW_inv(n_quad_pts);
2589  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2590  JxW_inv[iquad] = 1.0 / (quad_weights[iquad] * metric_oper.det_Jac_vol[iquad]);
2591  }
2592  projection_oper_aux.inner_product_1D(projection_of_input, JxW_inv,
2593  local_output_vector,
2594  projection_oper_aux.oneD_transpose_vol_operator);
2595  }
2596  else{
2597  std::vector<real> projection_of_input(n_quad_pts);
2598  projection_oper.matrix_vector_mult_1D(local_input_vector, projection_of_input,
2599  projection_oper.oneD_transpose_vol_operator);
2600  const std::vector<double> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2601  std::vector<real> JxW_inv(n_quad_pts);
2602  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2603  JxW_inv[iquad] = 1.0 / (quad_weights[iquad] * metric_oper.det_Jac_vol[iquad]);
2604  }
2605  projection_oper.inner_product_1D(projection_of_input, JxW_inv,
2606  local_output_vector,
2607  projection_oper.oneD_transpose_vol_operator);
2608  }
2609  }
2610 
2611  for(unsigned int ishape=0; ishape<n_shape_fns; ishape++){
2612  const unsigned int idof = istate * n_shape_fns + ishape;
2613  output_vector[current_dofs_indices[idof]] = local_output_vector[ishape];
2614  }
2615  }//end of state loop
2616  }//end of cell loop
2617 
2619  timer.stop();
2620  assemble_residual_time += timer.cpu_time();
2621  }
2622 }
2623 
2624 template<int dim, typename real, typename MeshType>
2626  const dealii::LinearAlgebra::distributed::Vector<double> &input_vector,
2627  dealii::LinearAlgebra::distributed::Vector<double> &output_vector,
2628  const bool use_auxiliary_eq,
2629  const bool use_unmodified_mass_matrix)
2630 {
2633  const FR_enum FR_cDG = FR_enum::cDG;
2634  // if using only the M norm, set c=0 through the choice of cDG, which results in K=0
2635  // and the un-modified mass matrix will be applied.
2636  const FR_enum FR_Type = (use_unmodified_mass_matrix) ? FR_cDG : this->all_parameters->flux_reconstruction_type;
2637  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2638 
2639  const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree();
2640  OPERATOR::mapping_shape_functions<dim,2*dim,real> mapping_basis(1, max_degree, init_grid_degree);
2641 
2642  OPERATOR::FR_mass<dim,2*dim,real> mass(1, max_degree, init_grid_degree, FR_Type);
2643  OPERATOR::FR_mass_aux<dim,2*dim,real> mass_aux(1, max_degree, init_grid_degree, FR_Type_Aux);
2644 
2645  OPERATOR::vol_projection_operator<dim,2*dim,real> projection_oper(1, max_degree, init_grid_degree);
2646 
2648 
2649  const unsigned int grid_degree = this->high_order_grid->fe_system.tensor_degree();
2650  const dealii::FESystem<dim> &fe_metric = high_order_grid->fe_system;
2651  const unsigned int n_metric_dofs = high_order_grid->fe_system.dofs_per_cell;
2652  auto metric_cell = high_order_grid->dof_handler_grid.begin_active();
2653 
2654  auto first_cell = dof_handler.begin_active();
2655  const bool Cartesian_first_element = (first_cell->manifold_id() == dealii::numbers::flat_manifold_id);
2656 
2657  if(use_auxiliary_eq){
2659  if(grid_degree>1 || !Cartesian_first_element){
2660  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2661  }
2662  }
2663  else{
2665  if(grid_degree>1 || !Cartesian_first_element){
2666  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2667  }
2668  }
2669 
2670  for (auto soln_cell = dof_handler.begin_active(); soln_cell != dof_handler.end(); ++soln_cell, ++metric_cell) {
2671  if (!soln_cell->is_locally_owned()) continue;
2672 
2673  const unsigned int poly_degree = soln_cell->active_fe_index();
2674  const unsigned int n_dofs_cell = fe_collection[poly_degree].n_dofs_per_cell();
2675  std::vector<dealii::types::global_dof_index> current_dofs_indices;
2676  current_dofs_indices.resize(n_dofs_cell);
2677  soln_cell->get_dof_indices (current_dofs_indices);
2678 
2679  const bool Cartesian_element = (soln_cell->manifold_id() == dealii::numbers::flat_manifold_id) ? true : false;
2680 
2681  //if poly degree changed for this cell, rinitialize
2682  if((poly_degree != mass.current_degree && (grid_degree == 1 || Cartesian_element) && !use_auxiliary_eq) ||
2683  (poly_degree != projection_oper.current_degree && (grid_degree > 1 || !Cartesian_element) && !use_auxiliary_eq)){
2685  if(use_auxiliary_eq){
2687  if(grid_degree>1 || !Cartesian_element){
2688  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2689  }
2690  }
2691  else{
2693  if(grid_degree>1 || !Cartesian_element){
2694  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2695  }
2696  }
2697  }
2698 
2699  //get mapping support points and determinant of Jacobian
2700  //setup metric cell
2701  std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
2702  metric_cell->get_dof_indices (metric_dof_indices);
2703  // get mapping_support points
2704  std::array<std::vector<real>,dim> mapping_support_points;
2705  for(int idim=0; idim<dim; idim++){
2706  mapping_support_points[idim].resize(n_metric_dofs/dim);
2707  }
2708  const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(grid_degree);
2709  for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
2710  const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]);
2711  const unsigned int istate = fe_metric.system_to_component_index(idof).first;
2712  const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
2713  const unsigned int igrid_node = index_renumbering[ishape];
2714  mapping_support_points[istate][igrid_node] = val;
2715  }
2716  //get determinant of Jacobian
2717  const unsigned int n_quad_pts = volume_quadrature_collection[poly_degree].size();
2718  const unsigned int n_grid_nodes = n_metric_dofs / dim;
2719  //get determinant of Jacobian
2720  OPERATOR::metric_operators<real, dim, 2*dim> metric_oper(1, poly_degree, grid_degree);
2722  n_quad_pts, n_grid_nodes,
2723  mapping_support_points,
2724  mapping_basis);
2725 
2726  //solve mass inverse times input vector for each state independently
2727  for(int istate=0; istate<nstate; istate++){
2728  const unsigned int n_shape_fns = n_dofs_cell / nstate;
2729  std::vector<real> local_input_vector(n_shape_fns);
2730  std::vector<real> local_output_vector(n_shape_fns);
2731 
2732  for(unsigned int ishape=0; ishape<n_shape_fns; ishape++){
2733  const unsigned int idof = istate * n_shape_fns + ishape;
2734  local_input_vector[ishape] = input_vector[current_dofs_indices[idof]];
2735  }
2736  if(Cartesian_element){
2737  if(use_auxiliary_eq){
2738  mass_aux.matrix_vector_mult_1D(local_input_vector, local_output_vector,
2739  mass_aux.oneD_vol_operator,
2740  false, metric_oper.det_Jac_vol[0]);
2741  }
2742  else{
2743  mass.matrix_vector_mult_1D(local_input_vector, local_output_vector,
2744  mass.oneD_vol_operator,
2745  false, metric_oper.det_Jac_vol[0]);
2746  }
2747  }
2748  else{
2749  const unsigned int n_dofs_1D = projection_oper.oneD_vol_operator.n();
2750  const unsigned int n_quad_pts_1D = projection_oper.oneD_vol_operator.m();
2751  if(use_auxiliary_eq){
2752  const std::vector<double> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2753  dealii::FullMatrix<double> proj_mass(n_quad_pts_1D, n_dofs_1D);
2754  projection_oper.oneD_vol_operator.Tmmult(proj_mass, mass_aux.oneD_vol_operator);
2755 
2756  std::vector<real> projection_of_input(n_quad_pts);
2757  projection_oper.matrix_vector_mult_1D(local_input_vector, projection_of_input,
2758  proj_mass);
2759  std::vector<real> JxW(n_quad_pts);
2760  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2761  JxW[iquad] = (metric_oper.det_Jac_vol[iquad] / quad_weights[iquad]);
2762  }
2763  projection_oper.inner_product_1D(projection_of_input, JxW,
2764  local_output_vector,
2765  proj_mass);
2766  }
2767  else{
2768  const std::vector<double> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2769 
2770  std::vector<real> proj_mass(n_shape_fns);
2771  mass.matrix_vector_mult_1D(local_input_vector, proj_mass,
2772  mass.oneD_vol_operator);
2773  std::vector<real> projection_of_input(n_quad_pts);
2774  std::vector<real> ones(n_shape_fns, 1.0);
2775  projection_oper.inner_product_1D(proj_mass, ones, projection_of_input,
2776  projection_oper.oneD_vol_operator);
2777  std::vector<real> JxW(n_quad_pts);
2778  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2779  JxW[iquad] = (metric_oper.det_Jac_vol[iquad] / quad_weights[iquad])
2780  * projection_of_input[iquad];
2781  }
2782  std::vector<real> temp(n_shape_fns);
2783  projection_oper.matrix_vector_mult_1D(JxW,
2784  temp,
2785  projection_oper.oneD_vol_operator);
2786  mass.matrix_vector_mult_1D(temp,
2787  local_output_vector,
2788  mass.oneD_vol_operator);
2789 
2790  }
2791  }
2792 
2793  for(unsigned int ishape=0; ishape<n_shape_fns; ishape++){
2794  const unsigned int idof = istate * n_shape_fns + ishape;
2795  output_vector[current_dofs_indices[idof]] = local_output_vector[ishape];
2796  }
2797  }//end of state loop
2798  }//end of cell loop
2799 }
2800 
2801 template<int dim, typename real, typename MeshType>
2803 {
2804  system_matrix.add(scale, global_mass_matrix);
2805 }
2806 template<int dim, typename real, typename MeshType>
2808 {
2810 }
2811 template<int dim, typename real, typename MeshType>
2813 {
2816  std::vector<dealii::types::global_dof_index> dofs_indices;
2817  for (auto cell = dof_handler.begin_active(); cell!=dof_handler.end(); ++cell) {
2818 
2819  if (!cell->is_locally_owned()) continue;
2820 
2821  const unsigned int fe_index_curr_cell = cell->active_fe_index();
2822 
2823  // Current reference element related to this physical cell
2824  const dealii::FESystem<dim,dim> &current_fe_ref = fe_collection[fe_index_curr_cell];
2825  const unsigned int n_dofs_cell = current_fe_ref.n_dofs_per_cell();
2826 
2827  dofs_indices.resize(n_dofs_cell);
2828  cell->get_dof_indices (dofs_indices);
2829 
2830  const double max_dt = max_dt_cell[cell->active_cell_index()];
2831 
2832  for (unsigned int itest=0; itest<n_dofs_cell; ++itest) {
2833  const unsigned int istate_test = current_fe_ref.system_to_component_index(itest).first;
2834  for (unsigned int itrial=itest; itrial<n_dofs_cell; ++itrial) {
2835  const unsigned int istate_trial = current_fe_ref.system_to_component_index(itrial).first;
2836 
2837  if(istate_test==istate_trial) {
2838  const unsigned int row = dofs_indices[itest];
2839  const unsigned int col = dofs_indices[itrial];
2840  const double value = global_mass_matrix.el(row, col);
2841  const double new_val = value / (dt_scale * max_dt);
2842  AssertIsFinite(new_val);
2843  time_scaled_global_mass_matrix.set(row, col, new_val);
2844  if (row!=col) time_scaled_global_mass_matrix.set(col, row, new_val);
2845  }
2846  }
2847  }
2848  }
2849  time_scaled_global_mass_matrix.compress(dealii::VectorOperation::insert);
2850 }
2851 
2852 template<int dim, typename real> // To be replaced with operators->projection_operator
2853 std::vector< real > project_function(
2854  const std::vector< real > &function_coeff,
2855  const dealii::FESystem<dim,dim> &fe_input,
2856  const dealii::FESystem<dim,dim> &fe_output,
2857  const dealii::QGauss<dim> &projection_quadrature)
2858 {
2859  const unsigned int nstate = fe_input.n_components();
2860  const unsigned int n_vector_dofs_in = fe_input.dofs_per_cell;
2861  const unsigned int n_vector_dofs_out = fe_output.dofs_per_cell;
2862  const unsigned int n_dofs_in = n_vector_dofs_in / nstate;
2863  const unsigned int n_dofs_out = n_vector_dofs_out / nstate;
2864 
2865  assert(n_vector_dofs_in == function_coeff.size());
2866  assert(nstate == fe_output.n_components());
2867 
2868  const unsigned int n_quad_pts = projection_quadrature.size();
2869  const std::vector<dealii::Point<dim,double>> &unit_quad_pts = projection_quadrature.get_points();
2870 
2871  std::vector< real > function_coeff_out(n_vector_dofs_out); // output function coefficients.
2872  for (unsigned istate = 0; istate < nstate; ++istate) {
2873 
2874  std::vector< real > function_at_quad(n_quad_pts);
2875 
2876  // Output interpolation_operator is V^T in the notes.
2877  dealii::FullMatrix<double> interpolation_operator(n_dofs_out,n_quad_pts);
2878 
2879  for (unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2880  function_at_quad[iquad] = 0.0;
2881  for (unsigned int idof=0; idof<n_dofs_in; ++idof) {
2882  const unsigned int idof_vector = fe_input.component_to_system_index(istate,idof);
2883  function_at_quad[iquad] += function_coeff[idof_vector] * fe_input.shape_value_component(idof_vector,unit_quad_pts[iquad],istate);
2884  }
2885  function_at_quad[iquad] *= projection_quadrature.weight(iquad);
2886 
2887  for (unsigned int idof=0; idof<n_dofs_out; ++idof) {
2888  const unsigned int idof_vector = fe_output.component_to_system_index(istate,idof);
2889  interpolation_operator[idof][iquad] = fe_output.shape_value_component(idof_vector,unit_quad_pts[iquad],istate);
2890  }
2891  }
2892 
2893  std::vector< real > rhs(n_dofs_out);
2894  for (unsigned int idof=0; idof<n_dofs_out; ++idof) {
2895  rhs[idof] = 0.0;
2896  for (unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2897  rhs[idof] += interpolation_operator[idof][iquad] * function_at_quad[iquad];
2898  }
2899  }
2900 
2901  dealii::FullMatrix<double> mass(n_dofs_out, n_dofs_out);
2902  for(unsigned int row=0; row<n_dofs_out; ++row) {
2903  for(unsigned int col=0; col<n_dofs_out; ++col) {
2904  mass[row][col] = 0;
2905  }
2906  }
2907  for(unsigned int row=0; row<n_dofs_out; ++row) {
2908  for(unsigned int col=0; col<n_dofs_out; ++col) {
2909  for(unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2910  mass[row][col] += interpolation_operator[row][iquad] * interpolation_operator[col][iquad] * projection_quadrature.weight(iquad);
2911  }
2912  }
2913  }
2914  dealii::FullMatrix<double> inverse_mass(n_dofs_out, n_dofs_out);
2915  inverse_mass.invert(mass);
2916 
2917  for(unsigned int row=0; row<n_dofs_out; ++row) {
2918  const unsigned int idof_vector = fe_output.component_to_system_index(istate,row);
2919  function_coeff_out[idof_vector] = 0.0;
2920  for(unsigned int col=0; col<n_dofs_out; ++col) {
2921  function_coeff_out[idof_vector] += inverse_mass[row][col] * rhs[col];
2922  }
2923  }
2924  }
2925 
2926  return function_coeff_out;
2927 
2928 }
2929 
2930 template <int dim, typename real,typename MeshType>
2931 template <typename real2>
2933  const dealii::Quadrature<dim> &volume_quadrature,
2934  const std::vector< real2 > &soln_coeff_high,
2935  const dealii::FiniteElement<dim,dim> &fe_high,
2936  const std::vector<real2> &jac_det)
2937 {
2938  const unsigned int degree = fe_high.tensor_degree();
2939 
2940  if (degree == 0) return 0;
2941 
2942  const unsigned int nstate = fe_high.components;
2943  const unsigned int n_dofs_high = fe_high.dofs_per_cell;
2944 
2945  // Lower degree basis.
2946  const unsigned int lower_degree = degree-1;
2947  const dealii::FE_DGQLegendre<dim> fe_dgq_lower(lower_degree);
2948  const dealii::FESystem<dim,dim> fe_lower(fe_dgq_lower, nstate);
2949 
2950  // Projection quadrature.
2951  const dealii::QGauss<dim> projection_quadrature(degree+5);
2952  std::vector< real2 > soln_coeff_lower = project_function<dim,real2>( soln_coeff_high, fe_high, fe_lower, projection_quadrature);
2953 
2954  // Quadrature used for solution difference.
2955  const std::vector<dealii::Point<dim,double>> &unit_quad_pts = volume_quadrature.get_points();
2956 
2957  const unsigned int n_quad_pts = volume_quadrature.size();
2958  const unsigned int n_dofs_lower = fe_lower.dofs_per_cell;
2959 
2960  real2 element_volume = 0.0;
2961  real2 error = 0.0;
2962  real2 soln_norm = 0.0;
2963  std::vector<real2> soln_high(nstate);
2964  std::vector<real2> soln_lower(nstate);
2965  for (unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2966  for (unsigned int s=0; s<nstate; ++s) {
2967  soln_high[s] = 0.0;
2968  soln_lower[s] = 0.0;
2969  }
2970  // Interpolate solution
2971  for (unsigned int idof=0; idof<n_dofs_high; ++idof) {
2972  const unsigned int istate = fe_high.system_to_component_index(idof).first;
2973  soln_high[istate] += soln_coeff_high[idof] * fe_high.shape_value_component(idof,unit_quad_pts[iquad],istate);
2974  }
2975  // Interpolate low order solution
2976  for (unsigned int idof=0; idof<n_dofs_lower; ++idof) {
2977  const unsigned int istate = fe_lower.system_to_component_index(idof).first;
2978  soln_lower[istate] += soln_coeff_lower[idof] * fe_lower.shape_value_component(idof,unit_quad_pts[iquad],istate);
2979  }
2980  // Quadrature
2981  const real2 JxW = jac_det[iquad] * volume_quadrature.weight(iquad);
2982  element_volume += JxW;
2983  // Only integrate over the first state variable.
2984  // Persson and Peraire only did density.
2985  for (unsigned int s=0; s<1/*nstate*/; ++s)
2986  {
2987  error += (soln_high[s] - soln_lower[s]) * (soln_high[s] - soln_lower[s]) * JxW;
2988  soln_norm += soln_high[s] * soln_high[s] * JxW;
2989  }
2990  }
2991 
2992  if (soln_norm < 1e-15) return 0;
2993 
2994  const real2 S_e = sqrt(error / soln_norm);
2995  const real2 s_e = log10(S_e);
2996 
2998  const double s_0 = -0.00 - 4.00*log10(degree);
3000  const double low = s_0 - kappa;
3001  const double upp = s_0 + kappa;
3002 
3003  const real2 diameter = pow(element_volume, 1.0/dim);
3004  const real2 eps_0 = mu_scale * diameter / (double)degree;
3005 
3006  if ( s_e < low) return 0.0;
3007 
3008  if ( s_e > upp)
3009  {
3010  return eps_0;
3011  }
3012 
3013  const double PI = 4*atan(1);
3014  real2 eps = 1.0 + sin(PI * (s_e - s_0) * 0.5 / kappa);
3015  eps *= eps_0 * 0.5;
3016  return eps;
3017 }
3018 
3019 template <int dim, typename real, typename MeshType>
3020 void DGBase<dim,real,MeshType>::set_current_time(const real current_time_input)
3021 {
3022  this->current_time = current_time_input;
3023 }
3024 
3025 #if PHILIP_DIM!=1
3027 #endif
3028 
3031 
3032 template double DGBase<PHILIP_DIM,double,dealii::Triangulation<PHILIP_DIM>>::discontinuity_sensor<double>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< double > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<double> &jac_det);
3033 template FadType DGBase<PHILIP_DIM,double,dealii::Triangulation<PHILIP_DIM>>::discontinuity_sensor<FadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< FadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<FadType> &jac_det);
3034 template RadType DGBase<PHILIP_DIM,double,dealii::Triangulation<PHILIP_DIM>>::discontinuity_sensor<RadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< RadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<RadType> &jac_det);
3035 template FadFadType DGBase<PHILIP_DIM,double,dealii::Triangulation<PHILIP_DIM>>::discontinuity_sensor<FadFadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< FadFadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<FadFadType> &jac_det);
3036 template RadFadType DGBase<PHILIP_DIM,double,dealii::Triangulation<PHILIP_DIM>>::discontinuity_sensor<RadFadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< RadFadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<RadFadType> &jac_det);
3037 
3038 
3039 template double DGBase<PHILIP_DIM,double,dealii::parallel::distributed::Triangulation<PHILIP_DIM>>::discontinuity_sensor<double>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< double > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<double> &jac_det);
3040 template FadType DGBase<PHILIP_DIM,double,dealii::parallel::distributed::Triangulation<PHILIP_DIM>>::discontinuity_sensor<FadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< FadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<FadType> &jac_det);
3041 template RadType DGBase<PHILIP_DIM,double,dealii::parallel::distributed::Triangulation<PHILIP_DIM>>::discontinuity_sensor<RadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< RadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<RadType> &jac_det);
3042 template FadFadType DGBase<PHILIP_DIM,double,dealii::parallel::distributed::Triangulation<PHILIP_DIM>>::discontinuity_sensor<FadFadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< FadFadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<FadFadType> &jac_det);
3043 template RadFadType DGBase<PHILIP_DIM,double,dealii::parallel::distributed::Triangulation<PHILIP_DIM>>::discontinuity_sensor<RadFadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< RadFadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<RadFadType> &jac_det);
3044 
3045 
3046 template double DGBase<PHILIP_DIM,double,dealii::parallel::shared::Triangulation<PHILIP_DIM>>::discontinuity_sensor<double>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< double > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<double> &jac_det);
3047 template FadType DGBase<PHILIP_DIM,double,dealii::parallel::shared::Triangulation<PHILIP_DIM>>::discontinuity_sensor<FadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< FadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<FadType> &jac_det);
3048 template RadType DGBase<PHILIP_DIM,double,dealii::parallel::shared::Triangulation<PHILIP_DIM>>::discontinuity_sensor<RadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< RadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<RadType> &jac_det);
3049 template FadFadType DGBase<PHILIP_DIM,double,dealii::parallel::shared::Triangulation<PHILIP_DIM>>::discontinuity_sensor<FadFadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< FadFadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<FadFadType> &jac_det);
3050 template RadFadType DGBase<PHILIP_DIM,double,dealii::parallel::shared::Triangulation<PHILIP_DIM>>::discontinuity_sensor<RadFadType>(const dealii::Quadrature<PHILIP_DIM> &volume_quadrature, const std::vector< RadFadType > &soln_coeff_high, const dealii::FiniteElement<PHILIP_DIM,PHILIP_DIM> &fe_high, const std::vector<RadFadType> &jac_det);
3051 
3052 
3053 template void
3054 DGBase<PHILIP_DIM,double,dealii::Triangulation<PHILIP_DIM>>::assemble_cell_residual<dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>>,dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>>>(
3055  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_cell,
3056  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_metric_cell,
3057  const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R,
3058  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume,
3059  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_int,
3060  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_ext,
3061  dealii::hp::FESubfaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_subface,
3062  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume_lagrange,
3071  const bool compute_auxiliary_right_hand_side,
3072  dealii::LinearAlgebra::distributed::Vector<double> &rhs,
3073  std::array<dealii::LinearAlgebra::distributed::Vector<double>,PHILIP_DIM> &rhs_aux);
3074 
3075 template void
3076 DGBase<PHILIP_DIM,double,dealii::parallel::distributed::Triangulation<PHILIP_DIM>>::assemble_cell_residual<dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>>,dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>>>(
3077  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_cell,
3078  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_metric_cell,
3079  const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R,
3080  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume,
3081  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_int,
3082  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_ext,
3083  dealii::hp::FESubfaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_subface,
3084  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume_lagrange,
3093  const bool compute_auxiliary_right_hand_side,
3094  dealii::LinearAlgebra::distributed::Vector<double> &rhs,
3095  std::array<dealii::LinearAlgebra::distributed::Vector<double>,PHILIP_DIM> &rhs_aux);
3096 
3097 template void
3098 DGBase<PHILIP_DIM,double,dealii::parallel::shared::Triangulation<PHILIP_DIM>>::assemble_cell_residual<dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>>,dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>>>(
3099  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_cell,
3100  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_metric_cell,
3101  const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R,
3102  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume,
3103  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_int,
3104  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_ext,
3105  dealii::hp::FESubfaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_subface,
3106  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume_lagrange,
3115  const bool compute_auxiliary_right_hand_side,
3116  dealii::LinearAlgebra::distributed::Vector<double> &rhs,
3117  std::array<dealii::LinearAlgebra::distributed::Vector<double>,PHILIP_DIM> &rhs_aux);
3118 } // PHiLiP namespace
void output_face_results_vtk(const unsigned int cycle, const double current_time=0.0)
Output Euler face solution.
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:732
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)
Definition: dg_base.cpp:2932
dealii::SparsityPattern get_d2RdWdX_sparsity_pattern()
Evaluate SparsityPattern of the residual Hessian dual.d2RdXdW.
double CFL_mass_dRdW
CFL used to add mass matrix in the optimization FlowConstraints class.
Definition: dg_base.hpp:425
dealii::FullMatrix< double > build_dim_mass_matrix(const int nstate, const unsigned int n_dofs, const unsigned int n_quad_pts, basis_functions< dim, n_faces, real > &basis, const std::vector< double > &det_Jac, const std::vector< double > &quad_weights)
Assemble the dim mass matrix on the fly with metric Jacobian dependence.
Definition: operators.cpp:1253
void build_determinant_volume_metric_Jacobian(const unsigned int n_quad_pts, const unsigned int n_metric_dofs, const std::array< std::vector< real >, dim > &mapping_support_points, mapping_shape_functions< dim, n_faces, real > &mapping_basis)
Builds just the determinant of the volume metric determinant.
Definition: operators.cpp:2273
PartialDifferentialEquation pde_type
Store the PDE type to be solved.
dealii::Vector< double > artificial_dissipation_coeffs
Artificial dissipation in each cell.
Definition: dg_base.hpp:462
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1082
The metric independent inverse of the FR mass matrix .
Definition: operators.h:782
bool use_auxiliary_eq
Flag for using the auxiliary equation.
Definition: dg_base.hpp:938
const dealii::UpdateFlags neighbor_face_update_flags
Update flags needed at neighbor&#39; face points.
Definition: dg_base.hpp:877
Sacado::Fad::DFad< FadType > FadFadType
Sacado AD type that allows 2nd derivatives.
Definition: ADTypes.hpp:12
void time_scaled_mass_matrices(const real scale)
Definition: dg_base.cpp:2812
virtual void allocate_second_derivatives()
Allocates the second derivatives.
Definition: dg_base.cpp:1990
dealii::LinearAlgebra::distributed::Vector< double > artificial_dissipation_c0
Artificial dissipation coefficients.
Definition: dg_base.hpp:673
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1766
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:550
const dealii::hp::FECollection< 1 > oneD_fe_collection
1D Finite Element Collection for p-finite-element to represent the solution
Definition: dg_base.hpp:620
const unsigned int initial_degree
Initial polynomial degree assigned during constructor.
Definition: dg_base.hpp:99
dealii::LinearAlgebra::distributed::Vector< double > solution_d2R
Definition: dg_base.hpp:436
Sacado::Fad::DFad< double > FadType
Sacado AD type for first derivatives.
Definition: ADTypes.hpp:11
dealii::TrilinosWrappers::SparseMatrix dRdXv
Definition: dg_base.hpp:356
unsigned int current_grid_degree
Stores the degree of the current grid degree.
Definition: operators.h:1039
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
Definition: dg_base.hpp:91
void add_time_scaled_mass_matrices()
Add time scaled mass matrices to the system.
Definition: dg_base.cpp:2807
double assemble_residual_time
Computational time for assembling residual.
Definition: dg_base.hpp:661
bool output_face_results_vtk
Flag for outputting the surface solution vtk files.
dealii::LinearAlgebra::distributed::Vector< real > dual
Current optimization dual variables corresponding to the residual constraints also known as the adjoi...
Definition: dg_base.hpp:479
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1845
codi_JacobianComputationType RadType
CoDiPaco reverse-AD type for first derivatives.
Definition: ADTypes.hpp:27
dealii::LinearAlgebra::distributed::Vector< double > volume_nodes_dRdX
Definition: dg_base.hpp:432
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1732
The metric independent FR mass matrix for auxiliary equation .
Definition: operators.h:852
std::array< dealii::LinearAlgebra::distributed::Vector< double >, dim > auxiliary_right_hand_side
The auxiliary equations&#39; right hand sides.
Definition: dg_base.hpp:412
dealii::FullMatrix< double > tensor_product_state(const int nstate, const dealii::FullMatrix< double > &basis_x, const dealii::FullMatrix< double > &basis_y, const dealii::FullMatrix< double > &basis_z)
Returns the tensor product of matrices passed, but makes it sparse diagonal by state.
Definition: operators.cpp:106
void add_mass_matrices(const real scale)
Add mass matrices to the system scaled by a factor (likely time-step)
Definition: dg_base.cpp:2802
dealii::TrilinosWrappers::SparseMatrix global_mass_matrix_auxiliary
Global auxiliary mass matrix.
Definition: dg_base.hpp:336
std::shared_ptr< Triangulation > triangulation
Mesh.
Definition: dg_base.hpp:160
void output_results_vtk(const unsigned int cycle, const double current_time=0.0)
Output solution.
Definition: dg_base.cpp:1749
bool use_energy
Flag to use an energy monotonicity test.
Projection operator corresponding to basis functions onto -norm for auxiliary equation.
Definition: operators.h:751
void inner_product_1D(const std::vector< real > &input_vect, const std::vector< real > &weight_vect, std::vector< real > &output_vect, const dealii::FullMatrix< double > &basis_x, const bool adding=false, const double factor=1.0)
Apply the inner product operation using the 1D operator in each direction.
Definition: operators.cpp:524
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1538
dealii::QGauss< 0 > oneD_face_quadrature
1D surface quadrature is always one single point for all poly degrees.
Definition: dg_base.hpp:634
void update_artificial_dissipation_discontinuity_sensor()
Update discontinuity sensor.
Definition: dg_base.cpp:861
dealii::Point< dim > coordinates_of_highest_refined_cell(bool check_for_p_refined_cell=false)
Returns the coordinates of the most refined cell.
Definition: dg_base.cpp:329
Files for the baseline physics.
Definition: ADTypes.hpp:10
void allocate_auxiliary_equation()
Allocates the auxiliary equations&#39; variables and right hand side (primarily for Strong form diffusive...
Definition: dg_base.cpp:1854
const dealii::hp::FECollection< 1 > oneD_fe_collection_flux
1D collocated flux basis used in strong form
Definition: dg_base.hpp:630
bool use_weak_form
Flag to use weak or strong form of DG.
ManufacturedSolutionParam manufactured_solution_param
Associated manufactured solution parameters.
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:1036
dealii::SparsityPattern get_d2RdXdX_sparsity_pattern()
Evaluate SparsityPattern of the residual Hessian dual.d2RdXdX.
double get_residual_linfnorm() const
Returns the Linf-norm of the right_hand_side vector.
Definition: dg_base.cpp:1352
dealii::TrilinosWrappers::SparseMatrix system_matrix_transpose
Definition: dg_base.hpp:347
DGBase(const int nstate_input, 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)
Principal constructor that will call delegated constructor.
Definition: dg_base.cpp:60
dealii::FullMatrix< double > oneD_transpose_vol_operator
Stores the transpose of the operator for fast weight-adjusted solves.
Definition: operators.h:777
virtual void allocate_model_variables()=0
Allocate the necessary variables declared in src/physics/model.h.
std::unique_ptr< Epetra_RowMatrixTransposer > epetra_rowmatrixtransposer_dRdW
Epetra_RowMatrixTransposer used to transpose the system_matrix.
Definition: dg_base.hpp:350
Flux_Reconstruction
Type of correction in Flux Reconstruction.
dealii::TrilinosWrappers::SparseMatrix d2RdWdW
Definition: dg_base.hpp:360
Flux_Reconstruction_Aux flux_reconstruction_aux_type
Store flux reconstruction type for the auxiliary variables.
double get_residual_l2norm() const
Returns the L2-norm of the right_hand_side vector.
Definition: dg_base.cpp:1400
-th order modal derivative of basis fuctions, ie/
Definition: operators.h:519
virtual 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 > &soln_basis, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &flux_basis_stiffness, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_int, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_ext, OPERATOR::metric_operators< real, dim, 2 *dim > &metric_oper, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &mapping_basis, std::array< std::vector< real >, dim > &mapping_support_points, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_int, const dealii::FESystem< dim, dim > &current_fe_ref, dealii::Vector< real > &local_rhs_int_cell, std::vector< dealii::Tensor< 1, dim, real >> &local_auxiliary_RHS, const bool compute_auxiliary_right_hand_side, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)=0
Builds the necessary operators/fe values and assembles boundary residual.
void build_1D_shape_functions_at_grid_nodes(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Constructs the volume operator and gradient operator.
Definition: operators.cpp:2155
dealii::TrilinosWrappers::SparseMatrix global_mass_matrix
Global mass matrix.
Definition: dg_base.hpp:329
void reinit_operators_for_cell_residual_loop(const unsigned int poly_degree_int, const unsigned int poly_degree_ext, const unsigned int grid_degree, OPERATOR::basis_functions< dim, 2 *dim, real > &soln_basis_int, OPERATOR::basis_functions< dim, 2 *dim, real > &soln_basis_ext, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis_int, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis_ext, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &flux_basis_stiffness, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_int, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_ext, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &mapping_basis)
Builds needed operators for cell residual loop.
Definition: dg_base.cpp:1045
MPI_Comm mpi_communicator
MPI communicator.
Definition: dg_base.hpp:893
dealii::Vector< double > max_dt_cell
Time it takes for the maximum wavespeed to cross the cell domain.
Definition: dg_base.hpp:457
Main parameter class that contains the various other sub-parameter classes.
const dealii::hp::FECollection< 1 > oneD_fe_collection_1state
1D Finite Element Collection for p-finite-element to represent the solution for a single state...
Definition: dg_base.hpp:627
void reinit_operators_for_mass_matrix(const bool Cartesian_element, const unsigned int poly_degree, const unsigned int grid_degree, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &mapping_basis, OPERATOR::basis_functions< dim, 2 *dim, real > &basis, OPERATOR::local_mass< dim, 2 *dim, real > &reference_mass_matrix, OPERATOR::local_Flux_Reconstruction_operator< dim, 2 *dim, real > &reference_FR, OPERATOR::local_Flux_Reconstruction_operator_aux< dim, 2 *dim, real > &reference_FR_aux, OPERATOR::derivative_p< dim, 2 *dim, real > &deriv_p)
Builds needed operators to compute mass matrices/inverses efficiently.
Definition: dg_base.cpp:2026
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution.
Definition: dg_base.hpp:409
ESFR correction matrix without jac dependence.
Definition: operators.h:539
std::vector< real > det_Jac_vol
The determinant of the metric Jacobian at volume cubature nodes.
Definition: operators.h:1171
Local mass matrix without jacobian dependence.
Definition: operators.h:436
virtual void update_model_variables()=0
Update the necessary variables declared in src/physics/model.h.
ManufacturedConvergenceStudyParam manufactured_convergence_study_param
Contains parameters for manufactured convergence study.
bool enable_higher_order_vtk_output
Enable writing of higher-order vtk results.
Flux_Reconstruction flux_reconstruction_type
Store flux reconstruction type.
const int nstate
Number of state variables.
Definition: dg_base.hpp:96
dealii::DoFHandler< dim > dof_handler_artificial_dissipation
Degrees of freedom handler for C0 artificial dissipation.
Definition: dg_base.hpp:670
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1696
dealii::IndexSet locally_owned_dofs
Locally own degrees of freedom.
Definition: dg_base.hpp:398
dealii::LinearAlgebra::distributed::Vector< double > solution_dRdW
Definition: dg_base.hpp:419
dealii::LinearAlgebra::distributed::Vector< double > volume_nodes_dRdW
Definition: dg_base.hpp:422
dealii::SparsityPattern mass_sparsity_pattern
Sparsity pattern used on the system_matrix.
Definition: dg_base.hpp:321
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:391
dealii::TrilinosWrappers::SparseMatrix global_inverse_mass_matrix_auxiliary
Global inverse of the auxiliary mass matrix.
Definition: dg_base.hpp:339
dealii::FullMatrix< double > oneD_transpose_vol_operator
Stores the transpose of the operator for fast weight-adjusted solves.
Definition: operators.h:746
void build_1D_gradient_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1102
void reinit()
Reinitializes the DG object after a change of triangulation.
Definition: dg_base.cpp:112
dealii::TrilinosWrappers::SparseMatrix time_scaled_global_mass_matrix
Global mass matrix divided by the time scales.
Definition: dg_base.hpp:325
dealii::hp::QCollection< dim-1 > face_quadrature_collection
Quadrature used to evaluate face integrals.
Definition: dg_base.hpp:610
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:666
real evaluate_penalty_scaling(const DoFCellAccessorType &cell, const int iface, const dealii::hp::FECollection< dim > fe_collection) const
Definition: dg_base.cpp:398
bool do_renumber_dofs
Flag for renumbering DOFs.
const unsigned int max_degree
Maximum degree used for p-refi1nement.
Definition: dg_base.hpp:104
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1219
Base metric operators class that stores functions used in both the volume and on surface.
Definition: operators.h:1086
real current_time
The current time set in set_current_time()
Definition: dg_base.hpp:665
ESFR correction matrix for AUX EQUATION without jac dependence.
Definition: operators.h:655
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
Definition: dg_base.hpp:894
unsigned int get_max_fe_degree()
Gets the maximum value of currently active FE degree.
Definition: dg_base.cpp:305
dealii::IndexSet ghost_dofs
Locally relevant ghost degrees of freedom.
Definition: dg_base.hpp:399
The mapping shape functions evaluated at the desired nodes (facet set included in volume grid nodes f...
Definition: operators.h:1026
virtual void allocate_system(const bool compute_dRdW=true, const bool compute_dRdX=true, const bool compute_d2R=true)
Allocates the system.
Definition: dg_base.cpp:1866
bool use_manufactured_source_term
Uses non-zero source term based on the manufactured solution and the PDE.
virtual void allocate_dRdX()
Allocates the residual derivatives w.r.t the volume nodes.
Definition: dg_base.cpp:2016
const dealii::UpdateFlags face_update_flags
Update flags needed at face points.
Definition: dg_base.hpp:873
std::shared_ptr< HighOrderGrid< dim, real, MeshType > > high_order_grid
High order grid that will provide the MappingFEField.
Definition: dg_base.hpp:655
void build_1D_shape_functions_at_volume_flux_nodes(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Constructs the volume and volume gradient operator.
Definition: operators.cpp:2176
std::vector< real > project_function(const std::vector< real > &function_coeff, const dealii::FESystem< dim, dim > &fe_input, const dealii::FESystem< dim, dim > &fe_output, const dealii::QGauss< dim > &projection_quadrature)
Get the coefficients of a function projected onto a set of basis (to be replaced with operators->proj...
Definition: dg_base.cpp:2853
The metric independent FR mass matrix .
Definition: operators.h:828
dealii::LinearAlgebra::distributed::Vector< double > solution_dRdX
Definition: dg_base.hpp:429
dealii::TrilinosWrappers::SparseMatrix d2RdWdX
Definition: dg_base.hpp:368
const unsigned int max_grid_degree
Maximum grid degree used for hp-refi1nement.
Definition: dg_base.hpp:109
virtual 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 > &current_dofs_indices, const std::vector< dealii::types::global_dof_index > &neighbor_dofs_indices, const std::vector< dealii::types::global_dof_index > &current_metric_dofs_indices, const std::vector< dealii::types::global_dof_index > &neighbor_metric_dofs_indices, const unsigned int poly_degree_int, const unsigned int poly_degree_ext, const unsigned int grid_degree_int, const unsigned int grid_degree_ext, OPERATOR::basis_functions< dim, 2 *dim, real > &soln_basis_int, OPERATOR::basis_functions< dim, 2 *dim, real > &soln_basis_ext, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis_int, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis_ext, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &flux_basis_stiffness, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_int, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_ext, OPERATOR::metric_operators< real, dim, 2 *dim > &metric_oper_int, OPERATOR::metric_operators< real, dim, 2 *dim > &metric_oper_ext, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &mapping_basis, std::array< std::vector< real >, dim > &mapping_support_points, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_int, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_ext, dealii::Vector< real > &current_cell_rhs, dealii::Vector< real > &neighbor_cell_rhs, std::vector< dealii::Tensor< 1, dim, real >> &current_cell_rhs_aux, dealii::LinearAlgebra::distributed::Vector< double > &rhs, std::array< dealii::LinearAlgebra::distributed::Vector< double >, dim > &rhs_aux, const bool compute_auxiliary_right_hand_side, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)=0
Builds the necessary operators/fe values and assembles face residual.
dealii::LinearAlgebra::distributed::Vector< double > dual_d2R
Definition: dg_base.hpp:442
const dealii::UpdateFlags volume_update_flags
Update flags needed at volume points.
Definition: dg_base.hpp:870
dealii::IndexSet locally_relevant_dofs
Union of locally owned degrees of freedom and relevant ghost degrees of freedom.
Definition: dg_base.hpp:400
virtual 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 > &current_dofs_indices, const std::vector< dealii::types::global_dof_index > &neighbor_dofs_indices, const std::vector< dealii::types::global_dof_index > &current_metric_dofs_indices, const std::vector< dealii::types::global_dof_index > &neighbor_metric_dofs_indices, const unsigned int poly_degree_int, const unsigned int poly_degree_ext, const unsigned int grid_degree_int, const unsigned int grid_degree_ext, OPERATOR::basis_functions< dim, 2 *dim, real > &soln_basis_int, OPERATOR::basis_functions< dim, 2 *dim, real > &soln_basis_ext, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis_int, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis_ext, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &flux_basis_stiffness, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_int, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_ext, OPERATOR::metric_operators< real, dim, 2 *dim > &metric_oper_int, OPERATOR::metric_operators< real, dim, 2 *dim > &metric_oper_ext, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &mapping_basis, std::array< std::vector< real >, dim > &mapping_support_points, dealii::hp::FEFaceValues< dim, dim > &fe_values_collection_face_int, dealii::hp::FESubfaceValues< dim, dim > &fe_values_collection_subface, dealii::Vector< real > &current_cell_rhs, dealii::Vector< real > &neighbor_cell_rhs, std::vector< dealii::Tensor< 1, dim, real >> &current_cell_rhs_aux, dealii::LinearAlgebra::distributed::Vector< double > &rhs, std::array< dealii::LinearAlgebra::distributed::Vector< double >, dim > &rhs_aux, const bool compute_auxiliary_right_hand_side, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)=0
Builds the necessary operators/fe values and assembles subface residual.
dealii::SparsityPattern get_dRdX_sparsity_pattern()
Evaluate SparsityPattern of dRdX.
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1385
dealii::FullMatrix< double > oneD_vol_operator
Stores the one dimensional volume operator.
Definition: operators.h:355
static std::unique_ptr< dealii::DataPostprocessor< dim > > create_Postprocessor(const Parameters::AllParameters *const parameters_input)
Create the post-processor with the correct template parameters.
double kappa_artificial_dissipation
Parameter kappa from Persson and Peraire, 2008.
Flux_Reconstruction_Aux
Type of correction in Flux Reconstruction for the auxiliary variables.
void evaluate_local_metric_dependent_mass_matrix_and_set_in_global_mass_matrix(const bool Cartesian_element, const bool do_inverse_mass_matrix, const unsigned int poly_degree, const unsigned int curr_grid_degree, const unsigned int n_quad_pts, const unsigned int n_dofs_cell, const std::vector< dealii::types::global_dof_index > dofs_indices, OPERATOR::metric_operators< real, dim, 2 *dim > &metric_oper, OPERATOR::basis_functions< dim, 2 *dim, real > &basis, OPERATOR::local_mass< dim, 2 *dim, real > &reference_mass_matrix, OPERATOR::local_Flux_Reconstruction_operator< dim, 2 *dim, real > &reference_FR, OPERATOR::local_Flux_Reconstruction_operator_aux< dim, 2 *dim, real > &reference_FR_aux, OPERATOR::derivative_p< dim, 2 *dim, real > &deriv_p)
Evaluates the metric dependent local mass matrices and inverses, then sets them in the global matrice...
Definition: dg_base.cpp:2229
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:793
void build_1D_surface_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 0 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1122
dealii::LinearAlgebra::distributed::Vector< double > volume_nodes_d2R
Definition: dg_base.hpp:439
virtual void allocate_dual_vector()=0
Allocate the dual vector for optimization.
double mu_artificial_dissipation
Parameter mu from Persson & Peraire, 2008.
dealii::Vector< double > artificial_dissipation_se
Artificial dissipation error ratio sensor in each cell.
Definition: dg_base.hpp:465
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:704
unsigned int get_min_fe_degree()
Gets the minimum value of currently active FE degree.
Definition: dg_base.cpp:317
RenumberDofsType
Renumber dofs type.
void set_high_order_grid(std::shared_ptr< HighOrderGrid< dim, real, MeshType >> new_high_order_grid)
Sets the associated high order grid with the provided one.
Definition: dg_base.cpp:121
std::string solution_vtk_files_directory_name
Name of directory for writing solution vtk files.
The metric independent inverse of the FR mass matrix for auxiliary equation .
Definition: operators.h:805
MassiveCollectionTuple create_collection_tuple(const unsigned int max_degree, const int nstate, const Parameters::AllParameters *const parameters_input) const
Used in the delegated constructor.
Definition: dg_base.cpp:142
virtual 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 > &soln_basis, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &flux_basis_stiffness, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_int, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_ext, OPERATOR::metric_operators< real, dim, 2 *dim > &metric_oper, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &mapping_basis, std::array< std::vector< real >, dim > &mapping_support_points, dealii::hp::FEValues< dim, dim > &fe_values_collection_volume, dealii::hp::FEValues< dim, dim > &fe_values_collection_volume_lagrange, const dealii::FESystem< dim, dim > &current_fe_ref, dealii::Vector< real > &local_rhs_int_cell, std::vector< dealii::Tensor< 1, dim, real >> &local_auxiliary_RHS, const bool compute_auxiliary_right_hand_side, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R)=0
Builds the necessary operators/fe values and assembles volume residual.
virtual void set_use_auxiliary_eq()=0
Set use_auxiliary_eq flag.
Projection operator corresponding to basis functions onto -norm.
Definition: operators.h:720
dealii::DoFHandler< dim > dof_handler
Finite Element Collection to represent the high-order grid.
Definition: dg_base.hpp:652
FluxNodes flux_nodes_type
Store selected FluxNodes from the input file.
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:446
dealii::FullMatrix< double > build_dim_Flux_Reconstruction_operator_directly(const int nstate, const unsigned int n_dofs, dealii::FullMatrix< double > &pth_deriv, dealii::FullMatrix< double > &mass_matrix)
Computes the dim sized flux reconstruction operator for general Mass Matrix (needed for curvilinear)...
Definition: operators.cpp:1556
dealii::SparsityPattern sparsity_pattern
Sparsity pattern used on the system_matrix.
Definition: dg_base.hpp:317
void apply_global_mass_matrix(const dealii::LinearAlgebra::distributed::Vector< double > &input_vector, dealii::LinearAlgebra::distributed::Vector< double > &output_vector, const bool use_auxiliary_eq=false, const bool use_unmodified_mass_matrix=false)
Applies the local metric dependent mass matrices when the global is not stored.
Definition: dg_base.cpp:2625
dealii::SparsityPattern get_d2RdWdW_sparsity_pattern()
Evaluate SparsityPattern of the residual Hessian dual.d2RdWdW.
void time_scale_solution_update(dealii::LinearAlgebra::distributed::Vector< double > &solution_update, const real CFL) const
Scales a solution update with the appropriate maximum time step.
Definition: dg_base.cpp:265
bool add_artificial_dissipation
Flag to add artificial dissipation from Persson&#39;s shock capturing paper.
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:839
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1305
dealii::TrilinosWrappers::SparseMatrix system_matrix
Definition: dg_base.hpp:343
void evaluate_mass_matrices(bool do_inverse_mass_matrix=false)
Allocates and evaluates the mass matrices for the entire grid.
Definition: dg_base.cpp:2064
const dealii::hp::FECollection< dim > fe_collection_lagrange
Lagrange basis used in strong form.
Definition: dg_base.hpp:614
dealii::Vector< double > cell_volume
Time it takes for the maximum wavespeed to cross the cell domain.
Definition: dg_base.hpp:450
bool current_cell_should_do_the_work(const DoFCellAccessorType1 &current_cell, const DoFCellAccessorType2 &neighbor_cell) const
In the case that two cells have the same coarseness, this function decides if the current cell should...
Definition: dg_base.cpp:418
virtual void assemble_auxiliary_residual()=0
Asembles the auxiliary equations&#39; residuals and solves.
double sipg_penalty_factor
Scaling of Symmetric Interior Penalty term to ensure coercivity.
void set_current_time(const real current_time_input)
Sets the current time within DG to be used for unsteady source terms.
Definition: dg_base.cpp:3020
dealii::FullMatrix< double > build_dim_Flux_Reconstruction_operator(const dealii::FullMatrix< double > &local_Mass_Matrix, const int nstate, const unsigned int n_dofs)
Computes the dim sized flux reconstruction operator with simplified tensor product form...
Definition: operators.cpp:1617
bool use_weight_adjusted_mass
Flag to use weight-adjusted Mass Matrix for curvilinear elements.
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1806
bool use_periodic_bc
Flag to use periodic BC.
dealii::hp::QCollection< 1 > oneD_quadrature_collection
1D quadrature to generate Lagrange polynomials for the sake of flux interpolation.
Definition: dg_base.hpp:632
std::array< dealii::LinearAlgebra::distributed::Vector< double >, dim > auxiliary_solution
The auxiliary equations&#39; solution.
Definition: dg_base.hpp:415
bool freeze_artificial_dissipation
Flag to freeze artificial dissipation.
Definition: dg_base.hpp:928
dealii::TrilinosWrappers::SparseMatrix d2RdXdX
Definition: dg_base.hpp:364
DGBase is independent of the number of state variables.
Definition: dg_base.hpp:82
void allocate_artificial_dissipation()
Allocates variables of artificial dissipation.
Definition: dg_base.cpp:1971
void assemble_cell_residual(const DoFCellAccessorType1 &current_cell, const DoFCellAccessorType2 &current_metric_cell, const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R, dealii::hp::FEValues< dim, dim > &fe_values_collection_volume, 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, dealii::hp::FEValues< dim, dim > &fe_values_collection_volume_lagrange, OPERATOR::basis_functions< dim, 2 *dim, real > &soln_basis_int, OPERATOR::basis_functions< dim, 2 *dim, real > &soln_basis_ext, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis_int, OPERATOR::basis_functions< dim, 2 *dim, real > &flux_basis_ext, OPERATOR::local_basis_stiffness< dim, 2 *dim, real > &flux_basis_stiffness, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_int, OPERATOR::vol_projection_operator< dim, 2 *dim, real > &soln_basis_projection_oper_ext, OPERATOR::mapping_shape_functions< dim, 2 *dim, real > &mapping_basis, const bool compute_auxiliary_right_hand_side, dealii::LinearAlgebra::distributed::Vector< double > &rhs, std::array< dealii::LinearAlgebra::distributed::Vector< double >, dim > &rhs_aux)
Used in assemble_residual().
Definition: dg_base.cpp:454
dealii::hp::QCollection< dim > volume_quadrature_collection
Finite Element Collection to represent the high-order grid.
Definition: dg_base.hpp:608
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1906
void set_all_cells_fe_degree(const unsigned int degree)
Refers to a collection Mappings, which represents the high-order grid.
Definition: dg_base.cpp:293
unsigned int n_dofs() const
Number of degrees of freedom.
Definition: dg_base.cpp:1458
void build_1D_shape_functions_at_flux_nodes(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature, const dealii::Quadrature< 0 > &face_quadrature)
Constructs the volume, gradient, surface, and surface gradient operator.
Definition: operators.cpp:2164
ArtificialDissipationParam artificial_dissipation_param
Contains parameters for artificial dissipation.
codi_HessianComputationType RadFadType
Nested reverse-forward mode type for Jacobian and Hessian computation using TapeHelper.
Definition: ADTypes.hpp:28
void matrix_vector_mult_1D(const std::vector< real > &input_vect, std::vector< real > &output_vect, const dealii::FullMatrix< double > &basis_x, const bool adding=false, const double factor=1.0)
Apply the matrix vector operation using the 1D operator in each direction.
Definition: operators.cpp:308
RenumberDofsType renumber_dofs_type
Store selected RenumberDofsType from the input file.
void build_1D_surface_gradient_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 0 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1149
const dealii::hp::FECollection< dim > fe_collection
Finite Element Collection for p-finite-element to represent the solution.
Definition: dg_base.hpp:597
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1936
std::tuple< dealii::hp::FECollection< dim >, dealii::hp::QCollection< dim >, dealii::hp::QCollection< dim-1 >, dealii::hp::FECollection< dim >, dealii::hp::FECollection< 1 >, dealii::hp::FECollection< 1 >, dealii::hp::FECollection< 1 >, dealii::hp::QCollection< 1 > > MassiveCollectionTuple
Makes for cleaner doxygen documentation.
Definition: dg_base.hpp:145
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:529
double max_artificial_dissipation_coeff
Stores maximum artificial dissipation while assembling the residual.
Definition: dg_base.hpp:930
Projection operator corresponding to basis functions onto M-norm (L2).
Definition: operators.h:694
dealii::LinearAlgebra::distributed::Vector< double > right_hand_side
Residual of the current solution.
Definition: dg_base.hpp:396
void assemble_residual(const bool compute_dRdW=false, const bool compute_dRdX=false, const bool compute_d2R=false, const double CFL_mass=0.0)
Main loop of the DG class.
Definition: dg_base.cpp:1091
Local stiffness matrix without jacobian dependence.
Definition: operators.h:472
dealii::TrilinosWrappers::SparseMatrix global_inverse_mass_matrix
Global inverser mass matrix.
Definition: dg_base.hpp:332
void set_dual(const dealii::LinearAlgebra::distributed::Vector< real > &dual_input)
Sets the stored dual variables used to compute the dual dotted with the residual Hessians.
Definition: dg_base.cpp:855
int overintegration
Number of additional quadrature points to use.
bool store_residual_cpu_time
Flag to store the residual local processor cput time.
const dealii::FE_Q< dim > fe_q_artificial_dissipation
Continuous distribution of artificial dissipation.
Definition: dg_base.hpp:667
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Definition: operators.cpp:1876
void apply_inverse_global_mass_matrix(const dealii::LinearAlgebra::distributed::Vector< double > &input_vector, dealii::LinearAlgebra::distributed::Vector< double > &output_vector, const bool use_auxiliary_eq=false)
Applies the inverse of the local metric dependent mass matrices when the global is not stored...
Definition: dg_base.cpp:2452