|
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 #ifndef INTREPID_UTILS_HPP 00036 #define INTREPID_UTILS_HPP 00037 00038 #include "Intrepid_ConfigDefs.hpp" 00039 #include "Intrepid_Types.hpp" 00040 #include "Teuchos_Array.hpp" 00041 #include "Teuchos_oblackholestream.hpp" 00042 #include "Teuchos_RCP.hpp" 00043 00044 namespace Intrepid { 00045 00046 /*************************************************************************************************** 00047 *************************************************************************************************** 00048 ** ** 00049 ** Declarations of non-templated utility functions for order and cardinality of operators ** 00050 ** ** 00051 *************************************************************************************************** 00052 ***************************************************************************************************/ 00053 00054 00066 int getFieldRank(const EFunctionSpace spaceType); 00067 00068 00069 00105 int getOperatorRank(const EFunctionSpace spaceType, 00106 const EOperator operatorType, 00107 const int spaceDim); 00108 00109 00110 00116 int getOperatorOrder(const EOperator operatorType); 00117 00118 00119 00144 int getDkEnumeration(const int xMult, 00145 const int yMult = -1, 00146 const int zMult = -1); 00147 00148 00149 00158 void getDkMultiplicities(Teuchos::Array<int>& partialMult, 00159 const int derivativeEnum, 00160 const EOperator operatorType, 00161 const int spaceDim); 00162 00163 00164 00183 int getDkCardinality(const EOperator operatorType, 00184 const int spaceDim); 00185 00186 00187 00188 /*************************************************************************************************** 00189 *************************************************************************************************** 00190 ** ** 00191 ** Declarations of helper functions for the basis class ** 00192 ** ** 00193 *************************************************************************************************** 00194 ***************************************************************************************************/ 00195 00207 void setOrdinalTagData(std::vector<std::vector<std::vector<int> > > &tagToOrdinal, 00208 std::vector<std::vector<int> > &ordinalToTag, 00209 const int *tags, 00210 const int basisCard, 00211 const int tagSize, 00212 const int posScDim, 00213 const int posScOrd, 00214 const int posDfOrd); 00215 00216 00217 00218 /*************************************************************************************************** 00219 *************************************************************************************************** 00220 ** ** 00221 ** Declarations of templated utility functions ** 00222 ** ** 00223 *************************************************************************************************** 00224 ***************************************************************************************************/ 00225 00226 enum TypeOfExactData{ 00227 INTREPID_UTILS_FRACTION=0, 00228 INTREPID_UTILS_SCALAR 00229 }; 00230 00231 /*************************************************************************************************** 00232 * * 00233 * Utility functions for handling external data in tests * 00234 * * 00235 ***************************************************************************************************/ 00236 00249 template<class Scalar> 00250 int compareToAnalytic(const Teuchos::Array< Teuchos::Array<Scalar> > testMat, 00251 std::ifstream & inputFile, 00252 Scalar reltol, 00253 int iprint, 00254 TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION); 00255 00269 template<class Scalar> 00270 int compareToAnalytic(const Scalar * testMat, 00271 std::ifstream & inputFile, 00272 Scalar reltol, 00273 int iprint, 00274 TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION); 00275 00276 00277 00287 template<class Scalar> 00288 void getAnalytic(Teuchos::Array< Teuchos::Array<Scalar> > & testMat, 00289 std::ifstream & inputFile, 00290 TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION); 00291 00301 template<class Scalar> 00302 void getAnalytic(Scalar * testMat, 00303 std::ifstream & inputFile, 00304 TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION); 00305 00306 00307 00308 /*************************************************************************************************** 00309 * * 00310 * Utility functions for checking requirements on ranks and dimensions of array arguments * 00311 * * 00312 ***************************************************************************************************/ 00313 00314 00324 template<class Array> 00325 bool requireRankRange(std::string& errmsg, 00326 const Array& array, 00327 const int lowerBound, 00328 const int upperBound); 00329 00330 00331 00340 template<class Array1, class Array2> 00341 bool requireRankMatch(std::string& errmsg, 00342 const Array1& array1, 00343 const Array2& array2); 00344 00345 00346 00357 template<class Array> 00358 bool requireDimensionRange(std::string& errmsg, 00359 const Array& array, 00360 const int dim, 00361 const int lowerBound, 00362 const int upperBound); 00363 00364 00365 00376 template<class Array1, class Array2> 00377 bool requireDimensionMatch(std::string& errmsg, 00378 const Array1& array1, 00379 const int a1_dim0, 00380 const Array2& array2, 00381 const int a2_dim0); 00382 00383 00384 00397 template<class Array1, class Array2> 00398 bool requireDimensionMatch(std::string& errmsg, 00399 const Array1& array1, 00400 const int a1_dim0, const int a1_dim1, 00401 const Array2& array2, 00402 const int a2_dim0, const int a2_dim1); 00403 00404 00405 00420 template<class Array1, class Array2> 00421 bool requireDimensionMatch(std::string& errmsg, 00422 const Array1& array1, 00423 const int a1_dim0, const int a1_dim1, const int a1_dim2, 00424 const Array2& array2, 00425 const int a2_dim0, const int a2_dim1, const int a2_dim2); 00426 00427 00428 00445 template<class Array1, class Array2> 00446 bool requireDimensionMatch(std::string& errmsg, 00447 const Array1& array1, 00448 const int a1_dim0, const int a1_dim1, const int a1_dim2, const int a1_dim3, 00449 const Array2& array2, 00450 const int a2_dim0, const int a2_dim1, const int a2_dim2, const int a2_dim3); 00451 00452 00453 00472 template<class Array1, class Array2> 00473 bool requireDimensionMatch(std::string& errmsg, 00474 const Array1& array1, 00475 const int a1_dim0, const int a1_dim1, 00476 const int a1_dim2, const int a1_dim3, const int a1_dim4, 00477 const Array2& array2, 00478 const int a2_dim0, const int a2_dim1, 00479 const int a2_dim2, const int a2_dim3, const int a2_dim4); 00480 00481 00482 00491 template<class Array1, class Array2> 00492 bool requireDimensionMatch(std::string& errmsg, 00493 const Array1& array1, 00494 const Array2& array2); 00495 00496 00497 00498 /*************************************************************************************************** 00499 *************************************************************************************************** 00500 ** ** 00501 ** Definitions of templated functions ** 00502 ** ** 00503 *************************************************************************************************** 00504 ***************************************************************************************************/ 00505 00506 00507 /*************************************************************************************************** 00508 * * 00509 * Utility functions for handling external data in tests * 00510 * * 00511 ***************************************************************************************************/ 00512 00513 template<class Scalar> 00514 int compareToAnalytic(const Teuchos::Array< Teuchos::Array<Scalar> > testMat, 00515 std::ifstream & inputFile, 00516 Scalar reltol, 00517 int iprint, 00518 TypeOfExactData analyticDataType ) { 00519 00520 // This little trick lets us print to std::cout only if 00521 // iprint > 0. 00522 Teuchos::RCP<std::ostream> outStream; 00523 Teuchos::oblackholestream bhs; // outputs nothing 00524 if (iprint > 0) 00525 outStream = Teuchos::rcp(&std::cout, false); 00526 else 00527 outStream = Teuchos::rcp(&bhs, false); 00528 00529 // Save the format state of the original std::cout. 00530 Teuchos::oblackholestream oldFormatState; 00531 oldFormatState.copyfmt(std::cout); 00532 00533 std::string line; 00534 std::string chunk; 00535 Scalar testentry; 00536 Scalar abstol; 00537 Scalar absdiff; 00538 int i=0, j=0; 00539 int err = 0; 00540 00541 while (! inputFile.eof() ) 00542 { 00543 std::getline (inputFile,line); 00544 std::istringstream linestream(line); 00545 std::string chunk; 00546 j = 0; 00547 while( linestream >> chunk ) { 00548 int num1; 00549 int num2; 00550 std::string::size_type loc = chunk.find( "/", 0); 00551 if( loc != std::string::npos ) { 00552 chunk.replace( loc, 1, " "); 00553 std::istringstream chunkstream(chunk); 00554 chunkstream >> num1; 00555 chunkstream >> num2; 00556 testentry = (Scalar)(num1)/(Scalar)(num2); 00557 abstol = ( std::fabs(testentry) < reltol ? reltol : std::fabs(reltol*testentry) ); 00558 absdiff = std::fabs(testentry - testMat[i][j]); 00559 if (absdiff > abstol) { 00560 err++; 00561 *outStream << "FAILURE --> "; 00562 } 00563 *outStream << "entry[" << i << "," << j << "]:" << " " 00564 << testMat[i][j] << " " << num1 << "/" << num2 << " " 00565 << absdiff << " " << "<?" << " " << abstol << "\n"; 00566 } 00567 else { 00568 std::istringstream chunkstream(chunk); 00569 if (analyticDataType == INTREPID_UTILS_FRACTION) { 00570 chunkstream >> num1; 00571 testentry = (Scalar)(num1); 00572 } 00573 else if (analyticDataType == INTREPID_UTILS_SCALAR) 00574 chunkstream >> testentry; 00575 abstol = ( std::fabs(testentry) < reltol ?reltol : std::fabs(reltol*testentry) ); 00576 absdiff = std::fabs(testentry - testMat[i][j]); 00577 if (absdiff > abstol) { 00578 err++; 00579 *outStream << "FAILURE --> "; 00580 } 00581 *outStream << "entry[" << i << "," << j << "]:" << " " 00582 << testMat[i][j] << " " << testentry << " " 00583 << absdiff << " " << "<?" << " " << abstol << "\n"; 00584 } 00585 j++; 00586 } 00587 i++; 00588 } 00589 00590 // reset format state of std::cout 00591 std::cout.copyfmt(oldFormatState); 00592 00593 return err; 00594 } // end compareToAnalytic 00595 00596 00597 00598 template<class Scalar> 00599 int compareToAnalytic(const Scalar * testMat, 00600 std::ifstream & inputFile, 00601 Scalar reltol, 00602 int iprint, 00603 TypeOfExactData analyticDataType ) { 00604 00605 // This little trick lets us print to std::cout only if 00606 // iprint > 0. 00607 Teuchos::RCP<std::ostream> outStream; 00608 Teuchos::oblackholestream bhs; // outputs nothing 00609 if (iprint > 0) 00610 outStream = Teuchos::rcp(&std::cout, false); 00611 else 00612 outStream = Teuchos::rcp(&bhs, false); 00613 00614 // Save the format state of the original std::cout. 00615 Teuchos::oblackholestream oldFormatState; 00616 oldFormatState.copyfmt(std::cout); 00617 00618 std::string line; 00619 std::string chunk; 00620 Scalar testentry; 00621 Scalar abstol; 00622 Scalar absdiff; 00623 int i=0, j=0, offset=0; 00624 int err = 0; 00625 00626 while (! inputFile.eof() ) 00627 { 00628 std::getline (inputFile,line); 00629 std::istringstream linestream(line); 00630 std::string chunk; 00631 j = 0; 00632 while( linestream >> chunk ) { 00633 int num1; 00634 int num2; 00635 std::string::size_type loc = chunk.find( "/", 0); 00636 if( loc != std::string::npos ) { 00637 chunk.replace( loc, 1, " "); 00638 std::istringstream chunkstream(chunk); 00639 chunkstream >> num1; 00640 chunkstream >> num2; 00641 testentry = (Scalar)(num1)/(Scalar)(num2); 00642 abstol = ( std::fabs(testentry) < reltol ? reltol : std::fabs(reltol*testentry) ); 00643 absdiff = std::fabs(testentry - testMat[i*offset+j]); 00644 if (absdiff > abstol) { 00645 err++; 00646 *outStream << "FAILURE --> "; 00647 } 00648 *outStream << "entry[" << i << "," << j << "]:" << " " 00649 << testMat[i*offset+j] << " " << num1 << "/" << num2 << " " 00650 << absdiff << " " << "<?" << " " << abstol << "\n"; 00651 } 00652 else { 00653 std::istringstream chunkstream(chunk); 00654 if (analyticDataType == INTREPID_UTILS_FRACTION) { 00655 chunkstream >> num1; 00656 testentry = (Scalar)(num1); 00657 } 00658 else if (analyticDataType == INTREPID_UTILS_SCALAR) 00659 chunkstream >> testentry; 00660 abstol = ( std::fabs(testentry) < reltol ?reltol : std::fabs(reltol*testentry) ); 00661 absdiff = std::fabs(testentry - testMat[i*offset+j]); 00662 if (absdiff > abstol) { 00663 err++; 00664 *outStream << "FAILURE --> "; 00665 } 00666 *outStream << "entry[" << i << "," << j << "]:" << " " 00667 << testMat[i*offset+j] << " " << testentry << " " 00668 << absdiff << " " << "<?" << " " << abstol << "\n"; 00669 } 00670 j++; 00671 } 00672 i++; 00673 offset = j; 00674 } 00675 00676 // reset format state of std::cout 00677 std::cout.copyfmt(oldFormatState); 00678 00679 return err; 00680 } // end compareToAnalytic 00681 00682 00683 00684 template<class Scalar> 00685 void getAnalytic(Teuchos::Array< Teuchos::Array<Scalar> > & testMat, 00686 std::ifstream & inputFile, 00687 TypeOfExactData analyticDataType ) { 00688 00689 // Save the format state of the original std::cout. 00690 Teuchos::oblackholestream oldFormatState; 00691 oldFormatState.copyfmt(std::cout); 00692 00693 std::string line; 00694 std::string chunk; 00695 Scalar testentry; 00696 int i=0, j=0; 00697 00698 while (! inputFile.eof() ) 00699 { 00700 std::getline (inputFile,line); 00701 std::istringstream linestream(line); 00702 std::string chunk; 00703 j = 0; 00704 while( linestream >> chunk ) { 00705 int num1; 00706 int num2; 00707 std::string::size_type loc = chunk.find( "/", 0); 00708 if( loc != std::string::npos ) { 00709 chunk.replace( loc, 1, " "); 00710 std::istringstream chunkstream(chunk); 00711 chunkstream >> num1; 00712 chunkstream >> num2; 00713 testentry = (Scalar)(num1)/(Scalar)(num2); 00714 testMat[i][j] = testentry; 00715 } 00716 else { 00717 std::istringstream chunkstream(chunk); 00718 if (analyticDataType == INTREPID_UTILS_FRACTION) { 00719 chunkstream >> num1; 00720 testentry = (Scalar)(num1); 00721 } 00722 else if (analyticDataType == INTREPID_UTILS_SCALAR) 00723 chunkstream >> testentry; 00724 testMat[i][j] = testentry; 00725 } 00726 j++; 00727 } 00728 i++; 00729 } 00730 00731 // reset format state of std::cout 00732 std::cout.copyfmt(oldFormatState); 00733 } // end getAnalytic 00734 00735 00736 00737 template<class Scalar> 00738 void getAnalytic(Scalar * testMat, 00739 std::ifstream & inputFile, 00740 TypeOfExactData analyticDataType) { 00741 00742 // Save the format state of the original std::cout. 00743 Teuchos::oblackholestream oldFormatState; 00744 oldFormatState.copyfmt(std::cout); 00745 00746 std::string line; 00747 std::string chunk; 00748 Scalar testentry; 00749 int i=0, j=0, offset=0; 00750 00751 while (! inputFile.eof() ) 00752 { 00753 std::getline (inputFile,line); 00754 std::istringstream linestream(line); 00755 std::string chunk; 00756 j = 0; 00757 while( linestream >> chunk ) { 00758 int num1; 00759 int num2; 00760 std::string::size_type loc = chunk.find( "/", 0); 00761 if( loc != std::string::npos ) { 00762 chunk.replace( loc, 1, " "); 00763 std::istringstream chunkstream(chunk); 00764 chunkstream >> num1; 00765 chunkstream >> num2; 00766 testentry = (Scalar)(num1)/(Scalar)(num2); 00767 testMat[i*offset+j] = testentry; 00768 } 00769 else { 00770 std::istringstream chunkstream(chunk); 00771 if (analyticDataType == INTREPID_UTILS_FRACTION) { 00772 chunkstream >> num1; 00773 testentry = (Scalar)(num1); 00774 } 00775 else if (analyticDataType == INTREPID_UTILS_SCALAR) 00776 chunkstream >> testentry; 00777 testMat[i*offset+j] = testentry; 00778 } 00779 j++; 00780 } 00781 i++; 00782 offset = j; 00783 } 00784 00785 // reset format state of std::cout 00786 std::cout.copyfmt(oldFormatState); 00787 } // end getAnalytic 00788 00789 00790 /*************************************************************************************************** 00791 * * 00792 * Utility functions for checking requirements on ranks and dimensions of array arguments * 00793 * * 00794 ***************************************************************************************************/ 00795 00796 00797 template<class Array> 00798 bool requireRankRange(std::string& errmsg, 00799 const Array& array, 00800 const int lowerBound, 00801 const int upperBound){ 00802 00803 TEST_FOR_EXCEPTION( (lowerBound > upperBound) , std::invalid_argument, 00804 ">>> ERROR (Intrepid_Utils::requireRankRange): lowerBound <= upperBound required!"); 00805 00806 bool OK = true; 00807 if( (lowerBound == upperBound) && !(array.rank() == lowerBound) ) { 00808 errmsg += "\n>>> Array rank = "; 00809 errmsg += (char)(48 + array.rank() ); 00810 errmsg += " while rank-"; 00811 errmsg += (char) (48 + lowerBound); 00812 errmsg += " array required."; 00813 OK = false; 00814 } 00815 else if ( (lowerBound < upperBound) && !( (lowerBound <= array.rank() ) && (array.rank() <= upperBound) ) ){ 00816 errmsg += "\n>>> Array rank = "; 00817 errmsg += (char)(48 + array.rank() ); 00818 errmsg += " while a rank between "; 00819 errmsg += (char) (48 + lowerBound); 00820 errmsg += " and "; 00821 errmsg += (char) (48 + upperBound); 00822 errmsg += " is required."; 00823 OK = false; 00824 } 00825 return OK; 00826 } 00827 00828 00829 template<class Array1, class Array2> 00830 bool requireRankMatch(std::string& errmsg, 00831 const Array1& array1, 00832 const Array2& array2){ 00833 bool OK = true; 00834 if(array1.rank() != array2.rank() ) { 00835 errmsg += "\n>>> Array ranks are required to match."; 00836 OK = false; 00837 } 00838 return OK; 00839 } 00840 00841 00842 template<class Array> 00843 bool requireDimensionRange(std::string& errmsg, 00844 const Array& array, 00845 const int dim, 00846 const int lowerBound, 00847 const int upperBound){ 00848 00849 TEST_FOR_EXCEPTION( (lowerBound > upperBound) , std::invalid_argument, 00850 ">>> ERROR (Intrepid_Utils::requireDimensionRange): lowerBound <= upperBound required!"); 00851 TEST_FOR_EXCEPTION( !( (0 <= dim) && (dim < array.rank() ) ), 00852 std::invalid_argument, 00853 ">>> ERROR (Intrepid_Utils::requireDimensionRange): 0 <= dim < array.rank() required!"); 00854 00855 bool OK = true; 00856 if( (lowerBound > upperBound) || ( dim >= array.rank() ) ) { 00857 errmsg += "\n>>> Unexpected error: "; 00858 OK = false; 00859 } 00860 if( (lowerBound == upperBound) && !(array.dimension(dim) == lowerBound) ) { 00861 errmsg += "\n>>> dimension("; 00862 errmsg += (char)(48 + dim); 00863 errmsg += ") = "; 00864 errmsg += (char)(48 + array.dimension(dim) ); 00865 errmsg += " while dimension("; 00866 errmsg += (char)(48 + dim); 00867 errmsg += ") = "; 00868 errmsg += (char)(48 + lowerBound); 00869 errmsg += " required."; 00870 OK = false; 00871 } 00872 else if( (lowerBound < upperBound) && 00873 !( (lowerBound <= array.dimension(dim) ) && (array.dimension(dim) <= upperBound) ) ){ 00874 errmsg += "\n>>> dimension("; 00875 errmsg += (char)(48 + dim); 00876 errmsg += ") = "; 00877 errmsg += (char)(48 + array.dimension(dim) ); 00878 errmsg += " while "; 00879 errmsg += (char)(48 + lowerBound); 00880 errmsg += " <= dimension("; 00881 errmsg += (char)(48 + dim); 00882 errmsg += ") <= "; 00883 errmsg +=(char)(48 + upperBound); 00884 errmsg +=" required."; 00885 OK = false; 00886 } 00887 return OK; 00888 } 00889 00890 00891 00892 template<class Array1, class Array2> 00893 bool requireDimensionMatch(std::string& errmsg, 00894 const Array1& array1, 00895 const int a1_dim0, 00896 const Array2& array2, 00897 const int a2_dim0){ 00898 00899 TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 00900 std::invalid_argument, 00901 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!"); 00902 TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ), 00903 std::invalid_argument, 00904 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!"); 00905 00906 bool OK = true; 00907 if(array1.dimension(a1_dim0) != array2.dimension(a2_dim0) ){ 00908 errmsg += "\n>>> dimension("; 00909 errmsg += (char)(48 + a1_dim0); 00910 errmsg += ") of 1st array and dimension("; 00911 errmsg += (char)(48 + a2_dim0); 00912 errmsg += ") of 2nd array are required to match."; 00913 OK = false; 00914 } 00915 return OK; 00916 } 00917 00918 00919 00920 template<class Array1, class Array2> 00921 bool requireDimensionMatch(std::string& errmsg, 00922 const Array1& array1, 00923 const int a1_dim0, const int a1_dim1, 00924 const Array2& array2, 00925 const int a2_dim0, const int a2_dim1){ 00926 00927 TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 00928 std::invalid_argument, 00929 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!"); 00930 TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && (a1_dim1 < array1.rank() ) ), 00931 std::invalid_argument, 00932 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!"); 00933 TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ), 00934 std::invalid_argument, 00935 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!"); 00936 TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && (a2_dim1 < array2.rank() ) ), 00937 std::invalid_argument, 00938 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!"); 00939 00940 bool OK = true; 00941 if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){ 00942 OK = false; 00943 } 00944 if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){ 00945 OK = false; 00946 } 00947 return OK; 00948 } 00949 00950 00951 00952 template<class Array1, class Array2> 00953 bool requireDimensionMatch(std::string& errmsg, 00954 const Array1& array1, 00955 const int a1_dim0, const int a1_dim1, const int a1_dim2, 00956 const Array2& array2, 00957 const int a2_dim0, const int a2_dim1, const int a2_dim2){ 00958 00959 TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 00960 std::invalid_argument, 00961 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!"); 00962 TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && (a1_dim1 < array1.rank() ) ), 00963 std::invalid_argument, 00964 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!"); 00965 TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && (a1_dim2 < array1.rank() ) ), 00966 std::invalid_argument, 00967 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!"); 00968 TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ), 00969 std::invalid_argument, 00970 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!"); 00971 TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && (a2_dim1 < array2.rank() ) ), 00972 std::invalid_argument, 00973 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!"); 00974 TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && (a2_dim2 < array2.rank() ) ), 00975 std::invalid_argument, 00976 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!"); 00977 00978 00979 bool OK = true; 00980 if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){ 00981 OK = false; 00982 } 00983 if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){ 00984 OK = false; 00985 } 00986 if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){ 00987 OK = false; 00988 } 00989 return OK; 00990 } 00991 00992 00993 00994 template<class Array1, class Array2> 00995 bool requireDimensionMatch(std::string& errmsg, 00996 const Array1& array1, 00997 const int a1_dim0, const int a1_dim1, const int a1_dim2, const int a1_dim3, 00998 const Array2& array2, 00999 const int a2_dim0, const int a2_dim1, const int a2_dim2, const int a2_dim3){ 01000 01001 TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 01002 std::invalid_argument, 01003 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!"); 01004 TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && (a1_dim1 < array1.rank() ) ), 01005 std::invalid_argument, 01006 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!"); 01007 TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && (a1_dim2 < array1.rank() ) ), 01008 std::invalid_argument, 01009 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!"); 01010 TEST_FOR_EXCEPTION( !( (0 <= a1_dim3) && (a1_dim3 < array1.rank() ) ), 01011 std::invalid_argument, 01012 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim3 < array1.rank() required!"); 01013 TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ), 01014 std::invalid_argument, 01015 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!"); 01016 TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && (a2_dim1 < array2.rank() ) ), 01017 std::invalid_argument, 01018 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!"); 01019 TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && (a2_dim2 < array2.rank() ) ), 01020 std::invalid_argument, 01021 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!"); 01022 TEST_FOR_EXCEPTION( !( (0 <= a2_dim3) && (a2_dim3 < array2.rank() ) ), 01023 std::invalid_argument, 01024 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim3 < array2.rank() required!"); 01025 bool OK = true; 01026 if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){ 01027 OK = false; 01028 } 01029 if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){ 01030 OK = false; 01031 } 01032 if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){ 01033 OK = false; 01034 } 01035 if( !requireDimensionMatch(errmsg, array1, a1_dim3, array2, a2_dim3) ){ 01036 OK = false; 01037 } 01038 return OK; 01039 } 01040 01041 01042 01043 template<class Array1, class Array2> 01044 bool requireDimensionMatch(std::string& errmsg, 01045 const Array1& array1, 01046 const int a1_dim0, const int a1_dim1, const int a1_dim2, 01047 const int a1_dim3, const int a1_dim4, 01048 const Array2& array2, 01049 const int a2_dim0, const int a2_dim1, const int a2_dim2, 01050 const int a2_dim3, const int a2_dim4){ 01051 01052 TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && (a1_dim0 < array1.rank() ) ), 01053 std::invalid_argument, 01054 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!"); 01055 TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && (a1_dim1 < array1.rank() ) ), 01056 std::invalid_argument, 01057 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!"); 01058 TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && (a1_dim2 < array1.rank() ) ), 01059 std::invalid_argument, 01060 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!"); 01061 TEST_FOR_EXCEPTION( !( (0 <= a1_dim3) && (a1_dim3 < array1.rank() ) ), 01062 std::invalid_argument, 01063 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim3 < array1.rank() required!"); 01064 TEST_FOR_EXCEPTION( !( (0 <= a1_dim4) && (a1_dim4 < array1.rank() ) ), 01065 std::invalid_argument, 01066 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim4 < array1.rank() required!"); 01067 TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && (a2_dim0 < array2.rank() ) ), 01068 std::invalid_argument, 01069 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!"); 01070 TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && (a2_dim1 < array2.rank() ) ), 01071 std::invalid_argument, 01072 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!"); 01073 TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && (a2_dim2 < array2.rank() ) ), 01074 std::invalid_argument, 01075 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!"); 01076 TEST_FOR_EXCEPTION( !( (0 <= a2_dim3) && (a2_dim3 < array2.rank() ) ), 01077 std::invalid_argument, 01078 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim3 < array2.rank() required!"); 01079 TEST_FOR_EXCEPTION( !( (0 <= a2_dim4) && (a2_dim4 < array2.rank() ) ), 01080 std::invalid_argument, 01081 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim4 < array2.rank() required!"); 01082 01083 bool OK = true; 01084 if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){ 01085 OK = false; 01086 } 01087 if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){ 01088 OK = false; 01089 } 01090 if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){ 01091 OK = false; 01092 } 01093 if( !requireDimensionMatch(errmsg, array1, a1_dim3, array2, a2_dim3) ){ 01094 OK = false; 01095 } 01096 if( !requireDimensionMatch(errmsg, array1, a1_dim4, array2, a2_dim4) ){ 01097 OK = false; 01098 } 01099 return OK; 01100 } 01101 01102 01103 01104 template<class Array1, class Array2> 01105 bool requireDimensionMatch(std::string& errmsg, 01106 const Array1& array1, 01107 const Array2& array2){ 01108 01109 TEST_FOR_EXCEPTION( !requireRankMatch(errmsg, array1, array2 ), std::invalid_argument, 01110 ">>> ERROR (Intrepid_Utils::requireDimensionMatch): Arrays with equal ranks are required to test for all dimensions match." ) 01111 01112 bool OK = true; 01113 for(int dim = 0; dim < array1.rank(); dim++){ 01114 if( !requireDimensionMatch(errmsg, array1, dim, array2, dim) ){ 01115 OK = false; 01116 break; 01117 } 01118 } 01119 return OK; 01120 } 01121 01122 01123 } // end namespace Intrepid 01124 01125 #endif
1.7.4