49 #ifndef __INTREPID2_REALSPACETOOLS_DEF_HPP__
50 #define __INTREPID2_REALSPACETOOLS_DEF_HPP__
62 template<
typename SpT>
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.");
131 template<
typename SpT>
132 template<
typename inMatValueType,
class ...inMatProperties>
133 KOKKOS_INLINE_FUNCTION
136 det(
const Kokkos::DynRankView<inMatValueType,inMatProperties...> inMat) {
138 typedef typename decltype(inMat)::non_const_value_type value_type;
139 #ifdef HAVE_INTREPID2_DEBUG
141 bool dbgInfo =
false;
142 INTREPID2_TEST_FOR_DEBUG_ABORT( inMat.rank() != 2, dbgInfo,
143 ">>> ERROR (RealSpaceTools::det): Rank of matrix argument must be 2!");
144 INTREPID2_TEST_FOR_DEBUG_ABORT( inMat.extent(0) != inMat.extent(1), dbgInfo,
145 ">>> ERROR (RealSpaceTools::det): Matrix is not square!");
146 INTREPID2_TEST_FOR_DEBUG_ABORT( inMat.extent(0) < 1 || inMat.extent(0) > 3, dbgInfo,
147 ">>> ERROR (RealSpaceTools::det): Spatial dimension must be 1, 2, or 3!");
148 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
149 if (dbgInfo)
return value_type(0);
153 const auto dim = inMat.extent(0);
155 value_type r_val = 0.0;
158 r_val = ( inMat(0,0) * inMat(1,1) * inMat(2,2) +
159 inMat(1,0) * inMat(2,1) * inMat(0,2) +
160 inMat(2,0) * inMat(0,1) * inMat(1,2) -
161 inMat(2,0) * inMat(1,1) * inMat(0,2) -
162 inMat(0,0) * inMat(2,1) * inMat(1,2) -
163 inMat(1,0) * inMat(0,1) * inMat(2,2) );
166 r_val = ( inMat(0,0) * inMat(1,1) -
167 inMat(0,1) * inMat(1,0) );
170 r_val = ( inMat(0,0) );
178 template<
typename SpT>
179 template<
typename inVec1ValueType,
class ...inVec1Properties,
180 typename inVec2ValueType,
class ...inVec2Properties>
181 KOKKOS_INLINE_FUNCTION
184 dot(
const Kokkos::DynRankView<inVec1ValueType,inVec1Properties...> inVec1,
185 const Kokkos::DynRankView<inVec2ValueType,inVec2Properties...> inVec2 ) {
187 #ifdef HAVE_INTREPID2_DEBUG
189 bool dbgInfo =
false;
190 INTREPID2_TEST_FOR_DEBUG_ABORT( inVec1.rank() != 1 || inVec2.rank() != 1, dbgInfo,
191 ">>> ERROR (RealSpaceTools::dot): Vector arguments must have rank 1!");
192 INTREPID2_TEST_FOR_DEBUG_ABORT( inVec1.extent(0) != inVec2.extent(0), dbgInfo,
193 ">>> ERROR (RealSpaceTools::dot): Dimensions of vector arguments must agree!");
194 #ifdef INTREPID2_TEST_FOR_EXCEPTION_OVERRIDE_TO_CONTINUE
195 if (dbgInfo)
return inVec1ValueType(0);
199 typedef inVec1ValueType value_type;
204 const ordinal_type iend = inVec1.extent(0);
205 for (ordinal_type i=0;i<iend;++i)
206 r_val += inVec1(i)*inVec2(i);
219 namespace FunctorRealSpaceTools {
224 template<
typename OutputViewType,
225 typename inputViewType>
227 OutputViewType _output;
228 inputViewType _input;
230 KOKKOS_INLINE_FUNCTION
232 inputViewType input_ )
233 : _output(output_), _input(input_) {}
235 KOKKOS_INLINE_FUNCTION
236 void operator()(
const ordinal_type i)
const {
237 const ordinal_type jend = _input.extent(1);
238 const ordinal_type kend = _input.extent(2);
239 const ordinal_type lend = _input.extent(3);
240 const ordinal_type mend = _input.extent(4);
242 for (ordinal_type j=0;j<jend;++j)
243 for (ordinal_type k=0;k<kend;++k)
244 for (ordinal_type l=0;l<lend;++l)
245 for (ordinal_type m=0;m<mend;++m)
246 _output.access(i,j,k,l,m) = get_scalar_value(_input.access(i,j,k,l,m));
251 template<
typename SpT>
252 template<
typename outputValueType,
class ...outputProperties,
253 typename inputValueType,
class ...inputProperties>
257 const Kokkos::DynRankView<inputValueType, inputProperties...> input ) {
258 typedef Kokkos::DynRankView<outputValueType,outputProperties...> OutputViewType;
259 typedef Kokkos::DynRankView<inputValueType,inputProperties...> inputViewType;
261 typedef typename ExecSpace<typename inputViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
263 const auto loopSize = input.extent(0);
264 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
265 Kokkos::parallel_for( policy, FunctorType(output, input) );
268 namespace FunctorRealSpaceTools {
272 template<
typename OutputViewType,
273 typename inputViewType>
275 OutputViewType _output;
276 inputViewType _input;
278 KOKKOS_INLINE_FUNCTION
279 F_clone( OutputViewType output_,
280 inputViewType input_ )
281 : _output(output_), _input(input_) {}
283 KOKKOS_INLINE_FUNCTION
284 void operator()(
const ordinal_type iter)
const {
285 ordinal_type k0(0), k1(0), k2(0);
286 const auto rankDiff = _output.rank() - _input.rank();
289 unrollIndex( k0, k1, k2,
306 auto out = (rankDiff == 3 ? Kokkos::subview(_output, k0, k1, k2, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()) :
307 rankDiff == 2 ? Kokkos::subview(_output, k0, k1, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()) :
308 rankDiff == 1 ? Kokkos::subview(_output, k0, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()) :
309 Kokkos::subview(_output, Kokkos::ALL(), Kokkos::ALL(), Kokkos::ALL()));
310 const ordinal_type iend = _input.extent(0);
311 const ordinal_type jend = _input.extent(1);
312 const ordinal_type kend = _input.extent(2);
313 for (ordinal_type i=0;i<iend;++i)
314 for (ordinal_type j=0;j<jend;++j)
315 for (ordinal_type k=0;k<kend;++k)
316 out.access(i,j,k) = _input.access(i,j,k);
321 template<
typename SpT>
322 template<
typename outputValueType,
class ...outputProperties,
323 typename inputValueType,
class ...inputProperties>
326 clone( Kokkos::DynRankView<outputValueType,outputProperties...> output,
327 const Kokkos::DynRankView<inputValueType,inputProperties...> input ) {
328 #ifdef HAVE_INTREPID2_DEBUG
331 INTREPID2_TEST_FOR_EXCEPTION( input.rank() > 3, std::invalid_argument,
332 ">>> ERROR (RealSpaceTools::clone): Input container has rank larger than 3.");
335 INTREPID2_TEST_FOR_EXCEPTION( input.rank() > output.rank(), std::invalid_argument,
336 ">>> ERROR (RealSpaceTools::clone): Input container rank should be smaller than ouput rank.");
338 const size_type rankDiff = output.rank() - input.rank();
341 INTREPID2_TEST_FOR_EXCEPTION( rankDiff > 3, std::invalid_argument,
342 ">>> ERROR (RealSpaceTools::clone): Difference between output container rank and input container rank is larger than 3.");
345 for (size_type i=0;i<input.rank();++i) {
346 INTREPID2_TEST_FOR_EXCEPTION( input.extent(i) != output.extent(rankDiff + i), std::invalid_argument,
347 ">>> ERROR (RealSpaceTools::clone): Dimensions of array arguments do not agree!");
351 typedef Kokkos::DynRankView<outputValueType,outputProperties...> OutputViewType;
352 typedef Kokkos::DynRankView<inputValueType,inputProperties...> inputViewType;
354 typedef typename ExecSpace<typename inputViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
356 size_type loopSize = 1;
357 const ordinal_type out_rank = output.rank();
358 const ordinal_type in_rank = input.rank();
359 const ordinal_type rankDiff = out_rank - in_rank;
360 for (ordinal_type i=0;i<rankDiff;++i)
361 loopSize *= output.extent(i);
363 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
364 Kokkos::parallel_for( policy, FunctorType(output, input) );
367 namespace FunctorRealSpaceTools {
371 template<
typename absArrayViewType,
372 typename inArrayViewType>
374 absArrayViewType _absArray;
375 inArrayViewType _inArray;
377 KOKKOS_INLINE_FUNCTION
378 F_absval( absArrayViewType absArray_,
379 inArrayViewType inArray_ )
380 : _absArray(absArray_), _inArray(inArray_) {}
382 KOKKOS_INLINE_FUNCTION
383 void operator()(
const ordinal_type i)
const {
384 const ordinal_type jend = _inArray.extent(1);
385 const ordinal_type kend = _inArray.extent(2);
386 const ordinal_type lend = _inArray.extent(3);
387 const ordinal_type mend = _inArray.extent(4);
389 typedef typename inArrayViewType::non_const_value_type value_type;
391 for (ordinal_type j=0;j<jend;++j)
392 for (ordinal_type k=0;k<kend;++k)
393 for (ordinal_type l=0;l<lend;++l)
394 for (ordinal_type m=0;m<mend;++m)
400 template<
typename SpT>
401 template<
typename absArrayValueType,
class ...absArrayProperties,
402 typename inArrayValueType,
class ...inArrayProperties>
405 absval( Kokkos::DynRankView<absArrayValueType,absArrayProperties...> absArray,
406 const Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArray ) {
407 #ifdef HAVE_INTREPID2_DEBUG
409 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() > 5, std::invalid_argument,
410 ">>> ERROR (RealSpaceTools::absval): Input array container has rank larger than 5.");
412 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() != absArray.rank(), std::invalid_argument,
413 ">>> ERROR (RealSpaceTools::absval): Array arguments must have identical ranks!");
414 for (size_type i=0;i<inArray.rank();++i) {
415 INTREPID2_TEST_FOR_EXCEPTION( inArray.extent(i) != absArray.extent(i), std::invalid_argument,
416 ">>> ERROR (RealSpaceTools::absval): Dimensions of array arguments do not agree!");
421 typedef Kokkos::DynRankView<absArrayValueType,absArrayProperties...> absArrayViewType;
422 typedef Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArrayViewType;
424 typedef typename ExecSpace<typename inArrayViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
426 const auto loopSize = inArray.extent(0);
427 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
428 Kokkos::parallel_for( policy, FunctorType(absArray, inArray) );
433 template<
typename SpT>
434 template<
typename inoutArrayValueType,
class ...inoutAbsArrayProperties>
437 absval( Kokkos::DynRankView<inoutArrayValueType,inoutAbsArrayProperties...> inoutAbsArray ) {
443 namespace FunctorRealSpaceTools {
447 template<
typename normArrayViewType,
448 typename inVecViewType>
450 normArrayViewType _normArray;
451 inVecViewType _inVecs;
452 const ENorm _normType;
454 KOKKOS_INLINE_FUNCTION
456 inVecViewType inVecs_,
457 const ENorm normType_ )
458 : _normArray(normArray_), _inVecs(inVecs_), _normType(normType_) {}
460 KOKKOS_INLINE_FUNCTION
461 void operator()(
const ordinal_type iter)
const {
464 _normArray.extent(0),
465 _normArray.extent(1),
468 auto vec = ( _inVecs.rank() == 2 ? Kokkos::subview(_inVecs, i, Kokkos::ALL()) :
469 Kokkos::subview(_inVecs, i, j, Kokkos::ALL()) );
476 template<
typename SpT>
477 template<
typename normArrayValueType,
class ...normArrayProperties,
478 typename inVecValueType,
class ...inVecProperties>
481 vectorNorm( Kokkos::DynRankView<normArrayValueType,normArrayProperties...> normArray,
482 const Kokkos::DynRankView<inVecValueType, inVecProperties...> inVecs,
483 const ENorm normType ) {
484 #ifdef HAVE_INTREPID2_DEBUG
486 INTREPID2_TEST_FOR_EXCEPTION( inVecs.rank() != (normArray.rank()+1), std::invalid_argument,
487 ">>> ERROR (RealSpaceTools::vectorNorm): Ranks of norm and vector array arguments are incompatible!");
488 INTREPID2_TEST_FOR_EXCEPTION( inVecs.rank() < 2 || inVecs.rank() > 3, std::invalid_argument,
489 ">>> ERROR (RealSpaceTools::vectorNorm): Rank of vector array must be 2 or 3!");
490 for (size_type i=0;i<inVecs.rank()-1;++i) {
491 INTREPID2_TEST_FOR_EXCEPTION( inVecs.extent(i) != normArray.extent(i), std::invalid_argument,
492 ">>> ERROR (RealSpaceTools::vectorNorm): Dimensions of norm and vector arguments do not agree!");
497 typedef Kokkos::DynRankView<normArrayValueType,normArrayProperties...> normArrayViewType;
498 typedef Kokkos::DynRankView<inVecValueType, inVecProperties...> inVecViewType;
500 typedef typename ExecSpace<typename inVecViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
503 const auto loopSize = normArray.extent(0)*normArray.extent(1);
504 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
505 Kokkos::parallel_for( policy, FunctorType(normArray, inVecs, normType) );
510 namespace FunctorRealSpaceTools {
514 template<
typename transposeMatViewType,
515 typename inMatViewType>
517 transposeMatViewType _transposeMats;
518 inMatViewType _inMats;
520 KOKKOS_INLINE_FUNCTION
522 inMatViewType inMats_)
523 : _transposeMats(transposeMats_), _inMats(inMats_) {}
525 KOKKOS_INLINE_FUNCTION
526 void operator()(
const size_type iter)
const {
528 const auto r = _transposeMats.rank();
529 ordinal_type _i = iter, _j = 0;
533 _transposeMats.extent(0),
534 _transposeMats.extent(1),
537 auto dst = ( r == 2 ? Kokkos::subview(_transposeMats, Kokkos::ALL(), Kokkos::ALL()) :
538 r == 3 ? Kokkos::subview(_transposeMats, _i, Kokkos::ALL(), Kokkos::ALL()) :
539 Kokkos::subview(_transposeMats, _i, _j, Kokkos::ALL(), Kokkos::ALL()) );
541 auto src = ( r == 2 ? Kokkos::subview(_inMats, Kokkos::ALL(), Kokkos::ALL()) :
542 r == 3 ? Kokkos::subview(_inMats, _i, Kokkos::ALL(), Kokkos::ALL()) :
543 Kokkos::subview(_inMats, _i, _j, Kokkos::ALL(), Kokkos::ALL()) );
545 for (size_type i=0;i<src.extent(0);++i) {
546 dst(i, i) = src(i, i);
547 for (size_type j=i+1;j<src.extent(1);++j) {
548 dst(i, j) = src(j, i);
549 dst(j, i) = src(i, j);
556 template<
typename SpT>
557 template<
typename transposeMatValueType,
class ...transposeMatProperties,
558 typename inMatValueType,
class ...inMatProperties>
561 transpose( Kokkos::DynRankView<transposeMatValueType,transposeMatProperties...> transposeMats,
562 const Kokkos::DynRankView<inMatValueType, inMatProperties...> inMats ) {
564 #ifdef HAVE_INTREPID2_DEBUG
567 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != transposeMats.rank(), std::invalid_argument,
568 ">>> ERROR (RealSpaceTools::transpose): Matrix array arguments do not have identical ranks!");
569 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() < 2 || inMats.rank() > 4, std::invalid_argument,
570 ">>> ERROR (RealSpaceTools::transpose): Rank of matrix array must be 2, 3, or 4!");
571 for (size_type i=0;i<inMats.rank();++i) {
572 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != transposeMats.extent(i), std::invalid_argument,
573 ">>> ERROR (RealSpaceTools::transpose): Dimensions of matrix arguments do not agree!");
575 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-2) != inMats.extent(inMats.rank()-1), std::invalid_argument,
576 ">>> ERROR (RealSpaceTools::transpose): Matrices are not square!");
580 typedef Kokkos::DynRankView<transposeMatValueType,transposeMatProperties...> transposeMatViewType;
581 typedef Kokkos::DynRankView<inMatValueType, inMatProperties...> inMatViewType;
583 typedef typename ExecSpace<typename inMatViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
585 const auto r = transposeMats.rank();
586 const auto loopSize = ( r == 2 ? 1 :
587 r == 3 ? transposeMats.extent(0) :
588 transposeMats.extent(0)*transposeMats.extent(1) );
590 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
591 Kokkos::parallel_for( policy, FunctorType(transposeMats, inMats) );
596 namespace FunctorRealSpaceTools {
600 template<
typename inverseMatViewType,
601 typename inMatViewType>
603 typedef typename inMatViewType::non_const_value_type value_type;
604 inverseMatViewType _inverseMats;
605 inMatViewType _inMats;
607 KOKKOS_INLINE_FUNCTION
608 F_inverse( inverseMatViewType inverseMats_,
609 inMatViewType inMats_ )
610 : _inverseMats(inverseMats_), _inMats(inMats_) {}
612 template<
typename matViewType,
613 typename invViewType>
614 KOKKOS_FORCEINLINE_FUNCTION
616 apply_inverse( invViewType inv,
617 const matViewType mat ) {
621 #ifdef HAVE_INTREPID2_DEBUG
623 #ifdef HAVE_INTREPID2_DEBUG_INF_CHECK
624 bool dbgInfo =
false;
625 INTREPID2_TEST_FOR_DEBUG_ABORT( val == 0, dbgInfo,
626 ">>> ERROR (Matrix): Inverse of a singular matrix is undefined!");
627 #ifdef INTREPID2_TEST_FOR_DEBUG_ABORT_OVERRIDE_TO_CONTINUE
633 switch (mat.extent(0)) {
635 inv(0,0) = value_type(1)/mat(0,0);
639 inv(0,0) = mat(1,1)/val;
640 inv(1,1) = mat(0,0)/val;
642 inv(1,0) = - mat(1,0)/val;
643 inv(0,1) = - mat(0,1)/val;
647 value_type val0, val1, val2;
649 val0 = mat(1,1)*mat(2,2) - mat(2,1)*mat(1,2);
650 val1 = - mat(1,0)*mat(2,2) + mat(2,0)*mat(1,2);
651 val2 = mat(1,0)*mat(2,1) - mat(2,0)*mat(1,1);
657 val0 = mat(2,1)*mat(0,2) - mat(0,1)*mat(2,2);
658 val1 = mat(0,0)*mat(2,2) - mat(2,0)*mat(0,2);
659 val2 = - mat(0,0)*mat(2,1) + mat(2,0)*mat(0,1);
665 val0 = mat(0,1)*mat(1,2) - mat(1,1)*mat(0,2);
666 val1 = - mat(0,0)*mat(1,2) + mat(1,0)*mat(0,2);
667 val2 = mat(0,0)*mat(1,1) - mat(1,0)*mat(0,1);
677 KOKKOS_INLINE_FUNCTION
678 void operator()(
const ordinal_type cl,
679 const ordinal_type pt)
const {
680 const auto mat = Kokkos::subview(_inMats, cl, pt, Kokkos::ALL(), Kokkos::ALL());
681 auto inv = Kokkos::subview(_inverseMats, cl, pt, Kokkos::ALL(), Kokkos::ALL());
683 apply_inverse( inv, mat );
686 KOKKOS_INLINE_FUNCTION
687 void operator()(
const ordinal_type pt)
const {
688 const auto mat = Kokkos::subview(_inMats, pt, Kokkos::ALL(), Kokkos::ALL());
689 auto inv = Kokkos::subview(_inverseMats, pt, Kokkos::ALL(), Kokkos::ALL());
691 apply_inverse( inv, mat );
696 template<
typename SpT>
697 template<
typename inverseMatValueType,
class ...inverseMatProperties,
698 typename inMatValueType,
class ...inMatProperties>
701 inverse( Kokkos::DynRankView<inverseMatValueType,inverseMatProperties...> inverseMats,
702 const Kokkos::DynRankView<inMatValueType, inMatProperties...> inMats ) {
704 #ifdef HAVE_INTREPID2_DEBUG
706 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != inverseMats.rank(), std::invalid_argument,
707 ">>> ERROR (RealSpaceTools::inverse): Matrix array arguments do not have identical ranks!");
708 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() < 3 || inMats.rank() > 4, std::invalid_argument,
709 ">>> ERROR (RealSpaceTools::inverse): Rank of matrix array must be 3, or 4!");
710 for (size_type i=0;i<inMats.rank();++i) {
711 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != inverseMats.extent(i), std::invalid_argument,
712 ">>> ERROR (RealSpaceTools::inverse): Dimensions of matrix arguments do not agree!");
714 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-2) != inMats.extent(inMats.rank()-1), std::invalid_argument,
715 ">>> ERROR (RealSpaceTools::inverse): Matrices are not square!");
716 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-2) < 1 || inMats.extent(inMats.rank()-2) > 3, std::invalid_argument,
717 ">>> ERROR (RealSpaceTools::inverse): Spatial dimension must be 1, 2, or 3!");
721 typedef Kokkos::DynRankView<inverseMatValueType,inverseMatProperties...> inverseMatViewType;
722 typedef Kokkos::DynRankView<inMatValueType, inMatProperties...> inMatViewType;
724 typedef typename ExecSpace<typename inMatViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
726 switch (inMats.rank()) {
728 using range_policy_type = Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> >;
729 range_policy_type policy(0, inverseMats.extent(0));
730 Kokkos::parallel_for( policy, FunctorType(inverseMats, inMats) );
734 using range_policy_type = Kokkos::Experimental::MDRangePolicy
735 < ExecSpaceType, Kokkos::Experimental::Rank<2>, Kokkos::IndexType<ordinal_type> >;
736 range_policy_type policy( { 0, 0 },
737 { inverseMats.extent(0), inverseMats.extent(1) } );
738 Kokkos::parallel_for( policy, FunctorType(inverseMats, inMats) );
742 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
743 ">>> ERROR (RealSpaceTools::inverse): Rank of matrix array must be 2, 3, or 4!");
750 namespace FunctorRealSpaceTools {
754 template<
typename detArrayViewType,
755 typename inMatViewType>
757 detArrayViewType _detArray;
758 inMatViewType _inMats;
760 KOKKOS_INLINE_FUNCTION
761 F_det( detArrayViewType detArray_,
762 inMatViewType inMats_ )
763 : _detArray(detArray_), _inMats(inMats_) {}
765 KOKKOS_INLINE_FUNCTION
766 void operator()(
const ordinal_type pt)
const {
767 const auto mat = Kokkos::subview(_inMats, pt, Kokkos::ALL(), Kokkos::ALL());
771 KOKKOS_INLINE_FUNCTION
772 void operator()(
const ordinal_type cl,
773 const ordinal_type pt)
const {
774 const auto mat = Kokkos::subview(_inMats, cl, pt, Kokkos::ALL(), Kokkos::ALL());
780 template<
typename SpT>
781 template<
typename detArrayValueType,
class ...detArrayProperties,
782 typename inMatValueType,
class ...inMatProperties>
785 det( Kokkos::DynRankView<detArrayValueType,detArrayProperties...> detArray,
786 const Kokkos::DynRankView<inMatValueType, inMatProperties...> inMats ) {
788 #ifdef HAVE_INTREPID2_DEBUG
790 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != detArray.rank()+2, std::invalid_argument,
791 ">>> ERROR (RealSpaceTools::det): Determinant and matrix array arguments do not have compatible ranks!");
792 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() < 3 || inMats.rank() > 4, std::invalid_argument,
793 ">>> ERROR (RealSpaceTools::det): Rank of matrix array must be 3 or 4!");
794 for (size_type i=0;i<inMats.rank()-2;++i) {
795 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != detArray.extent(i), std::invalid_argument,
796 ">>> ERROR (RealSpaceTools::det): Dimensions of determinant and matrix array arguments do not agree!");
798 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-2) != inMats.extent(inMats.rank()-1), std::invalid_argument,
799 ">>> ERROR (RealSpaceTools::det): Matrices are not square!");
800 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-2) < 1 || inMats.extent(inMats.rank()-2) > 3, std::invalid_argument,
801 ">>> ERROR (RealSpaceTools::det): Spatial dimension must be 1, 2, or 3!");
805 typedef Kokkos::DynRankView<detArrayValueType,detArrayProperties...> detArrayViewType;
806 typedef Kokkos::DynRankView<inMatValueType, inMatProperties...> inMatViewType;
808 typedef typename ExecSpace<typename inMatViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
810 switch (detArray.rank()) {
812 using range_policy_type = Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> >;
813 range_policy_type policy(0, detArray.extent(0));
814 Kokkos::parallel_for( policy, FunctorType(detArray, inMats) );
818 using range_policy_type = Kokkos::Experimental::MDRangePolicy
819 < ExecSpaceType, Kokkos::Experimental::Rank<2>, Kokkos::IndexType<ordinal_type> >;
820 range_policy_type policy( { 0, 0 },
821 { detArray.extent(0), detArray.extent(1) } );
822 Kokkos::parallel_for( policy, FunctorType(detArray, inMats) );
826 INTREPID2_TEST_FOR_EXCEPTION(
true, std::invalid_argument,
827 ">>> ERROR (RealSpaceTools::det): Rank of detArray must be 1 or 2!");
834 namespace FunctorRealSpaceTools {
838 template<
typename sumArrayViewType,
839 typename inArray1Viewtype,
840 typename inArray2ViewType>
842 sumArrayViewType _sumArray;
843 inArray1Viewtype _inArray1;
844 inArray2ViewType _inArray2;
846 KOKKOS_INLINE_FUNCTION
847 F_add( sumArrayViewType sumArray_,
848 inArray1Viewtype inArray1_,
849 inArray2ViewType inArray2_ )
850 : _sumArray(sumArray_), _inArray1(inArray1_), _inArray2(inArray2_) {}
852 KOKKOS_INLINE_FUNCTION
853 void operator()(
const ordinal_type i)
const {
854 const ordinal_type jend = _sumArray.extent(1);
855 const ordinal_type kend = _sumArray.extent(2);
856 const ordinal_type lend = _sumArray.extent(3);
857 const ordinal_type mend = _sumArray.extent(4);
859 for (ordinal_type j=0;j<jend;++j)
860 for (ordinal_type k=0;k<kend;++k)
861 for (ordinal_type l=0;l<lend;++l)
862 for (ordinal_type m=0;m<mend;++m)
863 _sumArray.access(i,j,k,l,m) = _inArray1.access(i,j,k,l,m) + _inArray2.access(i,j,k,l,m);
868 template<
typename SpT>
869 template<
typename sumArrayValueType,
class ...sumArrayProperties,
870 typename inArray1ValueType,
class ...inArray1Properties,
871 typename inArray2ValueType,
class ...inArray2Properties>
874 add( Kokkos::DynRankView<sumArrayValueType,sumArrayProperties...> sumArray,
875 const Kokkos::DynRankView<inArray1ValueType,inArray1Properties...> inArray1,
876 const Kokkos::DynRankView<inArray2ValueType,inArray2Properties...> inArray2 ) {
878 #ifdef HAVE_INTREPID2_DEBUG
880 INTREPID2_TEST_FOR_EXCEPTION( inArray1.rank() != inArray2.rank() ||
881 inArray1.rank() != sumArray.rank(), std::invalid_argument,
882 ">>> ERROR (RealSpaceTools::add): Array arguments must have identical ranks!");
883 for (size_type i=0;i<inArray1.rank();++i) {
884 INTREPID2_TEST_FOR_EXCEPTION( inArray1.extent(i) != inArray2.extent(i) ||
885 inArray1.extent(i) != sumArray.extent(i), std::invalid_argument,
886 ">>> ERROR (RealSpaceTools::add): Dimensions of array arguments do not agree!");
891 typedef Kokkos::DynRankView<sumArrayValueType,sumArrayProperties...> sumArrayViewType;
892 typedef Kokkos::DynRankView<inArray1ValueType,inArray1Properties...> inArray1ViewType;
893 typedef Kokkos::DynRankView<inArray2ValueType,inArray2Properties...> inArray2ViewType;
895 typedef typename ExecSpace<typename inArray1ViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
897 const auto loopSize = sumArray.extent(0);
898 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
899 Kokkos::parallel_for( policy, FunctorType(sumArray, inArray1, inArray2) );
904 template<
typename SpT>
905 template<
typename inoutSumArrayValueType,
class ...inoutSumArrayProperties,
906 typename inArrayValueType,
class ...inArrayProperties>
909 add( Kokkos::DynRankView<inoutSumArrayValueType,inoutSumArrayProperties...> inoutSumArray,
910 const Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArray ) {
912 #ifdef HAVE_INTREPID2_DEBUG
914 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() != inoutSumArray.rank(), std::invalid_argument,
915 ">>> ERROR (RealSpaceTools::sum): Array arguments must have identical ranks!");
916 for (size_type i=0;i<inArray.rank();++i) {
917 INTREPID2_TEST_FOR_EXCEPTION( inArray.extent(i) != inoutSumArray.extent(i), std::invalid_argument,
918 ">>> ERROR (RealSpaceTools::sum): Dimensions of array arguments do not agree!");
927 namespace FunctorRealSpaceTools {
931 template<
typename diffArrayViewType,
932 typename inArray1ViewType,
933 typename inArray2ViewType>
935 diffArrayViewType _diffArray;
936 const inArray1ViewType _inArray1;
937 const inArray2ViewType _inArray2;
939 KOKKOS_INLINE_FUNCTION
941 inArray1ViewType inArray1_,
942 inArray2ViewType inArray2_ )
943 : _diffArray(diffArray_), _inArray1(inArray1_), _inArray2(inArray2_) {}
945 KOKKOS_INLINE_FUNCTION
946 void operator()(
const ordinal_type i)
const {
947 const ordinal_type jend = _diffArray.extent(1);
948 const ordinal_type kend = _diffArray.extent(2);
949 const ordinal_type lend = _diffArray.extent(3);
950 const ordinal_type mend = _diffArray.extent(4);
952 for (ordinal_type j=0;j<jend;++j)
953 for (ordinal_type k=0;k<kend;++k)
954 for (ordinal_type l=0;l<lend;++l)
955 for (ordinal_type m=0;m<mend;++m)
956 _diffArray.access(i,j,k,l,m) = _inArray1.access(i,j,k,l,m) - _inArray2.access(i,j,k,l,m);
961 template<
typename SpT>
962 template<
typename diffArrayValueType,
class ...diffArrayProperties,
963 typename inArray1ValueType,
class ...inArray1Properties,
964 typename inArray2ValueType,
class ...inArray2Properties>
967 subtract( Kokkos::DynRankView<diffArrayValueType,diffArrayProperties...> diffArray,
968 const Kokkos::DynRankView<inArray1ValueType, inArray1Properties...> inArray1,
969 const Kokkos::DynRankView<inArray2ValueType, inArray2Properties...> inArray2 ) {
971 #ifdef HAVE_INTREPID2_DEBUG
973 INTREPID2_TEST_FOR_EXCEPTION( inArray1.rank() != inArray2.rank() ||
974 inArray1.rank() != diffArray.rank(), std::invalid_argument,
975 ">>> ERROR (RealSpaceTools::subtract): Array arguments must have identical ranks!");
976 for (size_type i=0;i<inArray1.rank();++i) {
977 INTREPID2_TEST_FOR_EXCEPTION( inArray1.extent(i) != inArray2.extent(i) ||
978 inArray1.extent(i) != diffArray.extent(i), std::invalid_argument,
979 ">>> ERROR (RealSpaceTools::subtract): Dimensions of array arguments do not agree!");
984 typedef Kokkos::DynRankView<diffArrayValueType,diffArrayProperties...> diffArrayViewType;
985 typedef Kokkos::DynRankView<inArray1ValueType, inArray1Properties...> inArray1ViewType;
986 typedef Kokkos::DynRankView<inArray2ValueType, inArray2Properties...> inArray2ViewType;
988 typedef typename ExecSpace<typename inArray1ViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
990 const size_type loopSize = diffArray.extent(0);
991 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
992 Kokkos::parallel_for( policy, FunctorType(diffArray, inArray1, inArray2) );
997 template<
typename SpT>
998 template<
typename inoutDiffArrayValueType,
class ...inoutDiffArrayProperties,
999 typename inArrayValueType,
class ...inArrayProperties>
1002 subtract( Kokkos::DynRankView<inoutDiffArrayValueType,inoutDiffArrayProperties...> inoutDiffArray,
1003 const Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArray ) {
1004 #ifdef HAVE_INTREPID2_DEBUG
1006 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() != inoutDiffArray.rank(), std::invalid_argument,
1007 ">>> ERROR (RealSpaceTools::subtract): Array arguments must have identical ranks!");
1008 for (size_type i=0;i<inArray.rank();++i) {
1009 INTREPID2_TEST_FOR_EXCEPTION( inArray.extent(i) != inoutDiffArray.extent(i), std::invalid_argument,
1010 ">>> ERROR (RealSpaceTools::subtract): Dimensions of array arguments do not agree!");
1019 namespace FunctorRealSpaceTools {
1023 template<
typename ValueType,
1024 typename scaledArrayViewType,
1025 typename inArrayViewType>
1027 scaledArrayViewType _scaledArray;
1028 const inArrayViewType _inArray;
1029 const ValueType _alpha;
1031 KOKKOS_INLINE_FUNCTION
1032 F_scale( scaledArrayViewType scaledArray_,
1033 inArrayViewType inArray_,
1034 const ValueType alpha_ )
1035 : _scaledArray(scaledArray_), _inArray(inArray_), _alpha(alpha_) {}
1037 KOKKOS_INLINE_FUNCTION
1038 void operator()(
const ordinal_type i)
const {
1039 const ordinal_type jend = _inArray.extent(1);
1040 const ordinal_type kend = _inArray.extent(2);
1041 const ordinal_type lend = _inArray.extent(3);
1042 const ordinal_type mend = _inArray.extent(4);
1044 for (ordinal_type j=0;j<jend;++j)
1045 for (ordinal_type k=0;k<kend;++k)
1046 for (ordinal_type l=0;l<lend;++l)
1047 for (ordinal_type m=0;m<mend;++m)
1048 _scaledArray.access(i,j,k,l,m) = _alpha*_inArray.access(i,j,k,l,m);
1054 template<
typename SpT>
1055 template<
typename ValueType,
1056 typename scaledArrayValueType,
class ...scaledArrayProperties,
1057 typename inArrayValueType,
class ...inArrayProperties>
1060 scale( Kokkos::DynRankView<scaledArrayValueType,scaledArrayProperties...> scaledArray,
1061 const Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArray,
1062 const ValueType alpha ) {
1064 #ifdef HAVE_INTREPID2_DEBUG
1066 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() > 5, std::invalid_argument,
1067 ">>> ERROR (RealSpaceTools::scale): Input array container has rank larger than 5.");
1068 INTREPID2_TEST_FOR_EXCEPTION( inArray.rank() != scaledArray.rank(), std::invalid_argument,
1069 ">>> ERROR (RealSpaceTools::scale): Array arguments must have identical ranks!");
1070 for (size_type i=0;i<inArray.rank();++i) {
1071 INTREPID2_TEST_FOR_EXCEPTION( inArray.extent(i) != scaledArray.extent(i), std::invalid_argument,
1072 ">>> ERROR (RealSpaceTools::scale): Dimensions of array arguments do not agree!");
1077 typedef Kokkos::DynRankView<scaledArrayValueType,scaledArrayProperties...> scaledArrayViewtype;
1078 typedef Kokkos::DynRankView<inArrayValueType, inArrayProperties...> inArrayViewType;
1080 typedef typename ExecSpace<typename inArrayViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
1082 const auto loopSize = scaledArray.extent(0);
1083 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1084 Kokkos::parallel_for( policy, FunctorType(scaledArray, inArray, alpha) );
1089 template<
typename SpT>
1090 template<
typename ValueType,
1091 typename inoutScaledArrayValueType,
class ...inoutScaledArrayProperties>
1094 scale( Kokkos::DynRankView<inoutScaledArrayValueType,inoutScaledArrayProperties...> inoutScaledArray,
1095 const ValueType alpha ) {
1102 namespace FunctorRealSpaceTools {
1106 template<
typename dotArrayViewType,
1107 typename inVec1ViewType,
1108 typename inVec2ViewType>
1110 dotArrayViewType _dotArray;
1111 const inVec1ViewType _inVecs1;
1112 const inVec2ViewType _inVecs2;
1114 KOKKOS_INLINE_FUNCTION
1115 F_dot( dotArrayViewType dotArray_,
1116 inVec1ViewType inVecs1_,
1117 inVec2ViewType inVecs2_ )
1118 : _dotArray(dotArray_), _inVecs1(inVecs1_), _inVecs2(inVecs2_) {}
1120 KOKKOS_INLINE_FUNCTION
1121 void operator()(
const ordinal_type iter)
const {
1125 _dotArray.extent(0),
1126 _dotArray.extent(1),
1129 const auto r = _inVecs1.rank();
1130 auto vec1 = ( r == 2 ? Kokkos::subview(_inVecs1, i, Kokkos::ALL()) :
1131 Kokkos::subview(_inVecs1, i, j, Kokkos::ALL()) );
1132 auto vec2 = ( r == 2 ? Kokkos::subview(_inVecs2, i, Kokkos::ALL()) :
1133 Kokkos::subview(_inVecs2, i, j, Kokkos::ALL()) );
1140 template<
typename SpT>
1141 template<
typename dotArrayValueType,
class ...dotArrayProperties,
1142 typename inVec1ValueType,
class ...inVec1Properties,
1143 typename inVec2ValueType,
class ...inVec2Properties>
1146 dot( Kokkos::DynRankView<dotArrayValueType,dotArrayProperties...> dotArray,
1147 const Kokkos::DynRankView<inVec1ValueType, inVec1Properties...> inVecs1,
1148 const Kokkos::DynRankView<inVec2ValueType, inVec2Properties...> inVecs2 ) {
1150 #ifdef HAVE_INTREPID2_DEBUG
1152 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.rank() != (dotArray.rank()+1), std::invalid_argument,
1153 ">>> ERROR (RealSpaceTools::dot): Ranks of norm and vector array arguments are incompatible!");
1154 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.rank() != inVecs2.rank(), std::invalid_argument,
1155 ">>> ERROR (RealSpaceTools::dot): Ranks of input vector arguments must be identical!");
1156 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.rank() < 2 || inVecs1.rank() > 3, std::invalid_argument,
1157 ">>> ERROR (RealSpaceTools::dot): Rank of input vector arguments must be 2 or 3!");
1158 for (size_type i=0;i<inVecs1.rank();++i) {
1159 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.extent(i) != inVecs2.extent(i), std::invalid_argument,
1160 ">>> ERROR (RealSpaceTools::dot): Dimensions of input vector arguments do not agree!");
1162 for (size_type i=0;i<dotArray.rank();++i) {
1163 INTREPID2_TEST_FOR_EXCEPTION( inVecs1.extent(i) != dotArray.extent(i), std::invalid_argument,
1164 ">>> ERROR (RealSpaceTools::dot): Dimensions of dot-product and vector arrays do not agree!");
1169 typedef Kokkos::DynRankView<dotArrayValueType,dotArrayProperties...> dotArrayViewType;
1170 typedef Kokkos::DynRankView<inVec1ValueType, inVec1Properties...> inVec1ViewType;
1171 typedef Kokkos::DynRankView<inVec2ValueType, inVec2Properties...> inVec2ViewType;
1173 typedef typename ExecSpace<typename inVec1ViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
1175 const auto loopSize = dotArray.extent(0)*dotArray.extent(1);
1176 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1177 Kokkos::parallel_for( policy, FunctorType(dotArray, inVecs1, inVecs2) );
1182 namespace FunctorRealSpaceTools {
1186 template<
typename matVecViewType,
1187 typename inMatViewType,
1188 typename inVecViewType>
1190 matVecViewType _matVecs;
1191 const inMatViewType _inMats;
1192 const inVecViewType _inVecs;
1194 KOKKOS_INLINE_FUNCTION
1196 inMatViewType inMats_,
1197 inVecViewType inVecs_ )
1198 : _matVecs(matVecs_), _inMats(inMats_), _inVecs(inVecs_) {}
1200 KOKKOS_INLINE_FUNCTION
1201 void operator()(
const ordinal_type iter)
const {
1202 const ordinal_type rm = _inMats.rank(), rv = _inVecs.rank(), rr = _matVecs.rank();
1203 ordinal_type _i = iter, _j = 0;
1206 unrollIndex( _i, _j,
1211 auto mat = ( rm == 2 ? Kokkos::subview(_inMats, Kokkos::ALL(), Kokkos::ALL()) :
1212 rm == 3 ? Kokkos::subview(_inMats, _i, Kokkos::ALL(), Kokkos::ALL()) :
1213 Kokkos::subview(_inMats, _i, _j, Kokkos::ALL(), Kokkos::ALL()) );
1215 auto vec = ( rv == 1 ? Kokkos::subview(_inVecs, Kokkos::ALL()) :
1216 rv == 2 ? Kokkos::subview(_inVecs, _i, Kokkos::ALL()) :
1217 Kokkos::subview(_inVecs, _i, _j, Kokkos::ALL()) );
1219 auto result = ( rr == 1 ? Kokkos::subview(_matVecs, Kokkos::ALL()) :
1220 rr == 2 ? Kokkos::subview(_matVecs, _i, Kokkos::ALL()) :
1221 Kokkos::subview(_matVecs, _i, _j, Kokkos::ALL()) );
1223 const ordinal_type iend = result.extent(0);
1224 const ordinal_type jend = vec.extent(0);
1226 for (ordinal_type i=0;i<iend;++i) {
1228 for (ordinal_type j=0;j<jend;++j)
1229 result(i) += mat(i, j)*vec(j);
1235 template<
typename SpT>
1236 template<
typename matVecValueType,
class ...matVecProperties,
1237 typename inMatValueType,
class ...inMatProperties,
1238 typename inVecValueType,
class ...inVecProperties>
1241 matvec( Kokkos::DynRankView<matVecValueType,matVecProperties...> matVecs,
1242 const Kokkos::DynRankView<inMatValueType, inMatProperties...> inMats,
1243 const Kokkos::DynRankView<inVecValueType, inVecProperties...> inVecs ) {
1245 #ifdef HAVE_INTREPID2_DEBUG
1246 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() < 2 || inMats.rank() > 4, std::invalid_argument,
1247 ">>> ERROR (RealSpaceTools::matvec): Rank of matrix array must be 2, 3 or 4!");
1248 INTREPID2_TEST_FOR_EXCEPTION( matVecs.rank() < 1 || matVecs.rank() > 3, std::invalid_argument,
1249 ">>> ERROR (RealSpaceTools::matvec): Rank of matVecs array must be 1, 2 or 3!");
1250 INTREPID2_TEST_FOR_EXCEPTION( inVecs.rank() < 1 || inVecs.rank() > 3, std::invalid_argument,
1251 ">>> ERROR (RealSpaceTools::matvec): Rank of inVecs array must be 1, 2 or 3!");
1252 if (inMats.rank() == 2) {
1254 INTREPID2_TEST_FOR_EXCEPTION( matVecs.rank() != inVecs.rank(), std::invalid_argument,
1255 ">>> ERROR (RealSpaceTools::matvec): Vector arrays must be have the same rank!");
1257 for (ordinal_type i=0;i< (static_cast<ordinal_type>(inVecs.rank())-1);++i) {
1258 INTREPID2_TEST_FOR_EXCEPTION( matVecs.extent(i) != inVecs.extent(i), std::invalid_argument,
1259 ">>> ERROR (RealSpaceTools::matvec): Dimensions of vector array arguments do not agree!");
1262 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(0) != matVecs.extent(matVecs.rank()-1) ||
1263 inMats.extent(1) != inVecs.extent(inVecs.rank()-1), std::invalid_argument,
1264 ">>> ERROR (RealSpaceTools::matvec): Matvec dimensions are not compatible each other.");
1265 }
else if (inVecs.rank() == 1) {
1267 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != (matVecs.rank()+1), std::invalid_argument,
1268 ">>> ERROR (RealSpaceTools::matvec): The result vector and matrix array arguments do not have compatible ranks!");
1269 for (ordinal_type i=0;i<(static_cast<ordinal_type>(inMats.rank())-2);++i) {
1270 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != matVecs.extent(i), std::invalid_argument,
1271 ">>> ERROR (RealSpaceTools::matvec): Dimensions of vector and matrix array arguments do not agree!");
1274 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-2) != matVecs.extent(matVecs.rank()-1) ||
1275 inMats.extent(inMats.rank()-1) != inVecs.extent(0), std::invalid_argument,
1276 ">>> ERROR (RealSpaceTools::matvec): Matvec dimensions are not compatible each other.");
1279 INTREPID2_TEST_FOR_EXCEPTION( inMats.rank() != (matVecs.rank()+1), std::invalid_argument,
1280 ">>> ERROR (RealSpaceTools::matvec): The result vector and matrix array arguments do not have compatible ranks!");
1281 INTREPID2_TEST_FOR_EXCEPTION( matVecs.rank() != inVecs.rank(), std::invalid_argument,
1282 ">>> ERROR (RealSpaceTools::matvec): Vector arrays must be have the same rank!");
1283 for (ordinal_type i=0;i<(static_cast<ordinal_type>(inMats.rank())-2);++i) {
1284 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(i) != matVecs.extent(i), std::invalid_argument,
1285 ">>> ERROR (RealSpaceTools::matvec): Dimensions of vector and matrix array arguments do not agree!");
1287 for (size_type i=0;i<inVecs.rank();++i) {
1288 INTREPID2_TEST_FOR_EXCEPTION( matVecs.extent(i) != inVecs.extent(i), std::invalid_argument,
1289 ">>> ERROR (RealSpaceTools::matvec): Dimensions of vector array arguments do not agree!");
1291 INTREPID2_TEST_FOR_EXCEPTION( inMats.extent(inMats.rank()-1) != inVecs.extent(inVecs.rank()-1), std::invalid_argument,
1292 ">>> ERROR (RealSpaceTools::matvec): Matrix column dimension does not match to the length of a vector!");
1296 typedef Kokkos::DynRankView<matVecValueType,matVecProperties...> matVecViewType;
1297 typedef Kokkos::DynRankView<inMatValueType, inMatProperties...> inMatViewType;
1298 typedef Kokkos::DynRankView<inVecValueType, inVecProperties...> inVecViewType;
1300 typedef typename ExecSpace<typename inMatViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
1302 size_type loopSize = 1;
1303 const ordinal_type r = matVecs.rank() - 1;
1304 for (ordinal_type i=0;i<r;++i)
1305 loopSize *= matVecs.extent(i);
1307 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1308 Kokkos::parallel_for( policy, FunctorType(matVecs, inMats, inVecs) );
1313 namespace FunctorRealSpaceTools {
1317 template<
typename vecProdViewType,
1318 typename inLeftViewType,
1319 typename inRightViewType>
1321 vecProdViewType _vecProd;
1322 const inLeftViewType _inLeft;
1323 const inRightViewType _inRight;
1324 const bool _is_vecprod_3d;
1326 KOKKOS_INLINE_FUNCTION
1328 inLeftViewType inLeft_,
1329 inRightViewType inRight_,
1330 const bool is_vecprod_3d_ )
1331 : _vecProd(vecProd_), _inLeft(inLeft_), _inRight(inRight_), _is_vecprod_3d(is_vecprod_3d_) {}
1333 KOKKOS_INLINE_FUNCTION
1334 void operator()(
const size_type iter)
const {
1341 const auto r = _inLeft.rank();
1343 auto left = ( r == 1 ? Kokkos::subview(_inLeft, Kokkos::ALL()) :
1344 r == 2 ? Kokkos::subview(_inLeft, i, Kokkos::ALL()) :
1345 Kokkos::subview(_inLeft, i, j, Kokkos::ALL()) );
1347 auto right = ( r == 1 ? Kokkos::subview(_inRight, Kokkos::ALL()) :
1348 r == 2 ? Kokkos::subview(_inRight, i, Kokkos::ALL()) :
1349 Kokkos::subview(_inRight, i, j, Kokkos::ALL()) );
1351 auto result = ( r == 1 ? Kokkos::subview(_vecProd, Kokkos::ALL()) :
1352 r == 2 ? Kokkos::subview(_vecProd, i, Kokkos::ALL()) :
1353 Kokkos::subview(_vecProd, i, j, Kokkos::ALL()) );
1356 if (_is_vecprod_3d) {
1357 result(0) = left(1)*right(2) - left(2)*right(1);
1358 result(1) = left(2)*right(0) - left(0)*right(2);
1359 result(2) = left(0)*right(1) - left(1)*right(0);
1361 result(0) = left(0)*right(1) - left(1)*right(0);
1367 template<
typename SpT>
1368 template<
typename vecProdValueType,
class ...vecProdProperties,
1369 typename inLeftValueType,
class ...inLeftProperties,
1370 typename inRightValueType,
class ...inRightProperties>
1373 vecprod( Kokkos::DynRankView<vecProdValueType,vecProdProperties...> vecProd,
1374 const Kokkos::DynRankView<inLeftValueType, inLeftProperties...> inLeft,
1375 const Kokkos::DynRankView<inRightValueType,inRightProperties...> inRight ) {
1377 #ifdef HAVE_INTREPID2_DEBUG
1385 INTREPID2_TEST_FOR_EXCEPTION( inLeft.rank() < 1 || inLeft.rank() > 3, std::invalid_argument,
1386 ">>> ERROR (RealSpaceTools::vecprod): Rank of matrix array must be 1, 2, or 3!");
1387 INTREPID2_TEST_FOR_EXCEPTION( inLeft.rank() != inRight.rank(), std::invalid_argument,
1388 ">>> ERROR (RealSpaceTools::vecprod): Right and left arrays must be have the same rank!");
1389 INTREPID2_TEST_FOR_EXCEPTION( inLeft.rank() != vecProd.rank(), std::invalid_argument,
1390 ">>> ERROR (RealSpaceTools::vecprod): Left and vecProd arrays must be have the same rank!");
1391 for (size_type i=0;i<inLeft.rank();++i) {
1392 INTREPID2_TEST_FOR_EXCEPTION( inLeft.extent(i) != inRight.extent(i), std::invalid_argument,
1393 ">>> ERROR (RealSpaceTools::vecprod): Dimensions of matrix arguments do not agree!");
1394 INTREPID2_TEST_FOR_EXCEPTION( inLeft.extent(i) != vecProd.extent(i), std::invalid_argument,
1395 ">>> ERROR (RealSpaceTools::vecprod): Dimensions of matrix arguments do not agree!");
1400 INTREPID2_TEST_FOR_EXCEPTION( inLeft.extent(inLeft.rank()-1) < 2 ||
1401 inLeft.extent(inLeft.rank()-1) > 3, std::invalid_argument,
1402 ">>> ERROR (RealSpaceTools::vecprod): Dimensions of arrays (rank-1) must be 2 or 3!");
1405 typedef Kokkos::DynRankView<vecProdValueType, vecProdProperties...> vecProdViewType;
1406 typedef Kokkos::DynRankView<inLeftValueType, inLeftProperties...> inLeftViewType;
1407 typedef Kokkos::DynRankView<inRightValueType, inRightProperties...> inRightViewType;
1409 typedef typename ExecSpace<typename inLeftViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
1411 const auto r = inLeft.rank();
1412 const auto loopSize = ( r == 1 ? 1 :
1413 r == 2 ? inLeft.extent(0) :
1414 inLeft.extent(0)*inLeft.extent(1) );
1415 const bool is_vecprod_3d = (inLeft.extent(inLeft.rank() - 1) == 3);
1416 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
1417 Kokkos::parallel_for( policy, FunctorType(vecProd, inLeft, inRight, is_vecprod_3d) );