52 #ifndef Intrepid2_BasisValues_h 53 #define Intrepid2_BasisValues_h 68 template<
class Scalar,
typename ExecSpaceType>
74 Kokkos::Array<TensorDataType,Parameters::MaxTensorComponents> tensorDataFamilies_;
77 int numTensorDataFamilies_ = -1;
83 numTensorDataFamilies_(1)
91 for (
int family=0; family<numTensorDataFamilies_; family++)
106 numTensorDataFamilies_(0)
111 template<typename OtherExecSpaceType, class = typename std::enable_if<!std::is_same<ExecSpaceType, OtherExecSpaceType>::value>::type>
115 numTensorDataFamilies_(basisValues.numTensorDataFamilies())
118 for (
int family=0; family<numTensorDataFamilies_; family++)
127 int familyStartOrdinal = -1, familyEndOrdinal = -1;
130 for (
int i=0; i<familyCount; i++)
132 const bool startMatches = (fieldsSoFar == fieldStartOrdinal);
133 familyStartOrdinal = startMatches ? i : familyStartOrdinal;
134 fieldsSoFar += numFieldsInFamily(i);
135 const bool endMatches = (fieldsSoFar - fieldStartOrdinal == numFields);
136 familyEndOrdinal = endMatches ? i : familyEndOrdinal;
138 INTREPID2_TEST_FOR_EXCEPTION(familyStartOrdinal == -1, std::invalid_argument,
"fieldStartOrdinal does not align with the start of a family.");
139 INTREPID2_TEST_FOR_EXCEPTION(familyEndOrdinal == -1, std::invalid_argument,
"fieldStartOrdinal + numFields does not align with the end of a family.");
141 const int numFamiliesInFieldSpan = familyEndOrdinal - familyStartOrdinal + 1;
142 if (numTensorDataFamilies_ > 0)
145 for (
int i=familyStartOrdinal; i<=familyEndOrdinal; i++)
154 std::vector< std::vector<TensorData<Scalar,ExecSpaceType> > > vectorComponents(numFamiliesInFieldSpan, std::vector<
TensorData<Scalar,ExecSpaceType> >(componentCount));
155 for (
int i=familyStartOrdinal; i<=familyEndOrdinal; i++)
157 for (
int j=0; j<componentCount; j++)
159 vectorComponents[i-familyStartOrdinal][j] = vectorData_.
getComponent(i,j);
169 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(numTensorDataFamilies_ != 1, std::invalid_argument,
"this method is not supported when numTensorDataFamilies_ != 1");
170 return tensorDataFamilies_[0];
176 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(familyOrdinal >= numTensorDataFamilies_, std::invalid_argument,
"familyOrdinal too large");
177 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(familyOrdinal < 0, std::invalid_argument,
"familyOrdinal may not be less than 0");
178 return tensorDataFamilies_[familyOrdinal];
182 KOKKOS_INLINE_FUNCTION
191 return numTensorDataFamilies_;
195 KOKKOS_INLINE_FUNCTION
196 int numTensorDataFamilies()
const 198 return numTensorDataFamilies_;
201 KOKKOS_INLINE_FUNCTION
202 int numFieldsInFamily(
int familyOrdinal)
const 210 return tensorDataFamilies_[familyOrdinal].extent_int(0);
217 return tensorDataFamilies_;
227 KOKKOS_INLINE_FUNCTION
228 Scalar
operator()(
const int &fieldOrdinal,
const int &pointOrdinal)
const 230 if (numTensorDataFamilies_ == 1)
232 #ifdef HAVE_INTREPID2_DEBUG 233 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(! tensorDataFamilies_[0].isValid(), std::invalid_argument,
"TensorData object not initialized!");
235 return tensorDataFamilies_[0](fieldOrdinal, pointOrdinal);
239 int familyForField = -1;
240 int previousFamilyEnd = -1;
241 int fieldAdjustment = 0;
243 for (
int family=0; family<numTensorDataFamilies_; family++)
245 const int familyFieldCount = tensorDataFamilies_[family].extent_int(0);
246 const bool fieldInRange = (fieldOrdinal > previousFamilyEnd) && (fieldOrdinal <= previousFamilyEnd + familyFieldCount);
247 familyForField = fieldInRange ? family : familyForField;
248 fieldAdjustment = fieldInRange ? previousFamilyEnd + 1 : fieldAdjustment;
249 previousFamilyEnd += familyFieldCount;
251 #ifdef HAVE_INTREPID2_DEBUG 252 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE( familyForField == -1, std::invalid_argument,
"fieldOrdinal appears to be out of range");
254 return tensorDataFamilies_[familyForField](fieldOrdinal-fieldAdjustment,pointOrdinal);
259 KOKKOS_INLINE_FUNCTION
260 Scalar
operator()(
const int &fieldOrdinal,
const int &pointOrdinal,
const int &dim)
const 262 #ifdef HAVE_INTREPID2_DEBUG 263 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(! vectorData_.
isValid(), std::invalid_argument,
"VectorData object not initialized!");
265 return vectorData_(fieldOrdinal, pointOrdinal, dim);
269 KOKKOS_INLINE_FUNCTION
270 Scalar
operator()(
const int &cellOrdinal,
const int &fieldOrdinal,
const int &pointOrdinal,
const int &dim)
const 272 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(
true, std::invalid_argument,
"CVFEM support not yet implemented in BasisValues");
276 KOKKOS_INLINE_FUNCTION
277 int extent_int(
const int &i)
const 283 for (
int familyOrdinal=0; familyOrdinal<
numFamilies(); familyOrdinal++)
285 numFields += numFieldsInFamily(familyOrdinal);
295 else if (tensorDataFamilies_[0].isValid())
297 return tensorDataFamilies_[0].extent_int(i);
307 KOKKOS_INLINE_FUNCTION
308 size_t extent(
const int &i)
const 310 return static_cast<size_t>(extent_int(i));
313 KOKKOS_INLINE_FUNCTION
318 return vectorData_.
rank();
320 else if (tensorDataFamilies_[0].isValid())
322 return tensorDataFamilies_[0].rank();
KOKKOS_INLINE_FUNCTION int extent_int(const int &r) const
Returns the extent in the specified dimension as an int.
const Kokkos::Array< TensorDataType, Parameters::MaxTensorComponents > & tensorDataFamilies() const
TensorDataFamilies accessor.
KOKKOS_INLINE_FUNCTION constexpr bool isValid() const
returns true for containers that have data; false for those that don't (e.g., those that have been co...
BasisValues(const BasisValues< Scalar, OtherExecSpaceType > &basisValues)
copy-like constructor for differing execution spaces. This does a deep copy of underlying views...
KOKKOS_INLINE_FUNCTION Scalar operator()(const int &fieldOrdinal, const int &pointOrdinal, const int &dim) const
operator() for (F,P,D) vector data; throws an exception if this is not a vector-valued container ...
KOKKOS_INLINE_FUNCTION int numFieldsInFamily(const unsigned &familyOrdinal) const
returns the number of fields in the specified family
KOKKOS_INLINE_FUNCTION int numComponents() const
returns the number of components
KOKKOS_INLINE_FUNCTION unsigned rank() const
Returns the rank of this container, which is 3.
BasisValues< Scalar, ExecSpaceType > basisValuesForFields(const int &fieldStartOrdinal, const int &numFields)
field start and length must align with families in vectorData_ or tensorDataFamilies_ (whichever is v...
The data containers in Intrepid2 that support sum factorization and other reduced-data optimizations ...
BasisValues(VectorDataType vectorData)
Constructor for vector-valued BasisValues.
BasisValues()
Default constructor.
KOKKOS_INLINE_FUNCTION int numFamilies() const
For valid vectorData, returns the number of families in vectorData; otherwise, returns number of Tens...
Reference-space field values for a basis, designed to support typical vector-valued bases...
KOKKOS_INLINE_FUNCTION Scalar operator()(const int &fieldOrdinal, const int &pointOrdinal) const
operator() for (F,P) scalar data; throws an exception if this is not a scalar-valued container ...
TensorDataType & tensorData(const int &familyOrdinal)
TensorData accessor for multi-family scalar data.
KOKKOS_INLINE_FUNCTION const TensorData< Scalar, DeviceType > & getComponent(const int &componentOrdinal) const
Single-argument component accessor for the axial-component or the single-family case; in this case...
BasisValues(std::vector< TensorDataType > tensorDataFamilies)
Constructor for scalar-valued BasisValues, with potentially multiple families of values. (Used, e.g., for op = DIV and functionSpace = HDIV.)
KOKKOS_INLINE_FUNCTION int numFamilies() const
returns the number of families
TensorDataType & tensorData()
TensorData accessor for single-family scalar data.
KOKKOS_INLINE_FUNCTION Scalar operator()(const int &cellOrdinal, const int &fieldOrdinal, const int &pointOrdinal, const int &dim) const
operator() for (C,F,P,D) data, which arises in CVFEM; at present unimplemented, and only declared her...
BasisValues(TensorDataType tensorData)
Constructor for scalar-valued BasisValues with a single family of values.
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...
const VectorDataType & vectorData() const
VectorData accessor.