Intrepid
http://trilinos.sandia.gov/packages/docs/r10.12/packages/intrepid/src/Shared/Intrepid_Utils.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 #ifndef INTREPID_UTILS_HPP
00050 #define INTREPID_UTILS_HPP
00051 
00052 #include "Intrepid_ConfigDefs.hpp"
00053 #include "Intrepid_Types.hpp"
00054 #include "Teuchos_Array.hpp"
00055 #include "Teuchos_oblackholestream.hpp"
00056 #include "Teuchos_RCP.hpp"
00057 
00058 namespace Intrepid {
00059 
00060 /***************************************************************************************************
00061  ***************************************************************************************************
00062  **                                                                                               **
00063  **  Declarations of non-templated utility functions for order and cardinality of operators       **
00064  **                                                                                               **
00065  ***************************************************************************************************
00066  ***************************************************************************************************/
00067   
00068   
00080   int getFieldRank(const EFunctionSpace spaceType); 
00081   
00082   
00083   
00119   int getOperatorRank(const EFunctionSpace spaceType,
00120                       const EOperator      operatorType,
00121                       const int            spaceDim);
00122   
00123   
00124   
00130   int getOperatorOrder(const EOperator operatorType);
00131   
00132   
00133   
00158   int getDkEnumeration(const int xMult,
00159                        const int yMult = -1,
00160                        const int zMult = -1);
00161   
00162   
00163   
00172   void getDkMultiplicities(Teuchos::Array<int>&  partialMult,
00173                            const int             derivativeEnum,
00174                            const EOperator       operatorType,
00175                            const int             spaceDim);
00176   
00177   
00178   
00197   int getDkCardinality(const EOperator operatorType,
00198                        const int       spaceDim);
00199   
00200   
00201   
00202 /***************************************************************************************************
00203  ***************************************************************************************************
00204  **                                                                                               **
00205  **                      Declarations of helper functions for the basis class                     **
00206  **                                                                                               **
00207  ***************************************************************************************************
00208  ***************************************************************************************************/
00209   
00221   void setOrdinalTagData(std::vector<std::vector<std::vector<int> > >   &tagToOrdinal,
00222                          std::vector<std::vector<int> >                 &ordinalToTag,
00223                          const int                                      *tags,
00224                          const int                                      basisCard,
00225                          const int                                      tagSize,
00226                          const int                                      posScDim,
00227                          const int                                      posScOrd,
00228                          const int                                      posDfOrd);
00229   
00230   
00231   
00232 /***************************************************************************************************
00233  ***************************************************************************************************
00234  **                                                                                               **
00235  **                      Declarations of templated utility functions                              **
00236  **                                                                                               **
00237  ***************************************************************************************************
00238  ***************************************************************************************************/
00239   
00240   enum TypeOfExactData{
00241     INTREPID_UTILS_FRACTION=0,
00242     INTREPID_UTILS_SCALAR
00243   };
00244   
00245 /***************************************************************************************************
00246  *                                                                                                 *
00247  *               Utility functions for handling external data in tests                             *
00248  *                                                                                                 *
00249  ***************************************************************************************************/
00250   
00263 template<class Scalar>
00264 int compareToAnalytic(const Teuchos::Array< Teuchos::Array<Scalar> > testMat,
00265                       std::ifstream & inputFile,
00266                       Scalar reltol,
00267                       int iprint,
00268                       TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
00269 
00283 template<class Scalar>
00284 int compareToAnalytic(const Scalar * testMat,
00285                       std::ifstream & inputFile,
00286                       Scalar reltol,
00287                       int iprint,
00288                       TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
00289 
00290 
00291 
00301 template<class Scalar>
00302 void getAnalytic(Teuchos::Array< Teuchos::Array<Scalar> > & testMat,
00303                  std::ifstream & inputFile,
00304                  TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
00305 
00315 template<class Scalar>
00316 void getAnalytic(Scalar * testMat,
00317                  std::ifstream & inputFile,
00318                  TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
00319 
00320 
00321 
00322 /***************************************************************************************************
00323  *                                                                                                 *
00324  *     Utility functions for checking requirements on ranks and dimensions of array arguments      *
00325  *                                                                                                 *
00326  ***************************************************************************************************/
00327 
00328   
00338   template<class Array>
00339   bool requireRankRange(std::string&   errmsg,
00340                         const Array&   array, 
00341                         const int      lowerBound, 
00342                         const int      upperBound);
00343 
00344   
00345   
00354   template<class Array1, class Array2>
00355   bool requireRankMatch(std::string&   errmsg, 
00356                         const Array1&  array1, 
00357                         const Array2&  array2);
00358 
00359 
00360   
00371   template<class Array>
00372   bool requireDimensionRange(std::string&  errmsg,
00373                              const Array&  array,
00374                              const int     dim,
00375                              const int     lowerBound,
00376                              const int     upperBound);
00377 
00378 
00379   
00390   template<class Array1, class Array2>
00391   bool requireDimensionMatch(std::string&   errmsg,
00392                              const Array1&  array1, 
00393                              const int      a1_dim0,
00394                              const Array2&  array2, 
00395                              const int      a2_dim0);
00396 
00397 
00398   
00411   template<class Array1, class Array2>
00412   bool requireDimensionMatch(std::string&   errmsg,
00413                              const Array1&  array1, 
00414                              const int      a1_dim0, const int a1_dim1,
00415                              const Array2&  array2, 
00416                              const int      a2_dim0, const int a2_dim1);
00417 
00418 
00419   
00434   template<class Array1, class Array2>
00435   bool requireDimensionMatch(std::string&   errmsg,
00436                              const Array1&  array1, 
00437                              const int      a1_dim0, const int a1_dim1, const int a1_dim2,
00438                              const Array2&  array2, 
00439                              const int      a2_dim0, const int a2_dim1, const int a2_dim2);
00440 
00441   
00442 
00459   template<class Array1, class Array2>
00460   bool requireDimensionMatch(std::string&   errmsg,
00461                              const Array1&  array1, 
00462                              const int      a1_dim0, const int a1_dim1, const int a1_dim2, const int a1_dim3,
00463                              const Array2&  array2, 
00464                              const int      a2_dim0, const int a2_dim1, const int a2_dim2, const int a2_dim3);
00465 
00466 
00467   
00486   template<class Array1, class Array2>
00487   bool requireDimensionMatch(std::string&   errmsg,
00488                              const Array1&  array1, 
00489                              const int      a1_dim0, const int a1_dim1, 
00490                              const int      a1_dim2, const int a1_dim3, const int a1_dim4,
00491                              const Array2&  array2, 
00492                              const int      a2_dim0, const int a2_dim1, 
00493                              const int      a2_dim2, const int a2_dim3, const int a2_dim4);
00494 
00495 
00496   
00505   template<class Array1, class Array2>
00506   bool requireDimensionMatch(std::string&   errmsg,
00507                              const Array1&  array1,
00508                              const Array2&  array2);
00509 
00510 
00511 
00512 /***************************************************************************************************
00513  ***************************************************************************************************
00514  **                                                                                               **
00515  **                           Definitions of templated functions                                  **
00516  **                                                                                               **
00517  ***************************************************************************************************
00518  ***************************************************************************************************/
00519 
00520 
00521 /***************************************************************************************************
00522  *                                                                                                 *
00523  *               Utility functions for handling external data in tests                             *
00524  *                                                                                                 *
00525  ***************************************************************************************************/
00526 
00527 template<class Scalar>
00528 int compareToAnalytic(const Teuchos::Array< Teuchos::Array<Scalar> > testMat,
00529                       std::ifstream & inputFile,
00530                       Scalar reltol,
00531                       int iprint,
00532                       TypeOfExactData analyticDataType ) {
00533   
00534   // This little trick lets us print to std::cout only if
00535   // iprint > 0.
00536   Teuchos::RCP<std::ostream> outStream;
00537   Teuchos::oblackholestream bhs; // outputs nothing
00538   if (iprint > 0)
00539     outStream = Teuchos::rcp(&std::cout, false);
00540   else
00541     outStream = Teuchos::rcp(&bhs, false);
00542   
00543   // Save the format state of the original std::cout.
00544   Teuchos::oblackholestream oldFormatState;
00545   oldFormatState.copyfmt(std::cout);
00546   
00547   std::string line;
00548   std::string chunk;
00549   Scalar testentry;
00550   Scalar abstol;
00551   Scalar absdiff;
00552   int i=0, j=0;
00553   int err = 0;
00554   
00555   while (! inputFile.eof() )
00556     {
00557     std::getline (inputFile,line);
00558     std::istringstream linestream(line);
00559     std::string chunk;
00560     j = 0;
00561     while( linestream >> chunk ) {
00562       int num1;
00563       int num2;
00564       std::string::size_type loc = chunk.find( "/", 0);
00565       if( loc != std::string::npos ) {
00566         chunk.replace( loc, 1, " ");
00567         std::istringstream chunkstream(chunk);
00568         chunkstream >> num1;
00569         chunkstream >> num2;
00570         testentry = (Scalar)(num1)/(Scalar)(num2);
00571         abstol = ( std::fabs(testentry) < reltol ? reltol : std::fabs(reltol*testentry) );
00572         absdiff = std::fabs(testentry - testMat[i][j]);
00573         if (absdiff > abstol) {
00574           err++;
00575           *outStream << "FAILURE --> ";
00576         }
00577         *outStream << "entry[" << i << "," << j << "]:" << "   "
00578           << testMat[i][j] << "   " << num1 << "/" << num2 << "   "
00579           << absdiff << "   " << "<?" << "   " << abstol << "\n";
00580       }
00581       else {
00582         std::istringstream chunkstream(chunk);
00583         if (analyticDataType == INTREPID_UTILS_FRACTION) {
00584           chunkstream >> num1;
00585           testentry = (Scalar)(num1);
00586         }
00587         else if (analyticDataType == INTREPID_UTILS_SCALAR)
00588           chunkstream >> testentry;
00589         abstol = ( std::fabs(testentry) < reltol ?reltol : std::fabs(reltol*testentry) );
00590         absdiff = std::fabs(testentry - testMat[i][j]);
00591         if (absdiff > abstol) {
00592           err++;
00593           *outStream << "FAILURE --> ";
00594         }
00595         *outStream << "entry[" << i << "," << j << "]:" << "   "
00596           << testMat[i][j] << "   " << testentry << "   "
00597           << absdiff << "   " << "<?" << "   " << abstol << "\n";
00598       }
00599       j++;
00600     }
00601     i++;
00602     }
00603   
00604   // reset format state of std::cout
00605   std::cout.copyfmt(oldFormatState);
00606   
00607   return err;
00608 } // end compareToAnalytic
00609 
00610 
00611 
00612 template<class Scalar>
00613 int compareToAnalytic(const Scalar * testMat,
00614                       std::ifstream & inputFile,
00615                       Scalar reltol,
00616                       int iprint,
00617                       TypeOfExactData analyticDataType ) {
00618   
00619   // This little trick lets us print to std::cout only if
00620   // iprint > 0.
00621   Teuchos::RCP<std::ostream> outStream;
00622   Teuchos::oblackholestream bhs; // outputs nothing
00623   if (iprint > 0)
00624     outStream = Teuchos::rcp(&std::cout, false);
00625   else
00626     outStream = Teuchos::rcp(&bhs, false);
00627   
00628   // Save the format state of the original std::cout.
00629   Teuchos::oblackholestream oldFormatState;
00630   oldFormatState.copyfmt(std::cout);
00631   
00632   std::string line;
00633   std::string chunk;
00634   Scalar testentry;
00635   Scalar abstol;
00636   Scalar absdiff;
00637   int i=0, j=0, offset=0;
00638   int err = 0;
00639   
00640   while (! inputFile.eof() )
00641     {
00642     std::getline (inputFile,line);
00643     std::istringstream linestream(line);
00644     std::string chunk;
00645     j = 0;
00646     while( linestream >> chunk ) {
00647       int num1;
00648       int num2;
00649       std::string::size_type loc = chunk.find( "/", 0);
00650       if( loc != std::string::npos ) {
00651         chunk.replace( loc, 1, " ");
00652         std::istringstream chunkstream(chunk);
00653         chunkstream >> num1;
00654         chunkstream >> num2;
00655         testentry = (Scalar)(num1)/(Scalar)(num2);
00656         abstol = ( std::fabs(testentry) < reltol ? reltol : std::fabs(reltol*testentry) );
00657         absdiff = std::fabs(testentry - testMat[i*offset+j]);
00658         if (absdiff > abstol) {
00659           err++;
00660           *outStream << "FAILURE --> ";
00661         }
00662         *outStream << "entry[" << i << "," << j << "]:" << "   "
00663           << testMat[i*offset+j] << "   " << num1 << "/" << num2 << "   "
00664           << absdiff << "   " << "<?" << "   " << abstol << "\n";
00665       }
00666       else {
00667         std::istringstream chunkstream(chunk);
00668         if (analyticDataType == INTREPID_UTILS_FRACTION) {
00669           chunkstream >> num1;
00670           testentry = (Scalar)(num1);
00671         }
00672         else if (analyticDataType == INTREPID_UTILS_SCALAR)
00673           chunkstream >> testentry;
00674         abstol = ( std::fabs(testentry) < reltol ?reltol : std::fabs(reltol*testentry) );
00675         absdiff = std::fabs(testentry - testMat[i*offset+j]);
00676         if (absdiff > abstol) {
00677           err++;
00678           *outStream << "FAILURE --> ";
00679         }
00680         *outStream << "entry[" << i << "," << j << "]:" << "   "
00681           << testMat[i*offset+j] << "   " << testentry << "   "
00682           << absdiff << "   " << "<?" << "   " << abstol << "\n";
00683       }
00684       j++;
00685     }
00686     i++;
00687     offset = j;
00688     }
00689   
00690   // reset format state of std::cout
00691   std::cout.copyfmt(oldFormatState);
00692   
00693   return err;
00694 } // end compareToAnalytic
00695 
00696 
00697 
00698 template<class Scalar>
00699 void getAnalytic(Teuchos::Array< Teuchos::Array<Scalar> > & testMat,
00700                  std::ifstream & inputFile,
00701                  TypeOfExactData analyticDataType ) {
00702   
00703   // Save the format state of the original std::cout.
00704   Teuchos::oblackholestream oldFormatState;
00705   oldFormatState.copyfmt(std::cout);
00706   
00707   std::string line;
00708   std::string chunk;
00709   Scalar testentry;
00710   int i=0, j=0;
00711   
00712   while (! inputFile.eof() )
00713     {
00714     std::getline (inputFile,line);
00715     std::istringstream linestream(line);
00716     std::string chunk;
00717     j = 0;
00718     while( linestream >> chunk ) {
00719       int num1;
00720       int num2;
00721       std::string::size_type loc = chunk.find( "/", 0);
00722       if( loc != std::string::npos ) {
00723         chunk.replace( loc, 1, " ");
00724         std::istringstream chunkstream(chunk);
00725         chunkstream >> num1;
00726         chunkstream >> num2;
00727         testentry = (Scalar)(num1)/(Scalar)(num2);
00728         testMat[i][j] = testentry;
00729       }
00730       else {
00731         std::istringstream chunkstream(chunk);
00732         if (analyticDataType == INTREPID_UTILS_FRACTION) {
00733           chunkstream >> num1;
00734           testentry = (Scalar)(num1);
00735         }
00736         else if (analyticDataType == INTREPID_UTILS_SCALAR)
00737           chunkstream >> testentry;
00738         testMat[i][j] = testentry;
00739       }
00740       j++;
00741     }
00742     i++;
00743     }
00744   
00745   // reset format state of std::cout
00746   std::cout.copyfmt(oldFormatState);
00747 } // end getAnalytic
00748 
00749 
00750 
00751 template<class Scalar>
00752 void getAnalytic(Scalar * testMat,
00753                  std::ifstream & inputFile,
00754                  TypeOfExactData analyticDataType) {
00755   
00756   // Save the format state of the original std::cout.
00757   Teuchos::oblackholestream oldFormatState;
00758   oldFormatState.copyfmt(std::cout);
00759   
00760   std::string line;
00761   std::string chunk;
00762   Scalar testentry;
00763   int i=0, j=0, offset=0;
00764   
00765   while (! inputFile.eof() )
00766     {
00767     std::getline (inputFile,line);
00768     std::istringstream linestream(line);
00769     std::string chunk;
00770     j = 0;
00771     while( linestream >> chunk ) {
00772       int num1;
00773       int num2;
00774       std::string::size_type loc = chunk.find( "/", 0);
00775       if( loc != std::string::npos ) {
00776         chunk.replace( loc, 1, " ");
00777         std::istringstream chunkstream(chunk);
00778         chunkstream >> num1;
00779         chunkstream >> num2;
00780         testentry = (Scalar)(num1)/(Scalar)(num2);
00781         testMat[i*offset+j] = testentry;
00782       }
00783       else {
00784         std::istringstream chunkstream(chunk);
00785         if (analyticDataType == INTREPID_UTILS_FRACTION) {
00786           chunkstream >> num1;
00787           testentry = (Scalar)(num1);
00788         }
00789         else if (analyticDataType == INTREPID_UTILS_SCALAR)
00790           chunkstream >> testentry;
00791         testMat[i*offset+j] = testentry;
00792       }
00793       j++;
00794     }
00795     i++;
00796     offset = j;
00797     }
00798   
00799   // reset format state of std::cout
00800   std::cout.copyfmt(oldFormatState);
00801 } // end getAnalytic
00802 
00803 
00804 /***************************************************************************************************
00805  *                                                                                                 *
00806  *     Utility functions for checking requirements on ranks and dimensions of array arguments      *
00807  *                                                                                                 *
00808  ***************************************************************************************************/
00809 
00810 
00811 template<class Array>
00812 bool requireRankRange(std::string&   errmsg,
00813                       const Array&   array, 
00814                       const int      lowerBound, 
00815                       const int      upperBound){
00816   
00817   TEUCHOS_TEST_FOR_EXCEPTION( (lowerBound > upperBound) , std::invalid_argument,
00818                       ">>> ERROR (Intrepid_Utils::requireRankRange): lowerBound <= upperBound required!");
00819   
00820   bool OK = true;
00821   if( (lowerBound == upperBound) && !(array.rank() == lowerBound) ) {
00822     errmsg += "\n>>> Array rank = ";
00823     errmsg += (char)(48 + array.rank() );
00824     errmsg += " while rank-";
00825     errmsg += (char) (48 + lowerBound);
00826     errmsg += " array required.";
00827     OK = false;
00828   }
00829   else if ( (lowerBound < upperBound) &&  !( (lowerBound <= array.rank() ) && (array.rank() <= upperBound)  ) ){
00830     errmsg += "\n>>> Array rank = ";
00831     errmsg += (char)(48 + array.rank() );
00832     errmsg += " while a rank between ";
00833     errmsg += (char) (48 + lowerBound);
00834     errmsg += " and ";
00835     errmsg += (char) (48 + upperBound);
00836     errmsg += " is required.";
00837     OK = false;
00838   }
00839   return OK;
00840 }
00841 
00842 
00843 template<class Array1, class Array2>
00844 bool requireRankMatch(std::string&   errmsg, 
00845                       const Array1&  array1, 
00846                       const Array2&  array2){    
00847   bool OK = true;
00848   if(array1.rank() != array2.rank() ) {
00849     errmsg += "\n>>> Array ranks are required to match.";
00850     OK = false; 
00851   }
00852   return OK;
00853 }
00854 
00855 
00856 template<class Array>
00857 bool requireDimensionRange(std::string&  errmsg,
00858                            const Array&  array,
00859                            const int     dim,
00860                            const int     lowerBound,
00861                            const int     upperBound){
00862   
00863   TEUCHOS_TEST_FOR_EXCEPTION( (lowerBound > upperBound) , std::invalid_argument,
00864                       ">>> ERROR (Intrepid_Utils::requireDimensionRange): lowerBound <= upperBound required!");
00865   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= dim) && (dim < array.rank() ) ), 
00866                       std::invalid_argument,
00867                       ">>> ERROR (Intrepid_Utils::requireDimensionRange): 0 <= dim < array.rank() required!");
00868   
00869   bool OK = true;
00870   if( (lowerBound > upperBound) || ( dim >= array.rank() ) ) {
00871     errmsg += "\n>>> Unexpected error: ";
00872     OK = false;
00873   }  
00874   if( (lowerBound == upperBound) && !(array.dimension(dim) == lowerBound) ) {
00875     errmsg += "\n>>> dimension(";
00876     errmsg += (char)(48 + dim);
00877     errmsg += ") = ";
00878     errmsg += (char)(48 + array.dimension(dim) );
00879     errmsg += " while dimension(";
00880     errmsg += (char)(48 + dim);
00881     errmsg += ") = ";
00882     errmsg += (char)(48 + lowerBound);
00883     errmsg += " required.";
00884     OK = false;
00885   }
00886   else if( (lowerBound < upperBound) && 
00887            !( (lowerBound <= array.dimension(dim) ) && (array.dimension(dim) <= upperBound) ) ){
00888     errmsg += "\n>>> dimension(";
00889     errmsg += (char)(48 + dim);
00890     errmsg += ") = ";
00891     errmsg += (char)(48 + array.dimension(dim) );
00892     errmsg += " while ";
00893     errmsg += (char)(48 + lowerBound);
00894     errmsg += " <= dimension(";
00895     errmsg += (char)(48 + dim);
00896     errmsg += ") <= ";
00897     errmsg +=(char)(48 + upperBound);
00898     errmsg +=" required.";
00899     OK = false;
00900   }
00901   return OK;
00902 }
00903 
00904 
00905 
00906 template<class Array1, class Array2>
00907 bool requireDimensionMatch(std::string&   errmsg,
00908                            const Array1&  array1,
00909                            const int      a1_dim0,
00910                            const Array2&  array2, 
00911                            const int      a2_dim0){
00912   
00913   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 
00914                       std::invalid_argument,
00915                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
00916   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ),
00917                       std::invalid_argument,
00918                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
00919 
00920   bool OK = true;
00921   if(array1.dimension(a1_dim0) != array2.dimension(a2_dim0) ){
00922     errmsg += "\n>>> dimension(";
00923     errmsg += (char)(48 + a1_dim0);
00924     errmsg += ") of 1st array and dimension(";
00925     errmsg += (char)(48 + a2_dim0);
00926     errmsg += ") of 2nd array are required to match.";
00927     OK = false;
00928   }
00929   return OK;
00930 }
00931 
00932 
00933 
00934 template<class Array1, class Array2>
00935 bool requireDimensionMatch(std::string&   errmsg,
00936                            const Array1&  array1, 
00937                            const int      a1_dim0, const int a1_dim1,
00938                            const Array2&  array2, 
00939                            const int      a2_dim0, const int a2_dim1){
00940   
00941   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 
00942                       std::invalid_argument,
00943                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
00944   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && (a1_dim1 < array1.rank() ) ), 
00945                       std::invalid_argument,
00946                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!");
00947   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ),
00948                       std::invalid_argument,
00949                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
00950   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && (a2_dim1 < array2.rank() ) ),
00951                       std::invalid_argument,
00952                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!");
00953  
00954   bool OK = true;
00955   if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){
00956     OK = false;
00957   }
00958   if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){
00959     OK = false;
00960   }
00961   return OK;
00962 }
00963 
00964 
00965 
00966 template<class Array1, class Array2>
00967 bool requireDimensionMatch(std::string&   errmsg,
00968                            const Array1&  array1, 
00969                            const int      a1_dim0, const int a1_dim1, const int a1_dim2,
00970                            const Array2&  array2, 
00971                            const int      a2_dim0, const int a2_dim1, const int a2_dim2){
00972   
00973   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 
00974                       std::invalid_argument,
00975                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
00976   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && (a1_dim1 < array1.rank() ) ), 
00977                       std::invalid_argument,
00978                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!");
00979   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && (a1_dim2 < array1.rank() ) ), 
00980                       std::invalid_argument,
00981                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!");
00982   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ),
00983                       std::invalid_argument,
00984                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
00985   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && (a2_dim1 < array2.rank() ) ),
00986                       std::invalid_argument,
00987                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!");
00988   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && (a2_dim2 < array2.rank() ) ),
00989                       std::invalid_argument,
00990                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!");
00991   
00992   
00993   bool OK = true;
00994   if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){
00995     OK = false;
00996   }
00997   if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){
00998     OK = false;
00999   }
01000   if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){
01001     OK = false;
01002   }
01003   return OK;
01004 }
01005 
01006 
01007 
01008 template<class Array1, class Array2>
01009 bool requireDimensionMatch(std::string&   errmsg,
01010                            const Array1&  array1, 
01011                            const int      a1_dim0, const int a1_dim1, const int a1_dim2, const int a1_dim3,
01012                            const Array2&  array2, 
01013                            const int      a2_dim0, const int a2_dim1, const int a2_dim2, const int a2_dim3){
01014   
01015   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 
01016                       std::invalid_argument,
01017                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
01018   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && (a1_dim1 < array1.rank() ) ), 
01019                       std::invalid_argument,
01020                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!");
01021   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && (a1_dim2 < array1.rank() ) ), 
01022                       std::invalid_argument,
01023                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!");
01024   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim3) && (a1_dim3 < array1.rank() ) ), 
01025                       std::invalid_argument,
01026                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim3 < array1.rank() required!");
01027   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ),
01028                       std::invalid_argument,
01029                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
01030   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && (a2_dim1 < array2.rank() ) ),
01031                       std::invalid_argument,
01032                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!");
01033   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && (a2_dim2 < array2.rank() ) ),
01034                       std::invalid_argument,
01035                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!");
01036   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim3) && (a2_dim3 < array2.rank() ) ),
01037                       std::invalid_argument,
01038                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim3 < array2.rank() required!");
01039   bool OK = true;
01040   if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){
01041     OK = false;
01042   }
01043   if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){
01044     OK = false;
01045   }
01046   if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){
01047     OK = false;
01048   }
01049   if( !requireDimensionMatch(errmsg, array1, a1_dim3, array2, a2_dim3) ){
01050     OK = false;
01051   }
01052   return OK;
01053 }
01054 
01055 
01056 
01057 template<class Array1, class Array2>
01058 bool requireDimensionMatch(std::string&   errmsg,
01059                            const Array1&  array1, 
01060                            const int      a1_dim0, const int a1_dim1, const int a1_dim2, 
01061                            const int      a1_dim3, const int a1_dim4,
01062                            const Array2&  array2, 
01063                            const int      a2_dim0, const int a2_dim1, const int a2_dim2, 
01064                            const int      a2_dim3, const int a2_dim4){
01065   
01066   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 
01067                       std::invalid_argument,
01068                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
01069   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && (a1_dim1 < array1.rank() ) ), 
01070                       std::invalid_argument,
01071                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!");
01072   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && (a1_dim2 < array1.rank() ) ), 
01073                       std::invalid_argument,
01074                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!");
01075   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim3) && (a1_dim3 < array1.rank() ) ), 
01076                       std::invalid_argument,
01077                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim3 < array1.rank() required!");
01078   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim4) && (a1_dim4 < array1.rank() ) ), 
01079                       std::invalid_argument,
01080                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim4 < array1.rank() required!");
01081   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ),
01082                       std::invalid_argument,
01083                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
01084   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && (a2_dim1 < array2.rank() ) ),
01085                       std::invalid_argument,
01086                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!");
01087   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && (a2_dim2 < array2.rank() ) ),
01088                       std::invalid_argument,
01089                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!");
01090   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim3) && (a2_dim3 < array2.rank() ) ),
01091                       std::invalid_argument,
01092                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim3 < array2.rank() required!");
01093   TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim4) && (a2_dim4 < array2.rank() ) ),
01094                       std::invalid_argument,
01095                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim4 < array2.rank() required!");
01096   
01097   bool OK = true;
01098   if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){
01099     OK = false;
01100   }
01101   if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){
01102     OK = false;
01103   }
01104   if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){
01105     OK = false;
01106   }
01107   if( !requireDimensionMatch(errmsg, array1, a1_dim3, array2, a2_dim3) ){
01108     OK = false;
01109   }
01110   if( !requireDimensionMatch(errmsg, array1, a1_dim4, array2, a2_dim4) ){
01111     OK = false;
01112   }
01113   return OK;
01114 }
01115 
01116 
01117 
01118 template<class Array1, class Array2>
01119 bool requireDimensionMatch(std::string&   errmsg,
01120                            const Array1&  array1,
01121                            const Array2&  array2){
01122   
01123   TEUCHOS_TEST_FOR_EXCEPTION( !requireRankMatch(errmsg, array1, array2 ), std::invalid_argument,
01124                       ">>> ERROR (Intrepid_Utils::requireDimensionMatch): Arrays with equal ranks are required to test for all dimensions match." )
01125   
01126   bool OK = true;  
01127   for(int dim = 0; dim < array1.rank(); dim++){
01128     if( !requireDimensionMatch(errmsg, array1, dim, array2, dim) ){
01129       OK = false;
01130       break;
01131     }
01132   } 
01133   return OK;
01134 }
01135 
01136 
01137 } // end namespace Intrepid
01138 
01139 #endif