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
51
52#ifndef Intrepid2_TransformedBasisValues_h
53#define Intrepid2_TransformedBasisValues_h
54
57#include "Intrepid2_ScalarView.hpp"
58#include "Intrepid2_Utils.hpp"
59
60namespace 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 */
Header file for the data-wrapper class Intrepid2::BasisValues.
Utility methods for manipulating Intrepid2::Data objects.
Header function for Intrepid2::Util class and other utility functions.
enable_if_t< has_rank_method< Functor >::value, unsigned > KOKKOS_INLINE_FUNCTION getFunctorRank(const Functor &functor)
#define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg)
The data containers in Intrepid2 that support sum factorization and other reduced-data optimizations ...
static void multiplyByCPWeights(Data< Scalar, DeviceType > &resultMatrixData, const Data< Scalar, DeviceType > &matrixDataIn, const Data< Scalar, DeviceType > &scalarDataIn)
Wrapper around a Kokkos::View that allows data that is constant or repeating in various logical dimen...
static Data< DataScalar, DeviceType > allocateInPlaceCombinationResult(const Data< DataScalar, DeviceType > &A, const Data< DataScalar, DeviceType > &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 DataVariationType cellVariationType() const
Returns the variation type corresponding to the cell dimension.
TransformedBasisValues(const Data< Scalar, DeviceType > &transform, const BasisValues< Scalar, DeviceType > &basisValues)
Standard constructor.
KOKKOS_INLINE_FUNCTION bool axisAligned() const
Returns true if the transformation matrix is diagonal.
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 int extent_int(const int &r) const
Returns the extent in the specified dimension as an int.
KOKKOS_INLINE_FUNCTION unsigned rank() const
Returns the rank of the container, which is 3 for scalar values, and 4 for vector values.
const VectorData< Scalar, DeviceType > & vectorData() const
Returns the reference-space vector data.
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).
KOKKOS_INLINE_FUNCTION int spaceDim() const
Returns the logical extent in the space dimension, which is the 3 dimension in this container.
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 int &dim1, const int &dim2) const
Returns the specified entry in the transform matrix.
const Data< Scalar, DeviceType > & transform() const
Returns the transform matrix. An invalid/empty container indicates the identity transform.
KOKKOS_INLINE_FUNCTION int numCells() const
Returns the logical extent in the cell dimension, which is the 0 dimension in this container.
KOKKOS_INLINE_FUNCTION int numPoints() const
Returns the logical extent in the points dimension, which is the 2 dimension in this container.
TransformedBasisValues()
Default constructor; an invalid container. Will return -1 for numCells().
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 Scalar operator()(const int &cellOrdinal, const int &fieldOrdinal, const int &pointOrdinal) const
Scalar accessor, with arguments (C,F,P).
void multiplyByPointwiseWeights(const ViewType &weights)
Replaces the internal pullback (transformation operator) with the result of the pullback multiplied b...
KOKKOS_INLINE_FUNCTION int numFields() const
Returns the logical extent in the fields dimension, which is the 1 dimension in this container.
Reference-space field values for a basis, designed to support typical vector-valued bases.