44 jacobianViewType _jacobian;
45 const worksetCellType _worksetCells;
46 const basisGradType _basisGrads;
49 KOKKOS_INLINE_FUNCTION
51 worksetCellType worksetCells_,
52 basisGradType basisGrads_,
54 : _jacobian(jacobian_), _worksetCells(worksetCells_), _basisGrads(basisGrads_),
55 _startCell(startCell_) {}
57 KOKKOS_INLINE_FUNCTION
58 void operator()(
const ordinal_type cell,
59 const ordinal_type point)
const {
61 const ordinal_type phys_dim = _jacobian.extent(2);
63 const ordinal_type gradRank = rank(_basisGrads);
64 const ordinal_type ref_dim = _basisGrads.extent_int(gradRank-1);
68 const ordinal_type cardinality = _basisGrads.extent(0);
69 for (ordinal_type i=0;i<phys_dim;++i)
70 for (ordinal_type j=0;j<ref_dim;++j) {
71 _jacobian(cell, point, i, j) = 0;
72 for (ordinal_type bf=0;bf<cardinality;++bf)
73 _jacobian(cell, point, i, j) += _worksetCells(cell+_startCell, bf, i) * _basisGrads(bf, point, j);
78 const ordinal_type cardinality = _basisGrads.extent(1);
79 for (ordinal_type i=0;i<phys_dim;++i)
80 for (ordinal_type j=0;j<ref_dim;++j) {
81 _jacobian(cell, point, i, j) = 0;
82 for (ordinal_type bf=0;bf<cardinality;++bf)
83 _jacobian(cell, point, i, j) += _worksetCells(cell+_startCell, bf, i) * _basisGrads(cell, bf, point, j);
172 const int CELL_DIM = 0;
173 const int POINT_DIM = 1;
174 const int D1_DIM = 2;
175 const bool cellVaries = (variationTypes[CELL_DIM] !=
CONSTANT);
176 const bool pointVaries = (variationTypes[POINT_DIM] !=
CONSTANT);
178 auto det2 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d) -> PointScalar
180 return a * d - b * c;
183 auto det3 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
184 const PointScalar &d,
const PointScalar &e,
const PointScalar &f,
185 const PointScalar &g,
const PointScalar &h,
const PointScalar &i) -> PointScalar
187 return a * det2(e,f,h,i) - b * det2(d,f,g,i) + c * det2(d,e,g,h);
190 auto det4 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d,
191 const PointScalar &e,
const PointScalar &f,
const PointScalar &g,
const PointScalar &h,
192 const PointScalar &i,
const PointScalar &j,
const PointScalar &k,
const PointScalar &l,
193 const PointScalar &m,
const PointScalar &n,
const PointScalar &o,
const PointScalar &p) -> PointScalar
195 return a * det3(f,g,h,j,k,l,n,o,p) - b * det3(e,g,h,i,k,l,m,o,p) + c * det3(e,f,h,i,j,l,m,n,p) - d * det3(e,f,g,i,j,k,m,n,o);
200 if (cellVaries && pointVaries)
205 Kokkos::parallel_for(
206 Kokkos::MDRangePolicy<ExecSpaceType,Kokkos::Rank<2>>({0,0},{data.extent_int(0),data.extent_int(1)}),
207 KOKKOS_LAMBDA (
int cellOrdinal,
int pointOrdinal) {
209 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
210 const int spaceDim = blockWidth + numDiagonals;
212 PointScalar det = 1.0;
220 det = data(cellOrdinal,pointOrdinal,0);
225 const auto & a = data(cellOrdinal,pointOrdinal,0);
226 const auto & b = data(cellOrdinal,pointOrdinal,1);
227 const auto & c = data(cellOrdinal,pointOrdinal,2);
228 const auto & d = data(cellOrdinal,pointOrdinal,3);
235 const auto & a = data(cellOrdinal,pointOrdinal,0);
236 const auto & b = data(cellOrdinal,pointOrdinal,1);
237 const auto & c = data(cellOrdinal,pointOrdinal,2);
238 const auto & d = data(cellOrdinal,pointOrdinal,3);
239 const auto & e = data(cellOrdinal,pointOrdinal,4);
240 const auto & f = data(cellOrdinal,pointOrdinal,5);
241 const auto & g = data(cellOrdinal,pointOrdinal,6);
242 const auto & h = data(cellOrdinal,pointOrdinal,7);
243 const auto & i = data(cellOrdinal,pointOrdinal,8);
244 det = det3(a,b,c,d,e,f,g,h,i);
250 const auto & a = data(cellOrdinal,pointOrdinal,0);
251 const auto & b = data(cellOrdinal,pointOrdinal,1);
252 const auto & c = data(cellOrdinal,pointOrdinal,2);
253 const auto & d = data(cellOrdinal,pointOrdinal,3);
254 const auto & e = data(cellOrdinal,pointOrdinal,4);
255 const auto & f = data(cellOrdinal,pointOrdinal,5);
256 const auto & g = data(cellOrdinal,pointOrdinal,6);
257 const auto & h = data(cellOrdinal,pointOrdinal,7);
258 const auto & i = data(cellOrdinal,pointOrdinal,8);
259 const auto & j = data(cellOrdinal,pointOrdinal,9);
260 const auto & k = data(cellOrdinal,pointOrdinal,10);
261 const auto & l = data(cellOrdinal,pointOrdinal,11);
262 const auto & m = data(cellOrdinal,pointOrdinal,12);
263 const auto & n = data(cellOrdinal,pointOrdinal,13);
264 const auto & o = data(cellOrdinal,pointOrdinal,14);
265 const auto & p = data(cellOrdinal,pointOrdinal,15);
266 det = det4(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
274 const int offset = blockWidth * blockWidth;
276 for (
int d=blockWidth; d<spaceDim; d++)
278 const int index = d-blockWidth+offset;
279 det *= data(cellOrdinal,pointOrdinal,index);
281 detData(cellOrdinal,pointOrdinal) = det;
284 else if (cellVaries || pointVaries)
289 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,data.extent_int(0)),
290 KOKKOS_LAMBDA (
const int &cellPointOrdinal) {
292 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
293 const int spaceDim = blockWidth + numDiagonals;
295 PointScalar det = 1.0;
303 det = data(cellPointOrdinal,0);
308 const auto & a = data(cellPointOrdinal,0);
309 const auto & b = data(cellPointOrdinal,1);
310 const auto & c = data(cellPointOrdinal,2);
311 const auto & d = data(cellPointOrdinal,3);
318 const auto & a = data(cellPointOrdinal,0);
319 const auto & b = data(cellPointOrdinal,1);
320 const auto & c = data(cellPointOrdinal,2);
321 const auto & d = data(cellPointOrdinal,3);
322 const auto & e = data(cellPointOrdinal,4);
323 const auto & f = data(cellPointOrdinal,5);
324 const auto & g = data(cellPointOrdinal,6);
325 const auto & h = data(cellPointOrdinal,7);
326 const auto & i = data(cellPointOrdinal,8);
327 det = det3(a,b,c,d,e,f,g,h,i);
335 const int offset = blockWidth * blockWidth;
337 for (
int d=blockWidth; d<spaceDim; d++)
339 const int index = d-blockWidth+offset;
340 det *= data(cellPointOrdinal,index);
342 detData(cellPointOrdinal) = det;
349 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,1),
350 KOKKOS_LAMBDA (
const int &dummyArg) {
352 const int numDiagonals = jacobian.
extent_int(2) - blockWidth * blockWidth;
353 const int spaceDim = blockWidth + numDiagonals;
355 PointScalar det = 1.0;
368 const auto & a = data(0);
369 const auto & b = data(1);
370 const auto & c = data(2);
371 const auto & d = data(3);
378 const auto & a = data(0);
379 const auto & b = data(1);
380 const auto & c = data(2);
381 const auto & d = data(3);
382 const auto & e = data(4);
383 const auto & f = data(5);
384 const auto & g = data(6);
385 const auto & h = data(7);
386 const auto & i = data(8);
387 det = det3(a,b,c,d,e,f,g,h,i);
395 const int offset = blockWidth * blockWidth;
397 for (
int d=blockWidth; d<spaceDim; d++)
399 const int index = d-blockWidth+offset;
422 Kokkos::parallel_for(
"fill jacobian det", Kokkos::RangePolicy<ExecSpaceType>(0,1), KOKKOS_LAMBDA(
const int &i)
424 detData(0) = Intrepid2::Kernels::Serial::determinant(data);
429 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"jacobian's underlying view must have rank 2,3, or 4");
449 const int CELL_DIM = 0;
450 const int POINT_DIM = 1;
451 const int D1_DIM = 2;
453 auto det2 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d) -> PointScalar
455 return a * d - b * c;
458 auto det3 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
459 const PointScalar &d,
const PointScalar &e,
const PointScalar &f,
460 const PointScalar &g,
const PointScalar &h,
const PointScalar &i) -> PointScalar
462 return a * det2(e,f,h,i) - b * det2(d,f,g,i) + c * det2(d,e,g,h);
467 const bool cellVaries = variationTypes[CELL_DIM] !=
CONSTANT;
468 const bool pointVaries = variationTypes[POINT_DIM] !=
CONSTANT;
469 if (cellVaries && pointVaries)
474 Kokkos::parallel_for(
475 Kokkos::MDRangePolicy<ExecSpaceType,Kokkos::Rank<2>>({0,0},{data.extent_int(0),data.extent_int(1)}),
476 KOKKOS_LAMBDA (
int cellOrdinal,
int pointOrdinal) {
478 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
479 const int spaceDim = blockWidth + numDiagonals;
487 invData(cellOrdinal,pointOrdinal,0) = 1.0 / data(cellOrdinal,pointOrdinal,0);
492 const auto & a = data(cellOrdinal,pointOrdinal,0);
493 const auto & b = data(cellOrdinal,pointOrdinal,1);
494 const auto & c = data(cellOrdinal,pointOrdinal,2);
495 const auto & d = data(cellOrdinal,pointOrdinal,3);
496 const PointScalar det = det2(a,b,c,d);
498 invData(cellOrdinal,pointOrdinal,0) = d/det;
499 invData(cellOrdinal,pointOrdinal,1) = - b/det;
500 invData(cellOrdinal,pointOrdinal,2) = - c/det;
501 invData(cellOrdinal,pointOrdinal,3) = a/det;
506 const auto & a = data(cellOrdinal,pointOrdinal,0);
507 const auto & b = data(cellOrdinal,pointOrdinal,1);
508 const auto & c = data(cellOrdinal,pointOrdinal,2);
509 const auto & d = data(cellOrdinal,pointOrdinal,3);
510 const auto & e = data(cellOrdinal,pointOrdinal,4);
511 const auto & f = data(cellOrdinal,pointOrdinal,5);
512 const auto & g = data(cellOrdinal,pointOrdinal,6);
513 const auto & h = data(cellOrdinal,pointOrdinal,7);
514 const auto & i = data(cellOrdinal,pointOrdinal,8);
515 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
518 const auto val0 = e*i - h*f;
519 const auto val1 = - d*i + g*f;
520 const auto val2 = d*h - g*e;
522 invData(cellOrdinal,pointOrdinal,0) = val0/det;
523 invData(cellOrdinal,pointOrdinal,1) = val1/det;
524 invData(cellOrdinal,pointOrdinal,2) = val2/det;
527 const auto val0 = h*c - b*i;
528 const auto val1 = a*i - g*c;
529 const auto val2 = - a*h + g*b;
531 invData(cellOrdinal,pointOrdinal,3) = val0/det;
532 invData(cellOrdinal,pointOrdinal,4) = val1/det;
533 invData(cellOrdinal,pointOrdinal,5) = val2/det;
536 const auto val0 = b*f - e*c;
537 const auto val1 = - a*f + d*c;
538 const auto val2 = a*e - d*b;
540 invData(cellOrdinal,pointOrdinal,6) = val0/det;
541 invData(cellOrdinal,pointOrdinal,7) = val1/det;
542 invData(cellOrdinal,pointOrdinal,8) = val2/det;
550 const int offset = blockWidth * blockWidth;
552 for (
int d=blockWidth; d<spaceDim; d++)
554 const int index = d-blockWidth+offset;
555 invData(cellOrdinal,pointOrdinal,index) = 1.0 / data(cellOrdinal,pointOrdinal,index);
559 else if (cellVaries || pointVaries)
564 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,data.extent_int(0)),
565 KOKKOS_LAMBDA (
const int &cellPointOrdinal) {
567 const int numDiagonals = data.extent_int(1) - blockWidth * blockWidth;
568 const int spaceDim = blockWidth + numDiagonals;
576 invData(cellPointOrdinal,0) = 1.0 / data(cellPointOrdinal,0);
581 const auto & a = data(cellPointOrdinal,0);
582 const auto & b = data(cellPointOrdinal,1);
583 const auto & c = data(cellPointOrdinal,2);
584 const auto & d = data(cellPointOrdinal,3);
585 const PointScalar det = det2(a,b,c,d);
587 invData(cellPointOrdinal,0) = d/det;
588 invData(cellPointOrdinal,1) = - b/det;
589 invData(cellPointOrdinal,2) = - c/det;
590 invData(cellPointOrdinal,3) = a/det;
595 const auto & a = data(cellPointOrdinal,0);
596 const auto & b = data(cellPointOrdinal,1);
597 const auto & c = data(cellPointOrdinal,2);
598 const auto & d = data(cellPointOrdinal,3);
599 const auto & e = data(cellPointOrdinal,4);
600 const auto & f = data(cellPointOrdinal,5);
601 const auto & g = data(cellPointOrdinal,6);
602 const auto & h = data(cellPointOrdinal,7);
603 const auto & i = data(cellPointOrdinal,8);
604 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
607 const auto val0 = e*i - h*f;
608 const auto val1 = - d*i + g*f;
609 const auto val2 = d*h - g*e;
611 invData(cellPointOrdinal,0) = val0/det;
612 invData(cellPointOrdinal,1) = val1/det;
613 invData(cellPointOrdinal,2) = val2/det;
616 const auto val0 = h*c - b*i;
617 const auto val1 = a*i - g*c;
618 const auto val2 = - a*h + g*b;
620 invData(cellPointOrdinal,3) = val0/det;
621 invData(cellPointOrdinal,4) = val1/det;
622 invData(cellPointOrdinal,5) = val2/det;
625 const auto val0 = b*f - e*c;
626 const auto val1 = - a*f + d*c;
627 const auto val2 = a*e - d*b;
629 invData(cellPointOrdinal,6) = val0/det;
630 invData(cellPointOrdinal,7) = val1/det;
631 invData(cellPointOrdinal,8) = val2/det;
639 const int offset = blockWidth * blockWidth;
641 for (
int d=blockWidth; d<spaceDim; d++)
643 const int index = d-blockWidth+offset;
644 invData(cellPointOrdinal,index) = 1.0 / data(cellPointOrdinal,index);
653 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,1),
654 KOKKOS_LAMBDA (
const int &dummyArg) {
656 const int numDiagonals = data.extent_int(0) - blockWidth * blockWidth;
657 const int spaceDim = blockWidth + numDiagonals;
665 invData(0) = 1.0 / data(0);
670 const auto & a = data(0);
671 const auto & b = data(1);
672 const auto & c = data(2);
673 const auto & d = data(3);
674 const PointScalar det = det2(a,b,c,d);
677 invData(1) = - b/det;
678 invData(2) = - c/det;
684 const auto & a = data(0);
685 const auto & b = data(1);
686 const auto & c = data(2);
687 const auto & d = data(3);
688 const auto & e = data(4);
689 const auto & f = data(5);
690 const auto & g = data(6);
691 const auto & h = data(7);
692 const auto & i = data(8);
693 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
696 const auto val0 = e*i - h*f;
697 const auto val1 = - d*i + g*f;
698 const auto val2 = d*h - g*e;
700 invData(0) = val0/det;
701 invData(1) = val1/det;
702 invData(2) = val2/det;
705 const auto val0 = h*c - b*i;
706 const auto val1 = a*i - g*c;
707 const auto val2 = - a*h + g*b;
709 invData(3) = val0/det;
710 invData(4) = val1/det;
711 invData(5) = val2/det;
714 const auto val0 = b*f - e*c;
715 const auto val1 = - a*f + d*c;
716 const auto val2 = a*e - d*b;
718 invData(6) = val0/det;
719 invData(7) = val1/det;
720 invData(8) = val2/det;
728 const int offset = blockWidth * blockWidth;
730 for (
int d=blockWidth; d<spaceDim; d++)
732 const int index = d-blockWidth+offset;
733 invData(index) = 1.0 / data(index);
757 Kokkos::parallel_for(
"fill jacobian inverse", Kokkos::RangePolicy<ExecSpaceType>(0,1), KOKKOS_LAMBDA(
const int &i)
759 Intrepid2::Kernels::Serial::inverse(invData,data);
764 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"jacobian's underlying view must have rank 2,3, or 4");
807 const PointViewType points,
808 const WorksetType worksetCell,
809 const Teuchos::RCP<HGradBasisType> basis,
810 const int startCell,
const int endCell) {
811 constexpr bool are_accessible =
812 Kokkos::SpaceAccessibility<MemSpaceType,
813 typename decltype(jacobian)::memory_space>::accessible &&
814 Kokkos::SpaceAccessibility<MemSpaceType,
815 typename decltype(points)::memory_space>::accessible;
816 static_assert(are_accessible,
"CellTools<DeviceType>::setJacobian(..): input/output views' memory spaces are not compatible with DeviceType");
818#ifdef HAVE_INTREPID2_DEBUG
819 CellTools_setJacobianArgs(jacobian, points, worksetCell, basis->getBaseCellTopology(), startCell, endCell);
822 const ordinal_type numCells = jacobian.extent(0);
825 const ordinal_type pointRank = points.rank();
826 const ordinal_type numPoints = (pointRank == 2 ? points.extent(0) : points.extent(1));
827 const ordinal_type basisCardinality = basis->getCardinality();
829 using GradViewType = Kokkos::DynRankView<
typename decltype(points)::value_type,DeviceType>;
836 grads = Impl::createMatchingView<GradViewType>(points,
"CellTools::setJacobian::grads", basisCardinality, numPoints, basis->getDomainDimension());
837 basis->getValues(grads,
844 grads = Impl::createMatchingView<GradViewType>(points,
"CellTools::setJacobian::grads", numCells, basisCardinality, numPoints, basis->getDomainDimension());
845 getHGradValues<OPERATOR_GRAD>(grads,points,basis.get());
850 setJacobian(jacobian, worksetCell, grads, startCell, endCell);