16 #ifndef __INTREPID2_ARRAYTOOLS_DEF_SCALAR_HPP__
17 #define __INTREPID2_ARRAYTOOLS_DEF_SCALAR_HPP__
21 namespace FunctorArrayTools {
25 template<
typename OutputViewType,
26 typename inputLeftViewType,
27 typename inputRightViewType,
31 OutputViewType _output;
32 const inputLeftViewType _inputLeft;
33 const inputRightViewType _inputRight;
35 KOKKOS_INLINE_FUNCTION
37 inputLeftViewType inputLeft_,
38 inputRightViewType inputRight_)
40 _inputLeft(inputLeft_),
41 _inputRight(inputRight_) {}
44 KOKKOS_INLINE_FUNCTION
45 void operator()(
const ordinal_type cl,
46 const ordinal_type pt)
const {
47 const auto val = _inputLeft(cl , pt%_inputLeft.extent(1));
51 auto out = Kokkos::subview(_output, cl, pt, Kokkos::ALL(), Kokkos::ALL());
54 const auto right = Kokkos::subview(_inputRight, cl, pt, Kokkos::ALL(), Kokkos::ALL());
55 if (reciprocal) Kernels::inv_scalar_mult_mat(out, val, right);
56 else Kernels:: scalar_mult_mat(out, val, right);
60 const auto right = Kokkos::subview(_inputRight, pt, Kokkos::ALL(), Kokkos::ALL());
61 if (reciprocal) Kernels::inv_scalar_mult_mat(out, val, right);
62 else Kernels:: scalar_mult_mat(out, val, right);
67 KOKKOS_INLINE_FUNCTION
68 void operator()(
const ordinal_type cl,
69 const ordinal_type bf,
70 const ordinal_type pt)
const {
71 const auto val = _inputLeft(cl , pt%_inputLeft.extent(1));
75 auto out = Kokkos::subview(_output, cl, bf, pt, Kokkos::ALL(), Kokkos::ALL());
78 auto right = Kokkos::subview(_inputRight, cl, bf, pt, Kokkos::ALL(), Kokkos::ALL());
79 if (reciprocal) Kernels::inv_scalar_mult_mat(out, val, right);
80 else Kernels:: scalar_mult_mat(out, val, right);
84 auto right = Kokkos::subview(_inputRight, bf, pt, Kokkos::ALL(), Kokkos::ALL());
85 if (reciprocal) Kernels::inv_scalar_mult_mat(out, val, right);
86 else Kernels:: scalar_mult_mat(out, val, right);
92 template<
typename DeviceType>
93 template<
typename outputFieldValueType,
class ...outputFieldProperties,
94 typename inputDataValueType,
class ...inputDataProperties,
95 typename inputFieldValueType,
class ...inputFieldProperties>
99 const Kokkos::DynRankView<inputDataValueType, inputDataProperties...> inputData,
100 const Kokkos::DynRankView<inputFieldValueType, inputFieldProperties...> inputFields,
101 const bool reciprocal ) {
103 #ifdef HAVE_INTREPID2_DEBUG
105 INTREPID2_TEST_FOR_EXCEPTION( inputData.rank() != 2, std::invalid_argument,
106 ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input data container must have rank 2.");
108 if (outputFields.rank() <= inputFields.rank()) {
109 INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() < 3 || inputFields.rank() > 5, std::invalid_argument,
110 ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input fields container must have rank 3, 4, or 5.");
111 INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != inputFields.rank(), std::invalid_argument,
112 ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input and output fields containers must have the same rank.");
113 INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(0) != inputData.extent(0), std::invalid_argument,
114 ">>> ERROR (ArrayTools::scalarMultiplyDataField): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
115 INTREPID2_TEST_FOR_EXCEPTION( inputData.extent(1) != inputFields.extent(2) &&
116 inputData.extent(1) != 1, std::invalid_argument,
117 ">>> ERROR (ArrayTools::scalarMultiplyDataField): Second dimension of the fields input container and first dimension of data input container (number of integration points) must agree, or first data dimension must be 1!");
118 for (size_type i=0;i<inputFields.rank();++i) {
119 INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(i) != outputFields.extent(i), std::invalid_argument,
120 ">>> ERROR (ArrayTools::scalarMultiplyDataField): inputFields dimension (i) does not match to the dimension (i) of outputFields");
124 INTREPID2_TEST_FOR_EXCEPTION( inputFields.rank() < 2 || inputFields.rank() > 4, std::invalid_argument,
125 ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input fields container must have rank 2, 3, or 4.");
126 INTREPID2_TEST_FOR_EXCEPTION( outputFields.rank() != (inputFields.rank()+1), std::invalid_argument,
127 ">>> ERROR (ArrayTools::scalarMultiplyDataField): The rank of the input fields container must be one less than the rank of the output fields container.");
128 INTREPID2_TEST_FOR_EXCEPTION( inputData.extent(1) != inputFields.extent(1) &&
129 inputData.extent(1) != 1, std::invalid_argument,
130 ">>> ERROR (ArrayTools::scalarMultiplyDataField): First dimensions of fields input container and data input container (number of integration points) must agree or first data dimension must be 1!");
131 INTREPID2_TEST_FOR_EXCEPTION( inputData.extent(0) != outputFields.extent(0), std::invalid_argument,
132 ">>> ERROR (ArrayTools::scalarMultiplyDataField): Zeroth dimensions of fields output container and data input containers (number of integration domains) must agree!");
133 for (size_type i=0;i<inputFields.rank();++i) {
134 INTREPID2_TEST_FOR_EXCEPTION( inputFields.extent(i) != outputFields.extent(i+1), std::invalid_argument,
135 ">>> ERROR (ArrayTools::scalarMultiplyDataField): inputFields dimension (i) does not match to the dimension (i+1) of outputFields");
141 typedef Kokkos::DynRankView<outputFieldValueType,outputFieldProperties...> outputFieldViewType;
142 typedef Kokkos::DynRankView<inputDataValueType,inputDataProperties...> inputDataViewType;
143 typedef Kokkos::DynRankView<inputFieldValueType,inputFieldProperties...> inputFieldViewType;
145 using range_policy_type = Kokkos::MDRangePolicy
146 < ExecSpaceType, Kokkos::Rank<3>, Kokkos::IndexType<ordinal_type> >;
148 const range_policy_type policy( { 0, 0, 0 },
149 { outputFields.extent(0), outputFields.extent(1), outputFields.extent(2) } );
151 const bool equalRank = ( outputFields.rank() == inputFields.rank() );
155 Kokkos::parallel_for( policy, FunctorType(outputFields, inputData, inputFields) );
158 Kokkos::parallel_for( policy, FunctorType(outputFields, inputData, inputFields) );
163 Kokkos::parallel_for( policy, FunctorType(outputFields, inputData, inputFields) );
166 Kokkos::parallel_for( policy, FunctorType(outputFields, inputData, inputFields) );
171 template<
typename DeviceType>
172 template<
typename outputDataValueType,
class ...outputDataProperties,
173 typename inputDataLeftValueType,
class ...inputDataLeftProperties,
174 typename inputDataRightValueType,
class ...inputDataRightProperties>
178 const Kokkos::DynRankView<inputDataLeftValueType, inputDataLeftProperties...> inputDataLeft,
179 const Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRight,
180 const bool reciprocal ) {
182 #ifdef HAVE_INTREPID2_DEBUG
184 INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.rank() != 2, std::invalid_argument,
185 ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
187 if (outputData.rank() <= inputDataRight.rank()) {
188 INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() < 2 || inputDataRight.rank() > 4, std::invalid_argument,
189 ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 2, 3, or 4.");
190 INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != inputDataRight.rank(), std::invalid_argument,
191 ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input and output data containers must have the same rank.");
192 INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.extent(0) != inputDataLeft.extent(0), std::invalid_argument,
193 ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions (number of integration domains) of the left and right data input containers must agree!");
194 INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(1) != inputDataRight.extent(1) &&
195 inputDataLeft.extent(1) != 1, std::invalid_argument,
196 ">>> ERROR (ArrayTools::scalarMultiplyDataData): First dimensions of the left and right data input containers (number of integration points) must agree, or first dimension of the left data input container must be 1!");
197 for (size_type i=0;i<inputDataRight.rank();++i) {
198 INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.extent(i) != outputData.extent(i), std::invalid_argument,
199 ">>> ERROR (ArrayTools::scalarMultiplyDataData): inputDataRight dimension (i) does not match to the dimension (i) of outputData");
202 INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.rank() < 1 || inputDataRight.rank() > 3, std::invalid_argument,
203 ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 1, 2, or 3.");
204 INTREPID2_TEST_FOR_EXCEPTION( outputData.rank() != (inputDataRight.rank()+1), std::invalid_argument,
205 ">>> ERROR (ArrayTools::scalarMultiplyDataData): The rank of the right input data container must be one less than the rank of the output data container.");
206 INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(1) != inputDataRight.extent(0) &&
207 inputDataLeft.extent(1) != 1, std::invalid_argument,
208 ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimension of the right input data container and first dimension of the left data input container (number of integration points) must agree or first dimension of the left data input container must be 1!");
209 INTREPID2_TEST_FOR_EXCEPTION( inputDataLeft.extent(0) != outputData.extent(0), std::invalid_argument,
210 ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions of data output and left data input containers (number of integration domains) must agree!");
211 for (size_type i=0;i<inputDataRight.rank();++i) {
212 INTREPID2_TEST_FOR_EXCEPTION( inputDataRight.extent(i) != outputData.extent(i+1), std::invalid_argument,
213 ">>> ERROR (ArrayTools::scalarMultiplyDataData): inputDataRight dimension (i) does not match to the dimension (i+1) of outputData");
219 typedef Kokkos::DynRankView<outputDataValueType,outputDataProperties...> outputDataViewType;
220 typedef Kokkos::DynRankView<inputDataLeftValueType,inputDataLeftProperties...> inputDataLeftViewType;
221 typedef Kokkos::DynRankView<inputDataRightValueType,inputDataRightProperties...> inputDataRightViewType;
223 using range_policy_type = Kokkos::MDRangePolicy
224 < ExecSpaceType, Kokkos::Rank<2>, Kokkos::IndexType<ordinal_type> >;
226 const range_policy_type policy( { 0, 0 },
227 { outputData.extent(0), outputData.extent(1) } );
229 const bool equalRank = ( outputData.rank() == inputDataRight.rank() );
233 Kokkos::parallel_for( policy, FunctorType(outputData, inputDataLeft, inputDataRight) );
236 Kokkos::parallel_for( policy, FunctorType(outputData, inputDataLeft, inputDataRight) );
241 Kokkos::parallel_for( policy, FunctorType(outputData, inputDataLeft, inputDataRight) );
244 Kokkos::parallel_for( policy, FunctorType(outputData, inputDataLeft, inputDataRight) );