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"
58namespace 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
263template<class Scalar>
264int 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
283template<class Scalar>
284int compareToAnalytic(const Scalar * testMat,
285 std::ifstream & inputFile,
286 Scalar reltol,
287 int iprint,
288 TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
289
290
291
301template<class Scalar>
302void getAnalytic(Teuchos::Array< Teuchos::Array<Scalar> > & testMat,
303 std::ifstream & inputFile,
304 TypeOfExactData analyticDataType = INTREPID_UTILS_FRACTION);
305
315template<class Scalar>
316void 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
527template<class Scalar>
528int 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
611template<class Scalar>
612int 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
696template<class Scalar>
697void 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
748template<class Scalar>
749void 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
807template<class Array>
808bool 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
839template<class Array1, class Array2>
840bool 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
852template<class Array>
853bool 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
902template<class Array1, class Array2>
903bool 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
930template<class Array1, class Array2>
931bool 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
962template<class Array1, class Array2>
963bool 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
1004template<class Array1, class Array2>
1005bool 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
1053template<class Array1, class Array2>
1054bool 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
1114template<class Array1, class Array2>
1115bool 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.
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.
int getFieldRank(const EFunctionSpace spaceType)
Returns the rank of fields in a function space of the specified type.
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 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...
int getDkCardinality(const EOperator operatorType, const int spaceDim)
Returns cardinality of Dk, i.e., the number of all derivatives of order k.
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,...
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...
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.
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 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.
bool requireRankMatch(std::string &errmsg, const Array1 &array1, const Array2 &array2)
Checks if two arrays have matching ranks.
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.