VertexCFD  0.0-dev
VertexCFD_ClosureModelFactory_impl.hpp
1 #ifndef VERTEXCFD_CLOSUREMODELFACTORY_IMPL_HPP
2 #define VERTEXCFD_CLOSUREMODELFACTORY_IMPL_HPP
3 
4 #include "VertexCFD_Closure_ElementLength.hpp"
5 #include "VertexCFD_Closure_ExternalInterpolation.hpp"
6 #include "VertexCFD_Closure_ExternalMagneticField.hpp"
7 #include "VertexCFD_Closure_MeasureElementLength.hpp"
8 #include "VertexCFD_Closure_MetricTensor.hpp"
9 #include "VertexCFD_Closure_MetricTensorElementLength.hpp"
10 #include "VertexCFD_Closure_SingularValueElementLength.hpp"
11 #include "VertexCFD_Closure_VariableOldValue.hpp"
12 #include "VertexCFD_Closure_VectorFieldDivergence.hpp"
13 #include "VertexCFD_Closure_WallDistance.hpp"
14 
15 #include "incompressible_lsvof_solver/closure_models/VertexCFD_IncompressibleLSVOFClosureModelFactory.hpp"
16 #include "incompressible_solver/closure_models/VertexCFD_IncompressibleClosureModelFactory.hpp"
17 #include "incompressible_solver/fluid_properties/VertexCFD_Closure_IncompressibleFluidProperties.hpp"
18 #include "induction_less_mhd_solver/closure_models/VertexCFD_InductionlessClosureModelFactory.hpp"
19 #include "turbulence_models/closure_models/VertexCFD_TurbulenceClosureModelFactory.hpp"
20 
21 #include "mesh/VertexCFD_Mesh_GeometryData.hpp"
22 #include "utils/VertexCFD_Utils_VectorizeOutputFieldNames.hpp"
23 
24 #include <optional>
25 
26 namespace VertexCFD
27 {
28 namespace ClosureModel
29 {
30 //---------------------------------------------------------------------------//
31 template<class EvalType, int NumSpaceDim>
32 Teuchos::RCP<std::vector<Teuchos::RCP<PHX::Evaluator<panzer::Traits>>>>
33 Factory<EvalType, NumSpaceDim>::buildClosureModels(
34  const std::string& model_id,
35  const Teuchos::ParameterList& model_params,
36  const panzer::FieldLayoutLibrary&,
37  const Teuchos::RCP<panzer::IntegrationRule>& ir,
38  const Teuchos::ParameterList&,
39  const Teuchos::ParameterList& user_params_orig,
40  const Teuchos::RCP<panzer::GlobalData>& global_data,
41  PHX::FieldManager<panzer::Traits>&) const
42 {
43  auto evaluators = Teuchos::rcp(
44  new std::vector<Teuchos::RCP<PHX::Evaluator<panzer::Traits>>>);
45 
46  constexpr int num_space_dim = NumSpaceDim;
47 
48  // Make a hard copy of `user_params_const` that we can modify in here
49  Teuchos::ParameterList user_params = user_params_orig;
50 
51  // Check for closure model, and make local copy
52  Teuchos::ParameterList closure_model_list;
53  if (!model_params.isSublist(model_id))
54  {
55  throw std::runtime_error("Closure model id not in list");
56  }
57  else
58  {
59  closure_model_list = model_params.sublist(model_id);
60  }
61 
62  // Check for closure model factory type and remove it if found
63  std::string factory_type = "Navier Stokes";
64  if (closure_model_list.isType<std::string>("Closure Factory Type"))
65  {
66  factory_type
67  = closure_model_list.get<std::string>("Closure Factory Type");
68  closure_model_list.remove("Closure Factory Type");
69  }
70 
71  // Return empty evaluators if the factory type is not found in
72  // 'factory_list'
73  const std::string factory_list = "LSVOF, Navier Stokes";
74  if (factory_list.find(factory_type) == std::string::npos)
75  return evaluators;
76 
77  // Build LSVOF factory if LSVOF factory type specified
78  std::optional<IncompressibleLSVOFFactory<EvalType, NumSpaceDim>> lsvof_factory
79  = factory_type == "LSVOF"
80  ? std::make_optional<
81  IncompressibleLSVOFFactory<EvalType, NumSpaceDim>>()
82  : std::nullopt;
83  std::string lsvof_error_msg = "None\n";
84 
85  if (lsvof_factory)
86  {
87  lsvof_factory->buildDefaultClosureModels(
88  ir, closure_model_list, user_params, global_data, evaluators);
89  }
90 
91  // Incompressible factory model object required for "Navier Stokes"
92  std::optional<IncompressibleFactory<EvalType, NumSpaceDim>> incomp_factory
93  = factory_type == "Navier Stokes"
94  ? std::make_optional<IncompressibleFactory<EvalType, NumSpaceDim>>()
95  : std::nullopt;
96  std::string incomp_error_msg = "None\n";
97 
98  // Get fluid properties for incompressible NS equations: read the Fluid
99  // Properties from the closure model list and remove it from the list.
100  bool build_indless_equ = false;
101  Teuchos::ParameterList fluid_prop_list;
102  if (incomp_factory)
103  {
104  // Fluid properties
105  fluid_prop_list = closure_model_list.sublist("Fluid Properties");
106  closure_model_list.remove("Fluid Properties");
107  const bool build_temp_equ
108  = fluid_prop_list.isType<bool>("Build Temperature Equation")
109  ? fluid_prop_list.get<bool>("Build Temperature Equation")
110  : false;
111  const bool build_buoyancy_source
112  = fluid_prop_list.isType<bool>("Build Buoyancy Source")
113  ? fluid_prop_list.get<bool>("Build Buoyancy Source")
114  : false;
115  build_indless_equ
116  = fluid_prop_list.isType<bool>("Build Inductionless MHD Equation")
117  ? fluid_prop_list.get<bool>(
118  "Build Inductionless MHD Equation")
119  : false;
120  fluid_prop_list.set<bool>("Build Inductionless MHD Equation",
121  build_indless_equ);
122  fluid_prop_list.set<bool>("Build Temperature Equation", build_temp_equ);
123  fluid_prop_list.set<bool>("Build Buoyancy Source",
124  build_buoyancy_source);
125 
126  // Initialize fluid properties
127  auto eval = Teuchos::rcp(
128  new FluidProperties::IncompressibleFluidProperties<EvalType,
129  panzer::Traits>(
130  *ir, fluid_prop_list));
131  evaluators->push_back(eval);
132  }
133 
134  // Inductionless solver factory object
135  std::optional<InductionlessFactory<EvalType, NumSpaceDim>> inductionless_factory
136  = build_indless_equ
137  ? std::make_optional<InductionlessFactory<EvalType, NumSpaceDim>>()
138  : std::nullopt;
139  std::string ind_less_error_msg = "None\n";
140 
141  // Get stability parameters for incompressible NS equations: read the
142  // Stability Parameters from the closure model list and remove it from the
143  // list.
144  Teuchos::ParameterList stability_param_list;
145  if (incomp_factory && closure_model_list.isSublist("Stability Parameters"))
146  {
147  stability_param_list
148  = closure_model_list.sublist("Stability Parameters");
149  closure_model_list.remove("Stability Parameters");
150  user_params.set<Teuchos::ParameterList>("Stability Parameters",
151  stability_param_list);
152  }
153  else if (incomp_factory
154  && !closure_model_list.isSublist("Stability Parameters"))
155  {
156  // We need to define an empty list for incompressible factory.
157  user_params.set<Teuchos::ParameterList>("Stability Parameters",
158  stability_param_list);
159  }
160 
161  // Turbulence model parameters
162  const std::string turbulence_model_name
163  = fluid_prop_list.isType<std::string>("Turbulence Model")
164  ? fluid_prop_list.get<std::string>("Turbulence Model")
165  : "No Turbulence Model";
166  std::optional<TurbulenceFactory<EvalType, NumSpaceDim>> tm_factory
167  = (turbulence_model_name != "No Turbulence Model")
168  ? std::make_optional<TurbulenceFactory<EvalType, NumSpaceDim>>()
169  : std::nullopt;
170  const bool use_turbulence_model = tm_factory.has_value();
171 
172  if (tm_factory)
173  {
174  tm_factory->buildClosureModel(
175  ir, global_data, user_params, turbulence_model_name, evaluators);
176  }
177 
178  // Closure model block in XML input file for `model_id`
179  for (const auto& closure_model : closure_model_list)
180  {
181  bool found_model = false;
182 
183  const auto closure_name = closure_model.first;
184 
185  const auto& closure_params
186  = Teuchos::getValue<Teuchos::ParameterList>(closure_model.second);
187 
188  if (closure_params.isType<std::string>("Type"))
189  {
190  const auto closure_type = closure_params.get<std::string>("Type");
191 
192  // Incompressible factory
193  if (incomp_factory)
194  {
195  incomp_factory->buildClosureModel(closure_type,
196  ir,
197  global_data,
198  fluid_prop_list,
199  user_params,
200  closure_params,
201  use_turbulence_model,
202  found_model,
203  incomp_error_msg,
204  evaluators);
205  }
206  // LSVOF factory
207  else if (lsvof_factory)
208  {
209  lsvof_factory->buildClosureModel(closure_type,
210  ir,
211  user_params,
212  closure_params,
213  global_data,
214  found_model,
215  lsvof_error_msg,
216  evaluators);
217  }
218 
219  // Inductionless MHD factory
220  if (inductionless_factory)
221  {
222  inductionless_factory->buildClosureModel(closure_type,
223  ir,
224  user_params,
225  closure_params,
226  found_model,
227  ind_less_error_msg,
228  evaluators);
229  }
230 
231  if (closure_type == "ExternalMagneticField")
232  {
233  auto eval = Teuchos::rcp(
234  new ExternalMagneticField<EvalType, panzer::Traits>(
235  *ir, user_params));
236  evaluators->push_back(eval);
237  found_model = true;
238  }
239 
240  if (closure_type == "MetricTensor")
241  {
242  auto eval = Teuchos::rcp(
243  new MetricTensor<EvalType, panzer::Traits>(*ir));
244  evaluators->push_back(eval);
245  found_model = true;
246  }
247 
248  if (closure_type == "ElementLength")
249  {
250  auto eval = Teuchos::rcp(
251  new ElementLength<EvalType, panzer::Traits>(*ir));
252  evaluators->push_back(eval);
253  found_model = true;
254  }
255  else if (closure_type == "MetricTensorElementLength")
256  {
257  auto eval = Teuchos::rcp(
258  new MetricTensorElementLength<EvalType, panzer::Traits>(
259  *ir));
260  evaluators->push_back(eval);
261  found_model = true;
262  }
263  else if (closure_type == "MeasureElementLength")
264  {
265  auto eval = Teuchos::rcp(
266  new MeasureElementLength<EvalType, panzer::Traits>(*ir));
267  evaluators->push_back(eval);
268  found_model = true;
269  }
270  else if (closure_type == "SingularValueElementLength")
271  {
272  const auto method
273  = closure_params.get<std::string>("Element Length Method");
274  auto eval = Teuchos::rcp(
275  new SingularValueElementLength<EvalType, panzer::Traits>(
276  *ir, method));
277  evaluators->push_back(eval);
278  found_model = true;
279  }
280 
281 #ifdef VERTEXCFD_HAVE_ARBORX
282  if (closure_type == "ExternalInterpolation")
283  {
284  auto eval = Teuchos::rcp(
285  new ExternalInterpolation<EvalType, panzer::Traits, num_space_dim>(
286  *ir, closure_params));
287  evaluators->push_back(eval);
288  found_model = true;
289  }
290 #endif
291 
292  if (closure_type == "WallDistance")
293  {
294  auto eval = Teuchos::rcp(
295  new WallDistance<EvalType, panzer::Traits, num_space_dim>(
296  *ir,
297  user_params
298  .get<Teuchos::RCP<Mesh::Topology::SidesetGeometry>>(
299  "Sideset Geometry")));
300  evaluators->push_back(eval);
301  found_model = true;
302  }
303 
304  if (std::string::npos != closure_type.find("VectorFieldDivergence"))
305  {
306  const auto field_names
307  = closure_params.get<std::string>("Field Names");
308  std::vector<std::string> tokens;
309  panzer::StringTokenizer(tokens, field_names, ",", true);
310  for (auto& field : tokens)
311  {
312  auto eval = Teuchos::rcp(
313  new VectorFieldDivergence<EvalType,
314  panzer::Traits,
315  num_space_dim>(
316  *ir, field, closure_type));
317  evaluators->push_back(eval);
318  }
319  found_model = true;
320  }
321 
322  if (closure_type == "VariableOldValue")
323  {
324  auto eval = Teuchos::rcp(
325  new VariableOldValue<EvalType, panzer::Traits>(
326  *ir, closure_params));
327 
328  evaluators->push_back(eval);
329 
330  found_model = true;
331  }
332  }
333 
334  if (!found_model)
335  {
336  std::string msg = "Closure model " + closure_name
337  + " failed to build.\n";
338  msg += "The closure models implemented in VertexCFD are:\n";
339  msg += "MeasureElementLength\n";
340  msg += "MetricTensor\n";
341  msg += "MetricTensorElementLength\n";
342  msg += "SingularValueElementLength\n";
343  msg += "ThermalConductivity\n";
344  msg += "VariableOldValue\n";
345  msg += "VectorFieldDivergence\n";
346  msg += "AbsVectorFieldDivergence\n";
347  msg += "=================================\n";
348  msg += "Incompressible closure models:\n";
349  msg += incomp_error_msg;
350  msg += "=================================\n";
351  msg += "LSVOF closure models:\n";
352  msg += lsvof_error_msg;
353  msg += "=================================\n";
354  msg += "Inductionless MHD closure models:\n";
355  msg += ind_less_error_msg;
356 
357  throw std::runtime_error(msg);
358  }
359  }
360 
361  return evaluators;
362 }
363 
364 //---------------------------------------------------------------------------//
365 
366 } // end namespace ClosureModel
367 } // end namespace VertexCFD
368 
369 #endif // end VERTEXCFD_CLOSUREMODELFACTORY_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23