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>
120 HCURLtransformVALUE( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
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>
242 HCURLtransformCURL( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
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>
260 HCURLtransformCURL( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
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>
281 HGRADtransformCURL( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
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>
303 HDIVtransformVALUE( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
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>
365 HVOLtransformVALUE( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
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>
583 computeFaceMeasure( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
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.");
599 auto faceNormals = Impl::createMatchingUnmanagedDynRankView(inputJac, scratch.data(), inputJac.extent(0), inputJac.extent(1), inputJac.extent(2));
613 template<
typename DeviceType>
614 template<
typename outputValValueType,
class ...outputValProperties,
615 typename inputJacValueType,
class ...inputJacProperties,
616 typename inputWeightValueType,
class ...inputWeightProperties,
617 typename scratchValueType,
class ...scratchProperties>
620 computeEdgeMeasure( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
621 const Kokkos::DynRankView<inputJacValueType, inputJacProperties...> inputJac,
622 const Kokkos::DynRankView<inputWeightValueType,inputWeightProperties...> inputWeights,
623 const ordinal_type whichEdge,
624 const shards::CellTopology parentCell,
625 const Kokkos::DynRankView<scratchValueType, scratchProperties...> scratch ) {
626#ifdef HAVE_INTREPID2_DEBUG
627 INTREPID2_TEST_FOR_EXCEPTION( (inputJac.rank() != 4), std::invalid_argument,
628 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Input Jacobian container must have rank 4.");
629 INTREPID2_TEST_FOR_EXCEPTION( scratch.rank() != 1, std::invalid_argument,
630 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Scratch view must have a rank 1.");
631 INTREPID2_TEST_FOR_EXCEPTION( scratch.size() < inputJac.size(), std::invalid_argument,
632 ">>> ERROR (FunctionSpaceTools::computeEdgeMeasure): Scratch storage must be greater than or equal to inputJac'one.");
636 auto edgeTangents = Impl::createMatchingUnmanagedDynRankView(inputJac, scratch.data(), inputJac.extent(0), inputJac.extent(1), inputJac.extent(2));
650 template<
typename DeviceType>
651 template<
typename outputValValueType,
class ...outputValProperties,
652 typename inputMeasureValueType,
class ...inputMeasureProperties,
653 typename inputValValueType,
class ...inputValProperties>
656 multiplyMeasure( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
657 const Kokkos::DynRankView<inputMeasureValueType,inputMeasureProperties...> inputMeasure,
658 const Kokkos::DynRankView<inputValValueType, inputValProperties...> inputVals ) {
667 template<
typename DeviceType>
668 template<
typename outputFieldValueType,
class ...outputFieldProperties,
669 typename inputDataValueType,
class ...inputDataProperties,
670 typename inputFieldValueType,
class ...inputFieldProperties>
674 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
675 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
676 const bool reciprocal ) {
685 template<
typename DeviceType>
686 template<
typename outputDataValuetype,
class ...outputDataProperties,
687 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
688 typename inputDataRightValueType,
class ...inputDataRightProperties>
692 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
693 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
694 const bool reciprocal ) {
703 template<
typename DeviceType>
704 template<
typename outputFieldValueType,
class ...outputFieldProperties,
705 typename inputDataValueType,
class ...inputDataProperties,
706 typename inputFieldValueType,
class ...inputFieldProperties>
709 dotMultiplyDataField( Kokkos::DynRankView<outputFieldValueType,outputFieldProperties...> outputFields,
710 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
711 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
719 template<
typename DeviceType>
720 template<
typename outputDataValueType,
class ...outputDataProperties,
721 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
722 typename inputDataRightValueType,
class ...inputDataRightProperties>
725 dotMultiplyDataData( Kokkos::DynRankView<outputDataValueType, outputDataProperties...> outputData,
726 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
727 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
735 template<
typename DeviceType>
736 template<
typename outputFieldValueType,
class ...outputFieldProperties,
737 typename inputDataValueType,
class ...inputDataProperties,
738 typename inputFieldValueType,
class ...inputFieldProperties>
742 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
743 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
744 const auto outRank = outputFields.rank();
758 INTREPID2_TEST_FOR_EXCEPTION( outRank < 3 && outRank > 5, std::runtime_error,
759 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataField): Output container must have rank 3, 4 or 5.");
766 template<
typename DeviceType>
767 template<
typename outputDataValueType,
class ...outputDataProperties,
768 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
769 typename inputDataRightValueType,
class ...inputDataRightProperties>
773 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
774 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
775 const auto outRank = outputData.rank();
789 INTREPID2_TEST_FOR_EXCEPTION( outRank < 2 && outRank > 4, std::runtime_error,
790 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataData): Output container must have rank 2, 3 or 4.");
797 template<
typename DeviceType>
798 template<
typename outputFieldValueType,
class ...outputFieldProperties,
799 typename inputDataValueType,
class ...inputDataProperties,
800 typename inputFieldValueType,
class ...inputFieldProperties>
804 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
805 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
806 const char transpose ) {
808 const auto outRank = outputFields.rank();
823 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
824 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
831 template<
typename DeviceType>
832 template<
typename outputDataValueType,
class ...outputDataProperties,
833 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
834 typename inputDataRightValueType,
class ...inputDataRightProperties>
838 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
839 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
840 const char transpose ) {
841 const auto outRank = outputData.rank();
856 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
857 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
864 namespace FunctorFunctionSpaceTools {
869 template<
typename inoutOperatorViewType,
870 typename fieldSignViewType>
872 inoutOperatorViewType _inoutOperator;
873 const fieldSignViewType _fieldSigns;
875 KOKKOS_INLINE_FUNCTION
877 fieldSignViewType fieldSigns_ )
878 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
880 KOKKOS_INLINE_FUNCTION
881 void operator()(
const ordinal_type cl)
const {
882 const ordinal_type nlbf = _inoutOperator.extent(1);
883 const ordinal_type nrbf = _inoutOperator.extent(2);
885 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
886 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
887 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, lbf);
892 template<
typename DeviceType>
893 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
894 typename fieldSignValueType,
class ...fieldSignProperties>
897 applyLeftFieldSigns( Kokkos::DynRankView<inoutOperatorValueType,inoutOperatorProperties...> inoutOperator,
898 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
900#ifdef HAVE_INTREPID2_DEBUG
901 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
902 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input operator container must have rank 3.");
903 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
904 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input field signs container must have rank 2.");
905 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
906 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
907 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(1) != fieldSigns.extent(1), std::invalid_argument,
908 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): First dimensions (number of left fields) of the operator and field signs containers must agree!");
911 constexpr bool are_accessible =
912 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
913 typename decltype(inoutOperator)::memory_space>::accessible &&
914 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
915 typename decltype(fieldSigns)::memory_space>::accessible;
916 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyLeftFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
919 <
decltype(inoutOperator),
decltype(fieldSigns)>;
921 const ordinal_type C = inoutOperator.extent(0);
922 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
923 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
928 namespace FunctorFunctionSpaceTools {
932 template<
typename inoutOperatorViewType,
933 typename fieldSignViewType>
935 inoutOperatorViewType _inoutOperator;
936 const fieldSignViewType _fieldSigns;
938 KOKKOS_INLINE_FUNCTION
940 fieldSignViewType fieldSigns_ )
941 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
943 KOKKOS_INLINE_FUNCTION
944 void operator()(
const ordinal_type cl)
const {
945 const ordinal_type nlbf = _inoutOperator.extent(1);
946 const ordinal_type nrbf = _inoutOperator.extent(2);
948 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
949 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
950 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, rbf);
955 template<
typename DeviceType>
956 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
957 typename fieldSignValueType,
class ...fieldSignProperties>
960 applyRightFieldSigns( Kokkos::DynRankView<inoutOperatorValueType,inoutOperatorProperties...> inoutOperator,
961 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
963#ifdef HAVE_INTREPID2_DEBUG
964 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
965 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input operator container must have rank 3.");
966 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
967 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input field signs container must have rank 2.");
968 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
969 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
970 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(2) != fieldSigns.extent(1), std::invalid_argument,
971 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Second dimension of the operator container and first dimension of the field signs container (number of right fields) must agree!");
974 constexpr bool are_accessible =
975 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
976 typename decltype(inoutOperator)::memory_space>::accessible &&
977 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
978 typename decltype(fieldSigns)::memory_space>::accessible;
979 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyRightFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
982 <
decltype(inoutOperator),
decltype(fieldSigns)>;
984 const ordinal_type C = inoutOperator.extent(0);
985 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
986 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
991 namespace FunctorFunctionSpaceTools {
995 template<
typename inoutFunctionViewType,
996 typename fieldSignViewType>
998 inoutFunctionViewType _inoutFunction;
999 const fieldSignViewType _fieldSigns;
1001 KOKKOS_INLINE_FUNCTION
1003 fieldSignViewType fieldSigns_)
1004 : _inoutFunction(inoutFunction_), _fieldSigns(fieldSigns_) {}
1006 KOKKOS_INLINE_FUNCTION
1007 void operator()(
const ordinal_type cl)
const {
1008 const ordinal_type nbfs = _inoutFunction.extent(1);
1009 const ordinal_type npts = _inoutFunction.extent(2);
1010 const ordinal_type iend = _inoutFunction.extent(3);
1011 const ordinal_type jend = _inoutFunction.extent(4);
1013 for (ordinal_type bf=0;bf<nbfs;++bf)
1014 for (ordinal_type pt=0;pt<npts;++pt)
1015 for (ordinal_type i=0;i<iend;++i)
1016 for (ordinal_type j=0;j<jend;++j)
1017 _inoutFunction(cl, bf, pt, i, j) *= _fieldSigns(cl, bf);
1022 template<
typename DeviceType>
1023 template<
typename inoutFunctionValueType,
class ...inoutFunctionProperties,
1024 typename fieldSignValueType,
class ...fieldSignProperties>
1027 applyFieldSigns( Kokkos::DynRankView<inoutFunctionValueType,inoutFunctionProperties...> inoutFunction,
1028 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
1030#ifdef HAVE_INTREPID2_DEBUG
1031 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.rank() < 2 || inoutFunction.rank() > 5, std::invalid_argument,
1032 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input function container must have rank 2, 3, 4, or 5.");
1033 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
1034 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input field signs container must have rank 2.");
1035 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(0) != fieldSigns.extent(0), std::invalid_argument,
1036 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Zeroth dimensions (number of integration domains) of the function and field signs containers must agree!");
1037 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(1) != fieldSigns.extent(1), std::invalid_argument,
1038 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): First dimensions (number of fields) of the function and field signs containers must agree!");
1042 constexpr bool are_accessible =
1043 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1044 typename decltype(inoutFunction)::memory_space>::accessible &&
1045 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1046 typename decltype(fieldSigns)::memory_space>::accessible;
1047 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
1050 <
decltype(inoutFunction),
decltype(fieldSigns)>;
1052 const ordinal_type C = inoutFunction.extent(0);
1053 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1054 Kokkos::parallel_for( policy, FunctorType(inoutFunction, fieldSigns) );
1059 namespace FunctorFunctionSpaceTools {
1064 template<
typename outputPointViewType,
1065 typename inputCoeffViewType,
1066 typename inputFieldViewType>
1068 outputPointViewType _outputPointVals;
1069 const inputCoeffViewType _inputCoeffs;
1070 const inputFieldViewType _inputFields;
1072 KOKKOS_INLINE_FUNCTION
1074 inputCoeffViewType inputCoeffs_,
1075 inputFieldViewType inputFields_ )
1076 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1078 KOKKOS_INLINE_FUNCTION
1079 void operator()(
const ordinal_type cl,
const ordinal_type pt)
const {
1080 const ordinal_type nbfs = _inputFields.extent(1);
1082 for (ordinal_type bf=0;bf<nbfs;++bf)
1083 _outputPointVals(cl, pt) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt);
1087 template<
typename outputPointViewType,
1088 typename inputCoeffViewType,
1089 typename inputFieldViewType>
1091 outputPointViewType _outputPointVals;
1092 const inputCoeffViewType _inputCoeffs;
1093 const inputFieldViewType _inputFields;
1095 KOKKOS_INLINE_FUNCTION
1097 inputCoeffViewType inputCoeffs_,
1098 inputFieldViewType inputFields_ )
1099 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1101 KOKKOS_INLINE_FUNCTION
1102 void operator()(
const ordinal_type cl,
const ordinal_type pt)
const {
1103 const ordinal_type nbfs = _inputFields.extent(1);
1104 const ordinal_type iend = _inputFields.extent(3);
1106 for (ordinal_type bf=0;bf<nbfs;++bf)
1107 for (ordinal_type i=0;i<iend;++i)
1108 _outputPointVals(cl, pt, i) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt, i);
1112 template<
typename outputPointViewType,
1113 typename inputCoeffViewType,
1114 typename inputFieldViewType>
1116 outputPointViewType _outputPointVals;
1117 const inputCoeffViewType _inputCoeffs;
1118 const inputFieldViewType _inputFields;
1120 KOKKOS_INLINE_FUNCTION
1122 inputCoeffViewType inputCoeffs_,
1123 inputFieldViewType inputFields_ )
1124 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1126 KOKKOS_INLINE_FUNCTION
1127 void operator()(
const ordinal_type cl,
const ordinal_type pt)
const {
1128 const ordinal_type nbfs = _inputFields.extent(1);
1129 const ordinal_type iend = _inputFields.extent(3);
1130 const ordinal_type jend = _inputFields.extent(4);
1132 for (ordinal_type bf=0;bf<nbfs;++bf)
1133 for (ordinal_type i=0;i<iend;++i)
1134 for (ordinal_type j=0;j<jend;++j)
1135 _outputPointVals(cl, pt, i, j) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt, i, j);
1140 template<
typename DeviceType>
1141 template<
typename outputPointValueType,
class ...outputPointProperties,
1142 typename inputCoeffValueType,
class ...inputCoeffProperties,
1143 typename inputFieldValueType,
class ...inputFieldProperties>
1146 evaluate( Kokkos::DynRankView<outputPointValueType,outputPointProperties...> outputPointVals,
1147 const Kokkos::DynRankView<inputCoeffValueType, inputCoeffProperties...> inputCoeffs,
1148 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
1150#ifdef HAVE_INTREPID2_DEBUG
1151 INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() < 3 || inputFields.rank() > 5, std::invalid_argument,
1152 ">>> ERROR (FunctionSpaceTools::evaluate): Input fields container must have rank 3, 4, or 5.");
1153 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.rank() != 2, std::invalid_argument,
1154 ">>> ERROR (FunctionSpaceTools::evaluate): Input coefficient container must have rank 2.");
1155 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.rank() != (inputFields.rank()-1), std::invalid_argument,
1156 ">>> ERROR (FunctionSpaceTools::evaluate): Output values container must have rank one less than the rank of the input fields container.");
1157 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(0) != inputFields.extent(0), std::invalid_argument,
1158 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the coefficient and fields input containers must agree!");
1159 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(1) != inputFields.extent(1), std::invalid_argument,
1160 ">>> ERROR (FunctionSpaceTools::evaluate): First dimensions (number of fields) of the coefficient and fields input containers must agree!");
1161 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(0) != inputFields.extent(0), std::invalid_argument,
1162 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the input fields container and the output values container must agree!");
1163 for (size_type i=1;i<outputPointVals.rank();++i)
1164 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(i) != inputFields.extent(i+1), std::invalid_argument,
1165 ">>> ERROR (FunctionSpaceTools::evaluate): outputPointVals dimension(i) does not match to inputFields dimension(i+1).");
1168 constexpr bool are_accessible =
1169 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1170 typename decltype(outputPointVals)::memory_space>::accessible &&
1171 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1172 typename decltype(inputCoeffs)::memory_space>::accessible &&
1173 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1174 typename decltype(inputFields)::memory_space>::accessible;
1175 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::evaluate(..): input/output views' memory spaces are not compatible with DeviceType");
1177 using range_policy_type = Kokkos::MDRangePolicy< ExecSpaceType, Kokkos::Rank<2>, Kokkos::IndexType<ordinal_type> >;
1179 const range_policy_type policy( { 0, 0 },
1180 { inputFields.extent(0), inputFields.extent(2)} );
1182 if (inputFields.rank() == 3) {
1184 Kokkos::parallel_for( policy, FunctorType(outputPointVals, inputCoeffs, inputFields) );
1186 else if (inputFields.rank() == 4) {
1188 Kokkos::parallel_for( policy, FunctorType(outputPointVals, inputCoeffs, inputFields) );
1192 Kokkos::parallel_for( policy, FunctorType(outputPointVals, inputCoeffs, inputFields) );
Defines the Intrepid2::FunctorIterator class, as well as the Intrepid2::functor_returns_ref SFINAE he...
Defines TensorArgumentIterator, which allows systematic enumeration of a TensorData object.