Intrepid
test_02.cpp
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 
44 
51 #include "Teuchos_oblackholestream.hpp"
52 #include "Teuchos_RCP.hpp"
53 #include "Teuchos_GlobalMPISession.hpp"
54 
55 
56 using namespace Intrepid;
57 
58 int main(int argc, char *argv[]) {
59 
60  Teuchos::GlobalMPISession mpiSession(&argc, &argv);
61 
62  // This little trick lets us print to cout only if a (dummy) command-line argument is provided.
63  int iprint = argc - 1;
64 
65  Teuchos::RCP<std::ostream> outStream;
66  Teuchos::oblackholestream bhs; // outputs nothing
67 
68  if (iprint > 0)
69  outStream = Teuchos::rcp(&std::cout, false);
70  else
71  outStream = Teuchos::rcp(&bhs, false);
72 
73  // Save the format state of the original cout .
74  Teuchos::oblackholestream oldFormatState;
75  oldFormatState.copyfmt(std::cout);
76 
77  *outStream \
78  << "===============================================================================\n" \
79  << "| |\n" \
80  << "| Unit Test FieldContainer |\n" \
81  << "| |\n" \
82  << "| 1) Testing exception handling |\n" \
83  << "| requires intrepid to be configured with --enable-intrepid-debug |\n" \
84  << "| |\n" \
85  << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov) or |\n" \
86  << "| Denis Ridzal (dridzal@sandia.gov). |\n" \
87  << "| |\n" \
88  << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
89  << "| Trilinos website: http://trilinos.sandia.gov |\n" \
90  << "| |\n" \
91  << "===============================================================================\n";
92 
93  // Test initializations
94  int errorFlag = 0;
95 
96  // Define variables to create and use FieldContainers
97  Teuchos::Array<int> dimensions;
98  Teuchos::Array<int> multiIndex;
99 
100  // Initialize dimensions for rank-4 multi-index value
101  dimensions.resize(4);
102  dimensions[0] = 5;
103  dimensions[1] = 3;
104  dimensions[2] = 2;
105  dimensions[3] = 7;
106 
107  // Create a FieldContainer
108  FieldContainer<double> myContainer(dimensions);
109 
110  // These tests should only run if intrepid was configured with --enable-intrepid-debug option
111  // Each test is designed to cause an exception. The total number of all caught exceptions should
112  // be the same as the number of tests in this section.
113 #ifdef HAVE_INTREPID_DEBUG
114 
115  *outStream << "\n" \
116  << "===============================================================================\n"\
117  << "| TEST 1: Catching exceptions |\n"\
118  << "===============================================================================\n\n";
119 
120  int numTestException =16;
121  int beginThrowNumber = Teuchos::TestForException_getThrowNumber();
122  int endThrowNumber = beginThrowNumber + numTestException;
123 
124  try{ // Outer try block contains all tests for exception
125 
126 
127  try{ // catch exception (1)
128 
129  // Trying to get enumeration using multi-index with the wrong rank:
130  *outStream << "\n" \
131  << "===============================================================================\n"\
132  << " Trying to get enumeration using multi-index with the wrong rank: \n";
133  multiIndex.resize(5);
134  multiIndex[0] = 3;
135  multiIndex[1] = 1;
136  multiIndex[2] = 2;
137  multiIndex[3] = 2;
138  multiIndex[4] = 6;
139  myContainer.getEnumeration(multiIndex);
140  }
141  catch (const std::logic_error & err) {
142  *outStream << err.what() << "\n";
143  };
144 
145 
146 
147  try{ // catch exception (2)
148 
149  // Trying to get enumeration using multi-index that is out of bounds: 3rd index is 4, must be <2
150  *outStream << "\n" \
151  << "===============================================================================\n"\
152  << " Trying to get enumeration using multi-index that is out of bounds: \n";
153  multiIndex.resize(4);
154  multiIndex[0] = 3;
155  multiIndex[1] = 1;
156  multiIndex[2] = 4;
157  multiIndex[3] = 2;
158  myContainer.getEnumeration(multiIndex);
159  }
160  catch (const std::logic_error & err) {
161  *outStream << err.what() << "\n";
162  };
163 
164 
165 
166  try{ // catch exception (3)
167 
168  // Trying to set values from array whose size is less than FieldContainer's size:
169  *outStream << "\n" \
170  << "===============================================================================\n"\
171  << " Trying to set values from array whose size is less than FieldContainer's size: \n";
172 
173  // Change one of the values of the dimensions to a lesser value: original value was 5
174  dimensions[0] = 4;
175 
176  // Define Teuchos::Array to store values with dimension equal to the number of multi-indexed values
177  Teuchos::Array<double> dataTeuchosArray(4*3*2*7);
178 
179  // Fill with data
180  int counter = 0;
181  for(int i=0; i < dimensions[0]; i++){
182  for(int j=0; j < dimensions[1]; j++){
183  for(int k=0; k < dimensions[2]; k++){
184  for(int l = 0; l < dimensions[3]; l++){
185  dataTeuchosArray[counter] = (double)counter;
186  counter++;
187  }
188  }
189  }
190  }
191 
192  // Now try to stuff this data into FieldContainer
193  myContainer.setValues(dataTeuchosArray);
194  }
195  catch (const std::logic_error & err) {
196  *outStream << err.what() << "\n";
197  };
198 
199 
200 
201  try{ // catch exception (4)
202 
203  // Trying to set values from array whose size is greater than FieldContainer's size:
204  *outStream << "\n" \
205  << "===============================================================================\n"\
206  << " Trying to set values from array whose size is greater than FieldContainer's size: \n";
207 
208  // Change one of the values of the dimensions to a lesser value: restore dimensions[0] to the
209  // value used to construct the LexArray and change dimensions[2] to a greater value
210  dimensions[0] = 5;
211  dimensions[2] = 3;
212 
213  // Define Teuchos::Array to store values with dimension equal to the number of multi-indexed values
214  Teuchos::ArrayRCP<double> dataTeuchosArray(5*3*3*7);
215 
216  // Fill with data
217  int counter = 0;
218  for(int i=0; i < dimensions[0]; i++){
219  for(int j=0; j < dimensions[1]; j++){
220  for(int k=0; k < dimensions[2]; k++){
221  for(int l = 0; l < dimensions[3]; l++){
222  dataTeuchosArray[counter] = (double)counter;
223  counter++;
224  }
225  }
226  }
227  }
228 
229  // Now try to stuff this data into FieldContainer
230  myContainer.setValues(dataTeuchosArray());
231  }
232  catch (const std::logic_error & err) {
233  *outStream << err.what() << "\n";
234  };
235 
236 
237 
238  try{ // catch exception (5)
239 
240  // Trying to use [] with enumeration that is out of range:
241  *outStream << "\n" \
242  << "===============================================================================\n"\
243  << " Trying to use [] with enumeration that is out of range: \n";
244  myContainer[1000];
245  }
246  catch (const std::logic_error & err) {
247  *outStream << err.what() << "\n";
248  }
249 
250 
251 
252  try{ // catch exception (6)
253 
254  // Trying to get multi-index from enumeration that is out of bounds:
255  *outStream << "\n" \
256  << "===============================================================================\n"\
257  << " Trying to get multi-index from enumeration that is out of bounds: \n";
258  myContainer.getMultiIndex(multiIndex,10000);
259  }
260  catch (const std::logic_error & err) {
261  *outStream << err.what() << "\n";
262  }
263 
264 
265 
266  try{ // catch exception (7)
267 
268  //Trying to self-assign FieldContainer
269  *outStream << "\n" \
270  << "===============================================================================\n"\
271  << " Trying to self-assign FieldContainer \n";
272  myContainer = myContainer;
273  }
274  catch (const std::logic_error & err) {
275  *outStream << err.what() << "\n";
276  }
277 
278 
279  // Container of rank-1
280  FieldContainer<double> rank1Container(3);
281 
282  // catch exception (8): method is for rank-2 container
283  try{
284  *outStream << "\n" \
285  << "===============================================================================\n"\
286  << " using a method for rank-2 container \n";
287  rank1Container.getEnumeration(1,1);
288  }
289  catch (const std::logic_error & err){
290  *outStream << err.what() << "\n";
291  }
292 
293  // catch exception (9): method is for rank-3 container
294  try{
295  *outStream << "\n" \
296  << "===============================================================================\n"\
297  << " using a method for rank-3 container \n";
298  rank1Container.getEnumeration(1,1,1);
299  }
300  catch (const std::logic_error & err){
301  *outStream << err.what() << "\n";
302  }
303 
304  // catch exception (10): method is for rank-4 container
305  try{
306  *outStream << "\n" \
307  << "===============================================================================\n"\
308  << " using a method for rank-4 container \n";
309  rank1Container.getEnumeration(1,1,1,1);
310  }
311  catch (const std::logic_error & err){
312  *outStream << err.what() << "\n";
313  }
314 
315  // catch exception (11): method is for rank-5 container
316  try{
317  *outStream << "\n" \
318  << "===============================================================================\n"\
319  << " using a method for rank-5 container \n";
320  rank1Container.getEnumeration(1,1,1,1,1);
321  }
322  catch (const std::logic_error & err){
323  *outStream << err.what() << "\n";
324  }
325 
326  // catch exception (12): 4 is out of bounds
327  try{
328  *outStream << "\n" \
329  << "===============================================================================\n"\
330  << " The specified enumeration is out of bounds \n";
331  int i0;
332  rank1Container.getMultiIndex(i0,4);
333  }
334  catch (const std::logic_error & err){
335  *outStream << err.what() << "\n";
336  }
337 
338  // catch exception (13): method for rank-2 container
339  try{
340  *outStream << "\n" \
341  << "===============================================================================\n"\
342  << " Using a method for rank-2 containers \n";
343  int i0,i1;
344  rank1Container.getMultiIndex(i0,i1,2);
345  }
346  catch (const std::logic_error & err){
347  *outStream << err.what() << "\n";
348  }
349 
350  // catch exception (14): method for rank-3 container
351  try{
352  *outStream << "\n" \
353  << "===============================================================================\n"\
354  << " Using a method for rank-2 containers \n";
355  int i0,i1,i2;
356  rank1Container.getMultiIndex(i0,i1,i2,2);
357  }
358  catch (const std::logic_error & err){
359  *outStream << err.what() << "\n";
360  }
361 
362 
363  // catch exception (15): method for rank-4 container
364  try{
365  *outStream << "\n" \
366  << "===============================================================================\n"\
367  << " Using a method for rank-4 containers \n";
368  int i0,i1,i2,i3;
369  rank1Container.getMultiIndex(i0,i1,i2,i3,2);
370  }
371  catch (const std::logic_error & err){
372  *outStream << err.what() << "\n";
373  }
374 
375 
376  // catch exception (16): method for rank-5 container
377  try{
378  *outStream << "\n" \
379  << "===============================================================================\n"\
380  << " Using a method for rank-5 containers \n";
381  int i0,i1,i2,i3,i4;
382  rank1Container.getMultiIndex(i0,i1,i2,i3,i4,2);
383  }
384  catch (const std::logic_error & err){
385  *outStream << err.what() << "\n";
386  }
387 
388 
389  // Check if number of caught exceptions matches the expected number
390  if (Teuchos::TestForException_getThrowNumber() != endThrowNumber) {
391  errorFlag++;
392 
393  }
394  } // outer try block
395  catch (const std::logic_error & err) {
396  *outStream << "UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
397  *outStream << err.what() << "\n";
398  *outStream << "-------------------------------------------------------------------------------" << "\n\n";
399  errorFlag = -1000;
400  }
401 #endif
402 
403  if (errorFlag != 0)
404  std::cout << "End Result: TEST FAILED\n";
405  else
406  std::cout << "End Result: TEST PASSED\n";
407 
408  // reset format state of std::cout
409  std::cout.copyfmt(oldFormatState);
410 
411  return errorFlag;
412 }
Header file for utility class to provide multidimensional containers.