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