1 #include "periodic_entropy_tests.h" 2 #include "physics/physics_factory.h" 12 template <
int dim,
int nstate>
15 , unsteady_data_table_filename_with_extension(this->all_param.flow_solver_param.unsteady_data_table_filename+
".txt")
21 template <
int dim,
int nstate>
29 const unsigned int number_of_degrees_of_freedom_per_state = dg->dof_handler.n_dofs()/nstate;
30 const double approximate_grid_spacing = (this->
domain_right-this->
domain_left)/pow(number_of_degrees_of_freedom_per_state,(1.0/dim));
32 double constant_time_step=0;
33 if (flow_case == FlowCaseEnum::isentropic_vortex){
37 }
else if (flow_case == FlowCaseEnum::kelvin_helmholtz_instability){
44 return constant_time_step;
46 this->
pcout <<
"Timestep size has not been defined in periodic_entropy_tests for this flow_case_type. Aborting..." << std::endl;
50 return constant_time_step;
53 template<
int dim,
int nstate>
59 this->
pcout <<
"ERROR: compute_integrated_quantities() is untested for nonuniform p. Aborting..." << std::endl;
63 double integrated_quantity = 0.0;
65 const unsigned int grid_degree = dg.
high_order_grid->fe_system.tensor_degree();
66 const unsigned int poly_degree = dg.
max_degree;
69 dealii::Quadrature<1> quad_1D;
70 std::vector<double> quad_weights_;
71 unsigned int n_quad_pts_;
72 if (overintegrate > 0) {
73 dealii::QGauss<dim> quad_extra(dg.
max_degree+1+overintegrate);
74 dealii::QGauss<1> quad_extra_1D(dg.
max_degree+1+overintegrate);
75 quad_1D = quad_extra_1D;
76 quad_weights_ = quad_extra.get_weights();
77 n_quad_pts_ = quad_extra.size();
83 const std::vector<double> &quad_weights = quad_weights_;
84 const unsigned int n_quad_pts = n_quad_pts_;
97 const bool store_vol_flux_nodes =
false;
98 const bool store_surf_flux_nodes =
false;
100 const unsigned int n_dofs = dg.
fe_collection[poly_degree].n_dofs_per_cell();
101 const unsigned int n_shape_fns = n_dofs / nstate;
102 std::vector<dealii::types::global_dof_index> dofs_indices (n_dofs);
103 auto metric_cell = dg.
high_order_grid->dof_handler_grid.begin_active();
106 if (!cell->is_locally_owned())
continue;
107 cell->get_dof_indices (dofs_indices);
110 const dealii::FESystem<dim> &fe_metric = dg.
high_order_grid->fe_system;
111 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
112 const unsigned int n_grid_nodes = n_metric_dofs / dim;
113 std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
114 metric_cell->get_dof_indices (metric_dof_indices);
115 std::array<std::vector<double>,dim> mapping_support_points;
116 for(
int idim=0; idim<dim; idim++){
117 mapping_support_points[idim].resize(n_grid_nodes);
121 const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(grid_degree);
122 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
123 const double val = (dg.
high_order_grid->volume_nodes[metric_dof_indices[idof]]);
124 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
125 const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
126 const unsigned int igrid_node = index_renumbering[ishape];
127 mapping_support_points[istate][igrid_node] = val;
135 n_quad_pts, n_grid_nodes,
136 mapping_support_points,
145 std::array<std::vector<double>,nstate> soln_coeff;
146 for (
unsigned int idof = 0; idof < n_dofs; ++idof) {
147 const unsigned int istate = dg.
fe_collection[poly_degree].system_to_component_index(idof).first;
148 const unsigned int ishape = dg.
fe_collection[poly_degree].system_to_component_index(idof).second;
150 soln_coeff[istate].resize(n_shape_fns);
153 soln_coeff[istate][ishape] = dg.
solution(dofs_indices[idof]);
157 std::array<std::vector<double>,nstate> soln_at_q_vect;
158 std::array<dealii::Tensor<1,dim,std::vector<double>>,nstate> soln_grad_at_q_vect;
159 for(
int istate=0; istate<nstate; istate++){
160 soln_at_q_vect[istate].resize(n_quad_pts);
165 dealii::Tensor<1,dim,std::vector<double>> ref_gradient_basis_fns_times_soln;
166 for(
int idim=0; idim<dim; idim++){
167 ref_gradient_basis_fns_times_soln[idim].resize(n_quad_pts);
168 soln_grad_at_q_vect[istate][idim].resize(n_quad_pts);
175 for(
int idim=0; idim<dim; idim++){
176 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
177 for(
int jdim=0; jdim<dim; jdim++){
179 soln_grad_at_q_vect[istate][idim][iquad] += metric_oper.
metric_cofactor_vol[idim][jdim][iquad]
180 * ref_gradient_basis_fns_times_soln[jdim][iquad]
188 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
190 std::array<double,nstate> soln_at_q;
191 std::array<dealii::Tensor<1,dim,double>,nstate> soln_grad_at_q;
193 for(
int istate=0; istate<nstate; istate++){
194 soln_at_q[istate] = soln_at_q_vect[istate][iquad];
195 for(
int idim=0; idim<dim; idim++){
196 soln_grad_at_q[istate][idim] = soln_grad_at_q_vect[istate][idim][iquad];
203 if (quantity == IntegratedQuantityEnum::kinetic_energy) {
204 const double KE_integrand = this->euler_physics->compute_kinetic_energy_from_conservative_solution(soln_at_q);
205 integrated_quantity += KE_integrand * quad_weights[iquad] * metric_oper.
det_Jac_vol[iquad];
206 }
else if (quantity == IntegratedQuantityEnum::numerical_entropy) {
207 const double quadrature_entropy = this->euler_physics->compute_numerical_entropy_function(soln_at_q);
209 if (isnan(quadrature_entropy)) std::cout <<
"WARNING: NaN entropy detected at a node!" << std::endl;
210 integrated_quantity += quadrature_entropy * quad_weights[iquad] * metric_oper.
det_Jac_vol[iquad];
211 }
else if (quantity == IntegratedQuantityEnum::max_wave_speed) {
212 const double local_wave_speed = this->euler_physics->max_convective_eigenvalue(soln_at_q);
213 if(local_wave_speed > integrated_quantity) integrated_quantity = local_wave_speed;
215 std::cout <<
"Integrated quantity is not correctly defined." << std::endl;
222 if (quantity == IntegratedQuantityEnum::max_wave_speed) {
223 integrated_quantity = dealii::Utilities::MPI::max(integrated_quantity, this->
mpi_communicator);
225 integrated_quantity = dealii::Utilities::MPI::sum(integrated_quantity, this->
mpi_communicator);
228 return integrated_quantity;
232 template <
int dim,
int nstate>
240 template <
int dim,
int nstate>
244 const std::shared_ptr<dealii::TableHandler> unsteady_data_table)
247 const unsigned int current_iteration = ode_solver->current_iteration;
248 const double current_time = ode_solver->current_time;
259 const double entropy = current_numerical_entropy -
previous_numerical_entropy + ode_solver->FR_entropy_contribution_RRK_solver;
262 if (std::isnan(entropy)){
266 this->
pcout <<
"Entropy is nan. Ending flow simulation by throwing an exception..." << std::endl << std::flush;
269 if (current_iteration == 0)
initial_entropy = current_numerical_entropy;
271 double relaxation_parameter = ode_solver->relaxation_parameter_RRK_solver;
274 if (std::isnan(kinetic_energy)){
275 this->
pcout <<
"Kinetic energy is nan. Ending flow simulation by throwing an exception..." << std::endl << std::flush;
283 if (output_solution_every_n_iterations > 0){
286 if ((current_iteration % output_solution_every_n_iterations) == 0){
288 this->
pcout <<
" Iter: " << current_iteration
289 <<
" Time: " << std::setprecision(16) << current_time
290 <<
" Entropy: " << entropy
292 <<
" Kinetic energy: " << kinetic_energy;
294 this->
pcout <<
" Relaxation Parameter: " << relaxation_parameter;
295 this->
pcout << std::endl;
300 unsteady_data_table->add_value(
"iteration", current_iteration);
301 unsteady_data_table->set_scientific(
"iteration",
false);
303 unsteady_data_table->set_scientific(
"time",
false);
305 unsteady_data_table->set_scientific(
"entropy",
false);
307 unsteady_data_table->set_scientific(
"U/Uo",
false);
309 unsteady_data_table->set_scientific(
"kinetic_energy",
false);
312 unsteady_data_table->set_scientific(
"gamma",
false);
315 unsteady_data_table->write_text(unsteady_data_table_file);
const Parameters::AllParameters all_param
All parameters.
const MPI_Comm mpi_communicator
MPI communicator.
FlowCaseType
Selects the flow case to be simulated.
dealii::Tensor< 2, dim, std::vector< real > > metric_cofactor_vol
The volume metric cofactor matrix.
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
FlowCaseType flow_case_type
Selected FlowCaseType from the input file.
double courant_friedrichs_lewy_number
Courant-Friedrich-Lewy (CFL) number for constant time step.
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
double compute_integrated_quantities(DGBase< dim, double > &dg, IntegratedQuantityEnum quantity, const int overintegrate=10) const
Compute and update integrated quantities.
dealii::FullMatrix< double > oneD_grad_operator
Stores the one dimensional gradient operator.
double mach_inf
Mach number at infinity.
int output_solution_every_x_steps
Outputs the solution every x steps to .vtk file.
PeriodicEntropyTests(const Parameters::AllParameters *const parameters_input)
Constructor.
double previous_time
Last time (for calculating relaxation factor)
std::string unsteady_data_table_filename_with_extension
Filename for unsteady data.
dealii::QGauss< 0 > oneD_face_quadrature
1D surface quadrature is always one single point for all poly degrees.
Files for the baseline physics.
const double domain_left
Domain left-boundary value for generating the grid.
double previous_numerical_entropy
Store previous entropy.
EulerParam euler_param
Contains parameters for the Euler equations non-dimensionalization.
ODESolverEnum
Types of ODE solver.
void build_1D_shape_functions_at_grid_nodes(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Constructs the volume operator and gradient operator.
double output_solution_every_dt_time_intervals
Outputs the solution every dt time intervals to .vtk file.
Main parameter class that contains the various other sub-parameter classes.
const dealii::hp::FECollection< 1 > oneD_fe_collection_1state
1D Finite Element Collection for p-finite-element to represent the solution for a single state...
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution.
std::vector< real > det_Jac_vol
The determinant of the metric Jacobian at volume cubature nodes.
void add_value_to_data_table(const double value, const std::string value_string, const std::shared_ptr< dealii::TableHandler > data_table) const
Add a value to a given data table with scientific format.
ODESolverParam ode_solver_param
Contains parameters for ODE solver.
IntegratedQuantityEnum
Enum of integrated quantities to calculate.
void build_1D_gradient_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
double initial_entropy
Storing entropy at first step.
const unsigned int max_degree
Maximum degree used for p-refi1nement.
Base metric operators class that stores functions used in both the volume and on surface.
unsigned int get_max_fe_degree()
Gets the maximum value of currently active FE degree.
The mapping shape functions evaluated at the desired nodes (facet set included in volume grid nodes f...
double get_constant_time_step(std::shared_ptr< DGBase< dim, double >> dg) const override
Function to compute the constant time step.
Euler equations. Derived from PhysicsBase.
std::shared_ptr< HighOrderGrid< dim, real, MeshType > > high_order_grid
High order grid that will provide the MappingFEField.
void gradient_matrix_vector_mult_1D(const std::vector< real > &input_vect, dealii::Tensor< 1, dim, std::vector< real >> &output_vect, const dealii::FullMatrix< double > &basis, const dealii::FullMatrix< double > &gradient_basis)
Computes the gradient of a scalar using sum-factorization where the basis are the same in each direct...
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.
unsigned int get_min_fe_degree()
Gets the minimum value of currently active FE degree.
ODESolverEnum ode_solver_type
ODE solver type.
double compute_entropy(const std::shared_ptr< DGBase< dim, double >> dg) const
dealii::DoFHandler< dim > dof_handler
Finite Element Collection to represent the high-order grid.
void build_volume_metric_operators(const unsigned int n_quad_pts, const unsigned int n_metric_dofs, const std::array< std::vector< real >, dim > &mapping_support_points, mapping_shape_functions< dim, n_faces, real > &mapping_basis, const bool use_invariant_curl_form=false)
Builds the volume metric operators.
const double domain_right
Domain right-boundary value for generating the grid.
void compute_unsteady_data_and_write_to_table(const std::shared_ptr< ODE::ODESolverBase< dim, double >> ode_solver, const std::shared_ptr< DGBase< dim, double >> dg, const std::shared_ptr< dealii::TableHandler > unsteady_data_table) override
Compute the desired unsteady data and write it to a table.
dealii::hp::QCollection< 1 > oneD_quadrature_collection
1D quadrature to generate Lagrange polynomials for the sake of flux interpolation.
DGBase is independent of the number of state variables.
dealii::ConditionalOStream pcout
ConditionalOStream.
dealii::hp::QCollection< dim > volume_quadrature_collection
Finite Element Collection to represent the high-order grid.
void build_1D_shape_functions_at_flux_nodes(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature, const dealii::Quadrature< 0 > &face_quadrature)
Constructs the volume, gradient, surface, and surface gradient operator.
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.
const dealii::hp::FECollection< dim > fe_collection
Finite Element Collection for p-finite-element to represent the solution.