|
Intrepid
|
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
1.7.6.1