|
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 // 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 00038 template<class Scalar, class ArrayOutFields, class ArrayInFields> 00039 void ArrayTools::cloneFields(ArrayOutFields & outputFields, 00040 const ArrayInFields & inputFields) { 00041 00042 #ifdef HAVE_INTREPID_DEBUG 00043 TEST_FOR_EXCEPTION( ( (inputFields.rank() < 2) || (inputFields.rank() > 4) ), std::invalid_argument, 00044 ">>> ERROR (ArrayTools::cloneFields): Input fields container must have rank 2, 3, or 4."); 00045 TEST_FOR_EXCEPTION( (outputFields.rank() != inputFields.rank()+1), std::invalid_argument, 00046 ">>> ERROR (ArrayTools::cloneFields): The rank of the input fields container must be one less than the rank of the output fields container."); 00047 for (int i=0; i<inputFields.rank(); i++) { 00048 std::string errmsg = ">>> ERROR (ArrayTools::cloneFields): Dimensions "; 00049 errmsg += (char)(48+i); 00050 errmsg += " and "; 00051 errmsg += (char)(48+i+1); 00052 errmsg += " of the input and output fields containers must agree!"; 00053 TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i+1)), std::invalid_argument, errmsg ); 00054 } 00055 #endif 00056 00057 // get sizes 00058 int invalRank = inputFields.rank(); 00059 int outvalRank = outputFields.rank(); 00060 int numCells = outputFields.dimension(0); 00061 int numFields = outputFields.dimension(1); 00062 int numPoints = outputFields.dimension(2); 00063 int dim1Tens = 0; 00064 int dim2Tens = 0; 00065 if (outvalRank > 3) { 00066 dim1Tens = outputFields.dimension(3); 00067 if (outvalRank > 4) { 00068 dim2Tens = outputFields.dimension(4); 00069 } 00070 } 00071 00072 switch(invalRank) { 00073 case 2: { 00074 for(int cl = 0; cl < numCells; cl++) { 00075 for(int bf = 0; bf < numFields; bf++) { 00076 for(int pt = 0; pt < numPoints; pt++) { 00077 outputFields(cl, bf, pt) = inputFields(bf, pt); 00078 } // P-loop 00079 } // F-loop 00080 } // C-loop 00081 }// case 2 00082 break; 00083 00084 case 3: { 00085 for(int cl = 0; cl < numCells; cl++) { 00086 for(int bf = 0; bf < numFields; bf++) { 00087 for(int pt = 0; pt < numPoints; pt++) { 00088 for( int iVec = 0; iVec < dim1Tens; iVec++) { 00089 outputFields(cl, bf, pt, iVec) = inputFields(bf, pt, iVec); 00090 } // D1-loop 00091 } // P-loop 00092 } // F-loop 00093 } // C-loop 00094 }// case 3 00095 break; 00096 00097 case 4: { 00098 for(int cl = 0; cl < numCells; cl++) { 00099 for(int bf = 0; bf < numFields; bf++) { 00100 for(int pt = 0; pt < numPoints; pt++) { 00101 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) { 00102 for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) { 00103 outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(bf, pt, iTens1, iTens2); 00104 } // D2-loop 00105 } // D1-loop 00106 } // P-loop 00107 } // F-loop 00108 } // C-loop 00109 }// case 4 00110 break; 00111 00112 default: 00113 TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument, 00114 ">>> ERROR (ArrayTools::cloneFields): This method is defined only for rank-2, 3 or 4 input containers."); 00115 }// invalRank 00116 00117 } // cloneFields 00118 00119 00120 template<class Scalar, class ArrayOutFields, class ArrayInFactors, class ArrayInFields> 00121 void ArrayTools::cloneScaleFields(ArrayOutFields & outputFields, 00122 const ArrayInFactors & inputFactors, 00123 const ArrayInFields & inputFields) { 00124 00125 #ifdef HAVE_INTREPID_DEBUG 00126 TEST_FOR_EXCEPTION( (inputFactors.rank() != 2), std::invalid_argument, 00127 ">>> ERROR (ArrayTools::cloneScaleFields): The rank of the input factors container must be 2."); 00128 TEST_FOR_EXCEPTION( ( (inputFields.rank() < 2) || (inputFields.rank() > 4) ), std::invalid_argument, 00129 ">>> ERROR (ArrayTools::cloneScaleFields): Input fields container must have rank 2, 3, or 4."); 00130 TEST_FOR_EXCEPTION( (outputFields.rank() != inputFields.rank()+1), std::invalid_argument, 00131 ">>> ERROR (ArrayTools::cloneScaleFields): The rank of the input fields container must be one less than the rank of the output fields container."); 00132 TEST_FOR_EXCEPTION( ( inputFactors.dimension(0) != outputFields.dimension(0) ), std::invalid_argument, 00133 ">>> ERROR (ArrayTools::cloneScaleFields): Zeroth dimensions of input factors container and output fields container (numbers of integration domains) must agree!"); 00134 TEST_FOR_EXCEPTION( ( inputFactors.dimension(1) != outputFields.dimension(1) ), std::invalid_argument, 00135 ">>> ERROR (ArrayTools::cloneScaleFields): First dimensions of input factors container and output fields container (numbers of fields) must agree!"); 00136 for (int i=0; i<inputFields.rank(); i++) { 00137 std::string errmsg = ">>> ERROR (ArrayTools::cloneScaleFields): Dimensions "; 00138 errmsg += (char)(48+i); 00139 errmsg += " and "; 00140 errmsg += (char)(48+i+1); 00141 errmsg += " of the input and output fields containers must agree!"; 00142 TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i+1)), std::invalid_argument, errmsg ); 00143 } 00144 #endif 00145 00146 // get sizes 00147 int invalRank = inputFields.rank(); 00148 int outvalRank = outputFields.rank(); 00149 int numCells = outputFields.dimension(0); 00150 int numFields = outputFields.dimension(1); 00151 int numPoints = outputFields.dimension(2); 00152 int dim1Tens = 0; 00153 int dim2Tens = 0; 00154 if (outvalRank > 3) { 00155 dim1Tens = outputFields.dimension(3); 00156 if (outvalRank > 4) { 00157 dim2Tens = outputFields.dimension(4); 00158 } 00159 } 00160 00161 switch(invalRank) { 00162 case 2: { 00163 for(int cl = 0; cl < numCells; cl++) { 00164 for(int bf = 0; bf < numFields; bf++) { 00165 for(int pt = 0; pt < numPoints; pt++) { 00166 outputFields(cl, bf, pt) = inputFields(bf, pt) * inputFactors(cl, bf); 00167 } // P-loop 00168 } // F-loop 00169 } // C-loop 00170 }// case 2 00171 break; 00172 00173 case 3: { 00174 for(int cl = 0; cl < numCells; cl++) { 00175 for(int bf = 0; bf < numFields; bf++) { 00176 for(int pt = 0; pt < numPoints; pt++) { 00177 for( int iVec = 0; iVec < dim1Tens; iVec++) { 00178 outputFields(cl, bf, pt, iVec) = inputFields(bf, pt, iVec) * inputFactors(cl, bf); 00179 } // D1-loop 00180 } // P-loop 00181 } // F-loop 00182 } // C-loop 00183 }// case 3 00184 break; 00185 00186 case 4: { 00187 for(int cl = 0; cl < numCells; cl++) { 00188 for(int bf = 0; bf < numFields; bf++) { 00189 for(int pt = 0; pt < numPoints; pt++) { 00190 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) { 00191 for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) { 00192 outputFields(cl, bf, pt, iTens1, iTens2) = inputFields(bf, pt, iTens1, iTens2) * inputFactors(cl, bf); 00193 } // D2-loop 00194 } // D1-loop 00195 } // P-loop 00196 } // F-loop 00197 } // C-loop 00198 }// case 4 00199 break; 00200 00201 default: 00202 TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument, 00203 ">>> ERROR (ArrayTools::cloneScaleFields): This method is defined only for rank-2, 3 or 4 input containers."); 00204 }// invalRank 00205 00206 } // cloneScaleFields 00207 00208 00209 template<class Scalar, class ArrayInOutFields, class ArrayInFactors> 00210 void ArrayTools::scaleFields(ArrayInOutFields & inoutFields, 00211 const ArrayInFactors & inputFactors) { 00212 00213 #ifdef HAVE_INTREPID_DEBUG 00214 TEST_FOR_EXCEPTION( (inputFactors.rank() != 2), std::invalid_argument, 00215 ">>> ERROR (ArrayTools::scaleFields): The rank of the input factors container must be 2."); 00216 TEST_FOR_EXCEPTION( ( (inoutFields.rank() < 3) || (inoutFields.rank() > 5) ), std::invalid_argument, 00217 ">>> ERROR (ArrayTools::scaleFields): Input/output fields container must have rank 3, 4, or 5."); 00218 TEST_FOR_EXCEPTION( ( inputFactors.dimension(0) != inoutFields.dimension(0) ), std::invalid_argument, 00219 ">>> ERROR (ArrayTools::scaleFields): Zeroth dimensions of input factors container and input/output fields container (numbers of integration domains) must agree!"); 00220 TEST_FOR_EXCEPTION( ( inputFactors.dimension(1) != inoutFields.dimension(1) ), std::invalid_argument, 00221 ">>> ERROR (ArrayTools::scaleFields): First dimensions (number of fields) of input factors and input/output fields containers must agree!"); 00222 #endif 00223 00224 // get sizes 00225 int inoutRank = inoutFields.rank(); 00226 int numCells = inoutFields.dimension(0); 00227 int numFields = inoutFields.dimension(1); 00228 int numPoints = inoutFields.dimension(2); 00229 int dim1Tens = 0; 00230 int dim2Tens = 0; 00231 if (inoutRank > 3) { 00232 dim1Tens = inoutFields.dimension(3); 00233 if (inoutRank > 4) { 00234 dim2Tens = inoutFields.dimension(4); 00235 } 00236 } 00237 00238 switch(inoutRank) { 00239 case 3: { 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 inoutFields(cl, bf, pt) = inoutFields(cl, bf, pt) * inputFactors(cl, bf); 00244 } // P-loop 00245 } // F-loop 00246 } // C-loop 00247 }// case 2 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 for( int iVec = 0; iVec < dim1Tens; iVec++) { 00255 inoutFields(cl, bf, pt, iVec) = inoutFields(cl, bf, pt, iVec) * inputFactors(cl, bf); 00256 } // D1-loop 00257 }// P-loop 00258 } // F-loop 00259 } // C-loop 00260 }// case 3 00261 break; 00262 00263 case 5: { 00264 for(int cl = 0; cl < numCells; cl++) { 00265 for(int bf = 0; bf < numFields; bf++) { 00266 for(int pt = 0; pt < numPoints; pt++) { 00267 for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) { 00268 for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) { 00269 inoutFields(cl, bf, pt, iTens1, iTens2) = inoutFields(cl, bf, pt, iTens1, iTens2) * inputFactors(cl, bf); 00270 } // D2-loop 00271 } // D1-loop 00272 } // P-loop 00273 } // F-loop 00274 } // C-loop 00275 }// case 4 00276 break; 00277 00278 default: 00279 TEST_FOR_EXCEPTION( !( (inoutRank == 3) || (inoutRank == 4) || (inoutRank == 5) ), std::invalid_argument, 00280 ">>> ERROR (ArrayTools::cloneScaleFields): This method is defined only for rank-3, 4 or 5 input/output containers."); 00281 }// inoutRank 00282 00283 } // scaleFields 00284 00285 00286 } // end namespace Intrepid
1.7.4