6 #include <deal.II/dofs/dof_tools.h>     8 #include <deal.II/distributed/tria.h>     9 #include <deal.II/grid/tria.h>    11 #include <deal.II/grid/grid_generator.h>    12 #include <deal.II/grid/grid_refinement.h>    13 #include <deal.II/grid/grid_tools.h>    14 #include <deal.II/grid/grid_out.h>    15 #include <deal.II/grid/grid_in.h>    17 #include <deal.II/numerics/vector_tools.h>    19 #include <deal.II/fe/fe_values.h>    24 #include "mesh/grids/curved_periodic_grid.hpp"    26 #include "grid_study.h"    28 #include "physics/physics_factory.h"    29 #include "physics/model_factory.h"    30 #include "physics/manufactured_solution.h"    31 #include "dg/dg_factory.hpp"    32 #include "ode_solver/ode_solver_factory.h"    34 #include "grid_refinement/grid_refinement.h"    35 #include "grid_refinement/gmsh_out.h"    36 #include "grid_refinement/size_field.h"    41 template <
int dim, 
int nstate>
    47 template <
int dim, 
int nstate>
    51     dealii::LinearAlgebra::distributed::Vector<double> solution_no_ghost;
    63 template <
int dim, 
int nstate>
    67     pcout << 
"Evaluating solution integral..." << std::endl;
    68     double solution_integral = 0.0;
    75     int overintegrate = 10;
    76     dealii::QGauss<dim> quad_extra(dg.
max_degree+1+overintegrate);
    79             dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
    80     const unsigned int n_quad_pts = fe_values_extra.n_quadrature_points;
    81     std::array<double,nstate> soln_at_q;
    83     const bool linear_output = 
