1 #include "ode_solver_base.h" 2 #include "limiter/bound_preserving_limiter_factory.hpp" 7 template <
int dim,
typename real,
typename MeshType>
13 , all_parameters(dg->all_parameters)
14 , ode_param(all_parameters->ode_solver_param)
15 , current_time(ode_param.initial_time)
16 , current_iteration(ode_param.initial_iteration)
17 , current_desired_time_for_output_solution_every_dt_time_intervals(ode_param.initial_desired_time_for_output_solution_every_dt_time_intervals)
18 , original_time_step(0.0)
19 , modified_time_step(0.0)
20 , mpi_communicator(MPI_COMM_WORLD)
21 , mpi_rank(dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD))
22 , pcout(
std::cout, mpi_rank==0)
25 template <
int dim,
typename real,
typename MeshType>
30 template <
int dim,
typename real,
typename MeshType>
37 template <
int dim,
typename real,
typename MeshType>
44 template <
int dim,
typename real,
typename MeshType>
50 template <
int dim,
typename real,
typename MeshType>
56 template <
int dim,
typename real,
typename MeshType>
59 pcout <<
" ************************************************************************ " << std::endl;
60 pcout <<
" Initializing DG with global polynomial degree = " << global_final_poly_degree <<
" by ramping from degree 0 ... " << std::endl;
61 pcout <<
" ************************************************************************ " << std::endl;
63 for (
unsigned int degree = 0; degree <= global_final_poly_degree; degree++) {
64 pcout <<
" ************************************************************************ " << std::endl;
65 pcout <<
" Ramping degree " << degree <<
" until p=" << global_final_poly_degree << std::endl;
66 pcout <<
" ************************************************************************ " << std::endl;
69 dealii::LinearAlgebra::distributed::Vector<double> old_solution(
dg->solution);
70 old_solution.update_ghost_values();
71 dealii::parallel::distributed::SolutionTransfer<dim, dealii::LinearAlgebra::distributed::Vector<double>, dealii::DoFHandler<dim>> solution_transfer(
dg->dof_handler);
72 solution_transfer.prepare_for_coarsening_and_refinement(old_solution);
73 dg->set_all_cells_fe_degree(degree);
74 dg->allocate_system ();
75 dg->solution.zero_out_ghosts();
76 solution_transfer.interpolate(
dg->solution);
77 dg->solution.update_ghost_values();
85 template <
int dim,
typename real,
typename MeshType>
88 for (
const auto &sol :
dg->solution) {
89 if (sol == std::numeric_limits<real>::lowest()) {
90 throw std::invalid_argument(
" User forgot to assign valid initial conditions. ");
95 template <
int dim,
typename real,
typename MeshType>
98 const double current_residual,
99 const std::shared_ptr <dealii::TableHandler> data_table)
const 103 std::string iteration_string =
"Iteration";
104 data_table->add_value(iteration_string, current_iteration);
106 std::string residual_string =
"Residual";
107 data_table->add_value(residual_string, current_residual);
108 data_table->set_precision(residual_string, 16);
109 data_table->set_scientific(residual_string,
true);
111 std::ofstream data_table_file(
"ode_solver_steady_state_convergence_data_table.txt");
112 data_table->write_text(data_table_file);
116 template <
int dim,
typename real,
typename MeshType>
122 catch(
const std::invalid_argument& e ) {
126 pcout <<
" Performing steady state analysis... " << std::endl;
129 std::shared_ptr<dealii::TableHandler> ode_solver_steady_state_convergence_table = std::make_shared<dealii::TableHandler>();
136 pcout <<
" Evaluating right-hand side and setting system_matrix to Jacobian before starting iterations... " << std::endl;
137 this->
dg->assemble_residual ();
140 pcout <<
" ********************************************************** " 142 <<
" Initial absolute residual norm: " << this->
residual_norm 154 auto initial_solution =
dg->solution;
156 double old_residual_norm = this->
residual_norm; (void) old_residual_norm;
161 while ( convergence_error
165 && this->residual_norm < 1e5
172 pcout.set_condition(
true);
174 pcout.set_condition(
false);
176 pcout <<
" ********************************************************** " 180 <<
" Residual norm decrease : " << this->residual_norm_decrease
190 pcout <<
" Evaluating right-hand side and setting system_matrix to Jacobian... " << std::endl;
194 if (this->residual_norm_decrease < 1.0) {
197 ramped_CFL = std::max(ramped_CFL,initial_CFL*CFL_factor);
198 pcout <<
"Initial CFL = " << initial_CFL <<
". Current CFL = " << ramped_CFL << std::endl;
201 this->
dg->freeze_artificial_dissipation =
true;
203 this->
dg->freeze_artificial_dissipation =
false;
206 const bool pseudotime =
true;
209 this->
dg->assemble_residual ();
213 if (is_output_iteration) {
215 this->
dg->output_results_vtk(file_number);
231 this->
dg->solution = initial_solution;
233 if(
CFL_factor <= 1e-2) this->
dg->right_hand_side.add(1.0);
237 dealii::LinearAlgebra::ReadWriteVector<double> write_dg_solution(this->
dg->solution.size());
238 write_dg_solution.import(this->
dg->solution, dealii::VectorOperation::values::insert);
241 for(
unsigned int i = 0 ; i < write_dg_solution.size() ; i++){
242 out_file <<
" " << std::setprecision(17) << write_dg_solution(i) <<
" \n";
248 pcout <<
" ********************************************************** " 250 <<
" ODESolver steady_state stopped at" 255 <<
" ********************************************************** " 258 return convergence_error;
261 template <
int dim,
typename real,
typename MeshType>
271 catch(
const std::invalid_argument& e ) {
275 pcout <<
" Advancing solution by " << time_advance <<
" time units, using " 276 << number_of_time_steps <<
" iterations of size dt=" << constant_time_step <<
" ... " << std::endl;
293 pcout <<
" ********************************************************** " 296 <<
" out of: " << number_of_time_steps
302 pcout <<
" Evaluating right-hand side and setting system_matrix to Jacobian... " << std::endl;
305 const bool pseudotime =
false;
310 if (is_output_iteration) {
312 this->
dg->output_results_vtk(file_number);
317 if (is_output_time) {
319 this->
dg->output_results_vtk(file_number);
OutputEnum ode_output
verbose or quiet.
virtual void step_in_time(real dt, const bool pseudotime)=0
Virtual function to evaluate solution update.
const MPI_Comm mpi_communicator
MPI communicator.
virtual int steady_state()
Evaluate steady state solution.
double CFL_factor
CFL factor for (un)successful linesearches.
const int mpi_rank
MPI rank.
int advance_solution_time(double time_advance)
Function to advance solution to time+dt.
double modified_time_step
Modified time step after calling step_in_time.
void write_ode_solver_steady_state_convergence_data_to_table(const unsigned int current_iteration, const double current_residual, const std::shared_ptr< dealii::TableHandler > data_table) const
Writes the ode solver steady state convergence data to a file.
unsigned int current_iteration
Current iteration.
void initialize_steady_polynomial_ramping(const unsigned int global_final_poly_degree)
Ramps up the solution from p0 all the way up to the given global_final_poly_degree.
int output_solution_every_x_steps
Outputs the solution every x steps to .vtk file.
bool use_energy
Flag to use an energy monotonicity test.
double current_desired_time_for_output_solution_every_dt_time_intervals
Current desired time for output solution every dt time intervals.
double time_step_factor_residual_exp
Scales initial time step by pow(time_step_factor_residual*(-log10(residual_norm_decrease)),time_step_factor_residual_exp)
Files for the baseline physics.
This class creates a new BoundPreservingLimiter object based on input parameters. ...
unsigned int print_iteration_modulo
If ode_output==verbose, print every print_iteration_modulo iterations.
bool output_ode_solver_steady_state_convergence_table
double residual_norm_decrease
Current residual norm normalized by initial residual. Only makes sense for steady state...
double initial_residual_norm
Initial residual norm.
double original_time_step
Original time step before calling step_in_time.
double get_modified_time_step() const
Getter for modified_time_step.
double output_solution_every_dt_time_intervals
Outputs the solution every dt time intervals to .vtk file.
ODESolverParam ode_solver_param
Contains parameters for ODE solver.
double initial_time_step
Time step used in ODE solver.
ODESolverBase(std::shared_ptr< DGBase< dim, real, MeshType > > dg_input, std::shared_ptr< ProperOrthogonalDecomposition::PODBase< dim >> pod)
Default constructor that will set the constants.
double current_time
Useful for accurate time-stepping.
double nonlinear_steady_residual_tolerance
Tolerance to determine steady-state convergence.
const Parameters::AllParameters *const all_parameters
Input parameters.
std::string steady_state_final_solution_filename
Filename to write final steady state solution.
double residual_norm
Current residual norm. Only makes sense for steady state.
const Parameters::ODESolverParam ode_param
Input ODE solver parameters.
void valid_initial_conditions() const
Checks whether the DG vector has valid values.
bool output_final_steady_state_solution_to_file
Output final steady state solution to file.
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
double time_step_factor_residual
Multiplies initial time-step by time_step_factor_residual*(-log10(residual_norm_decrease)) ...
double get_original_time_step() const
Getter for original_time_step.
virtual double get_automatic_initial_step_size(real dt, const bool pseudotime)
Virtual function to evaluate initial automatic error adaptive time step.
virtual void allocate_ode_system()=0
Virtual function to allocate the ODE system.
virtual double get_automatic_error_adaptive_step_size(real dt, const bool pseudotime)
Virtual function to evaluate automatic error adaptive time step.
double update_norm
Norm of the solution update.
DGBase is independent of the number of state variables.
unsigned int nonlinear_max_iterations
Maximum number of iterations.
std::shared_ptr< DGBase< dim, real, MeshType > > dg
Smart pointer to DGBase.