Intrepid
/usr/src/RPM/BUILD/trilinos10-10.6.4/packages/intrepid/src/Shared/Intrepid_ArrayToolsDefScalar.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::scalarMultiplyDataField(ArrayOutFields &     outputFields,
00039                                          const ArrayInData &  inputData,
00040                                          ArrayInFields &      inputFields,
00041                                          const bool           reciprocal) {
00042 
00043 #ifdef HAVE_INTREPID_DEBUG
00044   TEST_FOR_EXCEPTION( (inputData.rank() != 2), std::invalid_argument,
00045                       ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input data container must have rank 2.");
00046   if (outputFields.rank() <= inputFields.rank()) {
00047     TEST_FOR_EXCEPTION( ( (inputFields.rank() < 3) || (inputFields.rank() > 5) ), std::invalid_argument,
00048                         ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input fields container must have rank 3, 4, or 5.");
00049     TEST_FOR_EXCEPTION( (outputFields.rank() != inputFields.rank()), std::invalid_argument,
00050                         ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input and output fields containers must have the same rank.");
00051     TEST_FOR_EXCEPTION( (inputFields.dimension(0) != inputData.dimension(0) ), std::invalid_argument,
00052                         ">>> ERROR (ArrayTools::scalarMultiplyDataField): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
00053     TEST_FOR_EXCEPTION( ( (inputFields.dimension(2) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
00054                         ">>> 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!");
00055     for (int i=0; i<inputFields.rank(); i++) {
00056       std::string errmsg  = ">>> ERROR (ArrayTools::scalarMultiplyDataField): Dimension ";
00057       errmsg += (char)(48+i);
00058       errmsg += " of the input and output fields containers must agree!";
00059       TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i)), std::invalid_argument, errmsg );
00060     }
00061   }
00062   else {
00063     TEST_FOR_EXCEPTION( ( (inputFields.rank() < 2) || (inputFields.rank() > 4) ), std::invalid_argument,
00064                         ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input fields container must have rank 2, 3, or 4.");
00065     TEST_FOR_EXCEPTION( (outputFields.rank() != inputFields.rank()+1), std::invalid_argument,
00066                         ">>> ERROR (ArrayTools::scalarMultiplyDataField): The rank of the input fields container must be one less than the rank of the output fields container.");
00067     TEST_FOR_EXCEPTION( ( (inputFields.dimension(1) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
00068                         ">>> 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!");
00069     TEST_FOR_EXCEPTION( ( inputData.dimension(0) != outputFields.dimension(0) ), std::invalid_argument,
00070                         ">>> ERROR (ArrayTools::scalarMultiplyDataField): Zeroth dimensions of fields output container and data input containers (number of integration domains) must agree!");
00071     for (int i=0; i<inputFields.rank(); i++) {
00072       std::string errmsg  = ">>> ERROR (ArrayTools::scalarMultiplyDataField): Dimensions ";
00073       errmsg += (char)(48+i);
00074       errmsg += " and ";
00075       errmsg += (char)(48+i+1);
00076       errmsg += " of the input and output fields containers must agree!";
00077       TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i+1)), std::invalid_argument, errmsg );
00078     }
00079   }
00080 #endif
00081 
00082   // get sizes
00083   int invalRank      = inputFields.rank();
00084   int outvalRank     = outputFields.rank();
00085   int numCells       = outputFields.dimension(0);
00086   int numFields      = outputFields.dimension(1);
00087   int numPoints      = outputFields.dimension(2);
00088   int numDataPoints  = inputData.dimension(1);
00089   int dim1Tens       = 0;
00090   int dim2Tens       = 0;
00091   if (outvalRank > 3) {
00092     dim1Tens = outputFields.dimension(3);
00093     if (outvalRank > 4) {
00094       dim2Tens = outputFields.dimension(4);
00095     }
00096   }
00097 
00098   if (outvalRank == invalRank) {
00099 
00100     if (numDataPoints != 1) { // nonconstant data
00101 
00102       switch(invalRank) {
00103         case 3: {
00104           if (reciprocal) {
00105             for(int cl = 0; cl < numCells; cl++) {
00106               for(int bf = 0; bf < numFields; bf++) {
00107                 for(int pt = 0; pt < numPoints; pt++) {
00108                   outputFields(cl, bf, pt) = inputFields(cl, bf, pt)/inputData(cl, pt);
00109                 } // P-loop
00110               } // F-loop
00111             } // C-loop
00112           }
00113           else {
00114             for(int cl = 0; cl < numCells; cl++) {
00115               for(int bf = 0; bf < numFields; bf++) {
00116                 for(int pt = 0; pt < numPoints; pt++) {
00117                   outputFields(cl, bf, pt) = inputFields(cl, bf, pt)*inputData(cl, pt);
00118                 } // P-loop
00119               } // F-loop
00120             } // C-loop
00121           }
00122         }// case 3
00123         break;
00124 
00125         case 4: {
00126           if (reciprocal) {
00127             for(int cl = 0; cl < numCells; cl++) {
00128               for(int bf = 0; bf < numFields; bf++) {
00129                 for(int pt = 0; pt < numPoints; pt++) {
00130                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00131                     outputFields(cl, bf, pt, iVec) = inputFields(cl, bf, pt, iVec)/inputData(cl, pt);
00132                   } // D1-loop
00133                 } // P-loop
00134               } // F-loop
00135             } // C-loop
00136           }
00137           else {
00138             for(int cl = 0; cl < numCells; cl++) {
00139               for(int bf = 0; bf < numFields; bf++) {
00140                 for(int pt = 0; pt < numPoints; pt++) {
00141                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00142                     outputFields(cl, bf, pt, iVec) = inputFields(cl, bf, pt, iVec)*inputData(cl, pt);
00143                   } // D1-loop
00144                 } // P-loop
00145               } // F-loop
00146             } // C-loop
00147           }
00148         }// case 4
00149         break;
00150 
00151         case 5: {
00152           if (reciprocal) {
00153             for(int cl = 0; cl < numCells; cl++) {
00154               for(int bf = 0; bf < numFields; bf++) {
00155                 for(int pt = 0; pt < numPoints; pt++) {
00156                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00157                     for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00158                       outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(cl, bf, pt, iTens1, iTens2)/inputData(cl, pt);
00159                     } // D2-loop
00160                   } // D1-loop
00161                 } // F-loop
00162               } // P-loop
00163             } // C-loop
00164           }
00165           else {
00166             for(int cl = 0; cl < numCells; cl++) {
00167               for(int bf = 0; bf < numFields; bf++) {
00168                 for(int pt = 0; pt < numPoints; pt++) {
00169                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00170                     for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00171                       outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(cl, bf, pt, iTens1, iTens2)*inputData(cl, pt);
00172                     } // D2-loop
00173                   } // D1-loop
00174                 } // F-loop
00175               } // P-loop
00176             } // C-loop
00177           }
00178         }// case 5
00179         break;
00180 
00181         default:
00182               TEST_FOR_EXCEPTION( !( (invalRank == 3) || (invalRank == 4) || (invalRank == 5) ), std::invalid_argument,
00183                                   ">>> ERROR (ArrayTools::scalarMultiplyDataField): This branch of the method is defined only for rank-3,4 or 5 containers.");
00184       }// invalRank
00185 
00186     }
00187     else { //constant data
00188 
00189       switch(invalRank) {
00190         case 3: {
00191           if (reciprocal) {
00192             for(int cl = 0; cl < numCells; cl++) {
00193               for(int bf = 0; bf < numFields; bf++) {
00194                 for(int pt = 0; pt < numPoints; pt++) {
00195                   outputFields(cl, bf, pt) = inputFields(cl, bf, pt)/inputData(cl, 0);
00196                 } // P-loop
00197               } // F-loop
00198             } // C-loop
00199           }
00200           else {
00201             for(int cl = 0; cl < numCells; cl++) {
00202               for(int bf = 0; bf < numFields; bf++) {
00203                 for(int pt = 0; pt < numPoints; pt++) {
00204                   outputFields(cl, bf, pt) = inputFields(cl, bf, pt)*inputData(cl, 0);
00205                 } // P-loop
00206               } // F-loop
00207             } // C-loop
00208           }
00209         }// case 3
00210         break;
00211 
00212         case 4: {
00213           if (reciprocal) {
00214             for(int cl = 0; cl < numCells; cl++) {
00215               for(int bf = 0; bf < numFields; bf++) {
00216                 for(int pt = 0; pt < numPoints; pt++) {
00217                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00218                     outputFields(cl, bf, pt, iVec) = inputFields(cl, bf, pt, iVec)/inputData(cl, 0);
00219                   } // D1-loop
00220                 } // P-loop
00221               } // F-loop
00222             } // C-loop
00223           }
00224           else {
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                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00229                     outputFields(cl, bf, pt, iVec) = inputFields(cl, bf, pt, iVec)*inputData(cl, 0);
00230                   } // D1-loop
00231                 } // P-loop
00232               } // F-loop
00233             } // C-loop
00234           }
00235         }// case 4
00236         break;
00237 
00238         case 5: {
00239           if (reciprocal) {
00240             for(int cl = 0; cl < numCells; cl++) {
00241               for(int bf = 0; bf < numFields; bf++) {
00242                 for(int pt = 0; pt < numPoints; pt++) {
00243                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00244                     for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00245                       outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(cl, bf, pt, iTens1, iTens2)/inputData(cl, 0);
00246                     } // D2-loop
00247                   } // D1-loop
00248                 } // F-loop
00249               } // P-loop
00250             } // C-loop
00251           }
00252           else {
00253             for(int cl = 0; cl < numCells; cl++) {
00254               for(int bf = 0; bf < numFields; bf++) {
00255                 for(int pt = 0; pt < numPoints; pt++) {
00256                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00257                     for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00258                       outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(cl, bf, pt, iTens1, iTens2)*inputData(cl, 0);
00259                     } // D2-loop
00260                   } // D1-loop
00261                 } // F-loop
00262               } // P-loop
00263             } // C-loop
00264           }
00265         }// case 5
00266         break;
00267 
00268         default:
00269               TEST_FOR_EXCEPTION( !( (invalRank == 3) || (invalRank == 4) || (invalRank == 5) ), std::invalid_argument,
00270                                   ">>> ERROR (ArrayTools::scalarMultiplyDataField): This branch of the method is defined only for rank-3, 4 or 5 input containers.");
00271 
00272       } // invalRank
00273     } // numDataPoints
00274 
00275   }
00276   else {
00277 
00278     if (numDataPoints != 1) { // nonconstant data
00279 
00280       switch(invalRank) {
00281         case 2: {
00282           if (reciprocal) {
00283             for(int cl = 0; cl < numCells; cl++) {
00284               for(int bf = 0; bf < numFields; bf++) {
00285                 for(int pt = 0; pt < numPoints; pt++) {
00286                   outputFields(cl, bf, pt) = inputFields(bf, pt)/inputData(cl, pt);
00287                 } // P-loop
00288               } // F-loop
00289             } // C-loop
00290           }
00291           else {
00292             for(int cl = 0; cl < numCells; cl++) {
00293               for(int bf = 0; bf < numFields; bf++) {
00294                 for(int pt = 0; pt < numPoints; pt++) {
00295                   outputFields(cl, bf, pt) = inputFields(bf, pt)*inputData(cl, pt);
00296                 } // P-loop
00297               } // F-loop
00298             } // C-loop
00299           }
00300         }// case 2
00301         break;
00302 
00303         case 3: {
00304           if (reciprocal) {
00305             for(int cl = 0; cl < numCells; cl++) {
00306               for(int bf = 0; bf < numFields; bf++) {
00307                 for(int pt = 0; pt < numPoints; pt++) {
00308                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00309                     outputFields(cl, bf, pt, iVec) = inputFields(bf, pt, iVec)/inputData(cl, pt);
00310                   } // D1-loop
00311                 } // P-loop
00312               } // F-loop
00313             } // C-loop
00314           }
00315           else {
00316             for(int cl = 0; cl < numCells; cl++) {
00317               for(int bf = 0; bf < numFields; bf++) {
00318                 for(int pt = 0; pt < numPoints; pt++) {
00319                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00320                     outputFields(cl, bf, pt, iVec) = inputFields(bf, pt, iVec)*inputData(cl, pt);
00321                   } // D1-loop
00322                 } // P-loop
00323               } // F-loop
00324             } // C-loop
00325           }
00326         }// case 3
00327         break;
00328 
00329         case 4: {
00330           if (reciprocal) {
00331             for(int cl = 0; cl < numCells; cl++) {
00332               for(int bf = 0; bf < numFields; bf++) {
00333                 for(int pt = 0; pt < numPoints; pt++) {
00334                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00335                     for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00336                       outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(bf, pt, iTens1, iTens2)/inputData(cl, pt);
00337                     } // D2-loop
00338                   } // D1-loop
00339                 } // F-loop
00340               } // P-loop
00341             } // C-loop
00342           }
00343           else {
00344             for(int cl = 0; cl < numCells; cl++) {
00345               for(int bf = 0; bf < numFields; bf++) {
00346                 for(int pt = 0; pt < numPoints; pt++) {
00347                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00348                     for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00349                       outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(bf, pt, iTens1, iTens2)*inputData(cl, pt);
00350                     } // D2-loop
00351                   } // D1-loop
00352                 } // F-loop
00353               } // P-loop
00354             } // C-loop
00355           }
00356         }// case 4
00357         break;
00358 
00359         default:
00360               TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
00361                                   ">>> ERROR (ArrayTools::scalarMultiplyDataField): This branch of the method is defined only for rank-2, 3 or 4 input containers.");
00362       }// invalRank
00363 
00364     }
00365     else { //constant data
00366 
00367       switch(invalRank) {
00368         case 2: {
00369           if (reciprocal) {
00370             for(int cl = 0; cl < numCells; cl++) {
00371               for(int bf = 0; bf < numFields; bf++) {
00372                 for(int pt = 0; pt < numPoints; pt++) {
00373                   outputFields(cl, bf, pt) = inputFields(bf, pt)/inputData(cl, 0);
00374                 } // P-loop
00375               } // F-loop
00376             } // C-loop
00377           }
00378           else {
00379             for(int cl = 0; cl < numCells; cl++) {
00380               for(int bf = 0; bf < numFields; bf++) {
00381                 for(int pt = 0; pt < numPoints; pt++) {
00382                   outputFields(cl, bf, pt) = inputFields(bf, pt)*inputData(cl, 0);
00383                 } // P-loop
00384               } // F-loop
00385             } // C-loop
00386           }
00387         }// case 2
00388         break;
00389 
00390         case 3: {
00391           if (reciprocal) {
00392             for(int cl = 0; cl < numCells; cl++) {
00393               for(int bf = 0; bf < numFields; bf++) {
00394                 for(int pt = 0; pt < numPoints; pt++) {
00395                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00396                     outputFields(cl, bf, pt, iVec) = inputFields(bf, pt, iVec)/inputData(cl, 0);
00397                   } // D1-loop
00398                 } // P-loop
00399               } // F-loop
00400             } // C-loop
00401           }
00402           else {
00403             for(int cl = 0; cl < numCells; cl++) {
00404               for(int bf = 0; bf < numFields; bf++) {
00405                 for(int pt = 0; pt < numPoints; pt++) {
00406                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00407                     outputFields(cl, bf, pt, iVec) = inputFields(bf, pt, iVec)*inputData(cl, 0);
00408                   } // D1-loop
00409                 } // P-loop
00410               } // F-loop
00411             } // C-loop
00412           }
00413         }// case 3
00414         break;
00415 
00416         case 4: {
00417           if (reciprocal) {
00418             for(int cl = 0; cl < numCells; cl++) {
00419               for(int bf = 0; bf < numFields; bf++) {
00420                 for(int pt = 0; pt < numPoints; pt++) {
00421                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00422                     for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00423                       outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(bf, pt, iTens1, iTens2)/inputData(cl, 0);
00424                     } // D2-loop
00425                   } // D1-loop
00426                 } // F-loop
00427               } // P-loop
00428             } // C-loop
00429           }
00430           else {
00431             for(int cl = 0; cl < numCells; cl++) {
00432               for(int bf = 0; bf < numFields; bf++) {
00433                 for(int pt = 0; pt < numPoints; pt++) {
00434                   for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00435                     for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00436                       outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(bf, pt, iTens1, iTens2)*inputData(cl, 0);
00437                     } // D2-loop
00438                   } // D1-loop
00439                 } // F-loop
00440               } // P-loop
00441             } // C-loop
00442           }
00443         }// case 4
00444         break;
00445 
00446         default:
00447               TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 3) ), std::invalid_argument,
00448                                   ">>> ERROR (ArrayTools::scalarMultiplyDataField): This branch of the method is defined only for rank-2, 3 or 4 input containers.");
00449 
00450       } // invalRank
00451     } // numDataPoints
00452 
00453   } // end if (outvalRank = invalRank)
00454 
00455 } // scalarMultiplyDataField
00456 
00457 
00458 
00459 template<class Scalar, class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight>
00460 void ArrayTools::scalarMultiplyDataData(ArrayOutData &           outputData,
00461                                         ArrayInDataLeft &        inputDataLeft,
00462                                         ArrayInDataRight &       inputDataRight,
00463                                         const bool               reciprocal) {
00464 
00465 #ifdef HAVE_INTREPID_DEBUG
00466   TEST_FOR_EXCEPTION( (inputDataLeft.rank() != 2), std::invalid_argument,
00467                       ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
00468   if (outputData.rank() <= inputDataRight.rank()) {
00469     TEST_FOR_EXCEPTION( ( (inputDataRight.rank() < 2) || (inputDataRight.rank() > 4) ), std::invalid_argument,
00470                         ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 2, 3, or 4.");
00471     TEST_FOR_EXCEPTION( (outputData.rank() != inputDataRight.rank()), std::invalid_argument,
00472                         ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input and output data containers must have the same rank.");
00473     TEST_FOR_EXCEPTION( (inputDataRight.dimension(0) != inputDataLeft.dimension(0) ), std::invalid_argument,
00474                         ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions (number of integration domains) of the left and right data input containers must agree!");
00475     TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(1) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
00476                         ">>> 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!");
00477     for (int i=0; i<inputDataRight.rank(); i++) {
00478       std::string errmsg  = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimension ";
00479       errmsg += (char)(48+i);
00480       errmsg += " of the right input and output data containers must agree!";
00481       TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i)), std::invalid_argument, errmsg );
00482     }
00483   }
00484   else {
00485     TEST_FOR_EXCEPTION( ( (inputDataRight.rank() < 1) || (inputDataRight.rank() > 3) ), std::invalid_argument,
00486                         ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 1, 2, or 3.");
00487     TEST_FOR_EXCEPTION( (outputData.rank() != inputDataRight.rank()+1), std::invalid_argument,
00488                         ">>> ERROR (ArrayTools::scalarMultiplyDataData): The rank of the right input data container must be one less than the rank of the output data container.");
00489     TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(0) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
00490                         ">>> 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!");
00491     TEST_FOR_EXCEPTION( ( inputDataLeft.dimension(0) != outputData.dimension(0) ), std::invalid_argument,
00492                         ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions of data output and left data input containers (number of integration domains) must agree!");
00493     for (int i=0; i<inputDataRight.rank(); i++) {
00494       std::string errmsg  = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimensions ";
00495       errmsg += (char)(48+i);
00496       errmsg += " and ";
00497       errmsg += (char)(48+i+1);
00498       errmsg += " of the right input and output data containers must agree!";
00499       TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i+1)), std::invalid_argument, errmsg );
00500     }
00501   }
00502 #endif
00503 
00504   // get sizes
00505   int invalRank      = inputDataRight.rank();
00506   int outvalRank     = outputData.rank();
00507   int numCells       = outputData.dimension(0);
00508   int numPoints      = outputData.dimension(1);
00509   int numDataPoints  = inputDataLeft.dimension(1);
00510   int dim1Tens       = 0;
00511   int dim2Tens       = 0;
00512   if (outvalRank > 2) {
00513     dim1Tens = outputData.dimension(2);
00514     if (outvalRank > 3) {
00515       dim2Tens = outputData.dimension(3);
00516     }
00517   }
00518 
00519   if (outvalRank == invalRank) {
00520 
00521     if (numDataPoints != 1) { // nonconstant data
00522 
00523       switch(invalRank) {
00524         case 2: {
00525           if (reciprocal) {
00526             for(int cl = 0; cl < numCells; cl++) {
00527               for(int pt = 0; pt < numPoints; pt++) {
00528                   outputData(cl, pt) = inputDataRight(cl, pt)/inputDataLeft(cl, pt);
00529               } // P-loop
00530             } // C-loop
00531           }
00532           else {
00533             for(int cl = 0; cl < numCells; cl++) {
00534               for(int pt = 0; pt < numPoints; pt++) {
00535                   outputData(cl, pt) = inputDataRight(cl, pt)*inputDataLeft(cl, pt);
00536               } // P-loop
00537             } // C-loop
00538           }
00539         }// case 2
00540         break;
00541 
00542         case 3: {
00543           if (reciprocal) {
00544             for(int cl = 0; cl < numCells; cl++) {
00545               for(int pt = 0; pt < numPoints; pt++) {
00546                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00547                     outputData(cl, pt, iVec) = inputDataRight(cl, pt, iVec)/inputDataLeft(cl, pt);
00548                 } // D1-loop
00549               } // P-loop
00550             } // C-loop
00551           }
00552           else {
00553             for(int cl = 0; cl < numCells; cl++) {
00554               for(int pt = 0; pt < numPoints; pt++) {
00555                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00556                     outputData(cl, pt, iVec) = inputDataRight(cl, pt, iVec)*inputDataLeft(cl, pt);
00557                 } // D1-loop
00558               } // P-loop
00559             } // C-loop
00560           }
00561         }// case 3
00562         break;
00563 
00564         case 4: {
00565           if (reciprocal) {
00566             for(int cl = 0; cl < numCells; cl++) {
00567               for(int pt = 0; pt < numPoints; pt++) {
00568                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00569                   for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00570                       outputData(cl, pt, iTens1, iTens2) = inputDataRight(cl, pt, iTens1, iTens2)/inputDataLeft(cl, pt);
00571                   } // D2-loop
00572                 } // D1-loop
00573               } // P-loop
00574             } // C-loop
00575           }
00576           else {
00577             for(int cl = 0; cl < numCells; cl++) {
00578               for(int pt = 0; pt < numPoints; pt++) {
00579                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00580                   for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00581                       outputData(cl, pt, iTens1, iTens2) = inputDataRight(cl, pt, iTens1, iTens2)*inputDataLeft(cl, pt);
00582                   } // D2-loop
00583                 } // D1-loop
00584               } // P-loop
00585             } // C-loop
00586           }
00587         }// case 4
00588         break;
00589 
00590         default:
00591               TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
00592                                   ">>> ERROR (ArrayTools::scalarMultiplyDataData): This branch of the method is defined only for rank-2, 3 or 4 containers.");
00593       }// invalRank
00594 
00595     }
00596     else { // constant left data
00597 
00598       switch(invalRank) {
00599         case 2: {
00600           if (reciprocal) {
00601             for(int cl = 0; cl < numCells; cl++) {
00602               for(int pt = 0; pt < numPoints; pt++) {
00603                   outputData(cl, pt) = inputDataRight(cl, pt)/inputDataLeft(cl, 0);
00604               } // P-loop
00605             } // C-loop
00606           }
00607           else {
00608             for(int cl = 0; cl < numCells; cl++) {
00609               for(int pt = 0; pt < numPoints; pt++) {
00610                   outputData(cl, pt) = inputDataRight(cl, pt)*inputDataLeft(cl, 0);
00611               } // P-loop
00612             } // C-loop
00613           }
00614         }// case 2
00615         break;
00616 
00617         case 3: {
00618           if (reciprocal) {
00619             for(int cl = 0; cl < numCells; cl++) {
00620               for(int pt = 0; pt < numPoints; pt++) {
00621                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00622                     outputData(cl, pt, iVec) = inputDataRight(cl, pt, iVec)/inputDataLeft(cl, 0);
00623                 } // D1-loop
00624               } // P-loop
00625             } // C-loop
00626           }
00627           else {
00628             for(int cl = 0; cl < numCells; cl++) {
00629               for(int pt = 0; pt < numPoints; pt++) {
00630                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00631                     outputData(cl, pt, iVec) = inputDataRight(cl, pt, iVec)*inputDataLeft(cl, 0);
00632                 } // D1-loop
00633               } // P-loop
00634             } // C-loop
00635           }
00636         }// case 3
00637         break;
00638 
00639         case 4: {
00640           if (reciprocal) {
00641             for(int cl = 0; cl < numCells; cl++) {
00642               for(int pt = 0; pt < numPoints; pt++) {
00643                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00644                   for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00645                       outputData(cl, pt, iTens1, iTens2) = inputDataRight(cl, pt, iTens1, iTens2)/inputDataLeft(cl, 0);
00646                   } // D2-loop
00647                 } // D1-loop
00648               } // P-loop
00649             } // C-loop
00650           }
00651           else {
00652             for(int cl = 0; cl < numCells; cl++) {
00653               for(int pt = 0; pt < numPoints; pt++) {
00654                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00655                   for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00656                       outputData(cl, pt, iTens1, iTens2) = inputDataRight(cl, pt, iTens1, iTens2)*inputDataLeft(cl, 0);
00657                   } // D2-loop
00658                 } // D1-loop
00659               } // P-loop
00660             } // C-loop
00661           }
00662         }// case 4
00663         break;
00664 
00665         default:
00666               TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
00667                                   ">>> ERROR (ArrayTools::scalarMultiplyDataData): This branch of the method is defined only for rank-2, 3 or 4 input containers.");
00668 
00669       } // invalRank
00670     } // numDataPoints
00671 
00672   }
00673   else {
00674 
00675     if (numDataPoints != 1) { // nonconstant data
00676 
00677       switch(invalRank) {
00678         case 1: {
00679           if (reciprocal) {
00680             for(int cl = 0; cl < numCells; cl++) {
00681               for(int pt = 0; pt < numPoints; pt++) {
00682                   outputData(cl, pt) = inputDataRight(pt)/inputDataLeft(cl, pt);
00683               } // P-loop
00684             } // C-loop
00685           }
00686           else {
00687             for(int cl = 0; cl < numCells; cl++) {
00688               for(int pt = 0; pt < numPoints; pt++) {
00689                   outputData(cl, pt) = inputDataRight(pt)*inputDataLeft(cl, pt);
00690               } // P-loop
00691             } // C-loop
00692           }
00693         }// case 1
00694         break;
00695 
00696         case 2: {
00697           if (reciprocal) {
00698             for(int cl = 0; cl < numCells; cl++) {
00699               for(int pt = 0; pt < numPoints; pt++) {
00700                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00701                     outputData(cl, pt, iVec) = inputDataRight(pt, iVec)/inputDataLeft(cl, pt);
00702                 } // D1-loop
00703               } // P-loop
00704             } // C-loop
00705           }
00706           else {
00707             for(int cl = 0; cl < numCells; cl++) {
00708               for(int pt = 0; pt < numPoints; pt++) {
00709                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00710                     outputData(cl, pt, iVec) = inputDataRight(pt, iVec)*inputDataLeft(cl, pt);
00711                 } // D1-loop
00712               } // P-loop
00713             } // C-loop
00714           }
00715         }// case 2
00716         break;
00717 
00718         case 3: {
00719           if (reciprocal) {
00720             for(int cl = 0; cl < numCells; cl++) {
00721               for(int pt = 0; pt < numPoints; pt++) {
00722                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00723                   for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00724                       outputData(cl, pt, iTens1, iTens2) = inputDataRight(pt, iTens1, iTens2)/inputDataLeft(cl, pt);
00725                   } // D2-loop
00726                 } // D1-loop
00727               } // P-loop
00728             } // C-loop
00729           }
00730           else {
00731             for(int cl = 0; cl < numCells; cl++) {
00732               for(int pt = 0; pt < numPoints; pt++) {
00733                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00734                   for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00735                       outputData(cl, pt, iTens1, iTens2) = inputDataRight(pt, iTens1, iTens2)*inputDataLeft(cl, pt);
00736                   } // D2-loop
00737                 } // D1-loop
00738               } // P-loop
00739             } // C-loop
00740           }
00741         }// case 3
00742         break;
00743 
00744         default:
00745               TEST_FOR_EXCEPTION( !( (invalRank == 1) || (invalRank == 2) || (invalRank == 3) ), std::invalid_argument,
00746                                   ">>> ERROR (ArrayTools::scalarMultiplyDataData): This branch of the method is defined only for rank-1, 2 or 3 input containers.");
00747       }// invalRank
00748 
00749     }
00750     else { //constant data
00751 
00752       switch(invalRank) {
00753         case 1: {
00754           if (reciprocal) {
00755             for(int cl = 0; cl < numCells; cl++) {
00756               for(int pt = 0; pt < numPoints; pt++) {
00757                   outputData(cl, pt) = inputDataRight(pt)/inputDataLeft(cl, 0);
00758               } // P-loop
00759             } // C-loop
00760           }
00761           else {
00762             for(int cl = 0; cl < numCells; cl++) {
00763               for(int pt = 0; pt < numPoints; pt++) {
00764                   outputData(cl, pt) = inputDataRight(pt)*inputDataLeft(cl, 0);
00765               } // P-loop
00766             } // C-loop
00767           }
00768         }// case 1
00769         break;
00770 
00771         case 2: {
00772           if (reciprocal) {
00773             for(int cl = 0; cl < numCells; cl++) {
00774               for(int pt = 0; pt < numPoints; pt++) {
00775                   for( int iVec = 0; iVec < dim1Tens; iVec++) {
00776                     outputData(cl, pt, iVec) = inputDataRight(pt, iVec)/inputDataLeft(cl, 0);
00777                 } // D1-loop
00778               } // P-loop
00779             } // C-loop
00780           }
00781           else {
00782             for(int cl = 0; cl < numCells; cl++) {
00783               for(int pt = 0; pt < numPoints; pt++) {
00784                 for( int iVec = 0; iVec < dim1Tens; iVec++) {
00785                     outputData(cl, pt, iVec) = inputDataRight(pt, iVec)*inputDataLeft(cl, 0);
00786                 } // D1-loop
00787               } // P-loop
00788             } // C-loop
00789           }
00790         }// case 2
00791         break;
00792 
00793         case 3: {
00794           if (reciprocal) {
00795             for(int cl = 0; cl < numCells; cl++) {
00796               for(int pt = 0; pt < numPoints; pt++) {
00797                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00798                   for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00799                       outputData(cl, pt, iTens1, iTens2) = inputDataRight(pt, iTens1, iTens2)/inputDataLeft(cl, 0);
00800                   } // D2-loop
00801                 } // D1-loop
00802               } // P-loop
00803             } // C-loop
00804           }
00805           else {
00806             for(int cl = 0; cl < numCells; cl++) {
00807               for(int pt = 0; pt < numPoints; pt++) {
00808                 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00809                   for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00810                       outputData(cl, pt, iTens1, iTens2) = inputDataRight(pt, iTens1, iTens2)*inputDataLeft(cl, 0);
00811                   } // D2-loop
00812                 } // D1-loop
00813               } // P-loop
00814             } // C-loop
00815           }
00816         }// case 3
00817         break;
00818 
00819         default:
00820               TEST_FOR_EXCEPTION( !( (invalRank == 1) || (invalRank == 2) || (invalRank == 3) ), std::invalid_argument,
00821                                   ">>> ERROR (ArrayTools::scalarMultiplyDataData): This branch of the method is defined only for rank-1, 2 or 3 input containers.");
00822 
00823       } // invalRank
00824     } // numDataPoints
00825 
00826   } // end if (outvalRank = invalRank)
00827 
00828 } // scalarMultiplyDataData
00829 
00830 } // end namespace Intrepid