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.");
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>
630 computeEdgeMeasure( Kokkos::DynRankView<outputValValueType, outputValProperties...> outputVals,
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 ) {
687 template<
typename DeviceType>
688 template<
typename outputFieldValueType,
class ...outputFieldProperties,
689 typename inputDataValueType,
class ...inputDataProperties,
690 typename inputFieldValueType,
class ...inputFieldProperties>
694 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
695 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
696 const bool reciprocal ) {
705 template<
typename DeviceType>
706 template<
typename outputDataValuetype,
class ...outputDataProperties,
707 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
708 typename inputDataRightValueType,
class ...inputDataRightProperties>
712 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
713 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
714 const bool reciprocal ) {
723 template<
typename DeviceType>
724 template<
typename outputFieldValueType,
class ...outputFieldProperties,
725 typename inputDataValueType,
class ...inputDataProperties,
726 typename inputFieldValueType,
class ...inputFieldProperties>
729 dotMultiplyDataField( Kokkos::DynRankView<outputFieldValueType,outputFieldProperties...> outputFields,
730 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
731 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
739 template<
typename DeviceType>
740 template<
typename outputDataValueType,
class ...outputDataProperties,
741 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
742 typename inputDataRightValueType,
class ...inputDataRightProperties>
745 dotMultiplyDataData( Kokkos::DynRankView<outputDataValueType, outputDataProperties...> outputData,
746 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
747 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
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 ) {
764 const auto outRank = outputFields.rank();
778 INTREPID2_TEST_FOR_EXCEPTION( outRank < 3 && outRank > 5, std::runtime_error,
779 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataField): Output container must have rank 3, 4 or 5.");
786 template<
typename DeviceType>
787 template<
typename outputDataValueType,
class ...outputDataProperties,
788 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
789 typename inputDataRightValueType,
class ...inputDataRightProperties>
793 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
794 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight ) {
795 const auto outRank = outputData.rank();
809 INTREPID2_TEST_FOR_EXCEPTION( outRank < 2 && outRank > 4, std::runtime_error,
810 ">>> ERROR (FunctionSpaceTools::vectorMultiplyDataData): Output container must have rank 2, 3 or 4.");
817 template<
typename DeviceType>
818 template<
typename outputFieldValueType,
class ...outputFieldProperties,
819 typename inputDataValueType,
class ...inputDataProperties,
820 typename inputFieldValueType,
class ...inputFieldProperties>
824 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
825 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
826 const char transpose ) {
828 const auto outRank = outputFields.rank();
843 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
844 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
851 template<
typename DeviceType>
852 template<
typename outputDataValueType,
class ...outputDataProperties,
853 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
854 typename inputDataRightValueType,
class ...inputDataRightProperties>
858 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
859 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
860 const char transpose ) {
861 const auto outRank = outputData.rank();
876 INTREPID2_TEST_FOR_EXCEPTION( outRank < 4 && outRank > 5, std::runtime_error,
877 ">>> ERROR (FunctionSpaceTools::tensorMultiplyDataField): Output container must have rank 4 or 5.");
884 namespace FunctorFunctionSpaceTools {
889 template<
typename inoutOperatorViewType,
890 typename fieldSignViewType>
892 inoutOperatorViewType _inoutOperator;
893 const fieldSignViewType _fieldSigns;
895 KOKKOS_INLINE_FUNCTION
897 fieldSignViewType fieldSigns_ )
898 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
900 KOKKOS_INLINE_FUNCTION
901 void operator()(
const ordinal_type cl)
const {
902 const ordinal_type nlbf = _inoutOperator.extent(1);
903 const ordinal_type nrbf = _inoutOperator.extent(2);
905 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
906 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
907 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, lbf);
912 template<
typename DeviceType>
913 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
914 typename fieldSignValueType,
class ...fieldSignProperties>
917 applyLeftFieldSigns( Kokkos::DynRankView<inoutOperatorValueType,inoutOperatorProperties...> inoutOperator,
918 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
920#ifdef HAVE_INTREPID2_DEBUG
921 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
922 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input operator container must have rank 3.");
923 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
924 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Input field signs container must have rank 2.");
925 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
926 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
927 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(1) != fieldSigns.extent(1), std::invalid_argument,
928 ">>> ERROR (FunctionSpaceTools::applyLeftFieldSigns): First dimensions (number of left fields) of the operator and field signs containers must agree!");
931 constexpr bool are_accessible =
932 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
933 typename decltype(inoutOperator)::memory_space>::accessible &&
934 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
935 typename decltype(fieldSigns)::memory_space>::accessible;
936 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyLeftFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
939 <
decltype(inoutOperator),
decltype(fieldSigns)>;
941 const ordinal_type C = inoutOperator.extent(0);
942 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
943 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
948 namespace FunctorFunctionSpaceTools {
952 template<
typename inoutOperatorViewType,
953 typename fieldSignViewType>
955 inoutOperatorViewType _inoutOperator;
956 const fieldSignViewType _fieldSigns;
958 KOKKOS_INLINE_FUNCTION
960 fieldSignViewType fieldSigns_ )
961 : _inoutOperator(inoutOperator_), _fieldSigns(fieldSigns_) {}
963 KOKKOS_INLINE_FUNCTION
964 void operator()(
const ordinal_type cl)
const {
965 const ordinal_type nlbf = _inoutOperator.extent(1);
966 const ordinal_type nrbf = _inoutOperator.extent(2);
968 for (ordinal_type lbf=0;lbf<nlbf;++lbf)
969 for (ordinal_type rbf=0;rbf<nrbf;++rbf)
970 _inoutOperator(cl, lbf, rbf) *= _fieldSigns(cl, rbf);
975 template<
typename DeviceType>
976 template<
typename inoutOperatorValueType,
class ...inoutOperatorProperties,
977 typename fieldSignValueType,
class ...fieldSignProperties>
980 applyRightFieldSigns( Kokkos::DynRankView<inoutOperatorValueType,inoutOperatorProperties...> inoutOperator,
981 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
983#ifdef HAVE_INTREPID2_DEBUG
984 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.rank() != 3, std::invalid_argument,
985 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input operator container must have rank 3.");
986 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
987 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Input field signs container must have rank 2.");
988 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(0) != fieldSigns.extent(0), std::invalid_argument,
989 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Zeroth dimensions (number of cells) of the operator and field signs containers must agree!");
990 INTREPID2_TEST_FOR_EXCEPTION( inoutOperator.extent(2) != fieldSigns.extent(1), std::invalid_argument,
991 ">>> ERROR (FunctionSpaceTools::applyRightFieldSigns): Second dimension of the operator container and first dimension of the field signs container (number of right fields) must agree!");
994 constexpr bool are_accessible =
995 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
996 typename decltype(inoutOperator)::memory_space>::accessible &&
997 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
998 typename decltype(fieldSigns)::memory_space>::accessible;
999 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyRightFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
1002 <
decltype(inoutOperator),
decltype(fieldSigns)>;
1004 const ordinal_type C = inoutOperator.extent(0);
1005 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1006 Kokkos::parallel_for( policy, FunctorType(inoutOperator, fieldSigns) );
1011 namespace FunctorFunctionSpaceTools {
1015 template<
typename inoutFunctionViewType,
1016 typename fieldSignViewType>
1018 inoutFunctionViewType _inoutFunction;
1019 const fieldSignViewType _fieldSigns;
1021 KOKKOS_INLINE_FUNCTION
1023 fieldSignViewType fieldSigns_)
1024 : _inoutFunction(inoutFunction_), _fieldSigns(fieldSigns_) {}
1026 KOKKOS_INLINE_FUNCTION
1027 void operator()(
const ordinal_type cl)
const {
1028 const ordinal_type nbfs = _inoutFunction.extent(1);
1029 const ordinal_type npts = _inoutFunction.extent(2);
1030 const ordinal_type iend = _inoutFunction.extent(3);
1031 const ordinal_type jend = _inoutFunction.extent(4);
1033 for (ordinal_type bf=0;bf<nbfs;++bf)
1034 for (ordinal_type pt=0;pt<npts;++pt)
1035 for (ordinal_type i=0;i<iend;++i)
1036 for (ordinal_type j=0;j<jend;++j)
1037 _inoutFunction(cl, bf, pt, i, j) *= _fieldSigns(cl, bf);
1042 template<
typename DeviceType>
1043 template<
typename inoutFunctionValueType,
class ...inoutFunctionProperties,
1044 typename fieldSignValueType,
class ...fieldSignProperties>
1047 applyFieldSigns( Kokkos::DynRankView<inoutFunctionValueType,inoutFunctionProperties...> inoutFunction,
1048 const Kokkos::DynRankView<fieldSignValueType, fieldSignProperties...> fieldSigns ) {
1050#ifdef HAVE_INTREPID2_DEBUG
1051 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.rank() < 2 || inoutFunction.rank() > 5, std::invalid_argument,
1052 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input function container must have rank 2, 3, 4, or 5.");
1053 INTREPID2_TEST_FOR_EXCEPTION( fieldSigns.rank() != 2, std::invalid_argument,
1054 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Input field signs container must have rank 2.");
1055 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(0) != fieldSigns.extent(0), std::invalid_argument,
1056 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): Zeroth dimensions (number of integration domains) of the function and field signs containers must agree!");
1057 INTREPID2_TEST_FOR_EXCEPTION( inoutFunction.extent(1) != fieldSigns.extent(1), std::invalid_argument,
1058 ">>> ERROR (FunctionSpaceTools::applyFieldSigns): First dimensions (number of fields) of the function and field signs containers must agree!");
1062 constexpr bool are_accessible =
1063 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1064 typename decltype(inoutFunction)::memory_space>::accessible &&
1065 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1066 typename decltype(fieldSigns)::memory_space>::accessible;
1067 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::applyFieldSigns(..): input/output views' memory spaces are not compatible with DeviceType");
1070 <
decltype(inoutFunction),
decltype(fieldSigns)>;
1072 const ordinal_type C = inoutFunction.extent(0);
1073 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, C);
1074 Kokkos::parallel_for( policy, FunctorType(inoutFunction, fieldSigns) );
1079 namespace FunctorFunctionSpaceTools {
1084 template<
typename outputPointViewType,
1085 typename inputCoeffViewType,
1086 typename inputFieldViewType>
1088 outputPointViewType _outputPointVals;
1089 const inputCoeffViewType _inputCoeffs;
1090 const inputFieldViewType _inputFields;
1092 KOKKOS_INLINE_FUNCTION
1094 inputCoeffViewType inputCoeffs_,
1095 inputFieldViewType inputFields_ )
1096 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1098 KOKKOS_INLINE_FUNCTION
1099 void operator()(
const ordinal_type cl,
const ordinal_type pt)
const {
1100 const ordinal_type nbfs = _inputFields.extent(1);
1102 for (ordinal_type bf=0;bf<nbfs;++bf)
1103 _outputPointVals(cl, pt) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt);
1107 template<
typename outputPointViewType,
1108 typename inputCoeffViewType,
1109 typename inputFieldViewType>
1111 outputPointViewType _outputPointVals;
1112 const inputCoeffViewType _inputCoeffs;
1113 const inputFieldViewType _inputFields;
1115 KOKKOS_INLINE_FUNCTION
1117 inputCoeffViewType inputCoeffs_,
1118 inputFieldViewType inputFields_ )
1119 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1121 KOKKOS_INLINE_FUNCTION
1122 void operator()(
const ordinal_type cl,
const ordinal_type pt)
const {
1123 const ordinal_type nbfs = _inputFields.extent(1);
1124 const ordinal_type iend = _inputFields.extent(3);
1126 for (ordinal_type bf=0;bf<nbfs;++bf)
1127 for (ordinal_type i=0;i<iend;++i)
1128 _outputPointVals(cl, pt, i) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt, i);
1132 template<
typename outputPointViewType,
1133 typename inputCoeffViewType,
1134 typename inputFieldViewType>
1136 outputPointViewType _outputPointVals;
1137 const inputCoeffViewType _inputCoeffs;
1138 const inputFieldViewType _inputFields;
1140 KOKKOS_INLINE_FUNCTION
1142 inputCoeffViewType inputCoeffs_,
1143 inputFieldViewType inputFields_ )
1144 : _outputPointVals(outputPointVals_), _inputCoeffs(inputCoeffs_), _inputFields(inputFields_) {}
1146 KOKKOS_INLINE_FUNCTION
1147 void operator()(
const ordinal_type cl,
const ordinal_type pt)
const {
1148 const ordinal_type nbfs = _inputFields.extent(1);
1149 const ordinal_type iend = _inputFields.extent(3);
1150 const ordinal_type jend = _inputFields.extent(4);
1152 for (ordinal_type bf=0;bf<nbfs;++bf)
1153 for (ordinal_type i=0;i<iend;++i)
1154 for (ordinal_type j=0;j<jend;++j)
1155 _outputPointVals(cl, pt, i, j) += _inputCoeffs(cl, bf) * _inputFields(cl, bf, pt, i, j);
1160 template<
typename DeviceType>
1161 template<
typename outputPointValueType,
class ...outputPointProperties,
1162 typename inputCoeffValueType,
class ...inputCoeffProperties,
1163 typename inputFieldValueType,
class ...inputFieldProperties>
1166 evaluate( Kokkos::DynRankView<outputPointValueType,outputPointProperties...> outputPointVals,
1167 const Kokkos::DynRankView<inputCoeffValueType, inputCoeffProperties...> inputCoeffs,
1168 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields ) {
1170#ifdef HAVE_INTREPID2_DEBUG
1171 INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() < 3 || inputFields.rank() > 5, std::invalid_argument,
1172 ">>> ERROR (FunctionSpaceTools::evaluate): Input fields container must have rank 3, 4, or 5.");
1173 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.rank() != 2, std::invalid_argument,
1174 ">>> ERROR (FunctionSpaceTools::evaluate): Input coefficient container must have rank 2.");
1175 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.rank() != (inputFields.rank()-1), std::invalid_argument,
1176 ">>> ERROR (FunctionSpaceTools::evaluate): Output values container must have rank one less than the rank of the input fields container.");
1177 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(0) != inputFields.extent(0), std::invalid_argument,
1178 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the coefficient and fields input containers must agree!");
1179 INTREPID2_TEST_FOR_EXCEPTION( inputCoeffs.extent(1) != inputFields.extent(1), std::invalid_argument,
1180 ">>> ERROR (FunctionSpaceTools::evaluate): First dimensions (number of fields) of the coefficient and fields input containers must agree!");
1181 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(0) != inputFields.extent(0), std::invalid_argument,
1182 ">>> ERROR (FunctionSpaceTools::evaluate): Zeroth dimensions (number of cells) of the input fields container and the output values container must agree!");
1183 for (size_type i=1;i<outputPointVals.rank();++i)
1184 INTREPID2_TEST_FOR_EXCEPTION( outputPointVals.extent(i) != inputFields.extent(i+1), std::invalid_argument,
1185 ">>> ERROR (FunctionSpaceTools::evaluate): outputPointVals dimension(i) does not match to inputFields dimension(i+1).");
1188 constexpr bool are_accessible =
1189 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1190 typename decltype(outputPointVals)::memory_space>::accessible &&
1191 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1192 typename decltype(inputCoeffs)::memory_space>::accessible &&
1193 Kokkos::Impl::MemorySpaceAccess<MemSpaceType,
1194 typename decltype(inputFields)::memory_space>::accessible;
1195 static_assert(are_accessible,
"FunctionSpaceTools<DeviceType>::evaluate(..): input/output views' memory spaces are not compatible with DeviceType");
1197 using range_policy_type = Kokkos::MDRangePolicy< ExecSpaceType, Kokkos::Rank<2>, Kokkos::IndexType<ordinal_type> >;
1199 const range_policy_type policy( { 0, 0 },
1200 { inputFields.extent(0), inputFields.extent(2)} );
1202 if (inputFields.rank() == 3) {
1204 Kokkos::parallel_for( policy, FunctorType(outputPointVals, inputCoeffs, inputFields) );
1206 else if (inputFields.rank() == 4) {
1208 Kokkos::parallel_for( policy, FunctorType(outputPointVals, inputCoeffs, inputFields) );
1212 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.