VertexCFD  0.0-dev
VertexCFD_InitialCondition_DivergenceAdvectionTest_impl.hpp
1 #ifndef VERTEXCFD_INITIALCONDITION_DIVERGENCEADVECTIONTEST_IMPL_HPP
2 #define VERTEXCFD_INITIALCONDITION_DIVERGENCEADVECTIONTEST_IMPL_HPP
3 
4 #include <Panzer_GlobalIndexer.hpp>
5 #include <Panzer_HierarchicParallelism.hpp>
6 #include <Panzer_PureBasis.hpp>
7 #include <Panzer_Workset_Utilities.hpp>
8 
9 #include "utils/VertexCFD_Utils_Constants.hpp"
10 #include "utils/VertexCFD_Utils_VectorField.hpp"
11 
12 #include <cmath>
13 #include <string>
14 
15 namespace VertexCFD
16 {
17 namespace InitialCondition
18 {
19 //---------------------------------------------------------------------------//
20 template<class EvalType, class Traits, int NumSpaceDim>
21 DivergenceAdvectionTest<EvalType, Traits, NumSpaceDim>::DivergenceAdvectionTest(
22  const Teuchos::ParameterList& mhd_params, const panzer::PureBasis& basis)
23  : _lagrange_pressure("lagrange_pressure", basis.functional)
24  , _basis_name(basis.name())
25  , _phi(6.0)
26  , _r0(1.0 / std::sqrt(8.0))
27  , _xy_0({0.0, 0.0, 0.0})
28  , _vel({1.0, 1.0, 0.0})
29 {
30  Teuchos::ParameterList params;
31  if (mhd_params.isSublist("Divergence Advection Test"))
32  {
33  params = mhd_params.sublist("Divergence Advection Test");
34  }
35 
36  if (params.isType<double>("Lagrange Pressure"))
37  {
38  _phi = params.get<double>("Lagrange Pressure");
39  }
40 
41  if (params.isType<double>("Divergence Bubble Radius"))
42  {
43  _r0 = params.get<double>("Divergence Bubble Radius");
44  }
45 
46  if (params.isType<Teuchos::Array<double>>("Divergence Bubble Center"))
47  {
48  const auto xy_0
49  = params.get<Teuchos::Array<double>>("Divergence Bubble Center");
50  for (int dim = 0; dim < num_space_dim; ++dim)
51  {
52  _xy_0[dim] = xy_0[dim];
53  }
54  }
55 
56  if (params.isType<Teuchos::Array<double>>("Velocity"))
57  {
58  const auto vel = params.get<Teuchos::Array<double>>("Velocity");
59  for (int dim = 0; dim < num_space_dim; ++dim)
60  {
61  _vel[dim] = vel[dim];
62  }
63  }
64 
65  this->addEvaluatedField(_lagrange_pressure);
66  this->addUnsharedField(_lagrange_pressure.fieldTag().clone());
67 
68  Utils::addEvaluatedVectorField(
69  *this, basis.functional, _velocity, "velocity_", true);
70 
71  Utils::addEvaluatedVectorField(*this,
72  basis.functional,
73  _induced_magnetic_field,
74  "induced_magnetic_field_",
75  true);
76 
77  this->setName("DivergenceAdvectionTest " + std::to_string(num_space_dim)
78  + "D Initial Condition");
79 }
80 
81 //---------------------------------------------------------------------------//
82 template<class EvalType, class Traits, int NumSpaceDim>
83 void DivergenceAdvectionTest<EvalType, Traits, NumSpaceDim>::postRegistrationSetup(
84  typename Traits::SetupData sd, PHX::FieldManager<Traits>&)
85 {
86  _basis_index = panzer::getPureBasisIndex(
87  _basis_name, (*sd.worksets_)[0], this->wda);
88 }
89 
90 //---------------------------------------------------------------------------//
91 template<class EvalType, class Traits, int NumSpaceDim>
92 void DivergenceAdvectionTest<EvalType, Traits, NumSpaceDim>::evaluateFields(
93  typename Traits::EvalData workset)
94 {
95  _basis_coords = this->wda(workset).bases[_basis_index]->basis_coordinates;
96  auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
97  workset.num_cells);
98  Kokkos::parallel_for(this->getName(), policy, *this);
99 }
100 
101 //---------------------------------------------------------------------------//
102 template<class EvalType, class Traits, int NumSpaceDim>
103 KOKKOS_INLINE_FUNCTION void
104 DivergenceAdvectionTest<EvalType, Traits, NumSpaceDim>::operator()(
105  const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
106 {
107  const int cell = team.league_rank();
108  const int num_basis = _lagrange_pressure.extent(1);
109  using Constants::pi;
110  using std::pow;
111  using std::sqrt;
112 
113  const double b_coeff = 1.0 / sqrt(4.0 * pi);
114 
115  Kokkos::parallel_for(
116  Kokkos::TeamThreadRange(team, 0, num_basis), [&](const int basis) {
117  const double x = _basis_coords(cell, basis, 0);
118  const double y = _basis_coords(cell, basis, 1);
119  const double dx = x - _xy_0[0];
120  const double dy = y - _xy_0[1];
121  const double r = sqrt(dx * dx + dy * dy);
122 
123  _lagrange_pressure(cell, basis) = _phi;
124 
125  if (r < _r0)
126  {
127  _induced_magnetic_field[0](cell, basis)
128  = b_coeff * (pow(r / _r0, 8) - 2.0 * pow(r / _r0, 4) + 1);
129  }
130  else
131  {
132  _induced_magnetic_field[0](cell, basis) = 0.0;
133  }
134  _induced_magnetic_field[1](cell, basis) = 0.0;
135 
136  _velocity[0](cell, basis) = _vel[0];
137  _velocity[1](cell, basis) = _vel[1];
138 
139  if (num_space_dim > 2)
140  {
141  // For now, set induced B_z for 3D cases to zero, so that for
142  // both 2D and 3D we do the same thing (2D has no induced Bz
143  // so we need to use the ExternalMagneticField closure in that
144  // case until / unless we switch to always solving B_z
145  // independent of mesh dimension)
146  _induced_magnetic_field[2](cell, basis) = 0.0;
147  _velocity[2](cell, basis) = _vel[2];
148  }
149  });
150 }
151 
152 //---------------------------------------------------------------------------//
153 
154 } // end namespace InitialCondition
155 } // end namespace VertexCFD
156 
157 #endif // end VERTEXCFD_INITIALCONDITION_DIVERGENCEADVECTIONTEST_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23