48 #ifndef __INTREPID2_CELLTOOLS_SERIAL_HPP__
49 #define __INTREPID2_CELLTOOLS_SERIAL_HPP__
51 #include "Intrepid2_ConfigDefs.hpp"
53 #include "Shards_CellTopology.hpp"
68 typedef Kokkos::DynRankView<double,Kokkos::HostSpace> NodeDataHostView;
69 typedef Kokkos::DynRankView<const double,Kokkos::HostSpace,Kokkos::MemoryUnmanaged> ConstUnmanagedNodeDataHostView;
72 double line[2][3], line_3[3][3];
73 double triangle[3][3], triangle_4[4][3], triangle_6[6][3];
74 double quadrilateral[4][3], quadrilateral_8[8][3], quadrilateral_9[9][3];
75 double tetrahedron[4][3], tetrahedron_8[8][3], tetrahedron_10[10][3], tetrahedron_11[10][3];
76 double hexahedron[8][3], hexahedron_20[20][3], hexahedron_27[27][3];
77 double pyramid[5][3], pyramid_13[13][3], pyramid_14[14][3];
78 double wedge[6][3], wedge_15[15][3], wedge_18[18][3];
87 {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}
90 {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 0.0, 0.0}
94 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}
97 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, { 1/3, 1/3, 0.0}
100 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0},
101 { 0.5, 0.0, 0.0}, { 0.5, 0.5, 0.0}, { 0.0, 0.5, 0.0}
105 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}
108 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0},
109 { 0.0,-1.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}
112 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0},
113 { 0.0,-1.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, { 0.0, 0.0, 0.0}
117 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, { 0.0, 0.0, 1.0}
120 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
121 { 1/3, 0.0, 1/3}, { 1/3, 1/3, 1/3}, { 1/3, 1/3, 0.0}, { 0.0, 1/3, 1/3}
124 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
125 { 0.5, 0.0, 0.0}, { 0.5, 0.5, 0.0}, { 0.0, 0.5, 0.0}, { 0.0, 0.0, 0.5}, { 0.5, 0.0, 0.5}, { 0.0, 0.5, 0.5}
128 { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
129 { 0.5, 0.0, 0.0}, { 0.5, 0.5, 0.0}, { 0.0, 0.5, 0.0}, { 0.0, 0.0, 0.5}, { 0.5, 0.0, 0.5}, { 0.0, 0.5, 0.5}
133 {-1.0,-1.0,-1.0}, { 1.0,-1.0,-1.0}, { 1.0, 1.0,-1.0}, {-1.0, 1.0,-1.0},
134 {-1.0,-1.0, 1.0}, { 1.0,-1.0, 1.0}, { 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0}
137 {-1.0,-1.0,-1.0}, { 1.0,-1.0,-1.0}, { 1.0, 1.0,-1.0}, {-1.0, 1.0,-1.0},
138 {-1.0,-1.0, 1.0}, { 1.0,-1.0, 1.0}, { 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0},
139 { 0.0,-1.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, {-1.0, 0.0,-1.0},
140 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0},
141 { 0.0,-1.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0}, {-1.0, 0.0, 1.0}
144 {-1.0,-1.0,-1.0}, { 1.0,-1.0,-1.0}, { 1.0, 1.0,-1.0}, {-1.0, 1.0,-1.0},
145 {-1.0,-1.0, 1.0}, { 1.0,-1.0, 1.0}, { 1.0, 1.0, 1.0}, {-1.0, 1.0, 1.0},
146 { 0.0,-1.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, {-1.0, 0.0,-1.0},
147 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0},
148 { 0.0,-1.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0}, {-1.0, 0.0, 1.0},
150 { 0.0, 0.0,-1.0}, { 0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, {0.0,-1.0, 0.0}, {0.0, 1.0, 0.0}
154 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}, { 0.0, 0.0, 1.0}
157 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
158 { 0.0,-1.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0},
159 {-0.5,-0.5, 0.5}, { 0.5,-0.5, 0.5}, { 0.5, 0.5, 0.5}, {-0.5, 0.5, 0.5}
162 {-1.0,-1.0, 0.0}, { 1.0,-1.0, 0.0}, { 1.0, 1.0, 0.0}, {-1.0, 1.0, 0.0}, { 0.0, 0.0, 1.0},
163 { 0.0,-1.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0},
164 {-0.5,-0.5, 0.5}, { 0.5,-0.5, 0.5}, { 0.5, 0.5, 0.5}, {-0.5, 0.5, 0.5}, { 0.0, 0.0, 0.0}
168 { 0.0, 0.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, { 0.0, 0.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0}
171 { 0.0, 0.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, { 0.0, 0.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0},
172 { 0.5, 0.0,-1.0}, { 0.5, 0.5,-1.0}, { 0.0, 0.5,-1.0}, { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0},
173 { 0.5, 0.0, 1.0}, { 0.5, 0.5, 1.0}, { 0.0, 0.5, 1.0}
176 { 0.0, 0.0,-1.0}, { 1.0, 0.0,-1.0}, { 0.0, 1.0,-1.0}, { 0.0, 0.0, 1.0}, { 1.0, 0.0, 1.0}, { 0.0, 1.0, 1.0},
177 { 0.5, 0.0,-1.0}, { 0.5, 0.5,-1.0}, { 0.0, 0.5,-1.0}, { 0.0, 0.0, 0.0}, { 1.0, 0.0, 0.0}, { 0.0, 1.0, 0.0},
178 { 0.5, 0.0, 1.0}, { 0.5, 0.5, 1.0}, { 0.0, 0.5, 1.0},
179 { 0.5, 0.0, 0.0}, { 0.5, 0.5, 0.0}, { 0.0, 0.5, 0.0}
185 template<
typename refNodeViewType>
188 getReferenceNode(
const refNodeViewType &nodes,
189 const shards::CellTopology &cell,
190 const ordinal_type nodeOrd ) {
191 ConstUnmanagedNodeDataHostView ref;
192 switch (cell.getKey() ) {
193 case shards::Line<2>::key:
194 case shards::ShellLine<2>::key:
195 case shards::Beam<2>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().line, 2, 3);
break;
196 case shards::Line<3>::key:
197 case shards::ShellLine<3>::key:
198 case shards::Beam<3>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().line_3, 3, 3);
break;
200 case shards::Triangle<3>::key:
201 case shards::ShellTriangle<3>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().triangle, 3, 3);
break;
202 case shards::Triangle<4>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().triangle_4, 4, 3);
break;
203 case shards::Triangle<6>::key:
204 case shards::ShellTriangle<6>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().triangle_6, 6, 3);
break;
206 case shards::Quadrilateral<4>::key:
207 case shards::ShellQuadrilateral<4>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().quadrilateral, 4, 3);
break;
208 case shards::Quadrilateral<8>::key:
209 case shards::ShellQuadrilateral<8>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().quadrilateral_8, 8, 3);
break;
210 case shards::Quadrilateral<9>::key:
211 case shards::ShellQuadrilateral<9>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().quadrilateral_9, 9, 3);
break;
213 case shards::Tetrahedron<4>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().tetrahedron, 4, 3);
break;
214 case shards::Tetrahedron<8>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().tetrahedron_8, 8, 3);
break;
215 case shards::Tetrahedron<10>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().tetrahedron_10, 10, 3);
break;
216 case shards::Tetrahedron<11>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().tetrahedron_11, 11, 3);
break;
218 case shards::Hexahedron<8>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().hexahedron, 8, 3);
break;
219 case shards::Hexahedron<20>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().hexahedron_20, 20, 3);
break;
220 case shards::Hexahedron<27>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().hexahedron_27, 27, 3);
break;
222 case shards::Pyramid<5>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().pyramid, 5, 3);
break;
223 case shards::Pyramid<13>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().pyramid_13, 13, 3);
break;
224 case shards::Pyramid<14>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().pyramid_14, 14, 3);
break;
226 case shards::Wedge<6>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().wedge, 6, 3);
break;
227 case shards::Wedge<15>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().wedge_15, 15, 3);
break;
228 case shards::Wedge<18>::key: ref = ConstUnmanagedNodeDataHostView((
const double*)getRefNodeData().wedge_18, 18, 3);
break;
231 INTREPID2_TEST_FOR_ABORT(
true,
"invalid input cell topology.");
236 const ordinal_type D = cell.getDimension();
237 for (ordinal_type i=0;i<D;++i)
238 nodes(i) = ref(nodeOrd, i);
242 NodeDataHostView dummy;
243 NodeDataHostView lineEdges;
244 NodeDataHostView triEdges, quadEdges;
245 NodeDataHostView shellTriEdges, shellQuadEdges;
246 NodeDataHostView tetEdges, hexEdges, pyrEdges, wedgeEdges;
247 NodeDataHostView shellTriFaces, shellQuadFaces;
248 NodeDataHostView tetFaces, hexFaces, pyrFaces, wedgeFaces;
254 Kokkos::push_finalize_hook( [=] {
255 subcellParamData.dummy = NodeDataHostView();
256 subcellParamData.lineEdges = NodeDataHostView();
257 subcellParamData.triEdges = NodeDataHostView();
258 subcellParamData.quadEdges = NodeDataHostView();
259 subcellParamData.shellTriEdges = NodeDataHostView();
260 subcellParamData.shellQuadEdges = NodeDataHostView();
261 subcellParamData.tetEdges = NodeDataHostView();
262 subcellParamData.hexEdges = NodeDataHostView();
263 subcellParamData.pyrEdges = NodeDataHostView();
264 subcellParamData.wedgeEdges = NodeDataHostView();
265 subcellParamData.shellTriFaces = NodeDataHostView();
266 subcellParamData.shellQuadFaces = NodeDataHostView();
267 subcellParamData.tetFaces = NodeDataHostView();
268 subcellParamData.hexFaces = NodeDataHostView();
269 subcellParamData.pyrFaces = NodeDataHostView();
270 subcellParamData.wedgeFaces = NodeDataHostView();
272 return subcellParamData;
277 setSubcellParametrization() {
278 static bool isSubcellParametrizationSet =
false;
279 if (!isSubcellParametrizationSet) {
281 const auto tet = shards::CellTopology(shards::getCellTopologyData<shards::Tetrahedron<4> >());
282 setSubcellParametrization( getSubcellParamData().tetFaces, 2, tet );
283 setSubcellParametrization( getSubcellParamData().tetEdges, 1, tet );
286 const auto hex = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >());
287 setSubcellParametrization( getSubcellParamData().hexFaces, 2, hex );
288 setSubcellParametrization( getSubcellParamData().hexEdges, 1, hex );
291 const auto pyr = shards::CellTopology(shards::getCellTopologyData<shards::Pyramid<5> >());
292 setSubcellParametrization( getSubcellParamData().pyrFaces, 2, pyr );
293 setSubcellParametrization( getSubcellParamData().pyrEdges, 1, pyr );
296 const auto wedge = shards::CellTopology(shards::getCellTopologyData<shards::Wedge<6> >());
297 setSubcellParametrization( getSubcellParamData().wedgeFaces, 2, wedge );
298 setSubcellParametrization( getSubcellParamData().wedgeEdges, 1, wedge );
301 const auto tri = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >());
302 setSubcellParametrization( getSubcellParamData().triEdges, 1, tri );
305 const auto quad = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >());
306 setSubcellParametrization( getSubcellParamData().quadEdges, 1, quad );
309 const auto line = shards::CellTopology(shards::getCellTopologyData<shards::ShellLine<2> >());
310 setSubcellParametrization( getSubcellParamData().lineEdges, 1, line );
313 isSubcellParametrizationSet =
true;
318 setSubcellParametrization( NodeDataHostView &subcellParam,
319 const ordinal_type subcellDim,
320 const shards::CellTopology &parentCell ) {
322 const auto sc = parentCell.getSubcellCount(subcellDim);
323 const auto pcd = parentCell.getDimension();
324 const auto coeff = (subcellDim == 1) ? 2 : 3;
327 subcellParam = NodeDataHostView(
"subcellParam",
330 NodeDataHostView v0(
"v0", 3), v1(
"v1", 3), v2(
"v1", 3), v3(
"v1", 3);
331 if (subcellDim == 1) {
333 for (size_type subcellOrd=0;subcellOrd<sc;++subcellOrd) {
336 const auto v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0);
337 const auto v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1);
339 getReferenceNode(v0, parentCell, v0ord);
340 getReferenceNode(v1, parentCell, v1ord);
343 subcellParam(subcellOrd, 0, 0) = (v0[0] + v1[0])/2.0;
344 subcellParam(subcellOrd, 0, 1) = (v1[0] - v0[0])/2.0;
347 subcellParam(subcellOrd, 1, 0) = (v0[1] + v1[1])/2.0;
348 subcellParam(subcellOrd, 1, 1) = (v1[1] - v0[1])/2.0;
352 subcellParam(subcellOrd, 2, 0) = (v0[2] + v1[2])/2.0;
353 subcellParam(subcellOrd, 2, 1) = (v1[2] - v0[2])/2.0;
357 else if (subcellDim == 2) {
361 for (size_type subcellOrd=0;subcellOrd<sc;++subcellOrd) {
363 switch (parentCell.getKey(subcellDim,subcellOrd)) {
365 case shards::Triangle<3>::key:
366 case shards::Triangle<4>::key:
367 case shards::Triangle<6>::key: {
368 const auto v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0);
369 const auto v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1);
370 const auto v2ord = parentCell.getNodeMap(subcellDim, subcellOrd, 2);
372 getReferenceNode(v0, parentCell, v0ord);
373 getReferenceNode(v1, parentCell, v1ord);
374 getReferenceNode(v2, parentCell, v2ord);
377 subcellParam(subcellOrd, 0, 0) = v0[0];
378 subcellParam(subcellOrd, 0, 1) = v1[0] - v0[0];
379 subcellParam(subcellOrd, 0, 2) = v2[0] - v0[0];
382 subcellParam(subcellOrd, 1, 0) = v0[1];
383 subcellParam(subcellOrd, 1, 1) = v1[1] - v0[1];
384 subcellParam(subcellOrd, 1, 2) = v2[1] - v0[1];
387 subcellParam(subcellOrd, 2, 0) = v0[2];
388 subcellParam(subcellOrd, 2, 1) = v1[2] - v0[2];
389 subcellParam(subcellOrd, 2, 2) = v2[2] - v0[2];
392 case shards::Quadrilateral<4>::key:
393 case shards::Quadrilateral<8>::key:
394 case shards::Quadrilateral<9>::key: {
395 const auto v0ord = parentCell.getNodeMap(subcellDim, subcellOrd, 0);
396 const auto v1ord = parentCell.getNodeMap(subcellDim, subcellOrd, 1);
397 const auto v2ord = parentCell.getNodeMap(subcellDim, subcellOrd, 2);
398 const auto v3ord = parentCell.getNodeMap(subcellDim, subcellOrd, 3);
400 getReferenceNode(v0, parentCell, v0ord);
401 getReferenceNode(v1, parentCell, v1ord);
402 getReferenceNode(v2, parentCell, v2ord);
403 getReferenceNode(v3, parentCell, v3ord);
406 subcellParam(subcellOrd, 0, 0) = ( v0[0] + v1[0] + v2[0] + v3[0])/4.0;
407 subcellParam(subcellOrd, 0, 1) = (-v0[0] + v1[0] + v2[0] - v3[0])/4.0;
408 subcellParam(subcellOrd, 0, 2) = (-v0[0] - v1[0] + v2[0] + v3[0])/4.0;
410 subcellParam(subcellOrd, 1, 0) = ( v0[1] + v1[1] + v2[1] + v3[1])/4.0;
411 subcellParam(subcellOrd, 1, 1) = (-v0[1] + v1[1] + v2[1] - v3[1])/4.0;
412 subcellParam(subcellOrd, 1, 2) = (-v0[1] - v1[1] + v2[1] + v3[1])/4.0;
415 subcellParam(subcellOrd, 2, 0) = ( v0[2] + v1[2] + v2[2] + v3[2])/4.0;
416 subcellParam(subcellOrd, 2, 1) = (-v0[2] + v1[2] + v2[2] - v3[2])/4.0;
417 subcellParam(subcellOrd, 2, 2) = (-v0[2] - v1[2] + v2[2] + v3[2])/4.0;
421 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
422 ">>> ERROR (Intrepid2::CellTools::setSubcellParametrization): parametrization not defined for the specified face topology.");
436 template<
typename jacobianViewType,
437 typename basisGradViewType,
438 typename nodeViewType>
439 KOKKOS_INLINE_FUNCTION
441 computeJacobian(
const jacobianViewType &jacobian,
442 const basisGradViewType &grads,
443 const nodeViewType &nodes) {
444 const auto N = nodes.extent(0);
446 const auto D = jacobian.extent(0);
447 const auto sD = jacobian.extent(1);
449 INTREPID2_TEST_FOR_ABORT( N != grads.extent(0),
"grad dimension_0 does not match to cardinality.");
450 INTREPID2_TEST_FOR_ABORT(sD != grads.extent(1),
"grad dimension_1 does not match to space dim.");
451 INTREPID2_TEST_FOR_ABORT( D != nodes.extent(1),
"node dimension_1 does not match to space dim.");
453 Kernels::Serial::gemm_trans_notrans(1.0, nodes, grads, 0.0, jacobian);
461 template<
typename pointViewType,
462 typename basisValViewType,
463 typename nodeViewType>
464 KOKKOS_INLINE_FUNCTION
466 mapToPhysicalFrame(
const pointViewType &point,
467 const basisValViewType &vals,
468 const nodeViewType &nodes) {
469 const auto N = vals.extent(0);
470 const auto D = point.extent(0);
472 INTREPID2_TEST_FOR_ABORT(N != nodes.extent(0),
"nodes dimension_0 does not match to vals dimension_0.");
473 INTREPID2_TEST_FOR_ABORT(D != nodes.extent(1),
"node dimension_1 does not match to space dim.");
475 Kernels::Serial::gemv_trans(1.0, nodes, vals, 0.0, point);
485 template<
typename implBasisType,
486 typename refPointViewType,
487 typename phyPointViewType,
488 typename nodeViewType>
489 KOKKOS_INLINE_FUNCTION
491 mapToReferenceFrame(
const refPointViewType &xref,
492 const phyPointViewType &xphy,
493 const nodeViewType &nodes) {
494 const ordinal_type sD = xref.extent(0);
495 const ordinal_type D = xphy.extent(0);
496 const ordinal_type N = nodes.extent(0);
498 INTREPID2_TEST_FOR_ABORT(sD > D,
"subcell dimension is greater than physical cell dimension.");
499 INTREPID2_TEST_FOR_ABORT(D != static_cast<ordinal_type>(nodes.extent(1)),
"xphy dimension_0 does not match to space dim.");
501 typedef typename refPointViewType::non_const_value_type value_type;
505 value_type buf[27*3 + 27 + 9 + 9 + 9 + 9 + 3 + 3] = {}, *ptr = &buf[0];
506 Kokkos::DynRankView<value_type,
507 Kokkos::Impl::ActiveExecutionMemorySpace,
508 Kokkos::MemoryUnmanaged> grads(ptr, N, sD); ptr += N*sD;
510 Kokkos::DynRankView<value_type,
511 Kokkos::Impl::ActiveExecutionMemorySpace,
512 Kokkos::MemoryUnmanaged> vals(ptr, N); ptr += N;
514 Kokkos::DynRankView<value_type,
515 Kokkos::Impl::ActiveExecutionMemorySpace,
516 Kokkos::MemoryUnmanaged> jac(ptr, D, sD); ptr += D*sD;
518 Kokkos::DynRankView<value_type,
519 Kokkos::Impl::ActiveExecutionMemorySpace,
520 Kokkos::MemoryUnmanaged> metric(ptr, sD, sD); ptr += sD*sD;
522 Kokkos::DynRankView<value_type,
523 Kokkos::Impl::ActiveExecutionMemorySpace,
524 Kokkos::MemoryUnmanaged> invmetric(ptr, sD, sD); ptr += sD*sD;
526 Kokkos::DynRankView<value_type,
527 Kokkos::Impl::ActiveExecutionMemorySpace,
528 Kokkos::MemoryUnmanaged> invdf(ptr, sD, D); ptr += sD*D;
530 Kokkos::DynRankView<value_type,
531 Kokkos::Impl::ActiveExecutionMemorySpace,
532 Kokkos::MemoryUnmanaged> xtmp(ptr, sD); ptr += sD;
534 Kokkos::DynRankView<value_type,
535 Kokkos::Impl::ActiveExecutionMemorySpace,
536 Kokkos::MemoryUnmanaged> xold(ptr, sD); ptr += sD;
539 for (ordinal_type j=0;j<D;++j) xold(j) = 0;
541 const double tol = tolerence();
545 mapToPhysicalFrame(xtmp, vals, nodes);
549 CellTools::Serial::computeJacobian(jac, grads, nodes);
551 Kernels::Serial::gemm_trans_notrans(1.0, jac, jac, 0.0, metric);
552 Kernels::Serial::inverse(invmetric, metric);
553 Kernels::Serial::gemm_notrans_trans(1.0, invmetric, jac, 0.0, invdf);
556 Kernels::Serial::z_is_axby(xtmp, 1.0, xphy, -1.0, xtmp);
557 Kernels::Serial::gemv_notrans(1.0, invdf, xtmp, 0.0, xref);
558 Kernels::Serial::z_is_axby(xref, 1.0, xold, 1.0, xref);
561 Kernels::Serial::z_is_axby(xtmp, 1.0, xold, -1.0, xref);
563 double err = Kernels::Serial::norm(xtmp, NORM_ONE);
568 Kernels::Serial::copy(xold, xref);
577 static ConstUnmanagedNodeDataHostView
579 const shards::CellTopology parent_cell) {
583 Kokkos::DynRankView<const double,Kokkos::HostSpace,Kokkos::MemoryUnmanaged> r_val;
584 if (subcell_dim == 2) {
585 switch (parent_cell.getBaseKey()) {
586 case shards::Tetrahedron<>::key: r_val = getSubcellParamData().tetFaces;
break;
587 case shards::Hexahedron<>::key: r_val = getSubcellParamData().hexFaces;
break;
588 case shards::Pyramid<>::key: r_val = getSubcellParamData().pyrFaces;
break;
589 case shards::Wedge<18>::key: r_val = getSubcellParamData().wedgeFaces;
break;
592 else if (subcell_dim == 1) {
593 switch (parent_cell.getBaseKey()) {
594 case shards::Tetrahedron<>::key: r_val = getSubcellParamData().tetEdges;
break;
595 case shards::Hexahedron<>::key: r_val = getSubcellParamData().hexEdges;
break;
596 case shards::Pyramid<>::key: r_val = getSubcellParamData().pyrEdges;
break;
597 case shards::Wedge<>::key: r_val = getSubcellParamData().wedgeEdges;
break;
598 case shards::Triangle<>::key: r_val = getSubcellParamData().triEdges;
break;
599 case shards::Quadrilateral<>::key: r_val = getSubcellParamData().quadEdges;
break;
600 case shards::Line<>::key: r_val = getSubcellParamData().lineEdges;
break;
603 INTREPID2_TEST_FOR_ABORT(r_val.rank() == 0,
"subcell param is not set up before.");
607 template<
typename refEdgeTanViewType>
610 getReferenceEdgeTangent(
const refEdgeTanViewType &ref_edge_tangent,
611 const ordinal_type edge_ordinal,
612 const shards::CellTopology &parent_cell ) {
615 const ordinal_type D = parent_cell.getDimension();
616 for (ordinal_type i=0;i<D;++i)
617 ref_edge_tangent(i) = edge_map(edge_ordinal, i, 1);
620 template<
typename refFaceTanViewType>
622 getReferenceFaceTangent(
const refFaceTanViewType &ref_face_tan_u,
623 const refFaceTanViewType &ref_face_tan_v,
624 const ordinal_type face_ordinal,
625 const shards::CellTopology &parent_cell) {
630 const ordinal_type D = parent_cell.getDimension();
631 for (ordinal_type i=0;i<D;++i) {
632 ref_face_tan_u(i) = face_map(face_ordinal, i, 1);
633 ref_face_tan_v(i) = face_map(face_ordinal, i, 2);
637 template<
typename edgeTangentViewType,
638 typename jacobianViewType>
641 getPhysicalEdgeTangent(
const edgeTangentViewType &edge_tangent,
642 const jacobianViewType &jacobian,
643 const ordinal_type edge_ordinal,
644 const shards::CellTopology &parent_cell) {
645 typedef typename edgeTangentViewType::non_const_value_type value_type;
646 const ordinal_type D = parent_cell.getDimension();
648 Kokkos::DynRankView<value_type,
649 Kokkos::Impl::ActiveExecutionMemorySpace,
650 Kokkos::MemoryUnmanaged> ref_edge_tangent(&buf[0], D);
652 getReferenceEdgeTangent(ref_edge_tangent, edge_ordinal, parent_cell);
653 Kernels::Serial::matvec_product(edge_tangent, jacobian, ref_edge_tangent);
656 template<
typename faceTanViewType,
657 typename jacobianViewType>
660 getPhysicalFaceTangent(
const faceTanViewType &face_tan_u,
661 const faceTanViewType &face_tan_v,
662 const jacobianViewType &jacobian,
663 const ordinal_type face_ordinal,
664 const shards::CellTopology &parent_cell) {
665 typedef typename faceTanViewType::non_const_value_type value_type;
666 const ordinal_type D = parent_cell.getDimension();
667 INTREPID2_TEST_FOR_ABORT(D != 3,
"computing face normal requires dimension 3.");
669 Kokkos::DynRankView<value_type,
670 Kokkos::Impl::ActiveExecutionMemorySpace,
671 Kokkos::MemoryUnmanaged> ref_face_tan_u(&buf[0], D), ref_face_tan_v(&buf[3], D);
673 getReferenceFaceTangent(ref_face_tan_u,
678 Kernels::Serial::matvec_product_d3(face_tan_u, jacobian, ref_face_tan_u);
679 Kernels::Serial::matvec_product_d3(face_tan_v, jacobian, ref_face_tan_v);
683 template<
typename faceNormalViewType,
684 typename jacobianViewType>
687 getPhysicalFaceNormal(
const faceNormalViewType &face_normal,
688 const jacobianViewType &jacobian,
689 const ordinal_type face_ordinal,
690 const shards::CellTopology &parent_cell) {
691 typedef typename faceNormalViewType::non_const_value_type value_type;
692 const ordinal_type D = parent_cell.getDimension();
693 INTREPID2_TEST_FOR_ABORT(D != 3,
"computing face normal requires dimension 3.");
695 Kokkos::DynRankView<value_type,
696 Kokkos::Impl::ActiveExecutionMemorySpace,
697 Kokkos::MemoryUnmanaged> face_tan_u(&buf[0], D), face_tan_v(&buf[3], D);
699 getPhysicalFaceTangent(face_tan_u, face_tan_v,
703 Kernels::Serial::vector_product_d3(face_normal, face_tan_u, face_tan_v);
706 template<
typename sideNormalViewType,
707 typename jacobianViewType>
710 getPhysicalSideNormal(
const sideNormalViewType &side_normal,
711 const jacobianViewType &jacobian,
712 const ordinal_type side_ordinal,
713 const shards::CellTopology &parent_cell ) {
714 const ordinal_type D = parent_cell.getDimension();
715 typedef typename sideNormalViewType::non_const_value_type value_type;
719 Kokkos::DynRankView<value_type,
720 Kokkos::Impl::ActiveExecutionMemorySpace,
721 Kokkos::MemoryUnmanaged> edge_tangent(&buf[0], D);
722 getPhysicalEdgeTangent(edge_tangent, jacobian, side_ordinal, parent_cell);
723 side_normal(0) = edge_tangent(1);
724 side_normal(1) = -edge_tangent(0);
728 getPhysicalFaceNormal(side_normal, jacobian, side_ordinal, parent_cell);
732 INTREPID2_TEST_FOR_ABORT(
true,
"cell dimension is out of range.");