46 template<
typename jacobianViewType,
47 typename basisGradViewType,
48 typename nodeViewType>
49 KOKKOS_INLINE_FUNCTION
51 computeJacobian(
const jacobianViewType &jacobian,
52 const basisGradViewType &grads,
53 const nodeViewType &nodes) {
54 const auto numNodes = nodes.extent(0);
56 const auto physDim = jacobian.extent(0);
57 const auto refDim = jacobian.extent(1);
59 INTREPID2_TEST_FOR_ABORT( numNodes != grads.extent(0),
"grad dimension_0 does not match to cardinality.");
60 INTREPID2_TEST_FOR_ABORT(refDim != grads.extent(1),
"grad dimension_1 does not match to space dim.");
61 INTREPID2_TEST_FOR_ABORT( physDim != nodes.extent(1),
"node dimension_1 does not match to space dim.");
63 Kernels::Serial::gemm_trans_notrans(1.0, nodes, grads, 0.0, jacobian);
71 template<
typename PointViewType,
72 typename basisValViewType,
73 typename nodeViewType>
74 KOKKOS_INLINE_FUNCTION
76 mapToPhysicalFrame(
const PointViewType &point,
77 const basisValViewType &vals,
78 const nodeViewType &nodes) {
79 const auto numNodes = vals.extent(0);
80 const auto physDim = point.extent(0);
82 INTREPID2_TEST_FOR_ABORT(numNodes != nodes.extent(0),
"nodes dimension_0 does not match to vals dimension_0.");
83 INTREPID2_TEST_FOR_ABORT(physDim != nodes.extent(1),
"node dimension_1 does not match to space dim.");
85 Kernels::Serial::gemv_trans(1.0, nodes, vals, 0.0, point);
115 template<
typename implBasisType,
116 typename refPointViewType,
117 typename phyPointViewType,
118 typename nodeViewType>
119 KOKKOS_INLINE_FUNCTION
122 const phyPointViewType &physPoint,
123 const nodeViewType &nodes,
124 const double tol = tolerance(),
125 const typename phyPointViewType::value_type shellThickness = -1.0) {
127 bool isBeamOrShell = (shellThickness > 0);
130 const ordinal_type refDim = refPoint.extent(0) - ordinal_type(isBeamOrShell);
131 const ordinal_type physDim = physPoint.extent(0);
132 const ordinal_type numNodes = nodes.extent(0);
134 INTREPID2_TEST_FOR_ABORT(refDim > physDim,
"the dimension of the reference cell is greater than physical cell dimension.");
135 INTREPID2_TEST_FOR_ABORT(physDim !=
static_cast<ordinal_type
>(nodes.extent(1)),
"physPoint dimension_0 does not match to space dim.");
136 INTREPID2_TEST_FOR_ABORT(numNodes > 27,
"function hard-coded to support at most mappings with 27 Dofs");
138 typedef typename refPointViewType::non_const_value_type value_type;
142 value_type buf[27*3 + 27 + 9 + 9 + 9 + 9 + 3 + 3] = {}, *ptr = &buf[0];
143 Kokkos::DynRankView<value_type,
144 Kokkos::AnonymousSpace,
145 Kokkos::MemoryUnmanaged> grads(ptr, numNodes, refDim); ptr += numNodes*refDim;
147 Kokkos::DynRankView<value_type,
148 Kokkos::AnonymousSpace,
149 Kokkos::MemoryUnmanaged> vals(ptr, numNodes); ptr += numNodes;
151 Kokkos::DynRankView<value_type,
152 Kokkos::AnonymousSpace,
153 Kokkos::MemoryUnmanaged> jac(ptr, physDim, refDim); ptr += physDim*refDim;
155 Kokkos::DynRankView<value_type,
156 Kokkos::AnonymousSpace,
157 Kokkos::MemoryUnmanaged> metric(ptr, refDim, refDim); ptr += refDim*refDim;
159 Kokkos::DynRankView<value_type,
160 Kokkos::AnonymousSpace,
161 Kokkos::MemoryUnmanaged> invMetric(ptr, refDim, refDim); ptr += refDim*refDim;
163 Kokkos::DynRankView<value_type,
164 Kokkos::AnonymousSpace,
165 Kokkos::MemoryUnmanaged> invDf(ptr, refDim, physDim); ptr += refDim*physDim;
167 Kokkos::DynRankView<value_type,
168 Kokkos::AnonymousSpace,
169 Kokkos::MemoryUnmanaged> tmpPhysPoint(ptr, physDim); ptr += physDim;
171 Kokkos::DynRankView<value_type,
172 Kokkos::AnonymousSpace,
173 Kokkos::MemoryUnmanaged> oldRefPoint(ptr, refDim); ptr += refDim;
175 double xphyNorm = Kernels::Serial::norm(physPoint, NORM_TWO);
177 const auto refDimRange = Kokkos::pair<ordinal_type,ordinal_type>(0, refDim);
178 auto refPt = Kokkos::subview(refPoint,refDimRange);
181 Kernels::Serial::copy(oldRefPoint, refPt);
183 bool converged =
false;
187 mapToPhysicalFrame(tmpPhysPoint, vals, nodes);
188 Kernels::Serial::z_is_axby(tmpPhysPoint, 1.0, physPoint, -1.0, tmpPhysPoint);
189 double residualNorm = Kernels::Serial::norm(tmpPhysPoint, NORM_TWO);
190 if (residualNorm < tol*xphyNorm) {
197 CellTools::Serial::computeJacobian(jac, grads, nodes);
199 if(physDim == refDim) {
200 Kernels::Serial::inverse(invDf, jac);
202 Kernels::Serial::gemm_trans_notrans(1.0, jac, jac, 0.0, metric);
203 Kernels::Serial::inverse(invMetric, metric);
204 Kernels::Serial::gemm_notrans_trans(1.0, invMetric, jac, 0.0, invDf);
208 Kernels::Serial::gemv_notrans(1.0, invDf, tmpPhysPoint, 0.0, refPt);
210 double err = Kernels::Serial::norm(refPt, NORM_TWO);
212 Kernels::Serial::z_is_axby(refPt, 1.0, oldRefPoint, 1.0, refPt);
219 Kernels::Serial::copy(oldRefPoint, refPt);
224 CellTools::Serial::computeJacobian(jac, grads, nodes);
226 auto t1 = Kokkos::subview( jac, Kokkos::ALL(), 0);
227 auto t2 = Kokkos::subview( jac, Kokkos::ALL(), 1);
228 auto n = Kokkos::subview( invDf, 0, Kokkos::ALL());
229 Kernels::Serial::vector_product_d3(n, t1, t2);
230 refPoint(refDim) = (n(0)*tmpPhysPoint(0) + n(1)*tmpPhysPoint(1) + n(2)*tmpPhysPoint(2))*2.0/shellThickness/Kernels::Serial::norm(n, NORM_TWO);
232 auto t1 = Kokkos::subview( jac, Kokkos::ALL(), 0);
233 refPoint(refDim) = (-t1(1)*tmpPhysPoint(0) + t1(0)*tmpPhysPoint(1))*2.0/shellThickness/Kernels::Serial::norm(t1, NORM_TWO);
240 template<
typename refEdgeTanViewType,
typename ParamViewType>
241 KOKKOS_INLINE_FUNCTION
243 getReferenceEdgeTangent(
const refEdgeTanViewType refEdgeTangent,
244 const ParamViewType edgeParametrization,
245 const ordinal_type edgeOrdinal ) {
247 ordinal_type dim = edgeParametrization.extent(1);
248 for(ordinal_type i = 0; i < dim; ++i) {
249 refEdgeTangent(i) = edgeParametrization(edgeOrdinal, i, 1);
253 template<
typename refFaceTanViewType,
typename ParamViewType>
254 KOKKOS_INLINE_FUNCTION
256 getReferenceFaceTangent(
const refFaceTanViewType refFaceTanU,
257 const refFaceTanViewType refFaceTanV,
258 const ParamViewType faceParametrization,
259 const ordinal_type faceOrdinal) {
263 ordinal_type dim = faceParametrization.extent(1);
264 for(ordinal_type i = 0; i < dim; ++i) {
265 refFaceTanU(i) = faceParametrization(faceOrdinal, i, 1);
266 refFaceTanV(i) = faceParametrization(faceOrdinal, i, 2);
270 template<
typename edgeTangentViewType,
typename ParamViewType,
typename jacobianViewType>
271 KOKKOS_INLINE_FUNCTION
273 getPhysicalEdgeTangent(
const edgeTangentViewType edgeTangent,
274 const ParamViewType edgeParametrization,
275 const jacobianViewType jacobian,
276 const ordinal_type edgeOrdinal) {
277 typedef typename ParamViewType::non_const_value_type value_type;
278 const ordinal_type dim = edgeParametrization.extent(1);
280 Kokkos::DynRankView<value_type, Kokkos::AnonymousSpace,
281 Kokkos::MemoryUnmanaged> refEdgeTangent(&buf[0], dim);
283 getReferenceEdgeTangent(refEdgeTangent, edgeParametrization, edgeOrdinal);
284 Kernels::Serial::matvec_product(edgeTangent, jacobian, refEdgeTangent);
287 template<
typename faceTanViewType,
typename ParamViewType,
typename jacobianViewType>
288 KOKKOS_INLINE_FUNCTION
290 getPhysicalFaceTangents( faceTanViewType faceTanU,
291 faceTanViewType faceTanV,
292 const ParamViewType faceParametrization,
293 const jacobianViewType jacobian,
294 const ordinal_type faceOrdinal) {
295 typedef typename ParamViewType::non_const_value_type value_type;
296 const ordinal_type dim = faceParametrization.extent(1);
297 INTREPID2_TEST_FOR_ABORT(dim != 3,
298 "computing face tangents requires dimension 3.");
300 Kokkos::DynRankView<value_type,
301 Kokkos::AnonymousSpace,
302 Kokkos::MemoryUnmanaged> refFaceTanU(&buf[0], dim), refFaceTanV(&buf[3], dim);
304 getReferenceFaceTangent(refFaceTanU,
309 Kernels::Serial::matvec_product_d3(faceTanU, jacobian, refFaceTanU);
310 Kernels::Serial::matvec_product_d3(faceTanV, jacobian, refFaceTanV);
314 template<
typename faceNormalViewType,
typename ParamViewType,
typename jacobianViewType>
315 KOKKOS_INLINE_FUNCTION
317 getPhysicalFaceNormal(
const faceNormalViewType faceNormal,
318 const ParamViewType faceParametrization,
319 const jacobianViewType jacobian,
320 const ordinal_type faceOrdinal) {
321 typedef typename ParamViewType::non_const_value_type value_type;
322 const ordinal_type dim = faceParametrization.extent(1);
323 INTREPID2_TEST_FOR_ABORT(dim != 3,
324 "computing face normal requires dimension 3.");
326 Kokkos::DynRankView<value_type,
327 Kokkos::AnonymousSpace,
328 Kokkos::MemoryUnmanaged> faceTanU(&buf[0], dim), faceTanV(&buf[3], dim);
330 getPhysicalFaceTangents(faceTanU, faceTanV,
334 Kernels::Serial::vector_product_d3(faceNormal, faceTanU, faceTanV);
337 template<
typename s
ideNormalViewType,
typename ParamViewType,
typename jacobianViewType>
338 KOKKOS_INLINE_FUNCTION
340 getPhysicalSideNormal(
const sideNormalViewType sideNormal,
341 const ParamViewType sideParametrization,
342 const jacobianViewType jacobian,
343 const ordinal_type sideOrdinal) {
344 const ordinal_type dim = sideParametrization.extent(1);
345 typedef typename ParamViewType::non_const_value_type value_type;
349 Kokkos::DynRankView<value_type,
350 Kokkos::AnonymousSpace,
351 Kokkos::MemoryUnmanaged> edgeTangent(&buf[0], dim);
352 getPhysicalEdgeTangent(edgeTangent, sideParametrization, jacobian, sideOrdinal);
353 sideNormal(0) = edgeTangent(1);
354 sideNormal(1) = -edgeTangent(0);
358 getPhysicalFaceNormal(sideNormal, sideParametrization, jacobian, sideOrdinal);
362 INTREPID2_TEST_FOR_ABORT(
true,
"cell dimension is out of range.");