true;
    85     if (linear_output) exponent = 1;
    89     std::vector<dealii::types::global_dof_index> dofs_indices (fe_values_extra.dofs_per_cell);
    90     for (
auto cell : dg.
dof_handler.active_cell_iterators()) {
    92         if (!cell->is_locally_owned()) 
continue;
    94         fe_values_extra.reinit (cell);
    95         cell->get_dof_indices (dofs_indices);
    97         for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
   100             std::fill(soln_at_q.begin(), soln_at_q.end(), 0.0);
   101             for (
unsigned int idof=0; idof<fe_values_extra.dofs_per_cell; ++idof) {
   102                 const unsigned int istate = fe_values_extra.get_fe().system_to_component_index(idof).first;
   103                 soln_at_q[istate] += dg.
solution[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
   106             for (
int s=0; s<nstate; s++) {
   107                 solution_integral += pow(soln_at_q[s], exponent) * fe_values_extra.JxW(iquad);
   112     const double solution_integral_mpi_sum = dealii::Utilities::MPI::sum(solution_integral, 
mpi_communicator);
   113     return solution_integral_mpi_sum;
   116 template<
int dim, 
int nstate>
   121     std::string error_filename_baseline = 
"convergence_table";
   128     error_filename_baseline += std::string(
"_") + std::to_string(dim) + std::string(
"d");
   129     error_filename_baseline += std::string(
"_") + pde_string;
   130     error_filename_baseline += std::string(
"_") + conv_num_flux_string;
   131     error_filename_baseline += std::string(
"_") + diss_num_flux_string;
   132     error_filename_baseline += std::string(
"_") + manufactured_solution_string;
   133     return error_filename_baseline;
   136 template<
int dim, 
int nstate>
   139     const std::string error_filename_baseline,
   140     const dealii::ConvergenceTable convergence_table,
   141     const unsigned int poly_degree)
 const   143     std::string error_filename = error_filename_baseline;
   144     std::string error_fileType = std::string(
"txt");
   145     error_filename += std::string(
"_") + std::string(
"p") + std::to_string(poly_degree);
   146     std::ofstream error_table_file(error_filename + std::string(
".") + error_fileType);
   147     convergence_table.write_text(error_table_file);
   151 template<
int dim, 
int nstate>
   157     using GridEnum = ManParam::GridEnum;
   166     const unsigned int p_start             = manu_grid_conv_param.
degree_start;
   167     const unsigned int p_end               = manu_grid_conv_param.degree_end;
   169     const unsigned int n_grids_input       = manu_grid_conv_param.number_of_grids;
   175     double exact_solution_integral;
   176     pcout << 
"Evaluating EXACT solution integral..." << std::endl;
   179         using Triangulation = dealii::Triangulation<dim>;
   181         using Triangulation = dealii::parallel::distributed::Triangulation<dim>;
   185         std::shared_ptr<Triangulation> grid_super_fine = std::make_shared<Triangulation>(
   189             typename dealii::Triangulation<dim>::MeshSmoothing(
   190                 dealii::Triangulation<dim>::smoothing_on_refinement |
   191                 dealii::Triangulation<dim>::smoothing_on_coarsening));
   193         dealii::GridGenerator::subdivided_hyper_cube(*grid_super_fine, n_1d_cells[n_grids_input-1]);
   206         for (
auto cell = grid_super_fine->begin_active(); cell != grid_super_fine->end(); ++cell) {
   207             for (
unsigned int face=0; face<dealii::GeometryInfo<dim>::faces_per_cell; ++face) {
   208                 if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000);
   213         dg_super_fine->allocate_system ();
   216         if (manu_grid_conv_param.output_solution) {
   217             dg_super_fine->output_results_vtk(9999);
   220         pcout << 
"Exact solution integral is " << exact_solution_integral << std::endl;
   223     int n_flow_convergence_error = 0;
   224     std::vector<int> fail_conv_poly;
   225     std::vector<double> fail_conv_slop;
   226     std::vector<dealii::ConvergenceTable> convergence_table_vector;
   228     std::string error_filename_baseline;
   229     if (manu_grid_conv_param.output_convergence_tables) {
   233     for (
unsigned int poly_degree = p_start; poly_degree <= p_end; ++poly_degree) {
   236         unsigned int n_grids = n_grids_input;
   237         if (poly_degree <= 1) n_grids = n_grids_input + 1;
   239         std::vector<double> soln_error(n_grids);
   240         std::vector<double> output_error(n_grids);
   241         std::vector<double> grid_size(n_grids);
   245         dealii::ConvergenceTable convergence_table;
   251         std::shared_ptr<Triangulation> grid = std::make_shared<Triangulation>(
   255             typename dealii::Triangulation<dim>::MeshSmoothing(
   256                 dealii::Triangulation<dim>::smoothing_on_refinement |
   257                 dealii::Triangulation<dim>::smoothing_on_coarsening));
   259         dealii::Vector<float>  estimated_error_per_cell;
   260         dealii::Vector<double> estimated_error_per_cell_double;
   262         for (
unsigned int igrid=0; igrid<n_grids; ++igrid) {
   264             dealii::GridGenerator::subdivided_hyper_cube(*grid, n_1d_cells[igrid]);
   274             for (
auto cell = grid->begin_active(); cell != grid->end(); ++cell) {
   276                 cell->set_material_id(9002);
   277                 for (
unsigned int face=0; face<dealii::GeometryInfo<dim>::faces_per_cell; ++face) {
   278                     if (cell->face(face)->at_boundary()) cell->face(face)->set_boundary_id (1000);
   283             if (manu_grid_conv_param.grid_type == GridEnum::sinehypercube) dealii::GridTools::transform (&
warp, *grid);
   335             const double random_factor = manu_grid_conv_param.random_distortion;
   336             const bool keep_boundary = 
true;
   337             if (random_factor > 0.0) dealii::GridTools::distort_random (random_factor, *grid, keep_boundary);
   340             if (manu_grid_conv_param.grid_type == GridEnum::read_grid) {
   342                 std::string read_mshname = manu_grid_conv_param.input_grids+std::to_string(igrid)+
".msh";
   343                 pcout<<
"Reading grid: " << read_mshname << std::endl;
   344                 std::ifstream inmesh(read_mshname);
   345                 dealii::GridIn<dim,dim> grid_in;
   347                 grid_in.attach_triangulation(*grid);
   348                 grid_in.read_msh(inmesh);
   351             if (manu_grid_conv_param.output_meshes) {
   352                 std::string write_mshname = 
"grid-"+std::to_string(igrid)+
".msh";
   353                 std::ofstream outmesh(write_mshname);
   354                 dealii::GridOutFlags::Msh msh_flags(
true, 
true);
   355                 dealii::GridOut grid_out;
   356                 grid_out.set_flags(msh_flags);
   357                 grid_out.write_msh(*grid, outmesh);
   364             using FadType = Sacado::Fad::DFad<double>;
   368             dg->allocate_system ();
   378             const unsigned int n_global_active_cells = grid->n_global_active_cells();
   379             const unsigned int n_dofs = dg->dof_handler.n_dofs();
   380             pcout << 
"Dimension: " << dim
   381                  << 
"\t Polynomial degree p: " << poly_degree
   383                  << 
"Grid number: " << igrid+1 << 
"/" << n_grids
   384                  << 
". Number of active cells: " << n_global_active_cells
   385                  << 
". Number of degrees of freedom: " << n_dofs
   390             const int flow_convergence_error = ode_solver->steady_state();
   391             if (flow_convergence_error) n_flow_convergence_error += 1;
   394             int overintegrate = 10;
   395             dealii::QGauss<dim> quad_extra(dg->max_degree+overintegrate);
   397             dealii::FEValues<dim,dim> fe_values_extra(*(dg->high_order_grid->mapping_fe_field), dg->fe_collection[poly_degree], quad_extra, 
   398                     dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
   399             const unsigned int n_quad_pts = fe_values_extra.n_quadrature_points;
   400             std::array<double,nstate> soln_at_q;
   403             std::array<double,nstate> cell_l2error_state;
   404             std::array<double,nstate> l2error_state;
   405             for (
int istate=0; istate<nstate; ++istate) {
   406                 l2error_state[istate] = 0.0;
   413             std::vector<dealii::types::global_dof_index> dofs_indices (fe_values_extra.dofs_per_cell);
   414             estimated_error_per_cell.reinit(grid->n_active_cells());
   415             estimated_error_per_cell_double.reinit(grid->n_active_cells());
   416             for (
auto cell = dg->dof_handler.begin_active(); cell!=dg->dof_handler.end(); ++cell) {
   418                 if (!cell->is_locally_owned()) 
continue;
   420                 fe_values_extra.reinit (cell);
   421                 cell->get_dof_indices (dofs_indices);
   423                 double cell_l2error = 0;
   425                 for (
int istate=0; istate<nstate; ++istate) {
   426                     cell_l2error_state[istate] = 0.0;
   429                 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
   431                     std::fill(soln_at_q.begin(), soln_at_q.end(), 0);
   432                     for (
unsigned int idof=0; idof<fe_values_extra.dofs_per_cell; ++idof) {
   433                         const unsigned int istate = fe_values_extra.get_fe().system_to_component_index(idof).first;
   434                         soln_at_q[istate] += dg->solution[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
   437                     const dealii::Point<dim> qpoint = (fe_values_extra.quadrature_point(iquad));
   439                     for (
int istate=0; istate<nstate; ++istate) {
   440                         const double uexact = physics_double->manufactured_solution_function->value(qpoint, istate);
   443                         cell_l2error += pow(soln_at_q[istate] - uexact, 2) * fe_values_extra.JxW(iquad);
   445                         cell_l2error_state[istate] += pow(soln_at_q[istate] - uexact, 2) * fe_values_extra.JxW(iquad); 
   448                 estimated_error_per_cell[cell->active_cell_index()] = cell_l2error;
   449                 estimated_error_per_cell_double[cell->active_cell_index()] = cell_l2error;
   450                 l2error += cell_l2error;
   452                 for (
int istate=0; istate<nstate; ++istate) {
   453                     l2error_state[istate] += cell_l2error_state[istate];
   456             const double l2error_mpi_sum = std::sqrt(dealii::Utilities::MPI::sum(l2error, 
mpi_communicator));
   458             std::array<double,nstate> l2error_mpi_sum_state;
   459             for (
int istate=0; istate<nstate; ++istate) {
   460                 l2error_mpi_sum_state[istate] = std::sqrt(dealii::Utilities::MPI::sum(l2error_state[istate], 
mpi_communicator));
   465             if (manu_grid_conv_param.output_solution) {
   482                 std::shared_ptr< GridRefinement::GridRefinementBase<dim,nstate,double> >  gr 
   484                 gr->output_results_vtk(igrid);
   489             const double dx = 1.0/pow(n_dofs,(1.0/dim));
   490             grid_size[igrid] = dx;
   491             soln_error[igrid] = l2error_mpi_sum;
   492             output_error[igrid] = std::abs(solution_integral - exact_solution_integral);
   494             convergence_table.add_value(
"p", poly_degree);
   495             convergence_table.add_value(
"cells", n_global_active_cells);
   496             convergence_table.add_value(
"DoFs", n_dofs);
   497             convergence_table.add_value(
"dx", dx);
   498             convergence_table.add_value(
"residual", dg->get_residual_l2norm ());
   499             convergence_table.add_value(
"soln_L2_error", l2error_mpi_sum);
   500             convergence_table.add_value(
"output_error", output_error[igrid]);
   503             if (manu_grid_conv_param.add_statewise_solution_error_to_convergence_tables) {
   504                 std::array<std::string,nstate> soln_L2_error_state_str;
   505                 for (
int istate=0; istate<nstate; ++istate) {
   506                     soln_L2_error_state_str[istate] = std::string(
"soln_L2_error_state") + std::string(
"_") + std::to_string(istate);
   507                     convergence_table.add_value(soln_L2_error_state_str[istate], l2error_mpi_sum_state[istate]);
   511             pcout << 
" Grid size h: " << dx 
   512                  << 
" L2-soln_error: " << l2error_mpi_sum
   513                  << 
" Residual: " << ode_solver->residual_norm
   516             pcout << 
" output_exact: " << exact_solution_integral
   517                  << 
" output_discrete: " << solution_integral
   518                  << 
" output_error: " << output_error[igrid]
   522                 const double slope_soln_err = log(soln_error[igrid]/soln_error[igrid-1])
   523                                       / log(grid_size[igrid]/grid_size[igrid-1]);
   524                 const double slope_output_err = log(output_error[igrid]/output_error[igrid-1])
   525                                       / log(grid_size[igrid]/grid_size[igrid-1]);
   526                 pcout << 
"From grid " << igrid-1
   527                      << 
"  to grid " << igrid
   528                      << 
"  dimension: " << dim
   529                      << 
"  polynomial degree p: " << poly_degree
   531                      << 
"  solution_error1 " << soln_error[igrid-1]
   532                      << 
"  solution_error2 " << soln_error[igrid]
   533                      << 
"  slope " << slope_soln_err
   535                      << 
"  solution_integral_error1 " << output_error[igrid-1]
   536                      << 
"  solution_integral_error2 " << output_error[igrid]
   537                      << 
"  slope " << slope_output_err
   542             convergence_table.evaluate_convergence_rates(
"soln_L2_error", 
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
   543             convergence_table.evaluate_convergence_rates(
"output_error", 
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
   544             convergence_table.set_scientific(
"dx", 
true);
   545             convergence_table.set_scientific(
"residual", 
true);
   546             convergence_table.set_scientific(
"soln_L2_error", 
true);
   547             convergence_table.set_scientific(
"output_error", 
true);
   548             if (manu_grid_conv_param.add_statewise_solution_error_to_convergence_tables) {
   549                 std::string test_str;
   550                 for (
int istate=0; istate<nstate; ++istate) {
   551                     test_str = std::string(
"soln_L2_error_state") + std::string(
"_") + std::to_string(istate);
   552                     convergence_table.set_scientific(test_str,
true);
   556             if (manu_grid_conv_param.output_convergence_tables) {
   558                     error_filename_baseline,
   563         pcout << 
" ********************************************"   565              << 
" Convergence rates for p = " << poly_degree
   567              << 
" ********************************************"   570         if (
pcout.is_active()) convergence_table.write_text(
pcout.get_stream());
   572         convergence_table_vector.push_back(convergence_table);
   574         const double expected_slope = poly_degree+1;
   576         double last_slope = 0.0;
   578             last_slope = log(soln_error[n_grids-1]/soln_error[n_grids-2])
   579                              / log(grid_size[n_grids-1]/grid_size[n_grids-2]);
   581         double before_last_slope = last_slope;
   583             before_last_slope = log(soln_error[n_grids-2]/soln_error[n_grids-3])
   584                                 / log(grid_size[n_grids-2]/grid_size[n_grids-3]);
   586         const double slope_avg = 0.5*(before_last_slope+last_slope);
   587         const double slope_diff = slope_avg-expected_slope;
   589         double slope_deficit_tolerance = -std::abs(manu_grid_conv_param.slope_deficit_tolerance);
   590         if(poly_degree == 0) slope_deficit_tolerance *= 2; 
   592         if (slope_diff < slope_deficit_tolerance) {
   594                  << 
"Convergence order not achieved. Average last 2 slopes of "   595                  << slope_avg << 
" instead of expected "   596                  << expected_slope << 
" within a tolerance of "   597                  << slope_deficit_tolerance
   600             if(poly_degree!=0) fail_conv_poly.push_back(poly_degree);
   601             if(poly_degree!=0) fail_conv_slop.push_back(slope_avg);
   605     pcout << std::endl << std::endl << std::endl << std::endl;
   606     pcout << 
" ********************************************" << std::endl;
   607     pcout << 
" Convergence summary" << std::endl;
   608     pcout << 
" ********************************************" << std::endl;
   609     for (
auto conv = convergence_table_vector.begin(); conv!=convergence_table_vector.end(); conv++) {
   610         if (
pcout.is_active()) conv->write_text(
pcout.get_stream());
   611         pcout << 
" ********************************************" << std::endl;
   613     int n_fail_poly = fail_conv_poly.size();
   614     if (n_fail_poly > 0) {
   615         for (
int ifail=0; ifail < n_fail_poly; ++ifail) {
   616             const double expected_slope = fail_conv_poly[ifail]+1;
   617             const double slope_deficit_tolerance = -std::abs(manu_grid_conv_param.slope_deficit_tolerance);
   619                  << 
"Convergence order not achieved for polynomial p = "   620                  << fail_conv_poly[ifail]
   622                  << fail_conv_slop[ifail] << 
" instead of expected "   623                  << expected_slope << 
" within a tolerance of "   624                  << slope_deficit_tolerance
   628     if (n_fail_poly) test_fail += 1;
   629     test_fail += n_flow_convergence_error;
   630     if (n_flow_convergence_error) {
   632               << 
"Flow did not converge some some cases. Please check the residuals achieved versus the residual tolerance."   638 template <
int dim, 
int nstate>
   642     dealii::Point<dim> q = p;
   644     if (dim >= 2) q[0] += 1*std::sin(q[dim-1]);
   645     if (dim >= 3) q[1] += 1*std::cos(q[dim-1]);
   649 template <
int dim, 
int nstate>
   651 ::print_mesh_info(
const dealii::Triangulation<dim> &triangulation, 
const std::string &filename)
 const   653     pcout << 
"Mesh info:" << std::endl
   654          << 
" dimension: " << dim << std::endl
   655          << 
" no. of cells: " << triangulation.n_global_active_cells() << std::endl;
   656     std::map<dealii::types::boundary_id, unsigned int> boundary_count;
   657     for (
auto cell : triangulation.active_cell_iterators()) {
   658         for (
unsigned int face=0; face < dealii::GeometryInfo<dim>::faces_per_cell; ++face) {
   659             if (cell->face(face)->at_boundary()) boundary_count[cell->face(face)->boundary_id()]++;
   662     pcout << 
" boundary indicators: ";
   663     for (
const std::pair<const dealii::types::boundary_id, unsigned int> &pair : boundary_count) {
   664         pcout      << pair.first << 
"(" << pair.second << 
" times) ";
   668         std::ofstream out (filename);
   669         dealii::GridOut grid_out;
   670         grid_out.write_eps (triangulation, out);
   671         pcout << 
" written to " << filename << std::endl << std::endl;
 unsigned int degree_start
First polynomial degree to start the loop. If diffusion, must be at least 1. 
std::string get_convergence_tables_baseline_filename(const Parameters::AllParameters *const parameters_input) const
Returns the baseline filename for outputted convergence tables. 
double integrate_solution_over_domain(DGBase< dim, double > &dg) const
L2-Integral of the solution over the entire domain. 
Performs grid convergence for various polynomial degrees. 
Sacado::Fad::DFad< double > FadType
Sacado AD type for first derivatives. 
int run_test() const
Manufactured grid convergence. 
Parameters related to the manufactured convergence study. 
const MPI_Comm mpi_communicator
MPI communicator. 
Files for the baseline physics. 
GridRefinementStudyParam grid_refinement_study_param
Contains the parameters for grid refinement study. 
std::array< GridRefinementParam, MAX_REFINEMENTS > grid_refinement_param_vector
Array of grid refinement parameters to be run as part of grid refinement study. 
unsigned int dimension
Number of dimensions. Note that it has to match the executable PHiLiP_xD. 
Main parameter class that contains the various other sub-parameter classes. 
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution. 
ManufacturedConvergenceStudyParam manufactured_convergence_study_param
Contains parameters for manufactured convergence study. 
dealii::IndexSet locally_owned_dofs
Locally own degrees of freedom. 
const Parameters::AllParameters *const all_parameters
Pointer to all parameters. 
static std::shared_ptr< DGBase< dim, real, MeshType > > create_discontinuous_galerkin(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)
Creates a derived object DG, but returns it as DGBase. 
const unsigned int max_degree
Maximum degree used for p-refi1nement. 
std::string get_conv_num_flux_string(const Parameters::AllParameters *const param) const
Returns a string describing which convective numerical flux is being used. 
static std::shared_ptr< ModelBase< dim, nstate, real > > create_Model(const Parameters::AllParameters *const parameters_input)
Factory to return the correct model given input parameters. 
std::shared_ptr< HighOrderGrid< dim, real, MeshType > > high_order_grid
High order grid that will provide the MappingFEField. 
void write_convergence_table_to_output_file(const std::string error_filename_baseline, const dealii::ConvergenceTable convergence_table, const unsigned int poly_degree) const
Writes the convergence table output file. 
GridStudy()=delete
Constructor. Deleted the default constructor since it should not be used. 
std::string get_pde_string(const Parameters::AllParameters *const param) const
Returns a string describing which PDE is being used. 
static std::shared_ptr< PhysicsBase< dim, nstate, real > > create_Physics(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ModelBase< dim, nstate, real > > model_input=nullptr)
Factory to return the correct physics given input file. 
std::string get_diss_num_flux_string(const Parameters::AllParameters *const param) const
Returns a string describing which dissipative numerical flux is being used. 
dealii::DoFHandler< dim > dof_handler
Finite Element Collection to represent the high-order grid. 
static std::shared_ptr< GridRefinementBase< dim, nstate, real, MeshType > > create_GridRefinement(PHiLiP::Parameters::GridRefinementParam gr_param, std::shared_ptr< PHiLiP::Adjoint< dim, nstate, real, MeshType > > adj, std::shared_ptr< PHiLiP::Physics::PhysicsBase< dim, nstate, real > > physics_input)
Construct grid refinement class based on adjoint and physics. 
void print_mesh_info(const dealii::Triangulation< dim > &triangulation, const std::string &filename) const
Prints our mesh info and generates eps file if 2D grid. 
std::string get_manufactured_solution_string(const Parameters::AllParameters *const param) const
Returns a string describing which manufactured solution is being used. 
dealii::ConditionalOStream pcout
ConditionalOStream. 
void initialize_perturbed_solution(DGBase< dim, double > &dg, const Physics::PhysicsBase< dim, nstate, double > &physics) const
Initialize the solution with the exact solution. 
DGBase is independent of the number of state variables. 
std::vector< int > get_number_1d_cells(const int ngrids) const
Evaluates the number of cells to generate the grids for 1D grid based on input file. 
std::shared_ptr< ManufacturedSolutionFunction< dim, real > > manufactured_solution_function
Manufactured solution function. 
static std::shared_ptr< ODESolverBase< dim, real, MeshType > > create_ODESolver(std::shared_ptr< DGBase< dim, real, MeshType > > dg_input)
Creates either implicit or explicit ODE solver based on parameter value(no POD basis given) ...
const dealii::hp::FECollection< dim > fe_collection
Finite Element Collection for p-finite-element to represent the solution. 
Base class of all the tests. 
static dealii::Point< dim > warp(const dealii::Point< dim > &p)
Warps mesh into sinusoidal.