51 template<
class Scalar,
class ArrayOutFields,
class ArrayInData,
class ArrayInFields>
53 const ArrayInData & inputData,
54 const ArrayInFields & inputFields) {
55 #ifdef HAVE_INTREPID_DEBUG
56 if (getrank(inputFields) > getrank(inputData)) {
57 TEUCHOS_TEST_FOR_EXCEPTION( ((getrank(inputData) < 2) || (getrank(inputData) > 4)), std::invalid_argument,
58 ">>> ERROR (ArrayTools::dotMultiplyDataField): Input data container must have rank 2, 3 or 4.");
59 TEUCHOS_TEST_FOR_EXCEPTION( (getrank(inputFields) != getrank(inputData)+1), std::invalid_argument,
60 ">>> ERROR (ArrayTools::dotMultiplyDataField): Input fields container must have rank one larger than the rank of the input data container.");
61 TEUCHOS_TEST_FOR_EXCEPTION( (getrank(outputFields) != 3), std::invalid_argument,
62 ">>> ERROR (ArrayTools::dotMultiplyDataField): Output fields container must have rank 3.");
63 TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(0) != inputData.dimension(0) ), std::invalid_argument,
64 ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
65 TEUCHOS_TEST_FOR_EXCEPTION( ( (inputFields.dimension(2) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
66 ">>> ERROR (ArrayTools::dotMultiplyDataField): 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!");
67 for (
size_t i=2; i<getrank(inputData); i++) {
68 std::string errmsg =
">>> ERROR (ArrayTools::dotMultiplyDataField): Dimensions ";
69 errmsg += (char)(48+i);
71 errmsg += (char)(48+i+1);
72 errmsg +=
" of the input data and fields containers must agree!";
73 TEUCHOS_TEST_FOR_EXCEPTION( (inputData.dimension(i) != inputFields.dimension(i+1)), std::invalid_argument, errmsg );
75 for (
size_t i=0; i<getrank(outputFields); i++) {
76 std::string errmsg =
">>> ERROR (ArrayTools::dotMultiplyDataField): Dimensions ";
77 errmsg += (char)(48+i);
78 errmsg +=
" of the input and output fields containers must agree!";
79 TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i)), std::invalid_argument, errmsg );
82 TEUCHOS_TEST_FOR_EXCEPTION( ((getrank(inputData) < 2) || (getrank(inputData) > 4)), std::invalid_argument,
83 ">>> ERROR (ArrayTools::dotMultiplyDataField): Input data container must have rank 2, 3 or 4.");
84 TEUCHOS_TEST_FOR_EXCEPTION( (getrank(inputFields) != getrank(inputData)), std::invalid_argument,
85 ">>> ERROR (ArrayTools::dotMultiplyDataField): The rank of fields input container must equal the rank of data input container.");
86 TEUCHOS_TEST_FOR_EXCEPTION( (getrank(outputFields) != 3), std::invalid_argument,
87 ">>> ERROR (ArrayTools::dotMultiplyDataField): Output fields container must have rank 3.");
88 TEUCHOS_TEST_FOR_EXCEPTION( ( (inputFields.dimension(1) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
89 ">>> ERROR (ArrayTools::dotMultiplyDataField): First dimensions of the fields and data input containers (number of integration points) must agree or first data dimension must be 1!");
90 TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(0) != outputFields.dimension(1)), std::invalid_argument,
91 ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimension of the fields input container and first dimension of the fields output container (number of fields) must agree!");
92 TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(1) != outputFields.dimension(2)), std::invalid_argument,
93 ">>> ERROR (ArrayTools::dotMultiplyDataField): First dimension of the fields input container and second dimension of the fields output container (number of integration points) must agree!");
94 TEUCHOS_TEST_FOR_EXCEPTION( (outputFields.dimension(0) != inputData.dimension(0)), std::invalid_argument,
95 ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimensions of the fields output and data input containers (number of integration domains) must agree!");
96 for (
size_t i=2; i<getrank(inputData); i++) {
97 std::string errmsg =
">>> ERROR (ArrayTools::dotMultiplyDataField): Dimensions ";
98 errmsg += (char)(48+i);
99 errmsg +=
" of the input data and fields containers must agree!";
100 TEUCHOS_TEST_FOR_EXCEPTION( (inputData.dimension(i) != inputFields.dimension(i)), std::invalid_argument, errmsg );
106 ArrayWrapper<Scalar,ArrayOutFields, Rank<ArrayOutFields >::value,
false>outputFieldsWrap(outputFields);
107 ArrayWrapper<Scalar,ArrayInData, Rank<ArrayInData >::value,
true>inputDataWrap(inputData);
108 ArrayWrapper<Scalar,ArrayInFields, Rank<ArrayInFields >::value,
true>inputFieldsWrap(inputFields);
112 int invalRank = getrank(inputFields);
113 int dataRank = getrank(inputData);
114 int numCells = outputFields.dimension(0);
115 int numFields = outputFields.dimension(1);
116 int numPoints = outputFields.dimension(2);
117 int numDataPoints = inputData.dimension(1);
121 dim1Tens = inputData.dimension(2);
123 dim2Tens = inputData.dimension(3);
129 if (invalRank == dataRank + 1) {
131 if (numDataPoints != 1) {
135 for(
int cl = 0; cl < numCells; cl++) {
136 for(
int bf = 0; bf < numFields; bf++) {
137 for(
int pt = 0; pt < numPoints; pt++) {
138 outputFieldsWrap(cl, bf, pt) = inputDataWrap(cl, pt)*inputFieldsWrap(cl, bf, pt);
146 for(
int cl = 0; cl < numCells; cl++) {
147 for(
int bf = 0; bf < numFields; bf++) {
148 for(
int pt = 0; pt < numPoints; pt++) {
150 for(
int iVec = 0; iVec < dim1Tens; iVec++) {
151 temp += inputDataWrap(cl, pt, iVec)*inputFieldsWrap(cl, bf, pt, iVec);
153 outputFieldsWrap(cl, bf, pt) = temp;
161 for(
int cl = 0; cl < numCells; cl++) {
162 for(
int bf = 0; bf < numFields; bf++) {
163 for(
int pt = 0; pt < numPoints; pt++) {
165 for(
int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
166 for(
int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
167 temp += inputDataWrap(cl, pt, iTens1, iTens2)*inputFieldsWrap(cl, bf, pt, iTens1, iTens2);
170 outputFieldsWrap(cl, bf, pt) = temp;
178 TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 3) || (invalRank == 4) || (invalRank == 5) ), std::invalid_argument,
179 ">>> ERROR (ArrayTools::dotMultiplyDataField): This branch of the method is defined only for rank-3, 4 or 5 input fields containers.");
187 for(
int cl = 0; cl < numCells; cl++) {
188 for(
int bf = 0; bf < numFields; bf++) {
189 for(
int pt = 0; pt < numPoints; pt++) {
190 outputFieldsWrap(cl, bf, pt) = inputDataWrap(cl, 0)*inputFieldsWrap(cl, bf, pt);
198 for(
int cl = 0; cl < numCells; cl++) {
199 for(
int bf = 0; bf < numFields; bf++) {
200 for(
int pt = 0; pt < numPoints; pt++) {
202 for(
int iVec = 0; iVec < dim1Tens; iVec++) {
203 temp += inputDataWrap(cl, 0, iVec)*inputFieldsWrap(cl, bf, pt, iVec);
205 outputFieldsWrap(cl, bf, pt) = temp;
213 for(
int cl = 0; cl < numCells; cl++) {
214 for(
int bf = 0; bf < numFields; bf++) {
215 for(
int pt = 0; pt < numPoints; pt++) {
217 for(
int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
218 for(
int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
219 temp += inputDataWrap(cl, 0, iTens1, iTens2)*inputFieldsWrap(cl, bf, pt, iTens1, iTens2);
222 outputFieldsWrap(cl, bf, pt) = temp;
230 TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 3) || (invalRank == 4) || (invalRank == 5) ), std::invalid_argument,
231 ">>> ERROR (ArrayTools::dotMultiplyDataField): This branch of the method is defined only for rank-3, 4 or 5 input fields containers.");
239 if (numDataPoints != 1) {
243 for(
int cl = 0; cl < numCells; cl++) {
244 for(
int bf = 0; bf < numFields; bf++) {
245 for(
int pt = 0; pt < numPoints; pt++) {
246 outputFieldsWrap(cl, bf, pt) = inputDataWrap(cl, pt)*inputFieldsWrap(bf, pt);
254 for(
int cl = 0; cl < numCells; cl++) {
255 for(
int bf = 0; bf < numFields; bf++) {
256 for(
int pt = 0; pt < numPoints; pt++) {
258 for(
int iVec = 0; iVec < dim1Tens; iVec++) {
259 temp += inputDataWrap(cl, pt, iVec)*inputFieldsWrap(bf, pt, iVec);
261 outputFieldsWrap(cl, bf, pt) = temp;
269 for(
int cl = 0; cl < numCells; cl++) {
270 for(
int bf = 0; bf < numFields; bf++) {
271 for(
int pt = 0; pt < numPoints; pt++) {
273 for(
int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
274 for(
int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
275 temp += inputDataWrap(cl, pt, iTens1, iTens2)*inputFieldsWrap(bf, pt, iTens1, iTens2);
278 outputFieldsWrap(cl, bf, pt) = temp;
286 TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
287 ">>> ERROR (ArrayTools::dotMultiplyDataField): This branch of the method is defined only for rank-2, 3 or 4 input fields containers.");
295 for(
int cl = 0; cl < numCells; cl++) {
296 for(
int bf = 0; bf < numFields; bf++) {
297 for(
int pt = 0; pt < numPoints; pt++) {
298 outputFieldsWrap(cl, bf, pt) = inputDataWrap(cl, 0)*inputFieldsWrap(bf, pt);
306 for(
int cl = 0; cl < numCells; cl++) {
307 for(
int bf = 0; bf < numFields; bf++) {
308 for(
int pt = 0; pt < numPoints; pt++) {
310 for(
int iVec = 0; iVec < dim1Tens; iVec++) {
311 temp += inputDataWrap(cl, 0, iVec)*inputFieldsWrap(bf, pt, iVec);
313 outputFieldsWrap(cl, bf, pt) = temp;
321 for(
int cl = 0; cl < numCells; cl++) {
322 for(
int bf = 0; bf < numFields; bf++) {
323 for(
int pt = 0; pt < numPoints; pt++) {
325 for(
int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
326 for(
int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
327 temp += inputDataWrap(cl, 0, iTens1, iTens2)*inputFieldsWrap(bf, pt, iTens1, iTens2);
330 outputFieldsWrap(cl, bf, pt) = temp;
338 TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
339 ">>> ERROR (ArrayTools::dotMultiplyDataField): This branch of the method is defined only for rank-2, 3 or 4 input fields containers.");
350 template<
class Scalar,
class ArrayOutData,
class ArrayInDataLeft,
class ArrayInDataRight>
352 const ArrayInDataLeft & inputDataLeft,
353 const ArrayInDataRight & inputDataRight) {
354 #ifdef HAVE_INTREPID_DEBUG
355 if (getrank(inputDataRight) >= getrank(inputDataLeft)) {
356 TEUCHOS_TEST_FOR_EXCEPTION( ((getrank(inputDataLeft) < 2) || (getrank(inputDataLeft) > 4)), std::invalid_argument,
357 ">>> ERROR (ArrayTools::dotMultiplyDataData): Left data input container must have rank 2, 3 or 4.");
358 TEUCHOS_TEST_FOR_EXCEPTION( (getrank(inputDataRight) != getrank(inputDataLeft)), std::invalid_argument,
359 ">>> ERROR (ArrayTools::dotMultiplyDataData): The rank of the right data input container must equal the rank of the left data input container.");
360 TEUCHOS_TEST_FOR_EXCEPTION( (getrank(outputData) != 2), std::invalid_argument,
361 ">>> ERROR (ArrayTools::dotMultiplyDataData): Data output container must have rank 2.");
362 TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(1) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
363 ">>> ERROR (ArrayTools::dotMultiplyDataField): First dimensions of the left and right data input containers (number of integration points) must agree or first left data dimension must be 1!");
364 for (
size_t i=0; i<getrank(inputDataLeft); i++) {
366 std::string errmsg =
">>> ERROR (ArrayTools::dotMultiplyDataData): Dimensions ";
367 errmsg += (char)(48+i);
368 errmsg +=
" of the left and right data input containers must agree!";
369 TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.dimension(i) != inputDataRight.dimension(i)), std::invalid_argument, errmsg );
372 for (
size_t i=0; i<getrank(outputData); i++) {
373 std::string errmsg =
">>> ERROR (ArrayTools::dotMultiplyDataData): Dimensions ";
374 errmsg += (char)(48+i);
375 errmsg +=
" of the output and right input data containers must agree!";
376 TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i)), std::invalid_argument, errmsg );
380 TEUCHOS_TEST_FOR_EXCEPTION( ((getrank(inputDataLeft) < 2) || (getrank(inputDataLeft) > 4)), std::invalid_argument,
381 ">>> ERROR (ArrayTools::dotMultiplyDataData): Left data input container must have rank 2, 3 or 4.");
382 TEUCHOS_TEST_FOR_EXCEPTION( (getrank(inputDataRight) != getrank(inputDataLeft)-1), std::invalid_argument,
383 ">>> ERROR (ArrayTools::dotMultiplyDataData): Right data input container must have rank one less than the rank of left data input container.");
384 TEUCHOS_TEST_FOR_EXCEPTION( (getrank(outputData) != 2), std::invalid_argument,
385 ">>> ERROR (ArrayTools::dotMultiplyDataData): Data output container must have rank 2.");
386 TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(0) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
387 ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimension of the right data input container and first dimension of left data input container (number of integration points) must agree or first left data dimension must be 1!");
388 TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(0) != outputData.dimension(1)), std::invalid_argument,
389 ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimension of the right data input container and first dimension of output data container (number of integration points) must agree!");
390 TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.dimension(0) != outputData.dimension(0)), std::invalid_argument,
391 ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimensions of the left data input and data output containers (number of integration domains) must agree!");
392 for (
size_t i=1; i<getrank(inputDataRight); i++) {
393 std::string errmsg =
">>> ERROR (ArrayTools::dotMultiplyDataData): Dimensions ";
394 errmsg += (char)(48+i+1);
396 errmsg += (char)(48+i);
397 errmsg +=
" of the left and right data input containers must agree!";
398 TEUCHOS_TEST_FOR_EXCEPTION( (inputDataLeft.dimension(i+1) != inputDataRight.dimension(i)), std::invalid_argument, errmsg );
405 ArrayWrapper<Scalar,ArrayOutData, Rank<ArrayOutData >::value,
false>outputDataWrap(outputData);
406 ArrayWrapper<Scalar,ArrayInDataLeft, Rank<ArrayInDataLeft >::value,
true>inputDataLeftWrap(inputDataLeft);
407 ArrayWrapper<Scalar,ArrayInDataRight, Rank<ArrayInDataRight >::value,
true>inputDataRightWrap(inputDataRight);
411 size_t rightDataRank = getrank(inputDataRight);
412 size_t leftDataRank = getrank(inputDataLeft);
413 int numCells = outputData.dimension(0);
414 int numPoints = outputData.dimension(1);
415 int numDataPoints = inputDataLeft.dimension(1);
418 if (leftDataRank > 2) {
419 dim1Tens = inputDataLeft.dimension(2);
420 if (leftDataRank > 3) {
421 dim2Tens = inputDataLeft.dimension(3);
427 if (rightDataRank == leftDataRank) {
429 if (numDataPoints != 1) {
431 switch(rightDataRank) {
433 for(
int cl = 0; cl < numCells; cl++) {
434 for(
int pt = 0; pt < numPoints; pt++) {
435 outputDataWrap(cl, pt) = inputDataLeftWrap(cl, pt)*inputDataRightWrap(cl, pt);
442 for(
int cl = 0; cl < numCells; cl++) {
443 for(
int pt = 0; pt < numPoints; pt++) {
445 for(
int iVec = 0; iVec < dim1Tens; iVec++) {
446 temp += inputDataLeftWrap(cl, pt, iVec)*inputDataRightWrap(cl, pt, iVec);
448 outputDataWrap(cl, pt) = temp;
455 for(
int cl = 0; cl < numCells; cl++) {
456 for(
int pt = 0; pt < numPoints; pt++) {
458 for(
int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
459 for(
int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
460 temp += inputDataLeftWrap(cl, pt, iTens1, iTens2)*inputDataRightWrap(cl, pt, iTens1, iTens2);
463 outputDataWrap(cl, pt) = temp;
470 TEUCHOS_TEST_FOR_EXCEPTION( !( (rightDataRank == 2) || (rightDataRank == 3) || (rightDataRank == 4) ), std::invalid_argument,
471 ">>> ERROR (ArrayTools::dotMultiplyDataData): This branch of the method is defined only for rank-2, 3 or 4 right data input containers.");
477 switch(rightDataRank) {
479 for(
int cl = 0; cl < numCells; cl++) {
480 for(
int pt = 0; pt < numPoints; pt++) {
481 outputDataWrap(cl, pt) = inputDataLeftWrap(cl, 0)*inputDataRightWrap(cl, pt);
488 for(
int cl = 0; cl < numCells; cl++) {
489 for(
int pt = 0; pt < numPoints; pt++) {
491 for(
int iVec = 0; iVec < dim1Tens; iVec++) {
492 temp += inputDataLeftWrap(cl, 0, iVec)*inputDataRightWrap(cl, pt, iVec);
494 outputDataWrap(cl, pt) = temp;
501 for(
int cl = 0; cl < numCells; cl++) {
502 for(
int pt = 0; pt < numPoints; pt++) {
504 for(
int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
505 for(
int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
506 temp += inputDataLeftWrap(cl, 0, iTens1, iTens2)*inputDataRightWrap(cl, pt, iTens1, iTens2);
509 outputDataWrap(cl, pt) = temp;
516 TEUCHOS_TEST_FOR_EXCEPTION( !( (rightDataRank == 2) || (rightDataRank == 3) || (rightDataRank == 4) ), std::invalid_argument,
517 ">>> ERROR (ArrayTools::dotMultiplyDataData): This branch of the method is defined only for rank-2, 3 or 4 right data input containers.");
525 if (numDataPoints != 1) {
527 switch(rightDataRank) {
529 for(
int cl = 0; cl < numCells; cl++) {
530 for(
int pt = 0; pt < numPoints; pt++) {
531 outputDataWrap(cl, pt) = inputDataLeftWrap(cl, pt)*inputDataRightWrap(pt);
538 for(
int cl = 0; cl < numCells; cl++) {
539 for(
int pt = 0; pt < numPoints; pt++) {
541 for(
int iVec = 0; iVec < dim1Tens; iVec++) {
542 temp += inputDataLeftWrap(cl, pt, iVec)*inputDataRightWrap(pt, iVec);
544 outputDataWrap(cl, pt) = temp;
551 for(
int cl = 0; cl < numCells; cl++) {
552 for(
int pt = 0; pt < numPoints; pt++) {
554 for(
int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
555 for(
int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
556 temp += inputDataLeftWrap(cl, pt, iTens1, iTens2)*inputDataRightWrap(pt, iTens1, iTens2);
559 outputDataWrap(cl, pt) = temp;
566 TEUCHOS_TEST_FOR_EXCEPTION( !( (rightDataRank == 1) || (rightDataRank == 2) || (rightDataRank == 3) ), std::invalid_argument,
567 ">>> ERROR (ArrayTools::dotMultiplyDataData): This branch of the method is defined only for rank-1, 2 or 3 right data input containers.");
573 switch(rightDataRank) {
575 for(
int cl = 0; cl < numCells; cl++) {
576 for(
int pt = 0; pt < numPoints; pt++) {
577 outputDataWrap(cl, pt) = inputDataLeftWrap(cl, 0)*inputDataRightWrap(pt);
584 for(
int cl = 0; cl < numCells; cl++) {
585 for(
int pt = 0; pt < numPoints; pt++) {
587 for(
int iVec = 0; iVec < dim1Tens; iVec++) {
588 temp += inputDataLeftWrap(cl, 0, iVec)*inputDataRightWrap(pt, iVec);
590 outputDataWrap(cl, pt) = temp;
597 for(
int cl = 0; cl < numCells; cl++) {
598 for(
int pt = 0; pt < numPoints; pt++) {
600 for(
int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
601 for(
int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
602 temp += inputDataLeftWrap(cl, 0, iTens1, iTens2)*inputDataRightWrap(pt, iTens1, iTens2);
605 outputDataWrap(cl, pt) = temp;
612 TEUCHOS_TEST_FOR_EXCEPTION( !( (rightDataRank == 1) || (rightDataRank == 2) || (rightDataRank == 3) ), std::invalid_argument,
613 ">>> ERROR (ArrayTools::dotMultiplyDataData): This branch of the method is defined only for rank-1, 2 or 3 right data input containers.");