76 struct F_setJacobian {
77 jacobianViewType _jacobian;
78 const worksetCellType _worksetCells;
79 const basisGradType _basisGrads;
83 KOKKOS_INLINE_FUNCTION
84 F_setJacobian( jacobianViewType jacobian_,
85 worksetCellType worksetCells_,
86 basisGradType basisGrads_,
89 : _jacobian(jacobian_), _worksetCells(worksetCells_), _basisGrads(basisGrads_),
90 _startCell(startCell_), _endCell(endCell_) {}
92 KOKKOS_INLINE_FUNCTION
93 void operator()(
const ordinal_type cell,
94 const ordinal_type point)
const {
96 const ordinal_type dim = _jacobian.extent(2);
98 const ordinal_type gradRank = _basisGrads.rank();
101 const ordinal_type cardinality = _basisGrads.extent(0);
102 for (ordinal_type i=0;i<dim;++i)
103 for (ordinal_type j=0;j<dim;++j) {
104 _jacobian(cell, point, i, j) = 0;
105 for (ordinal_type bf=0;bf<cardinality;++bf)
106 _jacobian(cell, point, i, j) += _worksetCells(cell+_startCell, bf, i) * _basisGrads(bf, point, j);
111 const ordinal_type cardinality = _basisGrads.extent(1);
112 for (ordinal_type i=0;i<dim;++i)
113 for (ordinal_type j=0;j<dim;++j) {
114 _jacobian(cell, point, i, j) = 0;
115 for (ordinal_type bf=0;bf<cardinality;++bf)
116 _jacobian(cell, point, i, j) += _worksetCells(cell+_startCell, bf, i) * _basisGrads(cell, bf, point, j);
202 const int CELL_DIM = 0;
203 const int POINT_DIM = 1;
204 const int D1_DIM = 2;
205 const bool cellVaries = (variationTypes[CELL_DIM] !=
CONSTANT);
206 const bool pointVaries = (variationTypes[POINT_DIM] !=
CONSTANT);
208 auto det2 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d) -> PointScalar
210 return a * d - b * c;
213 auto det3 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
214 const PointScalar &d,
const PointScalar &e,
const PointScalar &f,
215 const PointScalar &g,
const PointScalar &h,
const PointScalar &i) -> PointScalar
217 return a * det2(e,f,h,i) - b * det2(d,f,g,i) + c * det2(d,e,g,h);
220 auto det4 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d,
221 const PointScalar &e,
const PointScalar &f,
const PointScalar &g,
const PointScalar &h,
222 const PointScalar &i,
const PointScalar &j,
const PointScalar &k,
const PointScalar &l,
223 const PointScalar &m,
const PointScalar &n,
const PointScalar &o,
const PointScalar &p) -> PointScalar
225 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);
230 if (cellVaries && pointVaries)
235 Kokkos::parallel_for(
236 Kokkos::MDRangePolicy<ExecSpaceType,Kokkos::Rank<2>>({0,0},{data.extent_int(0),data.extent_int(1)}),
237 KOKKOS_LAMBDA (
int cellOrdinal,
int pointOrdinal) {
239 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
240 const int spaceDim = blockWidth + numDiagonals;
242 PointScalar det = 1.0;
250 det = data(cellOrdinal,pointOrdinal,0);
255 const auto & a = data(cellOrdinal,pointOrdinal,0);
256 const auto & b = data(cellOrdinal,pointOrdinal,1);
257 const auto & c = data(cellOrdinal,pointOrdinal,2);
258 const auto & d = data(cellOrdinal,pointOrdinal,3);
265 const auto & a = data(cellOrdinal,pointOrdinal,0);
266 const auto & b = data(cellOrdinal,pointOrdinal,1);
267 const auto & c = data(cellOrdinal,pointOrdinal,2);
268 const auto & d = data(cellOrdinal,pointOrdinal,3);
269 const auto & e = data(cellOrdinal,pointOrdinal,4);
270 const auto & f = data(cellOrdinal,pointOrdinal,5);
271 const auto & g = data(cellOrdinal,pointOrdinal,6);
272 const auto & h = data(cellOrdinal,pointOrdinal,7);
273 const auto & i = data(cellOrdinal,pointOrdinal,8);
274 det = det3(a,b,c,d,e,f,g,h,i);
280 const auto & a = data(cellOrdinal,pointOrdinal,0);
281 const auto & b = data(cellOrdinal,pointOrdinal,1);
282 const auto & c = data(cellOrdinal,pointOrdinal,2);
283 const auto & d = data(cellOrdinal,pointOrdinal,3);
284 const auto & e = data(cellOrdinal,pointOrdinal,4);
285 const auto & f = data(cellOrdinal,pointOrdinal,5);
286 const auto & g = data(cellOrdinal,pointOrdinal,6);
287 const auto & h = data(cellOrdinal,pointOrdinal,7);
288 const auto & i = data(cellOrdinal,pointOrdinal,8);
289 const auto & j = data(cellOrdinal,pointOrdinal,9);
290 const auto & k = data(cellOrdinal,pointOrdinal,10);
291 const auto & l = data(cellOrdinal,pointOrdinal,11);
292 const auto & m = data(cellOrdinal,pointOrdinal,12);
293 const auto & n = data(cellOrdinal,pointOrdinal,13);
294 const auto & o = data(cellOrdinal,pointOrdinal,14);
295 const auto & p = data(cellOrdinal,pointOrdinal,15);
296 det = det4(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
304 const int offset = blockWidth * blockWidth;
306 for (
int d=blockWidth; d<spaceDim; d++)
308 const int index = d-blockWidth+offset;
309 det *= data(cellOrdinal,pointOrdinal,index);
311 detData(cellOrdinal,pointOrdinal) = det;
314 else if (cellVaries || pointVaries)
319 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,data.extent_int(0)),
320 KOKKOS_LAMBDA (
const int &cellPointOrdinal) {
322 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
323 const int spaceDim = blockWidth + numDiagonals;
325 PointScalar det = 1.0;
333 det = data(cellPointOrdinal,0);
338 const auto & a = data(cellPointOrdinal,0);
339 const auto & b = data(cellPointOrdinal,1);
340 const auto & c = data(cellPointOrdinal,2);
341 const auto & d = data(cellPointOrdinal,3);
348 const auto & a = data(cellPointOrdinal,0);
349 const auto & b = data(cellPointOrdinal,1);
350 const auto & c = data(cellPointOrdinal,2);
351 const auto & d = data(cellPointOrdinal,3);
352 const auto & e = data(cellPointOrdinal,4);
353 const auto & f = data(cellPointOrdinal,5);
354 const auto & g = data(cellPointOrdinal,6);
355 const auto & h = data(cellPointOrdinal,7);
356 const auto & i = data(cellPointOrdinal,8);
357 det = det3(a,b,c,d,e,f,g,h,i);
365 const int offset = blockWidth * blockWidth;
367 for (
int d=blockWidth; d<spaceDim; d++)
369 const int index = d-blockWidth+offset;
370 det *= data(cellPointOrdinal,index);
372 detData(cellPointOrdinal) = det;
379 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,1),
380 KOKKOS_LAMBDA (
const int &dummyArg) {
382 const int numDiagonals = jacobian.
extent_int(2) - blockWidth * blockWidth;
383 const int spaceDim = blockWidth + numDiagonals;
385 PointScalar det = 1.0;
398 const auto & a = data(0);
399 const auto & b = data(1);
400 const auto & c = data(2);
401 const auto & d = data(3);
408 const auto & a = data(0);
409 const auto & b = data(1);
410 const auto & c = data(2);
411 const auto & d = data(3);
412 const auto & e = data(4);
413 const auto & f = data(5);
414 const auto & g = data(6);
415 const auto & h = data(7);
416 const auto & i = data(8);
417 det = det3(a,b,c,d,e,f,g,h,i);
425 const int offset = blockWidth * blockWidth;
427 for (
int d=blockWidth; d<spaceDim; d++)
429 const int index = d-blockWidth+offset;
452 Kokkos::parallel_for(
"fill jacobian det", Kokkos::RangePolicy<ExecSpaceType>(0,1), KOKKOS_LAMBDA(
const int &i)
454 detData(0) = Intrepid2::Kernels::Serial::determinant(data);
459 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"jacobian's underlying view must have rank 2,3, or 4");
479 const int CELL_DIM = 0;
480 const int POINT_DIM = 1;
481 const int D1_DIM = 2;
483 auto det2 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d) -> PointScalar
485 return a * d - b * c;
488 auto det3 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
489 const PointScalar &d,
const PointScalar &e,
const PointScalar &f,
490 const PointScalar &g,
const PointScalar &h,
const PointScalar &i) -> PointScalar
492 return a * det2(e,f,h,i) - b * det2(d,f,g,i) + c * det2(d,e,g,h);
497 const bool cellVaries = variationTypes[CELL_DIM] !=
CONSTANT;
498 const bool pointVaries = variationTypes[POINT_DIM] !=
CONSTANT;
499 if (cellVaries && pointVaries)
504 Kokkos::parallel_for(
505 Kokkos::MDRangePolicy<ExecSpaceType,Kokkos::Rank<2>>({0,0},{data.extent_int(0),data.extent_int(1)}),
506 KOKKOS_LAMBDA (
int cellOrdinal,
int pointOrdinal) {
508 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
509 const int spaceDim = blockWidth + numDiagonals;
517 invData(cellOrdinal,pointOrdinal,0) = 1.0 / data(cellOrdinal,pointOrdinal,0);
522 const auto & a = data(cellOrdinal,pointOrdinal,0);
523 const auto & b = data(cellOrdinal,pointOrdinal,1);
524 const auto & c = data(cellOrdinal,pointOrdinal,2);
525 const auto & d = data(cellOrdinal,pointOrdinal,3);
526 const PointScalar det = det2(a,b,c,d);
528 invData(cellOrdinal,pointOrdinal,0) = d/det;
529 invData(cellOrdinal,pointOrdinal,1) = - b/det;
530 invData(cellOrdinal,pointOrdinal,2) = - c/det;
531 invData(cellOrdinal,pointOrdinal,3) = a/det;
536 const auto & a = data(cellOrdinal,pointOrdinal,0);
537 const auto & b = data(cellOrdinal,pointOrdinal,1);
538 const auto & c = data(cellOrdinal,pointOrdinal,2);
539 const auto & d = data(cellOrdinal,pointOrdinal,3);
540 const auto & e = data(cellOrdinal,pointOrdinal,4);
541 const auto & f = data(cellOrdinal,pointOrdinal,5);
542 const auto & g = data(cellOrdinal,pointOrdinal,6);
543 const auto & h = data(cellOrdinal,pointOrdinal,7);
544 const auto & i = data(cellOrdinal,pointOrdinal,8);
545 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
548 const auto val0 = e*i - h*f;
549 const auto val1 = - d*i + g*f;
550 const auto val2 = d*h - g*e;
552 invData(cellOrdinal,pointOrdinal,0) = val0/det;
553 invData(cellOrdinal,pointOrdinal,1) = val1/det;
554 invData(cellOrdinal,pointOrdinal,2) = val2/det;
557 const auto val0 = h*c - b*i;
558 const auto val1 = a*i - g*c;
559 const auto val2 = - a*h + g*b;
561 invData(cellOrdinal,pointOrdinal,3) = val0/det;
562 invData(cellOrdinal,pointOrdinal,4) = val1/det;
563 invData(cellOrdinal,pointOrdinal,5) = val2/det;
566 const auto val0 = b*f - e*c;
567 const auto val1 = - a*f + d*c;
568 const auto val2 = a*e - d*b;
570 invData(cellOrdinal,pointOrdinal,6) = val0/det;
571 invData(cellOrdinal,pointOrdinal,7) = val1/det;
572 invData(cellOrdinal,pointOrdinal,8) = val2/det;
580 const int offset = blockWidth * blockWidth;
582 for (
int d=blockWidth; d<spaceDim; d++)
584 const int index = d-blockWidth+offset;
585 invData(cellOrdinal,pointOrdinal,index) = 1.0 / data(cellOrdinal,pointOrdinal,index);
589 else if (cellVaries || pointVaries)
594 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,data.extent_int(0)),
595 KOKKOS_LAMBDA (
const int &cellPointOrdinal) {
597 const int numDiagonals = data.extent_int(1) - blockWidth * blockWidth;
598 const int spaceDim = blockWidth + numDiagonals;
606 invData(cellPointOrdinal,0) = 1.0 / data(cellPointOrdinal,0);
611 const auto & a = data(cellPointOrdinal,0);
612 const auto & b = data(cellPointOrdinal,1);
613 const auto & c = data(cellPointOrdinal,2);
614 const auto & d = data(cellPointOrdinal,3);
615 const PointScalar det = det2(a,b,c,d);
617 invData(cellPointOrdinal,0) = d/det;
618 invData(cellPointOrdinal,1) = - b/det;
619 invData(cellPointOrdinal,2) = - c/det;
620 invData(cellPointOrdinal,3) = a/det;
625 const auto & a = data(cellPointOrdinal,0);
626 const auto & b = data(cellPointOrdinal,1);
627 const auto & c = data(cellPointOrdinal,2);
628 const auto & d = data(cellPointOrdinal,3);
629 const auto & e = data(cellPointOrdinal,4);
630 const auto & f = data(cellPointOrdinal,5);
631 const auto & g = data(cellPointOrdinal,6);
632 const auto & h = data(cellPointOrdinal,7);
633 const auto & i = data(cellPointOrdinal,8);
634 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
637 const auto val0 = e*i - h*f;
638 const auto val1 = - d*i + g*f;
639 const auto val2 = d*h - g*e;
641 invData(cellPointOrdinal,0) = val0/det;
642 invData(cellPointOrdinal,1) = val1/det;
643 invData(cellPointOrdinal,2) = val2/det;
646 const auto val0 = h*c - b*i;
647 const auto val1 = a*i - g*c;
648 const auto val2 = - a*h + g*b;
650 invData(cellPointOrdinal,3) = val0/det;
651 invData(cellPointOrdinal,4) = val1/det;
652 invData(cellPointOrdinal,5) = val2/det;
655 const auto val0 = b*f - e*c;
656 const auto val1 = - a*f + d*c;
657 const auto val2 = a*e - d*b;
659 invData(cellPointOrdinal,6) = val0/det;
660 invData(cellPointOrdinal,7) = val1/det;
661 invData(cellPointOrdinal,8) = val2/det;
669 const int offset = blockWidth * blockWidth;
671 for (
int d=blockWidth; d<spaceDim; d++)
673 const int index = d-blockWidth+offset;
674 invData(cellPointOrdinal,index) = 1.0 / data(cellPointOrdinal,index);
683 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,1),
684 KOKKOS_LAMBDA (
const int &dummyArg) {
686 const int numDiagonals = data.extent_int(0) - blockWidth * blockWidth;
687 const int spaceDim = blockWidth + numDiagonals;
695 invData(0) = 1.0 / data(0);
700 const auto & a = data(0);
701 const auto & b = data(1);
702 const auto & c = data(2);
703 const auto & d = data(3);
704 const PointScalar det = det2(a,b,c,d);
707 invData(1) = - b/det;
708 invData(2) = - c/det;
714 const auto & a = data(0);
715 const auto & b = data(1);
716 const auto & c = data(2);
717 const auto & d = data(3);
718 const auto & e = data(4);
719 const auto & f = data(5);
720 const auto & g = data(6);
721 const auto & h = data(7);
722 const auto & i = data(8);
723 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
726 const auto val0 = e*i - h*f;
727 const auto val1 = - d*i + g*f;
728 const auto val2 = d*h - g*e;
730 invData(0) = val0/det;
731 invData(1) = val1/det;
732 invData(2) = val2/det;
735 const auto val0 = h*c - b*i;
736 const auto val1 = a*i - g*c;
737 const auto val2 = - a*h + g*b;
739 invData(3) = val0/det;
740 invData(4) = val1/det;
741 invData(5) = val2/det;
744 const auto val0 = b*f - e*c;
745 const auto val1 = - a*f + d*c;
746 const auto val2 = a*e - d*b;
748 invData(6) = val0/det;
749 invData(7) = val1/det;
750 invData(8) = val2/det;
758 const int offset = blockWidth * blockWidth;
760 for (
int d=blockWidth; d<spaceDim; d++)
762 const int index = d-blockWidth+offset;
763 invData(index) = 1.0 / data(index);
787 Kokkos::parallel_for(
"fill jacobian inverse", Kokkos::RangePolicy<ExecSpaceType>(0,1), KOKKOS_LAMBDA(
const int &i)
789 Intrepid2::Kernels::Serial::inverse(invData,data);
794 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"jacobian's underlying view must have rank 2,3, or 4");
833 setJacobian( Kokkos::DynRankView<jacobianValueType,jacobianProperties...> jacobian,
834 const Kokkos::DynRankView<pointValueType,pointProperties...> points,
835 const WorksetType worksetCell,
836 const Teuchos::RCP<HGradBasisType> basis,
837 const int startCell,
const int endCell) {
838 constexpr bool are_accessible =
839 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
840 typename decltype(jacobian)::memory_space>::accessible &&
841 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
842 typename decltype(points)::memory_space>::accessible;
843 static_assert(are_accessible,
"CellTools<DeviceType>::setJacobian(..): input/output views' memory spaces are not compatible with DeviceType");
845#ifdef HAVE_INTREPID2_DEBUG
849 const auto cellTopo = basis->getBaseCellTopology();
850 const ordinal_type spaceDim = cellTopo.getDimension();
851 const ordinal_type numCells = jacobian.extent(0);
854 const ordinal_type pointRank = points.rank();
855 const ordinal_type numPoints = (pointRank == 2 ? points.extent(0) : points.extent(1));
856 const ordinal_type basisCardinality = basis->getCardinality();
862 auto vcprop = Kokkos::common_view_alloc_prop(points);
863 using GradViewType = Kokkos::DynRankView<
typename decltype(vcprop)::value_type,DeviceType>;
870 grads = GradViewType(Kokkos::view_alloc(
"CellTools::setJacobian::grads", vcprop),basisCardinality, numPoints, spaceDim);
871 basis->getValues(grads,
878 grads = GradViewType(Kokkos::view_alloc(
"CellTools::setJacobian::grads", vcprop), numCells, basisCardinality, numPoints, spaceDim);
879 for (ordinal_type cell=0;cell<numCells;++cell)
880 basis->getValues(Kokkos::subview( grads, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() ),
881 Kokkos::subview( points, cell, Kokkos::ALL(), Kokkos::ALL() ),
887 setJacobian(jacobian, worksetCell, grads, startCell, endCell);