[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
physics_factory.cpp
1 #include <boost/preprocessor/seq/for_each.hpp>
2 
3 #include "parameters/all_parameters.h"
4 #include "parameters/parameters_manufactured_solution.h"
5 
6 #include <deal.II/base/tensor.h>
7 
8 #include "ADTypes.hpp"
9 
10 #include "physics_factory.h"
11 #include "manufactured_solution.h"
12 #include "physics.h"
13 #include "convection_diffusion.h"
14 #include "burgers.h"
15 #include "burgers_rewienski.h"
16 #include "euler.h"
17 #include "mhd.h"
18 #include "navier_stokes.h"
19 #include "physics_model.h"
20 #include "real_gas.h"
21 
22 namespace PHiLiP {
23 namespace Physics {
24 
25 template <int dim, int nspecies, int nstate, typename real>
26 std::shared_ptr < PhysicsBase<dim,nspecies,nstate,real> >
28 ::create_Physics(const Parameters::AllParameters *const parameters_input,
29  std::shared_ptr< ModelBase<dim,nspecies,nstate,real> > model_input)
30 {
32  PDE_enum pde_type = parameters_input->pde_type;
33 
34  return create_Physics(parameters_input, pde_type, model_input);
35 }
36 
37 template <int dim, int nspecies, int nstate, typename real>
38 std::shared_ptr < PhysicsBase<dim,nspecies,nstate,real> >
40 ::create_Physics(const Parameters::AllParameters *const parameters_input,
42  std::shared_ptr< ModelBase<dim,nspecies,nstate,real> > model_input)
43 {
45 
46  if constexpr(nspecies==1) {
47  // generating the manufactured solution from the manufactured solution factory
48  std::shared_ptr< ManufacturedSolutionFunction<dim,nspecies,real> > manufactured_solution_function
50 
51  // setting the diffusion tensor and advection vectors from parameters (if needed)
52  const dealii::Tensor<2,3,double> diffusion_tensor = parameters_input->manufactured_convergence_study_param.manufactured_solution_param.diffusion_tensor;
53  const dealii::Tensor<1,3,double> advection_vector = parameters_input->manufactured_convergence_study_param.manufactured_solution_param.advection_vector;
54  const double diffusion_coefficient = parameters_input->manufactured_convergence_study_param.manufactured_solution_param.diffusion_coefficient;
55 
56  if (pde_type == PDE_enum::advection || pde_type == PDE_enum::advection_vector) {
57  if constexpr (nstate<=2)
58  return std::make_shared < ConvectionDiffusion<dim,nspecies,nstate,real> >(
59  parameters_input,
60  true, false,
61  diffusion_tensor, advection_vector, diffusion_coefficient,
62  manufactured_solution_function);
63  } else if (pde_type == PDE_enum::diffusion) {
64  if constexpr (nstate==1)
65  return std::make_shared < ConvectionDiffusion<dim,nspecies,nstate,real> >(
66  parameters_input,
67  false, true,
68  diffusion_tensor, advection_vector, diffusion_coefficient,
69  manufactured_solution_function,
70  parameters_input->test_type);
71  } else if (pde_type == PDE_enum::convection_diffusion) {
72  if constexpr (nstate==1)
73  return std::make_shared < ConvectionDiffusion<dim,nspecies,nstate,real> >(
74  parameters_input,
75  true, true,
76  diffusion_tensor, advection_vector, diffusion_coefficient,
77  manufactured_solution_function,
78  parameters_input->test_type);
79  } else if (pde_type == PDE_enum::burgers_inviscid) {
80  if constexpr (nstate==dim)
81  return std::make_shared < Burgers<dim,nspecies,nstate,real> >(
82  parameters_input,
83  parameters_input->burgers_param.diffusion_coefficient,
84  true, false,
85  diffusion_tensor,
86  manufactured_solution_function,
87  parameters_input->test_type);
88  } else if (pde_type == PDE_enum::burgers_viscous) {
89  if constexpr (nstate==dim)
90  return std::make_shared < Burgers<dim,nspecies,nstate,real> >(
91  parameters_input,
92  parameters_input->burgers_param.diffusion_coefficient,
93  true, true,
94  diffusion_tensor,
95  manufactured_solution_function);
96  } else if (pde_type == PDE_enum::burgers_rewienski) {
97  if constexpr (nstate==dim)
98  return std::make_shared < BurgersRewienski<dim,nspecies,nstate,real> >(
99  parameters_input,
100  parameters_input->burgers_param.rewienski_a,
101  parameters_input->burgers_param.rewienski_b,
102  parameters_input->burgers_param.rewienski_manufactured_solution,
103  true,
104  false,
105  diffusion_tensor,
106  manufactured_solution_function);
107  } else if (pde_type == PDE_enum::euler) {
108  if constexpr (nstate==dim+2) {
109  return std::make_shared < Euler<dim,nspecies,nstate,real> > (
110  parameters_input,
111  parameters_input->euler_param.ref_length,
112  parameters_input->euler_param.gamma_gas,
113  parameters_input->euler_param.mach_inf,
114  parameters_input->euler_param.angle_of_attack,
115  parameters_input->euler_param.side_slip_angle,
116  manufactured_solution_function,
117  parameters_input->two_point_num_flux_type);
118  }
119  } else if (pde_type == PDE_enum::mhd) {
120  if constexpr (nstate == 8)
121  return std::make_shared < MHD<dim,nspecies,nstate,real> > (
122  parameters_input,
123  parameters_input->euler_param.gamma_gas,
124  diffusion_tensor,
125  manufactured_solution_function);
126  } else if (pde_type == PDE_enum::navier_stokes) {
127  if constexpr (nstate==dim+2) {
128  return std::make_shared < NavierStokes<dim,nspecies,nstate,real> > (
129  parameters_input,
130  parameters_input->euler_param.ref_length,
131  parameters_input->euler_param.gamma_gas,
132  parameters_input->euler_param.mach_inf,
133  parameters_input->euler_param.angle_of_attack,
134  parameters_input->euler_param.side_slip_angle,
135  parameters_input->navier_stokes_param.prandtl_number,
136  parameters_input->navier_stokes_param.reynolds_number_inf,
137  parameters_input->navier_stokes_param.use_constant_viscosity,
138  parameters_input->navier_stokes_param.nondimensionalized_constant_viscosity,
139  parameters_input->navier_stokes_param.temperature_inf,
140  parameters_input->navier_stokes_param.nondimensionalized_isothermal_wall_temperature,
141  parameters_input->navier_stokes_param.thermal_boundary_condition_type,
142  manufactured_solution_function,
143  parameters_input->two_point_num_flux_type);
144  }
145  } else if (pde_type == PDE_enum::navier_stokes_channel_flow_constant_source_term) {
146  if constexpr (nstate==dim+2) {
147  const double domain_length_y_direction = parameters_input->flow_solver_param.turbulent_channel_domain_length_y_direction;
148  const double half_channel_height = domain_length_y_direction/2.0;
149  return std::make_shared < NavierStokes_ChannelFlowConstantSourceTerm<dim,nspecies,nstate,real> > (
150  parameters_input,
151  parameters_input->euler_param.ref_length,
152  parameters_input->euler_param.gamma_gas,
153  parameters_input->euler_param.mach_inf,
154  parameters_input->euler_param.angle_of_attack,
155  parameters_input->euler_param.side_slip_angle,
156  parameters_input->navier_stokes_param.prandtl_number,
157  parameters_input->navier_stokes_param.reynolds_number_inf,
158  parameters_input->navier_stokes_param.use_constant_viscosity,
159  parameters_input->navier_stokes_param.nondimensionalized_constant_viscosity,
160  parameters_input->flow_solver_param.turbulent_channel_friction_velocity_reynolds_number,
161  half_channel_height,
162  parameters_input->navier_stokes_param.temperature_inf,
163  parameters_input->navier_stokes_param.nondimensionalized_isothermal_wall_temperature,
164  parameters_input->navier_stokes_param.thermal_boundary_condition_type,
165  manufactured_solution_function,
166  parameters_input->two_point_num_flux_type);
167  }
168  } else if (pde_type == PDE_enum::navier_stokes_channel_flow_constant_source_term_wall_model) {
169  if constexpr (nstate==dim+2) {
170  if(parameters_input->flow_solver_param.flow_case_type != Parameters::FlowSolverParam::FlowCaseType::channel_flow) {
171  std::cout << "Invalid flow case, can only create NavierStokes_ChannelFlowConstantSourceTerm_WallModel for ChannelFlow." << std::endl;
172  return nullptr;
173  }
174  const double domain_length_y_direction = parameters_input->flow_solver_param.turbulent_channel_domain_length_y_direction;
175  const double half_channel_height = domain_length_y_direction/2.0;
176  const int number_of_cells_y_direction = parameters_input->flow_solver_param.turbulent_channel_number_of_cells_y_direction;
177  const double uniform_spacing_y_direction = domain_length_y_direction/double(number_of_cells_y_direction);
178  return std::make_shared < NavierStokes_ChannelFlowConstantSourceTerm_WallModel<dim,nspecies,nstate,real> > (
179  parameters_input,
180  parameters_input->euler_param.ref_length,
181  parameters_input->euler_param.gamma_gas,
182  parameters_input->euler_param.mach_inf,
183  parameters_input->euler_param.angle_of_attack,
184  parameters_input->euler_param.side_slip_angle,
185  parameters_input->navier_stokes_param.prandtl_number,
186  parameters_input->navier_stokes_param.reynolds_number_inf,
187  parameters_input->navier_stokes_param.use_constant_viscosity,
188  parameters_input->navier_stokes_param.nondimensionalized_constant_viscosity,
189  parameters_input->flow_solver_param.turbulent_channel_friction_velocity_reynolds_number,
190  half_channel_height,
191  uniform_spacing_y_direction,
192  parameters_input->navier_stokes_param.temperature_inf,
193  parameters_input->navier_stokes_param.nondimensionalized_isothermal_wall_temperature,
194  parameters_input->navier_stokes_param.thermal_boundary_condition_type,
195  manufactured_solution_function,
196  parameters_input->two_point_num_flux_type);
197  }
198  } else if (pde_type == PDE_enum::physics_model || pde_type == PDE_enum::physics_model_filtered) {
199  if constexpr (nstate>=dim+2) {
200  return create_Physics_Model(parameters_input,
201  manufactured_solution_function,
202  model_input);
203  }
204  }
205  // prevent warnings for dim=3,nstate=4, etc.
206  (void) diffusion_tensor;
207  (void) advection_vector;
208  (void) diffusion_coefficient;
209  } else if (pde_type == PDE_enum::real_gas) {
210  if constexpr (nstate==dim+nspecies+1) {
211  return std::make_shared < RealGas<dim,nspecies,nstate,real> > (parameters_input);
212  }
213  }
214  std::cout << "Can't create PhysicsBase, invalid PDE type: " << pde_type << std::endl;
215  assert(0==1 && "Can't create PhysicsBase, invalid PDE type");
216  return nullptr;
217 }
218 
219 template <int dim, int nspecies, int nstate, typename real>
220 std::shared_ptr < PhysicsBase<dim,nspecies,nstate,real> >
222 ::create_Physics_Model(const Parameters::AllParameters *const parameters_input,
223  std::shared_ptr< ManufacturedSolutionFunction<dim,nspecies,real> > manufactured_solution_function,
224  std::shared_ptr< ModelBase<dim,nspecies,nstate,real> > model_input)
225 {
227  const PDE_enum pde_type = parameters_input->pde_type;
228 
229  using Model_enum = Parameters::AllParameters::ModelType;
230  const Model_enum model_type = parameters_input->model_type;
231 
233  const RANSModel_enum rans_model_type = parameters_input->physics_model_param.RANS_model_type;
234 
235  using FlowCase_enum = Parameters::FlowSolverParam::FlowCaseType;
236  const FlowCase_enum flow_case_type = parameters_input->flow_solver_param.flow_case_type;
237 
238  // ===============================================================================
239  // Physics Model
240  // ===============================================================================
241 
242  // Create baseline physics object
243  PDE_enum baseline_physics_type;
244 
245  // Flag to signal non-zero diffusion
246  bool has_nonzero_diffusion;
247 
248  // Flag to signal non-zero physical source
249  bool has_nonzero_physical_source;
250 
251  // -------------------------------------------------------------------------------
252  // Large Eddy Simulation (LES)
253  // -------------------------------------------------------------------------------
254  if (model_type==Model_enum::large_eddy_simulation || model_type==Model_enum::navier_stokes_model) {
255  has_nonzero_diffusion = true; // because of SGS model term (initialized as true)
256  has_nonzero_physical_source = false; // no physical source terms by default
257  if(flow_case_type==FlowCase_enum::channel_flow) {
258  has_nonzero_physical_source = true; // forcing function
259  }
260  if constexpr ((nstate==dim+2) && (dim==3) && nspecies == 1) {
261  // Assign baseline physics type (and corresponding nstates) based on the physics model type
262  // -- Assign nstates for the baseline physics (constexpr because template parameter)
263  constexpr int nstate_baseline_physics = dim+2;
264  // -- Assign baseline physics type
265  if(parameters_input->physics_model_param.euler_turbulence) {
266  baseline_physics_type = PDE_enum::euler;
267  if(model_type==Model_enum::navier_stokes_model) has_nonzero_diffusion = false; // no additional diffusion terms
268  }
269  else {
270  baseline_physics_type = PDE_enum::navier_stokes;
271  }
272 
273  // Create the physics model object in physics
274  if (pde_type == PDE_enum::physics_model) {
275  return std::make_shared < PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics> > (
276  parameters_input,
277  baseline_physics_type,
278  model_input,
279  manufactured_solution_function,
280  has_nonzero_diffusion,
281  has_nonzero_physical_source);
282  } else if(pde_type == PDE_enum::physics_model_filtered) {
283  return std::make_shared < PhysicsModelFiltered<dim,nspecies,nstate,real,nstate_baseline_physics> > (
284  parameters_input,
285  baseline_physics_type,
286  model_input,
287  manufactured_solution_function,
288  has_nonzero_diffusion,
289  has_nonzero_physical_source);
290  }
291  }
292  else {
293  // LES does not exist for nstate!=(dim+2) || dim!=3
294  (void) baseline_physics_type;
295  (void) has_nonzero_diffusion;
296  (void) has_nonzero_physical_source;
297  return nullptr;
298  }
299  }
300  // -------------------------------------------------------------------------------
301  // Reynolds-Averaged Navier-Stokes (RANS) + RANS model
302  // -------------------------------------------------------------------------------
303  else if (model_type == Model_enum::reynolds_averaged_navier_stokes) {
304  has_nonzero_diffusion = true; // RANS (baseline part) has diffusion terms
305  has_nonzero_physical_source = true; // RANS (baseline part) has physical source terms
306  if (rans_model_type == RANSModel_enum::SA_negative)
307  {
308  if constexpr (nstate==dim+3 && nspecies==1) {
309  // Assign baseline physics type (and corresponding nstates) based on the physics model type
310  // -- Assign nstates for the baseline physics (constexpr because template parameter)
311  constexpr int nstate_baseline_physics = dim+2;
312  // -- Assign baseline physics type
313  if(parameters_input->physics_model_param.euler_turbulence) {
314  baseline_physics_type = PDE_enum::euler;
315  }
316  else {
317  baseline_physics_type = PDE_enum::navier_stokes;
318  }
319 
320  // Create the physics model object in physics
321  return std::make_shared < PhysicsModel<dim,nspecies,nstate,real,nstate_baseline_physics> > (
322  parameters_input,
323  baseline_physics_type,
324  model_input,
325  manufactured_solution_function,
326  has_nonzero_diffusion,
327  has_nonzero_physical_source);
328  }
329  else {
330  // RANS+one-equation model does not exist for nstate!=(dim+3)
331  (void) baseline_physics_type;
332  (void) has_nonzero_physical_source;
333  std::cout << "Can't create RANS + negative SA model for nstate!=(dim+3). " << std::endl;
334  return nullptr;
335  }
336  }
337  }
338  else {
339  // prevent warnings for dim=3,nstate=4, etc.
340  (void) baseline_physics_type;
341  (void) has_nonzero_diffusion;
342  (void) has_nonzero_physical_source;
343  }
344  std::cout << "Can't create PhysicsModel, invalid ModelType type: " << model_type << std::endl;
345  assert(0==1 && "Can't create PhysicsModel, invalid ModelType type");
346  return nullptr;
347 }
348 
349 #if PHILIP_SPECIES==1
350  // Define a sequence of indices representing the range of nstate
351  #define POSSIBLE_NSTATE (1)(2)(3)(4)(5)(6)(8)
352 
353  // Define a macro to instantiate functions for a specific nstate
354  #define INSTANTIATE_FOR_NSTATE(r, data, nstate) \
355  template class PhysicsFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, double>; \
356  template class PhysicsFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, FadType>; \
357  template class PhysicsFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, RadType>; \
358  template class PhysicsFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, FadFadType>; \
359  template class PhysicsFactory<PHILIP_DIM, PHILIP_SPECIES, nstate, RadFadType>;
360  BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_FOR_NSTATE, _, POSSIBLE_NSTATE)
361 #else
362  #define POSSIBLE_TYPE (double)(FadType)(RadType)(FadFadType)(RadFadType)
363  #define INSTANTIATE_TYPES(r, data, type) \
364  template class PhysicsFactory<PHILIP_DIM, PHILIP_SPECIES, PHILIP_DIM+PHILIP_SPECIES+1, type>;
365  BOOST_PP_SEQ_FOR_EACH(INSTANTIATE_TYPES, _, POSSIBLE_TYPE)
366 #endif
367 
368 } // Physics namespace
369 } // PHiLiP namespace
370 
double diffusion_coefficient
Parameter for diffusion coefficient.
FlowCaseType
Selects the flow case to be simulated.
PartialDifferentialEquation pde_type
Store the PDE type to be solved.
FlowCaseType flow_case_type
Selected FlowCaseType from the input file.
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
double turbulent_channel_domain_length_y_direction
For channel flow, domain length in y-direction.
Manufactured solution used for grid studies to check convergence orders.
PartialDifferentialEquation
Possible Partial Differential Equations to solve.
Files for the baseline physics.
Definition: ADTypes.hpp:10
ManufacturedSolutionParam manufactured_solution_param
Associated manufactured solution parameters.
Physics model additional terms and equations to the baseline physics.
Definition: model.h:18
EulerParam euler_param
Contains parameters for the Euler equations non-dimensionalization.
ModelType
Types of models available.
Main parameter class that contains the various other sub-parameter classes.
ManufacturedConvergenceStudyParam manufactured_convergence_study_param
Contains parameters for manufactured convergence study.
double ref_length
Reference length.
static std::shared_ptr< PhysicsBase< dim, nspecies, nstate, real > > create_Physics_Model(const Parameters::AllParameters *const parameters_input, std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > manufactured_solution_function=nullptr, std::shared_ptr< ModelBase< dim, nspecies, nstate, real > > model_input=nullptr)
Factory to return the correct physics model, i.e. when PDE_type==physics_model || PDE_type==physics_m...
TestType test_type
Store selected TestType from the input file.
ReynoldsAveragedNavierStokesModel
Types of Reynolds-averaged Navier-Stokes (RANS) models that can be used.
dealii::Tensor< 1, 3, double > advection_vector
Advection velocity.
int turbulent_channel_number_of_cells_y_direction
For channel flow, number of cells in y-direction.
ReynoldsAveragedNavierStokesModel RANS_model_type
Store the Reynolds-averaged Navier-Stokes (RANS) model type.
static std::shared_ptr< ManufacturedSolutionFunction< dim, nspecies, real > > create_ManufacturedSolution(Parameters::AllParameters const *const param, int nstate)
Construct Manufactured solution object from global parameter file.
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.
dealii::Tensor< 2, 3, double > diffusion_tensor
Diffusion tensor.
ModelType model_type
Store the model type.
PhysicsModelParam physics_model_param
Contains parameters for Physics Model.
BurgersParam burgers_param
Contains parameters for Burgers equation.