VertexCFD  0.0-dev
VertexCFD_BCStrategy_FullInductionMHDBoundaryFlux_impl.hpp
1 #ifndef VERTEXCFD_BOUNDARYCONDITION_FULLINDUCTIONMHDBOUNDARYFLUX_IMPL_HPP
2 #define VERTEXCFD_BOUNDARYCONDITION_FULLINDUCTIONMHDBOUNDARYFLUX_IMPL_HPP
3 
4 #include "boundary_conditions/VertexCFD_BoundaryState_ViscousGradient.hpp"
5 #include "boundary_conditions/VertexCFD_BoundaryState_ViscousPenaltyParameter.hpp"
6 #include "boundary_conditions/VertexCFD_Integrator_BoundaryGradBasisDotVector.hpp"
7 
8 #include "closure_models/VertexCFD_Closure_ConstantScalarField.hpp"
9 #include "closure_models/VertexCFD_Closure_ExternalMagneticField.hpp"
10 
11 #include "incompressible_solver/boundary_conditions/VertexCFD_IncompressibleBoundaryState_Factory.hpp"
12 
13 #include "incompressible_solver/closure_models/VertexCFD_Closure_IncompressibleConvectiveFlux.hpp"
14 #include "incompressible_solver/closure_models/VertexCFD_Closure_IncompressibleViscousFlux.hpp"
15 #include "incompressible_solver/fluid_properties/VertexCFD_Closure_IncompressibleFluidProperties.hpp"
16 
17 #include "full_induction_mhd_solver/boundary_conditions/VertexCFD_FullInductionBoundaryState_Factory.hpp"
18 #include "full_induction_mhd_solver/closure_models/VertexCFD_Closure_InductionConvectiveFlux.hpp"
19 #include "full_induction_mhd_solver/closure_models/VertexCFD_Closure_InductionConvectiveMomentumFlux.hpp"
20 #include "full_induction_mhd_solver/closure_models/VertexCFD_Closure_InductionResistiveFlux.hpp"
21 #include "full_induction_mhd_solver/closure_models/VertexCFD_Closure_MagneticPressure.hpp"
22 #include "full_induction_mhd_solver/closure_models/VertexCFD_Closure_TotalMagneticField.hpp"
23 #include "full_induction_mhd_solver/closure_models/VertexCFD_Closure_TotalMagneticFieldGradient.hpp"
24 #include "full_induction_mhd_solver/mhd_properties/VertexCFD_FullInductionMHDProperties.hpp"
25 
26 #include <Panzer_DOF.hpp>
27 #include <Panzer_DOFGradient.hpp>
28 #include <Panzer_DotProduct.hpp>
29 #include <Panzer_Integrator_BasisTimesScalar.hpp>
30 #include <Panzer_Normals.hpp>
31 #include <Panzer_Sum.hpp>
32 
33 #include <Phalanx_DataLayout.hpp>
34 #include <Phalanx_DataLayout_MDALayout.hpp>
35 #include <Phalanx_MDField.hpp>
36 
37 #include <map>
38 #include <string>
39 #include <vector>
40 
41 namespace VertexCFD
42 {
43 namespace BoundaryCondition
44 {
45 //---------------------------------------------------------------------------//
46 template<class EvalType, int NumSpaceDim>
47 FullInductionMHDBoundaryFlux<EvalType, NumSpaceDim>::FullInductionMHDBoundaryFlux(
48  const panzer::BC& bc, const Teuchos::RCP<panzer::GlobalData>& global_data)
49  : BoundaryFluxBase<EvalType, NumSpaceDim>(bc, global_data)
50 {
51  // Check if boundary is an internal interface between solid and fluid
52  // regions
53  _internal_interface = bc.params()->isType<bool>("Fluid/Solid Interface")
54  ? bc.params()->get<bool>("Fluid/Solid Interface")
55  : false;
56 }
57 
58 //---------------------------------------------------------------------------//
59 template<class EvalType, int NumSpaceDim>
60 void FullInductionMHDBoundaryFlux<EvalType, NumSpaceDim>::setup(
61  const panzer::PhysicsBlock& side_pb,
62  const Teuchos::ParameterList& /*user_data*/)
63 {
64  // Get the physics block parameters associated with this sideset,
65  // and extract necessary information, including "Model IDs" for
66  // the incompressible NS and full induction closure models
67  const auto side_pb_params = *side_pb.getParameterList();
68  bool build_magn_corr = false;
69  for (int i = 0; i < side_pb_params.numParams(); ++i)
70  {
71  const std::string name = "child" + std::to_string(i);
72  if (side_pb_params.isSublist(name))
73  {
74  const auto& sl = side_pb_params.sublist(name);
75  const auto& type = sl.get<std::string>("Type");
76  if (type == "FullInductionMHD")
77  {
78  _induction_model_id = sl.get<std::string>("Model ID");
79  if (sl.isType<bool>("Build Magnetic Correction Potential "
80  "Equation"))
81  {
82  build_magn_corr = sl.get<bool>(
83  "Build Magnetic Correction Potential Equation");
84  }
85  }
86  else if (type == "IncompressibleNavierStokes")
87  {
88  _incompressible_model_id = sl.get<std::string>("Model ID");
89  _build_viscous_flux = sl.get<bool>("Build Viscous Flux");
90  }
91  }
92  }
93 
94  // Internal interface case: magnetic field and correction potential should
95  // not require boundary condition flux.
96  _build_full_induction_model = !(_internal_interface);
97 
98  // Initialize equation names and variable names for NS equations.
99  _equ_dof_ns_pair.insert({"continuity", "lagrange_pressure"});
100  for (int d = 0; d < num_space_dim; ++d)
101  {
102  const std::string ds = std::to_string(d);
103  _equ_dof_ns_pair.insert({"momentum_" + ds, "velocity_" + ds});
104  }
105 
106  // Initialize equation names and variables for FIM. The induced magnetic
107  // field DOFs are required even on interfaces to evaluate the magnetic flux
108  // contribution to the momentum equations.
109  for (int d = 0; d < num_space_dim; ++d)
110  {
111  const std::string ds = std::to_string(d);
112  _equ_dof_fim_pair.insert(
113  {"induction_" + ds, "induced_magnetic_field_" + ds});
114  }
115  if (build_magn_corr)
116  {
117  _equ_dof_fim_pair.insert(
118  {"magnetic_correction_potential", "scalar_magnetic_potential"});
119  }
120 
121  // Initialize parent class variables (only needed with one set of
122  // equations)
123  this->initialize(side_pb, _equ_dof_ns_pair);
124 }
125 
126 //---------------------------------------------------------------------------//
127 template<class EvalType, int NumSpaceDim>
128 void FullInductionMHDBoundaryFlux<EvalType, NumSpaceDim>::buildAndRegisterEvaluators(
129  PHX::FieldManager<panzer::Traits>& fm,
130  const panzer::PhysicsBlock& side_pb,
131  const panzer::ClosureModelFactory_TemplateManager<panzer::Traits>&,
132  const Teuchos::ParameterList& closure_models,
133  const Teuchos::ParameterList& user_data) const
134 {
135  // Map to store residuals for each equation listed in `_equ_dof_ns_pair`
136  std::unordered_map<std::string, std::vector<std::string>> eq_vct_map;
137 
138  // Get integration rule for closure models
139  const auto& ir = this->integrationRule();
140 
141  // Create degree of freedom and gradients for NS equations
142  for (auto& pair : _equ_dof_ns_pair)
143  {
144  this->registerDOFsGradient(fm, side_pb, pair.second);
145  }
146 
147  // Create degree of freedom and gradients for TM equations
148  for (auto& pair : _equ_dof_fim_pair)
149  {
150  this->registerDOFsGradient(fm, side_pb, pair.second);
151  }
152 
153  // Register normals
154  this->registerSideNormals(fm, side_pb);
155 
156  // Fluid properties: model id is stored in a sublist
157  Teuchos::ParameterList fluid_params
158  = closure_models.sublist(_incompressible_model_id)
159  .sublist("Fluid Properties");
160 
161  fluid_params.set<bool>("Build Temperature Equation", false);
162  fluid_params.set<bool>("Build Buoyancy Source", false);
163  fluid_params.set<bool>("Build Inductionless MHD Equation", false);
164 
165  auto eval = Teuchos::rcp(
166  new FluidProperties::IncompressibleFluidProperties<EvalType,
167  panzer::Traits>(
168  *ir, fluid_params));
169  this->template registerEvaluator<EvalType>(fm, eval);
170 
171  // Create boundary state operators for NS equations
172  // Get bc sublist
173  const auto bc_params = *(this->m_bc.params());
174 
175  // NS equations
176  const auto ns_bc_sublist = bc_params.isSublist("Navier-Stokes")
177  ? bc_params.sublist("Navier-Stokes")
178  : bc_params;
179  auto incomp_ns_boundary_state_op = IncompressibleBoundaryStateFactory<
180  EvalType,
181  panzer::Traits,
182  num_space_dim>::create(*ir, ns_bc_sublist, fluid_params);
183  this->template registerEvaluator<EvalType>(fm, incomp_ns_boundary_state_op);
184 
185  // First-order flux //
186 
187  // Create boundary convective fluxes for NS equations
188  auto convective_flux_op = Teuchos::rcp(
189  new ClosureModel::IncompressibleConvectiveFlux<EvalType,
190  panzer::Traits,
191  num_space_dim>(
192  *ir, fluid_params, "BOUNDARY_", "BOUNDARY_"));
193  this->template registerEvaluator<EvalType>(fm, convective_flux_op);
194 
195  for (auto& pair : _equ_dof_ns_pair)
196  {
197  this->registerConvectionTypeFluxOperator(
198  pair, eq_vct_map, "CONVECTIVE", fm, side_pb, 1.0);
199  }
200 
201  // Second-order flux //
202 
203  // NS equations
204  if (_build_viscous_flux)
205  {
206  // Check if the BC is a wall function type
207  const Teuchos::ParameterList ns_bc_params
208  = bc_params.isSublist("Navier-Stokes")
209  ? bc_params.sublist("Navier-Stokes")
210  : bc_params;
211  const std::string bc_type = ns_bc_params.get<std::string>("Type");
212 
213  // Register penalty and viscous gradient operators for each equation.
214  for (auto& pair : _equ_dof_ns_pair)
215  {
216  this->registerPenaltyAndViscousGradientOperator(
217  pair, fm, side_pb, bc_params);
218  }
219 
220  // Create boundary fluxes to be used with the penalty method
221  for (auto& pair : this->bnd_prefix)
222  {
223  // Prefix names
224  const std::string flux_prefix = pair.first;
225  const std::string gradient_prefix = pair.second;
226 
227  const bool turb_model = false;
228  const auto viscous_flux_op = Teuchos::rcp(
229  new ClosureModel::IncompressibleViscousFlux<EvalType,
230  panzer::Traits,
231  num_space_dim>(
232  *ir,
233  fluid_params,
234  user_data,
235  turb_model,
236  flux_prefix,
237  gradient_prefix));
238  this->template registerEvaluator<EvalType>(fm, viscous_flux_op);
239  }
240 
241  // Create viscous flux integrals.
242  for (auto& pair : _equ_dof_ns_pair)
243  {
244  this->registerViscousTypeFluxOperator(
245  pair, eq_vct_map, "VISCOUS", fm, side_pb, 1.0);
246  }
247  }
248 
249  // Full Induction Model boundary fluxes
250  const auto full_induction_params
251  = closure_models.sublist(_induction_model_id)
252  .sublist("Full Induction MHD Properties");
253  const MHDProperties::FullInductionMHDProperties mhd_props(
254  full_induction_params);
255 
256  // Add total magnetic field and magnetic pressure closures, which are
257  // always required for the momentum equation fluxes. For interfaces, build
258  // total magnetic field with no prefix, otherwise use the "BOUNDARY_"
259  // prefix to ensure the boundary values are used as appropriate.
260  const auto ext_magn_field_op = Teuchos::rcp(
261  new ClosureModel::ExternalMagneticField<EvalType, panzer::Traits>(
262  *ir, user_data));
263  this->template registerEvaluator<EvalType>(fm, ext_magn_field_op);
264 
265  const std::string tot_magn_field_prefix
266  = _build_full_induction_model ? "BOUNDARY_" : "";
267 
268  const auto tot_magn_field_op = Teuchos::rcp(
269  new ClosureModel::TotalMagneticField<EvalType, panzer::Traits, num_space_dim>(
270  *ir, tot_magn_field_prefix));
271  this->template registerEvaluator<EvalType>(fm, tot_magn_field_op);
272 
273  const auto magn_press_op = Teuchos::rcp(
274  new ClosureModel::MagneticPressure<EvalType, panzer::Traits>(
275  *ir, mhd_props));
276  this->template registerEvaluator<EvalType>(fm, magn_press_op);
277 
278  // Contribution to momentum convective fluxes from induction is always
279  // included
280  const auto induction_mtm_flux_op = Teuchos::rcp(
281  new ClosureModel::InductionConvectiveMomentumFlux<EvalType,
282  panzer::Traits,
283  num_space_dim>(
284  *ir, mhd_props, "BOUNDARY_"));
285  this->template registerEvaluator<EvalType>(fm, induction_mtm_flux_op);
286 
287  // Build fluxes for induction equations on external boundaries
288  if (_build_full_induction_model)
289  {
290  // Register boundary conditions for the induciton equations
291  const auto fim_boundary_state_op = FullInductionBoundaryStateFactory<
292  EvalType,
293  panzer::Traits,
294  num_space_dim>::create(*ir,
295  bc_params.sublist("Full Induction Model"),
296  mhd_props);
297  this->template registerEvaluator<EvalType>(fm, fim_boundary_state_op);
298 
299  const auto induction_flux_op = Teuchos::rcp(
300  new ClosureModel::InductionConvectiveFlux<EvalType,
301  panzer::Traits,
302  num_space_dim>(
303  *ir, mhd_props, "BOUNDARY_", "BOUNDARY_"));
304  this->template registerEvaluator<EvalType>(fm, induction_flux_op);
305 
306  for (auto& pair_fim : _equ_dof_fim_pair)
307  {
308  BoundaryFluxBase<EvalType, NumSpaceDim>::registerConvectionTypeFluxOperator(
309  pair_fim, eq_vct_map, "CONVECTIVE", fm, side_pb, 1.0);
310  }
311 
312  if (mhd_props.buildResistiveFlux())
313  {
314  const auto resistivity_op = Teuchos::rcp(
315  new ClosureModel::ConstantScalarField<EvalType, panzer::Traits>(
316  *ir, "resistivity", mhd_props.resistivity()));
317  this->template registerEvaluator<EvalType>(fm, resistivity_op);
318 
319  for (auto& pair_fim : _equ_dof_fim_pair)
320  {
321  // Register penalty and resistive gradient operators for each
322  // equation.
323  BoundaryFluxBase<EvalType, NumSpaceDim>::
324  registerPenaltyAndViscousGradientOperator(
325  pair_fim, fm, side_pb, bc_params);
326 
327  // Create boundary fluxes to be used with the penalty method
328  for (auto& pair_bnd :
329  BoundaryFluxBase<EvalType, NumSpaceDim>::bnd_prefix)
330  {
331  const std::string flux_prefix = pair_bnd.first;
332  const std::string gradient_prefix = pair_bnd.second;
333 
334  // Need total magnetic field symmetry and penalty gradients
335  const auto tot_magn_field_grad_op = Teuchos::rcp(
336  new ClosureModel::TotalMagneticFieldGradient<
337  EvalType,
338  panzer::Traits,
339  NumSpaceDim>(*ir, gradient_prefix));
340  this->template registerEvaluator<EvalType>(
341  fm, tot_magn_field_grad_op);
342 
343  const auto resistive_flux_op = Teuchos::rcp(
344  new ClosureModel::InductionResistiveFlux<EvalType,
345  panzer::Traits,
346  NumSpaceDim>(
347  *ir, mhd_props, flux_prefix, gradient_prefix));
348  this->template registerEvaluator<EvalType>(
349  fm, resistive_flux_op);
350  }
351  // Create resistive flux integral
352  BoundaryFluxBase<EvalType, NumSpaceDim>::registerViscousTypeFluxOperator(
353  pair_fim, eq_vct_map, "RESISTIVE", fm, side_pb, 1.0);
354  }
355  }
356  }
357 
358  // Compose total residual for NS equations
359  for (auto& pair : _equ_dof_ns_pair)
360  {
361  this->registerResidual(pair, eq_vct_map, fm, side_pb);
362  }
363 
364  // Compose total residual for FIM equations
365  if (_build_full_induction_model)
366  {
367  for (auto& pair : _equ_dof_fim_pair)
368  {
369  BoundaryFluxBase<EvalType, NumSpaceDim>::registerResidual(
370  pair, eq_vct_map, fm, side_pb);
371  }
372  }
373 }
374 
375 //---------------------------------------------------------------------------//
376 template<class EvalType, int NumSpaceDim>
377 void FullInductionMHDBoundaryFlux<EvalType, NumSpaceDim>::
378  buildAndRegisterScatterEvaluators(
379  PHX::FieldManager<panzer::Traits>& fm,
380  const panzer::PhysicsBlock& side_pb,
381  const panzer::LinearObjFactory<panzer::Traits>& lof,
382  const Teuchos::ParameterList& /*user_data*/) const
383 {
384  for (auto& pair : _equ_dof_ns_pair)
385  {
386  this->registerScatterOperator(pair, fm, side_pb, lof);
387  }
388 
389  if (_build_full_induction_model)
390  {
391  for (auto& pair : _equ_dof_fim_pair)
392  {
394  pair, fm, side_pb, lof);
395  }
396  }
397 }
398 
399 //---------------------------------------------------------------------------//
400 template<class EvalType, int NumSpaceDim>
401 void FullInductionMHDBoundaryFlux<EvalType, NumSpaceDim>::
402  buildAndRegisterGatherAndOrientationEvaluators(
403  PHX::FieldManager<panzer::Traits>& fm,
404  const panzer::PhysicsBlock& side_pb,
405  const panzer::LinearObjFactory<panzer::Traits>& lof,
406  const Teuchos::ParameterList& user_data) const
407 {
408  side_pb.buildAndRegisterGatherAndOrientationEvaluators(fm, lof, user_data);
409 }
410 
411 //---------------------------------------------------------------------------//
412 template<class EvalType, int NumSpaceDim>
413 void FullInductionMHDBoundaryFlux<EvalType, NumSpaceDim>::postRegistrationSetup(
414  typename panzer::Traits::SetupData, PHX::FieldManager<panzer::Traits>&)
415 {
416 }
417 
418 //---------------------------------------------------------------------------//
419 template<class EvalType, int NumSpaceDim>
420 void FullInductionMHDBoundaryFlux<EvalType, NumSpaceDim>::evaluateFields(
421  typename panzer::Traits::EvalData)
422 {
423 }
424 
425 //---------------------------------------------------------------------------//
426 
427 } // end namespace BoundaryCondition
428 } // end namespace VertexCFD
429 
430 #endif // end VERTEXCFD_BOUNDARYCONDITION_FULLINDUCTIONMHDBOUNDARYFLUX_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23
VertexCFD::BoundaryCondition::BoundaryFluxBase::registerScatterOperator
void registerScatterOperator(std::pair< const std::string, std::string > dof_eq_pair, PHX::FieldManager< panzer::Traits > &fm, const panzer::PhysicsBlock &side_pb, const panzer::LinearObjFactory< panzer::Traits > &lof) const
Definition: VertexCFD_BCStrategy_BoundaryFluxBase_impl.hpp:369