Intrepid
Intrepid_ArrayToolsDefScalar.hpp
Go to the documentation of this file.
1 #ifndef INTREPID_ARRAYTOOLSDEFSCALAR_HPP
2 #define INTREPID_ARRAYTOOLSDEFSCALAR_HPP
3 // @HEADER
4 // ************************************************************************
5 //
6 // Intrepid Package
7 // Copyright (2007) Sandia Corporation
8 //
9 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
10 // license for use of this work by or on behalf of the U.S. Government.
11 //
12 // Redistribution and use in source and binary forms, with or without
13 // modification, are permitted provided that the following conditions are
14 // met:
15 //
16 // 1. Redistributions of source code must retain the above copyright
17 // notice, this list of conditions and the following disclaimer.
18 //
19 // 2. Redistributions in binary form must reproduce the above copyright
20 // notice, this list of conditions and the following disclaimer in the
21 // documentation and/or other materials provided with the distribution.
22 //
23 // 3. Neither the name of the Corporation nor the names of the
24 // contributors may be used to endorse or promote products derived from
25 // this software without specific prior written permission.
26 //
27 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
28 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
31 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
34 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
35 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
36 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
37 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // Questions? Contact Pavel Bochev (pbboche@sandia.gov)
40 // Denis Ridzal (dridzal@sandia.gov), or
41 // Kara Peterson (kjpeter@sandia.gov)
42 //
43 // ************************************************************************
44 // @HEADER
45 
52 namespace Intrepid {
53 //Kokkos Only Implementation of scalarMultiplyDataData
54 
55 
56 /* template<class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight>
57  void ArrayTools::scalarMultiplyDataDataTemp( ArrayOutData& outputData,
58  ArrayInDataLeft& inputDataLeft,
59  ArrayInDataRight& inputDataRight,
60  const bool reciprocal){
61  ArrayTools::scalarMultiplyDataData2<ArrayOutData,ArrayInDataLeft,ArrayInDataRight, void, void, Rank<ArrayInDataRight>::value,Rank<ArrayOutData>::value>(outputData, inputDataLeft, inputDataRight,reciprocal);
62 
63  }
64  #ifdef INTREPID_OLD_KOKKOS_CODE
65  template<class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight, class Layout, class MemorySpace>
66  void ArrayTools::scalarMultiplyDataDataTemp(Kokkos::View<ArrayOutData,Layout,MemorySpace> &outputData,
67  Kokkos::View<ArrayInDataLeft,Layout,MemorySpace> &inputDataLeft,
68  Kokkos::View<ArrayInDataRight,Layout,MemorySpace> &inputDataRight,
69  const bool reciprocal){
70 
71  ArrayTools::scalarMultiplyDataData2Kokkos<Kokkos::View<ArrayOutData,Layout,MemorySpace>, Kokkos::View<ArrayInDataLeft,Layout,MemorySpace> , Kokkos::View<ArrayInDataRight,Layout,MemorySpace> , Layout, MemorySpace, Rank<Kokkos::View<ArrayInDataRight,Layout,MemorySpace> >::value,Rank<Kokkos::View<ArrayOutData,Layout,MemorySpace> >::value>(outputData, inputDataLeft, inputDataRight,reciprocal);
72 
73  }
74 #endif */
75 
76 template<class Scalar, class ArrayOutFields, class ArrayInData, class ArrayInFields>
77 void ArrayTools::scalarMultiplyDataField(ArrayOutFields & outputFields,
78  const ArrayInData & inputData,
79  const ArrayInFields & inputFields,
80  const bool reciprocal) {
81 #ifdef HAVE_INTREPID_DEBUG
82  TEUCHOS_TEST_FOR_EXCEPTION( (getrank(inputData) != 2), std::invalid_argument,
83  ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input data container must have rank 2.");
84  if (getrank(outputFields) <= getrank(inputFields)) {
85  TEUCHOS_TEST_FOR_EXCEPTION( ( (getrank(inputFields) < 3) || (getrank(inputFields) > 5) ), std::invalid_argument,
86  ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input fields container must have rank 3, 4, or 5.");
87  TEUCHOS_TEST_FOR_EXCEPTION( (getrank(outputFields) != getrank(inputFields)), std::invalid_argument,
88  ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input and output fields containers must have the same rank.");
89  TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(0) != inputData.dimension(0) ), std::invalid_argument,
90  ">>> ERROR (ArrayTools::scalarMultiplyDataField): Zeroth dimensions (number of integration domains) of the fields and data input containers must agree!");
91  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputFields.dimension(2) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
92  ">>> ERROR (ArrayTools::scalarMultiplyDataField): Second dimension of the fields input container and first dimension of data input container (number of integration points) must agree or first data dimension must be 1!");
93  for (size_t i=0; i<getrank(inputFields); i++) {
94  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataField): Dimension ";
95  errmsg += (char)(48+i);
96  errmsg += " of the input and output fields containers must agree!";
97  TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i)), std::invalid_argument, errmsg );
98  }
99  }
100  else {
101  TEUCHOS_TEST_FOR_EXCEPTION( ( (getrank(inputFields) < 2) || (getrank(inputFields) > 4) ), std::invalid_argument,
102  ">>> ERROR (ArrayTools::scalarMultiplyDataField): Input fields container must have rank 2, 3, or 4.");
103  TEUCHOS_TEST_FOR_EXCEPTION( (getrank(outputFields) != getrank(inputFields)+1), std::invalid_argument,
104  ">>> ERROR (ArrayTools::scalarMultiplyDataField): The rank of the input fields container must be one less than the rank of the output fields container.");
105  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputFields.dimension(1) != inputData.dimension(1)) && (inputData.dimension(1) != 1) ), std::invalid_argument,
106  ">>> ERROR (ArrayTools::scalarMultiplyDataField): First dimensions of fields input container and data input container (number of integration points) must agree or first data dimension must be 1!");
107  TEUCHOS_TEST_FOR_EXCEPTION( ( inputData.dimension(0) != outputFields.dimension(0) ), std::invalid_argument,
108  ">>> ERROR (ArrayTools::scalarMultiplyDataField): Zeroth dimensions of fields output container and data input containers (number of integration domains) must agree!");
109  for (size_t i=0; i<getrank(inputFields); i++) {
110  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataField): Dimensions ";
111  errmsg += (char)(48+i);
112  errmsg += " and ";
113  errmsg += (char)(48+i+1);
114  errmsg += " of the input and output fields containers must agree!";
115  TEUCHOS_TEST_FOR_EXCEPTION( (inputFields.dimension(i) != outputFields.dimension(i+1)), std::invalid_argument, errmsg );
116  }
117  }
118 #endif
119  ArrayWrapper<Scalar,ArrayOutFields, Rank<ArrayOutFields >::value, false>outputFieldsWrap(outputFields);
120  ArrayWrapper<Scalar,ArrayInData, Rank<ArrayInData >::value, true>inputDataWrap(inputData);
121  ArrayWrapper<Scalar,ArrayInFields, Rank<ArrayInFields >::value,true>inputFieldsWrap(inputFields);
122 
123  // get sizes
124  size_t invalRank = getrank(inputFields);
125  size_t outvalRank = getrank(outputFields);
126  int numCells = outputFields.dimension(0);
127  int numFields = outputFields.dimension(1);
128  int numPoints = outputFields.dimension(2);
129  int numDataPoints = inputData.dimension(1);
130  int dim1Tens = 0;
131  int dim2Tens = 0;
132  if (outvalRank > 3) {
133  dim1Tens = outputFields.dimension(3);
134  if (outvalRank > 4) {
135  dim2Tens = outputFields.dimension(4);
136  }
137  }
138 
139  if (outvalRank == invalRank) {
140 
141  if (numDataPoints != 1) { // nonconstant data
142  switch(invalRank) {
143  case 3: {
144  if (reciprocal) {
145  for(int cl = 0; cl < numCells; cl++) {
146  for(int bf = 0; bf < numFields; bf++) {
147  for(int pt = 0; pt < numPoints; pt++) {
148  outputFieldsWrap(cl, bf, pt) = inputFieldsWrap(cl, bf, pt)/inputDataWrap(cl, pt);
149  } // P-loop
150  } // F-loop
151  } // C-loop
152  }
153  else {
154 
155 
156  for(int cl = 0; cl < numCells; cl++) {
157  for(int bf = 0; bf < numFields; bf++) {
158  for(int pt = 0; pt < numPoints; pt++) {
159  outputFieldsWrap(cl, bf, pt) = inputFieldsWrap(cl, bf, pt)*inputDataWrap(cl, pt);
160  } // P-loop
161  } // F-loop
162  } // C-loop
163 
164  }
165  }// case 3
166  break;
167 
168  case 4: {
169  if (reciprocal) {
170  for(int cl = 0; cl < numCells; cl++) {
171  for(int bf = 0; bf < numFields; bf++) {
172  for(int pt = 0; pt < numPoints; pt++) {
173  for( int iVec = 0; iVec < dim1Tens; iVec++) {
174  outputFieldsWrap(cl, bf, pt, iVec) = inputFieldsWrap(cl, bf, pt, iVec)/inputDataWrap(cl, pt);
175  } // D1-loop
176  } // P-loop
177  } // F-loop
178  } // C-loop
179  }
180  else {
181  for(int cl = 0; cl < numCells; cl++) {
182  for(int bf = 0; bf < numFields; bf++) {
183  for(int pt = 0; pt < numPoints; pt++) {
184  for( int iVec = 0; iVec < dim1Tens; iVec++) {
185  outputFieldsWrap(cl, bf, pt, iVec) = inputFieldsWrap(cl, bf, pt, iVec)*inputDataWrap(cl, pt);
186  } // D1-loop
187  } // P-loop
188  } // F-loop
189  } // C-loop
190  }
191  }// case 4
192  break;
193 
194  case 5: {
195  if (reciprocal) {
196  for(int cl = 0; cl < numCells; cl++) {
197  for(int bf = 0; bf < numFields; bf++) {
198  for(int pt = 0; pt < numPoints; pt++) {
199  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
200  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
201  outputFieldsWrap(cl, bf, pt, iTens1, iTens2) = inputFieldsWrap(cl, bf, pt, iTens1, iTens2)/inputDataWrap(cl, pt);
202  } // D2-loop
203  } // D1-loop
204  } // F-loop
205  } // P-loop
206  } // C-loop
207  }
208  else {
209  for(int cl = 0; cl < numCells; cl++) {
210  for(int bf = 0; bf < numFields; bf++) {
211  for(int pt = 0; pt < numPoints; pt++) {
212  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
213  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
214  outputFieldsWrap(cl, bf, pt, iTens1, iTens2) = inputFieldsWrap(cl, bf, pt, iTens1, iTens2)*inputDataWrap(cl, pt);
215  } // D2-loop
216  } // D1-loop
217  } // F-loop
218  } // P-loop
219  } // C-loop
220  }
221  }// case 5
222  break;
223 
224  default:
225  TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 3) || (invalRank == 4) || (invalRank == 5) ), std::invalid_argument,
226  ">>> ERROR (ArrayTools::scalarMultiplyDataField): This branch of the method is defined only for rank-3,4 or 5 containers.");
227  }// invalRank
228 
229  }
230  else { //constant data
231 
232  switch(invalRank) {
233  case 3: {
234  if (reciprocal) {
235  for(int cl = 0; cl < numCells; cl++) {
236  for(int bf = 0; bf < numFields; bf++) {
237  for(int pt = 0; pt < numPoints; pt++) {
238  outputFieldsWrap(cl, bf, pt) = inputFieldsWrap(cl, bf, pt)/inputDataWrap(cl, 0);
239  } // P-loop
240  } // F-loop
241  } // C-loop
242  }
243  else {
244  for(int cl = 0; cl < numCells; cl++) {
245  for(int bf = 0; bf < numFields; bf++) {
246  for(int pt = 0; pt < numPoints; pt++) {
247  outputFieldsWrap(cl, bf, pt) = inputFieldsWrap(cl, bf, pt)*inputDataWrap(cl, 0);
248  } // P-loop
249  } // F-loop
250  } // C-loop
251  }
252  }// case 3
253  break;
254 
255  case 4: {
256  if (reciprocal) {
257  for(int cl = 0; cl < numCells; cl++) {
258  for(int bf = 0; bf < numFields; bf++) {
259  for(int pt = 0; pt < numPoints; pt++) {
260  for( int iVec = 0; iVec < dim1Tens; iVec++) {
261  outputFieldsWrap(cl, bf, pt, iVec) = inputFieldsWrap(cl, bf, pt, iVec)/inputDataWrap(cl, 0);
262  } // D1-loop
263  } // P-loop
264  } // F-loop
265  } // C-loop
266  }
267  else {
268  for(int cl = 0; cl < numCells; cl++) {
269  for(int bf = 0; bf < numFields; bf++) {
270  for(int pt = 0; pt < numPoints; pt++) {
271  for( int iVec = 0; iVec < dim1Tens; iVec++) {
272  outputFieldsWrap(cl, bf, pt, iVec) = inputFieldsWrap(cl, bf, pt, iVec)*inputDataWrap(cl, 0);
273  } // D1-loop
274  } // P-loop
275  } // F-loop
276  } // C-loop
277  }
278  }// case 4
279  break;
280 
281  case 5: {
282  if (reciprocal) {
283  for(int cl = 0; cl < numCells; cl++) {
284  for(int bf = 0; bf < numFields; bf++) {
285  for(int pt = 0; pt < numPoints; pt++) {
286  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
287  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
288  outputFieldsWrap(cl, bf, pt, iTens1, iTens2) = inputFieldsWrap(cl, bf, pt, iTens1, iTens2)/inputDataWrap(cl, 0);
289  } // D2-loop
290  } // D1-loop
291  } // F-loop
292  } // P-loop
293  } // C-loop
294  }
295  else {
296  for(int cl = 0; cl < numCells; cl++) {
297  for(int bf = 0; bf < numFields; bf++) {
298  for(int pt = 0; pt < numPoints; pt++) {
299  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
300  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
301  outputFieldsWrap(cl, bf, pt, iTens1, iTens2) = inputFieldsWrap(cl, bf, pt, iTens1, iTens2)*inputDataWrap(cl, 0);
302  } // D2-loop
303  } // D1-loop
304  } // F-loop
305  } // P-loop
306  } // C-loop
307  }
308  }// case 5
309  break;
310 
311  default:
312  TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 3) || (invalRank == 4) || (invalRank == 5) ), std::invalid_argument,
313  ">>> ERROR (ArrayTools::scalarMultiplyDataField): This branch of the method is defined only for rank-3, 4 or 5 input containers.");
314 
315  } // invalRank
316  } // numDataPoints
317 
318  }
319  else {
320 
321  if (numDataPoints != 1) { // nonconstant data
322 
323  switch(invalRank) {
324  case 2: {
325  if (reciprocal) {
326  for(int cl = 0; cl < numCells; cl++) {
327  for(int bf = 0; bf < numFields; bf++) {
328  for(int pt = 0; pt < numPoints; pt++) {
329  outputFieldsWrap(cl, bf, pt) = inputFieldsWrap(bf, pt)/inputDataWrap(cl, pt);
330  } // P-loop
331  } // F-loop
332  } // C-loop
333  }
334  else {
335  for(int cl = 0; cl < numCells; cl++) {
336  for(int bf = 0; bf < numFields; bf++) {
337  for(int pt = 0; pt < numPoints; pt++) {
338  outputFieldsWrap(cl, bf, pt) = inputFieldsWrap(bf, pt)*inputDataWrap(cl, pt);
339  } // P-loop
340  } // F-loop
341  } // C-loop
342  }
343  }// case 2
344  break;
345 
346  case 3: {
347  if (reciprocal) {
348  for(int cl = 0; cl < numCells; cl++) {
349  for(int bf = 0; bf < numFields; bf++) {
350  for(int pt = 0; pt < numPoints; pt++) {
351  for( int iVec = 0; iVec < dim1Tens; iVec++) {
352  outputFieldsWrap(cl, bf, pt, iVec) = inputFieldsWrap(bf, pt, iVec)/inputDataWrap(cl, pt);
353  } // D1-loop
354  } // P-loop
355  } // F-loop
356  } // C-loop
357  }
358  else {
359  for(int cl = 0; cl < numCells; cl++) {
360  for(int bf = 0; bf < numFields; bf++) {
361  for(int pt = 0; pt < numPoints; pt++) {
362  for( int iVec = 0; iVec < dim1Tens; iVec++) {
363  outputFieldsWrap(cl, bf, pt, iVec) = inputFieldsWrap(bf, pt, iVec)*inputDataWrap(cl, pt);
364  } // D1-loop
365  } // P-loop
366  } // F-loop
367  } // C-loop
368  }
369  }// case 3
370  break;
371 
372  case 4: {
373  if (reciprocal) {
374  for(int cl = 0; cl < numCells; cl++) {
375  for(int bf = 0; bf < numFields; bf++) {
376  for(int pt = 0; pt < numPoints; pt++) {
377  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
378  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
379  outputFieldsWrap(cl, bf, pt, iTens1, iTens2) = inputFieldsWrap(bf, pt, iTens1, iTens2)/inputDataWrap(cl, pt);
380  } // D2-loop
381  } // D1-loop
382  } // F-loop
383  } // P-loop
384  } // C-loop
385  }
386  else {
387  for(int cl = 0; cl < numCells; cl++) {
388  for(int bf = 0; bf < numFields; bf++) {
389  for(int pt = 0; pt < numPoints; pt++) {
390  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
391  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
392  outputFieldsWrap(cl, bf, pt, iTens1, iTens2) = inputFieldsWrap(bf, pt, iTens1, iTens2)*inputDataWrap(cl, pt);
393  } // D2-loop
394  } // D1-loop
395  } // F-loop
396  } // P-loop
397  } // C-loop
398  }
399  }// case 4
400  break;
401 
402  default:
403  TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
404  ">>> ERROR (ArrayTools::scalarMultiplyDataField): This branch of the method is defined only for rank-2, 3 or 4 input containers.");
405  }// invalRank
406 
407  }
408  else { //constant data
409 
410  switch(invalRank) {
411  case 2: {
412  if (reciprocal) {
413  for(int cl = 0; cl < numCells; cl++) {
414  for(int bf = 0; bf < numFields; bf++) {
415  for(int pt = 0; pt < numPoints; pt++) {
416  outputFieldsWrap(cl, bf, pt) = inputFieldsWrap(bf, pt)/inputDataWrap(cl, 0);
417  } // P-loop
418  } // F-loop
419  } // C-loop
420  }
421  else {
422  for(int cl = 0; cl < numCells; cl++) {
423  for(int bf = 0; bf < numFields; bf++) {
424  for(int pt = 0; pt < numPoints; pt++) {
425  outputFieldsWrap(cl, bf, pt) = inputFieldsWrap(bf, pt)*inputDataWrap(cl, 0);
426  } // P-loop
427  } // F-loop
428  } // C-loop
429  }
430  }// case 2
431  break;
432 
433  case 3: {
434  if (reciprocal) {
435  for(int cl = 0; cl < numCells; cl++) {
436  for(int bf = 0; bf < numFields; bf++) {
437  for(int pt = 0; pt < numPoints; pt++) {
438  for( int iVec = 0; iVec < dim1Tens; iVec++) {
439  outputFieldsWrap(cl, bf, pt, iVec) = inputFieldsWrap(bf, pt, iVec)/inputDataWrap(cl, 0);
440  } // D1-loop
441  } // P-loop
442  } // F-loop
443  } // C-loop
444  }
445  else {
446  for(int cl = 0; cl < numCells; cl++) {
447  for(int bf = 0; bf < numFields; bf++) {
448  for(int pt = 0; pt < numPoints; pt++) {
449  for( int iVec = 0; iVec < dim1Tens; iVec++) {
450  outputFieldsWrap(cl, bf, pt, iVec) = inputFieldsWrap(bf, pt, iVec)*inputDataWrap(cl, 0);
451  } // D1-loop
452  } // P-loop
453  } // F-loop
454  } // C-loop
455  }
456  }// case 3
457  break;
458 
459  case 4: {
460  if (reciprocal) {
461  for(int cl = 0; cl < numCells; cl++) {
462  for(int bf = 0; bf < numFields; bf++) {
463  for(int pt = 0; pt < numPoints; pt++) {
464  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
465  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
466  outputFieldsWrap(cl, bf, pt, iTens1, iTens2) = inputFieldsWrap(bf, pt, iTens1, iTens2)/inputDataWrap(cl, 0);
467  } // D2-loop
468  } // D1-loop
469  } // F-loop
470  } // P-loop
471  } // C-loop
472  }
473  else {
474  for(int cl = 0; cl < numCells; cl++) {
475  for(int bf = 0; bf < numFields; bf++) {
476  for(int pt = 0; pt < numPoints; pt++) {
477  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
478  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
479  outputFieldsWrap(cl, bf, pt, iTens1, iTens2) = inputFieldsWrap(bf, pt, iTens1, iTens2)*inputDataWrap(cl, 0);
480  } // D2-loop
481  } // D1-loop
482  } // F-loop
483  } // P-loop
484  } // C-loop
485  }
486  }// case 4
487  break;
488 
489  default:
490  TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 3) ), std::invalid_argument,
491  ">>> ERROR (ArrayTools::scalarMultiplyDataField): This branch of the method is defined only for rank-2, 3 or 4 input containers.");
492 
493  } // invalRank
494  } // numDataPoints
495 
496  } // end if (outvalRank = invalRank)
497 
498 } // scalarMultiplyDataField
499 
500 template<class Scalar, class ArrayOutData, class ArrayInDataLeft, class ArrayInDataRight>
501 void ArrayTools::scalarMultiplyDataData(ArrayOutData & outputData,
502  const ArrayInDataLeft & inputDataLeft,
503  const ArrayInDataRight & inputDataRight,
504  const bool reciprocal) {
505 
506 #ifdef HAVE_INTREPID_DEBUG
507  TEUCHOS_TEST_FOR_EXCEPTION( (getrank(inputDataLeft) != 2), std::invalid_argument,
508  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Left input data container must have rank 2.");
509  if (getrank(outputData) <= getrank(inputDataRight)) {
510  TEUCHOS_TEST_FOR_EXCEPTION( ( (getrank(inputDataRight) < 2) || (getrank(inputDataRight) > 4) ), std::invalid_argument,
511  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 2, 3, or 4.");
512  TEUCHOS_TEST_FOR_EXCEPTION( (getrank(outputData) != getrank(inputDataRight)), std::invalid_argument,
513  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input and output data containers must have the same rank.");
514  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(0) != inputDataLeft.dimension(0) ), std::invalid_argument,
515  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions (number of integration domains) of the left and right data input containers must agree!");
516  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(1) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
517  ">>> ERROR (ArrayTools::scalarMultiplyDataData): First dimensions of the left and right data input containers (number of integration points) must agree or first dimension of the left data input container must be 1!");
518  for (size_t i=0; i<getrank(inputDataRight); i++) {
519  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimension ";
520  errmsg += (char)(48+i);
521  errmsg += " of the right input and output data containers must agree!";
522  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i)), std::invalid_argument, errmsg );
523  }
524  }
525  else {
526  TEUCHOS_TEST_FOR_EXCEPTION( ( (getrank(inputDataRight) < 1) || (getrank(inputDataRight) > 3) ), std::invalid_argument,
527  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Right input data container must have rank 1, 2, or 3.");
528  TEUCHOS_TEST_FOR_EXCEPTION( (getrank(outputData) != getrank(inputDataRight)+1), std::invalid_argument,
529  ">>> ERROR (ArrayTools::scalarMultiplyDataData): The rank of the right input data container must be one less than the rank of the output data container.");
530  TEUCHOS_TEST_FOR_EXCEPTION( ( (inputDataRight.dimension(0) != inputDataLeft.dimension(1)) && (inputDataLeft.dimension(1) != 1) ), std::invalid_argument,
531  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimension of the right input data container and first dimension of the left data input container (number of integration points) must agree or first dimension of the left data input container must be 1!");
532  TEUCHOS_TEST_FOR_EXCEPTION( ( inputDataLeft.dimension(0) != outputData.dimension(0) ), std::invalid_argument,
533  ">>> ERROR (ArrayTools::scalarMultiplyDataData): Zeroth dimensions of data output and left data input containers (number of integration domains) must agree!");
534  for (size_t i=0; i<getrank(inputDataRight); i++) {
535  std::string errmsg = ">>> ERROR (ArrayTools::scalarMultiplyDataData): Dimensions ";
536  errmsg += (char)(48+i);
537  errmsg += " and ";
538  errmsg += (char)(48+i+1);
539  errmsg += " of the right input and output data containers must agree!";
540  TEUCHOS_TEST_FOR_EXCEPTION( (inputDataRight.dimension(i) != outputData.dimension(i+1)), std::invalid_argument, errmsg );
541  }
542  }
543 #endif
544 
545 
546  ArrayWrapper<Scalar,ArrayOutData, Rank<ArrayOutData >::value, false>outputDataWrap(outputData);
547  ArrayWrapper<Scalar,ArrayInDataLeft, Rank<ArrayInDataLeft >::value, true>inputDataLeftWrap(inputDataLeft);
548  ArrayWrapper<Scalar,ArrayInDataRight, Rank<ArrayInDataRight >::value,true>inputDataRightWrap(inputDataRight);
549 
550 
551  // get sizes
552  size_t invalRank = getrank(inputDataRight);
553  size_t outvalRank = getrank(outputData);
554  int numCells = outputData.dimension(0);
555  int numPoints = outputData.dimension(1);
556  int numDataPoints = inputDataLeft.dimension(1);
557  int dim1Tens = 0;
558  int dim2Tens = 0;
559  if (outvalRank > 2) {
560  dim1Tens = outputData.dimension(2);
561  if (outvalRank > 3) {
562  dim2Tens = outputData.dimension(3);
563  }
564  }
565 
566  if (outvalRank == invalRank) {
567 
568  if (numDataPoints != 1) { // nonconstant data
569 
570  switch(invalRank) {
571  case 2: {
572  if (reciprocal) {
573  for(int cl = 0; cl < numCells; cl++) {
574  for(int pt = 0; pt < numPoints; pt++) {
575  outputDataWrap(cl, pt) = inputDataRightWrap(cl, pt)/inputDataLeftWrap(cl, pt);
576  } // P-loop
577  } // C-loop
578  }
579  else {
580  for(int cl = 0; cl < numCells; cl++) {
581  for(int pt = 0; pt < numPoints; pt++) {
582  outputDataWrap(cl, pt) = inputDataRightWrap(cl, pt)*inputDataLeftWrap(cl, pt);
583  } // P-loop
584  } // C-loop
585  }
586  }// case 2
587  break;
588 
589  case 3: {
590  if (reciprocal) {
591  for(int cl = 0; cl < numCells; cl++) {
592  for(int pt = 0; pt < numPoints; pt++) {
593  for( int iVec = 0; iVec < dim1Tens; iVec++) {
594  outputDataWrap(cl, pt, iVec) = inputDataRightWrap(cl, pt, iVec)/inputDataLeftWrap(cl, pt);
595  } // D1-loop
596  } // P-loop
597  } // C-loop
598  }
599  else {
600  for(int cl = 0; cl < numCells; cl++) {
601  for(int pt = 0; pt < numPoints; pt++) {
602  for( int iVec = 0; iVec < dim1Tens; iVec++) {
603  outputDataWrap(cl, pt, iVec) = inputDataRightWrap(cl, pt, iVec)*inputDataLeftWrap(cl, pt);
604  } // D1-loop
605  } // P-loop
606  } // C-loop
607  }
608  }// case 3
609  break;
610 
611  case 4: {
612  if (reciprocal) {
613  for(int cl = 0; cl < numCells; cl++) {
614  for(int pt = 0; pt < numPoints; pt++) {
615  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
616  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
617  outputDataWrap(cl, pt, iTens1, iTens2) = inputDataRightWrap(cl, pt, iTens1, iTens2)/inputDataLeftWrap(cl, pt);
618  } // D2-loop
619  } // D1-loop
620  } // P-loop
621  } // C-loop
622  }
623  else {
624  for(int cl = 0; cl < numCells; cl++) {
625  for(int pt = 0; pt < numPoints; pt++) {
626  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
627  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
628  outputDataWrap(cl, pt, iTens1, iTens2) = inputDataRightWrap(cl, pt, iTens1, iTens2)*inputDataLeftWrap(cl, pt);
629  } // D2-loop
630  } // D1-loop
631  } // P-loop
632  } // C-loop
633  }
634  }// case 4
635  break;
636 
637  default:
638  TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
639  ">>> ERROR (ArrayTools::scalarMultiplyDataData): This branch of the method is defined only for rank-2, 3 or 4 containers.");
640  }// invalRank
641 
642  }
643  else { // constant left data
644 
645  switch(invalRank) {
646  case 2: {
647  if (reciprocal) {
648  for(int cl = 0; cl < numCells; cl++) {
649  for(int pt = 0; pt < numPoints; pt++) {
650  outputDataWrap(cl, pt) = inputDataRightWrap(cl, pt)/inputDataLeftWrap(cl, 0);
651  } // P-loop
652  } // C-loop
653  }
654  else {
655  for(int cl = 0; cl < numCells; cl++) {
656  for(int pt = 0; pt < numPoints; pt++) {
657  outputDataWrap(cl, pt) = inputDataRightWrap(cl, pt)*inputDataLeftWrap(cl, 0);
658  } // P-loop
659  } // C-loop
660  }
661  }// case 2
662  break;
663 
664  case 3: {
665  if (reciprocal) {
666  for(int cl = 0; cl < numCells; cl++) {
667  for(int pt = 0; pt < numPoints; pt++) {
668  for( int iVec = 0; iVec < dim1Tens; iVec++) {
669  outputDataWrap(cl, pt, iVec) = inputDataRightWrap(cl, pt, iVec)/inputDataLeftWrap(cl, 0);
670  } // D1-loop
671  } // P-loop
672  } // C-loop
673  }
674  else {
675  for(int cl = 0; cl < numCells; cl++) {
676  for(int pt = 0; pt < numPoints; pt++) {
677  for( int iVec = 0; iVec < dim1Tens; iVec++) {
678  outputDataWrap(cl, pt, iVec) = inputDataRightWrap(cl, pt, iVec)*inputDataLeftWrap(cl, 0);
679  } // D1-loop
680  } // P-loop
681  } // C-loop
682  }
683  }// case 3
684  break;
685 
686  case 4: {
687  if (reciprocal) {
688  for(int cl = 0; cl < numCells; cl++) {
689  for(int pt = 0; pt < numPoints; pt++) {
690  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
691  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
692  outputDataWrap(cl, pt, iTens1, iTens2) = inputDataRightWrap(cl, pt, iTens1, iTens2)/inputDataLeftWrap(cl, 0);
693  } // D2-loop
694  } // D1-loop
695  } // P-loop
696  } // C-loop
697  }
698  else {
699  for(int cl = 0; cl < numCells; cl++) {
700  for(int pt = 0; pt < numPoints; pt++) {
701  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
702  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
703  outputDataWrap(cl, pt, iTens1, iTens2) = inputDataRightWrap(cl, pt, iTens1, iTens2)*inputDataLeftWrap(cl, 0);
704  } // D2-loop
705  } // D1-loop
706  } // P-loop
707  } // C-loop
708  }
709  }// case 4
710  break;
711 
712  default:
713  TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 2) || (invalRank == 3) || (invalRank == 4) ), std::invalid_argument,
714  ">>> ERROR (ArrayTools::scalarMultiplyDataData): This branch of the method is defined only for rank-2, 3 or 4 input containers.");
715 
716  } // invalRank
717  } // numDataPoints
718 
719  }
720  else {
721 
722  if (numDataPoints != 1) { // nonconstant data
723 
724  switch(invalRank) {
725  case 1: {
726  if (reciprocal) {
727  for(int cl = 0; cl < numCells; cl++) {
728  for(int pt = 0; pt < numPoints; pt++) {
729  outputDataWrap(cl, pt) = inputDataRightWrap(pt)/inputDataLeftWrap(cl, pt);
730  } // P-loop
731  } // C-loop
732  }
733  else {
734  for(int cl = 0; cl < numCells; cl++) {
735  for(int pt = 0; pt < numPoints; pt++) {
736  outputDataWrap(cl, pt) = inputDataRightWrap(pt)*inputDataLeftWrap(cl, pt);
737  } // P-loop
738  } // C-loop
739  }
740  }// case 1
741  break;
742 
743  case 2: {
744  if (reciprocal) {
745  for(int cl = 0; cl < numCells; cl++) {
746  for(int pt = 0; pt < numPoints; pt++) {
747  for( int iVec = 0; iVec < dim1Tens; iVec++) {
748  outputDataWrap(cl, pt, iVec) = inputDataRightWrap(pt, iVec)/inputDataLeftWrap(cl, pt);
749  } // D1-loop
750  } // P-loop
751  } // C-loop
752  }
753  else {
754  for(int cl = 0; cl < numCells; cl++) {
755  for(int pt = 0; pt < numPoints; pt++) {
756  for( int iVec = 0; iVec < dim1Tens; iVec++) {
757  outputDataWrap(cl, pt, iVec) = inputDataRightWrap(pt, iVec)*inputDataLeftWrap(cl, pt);
758  } // D1-loop
759  } // P-loop
760  } // C-loop
761  }
762  }// case 2
763  break;
764 
765  case 3: {
766  if (reciprocal) {
767  for(int cl = 0; cl < numCells; cl++) {
768  for(int pt = 0; pt < numPoints; pt++) {
769  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
770  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
771  outputDataWrap(cl, pt, iTens1, iTens2) = inputDataRightWrap(pt, iTens1, iTens2)/inputDataLeftWrap(cl, pt);
772  } // D2-loop
773  } // D1-loop
774  } // P-loop
775  } // C-loop
776  }
777  else {
778  for(int cl = 0; cl < numCells; cl++) {
779  for(int pt = 0; pt < numPoints; pt++) {
780  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
781  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
782  outputDataWrap(cl, pt, iTens1, iTens2) = inputDataRightWrap(pt, iTens1, iTens2)*inputDataLeftWrap(cl, pt);
783  } // D2-loop
784  } // D1-loop
785  } // P-loop
786  } // C-loop
787  }
788  }// case 3
789  break;
790 
791  default:
792  TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 1) || (invalRank == 2) || (invalRank == 3) ), std::invalid_argument,
793  ">>> ERROR (ArrayTools::scalarMultiplyDataData): This branch of the method is defined only for rank-1, 2 or 3 input containers.");
794  }// invalRank
795 
796  }
797  else { //constant data
798 
799  switch(invalRank) {
800  case 1: {
801  if (reciprocal) {
802  for(int cl = 0; cl < numCells; cl++) {
803  for(int pt = 0; pt < numPoints; pt++) {
804  outputDataWrap(cl, pt) = inputDataRightWrap(pt)/inputDataLeftWrap(cl, 0);
805  } // P-loop
806  } // C-loop
807  }
808  else {
809  for(int cl = 0; cl < numCells; cl++) {
810  for(int pt = 0; pt < numPoints; pt++) {
811  outputDataWrap(cl, pt) = inputDataRightWrap(pt)*inputDataLeftWrap(cl, 0);
812  } // P-loop
813  } // C-loop
814  }
815  }// case 1
816  break;
817 
818  case 2: {
819  if (reciprocal) {
820  for(int cl = 0; cl < numCells; cl++) {
821  for(int pt = 0; pt < numPoints; pt++) {
822  for( int iVec = 0; iVec < dim1Tens; iVec++) {
823  outputDataWrap(cl, pt, iVec) = inputDataRightWrap(pt, iVec)/inputDataLeftWrap(cl, 0);
824  } // D1-loop
825  } // P-loop
826  } // C-loop
827  }
828  else {
829  for(int cl = 0; cl < numCells; cl++) {
830  for(int pt = 0; pt < numPoints; pt++) {
831  for( int iVec = 0; iVec < dim1Tens; iVec++) {
832  outputDataWrap(cl, pt, iVec) = inputDataRightWrap(pt, iVec)*inputDataLeftWrap(cl, 0);
833  } // D1-loop
834  } // P-loop
835  } // C-loop
836  }
837  }// case 2
838  break;
839 
840  case 3: {
841  if (reciprocal) {
842  for(int cl = 0; cl < numCells; cl++) {
843  for(int pt = 0; pt < numPoints; pt++) {
844  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
845  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
846  outputDataWrap(cl, pt, iTens1, iTens2) = inputDataRightWrap(pt, iTens1, iTens2)/inputDataLeftWrap(cl, 0);
847  } // D2-loop
848  } // D1-loop
849  } // P-loop
850  } // C-loop
851  }
852  else {
853  for(int cl = 0; cl < numCells; cl++) {
854  for(int pt = 0; pt < numPoints; pt++) {
855  for( int iTens1 = 0; iTens1 < dim1Tens; iTens1++) {
856  for( int iTens2 = 0; iTens2 < dim2Tens; iTens2++) {
857  outputDataWrap(cl, pt, iTens1, iTens2) = inputDataRightWrap(pt, iTens1, iTens2)*inputDataLeftWrap(cl, 0);
858  } // D2-loop
859  } // D1-loop
860  } // P-loop
861  } // C-loop
862  }
863  }// case 3
864  break;
865 
866  default:
867  TEUCHOS_TEST_FOR_EXCEPTION( !( (invalRank == 1) || (invalRank == 2) || (invalRank == 3) ), std::invalid_argument,
868  ">>> ERROR (ArrayTools::scalarMultiplyDataData): This branch of the method is defined only for rank-1, 2 or 3 input containers.");
869 
870  } // invalRank
871  } // numDataPoints
872 
873  } // end if (outvalRank = invalRank)
874 
875 } // scalarMultiplyDataData
876 } // end namespace Intrepid
877 #endif
878 
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...
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...