VertexCFD  0.0-dev
VertexCFD_Closure_InductionResistiveFlux_impl.hpp
1 #ifndef VERTEXCFD_CLOSURE_INDUCTIONRESISTIVEFLUX_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_INDUCTIONRESISTIVEFLUX_IMPL_HPP
3 
4 #include "utils/VertexCFD_Utils_MagneticLayout.hpp"
5 #include "utils/VertexCFD_Utils_VectorField.hpp"
6 
7 #include <Panzer_HierarchicParallelism.hpp>
8 
9 namespace VertexCFD
10 {
11 namespace ClosureModel
12 {
13 //---------------------------------------------------------------------------//
14 template<class EvalType, class Traits, int NumSpaceDim>
15 InductionResistiveFlux<EvalType, Traits, NumSpaceDim>::InductionResistiveFlux(
16  const panzer::IntegrationRule& ir,
17  const MHDProperties::FullInductionMHDProperties& mhd_props,
18  const std::string& flux_prefix,
19  const std::string& gradient_prefix)
20  : _magnetic_correction_potential_flux(
21  flux_prefix + "RESISTIVE_FLUX_magnetic_correction_potential",
22  ir.dl_vector)
23  , _total_magnetic_field(
24  "total_magnetic_field",
25  Utils::buildMagneticLayout(ir.dl_scalar, num_magnetic_field_dim))
26  , _resistivity("resistivity", ir.dl_scalar)
27  , _grad_total_magnetic_field(
28  gradient_prefix + "GRAD_total_magnetic_field",
29  Utils::buildMagneticGradLayout(ir.dl_vector, num_magnetic_field_dim))
30  , _divergence_total_magnetic_field(
31  gradient_prefix + "divergence_total_magnetic_field", ir.dl_scalar)
32  , _grad_resistivity("GRAD_resistivity", ir.dl_vector)
33  , _variable_resistivity(mhd_props.variableResistivity())
34  , _solve_magn_corr(mhd_props.buildMagnCorr())
35  , _magnetic_permeability(mhd_props.vacuumMagneticPermeability())
36 {
37  // Evaluated fields
38  this->addEvaluatedField(_magnetic_correction_potential_flux);
39 
40  Utils::addEvaluatedVectorField(*this, ir.dl_vector, _induction_flux,
41  flux_prefix + "RESISTIVE_FLUX_"
42  "induction_");
43 
44  if (_solve_magn_corr)
45  {
46  this->addEvaluatedField(_magnetic_correction_potential_flux);
47  }
48 
49  // Dependent fields
50  this->addDependentField(_total_magnetic_field);
51  this->addDependentField(_resistivity);
52  this->addDependentField(_grad_total_magnetic_field);
53  this->addDependentField(_divergence_total_magnetic_field);
54  if (_variable_resistivity)
55  {
56  this->addDependentField(_grad_resistivity);
57  }
58 
59  this->setName("Induction Resistive Flux " + std::to_string(num_space_dim)
60  + "D");
61 }
62 
63 //---------------------------------------------------------------------------//
64 template<class EvalType, class Traits, int NumSpaceDim>
65 void InductionResistiveFlux<EvalType, Traits, NumSpaceDim>::evaluateFields(
66  typename Traits::EvalData workset)
67 {
68  auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
69  workset.num_cells);
70  Kokkos::parallel_for(this->getName(), policy, *this);
71 }
72 
73 //---------------------------------------------------------------------------//
74 template<class EvalType, class Traits, int NumSpaceDim>
75 KOKKOS_INLINE_FUNCTION void
76 InductionResistiveFlux<EvalType, Traits, NumSpaceDim>::operator()(
77  const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
78 {
79  const int cell = team.league_rank();
80  const int num_point = _induction_flux[0].extent(1);
81  const int num_grad_dim = _induction_flux[0].extent(2);
82  const double mu_0_inv = 1.0 / _magnetic_permeability;
83 
84  Kokkos::parallel_for(
85  Kokkos::TeamThreadRange(team, 0, num_point), [&](const int point) {
86  // eta * Grad(B) contribution
87  for (int flux_dim = 0; flux_dim < num_grad_dim; ++flux_dim)
88  {
89  for (int vec_dim = 0; vec_dim < num_space_dim; ++vec_dim)
90  {
91  _induction_flux[vec_dim](cell, point, flux_dim)
92  = _resistivity(cell, point)
93  * _grad_total_magnetic_field(
94  cell, point, flux_dim, vec_dim);
95  }
96  }
97 
98  if (_variable_resistivity)
99  {
100  // B \otimes grad(eta) contribution
101  for (int flux_dim = 0; flux_dim < num_grad_dim; ++flux_dim)
102  {
103  for (int vec_dim = 0; vec_dim < num_grad_dim; ++vec_dim)
104  {
105  _induction_flux[vec_dim](cell, point, flux_dim)
106  += _total_magnetic_field(cell, point, flux_dim)
107  * _grad_resistivity(cell, point, vec_dim);
108  }
109  }
110  }
111 
112  // -Div(eta B) * I component: Div(eta B) = eta*Div(B) + grad(eta).B
113  // eta*Div(B):
114  for (int dim = 0; dim < num_grad_dim; ++dim)
115  {
116  _induction_flux[dim](cell, point, dim)
117  -= _resistivity(cell, point)
118  * _divergence_total_magnetic_field(cell, point);
119  }
120 
121  if (_variable_resistivity)
122  {
123  // grad(eta).B contribution to Div(eta B)
124  for (int flux_dim = 0; flux_dim < num_grad_dim; ++flux_dim)
125  {
126  for (int grad_dim = 0; grad_dim < num_grad_dim; ++grad_dim)
127  {
128  _induction_flux[flux_dim](cell, point, flux_dim)
129  -= _grad_resistivity(cell, point, grad_dim)
130  * _total_magnetic_field(cell, point, grad_dim);
131  }
132  }
133 
134  // B \otimes grad(eta) term
135  for (int flux_dim = 0; flux_dim < num_grad_dim; ++flux_dim)
136  {
137  for (int vec_dim = 0; vec_dim < num_grad_dim; ++vec_dim)
138  {
139  _induction_flux[vec_dim](cell, point, flux_dim)
140  += _total_magnetic_field(cell, point, flux_dim)
141  * _grad_resistivity(cell, point, vec_dim);
142  }
143  }
144  }
145 
146  // every term has eta or grad(eta), so can scale once by mu_0 to
147  // recover \hat(eta)
148  for (int flux_dim = 0; flux_dim < num_grad_dim; ++flux_dim)
149  {
150  for (int vec_dim = 0; vec_dim < num_space_dim; ++vec_dim)
151  {
152  _induction_flux[vec_dim](cell, point, flux_dim) *= mu_0_inv;
153  }
154  }
155 
156  if (_solve_magn_corr)
157  {
158  for (int flux_dim = 0; flux_dim < num_grad_dim; ++flux_dim)
159  {
160  _magnetic_correction_potential_flux(cell, point, flux_dim)
161  = 0.0;
162  }
163  }
164  });
165 }
166 
167 //---------------------------------------------------------------------------//
168 
169 } // end namespace ClosureModel
170 } // end namespace VertexCFD
171 
172 #endif // end VERTEXCFD_CLOSURE_INDUCTIONRESISTIVEFLUX_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23