[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
numerical_flux_factory.cpp
1 #include <boost/preprocessor/seq/for_each.hpp>
2 
3 #include "numerical_flux_factory.hpp"
4 
5 #include "convective_numerical_flux.hpp"
6 #include "ADTypes.hpp"
7 #include "physics/physics_model.h"
8 
9 namespace PHiLiP {
10 namespace NumericalFlux {
11 
12 using AllParam = Parameters::AllParameters;
13 
14 template <int dim, int nspecies, int nstate, typename real>
15 std::unique_ptr< NumericalFluxConvective<dim,nspecies,nstate,real> >
18  const AllParam::ConvectiveNumericalFlux conv_num_flux_type,
20  const AllParam::ModelType model_type,
21  std::shared_ptr<Physics::PhysicsBase<dim, nspecies, nstate, real>> physics_input)
22 {
23  // checks if conv_num_flux_type exists only for Euler equations
24  const bool is_euler_based = ((conv_num_flux_type == AllParam::ConvectiveNumericalFlux::roe) ||
25  (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::l2roe) ||
26  (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux_with_roe_dissipation) ||
27  (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux_with_l2roe_dissipation));
28  // checks if weak dg is being run with two point flux
29  const bool is_two_point_conv = ((conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux) ||
30  (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux_with_lax_friedrichs_dissipation) ||
31  (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux_with_roe_dissipation) ||
32  (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux_with_l2roe_dissipation));
33  if(is_two_point_conv && physics_input->all_parameters->use_split_form == false ) {
34  std::cout << "two point flux and not using split form are not compatible, please use another Convective Numerical Flux" << std::endl;
35  std::abort();
36  }
37 
38  if (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::central_flux) {
39  if constexpr (nstate<=5) {
40  return std::make_unique< Central<dim, nspecies, nstate, real> > (physics_input);
41  }
42  }
43  else if(conv_num_flux_type == AllParam::ConvectiveNumericalFlux::lax_friedrichs) {
44  return std::make_unique< LaxFriedrichs<dim, nspecies, nstate, real> > (physics_input);
45  }
46  else if(is_euler_based) {
47  if constexpr (dim+2==nstate && nspecies==1) {
48  return create_euler_based_convective_numerical_flux(conv_num_flux_type, pde_type, model_type, physics_input);
49  }
50  }
51  else if (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux) {
52  if constexpr ((nstate <= 5 && nspecies == 1) || (nstate == dim + nspecies + 1 && nspecies > 1)) {
53  return std::make_unique< EntropyConserving<dim, nspecies, nstate, real> > (physics_input);
54  }
55  }
56  else if (conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux_with_lax_friedrichs_dissipation) {
57  if constexpr ((nstate <= 5 && nspecies == 1) || (nstate == dim + nspecies + 1 && nspecies > 1)) {
58  return std::make_unique< EntropyConservingWithLaxFriedrichsDissipation<dim, nspecies, nstate, real> > (physics_input);
59  }
60  }
61  else {
62  (void) pde_type;
63  (void) model_type;
64  }
65 
66  std::cout << "Invalid convective numerical flux and/or invalid added Riemann solver dissipation type." << std::endl;
67  std::abort();
68  return nullptr;
69 }
70 
71 template <int dim, int nspecies, int nstate, typename real>
72 std::unique_ptr< NumericalFluxConvective<dim,nspecies,nstate,real> >
75  const AllParam::ConvectiveNumericalFlux conv_num_flux_type,
77  const AllParam::ModelType model_type,
78  std::shared_ptr<Physics::PhysicsBase<dim, nspecies, nstate, real>> physics_input)
79 {
81  using Model_enum = Parameters::AllParameters::ModelType;
82  std::shared_ptr<Physics::PhysicsBase<dim, nspecies, nstate, real>> euler_based_physics_to_be_passed = physics_input;
83 
84  if(pde_type!=PDE_enum::euler &&
85  pde_type!=PDE_enum::navier_stokes &&
86  !(pde_type==PDE_enum::physics_model && model_type==Model_enum::large_eddy_simulation) &&
87  pde_type!=PDE_enum::navier_stokes_channel_flow_constant_source_term &&
88  pde_type!=PDE_enum::navier_stokes_channel_flow_constant_source_term_wall_model &&
89  pde_type!=PDE_enum::real_gas && (pde_type==PDE_enum::real_gas && nspecies ==1))
90  {
91  std::cout << "Invalid convective numerical flux for pde_type. Aborting..." << std::endl;
92  std::abort();
93  }
94 
95 #if PHILIP_DIM==3
96  if(((pde_type==PDE_enum::physics_model || pde_type==PDE_enum::physics_model_filtered) &&
97  (model_type==Model_enum::large_eddy_simulation || model_type==Model_enum::navier_stokes_model)))
98  {
99  if constexpr (dim+2==nstate) {
100  std::shared_ptr<Physics::PhysicsModel<dim,nspecies,dim+2,real,dim+2>> physics_model = std::dynamic_pointer_cast<Physics::PhysicsModel<dim,nspecies,dim+2,real,dim+2>>(physics_input);
101  std::shared_ptr<Physics::Euler<dim,nspecies,dim+2,real>> physics_baseline = std::dynamic_pointer_cast<Physics::Euler<dim,nspecies,dim+2,real>>(physics_model->physics_baseline);
102  euler_based_physics_to_be_passed = physics_baseline;
103  }
104  }
105  else if((pde_type==PDE_enum::physics_model || pde_type==PDE_enum::physics_model_filtered) &&
106  (model_type!=Model_enum::large_eddy_simulation && model_type!=Model_enum::navier_stokes_model))
107  {
108  std::cout << "Invalid convective numerical flux for physics_model and/or corresponding baseline_physics_type" << std::endl;
109  if(nstate!=(dim+2)) std::cout << "Error: Cannot create_euler_based_convective_numerical_flux() for nstate_baseline_physics != nstate." << std::endl;
110  std::abort();
111  }
112 #endif
113  if(conv_num_flux_type == AllParam::ConvectiveNumericalFlux::roe && nspecies==1) {
114  if constexpr (dim+2==nstate) return std::make_unique< RoePike<dim, nspecies, nstate, real> > (euler_based_physics_to_be_passed);
115  }
116  else if(conv_num_flux_type == AllParam::ConvectiveNumericalFlux::l2roe && nspecies==1) {
117  if constexpr (dim+2==nstate) return std::make_unique< L2Roe<dim, nspecies, nstate, real> > (euler_based_physics_to_be_passed);
118  }
119  else if(conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux_with_roe_dissipation && nspecies==1) {
120  if constexpr (dim+2==nstate) return std::make_unique< EntropyConservingWithRoeDissipation<dim, nspecies, nstate, real> > (euler_based_physics_to_be_passed);
121  }
122  else if(conv_num_flux_type == AllParam::ConvectiveNumericalFlux::two_point_flux_with_l2roe_dissipation && nspecies==1) {
123  if constexpr (dim+2==nstate) return std::make_unique< EntropyConservingWithL2RoeDissipation<dim, nspecies, nstate, real> > (euler_based_physics_to_be_passed);
124  }
125 
126  (void) pde_type;
127  (void) model_type;
128 
129  std::cout << "Invalid Euler based convective numerical flux" << std::endl;
130  return nullptr;
131 }
132 
133 template <int dim, int nspecies, int nstate, typename real>
134 std::unique_ptr< NumericalFluxDissipative<dim,nspecies,nstate,real> >
137  const AllParam::DissipativeNumericalFlux diss_num_flux_type,
138  std::shared_ptr <Physics::PhysicsBase<dim, nspecies, nstate, real>> physics_input,
139  std::shared_ptr<ArtificialDissipationBase<dim, nspecies, nstate>> artificial_dissipation_input)
140 {
141  if(diss_num_flux_type == AllParam::symm_internal_penalty) {
142  return std::make_unique < SymmetricInternalPenalty<dim, nspecies, nstate, real> > (physics_input,artificial_dissipation_input);
143  } else if(diss_num_flux_type == AllParam::bassi_rebay_2) {
144  return std::make_unique < BassiRebay2<dim, nspecies, nstate, real> > (physics_input,artificial_dissipation_input);
145  } else if(diss_num_flux_type == AllParam::central_visc_flux) {
146  return std::make_unique < CentralViscousNumericalFlux<dim, nspecies, nstate, real> > (physics_input,artificial_dissipation_input);
147  }
148 
149  std::cout << "Invalid dissipative flux" << std::endl;
150  return nullptr;
151 }
152 
153 #if PHILIP_SPECIES==1
154  // Define a sequence of indices representing the range [1, 6]
155  #define POSSIBLE_NSTATE (1)(2)(3)(4)(5)(6)
156 
157  // Define a macro to instantiate functions for a specific nstate
158  #define INSTANTIATE_FOR_NSTATE(r, data, nstate) \
159  template class NumericalFluxFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, double>; \
160  template class NumericalFluxFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, FadType >; \
161  template class NumericalFluxFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, RadType >; \
162  template class NumericalFluxFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, FadFadType >; \
163  template class NumericalFluxFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, RadFadType >;
164  BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_FOR_NSTATE, _, POSSIBLE_NSTATE)
165 #else
166  #define POSSIBLE_TYPE (double)(FadType)(RadType)(FadFadType)(RadFadType)
167  #define INSTANTIATE_TYPES(r, data, type) \
168  template class NumericalFluxFactory<PHILIP_DIM, PHILIP_SPECIES, PHILIP_DIM+PHILIP_SPECIES+1, type>;
169  BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_TYPES, _, POSSIBLE_TYPE)
170 #endif
171 } // NumericalFlux namespace
172 } // PHiLiP namespace
Base class from which Advection, Diffusion, ConvectionDiffusion, and Euler is derived.
Definition: physics.h:34
Physics Model equations. Derived from PhysicsBase, holds a baseline physics and model terms and equat...
Definition: physics_model.h:14
PartialDifferentialEquation
Possible Partial Differential Equations to solve.
Files for the baseline physics.
Definition: ADTypes.hpp:10
ModelType
Types of models available.
static std::unique_ptr< NumericalFluxConvective< dim, nspecies, nstate, real > > create_convective_numerical_flux(const AllParam::ConvectiveNumericalFlux conv_num_flux_type, const AllParam::PartialDifferentialEquation pde_type, const AllParam::ModelType model_type, std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, real >> physics_input)
Creates convective numerical flux (baseline flux + upwind term) based on input.
DissipativeNumericalFlux
Possible dissipative numerical flux types.
ConvectiveNumericalFlux
Possible convective numerical flux types.
static std::unique_ptr< NumericalFluxDissipative< dim, nspecies, nstate, real > > create_dissipative_numerical_flux(const AllParam::DissipativeNumericalFlux diss_num_flux_type, std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, real >> physics_input, std::shared_ptr< ArtificialDissipationBase< dim, nspecies, nstate >> artificial_dissipation_input)
Creates dissipative numerical flux based on input.
static std::unique_ptr< NumericalFluxConvective< dim, nspecies, nstate, real > > create_euler_based_convective_numerical_flux(const AllParam::ConvectiveNumericalFlux conv_num_flux_type, const AllParam::PartialDifferentialEquation pde_type, const AllParam::ModelType model_type, std::shared_ptr< Physics::PhysicsBase< dim, nspecies, nstate, real >> physics_input)
Creates euler-based convective numerical flux (upwind term)
Class to add artificial dissipation with an option to add one of the 3 dissipation types: 1...