Intrepid
http://trilinos.sandia.gov/packages/docs/r10.12/packages/intrepid/src/Shared/Intrepid_ArrayToolsDefCloneScale.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 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Pavel Bochev  (pbboche@sandia.gov)
00038 //                    Denis Ridzal  (dridzal@sandia.gov), or
00039 //                    Kara Peterson (kjpeter@sandia.gov)
00040 //
00041 // ************************************************************************
00042 // @HEADER
00043 
00049 namespace Intrepid {
00050 
00051 
00052 template<class Scalar, class ArrayOutFields, class ArrayInFields>
00053 void ArrayTools::cloneFields(ArrayOutFields &       outputFields,
00054                              const ArrayInFields &  inputFields) {
00055 
00056 #ifdef HAVE_INTREPID_DEBUG
00057   TEUCHOS_TEST_FOR_EXCEPTION( ( (inputFields.rank() < 2) || (inputFields.rank() > 4) ), std::invalid_argument,
00058                       ">>> ERROR (ArrayTools::cloneFields): Input fields container must have rank 2, 3, or 4.");
00059   TEUCHOS_TEST_FOR_EXCEPTION( (outputFields.rank() != inputFields.rank()+1), std::invalid_argument,
00060                       ">>> ERROR (ArrayTools::cloneFields): The rank of the input fields container must be one less than the rank of the output fields container.");
00061   for (int i=0; i<inputFields.rank(); i++) {
00062     std::string errmsg  = ">>> ERROR (ArrayTools::cloneFields): Dimensions ";
00063     errmsg += (char)(48+i);
00064     errmsg += " and ";
00065     errmsg += (char)(48+i+1);
00066     errmsg += " of the input and output fields containers must agree!";
00067     TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i+1)), std::invalid_argument, errmsg );
00068   }
00069 #endif
00070 
00071   // get sizes
00072   int invalRank      = inputFields.rank();
00073   int outvalRank     = outputFields.rank();
00074   int numCells       = outputFields.dimension(0);
00075   int numFields      = outputFields.dimension(1);
00076   int numPoints      = outputFields.dimension(2);
00077   int dim1Tens       = 0;
00078   int dim2Tens       = 0;
00079   if (outvalRank > 3) {
00080     dim1Tens = outputFields.dimension(3);
00081     if (outvalRank > 4) {
00082       dim2Tens = outputFields.dimension(4);
00083     }
00084   }
00085 
00086   switch(invalRank) {
00087     case 2: {
00088       for(int cl = 0; cl < numCells; cl++) {
00089         for(int bf = 0; bf < numFields; bf++) {
00090           for(int pt = 0; pt < numPoints; pt++) {
00091             outputFields(cl, bf, pt) = inputFields(bf, pt);
00092           } // P-loop
00093         } // F-loop
00094       } // C-loop
00095     }// case 2
00096     break;
00097 
00098     case 3: {
00099       for(int cl = 0; cl < numCells; cl++) {
00100         for(int bf = 0; bf < numFields; bf++) {
00101           for(int pt = 0; pt < numPoints; pt++) {
00102             for( int iVec = 0; iVec < dim1Tens; iVec++) {
00103               outputFields(cl, bf, pt, iVec) = inputFields(bf, pt, iVec);
00104             } // D1-loop
00105           } // P-loop
00106         } // F-loop
00107       } // C-loop
00108     }// case 3
00109     break;
00110 
00111     case 4: {
00112       for(int cl = 0; cl < numCells; cl++) {
00113         for(int bf = 0; bf < numFields; bf++) {
00114           for(int pt = 0; pt < numPoints; pt++) {
00115             for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00116               for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00117                 outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(bf, pt, iTens1, iTens2);
00118               } // D2-loop
00119             } // D1-loop
00120           } // P-loop
00121         } // F-loop
00122       } // C-loop
00123     }// case 4
00124     break;
00125 
00126     default:
00127       TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
00128                           ">>> ERROR (ArrayTools::cloneFields): This method is defined only for rank-2, 3 or 4 input containers.");
00129   }// invalRank
00130 
00131 } // cloneFields
00132 
00133 
00134 template<class Scalar, class ArrayOutFields, class ArrayInFactors, class ArrayInFields>
00135 void ArrayTools::cloneScaleFields(ArrayOutFields &        outputFields,
00136                                   const ArrayInFactors &  inputFactors,
00137                                   const ArrayInFields &   inputFields) {
00138 
00139 #ifdef HAVE_INTREPID_DEBUG
00140   TEUCHOS_TEST_FOR_EXCEPTION( (inputFactors.rank() != 2), std::invalid_argument,
00141                       ">>> ERROR (ArrayTools::cloneScaleFields): The rank of the input factors container must be 2.");
00142   TEUCHOS_TEST_FOR_EXCEPTION( ( (inputFields.rank() < 2) || (inputFields.rank() > 4) ), std::invalid_argument,
00143                       ">>> ERROR (ArrayTools::cloneScaleFields): Input fields container must have rank 2, 3, or 4.");
00144   TEUCHOS_TEST_FOR_EXCEPTION( (outputFields.rank() != inputFields.rank()+1), std::invalid_argument,
00145                       ">>> ERROR (ArrayTools::cloneScaleFields): The rank of the input fields container must be one less than the rank of the output fields container.");
00146   TEUCHOS_TEST_FOR_EXCEPTION( ( inputFactors.dimension(0) != outputFields.dimension(0) ), std::invalid_argument,
00147                       ">>> ERROR (ArrayTools::cloneScaleFields): Zeroth dimensions of input factors container and output fields container (numbers of integration domains) must agree!");
00148   TEUCHOS_TEST_FOR_EXCEPTION( ( inputFactors.dimension(1) != outputFields.dimension(1) ), std::invalid_argument,
00149                       ">>> ERROR (ArrayTools::cloneScaleFields): First dimensions of input factors container and output fields container (numbers of fields) must agree!");
00150   for (int i=0; i<inputFields.rank(); i++) {
00151     std::string errmsg  = ">>> ERROR (ArrayTools::cloneScaleFields): Dimensions ";
00152     errmsg += (char)(48+i);
00153     errmsg += " and ";
00154     errmsg += (char)(48+i+1);
00155     errmsg += " of the input and output fields containers must agree!";
00156     TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i+1)), std::invalid_argument, errmsg );
00157   }
00158 #endif
00159 
00160   // get sizes
00161   int invalRank      = inputFields.rank();
00162   int outvalRank     = outputFields.rank();
00163   int numCells       = outputFields.dimension(0);
00164   int numFields      = outputFields.dimension(1);
00165   int numPoints      = outputFields.dimension(2);
00166   int dim1Tens       = 0;
00167   int dim2Tens       = 0;
00168   if (outvalRank > 3) {
00169     dim1Tens = outputFields.dimension(3);
00170     if (outvalRank > 4) {
00171       dim2Tens = outputFields.dimension(4);
00172     }
00173   }
00174 
00175   switch(invalRank) {
00176     case 2: {
00177       for(int cl = 0; cl < numCells; cl++) {
00178         for(int bf = 0; bf < numFields; bf++) {
00179           for(int pt = 0; pt < numPoints; pt++) {
00180             outputFields(cl, bf, pt) = inputFields(bf, pt) * inputFactors(cl, bf);
00181           } // P-loop
00182         } // F-loop
00183       } // C-loop
00184     }// case 2
00185     break;
00186 
00187     case 3: {
00188       for(int cl = 0; cl < numCells; cl++) {
00189         for(int bf = 0; bf < numFields; bf++) {
00190           for(int pt = 0; pt < numPoints; pt++) {
00191             for( int iVec = 0; iVec < dim1Tens; iVec++) {
00192               outputFields(cl, bf, pt, iVec) = inputFields(bf, pt, iVec) * inputFactors(cl, bf);
00193             } // D1-loop
00194           } // P-loop
00195         } // F-loop
00196       } // C-loop
00197     }// case 3
00198     break;
00199 
00200     case 4: {
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             for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00205               for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00206                 outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(bf, pt, iTens1, iTens2) * inputFactors(cl, bf);
00207               } // D2-loop
00208             } // D1-loop
00209           } // P-loop
00210         } // F-loop
00211       } // C-loop
00212     }// case 4
00213     break;
00214 
00215     default:
00216       TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
00217                           ">>> ERROR (ArrayTools::cloneScaleFields): This method is defined only for rank-2, 3 or 4 input containers.");
00218   }// invalRank
00219 
00220 } // cloneScaleFields
00221 
00222 
00223 template<class Scalar, class ArrayInOutFields, class ArrayInFactors>
00224 void ArrayTools::scaleFields(ArrayInOutFields &      inoutFields,
00225                              const ArrayInFactors &  inputFactors) {
00226 
00227 #ifdef HAVE_INTREPID_DEBUG
00228   TEUCHOS_TEST_FOR_EXCEPTION( (inputFactors.rank() != 2), std::invalid_argument,
00229                       ">>> ERROR (ArrayTools::scaleFields): The rank of the input factors container must be 2.");
00230   TEUCHOS_TEST_FOR_EXCEPTION( ( (inoutFields.rank() < 3) || (inoutFields.rank() > 5) ), std::invalid_argument,
00231                       ">>> ERROR (ArrayTools::scaleFields): Input/output fields container must have rank 3, 4, or 5.");
00232   TEUCHOS_TEST_FOR_EXCEPTION( ( inputFactors.dimension(0) != inoutFields.dimension(0) ), std::invalid_argument,
00233                       ">>> ERROR (ArrayTools::scaleFields): Zeroth dimensions of input factors container and input/output fields container (numbers of integration domains) must agree!");
00234   TEUCHOS_TEST_FOR_EXCEPTION( ( inputFactors.dimension(1) != inoutFields.dimension(1) ), std::invalid_argument,
00235                       ">>> ERROR (ArrayTools::scaleFields): First dimensions (number of fields) of input factors and input/output fields containers must agree!");
00236 #endif
00237 
00238   // get sizes
00239   int inoutRank      = inoutFields.rank();
00240   int numCells       = inoutFields.dimension(0);
00241   int numFields      = inoutFields.dimension(1);
00242   int numPoints      = inoutFields.dimension(2);
00243   int dim1Tens       = 0;
00244   int dim2Tens       = 0;
00245   if (inoutRank > 3) {
00246     dim1Tens = inoutFields.dimension(3);
00247     if (inoutRank > 4) {
00248       dim2Tens = inoutFields.dimension(4);
00249     }
00250   }
00251 
00252   switch(inoutRank) {
00253     case 3: {
00254       for(int cl = 0; cl < numCells; cl++) {
00255         for(int bf = 0; bf < numFields; bf++) {
00256           for(int pt = 0; pt < numPoints; pt++) {
00257             inoutFields(cl, bf, pt) = inoutFields(cl, bf, pt) * inputFactors(cl, bf);
00258           } // P-loop
00259         } // F-loop
00260       } // C-loop
00261     }// case 2
00262     break;
00263 
00264     case 4: {
00265       for(int cl = 0; cl < numCells; cl++) {
00266         for(int bf = 0; bf < numFields; bf++) {
00267           for(int pt = 0; pt < numPoints; pt++) {
00268             for( int iVec = 0; iVec < dim1Tens; iVec++) {
00269               inoutFields(cl, bf, pt, iVec) = inoutFields(cl, bf, pt, iVec) * inputFactors(cl, bf);
00270             } // D1-loop
00271           }// P-loop
00272         } // F-loop
00273       } // C-loop
00274     }// case 3
00275     break;
00276 
00277     case 5: {
00278       for(int cl = 0; cl < numCells; cl++) {
00279         for(int bf = 0; bf < numFields; bf++) {
00280           for(int pt = 0; pt < numPoints; pt++) {
00281             for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
00282               for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
00283                 inoutFields(cl, bf, pt, iTens1, iTens2) = inoutFields(cl, bf, pt, iTens1, iTens2) * inputFactors(cl, bf);
00284               } // D2-loop
00285             } // D1-loop
00286           } // P-loop
00287         } // F-loop
00288       } // C-loop
00289     }// case 4
00290     break;
00291 
00292     default:
00293       TEUCHOS_TEST_FOR_EXCEPTION( !( (inoutRank == 3) || (inoutRank == 4) || (inoutRank == 5) ), std::invalid_argument,
00294                           ">>> ERROR (ArrayTools::cloneScaleFields): This method is defined only for rank-3, 4 or 5 input/output containers.");
00295   }// inoutRank
00296 
00297 } // scaleFields
00298 
00299 
00300 } // end namespace Intrepid