1 #ifndef VERTEXCFD_EQUATIONSET_INCOMPRESSIBLE_NAVIERSTOKES_IMPL_HPP
2 #define VERTEXCFD_EQUATIONSET_INCOMPRESSIBLE_NAVIERSTOKES_IMPL_HPP
4 #include <Panzer_BasisIRLayout.hpp>
5 #include <Panzer_IntegrationRule.hpp>
7 #include <Panzer_Integrator_BasisTimesScalar.hpp>
8 #include <Panzer_Integrator_GradBasisDotVector.hpp>
9 #include <Panzer_String_Utilities.hpp>
11 #include <Phalanx_FieldManager.hpp>
13 #include <Teuchos_ParameterList.hpp>
14 #include <Teuchos_RCP.hpp>
15 #include <Teuchos_StandardParameterEntryValidators.hpp>
22 template<
class EvalType>
23 IncompressibleNavierStokes<EvalType>::IncompressibleNavierStokes(
24 const Teuchos::RCP<Teuchos::ParameterList>& params,
25 const int& default_integration_order,
26 const panzer::CellData& cell_data,
27 const Teuchos::RCP<panzer::GlobalData>& global_data,
28 const bool build_transient_support)
29 : panzer::EquationSet_DefaultImpl<EvalType>(params,
30 default_integration_order,
33 build_transient_support)
36 if (!this->buildTransientSupport())
38 throw std::logic_error(
39 "Transient support is required for solving all equation sets.");
43 _num_space_dim = cell_data.baseCellDimension();
44 if (!(_num_space_dim == 2 || _num_space_dim == 3))
46 throw std::runtime_error(
"Number of space dimensions not supported");
50 Teuchos::ParameterList valid_parameters;
51 this->setDefaultValidParameters(valid_parameters);
53 "Model ID",
"",
"Closure model id associated with this equation set");
54 valid_parameters.set(
"Basis Order", 1,
"Order of the basis");
55 valid_parameters.set(
"Integration Order", 2,
"Order of the integration");
56 valid_parameters.set(
"Continuity Model",
"AC",
"Continuity model string");
57 valid_parameters.set(
"Build Viscous Flux",
true,
"Viscous flux boolean");
59 "Build Temperature Equation",
false,
"Solve temperature equation");
60 valid_parameters.set(
"Build Inductionless MHD Equation",
62 "Solve electric potential equation");
64 "Build Constant Source",
false,
"Constant source boolean");
67 "Build Buoyancy Source",
false,
"Buoyancy source boolean");
69 valid_parameters.set(
"Build Viscous Heat",
false,
"Viscous heat boolean");
72 "Build Resistive Flux",
false,
"Resistive flux boolean");
75 "Build Godunov-Powell Source",
false,
"Godunov-Powell source boolean");
78 "Build Joule Heating Source",
false,
"Joule heating source boolean");
80 const auto turbulence_validator = Teuchos::rcp(
new Teuchos::StringValidator(
81 Teuchos::tuple<std::string>(
"No Turbulence Model",
85 "Realizable K-Epsilon",
91 valid_parameters.set(
"Turbulence Model",
92 "No Turbulence Model",
93 "Turbulence model choice",
94 turbulence_validator);
96 const auto stabilization_validator
97 = Teuchos::rcp(
new Teuchos::StringValidator(
98 Teuchos::tuple<std::string>(
"No Stabilization Method",
101 "Taylor-Hood and Grad-Div")));
103 valid_parameters.set(
"Stabilization Method",
104 "No Stabilization Method",
105 "Stabilization method choice",
106 stabilization_validator);
108 params->validateParametersAndSetDefaults(valid_parameters);
111 const int basis_order = params->get<
int>(
"Basis Order", 1);
112 const int integration_order
113 = params->get<
int>(
"Integration Order", basis_order + 1);
114 const std::string model_id = params->get<std::string>(
"Model ID");
115 const std::string continuity_model
116 = params->get<std::string>(
"Continuity Model");
117 _build_viscous_flux = params->get<
bool>(
"Build Viscous Flux",
true);
118 _build_temp_equ = params->get<
bool>(
"Build Temperature Equation",
false);
120 = params->get<
bool>(
"Build Inductionless MHD Equation",
false);
121 _build_constant_source = params->get<
bool>(
"Build Constant Source",
false);
122 _build_buoyancy_source = params->get<
bool>(
"Build Buoyancy Source",
false);
123 _build_viscous_heat = params->get<
bool>(
"Build Viscous Heat",
false);
124 _turbulence_model = params->get<std::string>(
"Turbulence Model");
125 _stabilization_method = params->get<std::string>(
"Stabilization Method");
126 _build_godunov_powell_source
127 = params->get<
bool>(
"Build Godunov-Powell Source",
false);
128 #ifndef VERTEXCFD_ENABLE_FULL_INDUCTION_MHD
129 if (_build_godunov_powell_source)
131 throw std::runtime_error(
132 "\"Build Godunov-Powell Source\" set to \"true\", "
133 "but sovler was built without full induction model. Set\n"
134 " cmake -DVertexCFD_ENABLE_FULL_INDUCTION_MHD=ON.");
137 _build_joule_heating_source
138 = params->get<
bool>(
"Build Joule Heating Source",
false);
140 if (continuity_model ==
"AC")
142 _continuity_model = ConModel::AC;
144 else if (continuity_model ==
"EDAC")
146 _continuity_model = ConModel::EDAC;
148 else if (continuity_model ==
"EDACTempNC")
150 _continuity_model = ConModel::EDACTempNC;
154 const std::string msg
155 =
"Continuity Model' must be AC, EDAC, or EDACTempNC.";
156 throw std::runtime_error(msg);
159 if (_build_buoyancy_source && !_build_temp_equ)
161 std::string msg =
"Build Buoyancy Source set to TRUE,\n";
162 msg +=
"but Build Temperature Equation set to FALSE.\n";
163 msg +=
"Please enable temperature equation to solve with buoyancy source.";
164 throw std::runtime_error(msg);
167 if (_build_viscous_heat && !_build_temp_equ)
169 std::string msg =
"Build Viscous Heat set to TRUE.\n";
170 msg +=
"but Build Temperature Equation set to FALSE.\n";
171 msg +=
"Please enable temperature equation to solve with buoyancy source.";
172 throw std::runtime_error(msg);
176 _equ_dof_ns_pair.insert({
"continuity",
"lagrange_pressure"});
177 for (
int d = 0; d < _num_space_dim; ++d)
179 const std::string ds = std::to_string(d);
180 _equ_dof_ns_pair.insert({
"momentum_" + ds,
"velocity_" + ds});
183 _equ_dof_ns_pair.insert({
"energy",
"temperature"});
186 if (_build_ind_less_equ)
187 _equ_dof_ep_pair.insert(
188 {
"electric_potential_equation",
"electric_potential"});
192 if (std::string::npos != _turbulence_model.find(
"Spalart-Allmaras"))
194 _equ_dof_tm_pair.insert(
195 {
"spalart_allmaras_equation",
"spalart_allmaras_variable"});
197 else if (std::string::npos != _turbulence_model.find(
"K-Epsilon"))
199 _equ_dof_tm_pair.insert(
200 {
"turb_kinetic_energy_equation",
"turb_kinetic_energy"});
201 _equ_dof_tm_pair.insert(
202 {
"turb_dissipation_rate_equation",
"turb_dissipation_rate"});
204 else if (std::string::npos != _turbulence_model.find(
"K-Omega"))
206 _equ_dof_tm_pair.insert(
207 {
"turb_kinetic_energy_equation",
"turb_kinetic_energy"});
208 _equ_dof_tm_pair.insert({
"turb_specific_dissipation_rate_equation",
209 "turb_specific_dissipation_rate"});
211 else if (std::string::npos != _turbulence_model.find(
"SST"))
213 _equ_dof_tm_pair.insert(
214 {
"turb_kinetic_energy_equation",
"turb_kinetic_energy"});
215 _equ_dof_tm_pair.insert({
"turb_specific_dissipation_rate_equation",
216 "turb_specific_dissipation_rate"});
218 else if (std::string::npos != _turbulence_model.find(
"K-Tau"))
220 _equ_dof_tm_pair.insert(
221 {
"turb_kinetic_energy_equation",
"turb_kinetic_energy"});
222 _equ_dof_tm_pair.insert({
"turb_specific_dissipation_rate_equation",
223 "turb_specific_dissipation_rate"});
227 auto set_dofs = [&,
this](
const std::string& equ_name,
228 const std::string& dof_name) {
229 const std::string residual_name =
"RESIDUAL_" + equ_name;
230 const std::string scatter_name =
"SCATTER_" + equ_name;
231 const std::string basis_type =
"HGrad";
232 int basis_order_dof = basis_order;
233 int integration_order_dof = integration_order;
234 if (std::string::npos != _stabilization_method.find(
"Taylor-Hood"))
236 if (std::string::npos != dof_name.find(
"velocity_"))
239 integration_order_dof++;
242 this->addDOF(dof_name,
245 integration_order_dof,
248 this->addDOFGrad(dof_name);
249 this->addDOFTimeDerivative(dof_name);
253 for (
auto it : _equ_dof_ns_pair)
255 const auto equ_name = it.first;
256 const auto dof_name = it.second;
257 set_dofs(equ_name, dof_name);
261 for (
auto it : _equ_dof_ep_pair)
263 const auto equ_name = it.first;
264 const auto dof_name = it.second;
265 set_dofs(equ_name, dof_name);
269 for (
auto it : _equ_dof_tm_pair)
271 const auto equ_name = it.first;
272 const auto dof_name = it.second;
273 set_dofs(equ_name, dof_name);
277 this->addClosureModel(model_id);
282 template<
class EvalType>
283 void IncompressibleNavierStokes<EvalType>::buildAndRegisterEquationSetEvaluators(
284 PHX::FieldManager<panzer::Traits>& fm,
285 const panzer::FieldLibrary&,
286 const Teuchos::ParameterList&)
const
289 auto add_basis_time_scalar_residual = [&,
this](
290 const std::string& equ_name,
291 const std::string& residual_name,
292 const std::string& dof_name,
293 const double& multiplier,
294 std::vector<std::string>& op_names) {
295 const std::string closure_model_residual = residual_name +
"_"
297 const std::string full_residual =
"RESIDUAL_" + closure_model_residual;
298 const auto ir = this->getIntRuleForDOF(dof_name);
299 const auto basis = this->getBasisIRLayoutForDOF(dof_name);
300 auto op = Teuchos::rcp(
301 new panzer::Integrator_BasisTimesScalar<EvalType, panzer::Traits>(
302 panzer::EvaluatorStyle::EVALUATES,
304 closure_model_residual,
308 this->
template registerEvaluator<EvalType>(fm, op);
309 op_names.push_back(full_residual);
313 auto add_grad_basis_time_residual = [&,
this](
314 const std::string& equ_name,
315 const std::string& residual_name,
316 const std::string& dof_name,
317 const double& multiplier,
318 std::vector<std::string>& op_names) {
319 const std::string closure_model_residual = residual_name +
"_"
321 const std::string full_residual =
"RESIDUAL_" + closure_model_residual;
322 const auto ir = this->getIntRuleForDOF(dof_name);
323 const auto basis = this->getBasisIRLayoutForDOF(dof_name);
324 auto op = Teuchos::rcp(
325 new panzer::Integrator_GradBasisDotVector<EvalType, panzer::Traits>(
326 panzer::EvaluatorStyle::EVALUATES,
328 closure_model_residual,
332 this->
template registerEvaluator<EvalType>(fm, op);
333 op_names.push_back(full_residual);
337 for (
auto it : _equ_dof_ns_pair)
340 const auto equ_name = it.first;
341 const auto dof_name = it.second;
342 std::vector<std::string> residual_operator_names;
345 add_basis_time_scalar_residual(
346 equ_name,
"DQDT", dof_name, 1.0, residual_operator_names);
349 if (_continuity_model == ConModel::EDACTempNC)
351 if (std::string::npos != equ_name.find(
"energy"))
353 add_basis_time_scalar_residual(equ_name,
354 "NON_CONSERVATIVE_SOURCE",
357 residual_operator_names);
362 add_grad_basis_time_residual(equ_name,
366 residual_operator_names);
372 add_grad_basis_time_residual(equ_name,
376 residual_operator_names);
380 if (_build_viscous_flux)
382 add_grad_basis_time_residual(equ_name,
386 residual_operator_names);
390 if (_build_constant_source)
393 if (std::string::npos != equ_name.find(
"momentum"))
395 add_basis_time_scalar_residual(equ_name,
399 residual_operator_names);
403 if (std::string::npos != equ_name.find(
"energy"))
405 add_basis_time_scalar_residual(equ_name,
409 residual_operator_names);
414 if (_build_buoyancy_source)
416 add_basis_time_scalar_residual(equ_name,
420 residual_operator_names);
424 if (_build_viscous_heat)
426 add_basis_time_scalar_residual(equ_name,
427 "VISCOUS_HEAT_SOURCE",
430 residual_operator_names);
434 if (_build_ind_less_equ)
437 if (std::string::npos != equ_name.find(
"momentum"))
439 add_basis_time_scalar_residual(equ_name,
443 residual_operator_names);
447 if (_build_joule_heating_source
448 && std::string::npos != equ_name.find(
"energy"))
450 add_basis_time_scalar_residual(equ_name,
454 residual_operator_names);
459 if (_build_godunov_powell_source
460 && std::string::npos != equ_name.find(
"momentum"))
462 add_basis_time_scalar_residual(equ_name,
463 "GODUNOV_POWELL_SOURCE",
466 residual_operator_names);
470 this->buildAndRegisterResidualSummationEvaluator(
471 fm, dof_name, residual_operator_names,
"RESIDUAL_" + equ_name);
475 for (
auto it : _equ_dof_ep_pair)
478 const auto equ_name = it.first;
479 const auto dof_name = it.second;
480 std::vector<std::string> residual_operator_names;
483 add_grad_basis_time_residual(equ_name,
484 "ELECTRIC_POTENTIAL_FLUX",
487 residual_operator_names);
490 this->buildAndRegisterResidualSummationEvaluator(
491 fm, dof_name, residual_operator_names,
"RESIDUAL_" + equ_name);
495 for (
auto it : _equ_dof_tm_pair)
498 const auto eq_name = it.first;
499 const auto dof_name = it.second;
500 std::vector<std::string> residual_operator_names;
503 add_basis_time_scalar_residual(
504 eq_name,
"DQDT", dof_name, 1.0, residual_operator_names);
505 add_grad_basis_time_residual(
506 eq_name,
"CONVECTIVE_FLUX", dof_name, -1.0, residual_operator_names);
507 add_grad_basis_time_residual(
508 eq_name,
"DIFFUSION_FLUX", dof_name, 1.0, residual_operator_names);
509 add_basis_time_scalar_residual(
510 eq_name,
"SOURCE", dof_name, -1.0, residual_operator_names);
513 this->buildAndRegisterResidualSummationEvaluator(
514 fm, dof_name, residual_operator_names,
"RESIDUAL_" + eq_name);
523 #endif // end VERTEXCFD_EQUATIONSET_INCOMPRESSIBLE_NAVIERSTOKES_IMPL_HPP