[P]arallel [Hi]gh-order [Li]brary for [P]DEs  Latest
Parallel High-Order Library for PDEs through hp-adaptive Discontinuous Galerkin methods
flow_solver_factory.cpp
1 #include "flow_solver_factory.h"
2 
3 #include <stdlib.h>
4 
5 // all flow solver cases:
6 #include "flow_solver_cases/periodic_turbulence.h"
7 #include "flow_solver_cases/periodic_1D_unsteady.h"
8 #include "flow_solver_cases/periodic_entropy_tests.h"
9 #include "flow_solver_cases/1D_burgers_rewienski_snapshot.h"
10 #include "flow_solver_cases/1d_burgers_viscous_snapshot.h"
11 #include "flow_solver_cases/naca0012.h"
12 #include "flow_solver_cases/gaussian_bump.h"
13 #include "flow_solver_cases/non_periodic_cube_flow.h"
14 #include "flow_solver_cases/channel_flow.h"
15 #include "flow_solver_cases/turbulent_airfoil_3D.h"
16 #include "flow_solver_cases/dipole_wall_collision.h"
17 #include "flow_solver_cases/positivity_preserving_tests.h"
18 #include "flow_solver_cases/multispecies_tests.h"
19 
20 namespace PHiLiP {
21 
22 namespace FlowSolver {
23 
24 //=========================================================
25 // FLOW SOLVER FACTORY
26 //=========================================================
27 template <int dim, int nspecies, int nstate>
28 std::unique_ptr < FlowSolver<dim,nspecies,nstate> >
30 ::select_flow_case(const Parameters::AllParameters *const parameters_input,
31  const dealii::ParameterHandler &parameter_handler_input)
32 {
33  // Get the flow case type
34  using FlowCaseEnum = Parameters::FlowSolverParam::FlowCaseType;
35  const FlowCaseEnum flow_type = parameters_input->flow_solver_param.flow_case_type;
36  if constexpr(nspecies==1) {
37  if (flow_type == FlowCaseEnum::taylor_green_vortex){
38  if constexpr (dim==3 && nstate==dim+2){
39  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PeriodicTurbulence<dim,nspecies,nstate>>(parameters_input);
40  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
41  }
42  } else if (flow_type == FlowCaseEnum::dipole_wall_collision_normal){
43  if constexpr (dim==2 && nstate==dim+2){
44  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<DipoleWallCollision<dim, nspecies, nstate>>(parameters_input);
45  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
46  }
47  } else if (flow_type == FlowCaseEnum::dipole_wall_collision_oblique){
48  if constexpr (dim==2 && nstate==dim+2){
49  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<DipoleWallCollision_Oblique<dim, nspecies, nstate>>(parameters_input);
50  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
51  }
52  } else if (flow_type == FlowCaseEnum::decaying_homogeneous_isotropic_turbulence){
53  if constexpr (dim==3 && nstate==dim+2){
54  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PeriodicTurbulence<dim,nspecies,nstate>>(parameters_input);
55  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
56  }
57  } else if (flow_type == FlowCaseEnum::burgers_viscous_snapshot){
58  if constexpr (dim==1 && nstate==dim) {
59  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<BurgersViscousSnapshot<dim,nspecies,nstate>>(parameters_input);
60  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
61  }
62  } else if (flow_type == FlowCaseEnum::burgers_rewienski_snapshot){
63  if constexpr (dim==1 && nstate==dim){
64  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<BurgersRewienskiSnapshot<dim,nspecies,nstate>>(parameters_input);
65  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
66  }
67  } else if (flow_type == FlowCaseEnum::naca0012){
68  if constexpr (dim==2 && nstate==dim+2){
69  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<NACA0012<dim,nspecies,nstate>>(parameters_input);
70  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
71  }
72  } else if (flow_type == FlowCaseEnum::periodic_1D_unsteady){
73  if constexpr (dim==1 && nstate==dim){
74  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<Periodic1DUnsteady<dim,nspecies,nstate>>(parameters_input);
75  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
76  }
77  } else if (flow_type == FlowCaseEnum::gaussian_bump){
78  if constexpr (dim>1 && nstate==dim+2){
79  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<GaussianBump<dim, nspecies, nstate>>(parameters_input);
80  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
81  }
82  } else if (flow_type == FlowCaseEnum::channel_flow){
83  if constexpr (dim==3 && nstate==dim+2){
84  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<ChannelFlow<dim, nspecies, nstate>>(parameters_input);
85  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
86  }
87  } else if (flow_type == FlowCaseEnum::burgers_inviscid){
88  if constexpr (dim==1 && nstate==dim){
89  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<Periodic1DUnsteady<dim,nspecies,nstate>>(parameters_input);
90  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
91  }
92  } else if (flow_type == FlowCaseEnum::isentropic_vortex){
93  if constexpr (nstate==dim+2 && dim!=1){
94  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PeriodicEntropyTests<dim,nspecies,nstate>>(parameters_input);
95  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
96  }
97  } else if (flow_type == FlowCaseEnum::kelvin_helmholtz_instability){
98  if constexpr (dim==2 && nstate==dim+2){
99  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PeriodicEntropyTests<dim,nspecies,nstate>>(parameters_input);
100  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
101  }
102  } else if (flow_type == FlowCaseEnum::non_periodic_cube_flow){
103  if constexpr (dim==2 && nstate==1){
104  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<NonPeriodicCubeFlow<dim, nspecies, nstate>>(parameters_input);
105  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
106  }
107  } else if (flow_type == FlowCaseEnum::sod_shock_tube){
108  if constexpr (dim==1 && nstate==dim+2){
109  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PositivityPreservingTests<dim, nspecies, nstate>>(parameters_input);
110  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
111  }
112  } else if (flow_type == FlowCaseEnum::leblanc_shock_tube){
113  if constexpr (dim==1 && nstate==dim+2){
114  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PositivityPreservingTests<dim, nspecies, nstate>>(parameters_input);
115  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
116  }
117  } else if (flow_type == FlowCaseEnum::shu_osher_problem) {
118  if constexpr (dim==1 && nstate==dim + 2) {
119  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PositivityPreservingTests<dim, nspecies, nstate>>(parameters_input);
120  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
121  }
122  } else if (flow_type == FlowCaseEnum::double_mach_reflection) {
123  if constexpr (dim==2 && nstate==dim + 2) {
124  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PositivityPreservingTests<dim, nspecies, nstate>>(parameters_input);
125  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
126  }
127  } else if (flow_type == FlowCaseEnum::shock_diffraction) {
128  if constexpr (dim==2 && nstate==dim + 2) {
129  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PositivityPreservingTests<dim, nspecies, nstate>>(parameters_input);
130  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
131  }
132  } else if (flow_type == FlowCaseEnum::astrophysical_jet) {
133  if constexpr (dim==2 && nstate==dim + 2) {
134  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PositivityPreservingTests<dim, nspecies, nstate>>(parameters_input);
135  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
136  }
137  } else if (flow_type == FlowCaseEnum::strong_vortex_shock_wave) {
138  if constexpr (dim==2 && nstate==dim + 2) {
139  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PositivityPreservingTests<dim, nspecies, nstate>>(parameters_input);
140  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
141  }
142  } else if (flow_type == FlowCaseEnum::advection_limiter) {
143  if constexpr (dim<3 && nstate==1) {
144  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PeriodicCubeFlow<dim, nspecies, nstate>>(parameters_input);
145  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
146  }
147  } else if (flow_type == FlowCaseEnum::burgers_limiter) {
148  if constexpr (dim<3 && nstate==dim) {
149  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PeriodicCubeFlow<dim, nspecies, nstate>>(parameters_input);
150  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
151  }
152  } else if (flow_type == FlowCaseEnum::low_density) {
153  if constexpr (dim<3 && nstate==dim + 2) {
154  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<PeriodicCubeFlow<dim, nspecies, nstate>>(parameters_input);
155  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
156  }
157  } else if (flow_type == FlowCaseEnum::turbulent_airfoil_3D){
158  if constexpr (dim==3 && nstate==dim+2){
159  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<Airfoil_3D_LES<dim,nspecies,nstate>>(parameters_input);
160  return std::make_unique<FlowSolver<dim,nspecies,nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
161  }
162  }
163  }
164  else if (nspecies > 1 && nstate==dim+2+nspecies-1) {
165  if (flow_type == FlowCaseEnum::multi_species_vortex_advection){
166  if constexpr ((nspecies==2||nspecies==3)){
167  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<MultispeciesTests<dim, nspecies, nstate>>(parameters_input);
168  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
169  }
170  } else if (flow_type == FlowCaseEnum::multi_species_vortex_advection_high_temp){
171  if constexpr ((nspecies==2||nspecies==3)){
172  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<MultispeciesTests<dim, nspecies, nstate>>(parameters_input);
173  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
174  }
175  } else if (flow_type == FlowCaseEnum::multi_species_sod_shock_tube){
176  if constexpr (dim==1 && nspecies==2){
177  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<MultispeciesTests<dim, nspecies, nstate>>(parameters_input);
178  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
179  }
180  } else if (flow_type == FlowCaseEnum::multi_species_isentropic_vortex){
181  if constexpr (dim==2 && nspecies==2){
182  std::shared_ptr<FlowSolverCaseBase<dim, nspecies, nstate>> flow_solver_case = std::make_shared<MultispeciesTests<dim, nspecies, nstate>>(parameters_input);
183  return std::make_unique<FlowSolver<dim, nspecies, nstate>>(parameters_input, flow_solver_case, parameter_handler_input);
184  }
185  }
186  } else {
187  std::cout << "Invalid flow case. You probably forgot to add it to the list of flow cases in flow_solver_factory.cpp" << std::endl;
188  std::abort();
189  }
190  return nullptr;
191 }
192 
193 template<int dim, int nspecies, int nstate>
194 std::unique_ptr< FlowSolverBase > FlowSolverFactory<dim,nspecies,nstate>
195 ::create_flow_solver(const Parameters::AllParameters *const parameters_input,
196  const dealii::ParameterHandler &parameter_handler_input)
197 {
198  // Recursive templating required because template parameters must be compile time constants
199  // As a results, this recursive template initializes all possible dimensions with all possible nstate
200  // without having 15 different if-else statements
201  if(dim == parameters_input->dimension)
202  {
203  // This template parameters dim and nstate match the runtime parameters
204  // then create the selected flow case with template parameters dim and nstate
205  // Otherwise, keep decreasing nstate and dim until it matches
206  if(nspecies > 1)
207  return FlowSolverFactory<dim,nspecies,dim+nspecies+1>::select_flow_case(parameters_input,parameter_handler_input);
208  else if(nstate == parameters_input->nstate)
209  return FlowSolverFactory<dim,nspecies,nstate>::select_flow_case(parameters_input,parameter_handler_input);
210  else if constexpr (nstate > 1)
211  return FlowSolverFactory<dim,nspecies,nstate-1>::create_flow_solver(parameters_input,parameter_handler_input);
212  else
213  return nullptr;
214  }
215  else if constexpr (dim > 1)
216  {
217  //return FlowSolverFactory<dim-1,nstate>::create_flow_solver(parameters_input);
218  return nullptr;
219  }
220  else
221  {
222  return nullptr;
223  }
224 }
225 #if PHILIP_SPECIES==1
227 #endif
229 } // FlowSolver namespace
230 } // PHiLiP namespace
231 
FlowCaseType
Selects the flow case to be simulated.
FlowCaseType flow_case_type
Selected FlowCaseType from the input file.
FlowSolverParam flow_solver_param
Contains the parameters for simulation cases (flow solver test)
Files for the baseline physics.
Definition: ADTypes.hpp:10
static std::unique_ptr< FlowSolver< dim, nspecies, nstate > > select_flow_case(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler &parameter_handler_input)
Factory to return the correct flow solver given input file.
unsigned int dimension
Number of dimensions. Note that it has to match the executable PHiLiP_xD.
Main parameter class that contains the various other sub-parameter classes.
static std::unique_ptr< FlowSolverBase > create_flow_solver(const Parameters::AllParameters *const parameters_input, const dealii::ParameterHandler &parameter_handler_input)
Recursive factory that will create FlowSolverBase (i.e. FlowSolver<dim,nspecies,nstate>) ...
int nstate
Number of state variables. Will depend on PDE.
Create specified flow solver as FlowSolver object.