4 #include <deal.II/base/convergence_table.h> 5 #include <deal.II/fe/fe_values.h> 7 #include "bound_preserving_limiter_tests.h" 9 #include "physics/initial_conditions/initial_condition_function.h" 10 #include "flow_solver/flow_solver_factory.h" 15 template <
int dim,
int nstate>
18 const dealii::ParameterHandler& parameter_handler_input)
21 , parameter_handler(parameter_handler_input)
24 template <
int dim,
int nstate>
30 const double pi = atan(1) * 4.0;
33 if (flow_case == Parameters::FlowSolverParam::FlowCaseType::low_density_2d && dim == 2) {
34 uexact = 1.00 + 0.99 * sin(qpoint[0] + qpoint[1] - (2.00 * final_time));
37 for (
int idim = 0; idim < dim; idim++) {
38 if (flow_case == Parameters::FlowSolverParam::FlowCaseType::burgers_limiter)
39 uexact *= cos(pi * (qpoint[idim] - final_time));
40 if (flow_case == Parameters::FlowSolverParam::FlowCaseType::advection_limiter)
41 uexact *= sin(2.0 * pi * (qpoint[idim] - adv_speeds[idim] * final_time));
48 template <
int dim,
int nstate>
51 const int poly_degree,
52 const double final_time)
const 55 int overintegrate = 10;
56 dealii::QGauss<dim> quad_extra(poly_degree + 1 + overintegrate);
57 dealii::FEValues<dim, dim> fe_values_extra(*(dg->high_order_grid->mapping_fe_field), dg->fe_collection[poly_degree], quad_extra,
58 dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
59 const unsigned int n_quad_pts = fe_values_extra.n_quadrature_points;
60 std::array<double, nstate> soln_at_q;
65 std::vector<dealii::types::global_dof_index> dofs_indices(fe_values_extra.dofs_per_cell);
67 for (
auto cell = dg->dof_handler.begin_active(); cell != dg->dof_handler.end(); ++cell) {
68 if (!cell->is_locally_owned())
continue;
70 fe_values_extra.reinit(cell);
71 cell->get_dof_indices(dofs_indices);
73 for (
unsigned int iquad = 0; iquad < n_quad_pts; ++iquad) {
75 std::fill(soln_at_q.begin(), soln_at_q.end(), 0.0);
76 for (
unsigned int idof = 0; idof < fe_values_extra.dofs_per_cell; ++idof) {
77 const unsigned int istate = fe_values_extra.get_fe().system_to_component_index(idof).first;
78 soln_at_q[istate] += dg->solution[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
81 const dealii::Point<dim> qpoint = (fe_values_extra.quadrature_point(iquad));
83 l2error += pow(soln_at_q[0] - uexact, 2) * fe_values_extra.JxW(iquad);
86 const double l2error_mpi_sum = std::sqrt(dealii::Utilities::MPI::sum(l2error, this->
mpi_communicator));
87 return l2error_mpi_sum;
90 template <
int dim,
int nstate>
93 pcout <<
" Running Bound Preserving Limiter test. " << std::endl;
94 pcout << dim <<
" " << nstate << std::endl;
108 template <
int dim,
int nstate>
111 pcout <<
"\n" <<
"Creating FlowSolver" << std::endl;
118 const double pi = atan(1) * 4.0;
119 if (flow_case == Parameters::FlowSolverParam::FlowCaseType::low_density_2d) {
130 template <
int dim,
int nstate>
137 dealii::ConvergenceTable convergence_table;
138 std::vector<double> grid_size(n_grids);
139 std::vector<double> soln_error(n_grids);
141 for (
unsigned int igrid = 0; igrid < n_grids; igrid++) {
143 pcout <<
"\n" <<
"Creating FlowSolver" << std::endl;
150 const double pi = atan(1) * 4.0;
152 if (flow_case == Parameters::FlowSolverParam::FlowCaseType::low_density_2d) {
158 const unsigned int n_global_active_cells = flow_solver->dg->triangulation->n_global_active_cells();
165 const unsigned int n_dofs = flow_solver->dg->dof_handler.n_dofs();
166 this->
pcout <<
"Dimension: " << dim
167 <<
"\t Polynomial degree p: " << poly_degree
169 <<
"Grid number: " << igrid + 1 <<
"/" << n_grids
170 <<
". Number of active cells: " << n_global_active_cells
171 <<
". Number of degrees of freedom: " << n_dofs
174 const double l2error_mpi_sum =
calculate_l2error(flow_solver->dg, poly_degree, final_time);
177 const double dx = 1.0 / pow(n_dofs, (1.0 / dim));
178 grid_size[igrid] = dx;
179 soln_error[igrid] = l2error_mpi_sum;
181 convergence_table.add_value(
"p", poly_degree);
182 convergence_table.add_value(
"cells", n_global_active_cells);
183 convergence_table.add_value(
"DoFs", n_dofs);
184 convergence_table.add_value(
"dx", dx);
185 convergence_table.add_value(
"soln_L2_error", l2error_mpi_sum);
187 this->
pcout <<
" Grid size h: " << dx
188 <<
" L2-soln_error: " << l2error_mpi_sum
189 <<
" Residual: " << flow_solver->ode_solver->residual_norm
193 const double slope_soln_err = log(soln_error[igrid] / soln_error[igrid - 1])
194 / log(grid_size[igrid] / grid_size[igrid - 1]);
195 this->
pcout <<
"From grid " << igrid - 1
196 <<
" to grid " << igrid
197 <<
" dimension: " << dim
198 <<
" polynomial degree p: " << poly_degree
200 <<
" solution_error1 " << soln_error[igrid - 1]
201 <<
" solution_error2 " << soln_error[igrid]
202 <<
" slope " << slope_soln_err
206 this->
pcout <<
" ********************************************" 208 <<
" Convergence rates for p = " << poly_degree
210 <<
" ********************************************" 212 convergence_table.evaluate_convergence_rates(
"soln_L2_error",
"cells", dealii::ConvergenceTable::reduction_rate_log2, dim);
213 convergence_table.set_scientific(
"dx",
true);
214 convergence_table.set_scientific(
"soln_L2_error",
true);
215 if (this->
pcout.is_active()) convergence_table.write_text(this->pcout.get_stream());
FlowCaseType
Selects the flow case to be simulated.
double final_time
Final solution time.
double calculate_l2error(std::shared_ptr< DGBase< dim, double >> flow_solver_dg, const int poly_degree, const double final_time) const
Calculate and return the L2 Error.
LimiterParam limiter_param
Contains parameters for limiter.
FlowCaseType flow_case_type
Selected FlowCaseType from the input file.
static dealii::Tensor< 1, 3, double > get_default_advection_vector()
gets the default advection vector
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
Parameters related to the manufactured convergence study.
Class used to run tests that verify implementation of bound preserving limiters.
const MPI_Comm mpi_communicator
MPI communicator.
const dealii::ParameterHandler & parameter_handler
Parameter handler for storing the .prm file being ran.
Files for the baseline physics.
bool use_OOA
Flag to perform convergence analysis for Limiter Tests (ie. burgers_limiter, advection_limiter, low_density_2d)
int run_convergence_test() const
Runs convergence test and prints out results in console.
unsigned int poly_degree
Polynomial order (P) of the basis functions for DG.
Main parameter class that contains the various other sub-parameter classes.
BoundPreservingLimiterTests(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler ¶meter_handler_input)
Constructor.
double grid_left_bound
Left bound of domain for hyper_cube mesh based cases.
ManufacturedConvergenceStudyParam manufactured_convergence_study_param
Contains parameters for manufactured convergence study.
static std::unique_ptr< FlowSolver< dim, nstate > > select_flow_case(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler ¶meter_handler_input)
Factory to return the correct flow solver given input file.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
int run_full_limiter_test() const
Runs full test and outputs VTK files.
int number_of_mesh_refinements
Number of refinements for naca0012 and Gaussian bump based cases.
dealii::ConditionalOStream pcout
ConditionalOStream.
double grid_right_bound
Right bound of domain for hyper_cube mesh based cases.
double calculate_uexact(const dealii::Point< dim > qpoint, const dealii::Tensor< 1, 3, double > adv_speeds, double final_time) const
Calculate and return the exact value at the point depending on the case being run.
DGBase is independent of the number of state variables.
int run_test() const override
Base class of all the tests.
unsigned int number_of_grids
Number of grid in the grid study.