1 #include "periodic_turbulence.h" 2 #include "ode_solver/low_storage_runge_kutta_ode_solver.h" 3 #include <deal.II/base/function.h> 6 #include <deal.II/dofs/dof_tools.h> 7 #include <deal.II/grid/grid_tools.h> 8 #include <deal.II/numerics/vector_tools.h> 9 #include <deal.II/fe/fe_values.h> 10 #include "physics/physics_factory.h" 11 #include <deal.II/base/table_handler.h> 12 #include <deal.II/base/tensor.h> 15 #include <deal.II/base/quadrature_lib.h> 19 namespace FlowSolver {
24 template <
int dim,
int nspecies,
int nstate>
27 , unsteady_data_table_filename_with_extension(this->all_param.flow_solver_param.unsteady_data_table_filename+
".txt")
28 , number_of_times_to_output_velocity_field(this->all_param.flow_solver_param.number_of_times_to_output_velocity_field)
29 , output_velocity_field_at_fixed_times(this->all_param.flow_solver_param.output_velocity_field_at_fixed_times)
30 , output_vorticity_magnitude_field_in_addition_to_velocity(this->all_param.flow_solver_param.output_vorticity_magnitude_field_in_addition_to_velocity)
31 , output_density_field_in_addition_to_velocity(this->all_param.flow_solver_param.output_density_field_in_addition_to_velocity)
32 , output_viscosity_field_in_addition_to_velocity(this->all_param.flow_solver_param.output_viscosity_field_in_addition_to_velocity)
33 , output_flow_field_files_directory_name(this->all_param.flow_solver_param.output_flow_field_files_directory_name)
34 , output_solution_at_exact_fixed_times(this->all_param.ode_solver_param.output_solution_at_exact_fixed_times)
35 , output_velocity_number_of_subvisions(this->all_param.flow_solver_param.output_velocity_number_of_subvisions)
36 , do_compute_angular_momentum(this->all_param.flow_solver_param.do_compute_angular_momentum)
51 parameters_navier_stokes.
pde_type = PDE_enum::navier_stokes;
71 std::string line = output_velocity_field_times_string;
72 std::string::size_type sz1;
75 line = line.substr(sz1);
99 template <
int dim,
int nspecies,
int nstate>
106 std::string flow_type_string;
114 template <
int dim,
int nspecies,
int nstate>
119 return constant_time_step;
121 const unsigned int number_of_degrees_of_freedom_per_state = dg->dof_handler.n_dofs()/nstate;
122 const double approximate_grid_spacing = (this->
domain_right-this->
domain_left)/pow(number_of_degrees_of_freedom_per_state,(1.0/dim));
124 return constant_time_step;
128 template <
int dim,
int nspecies,
int nstate>
133 return number_of_degrees_of_freedom_per_state;
136 std::string get_padded_mpi_rank_string(
const int mpi_rank_input) {
138 std::string mpi_rank_string = std::to_string(mpi_rank_input);
139 const unsigned int length_of_mpi_rank_with_padding = 5;
140 const int number_of_zeros = length_of_mpi_rank_with_padding - mpi_rank_string.length();
141 mpi_rank_string.insert(0, number_of_zeros,
'0');
143 return mpi_rank_string;
146 template<
int dim,
int nspecies,
int nstate>
149 const unsigned int output_file_index,
150 const double current_time)
const 152 this->
pcout <<
" ... Writting velocity field ... " << std::flush;
162 const std::string mpi_rank_string = get_padded_mpi_rank_string(this->
mpi_rank);
164 const std::string filename_without_extension = filename_prefix + std::string(
"-") + mpi_rank_string;
176 std::ofstream data_table_file(filename_for_time_table);
183 std::ofstream FILE (filename);
188 if (!FILE.is_open()) {
189 this->
pcout <<
"ERROR: Cannot open file " << filename << std::endl;
193 FILE << number_of_degrees_of_freedom_per_state << std::string(
"\n");
197 dealii::Quadrature<1> vol_quad_equidistant_1D = dealii::QIterated<1>(dealii::QTrapez<1>(),higher_poly_degree);
198 const unsigned int n_quad_pts = pow(vol_quad_equidistant_1D.size(),dim);
200 const unsigned int init_grid_degree = dg->high_order_grid->fe_system.tensor_degree();
210 const unsigned int max_dofs_per_cell = dg->dof_handler.get_fe_collection().max_dofs_per_cell();
211 std::vector<dealii::types::global_dof_index> current_dofs_indices(max_dofs_per_cell);
212 auto metric_cell = dg->high_order_grid->dof_handler_grid.begin_active();
213 for (
auto current_cell = dg->dof_handler.begin_active(); current_cell!=dg->dof_handler.end(); ++current_cell, ++metric_cell) {
214 if (!current_cell->is_locally_owned())
continue;
216 const int i_fele = current_cell->active_fe_index();
217 const unsigned int poly_degree = i_fele;
218 const unsigned int n_dofs_cell = dg->fe_collection[poly_degree].dofs_per_cell;
219 const unsigned int n_shape_fns = n_dofs_cell / nstate;
222 const dealii::FESystem<dim> &fe_metric = dg->high_order_grid->fe_system;
223 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
224 const unsigned int n_grid_nodes = n_metric_dofs / dim;
225 std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
226 metric_cell->get_dof_indices (metric_dof_indices);
227 std::array<std::vector<double>,dim> mapping_support_points;
228 for(
int idim=0; idim<dim; idim++){
229 mapping_support_points[idim].resize(n_grid_nodes);
233 const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(init_grid_degree);
234 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
235 const double val = (dg->high_order_grid->volume_nodes[metric_dof_indices[idof]]);
236 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
237 const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
238 const unsigned int igrid_node = index_renumbering[ishape];
239 mapping_support_points[istate][igrid_node] = val;
247 n_quad_pts, n_grid_nodes,
248 mapping_support_points,
249 mapping_basis_at_equidistant,
250 dg->all_parameters->use_invariant_curl_form);
252 current_dofs_indices.resize(n_dofs_cell);
253 current_cell->get_dof_indices (current_dofs_indices);
255 std::array<std::vector<double>,nstate> soln_coeff;
256 for(
unsigned int idof=0; idof<n_dofs_cell; idof++){
257 const unsigned int istate = dg->fe_collection[poly_degree].system_to_component_index(idof).first;
258 const unsigned int ishape = dg->fe_collection[poly_degree].system_to_component_index(idof).second;
260 soln_coeff[istate].resize(n_shape_fns);
262 soln_coeff[istate][ishape] = dg->solution(current_dofs_indices[idof]);
265 std::array<std::vector<double>,nstate> soln_at_q;
266 std::array<dealii::Tensor<1,dim,std::vector<double>>,nstate> soln_grad_at_q;
267 for(
int istate=0; istate<nstate; istate++){
268 soln_at_q[istate].resize(n_quad_pts);
273 dealii::Tensor<1,dim,std::vector<double>> ref_gradient_basis_fns_times_soln;
274 for(
int idim=0; idim<dim; idim++){
275 ref_gradient_basis_fns_times_soln[idim].resize(n_quad_pts);
282 for(
int idim=0; idim<dim; idim++){
283 soln_grad_at_q[istate][idim].resize(n_quad_pts);
284 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
285 for(
int jdim=0; jdim<dim; jdim++){
287 soln_grad_at_q[istate][idim][iquad] += metric_oper_equid.
metric_cofactor_vol[idim][jdim][iquad]
288 * ref_gradient_basis_fns_times_soln[jdim][iquad]
295 dealii::Tensor<1,dim,std::vector<double>> velocity_at_q;
296 std::vector<double> vorticity_magnitude_at_q(n_quad_pts);
297 std::vector<double> density_at_q(n_quad_pts);
298 std::vector<double> viscosity_at_q(n_quad_pts);
299 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
300 std::array<double,nstate> soln_state;
301 std::array<dealii::Tensor<1,dim,double>,nstate> soln_grad_state;
302 for(
int istate=0; istate<nstate; istate++){
303 soln_state[istate] = soln_at_q[istate][iquad];
304 for(
int idim=0; idim<dim; idim++){
305 soln_grad_state[istate][idim] = soln_grad_at_q[istate][idim][iquad];
308 const dealii::Tensor<1,dim,double> velocity = this->
navier_stokes_physics->compute_velocities(soln_state);
309 for(
int idim=0; idim<dim; idim++){
311 velocity_at_q[idim].resize(n_quad_pts);
312 velocity_at_q[idim][iquad] = velocity[idim];
317 vorticity_magnitude_at_q[iquad] = this->
navier_stokes_physics->compute_vorticity_magnitude(soln_state, soln_grad_state);
321 density_at_q[iquad] = soln_state[0];
325 const std::array<double,nstate> primitive_soln = this->
navier_stokes_physics->convert_conservative_to_primitive(soln_state);
330 for(
unsigned int ishape=0; ishape<n_quad_pts; ishape++){
331 dealii::Point<dim,double> vol_equid_node;
333 for(
int idim=0; idim<dim; idim++) {
334 vol_equid_node[idim] = metric_oper_equid.
flux_nodes_vol[idim][ishape];
335 FILE << std::setprecision(17) << vol_equid_node[idim] << std::string(
" ");
338 for (
int d=0; d<dim; ++d) {
339 FILE << std::setprecision(17) << velocity_at_q[d][ishape] << std::string(
" ");
343 FILE << std::setprecision(17) << vorticity_magnitude_at_q[ishape] << std::string(
" ");
347 FILE << std::setprecision(17) << density_at_q[ishape] << std::string(
" ");
351 FILE << std::setprecision(17) << viscosity_at_q[ishape] << std::string(
" ");
353 FILE << std::string(
"\n");
357 this->
pcout <<
"done." << std::endl;
360 template <
int dim,
int nspecies,
int nstate>
364 const unsigned int number_of_degrees_of_freedom_per_state = dg->dof_handler.n_dofs()/nstate;
365 const double approximate_grid_spacing = (this->
domain_right-this->
domain_left)/pow(number_of_degrees_of_freedom_per_state,(1.0/dim));
371 template<
int dim,
int nspecies,
int nstate>
378 int overintegrate = 10;
380 const unsigned int grid_degree = dg.
high_order_grid->fe_system.tensor_degree();
381 const unsigned int poly_degree = dg.
max_degree;
382 dealii::QGauss<dim> quad_extra(dg.
max_degree+1+overintegrate);
383 const unsigned int n_quad_pts = quad_extra.size();
384 dealii::QGauss<1> quad_extra_1D(dg.
max_degree+1+overintegrate);
388 const unsigned int n_dofs = dg.
fe_collection[poly_degree].n_dofs_per_cell();
389 const unsigned int n_shape_fns = n_dofs / nstate;
391 std::vector<dealii::types::global_dof_index> dofs_indices (n_dofs);
393 if (!cell->is_locally_owned())
continue;
394 cell->get_dof_indices (dofs_indices);
396 std::array<std::vector<double>,nstate> soln_coeff;
397 for (
unsigned int idof = 0; idof < n_dofs; ++idof) {
398 const unsigned int istate = dg.
fe_collection[poly_degree].system_to_component_index(idof).first;
399 const unsigned int ishape = dg.
fe_collection[poly_degree].system_to_component_index(idof).second;
401 soln_coeff[istate].resize(n_shape_fns);
404 soln_coeff[istate][ishape] = dg.
solution(dofs_indices[idof]);
406 std::array<std::vector<double>,nstate> soln_at_q_vect;
407 for(
int istate=0; istate<nstate; istate++){
408 soln_at_q_vect[istate].resize(n_quad_pts);
414 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
415 std::array<double,nstate> soln_at_q;
416 for(
int istate=0; istate<nstate; istate++){
417 soln_at_q[istate] = soln_at_q_vect[istate][iquad];
428 template <
int dim,
int nspecies,
int nstate>
432 const double radius_squared = position.norm_square();
433 const double vorticity_magnitude = vorticity.norm();
434 const double angular_momentum = 0.5*radius_squared*vorticity_magnitude;
435 return angular_momentum;
438 template<
int dim,
int nspecies,
int nstate>
441 std::array<double,NUMBER_OF_INTEGRATED_QUANTITIES> integral_values;
442 std::fill(integral_values.begin(), integral_values.end(), 0.0);
448 int overintegrate = 10;
451 dealii::QGauss<dim> quad_extra(dg.
max_degree+1+overintegrate);
452 dealii::QGauss<1> quad_extra_1D(dg.
max_degree+1+overintegrate);
454 const unsigned int n_quad_pts = quad_extra.size();
455 const unsigned int grid_degree = dg.
high_order_grid->fe_system.tensor_degree();
456 const unsigned int poly_degree = dg.
max_degree;
469 const std::vector<double> &quad_weights = quad_extra.get_weights();
472 bool store_vol_flux_nodes =
false;
474 const bool store_surf_flux_nodes =
false;
476 const unsigned int n_dofs = dg.
fe_collection[poly_degree].n_dofs_per_cell();
477 const unsigned int n_shape_fns = n_dofs / nstate;
478 std::vector<dealii::types::global_dof_index> dofs_indices (n_dofs);
479 auto metric_cell = dg.
high_order_grid->dof_handler_grid.begin_active();
482 if (!cell->is_locally_owned())
continue;
483 cell->get_dof_indices (dofs_indices);
486 const dealii::FESystem<dim> &fe_metric = dg.
high_order_grid->fe_system;
487 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
488 const unsigned int n_grid_nodes = n_metric_dofs / dim;
489 std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
490 metric_cell->get_dof_indices (metric_dof_indices);
491 std::array<std::vector<double>,dim> mapping_support_points;
492 for(
int idim=0; idim<dim; idim++){
493 mapping_support_points[idim].resize(n_grid_nodes);
497 const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(grid_degree);
498 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
499 const double val = (dg.
high_order_grid->volume_nodes[metric_dof_indices[idof]]);
500 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
501 const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
502 const unsigned int igrid_node = index_renumbering[ishape];
503 mapping_support_points[istate][igrid_node] = val;
511 n_quad_pts, n_grid_nodes,
512 mapping_support_points,
521 std::array<std::vector<double>,nstate> soln_coeff;
522 for (
unsigned int idof = 0; idof < n_dofs; ++idof) {
523 const unsigned int istate = dg.
fe_collection[poly_degree].system_to_component_index(idof).first;
524 const unsigned int ishape = dg.
fe_collection[poly_degree].system_to_component_index(idof).second;
526 soln_coeff[istate].resize(n_shape_fns);
529 soln_coeff[istate][ishape] = dg.
solution(dofs_indices[idof]);
533 std::array<std::vector<double>,nstate> soln_at_q_vect;
534 std::array<dealii::Tensor<1,dim,std::vector<double>>,nstate> soln_grad_at_q_vect;
535 for(
int istate=0; istate<nstate; istate++){
536 soln_at_q_vect[istate].resize(n_quad_pts);
541 dealii::Tensor<1,dim,std::vector<double>> ref_gradient_basis_fns_times_soln;
542 for(
int idim=0; idim<dim; idim++){
543 ref_gradient_basis_fns_times_soln[idim].resize(n_quad_pts);
544 soln_grad_at_q_vect[istate][idim].resize(n_quad_pts);
551 for(
int idim=0; idim<dim; idim++){
552 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
553 for(
int jdim=0; jdim<dim; jdim++){
555 soln_grad_at_q_vect[istate][idim][iquad] += metric_oper.
metric_cofactor_vol[idim][jdim][iquad]
556 * ref_gradient_basis_fns_times_soln[jdim][iquad]
563 std::array<std::vector<double>,3> vorticity_at_q_vect;
565 for(
int istate=0; istate<3; istate++){
566 vorticity_at_q_vect[istate].resize(n_quad_pts);
569 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
571 std::array<double,nstate> soln_at_q;
572 std::array<dealii::Tensor<1,dim,double>,nstate> soln_grad_at_q;
573 for(
int istate=0; istate<nstate; istate++){
574 soln_at_q[istate] = soln_at_q_vect[istate][iquad];
575 for(
int idim=0; idim<dim; idim++){
576 soln_grad_at_q[istate][idim] = soln_grad_at_q_vect[istate][idim][iquad];
579 dealii::Tensor<1,3,double> vorticity_at_q = this->
navier_stokes_physics->compute_vorticity(soln_at_q,soln_grad_at_q);
580 for(
int istate=0; istate<3; istate++){
581 vorticity_at_q_vect[istate][iquad] = vorticity_at_q[istate];
588 std::array<dealii::Tensor<1,dim,std::vector<double>>,3> vorticity_grad_at_q_vect;
589 for(
int istate=0; istate<3; istate++){
590 std::vector<double> vorticity_coeff(n_shape_fns);
594 dealii::Tensor<1,dim,std::vector<double>> ref_gradient_basis_fns_times_soln;
595 for(
int idim=0; idim<dim; idim++){
596 ref_gradient_basis_fns_times_soln[idim].resize(n_quad_pts);
597 vorticity_grad_at_q_vect[istate][idim].resize(n_quad_pts);
604 for(
int idim=0; idim<dim; idim++){
605 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
606 for(
int jdim=0; jdim<dim; jdim++){
608 vorticity_grad_at_q_vect[istate][idim][iquad] += metric_oper.
metric_cofactor_vol[idim][jdim][iquad]
609 * ref_gradient_basis_fns_times_soln[jdim][iquad]
618 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
620 std::array<double,nstate> soln_at_q;
621 std::array<dealii::Tensor<1,dim,double>,nstate> soln_grad_at_q;
622 dealii::Tensor<1,3,double> vorticity_at_q;
623 std::array<dealii::Tensor<1,dim,double>,3> vorticity_grad_at_q;
625 for(
int istate=0; istate<nstate; istate++){
626 soln_at_q[istate] = soln_at_q_vect[istate][iquad];
627 if(istate<3) vorticity_at_q[istate] = vorticity_at_q_vect[istate][iquad];
628 for(
int idim=0; idim<dim; idim++){
629 soln_grad_at_q[istate][idim] = soln_grad_at_q_vect[istate][idim][iquad];
630 if(istate<3) vorticity_grad_at_q[istate][idim] = vorticity_grad_at_q_vect[istate][idim][iquad];
633 dealii::Point<dim> qpoint;
635 for(
int idim=0; idim<dim; idim++){
640 std::array<double,NUMBER_OF_INTEGRATED_QUANTITIES> integrand_values;
641 std::fill(integrand_values.begin(), integrand_values.end(), 0.0);
642 integrand_values[IntegratedQuantitiesEnum::kinetic_energy] = this->
navier_stokes_physics->compute_kinetic_energy_from_conservative_solution(soln_at_q);
643 integrand_values[IntegratedQuantitiesEnum::enstrophy] = this->
navier_stokes_physics->compute_enstrophy(soln_at_q,soln_grad_at_q);
644 integrand_values[IntegratedQuantitiesEnum::pressure_dilatation] = this->
navier_stokes_physics->compute_pressure_dilatation(soln_at_q,soln_grad_at_q);
645 integrand_values[IntegratedQuantitiesEnum::viscosity_times_deviatoric_strain_rate_tensor_magnitude_sqr] = this->
navier_stokes_physics->compute_viscosity_times_deviatoric_strain_rate_tensor_magnitude_sqr(soln_at_q,soln_grad_at_q);
646 integrand_values[IntegratedQuantitiesEnum::viscosity_times_strain_rate_tensor_magnitude_sqr] = this->
navier_stokes_physics->compute_viscosity_times_strain_rate_tensor_magnitude_sqr(soln_at_q,soln_grad_at_q);
647 integrand_values[IntegratedQuantitiesEnum::incompressible_kinetic_energy] = this->
navier_stokes_physics->compute_incompressible_kinetic_energy_from_conservative_solution(soln_at_q);
648 integrand_values[IntegratedQuantitiesEnum::incompressible_enstrophy] = this->
navier_stokes_physics->compute_incompressible_enstrophy(soln_at_q,soln_grad_at_q);
649 integrand_values[IntegratedQuantitiesEnum::incompressible_palinstrophy] = this->
navier_stokes_physics->compute_incompressible_palinstrophy(soln_at_q,vorticity_grad_at_q);
651 else integrand_values[IntegratedQuantitiesEnum::angular_momentum] = 0.0;
653 integral_values[i_quantity] += integrand_values[i_quantity] * quad_weights[iquad] * metric_oper.
det_Jac_vol[iquad];
673 template<
int dim,
int nspecies,
int nstate>
676 const double integrated_kinetic_energy = this->
integrated_quantities[IntegratedQuantitiesEnum::kinetic_energy];
683 return integrated_kinetic_energy;
686 template<
int dim,
int nspecies,
int nstate>
692 template<
int dim,
int nspecies,
int nstate>
698 template<
int dim,
int nspecies,
int nstate>
704 template<
int dim,
int nspecies,
int nstate>
710 template<
int dim,
int nspecies,
int nstate>
716 template<
int dim,
int nspecies,
int nstate>
719 const double integrated_enstrophy = this->
integrated_quantities[IntegratedQuantitiesEnum::enstrophy];
720 double vorticity_based_dissipation_rate = 0.0;
722 vorticity_based_dissipation_rate = this->
navier_stokes_physics->compute_vorticity_based_dissipation_rate_from_integrated_enstrophy(integrated_enstrophy);
724 return vorticity_based_dissipation_rate;
727 template<
int dim,
int nspecies,
int nstate>
730 const double integrated_pressure_dilatation = this->
integrated_quantities[IntegratedQuantitiesEnum::pressure_dilatation];
731 return (-1.0*integrated_pressure_dilatation);
734 template<
int dim,
int nspecies,
int nstate>
737 const double integrated_viscosity_times_deviatoric_strain_rate_tensor_magnitude_sqr = this->
integrated_quantities[IntegratedQuantitiesEnum::viscosity_times_deviatoric_strain_rate_tensor_magnitude_sqr];
738 double deviatoric_strain_rate_tensor_based_dissipation_rate = 0.0;
740 deviatoric_strain_rate_tensor_based_dissipation_rate =
741 this->
navier_stokes_physics->compute_deviatoric_strain_rate_tensor_based_dissipation_rate_from_integrated_viscosity_times_deviatoric_strain_rate_tensor_magnitude_sqr(integrated_viscosity_times_deviatoric_strain_rate_tensor_magnitude_sqr);
743 return deviatoric_strain_rate_tensor_based_dissipation_rate;
746 template<
int dim,
int nspecies,
int nstate>
749 const double integrated_viscosity_times_strain_rate_tensor_magnitude_sqr = this->
integrated_quantities[IntegratedQuantitiesEnum::viscosity_times_strain_rate_tensor_magnitude_sqr];
750 double strain_rate_tensor_based_dissipation_rate = 0.0;
752 strain_rate_tensor_based_dissipation_rate =
753 this->
navier_stokes_physics->compute_strain_rate_tensor_based_dissipation_rate_from_integrated_viscosity_times_strain_rate_tensor_magnitude_sqr(integrated_viscosity_times_strain_rate_tensor_magnitude_sqr);
755 return strain_rate_tensor_based_dissipation_rate;
758 template<
int dim,
int nspecies,
int nstate>
764 template<
int dim,
int nspecies,
int nstate>
771 const unsigned int n_dofs_cell = dg->fe_collection[poly_degree].dofs_per_cell;
772 const unsigned int n_quad_pts = dg->volume_quadrature_collection[poly_degree].size();
773 const unsigned int n_shape_fns = n_dofs_cell / nstate;
776 vol_projection.
build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]);
780 soln_basis.
build_1D_volume_operator(dg->oneD_fe_collection_1state[poly_degree], dg->oneD_quadrature_collection[poly_degree]);
786 std::vector<dealii::types::global_dof_index> dofs_indices (n_dofs_cell);
788 double integrand_numerical_entropy_function=0;
789 double integral_numerical_entropy_function=0;
790 const std::vector<double> &quad_weights = dg->volume_quadrature_collection[poly_degree].get_weights();
792 auto metric_cell = dg->high_order_grid->dof_handler_grid.begin_active();
794 for (
auto cell = dg->dof_handler.begin_active(); cell!= dg->dof_handler.end(); ++cell, ++metric_cell) {
795 if (!cell->is_locally_owned())
continue;
796 cell->get_dof_indices (dofs_indices);
799 const dealii::FESystem<dim> &fe_metric = dg->high_order_grid->fe_system;
800 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
801 const unsigned int n_grid_nodes = n_metric_dofs / dim;
802 std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
803 metric_cell->get_dof_indices (metric_dof_indices);
804 std::array<std::vector<double>,dim> mapping_support_points;
805 for(
int idim=0; idim<dim; idim++){
806 mapping_support_points[idim].resize(n_grid_nodes);
810 const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(dg->max_grid_degree);
811 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
812 const double val = (dg->high_order_grid->volume_nodes[metric_dof_indices[idof]]);
813 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
814 const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
815 const unsigned int igrid_node = index_renumbering[ishape];
816 mapping_support_points[istate][igrid_node] = val;
824 n_quad_pts, n_grid_nodes,
825 mapping_support_points,
827 dg->all_parameters->use_invariant_curl_form);
834 std::array<std::vector<double>,nstate> soln_coeff;
835 for (
unsigned int idof = 0; idof < n_dofs_cell; ++idof) {
836 const unsigned int istate = dg->fe_collection[poly_degree].system_to_component_index(idof).first;
837 const unsigned int ishape = dg->fe_collection[poly_degree].system_to_component_index(idof).second;
839 soln_coeff[istate].resize(n_shape_fns);
841 soln_coeff[istate][ishape] = dg->solution(dofs_indices[idof]);
845 std::array<std::vector<double>,nstate> soln_at_q;
846 for(
int istate=0; istate<nstate; istate++){
847 soln_at_q[istate].resize(n_quad_pts);
854 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
856 std::array<double,nstate> soln_state;
858 for(
int istate=0; istate<nstate; istate++){
859 soln_state[istate] = soln_at_q[istate][iquad];
861 integrand_numerical_entropy_function = this->
navier_stokes_physics->compute_numerical_entropy_function(soln_state);
862 integral_numerical_entropy_function += integrand_numerical_entropy_function * quad_weights[iquad] * metric_oper.
det_Jac_vol[iquad];
866 const double mpi_integrated_numerical_entropy = dealii::Utilities::MPI::sum(integral_numerical_entropy_function, this->
mpi_communicator);
868 return mpi_integrated_numerical_entropy;
872 template <
int dim,
int nspecies,
int nstate>
874 const double current_time,
880 const double next_time = current_time +
time_step;
883 bool is_output_time =
false;
885 is_output_time = current_time == desired_time;
887 is_output_time = ((current_time<=desired_time) && (next_time>desired_time));
902 template <
int dim,
int nspecies,
int nstate>
904 const double FR_entropy_contribution_RRK_solver,
905 const unsigned int current_iteration,
911 if (current_iteration==0) {
922 template <
int dim,
int nspecies,
int nstate>
926 const std::shared_ptr <dealii::TableHandler> unsteady_data_table,
927 const bool do_write_unsteady_data_table_file)
930 const unsigned int current_iteration = ode_solver->current_iteration;
931 const double current_time = ode_solver->current_time;
944 const double relaxation_parameter = ode_solver->relaxation_parameter_RRK_solver;
953 double integrated_angular_momentum = 0.0;
967 this->
add_value_to_data_table(integrated_incompressible_kinetic_energy,
"incompressible_kinetic_energy",unsteady_data_table);
968 this->
add_value_to_data_table(integrated_incompressible_enstrophy,
"incompressible_enstrophy",unsteady_data_table);
969 this->
add_value_to_data_table(integrated_incompressible_palinstrophy,
"incompressible_palinstrophy",unsteady_data_table);
972 if(do_write_unsteady_data_table_file) {
974 unsteady_data_table->write_text(unsteady_data_table_file);
978 this->
pcout <<
" Iter: " << current_iteration
979 <<
" Time: " << current_time
980 <<
" Energy: " << integrated_kinetic_energy
981 <<
" Enstrophy: " << integrated_enstrophy;
983 this->
pcout <<
" eps_vorticity: " << vorticity_based_dissipation_rate
984 <<
" eps_p+eps_strain: " << (pressure_dilatation_based_dissipation_rate + strain_rate_tensor_based_dissipation_rate);
990 this->
pcout <<
" Relaxation Parameter: " << std::setprecision(16) << relaxation_parameter;
992 this->
pcout << std::endl;
995 if(std::isnan(integrated_kinetic_energy)) {
996 this->
pcout <<
" ERROR: Kinetic energy at time " << current_time <<
" is nan." << std::endl;
997 this->
pcout <<
" Consider decreasing the time step / CFL number. Aborting..." << std::endl;
1004 this->
pcout <<
" ERROR: Non-physical behaviour encountered in PeriodicTurbulence." << std::endl;
1005 this->
pcout <<
" --> Integrated kinetic energy has increased from the last time step in a closed system without any external sources." << std::endl;
1006 this->
pcout <<
" ==> Consider decreasing the time step / CFL number. Aborting..." << std::endl;
1007 if(this->
mpi_rank==0) std::abort();
1017 #if PHILIP_DIM!=1 && PHILIP_SPECIES==1 void update_maximum_local_wave_speed(DGBase< dim, nspecies, double > &dg) override
Updates the maximum local wave speed.
const double domain_size
Domain size (length in 1D, area in 2D, and volume in 3D)
FlowCaseType
Selects the flow case to be simulated.
dealii::Tensor< 2, dim, std::vector< real > > metric_cofactor_vol
The volume metric cofactor matrix.
PartialDifferentialEquation pde_type
Store the PDE type to be solved.
double initial_time
Initial time at which we initialize the ODE solver with.
bool check_nonphysical_flow_case_behavior
For TGV, flag to check if non-physical case dependant behaviour is encounted.
FlowCaseType flow_case_type
Selected FlowCaseType from the input file.
const Parameters::AllParameters all_param
All parameters.
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...
double courant_friedrichs_lewy_number
Courant-Friedrichs-Lewy (CFL) number for constant time step.
bool adaptive_time_step
Flag for computing the time step on the fly.
const bool output_vorticity_magnitude_field_in_addition_to_velocity
Flag for outputting vorticity magnitude field in addition to velocity field at fixed times...
void compute_and_update_integrated_quantities(DGBase< dim, nspecies, double > &dg)
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
const bool output_viscosity_field_in_addition_to_velocity
Flag for outputting viscosity field in addition to velocity field at fixed times. ...
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
double constant_time_step
Constant time step.
double mach_inf
Mach number at infinity.
bool restart_computation_from_file
Restart computation from restart file.
const bool do_compute_angular_momentum
Flag to compute angular momentum.
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.
virtual void display_additional_flow_case_specific_parameters() const override
Display additional more specific flow case parameters.
PartialDifferentialEquation
Possible Partial Differential Equations to solve.
const double domain_left
Domain left-boundary value for generating the grid.
const unsigned int output_velocity_number_of_subvisions
Number of subdivisions to apply when writting the velocity field at equidistant nodes.
Files for the baseline physics.
double get_adaptive_time_step(std::shared_ptr< DGBase< dim, nspecies, double >> dg) const override
Function to compute the adaptive time step.
double cumulative_numerical_entropy_change_FRcorrected
Cumulative change in numerical entropy.
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.
std::array< double, NUMBER_OF_INTEGRATED_QUANTITIES > integrated_quantities
Array for storing the integrated quantities; done for computational efficiency.
std::shared_ptr< Physics::NavierStokes< dim, nspecies, dim+2, double > > navier_stokes_physics
Pointer to Navier-Stokes physics object for computing things on the fly.
bool is_viscous_flow
Identifies if viscous flow; initialized as true.
dealii::QGauss< 0 > oneD_face_quadrature
1D surface quadrature is always one single point for all poly degrees.
std::shared_ptr< HighOrderGrid< dim, real, MeshType > > high_order_grid
High order grid that will provide the MappingFEField.
std::string flow_field_quantity_filename_prefix
Flow field quantity filename prefix.
double reynolds_number_inf
Farfield Reynolds number.
EulerParam euler_param
Contains parameters for the Euler equations non-dimensionalization.
double get_strain_rate_tensor_based_dissipation_rate() const
ODESolverEnum
Types of ODE solver.
unsigned int poly_degree
Polynomial order (P) of the basis functions for DG.
Main parameter class that contains the various other sub-parameter classes.
bool do_calculate_numerical_entropy
For TGV, flag to calculate and write numerical entropy.
bool do_calculate_numerical_entropy
Identifies if numerical entropy should be calculated; initialized as false.
dealii::Table< 1, double > output_velocity_field_times
Times at which to output the velocity field.
std::string output_velocity_field_times_string
String of velocity field output times.
std::vector< real > det_Jac_vol
The determinant of the metric Jacobian at volume cubature nodes.
dealii::DoFHandler< dim > dof_handler
Finite Element Collection to represent the high-order grid.
double initial_numerical_entropy_abs
Numerical entropy at initial time.
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 > &mapping_basis, const bool use_invariant_curl_form=false)
Builds the volume metric operators.
ODESolverParam ode_solver_param
Contains parameters for ODE solver.
const std::string unsteady_data_table_filename_with_extension
Filename (with extension) for the unsteady data table.
NavierStokesParam navier_stokes_param
Contains parameters for the Navier-Stokes equations non-dimensionalization.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
Base metric operators class that stores functions used in both the volume and on surface.
double previous_numerical_entropy
Numerical entropy at previous timestep.
dealii::FullMatrix< double > oneD_vol_operator
Stores the one dimensional volume operator.
The mapping shape functions evaluated at the desired nodes (facet set included in volume grid nodes f...
double get_integrated_incompressible_enstrophy() const
Gets the nondimensional integrated incompressible enstrophy given a DG object from dg->solution...
double compute_angular_momentum(const dealii::Point< dim > position, const dealii::Tensor< 1, 3, double > vorticity) const
Function to compute the angular momentum.
const bool output_solution_at_exact_fixed_times
Flag for outputting the solution at exact fixed times by decreasing the time step on the fly...
PeriodicTurbulence(const Parameters::AllParameters *const parameters_input)
Constructor.
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
double get_integrated_kinetic_energy() const
double time_step
Current time step.
dealii::FullMatrix< double > oneD_grad_operator
Stores the one dimensional gradient operator.
double get_numerical_entropy(const std::shared_ptr< DGBase< dim, nspecies, double >>) const
Retrieves cumulative_numerical_entropy_change_FRcorrected.
double get_integrated_incompressible_kinetic_energy() const
Gets the nondimensional integrated incompressible kinetic energy given a DG object from dg->solution...
void update_numerical_entropy(const double FR_entropy_contribution_RRK_solver, const unsigned int current_iteration, const std::shared_ptr< DGBase< dim, nspecies, double >> dg)
Update numerical entropy variables.
double integrated_kinetic_energy_at_previous_time_step
Integrated kinetic energy over the domain at previous time step; used for ensuring a physically consi...
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution.
const std::string output_flow_field_files_directory_name
Directory for writting flow field files.
const int number_of_cells_per_direction
Number of cells per direction for the grid.
double get_integrated_angular_momentum() const
Gets the nondimensional integrated angular momentum given a DG object from dg->solution.
const unsigned int number_of_times_to_output_velocity_field
Number of times to output the velocity field.
void output_velocity_field(std::shared_ptr< DGBase< dim, nspecies, double >> dg, const unsigned int output_file_index, const double current_time) const
Output the velocity field to file.
const bool output_density_field_in_addition_to_velocity
Flag for outputting density field in addition to velocity field at fixed times.
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.
const unsigned int max_degree
Maximum degree used for p-refi1nement.
static std::shared_ptr< PhysicsBase< dim, nspecies, nstate, real > > create_Physics(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ModelBase< dim, nspecies, nstate, real > > model_input=nullptr)
Factory to return the correct physics given input file.
void output_velocity_field_if_current_time_is_output_time(const double current_time, const std::shared_ptr< DGBase< dim, nspecies, double >> dg)
Outputs the velocity field if the current time is an output time for the velocity field...
const MPI_Comm mpi_communicator
MPI communicator.
virtual void compute_unsteady_data_and_write_to_table(const std::shared_ptr< ODE::ODESolverBase< dim, nspecies, double >> ode_solver, const std::shared_ptr< DGBase< dim, nspecies, double >> dg, const std::shared_ptr< dealii::TableHandler > unsteady_data_table, const bool do_write_unsteady_data_table_file) override
Compute the desired unsteady data and write it to a table.
dealii::ConditionalOStream pcout
ConditionalOStream.
static const int NUMBER_OF_INTEGRATED_QUANTITIES
bool is_taylor_green_vortex
Identifies if taylor green vortex case; initialized as false.
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.
std::shared_ptr< dealii::TableHandler > exact_output_times_of_velocity_field_files_table
Data table storing the exact output times for the velocity field files.
double get_integrated_incompressible_palinstrophy() const
Gets the nondimensional integrated incompressible palinstrophy given a DG object from dg->solution...
const dealii::hp::FECollection< dim > fe_collection
Finite Element Collection for p-finite-element to represent the solution.
bool use_relaxation_runge_kutta
Use relaxation runge-kutta.
double get_time_step() const
Getter for time step.
double get_integrated_enstrophy() const
DGBase is independent of the number of state variables.
double get_constant_time_step(std::shared_ptr< DGBase< dim, nspecies, double >> dg) const override
Function to compute the constant time step.
double get_vorticity_based_dissipation_rate() const
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...
bool is_decaying_homogeneous_isotropic_turbulence
Identified if DHIT case; initialized as false.
virtual unsigned int get_number_of_degrees_of_freedom_per_state_from_poly_degree(const unsigned int poly_degree_input) const
Get the number of degrees of freedom per state from a given poly degree.
const int mpi_rank
MPI rank.
dealii::Tensor< 1, dim, std::vector< real > > flux_nodes_vol
Stores the physical volume flux nodes.
double get_deviatoric_strain_rate_tensor_based_dissipation_rate() const
Navier-Stokes equations. Derived from Euler for the convective terms, which is derived from PhysicsBa...
unsigned int index_of_current_desired_time_to_output_velocity_field
Index of current desired time to output velocity field.
void build_1D_gradient_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
Projection operator corresponding to basis functions onto M-norm (L2).
double get_pressure_dilatation_based_dissipation_rate() const
const double domain_right
Domain right-boundary value for generating the grid.
double compute_current_integrated_numerical_entropy(const std::shared_ptr< DGBase< dim, nspecies, double >> dg) const
Calculate numerical entropy by matrix-vector product.
virtual void display_grid_parameters() const
Display grid parameters.
const bool output_velocity_field_at_fixed_times
Flag for outputting velocity field at fixed times.