44 jacobianViewType _jacobian;
45 const worksetCellType _worksetCells;
46 const basisGradType _basisGrads;
50 KOKKOS_INLINE_FUNCTION
52 worksetCellType worksetCells_,
53 basisGradType basisGrads_,
56 : _jacobian(jacobian_), _worksetCells(worksetCells_), _basisGrads(basisGrads_),
57 _startCell(startCell_), _endCell(endCell_) {}
59 KOKKOS_INLINE_FUNCTION
60 void operator()(
const ordinal_type cell,
61 const ordinal_type point)
const {
63 const ordinal_type dim = _jacobian.extent(2);
65 const ordinal_type gradRank = rank(_basisGrads);
68 const ordinal_type cardinality = _basisGrads.extent(0);
69 for (ordinal_type i=0;i<dim;++i)
70 for (ordinal_type j=0;j<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<dim;++i)
80 for (ordinal_type j=0;j<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);
169 const int CELL_DIM = 0;
170 const int POINT_DIM = 1;
171 const int D1_DIM = 2;
172 const bool cellVaries = (variationTypes[CELL_DIM] !=
CONSTANT);
173 const bool pointVaries = (variationTypes[POINT_DIM] !=
CONSTANT);
175 auto det2 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d) -> PointScalar
177 return a * d - b * c;
180 auto det3 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
181 const PointScalar &d,
const PointScalar &e,
const PointScalar &f,
182 const PointScalar &g,
const PointScalar &h,
const PointScalar &i) -> PointScalar
184 return a * det2(e,f,h,i) - b * det2(d,f,g,i) + c * det2(d,e,g,h);
187 auto det4 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d,
188 const PointScalar &e,
const PointScalar &f,
const PointScalar &g,
const PointScalar &h,
189 const PointScalar &i,
const PointScalar &j,
const PointScalar &k,
const PointScalar &l,
190 const PointScalar &m,
const PointScalar &n,
const PointScalar &o,
const PointScalar &p) -> PointScalar
192 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);
197 if (cellVaries && pointVaries)
202 Kokkos::parallel_for(
203 Kokkos::MDRangePolicy<ExecSpaceType,Kokkos::Rank<2>>({0,0},{data.extent_int(0),data.extent_int(1)}),
204 KOKKOS_LAMBDA (
int cellOrdinal,
int pointOrdinal) {
206 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
207 const int spaceDim = blockWidth + numDiagonals;
209 PointScalar det = 1.0;
217 det = data(cellOrdinal,pointOrdinal,0);
222 const auto & a = data(cellOrdinal,pointOrdinal,0);
223 const auto & b = data(cellOrdinal,pointOrdinal,1);
224 const auto & c = data(cellOrdinal,pointOrdinal,2);
225 const auto & d = data(cellOrdinal,pointOrdinal,3);
232 const auto & a = data(cellOrdinal,pointOrdinal,0);
233 const auto & b = data(cellOrdinal,pointOrdinal,1);
234 const auto & c = data(cellOrdinal,pointOrdinal,2);
235 const auto & d = data(cellOrdinal,pointOrdinal,3);
236 const auto & e = data(cellOrdinal,pointOrdinal,4);
237 const auto & f = data(cellOrdinal,pointOrdinal,5);
238 const auto & g = data(cellOrdinal,pointOrdinal,6);
239 const auto & h = data(cellOrdinal,pointOrdinal,7);
240 const auto & i = data(cellOrdinal,pointOrdinal,8);
241 det = det3(a,b,c,d,e,f,g,h,i);
247 const auto & a = data(cellOrdinal,pointOrdinal,0);
248 const auto & b = data(cellOrdinal,pointOrdinal,1);
249 const auto & c = data(cellOrdinal,pointOrdinal,2);
250 const auto & d = data(cellOrdinal,pointOrdinal,3);
251 const auto & e = data(cellOrdinal,pointOrdinal,4);
252 const auto & f = data(cellOrdinal,pointOrdinal,5);
253 const auto & g = data(cellOrdinal,pointOrdinal,6);
254 const auto & h = data(cellOrdinal,pointOrdinal,7);
255 const auto & i = data(cellOrdinal,pointOrdinal,8);
256 const auto & j = data(cellOrdinal,pointOrdinal,9);
257 const auto & k = data(cellOrdinal,pointOrdinal,10);
258 const auto & l = data(cellOrdinal,pointOrdinal,11);
259 const auto & m = data(cellOrdinal,pointOrdinal,12);
260 const auto & n = data(cellOrdinal,pointOrdinal,13);
261 const auto & o = data(cellOrdinal,pointOrdinal,14);
262 const auto & p = data(cellOrdinal,pointOrdinal,15);
263 det = det4(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p);
271 const int offset = blockWidth * blockWidth;
273 for (
int d=blockWidth; d<spaceDim; d++)
275 const int index = d-blockWidth+offset;
276 det *= data(cellOrdinal,pointOrdinal,index);
278 detData(cellOrdinal,pointOrdinal) = det;
281 else if (cellVaries || pointVaries)
286 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,data.extent_int(0)),
287 KOKKOS_LAMBDA (
const int &cellPointOrdinal) {
289 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
290 const int spaceDim = blockWidth + numDiagonals;
292 PointScalar det = 1.0;
300 det = data(cellPointOrdinal,0);
305 const auto & a = data(cellPointOrdinal,0);
306 const auto & b = data(cellPointOrdinal,1);
307 const auto & c = data(cellPointOrdinal,2);
308 const auto & d = data(cellPointOrdinal,3);
315 const auto & a = data(cellPointOrdinal,0);
316 const auto & b = data(cellPointOrdinal,1);
317 const auto & c = data(cellPointOrdinal,2);
318 const auto & d = data(cellPointOrdinal,3);
319 const auto & e = data(cellPointOrdinal,4);
320 const auto & f = data(cellPointOrdinal,5);
321 const auto & g = data(cellPointOrdinal,6);
322 const auto & h = data(cellPointOrdinal,7);
323 const auto & i = data(cellPointOrdinal,8);
324 det = det3(a,b,c,d,e,f,g,h,i);
332 const int offset = blockWidth * blockWidth;
334 for (
int d=blockWidth; d<spaceDim; d++)
336 const int index = d-blockWidth+offset;
337 det *= data(cellPointOrdinal,index);
339 detData(cellPointOrdinal) = det;
346 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,1),
347 KOKKOS_LAMBDA (
const int &dummyArg) {
349 const int numDiagonals = jacobian.
extent_int(2) - blockWidth * blockWidth;
350 const int spaceDim = blockWidth + numDiagonals;
352 PointScalar det = 1.0;
365 const auto & a = data(0);
366 const auto & b = data(1);
367 const auto & c = data(2);
368 const auto & d = data(3);
375 const auto & a = data(0);
376 const auto & b = data(1);
377 const auto & c = data(2);
378 const auto & d = data(3);
379 const auto & e = data(4);
380 const auto & f = data(5);
381 const auto & g = data(6);
382 const auto & h = data(7);
383 const auto & i = data(8);
384 det = det3(a,b,c,d,e,f,g,h,i);
392 const int offset = blockWidth * blockWidth;
394 for (
int d=blockWidth; d<spaceDim; d++)
396 const int index = d-blockWidth+offset;
419 Kokkos::parallel_for(
"fill jacobian det", Kokkos::RangePolicy<ExecSpaceType>(0,1), KOKKOS_LAMBDA(
const int &i)
421 detData(0) = Intrepid2::Kernels::Serial::determinant(data);
426 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"jacobian's underlying view must have rank 2,3, or 4");
446 const int CELL_DIM = 0;
447 const int POINT_DIM = 1;
448 const int D1_DIM = 2;
450 auto det2 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
const PointScalar &d) -> PointScalar
452 return a * d - b * c;
455 auto det3 = KOKKOS_LAMBDA (
const PointScalar &a,
const PointScalar &b,
const PointScalar &c,
456 const PointScalar &d,
const PointScalar &e,
const PointScalar &f,
457 const PointScalar &g,
const PointScalar &h,
const PointScalar &i) -> PointScalar
459 return a * det2(e,f,h,i) - b * det2(d,f,g,i) + c * det2(d,e,g,h);
464 const bool cellVaries = variationTypes[CELL_DIM] !=
CONSTANT;
465 const bool pointVaries = variationTypes[POINT_DIM] !=
CONSTANT;
466 if (cellVaries && pointVaries)
471 Kokkos::parallel_for(
472 Kokkos::MDRangePolicy<ExecSpaceType,Kokkos::Rank<2>>({0,0},{data.extent_int(0),data.extent_int(1)}),
473 KOKKOS_LAMBDA (
int cellOrdinal,
int pointOrdinal) {
475 const int numDiagonals = data.extent_int(2) - blockWidth * blockWidth;
476 const int spaceDim = blockWidth + numDiagonals;
484 invData(cellOrdinal,pointOrdinal,0) = 1.0 / data(cellOrdinal,pointOrdinal,0);
489 const auto & a = data(cellOrdinal,pointOrdinal,0);
490 const auto & b = data(cellOrdinal,pointOrdinal,1);
491 const auto & c = data(cellOrdinal,pointOrdinal,2);
492 const auto & d = data(cellOrdinal,pointOrdinal,3);
493 const PointScalar det = det2(a,b,c,d);
495 invData(cellOrdinal,pointOrdinal,0) = d/det;
496 invData(cellOrdinal,pointOrdinal,1) = - b/det;
497 invData(cellOrdinal,pointOrdinal,2) = - c/det;
498 invData(cellOrdinal,pointOrdinal,3) = a/det;
503 const auto & a = data(cellOrdinal,pointOrdinal,0);
504 const auto & b = data(cellOrdinal,pointOrdinal,1);
505 const auto & c = data(cellOrdinal,pointOrdinal,2);
506 const auto & d = data(cellOrdinal,pointOrdinal,3);
507 const auto & e = data(cellOrdinal,pointOrdinal,4);
508 const auto & f = data(cellOrdinal,pointOrdinal,5);
509 const auto & g = data(cellOrdinal,pointOrdinal,6);
510 const auto & h = data(cellOrdinal,pointOrdinal,7);
511 const auto & i = data(cellOrdinal,pointOrdinal,8);
512 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
515 const auto val0 = e*i - h*f;
516 const auto val1 = - d*i + g*f;
517 const auto val2 = d*h - g*e;
519 invData(cellOrdinal,pointOrdinal,0) = val0/det;
520 invData(cellOrdinal,pointOrdinal,1) = val1/det;
521 invData(cellOrdinal,pointOrdinal,2) = val2/det;
524 const auto val0 = h*c - b*i;
525 const auto val1 = a*i - g*c;
526 const auto val2 = - a*h + g*b;
528 invData(cellOrdinal,pointOrdinal,3) = val0/det;
529 invData(cellOrdinal,pointOrdinal,4) = val1/det;
530 invData(cellOrdinal,pointOrdinal,5) = val2/det;
533 const auto val0 = b*f - e*c;
534 const auto val1 = - a*f + d*c;
535 const auto val2 = a*e - d*b;
537 invData(cellOrdinal,pointOrdinal,6) = val0/det;
538 invData(cellOrdinal,pointOrdinal,7) = val1/det;
539 invData(cellOrdinal,pointOrdinal,8) = val2/det;
547 const int offset = blockWidth * blockWidth;
549 for (
int d=blockWidth; d<spaceDim; d++)
551 const int index = d-blockWidth+offset;
552 invData(cellOrdinal,pointOrdinal,index) = 1.0 / data(cellOrdinal,pointOrdinal,index);
556 else if (cellVaries || pointVaries)
561 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,data.extent_int(0)),
562 KOKKOS_LAMBDA (
const int &cellPointOrdinal) {
564 const int numDiagonals = data.extent_int(1) - blockWidth * blockWidth;
565 const int spaceDim = blockWidth + numDiagonals;
573 invData(cellPointOrdinal,0) = 1.0 / data(cellPointOrdinal,0);
578 const auto & a = data(cellPointOrdinal,0);
579 const auto & b = data(cellPointOrdinal,1);
580 const auto & c = data(cellPointOrdinal,2);
581 const auto & d = data(cellPointOrdinal,3);
582 const PointScalar det = det2(a,b,c,d);
584 invData(cellPointOrdinal,0) = d/det;
585 invData(cellPointOrdinal,1) = - b/det;
586 invData(cellPointOrdinal,2) = - c/det;
587 invData(cellPointOrdinal,3) = a/det;
592 const auto & a = data(cellPointOrdinal,0);
593 const auto & b = data(cellPointOrdinal,1);
594 const auto & c = data(cellPointOrdinal,2);
595 const auto & d = data(cellPointOrdinal,3);
596 const auto & e = data(cellPointOrdinal,4);
597 const auto & f = data(cellPointOrdinal,5);
598 const auto & g = data(cellPointOrdinal,6);
599 const auto & h = data(cellPointOrdinal,7);
600 const auto & i = data(cellPointOrdinal,8);
601 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
604 const auto val0 = e*i - h*f;
605 const auto val1 = - d*i + g*f;
606 const auto val2 = d*h - g*e;
608 invData(cellPointOrdinal,0) = val0/det;
609 invData(cellPointOrdinal,1) = val1/det;
610 invData(cellPointOrdinal,2) = val2/det;
613 const auto val0 = h*c - b*i;
614 const auto val1 = a*i - g*c;
615 const auto val2 = - a*h + g*b;
617 invData(cellPointOrdinal,3) = val0/det;
618 invData(cellPointOrdinal,4) = val1/det;
619 invData(cellPointOrdinal,5) = val2/det;
622 const auto val0 = b*f - e*c;
623 const auto val1 = - a*f + d*c;
624 const auto val2 = a*e - d*b;
626 invData(cellPointOrdinal,6) = val0/det;
627 invData(cellPointOrdinal,7) = val1/det;
628 invData(cellPointOrdinal,8) = val2/det;
636 const int offset = blockWidth * blockWidth;
638 for (
int d=blockWidth; d<spaceDim; d++)
640 const int index = d-blockWidth+offset;
641 invData(cellPointOrdinal,index) = 1.0 / data(cellPointOrdinal,index);
650 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,1),
651 KOKKOS_LAMBDA (
const int &dummyArg) {
653 const int numDiagonals = data.extent_int(0) - blockWidth * blockWidth;
654 const int spaceDim = blockWidth + numDiagonals;
662 invData(0) = 1.0 / data(0);
667 const auto & a = data(0);
668 const auto & b = data(1);
669 const auto & c = data(2);
670 const auto & d = data(3);
671 const PointScalar det = det2(a,b,c,d);
674 invData(1) = - b/det;
675 invData(2) = - c/det;
681 const auto & a = data(0);
682 const auto & b = data(1);
683 const auto & c = data(2);
684 const auto & d = data(3);
685 const auto & e = data(4);
686 const auto & f = data(5);
687 const auto & g = data(6);
688 const auto & h = data(7);
689 const auto & i = data(8);
690 const PointScalar det = det3(a,b,c,d,e,f,g,h,i);
693 const auto val0 = e*i - h*f;
694 const auto val1 = - d*i + g*f;
695 const auto val2 = d*h - g*e;
697 invData(0) = val0/det;
698 invData(1) = val1/det;
699 invData(2) = val2/det;
702 const auto val0 = h*c - b*i;
703 const auto val1 = a*i - g*c;
704 const auto val2 = - a*h + g*b;
706 invData(3) = val0/det;
707 invData(4) = val1/det;
708 invData(5) = val2/det;
711 const auto val0 = b*f - e*c;
712 const auto val1 = - a*f + d*c;
713 const auto val2 = a*e - d*b;
715 invData(6) = val0/det;
716 invData(7) = val1/det;
717 invData(8) = val2/det;
725 const int offset = blockWidth * blockWidth;
727 for (
int d=blockWidth; d<spaceDim; d++)
729 const int index = d-blockWidth+offset;
730 invData(index) = 1.0 / data(index);
754 Kokkos::parallel_for(
"fill jacobian inverse", Kokkos::RangePolicy<ExecSpaceType>(0,1), KOKKOS_LAMBDA(
const int &i)
756 Intrepid2::Kernels::Serial::inverse(invData,data);
761 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
"jacobian's underlying view must have rank 2,3, or 4");
800 const PointViewType points,
801 const WorksetType worksetCell,
802 const Teuchos::RCP<HGradBasisType> basis,
803 const int startCell,
const int endCell) {
804 constexpr bool are_accessible =
805 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
806 typename decltype(jacobian)::memory_space>::accessible &&
807 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
808 typename decltype(points)::memory_space>::accessible;
809 static_assert(are_accessible,
"CellTools<DeviceType>::setJacobian(..): input/output views' memory spaces are not compatible with DeviceType");
811#ifdef HAVE_INTREPID2_DEBUG
812 CellTools_setJacobianArgs(jacobian, points, worksetCell, basis->getBaseCellTopology(), startCell, endCell);
815 const auto cellTopo = basis->getBaseCellTopology();
816 const ordinal_type spaceDim = cellTopo.getDimension();
817 const ordinal_type numCells = jacobian.extent(0);
820 const ordinal_type pointRank = points.rank();
821 const ordinal_type numPoints = (pointRank == 2 ? points.extent(0) : points.extent(1));
822 const ordinal_type basisCardinality = basis->getCardinality();
828 auto vcprop = Kokkos::common_view_alloc_prop(points);
829 using GradViewType = Kokkos::DynRankView<
typename decltype(points)::value_type,DeviceType>;
836 grads = GradViewType(Kokkos::view_alloc(
"CellTools::setJacobian::grads", vcprop),basisCardinality, numPoints, spaceDim);
837 basis->getValues(grads,
844 grads = GradViewType(Kokkos::view_alloc(
"CellTools::setJacobian::grads", vcprop), numCells, basisCardinality, numPoints, spaceDim);
845 for (ordinal_type cell=0;cell<numCells;++cell)
846 basis->getValues(Kokkos::subview( grads, cell, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL() ),
847 Kokkos::subview( points, cell, Kokkos::ALL(), Kokkos::ALL() ),
853 setJacobian(jacobian, worksetCell, grads, startCell, endCell);