1 #include "general_refinement_study.h" 2 #include "flow_solver/flow_solver_factory.h" 3 #include "flow_solver/flow_solver_cases/periodic_1D_unsteady.h" 4 #include "flow_solver/flow_solver_cases/periodic_entropy_tests.h" 5 #include "physics/exact_solutions/exact_solution.h" 11 template <
int dim,
int nstate>
14 const dealii::ParameterHandler ¶meter_handler_input,
17 parameter_handler(parameter_handler_input),
18 refinement_type(refinement_type_input),
19 n_calculations(parameters_input->time_refinement_study_param.number_of_times_to_solve),
20 refine_ratio(parameters_input->time_refinement_study_param.refinement_ratio)
23 template <
int dim,
int nstate>
28 if (how == RefinementType::timestep){
30 }
else if (how == RefinementType::cell_length){
32 this->
pcout <<
"Warning: h refinement will use a refinement factor of 2." << std::endl
33 <<
"User input time_refinement_study_param.refinement_ratio will be ignored." << std::endl;
47 template <
int dim,
int nstate>
51 std::shared_ptr<ExactSolutionFunction<dim,nstate,double>> exact_solution_function;
53 this->
pcout <<
"End time: " << final_time << std::endl;
55 int overintegrate = 10;
58 dealii::Vector<double> difference_per_cell(dg->solution.size());
60 dealii::VectorTools::NormType norm_type;
61 if (norm_p == 1) norm_type = dealii::VectorTools::L1_norm;
62 else if (norm_p == 2) norm_type = dealii::VectorTools::L2_norm;
63 else if (norm_p<0) norm_type = dealii::VectorTools::Linfty_norm;
65 pcout <<
"Norm not defined. Aborting... " << std::endl;
69 dealii::VectorTools::integrate_difference(dg->dof_handler,
71 *exact_solution_function,
73 dealii::QGauss<dim>(poly_degree + overintegrate),
75 Lp_error = dealii::VectorTools::compute_global_error(*dg->triangulation,
81 template <
int dim,
int nstate>
85 std::shared_ptr<dealii::ConvergenceTable> convergence_table,
87 const double expected_order)
const 90 const double final_time_actual = flow_solver->ode_solver->current_time;
96 pcout <<
"Computed errors are: " << std::endl
97 <<
" L1: " << L1_error << std::endl
98 <<
" L2: " << L2_error << std::endl
99 <<
" Linfty: " << Linfty_error << std::endl;
107 double L2_error_expected = 2.14808703658e-5;
108 pcout <<
" Expected L2 error is: " << L2_error_expected << std::endl;
109 if (L2_error > L2_error_expected + 1e-9 || L2_error < L2_error_expected - 1e-9){
111 pcout <<
"Expected L2 error for RK3(2)5F[3S*+] using an atol = rtol = 1e-4 was not reached " << refinement <<std::endl;
115 std::string step_string;
124 convergence_table->add_value(
"refinement", refinement);
125 convergence_table->add_value(step_string, step );
126 convergence_table->set_precision(step_string, 16);
128 convergence_table->set_scientific(step_string,
true);
129 convergence_table->add_value(
"L1_error",L1_error);
130 convergence_table->set_precision(
"L1_error", 16);
131 convergence_table->evaluate_convergence_rates(
"L1_error", step_string, dealii::ConvergenceTable::reduction_rate_log2, 1);
132 convergence_table->add_value(
"L2_error",L2_error);
133 convergence_table->set_precision(
"L2_error", 16);
134 convergence_table->evaluate_convergence_rates(
"L2_error", step_string, dealii::ConvergenceTable::reduction_rate_log2, 1);
135 convergence_table->add_value(
"Linfty_error",Linfty_error);
136 convergence_table->set_precision(
"Linfty_error", 16);
137 convergence_table->evaluate_convergence_rates(
"Linfty_error", step_string, dealii::ConvergenceTable::reduction_rate_log2, 1);
142 const int n_timesteps= flow_solver->ode_solver->current_iteration;
143 pcout <<
" at dt = " << dt << std::endl;
145 const double gamma_aggregate_m1 = final_time_actual / (n_timesteps * dt)-1;
146 convergence_table->add_value(
"gamma_aggregate_m1", gamma_aggregate_m1);
147 convergence_table->set_precision(
"gamma_aggregate_m1", 16);
148 convergence_table->set_scientific(
"gamma_aggregate_m1",
true);
149 convergence_table->evaluate_convergence_rates(
"gamma_aggregate_m1", step_string, dealii::ConvergenceTable::reduction_rate_log2, 1);
152 const double order_tolerance = 0.1;
153 if (refinement > 0) {
154 double L2_error_conv_rate = abs(log(L2_error_old/L2_error)/log(
refine_ratio));
155 pcout <<
"L2 order at " << refinement <<
" is " << L2_error_conv_rate << std::endl;
156 if ((L2_error_conv_rate ) < expected_order - order_tolerance){
159 pcout <<
"Expected convergence order was not reached at refinement " << refinement <<std::endl;
165 return std::make_tuple(L2_error,testfail);
168 template <
int dim,
int nstate>
173 const int n_steps = floor(final_time/initial_time_step);
174 if (n_steps * initial_time_step != final_time){
175 pcout <<
"WARNING: final_time is not evenly divisible by initial_time_step!" << std::endl
176 <<
"Remainder is " << fmod(final_time, initial_time_step)
177 <<
". Consider modifying parameters." << std::endl;
182 std::shared_ptr<dealii::ConvergenceTable> convergence_table = std::make_shared<dealii::ConvergenceTable>();
183 double L2_error_old = 0;
186 for (
int refinement = 0; refinement <
n_calculations; ++refinement){
188 pcout <<
"\n\n---------------------------------------------" << std::endl;
189 pcout <<
"Refinement number " << refinement <<
" of " << n_calculations - 1 << std::endl;
190 pcout <<
"---------------------------------------------" << std::endl;
194 static_cast<void>(flow_solver->run());
196 pcout <<
"Finished flowsolver." << std::endl;
204 L2_error = std::get<0>(out_tuple);
205 int local_testfail = std::get<1>(out_tuple);
207 if (local_testfail == 1) {
208 this->
pcout<<
"Expected order was not reached at refinement " << refinement << std::endl;
211 if (check_only_last_refinement && refinement == n_calculations - 1) {
212 testfail = local_testfail;
213 }
else if (!check_only_last_refinement) {
215 testfail = (local_testfail == 1 || testfail == 1) ? 1 : 0;
217 L2_error_old = L2_error;
222 if (
pcout.is_active()){
223 convergence_table->write_text(
pcout.get_stream());
225 std::ofstream conv_tab_file;
226 const std::string fname =
"convergence_table.txt";
227 if (append_to_file ==
true) {
228 conv_tab_file.open(fname, std::ios::app);
230 conv_tab_file.open(fname);
232 convergence_table->write_text(conv_tab_file);
233 conv_tab_file.close();
240 template <
int dim,
int nstate>
244 double expected_order_=0;
250 const double expected_order = expected_order_;
double final_time
Final solution time.
GeneralRefinementStudy(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler ¶meter_handler_input, const RefinementType refinement_type_input)
Constructor.
RefinementType
Type of refinement to run.
Advection time refinement study.
unsigned int number_of_grid_elements_per_dimension
Number of grid elements per dimension for hyper_cube mesh based cases.
double calculate_Lp_error_at_final_time_wrt_function(std::shared_ptr< DGBase< dim, double >> dg, const Parameters::AllParameters parameters, double final_time, int norm_p) const
TimeRefinementStudyParam time_refinement_study_param
Contains the parameters for time refinement study.
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
Selects which flow case to simulate.
Parameters::AllParameters reinit_params_and_refine(const Parameters::AllParameters *parameters_in, int refinement, const RefinementType how) const
Reinitialize parameters while refining the timestep. Necessary because all_parameters is constant...
Files for the baseline physics.
int run_refinement_study_and_write_result(const Parameters::AllParameters *parameters_in, const double expected_order, const bool check_only_last_refinement=false, const bool append_to_file=false) const
Run the refinements.
GridRefinementStudyParam grid_refinement_study_param
Contains the parameters for grid refinement study.
int run_test() const override
Run test.
double atol
Absolute tolerance.
static std::shared_ptr< ExactSolutionFunction< dim, nstate, real > > create_ExactSolutionFunction(const Parameters::FlowSolverParam &flow_solver_parameters, const double time_compare)
Construct ExactSolutionFunction object from global parameter file.
ODESolverEnum
Types of ODE solver.
const RefinementType refinement_type
Type of refinement to run.
const int n_calculations
Number of times to solve for convergence summary.
unsigned int poly_degree
Polynomial order (P) of the basis functions for DG.
Main parameter class that contains the various other sub-parameter classes.
const double refine_ratio
Ratio to refine by.
double grid_left_bound
Left bound of domain for hyper_cube mesh based cases.
int rk_order
Order of the RK method; assigned based on runge_kutta_method.
ODESolverParam ode_solver_param
Contains parameters for ODE solver.
double initial_time_step
Time step used in ODE solver.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
double rtol
Relative tolerance.
Fourth-order, three register low-storage Runge-Kutta method.
bool end_exactly_at_final_time
Flag to adjust the last timestep such that the simulation ends exactly at final_time.
RKMethodEnum runge_kutta_method
Runge-kutta method.
ODESolverEnum ode_solver_type
ODE solver type.
const dealii::ParameterHandler & parameter_handler
Parameter handler for storing the .prm file being ran.
virtual std::tuple< double, int > process_and_write_conv_tables(std::shared_ptr< FlowSolver::FlowSolver< dim, nstate >> flow_solver, const Parameters::AllParameters params, double L2_error_old, std::shared_ptr< dealii::ConvergenceTable > convergence_table, int refinement, const double expected_order) const
Calculate the L2 error and return local testfail for the converged flowsolver.
dealii::ConditionalOStream pcout
ConditionalOStream.
double grid_right_bound
Right bound of domain for hyper_cube mesh based cases.
int number_of_times_to_solve
number of times to run the calculation
DGBase is independent of the number of state variables.
unsigned int poly_degree
Initial solution polynomial degree.
Base class of all the tests.
Create specified flow solver as FlowSolver object.