49 #ifndef __INTREPID2_REALSPACETOOLS_DEF_HPP__
50 #define __INTREPID2_REALSPACETOOLS_DEF_HPP__
62 template<
typename DeviceType>
63 template<
typename inVecValueType,
class ...inVecProperties>
64 KOKKOS_INLINE_FUNCTION
67 vectorNorm(
const Kokkos::DynRankView<inVecValueType,inVecProperties...> inVec,
68 const ENorm normType ) {
69 #ifdef HAVE_INTREPID2_DEBUG
72 INTREPID2_TEST_FOR_DEBUG_ABORT( !(inVec.rank() >= 1 && inVec.rank() <= 5), dbgInfo,
73 ">>> ERROR (RealSpaceTools::vectorNorm): Vector argument must have rank 1!" );
74 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
75 if (dbgInfo)
return inVecValueType(0);
79 typedef inVecValueType value_type;
83 const ordinal_type iend = inVec.extent(0);
84 const ordinal_type jend = inVec.extent(1);
85 const ordinal_type kend = inVec.extent(2);
86 const ordinal_type lend = inVec.extent(3);
87 const ordinal_type mend = inVec.extent(4);
90 for (ordinal_type i=0;i<iend;++i)
91 for (ordinal_type j=0;j<jend;++j)
92 for (ordinal_type k=0;k<kend;++k)
93 for (ordinal_type l=0;l<lend;++l)
94 for (ordinal_type m=0;m<mend;++m)
95 norm += inVec.access(i,j,k,l,m)*inVec.access(i,j,k,l,m);
100 for (ordinal_type i=0;i<iend;++i)
101 for (ordinal_type j=0;j<jend;++j)
102 for (ordinal_type k=0;k<kend;++k)
103 for (ordinal_type l=0;l<lend;++l)
104 for (ordinal_type m=0;m<mend;++m) {
106 norm = (norm < current ? current : norm);
111 for (ordinal_type i=0;i<iend;++i)
112 for (ordinal_type j=0;j<jend;++j)
113 for (ordinal_type k=0;k<kend;++k)
114 for (ordinal_type l=0;l<lend;++l)
115 for (ordinal_type m=0;m<mend;++m)
120 INTREPID2_TEST_FOR_ABORT( ( (normType != NORM_TWO) &&
121 (normType != NORM_INF) &&
122 (normType != NORM_ONE) ),
123 ">>> ERROR (RealSpaceTools::vectorNorm): Invalid argument normType.");
132 template<
typename DeviceType>
133 template<
class MatrixViewType>
134 KOKKOS_INLINE_FUNCTION
135 typename MatrixViewType::value_type
137 det(
const MatrixViewType inMat ) {
139 typedef typename decltype(inMat)::non_const_value_type value_type;
140 #ifdef HAVE_INTREPID2_DEBUG
142 bool dbgInfo =
false;
143 INTREPID2_TEST_FOR_DEBUG_ABORT( getFunctorRank( inMat ) != 2, dbgInfo,
144 ">>> ERROR (RealSpaceTools::det): Rank of matrix argument must be 2!");
145 INTREPID2_TEST_FOR_DEBUG_ABORT( inMat.extent(0) != inMat.extent(1), dbgInfo,
146 ">>> ERROR (RealSpaceTools::det): Matrix is not square!");
147 INTREPID2_TEST_FOR_DEBUG_ABORT( inMat.extent(0) < 1 || inMat.extent(0) > 3, dbgInfo,
148 ">>> ERROR (RealSpaceTools::det): Spatial dimension must be 1, 2, or 3!");
149 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
150 if (dbgInfo)
return value_type(0);
154 const auto dim = inMat.extent(0);
156 value_type r_val = 0.0;
159 r_val = ( inMat(0,0) * inMat(1,1) * inMat(2,2) +
160 inMat(1,0) * inMat(2,1) * inMat(0,2) +
161 inMat(2,0) * inMat(0,1) * inMat(1,2) -
162 inMat(2,0) * inMat(1,1) * inMat(0,2) -
163 inMat(0,0) * inMat(2,1) * inMat(1,2) -
164 inMat(1,0) * inMat(0,1) * inMat(2,2) );
167 r_val = ( inMat(0,0) * inMat(1,1) -
168 inMat(0,1) * inMat(1,0) );
171 r_val = ( inMat(0,0) );
179 template<
typename DeviceType>
180 template<
typename inVec1ValueType,
class ...inVec1Properties,
181 typename inVec2ValueType,
class ...inVec2Properties>
182 KOKKOS_INLINE_FUNCTION
185 dot(
const Kokkos::DynRankView<inVec1ValueType,inVec1Properties...> inVec1,
186 const Kokkos::DynRankView<inVec2ValueType,inVec2Properties...> inVec2 ) {
188 #ifdef HAVE_INTREPID2_DEBUG
190 bool dbgInfo =
false;
191 INTREPID2_TEST_FOR_DEBUG_ABORT( inVec1.rank() != 1 || inVec2.rank() != 1, dbgInfo,
192 ">>> ERROR (RealSpaceTools::dot): Vector arguments must have rank 1!");
193 INTREPID2_TEST_FOR_DEBUG_ABORT( inVec1.extent(0) != inVec2.extent(0), dbgInfo,
194 ">>> ERROR (RealSpaceTools::dot): Dimensions of vector arguments must agree!");
195 #ifdef INTREPID2_TEST_FOR_EXCEPTION_OVERRIDE_TO_CONTINUE
196 if (dbgInfo)
return inVec1ValueType(0);
200 typedef inVec1ValueType value_type;
205 const ordinal_type iend = inVec1.extent(0);
206 for (ordinal_type i=0;i<iend;++i)
207 r_val += inVec1(i)*inVec2(i);
220 namespace FunctorRealSpaceTools {
225 template<
typename OutputViewType,
226 typename inputViewType>
228 OutputViewType _output;
229 inputViewType _input;
231 KOKKOS_INLINE_FUNCTION
233 inputViewType input_ )
234 : _output(output_), _input(input_) {}
236 KOKKOS_INLINE_FUNCTION
237 void operator()(
const ordinal_type i)
const {
238 const ordinal_type jend = _input.extent(1);
239 const ordinal_type kend = _input.extent(2);
240 const ordinal_type lend = _input.extent(3);
241 const ordinal_type mend = _input.extent(4);
243 for (ordinal_type j=0;j<jend;++j)
244 for (ordinal_type k=0;k<kend;++k)
245 for (ordinal_type l=0;l<lend;++l)
246 for (ordinal_type m=0;m<mend;++m)
247 _output.access(i,j,k,l,m) = get_scalar_value(_input.access(i,j,k,l,m));
252 template<
typename DeviceType>
253 template<
typename outputValueType,
class ...outputProperties,
254 typename inputValueType,
class ...inputProperties>
258 const Kokkos::DynRankView<inputValueType, inputProperties...> input ) {
260 using MemSpaceType =
typename DeviceType::memory_space;
261 constexpr
bool are_accessible =
262 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
263 typename decltype(output)::memory_space>::accessible &&
264 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
265 typename decltype(input)::memory_space>::accessible;
266 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::extractScalarValues(..): input/output views' memory spaces are not compatible with DeviceType");
270 const auto loopSize = input.extent(0);
271 using ExecSpaceType =
typename DeviceType::execution_space;
272 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
273 Kokkos::parallel_for( policy, FunctorType(output, input) );
276 namespace FunctorRealSpaceTools {
280 template<
typename OutputViewType,
281 typename inputViewType>
283 OutputViewType _output;
284 inputViewType _input;
286 KOKKOS_INLINE_FUNCTION
287 F_clone( OutputViewType output_,
288 inputViewType input_ )
289 : _output(output_), _input(input_) {}
291 KOKKOS_INLINE_FUNCTION
292 void operator()(
const ordinal_type iter)
const {
293 ordinal_type k0(0), k1(0), k2(0);
294 const auto rankDiff = _output.rank() - _input.rank();
297 unrollIndex( k0, k1, k2,
314 auto out = (rankDiff == 3 ? Kokkos::subview(_output, k0, k1, k2, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()) :
315 rankDiff == 2 ? Kokkos::subview(_output, k0, k1, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()) :
316 rankDiff == 1 ? Kokkos::subview(_output, k0, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()) :
317 Kokkos::subview(_output, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()));
318 const ordinal_type iend = _input.extent(0);
319 const ordinal_type jend = _input.extent(1);
320 const ordinal_type kend = _input.extent(2);
321 for (ordinal_type i=0;i<iend;++i)
322 for (ordinal_type j=0;j<jend;++j)
323 for (ordinal_type k=0;k<kend;++k)
324 out.access(i,j,k) = _input.access(i,j,k);
329 template<
typename DeviceType>
330 template<
typename outputValueType,
class ...outputProperties,
331 typename inputValueType,
class ...inputProperties>
334 clone( Kokkos::DynRankView<outputValueType,outputProperties...> output,
335 const Kokkos::DynRankView<inputValueType,inputProperties...> input ) {
336 #ifdef HAVE_INTREPID2_DEBUG
339 INTREPID2_TEST_FOR_EXCEPTION( input.rank() > 3, std::invalid_argument,
340 ">>> ERROR (RealSpaceTools::clone): Input container has rank larger than 3.");
343 INTREPID2_TEST_FOR_EXCEPTION( input.rank() > output.rank(), std::invalid_argument,
344 ">>> ERROR (RealSpaceTools::clone): Input container rank should be smaller than ouput rank.");
346 const size_type rankDiff = output.rank() - input.rank();
349 INTREPID2_TEST_FOR_EXCEPTION( rankDiff > 3, std::invalid_argument,
350 ">>> ERROR (RealSpaceTools::clone): Difference between output container rank and input container rank is larger than 3.");
353 for (size_type i=0;i<input.rank();++i) {
354 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(rankDiff + i), std::invalid_argument,
355 ">>> ERROR (RealSpaceTools::clone): Dimensions of array arguments do not agree!");
359 using MemSpaceType =
typename DeviceType::memory_space;
360 constexpr
bool are_accessible =
361 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
362 typename decltype(output)::memory_space>::accessible &&
363 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
364 typename decltype(input)::memory_space>::accessible;
365 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::clone(..): input/output views' memory spaces are not compatible with DeviceType");
369 size_type loopSize = 1;
370 const ordinal_type out_rank = output.rank();
371 const ordinal_type in_rank = input.rank();
372 const ordinal_type rankDiff = out_rank - in_rank;
373 for (ordinal_type i=0;i<rankDiff;++i)
374 loopSize *= output.extent(i);
376 using ExecSpaceType =
typename DeviceType::execution_space;
377 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
378 Kokkos::parallel_for( policy, FunctorType(output, input) );
381 namespace FunctorRealSpaceTools {
385 template<
typename absArrayViewType,
386 typename inArrayViewType>
388 absArrayViewType _absArray;
389 inArrayViewType _inArray;
391 KOKKOS_INLINE_FUNCTION
392 F_absval( absArrayViewType absArray_,
393 inArrayViewType inArray_ )
394 : _absArray(absArray_), _inArray(inArray_) {}
396 KOKKOS_INLINE_FUNCTION
397 void operator()(
const ordinal_type i)
const {
398 const ordinal_type jend = _inArray.extent(1);
399 const ordinal_type kend = _inArray.extent(2);
400 const ordinal_type lend = _inArray.extent(3);
401 const ordinal_type mend = _inArray.extent(4);
403 typedef typename inArrayViewType::non_const_value_type value_type;
405 for (ordinal_type j=0;j<jend;++j)
406 for (ordinal_type k=0;k<kend;++k)
407 for (ordinal_type l=0;l<lend;++l)
408 for (ordinal_type m=0;m<mend;++m)
414 template<
typename DeviceType>
415 template<
typename absArrayValueType,
class ...absArrayProperties,
416 typename inArrayValueType,
class ...inArrayProperties>
419 absval( Kokkos::DynRankView<absArrayValueType,absArrayProperties...> absArray,
420 const Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArray ) {
421 #ifdef HAVE_INTREPID2_DEBUG
423 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() > 5, std::invalid_argument,
424 ">>> ERROR (RealSpaceTools::absval): Input array container has rank larger than 5.");
426 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() != absArray.rank(), std::invalid_argument,
427 ">>> ERROR (RealSpaceTools::absval): Array arguments must have identical ranks!");
428 for (size_type i=0;i<inArray.rank();++i) {
429 INTREPID2_TEST_FOR_EXCEPTION( inArray.extent(i) != absArray.extent(i), std::invalid_argument,
430 ">>> ERROR (RealSpaceTools::absval): Dimensions of array arguments do not agree!");
434 using MemSpaceType =
typename DeviceType::memory_space;
435 constexpr
bool are_accessible =
436 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
437 typename decltype(absArray)::memory_space>::accessible &&
438 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
439 typename decltype(inArray)::memory_space>::accessible;
440 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::absval(..): input/output views' memory spaces are not compatible with DeviceType");
444 const auto loopSize = inArray.extent(0);
445 using ExecSpaceType =
typename DeviceType::execution_space;
446 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
447 Kokkos::parallel_for( policy, FunctorType(absArray, inArray) );
452 template<
typename DeviceType>
453 template<
typename inoutArrayValueType,
class ...inoutAbsArrayProperties>
456 absval( Kokkos::DynRankView<inoutArrayValueType,inoutAbsArrayProperties...> inoutAbsArray ) {
462 namespace FunctorRealSpaceTools {
466 template<
typename normArrayViewType,
467 typename inVecViewType>
469 normArrayViewType _normArray;
470 inVecViewType _inVecs;
471 const ENorm _normType;
473 KOKKOS_INLINE_FUNCTION
475 inVecViewType inVecs_,
476 const ENorm normType_ )
477 : _normArray(normArray_), _inVecs(inVecs_), _normType(normType_) {}
479 KOKKOS_INLINE_FUNCTION
480 void operator()(
const ordinal_type iter)
const {
483 _normArray.extent(0),
484 _normArray.extent(1),
487 auto vec = ( _inVecs.rank() == 2 ? Kokkos::subview(_inVecs, i, Kokkos::ALL()) :
488 Kokkos::subview(_inVecs, i, j, Kokkos::ALL()) );
495 template<
typename DeviceType>
496 template<
typename normArrayValueType,
class ...normArrayProperties,
497 typename inVecValueType,
class ...inVecProperties>
500 vectorNorm( Kokkos::DynRankView<normArrayValueType,normArrayProperties...> normArray,
501 const Kokkos::DynRankView<inVecValueType, inVecProperties...> inVecs,
502 const ENorm normType ) {
503 #ifdef HAVE_INTREPID2_DEBUG
505 INTREPID2_TEST_FOR_EXCEPTION( inVecs.rank() != (normArray.rank()+1), std::invalid_argument,
506 ">>> ERROR (RealSpaceTools::vectorNorm): Ranks of norm and vector array arguments are incompatible!");
507 INTREPID2_TEST_FOR_EXCEPTION( inVecs.rank() < 2 || inVecs.rank() > 3, std::invalid_argument,
508 ">>> ERROR (RealSpaceTools::vectorNorm): Rank of vector array must be 2 or 3!");
509 for (size_type i=0;i<inVecs.rank()-1;++i) {
510 INTREPID2_TEST_FOR_EXCEPTION( inVecs.extent(i) != normArray.extent(i), std::invalid_argument,
511 ">>> ERROR (RealSpaceTools::vectorNorm): Dimensions of norm and vector arguments do not agree!");
516 using MemSpaceType =
typename DeviceType::memory_space;
517 constexpr
bool are_accessible =
518 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
519 typename decltype(normArray)::memory_space>::accessible &&
520 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
521 typename decltype(inVecs)::memory_space>::accessible;
522 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::vectorNorm(..): input/output views' memory spaces are not compatible with DeviceType");
526 const auto loopSize = normArray.extent(0)*normArray.extent(1);
527 using ExecSpaceType =
typename DeviceType::execution_space;
528 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
529 Kokkos::parallel_for( policy, FunctorType(normArray, inVecs, normType) );
534 namespace FunctorRealSpaceTools {
538 template<
typename transposeMatViewType,
539 typename inMatViewType>
541 transposeMatViewType _transposeMats;
542 inMatViewType _inMats;
544 KOKKOS_INLINE_FUNCTION
546 inMatViewType inMats_)
547 : _transposeMats(transposeMats_), _inMats(inMats_) {}
549 KOKKOS_INLINE_FUNCTION
550 void operator()(
const size_type iter)
const {
552 const auto r = _transposeMats.rank();
553 ordinal_type _i = iter, _j = 0;
557 _transposeMats.extent(0),
558 _transposeMats.extent(1),
561 auto dst = ( r == 2 ? Kokkos::subview(_transposeMats, Kokkos::ALL(), Kokkos::ALL()) :
562 r == 3 ? Kokkos::subview(_transposeMats, _i, Kokkos::ALL(), Kokkos::ALL()) :
563 Kokkos::subview(_transposeMats, _i, _j, Kokkos::ALL(), Kokkos::ALL()) );
565 auto src = ( r == 2 ? Kokkos::subview(_inMats, Kokkos::ALL(), Kokkos::ALL()) :
566 r == 3 ? Kokkos::subview(_inMats, _i, Kokkos::ALL(), Kokkos::ALL()) :
567 Kokkos::subview(_inMats, _i, _j, Kokkos::ALL(), Kokkos::ALL()) );
569 for (size_type i=0;i<src.extent(0);++i) {
570 dst(i, i) = src(i, i);
571 for (size_type j=i+1;j<src.extent(1);++j) {
572 dst(i, j) = src(j, i);
573 dst(j, i) = src(i, j);
580 template<
typename DeviceType>
581 template<
typename transposeMatValueType,
class ...transposeMatProperties,
582 typename inMatValueType,
class ...inMatProperties>
585 transpose( Kokkos::DynRankView<transposeMatValueType,transposeMatProperties...> transposeMats,
586 const Kokkos::DynRankView<inMatValueType, inMatProperties...> inMats ) {
588 #ifdef HAVE_INTREPID2_DEBUG
591 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != transposeMats.rank(), std::invalid_argument,
592 ">>> ERROR (RealSpaceTools::transpose): Matrix array arguments do not have identical ranks!");
593 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() < 2 || inMats.rank() > 4, std::invalid_argument,
594 ">>> ERROR (RealSpaceTools::transpose): Rank of matrix array must be 2, 3, or 4!");
595 for (size_type i=0;i<inMats.rank();++i) {
596 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != transposeMats.extent(i), std::invalid_argument,
597 ">>> ERROR (RealSpaceTools::transpose): Dimensions of matrix arguments do not agree!");
599 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-2) != inMats.extent(inMats.rank()-1), std::invalid_argument,
600 ">>> ERROR (RealSpaceTools::transpose): Matrices are not square!");
604 using MemSpaceType =
typename DeviceType::memory_space;
605 constexpr
bool are_accessible =
606 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
607 typename decltype(transposeMats)::memory_space>::accessible &&
608 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
609 typename decltype(inMats)::memory_space>::accessible;
610 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::transpose(..): input/output views' memory spaces are not compatible with DeviceType");
613 const auto r = transposeMats.rank();
614 const auto loopSize = ( r == 2 ? 1 :
615 r == 3 ? transposeMats.extent(0) :
616 transposeMats.extent(0)*transposeMats.extent(1) );
618 using ExecSpaceType =
typename DeviceType::execution_space;
619 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
620 Kokkos::parallel_for( policy, FunctorType(transposeMats, inMats) );
625 namespace FunctorRealSpaceTools {
629 template<
typename inverseMatViewType,
630 typename inMatViewType>
632 typedef typename inMatViewType::non_const_value_type value_type;
633 inverseMatViewType _inverseMats;
634 inMatViewType _inMats;
636 KOKKOS_INLINE_FUNCTION
637 F_inverse( inverseMatViewType inverseMats_,
638 inMatViewType inMats_ )
639 : _inverseMats(inverseMats_), _inMats(inMats_) {}
641 template<
typename matViewType,
642 typename invViewType>
643 KOKKOS_FORCEINLINE_FUNCTION
645 apply_inverse( invViewType inv,
646 const matViewType mat ) {
650 #ifdef HAVE_INTREPID2_DEBUG
652 #ifdef HAVE_INTREPID2_DEBUG_INF_CHECK
653 bool dbgInfo =
false;
654 INTREPID2_TEST_FOR_DEBUG_ABORT( val == 0, dbgInfo,
655 ">>> ERROR (Matrix): Inverse of a singular matrix is undefined!");
656 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
662 switch (mat.extent(0)) {
664 inv(0,0) = value_type(1)/mat(0,0);
668 inv(0,0) = mat(1,1)/val;
669 inv(1,1) = mat(0,0)/val;
671 inv(1,0) = - mat(1,0)/val;
672 inv(0,1) = - mat(0,1)/val;
676 value_type val0, val1, val2;
678 val0 = mat(1,1)*mat(2,2) - mat(2,1)*mat(1,2);
679 val1 = - mat(1,0)*mat(2,2) + mat(2,0)*mat(1,2);
680 val2 = mat(1,0)*mat(2,1) - mat(2,0)*mat(1,1);
686 val0 = mat(2,1)*mat(0,2) - mat(0,1)*mat(2,2);
687 val1 = mat(0,0)*mat(2,2) - mat(2,0)*mat(0,2);
688 val2 = - mat(0,0)*mat(2,1) + mat(2,0)*mat(0,1);
694 val0 = mat(0,1)*mat(1,2) - mat(1,1)*mat(0,2);
695 val1 = - mat(0,0)*mat(1,2) + mat(1,0)*mat(0,2);
696 val2 = mat(0,0)*mat(1,1) - mat(1,0)*mat(0,1);
706 template<
bool B,
class T =
void >
707 using enable_if_t =
typename std::enable_if<B,T>::type;
710 KOKKOS_INLINE_FUNCTION
711 enable_if_t<M==0 && supports_rank_4<inMatViewType>::value >
712 operator()(
const ordinal_type cl,
713 const ordinal_type pt)
const {
714 const auto mat = Kokkos::subview(_inMats, cl, pt, Kokkos::ALL(), Kokkos::ALL());
715 auto inv = Kokkos::subview(_inverseMats, cl, pt, Kokkos::ALL(), Kokkos::ALL());
717 apply_inverse( inv, mat );
721 KOKKOS_INLINE_FUNCTION
722 enable_if_t<M==0 && !supports_rank_4<inMatViewType>::value >
723 operator()(
const ordinal_type cl,
const ordinal_type pt)
const {
728 KOKKOS_INLINE_FUNCTION
729 enable_if_t<M==0 && supports_rank_3<inMatViewType>::value >
730 operator()(
const ordinal_type pt)
const {
731 const auto mat = Kokkos::subview(_inMats, pt, Kokkos::ALL(), Kokkos::ALL());
732 auto inv = Kokkos::subview(_inverseMats, pt, Kokkos::ALL(), Kokkos::ALL());
734 apply_inverse( inv, mat );
738 KOKKOS_INLINE_FUNCTION
739 enable_if_t<M==0 && !supports_rank_3<inMatViewType>::value >
740 operator()(
const ordinal_type pt)
const {
746 template<
typename DeviceType>
747 template<
class InverseMatrixViewType,
class MatrixViewType>
750 inverse( InverseMatrixViewType inverseMats, MatrixViewType inMats ) {
751 const unsigned rank = getFunctorRank(inMats);
752 #ifdef HAVE_INTREPID2_DEBUG
754 INTREPID2_TEST_FOR_EXCEPTION( rank != getFunctorRank(inverseMats), std::invalid_argument,
755 ">>> ERROR (RealSpaceTools::inverse): Matrix array arguments do not have identical ranks!");
756 INTREPID2_TEST_FOR_EXCEPTION( rank < 3 || rank > 4, std::invalid_argument,
757 ">>> ERROR (RealSpaceTools::inverse): Rank of matrix array must be 3, or 4!");
758 for (size_type i=0;i<rank;++i) {
759 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != inverseMats.extent(i), std::invalid_argument,
760 ">>> ERROR (RealSpaceTools::inverse): Dimensions of matrix arguments do not agree!");
762 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(rank-2) != inMats.extent(rank-1), std::invalid_argument,
763 ">>> ERROR (RealSpaceTools::inverse): Matrices are not square!");
764 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(rank-2) < 1 || inMats.extent(rank-2) > 3, std::invalid_argument,
765 ">>> ERROR (RealSpaceTools::inverse): Spatial dimension must be 1, 2, or 3!");
769 using ExecSpaceType =
typename DeviceType::execution_space;
774 using range_policy_type = Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> >;
775 range_policy_type policy(0, inverseMats.extent(0));
776 Kokkos::parallel_for( policy, FunctorType(inverseMats, inMats) );
780 using range_policy_type = Kokkos::MDRangePolicy
781 < ExecSpaceType, Kokkos::Rank<2>, Kokkos::IndexType<ordinal_type> >;
782 range_policy_type policy( { 0, 0 },
783 { inverseMats.extent(0), inverseMats.extent(1) } );
784 Kokkos::parallel_for( policy, FunctorType(inverseMats, inMats) );
788 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
789 ">>> ERROR (RealSpaceTools::inverse): Rank of matrix array must be 2, 3, or 4!");
796 namespace FunctorRealSpaceTools {
800 template<
typename detArrayViewType,
801 typename inMatViewType,
int rank>
803 detArrayViewType _detArray;
804 inMatViewType _inMats;
806 KOKKOS_INLINE_FUNCTION
807 F_det( detArrayViewType detArray_,
808 inMatViewType inMats_ )
809 : _detArray(detArray_), _inMats(inMats_) {}
811 template<
bool B,
class T =
void >
812 using enable_if_t =
typename std::enable_if<B,T>::type;
815 KOKKOS_INLINE_FUNCTION
816 enable_if_t<M==1 && supports_rank_3<inMatViewType>::value >
817 operator()(
const ordinal_type pt)
const {
818 const auto mat = Kokkos::subview(_inMats, pt, Kokkos::ALL(), Kokkos::ALL());
823 KOKKOS_INLINE_FUNCTION
824 enable_if_t<M==1 && !supports_rank_3<inMatViewType>::value >
825 operator()(
const ordinal_type pt)
const {
830 KOKKOS_INLINE_FUNCTION
831 enable_if_t<M==2 && supports_rank_4<inMatViewType>::value >
832 operator()(
const ordinal_type cl,
833 const ordinal_type pt)
const {
834 const auto mat = Kokkos::subview(_inMats, cl, pt, Kokkos::ALL(), Kokkos::ALL());
839 KOKKOS_INLINE_FUNCTION
840 enable_if_t<M==2 && !supports_rank_4<inMatViewType>::value >
841 operator()(
const ordinal_type cl,
842 const ordinal_type pt)
const {
848 template<
class DeterminantArrayViewType,
class MatrixViewType>
850 det( DeterminantArrayViewType detArray,
const MatrixViewType inMats );
852 template<
typename DeviceType>
853 template<
class DeterminantArrayViewType,
class MatrixViewType>
856 det( DeterminantArrayViewType detArray,
const MatrixViewType inMats ) {
858 #ifdef HAVE_INTREPID2_DEBUG
860 const unsigned matrixRank = getFunctorRank(inMats);
861 const unsigned detRank = getFunctorRank(detArray);
862 INTREPID2_TEST_FOR_EXCEPTION( matrixRank != detRank+2, std::invalid_argument,
863 ">>> ERROR (RealSpaceTools::det): Determinant and matrix array arguments do not have compatible ranks!");
864 INTREPID2_TEST_FOR_EXCEPTION( matrixRank < 3 || matrixRank > 4, std::invalid_argument,
865 ">>> ERROR (RealSpaceTools::det): Rank of matrix array must be 3 or 4!");
866 for (size_type i=0;i<matrixRank-2;++i) {
867 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != detArray.extent(i), std::invalid_argument,
868 ">>> ERROR (RealSpaceTools::det): Dimensions of determinant and matrix array arguments do not agree!");
870 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(matrixRank-2) != inMats.extent(matrixRank-1), std::invalid_argument,
871 ">>> ERROR (RealSpaceTools::det): Matrices are not square!");
872 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(matrixRank-2) < 1 || inMats.extent(matrixRank-2) > 3, std::invalid_argument,
873 ">>> ERROR (RealSpaceTools::det): Spatial dimension must be 1, 2, or 3!");
877 typedef typename DeviceType::execution_space ExecSpaceType;
879 const int detArrayRank = getFunctorRank(detArray);
881 switch (detArrayRank) {
884 using range_policy_type = Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> >;
885 range_policy_type policy(0, detArray.extent(0));
886 Kokkos::parallel_for( policy, FunctorType(detArray, inMats) );
891 using range_policy_type = Kokkos::MDRangePolicy
892 < ExecSpaceType, Kokkos::Rank<2>, Kokkos::IndexType<ordinal_type> >;
893 range_policy_type policy( { 0, 0 },
894 { detArray.extent(0), detArray.extent(1) } );
895 Kokkos::parallel_for( policy, FunctorType(detArray, inMats) );
899 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
900 ">>> ERROR (RealSpaceTools::det): Rank of detArray must be 1 or 2!");
907 namespace FunctorRealSpaceTools {
911 template<
typename sumArrayViewType,
912 typename inArray1Viewtype,
913 typename inArray2ViewType>
915 sumArrayViewType _sumArray;
916 inArray1Viewtype _inArray1;
917 inArray2ViewType _inArray2;
919 KOKKOS_INLINE_FUNCTION
920 F_add( sumArrayViewType sumArray_,
921 inArray1Viewtype inArray1_,
922 inArray2ViewType inArray2_ )
923 : _sumArray(sumArray_), _inArray1(inArray1_), _inArray2(inArray2_) {}
925 KOKKOS_INLINE_FUNCTION
926 void operator()(
const ordinal_type i)
const {
927 const ordinal_type jend = _sumArray.extent(1);
928 const ordinal_type kend = _sumArray.extent(2);
929 const ordinal_type lend = _sumArray.extent(3);
930 const ordinal_type mend = _sumArray.extent(4);
932 for (ordinal_type j=0;j<jend;++j)
933 for (ordinal_type k=0;k<kend;++k)
934 for (ordinal_type l=0;l<lend;++l)
935 for (ordinal_type m=0;m<mend;++m)
936 _sumArray.access(i,j,k,l,m) = _inArray1.access(i,j,k,l,m) + _inArray2.access(i,j,k,l,m);
941 template<
typename DeviceType>
942 template<
typename sumArrayValueType,
class ...sumArrayProperties,
943 typename inArray1ValueType,
class ...inArray1Properties,
944 typename inArray2ValueType,
class ...inArray2Properties>
947 add( Kokkos::DynRankView<sumArrayValueType,sumArrayProperties...> sumArray,
948 const Kokkos::DynRankView<inArray1ValueType,inArray1Properties...> inArray1,
949 const Kokkos::DynRankView<inArray2ValueType,inArray2Properties...> inArray2 ) {
951 #ifdef HAVE_INTREPID2_DEBUG
953 INTREPID2_TEST_FOR_EXCEPTION( inArray1.rank() != inArray2.rank() ||
954 inArray1.rank() != sumArray.rank(), std::invalid_argument,
955 ">>> ERROR (RealSpaceTools::add): Array arguments must have identical ranks!");
956 for (size_type i=0;i<inArray1.rank();++i) {
957 INTREPID2_TEST_FOR_EXCEPTION( inArray1.extent(i) != inArray2.extent(i) ||
958 inArray1.extent(i) != sumArray.extent(i), std::invalid_argument,
959 ">>> ERROR (RealSpaceTools::add): Dimensions of array arguments do not agree!");
963 using MemSpaceType =
typename DeviceType::memory_space;
964 constexpr
bool are_accessible =
965 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
966 typename decltype(sumArray)::memory_space>::accessible &&
967 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
968 typename decltype(inArray1)::memory_space>::accessible &&
969 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
970 typename decltype(inArray2)::memory_space>::accessible;
971 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::add(..): input/output views' memory spaces are not compatible with DeviceType");
975 const auto loopSize = sumArray.extent(0);
976 using ExecSpaceType =
typename DeviceType::execution_space;
977 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
978 Kokkos::parallel_for( policy, FunctorType(sumArray, inArray1, inArray2) );
983 template<
typename DeviceType>
984 template<
typename inoutSumArrayValueType,
class ...inoutSumArrayProperties,
985 typename inArrayValueType,
class ...inArrayProperties>
988 add( Kokkos::DynRankView<inoutSumArrayValueType,inoutSumArrayProperties...> inoutSumArray,
989 const Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArray ) {
991 #ifdef HAVE_INTREPID2_DEBUG
993 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() != inoutSumArray.rank(), std::invalid_argument,
994 ">>> ERROR (RealSpaceTools::sum): Array arguments must have identical ranks!");
995 for (size_type i=0;i<inArray.rank();++i) {
996 INTREPID2_TEST_FOR_EXCEPTION( inArray.extent(i) != inoutSumArray.extent(i), std::invalid_argument,
997 ">>> ERROR (RealSpaceTools::sum): Dimensions of array arguments do not agree!");
1006 namespace FunctorRealSpaceTools {
1010 template<
typename diffArrayViewType,
1011 typename inArray1ViewType,
1012 typename inArray2ViewType>
1014 diffArrayViewType _diffArray;
1015 const inArray1ViewType _inArray1;
1016 const inArray2ViewType _inArray2;
1018 KOKKOS_INLINE_FUNCTION
1020 inArray1ViewType inArray1_,
1021 inArray2ViewType inArray2_ )
1022 : _diffArray(diffArray_), _inArray1(inArray1_), _inArray2(inArray2_) {}
1024 KOKKOS_INLINE_FUNCTION
1025 void operator()(
const ordinal_type i)
const {
1026 const ordinal_type jend = _diffArray.extent(1);
1027 const ordinal_type kend = _diffArray.extent(2);
1028 const ordinal_type lend = _diffArray.extent(3);
1029 const ordinal_type mend = _diffArray.extent(4);
1031 for (ordinal_type j=0;j<jend;++j)
1032 for (ordinal_type k=0;k<kend;++k)
1033 for (ordinal_type l=0;l<lend;++l)
1034 for (ordinal_type m=0;m<mend;++m)
1035 _diffArray.access(i,j,k,l,m) = _inArray1.access(i,j,k,l,m) - _inArray2.access(i,j,k,l,m);
1040 template<
typename DeviceType>
1041 template<
typename diffArrayValueType,
class ...diffArrayProperties,
1042 typename inArray1ValueType,
class ...inArray1Properties,
1043 typename inArray2ValueType,
class ...inArray2Properties>
1046 subtract( Kokkos::DynRankView<diffArrayValueType,diffArrayProperties...> diffArray,
1047 const Kokkos::DynRankView<inArray1ValueType, inArray1Properties...> inArray1,
1048 const Kokkos::DynRankView<inArray2ValueType, inArray2Properties...> inArray2 ) {
1050 #ifdef HAVE_INTREPID2_DEBUG
1052 INTREPID2_TEST_FOR_EXCEPTION( inArray1.rank() != inArray2.rank() ||
1053 inArray1.rank() != diffArray.rank(), std::invalid_argument,
1054 ">>> ERROR (RealSpaceTools::subtract): Array arguments must have identical ranks!");
1055 for (size_type i=0;i<inArray1.rank();++i) {
1056 INTREPID2_TEST_FOR_EXCEPTION( inArray1.extent(i) != inArray2.extent(i) ||
1057 inArray1.extent(i) != diffArray.extent(i), std::invalid_argument,
1058 ">>> ERROR (RealSpaceTools::subtract): Dimensions of array arguments do not agree!");
1062 using MemSpaceType =
typename DeviceType::memory_space;
1063 constexpr
bool are_accessible =
1064 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1065 typename decltype(diffArray)::memory_space>::accessible &&
1066 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1067 typename decltype(inArray1)::memory_space>::accessible &&
1068 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1069 typename decltype(inArray2)::memory_space>::accessible;
1070 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::subtract(..): input/output views' memory spaces are not compatible with DeviceType");
1074 const size_type loopSize = diffArray.extent(0);
1075 using ExecSpaceType =
typename DeviceType::execution_space;
1076 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1077 Kokkos::parallel_for( policy, FunctorType(diffArray, inArray1, inArray2) );
1082 template<
typename DeviceType>
1083 template<
typename inoutDiffArrayValueType,
class ...inoutDiffArrayProperties,
1084 typename inArrayValueType,
class ...inArrayProperties>
1087 subtract( Kokkos::DynRankView<inoutDiffArrayValueType,inoutDiffArrayProperties...> inoutDiffArray,
1088 const Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArray ) {
1089 #ifdef HAVE_INTREPID2_DEBUG
1091 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() != inoutDiffArray.rank(), std::invalid_argument,
1092 ">>> ERROR (RealSpaceTools::subtract): Array arguments must have identical ranks!");
1093 for (size_type i=0;i<inArray.rank();++i) {
1094 INTREPID2_TEST_FOR_EXCEPTION( inArray.extent(i) != inoutDiffArray.extent(i), std::invalid_argument,
1095 ">>> ERROR (RealSpaceTools::subtract): Dimensions of array arguments do not agree!");
1104 namespace FunctorRealSpaceTools {
1108 template<
typename ValueType,
1109 typename scaledArrayViewType,
1110 typename inArrayViewType>
1112 scaledArrayViewType _scaledArray;
1113 const inArrayViewType _inArray;
1114 const ValueType _alpha;
1116 KOKKOS_INLINE_FUNCTION
1117 F_scale( scaledArrayViewType scaledArray_,
1118 inArrayViewType inArray_,
1119 const ValueType alpha_ )
1120 : _scaledArray(scaledArray_), _inArray(inArray_), _alpha(alpha_) {}
1122 KOKKOS_INLINE_FUNCTION
1123 void operator()(
const ordinal_type i)
const {
1124 const ordinal_type jend = _inArray.extent(1);
1125 const ordinal_type kend = _inArray.extent(2);
1126 const ordinal_type lend = _inArray.extent(3);
1127 const ordinal_type mend = _inArray.extent(4);
1129 for (ordinal_type j=0;j<jend;++j)
1130 for (ordinal_type k=0;k<kend;++k)
1131 for (ordinal_type l=0;l<lend;++l)
1132 for (ordinal_type m=0;m<mend;++m)
1133 _scaledArray.access(i,j,k,l,m) = _alpha*_inArray.access(i,j,k,l,m);
1139 template<
typename DeviceType>
1140 template<
typename ValueType,
1141 typename scaledArrayValueType,
class ...scaledArrayProperties,
1142 typename inArrayValueType,
class ...inArrayProperties>
1145 scale( Kokkos::DynRankView<scaledArrayValueType,scaledArrayProperties...> scaledArray,
1146 const Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArray,
1147 const ValueType alpha ) {
1149 #ifdef HAVE_INTREPID2_DEBUG
1151 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() > 5, std::invalid_argument,
1152 ">>> ERROR (RealSpaceTools::scale): Input array container has rank larger than 5.");
1153 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() != scaledArray.rank(), std::invalid_argument,
1154 ">>> ERROR (RealSpaceTools::scale): Array arguments must have identical ranks!");
1155 for (size_type i=0;i<inArray.rank();++i) {
1156 INTREPID2_TEST_FOR_EXCEPTION( inArray.extent(i) != scaledArray.extent(i), std::invalid_argument,
1157 ">>> ERROR (RealSpaceTools::scale): Dimensions of array arguments do not agree!");
1162 using MemSpaceType =
typename DeviceType::memory_space;
1163 constexpr
bool are_accessible =
1164 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1165 typename decltype(scaledArray)::memory_space>::accessible &&
1166 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1167 typename decltype(inArray)::memory_space>::accessible;
1168 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::scale(..): input/output views' memory spaces are not compatible with DeviceType");
1172 const auto loopSize = scaledArray.extent(0);
1173 using ExecSpaceType =
typename DeviceType::execution_space;
1174 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1175 Kokkos::parallel_for( policy, FunctorType(scaledArray, inArray, alpha) );
1180 template<
typename DeviceType>
1181 template<
typename ValueType,
1182 typename inoutScaledArrayValueType,
class ...inoutScaledArrayProperties>
1185 scale( Kokkos::DynRankView<inoutScaledArrayValueType,inoutScaledArrayProperties...> inoutScaledArray,
1186 const ValueType alpha ) {
1193 namespace FunctorRealSpaceTools {
1197 template<
typename dotArrayViewType,
1198 typename inVec1ViewType,
1199 typename inVec2ViewType>
1201 dotArrayViewType _dotArray;
1202 const inVec1ViewType _inVecs1;
1203 const inVec2ViewType _inVecs2;
1205 KOKKOS_INLINE_FUNCTION
1206 F_dot( dotArrayViewType dotArray_,
1207 inVec1ViewType inVecs1_,
1208 inVec2ViewType inVecs2_ )
1209 : _dotArray(dotArray_), _inVecs1(inVecs1_), _inVecs2(inVecs2_) {}
1211 KOKKOS_INLINE_FUNCTION
1212 void operator()(
const ordinal_type iter)
const {
1216 _dotArray.extent(0),
1217 _dotArray.extent(1),
1220 const auto r = _inVecs1.rank();
1221 auto vec1 = ( r == 2 ? Kokkos::subview(_inVecs1, i, Kokkos::ALL()) :
1222 Kokkos::subview(_inVecs1, i, j, Kokkos::ALL()) );
1223 auto vec2 = ( r == 2 ? Kokkos::subview(_inVecs2, i, Kokkos::ALL()) :
1224 Kokkos::subview(_inVecs2, i, j, Kokkos::ALL()) );
1231 template<
typename DeviceType>
1232 template<
typename dotArrayValueType,
class ...dotArrayProperties,
1233 typename inVec1ValueType,
class ...inVec1Properties,
1234 typename inVec2ValueType,
class ...inVec2Properties>
1237 dot( Kokkos::DynRankView<dotArrayValueType,dotArrayProperties...> dotArray,
1238 const Kokkos::DynRankView<inVec1ValueType, inVec1Properties...> inVecs1,
1239 const Kokkos::DynRankView<inVec2ValueType, inVec2Properties...> inVecs2 ) {
1241 #ifdef HAVE_INTREPID2_DEBUG
1243 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.rank() != (dotArray.rank()+1), std::invalid_argument,
1244 ">>> ERROR (RealSpaceTools::dot): Ranks of norm and vector array arguments are incompatible!");
1245 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.rank() != inVecs2.rank(), std::invalid_argument,
1246 ">>> ERROR (RealSpaceTools::dot): Ranks of input vector arguments must be identical!");
1247 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.rank() < 2 || inVecs1.rank() > 3, std::invalid_argument,
1248 ">>> ERROR (RealSpaceTools::dot): Rank of input vector arguments must be 2 or 3!");
1249 for (size_type i=0;i<inVecs1.rank();++i) {
1250 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.extent(i) != inVecs2.extent(i), std::invalid_argument,
1251 ">>> ERROR (RealSpaceTools::dot): Dimensions of input vector arguments do not agree!");
1253 for (size_type i=0;i<dotArray.rank();++i) {
1254 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.extent(i) != dotArray.extent(i), std::invalid_argument,
1255 ">>> ERROR (RealSpaceTools::dot): Dimensions of dot-product and vector arrays do not agree!");
1259 using MemSpaceType =
typename DeviceType::memory_space;
1260 constexpr
bool are_accessible =
1261 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1262 typename decltype(dotArray)::memory_space>::accessible &&
1263 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1264 typename decltype(inVecs1)::memory_space>::accessible &&
1265 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1266 typename decltype(inVecs2)::memory_space>::accessible;
1267 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::dot(..): input/output views' memory spaces are not compatible with DeviceType");
1271 const auto loopSize = dotArray.extent(0)*dotArray.extent(1);
1272 using ExecSpaceType =
typename DeviceType::execution_space;
1273 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1274 Kokkos::parallel_for( policy, FunctorType(dotArray, inVecs1, inVecs2) );
1279 namespace FunctorRealSpaceTools {
1283 template<
typename matVecViewType,
1284 typename inMatViewType,
1285 typename inVecViewType>
1287 matVecViewType _matVecs;
1288 const inMatViewType _inMats;
1289 const inVecViewType _inVecs;
1291 KOKKOS_INLINE_FUNCTION
1293 inMatViewType inMats_,
1294 inVecViewType inVecs_ )
1295 : _matVecs(matVecs_), _inMats(inMats_), _inVecs(inVecs_) {}
1297 KOKKOS_INLINE_FUNCTION
1298 void operator()(
const ordinal_type iter)
const {
1299 const ordinal_type rm = _inMats.rank(), rv = _inVecs.rank(), rr = _matVecs.rank();
1300 ordinal_type _i = iter, _j = 0;
1303 unrollIndex( _i, _j,
1308 auto mat = ( rm == 2 ? Kokkos::subview(_inMats, Kokkos::ALL(), Kokkos::ALL()) :
1309 rm == 3 ? Kokkos::subview(_inMats, _i, Kokkos::ALL(), Kokkos::ALL()) :
1310 Kokkos::subview(_inMats, _i, _j, Kokkos::ALL(), Kokkos::ALL()) );
1312 auto vec = ( rv == 1 ? Kokkos::subview(_inVecs, Kokkos::ALL()) :
1313 rv == 2 ? Kokkos::subview(_inVecs, _i, Kokkos::ALL()) :
1314 Kokkos::subview(_inVecs, _i, _j, Kokkos::ALL()) );
1316 auto result = ( rr == 1 ? Kokkos::subview(_matVecs, Kokkos::ALL()) :
1317 rr == 2 ? Kokkos::subview(_matVecs, _i, Kokkos::ALL()) :
1318 Kokkos::subview(_matVecs, _i, _j, Kokkos::ALL()) );
1320 const ordinal_type iend = result.extent(0);
1321 const ordinal_type jend = vec.extent(0);
1323 for (ordinal_type i=0;i<iend;++i) {
1325 for (ordinal_type j=0;j<jend;++j)
1326 result(i) += mat(i, j)*vec(j);
1335 template<
typename outMatViewType,
1336 typename inMatViewType>
1338 outMatViewType _outMats;
1339 const inMatViewType _inMats;
1341 KOKKOS_INLINE_FUNCTION
1342 F_AtA( outMatViewType outMats_,
1343 inMatViewType inMats_)
1344 : _outMats(outMats_), _inMats(inMats_) {}
1346 KOKKOS_INLINE_FUNCTION
1347 void operator()(
const ordinal_type iter)
const {
1348 const ordinal_type rIM = _inMats.rank(), rOM = _outMats.rank();
1349 ordinal_type _i = iter, _j = 0;
1352 unrollIndex( _i, _j,
1357 auto inMat = ( rIM == 2 ? Kokkos::subview(_inMats, Kokkos::ALL(), Kokkos::ALL()) :
1358 rIM == 3 ? Kokkos::subview(_inMats, _i, Kokkos::ALL(), Kokkos::ALL()) :
1359 Kokkos::subview(_inMats, _i, _j, Kokkos::ALL(), Kokkos::ALL()) );
1361 auto outMat = ( rOM == 2 ? Kokkos::subview(_outMats, Kokkos::ALL(), Kokkos::ALL()) :
1362 rOM == 3 ? Kokkos::subview(_outMats, _i, Kokkos::ALL(), Kokkos::ALL()) :
1363 Kokkos::subview(_outMats, _i, _j, Kokkos::ALL(), Kokkos::ALL()) );
1365 const ordinal_type iend = outMat.extent(0);
1366 const ordinal_type jend = outMat.extent(1);
1367 const ordinal_type kend = inMat.extent(0);
1369 for (ordinal_type i=0;i<iend;++i) {
1370 for (ordinal_type j=i;j<jend;++j) {
1372 for (ordinal_type k=0;k<kend;++k)
1373 outMat(i,j) += inMat(k, i)*inMat(k,j);
1375 for (ordinal_type j=0;j<i;++j)
1376 outMat(i,j) = outMat(j,i);
1383 template<
typename DeviceType>
1384 template<
typename matVecValueType,
class ...matVecProperties,
1385 typename inMatValueType,
class ...inMatProperties,
1386 typename inVecValueType,
class ...inVecProperties>
1389 matvec( Kokkos::DynRankView<matVecValueType,matVecProperties...> matVecs,
1390 const Kokkos::DynRankView<inMatValueType, inMatProperties...> inMats,
1391 const Kokkos::DynRankView<inVecValueType, inVecProperties...> inVecs ) {
1393 #ifdef HAVE_INTREPID2_DEBUG
1394 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() < 2 || inMats.rank() > 4, std::invalid_argument,
1395 ">>> ERROR (RealSpaceTools::matvec): Rank of matrix array must be 2, 3 or 4!");
1396 INTREPID2_TEST_FOR_EXCEPTION( matVecs.rank() < 1 || matVecs.rank() > 3, std::invalid_argument,
1397 ">>> ERROR (RealSpaceTools::matvec): Rank of matVecs array must be 1, 2 or 3!");
1398 INTREPID2_TEST_FOR_EXCEPTION( inVecs.rank() < 1 || inVecs.rank() > 3, std::invalid_argument,
1399 ">>> ERROR (RealSpaceTools::matvec): Rank of inVecs array must be 1, 2 or 3!");
1400 if (inMats.rank() == 2) {
1402 INTREPID2_TEST_FOR_EXCEPTION( matVecs.rank() != inVecs.rank(), std::invalid_argument,
1403 ">>> ERROR (RealSpaceTools::matvec): Vector arrays must be have the same rank!");
1405 for (ordinal_type i=0;i< (static_cast<ordinal_type>(inVecs.rank())-1);++i) {
1406 INTREPID2_TEST_FOR_EXCEPTION( matVecs.extent(i) != inVecs.extent(i), std::invalid_argument,
1407 ">>> ERROR (RealSpaceTools::matvec): Dimensions of vector array arguments do not agree!");
1410 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(0) != matVecs.extent(matVecs.rank()-1) ||
1411 inMats.extent(1) != inVecs.extent(inVecs.rank()-1), std::invalid_argument,
1412 ">>> ERROR (RealSpaceTools::matvec): Matvec dimensions are not compatible each other.");
1413 }
else if (inVecs.rank() < matVecs.rank()) {
1415 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != (matVecs.rank()+1), std::invalid_argument,
1416 ">>> ERROR (RealSpaceTools::matvec): The result vector and matrix array arguments do not have compatible ranks!");
1417 for (ordinal_type i=0;i<(static_cast<ordinal_type>(inMats.rank())-2);++i) {
1418 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != matVecs.extent(i), std::invalid_argument,
1419 ">>> ERROR (RealSpaceTools::matvec): Dimensions of vector and matrix array arguments do not agree!");
1422 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-2) != matVecs.extent(matVecs.rank()-1) ||
1423 inMats.extent(inMats.rank()-1) != inVecs.extent(inVecs.rank()-1), std::invalid_argument,
1424 ">>> ERROR (RealSpaceTools::matvec): Matvec dimensions are not compatible each other.");
1427 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != (matVecs.rank()+1), std::invalid_argument,
1428 ">>> ERROR (RealSpaceTools::matvec): The result vector and matrix array arguments do not have compatible ranks!");
1429 INTREPID2_TEST_FOR_EXCEPTION( matVecs.rank() != inVecs.rank(), std::invalid_argument,
1430 ">>> ERROR (RealSpaceTools::matvec): Vector arrays must be have the same rank!");
1431 for (ordinal_type i=0;i<(static_cast<ordinal_type>(inMats.rank())-2);++i) {
1432 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != matVecs.extent(i), std::invalid_argument,
1433 ">>> ERROR (RealSpaceTools::matvec): Dimensions of vector and matrix array arguments do not agree!");
1435 for (size_type i=0;i<inVecs.rank();++i) {
1436 INTREPID2_TEST_FOR_EXCEPTION( matVecs.extent(i) != inVecs.extent(i), std::invalid_argument,
1437 ">>> ERROR (RealSpaceTools::matvec): Dimensions of vector array arguments do not agree!");
1439 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-1) != inVecs.extent(inVecs.rank()-1), std::invalid_argument,
1440 ">>> ERROR (RealSpaceTools::matvec): Matrix column dimension does not match to the length of a vector!");
1443 using MemSpaceType =
typename DeviceType::memory_space;
1444 constexpr
bool are_accessible =
1445 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1446 typename decltype(matVecs)::memory_space>::accessible &&
1447 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1448 typename decltype(inMats)::memory_space>::accessible &&
1449 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1450 typename decltype(inVecs)::memory_space>::accessible;
1451 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::matvec(..): input/output views' memory spaces are not compatible with DeviceType");
1455 size_type loopSize = 1;
1456 const ordinal_type r = matVecs.rank() - 1;
1457 for (ordinal_type i=0;i<r;++i)
1458 loopSize *= matVecs.extent(i);
1460 using ExecSpaceType =
typename DeviceType::execution_space;
1461 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1462 Kokkos::parallel_for( policy, FunctorType(matVecs, inMats, inVecs) );
1466 template<
typename DeviceType>
1467 template<
typename outMatValueType,
class ...outMatProperties,
1468 typename inMatValueType,
class ...inMatProperties>
1471 AtA( Kokkos::DynRankView<outMatValueType,outMatProperties...> outMats,
1472 const Kokkos::DynRankView<inMatValueType, inMatProperties...> inMats) {
1474 #ifdef HAVE_INTREPID2_DEBUG
1475 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() < 2 || inMats.rank() > 4, std::invalid_argument,
1476 ">>> ERROR (RealSpaceTools::AtA): Rank of input matrix array must be 2, 3 or 4!");
1478 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != outMats.rank(), std::invalid_argument,
1479 ">>> ERROR (RealSpaceTools::AtA): The matrices do not have the same ranks!");
1480 for (ordinal_type i=0;i<(static_cast<ordinal_type>(inMats.rank())-2);++i) {
1481 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != outMats.extent(i), std::invalid_argument,
1482 ">>> ERROR (RealSpaceTools::AtA): Dimensions of matrices arrays do not agree!");
1485 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-1) != outMats.extent(outMats.rank()-1) ||
1486 outMats.extent(outMats.rank()-1) != outMats.extent(outMats.rank()-2), std::invalid_argument,
1487 ">>> ERROR (RealSpaceTools::AtA): Matrices dimensions are not compatible.");
1490 using MemSpaceType =
typename DeviceType::memory_space;
1491 constexpr
bool are_accessible =
1492 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1493 typename decltype(outMats)::memory_space>::accessible &&
1494 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1495 typename decltype(inMats)::memory_space>::accessible;
1496 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::AtA(..): input/output views' memory spaces are not compatible with DeviceType");
1500 size_type loopSize = 1;
1501 const ordinal_type r = outMats.rank() - 2;
1502 for (ordinal_type i=0;i<r;++i)
1503 loopSize *= outMats.extent(i);
1505 using ExecSpaceType =
typename DeviceType::execution_space;
1506 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1507 Kokkos::parallel_for( policy, FunctorType(outMats, inMats) );
1513 namespace FunctorRealSpaceTools {
1517 template<
typename vecProdViewType,
1518 typename inLeftViewType,
1519 typename inRightViewType>
1521 vecProdViewType _vecProd;
1522 const inLeftViewType _inLeft;
1523 const inRightViewType _inRight;
1524 const bool _is_vecprod_3d;
1526 KOKKOS_INLINE_FUNCTION
1528 inLeftViewType inLeft_,
1529 inRightViewType inRight_,
1530 const bool is_vecprod_3d_ )
1531 : _vecProd(vecProd_), _inLeft(inLeft_), _inRight(inRight_), _is_vecprod_3d(is_vecprod_3d_) {}
1533 KOKKOS_INLINE_FUNCTION
1534 void operator()(
const size_type iter)
const {
1541 const auto r = _inLeft.rank();
1543 auto left = ( r == 1 ? Kokkos::subview(_inLeft, Kokkos::ALL()) :
1544 r == 2 ? Kokkos::subview(_inLeft, i, Kokkos::ALL()) :
1545 Kokkos::subview(_inLeft, i, j, Kokkos::ALL()) );
1547 auto right = ( r == 1 ? Kokkos::subview(_inRight, Kokkos::ALL()) :
1548 r == 2 ? Kokkos::subview(_inRight, i, Kokkos::ALL()) :
1549 Kokkos::subview(_inRight, i, j, Kokkos::ALL()) );
1551 auto result = ( r == 1 ? Kokkos::subview(_vecProd, Kokkos::ALL()) :
1552 r == 2 ? Kokkos::subview(_vecProd, i, Kokkos::ALL()) :
1553 Kokkos::subview(_vecProd, i, j, Kokkos::ALL()) );
1556 if (_is_vecprod_3d) {
1557 result(0) = left(1)*right(2) - left(2)*right(1);
1558 result(1) = left(2)*right(0) - left(0)*right(2);
1559 result(2) = left(0)*right(1) - left(1)*right(0);
1561 result(0) = left(0)*right(1) - left(1)*right(0);
1567 template<
typename DeviceType>
1568 template<
typename vecProdValueType,
class ...vecProdProperties,
1569 typename inLeftValueType,
class ...inLeftProperties,
1570 typename inRightValueType,
class ...inRightProperties>
1573 vecprod( Kokkos::DynRankView<vecProdValueType,vecProdProperties...> vecProd,
1574 const Kokkos::DynRankView<inLeftValueType, inLeftProperties...> inLeft,
1575 const Kokkos::DynRankView<inRightValueType,inRightProperties...> inRight ) {
1577 #ifdef HAVE_INTREPID2_DEBUG
1585 INTREPID2_TEST_FOR_EXCEPTION( inLeft.rank() < 1 || inLeft.rank() > 3, std::invalid_argument,
1586 ">>> ERROR (RealSpaceTools::vecprod): Rank of matrix array must be 1, 2, or 3!");
1587 INTREPID2_TEST_FOR_EXCEPTION( inLeft.rank() != inRight.rank(), std::invalid_argument,
1588 ">>> ERROR (RealSpaceTools::vecprod): Right and left arrays must be have the same rank!");
1589 INTREPID2_TEST_FOR_EXCEPTION( inLeft.rank() != vecProd.rank(), std::invalid_argument,
1590 ">>> ERROR (RealSpaceTools::vecprod): Left and vecProd arrays must be have the same rank!");
1591 for (size_type i=0;i<inLeft.rank();++i) {
1592 INTREPID2_TEST_FOR_EXCEPTION( inLeft.extent(i) != inRight.extent(i), std::invalid_argument,
1593 ">>> ERROR (RealSpaceTools::vecprod): Dimensions of matrix arguments do not agree!");
1594 INTREPID2_TEST_FOR_EXCEPTION( inLeft.extent(i) != vecProd.extent(i), std::invalid_argument,
1595 ">>> ERROR (RealSpaceTools::vecprod): Dimensions of matrix arguments do not agree!");
1600 INTREPID2_TEST_FOR_EXCEPTION( inLeft.extent(inLeft.rank()-1) < 2 ||
1601 inLeft.extent(inLeft.rank()-1) > 3, std::invalid_argument,
1602 ">>> ERROR (RealSpaceTools::vecprod): Dimensions of arrays (rank-1) must be 2 or 3!");
1605 using MemSpaceType =
typename DeviceType::memory_space;
1606 constexpr
bool are_accessible =
1607 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1608 typename decltype(vecProd)::memory_space>::accessible &&
1609 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1610 typename decltype(inLeft)::memory_space>::accessible &&
1611 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1612 typename decltype(inRight)::memory_space>::accessible;
1613 static_assert(are_accessible,
"RealSpaceTools<DeviceType>::vecprod(..): input/output views' memory spaces are not compatible with DeviceType");
1617 const auto r = inLeft.rank();
1618 const auto loopSize = ( r == 1 ? 1 :
1619 r == 2 ? inLeft.extent(0) :
1620 inLeft.extent(0)*inLeft.extent(1) );
1621 const bool is_vecprod_3d = (inLeft.extent(inLeft.rank() - 1) == 3);
1622 using ExecSpaceType =
typename DeviceType::execution_space;
1623 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1624 Kokkos::parallel_for( policy, FunctorType(vecProd, inLeft, inRight, is_vecprod_3d) );