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_Rank.hpp"
54 #include "Intrepid_Types.hpp"
55 #include "Teuchos_Array.hpp"
56 #include "Teuchos_oblackholestream.hpp"
57 #include "Teuchos_RCP.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
int compareToAnalytic(const Teuchos::Array< Teuchos::Array< Scalar > > testMat, std::ifstream &inputFile, Scalar reltol, int iprint, TypeOfExactData analyticDataType=INTREPID_UTILS_FRACTION)
Compares the values in the test matrix testMat to precomputed analytic values stored in a file...
bool requireDimensionMatch(std::string &errmsg, const Array1 &array1, const int a1_dim0, const Array2 &array2, const int a2_dim0)
Checks arrays for a single matching dimension.
bool requireDimensionRange(std::string &errmsg, const Array &array, const int dim, const int lowerBound, const int upperBound)
Checks if the specified array dimension is in the required range.
void setOrdinalTagData(std::vector< std::vector< std::vector< int > > > &tagToOrdinal, std::vector< std::vector< int > > &ordinalToTag, const int *tags, const int basisCard, const int tagSize, const int posScDim, const int posScOrd, const int posDfOrd)
Fills ordinalToTag_ and tagToOrdinal_ by basis-specific tag data.
Contains definitions of custom data types in Intrepid.
int getOperatorOrder(const EOperator operatorType)
Returns order of an operator.
int getOperatorRank(const EFunctionSpace spaceType, const EOperator operatorType, const int spaceDim)
Returns rank of an operator.
int getFieldRank(const EFunctionSpace spaceType)
Returns the rank of fields in a function space of the specified type.
int getDkCardinality(const EOperator operatorType, const int spaceDim)
Returns cardinality of Dk, i.e., the number of all derivatives of order k.
int getDkEnumeration(const int xMult, const int yMult, const int zMult)
Returns the ordinal of a partial derivative of order k based on the multiplicities of the partials dx...
bool requireRankRange(std::string &errmsg, const Array &array, const int lowerBound, const int upperBound)
Checks if the rank of the array argument is in the required range.
void getDkMultiplicities(Teuchos::Array< int > &partialMult, const int derivativeEnum, const EOperator operatorType, const int spaceDim)
Returns multiplicities of dx, dy, and dz based on the enumeration of the partial derivative, its order and the space dimension. Inverse of the getDkEnumeration() method.
bool requireRankMatch(std::string &errmsg, const Array1 &array1, const Array2 &array2)
Checks if two arrays have matching ranks.
void getAnalytic(Teuchos::Array< Teuchos::Array< Scalar > > &testMat, std::ifstream &inputFile, TypeOfExactData analyticDataType=INTREPID_UTILS_FRACTION)
Loads analytic values stored in a file into the matrix testMat, where the output matrix is an array o...