1 #ifndef VERTEXCFD_CLOSURE_RADLOCALTIMESTEPSIZE_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_RADLOCALTIMESTEPSIZE_IMPL_HPP
4 #include "utils/VertexCFD_Utils_ScalarFieldView.hpp"
5 #include "utils/VertexCFD_Utils_VectorField.hpp"
7 #include <Panzer_HierarchicParallelism.hpp>
13 namespace ClosureModel
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_"
29 , _mic_cross_section(Kokkos::ViewAllocateWithoutInitializing(
"microscopic_"
34 , _build_bateman(species_prop.buildBateman())
35 , _build_transmutation(species_prop.buildTransmutationSource())
36 , _build_advection(species_prop.buildAdvection())
37 , _build_diffusion(species_prop.buildDiffusion())
40 this->addEvaluatedField(_local_dt);
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);
53 if (_build_transmutation)
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);
60 this->addDependentField(_neutron_flux);
64 Utils::addDependentVectorField(
65 *
this, ir.dl_scalar, _velocity,
"velocity_");
68 _nu = species_prop.constantDiffusionCoefficient();
70 if (_build_advection || _build_diffusion)
71 this->addDependentField(_element_length);
73 this->setName(
"RAD Local Time Step Size");
77 template<
class EvalType,
class Traits,
int NumSpaceDim>
78 void RADLocalTimeStepSize<EvalType, Traits, NumSpaceDim>::evaluateFields(
79 typename Traits::EvalData workset)
83 if constexpr (Sacado::IsADType<scalar_type>::value)
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);
91 bytes = scratch_view::shmem_size(_local_dt.extent(1), NUM_TMPS);
93 auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
95 policy.set_scratch_size(0, Kokkos::PerTeam(bytes));
96 Kokkos::parallel_for(this->getName(), policy, *
this);
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
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);
111 scratch_view tmp_field;
112 if constexpr (Sacado::IsADType<scalar_type>::value)
114 const int fad_size = Kokkos::dimension_scalar(_local_dt.get_view());
116 = scratch_view(team.team_shmem(), num_point, NUM_TMPS, fad_size);
120 tmp_field = scratch_view(team.team_shmem(), num_point, NUM_TMPS);
123 Kokkos::parallel_for(
124 Kokkos::TeamThreadRange(team, 0, num_point), [&](
const int point) {
125 _local_dt(cell, point) = std::numeric_limits<double>::max();
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);
132 local_dt_bateman = 0.0;
138 local_dt_bateman = 1.0 / abs(_bateman_matrix(0, 0));
139 for (
int num = 1; num < _num_species; ++num)
141 local_dt_bateman = min(
142 local_dt_bateman, 1.0 / abs(_bateman_matrix(num, num)));
144 _local_dt(cell, point)
145 = min(_local_dt(cell, point), local_dt_bateman);
148 if (_build_transmutation)
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)
156 = min(local_dt_transmut,
158 / abs(_mic_cross_section(num, num)
159 * _neutron_flux(cell, point)));
161 _local_dt(cell, point)
162 = min(_local_dt(cell, point), local_dt_transmut);
165 if (_build_advection)
168 for (
int dim = 0; dim < num_grad_dim; ++dim)
170 local_dt_adv += abs(_velocity[dim](cell, point))
171 / _element_length(cell, point, dim);
175 local_dt_adv = 1.0 / local_dt_adv;
176 _local_dt(cell, point)
177 = min(_local_dt(cell, point), local_dt_adv);
181 if (_build_diffusion)
184 for (
int dim = 0; dim < num_grad_dim; ++dim)
186 local_dt_dif += _nu / _element_length(cell, point, dim)
187 / _element_length(cell, point, dim);
191 _local_dt(cell, point)
192 = min(_local_dt(cell, point), 1.0 / local_dt_dif);
202 #endif // end VERTEXCFD_CLOSURE_RADLOCALTIMESTEPSIZE_IMPL_HPP