Intrepid2
Intrepid2_TransformedBasisValues.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 
52 #ifndef Intrepid2_TransformedBasisValues_h
53 #define Intrepid2_TransformedBasisValues_h
54 
56 #include "Intrepid2_DataTools.hpp"
57 #include "Intrepid2_ScalarView.hpp"
58 #include "Intrepid2_Utils.hpp"
59 
60 namespace Intrepid2 {
66  template<class Scalar, typename DeviceType>
68  {
69  public:
70  ordinal_type numCells_;
71 
72  Data<Scalar,DeviceType> transform_; // vector case: (C,P,D,D) jacobian or jacobian inverse; can also be unset for identity transform. Scalar case: (C,P), or unset for identity.
73 
75 
82  :
83  numCells_(transform.extent_int(0)),
84  transform_(transform),
85  basisValues_(basisValues)
86  {
87  // sanity check: when transform is diagonal, we expect there to be no pointwise variation.
88  INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(transform_.isDiagonal() && (transform_.getVariationTypes()[1] != CONSTANT), std::invalid_argument, "When transform is diagonal, we assume in various places that there is no pointwise variation; the transform_ Data should have CONSTANT as its variation type in dimension 1.");
89  }
90 
95  TransformedBasisValues(const ordinal_type &numCells, const BasisValues<Scalar,DeviceType> &basisValues)
96  :
97  numCells_(numCells),
98  basisValues_(basisValues)
99  {}
100 
102  template<typename OtherDeviceType, class = typename std::enable_if<!std::is_same<DeviceType, OtherDeviceType>::value>::type>
104  :
105  numCells_(transformedVectorData.numCells()),
106  transform_(transformedVectorData.transform()),
107  basisValues_(transformedVectorData.basisValues())
108  {}
109 
114  :
115  numCells_(-1)
116  {}
117 
119  KOKKOS_INLINE_FUNCTION bool axisAligned() const
120  {
121  if (!transform_.isValid())
122  {
123  // null transform is understood as the identity
124  return true;
125  }
126  else
127  {
128  return transform_.isDiagonal();
129  }
130  }
131 
132  BasisValues<Scalar, DeviceType> basisValues() const
133  {
134  return basisValues_;
135  }
136 
138  KOKKOS_INLINE_FUNCTION int cellDataExtent() const
139  {
140  return transform_.getDataExtent(0);
141  }
142 
144  KOKKOS_INLINE_FUNCTION DataVariationType cellVariationType() const
145  {
146  return transform_.getVariationTypes()[0];
147  }
148 
150  template<class ViewType>
151  void multiplyByPointwiseWeights(const ViewType &weights)
152  {
153  ordinal_type weightRank = getFunctorRank(weights); // .rank() or ::rank, depending on weights type
154  INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(weightRank != 2, std::invalid_argument, "pointwise weights must have shape (C,P).");
155 
156  Data<Scalar,DeviceType> weightData(weights);
157  if (!transform_.isValid())
158  {
159  // empty transform_ is understood as identity; multiplying by weightData is thus
160  // the same as transform_ = weightData
161  transform_ = weightData;
162  return;
163  }
164  else
165  {
166  if (transform_.rank() == 4)
167  {
168  transform_ = DataTools::multiplyByCPWeights(transform_,weightData);
169  }
170  else // transformRank == 2
171  {
172  auto result = Data<Scalar,DeviceType>::allocateInPlaceCombinationResult(weightData, transform_);
173 
174  result.storeInPlaceProduct(weightData,transform_);
175  transform_ = result;
176  }
177  }
178  }
179 
181  KOKKOS_INLINE_FUNCTION int numCells() const
182  {
183  return numCells_;
184  }
185 
187  KOKKOS_INLINE_FUNCTION int numFields() const
188  {
189  return basisValues_.extent_int(0);
190  }
191 
193  KOKKOS_INLINE_FUNCTION int numPoints() const
194  {
195  return basisValues_.extent_int(1);
196  }
197 
199  KOKKOS_INLINE_FUNCTION int spaceDim() const
200  {
201  return basisValues_.extent_int(2);
202  }
203 
205  KOKKOS_INLINE_FUNCTION Scalar operator()(const int &cellOrdinal, const int &fieldOrdinal, const int &pointOrdinal) const
206  {
207  if (!transform_.isValid())
208  {
209  // null transform is understood as the identity
210  return basisValues_(fieldOrdinal,pointOrdinal);
211  }
212  else
213  {
214  return transform_(cellOrdinal,pointOrdinal) * basisValues_(fieldOrdinal,pointOrdinal);
215  }
216  }
217 
219  KOKKOS_INLINE_FUNCTION Scalar operator()(const int &cellOrdinal, const int &fieldOrdinal, const int &pointOrdinal, const int &dim) const
220  {
221  if (!transform_.isValid())
222  {
223  // null transform is understood as the identity
224  return basisValues_(fieldOrdinal,pointOrdinal,dim);
225  }
226  else if (transform_.isDiagonal())
227  {
228  return transform_(cellOrdinal,pointOrdinal,dim,dim) * basisValues_(fieldOrdinal,pointOrdinal,dim);
229  }
230  else
231  {
232  Scalar value = 0.0;
233  for (int d2=0; d2<transform_.extent_int(2); d2++)
234  {
235  value += transform_(cellOrdinal,pointOrdinal,dim,d2) * basisValues_(fieldOrdinal,pointOrdinal,d2);
236  }
237  return value;
238  }
239  }
240 
242  KOKKOS_INLINE_FUNCTION Scalar transformWeight(const int &cellOrdinal, const int &pointOrdinal) const
243  {
244  if (!transform_.isValid())
245  {
246  // null transform is understood as identity
247  return 1.0;
248  }
249  else
250  {
251  return transform_(cellOrdinal,pointOrdinal);
252  }
253  }
254 
256  KOKKOS_INLINE_FUNCTION Scalar transformWeight(const int &cellOrdinal, const int &pointOrdinal, const int &dim1, const int &dim2) const
257  {
258  if (!transform_.isValid())
259  {
260  // null transform is understood as identity
261  return (dim1 == dim2) ? 1.0 : 0.0;
262  }
263  else
264  {
265  return transform_(cellOrdinal,pointOrdinal,dim1,dim2);
266  }
267  }
268 
271  {
272  return transform_;
273  }
274 
277  {
278  return basisValues_.vectorData();
279  }
280 
282  KOKKOS_INLINE_FUNCTION
283  unsigned rank() const
284  {
285  return basisValues_.rank() + 1; // transformation adds a cell dimension
286  }
287 
289  KOKKOS_INLINE_FUNCTION
290  int extent_int(const int &r) const
291  {
292  if (r == 0) return numCells();
293  else if (r == 1) return numFields();
294  else if (r == 2) return numPoints();
295  else if (r == 3) return spaceDim();
296  else if (r > 3) return 1;
297 
298  return -1; // unreachable return; here to avoid compiler warnings.
299  }
300  };
301 }
302 
303 #endif /* Intrepid2_TransformedBasisValues_h */
TransformedBasisValues(const Data< Scalar, DeviceType > &transform, const BasisValues< Scalar, DeviceType > &basisValues)
Standard constructor.
static void multiplyByCPWeights(Data< Scalar, DeviceType > &resultMatrixData, const Data< Scalar, DeviceType > &matrixDataIn, const Data< Scalar, DeviceType > &scalarDataIn)
Utility methods for manipulating Intrepid2::Data objects.
static Data< DataScalar, DeviceType > allocateInPlaceCombinationResult(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &B)
KOKKOS_INLINE_FUNCTION int spaceDim() const
Returns the logical extent in the space dimension, which is the 3 dimension in this container...
#define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg)
KOKKOS_INLINE_FUNCTION DataVariationType cellVariationType() const
Returns the variation type corresponding to the cell dimension.
KOKKOS_INLINE_FUNCTION unsigned rank() const
Returns the rank of the container, which is 3 for scalar values, and 4 for vector values...
KOKKOS_INLINE_FUNCTION Scalar operator()(const int &cellOrdinal, const int &fieldOrdinal, const int &pointOrdinal, const int &dim) const
Vector accessor, with arguments (C,F,P,D).
void multiplyByPointwiseWeights(const ViewType &weights)
Replaces the internal pullback (transformation operator) with the result of the pullback multiplied b...
KOKKOS_INLINE_FUNCTION int cellDataExtent() const
Returns the true data extent in the cell dimension (e.g., will be 1 for transform matrices that do no...
KOKKOS_INLINE_FUNCTION Scalar operator()(const int &cellOrdinal, const int &fieldOrdinal, const int &pointOrdinal) const
Scalar accessor, with arguments (C,F,P).
KOKKOS_INLINE_FUNCTION const Kokkos::Array< DataVariationType, 7 > & getVariationTypes() const
Returns an array with the variation types in each logical dimension.
TransformedBasisValues()
Default constructor; an invalid container. Will return -1 for numCells().
KOKKOS_INLINE_FUNCTION int numPoints() const
Returns the logical extent in the points dimension, which is the 2 dimension in this container...
Header function for Intrepid2::Util class and other utility functions.
const VectorDataType & vectorData() const
VectorData accessor.
KOKKOS_INLINE_FUNCTION bool isDiagonal() const
returns true for containers that have two dimensions marked as BLOCK_PLUS_DIAGONAL for which the non-...
const Data< Scalar, DeviceType > & transform() const
Returns the transform matrix. An invalid/empty container indicates the identity transform.
TransformedBasisValues(const ordinal_type &numCells, const BasisValues< Scalar, DeviceType > &basisValues)
Constructor for the case of an identity transform.
KOKKOS_INLINE_FUNCTION Scalar transformWeight(const int &cellOrdinal, const int &pointOrdinal) const
Returns the specified entry in the (scalar) transform. (Only valid for scalar-valued BasisValues; see...
KOKKOS_INLINE_FUNCTION constexpr bool isValid() const
returns true for containers that have data; false for those that don&#39;t (namely, those that have been ...
KOKKOS_INLINE_FUNCTION Scalar transformWeight(const int &cellOrdinal, const int &pointOrdinal, const int &dim1, const int &dim2) const
Returns the specified entry in the transform matrix.
KOKKOS_INLINE_FUNCTION unsigned rank() const
Returns the logical rank of the Data container.
KOKKOS_INLINE_FUNCTION int extent_int(const int &r) const
Returns the logical extent in the specified dimension.
TransformedBasisValues(const TransformedBasisValues< Scalar, OtherDeviceType > &transformedVectorData)
copy-like constructor for differing device types. This may do a deep_copy of underlying views...
KOKKOS_INLINE_FUNCTION int extent_int(const int &r) const
Returns the extent in the specified dimension as an int.
KOKKOS_INLINE_FUNCTION int numFields() const
Returns the logical extent in the fields dimension, which is the 1 dimension in this container...
KOKKOS_INLINE_FUNCTION int getDataExtent(const ordinal_type &d) const
returns the true extent of the data corresponding to the logical dimension provided; if the data does...
Structure-preserving representation of transformed vector data; reference space values and transforma...
const VectorData< Scalar, DeviceType > & vectorData() const
Returns the reference-space vector data.
Header file for the data-wrapper class Intrepid2::BasisValues.
Reference-space field values for a basis, designed to support typical vector-valued bases...
KOKKOS_INLINE_FUNCTION bool axisAligned() const
Returns true if the transformation matrix is diagonal.
KOKKOS_INLINE_FUNCTION int numCells() const
Returns the logical extent in the cell dimension, which is the 0 dimension in this container...