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.");
81 template<
typename DeviceType>
82 template<
typename outputValueType,
class ...outputProperties,
83 typename inputValueType,
class ...inputProperties>
87 const Kokkos::DynRankView<inputValueType, inputProperties...> input ) {
88 if(output.rank() == input.rank()) {
89 #ifdef HAVE_INTREPID2_DEBUG
91 for (size_type i=0;i< input.rank();++i) {
92 INTREPID2_TEST_FOR_EXCEPTION( (input.extent(i) != output.extent(i)), std::invalid_argument,
93 ">>> ERROR (FunctionSpaceTools::mapHGradDataFromPhysToRef): Dimensions of input and output fields containers do not match.");
103 template<
typename DeviceType>
104 template<
typename outputValueType,
class ...outputProperties,
105 typename inputValueType,
class ...inputProperties>
109 const Kokkos::DynRankView<inputValueType, inputProperties...> input ) {
110 if(output.rank() == input.rank()) {
111 #ifdef HAVE_INTREPID2_DEBUG
113 for (size_type i=0;i< input.rank();++i) {
114 INTREPID2_TEST_FOR_EXCEPTION( (input.extent(i) != output.extent(i)), std::invalid_argument,
115 ">>> ERROR (FunctionSpaceTools::mapHGradDataSideFromPhysToRefSide): Dimensions of input and output fields containers do not match.");
127 namespace FunctorFunctionSpaceTools {
133 template<
typename DeviceType>
134 template<
typename OutputValViewType,
135 typename JacobianInverseViewType,
136 typename InputValViewType>
140 const JacobianInverseViewType jacobianInverse,
141 const InputValViewType inputVals ) {
142 return HCURLtransformVALUE(outputVals, jacobianInverse, inputVals);
147 template<
typename DeviceType>
148 template<
typename outputValValueType,
class ...outputValProperties,
149 typename jacobianInverseValueType,
class ...jacobianInverseProperties,
150 typename inputValValueType,
class ...inputValProperties>
154 const Kokkos::DynRankView<jacobianInverseValueType,jacobianInverseProperties...> jacobianInverse,
155 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
159 template<
typename DeviceType>
160 template<
typename outputValValueType,
class ...outputValProperties,
161 typename jacobianValueType,
class ...jacobianProperties,
162 typename inputValValueType,
class ...inputValProperties>
166 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
167 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
172 namespace FunctorFunctionSpaceTools {
174 template<
typename outViewType,
175 typename inputViewType,
176 typename metricViewType
180 const inputViewType input_;
181 const metricViewType metricTensorDet_;
183 KOKKOS_INLINE_FUNCTION
185 const inputViewType input,
186 const metricViewType metricTensorDet)
187 : output_(output), input_(input), metricTensorDet_(metricTensorDet){};
189 KOKKOS_INLINE_FUNCTION
190 void operator()(
const size_type ic)
const {
191 for (
size_t pt=0; pt < input_.extent(1); pt++) {
192 auto measure = std::sqrt(metricTensorDet_(ic,pt));
193 output_(ic,pt,0) = - measure*input_(ic,pt,1);
194 output_(ic,pt,1) = measure*input_(ic,pt,0);
200 template<
typename DeviceType>
201 template<
typename outputValValueType,
class ...outputValProperties,
202 typename tangentsValueType,
class ...tangentsProperties,
203 typename metricTensorInvValueType,
class ...metricTensorInvProperties,
204 typename metricTensorDetValueType,
class ...metricTensorDetProperties,
205 typename inputValValueType,
class ...inputValProperties>
209 const Kokkos::DynRankView<tangentsValueType, tangentsProperties...> tangents,
210 const Kokkos::DynRankView<metricTensorInvValueType,metricTensorInvProperties...> metricTensorInv,
211 const Kokkos::DynRankView<metricTensorDetValueType,metricTensorDetProperties...> metricTensorDet,
212 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
213 auto work = Kokkos::DynRankView<outputValValueType, outputValProperties...>(
"work", outputVals.extent(0), outputVals.extent(1),outputVals.extent(2));
215 typename DeviceType::execution_space().fence();
217 typename DeviceType::execution_space().fence();
219 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,outputVals.extent(0)), FunctorType(outputVals, work, metricTensorDet) );
223 namespace FunctorFunctionSpaceTools {
225 template<
typename outViewType,
226 typename inputViewType,
227 typename metricViewType
231 const inputViewType input_;
232 const metricViewType metricTensorDet_;
233 const double scaling_;
235 KOKKOS_INLINE_FUNCTION
237 const inputViewType input,
238 const metricViewType metricTensorDet,
239 const double scaling)
240 : output_(output), input_(input), metricTensorDet_(metricTensorDet), scaling_(scaling){};
242 KOKKOS_INLINE_FUNCTION
243 void operator()(
const size_type ic)
const {
244 for (
size_t pt=0; pt < input_.extent(1); pt++) {
245 auto measure = std::sqrt(metricTensorDet_(ic,pt));
246 output_.access(ic,pt) = scaling_ * measure * input_.access(ic,pt);
252 template<
typename DeviceType>
253 template<
typename outputValValueType,
class ...outputValProperties,
254 typename jacobianDetValueType,
class ...jacobianDetProperties,
255 typename inputValValueType,
class ...inputValProperties>
259 Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
260 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> metricTensorDet,
261 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
263 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,outputVals.extent(0)), FunctorType(outputVals, inputVals, metricTensorDet, -1.0) );
268 template<
typename DeviceType>
269 template<
typename outputValValueType,
class ...outputValProperties,
270 typename jacobianValueType,
class ...jacobianProperties,
271 typename jacobianDetValueType,
class ...jacobianDetProperties,
272 typename inputValValueType,
class ...inputValProperties>
276 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
277 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
278 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
279 if(jacobian.data()==NULL || jacobian.extent(2)==2)
280 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
282 return HDIVtransformVALUE(outputVals, jacobian, jacobianDet, inputVals);
287 template<
typename DeviceType>
288 template<
typename outputValValueType,
class ...outputValProperties,
289 typename jacobianDetValueType,
class ...jacobianDetProperties,
290 typename inputValValueType,
class ...inputValProperties>
294 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
295 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
296 #ifdef HAVE_INTREPID2_DEBUG
298 INTREPID2_TEST_FOR_EXCEPTION( outputVals.rank() == 4, std::invalid_argument,
299 ">>> ERROR (FunctionSpaceTools::HCURLtransformCURL): Output rank must have rank 3.\n If these are 3D fields, then use the appropriate overload of this function.");
302 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
307 template<
typename DeviceType>
308 template<
typename outputValValueType,
class ...outputValProperties,
309 typename jacobianValueType,
class ...jacobianProperties,
310 typename jacobianDetValueType,
class ...jacobianDetProperties,
311 typename inputValValueType,
class ...inputValProperties>
315 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
316 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
317 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
318 #ifdef HAVE_INTREPID2_DEBUG
320 INTREPID2_TEST_FOR_EXCEPTION( outputVals.extent(3)!=2, std::invalid_argument,
321 ">>> ERROR (FunctionSpaceTools::HGRADtransformCURL):\n output field is 3D by the function is meant for 2D fields");
324 return HDIVtransformVALUE(outputVals, jacobian, jacobianDet, inputVals);
329 template<
typename DeviceType>
330 template<
typename outputValValueType,
class ...outputValProperties,
331 typename jacobianValueType,
class ...jacobianProperties,
332 typename jacobianDetValueType,
class ...jacobianDetProperties,
333 typename inputValValueType,
class ...inputValProperties>
337 const Kokkos::DynRankView<jacobianValueType, jacobianProperties...> jacobian,
338 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
339 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
344 template<
typename DeviceType>
345 template<
typename outputValValueType,
class ...outputValProperties,
346 typename jacobianInverseValueType,
class ...jacobianInverseProperties,
347 typename jacobianDetValueType,
class ...jacobianDetProperties,
348 typename inputValValueType,
class ...inputValProperties>
352 const Kokkos::DynRankView<jacobianInverseValueType, jacobianInverseProperties...> jacobianInv,
353 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
354 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
356 typename DeviceType::execution_space().fence();
362 template<
typename DeviceType>
363 template<
typename outputValValueType,
class ...outputValProperties,
364 typename jacobianDetValueType,
class ...jacobianDetProperties,
365 typename inputValValueType,
class ...inputValProperties>
369 Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
370 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> metricTensorDet,
371 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
373 Kokkos::parallel_for(Kokkos::RangePolicy<ExecSpaceType>(0,outputVals.extent(0)), FunctorType(outputVals, inputVals, metricTensorDet, 1.0) );
378 template<
typename DeviceType>
379 template<
typename outputValValueType,
class ...outputValProperties,
380 typename jacobianDetValueType,
class ...jacobianDetProperties,
381 typename inputValValueType,
class ...inputValProperties>
384 HDIVtransformDIV( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
385 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
386 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
387 return HVOLtransformVALUE(outputVals, jacobianDet, inputVals);
392 template<
typename DeviceType>
393 template<
typename outputValValueType,
class ...outputValProperties,
394 typename jacobianDetValueType,
class ...jacobianDetProperties,
395 typename inputValValueType,
class ...inputValProperties>
399 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
400 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
404 template<
typename DeviceType>
405 template<
typename outputValValueType,
class ...outputValProperties,
406 typename jacobianDetValueType,
class ...jacobianDetProperties,
407 typename inputValValueType,
class ...inputValProperties>
411 const Kokkos::DynRankView<jacobianDetValueType,jacobianDetProperties...> jacobianDet,
412 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
420 template<
typename DeviceType>
421 template<
typename outputValueValueType,
class ...outputValueProperties,
422 typename leftValueValueType,
class ...leftValueProperties,
423 typename rightValueValueType,
class ...rightValueProperties>
426 integrate( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
427 const Kokkos::DynRankView<leftValueValueType, leftValueProperties...> leftValues,
428 const Kokkos::DynRankView<rightValueValueType, rightValueProperties...> rightValues,
429 const bool sumInto ) {
431 #ifdef HAVE_INTREPID2_DEBUG
433 INTREPID2_TEST_FOR_EXCEPTION( leftValues.rank() < 2 ||
434 leftValues.rank() > 4, std::invalid_argument,
435 ">>> ERROR (FunctionSpaceTools::integrate): Left data must have rank 2, 3 or 4.");
436 INTREPID2_TEST_FOR_EXCEPTION( outputValues.rank() < 1 ||
437 outputValues.rank() > 3, std::invalid_argument,
438 ">>> ERROR (FunctionSpaceTools::integrate): Output values must have rank 1, 2 or 3.");
442 const ordinal_type outRank = outputValues.rank();
443 const ordinal_type leftRank = leftValues.rank();
444 const ordinal_type mode = outRank*10 + leftRank;
507 INTREPID2_TEST_FOR_EXCEPTION( outRank < 1 || outRank > 3, std::runtime_error,
508 ">>> ERROR (FunctionSpaceTools::integrate): outRank must be 1,2, or 3.");
509 INTREPID2_TEST_FOR_EXCEPTION( leftRank < 2 || leftRank > 4, std::runtime_error,
510 ">>> ERROR (FunctionSpaceTools::integrate): leftRank must be 1,2, 3 or 4.");
516 namespace FunctorFunctionSpaceTools {
520 template<
typename outputValViewType,
521 typename inputDetViewType,
522 typename inputWeightViewType>
524 outputValViewType _outputVals;
525 const inputDetViewType _inputDet;
526 const inputWeightViewType _inputWeight;
528 KOKKOS_INLINE_FUNCTION
530 inputDetViewType inputDet_,
531 inputWeightViewType inputWeight_)
532 : _outputVals(outputVals_),
533 _inputDet(inputDet_),
534 _inputWeight(inputWeight_) {}
536 typedef ordinal_type value_type;
549 KOKKOS_INLINE_FUNCTION
550 void operator()(
const size_type cl, value_type &dst)
const {
552 const bool hasNegativeDet = (_inputDet(cl, 0) < 0.0);
553 dst |= hasNegativeDet;
556 const auto sign = (hasNegativeDet ? -1.0 : 1.0);
557 const ordinal_type pt_end = _outputVals.extent(1);
558 for (ordinal_type pt=0;pt<pt_end;++pt)
559 _outputVals(cl, pt) = sign*_inputDet(cl, pt)*_inputWeight(pt);
564 template<
typename DeviceType>
565 template<
typename OutputValViewType,
566 typename InputDetViewType,
567 typename InputWeightViewType>
571 const InputDetViewType inputDet,
572 const InputWeightViewType inputWeights ) {
573 #ifdef HAVE_INTREPID2_DEBUG
575 INTREPID2_TEST_FOR_EXCEPTION( rank(inputDet) != 2 ||
576 rank(inputWeights) != 1 ||
577 rank(outputVals) != 2, std::invalid_argument,
578 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Ranks are not compatible.");
579 INTREPID2_TEST_FOR_EXCEPTION( outputVals.extent(0) != inputDet.extent(0), std::invalid_argument,
580 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Cell dimension does not match.");
581 INTREPID2_TEST_FOR_EXCEPTION( inputDet.extent(1) != outputVals.extent(1) ||
582 inputWeights.extent(0) != outputVals.extent(1), std::invalid_argument,
583 ">>> ERROR (FunctionSpaceTools::computeCellMeasure): Point dimension does not match.");
586 constexpr
bool are_accessible =
587 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
588 typename decltype(outputVals)::memory_space>::accessible &&
589 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
590 typename decltype(inputDet)::memory_space>::accessible &&
591 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
592 typename decltype(inputWeights)::memory_space>::accessible;
593 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::computeCellMeasure(..): input/output views' memory spaces are not compatible with DeviceType");
596 <decltype(outputVals),decltype(inputDet),decltype(inputWeights)>;
598 const ordinal_type C = inputDet.extent(0);
599 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
601 typename FunctorType::value_type hasNegativeDet =
false;
602 Kokkos::parallel_reduce( policy, FunctorType(outputVals, inputDet, inputWeights), hasNegativeDet );
604 return hasNegativeDet;
609 template<
typename DeviceType>
610 template<
typename outputValValueType,
class ...outputValProperties,
611 typename inputJacValueType,
class ...inputJacProperties,
612 typename inputWeightValueType,
class ...inputWeightProperties,
613 typename scratchValueType,
class ...scratchProperties>
617 const Kokkos::DynRankView<inputJacValueType, inputJacProperties...> inputJac,
618 const Kokkos::DynRankView<inputWeightValueType,inputWeightProperties...> inputWeights,
619 const ordinal_type whichFace,
620 const shards::CellTopology parentCell,
621 const Kokkos::DynRankView<scratchValueType, scratchProperties...> scratch ) {
622 #ifdef HAVE_INTREPID2_DEBUG
623 INTREPID2_TEST_FOR_EXCEPTION( inputJac.rank() != 4, std::invalid_argument,
624 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Input Jacobian container must have rank 4.");
625 INTREPID2_TEST_FOR_EXCEPTION( scratch.rank() != 1, std::invalid_argument,
626 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Scratch view imust have rank 1.");
627 INTREPID2_TEST_FOR_EXCEPTION( scratch.size() < inputJac.size(), std::invalid_argument,
628 ">>> ERROR (FunctionSpaceTools::computeFaceMeasure): Scratch storage must be greater than or equal to inputJac's one.");
636 auto vcprop = Kokkos::common_view_alloc_prop(scratch);
638 typedef Kokkos::DynRankView<scratchValueType, DeviceType> viewType;
639 viewType faceNormals(Kokkos::view_wrap(scratch.data(), vcprop),
656 template<
typename DeviceType>
657 template<
typename outputValValueType,
class ...outputValProperties,
658 typename inputJacValueType,
class ...inputJacProperties,
659 typename inputWeightValueType,
class ...inputWeightProperties,
660 typename scratchValueType,
class ...scratchProperties>
664 const Kokkos::DynRankView<inputJacValueType, inputJacProperties...> inputJac,
665 const Kokkos::DynRankView<inputWeightValueType,inputWeightProperties...> inputWeights,
666 const ordinal_type whichEdge,
667 const shards::CellTopology parentCell,
668 const Kokkos::DynRankView<scratchValueType, scratchProperties...> scratch ) {
669 #ifdef HAVE_INTREPID2_DEBUG
670 INTREPID2_TEST_FOR_EXCEPTION( (inputJac.rank() != 4), std::invalid_argument,
671 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Input Jacobian container must have rank 4.");
672 INTREPID2_TEST_FOR_EXCEPTION( scratch.rank() != 1, std::invalid_argument,
673 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Scratch view must have a rank 1.");
674 INTREPID2_TEST_FOR_EXCEPTION( scratch.size() < inputJac.size(), std::invalid_argument,
675 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Scratch storage must be greater than or equal to inputJac'one.");
683 auto vcprop = Kokkos::common_view_alloc_prop(scratch);
685 typedef Kokkos::DynRankView<scratchValueType, DeviceType> viewType;
686 viewType edgeTangents(Kokkos::view_wrap(scratch.data(), vcprop),
703 template<
typename DeviceType>
704 template<
typename outputValValueType,
class ...outputValProperties,
705 typename inputMeasureValueType,
class ...inputMeasureProperties,
706 typename inputValValueType,
class ...inputValProperties>
709 multiplyMeasure( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
710 const Kokkos::DynRankView<inputMeasureValueType,inputMeasureProperties...> inputMeasure,
711 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
712 scalarMultiplyDataField( outputVals,
719 template<
typename DeviceType>
720 template<
typename outputFieldValueType,
class ...outputFieldProperties,
721 typename inputDataValueType,
class ...inputDataProperties,
722 typename inputFieldValueType,
class ...inputFieldProperties>
726 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
727 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
728 const bool reciprocal ) {
737 template<
typename DeviceType>
738 template<
typename outputDataValuetype,
class ...outputDataProperties,
739 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
740 typename inputDataRightValueType,
class ...inputDataRightProperties>
744 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
745 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
746 const bool reciprocal ) {
755 template<
typename DeviceType>
756 template<
typename outputFieldValueType,
class ...outputFieldProperties,
757 typename inputDataValueType,
class ...inputDataProperties,
758 typename inputFieldValueType,
class ...inputFieldProperties>
762 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
763 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
771 template<
typename DeviceType>
772 template<
typename outputDataValueType,
class ...outputDataProperties,
773 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
774 typename inputDataRightValueType,
class ...inputDataRightProperties>
778 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
779 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
787 template<
typename DeviceType>
788 template<
typename outputFieldValueType,
class ...outputFieldProperties,
789 typename inputDataValueType,
class ...inputDataProperties,
790 typename inputFieldValueType,
class ...inputFieldProperties>
794 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
795 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
796 const auto outRank = outputFields.rank();
810 INTREPID2_TEST_FOR_EXCEPTION( outRank < 3 && outRank > 5, std::runtime_error,
811 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataField): Output container must have rank 3, 4 or 5.");
818 template<
typename DeviceType>
819 template<
typename outputDataValueType,
class ...outputDataProperties,
820 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
821 typename inputDataRightValueType,
class ...inputDataRightProperties>
825 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
826 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
827 const auto outRank = outputData.rank();
841 INTREPID2_TEST_FOR_EXCEPTION( outRank < 2 && outRank > 4, std::runtime_error,
842 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataData): Output container must have rank 2, 3 or 4.");
849 template<
typename DeviceType>
850 template<
typename outputFieldValueType,
class ...outputFieldProperties,
851 typename inputDataValueType,
class ...inputDataProperties,
852 typename inputFieldValueType,
class ...inputFieldProperties>
856 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
857 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
858 const char transpose ) {
860 const auto outRank = outputFields.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 template<
typename DeviceType>
884 template<
typename outputDataValueType,
class ...outputDataProperties,
885 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
886 typename inputDataRightValueType,
class ...inputDataRightProperties>
890 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
891 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
892 const char transpose ) {
893 const auto outRank = outputData.rank();
908 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
909 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
916 namespace FunctorFunctionSpaceTools {
921 template<
typename inoutOperatorViewType,
922 typename fieldSignViewType>
924 inoutOperatorViewType _inoutOperator;
925 const fieldSignViewType _fieldSigns;
927 KOKKOS_INLINE_FUNCTION
929 fieldSignViewType fieldSigns_ )
930 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
932 KOKKOS_INLINE_FUNCTION
933 void operator()(
const ordinal_type cl)
const {
934 const ordinal_type nlbf = _inoutOperator.extent(1);
935 const ordinal_type nrbf = _inoutOperator.extent(2);
937 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
938 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
939 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, lbf);
944 template<
typename DeviceType>
945 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
946 typename fieldSignValueType,
class ...fieldSignProperties>
949 applyLeftFieldSigns( Kokkos::DynRankView<inoutOperatorValueType,inoutOperatorProperties...> inoutOperator,
950 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
952 #ifdef HAVE_INTREPID2_DEBUG
953 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
954 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input operator container must have rank 3.");
955 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
956 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input field signs container must have rank 2.");
957 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
958 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
959 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(1) != fieldSigns.extent(1), std::invalid_argument,
960 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): First dimensions (number of left fields) of the operator and field signs containers must agree!");
963 constexpr
bool are_accessible =
964 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
965 typename decltype(inoutOperator)::memory_space>::accessible &&
966 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
967 typename decltype(fieldSigns)::memory_space>::accessible;
968 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyLeftFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
971 <decltype(inoutOperator),decltype(fieldSigns)>;
973 const ordinal_type C = inoutOperator.extent(0);
974 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
975 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
980 namespace FunctorFunctionSpaceTools {
984 template<
typename inoutOperatorViewType,
985 typename fieldSignViewType>
987 inoutOperatorViewType _inoutOperator;
988 const fieldSignViewType _fieldSigns;
990 KOKKOS_INLINE_FUNCTION
992 fieldSignViewType fieldSigns_ )
993 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
995 KOKKOS_INLINE_FUNCTION
996 void operator()(
const ordinal_type cl)
const {
997 const ordinal_type nlbf = _inoutOperator.extent(1);
998 const ordinal_type nrbf = _inoutOperator.extent(2);
1000 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
1001 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
1002 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, rbf);
1007 template<
typename DeviceType>
1008 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
1009 typename fieldSignValueType,
class ...fieldSignProperties>
1013 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
1015 #ifdef HAVE_INTREPID2_DEBUG
1016 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
1017 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input operator container must have rank 3.");
1018 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
1019 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input field signs container must have rank 2.");
1020 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
1021 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
1022 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(2) != fieldSigns.extent(1), std::invalid_argument,
1023 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Second dimension of the operator container and first dimension of the field signs container (number of right fields) must agree!");
1026 constexpr
bool are_accessible =
1027 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1028 typename decltype(inoutOperator)::memory_space>::accessible &&
1029 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1030 typename decltype(fieldSigns)::memory_space>::accessible;
1031 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyRightFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
1034 <decltype(inoutOperator),decltype(fieldSigns)>;
1036 const ordinal_type C = inoutOperator.extent(0);
1037 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1038 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
1043 namespace FunctorFunctionSpaceTools {
1047 template<
typename inoutFunctionViewType,
1048 typename fieldSignViewType>
1050 inoutFunctionViewType _inoutFunction;
1051 const fieldSignViewType _fieldSigns;
1053 KOKKOS_INLINE_FUNCTION
1055 fieldSignViewType fieldSigns_)
1056 : _inoutFunction(inoutFunction_), _fieldSigns(fieldSigns_) {}
1058 KOKKOS_INLINE_FUNCTION
1059 void operator()(
const ordinal_type cl)
const {
1060 const ordinal_type nbfs = _inoutFunction.extent(1);
1061 const ordinal_type npts = _inoutFunction.extent(2);
1062 const ordinal_type iend = _inoutFunction.extent(3);
1063 const ordinal_type jend = _inoutFunction.extent(4);
1065 for (ordinal_type bf=0;bf<nbfs;++bf)
1066 for (ordinal_type pt=0;pt<npts;++pt)
1067 for (ordinal_type i=0;i<iend;++i)
1068 for (ordinal_type j=0;j<jend;++j)
1069 _inoutFunction(cl, bf, pt, i, j) *= _fieldSigns(cl, bf);
1074 template<
typename DeviceType>
1075 template<
typename inoutFunctionValueType,
class ...inoutFunctionProperties,
1076 typename fieldSignValueType,
class ...fieldSignProperties>
1079 applyFieldSigns( Kokkos::DynRankView<inoutFunctionValueType,inoutFunctionProperties...> inoutFunction,
1080 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
1082 #ifdef HAVE_INTREPID2_DEBUG
1083 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.rank() < 2 || inoutFunction.rank() > 5, std::invalid_argument,
1084 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input function container must have rank 2, 3, 4, or 5.");
1085 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
1086 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input field signs container must have rank 2.");
1087 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(0) != fieldSigns.extent(0), std::invalid_argument,
1088 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Zeroth dimensions (number of integration domains) of the function and field signs containers must agree!");
1089 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(1) != fieldSigns.extent(1), std::invalid_argument,
1090 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): First dimensions (number of fields) of the function and field signs containers must agree!");
1094 constexpr
bool are_accessible =
1095 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1096 typename decltype(inoutFunction)::memory_space>::accessible &&
1097 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1098 typename decltype(fieldSigns)::memory_space>::accessible;
1099 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
1102 <decltype(inoutFunction),decltype(fieldSigns)>;
1104 const ordinal_type C = inoutFunction.extent(0);
1105 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1106 Kokkos::parallel_for( policy, FunctorType(inoutFunction, fieldSigns) );
1111 namespace FunctorFunctionSpaceTools {
1116 template<
typename outputPointViewType,
1117 typename inputCoeffViewType,
1118 typename inputFieldViewType>
1120 outputPointViewType _outputPointVals;
1121 const inputCoeffViewType _inputCoeffs;
1122 const inputFieldViewType _inputFields;
1124 KOKKOS_INLINE_FUNCTION
1125 F_evaluate( outputPointViewType outputPointVals_,
1126 inputCoeffViewType inputCoeffs_,
1127 inputFieldViewType inputFields_ )
1128 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1130 KOKKOS_INLINE_FUNCTION
1131 void operator()(
const ordinal_type cl)
const {
1132 const ordinal_type nbfs = _inputFields.extent(1);
1133 const ordinal_type npts = _inputFields.extent(2);
1135 const ordinal_type iend = _inputFields.extent(3);
1136 const ordinal_type jend = _inputFields.extent(4);
1138 for (ordinal_type bf=0;bf<nbfs;++bf)
1139 for (ordinal_type pt=0;pt<npts;++pt)
1140 for (ordinal_type i=0;i<iend;++i)
1141 for (ordinal_type j=0;j<jend;++j)
1142 _outputPointVals(cl, pt, i, j) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt, i, j);
1147 template<
typename DeviceType>
1148 template<
typename outputPointValueType,
class ...outputPointProperties,
1149 typename inputCoeffValueType,
class ...inputCoeffProperties,
1150 typename inputFieldValueType,
class ...inputFieldProperties>
1153 evaluate( Kokkos::DynRankView<outputPointValueType,outputPointProperties...> outputPointVals,
1154 const Kokkos::DynRankView<inputCoeffValueType, inputCoeffProperties...> inputCoeffs,
1155 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
1157 #ifdef HAVE_INTREPID2_DEBUG
1158 INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() < 3 || inputFields.rank() > 5, std::invalid_argument,
1159 ">>> ERROR (FunctionSpaceTools::evaluate): Input fields container must have rank 3, 4, or 5.");
1160 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.rank() != 2, std::invalid_argument,
1161 ">>> ERROR (FunctionSpaceTools::evaluate): Input coefficient container must have rank 2.");
1162 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.rank() != (inputFields.rank()-1), std::invalid_argument,
1163 ">>> ERROR (FunctionSpaceTools::evaluate): Output values container must have rank one less than the rank of the input fields container.");
1164 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(0) != inputFields.extent(0), std::invalid_argument,
1165 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the coefficient and fields input containers must agree!");
1166 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(1) != inputFields.extent(1), std::invalid_argument,
1167 ">>> ERROR (FunctionSpaceTools::evaluate): First dimensions (number of fields) of the coefficient and fields input containers must agree!");
1168 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(0) != inputFields.extent(0), std::invalid_argument,
1169 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the input fields container and the output values container must agree!");
1170 for (size_type i=1;i<outputPointVals.rank();++i)
1171 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(i) != inputFields.extent(i+1), std::invalid_argument,
1172 ">>> ERROR (FunctionSpaceTools::evaluate): outputPointVals dimension(i) does not match to inputFields dimension(i+1).");
1175 constexpr
bool are_accessible =
1176 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1177 typename decltype(outputPointVals)::memory_space>::accessible &&
1178 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1179 typename decltype(inputCoeffs)::memory_space>::accessible &&
1180 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1181 typename decltype(inputFields)::memory_space>::accessible;
1182 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::evaluate(..): input/output views' memory spaces are not compatible with DeviceType");
1185 <decltype(outputPointVals),decltype(inputCoeffs),decltype(inputFields)>;
1187 const ordinal_type C = inputFields.extent(0);
1188 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1189 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...