1 #ifndef VERTEXCFD_CLOSURE_METRICTENSOR_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_METRICTENSOR_IMPL_HPP
4 #include <Panzer_Workset_Utilities.hpp>
6 #include <Shards_BasicTopologies.hpp>
11 #include <type_traits>
15 namespace ClosureModel
18 template<
class EvalType,
class Traits>
19 MetricTensor<EvalType, Traits>::MetricTensor(
const panzer::IntegrationRule& ir)
20 : _metric_tensor(
"metric_tensor", ir.dl_tensor)
21 , _ir_degree(ir.cubature_degree)
22 , _num_topo_dim(ir.topology->getDimension())
23 , _element_map(Kokkos::ViewAllocateWithoutInitializing(
"element_map"),
30 auto map = Kokkos::create_mirror_view(Kokkos::HostSpace{}, _element_map);
31 switch (ir.topology->getBaseKey())
33 case shards::Line<>::key:
37 case shards::Triangle<>::key:
41 map(1, 0) = -1.0 / std::sqrt(3.0);
42 map(1, 1) = 2.0 / std::sqrt(3.0);
45 case shards::Quadrilateral<>::key:
53 case shards::Tetrahedron<>::key:
58 map(1, 0) = -1.0 / std::sqrt(3.0);
59 map(1, 1) = 2.0 / std::sqrt(3.0);
62 map(2, 0) = -1.0 / std::sqrt(6.0);
63 map(2, 1) = -1.0 / std::sqrt(6.0);
64 map(2, 2) = std::sqrt(3.0 / 2.0);
67 case shards::Pyramid<>::key:
78 map(2, 2) = std::sqrt(2.0);
81 case shards::Wedge<>::key:
86 map(1, 0) = -1.0 / std::sqrt(3.0);
87 map(1, 1) = 2.0 / std::sqrt(3.0);
95 case shards::Hexahedron<>::key:
110 using namespace std::string_literals;
111 throw std::runtime_error(
"Invalid base cell topology: "s
112 + ir.topology->getBaseName());
114 Kokkos::deep_copy(_element_map, map);
116 this->addEvaluatedField(_metric_tensor);
117 this->setName(
"Metric Tensor");
121 template<
class EvalType,
class Traits>
122 void MetricTensor<EvalType, Traits>::postRegistrationSetup(
123 typename Traits::SetupData sd, PHX::FieldManager<Traits>&)
125 _ir_index = panzer::getIntegrationRuleIndex(_ir_degree, (*sd.worksets_)[0]);
129 template<
class EvalType,
class Traits>
130 void MetricTensor<EvalType, Traits>::evaluateFields(
131 typename Traits::EvalData workset)
133 _jacobian = workset.int_rules[_ir_index]->jac;
135 const int num_cell = workset.num_cells;
136 const int num_point = _jacobian.extent(1);
138 if (_num_topo_dim == 1)
140 const Kokkos::MDRangePolicy<PHX::Device,
142 std::integral_constant<int, 1>>
143 policy({0, 0}, {num_cell, num_point});
145 Kokkos::parallel_for(this->getName(), policy, *
this);
147 else if (_num_topo_dim == 2)
149 const Kokkos::MDRangePolicy<PHX::Device,
151 std::integral_constant<int, 2>>
152 policy({0, 0}, {num_cell, num_point});
154 Kokkos::parallel_for(this->getName(), policy, *
this);
156 else if (_num_topo_dim == 3)
158 const Kokkos::MDRangePolicy<PHX::Device,
160 std::integral_constant<int, 3>>
161 policy({0, 0}, {num_cell, num_point});
163 Kokkos::parallel_for(this->getName(), policy, *
this);
168 template<
class EvalType,
class Traits>
169 template<
int NumSpaceDim>
170 KOKKOS_INLINE_FUNCTION
void MetricTensor<EvalType, Traits>::operator()(
171 std::integral_constant<int, NumSpaceDim>,
173 const int point)
const
175 constexpr
int num_space_dim = NumSpaceDim;
180 double jac[num_space_dim][num_space_dim]{};
182 for (
int i = 0; i < num_space_dim; ++i)
183 for (
int j = 0; j < num_space_dim; ++j)
184 for (
int k = 0; k < num_space_dim; ++k)
185 jac[i][j] += _jacobian(cell, point, i, k) * _element_map(j, k);
190 for (
int i = 0; i < num_space_dim; ++i)
192 for (
int j = 0; j < num_space_dim; ++j)
194 _metric_tensor(cell, point, i, j) = 0.0;
195 for (
int k = 0; k < num_space_dim; ++k)
196 _metric_tensor(cell, point, i, j) += jac[i][k] * jac[j][k];
206 #endif // end VERTEXCFD_CLOSURE_METRICTENSOR_IMPL_HPP