VertexCFD  0.0-dev
VertexCFD_Closure_RADBADExactSolution_impl.hpp
1 #ifndef VERTEXCFD_CLOSURE_RADBADExactSolution_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_RADBADExactSolution_IMPL_HPP
3 
4 #include "utils/VertexCFD_Utils_ScalarFieldView.hpp"
5 #include "utils/VertexCFD_Utils_VectorField.hpp"
6 
7 #include <Panzer_GlobalIndexer.hpp>
8 #include <Panzer_HierarchicParallelism.hpp>
9 #include <Panzer_PureBasis.hpp>
10 #include <Panzer_Workset_Utilities.hpp>
11 
12 #include <Teuchos_Array.hpp>
13 
14 #include <cmath>
15 #include <string>
16 
17 namespace VertexCFD
18 {
19 namespace ClosureModel
20 {
21 //---------------------------------------------------------------------------//
22 template<class EvalType, class Traits, int NumSpaceDim>
23 RADBADExactSolution<EvalType, Traits, NumSpaceDim>::RADBADExactSolution(
24  const panzer::IntegrationRule& ir,
25  const SpeciesProperties::ConstantSpeciesProperties& species_prop,
26  const Teuchos::ParameterList& closure_params)
27  : _num_species(species_prop.numSpecies())
28  , _ir_degree(ir.cubature_degree)
29  , _nu(species_prop.constantDiffusionCoefficient())
30  , _bateman_matrix(Kokkos::ViewAllocateWithoutInitializing("bateman_"
31  "matrix"),
32  _num_species,
33  _num_species)
34  , _build_bateman(species_prop.buildBateman())
35  , _build_advection(species_prop.buildAdvection())
36  , _build_diffusion(species_prop.buildDiffusion())
37 {
38  // Copy bateman matrix from host to device
39  auto bateman_matrix_host
40  = Kokkos::create_mirror_view(Kokkos::HostSpace{}, _bateman_matrix);
41  bateman_matrix_host = species_prop.batemanMatrix();
42  Kokkos::deep_copy(_bateman_matrix, bateman_matrix_host);
43 
44  const auto scale
45  = closure_params.get<Teuchos::Array<double>>("Initial Amplitude");
46  for (int i = 0; i < _num_species; ++i)
47  {
48  _scale[i] = scale[i];
49  }
50 
51  if (_build_advection || _build_diffusion)
52  {
53  _init_loc = closure_params.get<double>("Initial Location");
54  _sigma = closure_params.get<double>("Sigma");
55  }
56 
57  Utils::addEvaluatedScalarFieldView(
58  *this, ir.dl_scalar, _num_species, _exact_species, "Exact_species_");
59 
60  if (_build_advection)
61  Utils::addDependentVectorField(
62  *this, ir.dl_scalar, _velocity, "velocity_");
63 
64  this->setName("RAD Exact Solution");
65 }
66 
67 //---------------------------------------------------------------------------//
68 template<class EvalType, class Traits, int NumSpaceDim>
69 void RADBADExactSolution<EvalType, Traits, NumSpaceDim>::postRegistrationSetup(
70  typename Traits::SetupData sd, PHX::FieldManager<Traits>&)
71 {
72  _ir_index = panzer::getIntegrationRuleIndex(_ir_degree, (*sd.worksets_)[0]);
73 }
74 
75 //---------------------------------------------------------------------------//
76 template<class EvalType, class Traits, int NumSpaceDim>
77 void RADBADExactSolution<EvalType, Traits, NumSpaceDim>::evaluateFields(
78  typename Traits::EvalData workset)
79 {
80  // Allocate space for thread-local temporaries
81  size_t bytes;
82  if constexpr (Sacado::IsADType<scalar_type>::value)
83  {
84  const int fad_size
85  = Kokkos::dimension_scalar(_exact_species[0].get_view());
86  bytes = scratch_view::shmem_size(
87  _exact_species[0].extent(1), NUM_TMPS, fad_size);
88  }
89  else
90  {
91  bytes = scratch_view::shmem_size(_exact_species[0].extent(1), NUM_TMPS);
92  }
93 
94  auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
95  workset.num_cells);
96  policy.set_scratch_size(0, Kokkos::PerTeam(bytes));
97  _time = workset.time;
98  _ip_coords = workset.int_rules[_ir_index]->ip_coordinates;
99  Kokkos::parallel_for(this->getName(), policy, *this);
100 }
101 
102 //---------------------------------------------------------------------------//
103 template<class EvalType, class Traits, int NumSpaceDim>
104 KOKKOS_INLINE_FUNCTION void
105 RADBADExactSolution<EvalType, Traits, NumSpaceDim>::operator()(
106  const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
107 {
108  const int cell = team.league_rank();
109  const int num_point = _exact_species[0].extent(1);
110 
111  using Kokkos::exp;
112  using Kokkos::pow;
113  using Kokkos::sqrt;
114 
115  scratch_view tmp_field;
116  if constexpr (Sacado::IsADType<scalar_type>::value)
117  {
118  const int fad_size
119  = Kokkos::dimension_scalar(_exact_species[0].get_view());
120  tmp_field
121  = scratch_view(team.team_shmem(), num_point, NUM_TMPS, fad_size);
122  }
123  else
124  {
125  tmp_field = scratch_view(team.team_shmem(), num_point, NUM_TMPS);
126  }
127 
128  Kokkos::parallel_for(
129  Kokkos::TeamThreadRange(team, 0, num_point), [&](const int point) {
130  auto&& gaussian = tmp_field(point, GAUSSIAN);
131  auto&& denum = tmp_field(point, DENUM);
132 
133  auto&& sum_k = tmp_field(point, SUM_K);
134  auto&& prod_l = tmp_field(point, PROD_L);
135  auto&& lmbd_prod = tmp_field(point, LMBD_PROD);
136 
137  gaussian = 0.0;
138  denum = 0.0;
139 
140  sum_k = 0.0;
141  prod_l = 1.0;
142  lmbd_prod = 1.0;
143  if (_build_advection || _build_diffusion)
144  {
145  for (int num = 0; num < _num_species; ++num)
146  {
147  _exact_species[num](cell, point) = 0.0;
148  for (int dim = 0; dim < 1; ++dim)
149  {
150  gaussian = _ip_coords(cell, point, dim) - _init_loc;
151 
152  if (_build_advection)
153  gaussian -= _time * _velocity[dim](cell, point);
154 
155  denum = _sigma * _sigma;
156 
157  if (_build_diffusion)
158  denum += 2 * _nu * _time;
159 
160  for (int i = 0; i < 1000; ++i)
161  {
162  _exact_species[num](cell, point)
163  += exp(-pow(gaussian + i, 2) * 0.5 / (denum));
164  }
165 
166  if (_build_diffusion)
167  _exact_species[num](cell, point)
168  *= (1.0
169  / sqrt(1.0
170  * (1.0
171  + 2.0 * _nu * _time
172  / (_sigma * _sigma))));
173  }
174 
175  if (!_build_bateman)
176  _exact_species[num](cell, point) *= _scale[num];
177  }
178  }
179 
180  if (_build_bateman)
181  {
182  for (int num = 1; num < _num_species + 1; ++num)
183  {
184  lmbd_prod = 1.0;
185  for (int i = 0; i < num - 1; i++)
186  {
187  lmbd_prod *= -_bateman_matrix(i, i);
188  }
189  sum_k = 0;
190  for (int i = 0; i < num; i++)
191  {
192  prod_l = 1.0;
193  for (int j = 0; j < num; j++)
194  {
195  if (j != i)
196  prod_l *= (-_bateman_matrix(j, j)
197  + _bateman_matrix(i, i));
198  }
199  sum_k += exp(+_bateman_matrix(i, i) * _time) / prod_l;
200  }
201  if (_build_advection || _build_diffusion)
202  {
203  _exact_species[num - 1](cell, point)
204  *= _scale[0] * lmbd_prod * sum_k;
205  }
206  else
207  {
208  _exact_species[num - 1](cell, point)
209  = _scale[0] * lmbd_prod * sum_k;
210  }
211  }
212  }
213  });
214 }
215 
216 //---------------------------------------------------------------------------//
217 
218 } // end namespace ClosureModel
219 } // end namespace VertexCFD
220 
221 #endif // VERTEXCFD_CLOSURE_RADBADExactSolution_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23