VertexCFD  0.0-dev
VertexCFD_EquationSet_IncompressibleLSVOF_impl.hpp
1 #ifndef VERTEXCFD_EQUATIONSET_INCOMPRESSIBLE_LSVOF_IMPL_HPP
2 #define VERTEXCFD_EQUATIONSET_INCOMPRESSIBLE_LSVOF_IMPL_HPP
3 
4 #include <Panzer_BasisIRLayout.hpp>
5 #include <Panzer_IntegrationRule.hpp>
6 
7 #include <Panzer_Integrator_BasisTimesScalar.hpp>
8 #include <Panzer_Integrator_GradBasisDotVector.hpp>
9 
10 #include <Phalanx_FieldManager.hpp>
11 
12 #include <Teuchos_ParameterList.hpp>
13 #include <Teuchos_RCP.hpp>
14 #include <Teuchos_StandardParameterEntryValidators.hpp>
15 
16 namespace VertexCFD
17 {
18 namespace EquationSet
19 {
20 //---------------------------------------------------------------------------//
21 template<class EvalType>
22 IncompressibleLSVOF<EvalType>::IncompressibleLSVOF(
23  const Teuchos::RCP<Teuchos::ParameterList>& params,
24  const int& default_integration_order,
25  const panzer::CellData& cell_data,
26  const Teuchos::RCP<panzer::GlobalData>& global_data,
27  const bool build_transient_support)
28  : panzer::EquationSet_DefaultImpl<EvalType>(params,
29  default_integration_order,
30  cell_data,
31  global_data,
32  build_transient_support)
33 {
34  // This equation set is always transient.
35  if (!this->buildTransientSupport())
36  {
37  throw std::logic_error(
38  "Transient support is required for solving all equation sets.");
39  }
40 
41  // Get the number of space dimensions.
42  _num_space_dim = cell_data.baseCellDimension();
43  if (!(_num_space_dim == 2 || _num_space_dim == 3))
44  {
45  throw std::runtime_error("Number of space dimensions not supported");
46  }
47 
48  // Extract basic model parameters
49  const int basis_order = params->get<int>("Basis Order", 1);
50  const int integration_order
51  = params->get<int>("Integration Order", basis_order + 1);
52  const std::string model_id = params->get<std::string>("Model ID");
53 
54  // LSVOF parameters
55  Teuchos::ParameterList& lsvof_params = params->sublist("LSVOF_Properties");
56 
57  _build_lsvofmom_equ
58  = params->get<bool>("Build LSVOF Navier-Stokes Equations", true);
59 
60  _lsvof_model_name = lsvof_params.get<std::string>("LSVOF Model");
61 
62  const int num_phases = lsvof_params.get<int>("Number of Phases");
63 
64  _build_lsvof_buoyancy_source
65  = lsvof_params.get<bool>("Build LSVOF Buoyancy Source", true);
66 
67  _build_lsvof_surface_tension
68  = lsvof_params.get<bool>("Build LSVOF Surface Tension", true);
69 
70  // Initialize equation names and variable names for NS equations
71  if (_build_lsvofmom_equ)
72  {
73  _equ_dof_ns_pair.insert({"continuity", "lagrange_pressure"});
74 
75  for (int d = 0; d < _num_space_dim; ++d)
76  {
77  const std::string ds = std::to_string(d);
78  _equ_dof_ns_pair.insert({"momentum_" + ds, "velocity_" + ds});
79  }
80  }
81 
82  // Initialize equation name and variable names for LSVOF equations
83  if (_lsvof_model_name == "VOF")
84  {
85  for (int n = 1; n < num_phases; ++n)
86  {
87  const std::string list_name = "Phase " + std::to_string(n);
88 
89  Teuchos::ParameterList phase_list = lsvof_params.sublist(list_name);
90 
91  const std::string phase_name
92  = phase_list.get<std::string>("Phase Name");
93 
94  const std::string phase_fraction_name = "alpha_" + phase_name;
95 
96  _equ_dof_lsvof_pair.insert(
97  {phase_fraction_name + "_equation", phase_fraction_name});
98  }
99  }
100  else if (_lsvof_model_name == "CLS")
101  {
102  _equ_dof_lsvof_pair.insert({"level_set_equation", "level_set"});
103  }
104 
105  // Functions to set dofs
106  auto set_dofs
107  = [&, this](const std::string& equ_name, const std::string& dof_name) {
108  const std::string residual_name = "RESIDUAL_" + equ_name;
109  const std::string scatter_name = "SCATTER_" + equ_name;
110  const std::string basis_type = "HGrad";
111  this->addDOF(dof_name,
112  basis_type,
113  basis_order,
114  integration_order,
115  residual_name,
116  scatter_name);
117  this->addDOFGrad(dof_name);
118  this->addDOFTimeDerivative(dof_name);
119  };
120 
121  // Setup degrees of freedom for NS equations.
122  if (_build_lsvofmom_equ)
123  {
124  for (const auto& [equ_name, dof_name] : _equ_dof_ns_pair)
125  {
126  set_dofs(equ_name, dof_name);
127  }
128  }
129 
130  // Setup degrees of freedom for LSVOF equations.
131  for (const auto& [equ_name, dof_name] : _equ_dof_lsvof_pair)
132  {
133  set_dofs(equ_name, dof_name);
134  }
135 
136  // Add closure models and set-up DOFs
137  this->addClosureModel(model_id);
138  this->setupDOFs();
139 }
140 
141 //---------------------------------------------------------------------------//
142 template<class EvalType>
143 void IncompressibleLSVOF<EvalType>::buildAndRegisterEquationSetEvaluators(
144  PHX::FieldManager<panzer::Traits>& fm,
145  const panzer::FieldLibrary&,
146  const Teuchos::ParameterList&) const
147 {
148  // Integration data. The same rule and basis is used for all DOFs in this
149  // implementation so use the first entry of `_equ_dof_lsvof_pair` to get
150  // this data.
151  const auto it = _equ_dof_lsvof_pair.begin();
152  const auto ir = this->getIntRuleForDOF(it->second);
153  const auto basis = this->getBasisIRLayoutForDOF(it->second);
154 
155  // Add basis time residuals
156  auto add_basis_time_scalar_residual = [&, this](
157  const std::string& equ_name,
158  const std::string& residual_name,
159  const double& multiplier,
160  std::vector<std::string>& op_names) {
161  const std::string closure_model_residual = residual_name + "_"
162  + equ_name;
163  const std::string full_residual = "RESIDUAL_" + closure_model_residual;
164  auto op = Teuchos::rcp(
165  new panzer::Integrator_BasisTimesScalar<EvalType, panzer::Traits>(
166  panzer::EvaluatorStyle::EVALUATES,
167  full_residual,
168  closure_model_residual,
169  *basis,
170  *ir,
171  multiplier));
172  this->template registerEvaluator<EvalType>(fm, op);
173  op_names.push_back(full_residual);
174  };
175 
176  // Add grad-basis time residuals
177  auto add_grad_basis_time_residual = [&, this](
178  const std::string& equ_name,
179  const std::string& residual_name,
180  const double& multiplier,
181  std::vector<std::string>& op_names) {
182  const std::string closure_model_residual = residual_name + "_"
183  + equ_name;
184  const std::string full_residual = "RESIDUAL_" + closure_model_residual;
185  auto op = Teuchos::rcp(
186  new panzer::Integrator_GradBasisDotVector<EvalType, panzer::Traits>(
187  panzer::EvaluatorStyle::EVALUATES,
188  full_residual,
189  closure_model_residual,
190  *basis,
191  *ir,
192  multiplier));
193  this->template registerEvaluator<EvalType>(fm, op);
194  op_names.push_back(full_residual);
195  };
196 
197  // Build total residuals for NS equations
198  if (_build_lsvofmom_equ)
199  {
200  for (const auto& [equ_name, dof_name] : _equ_dof_ns_pair)
201  {
202  std::vector<std::string> residual_operator_names;
203 
204  // Time derivative residual
205  add_basis_time_scalar_residual(
206  equ_name, "DQDT", 1.0, residual_operator_names);
207 
208  // Convective flux residual
209  add_grad_basis_time_residual(
210  equ_name, "CONVECTIVE_FLUX", -1.0, residual_operator_names);
211 
212  // Viscous flux residual
213  add_grad_basis_time_residual(
214  equ_name, "VISCOUS_FLUX", 1.0, residual_operator_names);
215 
216  // TODO: add body force, surface tension, etc. to the total
217  // residual as they are created
218 
219  if (std::string::npos != equ_name.find("momentum"))
220  {
221  // Buoyancy source residual for LSVOF
222  if (_build_lsvof_buoyancy_source)
223  {
224  add_basis_time_scalar_residual(equ_name,
225  "LSVOF_BUOYANCY_SOURCE",
226  -1.0,
227  residual_operator_names);
228  }
229 
230  if (_build_lsvof_surface_tension)
231  {
232  add_grad_basis_time_residual(equ_name,
233  "SURFACE_TENSION_FLUX",
234  1.0,
235  residual_operator_names);
236  }
237  }
238 
239  // Build and register residuals
240  this->buildAndRegisterResidualSummationEvaluator(
241  fm, dof_name, residual_operator_names, "RESIDUAL_" + equ_name);
242  }
243  }
244 
245  // Build total residuals for LSVOF equations
246  for (const auto& [equ_name, dof_name] : _equ_dof_lsvof_pair)
247  {
248  std::vector<std::string> residual_operator_names;
249 
250  // Add time and convective flux residuals
251  add_basis_time_scalar_residual(
252  equ_name, "DQDT", 1.0, residual_operator_names);
253 
254  add_grad_basis_time_residual(
255  equ_name, "CONVECTIVE_FLUX", -1.0, residual_operator_names);
256 
257  if (_lsvof_model_name == "VOF")
258  {
259  add_grad_basis_time_residual(equ_name,
260  "ARTIFICIAL_COMPRESSION",
261  -1.0,
262  residual_operator_names);
263  }
264  else if (_lsvof_model_name == "CLS")
265  {
266  add_grad_basis_time_residual(
267  equ_name, "REG", -1.0, residual_operator_names);
268  }
269 
270  // TODO: add compressive flux, source terms, etc. to total residual
271  // as they are created
272 
273  // Build and register residuals
274  this->buildAndRegisterResidualSummationEvaluator(
275  fm, dof_name, residual_operator_names, "RESIDUAL_" + equ_name);
276  }
277 }
278 
279 //---------------------------------------------------------------------------//
280 
281 } // end namespace EquationSet
282 } // end namespace VertexCFD
283 
284 #endif // end VERTEXCFD_EQUATIONSET_INCOMPRESSIBLE_LSVOF_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23