49 #ifndef __INTREPID2_FUNCTIONSPACETOOLS_DEF_HPP__ 50 #define __INTREPID2_FUNCTIONSPACETOOLS_DEF_HPP__ 55 #include "Teuchos_TimeMonitor.hpp" 59 template<
typename DeviceType>
60 template<
typename outputValueType,
class ...outputProperties,
61 typename inputValueType,
class ...inputProperties>
65 const Kokkos::DynRankView<inputValueType, inputProperties...> input ) {
66 if(output.rank() == input.rank()) {
67 #ifdef HAVE_INTREPID2_DEBUG 69 for (size_type i=0;i< input.rank();++i) {
70 INTREPID2_TEST_FOR_EXCEPTION( (input.extent(i) != output.extent(i)), std::invalid_argument,
71 ">>> ERROR (FunctionSpaceTools::HGRADtransformVALUE): Dimensions of input and output fields containers do not match.");
83 namespace FunctorFunctionSpaceTools {
87 template <
typename OutputViewType,
88 typename jacInverseViewType,
89 typename inputViewType,
90 ordinal_type spaceDim>
92 OutputViewType _output;
93 const jacInverseViewType _jacInverse;
94 const inputViewType _input;
97 KOKKOS_INLINE_FUNCTION
99 jacInverseViewType jacInverse_,
100 inputViewType input_)
102 _jacInverse(jacInverse_),
105 KOKKOS_INLINE_FUNCTION
106 void operator()(
const ordinal_type cl,
107 const ordinal_type bf,
108 const ordinal_type pt)
const {
109 auto y = Kokkos::subview(_output, cl, bf, pt, Kokkos::ALL());
110 const auto A = Kokkos::subview(_jacInverse, cl, pt, Kokkos::ALL(), Kokkos::ALL());
111 const auto x = Kokkos::subview(_input, bf, pt, Kokkos::ALL());
114 Kernels::Serial::matvec_trans_product_d2( y, A, x );
116 Kernels::Serial::matvec_trans_product_d3( y, A, x );
122 template<
typename DeviceType>
123 template<
typename outputValValueType,
class ...outputValProperties,
124 typename jacobianInverseValueType,
class ...jacobianInverseProperties,
125 typename inputValValueType,
class ...inputValProperties>
129 const Kokkos::DynRankView<jacobianInverseValueType,jacobianInverseProperties...> jacobianInverse,
130 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
131 return HCURLtransformVALUE(outputVals, jacobianInverse, inputVals);
172 template<
typename DeviceType>
173 template<
typename outputValValueType,
class ...outputValProperties,
174 typename jacobianInverseValueType,
class ...jacobianInverseProperties,
175 typename inputValValueType,
class ...inputValProperties>
179 const Kokkos::DynRankView<jacobianInverseValueType,jacobianInverseProperties...> jacobianInverse,
180 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
186 template<
typename DeviceType>
187 template<
typename outputValValueType,
class ...outputValProperties,
188 typename jacobianValueType,
class ...jacobianProperties,
189 typename jacobianDetValueType,
class ...jacobianDetProperties,
190 typename inputValValueType,
class ...inputValProperties>
194 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
195 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
196 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
197 if(jacobian.data()==NULL || jacobian.extent(2)==2)
198 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
200 return HDIVtransformVALUE(outputVals, jacobian, jacobianDet, inputVals);
205 template<
typename DeviceType>
206 template<
typename outputValValueType,
class ...outputValProperties,
207 typename jacobianDetValueType,
class ...jacobianDetProperties,
208 typename inputValValueType,
class ...inputValProperties>
212 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
213 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
214 #ifdef HAVE_INTREPID2_DEBUG 216 INTREPID2_TEST_FOR_EXCEPTION( outputVals.rank() == 4, std::invalid_argument,
217 ">>> ERROR (FunctionSpaceTools::HCURLtransformCURL): Output rank must have rank 3.\n If these are 3D fields, then use the appropriate overload of this function.");
220 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
225 template<
typename DeviceType>
226 template<
typename outputValValueType,
class ...outputValProperties,
227 typename jacobianValueType,
class ...jacobianProperties,
228 typename jacobianDetValueType,
class ...jacobianDetProperties,
229 typename inputValValueType,
class ...inputValProperties>
233 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
234 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
235 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
236 #ifdef HAVE_INTREPID2_DEBUG 238 INTREPID2_TEST_FOR_EXCEPTION( outputVals.extent(3)!=2, std::invalid_argument,
239 ">>> ERROR (FunctionSpaceTools::HGRADtransformCURL):\n output field is 3D by the function is meant for 2D fields");
242 return HDIVtransformVALUE(outputVals, jacobian, jacobianDet, inputVals);
247 template<
typename DeviceType>
248 template<
typename outputValValueType,
class ...outputValProperties,
249 typename jacobianValueType,
class ...jacobianProperties,
250 typename jacobianDetValueType,
class ...jacobianDetProperties,
251 typename inputValValueType,
class ...inputValProperties>
255 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
256 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
257 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
264 template<
typename DeviceType>
265 template<
typename outputValValueType,
class ...outputValProperties,
266 typename jacobianDetValueType,
class ...jacobianDetProperties,
267 typename inputValValueType,
class ...inputValProperties>
270 HDIVtransformDIV( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
271 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
272 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
273 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
278 template<
typename DeviceType>
279 template<
typename outputValValueType,
class ...outputValProperties,
280 typename jacobianDetValueType,
class ...jacobianDetProperties,
281 typename inputValValueType,
class ...inputValProperties>
285 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
286 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
292 template<
typename DeviceType>
293 template<
typename outputValueValueType,
class ...outputValueProperties,
294 typename leftValueValueType,
class ...leftValueProperties,
295 typename rightValueValueType,
class ...rightValueProperties>
298 integrate( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
299 const Kokkos::DynRankView<leftValueValueType, leftValueProperties...> leftValues,
300 const Kokkos::DynRankView<rightValueValueType, rightValueProperties...> rightValues,
301 const bool sumInto ) {
303 #ifdef HAVE_INTREPID2_DEBUG 305 INTREPID2_TEST_FOR_EXCEPTION( leftValues.rank() < 2 ||
306 leftValues.rank() > 4, std::invalid_argument,
307 ">>> ERROR (FunctionSpaceTools::integrate): Left data must have rank 2, 3 or 4.");
308 INTREPID2_TEST_FOR_EXCEPTION( outputValues.rank() < 1 ||
309 outputValues.rank() > 3, std::invalid_argument,
310 ">>> ERROR (FunctionSpaceTools::integrate): Output values must have rank 1, 2 or 3.");
314 const ordinal_type outRank = outputValues.rank();
315 const ordinal_type leftRank = leftValues.rank();
316 const ordinal_type mode = outRank*10 + leftRank;
379 INTREPID2_TEST_FOR_EXCEPTION( outRank < 1 || outRank > 3, std::runtime_error,
380 ">>> ERROR (FunctionSpaceTools::integrate): outRank must be 1,2, or 3.");
381 INTREPID2_TEST_FOR_EXCEPTION( leftRank < 2 || leftRank > 4, std::runtime_error,
382 ">>> ERROR (FunctionSpaceTools::integrate): leftRank must be 1,2, 3 or 4.");
388 namespace FunctorFunctionSpaceTools {
392 template<
typename outputValViewType,
393 typename inputDetViewType,
394 typename inputWeightViewType>
396 outputValViewType _outputVals;
397 const inputDetViewType _inputDet;
398 const inputWeightViewType _inputWeight;
400 KOKKOS_INLINE_FUNCTION
402 inputDetViewType inputDet_,
403 inputWeightViewType inputWeight_)
404 : _outputVals(outputVals_),
405 _inputDet(inputDet_),
406 _inputWeight(inputWeight_) {}
408 typedef ordinal_type value_type;
421 KOKKOS_INLINE_FUNCTION
422 void operator()(
const size_type cl, value_type &dst)
const {
424 const bool hasNegativeDet = (_inputDet(cl, 0) < 0.0);
425 dst |= hasNegativeDet;
428 const auto sign = (hasNegativeDet ? -1.0 : 1.0);
429 const ordinal_type pt_end = _outputVals.extent(1);
430 for (ordinal_type pt=0;pt<pt_end;++pt)
431 _outputVals(cl, pt) = sign*_inputDet(cl, pt)*_inputWeight(pt);
436 template<
typename DeviceType>
437 template<
typename outputValValueType,
class ...outputValProperties,
438 typename inputDetValueType,
class ...inputDetProperties,
439 typename inputWeightValueType,
class ...inputWeightProperties>
443 const Kokkos::DynRankView<inputDetValueType, inputDetProperties...> inputDet,
444 const Kokkos::DynRankView<inputWeightValueType,inputWeightProperties...> inputWeights ) {
445 #ifdef HAVE_INTREPID2_DEBUG 447 INTREPID2_TEST_FOR_EXCEPTION( inputDet.rank() != 2 ||
448 inputWeights.rank() != 1 ||
449 outputVals.rank() != 2, std::invalid_argument,
450 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Ranks are not compatible.");
451 INTREPID2_TEST_FOR_EXCEPTION( outputVals.extent(0) != inputDet.extent(0), std::invalid_argument,
452 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Cell dimension does not match.");
453 INTREPID2_TEST_FOR_EXCEPTION( inputDet.extent(1) != outputVals.extent(1) ||
454 inputWeights.extent(0) != outputVals.extent(1), std::invalid_argument,
455 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Point dimension does not match.");
458 constexpr
bool are_accessible =
459 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
460 typename decltype(outputVals)::memory_space>::accessible &&
461 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
462 typename decltype(inputDet)::memory_space>::accessible &&
463 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
464 typename decltype(inputWeights)::memory_space>::accessible;
465 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::computeCellMeasure(..): input/output views' memory spaces are not compatible with DeviceType");
468 <decltype(outputVals),decltype(inputDet),decltype(inputWeights)>;
470 const ordinal_type C = inputDet.extent(0);
471 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
473 typename FunctorType::value_type hasNegativeDet =
false;
474 Kokkos::parallel_reduce( policy, FunctorType(outputVals, inputDet, inputWeights), hasNegativeDet );
476 return hasNegativeDet;
481 template<
typename DeviceType>
482 template<
typename outputValValueType,
class ...outputValProperties,
483 typename inputJacValueType,
class ...inputJacProperties,
484 typename inputWeightValueType,
class ...inputWeightProperties,
485 typename scratchValueType,
class ...scratchProperties>
489 const Kokkos::DynRankView<inputJacValueType, inputJacProperties...> inputJac,
490 const Kokkos::DynRankView<inputWeightValueType,inputWeightProperties...> inputWeights,
491 const ordinal_type whichFace,
492 const shards::CellTopology parentCell,
493 const Kokkos::DynRankView<scratchValueType, scratchProperties...> scratch ) {
494 #ifdef HAVE_INTREPID2_DEBUG 495 INTREPID2_TEST_FOR_EXCEPTION( inputJac.rank() != 4, std::invalid_argument,
496 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Input Jacobian container must have rank 4.");
497 INTREPID2_TEST_FOR_EXCEPTION( scratch.rank() != 1, std::invalid_argument,
498 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Scratch view imust have rank 1.");
499 INTREPID2_TEST_FOR_EXCEPTION( scratch.span() < inputJac.span(), std::invalid_argument,
500 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Scratch storage must be greater than or equal to inputJac's one.");
508 auto vcprop = Kokkos::common_view_alloc_prop(scratch);
510 typedef Kokkos::DynRankView<scratchValueType, DeviceType> viewType;
511 viewType faceNormals(Kokkos::view_wrap(scratch.data(), vcprop),
528 template<
typename DeviceType>
529 template<
typename outputValValueType,
class ...outputValProperties,
530 typename inputJacValueType,
class ...inputJacProperties,
531 typename inputWeightValueType,
class ...inputWeightProperties,
532 typename scratchValueType,
class ...scratchProperties>
536 const Kokkos::DynRankView<inputJacValueType, inputJacProperties...> inputJac,
537 const Kokkos::DynRankView<inputWeightValueType,inputWeightProperties...> inputWeights,
538 const ordinal_type whichEdge,
539 const shards::CellTopology parentCell,
540 const Kokkos::DynRankView<scratchValueType, scratchProperties...> scratch ) {
541 #ifdef HAVE_INTREPID2_DEBUG 542 INTREPID2_TEST_FOR_EXCEPTION( (inputJac.rank() != 4), std::invalid_argument,
543 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Input Jacobian container must have rank 4.");
544 INTREPID2_TEST_FOR_EXCEPTION( scratch.rank() != 1, std::invalid_argument,
545 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Scratch view must have a rank 1.");
546 INTREPID2_TEST_FOR_EXCEPTION( scratch.span() < inputJac.span(), std::invalid_argument,
547 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Scratch storage must be greater than or equal to inputJac'one.");
555 auto vcprop = Kokkos::common_view_alloc_prop(scratch);
557 typedef Kokkos::DynRankView<scratchValueType, DeviceType> viewType;
558 viewType edgeTangents(Kokkos::view_wrap(scratch.data(), vcprop),
575 template<
typename DeviceType>
576 template<
typename outputValValueType,
class ...outputValProperties,
577 typename inputMeasureValueType,
class ...inputMeasureProperties,
578 typename inputValValueType,
class ...inputValProperties>
581 multiplyMeasure( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
582 const Kokkos::DynRankView<inputMeasureValueType,inputMeasureProperties...> inputMeasure,
583 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
584 scalarMultiplyDataField( outputVals,
591 template<
typename DeviceType>
592 template<
typename outputFieldValueType,
class ...outputFieldProperties,
593 typename inputDataValueType,
class ...inputDataProperties,
594 typename inputFieldValueType,
class ...inputFieldProperties>
598 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
599 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
600 const bool reciprocal ) {
609 template<
typename DeviceType>
610 template<
typename outputDataValuetype,
class ...outputDataProperties,
611 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
612 typename inputDataRightValueType,
class ...inputDataRightProperties>
616 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
617 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
618 const bool reciprocal ) {
627 template<
typename DeviceType>
628 template<
typename outputFieldValueType,
class ...outputFieldProperties,
629 typename inputDataValueType,
class ...inputDataProperties,
630 typename inputFieldValueType,
class ...inputFieldProperties>
634 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
635 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
643 template<
typename DeviceType>
644 template<
typename outputDataValueType,
class ...outputDataProperties,
645 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
646 typename inputDataRightValueType,
class ...inputDataRightProperties>
650 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
651 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
659 template<
typename DeviceType>
660 template<
typename outputFieldValueType,
class ...outputFieldProperties,
661 typename inputDataValueType,
class ...inputDataProperties,
662 typename inputFieldValueType,
class ...inputFieldProperties>
666 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
667 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
668 const auto outRank = outputFields.rank();
682 INTREPID2_TEST_FOR_EXCEPTION( outRank < 3 && outRank > 5, std::runtime_error,
683 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataField): Output container must have rank 3, 4 or 5.");
690 template<
typename DeviceType>
691 template<
typename outputDataValueType,
class ...outputDataProperties,
692 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
693 typename inputDataRightValueType,
class ...inputDataRightProperties>
697 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
698 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
699 const auto outRank = outputData.rank();
713 INTREPID2_TEST_FOR_EXCEPTION( outRank < 2 && outRank > 4, std::runtime_error,
714 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataData): Output container must have rank 2, 3 or 4.");
721 template<
typename DeviceType>
722 template<
typename outputFieldValueType,
class ...outputFieldProperties,
723 typename inputDataValueType,
class ...inputDataProperties,
724 typename inputFieldValueType,
class ...inputFieldProperties>
728 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
729 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
730 const char transpose ) {
732 const auto outRank = outputFields.rank();
747 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
748 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
755 template<
typename DeviceType>
756 template<
typename outputDataValueType,
class ...outputDataProperties,
757 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
758 typename inputDataRightValueType,
class ...inputDataRightProperties>
762 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
763 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
764 const char transpose ) {
765 const auto outRank = outputData.rank();
780 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
781 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
788 namespace FunctorFunctionSpaceTools {
793 template<
typename inoutOperatorViewType,
794 typename fieldSignViewType>
796 inoutOperatorViewType _inoutOperator;
797 const fieldSignViewType _fieldSigns;
799 KOKKOS_INLINE_FUNCTION
801 fieldSignViewType fieldSigns_ )
802 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
804 KOKKOS_INLINE_FUNCTION
805 void operator()(
const ordinal_type cl)
const {
806 const ordinal_type nlbf = _inoutOperator.extent(1);
807 const ordinal_type nrbf = _inoutOperator.extent(2);
809 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
810 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
811 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, lbf);
816 template<
typename DeviceType>
817 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
818 typename fieldSignValueType,
class ...fieldSignProperties>
821 applyLeftFieldSigns( Kokkos::DynRankView<inoutOperatorValueType,inoutOperatorProperties...> inoutOperator,
822 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
824 #ifdef HAVE_INTREPID2_DEBUG 825 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
826 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input operator container must have rank 3.");
827 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
828 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input field signs container must have rank 2.");
829 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
830 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
831 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(1) != fieldSigns.extent(1), std::invalid_argument,
832 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): First dimensions (number of left fields) of the operator and field signs containers must agree!");
835 constexpr
bool are_accessible =
836 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
837 typename decltype(inoutOperator)::memory_space>::accessible &&
838 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
839 typename decltype(fieldSigns)::memory_space>::accessible;
840 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyLeftFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
843 <decltype(inoutOperator),decltype(fieldSigns)>;
845 const ordinal_type C = inoutOperator.extent(0);
846 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
847 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
852 namespace FunctorFunctionSpaceTools {
856 template<
typename inoutOperatorViewType,
857 typename fieldSignViewType>
859 inoutOperatorViewType _inoutOperator;
860 const fieldSignViewType _fieldSigns;
862 KOKKOS_INLINE_FUNCTION
864 fieldSignViewType fieldSigns_ )
865 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
867 KOKKOS_INLINE_FUNCTION
868 void operator()(
const ordinal_type cl)
const {
869 const ordinal_type nlbf = _inoutOperator.extent(1);
870 const ordinal_type nrbf = _inoutOperator.extent(2);
872 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
873 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
874 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, rbf);
879 template<
typename DeviceType>
880 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
881 typename fieldSignValueType,
class ...fieldSignProperties>
885 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
887 #ifdef HAVE_INTREPID2_DEBUG 888 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
889 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input operator container must have rank 3.");
890 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
891 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input field signs container must have rank 2.");
892 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
893 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
894 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(2) != fieldSigns.extent(1), std::invalid_argument,
895 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Second dimension of the operator container and first dimension of the field signs container (number of right fields) must agree!");
898 constexpr
bool are_accessible =
899 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
900 typename decltype(inoutOperator)::memory_space>::accessible &&
901 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
902 typename decltype(fieldSigns)::memory_space>::accessible;
903 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyRightFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
906 <decltype(inoutOperator),decltype(fieldSigns)>;
908 const ordinal_type C = inoutOperator.extent(0);
909 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
910 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
915 namespace FunctorFunctionSpaceTools {
919 template<
typename inoutFunctionViewType,
920 typename fieldSignViewType>
922 inoutFunctionViewType _inoutFunction;
923 const fieldSignViewType _fieldSigns;
925 KOKKOS_INLINE_FUNCTION
927 fieldSignViewType fieldSigns_)
928 : _inoutFunction(inoutFunction_), _fieldSigns(fieldSigns_) {}
930 KOKKOS_INLINE_FUNCTION
931 void operator()(
const ordinal_type cl)
const {
932 const ordinal_type nbfs = _inoutFunction.extent(1);
933 const ordinal_type npts = _inoutFunction.extent(2);
934 const ordinal_type iend = _inoutFunction.extent(3);
935 const ordinal_type jend = _inoutFunction.extent(4);
937 for (ordinal_type bf=0;bf<nbfs;++bf)
938 for (ordinal_type pt=0;pt<npts;++pt)
939 for (ordinal_type i=0;i<iend;++i)
940 for (ordinal_type j=0;j<jend;++j)
941 _inoutFunction(cl, bf, pt, i, j) *= _fieldSigns(cl, bf);
946 template<
typename DeviceType>
947 template<
typename inoutFunctionValueType,
class ...inoutFunctionProperties,
948 typename fieldSignValueType,
class ...fieldSignProperties>
951 applyFieldSigns( Kokkos::DynRankView<inoutFunctionValueType,inoutFunctionProperties...> inoutFunction,
952 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
954 #ifdef HAVE_INTREPID2_DEBUG 955 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.rank() < 2 || inoutFunction.rank() > 5, std::invalid_argument,
956 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input function container must have rank 2, 3, 4, or 5.");
957 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
958 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input field signs container must have rank 2.");
959 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(0) != fieldSigns.extent(0), std::invalid_argument,
960 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Zeroth dimensions (number of integration domains) of the function and field signs containers must agree!");
961 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(1) != fieldSigns.extent(1), std::invalid_argument,
962 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): First dimensions (number of fields) of the function and field signs containers must agree!");
966 constexpr
bool are_accessible =
967 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
968 typename decltype(inoutFunction)::memory_space>::accessible &&
969 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
970 typename decltype(fieldSigns)::memory_space>::accessible;
971 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
974 <decltype(inoutFunction),decltype(fieldSigns)>;
976 const ordinal_type C = inoutFunction.extent(0);
977 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
978 Kokkos::parallel_for( policy, FunctorType(inoutFunction, fieldSigns) );
983 namespace FunctorFunctionSpaceTools {
988 template<
typename outputPointViewType,
989 typename inputCoeffViewType,
990 typename inputFieldViewType>
992 outputPointViewType _outputPointVals;
993 const inputCoeffViewType _inputCoeffs;
994 const inputFieldViewType _inputFields;
996 KOKKOS_INLINE_FUNCTION
997 F_evaluate( outputPointViewType outputPointVals_,
998 inputCoeffViewType inputCoeffs_,
999 inputFieldViewType inputFields_ )
1000 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1002 KOKKOS_INLINE_FUNCTION
1003 void operator()(
const ordinal_type cl)
const {
1004 const ordinal_type nbfs = _inputFields.extent(1);
1005 const ordinal_type npts = _inputFields.extent(2);
1007 const ordinal_type iend = _inputFields.extent(3);
1008 const ordinal_type jend = _inputFields.extent(4);
1010 for (ordinal_type bf=0;bf<nbfs;++bf)
1011 for (ordinal_type pt=0;pt<npts;++pt)
1012 for (ordinal_type i=0;i<iend;++i)
1013 for (ordinal_type j=0;j<jend;++j)
1014 _outputPointVals(cl, pt, i, j) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt, i, j);
1019 template<
typename DeviceType>
1020 template<
typename outputPointValueType,
class ...outputPointProperties,
1021 typename inputCoeffValueType,
class ...inputCoeffProperties,
1022 typename inputFieldValueType,
class ...inputFieldProperties>
1025 evaluate( Kokkos::DynRankView<outputPointValueType,outputPointProperties...> outputPointVals,
1026 const Kokkos::DynRankView<inputCoeffValueType, inputCoeffProperties...> inputCoeffs,
1027 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
1029 #ifdef HAVE_INTREPID2_DEBUG 1030 INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() < 3 || inputFields.rank() > 5, std::invalid_argument,
1031 ">>> ERROR (FunctionSpaceTools::evaluate): Input fields container must have rank 3, 4, or 5.");
1032 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.rank() != 2, std::invalid_argument,
1033 ">>> ERROR (FunctionSpaceTools::evaluate): Input coefficient container must have rank 2.");
1034 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.rank() != (inputFields.rank()-1), std::invalid_argument,
1035 ">>> ERROR (FunctionSpaceTools::evaluate): Output values container must have rank one less than the rank of the input fields container.");
1036 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(0) != inputFields.extent(0), std::invalid_argument,
1037 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the coefficient and fields input containers must agree!");
1038 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(1) != inputFields.extent(1), std::invalid_argument,
1039 ">>> ERROR (FunctionSpaceTools::evaluate): First dimensions (number of fields) of the coefficient and fields input containers must agree!");
1040 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(0) != inputFields.extent(0), std::invalid_argument,
1041 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the input fields container and the output values container must agree!");
1042 for (size_type i=1;i<outputPointVals.rank();++i)
1043 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(i) != inputFields.extent(i+1), std::invalid_argument,
1044 ">>> ERROR (FunctionSpaceTools::evaluate): outputPointVals dimension(i) does not match to inputFields dimension(i+1).");
1047 constexpr
bool are_accessible =
1048 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1049 typename decltype(outputPointVals)::memory_space>::accessible &&
1050 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1051 typename decltype(inputCoeffs)::memory_space>::accessible &&
1052 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1053 typename decltype(inputFields)::memory_space>::accessible;
1054 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::evaluate(..): input/output views' memory spaces are not compatible with DeviceType");
1057 <decltype(outputPointVals),decltype(inputCoeffs),decltype(inputFields)>;
1059 const ordinal_type C = inputFields.extent(0);
1060 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1061 Kokkos::parallel_for( policy, FunctorType(outputPointVals, inputCoeffs, inputFields) );
Defines TensorArgumentIterator, which allows systematic enumeration of a TensorData object...
Defines the Intrepid2::FunctorIterator class, as well as the Intrepid2::functor_returns_ref SFINAE he...