00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035 namespace Intrepid {
00036
00037 template<class Scalar, class ArrayOutFields, class ArrayInFieldsLeft, class ArrayInFieldsRight>
00038 void ArrayTools::contractFieldFieldScalar(ArrayOutFields & outputFields,
00039 const ArrayInFieldsLeft & leftFields,
00040 const ArrayInFieldsRight & rightFields,
00041 const ECompEngine compEngine,
00042 const bool sumInto) {
00043
00044
00045 #ifdef HAVE_INTREPID_DEBUG
00046 TEST_FOR_EXCEPTION( (leftFields.rank() != 3 ), std::invalid_argument,
00047 ">>> ERROR (ArrayTools::contractFieldFieldScalar): Rank of the left input argument must equal 3!");
00048 TEST_FOR_EXCEPTION( (rightFields.rank() != 3 ), std::invalid_argument,
00049 ">>> ERROR (ArrayTools::contractFieldFieldScalar): Rank of right input argument must equal 3!");
00050 TEST_FOR_EXCEPTION( (outputFields.rank() != 3 ), std::invalid_argument,
00051 ">>> ERROR (ArrayTools::contractFieldFieldScalar): Rank of output argument must equal 3!");
00052 TEST_FOR_EXCEPTION( (leftFields.dimension(0) != rightFields.dimension(0) ), std::invalid_argument,
00053 ">>> ERROR (ArrayTools::contractFieldFieldScalar): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
00054 TEST_FOR_EXCEPTION( (leftFields.dimension(2) != rightFields.dimension(2) ), std::invalid_argument,
00055 ">>> ERROR (ArrayTools::contractFieldFieldScalar): Second dimensions (numbers of integration points) of the left and right input containers must agree!");
00056 TEST_FOR_EXCEPTION( (outputFields.dimension(0) != rightFields.dimension(0) ), std::invalid_argument,
00057 ">>> ERROR (ArrayTools::contractFieldFieldScalar): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
00058 TEST_FOR_EXCEPTION( (outputFields.dimension(1) != leftFields.dimension(1) ), std::invalid_argument,
00059 ">>> ERROR (ArrayTools::contractFieldFieldScalar): First dimension of output container and first dimension of left input container must agree!");
00060 TEST_FOR_EXCEPTION( (outputFields.dimension(2) != rightFields.dimension(1) ), std::invalid_argument,
00061 ">>> ERROR (ArrayTools::contractFieldFieldScalar): Second dimension of output container and first dimension of right input container must agree!");
00062 #endif
00063
00064
00065 int numCells = leftFields.dimension(0);
00066 int numLeftFields = leftFields.dimension(1);
00067 int numRightFields = rightFields.dimension(1);
00068 int numPoints = leftFields.dimension(2);
00069
00070 switch(compEngine) {
00071 case COMP_CPP: {
00072 if (sumInto) {
00073 for (int cl = 0; cl < numCells; cl++) {
00074 for (int lbf = 0; lbf < numLeftFields; lbf++) {
00075 for (int rbf = 0; rbf < numRightFields; rbf++) {
00076 Scalar tmpVal(0);
00077 for (int qp = 0; qp < numPoints; qp++) {
00078 tmpVal += leftFields(cl, lbf, qp)*rightFields(cl, rbf, qp);
00079 }
00080 outputFields(cl, lbf, rbf) += tmpVal;
00081 }
00082 }
00083 }
00084 }
00085 else {
00086 for (int cl = 0; cl < numCells; cl++) {
00087 for (int lbf = 0; lbf < numLeftFields; lbf++) {
00088 for (int rbf = 0; rbf < numRightFields; rbf++) {
00089 Scalar tmpVal(0);
00090 for (int qp = 0; qp < numPoints; qp++) {
00091 tmpVal += leftFields(cl, lbf, qp)*rightFields(cl, rbf, qp);
00092 }
00093 outputFields(cl, lbf, rbf) = tmpVal;
00094 }
00095 }
00096 }
00097 }
00098 }
00099 break;
00100
00101 case COMP_BLAS: {
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 int skipL = numLeftFields*numPoints;
00123 int skipR = numRightFields*numPoints;
00124 int skipOp = numLeftFields*numRightFields;
00125 Scalar alpha(1.0);
00126 Scalar beta(0.0);
00127 if (sumInto) {
00128 beta = 1.0;
00129 }
00130
00131 for (int cl=0; cl < numCells; cl++) {
00132
00133 Teuchos::BLAS<int, Scalar> myblas;
00134 myblas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
00135 numRightFields, numLeftFields, numPoints,
00136 alpha, &rightFields[cl*skipR], numPoints,
00137 &leftFields[cl*skipL], numPoints,
00138 beta, &outputFields[cl*skipOp], numRightFields);
00139
00140
00141
00142
00143
00144
00145
00146
00147 }
00148 }
00149 break;
00150
00151 default:
00152 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
00153 ">>> ERROR (ArrayTools::contractFieldFieldScalar): Computational engine not defined!");
00154 }
00155 }
00156
00157
00158 template<class Scalar, class ArrayOutFields, class ArrayInFieldsLeft, class ArrayInFieldsRight>
00159 void ArrayTools::contractFieldFieldVector(ArrayOutFields & outputFields,
00160 const ArrayInFieldsLeft & leftFields,
00161 const ArrayInFieldsRight & rightFields,
00162 const ECompEngine compEngine,
00163 const bool sumInto) {
00164
00165 #ifdef HAVE_INTREPID_DEBUG
00166 TEST_FOR_EXCEPTION( (leftFields.rank() != 4 ), std::invalid_argument,
00167 ">>> ERROR (ArrayTools::contractFieldFieldVector): Rank of the left input argument must equal 4!");
00168 TEST_FOR_EXCEPTION( (rightFields.rank() != 4 ), std::invalid_argument,
00169 ">>> ERROR (ArrayTools::contractFieldFieldVector): Rank of right input argument must equal 4!");
00170 TEST_FOR_EXCEPTION( (outputFields.rank() != 3 ), std::invalid_argument,
00171 ">>> ERROR (ArrayTools::contractFieldFieldVector): Rank of output argument must equal 3!");
00172 TEST_FOR_EXCEPTION( (leftFields.dimension(0) != rightFields.dimension(0) ), std::invalid_argument,
00173 ">>> ERROR (ArrayTools::contractFieldFieldVector): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
00174 TEST_FOR_EXCEPTION( (leftFields.dimension(2) != rightFields.dimension(2) ), std::invalid_argument,
00175 ">>> ERROR (ArrayTools::contractFieldFieldVector): Second dimensions (numbers of integration points) of the left and right input containers must agree!");
00176 TEST_FOR_EXCEPTION( (leftFields.dimension(3) != rightFields.dimension(3) ), std::invalid_argument,
00177 ">>> ERROR (ArrayTools::contractFieldFieldVector): Third dimensions (numbers of vector components) of the left and right input containers must agree!");
00178 TEST_FOR_EXCEPTION( (outputFields.dimension(0) != rightFields.dimension(0) ), std::invalid_argument,
00179 ">>> ERROR (ArrayTools::contractFieldFieldVector): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
00180 TEST_FOR_EXCEPTION( (outputFields.dimension(1) != leftFields.dimension(1) ), std::invalid_argument,
00181 ">>> ERROR (ArrayTools::contractFieldFieldVector): First dimension of output container and first dimension of left input container must agree!");
00182 TEST_FOR_EXCEPTION( (outputFields.dimension(2) != rightFields.dimension(1) ), std::invalid_argument,
00183 ">>> ERROR (ArrayTools::contractFieldFieldVector): Second dimension of output container and first dimension of right input container must agree!");
00184 #endif
00185
00186
00187 int numCells = leftFields.dimension(0);
00188 int numLeftFields = leftFields.dimension(1);
00189 int numRightFields = rightFields.dimension(1);
00190 int numPoints = leftFields.dimension(2);
00191 int dimVec = leftFields.dimension(3);
00192
00193 switch(compEngine) {
00194 case COMP_CPP: {
00195 if (sumInto) {
00196 for (int cl = 0; cl < numCells; cl++) {
00197 for (int lbf = 0; lbf < numLeftFields; lbf++) {
00198 for (int rbf = 0; rbf < numRightFields; rbf++) {
00199 Scalar tmpVal(0);
00200 for (int qp = 0; qp < numPoints; qp++) {
00201 for (int iVec = 0; iVec < dimVec; iVec++) {
00202 tmpVal += leftFields(cl, lbf, qp, iVec)*rightFields(cl, rbf, qp, iVec);
00203 }
00204 }
00205 outputFields(cl, lbf, rbf) += tmpVal;
00206 }
00207 }
00208 }
00209 }
00210 else {
00211 for (int cl = 0; cl < numCells; cl++) {
00212 for (int lbf = 0; lbf < numLeftFields; lbf++) {
00213 for (int rbf = 0; rbf < numRightFields; rbf++) {
00214 Scalar tmpVal(0);
00215 for (int qp = 0; qp < numPoints; qp++) {
00216 for (int iVec = 0; iVec < dimVec; iVec++) {
00217 tmpVal += leftFields(cl, lbf, qp, iVec)*rightFields(cl, rbf, qp, iVec);
00218 }
00219 }
00220 outputFields(cl, lbf, rbf) = tmpVal;
00221 }
00222 }
00223 }
00224 }
00225 }
00226 break;
00227
00228 case COMP_BLAS: {
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249 int numData = numPoints*dimVec;
00250 int skipL = numLeftFields*numData;
00251 int skipR = numRightFields*numData;
00252 int skipOp = numLeftFields*numRightFields;
00253 Scalar alpha(1.0);
00254 Scalar beta(0.0);
00255 if (sumInto) {
00256 beta = 1.0;
00257 }
00258
00259 for (int cl=0; cl < numCells; cl++) {
00260
00261 Teuchos::BLAS<int, Scalar> myblas;
00262 myblas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
00263 numRightFields, numLeftFields, numData,
00264 alpha, &rightFields[cl*skipR], numData,
00265 &leftFields[cl*skipL], numData,
00266 beta, &outputFields[cl*skipOp], numRightFields);
00267
00268
00269
00270
00271
00272
00273
00274
00275 }
00276 }
00277 break;
00278
00279 default:
00280 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
00281 ">>> ERROR (ArrayTools::contractFieldFieldVector): Computational engine not defined!");
00282 }
00283 }
00284
00285
00286 template<class Scalar, class ArrayOutFields, class ArrayInFieldsLeft, class ArrayInFieldsRight>
00287 void ArrayTools::contractFieldFieldTensor(ArrayOutFields & outputFields,
00288 const ArrayInFieldsLeft & leftFields,
00289 const ArrayInFieldsRight & rightFields,
00290 const ECompEngine compEngine,
00291 const bool sumInto) {
00292
00293 #ifdef HAVE_INTREPID_DEBUG
00294 TEST_FOR_EXCEPTION( (leftFields.rank() != 5 ), std::invalid_argument,
00295 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Rank of the left input argument must equal 5!");
00296 TEST_FOR_EXCEPTION( (rightFields.rank() != 5 ), std::invalid_argument,
00297 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Rank of right input argument must equal 5!");
00298 TEST_FOR_EXCEPTION( (outputFields.rank() != 3 ), std::invalid_argument,
00299 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Rank of output argument must equal 3!");
00300 TEST_FOR_EXCEPTION( (leftFields.dimension(0) != rightFields.dimension(0) ), std::invalid_argument,
00301 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
00302 TEST_FOR_EXCEPTION( (leftFields.dimension(2) != rightFields.dimension(2) ), std::invalid_argument,
00303 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Second dimensions (numbers of integration points) of the left and right input containers must agree!");
00304 TEST_FOR_EXCEPTION( (leftFields.dimension(3) != rightFields.dimension(3) ), std::invalid_argument,
00305 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Third dimensions (first tensor dimensions) of the left and right input containers must agree!");
00306 TEST_FOR_EXCEPTION( (leftFields.dimension(4) != rightFields.dimension(4) ), std::invalid_argument,
00307 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Fourth dimensions (second tensor dimensions) of the left and right input containers must agree!");
00308 TEST_FOR_EXCEPTION( (outputFields.dimension(0) != rightFields.dimension(0) ), std::invalid_argument,
00309 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
00310 TEST_FOR_EXCEPTION( (outputFields.dimension(1) != leftFields.dimension(1) ), std::invalid_argument,
00311 ">>> ERROR (ArrayTools::contractFieldFieldTensor): First dimension of output container and first dimension of left input container must agree!");
00312 TEST_FOR_EXCEPTION( (outputFields.dimension(2) != rightFields.dimension(1) ), std::invalid_argument,
00313 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Second dimension of output container and first dimension of right input container must agree!");
00314 #endif
00315
00316
00317 int numCells = leftFields.dimension(0);
00318 int numLeftFields = leftFields.dimension(1);
00319 int numRightFields = rightFields.dimension(1);
00320 int numPoints = leftFields.dimension(2);
00321 int dim1Tensor = leftFields.dimension(3);
00322 int dim2Tensor = leftFields.dimension(4);
00323
00324 switch(compEngine) {
00325 case COMP_CPP: {
00326 if (sumInto) {
00327 for (int cl = 0; cl < numCells; cl++) {
00328 for (int lbf = 0; lbf < numLeftFields; lbf++) {
00329 for (int rbf = 0; rbf < numRightFields; rbf++) {
00330 Scalar tmpVal(0);
00331 for (int qp = 0; qp < numPoints; qp++) {
00332 for (int iTens1 = 0; iTens1 < dim1Tensor; iTens1++) {
00333 for (int iTens2 = 0; iTens2 < dim2Tensor; iTens2++) {
00334 tmpVal += leftFields(cl, lbf, qp, iTens1, iTens2)*rightFields(cl, rbf, qp, iTens1, iTens2);
00335 }
00336 }
00337 }
00338 outputFields(cl, lbf, rbf) += tmpVal;
00339 }
00340 }
00341 }
00342 }
00343 else {
00344 for (int cl = 0; cl < numCells; cl++) {
00345 for (int lbf = 0; lbf < numLeftFields; lbf++) {
00346 for (int rbf = 0; rbf < numRightFields; rbf++) {
00347 Scalar tmpVal(0);
00348 for (int qp = 0; qp < numPoints; qp++) {
00349 for (int iTens1 = 0; iTens1 < dim1Tensor; iTens1++) {
00350 for (int iTens2 = 0; iTens2 < dim2Tensor; iTens2++) {
00351 tmpVal += leftFields(cl, lbf, qp, iTens1, iTens2)*rightFields(cl, rbf, qp, iTens1, iTens2);
00352 }
00353 }
00354 }
00355 outputFields(cl, lbf, rbf) = tmpVal;
00356 }
00357 }
00358 }
00359 }
00360 }
00361 break;
00362
00363 case COMP_BLAS: {
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 int numData = numPoints*dim1Tensor*dim2Tensor;
00385 int skipL = numLeftFields*numData;
00386 int skipR = numRightFields*numData;
00387 int skipOp = numLeftFields*numRightFields;
00388 Scalar alpha(1.0);
00389 Scalar beta(0.0);
00390 if (sumInto) {
00391 beta = 1.0;
00392 }
00393
00394 for (int cl=0; cl < numCells; cl++) {
00395
00396 Teuchos::BLAS<int, Scalar> myblas;
00397 myblas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
00398 numRightFields, numLeftFields, numData,
00399 alpha, &rightFields[cl*skipR], numData,
00400 &leftFields[cl*skipL], numData,
00401 beta, &outputFields[cl*skipOp], numRightFields);
00402
00403
00404
00405
00406
00407
00408
00409
00410 }
00411 }
00412 break;
00413
00414 default:
00415 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
00416 ">>> ERROR (ArrayTools::contractFieldFieldTensor): Computational engine not defined!");
00417 }
00418 }
00419
00420
00421 template<class Scalar, class ArrayOutFields, class ArrayInData, class ArrayInFields>
00422 void ArrayTools::contractDataFieldScalar(ArrayOutFields & outputFields,
00423 const ArrayInData & inputData,
00424 const ArrayInFields & inputFields,
00425 const ECompEngine compEngine,
00426 const bool sumInto) {
00427
00428
00429 #ifdef HAVE_INTREPID_DEBUG
00430 TEST_FOR_EXCEPTION( (inputFields.rank() != 3 ), std::invalid_argument,
00431 ">>> ERROR (ArrayTools::contractDataFieldScalar): Rank of the fields input argument must equal 3!");
00432 TEST_FOR_EXCEPTION( (inputData.rank() != 2 ), std::invalid_argument,
00433 ">>> ERROR (ArrayTools::contractDataFieldScalar): Rank of the data input argument must equal 2!");
00434 TEST_FOR_EXCEPTION( (outputFields.rank() != 2 ), std::invalid_argument,
00435 ">>> ERROR (ArrayTools::contractDataFieldScalar): Rank of output argument must equal 2!");
00436 TEST_FOR_EXCEPTION( (inputFields.dimension(0) != inputData.dimension(0) ), std::invalid_argument,
00437 ">>> ERROR (ArrayTools::contractDataFieldScalar): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
00438 TEST_FOR_EXCEPTION( ( (inputFields.dimension(2) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
00439 ">>> ERROR (ArrayTools::contractDataFieldScalar): Second dimension of fields input container and first dimension of data input container (number of integration points) must agree or first data dimension must be 1!");
00440 TEST_FOR_EXCEPTION( (outputFields.dimension(0) != inputFields.dimension(0) ), std::invalid_argument,
00441 ">>> ERROR (ArrayTools::contractDataFieldScalar): Zeroth dimensions (numbers of integration domains) of the fields input and output containers must agree!");
00442 TEST_FOR_EXCEPTION( (outputFields.dimension(1) != inputFields.dimension(1) ), std::invalid_argument,
00443 ">>> ERROR (ArrayTools::contractDataFieldScalar): First dimensions (number of fields) of the fields input and output containers must agree!");
00444 #endif
00445
00446
00447 int numCells = inputFields.dimension(0);
00448 int numFields = inputFields.dimension(1);
00449 int numPoints = inputFields.dimension(2);
00450 int numDataPoints = inputData.dimension(1);
00451
00452 ECompEngine myCompEngine = (numDataPoints == 1 ? COMP_CPP : compEngine);
00453
00454 switch(myCompEngine) {
00455 case COMP_CPP: {
00456 if (sumInto) {
00457 if (numDataPoints != 1) {
00458 for (int cl = 0; cl < numCells; cl++) {
00459 for (int lbf = 0; lbf < numFields; lbf++) {
00460 Scalar tmpVal(0);
00461 for (int qp = 0; qp < numPoints; qp++) {
00462 tmpVal += inputFields(cl, lbf, qp)*inputData(cl, qp);
00463 }
00464 outputFields(cl, lbf) += tmpVal;
00465 }
00466 }
00467 }
00468 else {
00469 for (int cl = 0; cl < numCells; cl++) {
00470 for (int lbf = 0; lbf < numFields; lbf++) {
00471 Scalar tmpVal(0);
00472 for (int qp = 0; qp < numPoints; qp++) {
00473 tmpVal += inputFields(cl, lbf, qp)*inputData(cl, 0);
00474 }
00475 outputFields(cl, lbf) += tmpVal;
00476 }
00477 }
00478 }
00479 }
00480 else {
00481 if (numDataPoints != 1) {
00482 for (int cl = 0; cl < numCells; cl++) {
00483 for (int lbf = 0; lbf < numFields; lbf++) {
00484 Scalar tmpVal(0);
00485 for (int qp = 0; qp < numPoints; qp++) {
00486 tmpVal += inputFields(cl, lbf, qp)*inputData(cl, qp);
00487 }
00488 outputFields(cl, lbf) = tmpVal;
00489 }
00490 }
00491 }
00492 else {
00493 for (int cl = 0; cl < numCells; cl++) {
00494 for (int lbf = 0; lbf < numFields; lbf++) {
00495 Scalar tmpVal(0);
00496 for (int qp = 0; qp < numPoints; qp++) {
00497 tmpVal += inputFields(cl, lbf, qp)*inputData(cl, 0);
00498 }
00499 outputFields(cl, lbf) = tmpVal;
00500 }
00501 }
00502 }
00503 }
00504 }
00505 break;
00506
00507 case COMP_BLAS: {
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528 int numData = numPoints;
00529 int skipL = numFields*numPoints;
00530 int skipR = numPoints;
00531 int skipOp = numFields;
00532 Scalar alpha(1.0);
00533 Scalar beta(0.0);
00534 if (sumInto) {
00535 beta = 1.0;
00536 }
00537
00538 for (int cl=0; cl < numCells; cl++) {
00539
00540 Teuchos::BLAS<int, Scalar> myblas;
00541 myblas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
00542 1, numFields, numData,
00543 alpha, &inputData[cl*skipR], numData,
00544 &inputFields[cl*skipL], numData,
00545 beta, &outputFields[cl*skipOp], 1);
00546
00547
00548
00549
00550
00551
00552
00553
00554 }
00555 }
00556 break;
00557
00558 default:
00559 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
00560 ">>> ERROR (ArrayTools::contractDataFieldScalar): Computational engine not defined!");
00561 }
00562 }
00563
00564
00565 template<class Scalar, class ArrayOutFields, class ArrayInData, class ArrayInFields>
00566 void ArrayTools::contractDataFieldVector(ArrayOutFields & outputFields,
00567 const ArrayInData & inputData,
00568 const ArrayInFields & inputFields,
00569 const ECompEngine compEngine,
00570 const bool sumInto) {
00571
00572 #ifdef HAVE_INTREPID_DEBUG
00573 TEST_FOR_EXCEPTION( (inputFields.rank() != 4 ), std::invalid_argument,
00574 ">>> ERROR (ArrayTools::contractDataFieldVector): Rank of the fields input argument must equal 4!");
00575 TEST_FOR_EXCEPTION( (inputData.rank() != 3 ), std::invalid_argument,
00576 ">>> ERROR (ArrayTools::contractDataFieldVector): Rank of the data input argument must equal 3!");
00577 TEST_FOR_EXCEPTION( (outputFields.rank() != 2 ), std::invalid_argument,
00578 ">>> ERROR (ArrayTools::contractDataFieldVector): Rank of output argument must equal 2!");
00579 TEST_FOR_EXCEPTION( (inputFields.dimension(0) != inputData.dimension(0) ), std::invalid_argument,
00580 ">>> ERROR (ArrayTools::contractDataFieldVector): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
00581 TEST_FOR_EXCEPTION( ( (inputFields.dimension(2) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
00582 ">>> ERROR (ArrayTools::contractDataFieldVector): 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!");
00583 TEST_FOR_EXCEPTION( (inputFields.dimension(3) != inputData.dimension(2) ), std::invalid_argument,
00584 ">>> ERROR (ArrayTools::contractDataFieldVector): Third dimension of the fields input container and second dimension of data input container (vector index) must agree!");
00585 TEST_FOR_EXCEPTION( (outputFields.dimension(0) != inputFields.dimension(0) ), std::invalid_argument,
00586 ">>> ERROR (ArrayTools::contractDataFieldVector): Zeroth dimensions (numbers of integration domains) of the fields input and output containers must agree!");
00587 TEST_FOR_EXCEPTION( (outputFields.dimension(1) != inputFields.dimension(1) ), std::invalid_argument,
00588 ">>> ERROR (ArrayTools::contractDataFieldVector): First dimensions of output container and fields input container (number of fields) must agree!");
00589 #endif
00590
00591
00592 int numCells = inputFields.dimension(0);
00593 int numFields = inputFields.dimension(1);
00594 int numPoints = inputFields.dimension(2);
00595 int dimVec = inputFields.dimension(3);
00596 int numDataPoints = inputData.dimension(1);
00597
00598 ECompEngine myCompEngine = (numDataPoints == 1 ? COMP_CPP : compEngine);
00599
00600 switch(myCompEngine) {
00601 case COMP_CPP: {
00602 if (sumInto) {
00603 if (numDataPoints != 1) {
00604 for (int cl = 0; cl < numCells; cl++) {
00605 for (int lbf = 0; lbf < numFields; lbf++) {
00606 Scalar tmpVal(0);
00607 for (int qp = 0; qp < numPoints; qp++) {
00608 for (int iVec = 0; iVec < dimVec; iVec++) {
00609 tmpVal += inputFields(cl, lbf, qp, iVec)*inputData(cl, qp, iVec);
00610 }
00611 }
00612 outputFields(cl, lbf) += tmpVal;
00613 }
00614 }
00615 }
00616 else {
00617 for (int cl = 0; cl < numCells; cl++) {
00618 for (int lbf = 0; lbf < numFields; lbf++) {
00619 Scalar tmpVal(0);
00620 for (int qp = 0; qp < numPoints; qp++) {
00621 for (int iVec = 0; iVec < dimVec; iVec++) {
00622 tmpVal += inputFields(cl, lbf, qp, iVec)*inputData(cl, 0, iVec);
00623 }
00624 }
00625 outputFields(cl, lbf) += tmpVal;
00626 }
00627 }
00628 }
00629 }
00630 else {
00631 if (numDataPoints != 1) {
00632 for (int cl = 0; cl < numCells; cl++) {
00633 for (int lbf = 0; lbf < numFields; lbf++) {
00634 Scalar tmpVal(0);
00635 for (int qp = 0; qp < numPoints; qp++) {
00636 for (int iVec = 0; iVec < dimVec; iVec++) {
00637 tmpVal += inputFields(cl, lbf, qp, iVec)*inputData(cl, qp, iVec);
00638 }
00639 }
00640 outputFields(cl, lbf) = tmpVal;
00641 }
00642 }
00643 }
00644 else {
00645 for (int cl = 0; cl < numCells; cl++) {
00646 for (int lbf = 0; lbf < numFields; lbf++) {
00647 Scalar tmpVal(0);
00648 for (int qp = 0; qp < numPoints; qp++) {
00649 for (int iVec = 0; iVec < dimVec; iVec++) {
00650 tmpVal += inputFields(cl, lbf, qp, iVec)*inputData(cl, 0, iVec);
00651 }
00652 }
00653 outputFields(cl, lbf) = tmpVal;
00654 }
00655 }
00656 }
00657 }
00658 }
00659 break;
00660
00661 case COMP_BLAS: {
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682 int numData = numPoints*dimVec;
00683 int skipL = numFields*numData;
00684 int skipR = numData;
00685 int skipOp = numFields;
00686 Scalar alpha(1.0);
00687 Scalar beta(0.0);
00688 if (sumInto) {
00689 beta = 1.0;
00690 }
00691
00692 for (int cl=0; cl < numCells; cl++) {
00693
00694 Teuchos::BLAS<int, Scalar> myblas;
00695 myblas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
00696 1, numFields, numData,
00697 alpha, &inputData[cl*skipR], numData,
00698 &inputFields[cl*skipL], numData,
00699 beta, &outputFields[cl*skipOp], 1);
00700
00701
00702
00703
00704
00705
00706
00707
00708 }
00709 }
00710 break;
00711
00712 default:
00713 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
00714 ">>> ERROR (ArrayTools::contractDataFieldVector): Computational engine not defined!");
00715 }
00716 }
00717
00718
00719 template<class Scalar, class ArrayOutFields, class ArrayInData, class ArrayInFields>
00720 void ArrayTools::contractDataFieldTensor(ArrayOutFields & outputFields,
00721 const ArrayInData & inputData,
00722 const ArrayInFields & inputFields,
00723 const ECompEngine compEngine,
00724 const bool sumInto) {
00725
00726 #ifdef HAVE_INTREPID_DEBUG
00727 TEST_FOR_EXCEPTION( (inputFields.rank() != 5 ), std::invalid_argument,
00728 ">>> ERROR (ArrayTools::contractDataFieldTensor): Rank of the fields input argument must equal 5!");
00729 TEST_FOR_EXCEPTION( (inputData.rank() != 4 ), std::invalid_argument,
00730 ">>> ERROR (ArrayTools::contractDataFieldTensor): Rank of the data input argument must equal 4!");
00731 TEST_FOR_EXCEPTION( (outputFields.rank() != 2 ), std::invalid_argument,
00732 ">>> ERROR (ArrayTools::contractDataFieldTensor): Rank of output argument must equal 2!");
00733 TEST_FOR_EXCEPTION( (inputFields.dimension(0) != inputData.dimension(0) ), std::invalid_argument,
00734 ">>> ERROR (ArrayTools::contractDataFieldTensor): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
00735 TEST_FOR_EXCEPTION( ( (inputFields.dimension(2) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
00736 ">>> ERROR (ArrayTools::contractDataFieldTensor): 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!");
00737 TEST_FOR_EXCEPTION( (inputFields.dimension(3) != inputData.dimension(2) ), std::invalid_argument,
00738 ">>> ERROR (ArrayTools::contractDataFieldTensor): Third dimension of the fields input container and second dimension of data input container (first tensor dimension) must agree!");
00739 TEST_FOR_EXCEPTION( (inputFields.dimension(4) != inputData.dimension(3) ), std::invalid_argument,
00740 ">>> ERROR (ArrayTools::contractDataFieldTensor): Fourth dimension of the fields input container and third dimension of data input container (second tensor dimension) must agree!");
00741 TEST_FOR_EXCEPTION( (outputFields.dimension(0) != inputFields.dimension(0) ), std::invalid_argument,
00742 ">>> ERROR (ArrayTools::contractDataFieldTensor): Zeroth dimensions (numbers of integration domains) of the fields input and output containers must agree!");
00743 TEST_FOR_EXCEPTION( (outputFields.dimension(1) != inputFields.dimension(1) ), std::invalid_argument,
00744 ">>> ERROR (ArrayTools::contractDataFieldTensor): First dimensions (number of fields) of output container and fields input container must agree!");
00745 #endif
00746
00747
00748 int numCells = inputFields.dimension(0);
00749 int numFields = inputFields.dimension(1);
00750 int numPoints = inputFields.dimension(2);
00751 int dim1Tens = inputFields.dimension(3);
00752 int dim2Tens = inputFields.dimension(4);
00753 int numDataPoints = inputData.dimension(1);
00754
00755 ECompEngine myCompEngine = (numDataPoints == 1 ? COMP_CPP : compEngine);
00756
00757 switch(myCompEngine) {
00758 case COMP_CPP: {
00759 if (sumInto) {
00760 if (numDataPoints != 1) {
00761 for (int cl = 0; cl < numCells; cl++) {
00762 for (int lbf = 0; lbf < numFields; lbf++) {
00763 Scalar tmpVal(0);
00764 for (int qp = 0; qp < numPoints; qp++) {
00765 for (int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00766 for (int iTens2 =0; iTens2 < dim2Tens; iTens2++) {
00767 tmpVal += inputFields(cl, lbf, qp, iTens1, iTens2)*inputData(cl, qp, iTens1, iTens2);
00768 }
00769 }
00770 }
00771 outputFields(cl, lbf) += tmpVal;
00772 }
00773 }
00774 }
00775 else {
00776 for (int cl = 0; cl < numCells; cl++) {
00777 for (int lbf = 0; lbf < numFields; lbf++) {
00778 Scalar tmpVal(0);
00779 for (int qp = 0; qp < numPoints; qp++) {
00780 for (int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00781 for (int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00782 tmpVal += inputFields(cl, lbf, qp, iTens1, iTens2)*inputData(cl, 0, iTens1, iTens2);
00783 }
00784 }
00785 }
00786 outputFields(cl, lbf) += tmpVal;
00787 }
00788 }
00789 }
00790 }
00791 else {
00792 if (numDataPoints != 1) {
00793 for (int cl = 0; cl < numCells; cl++) {
00794 for (int lbf = 0; lbf < numFields; lbf++) {
00795 Scalar tmpVal(0);
00796 for (int qp = 0; qp < numPoints; qp++) {
00797 for (int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00798 for (int iTens2 =0; iTens2 < dim2Tens; iTens2++) {
00799 tmpVal += inputFields(cl, lbf, qp, iTens1, iTens2)*inputData(cl, qp, iTens1, iTens2);
00800 }
00801 }
00802 }
00803 outputFields(cl, lbf) = tmpVal;
00804 }
00805 }
00806 }
00807 else {
00808 for (int cl = 0; cl < numCells; cl++) {
00809 for (int lbf = 0; lbf < numFields; lbf++) {
00810 Scalar tmpVal(0);
00811 for (int qp = 0; qp < numPoints; qp++) {
00812 for (int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00813 for (int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00814 tmpVal += inputFields(cl, lbf, qp, iTens1, iTens2)*inputData(cl, 0, iTens1, iTens2);
00815 }
00816 }
00817 }
00818 outputFields(cl, lbf) = tmpVal;
00819 }
00820 }
00821 }
00822 }
00823 }
00824 break;
00825
00826 case COMP_BLAS: {
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847 int numData = numPoints*dim1Tens*dim2Tens;
00848 int skipL = numFields*numData;
00849 int skipR = numData;
00850 int skipOp = numFields;
00851 Scalar alpha(1.0);
00852 Scalar beta(0.0);
00853 if (sumInto) {
00854 beta = 1.0;
00855 }
00856
00857 for (int cl=0; cl < numCells; cl++) {
00858
00859 Teuchos::BLAS<int, Scalar> myblas;
00860 myblas.GEMM(Teuchos::TRANS, Teuchos::NO_TRANS,
00861 1, numFields, numData,
00862 alpha, &inputData[cl*skipR], numData,
00863 &inputFields[cl*skipL], numData,
00864 beta, &outputFields[cl*skipOp], 1);
00865
00866
00867
00868
00869
00870
00871
00872
00873 }
00874 }
00875 break;
00876
00877 default:
00878 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
00879 ">>> ERROR (ArrayTools::contractDataFieldTensor): Computational engine not defined!");
00880 }
00881 }
00882
00883
00884 template<class Scalar, class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight>
00885 void ArrayTools::contractDataDataScalar(ArrayOutData & outputData,
00886 const ArrayInDataLeft & inputDataLeft,
00887 const ArrayInDataRight & inputDataRight,
00888 const ECompEngine compEngine,
00889 const bool sumInto) {
00890
00891 #ifdef HAVE_INTREPID_DEBUG
00892 TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 2 ), std::invalid_argument,
00893 ">>> ERROR (ArrayTools::contractDataDataScalar): Rank of the left input argument must equal 2!");
00894 TEST_FOR_EXCEPTION( (inputDataRight.rank() != 2 ), std::invalid_argument,
00895 ">>> ERROR (ArrayTools::contractDataDataScalar): Rank of right input argument must equal 2!");
00896 TEST_FOR_EXCEPTION( (outputData.rank() != 1 ), std::invalid_argument,
00897 ">>> ERROR (ArrayTools::contractDataDataScalar): Rank of output argument must equal 1!");
00898 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(0) != inputDataRight.dimension(0) ), std::invalid_argument,
00899 ">>> ERROR (ArrayTools::contractDataDataScalar): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
00900 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(1) != inputDataRight.dimension(1) ), std::invalid_argument,
00901 ">>> ERROR (ArrayTools::contractDataDataScalar): First dimensions (numbers of integration points) of the left and right input containers must agree!");
00902 TEST_FOR_EXCEPTION( (outputData.dimension(0) != inputDataRight.dimension(0) ), std::invalid_argument,
00903 ">>> ERROR (ArrayTools::contractDataDataScalar): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
00904 #endif
00905
00906
00907 int numCells = inputDataLeft.dimension(0);
00908 int numPoints = inputDataLeft.dimension(1);
00909
00910 switch(compEngine) {
00911 case COMP_CPP: {
00912 if (sumInto) {
00913 for (int cl = 0; cl < numCells; cl++) {
00914 Scalar tmpVal(0);
00915 for (int qp = 0; qp < numPoints; qp++) {
00916 tmpVal += inputDataLeft(cl, qp)*inputDataRight(cl, qp);
00917 }
00918 outputData(cl) += tmpVal;
00919 }
00920 }
00921 else {
00922 for (int cl = 0; cl < numCells; cl++) {
00923 Scalar tmpVal(0);
00924 for (int qp = 0; qp < numPoints; qp++) {
00925 tmpVal += inputDataLeft(cl, qp)*inputDataRight(cl, qp);
00926 }
00927 outputData(cl) = tmpVal;
00928 }
00929 }
00930 }
00931 break;
00932
00933 case COMP_BLAS: {
00934 int incr = 1;
00935 if (sumInto) {
00936 for (int cl=0; cl < numCells; cl++) {
00937 Teuchos::BLAS<int, Scalar> myblas;
00938 outputData(cl) += myblas.DOT(numPoints, &inputDataLeft[cl*numPoints], incr, &inputDataRight[cl*numPoints], incr);
00939 }
00940 }
00941 else {
00942 for (int cl=0; cl < numCells; cl++) {
00943 Teuchos::BLAS<int, Scalar> myblas;
00944 outputData(cl) = myblas.DOT(numPoints, &inputDataLeft[cl*numPoints], incr, &inputDataRight[cl*numPoints], incr);
00945 }
00946 }
00947 }
00948 break;
00949
00950 default:
00951 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
00952 ">>> ERROR (ArrayTools::contractDataDataScalar): Computational engine not defined!");
00953 }
00954 }
00955
00956
00957 template<class Scalar, class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight>
00958 void ArrayTools::contractDataDataVector(ArrayOutData & outputData,
00959 const ArrayInDataLeft & inputDataLeft,
00960 const ArrayInDataRight & inputDataRight,
00961 const ECompEngine compEngine,
00962 const bool sumInto) {
00963
00964 #ifdef HAVE_INTREPID_DEBUG
00965 TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 3 ), std::invalid_argument,
00966 ">>> ERROR (ArrayTools::contractDataDataVector): Rank of the left input argument must equal 3!");
00967 TEST_FOR_EXCEPTION( (inputDataRight.rank() != 3 ), std::invalid_argument,
00968 ">>> ERROR (ArrayTools::contractDataDataVector): Rank of right input argument must equal 3!");
00969 TEST_FOR_EXCEPTION( (outputData.rank() != 1 ), std::invalid_argument,
00970 ">>> ERROR (ArrayTools::contractDataDataVector): Rank of output argument must equal 1!");
00971 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(0) != inputDataRight.dimension(0) ), std::invalid_argument,
00972 ">>> ERROR (ArrayTools::contractDataDataVector): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
00973 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(1) != inputDataRight.dimension(1) ), std::invalid_argument,
00974 ">>> ERROR (ArrayTools::contractDataDataVector): First dimensions (numbers of integration points) of the left and right input containers must agree!");
00975 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(2) != inputDataRight.dimension(2) ), std::invalid_argument,
00976 ">>> ERROR (ArrayTools::contractDataDataVector): Second dimensions (numbers of vector components) of the left and right input containers must agree!");
00977 TEST_FOR_EXCEPTION( (outputData.dimension(0) != inputDataRight.dimension(0) ), std::invalid_argument,
00978 ">>> ERROR (ArrayTools::contractDataDataVector): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
00979 #endif
00980
00981
00982 int numCells = inputDataLeft.dimension(0);
00983 int numPoints = inputDataLeft.dimension(1);
00984 int dimVec = inputDataLeft.dimension(2);
00985
00986 switch(compEngine) {
00987 case COMP_CPP: {
00988 if (sumInto) {
00989 for (int cl = 0; cl < numCells; cl++) {
00990 Scalar tmpVal(0);
00991 for (int qp = 0; qp < numPoints; qp++) {
00992 for (int iVec = 0; iVec < dimVec; iVec++) {
00993 tmpVal += inputDataLeft(cl, qp, iVec)*inputDataRight(cl, qp, iVec);
00994 }
00995 }
00996 outputData(cl) += tmpVal;
00997 }
00998 }
00999 else {
01000 for (int cl = 0; cl < numCells; cl++) {
01001 Scalar tmpVal(0);
01002 for (int qp = 0; qp < numPoints; qp++) {
01003 for (int iVec = 0; iVec < dimVec; iVec++) {
01004 tmpVal += inputDataLeft(cl, qp, iVec)*inputDataRight(cl, qp, iVec);
01005 }
01006 }
01007 outputData(cl) = tmpVal;
01008 }
01009 }
01010 }
01011 break;
01012
01013 case COMP_BLAS: {
01014 int skip = numPoints*dimVec;
01015 int incr = 1;
01016 if (sumInto) {
01017 for (int cl=0; cl < numCells; cl++) {
01018 Teuchos::BLAS<int, Scalar> myblas;
01019 outputData(cl) += myblas.DOT(skip, &inputDataLeft[cl*skip], incr, &inputDataRight[cl*skip], incr);
01020 }
01021 }
01022 else {
01023 for (int cl=0; cl < numCells; cl++) {
01024 Teuchos::BLAS<int, Scalar> myblas;
01025 outputData(cl) = myblas.DOT(skip, &inputDataLeft[cl*skip], incr, &inputDataRight[cl*skip], incr);
01026 }
01027 }
01028 }
01029 break;
01030
01031 default:
01032 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
01033 ">>> ERROR (ArrayTools::contractDataDataVector): Computational engine not defined!");
01034 }
01035 }
01036
01037
01038 template<class Scalar, class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight>
01039 void ArrayTools::contractDataDataTensor(ArrayOutData & outputData,
01040 const ArrayInDataLeft & inputDataLeft,
01041 const ArrayInDataRight & inputDataRight,
01042 const ECompEngine compEngine,
01043 const bool sumInto) {
01044
01045 #ifdef HAVE_INTREPID_DEBUG
01046 TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 4 ), std::invalid_argument,
01047 ">>> ERROR (ArrayTools::contractDataDataTensor): Rank of the left input argument must equal 4");
01048 TEST_FOR_EXCEPTION( (inputDataRight.rank() != 4 ), std::invalid_argument,
01049 ">>> ERROR (ArrayTools::contractDataDataTensor): Rank of right input argument must equal 4!");
01050 TEST_FOR_EXCEPTION( (outputData.rank() != 1 ), std::invalid_argument,
01051 ">>> ERROR (ArrayTools::contractDataDataTensor): Rank of output argument must equal 1!");
01052 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(0) != inputDataRight.dimension(0) ), std::invalid_argument,
01053 ">>> ERROR (ArrayTools::contractDataDataTensor): Zeroth dimensions (number of integration domains) of the left and right input containers must agree!");
01054 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(1) != inputDataRight.dimension(1) ), std::invalid_argument,
01055 ">>> ERROR (ArrayTools::contractDataDataTensor): First dimensions (numbers of integration points) of the left and right input containers must agree!");
01056 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(2) != inputDataRight.dimension(2) ), std::invalid_argument,
01057 ">>> ERROR (ArrayTools::contractDataDataTensor): Second dimensions (first tensor dimensions) of the left and right input containers must agree!");
01058 TEST_FOR_EXCEPTION( (inputDataLeft.dimension(3) != inputDataRight.dimension(3) ), std::invalid_argument,
01059 ">>> ERROR (ArrayTools::contractDataDataTensor): Third dimensions (second tensor dimensions) of the left and right input containers must agree!");
01060 TEST_FOR_EXCEPTION( (outputData.dimension(0) != inputDataRight.dimension(0) ), std::invalid_argument,
01061 ">>> ERROR (ArrayTools::contractDataDataTensor): Zeroth dimensions (numbers of integration domains) of the input and output containers must agree!");
01062 #endif
01063
01064
01065 int numCells = inputDataLeft.dimension(0);
01066 int numPoints = inputDataLeft.dimension(1);
01067 int dim1Tensor = inputDataLeft.dimension(2);
01068 int dim2Tensor = inputDataLeft.dimension(3);
01069
01070 switch(compEngine) {
01071 case COMP_CPP: {
01072 if (sumInto) {
01073 for (int cl = 0; cl < numCells; cl++) {
01074 Scalar tmpVal(0);
01075 for (int qp = 0; qp < numPoints; qp++) {
01076 for (int iTens1 = 0; iTens1 < dim1Tensor; iTens1++) {
01077 for (int iTens2 = 0; iTens2 < dim2Tensor; iTens2++) {
01078 tmpVal += inputDataLeft(cl, qp, iTens1, iTens2)*inputDataRight(cl, qp, iTens1, iTens2);
01079 }
01080 }
01081 }
01082 outputData(cl) += tmpVal;
01083 }
01084 }
01085 else {
01086 for (int cl = 0; cl < numCells; cl++) {
01087 Scalar tmpVal(0);
01088 for (int qp = 0; qp < numPoints; qp++) {
01089 for (int iTens1 = 0; iTens1 < dim1Tensor; iTens1++) {
01090 for (int iTens2 = 0; iTens2 < dim2Tensor; iTens2++) {
01091 tmpVal += inputDataLeft(cl, qp, iTens1, iTens2)*inputDataRight(cl, qp, iTens1, iTens2);
01092 }
01093 }
01094 }
01095 outputData(cl) = tmpVal;
01096 }
01097 }
01098 }
01099 break;
01100
01101 case COMP_BLAS: {
01102 int skip = numPoints*dim1Tensor*dim2Tensor;
01103 int incr = 1;
01104 if (sumInto) {
01105 for (int cl=0; cl < numCells; cl++) {
01106 Teuchos::BLAS<int, Scalar> myblas;
01107 outputData(cl) += myblas.DOT(skip, &inputDataLeft[cl*skip], incr, &inputDataRight[cl*skip], incr);
01108 }
01109 }
01110 else {
01111 for (int cl=0; cl < numCells; cl++) {
01112 Teuchos::BLAS<int, Scalar> myblas;
01113 outputData(cl) = myblas.DOT(skip, &inputDataLeft[cl*skip], incr, &inputDataRight[cl*skip], incr);
01114 }
01115 }
01116 }
01117 break;
01118
01119 default:
01120 TEST_FOR_EXCEPTION( ( ~isValidCompEngine(compEngine) ), std::invalid_argument,
01121 ">>> ERROR (ArrayTools::contractDataDataTensor): Computational engine not defined!");
01122 }
01123 }
01124
01125
01126 }