VertexCFD  0.0-dev
VertexCFD_Closure_RADLocalTimeStepSize_impl.hpp
1 #ifndef VERTEXCFD_CLOSURE_RADLOCALTIMESTEPSIZE_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_RADLOCALTIMESTEPSIZE_IMPL_HPP
3 
4 #include "utils/VertexCFD_Utils_ScalarFieldView.hpp"
5 #include "utils/VertexCFD_Utils_VectorField.hpp"
6 
7 #include <Panzer_HierarchicParallelism.hpp>
8 
9 #include <cmath>
10 
11 namespace VertexCFD
12 {
13 namespace ClosureModel
14 {
15 //---------------------------------------------------------------------------//
16 template<class EvalType, class Traits, int NumSpaceDim>
17 RADLocalTimeStepSize<EvalType, Traits, NumSpaceDim>::RADLocalTimeStepSize(
18  const panzer::IntegrationRule& ir,
19  const SpeciesProperties::ConstantSpeciesProperties& species_prop,
20  const std::string& neutron_flux_name)
21  : _num_species(species_prop.numSpecies())
22  , _local_dt("local_dt", ir.dl_scalar)
23  , _element_length("element_length", ir.dl_vector)
24  , _neutron_flux(neutron_flux_name, ir.dl_scalar)
25  , _bateman_matrix(Kokkos::ViewAllocateWithoutInitializing("bateman_"
26  "matrix"),
27  _num_species,
28  _num_species)
29  , _mic_cross_section(Kokkos::ViewAllocateWithoutInitializing("microscopic_"
30  "cross_"
31  "section"),
32  _num_species,
33  _num_species)
34  , _build_bateman(species_prop.buildBateman())
35  , _build_transmutation(species_prop.buildTransmutationSource())
36  , _build_advection(species_prop.buildAdvection())
37  , _build_diffusion(species_prop.buildDiffusion())
38 {
39  // Add evaluated field
40  this->addEvaluatedField(_local_dt);
41 
42  // Add dependent fields
43  if (_build_bateman)
44  {
45  // Copy bateman matrix from host to device
46  auto bateman_matrix_host
47  = Kokkos::create_mirror_view(Kokkos::HostSpace{}, _bateman_matrix);
48  bateman_matrix_host = species_prop.batemanMatrix();
49  Kokkos::deep_copy(_bateman_matrix, bateman_matrix_host);
50  }
51 
52  // Copy microscopic cross-section matrix from host to device
53  if (_build_transmutation)
54  {
55  auto mic_cross_sec_host = Kokkos::create_mirror_view(
56  Kokkos::HostSpace{}, _mic_cross_section);
57  mic_cross_sec_host = species_prop.microscopicCrossSection();
58  Kokkos::deep_copy(_mic_cross_section, mic_cross_sec_host);
59 
60  this->addDependentField(_neutron_flux);
61  }
62 
63  if (_build_advection)
64  Utils::addDependentVectorField(
65  *this, ir.dl_scalar, _velocity, "velocity_");
66 
67  if (_build_diffusion)
68  _nu = species_prop.constantDiffusionCoefficient();
69 
70  if (_build_advection || _build_diffusion)
71  this->addDependentField(_element_length);
72 
73  this->setName("RAD Local Time Step Size");
74 }
75 
76 //---------------------------------------------------------------------------//
77 template<class EvalType, class Traits, int NumSpaceDim>
78 void RADLocalTimeStepSize<EvalType, Traits, NumSpaceDim>::evaluateFields(
79  typename Traits::EvalData workset)
80 {
81  // Allocate space for thread-local temporaries
82  size_t bytes;
83  if constexpr (Sacado::IsADType<scalar_type>::value)
84  {
85  const int fad_size = Kokkos::dimension_scalar(_local_dt.get_view());
86  bytes = scratch_view::shmem_size(
87  _local_dt.extent(1), NUM_TMPS, fad_size);
88  }
89  else
90  {
91  bytes = scratch_view::shmem_size(_local_dt.extent(1), NUM_TMPS);
92  }
93  auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
94  workset.num_cells);
95  policy.set_scratch_size(0, Kokkos::PerTeam(bytes));
96  Kokkos::parallel_for(this->getName(), policy, *this);
97 }
98 
99 //---------------------------------------------------------------------------//
100 template<class EvalType, class Traits, int NumSpaceDim>
101 KOKKOS_INLINE_FUNCTION void
102 RADLocalTimeStepSize<EvalType, Traits, NumSpaceDim>::operator()(
103  const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team) const
104 {
105  const int cell = team.league_rank();
106  const int num_point = _local_dt.extent(1);
107  const int num_grad_dim = _element_length.extent(2);
108  using Kokkos::abs;
109  using Kokkos::min;
110 
111  scratch_view tmp_field;
112  if constexpr (Sacado::IsADType<scalar_type>::value)
113  {
114  const int fad_size = Kokkos::dimension_scalar(_local_dt.get_view());
115  tmp_field
116  = scratch_view(team.team_shmem(), num_point, NUM_TMPS, fad_size);
117  }
118  else
119  {
120  tmp_field = scratch_view(team.team_shmem(), num_point, NUM_TMPS);
121  }
122 
123  Kokkos::parallel_for(
124  Kokkos::TeamThreadRange(team, 0, num_point), [&](const int point) {
125  _local_dt(cell, point) = std::numeric_limits<double>::max();
126 
127  auto&& local_dt_bateman = tmp_field(point, LOCAL_DT_BATEMAN);
128  auto&& local_dt_transmut = tmp_field(point, LOCAL_DT_TRANSMUT);
129  auto&& local_dt_adv = tmp_field(point, LOCAL_DT_ADV);
130  auto&& local_dt_dif = tmp_field(point, LOCAL_DT_DIF);
131 
132  local_dt_bateman = 0.0;
133  local_dt_adv = 0.0;
134  local_dt_dif = 0.0;
135 
136  if (_build_bateman)
137  {
138  local_dt_bateman = 1.0 / abs(_bateman_matrix(0, 0));
139  for (int num = 1; num < _num_species; ++num)
140  {
141  local_dt_bateman = min(
142  local_dt_bateman, 1.0 / abs(_bateman_matrix(num, num)));
143  }
144  _local_dt(cell, point)
145  = min(_local_dt(cell, point), local_dt_bateman);
146  }
147 
148  if (_build_transmutation)
149  {
150  local_dt_transmut = 1.0
151  / abs(_mic_cross_section(0, 0)
152  * _neutron_flux(cell, point));
153  for (int num = 1; num < _num_species; ++num)
154  {
155  local_dt_transmut
156  = min(local_dt_transmut,
157  1.0
158  / abs(_mic_cross_section(num, num)
159  * _neutron_flux(cell, point)));
160  }
161  _local_dt(cell, point)
162  = min(_local_dt(cell, point), local_dt_transmut);
163  }
164 
165  if (_build_advection)
166  {
167  // Accumulate 1/dt for velocity
168  for (int dim = 0; dim < num_grad_dim; ++dim)
169  {
170  local_dt_adv += abs(_velocity[dim](cell, point))
171  / _element_length(cell, point, dim);
172  }
173 
174  // Take minimum time step
175  local_dt_adv = 1.0 / local_dt_adv;
176  _local_dt(cell, point)
177  = min(_local_dt(cell, point), local_dt_adv);
178  }
179 
180  // Consider velocity if diffusion terms are included
181  if (_build_diffusion)
182  {
183  // Accumulate 1/dt for velocity
184  for (int dim = 0; dim < num_grad_dim; ++dim)
185  {
186  local_dt_dif += _nu / _element_length(cell, point, dim)
187  / _element_length(cell, point, dim);
188  }
189 
190  // Take minimum time step
191  _local_dt(cell, point)
192  = min(_local_dt(cell, point), 1.0 / local_dt_dif);
193  }
194  });
195 }
196 
197 //---------------------------------------------------------------------------//
198 
199 } // end namespace ClosureModel
200 } // end namespace VertexCFD
201 
202 #endif // end VERTEXCFD_CLOSURE_RADLOCALTIMESTEPSIZE_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23