Intrepid
Intrepid_Utils.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Intrepid Package
5 // Copyright (2007) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // Redistribution and use in source and binary forms, with or without
11 // modification, are permitted provided that the following conditions are
12 // met:
13 //
14 // 1. Redistributions of source code must retain the above copyright
15 // notice, this list of conditions and the following disclaimer.
16 //
17 // 2. Redistributions in binary form must reproduce the above copyright
18 // notice, this list of conditions and the following disclaimer in the
19 // documentation and/or other materials provided with the distribution.
20 //
21 // 3. Neither the name of the Corporation nor the names of the
22 // contributors may be used to endorse or promote products derived from
23 // this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 //
37 // Questions? Contact Pavel Bochev (pbboche@sandia.gov)
38 // Denis Ridzal (dridzal@sandia.gov), or
39 // Kara Peterson (kjpeter@sandia.gov)
40 //
41 // ************************************************************************
42 // @HEADER
43 
49 #ifndef INTREPID_UTILS_HPP
50 #define INTREPID_UTILS_HPP
51 
52 #include "Intrepid_ConfigDefs.hpp"
53 #include "Intrepid_Types.hpp"
54 #include "Teuchos_Array.hpp"
55 #include "Teuchos_oblackholestream.hpp"
56 #include "Teuchos_RCP.hpp"
57 #include "Intrepid_KokkosRank.hpp"
58 namespace Intrepid {
59 
60 /***************************************************************************************************
61  ***************************************************************************************************
62  ** **
63  ** Declarations of non-templated utility functions for order and cardinality of operators **
64  ** **
65  ***************************************************************************************************
66  ***************************************************************************************************/
67 
68 
80  int getFieldRank(const EFunctionSpace spaceType);
81 
82 
83 
119  int getOperatorRank(const EFunctionSpace spaceType,
120  const EOperator operatorType,
121  const int spaceDim);
122 
123 
124 
130  int getOperatorOrder(const EOperator operatorType);
131 
132 
133 
158  int getDkEnumeration(const int xMult,
159  const int yMult = -1,
160  const int zMult = -1);
161 
162 
163 
172  void getDkMultiplicities(Teuchos::Array<int>& partialMult,
173  const int derivativeEnum,
174  const EOperator operatorType,
175  const int spaceDim);
176 
177 
178 
197  int getDkCardinality(const EOperator operatorType,
198  const int spaceDim);
199 
200 
201 
202 /***************************************************************************************************
203  ***************************************************************************************************
204  ** **
205  ** Declarations of helper functions for the basis class **
206  ** **
207  ***************************************************************************************************
208  ***************************************************************************************************/
209 
221  void setOrdinalTagData(std::vector<std::vector<std::vector<int> > > &tagToOrdinal,
222  std::vector<std::vector<int> > &ordinalToTag,
223  const int *tags,
224  const int basisCard,
225  const int tagSize,
226  const int posScDim,
227  const int posScOrd,
228  const int posDfOrd);
229 
230 
231 
232 /***************************************************************************************************
233  ***************************************************************************************************
234  ** **
235  ** Declarations of templated utility functions **
236  ** **
237  ***************************************************************************************************
238  ***************************************************************************************************/
239 
240  enum TypeOfExactData{
241  INTREPID_UTILS_FRACTION=0,
242  INTREPID_UTILS_SCALAR
243  };
244 
245 /***************************************************************************************************
246  * *
247  * Utility functions for handling external data in tests *
248  * *
249  ***************************************************************************************************/
250 
263 template<class Scalar>
264 int compareToAnalytic(const Teuchos::Array< Teuchos::Array<Scalar> > testMat,
265  std::ifstream & inputFile,
266  Scalar reltol,
267  int iprint,
268  TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
269 
283 template<class Scalar>
284 int compareToAnalytic(const Scalar * testMat,
285  std::ifstream & inputFile,
286  Scalar reltol,
287  int iprint,
288  TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
289 
290 
291 
301 template<class Scalar>
302 void getAnalytic(Teuchos::Array< Teuchos::Array<Scalar> > & testMat,
303  std::ifstream & inputFile,
304  TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
305 
315 template<class Scalar>
316 void getAnalytic(Scalar * testMat,
317  std::ifstream & inputFile,
318  TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
319 
320 
321 
322 /***************************************************************************************************
323  * *
324  * Utility functions for checking requirements on ranks and dimensions of array arguments *
325  * *
326  ***************************************************************************************************/
327 
328 
338  template<class Array>
339  bool requireRankRange(std::string& errmsg,
340  const Array& array,
341  const int lowerBound,
342  const int upperBound);
343 
344 
345 
354  template<class Array1, class Array2>
355  bool requireRankMatch(std::string& errmsg,
356  const Array1& array1,
357  const Array2& array2);
358 
359 
360 
371  template<class Array>
372  bool requireDimensionRange(std::string& errmsg,
373  const Array& array,
374  const int dim,
375  const int lowerBound,
376  const int upperBound);
377 
378 
379 
390  template<class Array1, class Array2>
391  bool requireDimensionMatch(std::string& errmsg,
392  const Array1& array1,
393  const int a1_dim0,
394  const Array2& array2,
395  const int a2_dim0);
396 
397 
398 
411  template<class Array1, class Array2>
412  bool requireDimensionMatch(std::string& errmsg,
413  const Array1& array1,
414  const int a1_dim0, const int a1_dim1,
415  const Array2& array2,
416  const int a2_dim0, const int a2_dim1);
417 
418 
419 
434  template<class Array1, class Array2>
435  bool requireDimensionMatch(std::string& errmsg,
436  const Array1& array1,
437  const int a1_dim0, const int a1_dim1, const int a1_dim2,
438  const Array2& array2,
439  const int a2_dim0, const int a2_dim1, const int a2_dim2);
440 
441 
442 
459  template<class Array1, class Array2>
460  bool requireDimensionMatch(std::string& errmsg,
461  const Array1& array1,
462  const int a1_dim0, const int a1_dim1, const int a1_dim2, const int a1_dim3,
463  const Array2& array2,
464  const int a2_dim0, const int a2_dim1, const int a2_dim2, const int a2_dim3);
465 
466 
467 
486  template<class Array1, class Array2>
487  bool requireDimensionMatch(std::string& errmsg,
488  const Array1& array1,
489  const int a1_dim0, const int a1_dim1,
490  const int a1_dim2, const int a1_dim3, const int a1_dim4,
491  const Array2& array2,
492  const int a2_dim0, const int a2_dim1,
493  const int a2_dim2, const int a2_dim3, const int a2_dim4);
494 
495 
496 
505  template<class Array1, class Array2>
506  bool requireDimensionMatch(std::string& errmsg,
507  const Array1& array1,
508  const Array2& array2);
509 
510 
511 
512 /***************************************************************************************************
513  ***************************************************************************************************
514  ** **
515  ** Definitions of templated functions **
516  ** **
517  ***************************************************************************************************
518  ***************************************************************************************************/
519 
520 
521 /***************************************************************************************************
522  * *
523  * Utility functions for handling external data in tests *
524  * *
525  ***************************************************************************************************/
526 
527 template<class Scalar>
528 int compareToAnalytic(const Teuchos::Array< Teuchos::Array<Scalar> > testMat,
529  std::ifstream & inputFile,
530  Scalar reltol,
531  int iprint,
532  TypeOfExactData analyticDataType ) {
533 
534  // This little trick lets us print to std::cout only if
535  // iprint > 0.
536  Teuchos::RCP<std::ostream> outStream;
537  Teuchos::oblackholestream bhs; // outputs nothing
538  if (iprint > 0)
539  outStream = Teuchos::rcp(&std::cout, false);
540  else
541  outStream = Teuchos::rcp(&bhs, false);
542 
543  // Save the format state of the original std::cout.
544  Teuchos::oblackholestream oldFormatState;
545  oldFormatState.copyfmt(std::cout);
546 
547  std::string line;
548  Scalar testentry;
549  Scalar abstol;
550  Scalar absdiff;
551  int i=0, j=0;
552  int err = 0;
553 
554  while (! inputFile.eof() )
555  {
556  std::getline (inputFile,line);
557  std::istringstream linestream(line);
558  std::string chunk;
559  j = 0;
560  while( linestream >> chunk ) {
561  int num1;
562  int num2;
563  std::string::size_type loc = chunk.find( "/", 0);
564  if( loc != std::string::npos ) {
565  chunk.replace( loc, 1, " ");
566  std::istringstream chunkstream(chunk);
567  chunkstream >> num1;
568  chunkstream >> num2;
569  testentry = (Scalar)(num1)/(Scalar)(num2);
570  abstol = ( std::fabs(testentry) < reltol ? reltol : std::fabs(reltol*testentry) );
571  absdiff = std::fabs(testentry - testMat[i][j]);
572  if (absdiff > abstol) {
573  err++;
574  *outStream << "FAILURE --> ";
575  }
576  *outStream << "entry[" << i << "," << j << "]:" << " "
577  << testMat[i][j] << " " << num1 << "/" << num2 << " "
578  << absdiff << " " << "<?" << " " << abstol << "\n";
579  }
580  else {
581  std::istringstream chunkstream(chunk);
582  if (analyticDataType == INTREPID_UTILS_FRACTION) {
583  chunkstream >> num1;
584  testentry = (Scalar)(num1);
585  }
586  else if (analyticDataType == INTREPID_UTILS_SCALAR)
587  chunkstream >> testentry;
588  abstol = ( std::fabs(testentry) < reltol ?reltol : std::fabs(reltol*testentry) );
589  absdiff = std::fabs(testentry - testMat[i][j]);
590  if (absdiff > abstol) {
591  err++;
592  *outStream << "FAILURE --> ";
593  }
594  *outStream << "entry[" << i << "," << j << "]:" << " "
595  << testMat[i][j] << " " << testentry << " "
596  << absdiff << " " << "<?" << " " << abstol << "\n";
597  }
598  j++;
599  }
600  i++;
601  }
602 
603  // reset format state of std::cout
604  std::cout.copyfmt(oldFormatState);
605 
606  return err;
607 } // end compareToAnalytic
608 
609 
610 
611 template<class Scalar>
612 int compareToAnalytic(const Scalar * testMat,
613  std::ifstream & inputFile,
614  Scalar reltol,
615  int iprint,
616  TypeOfExactData analyticDataType ) {
617 
618  // This little trick lets us print to std::cout only if
619  // iprint > 0.
620  Teuchos::RCP<std::ostream> outStream;
621  Teuchos::oblackholestream bhs; // outputs nothing
622  if (iprint > 0)
623  outStream = Teuchos::rcp(&std::cout, false);
624  else
625  outStream = Teuchos::rcp(&bhs, false);
626 
627  // Save the format state of the original std::cout.
628  Teuchos::oblackholestream oldFormatState;
629  oldFormatState.copyfmt(std::cout);
630 
631  std::string line;
632  Scalar testentry;
633  Scalar abstol;
634  Scalar absdiff;
635  int i=0, j=0, offset=0;
636  int err = 0;
637 
638  while (! inputFile.eof() )
639  {
640  std::getline (inputFile,line);
641  std::istringstream linestream(line);
642  std::string chunk;
643  j = 0;
644  while( linestream >> chunk ) {
645  int num1;
646  int num2;
647  std::string::size_type loc = chunk.find( "/", 0);
648  if( loc != std::string::npos ) {
649  chunk.replace( loc, 1, " ");
650  std::istringstream chunkstream(chunk);
651  chunkstream >> num1;
652  chunkstream >> num2;
653  testentry = (Scalar)(num1)/(Scalar)(num2);
654  abstol = ( std::fabs(testentry) < reltol ? reltol : std::fabs(reltol*testentry) );
655  absdiff = std::fabs(testentry - testMat[i*offset+j]);
656  if (absdiff > abstol) {
657  err++;
658  *outStream << "FAILURE --> ";
659  }
660  *outStream << "entry[" << i << "," << j << "]:" << " "
661  << testMat[i*offset+j] << " " << num1 << "/" << num2 << " "
662  << absdiff << " " << "<?" << " " << abstol << "\n";
663  }
664  else {
665  std::istringstream chunkstream(chunk);
666  if (analyticDataType == INTREPID_UTILS_FRACTION) {
667  chunkstream >> num1;
668  testentry = (Scalar)(num1);
669  }
670  else if (analyticDataType == INTREPID_UTILS_SCALAR)
671  chunkstream >> testentry;
672  abstol = ( std::fabs(testentry) < reltol ?reltol : std::fabs(reltol*testentry) );
673  absdiff = std::fabs(testentry - testMat[i*offset+j]);
674  if (absdiff > abstol) {
675  err++;
676  *outStream << "FAILURE --> ";
677  }
678  *outStream << "entry[" << i << "," << j << "]:" << " "
679  << testMat[i*offset+j] << " " << testentry << " "
680  << absdiff << " " << "<?" << " " << abstol << "\n";
681  }
682  j++;
683  }
684  i++;
685  offset = j;
686  }
687 
688  // reset format state of std::cout
689  std::cout.copyfmt(oldFormatState);
690 
691  return err;
692 } // end compareToAnalytic
693 
694 
695 
696 template<class Scalar>
697 void getAnalytic(Teuchos::Array< Teuchos::Array<Scalar> > & testMat,
698  std::ifstream & inputFile,
699  TypeOfExactData analyticDataType ) {
700 
701  // Save the format state of the original std::cout.
702  Teuchos::oblackholestream oldFormatState;
703  oldFormatState.copyfmt(std::cout);
704 
705  std::string line;
706  Scalar testentry;
707  int i=0, j=0;
708 
709  while (! inputFile.eof() )
710  {
711  std::getline (inputFile,line);
712  std::istringstream linestream(line);
713  std::string chunk;
714  j = 0;
715  while( linestream >> chunk ) {
716  int num1;
717  int num2;
718  std::string::size_type loc = chunk.find( "/", 0);
719  if( loc != std::string::npos ) {
720  chunk.replace( loc, 1, " ");
721  std::istringstream chunkstream(chunk);
722  chunkstream >> num1;
723  chunkstream >> num2;
724  testentry = (Scalar)(num1)/(Scalar)(num2);
725  testMat[i][j] = testentry;
726  }
727  else {
728  std::istringstream chunkstream(chunk);
729  if (analyticDataType == INTREPID_UTILS_FRACTION) {
730  chunkstream >> num1;
731  testentry = (Scalar)(num1);
732  }
733  else if (analyticDataType == INTREPID_UTILS_SCALAR)
734  chunkstream >> testentry;
735  testMat[i][j] = testentry;
736  }
737  j++;
738  }
739  i++;
740  }
741 
742  // reset format state of std::cout
743  std::cout.copyfmt(oldFormatState);
744 } // end getAnalytic
745 
746 
747 
748 template<class Scalar>
749 void getAnalytic(Scalar * testMat,
750  std::ifstream & inputFile,
751  TypeOfExactData analyticDataType) {
752 
753  // Save the format state of the original std::cout.
754  Teuchos::oblackholestream oldFormatState;
755  oldFormatState.copyfmt(std::cout);
756 
757  std::string line;
758  Scalar testentry;
759  int i=0, j=0, offset=0;
760 
761  while (! inputFile.eof() )
762  {
763  std::getline (inputFile,line);
764  std::istringstream linestream(line);
765  std::string chunk;
766  j = 0;
767  while( linestream >> chunk ) {
768  int num1;
769  int num2;
770  std::string::size_type loc = chunk.find( "/", 0);
771  if( loc != std::string::npos ) {
772  chunk.replace( loc, 1, " ");
773  std::istringstream chunkstream(chunk);
774  chunkstream >> num1;
775  chunkstream >> num2;
776  testentry = (Scalar)(num1)/(Scalar)(num2);
777  testMat[i*offset+j] = testentry;
778  }
779  else {
780  std::istringstream chunkstream(chunk);
781  if (analyticDataType == INTREPID_UTILS_FRACTION) {
782  chunkstream >> num1;
783  testentry = (Scalar)(num1);
784  }
785  else if (analyticDataType == INTREPID_UTILS_SCALAR)
786  chunkstream >> testentry;
787  testMat[i*offset+j] = testentry;
788  }
789  j++;
790  }
791  i++;
792  offset = j;
793  }
794 
795  // reset format state of std::cout
796  std::cout.copyfmt(oldFormatState);
797 } // end getAnalytic
798 
799 
800 /***************************************************************************************************
801  * *
802  * Utility functions for checking requirements on ranks and dimensions of array arguments *
803  * *
804  ***************************************************************************************************/
805 
806 
807 template<class Array>
808 bool requireRankRange(std::string& errmsg,
809  const Array& array,
810  const int lowerBound,
811  const int upperBound){
812 
813  TEUCHOS_TEST_FOR_EXCEPTION( (lowerBound > upperBound) , std::invalid_argument,
814  ">>> ERROR (Intrepid_Utils::requireRankRange): lowerBound <= upperBound required!");
815 
816  bool OK = true;
817  if( (lowerBound == upperBound) && !(getrank(array) == (size_t)lowerBound) ) {
818  errmsg += "\n>>> Array rank = ";
819  errmsg += (char)(48 + getrank(array) );
820  errmsg += " while rank-";
821  errmsg += (char) (48 + lowerBound);
822  errmsg += " array required.";
823  OK = false;
824  }
825  else if ( (lowerBound < upperBound) && !( ((size_t)lowerBound <= getrank(array) ) && (getrank(array) <= (size_t)upperBound) ) ){
826  errmsg += "\n>>> Array rank = ";
827  errmsg += (char)(48 + getrank(array) );
828  errmsg += " while a rank between ";
829  errmsg += (char) (48 + lowerBound);
830  errmsg += " and ";
831  errmsg += (char) (48 + upperBound);
832  errmsg += " is required.";
833  OK = false;
834  }
835  return OK;
836 }
837 
838 
839 template<class Array1, class Array2>
840 bool requireRankMatch(std::string& errmsg,
841  const Array1& array1,
842  const Array2& array2){
843  bool OK = true;
844  if(getrank(array1) != getrank(array2) ) {
845  errmsg += "\n>>> Array ranks are required to match.";
846  OK = false;
847  }
848  return OK;
849 }
850 
851 
852 template<class Array>
853 bool requireDimensionRange(std::string& errmsg,
854  const Array& array,
855  const int dim,
856  const int lowerBound,
857  const int upperBound){
858 
859  TEUCHOS_TEST_FOR_EXCEPTION( (lowerBound > upperBound) , std::invalid_argument,
860  ">>> ERROR (Intrepid_Utils::requireDimensionRange): lowerBound <= upperBound required!");
861  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= dim) && ((size_t)dim < getrank(array) ) ),
862  std::invalid_argument,
863  ">>> ERROR (Intrepid_Utils::requireDimensionRange): 0 <= dim < array.rank() required!");
864 
865  bool OK = true;
866  if( (lowerBound > upperBound) || ( (size_t)dim >= getrank(array) ) ) {
867  errmsg += "\n>>> Unexpected error: ";
868  OK = false;
869  }
870  if( (lowerBound == upperBound) && !(static_cast<int>(array.dimension(dim)) == lowerBound) ) {
871  errmsg += "\n>>> dimension(";
872  errmsg += (char)(48 + dim);
873  errmsg += ") = ";
874  errmsg += (char)(48 + array.dimension(dim) );
875  errmsg += " while dimension(";
876  errmsg += (char)(48 + dim);
877  errmsg += ") = ";
878  errmsg += (char)(48 + lowerBound);
879  errmsg += " required.";
880  OK = false;
881  }
882  else if( (lowerBound < upperBound) &&
883  !( ((size_t)lowerBound <= (size_t)array.dimension(dim) ) && (static_cast<size_t>(array.dimension(dim)) <= (size_t)upperBound) ) ){
884  errmsg += "\n>>> dimension(";
885  errmsg += (char)(48 + dim);
886  errmsg += ") = ";
887  errmsg += (char)(48 + array.dimension(dim) );
888  errmsg += " while ";
889  errmsg += (char)(48 + lowerBound);
890  errmsg += " <= dimension(";
891  errmsg += (char)(48 + dim);
892  errmsg += ") <= ";
893  errmsg +=(char)(48 + upperBound);
894  errmsg +=" required.";
895  OK = false;
896  }
897  return OK;
898 }
899 
900 
901 
902 template<class Array1, class Array2>
903 bool requireDimensionMatch(std::string& errmsg,
904  const Array1& array1,
905  const int a1_dim0,
906  const Array2& array2,
907  const int a2_dim0){
908 
909  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && ((size_t)a1_dim0 < getrank(array1) ) ),
910  std::invalid_argument,
911  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
912  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && ((size_t)a2_dim0 < getrank(array2) ) ),
913  std::invalid_argument,
914  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
915 
916  bool OK = true;
917  if(static_cast<int>(array1.dimension(a1_dim0)) != static_cast<int>(array2.dimension(a2_dim0)) ){
918  errmsg += "\n>>> dimension(";
919  errmsg += (char)(48 + a1_dim0);
920  errmsg += ") of 1st array and dimension(";
921  errmsg += (char)(48 + a2_dim0);
922  errmsg += ") of 2nd array are required to match.";
923  OK = false;
924  }
925  return OK;
926 }
927 
928 
929 
930 template<class Array1, class Array2>
931 bool requireDimensionMatch(std::string& errmsg,
932  const Array1& array1,
933  const int a1_dim0, const int a1_dim1,
934  const Array2& array2,
935  const int a2_dim0, const int a2_dim1){
936 
937  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && ((size_t)a1_dim0 < getrank(array1) ) ),
938  std::invalid_argument,
939  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
940  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && ((size_t)a1_dim1 < getrank(array1) ) ),
941  std::invalid_argument,
942  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!");
943  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && ((size_t)a2_dim0 < getrank(array2) ) ),
944  std::invalid_argument,
945  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
946  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && ((size_t)a2_dim1 < getrank(array2) ) ),
947  std::invalid_argument,
948  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!");
949 
950  bool OK = true;
951  if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){
952  OK = false;
953  }
954  if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){
955  OK = false;
956  }
957  return OK;
958 }
959 
960 
961 
962 template<class Array1, class Array2>
963 bool requireDimensionMatch(std::string& errmsg,
964  const Array1& array1,
965  const int a1_dim0, const int a1_dim1, const int a1_dim2,
966  const Array2& array2,
967  const int a2_dim0, const int a2_dim1, const int a2_dim2){
968 
969  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && ((size_t)a1_dim0 < getrank(array1) ) ),
970  std::invalid_argument,
971  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
972  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && ((size_t)a1_dim1 < getrank(array1) ) ),
973  std::invalid_argument,
974  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!");
975  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && ((size_t)a1_dim2 < getrank(array1) ) ),
976  std::invalid_argument,
977  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!");
978  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && ((size_t)a2_dim0 < getrank(array2) ) ),
979  std::invalid_argument,
980  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
981  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && ((size_t)a2_dim1 < getrank(array2) ) ),
982  std::invalid_argument,
983  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!");
984  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && ((size_t)a2_dim2 < getrank(array2) ) ),
985  std::invalid_argument,
986  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!");
987 
988 
989  bool OK = true;
990  if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){
991  OK = false;
992  }
993  if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){
994  OK = false;
995  }
996  if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){
997  OK = false;
998  }
999  return OK;
1000 }
1001 
1002 
1003 
1004 template<class Array1, class Array2>
1005 bool requireDimensionMatch(std::string& errmsg,
1006  const Array1& array1,
1007  const int a1_dim0, const int a1_dim1, const int a1_dim2, const int a1_dim3,
1008  const Array2& array2,
1009  const int a2_dim0, const int a2_dim1, const int a2_dim2, const int a2_dim3){
1010 
1011  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && ((size_t)a1_dim0 < getrank(array1) ) ),
1012  std::invalid_argument,
1013  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
1014  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && ((size_t)a1_dim1 < getrank(array1) ) ),
1015  std::invalid_argument,
1016  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!");
1017  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && ((size_t)a1_dim2 < getrank(array1) ) ),
1018  std::invalid_argument,
1019  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!");
1020  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim3) && ((size_t)a1_dim3 < getrank(array1) ) ),
1021  std::invalid_argument,
1022  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim3 < array1.rank() required!");
1023  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && ((size_t)a2_dim0 < getrank(array2) ) ),
1024  std::invalid_argument,
1025  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
1026  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && ((size_t)a2_dim1 < getrank(array2) ) ),
1027  std::invalid_argument,
1028  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!");
1029  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && ((size_t)a2_dim2 < getrank(array2) ) ),
1030  std::invalid_argument,
1031  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!");
1032  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim3) && ((size_t)a2_dim3 < getrank(array2) ) ),
1033  std::invalid_argument,
1034  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim3 < array2.rank() required!");
1035  bool OK = true;
1036  if( !requireDimensionMatch(errmsg, array1, static_cast<int>(a1_dim0), array2, static_cast<int>(a2_dim0)) ){
1037  OK = false;
1038  }
1039  if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){
1040  OK = false;
1041  }
1042  if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){
1043  OK = false;
1044  }
1045  if( !requireDimensionMatch(errmsg, array1, a1_dim3, array2, a2_dim3) ){
1046  OK = false;
1047  }
1048  return OK;
1049 }
1050 
1051 
1052 
1053 template<class Array1, class Array2>
1054 bool requireDimensionMatch(std::string& errmsg,
1055  const Array1& array1,
1056  const int a1_dim0, const int a1_dim1, const int a1_dim2,
1057  const int a1_dim3, const int a1_dim4,
1058  const Array2& array2,
1059  const int a2_dim0, const int a2_dim1, const int a2_dim2,
1060  const int a2_dim3, const int a2_dim4){
1061 
1062  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim0) && ((size_t)a1_dim0 < getrank(array1) ) ),
1063  std::invalid_argument,
1064  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim0 < array1.rank() required!");
1065  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim1) && ((size_t)a1_dim1 < getrank(array1) ) ),
1066  std::invalid_argument,
1067  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim1 < array1.rank() required!");
1068  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim2) && ((size_t)a1_dim2 < getrank(array1) ) ),
1069  std::invalid_argument,
1070  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim2 < array1.rank() required!");
1071  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim3) && ((size_t)a1_dim3 < getrank(array1) ) ),
1072  std::invalid_argument,
1073  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim3 < array1.rank() required!");
1074  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a1_dim4) && ((size_t)a1_dim4 < getrank(array1) ) ),
1075  std::invalid_argument,
1076  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a1_dim4 < array1.rank() required!");
1077  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim0) && ((size_t)a2_dim0 < getrank(array2) ) ),
1078  std::invalid_argument,
1079  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim0 < array2.rank() required!");
1080  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim1) && ((size_t)a2_dim1 < getrank(array2) ) ),
1081  std::invalid_argument,
1082  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim1 < array2.rank() required!");
1083  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim2) && ((size_t)a2_dim2 < getrank(array2) ) ),
1084  std::invalid_argument,
1085  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim2 < array2.rank() required!");
1086  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim3) && ((size_t)a2_dim3 < getrank(array2) ) ),
1087  std::invalid_argument,
1088  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim3 < array2.rank() required!");
1089  TEUCHOS_TEST_FOR_EXCEPTION( !( (0 <= a2_dim4) && ((size_t)a2_dim4 < getrank(array2) ) ),
1090  std::invalid_argument,
1091  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): 0 <= a2_dim4 < array2.rank() required!");
1092 
1093  bool OK = true;
1094  if( !requireDimensionMatch(errmsg, array1, a1_dim0, array2, a2_dim0) ){
1095  OK = false;
1096  }
1097  if( !requireDimensionMatch(errmsg, array1, a1_dim1, array2, a2_dim1) ){
1098  OK = false;
1099  }
1100  if( !requireDimensionMatch(errmsg, array1, a1_dim2, array2, a2_dim2) ){
1101  OK = false;
1102  }
1103  if( !requireDimensionMatch(errmsg, array1, a1_dim3, array2, a2_dim3) ){
1104  OK = false;
1105  }
1106  if( !requireDimensionMatch(errmsg, array1, a1_dim4, array2, a2_dim4) ){
1107  OK = false;
1108  }
1109  return OK;
1110 }
1111 
1112 
1113 
1114 template<class Array1, class Array2>
1115 bool requireDimensionMatch(std::string& errmsg,
1116  const Array1& array1,
1117  const Array2& array2){
1118 
1119  TEUCHOS_TEST_FOR_EXCEPTION( !requireRankMatch(errmsg, array1, array2 ), std::invalid_argument,
1120  ">>> ERROR (Intrepid_Utils::requireDimensionMatch): Arrays with equal ranks are required to test for all dimensions match." )
1121 
1122  bool OK = true;
1123  for(size_t dim = 0; dim < getrank(array1); dim++){
1124  if( !requireDimensionMatch(errmsg, array1, dim, array2, dim) ){
1125  OK = false;
1126  break;
1127  }
1128  }
1129  return OK;
1130 }
1131 
1132 
1133 } // end namespace Intrepid
1134 
1135 #endif
Contains definitions of custom data types in Intrepid.