[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 
2069  const double FR_user_specified_correction_parameter_value = this->all_parameters->FR_user_specified_correction_parameter_value;
2070 
2072  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2073 
2074  // flag for energy tests
2075  const bool use_energy = this->all_parameters->use_energy;
2076 
2077  // Mass matrix sparsity pattern
2078  dealii::DynamicSparsityPattern dsp(dof_handler.n_dofs());
2079  std::vector<dealii::types::global_dof_index> dofs_indices;
2080  for (auto cell = dof_handler.begin_active(); cell!=dof_handler.end(); ++cell) {
2081 
2082  if (!cell->is_locally_owned()) continue;
2083 
2084  const unsigned int fe_index_curr_cell = cell->active_fe_index();
2085 
2086  // Current reference element related to this physical cell
2087  const dealii::FESystem<dim,dim> &current_fe_ref = fe_collection[fe_index_curr_cell];
2088  const unsigned int n_dofs_cell = current_fe_ref.n_dofs_per_cell();
2089 
2090  dofs_indices.resize(n_dofs_cell);
2091  cell->get_dof_indices (dofs_indices);
2092  for (unsigned int itest=0; itest<n_dofs_cell; ++itest) {
2093  for (unsigned int itrial=0; itrial<n_dofs_cell; ++itrial) {
2094  dsp.add(dofs_indices[itest], dofs_indices[itrial]);
2095  }
2096  }
2097  }
2098  // Initialize global matrices to 0.
2099  dealii::SparsityTools::distribute_sparsity_pattern(dsp, dof_handler.locally_owned_dofs(), mpi_communicator, locally_owned_dofs);
2100  mass_sparsity_pattern.copy_from(dsp);
2101  if (do_inverse_mass_matrix) {
2103  if (use_auxiliary_eq){
2105  }
2106  if (use_energy){//for split form get energy
2108  if (use_auxiliary_eq){
2110  }
2111  }
2112  } else {
2114  if (use_auxiliary_eq){
2116  }
2117  }
2118 
2119  // setup 1D operators for ONE STATE. We loop over states in assembly for speedup.
2120  const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree();
2121  OPERATOR::mapping_shape_functions<dim,2*dim,real> mapping_basis(1, max_degree, init_grid_degree);//first set at max degree
2122  OPERATOR::basis_functions<dim,2*dim,real> basis(1, max_degree, init_grid_degree);
2123  OPERATOR::local_mass<dim,2*dim,real> reference_mass_matrix(1, max_degree, init_grid_degree);//first set at max degree
2124  OPERATOR::local_Flux_Reconstruction_operator<dim,2*dim,real> reference_FR(1, max_degree, init_grid_degree, FR_Type, FR_user_specified_correction_parameter_value);
2125  OPERATOR::local_Flux_Reconstruction_operator_aux<dim,2*dim,real> reference_FR_aux(1, max_degree, init_grid_degree, FR_Type_Aux);
2126  OPERATOR::derivative_p<dim,2*dim,real> deriv_p(1, max_degree, init_grid_degree);
2127 
2128  auto first_cell = dof_handler.begin_active();
2129  const bool Cartesian_first_element = (first_cell->manifold_id() == dealii::numbers::flat_manifold_id);
2130 
2131  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);
2132 
2133  //Loop over cells and set the matrices.
2134  auto metric_cell = high_order_grid->dof_handler_grid.begin_active();
2135  for (auto cell = dof_handler.begin_active(); cell!=dof_handler.end(); ++cell, ++metric_cell) {
2136 
2137  if (!cell->is_locally_owned()) continue;
2138 
2139  const bool Cartesian_element = (cell->manifold_id() == dealii::numbers::flat_manifold_id);
2140 
2141  const unsigned int fe_index_curr_cell = cell->active_fe_index();
2142  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
2143 
2144  //Check if need to recompute the 1D basis for the current degree (if different than previous cell)
2145  //That is, if the poly_degree, manifold type, or grid degree is different than previous reference operator
2146  if((fe_index_curr_cell != mapping_basis.current_degree) ||
2147  (curr_grid_degree != mapping_basis.current_grid_degree))
2148  {
2149  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);
2150 
2151  mapping_basis.current_degree = fe_index_curr_cell;
2152  basis.current_degree = fe_index_curr_cell;
2153  reference_mass_matrix.current_degree = fe_index_curr_cell;
2154  reference_FR.current_degree = fe_index_curr_cell;
2155  reference_FR_aux.current_degree = fe_index_curr_cell;
2156  deriv_p.current_degree = fe_index_curr_cell;
2157  }
2158 
2159  // Current reference element related to this physical cell
2160  const unsigned int n_dofs_cell = fe_collection[fe_index_curr_cell].n_dofs_per_cell();
2161  const unsigned int n_quad_pts = volume_quadrature_collection[fe_index_curr_cell].size();
2162 
2163  //setup metric cell
2164  const dealii::FESystem<dim> &fe_metric = high_order_grid->fe_system;
2165  const unsigned int n_metric_dofs = high_order_grid->fe_system.dofs_per_cell;
2166  const unsigned int n_grid_nodes = n_metric_dofs/dim;
2167  std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
2168  metric_cell->get_dof_indices (metric_dof_indices);
2169  // get mapping_support points
2170  std::array<std::vector<real>,dim> mapping_support_points;
2171  for(int idim=0; idim<dim; idim++){
2172  mapping_support_points[idim].resize(n_metric_dofs/dim);
2173  }
2174  const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(curr_grid_degree);
2175  for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
2176  const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]);
2177  const unsigned int istate = fe_metric.system_to_component_index(idof).first;
2178  const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
2179  const unsigned int igrid_node = index_renumbering[ishape];
2180  mapping_support_points[istate][igrid_node] = val;
2181  }
2182 
2183  //get determinant of Jacobian
2184  OPERATOR::metric_operators<real, dim, 2*dim> metric_oper(nstate, fe_index_curr_cell, curr_grid_degree);
2186  n_quad_pts, n_grid_nodes,
2187  mapping_support_points,
2188  mapping_basis);
2189 
2190  //Get dofs indices to set local matrices in global.
2191  dofs_indices.resize(n_dofs_cell);
2192  cell->get_dof_indices (dofs_indices);
2193  //Compute local matrices and set them in the global system.
2195  Cartesian_element,
2196  do_inverse_mass_matrix,
2197  fe_index_curr_cell,
2198  curr_grid_degree,
2199  n_quad_pts,
2200  n_dofs_cell,
2201  dofs_indices,
2202  metric_oper,
2203  basis,
2204  reference_mass_matrix,
2205  reference_FR,
2206  reference_FR_aux,
2207  deriv_p);
2208  }//end of cell loop
2209 
2210  //Compress global matrices.
2211  if (do_inverse_mass_matrix) {
2212  global_inverse_mass_matrix.compress(dealii::VectorOperation::insert);
2213  if (use_auxiliary_eq){
2214  global_inverse_mass_matrix_auxiliary.compress(dealii::VectorOperation::insert);
2215  }
2216  if (use_energy){//for split form energy
2217  global_mass_matrix.compress(dealii::VectorOperation::insert);
2218  if (use_auxiliary_eq){
2219  global_mass_matrix_auxiliary.compress(dealii::VectorOperation::insert);
2220  }
2221  }
2222  } else {
2223  global_mass_matrix.compress(dealii::VectorOperation::insert);
2224  if (use_auxiliary_eq){
2225  global_mass_matrix_auxiliary.compress(dealii::VectorOperation::insert);
2226  }
2227  }
2228 }
2229 
2230 template<int dim, typename real, typename MeshType>
2232  const bool Cartesian_element,
2233  const bool do_inverse_mass_matrix,
2234  const unsigned int poly_degree,
2235  const unsigned int /*curr_grid_degree*/,
2236  const unsigned int n_quad_pts,
2237  const unsigned int n_dofs_cell,
2238  const std::vector<dealii::types::global_dof_index> dofs_indices,
2241  OPERATOR::local_mass<dim,2*dim,real> &reference_mass_matrix,
2245 {
2247  const FR_enum FR_Type = this->all_parameters->flux_reconstruction_type;
2248 
2250  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2251 
2252  dealii::FullMatrix<real> local_mass_matrix(n_dofs_cell);
2253  dealii::FullMatrix<real> local_mass_matrix_inv(n_dofs_cell);
2254  dealii::FullMatrix<real> local_mass_matrix_aux(n_dofs_cell);
2255  dealii::FullMatrix<real> local_mass_matrix_aux_inv(n_dofs_cell);
2256 
2257  for(int istate=0; istate<nstate; istate++){
2258  const unsigned int n_shape_fns = n_dofs_cell / nstate;
2259  dealii::FullMatrix<real> local_mass_matrix_state(n_shape_fns);
2260  dealii::FullMatrix<real> local_mass_matrix_inv_state(n_shape_fns);
2261  dealii::FullMatrix<real> local_mass_matrix_aux_state(n_shape_fns);
2262  dealii::FullMatrix<real> local_mass_matrix_aux_inv_state(n_shape_fns);
2263  // compute mass matrix and inverse the standard way
2264  if(this->all_parameters->use_weight_adjusted_mass == false){
2265  //check if Cartesian grid because we can factor out determinant of Jacobian
2266  if(Cartesian_element){
2267  local_mass_matrix_state.add(metric_oper.det_Jac_vol[0],
2268  reference_mass_matrix.tensor_product_state(
2269  1,
2270  reference_mass_matrix.oneD_vol_operator,
2271  reference_mass_matrix.oneD_vol_operator,
2272  reference_mass_matrix.oneD_vol_operator));
2273  if(use_auxiliary_eq){
2274  local_mass_matrix_aux_state.add(1.0, local_mass_matrix_state);
2275  }
2276  if(FR_Type != FR_enum::cDG){
2277  local_mass_matrix_state.add(metric_oper.det_Jac_vol[0],
2279  reference_mass_matrix.oneD_vol_operator,
2280  1,
2281  n_shape_fns));
2282  }
2283  if(use_auxiliary_eq){
2284  if(FR_Type_Aux != FR_Aux_enum::kDG){
2285  local_mass_matrix_aux_state.add(metric_oper.det_Jac_vol[0],
2286  reference_FR_aux.build_dim_Flux_Reconstruction_operator(
2287  reference_mass_matrix.oneD_vol_operator,
2288  1,
2289  n_shape_fns));
2290  }
2291  }
2292  if(do_inverse_mass_matrix){
2293  local_mass_matrix_inv_state.invert(local_mass_matrix_state);
2294  if(use_auxiliary_eq)
2295  local_mass_matrix_aux_inv_state.invert(local_mass_matrix_aux_state);
2296  }
2297  }
2298  //if not a linear grid, we have to build the dim matrices on the fly
2299  else{
2300  //quadrature weights
2301  const std::vector<real> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2302  local_mass_matrix_state = reference_mass_matrix.build_dim_mass_matrix(
2303  1,
2304  n_shape_fns, n_quad_pts,
2305  basis,
2306  metric_oper.det_Jac_vol,
2307  quad_weights);
2308 
2309  if(use_auxiliary_eq) local_mass_matrix_aux_state.add(1.0, local_mass_matrix_state);
2310 
2311  if(FR_Type != FR_enum::cDG){
2312  dealii::FullMatrix<real> local_FR(n_shape_fns);
2313  local_FR = reference_FR.build_dim_Flux_Reconstruction_operator_directly(
2314  1,
2315  n_shape_fns,
2316  deriv_p.oneD_vol_operator,
2317  local_mass_matrix_state);
2318  local_mass_matrix_state.add(1.0, local_FR);
2319  }
2320  if(use_auxiliary_eq){
2321  if(FR_Type_Aux != FR_Aux_enum::kDG){
2322  dealii::FullMatrix<real> local_FR_aux(n_shape_fns);
2323  local_FR_aux = reference_FR_aux.build_dim_Flux_Reconstruction_operator_directly(
2324  1,
2325  n_shape_fns,
2326  deriv_p.oneD_vol_operator,
2327  local_mass_matrix_aux_state);
2328  local_mass_matrix_aux_state.add(1.0, local_FR_aux);
2329  }
2330  }
2331  }
2332  if(do_inverse_mass_matrix){
2333  local_mass_matrix_inv_state.invert(local_mass_matrix_state);
2334  if(use_auxiliary_eq)
2335  local_mass_matrix_aux_inv_state.invert(local_mass_matrix_aux_state);
2336  }
2337  }
2338  else{//do weight adjusted inverse
2339  //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.
2340  //quadrature weights
2341  const std::vector<real> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2342  std::vector<real> J_inv(n_quad_pts);
2343  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2344  J_inv[iquad] = 1.0 / metric_oper.det_Jac_vol[iquad];
2345  }
2346  dealii::FullMatrix<real> local_weighted_mass_matrix(n_shape_fns);
2347  dealii::FullMatrix<real> local_weighted_mass_matrix_aux(n_shape_fns);
2348  local_weighted_mass_matrix = reference_mass_matrix.build_dim_mass_matrix(
2349  1,
2350  n_shape_fns, n_quad_pts,
2351  basis,
2352  J_inv,
2353  quad_weights);
2354  if(use_auxiliary_eq)
2355  local_weighted_mass_matrix_aux.add(1.0, local_weighted_mass_matrix);
2356 
2357  if(FR_Type != FR_enum::cDG){
2358  dealii::FullMatrix<real> local_FR(n_shape_fns);
2359  local_FR = reference_FR.build_dim_Flux_Reconstruction_operator_directly(
2360  1,
2361  n_shape_fns,
2362  deriv_p.oneD_vol_operator,
2363  local_weighted_mass_matrix);
2364  local_weighted_mass_matrix.add(1.0, local_FR);
2365  }
2366  //auxiliary weighted not correct and not yet implemented properly...
2367  if(use_auxiliary_eq){
2368  if(FR_Type_Aux != FR_Aux_enum::kDG){
2369  dealii::FullMatrix<real> local_FR_aux(n_shape_fns);
2370  local_FR_aux = reference_FR_aux.build_dim_Flux_Reconstruction_operator_directly(
2371  1,
2372  n_shape_fns,
2373  deriv_p.oneD_vol_operator,
2374  local_mass_matrix);
2375  local_weighted_mass_matrix_aux.add(1.0, local_FR_aux);
2376  }
2377  }
2378  dealii::FullMatrix<real> ref_mass_dim(n_shape_fns);
2379  ref_mass_dim = reference_mass_matrix.tensor_product_state(
2380  1,
2381  reference_mass_matrix.oneD_vol_operator,
2382  reference_mass_matrix.oneD_vol_operator,
2383  reference_mass_matrix.oneD_vol_operator);
2384  if(FR_Type != FR_enum::cDG){
2385  dealii::FullMatrix<real> local_FR(n_shape_fns);
2386  local_FR = reference_FR.build_dim_Flux_Reconstruction_operator(
2387  reference_mass_matrix.oneD_vol_operator,
2388  1,
2389  n_shape_fns);
2390  ref_mass_dim.add(1.0, local_FR);
2391  }
2392  dealii::FullMatrix<real> ref_mass_dim_inv(n_shape_fns);
2393  ref_mass_dim_inv.invert(ref_mass_dim);
2394  dealii::FullMatrix<real> temp(n_shape_fns);
2395  ref_mass_dim_inv.mmult(temp, local_weighted_mass_matrix);
2396  temp.mmult(local_mass_matrix_inv_state, ref_mass_dim_inv);
2397  local_mass_matrix_state.invert(local_mass_matrix_inv_state);
2398  if(use_auxiliary_eq){
2399  dealii::FullMatrix<real> temp2(n_shape_fns);
2400  ref_mass_dim_inv.mmult(temp2, local_weighted_mass_matrix_aux);
2401  temp2.mmult(local_mass_matrix_aux_inv_state, ref_mass_dim_inv);
2402  local_mass_matrix_aux_state.invert(local_mass_matrix_aux_inv_state);
2403  }
2404  }
2405  //write the ONE state, dim sized mass matrices using symmetry into nstate, dim sized mass matrices.
2406  for(unsigned int test_shape=0; test_shape<n_shape_fns; test_shape++){
2407 
2408  const unsigned int test_index = istate * n_shape_fns + test_shape;
2409 
2410  for(unsigned int trial_shape=test_shape; trial_shape<n_shape_fns; trial_shape++){
2411  const unsigned int trial_index = istate * n_shape_fns + trial_shape;
2412  local_mass_matrix[test_index][trial_index] = local_mass_matrix_state[test_shape][trial_shape];
2413  local_mass_matrix[trial_index][test_index] = local_mass_matrix_state[test_shape][trial_shape];
2414 
2415  local_mass_matrix_inv[test_index][trial_index] = local_mass_matrix_inv_state[test_shape][trial_shape];
2416  local_mass_matrix_inv[trial_index][test_index] = local_mass_matrix_inv_state[test_shape][trial_shape];
2417 
2418  if(use_auxiliary_eq){
2419  local_mass_matrix_aux[test_index][trial_index] = local_mass_matrix_aux_state[test_shape][trial_shape];
2420  local_mass_matrix_aux[trial_index][test_index] = local_mass_matrix_aux_state[test_shape][trial_shape];
2421 
2422  local_mass_matrix_aux_inv[test_index][trial_index] = local_mass_matrix_aux_inv_state[test_shape][trial_shape];
2423  local_mass_matrix_aux_inv[trial_index][test_index] = local_mass_matrix_aux_inv_state[test_shape][trial_shape];
2424  }
2425  }
2426  }
2427  }
2428 
2429  //set in global matrices
2430  if (do_inverse_mass_matrix) {
2431  //set the global inverse mass matrix
2432  global_inverse_mass_matrix.set(dofs_indices, local_mass_matrix_inv);
2433  //set the global inverse mass matrix for auxiliary equations
2434  if(use_auxiliary_eq){
2435  global_inverse_mass_matrix_auxiliary.set(dofs_indices, local_mass_matrix_aux_inv);
2436  }
2437  //If an energy test, we also need to store the mass matrix to compute energy/entropy and conservation.
2438  if (this->all_parameters->use_energy){//for split form energy
2439  global_mass_matrix.set(dofs_indices, local_mass_matrix);
2440  if(use_auxiliary_eq){
2441  global_mass_matrix_auxiliary.set(dofs_indices, local_mass_matrix_aux);
2442  }
2443  }
2444  } else {
2445  //only store global mass matrix
2446  global_mass_matrix.set(dofs_indices, local_mass_matrix);
2447  if(use_auxiliary_eq){
2448  global_mass_matrix_auxiliary.set(dofs_indices, local_mass_matrix_aux);
2449  }
2450  }
2451 }
2452 
2453 template<int dim, typename real, typename MeshType>
2455  const dealii::LinearAlgebra::distributed::Vector<double> &input_vector,
2456  dealii::LinearAlgebra::distributed::Vector<double> &output_vector,
2457  const bool use_auxiliary_eq)
2458 {
2461  const FR_enum FR_Type = this->all_parameters->flux_reconstruction_type;
2462  const double FR_user_specified_correction_parameter_value = this->all_parameters->FR_user_specified_correction_parameter_value;
2463  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2464 
2465  const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree();
2466  OPERATOR::mapping_shape_functions<dim,2*dim,real> mapping_basis(1, init_grid_degree, init_grid_degree);
2467 
2468  OPERATOR::FR_mass_inv<dim,2*dim,real> mass_inv(1, max_degree, init_grid_degree, FR_Type, FR_user_specified_correction_parameter_value);
2469  OPERATOR::FR_mass_inv_aux<dim,2*dim,real> mass_inv_aux(1, max_degree, init_grid_degree, FR_Type_Aux);
2470 
2471  OPERATOR::vol_projection_operator_FR<dim,2*dim,real> projection_oper(1, max_degree, init_grid_degree, FR_Type, FR_user_specified_correction_parameter_value, true);
2472  OPERATOR::vol_projection_operator_FR_aux<dim,2*dim,real> projection_oper_aux(1, max_degree, init_grid_degree, FR_Type_Aux, true);
2473 
2475 
2476  const unsigned int grid_degree = this->high_order_grid->fe_system.tensor_degree();
2477  const dealii::FESystem<dim> &fe_metric = high_order_grid->fe_system;
2478  const unsigned int n_metric_dofs = high_order_grid->fe_system.dofs_per_cell;
2479  auto metric_cell = high_order_grid->dof_handler_grid.begin_active();
2480 
2481  auto first_cell = dof_handler.begin_active();
2482  const bool Cartesian_first_element = (first_cell->manifold_id() == dealii::numbers::flat_manifold_id) ? true : false;
2483 
2484  if(Cartesian_first_element){//then we can factor out det of Jac and rapidly simplify
2485  if(use_auxiliary_eq){
2486  mass_inv_aux.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2487  }
2488  else{
2490  }
2491  }
2492  else{//we always use weight-adjusted for curvilinear based off the projection operator
2493  if(use_auxiliary_eq){
2494  projection_oper_aux.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2495  }
2496  else{
2497  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2498  }
2499  }
2500 
2501  dealii::Timer timer;
2503  timer.start();
2504  }
2505 
2506  for (auto soln_cell = dof_handler.begin_active(); soln_cell != dof_handler.end(); ++soln_cell, ++metric_cell) {
2507  if (!soln_cell->is_locally_owned()) continue;
2508 
2509  const unsigned int poly_degree = soln_cell->active_fe_index();
2510  const unsigned int n_dofs_cell = fe_collection[poly_degree].n_dofs_per_cell();
2511  std::vector<dealii::types::global_dof_index> current_dofs_indices;
2512  current_dofs_indices.resize(n_dofs_cell);
2513  soln_cell->get_dof_indices (current_dofs_indices);
2514 
2515  const bool Cartesian_element = (soln_cell->manifold_id() == dealii::numbers::flat_manifold_id);
2516 
2517  // if poly degree, the element manifold type, or grid degree changed for this cell, reinitialize the reference operator
2518  if((poly_degree != mass_inv.current_degree && Cartesian_element && !use_auxiliary_eq) ||
2519  (poly_degree != projection_oper.current_degree && (grid_degree > 1 || Cartesian_element) && !use_auxiliary_eq))
2520  {
2522  if(Cartesian_element){//then we can factor out det of Jac and rapidly simplify
2524  if(use_auxiliary_eq){
2525  mass_inv_aux.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2526  }
2527  }
2528  else{//we always use weight-adjusted for curvilinear based off the projection operator
2529  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2530  if(use_auxiliary_eq){
2531  projection_oper_aux.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2532  }
2533  }
2534  }
2535 
2536  // get mapping support points and determinant of Jacobian
2537  // setup metric cell
2538  std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
2539  metric_cell->get_dof_indices (metric_dof_indices);
2540  // get mapping_support points
2541  std::array<std::vector<real>,dim> mapping_support_points;
2542  for(int idim=0; idim<dim; idim++){
2543  mapping_support_points[idim].resize(n_metric_dofs/dim);
2544  }
2545  const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(grid_degree);
2546  for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
2547  const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]);
2548  const unsigned int istate = fe_metric.system_to_component_index(idof).first;
2549  const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
2550  const unsigned int igrid_node = index_renumbering[ishape];
2551  mapping_support_points[istate][igrid_node] = val;
2552  }
2553  //get determinant of Jacobian
2554  const unsigned int n_quad_pts = volume_quadrature_collection[poly_degree].size();
2555  const unsigned int n_grid_nodes = n_metric_dofs / dim;
2556  //get determinant of Jacobian
2557  OPERATOR::metric_operators<real, dim, 2*dim> metric_oper(1, poly_degree, grid_degree);
2559  n_quad_pts, n_grid_nodes,
2560  mapping_support_points,
2561  mapping_basis);
2562  //solve mass inverse times input vector for each state independently
2563  for(int istate=0; istate<nstate; istate++){
2564  const unsigned int n_shape_fns = n_dofs_cell / nstate;
2565  std::vector<real> local_input_vector(n_shape_fns);
2566  std::vector<real> local_output_vector(n_shape_fns);
2567 
2568  for(unsigned int ishape=0; ishape<n_shape_fns; ishape++){
2569  const unsigned int idof = istate * n_shape_fns + ishape;
2570  local_input_vector[ishape] = input_vector[current_dofs_indices[idof]];
2571  }
2572 
2573  if(Cartesian_element){
2574  if(use_auxiliary_eq){
2575  mass_inv_aux.matrix_vector_mult_1D(local_input_vector, local_output_vector,
2576  mass_inv_aux.oneD_vol_operator,
2577  false, 1.0 / metric_oper.det_Jac_vol[0]);
2578  }
2579  else{
2580  mass_inv.matrix_vector_mult_1D(local_input_vector, local_output_vector,
2581  mass_inv.oneD_vol_operator,
2582  false, 1.0 / metric_oper.det_Jac_vol[0]);
2583  }
2584  }
2585  else{
2586  if(use_auxiliary_eq){
2587  std::vector<real> projection_of_input(n_quad_pts);
2588  projection_oper_aux.matrix_vector_mult_1D(local_input_vector, projection_of_input,
2589  projection_oper_aux.oneD_transpose_vol_operator);
2590  const std::vector<double> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2591  std::vector<real> JxW_inv(n_quad_pts);
2592  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2593  JxW_inv[iquad] = 1.0 / (quad_weights[iquad] * metric_oper.det_Jac_vol[iquad]);
2594  }
2595  projection_oper_aux.inner_product_1D(projection_of_input, JxW_inv,
2596  local_output_vector,
2597  projection_oper_aux.oneD_transpose_vol_operator);
2598  }
2599  else{
2600  std::vector<real> projection_of_input(n_quad_pts);
2601  projection_oper.matrix_vector_mult_1D(local_input_vector, projection_of_input,
2602  projection_oper.oneD_transpose_vol_operator);
2603  const std::vector<double> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2604  std::vector<real> JxW_inv(n_quad_pts);
2605  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2606  JxW_inv[iquad] = 1.0 / (quad_weights[iquad] * metric_oper.det_Jac_vol[iquad]);
2607  }
2608  projection_oper.inner_product_1D(projection_of_input, JxW_inv,
2609  local_output_vector,
2610  projection_oper.oneD_transpose_vol_operator);
2611  }
2612  }
2613 
2614  for(unsigned int ishape=0; ishape<n_shape_fns; ishape++){
2615  const unsigned int idof = istate * n_shape_fns + ishape;
2616  output_vector[current_dofs_indices[idof]] = local_output_vector[ishape];
2617  }
2618  }//end of state loop
2619  }//end of cell loop
2620 
2622  timer.stop();
2623  assemble_residual_time += timer.cpu_time();
2624  }
2625 }
2626 
2627 template<int dim, typename real, typename MeshType>
2629  const dealii::LinearAlgebra::distributed::Vector<double> &input_vector,
2630  dealii::LinearAlgebra::distributed::Vector<double> &output_vector,
2631  const bool use_auxiliary_eq,
2632  const bool use_unmodified_mass_matrix)
2633 {
2636  const FR_enum FR_cDG = FR_enum::cDG;
2637  // if using only the M norm, set c=0 through the choice of cDG, which results in K=0
2638  // and the un-modified mass matrix will be applied.
2639  const FR_enum FR_Type = (use_unmodified_mass_matrix) ? FR_cDG : this->all_parameters->flux_reconstruction_type;
2640  const double FR_user_specified_correction_parameter_value = this->all_parameters->FR_user_specified_correction_parameter_value;
2641  const FR_Aux_enum FR_Type_Aux = this->all_parameters->flux_reconstruction_aux_type;
2642 
2643  const unsigned int init_grid_degree = high_order_grid->fe_system.tensor_degree();
2644  OPERATOR::mapping_shape_functions<dim,2*dim,real> mapping_basis(1, max_degree, init_grid_degree);
2645 
2646  OPERATOR::FR_mass<dim,2*dim,real> mass(1, max_degree, init_grid_degree, FR_Type, FR_user_specified_correction_parameter_value);
2647  OPERATOR::FR_mass_aux<dim,2*dim,real> mass_aux(1, max_degree, init_grid_degree, FR_Type_Aux);
2648 
2649  OPERATOR::vol_projection_operator<dim,2*dim,real> projection_oper(1, max_degree, init_grid_degree);
2650 
2652 
2653  const unsigned int grid_degree = this->high_order_grid->fe_system.tensor_degree();
2654  const dealii::FESystem<dim> &fe_metric = high_order_grid->fe_system;
2655  const unsigned int n_metric_dofs = high_order_grid->fe_system.dofs_per_cell;
2656  auto metric_cell = high_order_grid->dof_handler_grid.begin_active();
2657 
2658  auto first_cell = dof_handler.begin_active();
2659  const bool Cartesian_first_element = (first_cell->manifold_id() == dealii::numbers::flat_manifold_id);
2660 
2661  if(use_auxiliary_eq){
2663  if(grid_degree>1 || !Cartesian_first_element){
2664  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2665  }
2666  }
2667  else{
2669  if(grid_degree>1 || !Cartesian_first_element){
2670  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[max_degree], oneD_quadrature_collection[max_degree]);
2671  }
2672  }
2673 
2674  for (auto soln_cell = dof_handler.begin_active(); soln_cell != dof_handler.end(); ++soln_cell, ++metric_cell) {
2675  if (!soln_cell->is_locally_owned()) continue;
2676 
2677  const unsigned int poly_degree = soln_cell->active_fe_index();
2678  const unsigned int n_dofs_cell = fe_collection[poly_degree].n_dofs_per_cell();
2679  std::vector<dealii::types::global_dof_index> current_dofs_indices;
2680  current_dofs_indices.resize(n_dofs_cell);
2681  soln_cell->get_dof_indices (current_dofs_indices);
2682 
2683  const bool Cartesian_element = (soln_cell->manifold_id() == dealii::numbers::flat_manifold_id) ? true : false;
2684 
2685  //if poly degree changed for this cell, rinitialize
2686  if((poly_degree != mass.current_degree && (grid_degree == 1 || Cartesian_element) && !use_auxiliary_eq) ||
2687  (poly_degree != projection_oper.current_degree && (grid_degree > 1 || !Cartesian_element) && !use_auxiliary_eq)){
2689  if(use_auxiliary_eq){
2691  if(grid_degree>1 || !Cartesian_element){
2692  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2693  }
2694  }
2695  else{
2697  if(grid_degree>1 || !Cartesian_element){
2698  projection_oper.build_1D_volume_operator(oneD_fe_collection_1state[poly_degree], oneD_quadrature_collection[poly_degree]);
2699  }
2700  }
2701  }
2702 
2703  //get mapping support points and determinant of Jacobian
2704  //setup metric cell
2705  std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
2706  metric_cell->get_dof_indices (metric_dof_indices);
2707  // get mapping_support points
2708  std::array<std::vector<real>,dim> mapping_support_points;
2709  for(int idim=0; idim<dim; idim++){
2710  mapping_support_points[idim].resize(n_metric_dofs/dim);
2711  }
2712  const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(grid_degree);
2713  for (unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
2714  const real val = (high_order_grid->volume_nodes[metric_dof_indices[idof]]);
2715  const unsigned int istate = fe_metric.system_to_component_index(idof).first;
2716  const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
2717  const unsigned int igrid_node = index_renumbering[ishape];
2718  mapping_support_points[istate][igrid_node] = val;
2719  }
2720  //get determinant of Jacobian
2721  const unsigned int n_quad_pts = volume_quadrature_collection[poly_degree].size();
2722  const unsigned int n_grid_nodes = n_metric_dofs / dim;
2723  //get determinant of Jacobian
2724  OPERATOR::metric_operators<real, dim, 2*dim> metric_oper(1, poly_degree, grid_degree);
2726  n_quad_pts, n_grid_nodes,
2727  mapping_support_points,
2728  mapping_basis);
2729 
2730  //solve mass inverse times input vector for each state independently
2731  for(int istate=0; istate<nstate; istate++){
2732  const unsigned int n_shape_fns = n_dofs_cell / nstate;
2733  std::vector<real> local_input_vector(n_shape_fns);
2734  std::vector<real> local_output_vector(n_shape_fns);
2735 
2736  for(unsigned int ishape=0; ishape<n_shape_fns; ishape++){
2737  const unsigned int idof = istate * n_shape_fns + ishape;
2738  local_input_vector[ishape] = input_vector[current_dofs_indices[idof]];
2739  }
2740  if(Cartesian_element){
2741  if(use_auxiliary_eq){
2742  mass_aux.matrix_vector_mult_1D(local_input_vector, local_output_vector,
2743  mass_aux.oneD_vol_operator,
2744  false, metric_oper.det_Jac_vol[0]);
2745  }
2746  else{
2747  mass.matrix_vector_mult_1D(local_input_vector, local_output_vector,
2748  mass.oneD_vol_operator,
2749  false, metric_oper.det_Jac_vol[0]);
2750  }
2751  }
2752  else{
2753  const unsigned int n_dofs_1D = projection_oper.oneD_vol_operator.n();
2754  const unsigned int n_quad_pts_1D = projection_oper.oneD_vol_operator.m();
2755  if(use_auxiliary_eq){
2756  const std::vector<double> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2757  dealii::FullMatrix<double> proj_mass(n_quad_pts_1D, n_dofs_1D);
2758  projection_oper.oneD_vol_operator.Tmmult(proj_mass, mass_aux.oneD_vol_operator);
2759 
2760  std::vector<real> projection_of_input(n_quad_pts);
2761  projection_oper.matrix_vector_mult_1D(local_input_vector, projection_of_input,
2762  proj_mass);
2763  std::vector<real> JxW(n_quad_pts);
2764  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2765  JxW[iquad] = (metric_oper.det_Jac_vol[iquad] / quad_weights[iquad]);
2766  }
2767  projection_oper.inner_product_1D(projection_of_input, JxW,
2768  local_output_vector,
2769  proj_mass);
2770  }
2771  else{
2772  const std::vector<double> &quad_weights = volume_quadrature_collection[poly_degree].get_weights();
2773 
2774  std::vector<real> proj_mass(n_shape_fns);
2775  mass.matrix_vector_mult_1D(local_input_vector, proj_mass,
2776  mass.oneD_vol_operator);
2777  std::vector<real> projection_of_input(n_quad_pts);
2778  std::vector<real> ones(n_shape_fns, 1.0);
2779  projection_oper.inner_product_1D(proj_mass, ones, projection_of_input,
2780  projection_oper.oneD_vol_operator);
2781  std::vector<real> JxW(n_quad_pts);
2782  for(unsigned int iquad=0; iquad<n_quad_pts; iquad++){
2783  JxW[iquad] = (metric_oper.det_Jac_vol[iquad] / quad_weights[iquad])
2784  * projection_of_input[iquad];
2785  }
2786  std::vector<real> temp(n_shape_fns);
2787  projection_oper.matrix_vector_mult_1D(JxW,
2788  temp,
2789  projection_oper.oneD_vol_operator);
2790  mass.matrix_vector_mult_1D(temp,
2791  local_output_vector,
2792  mass.oneD_vol_operator);
2793 
2794  }
2795  }
2796 
2797  for(unsigned int ishape=0; ishape<n_shape_fns; ishape++){
2798  const unsigned int idof = istate * n_shape_fns + ishape;
2799  output_vector[current_dofs_indices[idof]] = local_output_vector[ishape];
2800  }
2801  }//end of state loop
2802  }//end of cell loop
2803 }
2804 
2805 template<int dim, typename real, typename MeshType>
2807 {
2808  system_matrix.add(scale, global_mass_matrix);
2809 }
2810 template<int dim, typename real, typename MeshType>
2812 {
2814 }
2815 template<int dim, typename real, typename MeshType>
2817 {
2820  std::vector<dealii::types::global_dof_index> dofs_indices;
2821  for (auto cell = dof_handler.begin_active(); cell!=dof_handler.end(); ++cell) {
2822 
2823  if (!cell->is_locally_owned()) continue;
2824 
2825  const unsigned int fe_index_curr_cell = cell->active_fe_index();
2826 
2827  // Current reference element related to this physical cell
2828  const dealii::FESystem<dim,dim> &current_fe_ref = fe_collection[fe_index_curr_cell];
2829  const unsigned int n_dofs_cell = current_fe_ref.n_dofs_per_cell();
2830 
2831  dofs_indices.resize(n_dofs_cell);
2832  cell->get_dof_indices (dofs_indices);
2833 
2834  const double max_dt = max_dt_cell[cell->active_cell_index()];
2835 
2836  for (unsigned int itest=0; itest<n_dofs_cell; ++itest) {
2837  const unsigned int istate_test = current_fe_ref.system_to_component_index(itest).first;
2838  for (unsigned int itrial=itest; itrial<n_dofs_cell; ++itrial) {
2839  const unsigned int istate_trial = current_fe_ref.system_to_component_index(itrial).first;
2840 
2841  if(istate_test==istate_trial) {
2842  const unsigned int row = dofs_indices[itest];
2843  const unsigned int col = dofs_indices[itrial];
2844  const double value = global_mass_matrix.el(row, col);
2845  const double new_val = value / (dt_scale * max_dt);
2846  AssertIsFinite(new_val);
2847  time_scaled_global_mass_matrix.set(row, col, new_val);
2848  if (row!=col) time_scaled_global_mass_matrix.set(col, row, new_val);
2849  }
2850  }
2851  }
2852  }
2853  time_scaled_global_mass_matrix.compress(dealii::VectorOperation::insert);
2854 }
2855 
2856 template<int dim, typename real> // To be replaced with operators->projection_operator
2857 std::vector< real > project_function(
2858  const std::vector< real > &function_coeff,
2859  const dealii::FESystem<dim,dim> &fe_input,
2860  const dealii::FESystem<dim,dim> &fe_output,
2861  const dealii::QGauss<dim> &projection_quadrature)
2862 {
2863  const unsigned int nstate = fe_input.n_components();
2864  const unsigned int n_vector_dofs_in = fe_input.dofs_per_cell;
2865  const unsigned int n_vector_dofs_out = fe_output.dofs_per_cell;
2866  const unsigned int n_dofs_in = n_vector_dofs_in / nstate;
2867  const unsigned int n_dofs_out = n_vector_dofs_out / nstate;
2868 
2869  assert(n_vector_dofs_in == function_coeff.size());
2870  assert(nstate == fe_output.n_components());
2871 
2872  const unsigned int n_quad_pts = projection_quadrature.size();
2873  const std::vector<dealii::Point<dim,double>> &unit_quad_pts = projection_quadrature.get_points();
2874 
2875  std::vector< real > function_coeff_out(n_vector_dofs_out); // output function coefficients.
2876  for (unsigned istate = 0; istate < nstate; ++istate) {
2877 
2878  std::vector< real > function_at_quad(n_quad_pts);
2879 
2880  // Output interpolation_operator is V^T in the notes.
2881  dealii::FullMatrix<double> interpolation_operator(n_dofs_out,n_quad_pts);
2882 
2883  for (unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2884  function_at_quad[iquad] = 0.0;
2885  for (unsigned int idof=0; idof<n_dofs_in; ++idof) {
2886  const unsigned int idof_vector = fe_input.component_to_system_index(istate,idof);
2887  function_at_quad[iquad] += function_coeff[idof_vector] * fe_input.shape_value_component(idof_vector,unit_quad_pts[iquad],istate);
2888  }
2889  function_at_quad[iquad] *= projection_quadrature.weight(iquad);
2890 
2891  for (unsigned int idof=0; idof<n_dofs_out; ++idof) {
2892  const unsigned int idof_vector = fe_output.component_to_system_index(istate,idof);
2893  interpolation_operator[idof][iquad] = fe_output.shape_value_component(idof_vector,unit_quad_pts[iquad],istate);
2894  }
2895  }
2896 
2897  std::vector< real > rhs(n_dofs_out);
2898  for (unsigned int idof=0; idof<n_dofs_out; ++idof) {
2899  rhs[idof] = 0.0;
2900  for (unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2901  rhs[idof] += interpolation_operator[idof][iquad] * function_at_quad[iquad];
2902  }
2903  }
2904 
2905  dealii::FullMatrix<double> mass(n_dofs_out, n_dofs_out);
2906  for(unsigned int row=0; row<n_dofs_out; ++row) {
2907  for(unsigned int col=0; col<n_dofs_out; ++col) {
2908  mass[row][col] = 0;
2909  }
2910  }
2911  for(unsigned int row=0; row<n_dofs_out; ++row) {
2912  for(unsigned int col=0; col<n_dofs_out; ++col) {
2913  for(unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2914  mass[row][col] += interpolation_operator[row][iquad] * interpolation_operator[col][iquad] * projection_quadrature.weight(iquad);
2915  }
2916  }
2917  }
2918  dealii::FullMatrix<double> inverse_mass(n_dofs_out, n_dofs_out);
2919  inverse_mass.invert(mass);
2920 
2921  for(unsigned int row=0; row<n_dofs_out; ++row) {
2922  const unsigned int idof_vector = fe_output.component_to_system_index(istate,row);
2923  function_coeff_out[idof_vector] = 0.0;
2924  for(unsigned int col=0; col<n_dofs_out; ++col) {
2925  function_coeff_out[idof_vector] += inverse_mass[row][col] * rhs[col];
2926  }
2927  }
2928  }
2929 
2930  return function_coeff_out;
2931 
2932 }
2933 
2934 template <int dim, typename real,typename MeshType>
2935 template <typename real2>
2937  const dealii::Quadrature<dim> &volume_quadrature,
2938  const std::vector< real2 > &soln_coeff_high,
2939  const dealii::FiniteElement<dim,dim> &fe_high,
2940  const std::vector<real2> &jac_det)
2941 {
2942  const unsigned int degree = fe_high.tensor_degree();
2943 
2944  if (degree == 0) return 0;
2945 
2946  const unsigned int nstate = fe_high.components;
2947  const unsigned int n_dofs_high = fe_high.dofs_per_cell;
2948 
2949  // Lower degree basis.
2950  const unsigned int lower_degree = degree-1;
2951  const dealii::FE_DGQLegendre<dim> fe_dgq_lower(lower_degree);
2952  const dealii::FESystem<dim,dim> fe_lower(fe_dgq_lower, nstate);
2953 
2954  // Projection quadrature.
2955  const dealii::QGauss<dim> projection_quadrature(degree+5);
2956  std::vector< real2 > soln_coeff_lower = project_function<dim,real2>( soln_coeff_high, fe_high, fe_lower, projection_quadrature);
2957 
2958  // Quadrature used for solution difference.
2959  const std::vector<dealii::Point<dim,double>> &unit_quad_pts = volume_quadrature.get_points();
2960 
2961  const unsigned int n_quad_pts = volume_quadrature.size();
2962  const unsigned int n_dofs_lower = fe_lower.dofs_per_cell;
2963 
2964  real2 element_volume = 0.0;
2965  real2 error = 0.0;
2966  real2 soln_norm = 0.0;
2967  std::vector<real2> soln_high(nstate);
2968  std::vector<real2> soln_lower(nstate);
2969  for (unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
2970  for (unsigned int s=0; s<nstate; ++s) {
2971  soln_high[s] = 0.0;
2972  soln_lower[s] = 0.0;
2973  }
2974  // Interpolate solution
2975  for (unsigned int idof=0; idof<n_dofs_high; ++idof) {
2976  const unsigned int istate = fe_high.system_to_component_index(idof).first;
2977  soln_high[istate] += soln_coeff_high[idof] * fe_high.shape_value_component(idof,unit_quad_pts[iquad],istate);
2978  }
2979  // Interpolate low order solution
2980  for (unsigned int idof=0; idof<n_dofs_lower; ++idof) {
2981  const unsigned int istate = fe_lower.system_to_component_index(idof).first;
2982  soln_lower[istate] += soln_coeff_lower[idof] * fe_lower.shape_value_component(idof,unit_quad_pts[iquad],istate);
2983  }
2984  // Quadrature
2985  const real2 JxW = jac_det[iquad] * volume_quadrature.weight(iquad);
2986  element_volume += JxW;
2987  // Only integrate over the first state variable.
2988  // Persson and Peraire only did density.
2989  for (unsigned int s=0; s<1/*nstate*/; ++s)
2990  {
2991  error += (soln_high[s] - soln_lower[s]) * (soln_high[s] - soln_lower[s]) * JxW;
2992  soln_norm += soln_high[s] * soln_high[s] * JxW;
2993  }
2994  }
2995 
2996  if (soln_norm < 1e-15) return 0;
2997 
2998  const real2 S_e = sqrt(error / soln_norm);
2999  const real2 s_e = log10(S_e);
3000 
3002  const double s_0 = -0.00 - 4.00*log10(degree);
3004  const double low = s_0 - kappa;
3005  const double upp = s_0 + kappa;
3006 
3007  const real2 diameter = pow(element_volume, 1.0/dim);
3008  const real2 eps_0 = mu_scale * diameter / (double)degree;
3009 
3010  if ( s_e < low) return 0.0;
3011 
3012  if ( s_e > upp)
3013  {
3014  return eps_0;
3015  }
3016 
3017  const double PI = 4*atan(1);
3018  real2 eps = 1.0 + sin(PI * (s_e - s_0) * 0.5 / kappa);
3019  eps *= eps_0 * 0.5;
3020  return eps;
3021 }
3022 
3023 template <int dim, typename real, typename MeshType>
3024 void DGBase<dim,real,MeshType>::set_current_time(const real current_time_input)
3025 {
3026  this->current_time = current_time_input;
3027 }
3028 
3029 #if PHILIP_DIM!=1
3031 #endif
3032 
3035 
3036 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);
3037 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);
3038 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);
3039 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);
3040 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);
3041 
3042 
3043 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);
3044 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);
3045 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);
3046 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);
3047 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);
3048 
3049 
3050 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);
3051 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);
3052 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);
3053 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);
3054 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);
3055 
3056 
3057 template void
3058 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>>>(
3059  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_cell,
3060  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_metric_cell,
3061  const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R,
3062  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume,
3063  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_int,
3064  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_ext,
3065  dealii::hp::FESubfaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_subface,
3066  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume_lagrange,
3075  const bool compute_auxiliary_right_hand_side,
3076  dealii::LinearAlgebra::distributed::Vector<double> &rhs,
3077  std::array<dealii::LinearAlgebra::distributed::Vector<double>,PHILIP_DIM> &rhs_aux);
3078 
3079 template void
3080 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>>>(
3081  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_cell,
3082  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_metric_cell,
3083  const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R,
3084  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume,
3085  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_int,
3086  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_ext,
3087  dealii::hp::FESubfaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_subface,
3088  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume_lagrange,
3097  const bool compute_auxiliary_right_hand_side,
3098  dealii::LinearAlgebra::distributed::Vector<double> &rhs,
3099  std::array<dealii::LinearAlgebra::distributed::Vector<double>,PHILIP_DIM> &rhs_aux);
3100 
3101 template void
3102 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>>>(
3103  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_cell,
3104  const dealii::TriaActiveIterator<dealii::DoFCellAccessor<PHILIP_DIM, PHILIP_DIM, false>> &current_metric_cell,
3105  const bool compute_dRdW, const bool compute_dRdX, const bool compute_d2R,
3106  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume,
3107  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_int,
3108  dealii::hp::FEFaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_face_ext,
3109  dealii::hp::FESubfaceValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_subface,
3110  dealii::hp::FEValues<PHILIP_DIM,PHILIP_DIM> &fe_values_collection_volume_lagrange,
3119  const bool compute_auxiliary_right_hand_side,
3120  dealii::LinearAlgebra::distributed::Vector<double> &rhs,
3121  std::array<dealii::LinearAlgebra::distributed::Vector<double>,PHILIP_DIM> &rhs_aux);
3122 } // 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:746
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:2936
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:2287
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:790
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:2816
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:1774
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:557
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:1059
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:2811
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:1855
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:1738
The metric independent FR mass matrix for auxiliary equation .
Definition: operators.h:868
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:2806
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:759
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:1544
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:1056
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:785
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:2169
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:1191
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:1702
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:754
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:670
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:1106
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:659
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:1046
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.
double FR_user_specified_correction_parameter_value
User specified flux recontruction correction parameter value.
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:2190
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:2857
The metric independent FR mass matrix .
Definition: operators.h:840
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:2231
unsigned int current_degree
Stores the degree of the current poly degree.
Definition: operators.h:802
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:708
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:817
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:724
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:1562
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:2628
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:852
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:3024
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:1623
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:1814
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:1918
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:2178
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:1948
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:698
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:1886
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:2454