1 #ifndef VERTEXCFD_INITIALCONDITION_INVERSEGAUSSIAN_IMPL_HPP
2 #define VERTEXCFD_INITIALCONDITION_INVERSEGAUSSIAN_IMPL_HPP
4 #include "utils/VertexCFD_Utils_Constants.hpp"
6 #include <Panzer_GlobalIndexer.hpp>
7 #include <Panzer_HierarchicParallelism.hpp>
8 #include <Panzer_PureBasis.hpp>
9 #include <Panzer_Workset_Utilities.hpp>
11 #include <Teuchos_Array.hpp>
18 namespace InitialCondition
21 template<
class EvalType,
class Traits,
int NumSpaceDim>
22 InverseGaussian<EvalType, Traits, NumSpaceDim>::InverseGaussian(
23 const Teuchos::ParameterList& params,
const panzer::PureBasis& basis)
24 : _basis_name(basis.name())
25 , _a(Kokkos::ViewAllocateWithoutInitializing(
"InverseGaussian a"),
27 , _b(Kokkos::ViewAllocateWithoutInitializing(
"InverseGaussian b"),
29 , _c(Kokkos::ViewAllocateWithoutInitializing(
"InverseGaussian c"),
32 const std::string dof_name = params.get<std::string>(
"Equation Set Name");
33 _ic = PHX::MDField<scalar_type, panzer::Cell, panzer::BASIS>(
34 dof_name, basis.functional);
35 this->addEvaluatedField(_ic);
36 this->addUnsharedField(_ic.fieldTag().clone());
37 this->setName(
"InverseGaussian Initial Condition: " + dof_name);
39 auto center = params.get<Teuchos::Array<double>>(
"Center");
40 auto sigma = params.get<Teuchos::Array<double>>(
"Sigma");
41 _d = params.get<
double>(
"Base");
42 const double sqrt2pi = std::sqrt(2.0 * Constants::pi);
43 auto a_host = Kokkos::create_mirror_view(Kokkos::HostSpace{}, _a);
44 auto b_host = Kokkos::create_mirror_view(Kokkos::HostSpace{}, _b);
45 auto c_host = Kokkos::create_mirror_view(Kokkos::HostSpace{}, _c);
46 for (
int dim = 0; dim < basis.dimension(); ++dim)
48 a_host(dim) = 1.0 / (sqrt2pi * sigma[dim]);
49 b_host(dim) = center[dim];
50 c_host(dim) = 0.5 / (sigma[dim] * sigma[dim]);
52 Kokkos::deep_copy(_a, a_host);
53 Kokkos::deep_copy(_b, b_host);
54 Kokkos::deep_copy(_c, c_host);
58 template<
class EvalType,
class Traits,
int NumSpaceDim>
59 void InverseGaussian<EvalType, Traits, NumSpaceDim>::postRegistrationSetup(
60 typename Traits::SetupData sd, PHX::FieldManager<Traits>&)
62 _basis_index = panzer::getPureBasisIndex(
63 _basis_name, (*sd.worksets_)[0], this->wda);
67 template<
class EvalType,
class Traits,
int NumSpaceDim>
68 void InverseGaussian<EvalType, Traits, NumSpaceDim>::evaluateFields(
69 typename Traits::EvalData workset)
71 _basis_coords = this->wda(workset).bases[_basis_index]->basis_coordinates;
72 auto policy = panzer::HP::inst().teamPolicy<scalar_type, PHX::Device>(
74 Kokkos::parallel_for(this->getName(), policy, *
this);
78 template<
class EvalType,
class Traits,
int NumSpaceDim>
79 KOKKOS_INLINE_FUNCTION
void
80 InverseGaussian<EvalType, Traits, NumSpaceDim>::operator()(
81 const Kokkos::TeamPolicy<PHX::exec_space>::member_type& team)
const
83 const int cell = team.league_rank();
84 const int num_basis = _ic.extent(1);
87 Kokkos::TeamThreadRange(team, 0, num_basis), [&](
const int basis) {
90 for (
int dim = 0; dim < num_space_dim; ++dim)
92 const auto x = _basis_coords(cell, basis, dim);
94 * exp((_b(dim) - x) * (x - _b(dim)) * _c(dim));
96 _ic(cell, basis) = 1.0 / (result + _d);
105 #endif // end VERTEXCFD_INITIALCONDITION_INVERSEGAUSSIAN_IMPL_HPP