52#include "Teuchos_oblackholestream.hpp"
53#include "Teuchos_RCP.hpp"
54#include "Teuchos_ScalarTraits.hpp"
55#include "Teuchos_GlobalMPISession.hpp"
58using namespace Intrepid;
60#define INTREPID_TEST_COMMAND( S ) \
65 catch (const std::logic_error & err) { \
66 *outStream << "Expected Error ----------------------------------------------------------------\n"; \
67 *outStream << err.what() << '\n'; \
68 *outStream << "-------------------------------------------------------------------------------" << "\n\n"; \
73int main(
int argc,
char *argv[]) {
75 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
79 int iprint = argc - 1;
80 Teuchos::RCP<std::ostream> outStream;
81 Teuchos::oblackholestream bhs;
83 outStream = Teuchos::rcp(&std::cout,
false);
85 outStream = Teuchos::rcp(&bhs,
false);
88 Teuchos::oblackholestream oldFormatState;
89 oldFormatState.copyfmt(std::cout);
92 <<
"===============================================================================\n" \
94 <<
"| Unit Test (ArrayTools) |\n" \
96 <<
"| 1) Array operations: clone / scale |\n" \
98 <<
"| Questions? Contact Pavel Bochev (pbboche@sandia.gov) or |\n" \
99 <<
"| Denis Ridzal (dridzal@sandia.gov). |\n" \
101 <<
"| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
102 <<
"| Trilinos website: http://trilinos.sandia.gov |\n" \
104 <<
"===============================================================================\n";
108#ifdef HAVE_INTREPID_DEBUG
109 int beginThrowNumber = Teuchos::TestForException_getThrowNumber();
110 int endThrowNumber = beginThrowNumber + 21;
114 typedef RealSpaceTools<double> rst;
115#ifdef HAVE_INTREPID_DEBUG
121 <<
"===============================================================================\n"\
122 <<
"| TEST 1: exceptions |\n"\
123 <<
"===============================================================================\n";
127#ifdef HAVE_INTREPID_DEBUG
128 FieldContainer<double> a_2(2);
129 FieldContainer<double> a_9_2(9, 2);
130 FieldContainer<double> a_10_2(10, 2);
131 FieldContainer<double> a_10_3(10, 3);
132 FieldContainer<double> a_10_2_2(10, 2, 2);
133 FieldContainer<double> a_10_2_2_2(10, 2, 2, 2);
134 FieldContainer<double> a_10_3_2_2(10, 3, 2, 2);
135 FieldContainer<double> a_10_3_2(10, 3, 2);
136 FieldContainer<double> a_2_2(2, 2);
137 FieldContainer<double> a_2_3_2_2(2, 3, 2, 2);
138 FieldContainer<double> a_2_2_2_2(2, 2, 2, 2);
139 FieldContainer<double> a_10_2_2_2_2(10, 2, 2, 2, 2);
140 FieldContainer<double> a_10_3_2_2_2(10, 3, 2, 2, 2);
141 FieldContainer<double> a_10_2_3_2_2(10, 2, 3, 2, 2);
142 FieldContainer<double> a_10_2_2_3_2(10, 2, 2, 3, 2);
143 FieldContainer<double> a_10_2_2_2_3(10, 2, 2, 2, 3);
145 *outStream <<
"-> cloneFields:\n";
146 INTREPID_TEST_COMMAND( atools.cloneFields<
double>(a_10_2_2_2, a_2) );
147 INTREPID_TEST_COMMAND( atools.cloneFields<
double>(a_10_2_2_2, a_10_2) );
148 INTREPID_TEST_COMMAND( atools.cloneFields<
double>(a_10_3_2, a_2_2) );
149 INTREPID_TEST_COMMAND( atools.cloneFields<
double>(a_10_2_2_2_2, a_2_3_2_2) );
150 INTREPID_TEST_COMMAND( atools.cloneFields<
double>(a_10_2_2_3_2, a_2_2_2_2) );
151 INTREPID_TEST_COMMAND( atools.cloneFields<
double>(a_10_2_2_2_3, a_2_2_2_2) );
152 INTREPID_TEST_COMMAND( atools.cloneFields<
double>(a_10_2_2, a_2_2) );
153 INTREPID_TEST_COMMAND( atools.cloneFields<
double>(a_10_2_2_2_2, a_2_2_2_2) );
155 *outStream <<
"-> cloneScaleFields:\n";
156 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2_2, a_2, a_2) );
157 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2_2, a_10_2, a_2) );
158 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2_2, a_10_2, a_10_2) );
159 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2, a_9_2, a_10_2) );
160 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2, a_10_3, a_10_2) );
161 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_3_2_2_2, a_10_3, a_2_2_2_2) );
162 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_3_2_2, a_10_2, a_2_2_2_2) );
163 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2_3_2, a_10_2, a_2_2_2_2) );
164 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2_2_3, a_10_2, a_2_2_2_2) );
165 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2, a_10_2, a_2_2) );
166 INTREPID_TEST_COMMAND( atools.cloneScaleFields<
double>(a_10_2_2_2_2, a_10_2, a_2_2_2_2) );
168 *outStream <<
"-> scaleFields:\n";
169 INTREPID_TEST_COMMAND( atools.scaleFields<
double>(a_10_2_2_2, a_2) );
170 INTREPID_TEST_COMMAND( atools.scaleFields<
double>(a_10_2, a_2_2) );
171 INTREPID_TEST_COMMAND( atools.scaleFields<
double>(a_10_2_2, a_2_2) );
172 INTREPID_TEST_COMMAND( atools.scaleFields<
double>(a_10_3_2, a_10_2) );
173 INTREPID_TEST_COMMAND( atools.scaleFields<
double>(a_10_3_2_2, a_10_2) );
174 INTREPID_TEST_COMMAND( atools.scaleFields<
double>(a_10_3_2_2_2, a_10_2) );
175 INTREPID_TEST_COMMAND( atools.scaleFields<
double>(a_10_2_2_2_2, a_10_2) );
179 catch (
const std::logic_error & err) {
180 *outStream <<
"UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
181 *outStream << err.what() <<
'\n';
182 *outStream <<
"-------------------------------------------------------------------------------" <<
"\n\n";
186#ifdef HAVE_INTREPID_DEBUG
187 if (Teuchos::TestForException_getThrowNumber() != endThrowNumber)
193 <<
"===============================================================================\n"\
194 <<
"| TEST 2: correctness of math operations |\n"\
195 <<
"===============================================================================\n";
197 outStream->precision(20);
201 *outStream <<
"\n************ Checking cloneFields ************\n";
203 int c=5, p=9, f=7, d1=7, d2=13;
205 FieldContainer<double> in_f_p(f, p);
206 FieldContainer<double> in_f_p_d(f, p, d1);
207 FieldContainer<double> in_f_p_d_d(f, p, d1, d2);
208 FieldContainer<double> in_c_f_p(c, f, p);
209 FieldContainer<double> in_c_f_p_d(c, f, p, d1);
210 FieldContainer<double> in_c_f_p_d_d(c, f, p, d1, d2);
211 FieldContainer<double> data_c_p_one(c, p);
212 FieldContainer<double> out_c_f_p(c, f, p);
213 FieldContainer<double> out_c_f_p_d(c, f, p, d1);
214 FieldContainer<double> out_c_f_p_d_d(c, f, p, d1, d2);
215 double zero = INTREPID_TOL*100.0;
218 for (
int i=0; i<in_f_p.size(); i++) {
219 in_f_p[i] = Teuchos::ScalarTraits<double>::random();
221 for (
int i=0; i<in_f_p_d.size(); i++) {
222 in_f_p_d[i] = Teuchos::ScalarTraits<double>::random();
224 for (
int i=0; i<in_f_p_d_d.size(); i++) {
225 in_f_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
227 for (
int i=0; i<data_c_p_one.size(); i++) {
228 data_c_p_one[i] = 1.0;
231 art::cloneFields<double>(out_c_f_p, in_f_p);
232 art::scalarMultiplyDataField<double>(in_c_f_p, data_c_p_one, in_f_p);
233 rst::subtract(&out_c_f_p[0], &in_c_f_p[0], out_c_f_p.size());
234 if (rst::vectorNorm(&out_c_f_p[0], out_c_f_p.size(), NORM_ONE) > zero) {
235 *outStream <<
"\n\nINCORRECT cloneFields (1): check multiplyScalarData vs. cloneFields\n\n";
238 art::cloneFields<double>(out_c_f_p_d, in_f_p_d);
239 art::scalarMultiplyDataField<double>(in_c_f_p_d, data_c_p_one, in_f_p_d);
240 rst::subtract(&out_c_f_p_d[0], &in_c_f_p_d[0], out_c_f_p_d.size());
241 if (rst::vectorNorm(&out_c_f_p_d[0], out_c_f_p_d.size(), NORM_ONE) > zero) {
242 *outStream <<
"\n\nINCORRECT cloneFields (2): check multiplyScalarData vs. cloneFields\n\n";
245 art::cloneFields<double>(out_c_f_p_d_d, in_f_p_d_d);
246 art::scalarMultiplyDataField<double>(in_c_f_p_d_d, data_c_p_one, in_f_p_d_d);
247 rst::subtract(&out_c_f_p_d_d[0], &in_c_f_p_d_d[0], out_c_f_p_d_d.size());
248 if (rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) > zero) {
249 *outStream <<
"\n\nINCORRECT cloneFields (3): check multiplyScalarData vs. cloneFields\n\n";
255 *outStream <<
"\n************ Checking cloneScaleFields ************\n";
256 int c=5, p=9, f=7, d1=7, d2=13;
258 FieldContainer<double> in_f_p(f, p);
259 FieldContainer<double> in_f_p_d(f, p, d1);
260 FieldContainer<double> in_f_p_d_d(f, p, d1, d2);
261 FieldContainer<double> data_c_f(c, f);
262 FieldContainer<double> datainv_c_f(c, f);
263 FieldContainer<double> c_f_p_one(c, f, p);
264 FieldContainer<double> c_f_p_d_one(c, f, p, d1);
265 FieldContainer<double> c_f_p_d_d_one(c, f, p, d1, d2);
266 FieldContainer<double> out_c_f_p(c, f, p);
267 FieldContainer<double> outi_c_f_p(c, f, p);
268 FieldContainer<double> out_c_f_p_d(c, f, p, d1);
269 FieldContainer<double> outi_c_f_p_d(c, f, p, d1);
270 FieldContainer<double> out_c_f_p_d_d(c, f, p, d1, d2);
271 FieldContainer<double> outi_c_f_p_d_d(c, f, p, d1, d2);
272 double zero = INTREPID_TOL*100.0;
275 for (
int i=0; i<in_f_p.size(); i++) {
278 for (
int i=0; i<in_f_p_d.size(); i++) {
281 for (
int i=0; i<in_f_p_d_d.size(); i++) {
284 for (
int i=0; i<c_f_p_one.size(); i++) {
287 for (
int i=0; i<c_f_p_d_one.size(); i++) {
288 c_f_p_d_one[i] = 1.0;
290 for (
int i=0; i<c_f_p_d_d_one.size(); i++) {
291 c_f_p_d_d_one[i] = 1.0;
294 for (
int i=0; i<data_c_f.size(); i++) {
295 data_c_f[i] = Teuchos::ScalarTraits<double>::random();
296 datainv_c_f[i] = 1.0 / data_c_f[i];
299 art::cloneScaleFields<double>(out_c_f_p, data_c_f, in_f_p);
300 art::cloneScaleFields<double>(outi_c_f_p, datainv_c_f, in_f_p);
301 for (
int i=0; i<out_c_f_p.size(); i++) {
302 out_c_f_p[i] *= outi_c_f_p[i];
304 rst::subtract(&out_c_f_p[0], &c_f_p_one[0], out_c_f_p.size());
305 if (rst::vectorNorm(&out_c_f_p[0], out_c_f_p.size(), NORM_ONE) > zero) {
306 *outStream <<
"\n\nINCORRECT cloneScaleValue (1): check scalar inverse property\n\n";
310 art::cloneScaleFields<double>(out_c_f_p_d, data_c_f, in_f_p_d);
311 art::cloneScaleFields<double>(outi_c_f_p_d, datainv_c_f, in_f_p_d);
312 for (
int i=0; i<out_c_f_p_d.size(); i++) {
313 out_c_f_p_d[i] *= outi_c_f_p_d[i];
315 rst::subtract(&out_c_f_p_d[0], &c_f_p_d_one[0], out_c_f_p_d.size());
316 if (rst::vectorNorm(&out_c_f_p_d[0], out_c_f_p_d.size(), NORM_ONE) > zero) {
317 *outStream <<
"\n\nINCORRECT cloneScaleValue (2): check scalar inverse property\n\n";
321 art::cloneScaleFields<double>(out_c_f_p_d_d, data_c_f, in_f_p_d_d);
322 art::cloneScaleFields<double>(outi_c_f_p_d_d, datainv_c_f, in_f_p_d_d);
323 for (
int i=0; i<out_c_f_p_d_d.size(); i++) {
324 out_c_f_p_d_d[i] *= outi_c_f_p_d_d[i];
326 rst::subtract(&out_c_f_p_d_d[0], &c_f_p_d_d_one[0], out_c_f_p_d_d.size());
327 if (rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) > zero) {
328 *outStream <<
"\n\nINCORRECT cloneScaleValue (3): check scalar inverse property\n\n";
334 *outStream <<
"\n************ Checking scaleFields ************\n";
335 int c=5, p=9, f=7, d1=7, d2=13;
337 FieldContainer<double> data_c_f(c, f);
338 FieldContainer<double> datainv_c_f(c, f);
339 FieldContainer<double> out_c_f_p(c, f, p);
340 FieldContainer<double> outi_c_f_p(c, f, p);
341 FieldContainer<double> out_c_f_p_d(c, f, p, d1);
342 FieldContainer<double> outi_c_f_p_d(c, f, p, d1);
343 FieldContainer<double> out_c_f_p_d_d(c, f, p, d1, d2);
344 FieldContainer<double> outi_c_f_p_d_d(c, f, p, d1, d2);
345 double zero = INTREPID_TOL*100.0;
348 for (
int i=0; i<out_c_f_p.size(); i++) {
349 out_c_f_p[i] = Teuchos::ScalarTraits<double>::random();
350 outi_c_f_p[i] = out_c_f_p[i];
352 for (
int i=0; i<out_c_f_p_d.size(); i++) {
353 out_c_f_p_d[i] = Teuchos::ScalarTraits<double>::random();
354 outi_c_f_p_d[i] = out_c_f_p_d[i];
356 for (
int i=0; i<out_c_f_p_d_d.size(); i++) {
357 out_c_f_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
358 outi_c_f_p_d_d[i] = out_c_f_p_d_d[i];
360 for (
int i=0; i<data_c_f.size(); i++) {
361 data_c_f[i] = Teuchos::ScalarTraits<double>::random();
362 datainv_c_f[i] = 1.0 / data_c_f[i];
365 art::scaleFields<double>(out_c_f_p, data_c_f);
366 art::scaleFields<double>(out_c_f_p, datainv_c_f);
367 rst::subtract(&out_c_f_p[0], &outi_c_f_p[0], out_c_f_p.size());
368 if (rst::vectorNorm(&out_c_f_p[0], out_c_f_p.size(), NORM_ONE) > zero) {
369 *outStream <<
"\n\nINCORRECT scaleValue (1): check scalar inverse property\n\n";
373 art::scaleFields<double>(out_c_f_p_d, data_c_f);
374 art::scaleFields<double>(out_c_f_p_d, datainv_c_f);
375 rst::subtract(&out_c_f_p_d[0], &outi_c_f_p_d[0], out_c_f_p_d.size());
376 if (rst::vectorNorm(&out_c_f_p_d[0], out_c_f_p_d.size(), NORM_ONE) > zero) {
377 *outStream <<
"\n\nINCORRECT scaleValue (2): check scalar inverse property\n\n";
381 art::scaleFields<double>(out_c_f_p_d_d, data_c_f);
382 art::scaleFields<double>(out_c_f_p_d_d, datainv_c_f);
383 rst::subtract(&out_c_f_p_d_d[0], &outi_c_f_p_d_d[0], out_c_f_p_d_d.size());
384 if (rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) > zero) {
385 *outStream <<
"\n\nINCORRECT cloneScaleValue (3): check scalar inverse property\n\n";
393 catch (
const std::logic_error & err) {
394 *outStream <<
"UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
395 *outStream << err.what() <<
'\n';
396 *outStream <<
"-------------------------------------------------------------------------------" <<
"\n\n";
402 std::cout <<
"End Result: TEST FAILED\n";
404 std::cout <<
"End Result: TEST PASSED\n";
407 std::cout.copyfmt(oldFormatState);
Header file for utility class to provide multidimensional containers.