Intrepid
/usr/src/RPM/BUILD/trilinos10-10.6.4/packages/intrepid/src/Shared/Intrepid_ArrayToolsDefDot.hpp
Go to the documentation of this file.
00001 // @HEADER
00002 // ************************************************************************
00003 //
00004 //                           Intrepid Package
00005 //                 Copyright (2007) Sandia Corporation
00006 //
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 //
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Pavel Bochev (pbboche@sandia.gov) or
00025 //                    Denis Ridzal (dridzal@sandia.gov).
00026 //
00027 // ************************************************************************
00028 // @HEADER
00029 
00035 namespace Intrepid {
00036 
00037 template<class Scalar, class ArrayOutFields, class ArrayInData, class ArrayInFields>
00038 void ArrayTools::dotMultiplyDataField(ArrayOutFields &       outputFields,
00039                                       const ArrayInData &    inputData,
00040                                       const ArrayInFields &  inputFields) {
00041 
00042 #ifdef HAVE_INTREPID_DEBUG
00043   if (inputFields.rank() > inputData.rank()) {
00044     TEST_FOR_EXCEPTION( ((inputData.rank() < 2) || (inputData.rank() > 4)), std::invalid_argument,
00045                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Input data container must have rank 2, 3 or 4.");
00046     TEST_FOR_EXCEPTION( (inputFields.rank() != inputData.rank()+1), std::invalid_argument,
00047                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Input fields container must have rank one larger than the rank of the input data container.");
00048     TEST_FOR_EXCEPTION( (outputFields.rank() != 3), std::invalid_argument,
00049                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Output fields container must have rank 3.");
00050     TEST_FOR_EXCEPTION( (inputFields.dimension(0) != inputData.dimension(0) ), std::invalid_argument,
00051                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
00052     TEST_FOR_EXCEPTION( ( (inputFields.dimension(2) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
00053                         ">>> 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!");
00054     for (int i=2; i<inputData.rank(); i++) {
00055       std::string errmsg  = ">>> ERROR (ArrayTools::dotMultiplyDataField): Dimensions ";
00056       errmsg += (char)(48+i);
00057       errmsg += " and ";
00058       errmsg += (char)(48+i+1);
00059       errmsg += " of the input data and fields containers must agree!";
00060       TEST_FOR_EXCEPTION( (inputData.dimension(i) != inputFields.dimension(i+1)), std::invalid_argument, errmsg );
00061     }
00062     for (int i=0; i<outputFields.rank(); i++) {
00063       std::string errmsg  = ">>> ERROR (ArrayTools::dotMultiplyDataField): Dimensions ";
00064       errmsg += (char)(48+i);
00065       errmsg += " of the input and output fields containers must agree!";
00066       TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i)), std::invalid_argument, errmsg );
00067     }
00068   }
00069   else {
00070     TEST_FOR_EXCEPTION( ((inputData.rank() < 2) || (inputData.rank() > 4)), std::invalid_argument,
00071                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Input data container must have rank 2, 3 or 4.");
00072     TEST_FOR_EXCEPTION( (inputFields.rank() != inputData.rank()), std::invalid_argument,
00073                         ">>> ERROR (ArrayTools::dotMultiplyDataField): The rank of fields input container must equal the rank of data input container.");
00074     TEST_FOR_EXCEPTION( (outputFields.rank() != 3), std::invalid_argument,
00075                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Output fields container must have rank 3.");
00076     TEST_FOR_EXCEPTION( ( (inputFields.dimension(1) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
00077                         ">>> 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!");
00078     TEST_FOR_EXCEPTION( (inputFields.dimension(0) != outputFields.dimension(1)), std::invalid_argument,
00079                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimension of the fields input container and first dimension of the fields output container (number of fields) must agree!");
00080     TEST_FOR_EXCEPTION( (inputFields.dimension(1) != outputFields.dimension(2)), std::invalid_argument,
00081                         ">>> ERROR (ArrayTools::dotMultiplyDataField): First dimension of the fields input container and second dimension of the fields output container (number of integration points) must agree!");
00082     TEST_FOR_EXCEPTION( (outputFields.dimension(0) != inputData.dimension(0)), std::invalid_argument,
00083                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimensions of the fields output and data input containers (number of integration domains) must agree!");
00084     for (int i=2; i<inputData.rank(); i++) {
00085       std::string errmsg  = ">>> ERROR (ArrayTools::dotMultiplyDataField): Dimensions ";
00086       errmsg += (char)(48+i);
00087       errmsg += " of the input data and fields containers must agree!";
00088       TEST_FOR_EXCEPTION( (inputData.dimension(i) != inputFields.dimension(i)), std::invalid_argument, errmsg );
00089     }
00090   }
00091 #endif
00092 
00093   // get sizes
00094   int invalRank      = inputFields.rank();
00095   int dataRank       = inputData.rank();
00096   int numCells       = outputFields.dimension(0);
00097   int numFields      = outputFields.dimension(1);
00098   int numPoints      = outputFields.dimension(2);
00099   int numDataPoints  = inputData.dimension(1);
00100   int dim1Tens       = 0;
00101   int dim2Tens       = 0;
00102   if (dataRank > 2) {
00103     dim1Tens = inputData.dimension(2);
00104     if (dataRank > 3) {
00105       dim2Tens = inputData.dimension(3);
00106     }
00107   }
00108 
00109   Scalar temp(0);
00110 
00111   if (invalRank == dataRank + 1) {
00112 
00113     if (numDataPoints != 1) { // nonconstant data
00114 
00115       switch(invalRank) {
00116         case 3: {
00117           for(int cl = 0; cl < numCells; cl++) {
00118             for(int bf = 0; bf < numFields; bf++) {
00119               for(int pt = 0; pt < numPoints; pt++) {
00120                 outputFields(cl, bf, pt) = inputData(cl, pt)*inputFields(cl, bf, pt);
00121               } // P-loop
00122             } // F-loop
00123           } // C-loop
00124         }// case 3
00125         break;
00126 
00127         case 4: {
00128           for(int cl = 0; cl < numCells; cl++) {
00129             for(int bf = 0; bf < numFields; bf++) {
00130               for(int pt = 0; pt < numPoints; pt++) {
00131                 temp = 0;
00132                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00133                   temp += inputData(cl, pt, iVec)*inputFields(cl, bf, pt, iVec);
00134                 } // D1-loop
00135                 outputFields(cl, bf, pt) = temp;
00136               } // P-loop
00137             } // F-loop
00138           } // C-loop
00139         }// case 4
00140         break;
00141 
00142         case 5: {
00143           for(int cl = 0; cl < numCells; cl++) {
00144             for(int bf = 0; bf < numFields; bf++) {
00145               for(int pt = 0; pt < numPoints; pt++) {
00146                 temp = 0;
00147                 for(int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00148                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00149                     temp += inputData(cl, pt, iTens1, iTens2)*inputFields(cl, bf, pt, iTens1, iTens2);
00150                   } // D1-loop
00151                 } // D2-loop
00152                 outputFields(cl, bf, pt) =  temp;
00153               } // P-loop
00154             } // F-loop
00155           } // C-loop
00156         }// case 5
00157         break;
00158 
00159         default:
00160               TEST_FOR_EXCEPTION( !( (invalRank == 3) || (invalRank == 4) || (invalRank == 5) ), std::invalid_argument,
00161                                   ">>> ERROR (ArrayTools::dotMultiplyDataField): This branch of the method is defined only for rank-3, 4 or 5 input fields containers.");
00162       }// invalRank
00163 
00164     }
00165     else { //constant data
00166 
00167       switch(invalRank) {
00168         case 3: {
00169           for(int cl = 0; cl < numCells; cl++) {
00170             for(int bf = 0; bf < numFields; bf++) {
00171               for(int pt = 0; pt < numPoints; pt++) {
00172                 outputFields(cl, bf, pt) = inputData(cl, 0)*inputFields(cl, bf, pt);
00173               } // P-loop
00174             } // F-loop
00175           } // C-loop
00176         }// case 3
00177         break;
00178 
00179         case 4: {
00180           for(int cl = 0; cl < numCells; cl++) {
00181             for(int bf = 0; bf < numFields; bf++) {
00182               for(int pt = 0; pt < numPoints; pt++) {
00183               temp = 0;
00184                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00185                   temp += inputData(cl, 0, iVec)*inputFields(cl, bf, pt, iVec);
00186                 } // D1-loop
00187                 outputFields(cl, bf, pt) = temp;
00188               } // P-loop
00189             } // F-loop
00190           } // C-loop
00191         }// case 4
00192         break;
00193 
00194         case 5: {
00195           for(int cl = 0; cl < numCells; cl++) {
00196             for(int bf = 0; bf < numFields; bf++) {
00197               for(int pt = 0; pt < numPoints; pt++) {
00198                 temp = 0;
00199                 for(int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00200                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00201                     temp += inputData(cl, 0, iTens1, iTens2)*inputFields(cl, bf, pt, iTens1, iTens2);
00202                   } // D1-loop
00203                 } // D2-loop
00204                 outputFields(cl, bf, pt) =  temp;
00205               } // P-loop
00206             } // F-loop
00207           } // C-loop
00208         }// case 5
00209         break;
00210 
00211         default:
00212               TEST_FOR_EXCEPTION( !( (invalRank == 3) || (invalRank == 4) || (invalRank == 5) ), std::invalid_argument,
00213                                   ">>> ERROR (ArrayTools::dotMultiplyDataField): This branch of the method is defined only for rank-3, 4 or 5 input fields containers.");
00214       }// invalRank
00215 
00216     } // numDataPoints
00217 
00218   }
00219   else {
00220 
00221     if (numDataPoints != 1) { // nonconstant data
00222 
00223       switch(invalRank) {
00224         case 2: {
00225           for(int cl = 0; cl < numCells; cl++) {
00226             for(int bf = 0; bf < numFields; bf++) {
00227               for(int pt = 0; pt < numPoints; pt++) {
00228                 outputFields(cl, bf, pt) = inputData(cl, pt)*inputFields(bf, pt);
00229               } // P-loop
00230             } // F-loop
00231           } // C-loop
00232         }// case 2
00233         break;
00234 
00235         case 3: {
00236           for(int cl = 0; cl < numCells; cl++) {
00237             for(int bf = 0; bf < numFields; bf++) {
00238               for(int pt = 0; pt < numPoints; pt++) {
00239                 temp = 0;
00240                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00241                   temp += inputData(cl, pt, iVec)*inputFields(bf, pt, iVec);
00242                 } // D1-loop
00243                 outputFields(cl, bf, pt) = temp;
00244               } // P-loop
00245             } // F-loop
00246           } // C-loop
00247         }// case 3
00248         break;
00249 
00250         case 4: {
00251           for(int cl = 0; cl < numCells; cl++) {
00252             for(int bf = 0; bf < numFields; bf++) {
00253               for(int pt = 0; pt < numPoints; pt++) {
00254                 temp = 0;
00255                 for(int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00256                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00257                     temp += inputData(cl, pt, iTens1, iTens2)*inputFields(bf, pt, iTens1, iTens2);
00258                   } // D1-loop
00259                 } // D2-loop
00260                 outputFields(cl, bf, pt) =  temp;
00261               } // P-loop
00262             } // F-loop
00263           } // C-loop
00264         }// case 4
00265         break;
00266 
00267         default:
00268               TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
00269                                   ">>> ERROR (ArrayTools::dotMultiplyDataField): This branch of the method is defined only for rank-2, 3 or 4 input fields containers.");
00270       }// invalRank
00271 
00272     }
00273     else { //constant data
00274 
00275       switch(invalRank) {
00276         case 2: {
00277           for(int cl = 0; cl < numCells; cl++) {
00278             for(int bf = 0; bf < numFields; bf++) {
00279               for(int pt = 0; pt < numPoints; pt++) {
00280                 outputFields(cl, bf, pt) = inputData(cl, 0)*inputFields(bf, pt);
00281               } // P-loop
00282             } // F-loop
00283           } // C-loop
00284         }// case 2
00285         break;
00286 
00287         case 3: {
00288           for(int cl = 0; cl < numCells; cl++) {
00289             for(int bf = 0; bf < numFields; bf++) {
00290               for(int pt = 0; pt < numPoints; pt++) {
00291               temp = 0;
00292                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00293                   temp += inputData(cl, 0, iVec)*inputFields(bf, pt, iVec);
00294                 } // D1-loop
00295                 outputFields(cl, bf, pt) = temp;
00296               } // P-loop
00297             } // F-loop
00298           } // C-loop
00299         }// case 3
00300         break;
00301 
00302         case 4: {
00303           for(int cl = 0; cl < numCells; cl++) {
00304             for(int bf = 0; bf < numFields; bf++) {
00305               for(int pt = 0; pt < numPoints; pt++) {
00306                 temp = 0;
00307                 for(int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00308                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00309                     temp += inputData(cl, 0, iTens1, iTens2)*inputFields(bf, pt, iTens1, iTens2);
00310                   } // D1-loop
00311                 } // D2-loop
00312                 outputFields(cl, bf, pt) =  temp;
00313               } // P-loop
00314             } // F-loop
00315           } // C-loop
00316         }// case 4
00317         break;
00318 
00319         default:
00320               TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
00321                                   ">>> ERROR (ArrayTools::dotMultiplyDataField): This branch of the method is defined only for rank-2, 3 or 4 input fields containers.");
00322       }// invalRank
00323 
00324     } // numDataPoints
00325 
00326   } // end if (invalRank == dataRank + 1)
00327 
00328 }// dotMultiplyDataField
00329 
00330 
00331 
00332 template<class Scalar, class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight>
00333 void ArrayTools::dotMultiplyDataData(ArrayOutData &            outputData,
00334                                      const ArrayInDataLeft  &  inputDataLeft,
00335                                      const ArrayInDataRight &  inputDataRight) {
00336 
00337 #ifdef HAVE_INTREPID_DEBUG
00338   if (inputDataRight.rank() >= inputDataLeft.rank()) {
00339     TEST_FOR_EXCEPTION( ((inputDataLeft.rank() < 2) || (inputDataLeft.rank() > 4)), std::invalid_argument,
00340                         ">>> ERROR (ArrayTools::dotMultiplyDataData): Left data input container must have rank 2, 3 or 4.");
00341     TEST_FOR_EXCEPTION( (inputDataRight.rank() != inputDataLeft.rank()), std::invalid_argument,
00342                         ">>> ERROR (ArrayTools::dotMultiplyDataData): The rank of the right data input container must equal the rank of the left data input container.");
00343     TEST_FOR_EXCEPTION( (outputData.rank() != 2), std::invalid_argument,
00344                         ">>> ERROR (ArrayTools::dotMultiplyDataData): Data output container must have rank 2.");
00345     TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(1) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
00346                         ">>> 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!");
00347     for (int i=0; i<inputDataLeft.rank(); i++) {
00348       if (i != 1) {
00349         std::string errmsg  = ">>> ERROR (ArrayTools::dotMultiplyDataData): Dimensions ";
00350         errmsg += (char)(48+i);
00351         errmsg += " of the left and right data input containers must agree!";
00352         TEST_FOR_EXCEPTION( (inputDataLeft.dimension(i) != inputDataRight.dimension(i)), std::invalid_argument, errmsg );
00353       }
00354     }
00355     for (int i=0; i<outputData.rank(); i++) {
00356       std::string errmsg  = ">>> ERROR (ArrayTools::dotMultiplyDataData): Dimensions ";
00357       errmsg += (char)(48+i);
00358       errmsg += " of the output and right input data containers must agree!";
00359       TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i)), std::invalid_argument, errmsg );
00360     }
00361   }
00362   else {
00363     TEST_FOR_EXCEPTION( ((inputDataLeft.rank() < 2) || (inputDataLeft.rank() > 4)), std::invalid_argument,
00364                         ">>> ERROR (ArrayTools::dotMultiplyDataData): Left data input container must have rank 2, 3 or 4.");
00365     TEST_FOR_EXCEPTION( (inputDataRight.rank() != inputDataLeft.rank()-1), std::invalid_argument,
00366                         ">>> ERROR (ArrayTools::dotMultiplyDataData): Right data input container must have rank one less than the rank of left data input container.");
00367     TEST_FOR_EXCEPTION( (outputData.rank() != 2), std::invalid_argument,
00368                         ">>> ERROR (ArrayTools::dotMultiplyDataData): Data output container must have rank 2.");
00369     TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(0) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
00370                         ">>> 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!");
00371     TEST_FOR_EXCEPTION( (inputDataRight.dimension(0) != outputData.dimension(1)), std::invalid_argument,
00372                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimension of the right data input container and first dimension of output data container (number of integration points) must agree!");
00373     TEST_FOR_EXCEPTION( (inputDataLeft.dimension(0) != outputData.dimension(0)), std::invalid_argument,
00374                         ">>> ERROR (ArrayTools::dotMultiplyDataField): Zeroth dimensions of the left data input and data output containers (number of integration domains) must agree!");
00375     for (int i=1; i<inputDataRight.rank(); i++) {
00376       std::string errmsg  = ">>> ERROR (ArrayTools::dotMultiplyDataData): Dimensions ";
00377       errmsg += (char)(48+i+1);
00378       errmsg += " and ";
00379       errmsg += (char)(48+i);
00380       errmsg += " of the left and right data input containers must agree!";
00381       TEST_FOR_EXCEPTION( (inputDataLeft.dimension(i+1) != inputDataRight.dimension(i)), std::invalid_argument, errmsg );
00382     }
00383   }
00384 #endif
00385 
00386   // get sizes
00387   int rightDataRank  = inputDataRight.rank();
00388   int leftDataRank   = inputDataLeft.rank();
00389   int numCells       = outputData.dimension(0);
00390   int numPoints      = outputData.dimension(1);
00391   int numDataPoints  = inputDataLeft.dimension(1);
00392   int dim1Tens       = 0;
00393   int dim2Tens       = 0;
00394   if (leftDataRank > 2) {
00395     dim1Tens = inputDataLeft.dimension(2);
00396     if (leftDataRank > 3) {
00397       dim2Tens = inputDataLeft.dimension(3);
00398     }
00399   }
00400 
00401   Scalar temp(0);
00402 
00403   if (rightDataRank == leftDataRank) {
00404 
00405     if (numDataPoints != 1) { // nonconstant data
00406 
00407       switch(rightDataRank) {
00408         case 2: {
00409           for(int cl = 0; cl < numCells; cl++) {
00410             for(int pt = 0; pt < numPoints; pt++) {
00411                 outputData(cl, pt) = inputDataLeft(cl, pt)*inputDataRight(cl, pt);
00412             } // P-loop
00413           } // C-loop
00414         }// case 2
00415         break;
00416 
00417         case 3: {
00418           for(int cl = 0; cl < numCells; cl++) {
00419             for(int pt = 0; pt < numPoints; pt++) {
00420               temp = 0;
00421               for( int iVec = 0; iVec < dim1Tens; iVec++) {
00422                   temp += inputDataLeft(cl, pt, iVec)*inputDataRight(cl, pt, iVec);
00423               } // D1-loop
00424               outputData(cl, pt) = temp;
00425             } // P-loop
00426           } // C-loop
00427         }// case 3
00428         break;
00429 
00430         case 4: {
00431           for(int cl = 0; cl < numCells; cl++) {
00432             for(int pt = 0; pt < numPoints; pt++) {
00433               temp = 0;
00434               for(int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00435                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00436                     temp += inputDataLeft(cl, pt, iTens1, iTens2)*inputDataRight(cl, pt, iTens1, iTens2);
00437                 } // D1-loop
00438               } // D2-loop
00439               outputData(cl, pt) =  temp;
00440             } // P-loop
00441           } // C-loop
00442         }// case 4
00443         break;
00444 
00445         default:
00446               TEST_FOR_EXCEPTION( !( (rightDataRank == 2) || (rightDataRank == 3) || (rightDataRank == 4) ), std::invalid_argument,
00447                                   ">>> ERROR (ArrayTools::dotMultiplyDataData): This branch of the method is defined only for rank-2, 3 or 4 right data input containers.");
00448       }// rightDataRank
00449 
00450     }
00451     else { //constant data
00452 
00453       switch(rightDataRank) {
00454         case 2: {
00455           for(int cl = 0; cl < numCells; cl++) {
00456             for(int pt = 0; pt < numPoints; pt++) {
00457                 outputData(cl, pt) = inputDataLeft(cl, 0)*inputDataRight(cl, pt);
00458             } // P-loop
00459           } // C-loop
00460         }// case 2
00461         break;
00462 
00463         case 3: {
00464           for(int cl = 0; cl < numCells; cl++) {
00465             for(int pt = 0; pt < numPoints; pt++) {
00466               temp = 0;
00467               for( int iVec = 0; iVec < dim1Tens; iVec++) {
00468                   temp += inputDataLeft(cl, 0, iVec)*inputDataRight(cl, pt, iVec);
00469               } // D1-loop
00470               outputData(cl, pt) = temp;
00471             } // P-loop
00472           } // C-loop
00473         }// case 3
00474         break;
00475 
00476         case 4: {
00477           for(int cl = 0; cl < numCells; cl++) {
00478             for(int pt = 0; pt < numPoints; pt++) {
00479               temp = 0;
00480               for(int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00481                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00482                     temp += inputDataLeft(cl, 0, iTens1, iTens2)*inputDataRight(cl, pt, iTens1, iTens2);
00483                 } // D1-loop
00484               } // D2-loop
00485               outputData(cl, pt) =  temp;
00486             } // P-loop
00487           } // C-loop
00488         }// case 4
00489         break;
00490 
00491         default:
00492               TEST_FOR_EXCEPTION( !( (rightDataRank == 2) || (rightDataRank == 3) || (rightDataRank == 4) ), std::invalid_argument,
00493                                   ">>> ERROR (ArrayTools::dotMultiplyDataData): This branch of the method is defined only for rank-2, 3 or 4 right data input containers.");
00494       }// rightDataRank
00495 
00496     } // numDataPoints
00497 
00498   }
00499   else {
00500 
00501     if (numDataPoints != 1) { // nonconstant data
00502 
00503       switch(rightDataRank) {
00504         case 1: {
00505           for(int cl = 0; cl < numCells; cl++) {
00506             for(int pt = 0; pt < numPoints; pt++) {
00507                 outputData(cl, pt) = inputDataLeft(cl, pt)*inputDataRight(pt);
00508             } // P-loop
00509           } // C-loop
00510         }// case 1
00511         break;
00512 
00513         case 2: {
00514           for(int cl = 0; cl < numCells; cl++) {
00515             for(int pt = 0; pt < numPoints; pt++) {
00516               temp = 0;
00517               for( int iVec = 0; iVec < dim1Tens; iVec++) {
00518                   temp += inputDataLeft(cl, pt, iVec)*inputDataRight(pt, iVec);
00519               } // D1-loop
00520               outputData(cl, pt) = temp;
00521             } // P-loop
00522           } // C-loop
00523         }// case 2
00524         break;
00525 
00526         case 3: {
00527           for(int cl = 0; cl < numCells; cl++) {
00528             for(int pt = 0; pt < numPoints; pt++) {
00529               temp = 0;
00530               for(int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00531                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00532                     temp += inputDataLeft(cl, pt, iTens1, iTens2)*inputDataRight(pt, iTens1, iTens2);
00533                 } // D1-loop
00534               } // D2-loop
00535               outputData(cl, pt) =  temp;
00536             } // P-loop
00537           } // C-loop
00538         }// case 3
00539         break;
00540 
00541         default:
00542               TEST_FOR_EXCEPTION( !( (rightDataRank == 1) || (rightDataRank == 2) || (rightDataRank == 3) ), std::invalid_argument,
00543                                   ">>> ERROR (ArrayTools::dotMultiplyDataData): This branch of the method is defined only for rank-1, 2 or 3 right data input containers.");
00544       }// rightDataRank
00545 
00546     }
00547     else { //constant data
00548 
00549       switch(rightDataRank) {
00550         case 1: {
00551           for(int cl = 0; cl < numCells; cl++) {
00552             for(int pt = 0; pt < numPoints; pt++) {
00553                 outputData(cl, pt) = inputDataLeft(cl, 0)*inputDataRight(pt);
00554             } // P-loop
00555           } // C-loop
00556         }// case 1
00557         break;
00558 
00559         case 2: {
00560           for(int cl = 0; cl < numCells; cl++) {
00561             for(int pt = 0; pt < numPoints; pt++) {
00562               temp = 0;
00563               for( int iVec = 0; iVec < dim1Tens; iVec++) {
00564                   temp += inputDataLeft(cl, 0, iVec)*inputDataRight(pt, iVec);
00565               } // D1-loop
00566               outputData(cl, pt) = temp;
00567             } // P-loop
00568           } // C-loop
00569         }// case 2
00570         break;
00571 
00572         case 3: {
00573           for(int cl = 0; cl < numCells; cl++) {
00574             for(int pt = 0; pt < numPoints; pt++) {
00575               temp = 0;
00576               for(int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00577                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00578                     temp += inputDataLeft(cl, 0, iTens1, iTens2)*inputDataRight(pt, iTens1, iTens2);
00579                 } // D1-loop
00580               } // D2-loop
00581               outputData(cl, pt) =  temp;
00582             } // P-loop
00583           } // C-loop
00584         }// case 3
00585         break;
00586 
00587         default:
00588               TEST_FOR_EXCEPTION( !( (rightDataRank == 1) || (rightDataRank == 2) || (rightDataRank == 3) ), std::invalid_argument,
00589                                   ">>> ERROR (ArrayTools::dotMultiplyDataData): This branch of the method is defined only for rank-1, 2 or 3 right data input containers.");
00590       }// rightDataRank
00591 
00592     } // numDataPoints
00593 
00594   } // end if (rightDataRank == leftDataRank)
00595 
00596 }// dotMultiplyDataData
00597 
00598 
00599 
00600 } // end namespace Intrepid