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 
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 
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 
77  // This little trick lets us print to std::cout only if
78  // a (dummy) command-line argument is provided.
79  int iprint = argc - 1;
80  Teuchos::RCP<std::ostream> outStream;
81  Teuchos::oblackholestream bhs; // outputs nothing
82  if (iprint > 0)
83  outStream = Teuchos::rcp(&std::cout, false);
84  else
85  outStream = Teuchos::rcp(&bhs, false);
86 
87  // Save the format state of the original std::cout.
88  Teuchos::oblackholestream oldFormatState;
89  oldFormatState.copyfmt(std::cout);
90 
91  *outStream \
92  << "===============================================================================\n" \
93  << "| |\n" \
94  << "| Unit Test (ArrayTools) |\n" \
95  << "| |\n" \
96  << "| 1) Array operations: scalar multiply |\n" \
97  << "| |\n" \
98  << "| Questions? Contact Pavel Bochev (pbboche@sandia.gov) or |\n" \
99  << "| Denis Ridzal (dridzal@sandia.gov). |\n" \
100  << "| |\n" \
101  << "| Intrepid's website: http://trilinos.sandia.gov/packages/intrepid |\n" \
102  << "| Trilinos website: http://trilinos.sandia.gov |\n" \
103  << "| |\n" \
104  << "===============================================================================\n";
105 
106 
107  int errorFlag = 0;
108 #ifdef HAVE_INTREPID_DEBUG
109  int beginThrowNumber = Teuchos::TestForException_getThrowNumber();
110  int endThrowNumber = beginThrowNumber + 36;
111 #endif
112 
113  typedef ArrayTools art;
114  typedef RealSpaceTools<double> rst;
115 #ifdef HAVE_INTREPID_DEBUG
116  ArrayTools atools;
117 #endif
118 
119  *outStream \
120  << "\n"
121  << "===============================================================================\n"\
122  << "| TEST 1: exceptions |\n"\
123  << "===============================================================================\n";
124 
125  try{
126 
127 #ifdef HAVE_INTREPID_DEBUG
128  FieldContainer<double> a_2_2(2, 2);
129  FieldContainer<double> a_10_2(10, 2);
130  FieldContainer<double> a_10_3(10, 3);
131  FieldContainer<double> a_10_2_2(10, 2, 2);
132  FieldContainer<double> a_10_2_3(10, 2, 3);
133  FieldContainer<double> a_10_3_2(10, 3, 2);
134  FieldContainer<double> a_9_2_2(9, 2, 2);
135 
136  FieldContainer<double> a_10_2_2_2(10, 2, 2, 2);
137  FieldContainer<double> a_9_2_2_2(9, 2, 2, 2);
138  FieldContainer<double> a_10_3_2_2(10, 3, 2, 2);
139  FieldContainer<double> a_10_2_3_2(10, 2, 3, 2);
140  FieldContainer<double> a_10_2_2_3(10, 2, 2, 3);
141 
142  FieldContainer<double> a_10_2_2_2_2(10, 2, 2, 2, 2);
143  FieldContainer<double> a_9_2_2_2_2(9, 2, 2, 2, 2);
144  FieldContainer<double> a_10_3_2_2_2(10, 3, 2, 2, 2);
145  FieldContainer<double> a_10_2_3_2_2(10, 2, 3, 2, 2);
146  FieldContainer<double> a_10_2_2_3_2(10, 2, 2, 3, 2);
147  FieldContainer<double> a_10_2_2_2_3(10, 2, 2, 2, 3);
148 
149  FieldContainer<double> a_9_2(9, 2);
150  FieldContainer<double> a_10_1(10, 1);
151 
152  FieldContainer<double> a_10_1_2(10, 1, 2);
153  FieldContainer<double> a_10_1_3(10, 1, 3);
154 
155  FieldContainer<double> a_10_1_2_2(10, 1, 2, 2);
156 
157  FieldContainer<double> a_2_3_2_2(2, 3, 2, 2);
158  FieldContainer<double> a_2_2_2_2(2, 2, 2, 2);
159  FieldContainer<double> a_2_10(2, 10);
160  FieldContainer<double> a_2(2);
161 
162  *outStream << "-> scalarMultiplyDataField:\n";
163  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_2_2, a_10_2_2, a_2_2) );
164  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_2_2, a_2_2, a_2_2) );
165  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_2_2, a_2_2, a_10_2_2) );
166  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2, a_2_2, a_10_2_2) );
167  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2, a_10_3, a_10_2_2) );
168  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_9_2_2_2_2, a_10_2, a_10_2_2_2_2) );
169  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_3_2_2_2, a_10_2, a_10_2_2_2_2) );
170  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_3_2_2, a_10_2, a_10_2_2_2_2) );
171  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_3_2, a_10_2, a_10_2_2_2_2) );
172  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2_3, a_10_2, a_10_2_2_2_2) );
173  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2_2, a_10_2, a_10_2_2_2_2) );
174  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2_2, a_10_1, a_10_2_2_2_2) );
175  //
176  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_2_2, a_10_2_2, a_2) );
177  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2, a_2_2, a_2) );
178  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2, a_2_2, a_10_2) );
179  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2, a_10_2, a_2_10) );
180  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2_2, a_9_2, a_2_2_2_2) );
181  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_3_2_2_2, a_10_2, a_2_2_2_2) );
182  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_3_2_2, a_10_2, a_2_2_2_2) );
183  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_3_2, a_10_2, a_2_2_2_2) );
184  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2_3, a_10_2, a_2_2_2_2) );
185  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2_2, a_10_2, a_2_2_2_2) );
186  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataField<double>(a_10_2_2_2_2, a_10_1, a_2_2_2_2) );
187 
188 
189  FieldContainer<double> a_2_2_2(2, 2, 2);
190 
191  *outStream << "-> scalarMultiplyDataData:\n";
192  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_2_2, a_10_2_2, a_2_2) );
193  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_2, a_2_2, a_2) );
194  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_2_2, a_2_2, a_10_2_2) );
195  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2, a_2_2, a_10_2_2) );
196  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2, a_10_3, a_10_2_2) );
197  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_9_2_2_2, a_10_2, a_10_2_2_2) );
198  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_3_2_2, a_10_2, a_10_2_2_2) );
199  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_3_2, a_10_2, a_10_2_2_2) );
200  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_3, a_10_2, a_10_2_2_2) );
201  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_2, a_10_2, a_10_2_2_2) );
202  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_2, a_10_1, a_10_2_2_2) );
203  //
204  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_2_2, a_10_2_2, a_2) );
205  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_2_2, a_2_2, a_10_2_2_2) );
206  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_2, a_2_2, a_10_2) );
207  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2, a_2_2, a_10_2) );
208  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_2, a_9_2, a_2_2_2) );
209  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_3_2_2, a_10_2, a_2_2_2) );
210  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_3_2, a_10_2, a_2_2_2) );
211  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_3, a_10_2, a_2_2_2) );
212  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_2, a_10_2, a_2_2_2) );
213  INTREPID_TEST_COMMAND( atools.scalarMultiplyDataData<double>(a_10_2_2_2, a_10_1, a_2_2_2) );
214 #endif
215 
216  }
217  catch (std::logic_error err) {
218  *outStream << "UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
219  *outStream << err.what() << '\n';
220  *outStream << "-------------------------------------------------------------------------------" << "\n\n";
221  errorFlag = -1000;
222  };
223 
224 #ifdef HAVE_INTREPID_DEBUG
225  if (Teuchos::TestForException_getThrowNumber() != endThrowNumber)
226  errorFlag++;
227 #endif
228 
229  *outStream \
230  << "\n"
231  << "===============================================================================\n"\
232  << "| TEST 2: correctness of math operations |\n"\
233  << "===============================================================================\n";
234 
235  outStream->precision(20);
236 
237  try {
238  { // start scope
239  *outStream << "\n************ Checking scalarMultiplyDataField, reciprocal=false (branch 1) ************\n";
240 
241  int c=5, p=9, f=7, d1=7, d2=13;
242 
243  FieldContainer<double> in_c_f_p(c, f, p);
244  FieldContainer<double> in_c_f_p_d(c, f, p, d1);
245  FieldContainer<double> in_c_f_p_d_d(c, f, p, d1, d2);
246  FieldContainer<double> data_c_p(c, p);
247  FieldContainer<double> datainv_c_p(c, p);
248  FieldContainer<double> data_c_1(c, 1);
249  FieldContainer<double> datainv_c_1(c, 1);
250  FieldContainer<double> out_c_f_p(c, f, p);
251  FieldContainer<double> outi_c_f_p(c, f, p);
252  FieldContainer<double> out_c_f_p_d(c, f, p, d1);
253  FieldContainer<double> outi_c_f_p_d(c, f, p, d1);
254  FieldContainer<double> out_c_f_p_d_d(c, f, p, d1, d2);
255  FieldContainer<double> outi_c_f_p_d_d(c, f, p, d1, d2);
256  double zero = INTREPID_TOL*10000.0;
257 
258  // fill with random numbers
259  for (int i=0; i<in_c_f_p.size(); i++) {
260  in_c_f_p[i] = Teuchos::ScalarTraits<double>::random();
261  }
262  for (int i=0; i<in_c_f_p_d.size(); i++) {
263  in_c_f_p_d[i] = Teuchos::ScalarTraits<double>::random();
264  }
265  for (int i=0; i<in_c_f_p_d_d.size(); i++) {
266  in_c_f_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
267  }
268  for (int i=0; i<data_c_p.size(); i++) {
269  data_c_p[i] = Teuchos::ScalarTraits<double>::random();
270  datainv_c_p[i] = 1.0 / data_c_p[i];
271  }
272  for (int i=0; i<data_c_1.size(); i++) {
273  data_c_1[i] = Teuchos::ScalarTraits<double>::random();
274  datainv_c_1[i] = 1.0 / data_c_1[i];
275  }
276 
277  art::scalarMultiplyDataField<double>(out_c_f_p, data_c_p, in_c_f_p);
278  art::scalarMultiplyDataField<double>(outi_c_f_p, datainv_c_p, out_c_f_p);
279  rst::subtract(&outi_c_f_p[0], &in_c_f_p[0], outi_c_f_p.size());
280  if (rst::vectorNorm(&outi_c_f_p[0], outi_c_f_p.size(), NORM_ONE) > zero) {
281  *outStream << "\n\nINCORRECT scalarMultiplyDataField (1): check scalar inverse property\n\n";
282  errorFlag = -1000;
283  }
284  art::scalarMultiplyDataField<double>(out_c_f_p_d, data_c_p, in_c_f_p_d);
285  art::scalarMultiplyDataField<double>(outi_c_f_p_d, datainv_c_p, out_c_f_p_d);
286  rst::subtract(&outi_c_f_p_d[0], &in_c_f_p_d[0], outi_c_f_p_d.size());
287  if (rst::vectorNorm(&outi_c_f_p_d[0], outi_c_f_p_d.size(), NORM_ONE) > zero) {
288  *outStream << "\n\nINCORRECT scalarMultiplyDataField (2): check scalar inverse property\n\n";
289  errorFlag = -1000;
290  }
291  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_p, in_c_f_p_d_d);
292  art::scalarMultiplyDataField<double>(outi_c_f_p_d_d, datainv_c_p, out_c_f_p_d_d);
293  rst::subtract(&outi_c_f_p_d_d[0], &in_c_f_p_d_d[0], outi_c_f_p_d_d.size());
294  if (rst::vectorNorm(&outi_c_f_p_d_d[0], outi_c_f_p_d_d.size(), NORM_ONE) > zero) {
295  *outStream << "\n\nINCORRECT scalarMultiplyDataField (3): check scalar inverse property\n\n";
296  errorFlag = -1000;
297  }
298  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_1, in_c_f_p_d_d);
299  art::scalarMultiplyDataField<double>(outi_c_f_p_d_d, datainv_c_1, out_c_f_p_d_d);
300  rst::subtract(&outi_c_f_p_d_d[0], &in_c_f_p_d_d[0], outi_c_f_p_d_d.size());
301  if (rst::vectorNorm(&outi_c_f_p_d_d[0], outi_c_f_p_d_d.size(), NORM_ONE) > zero) {
302  *outStream << "\n\nINCORRECT scalarMultiplyDataField (4): check scalar inverse property\n\n";
303  errorFlag = -1000;
304  }
305 
306  // fill with constants
307  for (int i=0; i<in_c_f_p_d_d.size(); i++) {
308  in_c_f_p_d_d[i] = 1.0;
309  }
310  for (int i=0; i<data_c_p.size(); i++) {
311  data_c_p[i] = 5.0;
312  }
313  for (int i=0; i<data_c_1.size(); i++) {
314  data_c_1[i] = 5.0;
315  }
316  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_p, in_c_f_p_d_d);
317  if (std::abs(rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) - data_c_p[0]*in_c_f_p_d_d[0]*c*p*f*d1*d2) > zero) {
318  *outStream << "\n\nINCORRECT scalarMultiplyDataField (5): check result: "
319  << rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) << " != "
320  << data_c_p[0]*in_c_f_p_d_d[0]*c*f*p*d1*d2 << "\n\n";
321  errorFlag = -1000;
322  }
323  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_1, in_c_f_p_d_d);
324  if (std::abs(rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) - data_c_1[0]*in_c_f_p_d_d[0]*c*p*f*d1*d2) > zero) {
325  *outStream << "\n\nINCORRECT scalarMultiplyDataField (6): check result: "
326  << rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) << " != "
327  << data_c_p[0]*in_c_f_p_d_d[0]*c*f*p*d1*d2 << "\n\n";
328  errorFlag = -1000;
329  }
330  } // end scope
331 
332  { // start scope
333  *outStream << "\n************ Checking scalarMultiplyDataField, reciprocal=false (branch 2) ************\n";
334 
335  int c=5, p=9, f=7, d1=7, d2=13;
336 
337  FieldContainer<double> in_f_p(f, p);
338  FieldContainer<double> in_f_p_d(f, p, d1);
339  FieldContainer<double> in_f_p_d_d(f, p, d1, d2);
340  FieldContainer<double> in_c_f_p(c, f, p);
341  FieldContainer<double> in_c_f_p_d(c, f, p, d1);
342  FieldContainer<double> in_c_f_p_d_d(c, f, p, d1, d2);
343  FieldContainer<double> data_c_p(c, p);
344  FieldContainer<double> datainv_c_p(c, p);
345  FieldContainer<double> data_c_1(c, 1);
346  FieldContainer<double> datainv_c_1(c, 1);
347  FieldContainer<double> data_c_p_one(c, p);
348  FieldContainer<double> data_c_1_one(c, 1);
349  FieldContainer<double> out_c_f_p(c, f, p);
350  FieldContainer<double> outi_c_f_p(c, f, p);
351  FieldContainer<double> out_c_f_p_d(c, f, p, d1);
352  FieldContainer<double> outi_c_f_p_d(c, f, p, d1);
353  FieldContainer<double> out_c_f_p_d_d(c, f, p, d1, d2);
354  FieldContainer<double> outi_c_f_p_d_d(c, f, p, d1, d2);
355  double zero = INTREPID_TOL*10000.0;
356 
357  // fill with random numbers
358  for (int i=0; i<in_f_p.size(); i++) {
359  in_f_p[i] = Teuchos::ScalarTraits<double>::random();
360  }
361  for (int i=0; i<in_f_p_d.size(); i++) {
362  in_f_p_d[i] = Teuchos::ScalarTraits<double>::random();
363  }
364  for (int i=0; i<in_f_p_d_d.size(); i++) {
365  in_f_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
366  }
367  for (int i=0; i<data_c_p.size(); i++) {
368  data_c_p[i] = Teuchos::ScalarTraits<double>::random();
369  datainv_c_p[i] = 1.0 / data_c_p[i];
370  data_c_p_one[i] = 1.0;
371  }
372  for (int i=0; i<data_c_1.size(); i++) {
373  data_c_1[i] = Teuchos::ScalarTraits<double>::random();
374  datainv_c_1[i] = 1.0 / data_c_1[i];
375  data_c_1_one[i] = 1.0;
376  }
377 
378  art::scalarMultiplyDataField<double>(out_c_f_p, data_c_p, in_f_p);
379  art::scalarMultiplyDataField<double>(outi_c_f_p, datainv_c_p, out_c_f_p);
380  art::scalarMultiplyDataField<double>(in_c_f_p, data_c_p_one, in_f_p);
381  rst::subtract(&outi_c_f_p[0], &in_c_f_p[0], outi_c_f_p.size());
382  if (rst::vectorNorm(&outi_c_f_p[0], outi_c_f_p.size(), NORM_ONE) > zero) {
383  *outStream << "\n\nINCORRECT scalarMultiplyDataField (1): check scalar inverse property\n\n";
384  errorFlag = -1000;
385  }
386  art::scalarMultiplyDataField<double>(out_c_f_p_d, data_c_p, in_f_p_d);
387  art::scalarMultiplyDataField<double>(outi_c_f_p_d, datainv_c_p, out_c_f_p_d);
388  art::scalarMultiplyDataField<double>(in_c_f_p_d, data_c_p_one, in_f_p_d);
389  rst::subtract(&outi_c_f_p_d[0], &in_c_f_p_d[0], outi_c_f_p_d.size());
390  if (rst::vectorNorm(&outi_c_f_p_d[0], outi_c_f_p_d.size(), NORM_ONE) > zero) {
391  *outStream << "\n\nINCORRECT scalarMultiplyDataField (2): check scalar inverse property\n\n";
392  errorFlag = -1000;
393  }
394  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_p, in_f_p_d_d);
395  art::scalarMultiplyDataField<double>(outi_c_f_p_d_d, datainv_c_p, out_c_f_p_d_d);
396  art::scalarMultiplyDataField<double>(in_c_f_p_d_d, data_c_p_one, in_f_p_d_d);
397  rst::subtract(&outi_c_f_p_d_d[0], &in_c_f_p_d_d[0], outi_c_f_p_d_d.size());
398  if (rst::vectorNorm(&outi_c_f_p_d_d[0], outi_c_f_p_d_d.size(), NORM_ONE) > zero) {
399  *outStream << "\n\nINCORRECT scalarMultiplyDataField (3): check scalar inverse property\n\n";
400  errorFlag = -1000;
401  }
402  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_1, in_f_p_d_d);
403  art::scalarMultiplyDataField<double>(outi_c_f_p_d_d, datainv_c_1, out_c_f_p_d_d);
404  art::scalarMultiplyDataField<double>(in_c_f_p_d_d, data_c_p_one, in_f_p_d_d);
405  rst::subtract(&outi_c_f_p_d_d[0], &in_c_f_p_d_d[0], outi_c_f_p_d_d.size());
406  if (rst::vectorNorm(&outi_c_f_p_d_d[0], outi_c_f_p_d_d.size(), NORM_ONE) > zero) {
407  *outStream << "\n\nINCORRECT scalarMultiplyDataField (4): check scalar inverse property\n\n";
408  errorFlag = -1000;
409  }
410 
411  // fill with constants
412  for (int i=0; i<in_f_p_d_d.size(); i++) {
413  in_f_p_d_d[i] = 1.0;
414  }
415  for (int i=0; i<data_c_p.size(); i++) {
416  data_c_p[i] = 5.0;
417  }
418  for (int i=0; i<data_c_1.size(); i++) {
419  data_c_1[i] = 5.0;
420  }
421  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_p, in_f_p_d_d);
422  if (std::abs(rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) - data_c_p[0]*in_f_p_d_d[0]*c*p*f*d1*d2) > zero) {
423  *outStream << "\n\nINCORRECT scalarMultiplyDataField (5): check result: "
424  << rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) << " != "
425  << data_c_p[0]*in_f_p_d_d[0]*c*f*p*d1*d2 << "\n\n";
426  errorFlag = -1000;
427  }
428  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_1, in_f_p_d_d);
429  if (std::abs(rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) - data_c_1[0]*in_f_p_d_d[0]*c*p*f*d1*d2) > zero) {
430  *outStream << "\n\nINCORRECT scalarMultiplyDataField (6): check result: "
431  << rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) << " != "
432  << data_c_1[0]*in_f_p_d_d[0]*c*f*p*d1*d2 << "\n\n";
433  errorFlag = -1000;
434  }
435  } // end scope
436 
437  { // start scope
438  *outStream << "\n************ Checking scalarMultiplyDataField, reciprocal=true, i.e. division (branch 1) ************\n";
439 
440  int c=5, p=9, f=7, d1=7, d2=13;
441 
442  FieldContainer<double> in_c_f_p(c, f, p);
443  FieldContainer<double> in_c_f_p_d(c, f, p, d1);
444  FieldContainer<double> in_c_f_p_d_d(c, f, p, d1, d2);
445  FieldContainer<double> data_c_p(c, p);
446  FieldContainer<double> datainv_c_p(c, p);
447  FieldContainer<double> data_c_1(c, 1);
448  FieldContainer<double> datainv_c_1(c, 1);
449  FieldContainer<double> out_c_f_p(c, f, p);
450  FieldContainer<double> outi_c_f_p(c, f, p);
451  FieldContainer<double> out_c_f_p_d(c, f, p, d1);
452  FieldContainer<double> outi_c_f_p_d(c, f, p, d1);
453  FieldContainer<double> out_c_f_p_d_d(c, f, p, d1, d2);
454  FieldContainer<double> outi_c_f_p_d_d(c, f, p, d1, d2);
455  double zero = INTREPID_TOL*10000.0;
456 
457  // fill with random numbers
458  for (int i=0; i<in_c_f_p.size(); i++) {
459  in_c_f_p[i] = Teuchos::ScalarTraits<double>::random();
460  }
461  for (int i=0; i<in_c_f_p_d.size(); i++) {
462  in_c_f_p_d[i] = Teuchos::ScalarTraits<double>::random();
463  }
464  for (int i=0; i<in_c_f_p_d_d.size(); i++) {
465  in_c_f_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
466  }
467  for (int i=0; i<data_c_p.size(); i++) {
468  data_c_p[i] = Teuchos::ScalarTraits<double>::random();
469  datainv_c_p[i] = 1.0 / data_c_p[i];
470  }
471  for (int i=0; i<data_c_1.size(); i++) {
472  data_c_1[i] = Teuchos::ScalarTraits<double>::random();
473  datainv_c_1[i] = 1.0 / data_c_1[i];
474  }
475 
476  art::scalarMultiplyDataField<double>(out_c_f_p, data_c_p, in_c_f_p, true);
477  art::scalarMultiplyDataField<double>(outi_c_f_p, datainv_c_p, out_c_f_p, true);
478  rst::subtract(&outi_c_f_p[0], &in_c_f_p[0], outi_c_f_p.size());
479  if (rst::vectorNorm(&outi_c_f_p[0], outi_c_f_p.size(), NORM_ONE) > zero) {
480  *outStream << "\n\nINCORRECT scalarMultiplyDataField (1): check scalar inverse property\n\n";
481  errorFlag = -1000;
482  }
483  art::scalarMultiplyDataField<double>(out_c_f_p_d, data_c_p, in_c_f_p_d, true);
484  art::scalarMultiplyDataField<double>(outi_c_f_p_d, datainv_c_p, out_c_f_p_d, true);
485  rst::subtract(&outi_c_f_p_d[0], &in_c_f_p_d[0], outi_c_f_p_d.size());
486  if (rst::vectorNorm(&outi_c_f_p_d[0], outi_c_f_p_d.size(), NORM_ONE) > zero) {
487  *outStream << "\n\nINCORRECT scalarMultiplyDataField (2): check scalar inverse property\n\n";
488  errorFlag = -1000;
489  }
490  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_p, in_c_f_p_d_d, true);
491  art::scalarMultiplyDataField<double>(outi_c_f_p_d_d, datainv_c_p, out_c_f_p_d_d, true);
492  rst::subtract(&outi_c_f_p_d_d[0], &in_c_f_p_d_d[0], outi_c_f_p_d_d.size());
493  if (rst::vectorNorm(&outi_c_f_p_d_d[0], outi_c_f_p_d_d.size(), NORM_ONE) > zero) {
494  *outStream << "\n\nINCORRECT scalarMultiplyDataField (3): check scalar inverse property\n\n";
495  errorFlag = -1000;
496  }
497  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_1, in_c_f_p_d_d, true);
498  art::scalarMultiplyDataField<double>(outi_c_f_p_d_d, datainv_c_1, out_c_f_p_d_d, true);
499  rst::subtract(&outi_c_f_p_d_d[0], &in_c_f_p_d_d[0], outi_c_f_p_d_d.size());
500  if (rst::vectorNorm(&outi_c_f_p_d_d[0], outi_c_f_p_d_d.size(), NORM_ONE) > zero) {
501  *outStream << "\n\nINCORRECT scalarMultiplyDataField (4): check scalar inverse property\n\n";
502  errorFlag = -1000;
503  }
504 
505  // fill with constants
506  for (int i=0; i<in_c_f_p_d_d.size(); i++) {
507  in_c_f_p_d_d[i] = 1.0;
508  }
509  for (int i=0; i<data_c_p.size(); i++) {
510  data_c_p[i] = 5.0;
511  }
512  for (int i=0; i<data_c_1.size(); i++) {
513  data_c_1[i] = 5.0;
514  }
515  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_p, in_c_f_p_d_d, true);
516  if (std::abs(rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) - (1.0/data_c_p[0])*in_c_f_p_d_d[0]*c*p*f*d1*d2)/rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) > zero) {
517  *outStream << "\n\nINCORRECT scalarMultiplyDataField (5): check result: "
518  << rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) << " != "
519  << (1.0/data_c_p[0])*in_c_f_p_d_d[0]*c*p*f*d1*d2 << "\n\n";
520  errorFlag = -1000;
521  }
522  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_1, in_c_f_p_d_d, true);
523  if (std::abs(rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) - (1.0/data_c_1[0])*in_c_f_p_d_d[0]*c*p*f*d1*d2)/rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) > zero) {
524  *outStream << "\n\nINCORRECT scalarMultiplyDataField (6): check result: "
525  << rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) << " != "
526  << (1.0/data_c_p[0])*in_c_f_p_d_d[0]*c*p*f*d1*d2 << "\n\n";
527  errorFlag = -1000;
528  }
529  } // end scope
530 
531  { // start scope
532  *outStream << "\n************ Checking scalarMultiplyDataField, reciprocal=true, i.e. division (branch 2) ************\n";
533 
534  int c=5, p=9, f=7, d1=7, d2=13;
535 
536  FieldContainer<double> in_f_p(f, p);
537  FieldContainer<double> in_f_p_d(f, p, d1);
538  FieldContainer<double> in_f_p_d_d(f, p, d1, d2);
539  FieldContainer<double> in_c_f_p(c, f, p);
540  FieldContainer<double> in_c_f_p_d(c, f, p, d1);
541  FieldContainer<double> in_c_f_p_d_d(c, f, p, d1, d2);
542  FieldContainer<double> data_c_p(c, p);
543  FieldContainer<double> datainv_c_p(c, p);
544  FieldContainer<double> data_c_1(c, 1);
545  FieldContainer<double> datainv_c_1(c, 1);
546  FieldContainer<double> data_c_p_one(c, p);
547  FieldContainer<double> data_c_1_one(c, 1);
548  FieldContainer<double> out_c_f_p(c, f, p);
549  FieldContainer<double> outi_c_f_p(c, f, p);
550  FieldContainer<double> out_c_f_p_d(c, f, p, d1);
551  FieldContainer<double> outi_c_f_p_d(c, f, p, d1);
552  FieldContainer<double> out_c_f_p_d_d(c, f, p, d1, d2);
553  FieldContainer<double> outi_c_f_p_d_d(c, f, p, d1, d2);
554  double zero = INTREPID_TOL*10000.0;
555 
556  // fill with random numbers
557  for (int i=0; i<in_f_p.size(); i++) {
558  in_f_p[i] = Teuchos::ScalarTraits<double>::random();
559  }
560  for (int i=0; i<in_f_p_d.size(); i++) {
561  in_f_p_d[i] = Teuchos::ScalarTraits<double>::random();
562  }
563  for (int i=0; i<in_f_p_d_d.size(); i++) {
564  in_f_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
565  }
566  for (int i=0; i<data_c_p.size(); i++) {
567  data_c_p[i] = Teuchos::ScalarTraits<double>::random();
568  datainv_c_p[i] = 1.0 / data_c_p[i];
569  data_c_p_one[i] = 1.0;
570  }
571  for (int i=0; i<data_c_1.size(); i++) {
572  data_c_1[i] = Teuchos::ScalarTraits<double>::random();
573  datainv_c_1[i] = 1.0 / data_c_1[i];
574  data_c_1_one[i] = 1.0;
575  }
576 
577  art::scalarMultiplyDataField<double>(out_c_f_p, data_c_p, in_f_p, true);
578  art::scalarMultiplyDataField<double>(outi_c_f_p, datainv_c_p, out_c_f_p, true);
579  art::scalarMultiplyDataField<double>(in_c_f_p, data_c_p_one, in_f_p);
580  rst::subtract(&outi_c_f_p[0], &in_c_f_p[0], outi_c_f_p.size());
581  if (rst::vectorNorm(&outi_c_f_p[0], outi_c_f_p.size(), NORM_ONE) > zero) {
582  *outStream << "\n\nINCORRECT scalarMultiplyDataField (1): check scalar inverse property\n\n";
583  errorFlag = -1000;
584  }
585  art::scalarMultiplyDataField<double>(out_c_f_p_d, data_c_p, in_f_p_d, true);
586  art::scalarMultiplyDataField<double>(outi_c_f_p_d, datainv_c_p, out_c_f_p_d, true);
587  art::scalarMultiplyDataField<double>(in_c_f_p_d, data_c_p_one, in_f_p_d);
588  rst::subtract(&outi_c_f_p_d[0], &in_c_f_p_d[0], outi_c_f_p_d.size());
589  if (rst::vectorNorm(&outi_c_f_p_d[0], outi_c_f_p_d.size(), NORM_ONE) > zero) {
590  *outStream << "\n\nINCORRECT scalarMultiplyDataField (2): check scalar inverse property\n\n";
591  errorFlag = -1000;
592  }
593  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_p, in_f_p_d_d, true);
594  art::scalarMultiplyDataField<double>(outi_c_f_p_d_d, datainv_c_p, out_c_f_p_d_d, true);
595  art::scalarMultiplyDataField<double>(in_c_f_p_d_d, data_c_p_one, in_f_p_d_d);
596  rst::subtract(&outi_c_f_p_d_d[0], &in_c_f_p_d_d[0], outi_c_f_p_d_d.size());
597  if (rst::vectorNorm(&outi_c_f_p_d_d[0], outi_c_f_p_d_d.size(), NORM_ONE) > zero) {
598  *outStream << "\n\nINCORRECT scalarMultiplyDataField (3): check scalar inverse property\n\n";
599  errorFlag = -1000;
600  }
601  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_1, in_f_p_d_d, true);
602  art::scalarMultiplyDataField<double>(outi_c_f_p_d_d, datainv_c_1, out_c_f_p_d_d, true);
603  art::scalarMultiplyDataField<double>(in_c_f_p_d_d, data_c_p_one, in_f_p_d_d);
604  rst::subtract(&outi_c_f_p_d_d[0], &in_c_f_p_d_d[0], outi_c_f_p_d_d.size());
605  if (rst::vectorNorm(&outi_c_f_p_d_d[0], outi_c_f_p_d_d.size(), NORM_ONE) > zero) {
606  *outStream << "\n\nINCORRECT scalarMultiplyDataField (4): check scalar inverse property\n\n";
607  errorFlag = -1000;
608  }
609 
610  // fill with constants
611  for (int i=0; i<in_f_p_d_d.size(); i++) {
612  in_f_p_d_d[i] = 1.0;
613  }
614  for (int i=0; i<data_c_p.size(); i++) {
615  data_c_p[i] = 5.0;
616  }
617  for (int i=0; i<data_c_1.size(); i++) {
618  data_c_1[i] = 5.0;
619  }
620  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_p, in_f_p_d_d, true);
621  if (std::abs(rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) - (1.0/data_c_p[0])*in_f_p_d_d[0]*c*p*f*d1*d2)/rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) > zero) {
622  *outStream << "\n\nINCORRECT scalarMultiplyDataField (5): check result: "
623  << rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) << " != "
624  << (1.0/data_c_p[0])*in_f_p_d_d[0]*c*p*f*d1*d2 << "\n\n";
625  errorFlag = -1000;
626  }
627  art::scalarMultiplyDataField<double>(out_c_f_p_d_d, data_c_1, in_f_p_d_d, true);
628  if (std::abs(rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) - (1.0/data_c_1[0])*in_f_p_d_d[0]*c*p*f*d1*d2)/rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) > zero) {
629  *outStream << "\n\nINCORRECT scalarMultiplyDataField (6): check result: "
630  << rst::vectorNorm(&out_c_f_p_d_d[0], out_c_f_p_d_d.size(), NORM_ONE) << " != "
631  << (1.0/data_c_1[0])*in_f_p_d_d[0]*c*p*f*d1*d2 << "\n\n";
632  errorFlag = -1000;
633  }
634  } // end scope
635 
636 
637 
638 
639  { // start scope
640  *outStream << "\n************ Checking scalarMultiplyDataData, reciprocal=false (branch 1) ************\n";
641 
642  int c=5, p=9, d1=7, d2=13;
643 
644  FieldContainer<double> in_c_p(c, p);
645  FieldContainer<double> in_c_p_d(c, p, d1);
646  FieldContainer<double> in_c_p_d_d(c, p, d1, d2);
647  FieldContainer<double> data_c_p(c, p);
648  FieldContainer<double> datainv_c_p(c, p);
649  FieldContainer<double> data_c_1(c, 1);
650  FieldContainer<double> datainv_c_1(c, 1);
651  FieldContainer<double> out_c_p(c, p);
652  FieldContainer<double> outi_c_p(c, p);
653  FieldContainer<double> out_c_p_d(c, p, d1);
654  FieldContainer<double> outi_c_p_d(c, p, d1);
655  FieldContainer<double> out_c_p_d_d(c, p, d1, d2);
656  FieldContainer<double> outi_c_p_d_d(c, p, d1, d2);
657  double zero = INTREPID_TOL*10000.0;
658 
659  // fill with random numbers
660  for (int i=0; i<in_c_p.size(); i++) {
661  in_c_p[i] = Teuchos::ScalarTraits<double>::random();
662  }
663  for (int i=0; i<in_c_p_d.size(); i++) {
664  in_c_p_d[i] = Teuchos::ScalarTraits<double>::random();
665  }
666  for (int i=0; i<in_c_p_d_d.size(); i++) {
667  in_c_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
668  }
669  for (int i=0; i<data_c_p.size(); i++) {
670  data_c_p[i] = Teuchos::ScalarTraits<double>::random();
671  datainv_c_p[i] = 1.0 / data_c_p[i];
672  }
673  for (int i=0; i<data_c_1.size(); i++) {
674  data_c_1[i] = Teuchos::ScalarTraits<double>::random();
675  datainv_c_1[i] = 1.0 / data_c_1[i];
676  }
677 
678  art::scalarMultiplyDataData<double>(out_c_p, data_c_p, in_c_p);
679  art::scalarMultiplyDataData<double>(outi_c_p, datainv_c_p, out_c_p);
680  rst::subtract(&outi_c_p[0], &in_c_p[0], outi_c_p.size());
681  if (rst::vectorNorm(&outi_c_p[0], outi_c_p.size(), NORM_ONE) > zero) {
682  *outStream << "\n\nINCORRECT scalarMultiplyDataData (1): check scalar inverse property\n\n";
683  errorFlag = -1000;
684  }
685  art::scalarMultiplyDataData<double>(out_c_p_d, data_c_p, in_c_p_d);
686  art::scalarMultiplyDataData<double>(outi_c_p_d, datainv_c_p, out_c_p_d);
687  rst::subtract(&outi_c_p_d[0], &in_c_p_d[0], outi_c_p_d.size());
688  if (rst::vectorNorm(&outi_c_p_d[0], outi_c_p_d.size(), NORM_ONE) > zero) {
689  *outStream << "\n\nINCORRECT scalarMultiplyDataData (2): check scalar inverse property\n\n";
690  errorFlag = -1000;
691  }
692  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_p, in_c_p_d_d);
693  art::scalarMultiplyDataData<double>(outi_c_p_d_d, datainv_c_p, out_c_p_d_d);
694  rst::subtract(&outi_c_p_d_d[0], &in_c_p_d_d[0], outi_c_p_d_d.size());
695  if (rst::vectorNorm(&outi_c_p_d_d[0], outi_c_p_d_d.size(), NORM_ONE) > zero) {
696  *outStream << "\n\nINCORRECT scalarMultiplyDataData (3): check scalar inverse property\n\n";
697  errorFlag = -1000;
698  }
699  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_1, in_c_p_d_d);
700  art::scalarMultiplyDataData<double>(outi_c_p_d_d, datainv_c_1, out_c_p_d_d);
701  rst::subtract(&outi_c_p_d_d[0], &in_c_p_d_d[0], outi_c_p_d_d.size());
702  if (rst::vectorNorm(&outi_c_p_d_d[0], outi_c_p_d_d.size(), NORM_ONE) > zero) {
703  *outStream << "\n\nINCORRECT scalarMultiplyDataData (4): check scalar inverse property\n\n";
704  errorFlag = -1000;
705  }
706 
707  // fill with constants
708  for (int i=0; i<in_c_p_d_d.size(); i++) {
709  in_c_p_d_d[i] = 1.0;
710  }
711  for (int i=0; i<data_c_p.size(); i++) {
712  data_c_p[i] = 5.0;
713  }
714  for (int i=0; i<data_c_1.size(); i++) {
715  data_c_1[i] = 5.0;
716  }
717  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_p, in_c_p_d_d);
718  if (std::abs(rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) - data_c_p[0]*in_c_p_d_d[0]*c*p*d1*d2) > zero) {
719  *outStream << "\n\nINCORRECT scalarMultiplyDataData (5): check result: "
720  << rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) << " != "
721  << data_c_p[0]*in_c_p_d_d[0]*c*p*d1*d2 << "\n\n";
722  errorFlag = -1000;
723  }
724  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_1, in_c_p_d_d);
725  if (std::abs(rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) - data_c_1[0]*in_c_p_d_d[0]*c*p*d1*d2) > zero) {
726  *outStream << "\n\nINCORRECT scalarMultiplyDataData (6): check result: "
727  << rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) << " != "
728  << data_c_p[0]*in_c_p_d_d[0]*c*p*d1*d2 << "\n\n";
729  errorFlag = -1000;
730  }
731  } // end scope
732 
733  { // start scope
734  *outStream << "\n************ Checking scalarMultiplyDataData, reciprocal=false (branch 2) ************\n";
735 
736  int c=5, p=9, d1=7, d2=13;
737 
738  FieldContainer<double> in_p(p);
739  FieldContainer<double> in_p_d(p, d1);
740  FieldContainer<double> in_p_d_d(p, d1, d2);
741  FieldContainer<double> in_c_p(c, p);
742  FieldContainer<double> in_c_p_d(c, p, d1);
743  FieldContainer<double> in_c_p_d_d(c, p, d1, d2);
744  FieldContainer<double> data_c_p(c, p);
745  FieldContainer<double> datainv_c_p(c, p);
746  FieldContainer<double> data_c_1(c, 1);
747  FieldContainer<double> datainv_c_1(c, 1);
748  FieldContainer<double> data_c_p_one(c, p);
749  FieldContainer<double> data_c_1_one(c, 1);
750  FieldContainer<double> out_c_p(c, p);
751  FieldContainer<double> outi_c_p(c, p);
752  FieldContainer<double> out_c_p_d(c, p, d1);
753  FieldContainer<double> outi_c_p_d(c, p, d1);
754  FieldContainer<double> out_c_p_d_d(c, p, d1, d2);
755  FieldContainer<double> outi_c_p_d_d(c, p, d1, d2);
756  double zero = INTREPID_TOL*10000.0;
757 
758  // fill with random numbers
759  for (int i=0; i<in_p.size(); i++) {
760  in_p[i] = Teuchos::ScalarTraits<double>::random();
761  }
762  for (int i=0; i<in_p_d.size(); i++) {
763  in_p_d[i] = Teuchos::ScalarTraits<double>::random();
764  }
765  for (int i=0; i<in_p_d_d.size(); i++) {
766  in_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
767  }
768  for (int i=0; i<data_c_p.size(); i++) {
769  data_c_p[i] = Teuchos::ScalarTraits<double>::random();
770  datainv_c_p[i] = 1.0 / data_c_p[i];
771  data_c_p_one[i] = 1.0;
772  }
773  for (int i=0; i<data_c_1.size(); i++) {
774  data_c_1[i] = Teuchos::ScalarTraits<double>::random();
775  datainv_c_1[i] = 1.0 / data_c_1[i];
776  data_c_1_one[i] = 1.0;
777  }
778 
779  art::scalarMultiplyDataData<double>(out_c_p, data_c_p, in_p);
780  art::scalarMultiplyDataData<double>(outi_c_p, datainv_c_p, out_c_p);
781  art::scalarMultiplyDataData<double>(in_c_p, data_c_p_one, in_p);
782  rst::subtract(&outi_c_p[0], &in_c_p[0], outi_c_p.size());
783  if (rst::vectorNorm(&outi_c_p[0], outi_c_p.size(), NORM_ONE) > zero) {
784  *outStream << "\n\nINCORRECT scalarMultiplyDataData (1): check scalar inverse property\n\n";
785  errorFlag = -1000;
786  }
787  art::scalarMultiplyDataData<double>(out_c_p_d, data_c_p, in_p_d);
788  art::scalarMultiplyDataData<double>(outi_c_p_d, datainv_c_p, out_c_p_d);
789  art::scalarMultiplyDataData<double>(in_c_p_d, data_c_p_one, in_p_d);
790  rst::subtract(&outi_c_p_d[0], &in_c_p_d[0], outi_c_p_d.size());
791  if (rst::vectorNorm(&outi_c_p_d[0], outi_c_p_d.size(), NORM_ONE) > zero) {
792  *outStream << "\n\nINCORRECT scalarMultiplyDataData (2): check scalar inverse property\n\n";
793  errorFlag = -1000;
794  }
795  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_p, in_p_d_d);
796  art::scalarMultiplyDataData<double>(outi_c_p_d_d, datainv_c_p, out_c_p_d_d);
797  art::scalarMultiplyDataData<double>(in_c_p_d_d, data_c_p_one, in_p_d_d);
798  rst::subtract(&outi_c_p_d_d[0], &in_c_p_d_d[0], outi_c_p_d_d.size());
799  if (rst::vectorNorm(&outi_c_p_d_d[0], outi_c_p_d_d.size(), NORM_ONE) > zero) {
800  *outStream << "\n\nINCORRECT scalarMultiplyDataData (3): check scalar inverse property\n\n";
801  errorFlag = -1000;
802  }
803  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_1, in_p_d_d);
804  art::scalarMultiplyDataData<double>(outi_c_p_d_d, datainv_c_1, out_c_p_d_d);
805  art::scalarMultiplyDataData<double>(in_c_p_d_d, data_c_p_one, in_p_d_d);
806  rst::subtract(&outi_c_p_d_d[0], &in_c_p_d_d[0], outi_c_p_d_d.size());
807  if (rst::vectorNorm(&outi_c_p_d_d[0], outi_c_p_d_d.size(), NORM_ONE) > zero) {
808  *outStream << "\n\nINCORRECT scalarMultiplyDataData (4): check scalar inverse property\n\n";
809  errorFlag = -1000;
810  }
811 
812  // fill with constants
813  for (int i=0; i<in_p_d_d.size(); i++) {
814  in_p_d_d[i] = 1.0;
815  }
816  for (int i=0; i<data_c_p.size(); i++) {
817  data_c_p[i] = 5.0;
818  }
819  for (int i=0; i<data_c_1.size(); i++) {
820  data_c_1[i] = 5.0;
821  }
822  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_p, in_p_d_d);
823  if (std::abs(rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) - data_c_p[0]*in_p_d_d[0]*c*p*d1*d2) > zero) {
824  *outStream << "\n\nINCORRECT scalarMultiplyDataData (5): check result: "
825  << rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) << " != "
826  << data_c_p[0]*in_p_d_d[0]*c*p*d1*d2 << "\n\n";
827  errorFlag = -1000;
828  }
829  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_1, in_p_d_d);
830  if (std::abs(rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) - data_c_1[0]*in_p_d_d[0]*c*p*d1*d2) > zero) {
831  *outStream << "\n\nINCORRECT scalarMultiplyDataData (6): check result: "
832  << rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) << " != "
833  << data_c_1[0]*in_p_d_d[0]*c*p*d1*d2 << "\n\n";
834  errorFlag = -1000;
835  }
836  } // end scope
837 
838  { // start scope
839  *outStream << "\n************ Checking scalarMultiplyDataData, reciprocal=true, i.e. division (branch 1) ************\n";
840 
841  int c=5, p=9, d1=7, d2=13;
842 
843  FieldContainer<double> in_c_p(c, p);
844  FieldContainer<double> in_c_p_d(c, p, d1);
845  FieldContainer<double> in_c_p_d_d(c, p, d1, d2);
846  FieldContainer<double> data_c_p(c, p);
847  FieldContainer<double> datainv_c_p(c, p);
848  FieldContainer<double> data_c_1(c, 1);
849  FieldContainer<double> datainv_c_1(c, 1);
850  FieldContainer<double> out_c_p(c, p);
851  FieldContainer<double> outi_c_p(c, p);
852  FieldContainer<double> out_c_p_d(c, p, d1);
853  FieldContainer<double> outi_c_p_d(c, p, d1);
854  FieldContainer<double> out_c_p_d_d(c, p, d1, d2);
855  FieldContainer<double> outi_c_p_d_d(c, p, d1, d2);
856  double zero = INTREPID_TOL*10000.0;
857 
858  // fill with random numbers
859  for (int i=0; i<in_c_p.size(); i++) {
860  in_c_p[i] = Teuchos::ScalarTraits<double>::random();
861  }
862  for (int i=0; i<in_c_p_d.size(); i++) {
863  in_c_p_d[i] = Teuchos::ScalarTraits<double>::random();
864  }
865  for (int i=0; i<in_c_p_d_d.size(); i++) {
866  in_c_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
867  }
868  for (int i=0; i<data_c_p.size(); i++) {
869  data_c_p[i] = Teuchos::ScalarTraits<double>::random();
870  datainv_c_p[i] = 1.0 / data_c_p[i];
871  }
872  for (int i=0; i<data_c_1.size(); i++) {
873  data_c_1[i] = Teuchos::ScalarTraits<double>::random();
874  datainv_c_1[i] = 1.0 / data_c_1[i];
875  }
876 
877  art::scalarMultiplyDataData<double>(out_c_p, data_c_p, in_c_p, true);
878  art::scalarMultiplyDataData<double>(outi_c_p, datainv_c_p, out_c_p, true);
879  rst::subtract(&outi_c_p[0], &in_c_p[0], outi_c_p.size());
880  if (rst::vectorNorm(&outi_c_p[0], outi_c_p.size(), NORM_ONE) > zero) {
881  *outStream << "\n\nINCORRECT scalarMultiplyDataData (1): check scalar inverse property\n\n";
882  errorFlag = -1000;
883  }
884  art::scalarMultiplyDataData<double>(out_c_p_d, data_c_p, in_c_p_d, true);
885  art::scalarMultiplyDataData<double>(outi_c_p_d, datainv_c_p, out_c_p_d, true);
886  rst::subtract(&outi_c_p_d[0], &in_c_p_d[0], outi_c_p_d.size());
887  if (rst::vectorNorm(&outi_c_p_d[0], outi_c_p_d.size(), NORM_ONE) > zero) {
888  *outStream << "\n\nINCORRECT scalarMultiplyDataData (2): check scalar inverse property\n\n";
889  errorFlag = -1000;
890  }
891  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_p, in_c_p_d_d, true);
892  art::scalarMultiplyDataData<double>(outi_c_p_d_d, datainv_c_p, out_c_p_d_d, true);
893  rst::subtract(&outi_c_p_d_d[0], &in_c_p_d_d[0], outi_c_p_d_d.size());
894  if (rst::vectorNorm(&outi_c_p_d_d[0], outi_c_p_d_d.size(), NORM_ONE) > zero) {
895  *outStream << "\n\nINCORRECT scalarMultiplyDataData (3): check scalar inverse property\n\n";
896  errorFlag = -1000;
897  }
898  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_1, in_c_p_d_d, true);
899  art::scalarMultiplyDataData<double>(outi_c_p_d_d, datainv_c_1, out_c_p_d_d, true);
900  rst::subtract(&outi_c_p_d_d[0], &in_c_p_d_d[0], outi_c_p_d_d.size());
901  if (rst::vectorNorm(&outi_c_p_d_d[0], outi_c_p_d_d.size(), NORM_ONE) > zero) {
902  *outStream << "\n\nINCORRECT scalarMultiplyDataData (4): check scalar inverse property\n\n";
903  errorFlag = -1000;
904  }
905 
906  // fill with constants
907  for (int i=0; i<in_c_p_d_d.size(); i++) {
908  in_c_p_d_d[i] = 1.0;
909  }
910  for (int i=0; i<data_c_p.size(); i++) {
911  data_c_p[i] = 5.0;
912  }
913  for (int i=0; i<data_c_1.size(); i++) {
914  data_c_1[i] = 5.0;
915  }
916  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_p, in_c_p_d_d, true);
917  if (std::abs(rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) - (1.0/data_c_p[0])*in_c_p_d_d[0]*c*p*d1*d2)/rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) > zero) {
918  *outStream << "\n\nINCORRECT scalarMultiplyDataData (5): check result: "
919  << rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) << " != "
920  << (1.0/data_c_p[0])*in_c_p_d_d[0]*c*p*d1*d2 << "\n\n";
921  errorFlag = -1000;
922  }
923  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_1, in_c_p_d_d, true);
924  if (std::abs(rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) - (1.0/data_c_1[0])*in_c_p_d_d[0]*c*p*d1*d2)/rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) > zero) {
925  *outStream << "\n\nINCORRECT scalarMultiplyDataData (6): check result: "
926  << rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) << " != "
927  << (1.0/data_c_p[0])*in_c_p_d_d[0]*c*p*d1*d2 << "\n\n";
928  errorFlag = -1000;
929  }
930  } // end scope
931 
932  { // start scope
933  *outStream << "\n************ Checking scalarMultiplyDataData, reciprocal=true, i.e. division (branch 2) ************\n";
934 
935  int c=5, p=9, d1=7, d2=13;
936 
937  FieldContainer<double> in_p(p);
938  FieldContainer<double> in_p_d(p, d1);
939  FieldContainer<double> in_p_d_d(p, d1, d2);
940  FieldContainer<double> in_c_p(c, p);
941  FieldContainer<double> in_c_p_d(c, p, d1);
942  FieldContainer<double> in_c_p_d_d(c, p, d1, d2);
943  FieldContainer<double> data_c_p(c, p);
944  FieldContainer<double> datainv_c_p(c, p);
945  FieldContainer<double> data_c_1(c, 1);
946  FieldContainer<double> datainv_c_1(c, 1);
947  FieldContainer<double> data_c_p_one(c, p);
948  FieldContainer<double> data_c_1_one(c, 1);
949  FieldContainer<double> out_c_p(c, p);
950  FieldContainer<double> outi_c_p(c, p);
951  FieldContainer<double> out_c_p_d(c, p, d1);
952  FieldContainer<double> outi_c_p_d(c, p, d1);
953  FieldContainer<double> out_c_p_d_d(c, p, d1, d2);
954  FieldContainer<double> outi_c_p_d_d(c, p, d1, d2);
955  double zero = INTREPID_TOL*10000.0;
956 
957  // fill with random numbers
958  for (int i=0; i<in_p.size(); i++) {
959  in_p[i] = Teuchos::ScalarTraits<double>::random();
960  }
961  for (int i=0; i<in_p_d.size(); i++) {
962  in_p_d[i] = Teuchos::ScalarTraits<double>::random();
963  }
964  for (int i=0; i<in_p_d_d.size(); i++) {
965  in_p_d_d[i] = Teuchos::ScalarTraits<double>::random();
966  }
967  for (int i=0; i<data_c_p.size(); i++) {
968  data_c_p[i] = Teuchos::ScalarTraits<double>::random();
969  datainv_c_p[i] = 1.0 / data_c_p[i];
970  data_c_p_one[i] = 1.0;
971  }
972  for (int i=0; i<data_c_1.size(); i++) {
973  data_c_1[i] = Teuchos::ScalarTraits<double>::random();
974  datainv_c_1[i] = 1.0 / data_c_1[i];
975  data_c_1_one[i] = 1.0;
976  }
977 
978  art::scalarMultiplyDataData<double>(out_c_p, data_c_p, in_p, true);
979  art::scalarMultiplyDataData<double>(outi_c_p, datainv_c_p, out_c_p, true);
980  art::scalarMultiplyDataData<double>(in_c_p, data_c_p_one, in_p);
981  rst::subtract(&outi_c_p[0], &in_c_p[0], outi_c_p.size());
982  if (rst::vectorNorm(&outi_c_p[0], outi_c_p.size(), NORM_ONE) > zero) {
983  *outStream << "\n\nINCORRECT scalarMultiplyDataData (1): check scalar inverse property\n\n";
984  errorFlag = -1000;
985  }
986  art::scalarMultiplyDataData<double>(out_c_p_d, data_c_p, in_p_d, true);
987  art::scalarMultiplyDataData<double>(outi_c_p_d, datainv_c_p, out_c_p_d, true);
988  art::scalarMultiplyDataData<double>(in_c_p_d, data_c_p_one, in_p_d);
989  rst::subtract(&outi_c_p_d[0], &in_c_p_d[0], outi_c_p_d.size());
990  if (rst::vectorNorm(&outi_c_p_d[0], outi_c_p_d.size(), NORM_ONE) > zero) {
991  *outStream << "\n\nINCORRECT scalarMultiplyDataData (2): check scalar inverse property\n\n";
992  errorFlag = -1000;
993  }
994  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_p, in_p_d_d, true);
995  art::scalarMultiplyDataData<double>(outi_c_p_d_d, datainv_c_p, out_c_p_d_d, true);
996  art::scalarMultiplyDataData<double>(in_c_p_d_d, data_c_p_one, in_p_d_d);
997  rst::subtract(&outi_c_p_d_d[0], &in_c_p_d_d[0], outi_c_p_d_d.size());
998  if (rst::vectorNorm(&outi_c_p_d_d[0], outi_c_p_d_d.size(), NORM_ONE) > zero) {
999  *outStream << "\n\nINCORRECT scalarMultiplyDataData (3): check scalar inverse property\n\n";
1000  errorFlag = -1000;
1001  }
1002  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_1, in_p_d_d, true);
1003  art::scalarMultiplyDataData<double>(outi_c_p_d_d, datainv_c_1, out_c_p_d_d, true);
1004  art::scalarMultiplyDataData<double>(in_c_p_d_d, data_c_p_one, in_p_d_d);
1005  rst::subtract(&outi_c_p_d_d[0], &in_c_p_d_d[0], outi_c_p_d_d.size());
1006  if (rst::vectorNorm(&outi_c_p_d_d[0], outi_c_p_d_d.size(), NORM_ONE) > zero) {
1007  *outStream << "\n\nINCORRECT scalarMultiplyDataData (4): check scalar inverse property\n\n";
1008  errorFlag = -1000;
1009  }
1010 
1011  // fill with constants
1012  for (int i=0; i<in_p_d_d.size(); i++) {
1013  in_p_d_d[i] = 1.0;
1014  }
1015  for (int i=0; i<data_c_p.size(); i++) {
1016  data_c_p[i] = 5.0;
1017  }
1018  for (int i=0; i<data_c_1.size(); i++) {
1019  data_c_1[i] = 5.0;
1020  }
1021  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_p, in_p_d_d, true);
1022  if (std::abs(rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) - (1.0/data_c_p[0])*in_p_d_d[0]*c*p*d1*d2)/rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) > zero) {
1023  *outStream << "\n\nINCORRECT scalarMultiplyDataData (5): check result: "
1024  << rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) << " != "
1025  << (1.0/data_c_p[0])*in_p_d_d[0]*c*p*d1*d2 << "\n\n";
1026  errorFlag = -1000;
1027  }
1028  art::scalarMultiplyDataData<double>(out_c_p_d_d, data_c_1, in_p_d_d, true);
1029  if (std::abs(rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) - (1.0/data_c_1[0])*in_p_d_d[0]*c*p*d1*d2)/rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) > zero) {
1030  *outStream << "\n\nINCORRECT scalarMultiplyDataData (6): check result: "
1031  << rst::vectorNorm(&out_c_p_d_d[0], out_c_p_d_d.size(), NORM_ONE) << " != "
1032  << (1.0/data_c_1[0])*in_p_d_d[0]*c*p*d1*d2 << "\n\n";
1033  errorFlag = -1000;
1034  }
1035  } // end scope
1036 
1037  /******************************************/
1038  *outStream << "\n";
1039  }
1040  catch (std::logic_error err) {
1041  *outStream << "UNEXPECTED ERROR !!! ----------------------------------------------------------\n";
1042  *outStream << err.what() << '\n';
1043  *outStream << "-------------------------------------------------------------------------------" << "\n\n";
1044  errorFlag = -1000;
1045  };
1046 
1047 
1048  if (errorFlag != 0)
1049  std::cout << "End Result: TEST FAILED\n";
1050  else
1051  std::cout << "End Result: TEST PASSED\n";
1052 
1053  // reset format state of std::cout
1054  std::cout.copyfmt(oldFormatState);
1055 
1056  return errorFlag;
1057 }
Implementation of basic linear algebra functionality in Euclidean space.
int main(int argc, char *argv[])
outdated tests for orthogonal bases
Definition: test_02.cpp:63
Header file for utility class to provide multidimensional containers.
Header file for utility class to provide array tools, such as tensor contractions, etc.
static void scalarMultiplyDataData(ArrayOutData &outputData, const ArrayInDataLeft &inputDataLeft, const ArrayInDataRight &inputDataRight, const bool reciprocal=false)
There are two use cases: (1) multiplies a rank-2, 3, or 4 container inputDataRight with dimensions (C...
Header file for classes providing basic linear algebra functionality in 1D, 2D and 3D...
static void scalarMultiplyDataField(ArrayOutFields &outputFields, const ArrayInData &inputData, const ArrayInFields &inputFields, const bool reciprocal=false)
There are two use cases: (1) multiplies a rank-3, 4, or 5 container inputFields with dimensions (C...