Intrepid
test_01.cpp
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 
50 #include "Intrepid_HGRAD_LINE_Cn_FEM.hpp"
52 #include "Intrepid_ArrayTools.hpp"
53 #include "Intrepid_PointTools.hpp"
55 #include "Teuchos_oblackholestream.hpp"
56 #include "Teuchos_RCP.hpp"
57 #include "Teuchos_GlobalMPISession.hpp"
58 
59 using namespace std;
60 using namespace Intrepid;
61 
62 #define INTREPID_TEST_COMMAND( S , throwCounter, nException ) \
63 { \
64  ++nException; \
65  try { \
66  S ; \
67  } \
68  catch (const std::logic_error & err) { \
69  ++throwCounter; \
70  *outStream << "Expected Error " << nException << " -------------------------------------------------------------\n"; \
71  *outStream << err.what() << '\n'; \
72  *outStream << "-------------------------------------------------------------------------------" << "\n\n"; \
73  }; \
74 }
75 
76 
77 int main(int argc, char *argv[]) {
78 
79  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
80 
81  // This little trick lets us print to std::cout only if
82  // a (dummy) command-line argument is provided.
83  int iprint = argc - 1;
84  Teuchos::RCP<std::ostream> outStream;
85  Teuchos::oblackholestream bhs; // outputs nothing
86  if (iprint > 0)
87  outStream = Teuchos::rcp(&std::cout, false);
88  else
89  outStream = Teuchos::rcp(&bhs, false);
90 
91  // Save the format state of the original std::cout.
92  Teuchos::oblackholestream oldFormatState;
93  oldFormatState.copyfmt(std::cout);
94 
95  *outStream \
96  << "===============================================================================\n" \
97  << "| |\n" \
98  << "| Unit Test (Basis_HGRAD_LINE_Cn_FEM) |\n" \
99  << "| |\n" \
100  << "| 1) Conversion of Dof tags into Dof ordinals and back |\n" \
101  << "| 2) Basis values for VALUE, GRAD, CURL, and Dk operators |\n" \
102  << "| |\n" \
103  << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov), |\n" \
104  << "| Denis Ridzal (dridzal@sandia.gov), |\n" \
105  << "| Kara Peterson (kjpeter@sandia.gov). |\n" \
106  << "| |\n" \
107  << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
108  << "| Trilinos website: http://trilinos.sandia.gov |\n" \
109  << "| |\n" \
110  << "===============================================================================\n"\
111  << "| TEST 1: Basis creation, exception testing |\n"\
112  << "===============================================================================\n";
113 
114 
115  // Define basis and error flag
116  shards::CellTopology line(shards::getCellTopologyData< shards::Line<> >()); // create cell topology
117  const int deg = 5;
118 
119  // get the points for the basis
120  FieldContainer<double> pts(PointTools::getLatticeSize(line,deg),1);
121  PointTools::getLattice<double,FieldContainer<double> >(pts,line,deg);
122 
124  int errorFlag = 0;
125 
126  // Initialize throw counter for exception testing
127  int nException = 0;
128  int throwCounter = 0;
129 
130  // Define array containing vertices of the reference Line and a few other points
131  int numIntervals = 100;
132  FieldContainer<double> lineNodes(numIntervals+1, 1);
133  for (int i=0; i<numIntervals+1; i++) {
134  lineNodes(i,0) = -1.0+(2.0*(double)i)/(double)numIntervals;
135  }
136 
137  // Generic array for the output values; needs to be properly resized depending on the operator type
139 
140  try{
141  // exception #1: DIV cannot be applied to scalar functions
142  // resize vals to rank-2 container with dimensions (num. points, num. basis functions)
143  vals.resize(lineBasis.getCardinality(), lineNodes.dimension(0) );
144  //INTREPID_TEST_COMMAND( lineBasis.getValues(vals, lineNodes, OPERATOR_DIV), throwCounter, nException );
145 
146  // Exceptions 1-5: all bf tags/bf Ids below are wrong and should cause getDofOrdinal() and
147  // getDofTag() to access invalid array elements thereby causing bounds check exception
148  // exception #1
149  INTREPID_TEST_COMMAND( lineBasis.getDofOrdinal(2,0,0), throwCounter, nException );
150  // exception #2
151  INTREPID_TEST_COMMAND( lineBasis.getDofOrdinal(1,1,1), throwCounter, nException );
152  // exception #3
153  INTREPID_TEST_COMMAND( lineBasis.getDofOrdinal(1,0,7), throwCounter, nException );
154  // exception #4
155  INTREPID_TEST_COMMAND( lineBasis.getDofTag(6), throwCounter, nException );
156  // exception #5
157  INTREPID_TEST_COMMAND( lineBasis.getDofTag(-1), throwCounter, nException );
158  // not an exception
159  INTREPID_TEST_COMMAND( lineBasis.getDofTag(5), throwCounter, nException ); --nException;
160 
161 #ifdef HAVE_INTREPID_DEBUG
162  // Exceptions 6-14 test exception handling with incorrectly dimensioned input/output arrays
163  // exception #6: input points array must be of rank-2
164  FieldContainer<double> badPoints1(4, 5, 3);
165  INTREPID_TEST_COMMAND( lineBasis.getValues(vals, badPoints1, OPERATOR_VALUE), throwCounter, nException );
166 
167  // exception #7: dimension 1 in the input point array must equal space dimension of the cell
168  FieldContainer<double> badPoints2(4, 3);
169  INTREPID_TEST_COMMAND( lineBasis.getValues(vals, badPoints2, OPERATOR_VALUE), throwCounter, nException );
170 
171  // exception #8: output values must be of rank-2 for OPERATOR_VALUE
172  FieldContainer<double> badVals1(4, 3, 1);
173  INTREPID_TEST_COMMAND( lineBasis.getValues(badVals1, lineNodes, OPERATOR_VALUE), throwCounter, nException );
174 
175  // exception #9: output values must be of rank-3 for OPERATOR_GRAD
176  FieldContainer<double> badVals2(4, 3);
177  INTREPID_TEST_COMMAND( lineBasis.getValues(badVals2, lineNodes, OPERATOR_GRAD), throwCounter, nException );
178 
179  // exception #10: output values must be of rank-2 for OPERATOR_D1
180  INTREPID_TEST_COMMAND( lineBasis.getValues(badVals2, lineNodes, OPERATOR_D1), throwCounter, nException );
181 
182  // exception #11: incorrect 0th dimension of output array (must equal number of basis functions)
183  FieldContainer<double> badVals3(lineBasis.getCardinality() + 1, lineNodes.dimension(0));
184  INTREPID_TEST_COMMAND( lineBasis.getValues(badVals3, lineNodes, OPERATOR_VALUE), throwCounter, nException );
185 
186  // exception #12: incorrect 1st dimension of output array (must equal number of points)
187  FieldContainer<double> badVals4(lineBasis.getCardinality(), lineNodes.dimension(0) + 1);
188  INTREPID_TEST_COMMAND( lineBasis.getValues(badVals4, lineNodes, OPERATOR_VALUE), throwCounter, nException );
189 
190  // exception #13: incorrect 2nd dimension of output array (must equal spatial dimension)
191  FieldContainer<double> badVals5(lineBasis.getCardinality(), lineNodes.dimension(0), 2);
192  INTREPID_TEST_COMMAND( lineBasis.getValues(badVals5, lineNodes, OPERATOR_GRAD), throwCounter, nException );
193 
194 
195  // not an exception
196  FieldContainer<double> goodVals2(lineBasis.getCardinality(), lineNodes.dimension(0));
197  INTREPID_TEST_COMMAND( lineBasis.getValues(goodVals2, lineNodes, OPERATOR_VALUE), throwCounter, nException ); --nException;
198 #endif
199 
200  }
201  catch (const std::logic_error & err) {
202  *outStream << "UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
203  *outStream << err.what() << '\n';
204  *outStream << "-------------------------------------------------------------------------------" << "\n\n";
205  errorFlag = -1000;
206  };
207 
208  // Check if number of thrown exceptions matches the one we expect
209  if (throwCounter != nException) {
210  errorFlag++;
211  *outStream << std::setw(70) << "FAILURE! Incorrect number of exceptions." << "\n";
212  }
213 
214  *outStream \
215  << "\n"
216  << "===============================================================================\n" \
217  << "| TEST 2: correctness of basis function values |\n" \
218  << "===============================================================================\n";
219  outStream -> precision(20);
220 
221 
222  try {
223  // Check Kronecker property for Lagrange polynomials.
224  int maxorder = 4;
225 
226  for (int ordi=1; ordi <= maxorder; ordi++) {
227  FieldContainer<double> pts(PointTools::getLatticeSize(line,ordi),1);
228  PointTools::getLattice<double,FieldContainer<double> >(pts,line,ordi);
230  FieldContainer<double> vals(lineBasis.getCardinality(),pts.dimension(0));
231  lineBasis.getValues(vals,pts,OPERATOR_VALUE);
232  for (int i=0;i<lineBasis.getCardinality();i++) {
233  for (int j=0;j<pts.dimension(0);j++) {
234  if ( i==j && std::abs( vals(i,j) - 1.0 ) > INTREPID_TOL ) {
235  errorFlag++;
236  *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n";
237  *outStream << " Basis function " << i << " does not have unit value at its node\n";
238  }
239  if ( i!=j && std::abs( vals(i,j) ) > INTREPID_TOL ) {
240  errorFlag++;
241  *outStream << std::setw(70) << "^^^^----FAILURE!" << "\n";
242  *outStream << " Basis function " << i << " does not vanish at node " << j << "\n";
243  }
244  }
245  }
246  }
247  }
248  // Catch unexpected errors
249  catch (const std::logic_error & err) {
250  *outStream << err.what() << "\n\n";
251  errorFlag = -1000;
252  };
253 
254  if (errorFlag != 0)
255  std::cout << "End Result: TEST FAILED\n";
256  else
257  std::cout << "End Result: TEST PASSED\n";
258 
259  // reset format state of std::cout
260  std::cout.copyfmt(oldFormatState);
261 
262  return errorFlag;
263 }
int main(int argc, char *argv[])
Performs a code-code comparison to FIAT for Nedelec bases on tets (values and curls)
Definition: test_01.cpp:65
Header file for utility class to provide array tools, such as tensor contractions,...
Header file for the abstract base class Intrepid::DefaultCubatureFactory.
Header file for utility class to provide multidimensional containers.
Header file for the Intrepid::FunctionSpaceTools class.
Header file for utility class to provide point tools, such as barycentric coordinates,...
Implementation of the locally H(grad)-compatible FEM basis of variable order on the [-1,...
void resize(const int dim0)
Resizes FieldContainer to a rank-1 container with the specified dimension, initialized by 0.