Intrepid2
Intrepid2_TensorArgumentIterator.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ************************************************************************
3 //
4 // Intrepid2 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 Kyungjoo Kim (kyukim@sandia.gov),
38 // Mauro Perego (mperego@sandia.gov), or
39 // Nate Roberts (nvrober@sandia.gov),
40 //
41 // ************************************************************************
42 // @HEADER
43 
49 #ifndef Intrepid2_TensorArgumentIterator_h
50 #define Intrepid2_TensorArgumentIterator_h
51 
52 #include "Intrepid2_TensorData.hpp"
53 #include "Intrepid2_Types.hpp"
54 
55 namespace Intrepid2
56 {
63  Kokkos::Array<ordinal_type,Parameters::MaxTensorComponents> arguments_;
64  Kokkos::Array<ordinal_type,Parameters::MaxTensorComponents> bounds_;
65  ordinal_type numTensorComponents_;
66  public:
67  template<class Scalar, typename ExecSpaceType>
68  KOKKOS_INLINE_FUNCTION
69  TensorArgumentIterator(const TensorData<Scalar,ExecSpaceType> &tensorData, const ordinal_type argumentOrdinal)
70  :
71  numTensorComponents_(tensorData.numTensorComponents())
72  {
73  for (ordinal_type r=0; r<numTensorComponents_; r++)
74  {
75  arguments_[r] = 0;
76  bounds_[r] = tensorData.getTensorComponent(r).extent_int(argumentOrdinal);
77  }
78  }
79 
81  template<class Scalar, typename ExecSpaceType>
82  KOKKOS_INLINE_FUNCTION
83  TensorArgumentIterator(const TensorData<Scalar,ExecSpaceType> &tensorData, const ordinal_type argumentOrdinal, const ordinal_type numTensorComponents)
84  :
85  numTensorComponents_(numTensorComponents)
86  {
87  for (ordinal_type r=0; r<numTensorComponents_; r++)
88  {
89  arguments_[r] = 0;
90  bounds_[r] = tensorData.getTensorComponent(r).extent_int(argumentOrdinal);
91  }
92  }
93 
95  TensorArgumentIterator(const std::vector<ordinal_type> tensorComponentBounds)
96  :
97  numTensorComponents_(tensorComponentBounds.size())
98  {
99  for (ordinal_type r=0; r<numTensorComponents_; r++)
100  {
101  arguments_[r] = 0;
102  bounds_[r] = tensorComponentBounds[r];
103  }
104  }
105 
107  template<size_t rank>
108  KOKKOS_INLINE_FUNCTION
109  TensorArgumentIterator(const Kokkos::Array<ordinal_type,rank> &tensorComponentBounds)
110  :
111  numTensorComponents_(rank)
112  {
113  for (ordinal_type r=0; r<rank; r++)
114  {
115  arguments_[r] = 0;
116  bounds_[r] = tensorComponentBounds[r];
117  }
118  }
119 
121  KOKKOS_INLINE_FUNCTION ordinal_type increment()
122  {
123  ordinal_type r = numTensorComponents_ - 1;
124  while (arguments_[r] + 1 >= bounds_[r])
125  {
126  arguments_[r] = 0; // reset
127  r--;
128  if (r < 0) break;
129  }
130  if (r >= 0) ++arguments_[r];
131  return r;
132  }
133 
136  KOKKOS_INLINE_FUNCTION
137  ordinal_type nextIncrementResult() const
138  {
139  ordinal_type r = numTensorComponents_ - 1;
140  while (arguments_[r] + 1 >= bounds_[r])
141  {
142  r--;
143  if (r < 0) break;
144  }
145  return r;
146  }
147 
150  KOKKOS_INLINE_FUNCTION const ordinal_type & argument(const ordinal_type &r) const
151  {
152  return arguments_[r];
153  }
154 
156  KOKKOS_INLINE_FUNCTION ordinal_type enumerationIndex() const
157  {
158  // commented-out code belongs to implementation with rightmost argument as the fastest-moving. We may want to support this as an option.
159 // ordinal_type i = 0;
160 // for (ordinal_type r=0; r<numTensorComponents_-1; r++)
161 // {
162 // i += arguments_[r];
163 // i *= bounds_[r+1];
164 // }
165 // i += arguments_[numTensorComponents_-1];
166 // return i;
167 
168  // TensorData's numbering has the leftmost argument as the fastest-moving
169  // We return that numbering here.
170  ordinal_type i = 0;
171  for (ordinal_type r=numTensorComponents_-1; r>0; r--)
172  {
173  i += arguments_[r];
174  i *= bounds_[r-1];
175  }
176  i += arguments_[0];
177  return i;
178  }
179 
181  KOKKOS_INLINE_FUNCTION ordinal_type relativeEnumerationIndex(const ordinal_type &startingComponent) const
182  {
183  // commented-out code belongs to implementation with rightmost argument as the fastest-moving. We may want to support this as an option.
184 // ordinal_type i = 0;
185 // for (ordinal_type r=startingComponent; r<numTensorComponents_-1; r++)
186 // {
187 // i += arguments_[r];
188 // i *= bounds_[r+1];
189 // }
190 // i += arguments_[numTensorComponents_-1];
191 // return i;
192 
193  // TensorData's numbering has the leftmost argument as the fastest-moving
194  // We return that numbering here.
195  ordinal_type i = 0;
196  for (ordinal_type r=numTensorComponents_-1; r>startingComponent; r--)
197  {
198  i += arguments_[r];
199  i *= bounds_[r-1];
200  }
201  i += arguments_[startingComponent];
202  return i;
203  }
204 
206  KOKKOS_INLINE_FUNCTION ordinal_type relativeEnumerationSpan(const ordinal_type &startingComponent) const
207  {
208  ordinal_type i = 1;
209  for (ordinal_type r=startingComponent; r<numTensorComponents_; r++)
210  {
211  i *= bounds_[r];
212  }
213  return i;
214  }
215 
218  KOKKOS_INLINE_FUNCTION
219  void reset(ordinal_type from_component_number=0)
220  {
221  for (ordinal_type r=from_component_number; r<numTensorComponents_; r++)
222  {
223  arguments_[r] = 0;
224  }
225  }
226 
230  KOKKOS_INLINE_FUNCTION
231  void setArgumentForComponent(const ordinal_type &r, const ordinal_type &i)
232  {
233  arguments_[r] = i;
234  }
235 
241  KOKKOS_INLINE_FUNCTION
242  void setEnumerationIndex(const ordinal_type &enumerationIndex)
243  {
244  ordinal_type remainder = enumerationIndex;
245  for (ordinal_type d=0; d<numTensorComponents_; d++)
246  {
247  arguments_[d] = remainder % bounds_[d];
248  remainder /= bounds_[d];
249  }
250  }
251 
254  KOKKOS_INLINE_FUNCTION
255  void copyArguments(TensorArgumentIterator &otherArgumentIterator, const ordinal_type &r0_from, const ordinal_type &r0_to, const ordinal_type &numArguments)
256  {
257  for (ordinal_type i=0; i<numArguments; i++)
258  {
259  arguments_[r0_to + i] = otherArgumentIterator.argument(r0_from + i);
260  }
261  }
262 
263  };
264 } // namespace Intrepid2
265 
266 #endif /* Intrepid2_TensorArgumentIterator_h */
KOKKOS_INLINE_FUNCTION const ordinal_type & argument(const ordinal_type &r) const
KOKKOS_INLINE_FUNCTION TensorArgumentIterator(const TensorData< Scalar, ExecSpaceType > &tensorData, const ordinal_type argumentOrdinal, const ordinal_type numTensorComponents)
Variant that allows truncation of the tensor components at the specified number of components...
KOKKOS_INLINE_FUNCTION ordinal_type nextIncrementResult() const
KOKKOS_INLINE_FUNCTION void copyArguments(TensorArgumentIterator &otherArgumentIterator, const ordinal_type &r0_from, const ordinal_type &r0_to, const ordinal_type &numArguments)
Sets a subset of this iterator&#39;s component arguments to match the component arguments from otherArgum...
TensorArgumentIterator(const std::vector< ordinal_type > tensorComponentBounds)
Basic constructor in which only the bounds of the tensor components are required. ...
KOKKOS_INLINE_FUNCTION void setArgumentForComponent(const ordinal_type &r, const ordinal_type &i)
KOKKOS_INLINE_FUNCTION ordinal_type enumerationIndex() const
Note: enumerationIndex() matches the ordering in TensorData. This is different from the order in whic...
KOKKOS_INLINE_FUNCTION const Data< Scalar, DeviceType > & getTensorComponent(const ordinal_type &r) const
Returns the requested tensor component.
KOKKOS_INLINE_FUNCTION void reset(ordinal_type from_component_number=0)
KOKKOS_INLINE_FUNCTION TensorArgumentIterator(const Kokkos::Array< ordinal_type, rank > &tensorComponentBounds)
Basic constructor in which only the bounds of the tensor components are required. ...
KOKKOS_INLINE_FUNCTION void setEnumerationIndex(const ordinal_type &enumerationIndex)
Sets the enumeration index; this refers to a 1D enumeration of the possible in-bound arguments...
Contains definitions of custom data types in Intrepid2.
KOKKOS_INLINE_FUNCTION ordinal_type relativeEnumerationIndex(const ordinal_type &startingComponent) const
Note: relativeEnumerationIndex() matches the ordering in TensorData. This is different from the order...
KOKKOS_INLINE_FUNCTION ordinal_type relativeEnumerationSpan(const ordinal_type &startingComponent) const
total number of enumeration indices with arguments prior to the startingComponent fixed ...
View-like interface to tensor data; tensor components are stored separately and multiplied together a...
View-like interface to tensor data; tensor components are stored separately and multiplied together a...
Allows systematic enumeration of all entries in a TensorData object, tracking indices for each tensor...
KOKKOS_INLINE_FUNCTION ordinal_type increment()
Proceed to next entry.
KOKKOS_INLINE_FUNCTION ordinal_type numTensorComponents() const
Return the number of tensorial components.