1 #include <deal.II/base/tensor.h> 2 #include <deal.II/fe/fe_values.h> 3 #include <deal.II/dofs/dof_handler.h> 4 #include <deal.II/dofs/dof_tools.h> 5 #include <deal.II/dofs/dof_renumbering.h> 6 #include <deal.II/dofs/dof_accessor.h> 7 #include <deal.II/lac/vector.h> 9 #include <deal.II/fe/fe_dgq.h> 11 #include "strong_dg_les.hpp" 15 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
18 const unsigned int degree,
19 const unsigned int max_degree_input,
20 const unsigned int grid_degree_input,
21 const std::shared_ptr<Triangulation> triangulation_input)
22 :
DGStrong<dim,nspecies,nstate,real,MeshType>::
DGStrong(parameters_input, degree, max_degree_input, grid_degree_input, triangulation_input)
24 if constexpr (dim+2==
nstate) {
30 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
33 pcout <<
"Destructing DGStrongLES..." << std::endl;
36 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
45 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
60 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
65 dealii::hp::MappingCollection<dim> mapping_collection(mapping);
66 const dealii::UpdateFlags update_flags = dealii::update_values | dealii::update_JxW_values;
67 dealii::hp::FEValues<dim,dim> fe_values_collection_volume (mapping_collection,
73 for (
auto cell : this->
dof_handler.active_cell_iterators()) {
74 if (!(cell->is_locally_owned() || cell->is_ghost()))
continue;
77 const int i_fele = cell->active_fe_index();
78 const int i_quad = i_fele;
80 fe_values_collection_volume.reinit(cell, i_quad, i_mapp, i_fele);
81 const dealii::FEValues<dim,dim> &fe_values_volume = fe_values_collection_volume.get_present_fe_values();
84 const dealii::FESystem<dim,dim> &fe_high = this->
fe_collection[i_fele];
85 const unsigned int cell_poly_degree = fe_high.tensor_degree();
88 const dealii::Quadrature<dim> &quadrature = fe_values_volume.get_quadrature();
89 const unsigned int n_quad_pts = quadrature.size();
90 const std::vector<real> &JxW = fe_values_volume.get_JxW_values();
91 real cell_volume_estimate = 0.0;
92 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
93 cell_volume_estimate = cell_volume_estimate + JxW[iquad];
98 const dealii::types::global_dof_index cell_index = cell->active_cell_index();
103 this->
pde_model_double->cellwise_poly_degree[cell_index] = cell_poly_degree;
110 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
116 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
119 const unsigned int degree,
120 const unsigned int max_degree_input,
121 const unsigned int grid_degree_input,
122 const std::shared_ptr<Triangulation> triangulation_input)
123 :
DGStrongLES<dim,nspecies,
nstate,real,MeshType>::
DGStrongLES(parameters_input, degree, max_degree_input, grid_degree_input, triangulation_input)
129 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
132 pcout <<
"Destructing DGStrongLES_ShearImproved..." << std::endl;
135 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
147 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
151 int overintegrate = 10;
154 dealii::QGauss<dim> quad_extra(this->
max_degree+1+overintegrate);
155 dealii::QGauss<1> quad_extra_1D(this->
max_degree+1+overintegrate);
157 const unsigned int n_quad_pts = quad_extra.size();
158 const unsigned int grid_degree = this->
high_order_grid->fe_system.tensor_degree();
159 const unsigned int poly_degree = this->
max_degree;
169 const std::vector<double> &quad_weights = quad_extra.get_weights();
176 const unsigned int n_shape_fns = n_dofs /
nstate;
177 std::vector<dealii::types::global_dof_index> dofs_indices (n_dofs);
178 auto metric_cell = this->
high_order_grid->dof_handler_grid.begin_active();
180 for (
auto cell = this->
dof_handler.begin_active(); cell!= this->
dof_handler.end(); ++cell, ++metric_cell) {
181 if (!(cell->is_locally_owned() || cell->is_ghost()))
continue;
182 cell->get_dof_indices (dofs_indices);
185 dealii::Tensor<2,dim,double> cell_strain_rate_tensor_integral;
186 for (
int d1=0; d1<dim; ++d1) {
187 for (
int d2=0; d2<dim; ++d2) {
188 cell_strain_rate_tensor_integral[d1][d2] = 0.0;
193 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
194 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
195 const unsigned int n_grid_nodes = n_metric_dofs / dim;
196 std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
197 metric_cell->get_dof_indices (metric_dof_indices);
198 std::array<std::vector<double>,dim> mapping_support_points;
199 for(
int idim=0; idim<dim; idim++){
200 mapping_support_points[idim].resize(n_grid_nodes);
204 const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(grid_degree);
205 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
206 const double val = (this->
high_order_grid->volume_nodes[metric_dof_indices[idof]]);
207 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
208 const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
209 const unsigned int igrid_node = index_renumbering[ishape];
210 mapping_support_points[istate][igrid_node] = val;
218 n_quad_pts, n_grid_nodes,
219 mapping_support_points,
228 std::array<std::vector<double>,
nstate> soln_coeff;
229 for (
unsigned int idof = 0; idof <
n_dofs; ++idof) {
230 const unsigned int istate = this->
fe_collection[poly_degree].system_to_component_index(idof).first;
231 const unsigned int ishape = this->
fe_collection[poly_degree].system_to_component_index(idof).second;
233 soln_coeff[istate].resize(n_shape_fns);
236 soln_coeff[istate][ishape] = this->
solution(dofs_indices[idof]);
240 std::array<std::vector<double>,
nstate> soln_at_q_vect;
241 std::array<dealii::Tensor<1,dim,std::vector<double>>,
nstate> soln_grad_at_q_vect;
242 for(
int istate=0; istate<
nstate; istate++){
243 soln_at_q_vect[istate].resize(n_quad_pts);
248 dealii::Tensor<1,dim,std::vector<double>> ref_gradient_basis_fns_times_soln;
249 for(
int idim=0; idim<dim; idim++){
250 ref_gradient_basis_fns_times_soln[idim].resize(n_quad_pts);
251 soln_grad_at_q_vect[istate][idim].resize(n_quad_pts);
258 for(
int idim=0; idim<dim; idim++){
259 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
260 for(
int jdim=0; jdim<dim; jdim++){
262 soln_grad_at_q_vect[istate][idim][iquad] += metric_oper.
metric_cofactor_vol[idim][jdim][iquad]
263 * ref_gradient_basis_fns_times_soln[jdim][iquad]
271 std::array<std::vector<real>,nstate> legendre_soln_at_q_vect;
272 std::array<dealii::Tensor<1,dim,std::vector<real>>,nstate> legendre_aux_soln_at_q_vect;
279 std::array<std::vector<real>,nstate> primitive_soln_at_q;
280 std::array<dealii::Tensor<1,dim,std::vector<real>>,nstate> primitive_aux_soln_at_q;
282 for(
int istate=0; istate<
nstate; istate++){
283 primitive_soln_at_q[istate].resize(n_quad_pts);
284 for(
int idim=0; idim<dim; idim++){
285 primitive_aux_soln_at_q[istate][idim].resize(n_quad_pts);
289 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
291 std::array<real,nstate> soln_state;
292 std::array<dealii::Tensor<1,dim,real>,nstate> aux_soln_state;
293 for(
int istate=0; istate<
nstate; istate++){
294 soln_state[istate] = soln_at_q_vect[istate][iquad];
295 for(
int idim=0; idim<dim; idim++){
296 aux_soln_state[istate][idim] = soln_grad_at_q_vect[istate][idim][iquad];
300 std::array<real,nstate> primitive_soln_state = this->
pde_physics_double->convert_conservative_to_primitive(soln_state);
301 std::array<dealii::Tensor<1,dim,real>,nstate> primitive_aux_soln_state = this->
pde_physics_double->convert_conservative_gradient_to_primitive_gradient(soln_state,aux_soln_state);
303 for(
int istate=0; istate<
nstate; istate++){
304 primitive_soln_at_q[istate][iquad] = primitive_soln_state[istate];
305 for(
int idim=0; idim<dim; idim++){
306 primitive_aux_soln_at_q[istate][idim][iquad] = primitive_aux_soln_state[istate][idim];
315 std::array<std::vector<real>,nstate> primitive_legendre_soln_at_q;
316 std::array<dealii::Tensor<1,dim,std::vector<real>>,nstate> primitive_legendre_aux_soln_at_q;
320 dealii::FE_DGQLegendre<1,1> legendre_poly_1D(poly_degree);
328 for(
int istate=0; istate<
nstate; istate++){
333 std::vector<real> legendre_soln_coeff(n_shape_fns);
334 legendre_soln_basis_projection_oper.
matrix_vector_mult_1D(primitive_soln_at_q[istate], legendre_soln_coeff,
338 for(
unsigned int ishape=0; ishape<n_shape_fns; ishape++){
339 if(ishape < p_min_filtered){
340 legendre_soln_coeff[ishape] = 0.0;
345 primitive_legendre_soln_at_q[istate].resize(n_quad_pts);
350 dealii::Tensor<1,dim,std::vector<double>> ref_gradient_basis_fns_times_soln;
351 for(
int idim=0; idim<dim; idim++){
352 ref_gradient_basis_fns_times_soln[idim].resize(n_quad_pts);
353 primitive_legendre_aux_soln_at_q[istate][idim].resize(n_quad_pts);
360 for(
int idim=0; idim<dim; idim++){
361 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
362 for(
int jdim=0; jdim<dim; jdim++){
364 primitive_legendre_aux_soln_at_q[istate][idim][iquad] += metric_oper.
metric_cofactor_vol[idim][jdim][iquad]
365 * ref_gradient_basis_fns_times_soln[jdim][iquad]
376 for(
int istate=0; istate<
nstate; istate++){
377 legendre_soln_at_q_vect[istate].resize(n_quad_pts);
378 for(
int idim=0; idim<dim; idim++){
379 legendre_aux_soln_at_q_vect[istate][idim].resize(n_quad_pts);
383 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
385 std::array<real,nstate> primitive_legendre_soln_state;
386 std::array<dealii::Tensor<1,dim,real>,nstate> primitive_legendre_aux_soln_state;
387 for(
int istate=0; istate<
nstate; istate++){
388 primitive_legendre_soln_state[istate] = primitive_legendre_soln_at_q[istate][iquad];
389 for(
int idim=0; idim<dim; idim++){
390 primitive_legendre_aux_soln_state[istate][idim] = primitive_legendre_aux_soln_at_q[istate][idim][iquad];
394 std::array<real,nstate> legendre_soln_state = this->
pde_physics_double->convert_primitive_to_conservative(primitive_legendre_soln_state);
395 std::array<dealii::Tensor<1,dim,real>,nstate> legendre_aux_soln_state = this->
pde_physics_double->convert_primitive_gradient_to_conservative_gradient(primitive_legendre_soln_state,primitive_legendre_aux_soln_state);
397 for(
int istate=0; istate<
nstate; istate++){
398 legendre_soln_at_q_vect[istate][iquad] = legendre_soln_state[istate];
399 for(
int idim=0; idim<dim; idim++){
400 legendre_aux_soln_at_q_vect[istate][idim][iquad] = legendre_aux_soln_state[istate][idim];
407 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
409 std::array<double,nstate> soln_at_q;
410 std::array<dealii::Tensor<1,dim,double>,nstate> soln_grad_at_q;
412 for(
int istate=0; istate<
nstate; istate++){
414 else soln_at_q[istate] = soln_at_q_vect[istate][iquad];
415 for(
int idim=0; idim<dim; idim++){
417 else soln_grad_at_q[istate][idim] = soln_grad_at_q_vect[istate][idim][iquad];
422 const dealii::Tensor<2,dim,double> strain_rate_tensor = this->
pde_model_les_double->navier_stokes_physics->compute_strain_rate_tensor_from_conservative(soln_at_q,soln_grad_at_q);
423 for (
int d1=0; d1<dim; ++d1) {
424 for (
int d2=0; d2<dim; ++d2) {
425 cell_strain_rate_tensor_integral[d1][d2] += strain_rate_tensor[d1][d2] * quad_weights[iquad] * metric_oper.
det_Jac_vol[iquad];
431 const dealii::types::global_dof_index cell_index = cell->active_cell_index();
433 dealii::Tensor<2,dim,double> cell_mean_strain_rate_tensor;
434 for (
int d1=0; d1<dim; ++d1) {
435 for (
int d2=0; d2<dim; ++d2) {
436 cell_mean_strain_rate_tensor[d1][d2] = cell_strain_rate_tensor_integral[d1][d2];
437 cell_mean_strain_rate_tensor[d1][d2] /= this->
pde_model_double->cellwise_volume[cell_index];
441 const double cell_mean_strain_rate_tensor_magnitude = this->
pde_model_les_double->navier_stokes_physics->get_tensor_magnitude(cell_mean_strain_rate_tensor);
442 this->
pde_model_double->cellwise_mean_strain_rate_tensor_magnitude[cell_index] = cell_mean_strain_rate_tensor_magnitude;
445 this->
pde_model_double->cellwise_mean_strain_rate_tensor_magnitude.update_ghost_values();
448 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
451 const unsigned int degree,
452 const unsigned int max_degree_input,
453 const unsigned int grid_degree_input,
454 const std::shared_ptr<Triangulation> triangulation_input)
455 :
DGStrongLES<dim,nspecies,
nstate,real,MeshType>::
DGStrongLES(parameters_input, degree, max_degree_input, grid_degree_input, triangulation_input)
456 , dynamic_smagorinsky_model_constant_clipping_limit(this->
all_parameters->physics_model_param.dynamic_smagorinsky_model_constant_clipping_limit)
462 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
465 pcout <<
"Destructing DGStrongLES_DynamicSmagorinsky..." << std::endl;
468 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
480 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
484 int overintegrate = 10;
487 dealii::QGauss<dim> quad_extra(this->
max_degree+1+overintegrate);
488 dealii::QGauss<1> quad_extra_1D(this->
max_degree+1+overintegrate);
490 const unsigned int n_quad_pts = quad_extra.size();
491 const unsigned int grid_degree = this->
high_order_grid->fe_system.tensor_degree();
492 const unsigned int poly_degree = this->
max_degree;
502 const std::vector<double> &quad_weights = quad_extra.get_weights();
509 const unsigned int n_shape_fns = n_dofs /
nstate;
510 std::vector<dealii::types::global_dof_index> dofs_indices (n_dofs);
511 auto metric_cell = this->
high_order_grid->dof_handler_grid.begin_active();
513 for (
auto cell = this->
dof_handler.begin_active(); cell!= this->
dof_handler.end(); ++cell, ++metric_cell) {
514 if (!(cell->is_locally_owned() || cell->is_ghost()))
continue;
515 cell->get_dof_indices (dofs_indices);
518 real cell_matrix_L_times_matrix_M_integral = 0.0;
519 real cell_matrix_M_times_matrix_M_integral = 0.0;
522 const dealii::FESystem<dim> &fe_metric = this->
high_order_grid->fe_system;
523 const unsigned int n_metric_dofs = fe_metric.dofs_per_cell;
524 const unsigned int n_grid_nodes = n_metric_dofs / dim;
525 std::vector<dealii::types::global_dof_index> metric_dof_indices(n_metric_dofs);
526 metric_cell->get_dof_indices (metric_dof_indices);
527 std::array<std::vector<double>,dim> mapping_support_points;
528 for(
int idim=0; idim<dim; idim++){
529 mapping_support_points[idim].resize(n_grid_nodes);
533 const std::vector<unsigned int > &index_renumbering = dealii::FETools::hierarchic_to_lexicographic_numbering<dim>(grid_degree);
534 for (
unsigned int idof = 0; idof< n_metric_dofs; ++idof) {
535 const double val = (this->
high_order_grid->volume_nodes[metric_dof_indices[idof]]);
536 const unsigned int istate = fe_metric.system_to_component_index(idof).first;
537 const unsigned int ishape = fe_metric.system_to_component_index(idof).second;
538 const unsigned int igrid_node = index_renumbering[ishape];
539 mapping_support_points[istate][igrid_node] = val;
547 n_quad_pts, n_grid_nodes,
548 mapping_support_points,
557 std::array<std::vector<double>,
nstate> soln_coeff;
558 for (
unsigned int idof = 0; idof <
n_dofs; ++idof) {
559 const unsigned int istate = this->
fe_collection[poly_degree].system_to_component_index(idof).first;
560 const unsigned int ishape = this->
fe_collection[poly_degree].system_to_component_index(idof).second;
562 soln_coeff[istate].resize(n_shape_fns);
565 soln_coeff[istate][ishape] = this->
solution(dofs_indices[idof]);
569 std::array<std::vector<double>,
nstate> soln_at_q_vect;
570 std::array<dealii::Tensor<1,dim,std::vector<double>>,
nstate> soln_grad_at_q_vect;
571 for(
int istate=0; istate<
nstate; istate++){
572 soln_at_q_vect[istate].resize(n_quad_pts);
577 dealii::Tensor<1,dim,std::vector<double>> ref_gradient_basis_fns_times_soln;
578 for(
int idim=0; idim<dim; idim++){
579 ref_gradient_basis_fns_times_soln[idim].resize(n_quad_pts);
580 soln_grad_at_q_vect[istate][idim].resize(n_quad_pts);
587 for(
int idim=0; idim<dim; idim++){
588 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
589 for(
int jdim=0; jdim<dim; jdim++){
591 soln_grad_at_q_vect[istate][idim][iquad] += metric_oper.
metric_cofactor_vol[idim][jdim][iquad]
592 * ref_gradient_basis_fns_times_soln[jdim][iquad]
600 std::array<std::vector<real>,nstate> legendre_soln_at_q_vect;
601 std::array<dealii::Tensor<1,dim,std::vector<real>>,nstate> legendre_aux_soln_at_q_vect;
602 dealii::Tensor<2,dim,std::vector<real>> legendre_matrix_L_component_at_q_vect;
603 dealii::Tensor<2,dim,std::vector<real>> legendre_matrix_M_component_at_q_vect;
609 std::array<std::vector<real>,nstate> primitive_soln_at_q;
610 std::array<dealii::Tensor<1,dim,std::vector<real>>,nstate> primitive_aux_soln_at_q;
611 dealii::Tensor<2,dim,std::vector<real>> matrix_L_component_at_q;
612 dealii::Tensor<2,dim,std::vector<real>> matrix_M_component_at_q;
615 for(
int istate=0; istate<
nstate; istate++){
616 primitive_soln_at_q[istate].resize(n_quad_pts);
617 for(
int idim=0; idim<dim; idim++){
618 primitive_aux_soln_at_q[istate][idim].resize(n_quad_pts);
621 for(
int jdim=0; jdim<dim; jdim++){
622 for(
int idim=0; idim<dim; idim++){
623 matrix_L_component_at_q[jdim][idim].resize(n_quad_pts);
624 matrix_M_component_at_q[jdim][idim].resize(n_quad_pts);
629 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
631 std::array<real,nstate> soln_state;
632 std::array<dealii::Tensor<1,dim,real>,nstate> aux_soln_state;
633 for(
int istate=0; istate<
nstate; istate++){
634 soln_state[istate] = soln_at_q_vect[istate][iquad];
635 for(
int idim=0; idim<dim; idim++){
636 aux_soln_state[istate][idim] = soln_grad_at_q_vect[istate][idim][iquad];
640 const std::array<real,nstate> primitive_soln_state = this->
pde_physics_double->convert_conservative_to_primitive(soln_state);
641 const std::array<dealii::Tensor<1,dim,real>,nstate> primitive_aux_soln_state = this->
pde_physics_double->convert_conservative_gradient_to_primitive_gradient(soln_state,aux_soln_state);
643 for(
int istate=0; istate<
nstate; istate++){
644 primitive_soln_at_q[istate][iquad] = primitive_soln_state[istate];
645 for(
int idim=0; idim<dim; idim++){
646 primitive_aux_soln_at_q[istate][idim][iquad] = primitive_aux_soln_state[istate][idim];
651 const dealii::Tensor<2,dim,real> matrix_L_component_state = this->
pde_model_les_double->navier_stokes_physics->compute_germano_idendity_matrix_L_component(soln_state);
653 for(
int jdim=0; jdim<dim; jdim++){
654 for(
int idim=0; idim<dim; idim++){
655 matrix_L_component_at_q[jdim][idim][iquad] = matrix_L_component_state[jdim][idim];
659 const dealii::Tensor<2,dim,real> matrix_M_component_state = this->
pde_model_les_double->navier_stokes_physics->compute_germano_identity_matrix_M_component(soln_state,aux_soln_state);
661 for(
int jdim=0; jdim<dim; jdim++){
662 for(
int idim=0; idim<dim; idim++){
663 matrix_M_component_at_q[jdim][idim][iquad] = matrix_M_component_state[jdim][idim];
672 std::array<std::vector<real>,nstate> primitive_legendre_soln_at_q;
673 std::array<dealii::Tensor<1,dim,std::vector<real>>,nstate> primitive_legendre_aux_soln_at_q;
676 dealii::FE_DGQLegendre<1,1> legendre_poly_1D(poly_degree);
684 for(
int istate=0; istate<
nstate; istate++){
689 std::vector<real> legendre_soln_coeff(n_shape_fns);
690 legendre_soln_basis_projection_oper.
matrix_vector_mult_1D(primitive_soln_at_q[istate], legendre_soln_coeff,
693 if((istate!=0 && istate!=(nstate-1))) {
694 for(
unsigned int ishape=0; ishape<n_shape_fns; ishape++){
695 if(ishape < p_min_filtered){
696 legendre_soln_coeff[ishape] = 0.0;
701 primitive_legendre_soln_at_q[istate].resize(n_quad_pts);
706 dealii::Tensor<1,dim,std::vector<double>> ref_gradient_basis_fns_times_soln;
707 for(
int idim=0; idim<dim; idim++){
708 ref_gradient_basis_fns_times_soln[idim].resize(n_quad_pts);
709 primitive_legendre_aux_soln_at_q[istate][idim].resize(n_quad_pts);
716 for(
int idim=0; idim<dim; idim++){
717 for(
unsigned int iquad=0; iquad<n_quad_pts; iquad++){
718 for(
int jdim=0; jdim<dim; jdim++){
720 primitive_legendre_aux_soln_at_q[istate][idim][iquad] += metric_oper.
metric_cofactor_vol[idim][jdim][iquad]
721 * ref_gradient_basis_fns_times_soln[jdim][iquad]
734 dealii::Tensor<2,dim,std::vector<real>> legendre_matrix_L_component_at_q;
735 dealii::Tensor<2,dim,std::vector<real>> legendre_matrix_M_component_at_q;
736 for(
int jdim=0; jdim<dim; jdim++){
737 dealii::Tensor<1,dim,std::vector<real>> legendre_matrix_L_component_coeff;
738 dealii::Tensor<1,dim,std::vector<real>> legendre_matrix_M_component_coeff;
739 for(
int idim=0; idim<dim; idim++){
741 legendre_matrix_L_component_coeff[idim].resize(n_shape_fns);
742 legendre_soln_basis_projection_oper.
matrix_vector_mult_1D(matrix_L_component_at_q[jdim][idim], legendre_matrix_L_component_coeff[idim],
744 legendre_matrix_M_component_coeff[idim].resize(n_shape_fns);
745 legendre_soln_basis_projection_oper.
matrix_vector_mult_1D(matrix_M_component_at_q[jdim][idim], legendre_matrix_M_component_coeff[idim],
749 for(
unsigned int ishape=0; ishape<n_shape_fns; ishape++){
750 if(ishape < p_min_filtered){
751 legendre_matrix_L_component_coeff[idim][ishape] = 0.0;
752 legendre_matrix_M_component_coeff[idim][ishape] = 0.0;
758 legendre_matrix_L_component_at_q[jdim][idim].resize(n_quad_pts);
759 legendre_soln_basis.
matrix_vector_mult_1D(legendre_matrix_L_component_coeff[idim], legendre_matrix_L_component_at_q[jdim][idim],
761 legendre_matrix_M_component_at_q[jdim][idim].resize(n_quad_pts);
762 legendre_soln_basis.
matrix_vector_mult_1D(legendre_matrix_M_component_coeff[idim], legendre_matrix_M_component_at_q[jdim][idim],
773 for(
int istate=0; istate<
nstate; istate++){
774 legendre_soln_at_q_vect[istate].resize(n_quad_pts);
775 for(
int idim=0; idim<dim; idim++){
776 legendre_aux_soln_at_q_vect[istate][idim].resize(n_quad_pts);
779 for(
int jdim=0; jdim<dim; jdim++){
780 for(
int idim=0; idim<dim; idim++){
781 legendre_matrix_L_component_at_q_vect[jdim][idim].resize(n_quad_pts);
782 legendre_matrix_M_component_at_q_vect[jdim][idim].resize(n_quad_pts);
786 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
788 std::array<real,nstate> primitive_legendre_soln_state;
789 std::array<dealii::Tensor<1,dim,real>,nstate> primitive_legendre_aux_soln_state;
790 for(
int istate=0; istate<
nstate; istate++){
791 primitive_legendre_soln_state[istate] = primitive_legendre_soln_at_q[istate][iquad];
792 for(
int idim=0; idim<dim; idim++){
793 primitive_legendre_aux_soln_state[istate][idim] = primitive_legendre_aux_soln_at_q[istate][idim][iquad];
797 std::array<real,nstate> legendre_soln_state = this->
pde_physics_double->convert_primitive_to_conservative(primitive_legendre_soln_state);
798 std::array<dealii::Tensor<1,dim,real>,nstate> legendre_aux_soln_state = this->
pde_physics_double->convert_primitive_gradient_to_conservative_gradient(primitive_legendre_soln_state,primitive_legendre_aux_soln_state);
800 for(
int istate=0; istate<
nstate; istate++){
801 legendre_soln_at_q_vect[istate][iquad] = legendre_soln_state[istate];
802 for(
int idim=0; idim<dim; idim++){
803 legendre_aux_soln_at_q_vect[istate][idim][iquad] = legendre_aux_soln_state[istate][idim];
806 for(
int jdim=0; jdim<dim; jdim++){
807 for(
int idim=0; idim<dim; idim++){
808 legendre_matrix_L_component_at_q_vect[jdim][idim][iquad] = legendre_matrix_L_component_at_q[jdim][idim][iquad];
809 legendre_matrix_M_component_at_q_vect[jdim][idim][iquad] = legendre_matrix_M_component_at_q[jdim][idim][iquad];
816 const dealii::types::global_dof_index cell_index = cell->active_cell_index();
821 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
823 std::array<double,nstate> soln_at_q;
824 std::array<dealii::Tensor<1,dim,double>,nstate> soln_grad_at_q;
825 std::array<double,nstate> filtered_soln_at_q;
826 std::array<dealii::Tensor<1,dim,double>,nstate> filtered_soln_grad_at_q;
828 for(
int istate=0; istate<
nstate; istate++){
829 filtered_soln_at_q[istate] = legendre_soln_at_q_vect[istate][iquad];
830 soln_at_q[istate] = soln_at_q_vect[istate][iquad];
831 for(
int idim=0; idim<dim; idim++){
832 filtered_soln_grad_at_q[istate][idim] = legendre_aux_soln_at_q_vect[istate][idim][iquad];
833 soln_grad_at_q[istate][idim] = soln_grad_at_q_vect[istate][idim][iquad];
838 const dealii::Tensor<2,dim,real> matrix_L_component_state_from_filtered_soln = this->
pde_model_les_double->navier_stokes_physics->compute_germano_idendity_matrix_L_component(filtered_soln_at_q);
839 const dealii::Tensor<2,dim,real> matrix_M_component_state_from_filtered_soln = this->
pde_model_les_double->navier_stokes_physics->compute_germano_identity_matrix_M_component(filtered_soln_at_q,filtered_soln_grad_at_q);
841 dealii::Tensor<2,dim,real> filtered_matrix_L_component_state;
842 dealii::Tensor<2,dim,real> filtered_matrix_M_component_state;
843 for(
int jdim=0; jdim<dim; jdim++){
844 for(
int idim=0; idim<dim; idim++){
845 filtered_matrix_L_component_state[jdim][idim] = legendre_matrix_L_component_at_q_vect[jdim][idim][iquad];
846 filtered_matrix_M_component_state[jdim][idim] = legendre_matrix_M_component_at_q_vect[jdim][idim][iquad];
850 dealii::Tensor<2,dim,real> matrix_L;
851 dealii::Tensor<2,dim,real> matrix_M;
852 for (
int d1=0; d1<dim; ++d1) {
853 for (
int d2=0; d2<dim; ++d2) {
854 matrix_L[d1][d2] = filtered_matrix_L_component_state[d1][d2] - matrix_L_component_state_from_filtered_soln[d1][d2];
855 matrix_M[d1][d2] = filter_width*filter_width*filtered_matrix_M_component_state[d1][d2] - test_filter_width*test_filter_width*matrix_M_component_state_from_filtered_soln[d1][d2];
859 const real matrix_L_times_matrix_M = this->
pde_model_les_double->navier_stokes_physics->get_tensor_product_magnitude_sqr(matrix_L,matrix_M);
860 const real matrix_M_times_matrix_M = this->
pde_model_les_double->navier_stokes_physics->get_tensor_product_magnitude_sqr(matrix_M,matrix_M);
862 cell_matrix_L_times_matrix_M_integral += matrix_L_times_matrix_M * quad_weights[iquad] * metric_oper.
det_Jac_vol[iquad];
863 cell_matrix_M_times_matrix_M_integral += matrix_M_times_matrix_M * quad_weights[iquad] * metric_oper.
det_Jac_vol[iquad];
867 const real cell_averaged_matrix_L_times_matrix_M = cell_matrix_L_times_matrix_M_integral/
cell_volume;
868 const real cell_averaged_matrix_M_times_matrix_M = cell_matrix_M_times_matrix_M_integral/
cell_volume;
870 real dynamic_smagorinsky_model_constant = -0.5*cell_averaged_matrix_L_times_matrix_M/cell_averaged_matrix_M_times_matrix_M;
871 if(dynamic_smagorinsky_model_constant < 0.0) {
873 dynamic_smagorinsky_model_constant = 0.0;
878 this->
pde_model_double->dynamic_smagorinsky_model_constant_times_filter_width_sqr[cell_index] = dynamic_smagorinsky_model_constant*filter_width*filter_width;
881 this->
pde_model_double->dynamic_smagorinsky_model_constant_times_filter_width_sqr.update_ghost_values();
884 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
887 const unsigned int degree,
888 const unsigned int max_degree_input,
889 const unsigned int grid_degree_input,
890 const std::shared_ptr<Triangulation> triangulation_input)
891 :
DGStrong<dim,nspecies,
nstate,real,MeshType>::
DGStrong(parameters_input, degree, max_degree_input, grid_degree_input, triangulation_input)
892 , channel_height(parameters_input->flow_solver_param.turbulent_channel_domain_length_y_direction)
893 , half_channel_height(channel_height/2.0)
894 , channel_friction_velocity_reynolds_number(parameters_input->flow_solver_param.turbulent_channel_friction_velocity_reynolds_number)
895 , number_of_cells_x_direction(parameters_input->flow_solver_param.turbulent_channel_number_of_cells_x_direction)
896 , number_of_cells_y_direction(parameters_input->flow_solver_param.turbulent_channel_number_of_cells_y_direction)
897 , number_of_cells_z_direction(parameters_input->flow_solver_param.turbulent_channel_number_of_cells_z_direction)
898 , pi_val(3.141592653589793238)
899 , domain_length_x(parameters_input->flow_solver_param.turbulent_channel_domain_length_x_direction)
900 , domain_length_y(channel_height)
901 , domain_length_z(parameters_input->flow_solver_param.turbulent_channel_domain_length_z_direction)
902 , domain_volume(domain_length_x*domain_length_y*domain_length_z)
903 , channel_bulk_velocity_reynolds_number(pow(0.073, -4.0/7.0)*pow(2.0, 5.0/7.0)*pow(channel_friction_velocity_reynolds_number, 8.0/7.0))
904 , channel_centerline_velocity_reynolds_number(1.28*pow(2.0, -0.0116)*pow(channel_bulk_velocity_reynolds_number,1.0-0.0116))
905 , total_wall_area(2.0*domain_length_x*domain_length_z)
907 if constexpr (dim+2==
nstate) {
912 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
915 pcout <<
"Destructing DGStrong_ChannelFlow..." << std::endl;
918 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
926 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
933 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
936 const int NUMBER_OF_INTEGRATED_QUANTITIES = 2;
937 std::array<double,NUMBER_OF_INTEGRATED_QUANTITIES> integrated_quantities;
939 enum IntegratedQuantitiesEnum {
943 std::array<double,NUMBER_OF_INTEGRATED_QUANTITIES> integral_values;
944 std::fill(integral_values.begin(), integral_values.end(), 0.0);
947 int overintegrate = 10;
948 dealii::QGauss<dim> quad_extra(this->
max_degree+1+overintegrate);
949 dealii::FEValues<dim,dim> fe_values_extra(*(this->
high_order_grid->mapping_fe_field), this->fe_collection[this->max_degree], quad_extra,
950 dealii::update_values | dealii::update_JxW_values | dealii::update_quadrature_points);
952 const unsigned int n_quad_pts = fe_values_extra.n_quadrature_points;
953 std::array<double,nstate> soln_at_q;
956 std::vector<dealii::types::global_dof_index> dofs_indices (fe_values_extra.dofs_per_cell);
957 for (
auto cell : this->
dof_handler.active_cell_iterators()) {
958 if (!cell->is_locally_owned())
continue;
959 fe_values_extra.reinit (cell);
960 cell->get_dof_indices (dofs_indices);
963 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
965 std::fill(soln_at_q.begin(), soln_at_q.end(), 0.0);
971 for (
unsigned int idof=0; idof<fe_values_extra.dofs_per_cell; ++idof) {
972 const unsigned int istate = fe_values_extra.get_fe().system_to_component_index(idof).first;
973 soln_at_q[istate] += this->
solution[dofs_indices[idof]] * fe_values_extra.shape_value_component(idof, iquad, istate);
978 std::array<double,NUMBER_OF_INTEGRATED_QUANTITIES> integrand_values;
979 std::fill(integrand_values.begin(), integrand_values.end(), 0.0);
980 integrand_values[IntegratedQuantitiesEnum::bulk_density] = soln_at_q[0];
981 integrand_values[IntegratedQuantitiesEnum::bulk_mass_flow_rate] = soln_at_q[1];
985 for(
int i_quantity=0; i_quantity<NUMBER_OF_INTEGRATED_QUANTITIES; ++i_quantity) {
986 integral_values[i_quantity] += integrand_values[i_quantity] * fe_values_extra.JxW(iquad);
995 for(
int i_quantity=0; i_quantity<NUMBER_OF_INTEGRATED_QUANTITIES; ++i_quantity) {
996 integrated_quantities[i_quantity] = dealii::Utilities::MPI::sum(integral_values[i_quantity], this->
mpi_communicator);
1000 this->
pde_model_double->bulk_density = integrated_quantities[IntegratedQuantitiesEnum::bulk_density];
1001 this->
pde_model_double->bulk_mass_flow_rate = integrated_quantities[IntegratedQuantitiesEnum::bulk_mass_flow_rate];
1005 template <
int dim,
int nspecies,
int nstate,
typename real,
typename MeshType>
1009 const dealii::UpdateFlags
face_update_flags = dealii::update_values | dealii::update_gradients | dealii::update_quadrature_points | dealii::update_JxW_values | dealii::update_normal_vectors;
1010 double integral_value = 0.0;
1011 double integral_area_value = 0.0;
1014 int overintegrate = 10;
1015 dealii::QGauss<dim-1> quad_extra(this->
max_degree+1+overintegrate);
1016 dealii::FEFaceValues<dim,dim> fe_face_values_extra(*(this->
high_order_grid->mapping_fe_field), this->fe_collection[this->max_degree], quad_extra,
1019 std::array<double,nstate> soln_at_q;
1020 std::array<dealii::Tensor<1,dim,double>,
nstate> soln_grad_at_q;
1022 std::vector<dealii::types::global_dof_index> dofs_indices (fe_face_values_extra.dofs_per_cell);
1023 for (
auto cell : this->
dof_handler.active_cell_iterators()) {
1024 if (!cell->is_locally_owned())
continue;
1026 cell->get_dof_indices (dofs_indices);
1028 for(
unsigned int iface = 0; iface < dealii::GeometryInfo<dim>::faces_per_cell; ++iface){
1029 auto face = cell->face(iface);
1031 if(face->at_boundary()){
1032 const unsigned int boundary_id = face->boundary_id();
1033 if(boundary_id==1001){
1034 fe_face_values_extra.reinit (cell,iface);
1035 const unsigned int n_quad_pts = fe_face_values_extra.n_quadrature_points;
1036 for (
unsigned int iquad=0; iquad<n_quad_pts; ++iquad) {
1037 std::fill(soln_at_q.begin(), soln_at_q.end(), 0.0);
1038 for (
int s=0; s<
nstate; ++s) {
1039 for (
int d=0; d<dim; ++d) {
1040 soln_grad_at_q[s][d] = 0.0;
1043 for (
unsigned int idof=0; idof<fe_face_values_extra.dofs_per_cell; ++idof) {
1044 const unsigned int istate = fe_face_values_extra.get_fe().system_to_component_index(idof).first;
1045 soln_at_q[istate] += this->
solution[dofs_indices[idof]] * fe_face_values_extra.shape_value_component(idof, iquad, istate);
1046 soln_grad_at_q[istate] += this->
solution[dofs_indices[idof]] * fe_face_values_extra.shape_grad_component(idof,iquad,istate);
1049 const dealii::Tensor<1,dim,double> normal_vector = -fe_face_values_extra.normal_vector(iquad);
1050 double integrand_value = this->
pde_model_navier_stokes_double->navier_stokes_physics->compute_wall_shear_stress(soln_at_q,soln_grad_at_q,normal_vector);
1051 integral_value += integrand_value * fe_face_values_extra.JxW(iquad);
1052 integral_area_value += fe_face_values_extra.JxW(iquad);
1058 const double mpi_sum_integral_value = dealii::Utilities::MPI::sum(integral_value, this->
mpi_communicator);
1059 const double mpi_sum_integral_area_value = dealii::Utilities::MPI::sum(integral_area_value, this->
mpi_communicator);
1060 const double averaged_value = mpi_sum_integral_value/mpi_sum_integral_area_value;
1061 return averaged_value;
dealii::Tensor< 2, dim, std::vector< real > > metric_cofactor_vol
The volume metric cofactor matrix.
~DGStrongLES()
Destructor.
void set_bulk_flow_quantities()
< Parallel std::cout that only outputs on mpi_rank==0
virtual void update_cellwise_mean_quantities()
Update the cellwise mean quantities.
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...
DGStrongLES_DynamicSmagorinsky class templated on the number of state variables.
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
dealii::ConditionalOStream pcout
Parallel std::cout that only outputs on mpi_rank==0.
const double domain_volume
Domain volume.
std::shared_ptr< Physics::NavierStokesWithModelSourceTerms< dim, nspecies, nstate, real > > pde_model_navier_stokes_double
Contains the Navier-Stokes with model source terms object.
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.
Files for the baseline physics.
DGStrong_ChannelFlow class templated on the number of state variables.
double get_average_wall_shear_stress() const
computes the average wall shear stress
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.
bool use_invariant_curl_form
Flag to use invariant curl form for metric cofactor operator.
std::shared_ptr< Physics::ModelBase< dim, nspecies, nstate, real > > pde_model_double
Contains the model terms of the PDEType == PhysicsModel with real type.
std::shared_ptr< HighOrderGrid< dim, real, MeshType > > high_order_grid
High order grid that will provide the MappingFEField.
const int nstate
Number of state variables.
dealii::hp::QCollection< dim > volume_quadrature_collection
Finite Element Collection to represent the high-order grid.
Main parameter class that contains the various other sub-parameter classes.
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.
unsigned int n_dofs() const
Number of degrees of freedom.
const bool do_compute_filtered_solution
Flag to compute the filtered solution.
~DGStrongLES_DynamicSmagorinsky()
Destructor.
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.
DGStrong class templated on the number of state variables.
dealii::Vector< double > cell_volume
Time it takes for the maximum wavespeed to cross the cell domain.
DGStrongLES class templated on the number of state variables.
const Parameters::AllParameters *const all_parameters
Pointer to all parameters.
Large Eddy Simulation equations. Derived from Navier-Stokes for modifying the stress tensor and heat ...
MPI_Comm mpi_communicator
MPI communicator.
Base metric operators class that stores functions used in both the volume and on surface.
void allocate_model_variables() override
Allocate the necessary variables declared in src/physics/model.h.
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...
void build_1D_volume_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
void update_model_variables() override
Update the necessary variables declared in src/physics/model.h.
const bool apply_modal_high_pass_filter_on_filtered_solution
Flag to apply modal high pass filter on the filtered solution.
DGStrongLES_ShearImproved class templated on the number of state variables.
const double dynamic_smagorinsky_model_constant_clipping_limit
Clipping limit for the Dynamic Smagorinsky model constant.
const double half_channel_height
Half channel height.
void allocate_model_variables() override
Allocate the necessary variables declared in src/physics/model.h.
dealii::FullMatrix< double > oneD_grad_operator
Stores the one dimensional gradient operator.
void allocate_model_variables() override
Allocate the necessary variables declared in src/physics/model.h.
DGStrongLES_DynamicSmagorinsky(const Parameters::AllParameters *const parameters_input, const unsigned int degree, const unsigned int max_degree_input, const unsigned int grid_degree_input, const std::shared_ptr< Triangulation > triangulation_input)
Constructor.
~DGStrongLES_ShearImproved()
Destructor.
dealii::LinearAlgebra::distributed::Vector< double > solution
Current modal coefficients of the solution.
Navier Stokes equations with model source term.
const double total_wall_area
Total wall area.
bool store_surf_flux_nodes
Flag for storing surface flux nodes.
void update_model_variables() override
Update the necessary variables declared in src/physics/model.h.
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.
DGStrongLES(const Parameters::AllParameters *const parameters_input, const unsigned int degree, const unsigned int max_degree_input, const unsigned int grid_degree_input, const std::shared_ptr< Triangulation > triangulation_input)
Constructor.
DGStrong_ChannelFlow(const Parameters::AllParameters *const parameters_input, const unsigned int degree, const unsigned int max_degree_input, const unsigned int grid_degree_input, const std::shared_ptr< Triangulation > triangulation_input)
Constructor.
virtual void allocate_model_variables() override
Allocate the necessary variables declared in src/physics/model.h.
const dealii::UpdateFlags face_update_flags
Update flags needed at face points.
void update_cellwise_mean_quantities() override
Update the cellwise mean quantities.
const unsigned int poly_degree_max_large_scales
For filtered solution; lower bound of high pass filter.
DGStrongLES_ShearImproved(const Parameters::AllParameters *const parameters_input, const unsigned int degree, const unsigned int max_degree_input, const unsigned int grid_degree_input, const std::shared_ptr< Triangulation > triangulation_input)
Constructor.
std::shared_ptr< Triangulation > triangulation
Mesh.
~DGStrong_ChannelFlow()
Destructor.
void update_cellwise_mean_quantities() override
Update the cellwise mean quantities.
void update_cellwise_volume_and_poly_degree()
Update the cellwise volume and polynomial degree.
const dealii::hp::FECollection< dim > fe_collection
Finite Element Collection for p-finite-element to represent the solution.
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...
void build_1D_gradient_operator(const dealii::FESystem< 1, 1 > &finite_element, const dealii::Quadrature< 1 > &quadrature)
Assembles the one dimensional operator.
std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, real > > pde_physics_double
Contains the physics of the PDE with real type.
Projection operator corresponding to basis functions onto M-norm (L2).
std::shared_ptr< Physics::LargeEddySimulationBase< dim, nspecies, nstate, real > > pde_model_les_double
Contains the large eddy simulation object.
bool store_vol_flux_nodes
Flag for storing volume flux nodes.