1 #include "rrk_ode_solver_base.h" 2 #include "physics/euler.h" 3 #include "physics/physics_factory.h" 8 template <
int dim,
typename real,
typename MeshType>
12 , butcher_tableau(rk_tableau_input)
13 , n_rk_stages(butcher_tableau->n_rk_stages)
14 , mpi_communicator(MPI_COMM_WORLD)
15 , mpi_rank(dealii::Utilities::MPI::this_mpi_process(MPI_COMM_WORLD))
16 , pcout(
std::cout, mpi_rank==0)
22 template <
int dim,
typename real,
typename MeshType>
30 template <
int dim,
typename real,
typename MeshType>
35 const unsigned int nstate = dim + 2;
37 const unsigned int poly_degree = dg->get_max_fe_degree();
38 if (poly_degree != dg->get_min_fe_degree()){
39 this->
pcout <<
"Error: Entropy RRK is only implemented for uniform p. Aborting..." << std::endl;
45 parameters_using_euler_pde_type.
pde_type = Parameters::AllParameters::PartialDifferentialEquation::euler;
49 const unsigned int n_dofs_cell = dg->fe_collection[poly_degree].dofs_per_cell;
50 const unsigned int n_quad_pts = dg->volume_quadrature_collection[poly_degree].size();
51 const unsigned int n_shape_fns = n_dofs_cell / nstate;
54 vol_projection.
build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]);
57 soln_basis.
build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]);
59 dealii::LinearAlgebra::distributed::Vector<double> entropy_var_hat_global(dg->right_hand_side);
60 std::vector<dealii::types::global_dof_index> dofs_indices (n_dofs_cell);
62 for (
auto cell = dg->dof_handler.begin_active(); cell!=dg->dof_handler.end(); ++cell) {
63 if (!cell->is_locally_owned())
continue;
64 cell->get_dof_indices (dofs_indices);
66 std::array<std::vector<double>,nstate> soln_coeff;
67 for(
unsigned int idof=0; idof<n_dofs_cell; idof++){
68 const unsigned int istate = dg->fe_collection[poly_degree].system_to_component_index(idof).first;
69 const unsigned int ishape = dg->fe_collection[poly_degree].system_to_component_index(idof).second;
71 soln_coeff[istate].resize(n_shape_fns);
72 soln_coeff[istate][ishape] = u(dofs_indices[idof]);
75 std::array<std::vector<double>,nstate> soln_at_q;
76 for(
unsigned int istate=0; istate<nstate; istate++){
77 soln_at_q[istate].resize(n_quad_pts);
81 std::array<std::vector<double>,nstate> entropy_var_at_q;
82 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
83 std::array<double,nstate> soln_state;
84 for(
unsigned int istate=0; istate<nstate; istate++){
85 soln_state[istate] = soln_at_q[istate][iquad];
88 std::array<double,nstate> entropy_var = euler_physics->compute_entropy_variables(soln_state);
90 for(
unsigned int istate=0; istate<nstate; istate++){
92 entropy_var_at_q[istate].resize(n_quad_pts);
93 entropy_var_at_q[istate][iquad] = entropy_var[istate];
96 for(
unsigned int istate=0; istate<nstate; istate++){
98 std::vector<double> entropy_var_hat(n_shape_fns);
102 for(
unsigned int ishape=0; ishape<n_shape_fns; ishape++){
103 const unsigned int idof = istate * n_shape_fns + ishape;
104 entropy_var_hat_global[dofs_indices[idof]] = entropy_var_hat[ishape];
108 return entropy_var_hat_global;
112 template <
int dim,
typename real,
typename MeshType>
115 const std::vector<dealii::LinearAlgebra::distributed::Vector<double>> &rk_stage,
116 const bool compute_K_norm)
const 118 double entropy_contribution = 0;
120 for (
int istage = 0; istage<
n_rk_stages; ++istage){
124 dealii::LinearAlgebra::distributed::Vector<double> M_matrix_times_rk_stage(dg->solution);
125 dealii::LinearAlgebra::distributed::Vector<double> MpK_matrix_times_rk_stage(dg->solution);
126 if(dg->all_parameters->use_inverse_mass_on_the_fly)
128 dg->apply_global_mass_matrix(rk_stage[istage],M_matrix_times_rk_stage,
133 dg->apply_global_mass_matrix(rk_stage[istage],MpK_matrix_times_rk_stage,
138 this->
pcout <<
"ERROR: FR Numerical entropy estimate currently not compatible with use_inverse_mass_matrix = false. Please modify params." << std::endl;
144 dealii::LinearAlgebra::distributed::Vector<double> entropy_var_hat_global=0;
145 if (dg->all_parameters->pde_type == PDEEnum::burgers_inviscid){
147 }
else if (dg->all_parameters->pde_type == PDEEnum::euler || dg->all_parameters->pde_type == PDEEnum::navier_stokes) {
150 this->
pcout <<
"ERROR: Cannot store FR-corrected numerical entropy for this PDE type. Aborting..." << std::endl;
154 double entropy_contribution_stage = 0;
155 if (compute_K_norm) {
156 entropy_contribution_stage = entropy_var_hat_global * MpK_matrix_times_rk_stage - entropy_var_hat_global * M_matrix_times_rk_stage;
158 entropy_contribution_stage = entropy_var_hat_global * M_matrix_times_rk_stage;
161 entropy_contribution += this->
butcher_tableau->get_b(istage) * entropy_contribution_stage;
164 entropy_contribution *= dt;
166 return entropy_contribution;
const int n_rk_stages
Number of RK stages.
PartialDifferentialEquation pde_type
Store the PDE type to be solved.
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
dealii::LinearAlgebra::distributed::Vector< double > compute_entropy_vars(const dealii::LinearAlgebra::distributed::Vector< double > &u, std::shared_ptr< DGBase< dim, real, MeshType >> dg) const
Return the entropy variables from a solution vector u.
real compute_FR_entropy_contribution(const real dt, std::shared_ptr< DGBase< dim, real, MeshType >> dg, const std::vector< dealii::LinearAlgebra::distributed::Vector< double >> &rk_stage, const bool compute_K_norm) const override
Calculate FR entropy adjustment.
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
PartialDifferentialEquation
Possible Partial Differential Equations to solve.
Files for the baseline physics.
void store_stage_solutions(const int istage, const dealii::LinearAlgebra::distributed::Vector< double > rk_stage_i) override
Update stored quantities at the current stage.
Main parameter class that contains the various other sub-parameter classes.
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
RKNumEntropy(std::shared_ptr< RKTableauBase< dim, real, MeshType >> rk_tableau_input)
Default constructor that will set the constants.
Euler equations. Derived from PhysicsBase.
dealii::FullMatrix< double > oneD_vol_operator
Stores the one dimensional volume operator.
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.
Base class for storing the RK method.
DGBase is independent of the number of state variables.
std::vector< dealii::LinearAlgebra::distributed::Vector< double > > rk_stage_solution
Storage for the solution at each Runge-Kutta stage.
std::shared_ptr< RKTableauBase< dim, real, MeshType > > butcher_tableau
Store pointer to RK tableau.
void matrix_vector_mult_1D(const std::vector< real > &input_vect, std::vector< real > &output_vect, const dealii::FullMatrix< double > &basis_x, const bool adding=false, const double factor=1.0)
Apply the matrix vector operation using the 1D operator in each direction.
Projection operator corresponding to basis functions onto M-norm (L2).