VertexCFD  0.0-dev
VertexCFD_Closure_MetricTensor_impl.hpp
1 #ifndef VERTEXCFD_CLOSURE_METRICTENSOR_IMPL_HPP
2 #define VERTEXCFD_CLOSURE_METRICTENSOR_IMPL_HPP
3 
4 #include <Panzer_Workset_Utilities.hpp>
5 
6 #include <Shards_BasicTopologies.hpp>
7 
8 #include <cmath>
9 #include <stdexcept>
10 #include <string>
11 #include <type_traits>
12 
13 namespace VertexCFD
14 {
15 namespace ClosureModel
16 {
17 //---------------------------------------------------------------------------//
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"),
24  _num_topo_dim,
25  _num_topo_dim)
26 {
27  //
28  // Define the mapping between the ideal and the reference element.
29  //
30  auto map = Kokkos::create_mirror_view(Kokkos::HostSpace{}, _element_map);
31  switch (ir.topology->getBaseKey())
32  {
33  case shards::Line<>::key:
34  map(0, 0) = 2.0;
35 
36  break;
37  case shards::Triangle<>::key:
38  map(0, 0) = 1.0;
39  map(0, 1) = 0.0;
40 
41  map(1, 0) = -1.0 / std::sqrt(3.0);
42  map(1, 1) = 2.0 / std::sqrt(3.0);
43 
44  break;
45  case shards::Quadrilateral<>::key:
46  map(0, 0) = 2.0;
47  map(0, 1) = 0.0;
48 
49  map(1, 0) = 0.0;
50  map(1, 1) = 2.0;
51 
52  break;
53  case shards::Tetrahedron<>::key:
54  map(0, 0) = 1.0;
55  map(0, 1) = 0.0;
56  map(0, 2) = 0.0;
57 
58  map(1, 0) = -1.0 / std::sqrt(3.0);
59  map(1, 1) = 2.0 / std::sqrt(3.0);
60  map(1, 2) = 0.0;
61 
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);
65 
66  break;
67  case shards::Pyramid<>::key:
68  map(0, 0) = 2.0;
69  map(0, 1) = 0.0;
70  map(0, 2) = 0.0;
71 
72  map(1, 0) = 0.0;
73  map(1, 1) = 2.0;
74  map(1, 2) = 0.0;
75 
76  map(2, 0) = 0.0;
77  map(2, 1) = 0.0;
78  map(2, 2) = std::sqrt(2.0);
79 
80  break;
81  case shards::Wedge<>::key:
82  map(0, 0) = 1.0;
83  map(0, 1) = 0.0;
84  map(0, 2) = 0.0;
85 
86  map(1, 0) = -1.0 / std::sqrt(3.0);
87  map(1, 1) = 2.0 / std::sqrt(3.0);
88  map(1, 2) = 0.0;
89 
90  map(2, 0) = 0.0;
91  map(2, 1) = 0.0;
92  map(2, 2) = 2.0;
93 
94  break;
95  case shards::Hexahedron<>::key:
96  map(0, 0) = 2.0;
97  map(0, 1) = 0.0;
98  map(0, 2) = 0.0;
99 
100  map(1, 0) = 0.0;
101  map(1, 1) = 2.0;
102  map(1, 2) = 0.0;
103 
104  map(2, 0) = 0.0;
105  map(2, 1) = 0.0;
106  map(2, 2) = 2.0;
107 
108  break;
109  default:
110  using namespace std::string_literals;
111  throw std::runtime_error("Invalid base cell topology: "s
112  + ir.topology->getBaseName());
113  }
114  Kokkos::deep_copy(_element_map, map);
115 
116  this->addEvaluatedField(_metric_tensor);
117  this->setName("Metric Tensor");
118 }
119 
120 //---------------------------------------------------------------------------//
121 template<class EvalType, class Traits>
122 void MetricTensor<EvalType, Traits>::postRegistrationSetup(
123  typename Traits::SetupData sd, PHX::FieldManager<Traits>&)
124 {
125  _ir_index = panzer::getIntegrationRuleIndex(_ir_degree, (*sd.worksets_)[0]);
126 }
127 
128 //---------------------------------------------------------------------------//
129 template<class EvalType, class Traits>
130 void MetricTensor<EvalType, Traits>::evaluateFields(
131  typename Traits::EvalData workset)
132 {
133  _jacobian = workset.int_rules[_ir_index]->jac;
134 
135  const int num_cell = workset.num_cells;
136  const int num_point = _jacobian.extent(1);
137 
138  if (_num_topo_dim == 1)
139  {
140  const Kokkos::MDRangePolicy<PHX::Device,
141  Kokkos::Rank<2>,
142  std::integral_constant<int, 1>>
143  policy({0, 0}, {num_cell, num_point});
144 
145  Kokkos::parallel_for(this->getName(), policy, *this);
146  }
147  else if (_num_topo_dim == 2)
148  {
149  const Kokkos::MDRangePolicy<PHX::Device,
150  Kokkos::Rank<2>,
151  std::integral_constant<int, 2>>
152  policy({0, 0}, {num_cell, num_point});
153 
154  Kokkos::parallel_for(this->getName(), policy, *this);
155  }
156  else if (_num_topo_dim == 3)
157  {
158  const Kokkos::MDRangePolicy<PHX::Device,
159  Kokkos::Rank<2>,
160  std::integral_constant<int, 3>>
161  policy({0, 0}, {num_cell, num_point});
162 
163  Kokkos::parallel_for(this->getName(), policy, *this);
164  }
165 }
166 
167 //---------------------------------------------------------------------------//
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>,
172  const int cell,
173  const int point) const
174 {
175  constexpr int num_space_dim = NumSpaceDim;
176 
177  //
178  // Transform Jacobian to ideal element.
179  //
180  double jac[num_space_dim][num_space_dim]{};
181 
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);
186 
187  //
188  // Compute metric tensor (covariant) from ideal Jacobian.
189  //
190  for (int i = 0; i < num_space_dim; ++i)
191  {
192  for (int j = 0; j < num_space_dim; ++j)
193  {
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];
197  }
198  }
199 }
200 
201 //---------------------------------------------------------------------------//
202 
203 } // end namespace ClosureModel
204 } // end namespace VertexCFD
205 
206 #endif // end VERTEXCFD_CLOSURE_METRICTENSOR_IMPL_HPP
VertexCFD
Definition: tstMethodManufacturedSolutionBC.cpp:23