VertexCFD  0.0-dev
VertexCFD_Closure_IncompressibleConstantSource_impl.hpp
1 #ifndef VERTEXCFD_CLOSURE_CONSTANTSOURCE_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_CONSTANTSOURCE_IMPL_HPP
3 
4 #include "utils/VertexCFD_Utils_VectorField.hpp"
5 
6 #include <Panzer_HierarchicParallelism.hpp>
7 
8 #include <Teuchos_StandardParameterEntryValidators.hpp>
9 
10 #include <string>
11 
12 namespace VertexCFD
13 {
14 namespace ClosureModel
15 {
16 //---------------------------------------------------------------------------//
17 template<class EvalType, class Traits, int NumSpaceDim>
18 IncompressibleConstantSource<EvalType, Traits, NumSpaceDim>::
19  IncompressibleConstantSource(
20  const panzer::IntegrationRule& ir,
21  const Teuchos::ParameterList& fluid_params,
22  const Teuchos::RCP<panzer::GlobalData>& global_data,
23  const Teuchos::ParameterList& closure_params)
24  : _energy_source("CONSTANT_SOURCE_energy", ir.dl_scalar)
25  , _global_data(global_data)
26  , _solve_temp(fluid_params.get<bool>("Build Temperature Equation"))
27  , _solve_ind_less_mhd(fluid_params.get<bool>("Build Inductionless MHD "
28  "Equation"))
29  , _flow_direction(FlowDirection::x)
30  , _const_vol_flow(false)
31 {
32  if (closure_params.isType<bool>("Constant Volumetric Flow Rate"))
33  _const_vol_flow
34  = closure_params.get<bool>("Constant Volumetric Flow Rate");
35 
36  if (_const_vol_flow)
37  {
38  _m_target = closure_params.get<double>("Target Volumetric Flow Rate");
39  _bottom_wall_area
40  = closure_params.get<double>("Bottom Wall Surface Area");
41  _inlet_wall_area
42  = closure_params.get<double>("Inlet Wall Surface Area");
43  _flow_direction_idx = 0;
44  if (closure_params.isType<std::string>("Flow Direction"))
45  {
46  const auto type_validator = Teuchos::rcp(
47  new Teuchos::StringToIntegralParameterEntryValidator<FlowDirection>(
48  Teuchos::tuple<std::string>("x", "y", "z"), "x"));
49  _flow_direction = type_validator->getIntegralValue(
50  closure_params.get<std::string>("Flow Direction"));
51  if (_flow_direction == FlowDirection::x)
52  _flow_direction_idx = 0;
53  if (_flow_direction == FlowDirection::y)
54  _flow_direction_idx = 1;
55  if (_flow_direction == FlowDirection::z)
56  _flow_direction_idx = 2;
57  }
58  }
59  else
60  {
61  const auto mom_input_source
62  = closure_params.get<Teuchos::Array<double>>("Momentum Source");
63  for (int dim = 0; dim < num_space_dim; ++dim)
64  {
65  _mom_input_source[dim] = mom_input_source[dim];
66  }
67  }
68 
69  // Evaluated fields
70  Utils::addEvaluatedVectorField(*this,
71  ir.dl_scalar,
72  _momentum_source,
73  "CONSTANT_SOURCE_"
74  "momentum_");
75 
76  if (_solve_temp)
77  {
78  _energy_input_source = closure_params.get<double>("Energy Source");
79  this->addEvaluatedField(_energy_source);
80  }
81 
82  // Dependent fields
83  this->setName("Incompressible Constant Source "
84  + std::to_string(num_space_dim) + "D");
85 }
86 
87 //---------------------------------------------------------------------------//
88 template<class EvalType, class Traits, int NumSpaceDim>
89 void
90  IncompressibleConstantSource<EvalType, Traits, NumSpaceDim>::evaluateFields(
91  typename Traits::EvalData /* workset */)
92 {
93  if (_const_vol_flow)
94  {
95  const auto& pl = *_global_data->pl;
96  const std::string m_bc_name = "Volumetric Flow Rate - velocity_"
97  + std::to_string(_flow_direction_idx);
98  _m_bc = pl.getValue<EvalType>(m_bc_name);
99 
100  const std::string wall_shear_stress_name
101  = "Wall Shear Stress - wall_shear_stress";
102  _wall_shear_stress = pl.getValue<EvalType>(wall_shear_stress_name)
103  / _bottom_wall_area;
104 
105  if (_solve_ind_less_mhd)
106  {
107  const std::string lorentz_name
108  = "Lorentz Force - VOLUMETRIC_SOURCE_momentum_"
109  + std::to_string(_flow_direction_idx);
110  _lorentz_force = pl.getValue<EvalType>(lorentz_name)
111  / _inlet_wall_area;
112  }
113  }
114  for (int mom_dim = 0; mom_dim < num_space_dim; ++mom_dim)
115  {
116  if (_const_vol_flow)
117  {
118  if (mom_dim == _flow_direction_idx)
119  {
120  // Calculate the friction loss (wall shear stress on the bottom
121  // and top surfaces (bottom = top))
122  _mom_input_source[mom_dim]
123  = _m_target / _m_bc
124  * (2.0 * _wall_shear_stress / _inlet_wall_area);
125  // If lorentz force is available, add the contribution from the
126  // magnetic field induced drag
127  if (_solve_ind_less_mhd)
128  _mom_input_source[mom_dim] -= _m_target / _m_bc
129  * _lorentz_force;
130  }
131  else
132  _mom_input_source[mom_dim] = 0.0;
133  }
134 
135  Kokkos::deep_copy(_momentum_source[mom_dim].get_view(),
136  _mom_input_source[mom_dim]);
137  }
138 
139  if (_solve_temp)
140  Kokkos::deep_copy(_energy_source.get_view(), _energy_input_source);
141 }
142 
143 //---------------------------------------------------------------------------//
144 
145 } // end namespace ClosureModel
146 } // end namespace VertexCFD
147 
148 #endif // end VERTEXCFD_CLOSURE_CONSTANTSOURCE_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23