52 #include "Teuchos_oblackholestream.hpp"
53 #include "Teuchos_RCP.hpp"
54 #include "Teuchos_ScalarTraits.hpp"
55 #include "Teuchos_GlobalMPISession.hpp"
56 #include <Kokkos_Core.hpp>
58 using namespace Intrepid;
60 #define INTREPID_TEST_COMMAND( S ) \
65 catch (std::logic_error err) { \
66 *outStream << "Expected Error ----------------------------------------------------------------\n"; \
67 *outStream << err.what() << '\n'; \
68 *outStream << "-------------------------------------------------------------------------------" << "\n\n"; \
73 int main(
int argc,
char *argv[]) {
75 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
80 int iprint = argc - 1;
81 Teuchos::RCP<std::ostream> outStream;
82 Teuchos::oblackholestream bhs;
84 outStream = Teuchos::rcp(&std::cout,
false);
86 outStream = Teuchos::rcp(&bhs,
false);
89 Teuchos::oblackholestream oldFormatState;
90 oldFormatState.copyfmt(std::cout);
93 <<
"===============================================================================\n" \
95 <<
"| Unit Test (ArrayTools) |\n" \
97 <<
"| 1) Array operations: clone / scale |\n" \
99 <<
"| Questions? Contact Pavel Bochev (pbboche@sandia.gov) or |\n" \
100 <<
"| Denis Ridzal (dridzal@sandia.gov). |\n" \
102 <<
"| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
103 <<
"| Trilinos website: http://trilinos.sandia.gov |\n" \
105 <<
"===============================================================================\n";
109 #ifdef HAVE_INTREPID_DEBUG
110 int beginThrowNumber = Teuchos::TestForException_getThrowNumber();
111 int endThrowNumber = beginThrowNumber + 21;
116 #ifdef HAVE_INTREPID_DEBUG
122 <<
"===============================================================================\n"\
123 <<
"| TEST 1: exceptions |\n"\
124 <<
"===============================================================================\n";
128 #ifdef HAVE_INTREPID_DEBUG
129 Kokkos::View<double*> a_2(
"a_2",2);
130 Kokkos::View<double**> a_9_2(
"a_9_2",9, 2);
131 Kokkos::View<double**> a_10_2(
"a_10_2",10, 2);
132 Kokkos::View<double**> a_10_3(
"a_10_3",10, 3);
133 Kokkos::View<double***> a_10_2_2(
"a_10_2_2",10, 2, 2);
134 Kokkos::View<double****> a_10_2_2_2(
"a_10_2_2_2",10, 2, 2, 2);
135 Kokkos::View<double****> a_10_3_2_2(
"a_10_3_2_2",10, 3, 2, 2);
136 Kokkos::View<double***> a_10_3_2(
"a_10_3_2",10, 3, 2);
137 Kokkos::View<double**> a_2_2(
"a_2_2",2, 2);
138 Kokkos::View<double****> a_2_3_2_2(
"a_2_3_2_2",2, 3, 2, 2);
139 Kokkos::View<double****> a_2_2_2_2(
"a_2_2_2_2",2, 2, 2, 2);
140 Kokkos::View<double*****> a_10_2_2_2_2(
"a_10_2_2_2_2",10, 2, 2, 2, 2);
141 Kokkos::View<double*****> a_10_3_2_2_2(
"a_10_3_2_2_2",10, 3, 2, 2, 2);
142 Kokkos::View<double*****> a_10_2_3_2_2(
"a_10_2_3_2_2",10, 2, 3, 2, 2);
143 Kokkos::View<double*****> a_10_2_2_3_2(
"a_10_2_2_3_2",10, 2, 2, 3, 2);
144 Kokkos::View<double*****> a_10_2_2_2_3(
"a_10_2_2_2_3",10, 2, 2, 2, 3);
146 *outStream <<
"-> cloneFields:\n";
147 INTREPID_TEST_COMMAND( atools.
cloneFields<
double>(a_10_2_2_2, a_2) );
148 INTREPID_TEST_COMMAND( atools.
cloneFields<
double>(a_10_2_2_2, a_10_2) );
149 INTREPID_TEST_COMMAND( atools.
cloneFields<
double>(a_10_3_2, a_2_2) );
150 INTREPID_TEST_COMMAND( atools.
cloneFields<
double>(a_10_2_2_2_2, a_2_3_2_2) );
151 INTREPID_TEST_COMMAND( atools.
cloneFields<
double>(a_10_2_2_3_2, a_2_2_2_2) );
152 INTREPID_TEST_COMMAND( atools.
cloneFields<
double>(a_10_2_2_2_3, a_2_2_2_2) );
153 INTREPID_TEST_COMMAND( atools.
cloneFields<
double>(a_10_2_2, a_2_2) );
154 INTREPID_TEST_COMMAND( atools.
cloneFields<
double>(a_10_2_2_2_2, a_2_2_2_2) );
156 *outStream <<
"-> cloneScaleFields:\n";
157 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2_2, a_2, a_2) );
158 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2_2, a_10_2, a_2) );
159 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2_2, a_10_2, a_10_2) );
160 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2, a_9_2, a_10_2) );
161 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2, a_10_3, a_10_2) );
162 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_3_2_2_2, a_10_3, a_2_2_2_2) );
163 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_3_2_2, a_10_2, a_2_2_2_2) );
164 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2_3_2, a_10_2, a_2_2_2_2) );
165 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2_2_3, a_10_2, a_2_2_2_2) );
166 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2, a_10_2, a_2_2) );
167 INTREPID_TEST_COMMAND( atools.
cloneScaleFields<
double>(a_10_2_2_2_2, a_10_2, a_2_2_2_2) );
169 *outStream <<
"-> scaleFields:\n";
170 INTREPID_TEST_COMMAND( atools.
scaleFields<
double>(a_10_2_2_2, a_2) );
171 INTREPID_TEST_COMMAND( atools.
scaleFields<
double>(a_10_2, a_2_2) );
172 INTREPID_TEST_COMMAND( atools.
scaleFields<
double>(a_10_2_2, a_2_2) );
173 INTREPID_TEST_COMMAND( atools.
scaleFields<
double>(a_10_3_2, a_10_2) );
174 INTREPID_TEST_COMMAND( atools.
scaleFields<
double>(a_10_3_2_2, a_10_2) );
175 INTREPID_TEST_COMMAND( atools.
scaleFields<
double>(a_10_3_2_2_2, a_10_2) );
176 INTREPID_TEST_COMMAND( atools.
scaleFields<
double>(a_10_2_2_2_2, a_10_2) );
180 catch (std::logic_error err) {
181 *outStream <<
"UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
182 *outStream << err.what() <<
'\n';
183 *outStream <<
"-------------------------------------------------------------------------------" <<
"\n\n";
186 #ifdef HAVE_INTREPID_DEBUG
187 if (Teuchos::TestForException_getThrowNumber() != endThrowNumber)
192 <<
"===============================================================================\n"\
193 <<
"| TEST 2: correctness of math operations |\n"\
194 <<
"===============================================================================\n";
196 outStream->precision(20);
200 *outStream <<
"\n************ Checking cloneFields ************\n";
202 int c=5, p=9, f=7, d1=7, d2=13;
204 Kokkos::View<double**> in_f_p(
"in_f_p",f, p);
205 Kokkos::View<double***> in_f_p_d(
"in_f_p_d",f, p, d1);
206 Kokkos::View<double****> in_f_p_d_d(
"in_f_p_d_d",f, p, d1, d2);
207 Kokkos::View<double***> in_c_f_p(
"in_c_f_p",c, f, p);
208 Kokkos::View<double****> in_c_f_p_d(
"in_c_f_p_d",c, f, p, d1);
209 Kokkos::View<double*****> in_c_f_p_d_d(
"in_c_f_p_d_d",c, f, p, d1, d2);
210 Kokkos::View<double**> data_c_p_one(
"data_c_p_one",c, p);
211 Kokkos::View<double***> out_c_f_p(
"out_c_f_p",c, f, p);
212 Kokkos::View<double****> out_c_f_p_d(
"out_c_f_p_d",c, f, p, d1);
213 Kokkos::View<double*****> out_c_f_p_d_d(
"out_c_f_p_d_d",c, f, p, d1, d2);
214 double zero = INTREPID_TOL*100.0;
217 for (
unsigned int i=0; i<in_f_p.dimension(0); i++) {
218 for (
unsigned int j=0; j<in_f_p.dimension(1); j++) {
219 in_f_p(i,j) = Teuchos::ScalarTraits<double>::random();
222 for (
unsigned int i=0; i<in_f_p_d.dimension(0); i++) {
223 for (
unsigned int j=0; j<in_f_p_d.dimension(1); j++) {
224 for (
unsigned int k=0; k<in_f_p_d.dimension(2); k++) {
225 in_f_p_d(i,j,k) = Teuchos::ScalarTraits<double>::random();
229 for (
unsigned int i=0; i<in_f_p_d_d.dimension(0); i++) {
230 for (
unsigned int j=0; j<in_f_p_d_d.dimension(1); j++) {
231 for (
unsigned int k=0; k<in_f_p_d_d.dimension(2); k++) {
232 for (
unsigned int l=0; l<in_f_p_d_d.dimension(3); l++) {
233 in_f_p_d_d(i,j,k,l) = Teuchos::ScalarTraits<double>::random();
239 for (
unsigned int i=0; i<data_c_p_one.dimension(0); i++) {
240 for (
unsigned int j=0; j<data_c_p_one.dimension(1); j++) {
241 data_c_p_one(i,j) = 1;
245 art::cloneFields<double>(out_c_f_p, in_f_p);
246 art::scalarMultiplyDataField<double>(in_c_f_p, data_c_p_one, in_f_p);
247 rst::subtract(out_c_f_p, in_c_f_p);
248 if (rst::vectorNorm(out_c_f_p, NORM_ONE) > zero) {
249 *outStream <<
"\n\nINCORRECT cloneFields (1): check multiplyScalarData vs. cloneFields\n\n";
252 art::cloneFields<double>(out_c_f_p_d, in_f_p_d);
253 art::scalarMultiplyDataField<double>(in_c_f_p_d, data_c_p_one, in_f_p_d);
254 rst::subtract(out_c_f_p_d, in_c_f_p_d);
255 if (rst::vectorNorm(out_c_f_p_d, NORM_ONE) > zero) {
256 *outStream <<
"\n\nINCORRECT cloneFields (2): check multiplyScalarData vs. cloneFields\n\n";
259 art::cloneFields<double>(out_c_f_p_d_d, in_f_p_d_d);
260 art::scalarMultiplyDataField<double>(in_c_f_p_d_d, data_c_p_one, in_f_p_d_d);
261 rst::subtract(out_c_f_p_d_d, in_c_f_p_d_d);
262 if (rst::vectorNorm(out_c_f_p_d_d, NORM_ONE) > zero) {
263 *outStream <<
"\n\nINCORRECT cloneFields (3): check multiplyScalarData vs. cloneFields\n\n";
269 *outStream <<
"\n************ Checking cloneScaleFields ************\n";
270 int c=5, p=9, f=7, d1=7, d2=13;
272 Kokkos::View<double**> in_f_p(
"in_f_p",f, p);
273 Kokkos::View<double***> in_f_p_d(
"in_f_p_d",f, p, d1);
274 Kokkos::View<double****> in_f_p_d_d(
"in_f_p_d_d",f, p, d1, d2);
275 Kokkos::View<double**> data_c_f(
"data_c_f",c, f);
276 Kokkos::View<double**> datainv_c_f(
"datainv_c_f",c, f);
277 Kokkos::View<double***> c_f_p_one(
"c_f_p_one",c, f, p);
278 Kokkos::View<double****> c_f_p_d_one(
"c_f_p_d_one",c, f, p, d1);
279 Kokkos::View<double*****> c_f_p_d_d_one(
"c_f_p_d_d_one",c, f, p, d1, d2);
280 Kokkos::View<double***> out_c_f_p(
"out_c_f_p",c, f, p);
281 Kokkos::View<double***> outi_c_f_p(
"outi_c_f_p",c, f, p);
282 Kokkos::View<double****> out_c_f_p_d(
"out_c_f_p_d",c, f, p, d1);
283 Kokkos::View<double****> outi_c_f_p_d(
"outi_c_f_p_d",c, f, p, d1);
284 Kokkos::View<double*****> out_c_f_p_d_d(
"out_c_f_p_d_d",c, f, p, d1, d2);
285 Kokkos::View<double*****> outi_c_f_p_d_d(
"outi_c_f_p_d_d",c, f, p, d1, d2);
286 double zero = INTREPID_TOL*100.0;
288 for (
unsigned int i=0; i<in_f_p.dimension(0); i++) {
289 for (
unsigned int j=0; j<in_f_p.dimension(1); j++) {
293 for (
unsigned int i=0; i<in_f_p_d.dimension(0); i++) {
294 for (
unsigned int j=0; j<in_f_p_d.dimension(1); j++) {
295 for (
unsigned int k=0; k<in_f_p_d.dimension(2); k++) {
300 for (
unsigned int i=0; i<in_f_p_d_d.dimension(0); i++) {
301 for (
unsigned int j=0; j<in_f_p_d_d.dimension(1); j++) {
302 for (
unsigned int k=0; k<in_f_p_d_d.dimension(2); k++) {
303 for (
unsigned int l=0; l<in_f_p_d_d.dimension(3); l++) {
304 in_f_p_d_d(i,j,k,l) = 1;
309 for (
unsigned int i=0; i<c_f_p_one.dimension(0); i++) {
310 for (
unsigned int j=0; j<c_f_p_one.dimension(1); j++) {
311 for (
unsigned int k=0; k<c_f_p_one.dimension(2); k++) {
312 c_f_p_one(i,j,k) = 1;
316 for (
unsigned int i=0; i<c_f_p_d_one.dimension(0); i++) {
317 for (
unsigned int j=0; j<c_f_p_d_one.dimension(1); j++) {
318 for (
unsigned int k=0; k<c_f_p_d_one.dimension(2); k++) {
319 for (
unsigned int l=0; l<c_f_p_d_one.dimension(3); l++) {
320 c_f_p_d_one(i,j,k,l) = 1;
325 for (
unsigned int i=0; i<c_f_p_d_d_one.dimension(0); i++) {
326 for (
unsigned int j=0; j<c_f_p_d_d_one.dimension(1); j++) {
327 for (
unsigned int k=0; k<c_f_p_d_d_one.dimension(2); k++) {
328 for (
unsigned int l=0; l<c_f_p_d_d_one.dimension(3); l++) {
329 for (
unsigned int m=0; m<c_f_p_d_d_one.dimension(4); m++) {
330 c_f_p_d_d_one(i,j,k,l,m) = 1;
337 for (
unsigned int i=0; i<data_c_f.dimension(0); i++) {
338 for (
unsigned int j=0; j<data_c_f.dimension(1); j++) {
339 data_c_f(i,j) = Teuchos::ScalarTraits<double>::random();
340 datainv_c_f(i,j) = 1.0 / data_c_f(i,j);
344 art::cloneScaleFields<double>(out_c_f_p, data_c_f, in_f_p);
345 art::cloneScaleFields<double>(outi_c_f_p, datainv_c_f, in_f_p);
346 for (
unsigned int i=0; i<out_c_f_p.dimension(0); i++) {
347 for (
unsigned int j=0; j<out_c_f_p.dimension(1); j++) {
348 for (
unsigned int k=0; k<out_c_f_p.dimension(2); k++) {
349 out_c_f_p(i,j,k) *= outi_c_f_p(i,j,k);
354 rst::subtract(out_c_f_p, c_f_p_one);
355 if (rst::vectorNorm(out_c_f_p, NORM_ONE) > zero) {
356 *outStream <<
"\n\nINCORRECT cloneScaleValue (1): check scalar inverse property\n\n";
360 art::cloneScaleFields<double>(out_c_f_p_d, data_c_f, in_f_p_d);
361 art::cloneScaleFields<double>(outi_c_f_p_d, datainv_c_f, in_f_p_d);
362 for (
unsigned int i=0; i<out_c_f_p_d.dimension(0); i++) {
363 for (
unsigned int j=0; j<out_c_f_p_d.dimension(1); j++) {
364 for (
unsigned int k=0; k<out_c_f_p_d.dimension(2); k++) {
365 for (
unsigned int l=0; l<out_c_f_p_d.dimension(3); l++) {
366 out_c_f_p_d(i,j,k,l) *= outi_c_f_p_d(i,j,k,l);
372 rst::subtract(out_c_f_p_d, c_f_p_d_one);
373 if (rst::vectorNorm(out_c_f_p_d, NORM_ONE) > zero) {
374 *outStream <<
"\n\nINCORRECT cloneScaleValue (2): check scalar inverse property\n\n";
378 art::cloneScaleFields<double>(out_c_f_p_d_d, data_c_f, in_f_p_d_d);
379 art::cloneScaleFields<double>(outi_c_f_p_d_d, datainv_c_f, in_f_p_d_d);
380 for (
unsigned int i=0; i<out_c_f_p_d_d.dimension(0); i++) {
381 for (
unsigned int j=0; j<out_c_f_p_d_d.dimension(1); j++) {
382 for (
unsigned int k=0; k<out_c_f_p_d_d.dimension(2); k++) {
383 for (
unsigned int l=0; l<out_c_f_p_d_d.dimension(3); l++) {
384 for (
unsigned int m=0; m<out_c_f_p_d_d.dimension(4); m++) {
385 out_c_f_p_d_d(i,j,k,l,m) *= outi_c_f_p_d_d(i,j,k,l,m);
393 rst::subtract(out_c_f_p_d_d, c_f_p_d_d_one);
394 if (rst::vectorNorm(out_c_f_p_d_d, NORM_ONE) > zero) {
395 *outStream <<
"\n\nINCORRECT cloneScaleValue (3): check scalar inverse property\n\n";
401 *outStream <<
"\n************ Checking scaleFields ************\n";
402 int c=5, p=9, f=7, d1=7, d2=13;
403 Kokkos::View<double**> data_c_f(
"data_c_f",c, f);
404 Kokkos::View<double**> datainv_c_f(
"datainv_c_f",c, f);
405 Kokkos::View<double***> out_c_f_p(
"out_c_f_p",c, f, p);
406 Kokkos::View<double***> outi_c_f_p(
"outi_c_f_p",c, f, p);
407 Kokkos::View<double****> out_c_f_p_d(
"out_c_f_p_d",c, f, p, d1);
408 Kokkos::View<double****> outi_c_f_p_d(
"outi_c_f_p_d",c, f, p, d1);
409 Kokkos::View<double*****> out_c_f_p_d_d(
"out_c_f_p_d_d",c, f, p, d1, d2);
410 Kokkos::View<double*****> outi_c_f_p_d_d(
"outi_c_f_p_d_d",c, f, p, d1, d2);
411 double zero = INTREPID_TOL*100.0;
414 for (
unsigned int i=0; i<out_c_f_p.dimension(0); i++) {
415 for (
unsigned int j=0; j<out_c_f_p.dimension(1); j++) {
416 for (
unsigned int k=0; k<out_c_f_p.dimension(2); k++) {
417 out_c_f_p(i,j,k) = Teuchos::ScalarTraits<double>::random();
418 outi_c_f_p(i,j,k) = out_c_f_p(i,j,k);
423 for (
unsigned int i=0; i<out_c_f_p_d.dimension(0); i++) {
424 for (
unsigned int j=0; j<out_c_f_p_d.dimension(1); j++) {
425 for (
unsigned int k=0; k<out_c_f_p_d.dimension(2); k++) {
426 for (
unsigned int l=0; l<out_c_f_p_d.dimension(3); l++) {
427 out_c_f_p_d(i,j,k,l) = Teuchos::ScalarTraits<double>::random();
428 outi_c_f_p_d(i,j,k,l) = out_c_f_p_d(i,j,k,l);
434 for (
unsigned int i=0; i<out_c_f_p_d_d.dimension(0); i++) {
435 for (
unsigned int j=0; j<out_c_f_p_d_d.dimension(1); j++) {
436 for (
unsigned int k=0; k<out_c_f_p_d_d.dimension(2); k++) {
437 for (
unsigned int l=0; l<out_c_f_p_d_d.dimension(3); l++) {
438 for (
unsigned int m=0; m<out_c_f_p_d_d.dimension(4); m++) {
439 out_c_f_p_d_d(i,j,k,l,m) = Teuchos::ScalarTraits<double>::random();
440 outi_c_f_p_d_d(i,j,k,l,m) = out_c_f_p_d_d(i,j,k,l,m);
447 for (
unsigned int i=0; i<data_c_f.dimension(0); i++) {
448 for (
unsigned int j=0; j<data_c_f.dimension(1); j++) {
449 data_c_f(i,j) = Teuchos::ScalarTraits<double>::random();
450 datainv_c_f(i,j) = 1.0 / data_c_f(i,j);
454 art::scaleFields<double>(out_c_f_p, data_c_f);
455 art::scaleFields<double>(out_c_f_p, datainv_c_f);
456 rst::subtract(out_c_f_p, outi_c_f_p);
457 if (rst::vectorNorm(out_c_f_p, NORM_ONE) > zero) {
458 *outStream <<
"\n\nINCORRECT scaleValue (1): check scalar inverse property\n\n";
461 art::scaleFields<double>(out_c_f_p_d, data_c_f);
462 art::scaleFields<double>(out_c_f_p_d, datainv_c_f);
463 rst::subtract(out_c_f_p_d, outi_c_f_p_d);
464 if (rst::vectorNorm(out_c_f_p_d, NORM_ONE) > zero) {
465 *outStream <<
"\n\nINCORRECT scaleValue (2): check scalar inverse property\n\n";
468 art::scaleFields<double>(out_c_f_p_d_d, data_c_f);
469 art::scaleFields<double>(out_c_f_p_d_d, datainv_c_f);
470 rst::subtract(out_c_f_p_d_d, outi_c_f_p_d_d);
471 if (rst::vectorNorm(out_c_f_p_d_d, NORM_ONE) > zero) {
472 *outStream <<
"\n\nINCORRECT cloneScaleValue (3): check scalar inverse property\n\n";
480 catch (std::logic_error err) {
481 *outStream <<
"UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
482 *outStream << err.what() <<
'\n';
483 *outStream <<
"-------------------------------------------------------------------------------" <<
"\n\n";
489 std::cout <<
"End Result: TEST FAILED\n";
491 std::cout <<
"End Result: TEST PASSED\n";
494 std::cout.copyfmt(oldFormatState);
Header file for utility class to provide multidimensional containers.