16 #ifndef __INTREPID2_FUNCTIONSPACETOOLS_DEF_HPP__
17 #define __INTREPID2_FUNCTIONSPACETOOLS_DEF_HPP__
22 #include "Teuchos_TimeMonitor.hpp"
26 template<
typename DeviceType>
27 template<
typename outputValueType,
class ...outputProperties,
28 typename inputValueType,
class ...inputProperties>
32 const Kokkos::DynRankView<inputValueType, inputProperties...> input ) {
33 if(output.rank() == input.rank()) {
34 #ifdef HAVE_INTREPID2_DEBUG
36 for (size_type i=0;i< input.rank();++i) {
37 INTREPID2_TEST_FOR_EXCEPTION( (input.extent(i) != output.extent(i)), std::invalid_argument,
38 ">>> ERROR (FunctionSpaceTools::HGRADtransformVALUE): Dimensions of input and output fields containers do not match.");
48 template<
typename DeviceType>
49 template<
typename outputValueType,
class ...outputProperties,
50 typename inputValueType,
class ...inputProperties>
54 const Kokkos::DynRankView<inputValueType, inputProperties...> input ) {
55 if(output.rank() == input.rank()) {
56 #ifdef HAVE_INTREPID2_DEBUG
58 for (size_type i=0;i< input.rank();++i) {
59 INTREPID2_TEST_FOR_EXCEPTION( (input.extent(i) != output.extent(i)), std::invalid_argument,
60 ">>> ERROR (FunctionSpaceTools::mapHGradDataFromPhysToRef): Dimensions of input and output fields containers do not match.");
70 template<
typename DeviceType>
71 template<
typename outputValueType,
class ...outputProperties,
72 typename inputValueType,
class ...inputProperties>
76 const Kokkos::DynRankView<inputValueType, inputProperties...> input ) {
77 if(output.rank() == input.rank()) {
78 #ifdef HAVE_INTREPID2_DEBUG
80 for (size_type i=0;i< input.rank();++i) {
81 INTREPID2_TEST_FOR_EXCEPTION( (input.extent(i) != output.extent(i)), std::invalid_argument,
82 ">>> ERROR (FunctionSpaceTools::mapHGradDataSideFromPhysToRefSide): Dimensions of input and output fields containers do not match.");
94 namespace FunctorFunctionSpaceTools {
100 template<
typename DeviceType>
101 template<
typename OutputValViewType,
102 typename JacobianInverseViewType,
103 typename InputValViewType>
107 const JacobianInverseViewType jacobianInverse,
108 const InputValViewType inputVals ) {
109 return HCURLtransformVALUE(outputVals, jacobianInverse, inputVals);
114 template<
typename DeviceType>
115 template<
typename outputValValueType,
class ...outputValProperties,
116 typename jacobianInverseValueType,
class ...jacobianInverseProperties,
117 typename inputValValueType,
class ...inputValProperties>
121 const Kokkos::DynRankView<jacobianInverseValueType,jacobianInverseProperties...> jacobianInverse,
122 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
126 template<
typename DeviceType>
127 template<
typename outputValValueType,
class ...outputValProperties,
128 typename jacobianValueType,
class ...jacobianProperties,
129 typename inputValValueType,
class ...inputValProperties>
133 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
134 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
139 namespace FunctorFunctionSpaceTools {
141 template<
typename outViewType,
142 typename inputViewType,
143 typename metricViewType
147 const inputViewType input_;
148 const metricViewType metricTensorDet_;
150 KOKKOS_INLINE_FUNCTION
152 const inputViewType input,
153 const metricViewType metricTensorDet)
154 : output_(output), input_(input), metricTensorDet_(metricTensorDet){};
156 KOKKOS_INLINE_FUNCTION
157 void operator()(
const size_type ic)
const {
158 for (
size_t pt=0; pt < input_.extent(1); pt++) {
159 auto measure = std::sqrt(metricTensorDet_(ic,pt));
160 output_(ic,pt,0) = - measure*input_(ic,pt,1);
161 output_(ic,pt,1) = measure*input_(ic,pt,0);
167 template<
typename DeviceType>
168 template<
typename outputValValueType,
class ...outputValProperties,
169 typename tangentsValueType,
class ...tangentsProperties,
170 typename metricTensorInvValueType,
class ...metricTensorInvProperties,
171 typename metricTensorDetValueType,
class ...metricTensorDetProperties,
172 typename inputValValueType,
class ...inputValProperties>
176 const Kokkos::DynRankView<tangentsValueType, tangentsProperties...> tangents,
177 const Kokkos::DynRankView<metricTensorInvValueType,metricTensorInvProperties...> metricTensorInv,
178 const Kokkos::DynRankView<metricTensorDetValueType,metricTensorDetProperties...> metricTensorDet,
179 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
180 auto work = Kokkos::DynRankView<outputValValueType, outputValProperties...>(
"work", outputVals.extent(0), outputVals.extent(1),outputVals.extent(2));
182 typename DeviceType::execution_space().fence();
184 typename DeviceType::execution_space().fence();
186 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,outputVals.extent(0)), FunctorType(outputVals, work, metricTensorDet) );
190 namespace FunctorFunctionSpaceTools {
192 template<
typename outViewType,
193 typename inputViewType,
194 typename metricViewType
198 const inputViewType input_;
199 const metricViewType metricTensorDet_;
200 const double scaling_;
202 KOKKOS_INLINE_FUNCTION
204 const inputViewType input,
205 const metricViewType metricTensorDet,
206 const double scaling)
207 : output_(output), input_(input), metricTensorDet_(metricTensorDet), scaling_(scaling){};
209 KOKKOS_INLINE_FUNCTION
210 void operator()(
const size_type ic)
const {
211 for (
size_t pt=0; pt < input_.extent(1); pt++) {
212 auto measure = std::sqrt(metricTensorDet_(ic,pt));
213 output_.access(ic,pt) = scaling_ * measure * input_.access(ic,pt);
219 template<
typename DeviceType>
220 template<
typename outputValValueType,
class ...outputValProperties,
221 typename jacobianDetValueType,
class ...jacobianDetProperties,
222 typename inputValValueType,
class ...inputValProperties>
226 Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
227 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> metricTensorDet,
228 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
230 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,outputVals.extent(0)), FunctorType(outputVals, inputVals, metricTensorDet, -1.0) );
235 template<
typename DeviceType>
236 template<
typename outputValValueType,
class ...outputValProperties,
237 typename jacobianValueType,
class ...jacobianProperties,
238 typename jacobianDetValueType,
class ...jacobianDetProperties,
239 typename inputValValueType,
class ...inputValProperties>
243 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
244 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
245 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
246 if(jacobian.data()==NULL || jacobian.extent(2)==2)
247 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
249 return HDIVtransformVALUE(outputVals, jacobian, jacobianDet, inputVals);
254 template<
typename DeviceType>
255 template<
typename outputValValueType,
class ...outputValProperties,
256 typename jacobianDetValueType,
class ...jacobianDetProperties,
257 typename inputValValueType,
class ...inputValProperties>
261 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
262 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
263 #ifdef HAVE_INTREPID2_DEBUG
265 INTREPID2_TEST_FOR_EXCEPTION( outputVals.rank() == 4, std::invalid_argument,
266 ">>> ERROR (FunctionSpaceTools::HCURLtransformCURL): Output rank must have rank 3.\n If these are 3D fields, then use the appropriate overload of this function.");
269 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
274 template<
typename DeviceType>
275 template<
typename outputValValueType,
class ...outputValProperties,
276 typename jacobianValueType,
class ...jacobianProperties,
277 typename jacobianDetValueType,
class ...jacobianDetProperties,
278 typename inputValValueType,
class ...inputValProperties>
282 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
283 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
284 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
285 #ifdef HAVE_INTREPID2_DEBUG
287 INTREPID2_TEST_FOR_EXCEPTION( outputVals.extent(3)!=2, std::invalid_argument,
288 ">>> ERROR (FunctionSpaceTools::HGRADtransformCURL):\n output field is 3D by the function is meant for 2D fields");
291 return HDIVtransformVALUE(outputVals, jacobian, jacobianDet, inputVals);
296 template<
typename DeviceType>
297 template<
typename outputValValueType,
class ...outputValProperties,
298 typename jacobianValueType,
class ...jacobianProperties,
299 typename jacobianDetValueType,
class ...jacobianDetProperties,
300 typename inputValValueType,
class ...inputValProperties>
304 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
305 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
306 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
311 template<
typename DeviceType>
312 template<
typename outputValValueType,
class ...outputValProperties,
313 typename jacobianInverseValueType,
class ...jacobianInverseProperties,
314 typename jacobianDetValueType,
class ...jacobianDetProperties,
315 typename inputValValueType,
class ...inputValProperties>
319 const Kokkos::DynRankView<jacobianInverseValueType, jacobianInverseProperties...> jacobianInv,
320 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
321 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
323 typename DeviceType::execution_space().fence();
329 template<
typename DeviceType>
330 template<
typename outputValValueType,
class ...outputValProperties,
331 typename jacobianDetValueType,
class ...jacobianDetProperties,
332 typename inputValValueType,
class ...inputValProperties>
336 Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
337 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> metricTensorDet,
338 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
340 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,outputVals.extent(0)), FunctorType(outputVals, inputVals, metricTensorDet, 1.0) );
345 template<
typename DeviceType>
346 template<
typename outputValValueType,
class ...outputValProperties,
347 typename jacobianDetValueType,
class ...jacobianDetProperties,
348 typename inputValValueType,
class ...inputValProperties>
351 HDIVtransformDIV( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
352 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
353 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
354 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
359 template<
typename DeviceType>
360 template<
typename outputValValueType,
class ...outputValProperties,
361 typename jacobianDetValueType,
class ...jacobianDetProperties,
362 typename inputValValueType,
class ...inputValProperties>
366 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
367 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
371 template<
typename DeviceType>
372 template<
typename outputValValueType,
class ...outputValProperties,
373 typename jacobianDetValueType,
class ...jacobianDetProperties,
374 typename inputValValueType,
class ...inputValProperties>
378 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
379 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
387 template<
typename DeviceType>
388 template<
typename outputValueValueType,
class ...outputValueProperties,
389 typename leftValueValueType,
class ...leftValueProperties,
390 typename rightValueValueType,
class ...rightValueProperties>
393 integrate( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
394 const Kokkos::DynRankView<leftValueValueType, leftValueProperties...> leftValues,
395 const Kokkos::DynRankView<rightValueValueType, rightValueProperties...> rightValues,
396 const bool sumInto ) {
398 #ifdef HAVE_INTREPID2_DEBUG
400 INTREPID2_TEST_FOR_EXCEPTION( leftValues.rank() < 2 ||
401 leftValues.rank() > 4, std::invalid_argument,
402 ">>> ERROR (FunctionSpaceTools::integrate): Left data must have rank 2, 3 or 4.");
403 INTREPID2_TEST_FOR_EXCEPTION( outputValues.rank() < 1 ||
404 outputValues.rank() > 3, std::invalid_argument,
405 ">>> ERROR (FunctionSpaceTools::integrate): Output values must have rank 1, 2 or 3.");
409 const ordinal_type outRank = outputValues.rank();
410 const ordinal_type leftRank = leftValues.rank();
411 const ordinal_type mode = outRank*10 + leftRank;
474 INTREPID2_TEST_FOR_EXCEPTION( outRank < 1 || outRank > 3, std::runtime_error,
475 ">>> ERROR (FunctionSpaceTools::integrate): outRank must be 1,2, or 3.");
476 INTREPID2_TEST_FOR_EXCEPTION( leftRank < 2 || leftRank > 4, std::runtime_error,
477 ">>> ERROR (FunctionSpaceTools::integrate): leftRank must be 1,2, 3 or 4.");
483 namespace FunctorFunctionSpaceTools {
487 template<
typename outputValViewType,
488 typename inputDetViewType,
489 typename inputWeightViewType>
491 outputValViewType _outputVals;
492 const inputDetViewType _inputDet;
493 const inputWeightViewType _inputWeight;
495 KOKKOS_INLINE_FUNCTION
497 inputDetViewType inputDet_,
498 inputWeightViewType inputWeight_)
499 : _outputVals(outputVals_),
500 _inputDet(inputDet_),
501 _inputWeight(inputWeight_) {}
503 typedef ordinal_type value_type;
516 KOKKOS_INLINE_FUNCTION
517 void operator()(
const size_type cl, value_type &dst)
const {
519 const bool hasNegativeDet = (_inputDet(cl, 0) < 0.0);
520 dst |= hasNegativeDet;
523 const auto sign = (hasNegativeDet ? -1.0 : 1.0);
524 const ordinal_type pt_end = _outputVals.extent(1);
525 for (ordinal_type pt=0;pt<pt_end;++pt)
526 _outputVals(cl, pt) = sign*_inputDet(cl, pt)*_inputWeight(pt);
531 template<
typename DeviceType>
532 template<
typename OutputValViewType,
533 typename InputDetViewType,
534 typename InputWeightViewType>
538 const InputDetViewType inputDet,
539 const InputWeightViewType inputWeights ) {
540 #ifdef HAVE_INTREPID2_DEBUG
542 INTREPID2_TEST_FOR_EXCEPTION( rank(inputDet) != 2 ||
543 rank(inputWeights) != 1 ||
544 rank(outputVals) != 2, std::invalid_argument,
545 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Ranks are not compatible.");
546 INTREPID2_TEST_FOR_EXCEPTION( outputVals.extent(0) != inputDet.extent(0), std::invalid_argument,
547 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Cell dimension does not match.");
548 INTREPID2_TEST_FOR_EXCEPTION( inputDet.extent(1) != outputVals.extent(1) ||
549 inputWeights.extent(0) != outputVals.extent(1), std::invalid_argument,
550 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Point dimension does not match.");
553 constexpr
bool are_accessible =
554 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
555 typename decltype(outputVals)::memory_space>::accessible &&
556 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
557 typename decltype(inputDet)::memory_space>::accessible &&
558 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
559 typename decltype(inputWeights)::memory_space>::accessible;
560 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::computeCellMeasure(..): input/output views' memory spaces are not compatible with DeviceType");
563 <decltype(outputVals),decltype(inputDet),decltype(inputWeights)>;
565 const ordinal_type C = inputDet.extent(0);
566 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
568 typename FunctorType::value_type hasNegativeDet =
false;
569 Kokkos::parallel_reduce( policy, FunctorType(outputVals, inputDet, inputWeights), hasNegativeDet );
571 return hasNegativeDet;
576 template<
typename DeviceType>
577 template<
typename outputValValueType,
class ...outputValProperties,
578 typename inputJacValueType,
class ...inputJacProperties,
579 typename inputWeightValueType,
class ...inputWeightProperties,
580 typename scratchValueType,
class ...scratchProperties>
584 const Kokkos::DynRankView<inputJacValueType, inputJacProperties...> inputJac,
585 const Kokkos::DynRankView<inputWeightValueType,inputWeightProperties...> inputWeights,
586 const ordinal_type whichFace,
587 const shards::CellTopology parentCell,
588 const Kokkos::DynRankView<scratchValueType, scratchProperties...> scratch ) {
589 #ifdef HAVE_INTREPID2_DEBUG
590 INTREPID2_TEST_FOR_EXCEPTION( inputJac.rank() != 4, std::invalid_argument,
591 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Input Jacobian container must have rank 4.");
592 INTREPID2_TEST_FOR_EXCEPTION( scratch.rank() != 1, std::invalid_argument,
593 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Scratch view imust have rank 1.");
594 INTREPID2_TEST_FOR_EXCEPTION( scratch.size() < inputJac.size(), std::invalid_argument,
595 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Scratch storage must be greater than or equal to inputJac's one.");
603 auto vcprop = Kokkos::common_view_alloc_prop(scratch);
605 typedef Kokkos::DynRankView<scratchValueType, DeviceType> viewType;
606 viewType faceNormals(Kokkos::view_wrap(scratch.data(), vcprop),
623 template<
typename DeviceType>
624 template<
typename outputValValueType,
class ...outputValProperties,
625 typename inputJacValueType,
class ...inputJacProperties,
626 typename inputWeightValueType,
class ...inputWeightProperties,
627 typename scratchValueType,
class ...scratchProperties>
631 const Kokkos::DynRankView<inputJacValueType, inputJacProperties...> inputJac,
632 const Kokkos::DynRankView<inputWeightValueType,inputWeightProperties...> inputWeights,
633 const ordinal_type whichEdge,
634 const shards::CellTopology parentCell,
635 const Kokkos::DynRankView<scratchValueType, scratchProperties...> scratch ) {
636 #ifdef HAVE_INTREPID2_DEBUG
637 INTREPID2_TEST_FOR_EXCEPTION( (inputJac.rank() != 4), std::invalid_argument,
638 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Input Jacobian container must have rank 4.");
639 INTREPID2_TEST_FOR_EXCEPTION( scratch.rank() != 1, std::invalid_argument,
640 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Scratch view must have a rank 1.");
641 INTREPID2_TEST_FOR_EXCEPTION( scratch.size() < inputJac.size(), std::invalid_argument,
642 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Scratch storage must be greater than or equal to inputJac'one.");
650 auto vcprop = Kokkos::common_view_alloc_prop(scratch);
652 typedef Kokkos::DynRankView<scratchValueType, DeviceType> viewType;
653 viewType edgeTangents(Kokkos::view_wrap(scratch.data(), vcprop),
670 template<
typename DeviceType>
671 template<
typename outputValValueType,
class ...outputValProperties,
672 typename inputMeasureValueType,
class ...inputMeasureProperties,
673 typename inputValValueType,
class ...inputValProperties>
676 multiplyMeasure( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
677 const Kokkos::DynRankView<inputMeasureValueType,inputMeasureProperties...> inputMeasure,
678 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
679 scalarMultiplyDataField( outputVals,
686 template<
typename DeviceType>
687 template<
typename outputFieldValueType,
class ...outputFieldProperties,
688 typename inputDataValueType,
class ...inputDataProperties,
689 typename inputFieldValueType,
class ...inputFieldProperties>
693 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
694 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
695 const bool reciprocal ) {
704 template<
typename DeviceType>
705 template<
typename outputDataValuetype,
class ...outputDataProperties,
706 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
707 typename inputDataRightValueType,
class ...inputDataRightProperties>
711 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
712 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
713 const bool reciprocal ) {
722 template<
typename DeviceType>
723 template<
typename outputFieldValueType,
class ...outputFieldProperties,
724 typename inputDataValueType,
class ...inputDataProperties,
725 typename inputFieldValueType,
class ...inputFieldProperties>
729 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
730 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
738 template<
typename DeviceType>
739 template<
typename outputDataValueType,
class ...outputDataProperties,
740 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
741 typename inputDataRightValueType,
class ...inputDataRightProperties>
745 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
746 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
754 template<
typename DeviceType>
755 template<
typename outputFieldValueType,
class ...outputFieldProperties,
756 typename inputDataValueType,
class ...inputDataProperties,
757 typename inputFieldValueType,
class ...inputFieldProperties>
761 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
762 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
763 const auto outRank = outputFields.rank();
777 INTREPID2_TEST_FOR_EXCEPTION( outRank < 3 && outRank > 5, std::runtime_error,
778 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataField): Output container must have rank 3, 4 or 5.");
785 template<
typename DeviceType>
786 template<
typename outputDataValueType,
class ...outputDataProperties,
787 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
788 typename inputDataRightValueType,
class ...inputDataRightProperties>
792 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
793 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
794 const auto outRank = outputData.rank();
808 INTREPID2_TEST_FOR_EXCEPTION( outRank < 2 && outRank > 4, std::runtime_error,
809 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataData): Output container must have rank 2, 3 or 4.");
816 template<
typename DeviceType>
817 template<
typename outputFieldValueType,
class ...outputFieldProperties,
818 typename inputDataValueType,
class ...inputDataProperties,
819 typename inputFieldValueType,
class ...inputFieldProperties>
823 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
824 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
825 const char transpose ) {
827 const auto outRank = outputFields.rank();
842 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
843 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
850 template<
typename DeviceType>
851 template<
typename outputDataValueType,
class ...outputDataProperties,
852 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
853 typename inputDataRightValueType,
class ...inputDataRightProperties>
857 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
858 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
859 const char transpose ) {
860 const auto outRank = outputData.rank();
875 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
876 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
883 namespace FunctorFunctionSpaceTools {
888 template<
typename inoutOperatorViewType,
889 typename fieldSignViewType>
891 inoutOperatorViewType _inoutOperator;
892 const fieldSignViewType _fieldSigns;
894 KOKKOS_INLINE_FUNCTION
896 fieldSignViewType fieldSigns_ )
897 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
899 KOKKOS_INLINE_FUNCTION
900 void operator()(
const ordinal_type cl)
const {
901 const ordinal_type nlbf = _inoutOperator.extent(1);
902 const ordinal_type nrbf = _inoutOperator.extent(2);
904 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
905 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
906 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, lbf);
911 template<
typename DeviceType>
912 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
913 typename fieldSignValueType,
class ...fieldSignProperties>
916 applyLeftFieldSigns( Kokkos::DynRankView<inoutOperatorValueType,inoutOperatorProperties...> inoutOperator,
917 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
919 #ifdef HAVE_INTREPID2_DEBUG
920 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
921 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input operator container must have rank 3.");
922 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
923 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input field signs container must have rank 2.");
924 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
925 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
926 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(1) != fieldSigns.extent(1), std::invalid_argument,
927 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): First dimensions (number of left fields) of the operator and field signs containers must agree!");
930 constexpr
bool are_accessible =
931 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
932 typename decltype(inoutOperator)::memory_space>::accessible &&
933 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
934 typename decltype(fieldSigns)::memory_space>::accessible;
935 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyLeftFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
938 <decltype(inoutOperator),decltype(fieldSigns)>;
940 const ordinal_type C = inoutOperator.extent(0);
941 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
942 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
947 namespace FunctorFunctionSpaceTools {
951 template<
typename inoutOperatorViewType,
952 typename fieldSignViewType>
954 inoutOperatorViewType _inoutOperator;
955 const fieldSignViewType _fieldSigns;
957 KOKKOS_INLINE_FUNCTION
959 fieldSignViewType fieldSigns_ )
960 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
962 KOKKOS_INLINE_FUNCTION
963 void operator()(
const ordinal_type cl)
const {
964 const ordinal_type nlbf = _inoutOperator.extent(1);
965 const ordinal_type nrbf = _inoutOperator.extent(2);
967 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
968 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
969 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, rbf);
974 template<
typename DeviceType>
975 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
976 typename fieldSignValueType,
class ...fieldSignProperties>
980 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
982 #ifdef HAVE_INTREPID2_DEBUG
983 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
984 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input operator container must have rank 3.");
985 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
986 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input field signs container must have rank 2.");
987 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
988 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
989 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(2) != fieldSigns.extent(1), std::invalid_argument,
990 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Second dimension of the operator container and first dimension of the field signs container (number of right fields) must agree!");
993 constexpr
bool are_accessible =
994 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
995 typename decltype(inoutOperator)::memory_space>::accessible &&
996 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
997 typename decltype(fieldSigns)::memory_space>::accessible;
998 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyRightFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
1001 <decltype(inoutOperator),decltype(fieldSigns)>;
1003 const ordinal_type C = inoutOperator.extent(0);
1004 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1005 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
1010 namespace FunctorFunctionSpaceTools {
1014 template<
typename inoutFunctionViewType,
1015 typename fieldSignViewType>
1017 inoutFunctionViewType _inoutFunction;
1018 const fieldSignViewType _fieldSigns;
1020 KOKKOS_INLINE_FUNCTION
1022 fieldSignViewType fieldSigns_)
1023 : _inoutFunction(inoutFunction_), _fieldSigns(fieldSigns_) {}
1025 KOKKOS_INLINE_FUNCTION
1026 void operator()(
const ordinal_type cl)
const {
1027 const ordinal_type nbfs = _inoutFunction.extent(1);
1028 const ordinal_type npts = _inoutFunction.extent(2);
1029 const ordinal_type iend = _inoutFunction.extent(3);
1030 const ordinal_type jend = _inoutFunction.extent(4);
1032 for (ordinal_type bf=0;bf<nbfs;++bf)
1033 for (ordinal_type pt=0;pt<npts;++pt)
1034 for (ordinal_type i=0;i<iend;++i)
1035 for (ordinal_type j=0;j<jend;++j)
1036 _inoutFunction(cl, bf, pt, i, j) *= _fieldSigns(cl, bf);
1041 template<
typename DeviceType>
1042 template<
typename inoutFunctionValueType,
class ...inoutFunctionProperties,
1043 typename fieldSignValueType,
class ...fieldSignProperties>
1046 applyFieldSigns( Kokkos::DynRankView<inoutFunctionValueType,inoutFunctionProperties...> inoutFunction,
1047 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
1049 #ifdef HAVE_INTREPID2_DEBUG
1050 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.rank() < 2 || inoutFunction.rank() > 5, std::invalid_argument,
1051 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input function container must have rank 2, 3, 4, or 5.");
1052 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
1053 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input field signs container must have rank 2.");
1054 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(0) != fieldSigns.extent(0), std::invalid_argument,
1055 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Zeroth dimensions (number of integration domains) of the function and field signs containers must agree!");
1056 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(1) != fieldSigns.extent(1), std::invalid_argument,
1057 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): First dimensions (number of fields) of the function and field signs containers must agree!");
1061 constexpr
bool are_accessible =
1062 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1063 typename decltype(inoutFunction)::memory_space>::accessible &&
1064 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1065 typename decltype(fieldSigns)::memory_space>::accessible;
1066 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
1069 <decltype(inoutFunction),decltype(fieldSigns)>;
1071 const ordinal_type C = inoutFunction.extent(0);
1072 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1073 Kokkos::parallel_for( policy, FunctorType(inoutFunction, fieldSigns) );
1078 namespace FunctorFunctionSpaceTools {
1083 template<
typename outputPointViewType,
1084 typename inputCoeffViewType,
1085 typename inputFieldViewType>
1087 outputPointViewType _outputPointVals;
1088 const inputCoeffViewType _inputCoeffs;
1089 const inputFieldViewType _inputFields;
1091 KOKKOS_INLINE_FUNCTION
1092 F_evaluate( outputPointViewType outputPointVals_,
1093 inputCoeffViewType inputCoeffs_,
1094 inputFieldViewType inputFields_ )
1095 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1097 KOKKOS_INLINE_FUNCTION
1098 void operator()(
const ordinal_type cl)
const {
1099 const ordinal_type nbfs = _inputFields.extent(1);
1100 const ordinal_type npts = _inputFields.extent(2);
1102 const ordinal_type iend = _inputFields.extent(3);
1103 const ordinal_type jend = _inputFields.extent(4);
1105 for (ordinal_type bf=0;bf<nbfs;++bf)
1106 for (ordinal_type pt=0;pt<npts;++pt)
1107 for (ordinal_type i=0;i<iend;++i)
1108 for (ordinal_type j=0;j<jend;++j)
1109 _outputPointVals(cl, pt, i, j) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt, i, j);
1114 template<
typename DeviceType>
1115 template<
typename outputPointValueType,
class ...outputPointProperties,
1116 typename inputCoeffValueType,
class ...inputCoeffProperties,
1117 typename inputFieldValueType,
class ...inputFieldProperties>
1120 evaluate( Kokkos::DynRankView<outputPointValueType,outputPointProperties...> outputPointVals,
1121 const Kokkos::DynRankView<inputCoeffValueType, inputCoeffProperties...> inputCoeffs,
1122 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
1124 #ifdef HAVE_INTREPID2_DEBUG
1125 INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() < 3 || inputFields.rank() > 5, std::invalid_argument,
1126 ">>> ERROR (FunctionSpaceTools::evaluate): Input fields container must have rank 3, 4, or 5.");
1127 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.rank() != 2, std::invalid_argument,
1128 ">>> ERROR (FunctionSpaceTools::evaluate): Input coefficient container must have rank 2.");
1129 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.rank() != (inputFields.rank()-1), std::invalid_argument,
1130 ">>> ERROR (FunctionSpaceTools::evaluate): Output values container must have rank one less than the rank of the input fields container.");
1131 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(0) != inputFields.extent(0), std::invalid_argument,
1132 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the coefficient and fields input containers must agree!");
1133 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(1) != inputFields.extent(1), std::invalid_argument,
1134 ">>> ERROR (FunctionSpaceTools::evaluate): First dimensions (number of fields) of the coefficient and fields input containers must agree!");
1135 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(0) != inputFields.extent(0), std::invalid_argument,
1136 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the input fields container and the output values container must agree!");
1137 for (size_type i=1;i<outputPointVals.rank();++i)
1138 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(i) != inputFields.extent(i+1), std::invalid_argument,
1139 ">>> ERROR (FunctionSpaceTools::evaluate): outputPointVals dimension(i) does not match to inputFields dimension(i+1).");
1142 constexpr
bool are_accessible =
1143 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1144 typename decltype(outputPointVals)::memory_space>::accessible &&
1145 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1146 typename decltype(inputCoeffs)::memory_space>::accessible &&
1147 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1148 typename decltype(inputFields)::memory_space>::accessible;
1149 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::evaluate(..): input/output views' memory spaces are not compatible with DeviceType");
1152 <decltype(outputPointVals),decltype(inputCoeffs),decltype(inputFields)>;
1154 const ordinal_type C = inputFields.extent(0);
1155 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1156 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...