1 #include "time_refinement_study_reference.h" 2 #include "flow_solver/flow_solver_factory.h" 3 #include "flow_solver/flow_solver_cases/periodic_1D_unsteady.h" 4 #include "physics/exact_solutions/exact_solution.h" 10 template <
int dim,
int nstate>
13 const dealii::ParameterHandler ¶meter_handler_input)
15 parameter_handler(parameter_handler_input),
16 n_time_calculations(parameters_input->time_refinement_study_param.number_of_times_to_solve),
17 refine_ratio(parameters_input->time_refinement_study_param.refinement_ratio)
20 template <
int dim,
int nstate>
25 const double dt = final_time/number_of_timesteps;
36 pcout <<
"Using timestep size dt = " << dt <<
" for reference solution." << std::endl;
41 template <
int dim,
int nstate>
59 template <
int dim,
int nstate>
61 double final_time)
const 66 static_cast<void>(flow_solver_reference->run());
68 pcout <<
" Actual final time: " << flow_solver_reference->ode_solver->current_time << std::endl;
70 return flow_solver_reference->dg->solution;
73 template <
int dim,
int nstate>
77 double final_time_actual,
78 dealii::LinearAlgebra::distributed::Vector<double> reference_solution)
const 82 if (abs(final_time_target-final_time_actual)<1E-13){
84 pcout <<
"Comparing to reference solution at target final_time = " << final_time_target <<
" ..." << std::endl;
87 dealii::LinearAlgebra::distributed::Vector<double> cellwise_difference(reference_solution);
88 cellwise_difference.add(-1.0, dg->solution);
89 const double L2_error = cellwise_difference.l2_norm();
95 pcout <<
" -------------------------------------------------------" << std::endl;
96 pcout <<
" Calculating reference solution at actual final_time = " << final_time_actual <<
" ..."<<std::endl;
97 pcout <<
" -------------------------------------------------------" << std::endl;
98 const dealii::LinearAlgebra::distributed::Vector<double> reference_solution_actual = calculate_reference_solution(final_time_actual);
100 dealii::LinearAlgebra::distributed::Vector<double> cellwise_difference(reference_solution_actual);
101 cellwise_difference.add(-1.0, dg->solution);
102 const double L2_error = cellwise_difference.l2_norm();
108 template <
int dim,
int nstate>
115 const int n_steps = round(final_time/initial_time_step);
116 if (n_steps * initial_time_step != final_time){
117 pcout <<
"WARNING: final_time is not evenly divisible by initial_time_step!" << std::endl
118 <<
"Remainder is " << fmod(final_time, initial_time_step)
119 <<
". Consider modifying parameters." << std::endl;
125 std::unique_ptr<FlowSolver::Periodic1DUnsteady<dim, nstate>> flow_solver_case = std::make_unique<FlowSolver::Periodic1DUnsteady<dim,nstate>>(this->
all_parameters);
127 pcout <<
"\n\n-------------------------------------------------------" << std::endl;
128 pcout <<
"Calculating reference solution at target final_time = " << std::setprecision(16) << final_time <<
" ..."<<std::endl;
129 pcout <<
"-------------------------------------------------------" << std::endl;
132 const dealii::LinearAlgebra::distributed::Vector<double> reference_solution = calculate_reference_solution(final_time_target);
134 dealii::ConvergenceTable convergence_table;
135 double L2_error_old = 0;
136 double L2_error_conv_rate=0;
140 pcout <<
"\n\n-------------------------------------------------------" << std::endl;
141 pcout <<
"Refinement number " << refinement <<
" of " << n_time_calculations - 1 << std::endl;
142 pcout <<
"-------------------------------------------------------" << std::endl;
146 const double energy_initial = flow_solver_case->compute_energy(flow_solver->dg);
147 static_cast<void>(flow_solver->run());
149 const double final_time_actual = flow_solver->ode_solver->current_time;
150 pcout <<
" Actual final time: " << final_time_actual << std::endl;
152 const int n_timesteps= flow_solver->ode_solver->current_iteration;
160 pcout <<
"Computed error is " << L2_error << std::endl;
163 convergence_table.add_value(
"refinement", refinement);
164 convergence_table.add_value(
"dt", dt );
165 convergence_table.set_precision(
"dt", 16);
166 convergence_table.set_scientific(
"dt",
true);
167 convergence_table.add_value(
"final_time", final_time_actual );
168 convergence_table.set_precision(
"final_time", 16);
169 convergence_table.add_value(
"n_timesteps", n_timesteps);
170 convergence_table.add_value(
"L2_error",L2_error);
171 convergence_table.set_precision(
"L2_error", 16);
172 convergence_table.evaluate_convergence_rates(
"L2_error",
"dt", dealii::ConvergenceTable::reduction_rate_log2, 1);
174 const double energy_end = flow_solver_case->compute_energy(flow_solver->dg);
175 const double energy_change = energy_initial - energy_end;
176 convergence_table.add_value(
"energy_change", energy_change);
177 convergence_table.set_precision(
"energy_change", 16);
178 convergence_table.evaluate_convergence_rates(
"energy_change",
"dt", dealii::ConvergenceTable::reduction_rate_log2, 1);
182 const double gamma_aggregate_m1 = final_time_actual / (n_timesteps * dt)-1;
183 convergence_table.add_value(
"gamma_aggregate_m1", gamma_aggregate_m1);
184 convergence_table.set_precision(
"gamma_aggregate_m1", 16);
185 convergence_table.set_scientific(
"gamma_aggregate_m1",
true);
186 convergence_table.evaluate_convergence_rates(
"gamma_aggregate_m1",
"dt", dealii::ConvergenceTable::reduction_rate_log2, 1);
191 const double order_tolerance = 0.1;
192 if (refinement > 0) {
193 L2_error_conv_rate = -log(L2_error_old/L2_error)/log(
refine_ratio);
194 pcout <<
"Order at " << refinement <<
" is " << L2_error_conv_rate << std::endl;
195 if (abs(L2_error_conv_rate - expected_order) > order_tolerance){
197 pcout <<
"Expected convergence order was not reached at refinement " << refinement <<std::endl;
200 L2_error_old = L2_error;
205 if (
pcout.is_active()) {
206 convergence_table.write_text(
pcout.get_stream());
208 std::ofstream conv_tab_file;
209 const std::string fname =
"temporal_convergence_table.txt";
210 conv_tab_file.open(fname);
211 convergence_table.write_text(conv_tab_file);
212 conv_tab_file.close();
double calculate_L2_error_at_final_time_wrt_reference(std::shared_ptr< DGBase< dim, double >> dg, const Parameters::AllParameters parameters, double final_time_actual, dealii::LinearAlgebra::distributed::Vector< double > reference_solution) const
Calculate L2 error at the final time in the passed parameters.
double final_time
Final solution time.
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)
Parameters::AllParameters reinit_params_and_refine_timestep(int refinement) const
Reinitialize parameters while refining the timestep. Necessary because all_parameters is constant...
Files for the baseline physics.
ODESolverEnum
Types of ODE solver.
int run_test() const override
Run test.
int number_of_timesteps_for_reference_solution
For time refinement study with reference solution, number of steps for reference solution.
Parameters::AllParameters reinit_params_for_reference_solution(int number_of_timesteps, double final_time) const
Reinitialize parameters and set initial_timestep according to reference solution and passed final tim...
Main parameter class that contains the various other sub-parameter classes.
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.
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.
bool end_exactly_at_final_time
Flag to adjust the last timestep such that the simulation ends exactly at final_time.
const dealii::ParameterHandler & parameter_handler
Parameter handler for storing the .prm file being ran.
TimeRefinementStudyReference(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler ¶meter_handler_input)
Constructor.
const double refine_ratio
Ratio to refine by.
ODESolverEnum ode_solver_type
ODE solver type.
std::string unsteady_data_table_filename
dealii::ConditionalOStream pcout
ConditionalOStream.
Time refinement study which compares to a reference solution.
DGBase is independent of the number of state variables.
const int n_time_calculations
Number of times to solve for convergence summary.
Base class of all the tests.