Intrepid
test_05_kokkos.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 
49 #include "Intrepid_ArrayTools.hpp"
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>
57 using namespace std;
58 using namespace Intrepid;
59 
60 #define INTREPID_TEST_COMMAND( S ) \
61 { \
62  try { \
63  S ; \
64  } \
65  catch (std::logic_error err) { \
66  *outStream << "Expected Error ----------------------------------------------------------------\n"; \
67  *outStream << err.what() << '\n'; \
68  *outStream << "-------------------------------------------------------------------------------" << "\n\n"; \
69  }; \
70 }
71 
72 
73 int main(int argc, char *argv[]) {
74 
75 Teuchos::GlobalMPISession mpiSession(&argc, &argv);
76 Kokkos::initialize();
77 
78  // This little trick lets us print to std::cout only if
79  // a (dummy) command-line argument is provided.
80  int iprint = argc - 1;
81  Teuchos::RCP<std::ostream> outStream;
82  Teuchos::oblackholestream bhs; // outputs nothing
83  if (iprint > 0)
84  outStream = Teuchos::rcp(&std::cout, false);
85  else
86  outStream = Teuchos::rcp(&bhs, false);
87 
88  // Save the format state of the original std::cout.
89  Teuchos::oblackholestream oldFormatState;
90  oldFormatState.copyfmt(std::cout);
91 
92  *outStream \
93  << "===============================================================================\n" \
94  << "| |\n" \
95  << "| Unit Test (ArrayTools) |\n" \
96  << "| |\n" \
97  << "| 1) Array operations: clone / scale |\n" \
98  << "| |\n" \
99  << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov) or |\n" \
100  << "| Denis Ridzal (dridzal@sandia.gov). |\n" \
101  << "| |\n" \
102  << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
103  << "| Trilinos website: http://trilinos.sandia.gov |\n" \
104  << "| |\n" \
105  << "===============================================================================\n";
106 
107 
108  int errorFlag = 0;
109 #ifdef HAVE_INTREPID_DEBUG
110  int beginThrowNumber = Teuchos::TestForException_getThrowNumber();
111  int endThrowNumber = beginThrowNumber + 21;
112 #endif
113 
114  typedef ArrayTools art;
115  typedef RealSpaceTools<double> rst;
116 #ifdef HAVE_INTREPID_DEBUG
117  ArrayTools atools;
118 #endif
119 
120  *outStream \
121  << "\n"
122  << "===============================================================================\n"\
123  << "| TEST 1: exceptions |\n"\
124  << "===============================================================================\n";
125 
126  try{
127 
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);
145 
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) );
155 
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) );
168 
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) );
177 #endif
178 
179  }
180  catch (std::logic_error err) {
181  *outStream << "UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
182  *outStream << err.what() << '\n';
183  *outStream << "-------------------------------------------------------------------------------" << "\n\n";
184  errorFlag = -1000;
185  };
186 #ifdef HAVE_INTREPID_DEBUG
187  if (Teuchos::TestForException_getThrowNumber() != endThrowNumber)
188  errorFlag++;
189 #endif
190  *outStream \
191  << "\n"
192  << "===============================================================================\n"\
193  << "| TEST 2: correctness of math operations |\n"\
194  << "===============================================================================\n";
195 
196  outStream->precision(20);
197 
198  try {
199  { // start scope
200  *outStream << "\n************ Checking cloneFields ************\n";
201 
202  int c=5, p=9, f=7, d1=7, d2=13;
203 
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;
215 
216  // fill with random numbers
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();
220  }
221  }
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();
226  }
227  }
228  }
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();
234  }
235  }
236  }
237  }
238 
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;
242  }
243  }
244 
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";
250  errorFlag = -1000;
251  }
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";
257  errorFlag = -1000;
258  }
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";
264  errorFlag = -1000;
265  }
266  } // end scope
267 
268  { // start scope
269  *outStream << "\n************ Checking cloneScaleFields ************\n";
270  int c=5, p=9, f=7, d1=7, d2=13;
271 
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;
287  // fill with 1's
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++) {
290  in_f_p(i,j) = 1;
291  }
292  }
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++) {
296  in_f_p_d(i,j,k) = 1;
297  }
298  }
299  }
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;
305  }
306  }
307  }
308  }
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;
313  }
314  }
315  }
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;
321  }
322  }
323  }
324  }
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;
331  }
332  }
333  }
334  }
335 }
336  // fill with random numbers
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);
341  }
342  }
343 
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);
350  }
351  }
352  }
353 
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";
357  errorFlag = -1000;
358  }
359 
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);
367  }
368  }
369  }
370  }
371 
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";
375  errorFlag = -1000;
376  }
377 
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);
386 
387  }
388  }
389  }
390  }
391  }
392 
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";
396  errorFlag = -1000;
397  }
398  } // end scope
399 
400  { // start scope
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;
412 
413  // fill with random numbers
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);
419  }
420  }
421  }
422 
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);
429  }
430  }
431  }
432  }
433 
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);
441  }
442  }
443  }
444  }
445  }
446 
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);
451  }
452  }
453 
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";
459  errorFlag = -1000;
460  }
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";
466  errorFlag = -1000;
467  }
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";
473  errorFlag = -1000;
474  }
475  } // end scope
476 
477  /******************************************/
478  *outStream << "\n";
479  }
480  catch (std::logic_error err) {
481  *outStream << "UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
482  *outStream << err.what() << '\n';
483  *outStream << "-------------------------------------------------------------------------------" << "\n\n";
484  errorFlag = -1000;
485  };
486 
487 
488  if (errorFlag != 0)
489  std::cout << "End Result: TEST FAILED\n";
490  else
491  std::cout << "End Result: TEST PASSED\n";
492 
493  // reset format state of std::cout
494  std::cout.copyfmt(oldFormatState);
495  Kokkos::finalize();
496 
497  return errorFlag;
498 }
Implementation of basic linear algebra functionality in Euclidean space.
static void cloneScaleFields(ArrayOutFields &outputFields, const ArrayInFactors &inputFactors, const ArrayInFields &inputFields)
Multiplies a rank-2, 3, or 4 container with dimensions (F,P), (F,P,D1) or (F,P,D1,D2), representing the values of a scalar, vector or a tensor field, F-componentwise with a scalar container indexed by (C,F), and stores the result in an output value container of size (C,F,P), (C,F,P,D1) or (C,F,P,D1,D2).
Header file for utility class to provide multidimensional containers.
Header file for utility class to provide array tools, such as tensor contractions, etc.
Header file for classes providing basic linear algebra functionality in 1D, 2D and 3D...
Utility class that provides methods for higher-order algebraic manipulation of user-defined arrays...
static void cloneFields(ArrayOutFields &outputFields, const ArrayInFields &inputFields)
Replicates a rank-2, 3, or 4 container with dimensions (F,P), (F,P,D1) or (F,P,D1,D2), representing the values of a scalar, vector or a tensor field, into an output value container of size (C,F,P), (C,F,P,D1) or (C,F,P,D1,D2).
static void scaleFields(ArrayInOutFields &inoutFields, const ArrayInFactors &inputFactors)
Multiplies, in place, a rank-2, 3, or 4 container with dimensions (C,F,P), (C,F,P,D1) or (C,F,P,D1,D2), representing the values of a scalar, vector or a tensor field, F-componentwise with a scalar container indexed by (C,F).