Intrepid2
Intrepid2_Basis.hpp
Go to the documentation of this file.
1// @HEADER
2// *****************************************************************************
3// Intrepid2 Package
4//
5// Copyright 2007 NTESS and the Intrepid2 contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
16#ifndef __INTREPID2_BASIS_HPP__
17#define __INTREPID2_BASIS_HPP__
18
19#include "Intrepid2_ConfigDefs.hpp"
20#include "Intrepid2_Types.hpp"
21#include "Intrepid2_Utils.hpp"
22
26#include "Shards_CellTopology.hpp"
28#include <Teuchos_RCPDecl.hpp>
29#include <Kokkos_Core.hpp>
30
31#include <vector>
32
33namespace Intrepid2 {
34
35template<typename DeviceType = void,
36 typename OutputType = double,
37 typename PointType = double>
38class Basis;
39
42template <typename DeviceType = void, typename OutputType = double, typename PointType = double>
43using BasisPtr = Teuchos::RCP<Basis<DeviceType,OutputType,PointType> >;
44
47template <typename OutputType = double, typename PointType = double>
49
86 template<typename Device,
87 typename outputValueType,
88 typename pointValueType>
89 class Basis {
90 public:
93 using DeviceType = Device;
94
97 using ExecutionSpace = typename DeviceType::execution_space;
98
99
102 using OutputValueType = outputValueType;
103
106 using PointValueType = pointValueType;
107
110 using OrdinalViewType = Kokkos::View<ordinal_type,DeviceType>;
111
114 using EBasisViewType = Kokkos::View<EBasis,DeviceType>;
115
118 using ECoordinatesViewType = Kokkos::View<ECoordinates,DeviceType>;
119
120 // ** tag interface
121 // - tag interface is not decorated with Kokkos inline so it should be allocated on hostspace
122
125 using OrdinalTypeArray1DHost = Kokkos::View<ordinal_type*,typename ExecutionSpace::array_layout,Kokkos::HostSpace>;
126
129 using OrdinalTypeArray2DHost = Kokkos::View<ordinal_type**,typename ExecutionSpace::array_layout,Kokkos::HostSpace>;
130
133 using OrdinalTypeArray3DHost = Kokkos::View<ordinal_type***,typename ExecutionSpace::array_layout,Kokkos::HostSpace>;
134
137 using OrdinalTypeArrayStride1DHost = Kokkos::View<ordinal_type*, Kokkos::LayoutStride, Kokkos::HostSpace>;
138
141 using OrdinalTypeArray1D = Kokkos::View<ordinal_type*,DeviceType>;
142
145 using OrdinalTypeArray2D = Kokkos::View<ordinal_type**,DeviceType>;
146
149 using OrdinalTypeArray3D = Kokkos::View<ordinal_type***,DeviceType>;
150
153 using OrdinalTypeArrayStride1D = Kokkos::View<ordinal_type*, Kokkos::LayoutStride, DeviceType>;
154
157 typedef typename ScalarTraits<pointValueType>::scalar_type scalarType;
158 protected:
159
162 ordinal_type basisCardinality_;
163
166 ordinal_type basisDegree_;
167
176
180
183 ECoordinates basisCoordinates_;
184
187 EFunctionSpace functionSpace_ = FUNCTION_SPACE_MAX;
188
191 //Kokkos::View<bool,DeviceType> basisTagsAreSet_;
192
205
218
230 template<typename OrdinalTypeView3D,
231 typename OrdinalTypeView2D,
232 typename OrdinalTypeView1D>
233 void setOrdinalTagData( OrdinalTypeView3D &tagToOrdinal,
234 OrdinalTypeView2D &ordinalToTag,
235 const OrdinalTypeView1D tags,
236 const ordinal_type basisCard,
237 const ordinal_type tagSize,
238 const ordinal_type posScDim,
239 const ordinal_type posScOrd,
240 const ordinal_type posDfOrd ) {
241 // Create ordinalToTag
242 ordinalToTag = OrdinalTypeView2D("ordinalToTag", basisCard, tagSize);
243
244 // Initialize with -1
245 Kokkos::deep_copy( ordinalToTag, -1 );
246
247 // Copy tags
248 for (ordinal_type i=0;i<basisCard;++i)
249 for (ordinal_type j=0;j<tagSize;++j)
250 ordinalToTag(i, j) = tags(i*tagSize + j);
251
252 // Find out dimension of tagToOrdinal
253 auto maxScDim = 0; // first dimension of tagToOrdinal
254 for (ordinal_type i=0;i<basisCard;++i)
255 if (maxScDim < tags(i*tagSize + posScDim))
256 maxScDim = tags(i*tagSize + posScDim);
257 ++maxScDim;
258
259 auto maxScOrd = 0; // second dimension of tagToOrdinal
260 for (ordinal_type i=0;i<basisCard;++i)
261 if (maxScOrd < tags(i*tagSize + posScOrd))
262 maxScOrd = tags(i*tagSize + posScOrd);
263 ++maxScOrd;
264
265 auto maxDfOrd = 0; // third dimension of tagToOrdinal
266 for (ordinal_type i=0;i<basisCard;++i)
267 if (maxDfOrd < tags(i*tagSize + posDfOrd))
268 maxDfOrd = tags(i*tagSize + posDfOrd);
269 ++maxDfOrd;
270
271 // Create tagToOrdinal
272 tagToOrdinal = OrdinalTypeView3D("tagToOrdinal", maxScDim, maxScOrd, maxDfOrd);
273
274 // Initialize with -1
275 Kokkos::deep_copy( tagToOrdinal, -1 );
276
277 // Overwrite elements of the array corresponding to tags with local DoF Id's, leave all other = -1
278 for (ordinal_type i=0;i<basisCard;++i)
279 tagToOrdinal(tags(i*tagSize), tags(i*tagSize+1), tags(i*tagSize+2)) = i;
280 }
281
282 // dof coords
285 Kokkos::DynRankView<scalarType,DeviceType> dofCoords_;
286
287 // dof coeffs
295 Kokkos::DynRankView<scalarType,DeviceType> dofCoeffs_;
296
305
318 public:
319
320 Basis() = default;
321 virtual~Basis() = default;
322
323 // receives input arguments
326 OutputValueType getDummyOutputValue() { return outputValueType(); }
327
330 PointValueType getDummyPointValue() { return pointValueType(); }
331
334 using OutputViewType = Kokkos::DynRankView<OutputValueType,Kokkos::LayoutStride,DeviceType>;
335
338 using PointViewType = Kokkos::DynRankView<PointValueType,Kokkos::LayoutStride,DeviceType>;
342 using ScalarViewType = Kokkos::DynRankView<scalarType,Kokkos::LayoutStride,DeviceType>;
348 Kokkos::DynRankView<OutputValueType,DeviceType> allocateOutputView( const int numPoints, const EOperator operatorType = OPERATOR_VALUE) const;
349
355 virtual BasisValues<OutputValueType,DeviceType> allocateBasisValues( TensorPoints<PointValueType,DeviceType> points, const EOperator operatorType = OPERATOR_VALUE) const
356 {
357 const bool operatorIsDk = (operatorType >= OPERATOR_D1) && (operatorType <= OPERATOR_D10);
358 const bool operatorSupported = (operatorType == OPERATOR_VALUE) || (operatorType == OPERATOR_GRAD) || (operatorType == OPERATOR_CURL) || (operatorType == OPERATOR_DIV) || operatorIsDk;
359 INTREPID2_TEST_FOR_EXCEPTION(!operatorSupported, std::invalid_argument, "operator is not supported by allocateBasisValues");
360
361 const int numPoints = points.extent_int(0);
362
363 using Scalar = OutputValueType;
364
365 auto dataView = allocateOutputView(numPoints, operatorType);
366 Data<Scalar,DeviceType> data(dataView);
367
368 bool useVectorData = (rank(dataView) == 3);
369
370 if (useVectorData)
371 {
372 VectorData<Scalar,DeviceType> vectorData(data);
373 return BasisValues<Scalar,DeviceType>(vectorData);
374 }
375 else
376 {
377 TensorData<Scalar,DeviceType> tensorData(data);
378 return BasisValues<Scalar,DeviceType>(tensorData);
379 }
380 }
381
382
394 virtual
395 void getScratchSpaceSize( ordinal_type& perTeamSpaceSize,
396 ordinal_type& perThreadSpaceSize,
397 const PointViewType inputPoints,
398 const EOperator operatorType = OPERATOR_VALUE) const {
399 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE( true, std::logic_error,
400 ">>> ERROR (Basis::getValuesScratchSpace): this method is not supported or should be overridden accordingly by derived classes.");
401 }
402
403
424 KOKKOS_INLINE_FUNCTION
425 virtual
426 void getValues( OutputViewType /* outputValues */,
427 const PointViewType /* inputPoints */,
428 const EOperator /* operatorType */,
429 const typename Kokkos::TeamPolicy<ExecutionSpace>::member_type& teamMember,
430 const typename ExecutionSpace::scratch_memory_space &scratchStorage,
431 const ordinal_type subcellDim=-1,
432 const ordinal_type subcellOrdinal=-1) const {
433 INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE( true, std::logic_error,
434 ">>> ERROR (Basis::getValues): this method is not supported or should be overridden accordingly by derived classes.");
435 }
436
456 virtual
457 void
458 getValues( const ExecutionSpace& /* space */,
459 OutputViewType /* outputValues */,
460 const PointViewType /* inputPoints */,
461 const EOperator /* operatorType */ = OPERATOR_VALUE ) const {
462 INTREPID2_TEST_FOR_EXCEPTION( true, std::logic_error,
463 ">>> ERROR (Basis::getValues): this method (FEM) is not supported or should be overridden accordingly by derived classes.");
464 }
465
467 virtual void getValues(
468 OutputViewType outputValues,
469 const PointViewType inputPoints,
470 const EOperator operatorType = OPERATOR_VALUE
471 ) const {
472 this->getValues(ExecutionSpace{}, outputValues, inputPoints, operatorType);
473 }
474
486 virtual
487 void
490 const EOperator operatorType = OPERATOR_VALUE ) const {
491 // note the extra allocation/copy here (this is one reason, among several, to override this method):
492 auto rawExpandedPoints = inputPoints.allocateAndFillExpandedRawPointView();
493
494 OutputViewType rawOutputView;
496 if (outputValues.numTensorDataFamilies() > 0)
497 {
498 INTREPID2_TEST_FOR_EXCEPTION(outputValues.tensorData(0).numTensorComponents() != 1, std::invalid_argument, "default implementation of getValues() only supports outputValues with trivial tensor-product structure");
499 outputData = outputValues.tensorData().getTensorComponent(0);
500 }
501 else if (outputValues.vectorData().isValid())
502 {
503 INTREPID2_TEST_FOR_EXCEPTION(outputValues.vectorData().numComponents() != 1, std::invalid_argument, "default implementation of getValues() only supports outputValues with trivial tensor-product structure");
504 INTREPID2_TEST_FOR_EXCEPTION(outputValues.vectorData().getComponent(0).numTensorComponents() != 1, std::invalid_argument, "default implementation of getValues() only supports outputValues with trivial tensor-product structure");
505 outputData = outputValues.vectorData().getComponent(0).getTensorComponent(0);
506 }
507
508 this->getValues(outputData.getUnderlyingView(), rawExpandedPoints, operatorType);
509 }
510
530 virtual
531 void
532 getValues( OutputViewType /* outputValues */,
533 const PointViewType /* inputPoints */,
534 const PointViewType /* cellVertices */,
535 const EOperator /* operatorType */ = OPERATOR_VALUE ) const {
536 INTREPID2_TEST_FOR_EXCEPTION( true, std::logic_error,
537 ">>> ERROR (Basis::getValues): this method (FVM) is not supported or should be overridden accordingly by derived classes.");
538 }
539
540
544 virtual
545 void
546 getDofCoords( ScalarViewType /* dofCoords */ ) const {
547 INTREPID2_TEST_FOR_EXCEPTION( true, std::logic_error,
548 ">>> ERROR (Basis::getDofCoords): this method is not supported or should be overridden accordingly by derived classes.");
549 }
550
559 virtual
560 void
561 getDofCoeffs( ScalarViewType /* dofCoeffs */ ) const {
562 INTREPID2_TEST_FOR_EXCEPTION( true, std::logic_error,
563 ">>> ERROR (Basis::getDofCoeffs): this method is not supported or should be overridden accordingly by derived classes.");
564 }
565
574 {
575 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
576 ">>> ERROR (Basis::getFieldOrdinalsForDegree): this method is not supported for non-hierarchical bases.");
577 int degreeEntryLength = fieldOrdinalPolynomialDegree_.extent_int(1);
578 int requestedDegreeLength = degrees.extent_int(0);
579 INTREPID2_TEST_FOR_EXCEPTION(degreeEntryLength != requestedDegreeLength, std::invalid_argument, "length of degrees does not match the entries in fieldOrdinalPolynomialDegree_");
580 std::vector<int> fieldOrdinalsVector;
581 for (int basisOrdinal=0; basisOrdinal<fieldOrdinalPolynomialDegree_.extent_int(0); basisOrdinal++)
582 {
583 bool matches = true;
584 for (int d=0; d<degreeEntryLength; d++)
585 {
586 if (fieldOrdinalPolynomialDegree_(basisOrdinal,d) > degrees(d)) matches = false;
587 }
588 if (matches) fieldOrdinalsVector.push_back(basisOrdinal);
589 }
590 OrdinalTypeArray1DHost fieldOrdinals("fieldOrdinalsForDegree",fieldOrdinalsVector.size());
591 for (unsigned i=0; i<fieldOrdinalsVector.size(); i++)
592 {
593 fieldOrdinals(i) = fieldOrdinalsVector[i];
594 }
595 return fieldOrdinals;
596 }
597
606 {
607 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
608 ">>> ERROR (Basis::getFieldOrdinalsForDegree): this method is not supported for non-hierarchical bases.");
609 int degreeEntryLength = fieldOrdinalH1PolynomialDegree_.extent_int(1);
610 int requestedDegreeLength = degrees.extent_int(0);
611 INTREPID2_TEST_FOR_EXCEPTION(degreeEntryLength != requestedDegreeLength, std::invalid_argument, "length of degrees does not match the entries in fieldOrdinalPolynomialDegree_");
612 std::vector<int> fieldOrdinalsVector;
613 for (int basisOrdinal=0; basisOrdinal<fieldOrdinalH1PolynomialDegree_.extent_int(0); basisOrdinal++)
614 {
615 bool matches = true;
616 for (int d=0; d<degreeEntryLength; d++)
617 {
618 if (fieldOrdinalH1PolynomialDegree_(basisOrdinal,d) > degrees(d)) matches = false;
619 }
620 if (matches) fieldOrdinalsVector.push_back(basisOrdinal);
621 }
622 OrdinalTypeArray1DHost fieldOrdinals("fieldOrdinalsForH1Degree",fieldOrdinalsVector.size());
623 for (unsigned i=0; i<fieldOrdinalsVector.size(); i++)
624 {
625 fieldOrdinals(i) = fieldOrdinalsVector[i];
626 }
627 return fieldOrdinals;
628 }
629
641 std::vector<int> getFieldOrdinalsForDegree(std::vector<int> &degrees) const
642 {
643 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
644 ">>> ERROR (Basis::getFieldOrdinalsForDegree): this method is not supported for non-hierarchical bases.");
645 OrdinalTypeArray1DHost degreesView("degrees",degrees.size());
646 for (unsigned d=0; d<degrees.size(); d++)
647 {
648 degreesView(d) = degrees[d];
649 }
650 auto fieldOrdinalsView = getFieldOrdinalsForDegree(degreesView);
651 std::vector<int> fieldOrdinalsVector(fieldOrdinalsView.extent_int(0));
652 for (int i=0; i<fieldOrdinalsView.extent_int(0); i++)
653 {
654 fieldOrdinalsVector[i] = fieldOrdinalsView(i);
655 }
656 return fieldOrdinalsVector;
657 }
658
669 std::vector<int> getFieldOrdinalsForH1Degree(std::vector<int> &degrees) const
670 {
671 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
672 ">>> ERROR (Basis::getFieldOrdinalsForDegree): this method is not supported for non-hierarchical bases.");
673 OrdinalTypeArray1DHost degreesView("degrees",degrees.size());
674 for (unsigned d=0; d<degrees.size(); d++)
675 {
676 degreesView(d) = degrees[d];
677 }
678 auto fieldOrdinalsView = getFieldOrdinalsForH1Degree(degreesView);
679 std::vector<int> fieldOrdinalsVector(fieldOrdinalsView.extent_int(0));
680 for (int i=0; i<fieldOrdinalsView.extent_int(0); i++)
681 {
682 fieldOrdinalsVector[i] = fieldOrdinalsView(i);
683 }
684 return fieldOrdinalsVector;
685 }
686
694 {
695 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
696 ">>> ERROR (Basis::getPolynomialDegreeOfField): this method is not supported for non-hierarchical bases.");
697 INTREPID2_TEST_FOR_EXCEPTION(fieldOrdinal < 0, std::invalid_argument, "field ordinal must be non-negative");
698 INTREPID2_TEST_FOR_EXCEPTION(fieldOrdinal >= fieldOrdinalPolynomialDegree_.extent_int(0), std::invalid_argument, "field ordinal out of bounds");
699
700 int polyDegreeLength = getPolynomialDegreeLength();
701 OrdinalTypeArray1DHost polyDegree("polynomial degree", polyDegreeLength);
702 for (int d=0; d<polyDegreeLength; d++)
703 {
704 polyDegree(d) = fieldOrdinalPolynomialDegree_(fieldOrdinal,d);
705 }
706 return polyDegree;
707 }
708
716 {
717 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
718 ">>> ERROR (Basis::getPolynomialDegreeOfField): this method is not supported for non-hierarchical bases.");
719 INTREPID2_TEST_FOR_EXCEPTION(fieldOrdinal < 0, std::invalid_argument, "field ordinal must be non-negative");
720 INTREPID2_TEST_FOR_EXCEPTION(fieldOrdinal >= fieldOrdinalH1PolynomialDegree_.extent_int(0), std::invalid_argument, "field ordinal out of bounds");
721
722 int polyDegreeLength = getPolynomialDegreeLength();
723 OrdinalTypeArray1DHost polyDegree("polynomial degree", polyDegreeLength);
724 for (int d=0; d<polyDegreeLength; d++)
725 {
726 polyDegree(d) = fieldOrdinalH1PolynomialDegree_(fieldOrdinal,d);
727 }
728 return polyDegree;
729 }
730
738 std::vector<int> getPolynomialDegreeOfFieldAsVector(int fieldOrdinal) const
739 {
740 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
741 ">>> ERROR (Basis::getPolynomialDegreeOfFieldAsVector): this method is not supported for non-hierarchical bases.");
742 auto polynomialDegreeView = getPolynomialDegreeOfField(fieldOrdinal);
743 std::vector<int> polynomialDegree(polynomialDegreeView.extent_int(0));
744
745 for (unsigned d=0; d<polynomialDegree.size(); d++)
746 {
747 polynomialDegree[d] = polynomialDegreeView(d);
748 }
749 return polynomialDegree;
750 }
751
759 std::vector<int> getH1PolynomialDegreeOfFieldAsVector(int fieldOrdinal) const
760 {
761 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
762 ">>> ERROR (Basis::getPolynomialDegreeOfFieldAsVector): this method is not supported for non-hierarchical bases.");
763 auto polynomialDegreeView = getH1PolynomialDegreeOfField(fieldOrdinal);
764 std::vector<int> polynomialDegree(polynomialDegreeView.extent_int(0));
765
766 for (unsigned d=0; d<polynomialDegree.size(); d++)
767 {
768 polynomialDegree[d] = polynomialDegreeView(d);
769 }
770 return polynomialDegree;
771 }
772
776 {
777 INTREPID2_TEST_FOR_EXCEPTION( basisType_ != BASIS_FEM_HIERARCHICAL, std::logic_error,
778 ">>> ERROR (Basis::getPolynomialDegreeLength): this method is not supported for non-hierarchical bases.");
779 return fieldOrdinalPolynomialDegree_.extent_int(1);
780 }
781
786 virtual
787 const char*
788 getName() const {
789 return "Intrepid2_Basis";
790 }
791
794 virtual
795 bool
797 return false;
798 }
799
804 ordinal_type
806 return basisCardinality_;
807 }
808
809
814 ordinal_type
815 getDegree() const {
816 return basisDegree_;
817 }
818
823 EFunctionSpace
825 return functionSpace_;
826 }
827
833 shards::CellTopology
835 return getCellTopologyData(basisCellTopologyKey_);
836 }
837
838
843 EBasis
844 getBasisType() const {
845 return basisType_;
846 }
847
848
853 ECoordinates
855 return basisCoordinates_;
856 }
857
865 ordinal_type
866 getDofCount( const ordinal_type subcDim,
867 const ordinal_type subcOrd ) const {
868 if ( subcDim >= 0 && subcDim < static_cast<ordinal_type>(tagToOrdinal_.extent(0)) &&
869 subcOrd >= 0 && subcOrd < static_cast<ordinal_type>(tagToOrdinal_.extent(1)) )
870 {
871 int firstDofOrdinal = tagToOrdinal_(subcDim, subcOrd, 0); // will be -1 if no dofs for subcell
872 if (firstDofOrdinal == -1) return static_cast<ordinal_type>(0);
873 // otherwise, lookup its tag and return the dof count stored there
874 return static_cast<ordinal_type>(this->getDofTag(firstDofOrdinal)[3]);
875 }
876 else
877 {
878 // subcDim and/or subcOrd out of bounds -> no dofs associated with subcell
879 return static_cast<ordinal_type>(0);
880 }
881 }
882
891 ordinal_type
892 getDofOrdinal( const ordinal_type subcDim,
893 const ordinal_type subcOrd,
894 const ordinal_type subcDofOrd ) const {
895 // this should be abort and able to be called as a device function
896#ifdef HAVE_INTREPID2_DEBUG
897 INTREPID2_TEST_FOR_EXCEPTION( subcDim < 0 || subcDim >= static_cast<ordinal_type>(tagToOrdinal_.extent(0)), std::out_of_range,
898 ">>> ERROR (Basis::getDofOrdinal): subcDim is out of range");
899 INTREPID2_TEST_FOR_EXCEPTION( subcOrd < 0 || subcOrd >= static_cast<ordinal_type>(tagToOrdinal_.extent(1)), std::out_of_range,
900 ">>> ERROR (Basis::getDofOrdinal): subcOrd is out of range");
901 INTREPID2_TEST_FOR_EXCEPTION( subcDofOrd < 0 || subcDofOrd >= static_cast<ordinal_type>(tagToOrdinal_.extent(2)), std::out_of_range,
902 ">>> ERROR (Basis::getDofOrdinal): subcDofOrd is out of range");
903#endif
904 ordinal_type r_val = -1;
905 if ( subcDim < static_cast<ordinal_type>(tagToOrdinal_.extent(0)) &&
906 subcOrd < static_cast<ordinal_type>(tagToOrdinal_.extent(1)) &&
907 subcDofOrd < static_cast<ordinal_type>(tagToOrdinal_.extent(2)) )
908 r_val = tagToOrdinal_(subcDim, subcOrd, subcDofOrd);
909#ifdef HAVE_INTREPID2_DEBUG
910 INTREPID2_TEST_FOR_EXCEPTION( r_val == -1, std::runtime_error,
911 ">>> ERROR (Basis::getDofOrdinal): Invalid DoF tag is found.");
912#endif
913 return r_val;
914 }
915
918 virtual int getNumTensorialExtrusions() const
919 {
920 return 0;
921 }
922
926 return tagToOrdinal_;
927 }
928
929
941 getDofTag( const ordinal_type dofOrd ) const {
942#ifdef HAVE_INTREPID2_DEBUG
943 INTREPID2_TEST_FOR_EXCEPTION( dofOrd < 0 || dofOrd >= static_cast<ordinal_type>(ordinalToTag_.extent(0)), std::out_of_range,
944 ">>> ERROR (Basis::getDofTag): dofOrd is out of range");
945#endif
946 return Kokkos::subview(ordinalToTag_, dofOrd, Kokkos::ALL());
947 }
948
949
960 return ordinalToTag_;
961 }
962
978 getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const {
979 INTREPID2_TEST_FOR_EXCEPTION( true, std::logic_error,
980 ">>> ERROR (Basis::getSubCellRefBasis): this method is not supported or should be overridden accordingly by derived classes.");
981 }
982
987 ordinal_type getDomainDimension() const
988 {
989 return this->getBaseCellTopology().getDimension() + this->getNumTensorialExtrusions();
990 }
991
997 getHostBasis() const {
998 INTREPID2_TEST_FOR_EXCEPTION( true, std::logic_error,
999 ">>> ERROR (Basis::getHostBasis): this method is not supported or should be overridden accordingly by derived classes.");
1000 }
1001
1002 }; // class Basis
1003
1004 //--------------------------------------------------------------------------------------------//
1005 // //
1006 // Helper functions of the Basis class //
1007 // //
1008 //--------------------------------------------------------------------------------------------//
1009
1010 //
1011 // functions for orders, cardinality, etc.
1012 //
1013
1014
1026 KOKKOS_INLINE_FUNCTION
1027 ordinal_type getFieldRank(const EFunctionSpace spaceType);
1028
1064 KOKKOS_INLINE_FUNCTION
1065 ordinal_type getOperatorRank(const EFunctionSpace spaceType,
1066 const EOperator operatorType,
1067 const ordinal_type spaceDim);
1068
1074 KOKKOS_INLINE_FUNCTION
1075 ordinal_type getOperatorOrder(const EOperator operatorType);
1076
1077 template<EOperator operatorType>
1078 KOKKOS_INLINE_FUNCTION
1079 constexpr ordinal_type getOperatorOrder();
1080
1104 template<ordinal_type spaceDim>
1105 KOKKOS_INLINE_FUNCTION
1106 ordinal_type getDkEnumeration(const ordinal_type xMult,
1107 const ordinal_type yMult = -1,
1108 const ordinal_type zMult = -1);
1109
1110
1121 template<ordinal_type spaceDim>
1122 KOKKOS_INLINE_FUNCTION
1123 ordinal_type getPnEnumeration(const ordinal_type p,
1124 const ordinal_type q = 0,
1125 const ordinal_type r = 0);
1126
1127
1128
1147template<typename value_type>
1148KOKKOS_INLINE_FUNCTION
1149void getJacobyRecurrenceCoeffs (
1150 value_type &an,
1151 value_type &bn,
1152 value_type &cn,
1153 const ordinal_type alpha,
1154 const ordinal_type beta ,
1155 const ordinal_type n);
1156
1157
1158
1159
1160
1161 // /** \brief Returns multiplicities of dx, dy, and dz based on the enumeration of the partial
1162 // derivative, its order and the space dimension. Inverse of the getDkEnumeration() method.
1163
1164 // \param partialMult [out] - array with the multiplicities f dx, dy and dz
1165 // \param derivativeEnum [in] - enumeration of the partial derivative
1166 // \param operatorType [in] - k-th partial derivative Dk
1167 // \param spaceDim [in] - space dimension
1168 // */
1169 // template<typename OrdinalArrayType>
1170 // KOKKOS_INLINE_FUNCTION
1171 // void getDkMultiplicities(OrdinalArrayType partialMult,
1172 // const ordinal_type derivativeEnum,
1173 // const EOperator operatorType,
1174 // const ordinal_type spaceDim);
1175
1194 KOKKOS_INLINE_FUNCTION
1195 ordinal_type getDkCardinality(const EOperator operatorType,
1196 const ordinal_type spaceDim);
1197
1198 template<EOperator operatorType, ordinal_type spaceDim>
1199 KOKKOS_INLINE_FUNCTION
1200 constexpr ordinal_type getDkCardinality();
1201
1202
1203
1213 template<ordinal_type spaceDim>
1214 KOKKOS_INLINE_FUNCTION
1215 ordinal_type getPnCardinality (ordinal_type n);
1216
1217 template<ordinal_type spaceDim, ordinal_type n>
1218 KOKKOS_INLINE_FUNCTION
1219 constexpr ordinal_type getPnCardinality ();
1220
1221
1222
1223 //
1224 // Argument check
1225 //
1226
1227
1238 template<typename outputValueViewType,
1239 typename inputPointViewType>
1240 void getValues_HGRAD_Args( const outputValueViewType outputValues,
1241 const inputPointViewType inputPoints,
1242 const EOperator operatorType,
1243 const shards::CellTopology cellTopo,
1244 const ordinal_type basisCard );
1245
1256 template<typename outputValueViewType,
1257 typename inputPointViewType>
1258 void getValues_HCURL_Args( const outputValueViewType outputValues,
1259 const inputPointViewType inputPoints,
1260 const EOperator operatorType,
1261 const shards::CellTopology cellTopo,
1262 const ordinal_type basisCard );
1263
1274 template<typename outputValueViewType,
1275 typename inputPointViewType>
1276 void getValues_HDIV_Args( const outputValueViewType outputValues,
1277 const inputPointViewType inputPoints,
1278 const EOperator operatorType,
1279 const shards::CellTopology cellTopo,
1280 const ordinal_type basisCard );
1281
1292 template<typename outputValueViewType,
1293 typename inputPointViewType>
1294 void getValues_HVOL_Args( const outputValueViewType outputValues,
1295 const inputPointViewType inputPoints,
1296 const EOperator operatorType,
1297 const shards::CellTopology cellTopo,
1298 const ordinal_type basisCard );
1299
1300}// namespace Intrepid2
1301
1302#include <Intrepid2_BasisDef.hpp>
1303
1304//--------------------------------------------------------------------------------------------//
1305// //
1306// D O C U M E N T A T I O N P A G E S //
1307// //
1308//--------------------------------------------------------------------------------------------//
1410#endif
Implementation file for the abstract base class Intrepid2::Basis.
Header file for the data-wrapper class Intrepid2::BasisValues.
BasisPtr< typename Kokkos::HostSpace::device_type, OutputType, PointType > HostBasisPtr
Pointer to a Basis whose device type is on the host (Kokkos::HostSpace::device_type),...
Teuchos::RCP< Basis< DeviceType, OutputType, PointType > > BasisPtr
Basis Pointer.
Header file for the classes: Intrepid2::RefSubcellParametrization, Intrepid2::RefCellNodes,...
Definition of cell topology information.
View-like interface to tensor points; point components are stored separately; the appropriate coordin...
Contains definitions of custom data types in Intrepid2.
Header function for Intrepid2::Util class and other utility functions.
#define INTREPID2_TEST_FOR_EXCEPTION_DEVICE_SAFE(test, x, msg)
The data containers in Intrepid2 that support sum factorization and other reduced-data optimizations ...
const VectorDataType & vectorData() const
VectorData accessor.
TensorDataType & tensorData()
TensorData accessor for single-family scalar data.
An abstract base class that defines interface for concrete basis implementations for Finite Element (...
OrdinalTypeArray1DHost getFieldOrdinalsForDegree(OrdinalTypeArray1DHost &degrees) const
For hierarchical bases, returns the field ordinals that have at most the specified degree in each dim...
ECoordinates basisCoordinates_
The coordinate system for which the basis is defined.
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, DeviceType > PointViewType
View type for input points.
OrdinalTypeArray1DHost getFieldOrdinalsForH1Degree(OrdinalTypeArray1DHost &degrees) const
For hierarchical bases, returns the field ordinals that have at most the specified H^1 degree in each...
virtual KOKKOS_INLINE_FUNCTION void getValues(OutputViewType, const PointViewType, const EOperator, const typename Kokkos::TeamPolicy< ExecutionSpace >::member_type &teamMember, const typename ExecutionSpace::scratch_memory_space &scratchStorage, const ordinal_type subcellDim=-1, const ordinal_type subcellOrdinal=-1) const
Team-level evaluation of basis functions on a reference cell.
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, DeviceType > OutputViewType
View type for basis value output.
const OrdinalTypeArrayStride1DHost getDofTag(const ordinal_type dofOrd) const
DoF ordinal to DoF tag lookup.
outputValueType OutputValueType
Output value type for basis; default is double.
ordinal_type getDofOrdinal(const ordinal_type subcDim, const ordinal_type subcOrd, const ordinal_type subcDofOrd) const
DoF tag to ordinal lookup.
ordinal_type getDofCount(const ordinal_type subcDim, const ordinal_type subcOrd) const
DoF count for specified subcell.
virtual void getScratchSpaceSize(ordinal_type &perTeamSpaceSize, ordinal_type &perThreadSpaceSize, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const
Return the size of the scratch space, in bytes, needed for using the team-level implementation of get...
Kokkos::View< ordinal_type ***, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray3DHost
View type for 3d host array.
const OrdinalTypeArray2DHost getAllDofTags() const
Retrieves all DoF tags.
std::vector< int > getFieldOrdinalsForH1Degree(std::vector< int > &degrees) const
For hierarchical bases, returns the field ordinals that have at most the specified H^1 degree in each...
std::vector< int > getH1PolynomialDegreeOfFieldAsVector(int fieldOrdinal) const
For hierarchical bases, returns the polynomial degree (which may have multiple values in higher spati...
EBasis basisType_
Type of the basis.
ordinal_type basisDegree_
Degree of the largest complete polynomial space that can be represented by the basis.
Kokkos::View< ordinal_type *, Kokkos::LayoutStride, DeviceType > OrdinalTypeArrayStride1D
View type for 1d device array.
Kokkos::View< ordinal_type *, Kokkos::LayoutStride, Kokkos::HostSpace > OrdinalTypeArrayStride1DHost
View type for 1d host array.
ordinal_type getDegree() const
Returns the degree of the basis.
void setOrdinalTagData(OrdinalTypeView3D &tagToOrdinal, OrdinalTypeView2D &ordinalToTag, const OrdinalTypeView1D tags, const ordinal_type basisCard, const ordinal_type tagSize, const ordinal_type posScDim, const ordinal_type posScOrd, const ordinal_type posDfOrd)
Fills ordinalToTag_ and tagToOrdinal_ by basis-specific tag data.
virtual HostBasisPtr< OutputValueType, PointValueType > getHostBasis() const
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...
ordinal_type getCardinality() const
Returns cardinality of the basis.
virtual BasisValues< OutputValueType, DeviceType > allocateBasisValues(TensorPoints< PointValueType, DeviceType > points, const EOperator operatorType=OPERATOR_VALUE) const
Allocate BasisValues container suitable for passing to the getValues() variant that takes a TensorPoi...
Kokkos::DynRankView< scalarType, Kokkos::LayoutStride, DeviceType > ScalarViewType
View type for scalars.
OutputValueType getDummyOutputValue()
Dummy array to receive input arguments.
ECoordinates getCoordinateSystem() const
Returns the type of coordinate system for which the basis is defined.
OrdinalTypeArray2DHost ordinalToTag_
"true" if tagToOrdinal_ and ordinalToTag_ have been initialized
PointValueType getDummyPointValue()
Dummy array to receive input arguments.
int getPolynomialDegreeLength() const
For hierarchical bases, returns the number of entries required to specify the polynomial degree of a ...
virtual bool requireOrientation() const
True if orientation is required.
Kokkos::View< ordinal_type, DeviceType > OrdinalViewType
View type for ordinal.
const OrdinalTypeArray3DHost getAllDofOrdinal() const
DoF tag to ordinal data structure.
Device DeviceType
(Kokkos) Device type on which Basis is templated. Does not necessarily return true for Kokkos::is_dev...
virtual void getValues(const ExecutionSpace &, OutputViewType, const PointViewType, const EOperator=OPERATOR_VALUE) const
Evaluation of a FEM basis on a reference cell.
Kokkos::DynRankView< scalarType, DeviceType > dofCoords_
Coordinates of degrees-of-freedom for basis functions defined in physical space.
Kokkos::View< ECoordinates, DeviceType > ECoordinatesViewType
View for coordinate system type.
ordinal_type getDomainDimension() const
Returns the spatial dimension of the domain of the basis; this is equal to getBaseCellTopology()....
OrdinalTypeArray2DHost fieldOrdinalH1PolynomialDegree_
H^1 polynomial degree for each degree of freedom. Only defined for hierarchical bases right now....
virtual void getValues(BasisValues< OutputValueType, DeviceType > outputValues, const TensorPoints< PointValueType, DeviceType > inputPoints, const EOperator operatorType=OPERATOR_VALUE) const
Evaluation of a FEM basis on a reference cell, using point and output value containers that allow pre...
pointValueType PointValueType
Point value type for basis; default is double.
Kokkos::View< ordinal_type **, DeviceType > OrdinalTypeArray2D
View type for 2d device array.
Kokkos::DynRankView< scalarType, DeviceType > dofCoeffs_
Coefficients for computing degrees of freedom for Lagrangian basis If P is an element of the space sp...
OrdinalTypeArray1DHost getPolynomialDegreeOfField(int fieldOrdinal) const
For hierarchical bases, returns the polynomial degree (which may have multiple values in higher spati...
Kokkos::View< ordinal_type **, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray2DHost
View type for 2d host array.
virtual void getDofCoords(ScalarViewType) const
Returns spatial locations (coordinates) of degrees of freedom on the reference cell.
ordinal_type basisCardinality_
Cardinality of the basis, i.e., the number of basis functions/degrees-of-freedom.
OrdinalTypeArray3DHost tagToOrdinal_
DoF tag to ordinal lookup table.
EFunctionSpace getFunctionSpace() const
Returns the function space for the basis.
Kokkos::DynRankView< OutputValueType, DeviceType > allocateOutputView(const int numPoints, const EOperator operatorType=OPERATOR_VALUE) const
Allocate a View container suitable for passing to the getValues() variant that accepts Kokkos DynRank...
virtual void getDofCoeffs(ScalarViewType) const
Coefficients for computing degrees of freedom for Lagrangian basis If P is an element of the space sp...
EBasis getBasisType() const
Returns the basis type.
OrdinalTypeArray1DHost getH1PolynomialDegreeOfField(int fieldOrdinal) const
For hierarchical bases, returns the polynomial degree (which may have multiple values in higher spati...
ScalarTraits< pointValueType >::scalar_type scalarType
Scalar type for point values.
Kokkos::View< ordinal_type ***, DeviceType > OrdinalTypeArray3D
View type for 3d device array.
shards::CellTopology getBaseCellTopology() const
Returns the base cell topology for which the basis is defined. See Shards documentation https://trili...
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
unsigned basisCellTopologyKey_
Identifier of the base topology of the cells for which the basis is defined. See the Shards package f...
Kokkos::View< ordinal_type *, DeviceType > OrdinalTypeArray1D
View type for 1d device array.
virtual void getValues(OutputViewType, const PointViewType, const PointViewType, const EOperator=OPERATOR_VALUE) const
Evaluation of an FVD basis evaluation on a physical cell.
typename DeviceType::execution_space ExecutionSpace
(Kokkos) Execution space for basis.
virtual const char * getName() const
Returns basis name.
std::vector< int > getFieldOrdinalsForDegree(std::vector< int > &degrees) const
For hierarchical bases, returns the field ordinals that have at most the specified degree in each dim...
OrdinalTypeArray2DHost fieldOrdinalPolynomialDegree_
Polynomial degree for each degree of freedom. Only defined for hierarchical bases right now....
virtual BasisPtr< DeviceType, OutputValueType, PointValueType > getSubCellRefBasis(const ordinal_type subCellDim, const ordinal_type subCellOrd) const
returns the basis associated to a subCell.
virtual int getNumTensorialExtrusions() const
returns the number of tensorial extrusions relative to the cell topology returned by getBaseCellTopol...
EFunctionSpace functionSpace_
The function space in which the basis is defined.
std::vector< int > getPolynomialDegreeOfFieldAsVector(int fieldOrdinal) const
For hierarchical bases, returns the polynomial degree (which may have multiple values in higher spati...
Kokkos::View< EBasis, DeviceType > EBasisViewType
View for basis type.
Wrapper around a Kokkos::View that allows data that is constant or repeating in various logical dimen...
KOKKOS_INLINE_FUNCTION enable_if_t< rank==1, const Kokkos::View< typename RankExpander< DataScalar, rank >::value_type, DeviceType > & > getUnderlyingView() const
Returns the underlying view. Throws an exception if the underlying view is not rank 1.
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, DeviceType > OutputViewType
View type for basis value output.
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, DeviceType > PointViewType
View type for input points.
Kokkos::DynRankView< OutputValueType, Kokkos::LayoutStride, DeviceType > OutputViewType
View type for basis value output.
typename DeviceType::execution_space ExecutionSpace
(Kokkos) Execution space for basis.
View-like interface to tensor data; tensor components are stored separately and multiplied together a...
KOKKOS_INLINE_FUNCTION const Data< Scalar, DeviceType > & getTensorComponent(const ordinal_type &r) const
Returns the requested tensor component.
KOKKOS_INLINE_FUNCTION ordinal_type numTensorComponents() const
Return the number of tensorial components.
View-like interface to tensor points; point components are stored separately; the appropriate coordin...
KOKKOS_INLINE_FUNCTION std::enable_if< std::is_integral< iType >::value, int >::type extent_int(const iType &r) const
Returns the logical extent in the requested dimension.
ScalarView< PointScalar, DeviceType > allocateAndFillExpandedRawPointView() const
This method is for compatibility with existing methods that take raw point views. Note that in genera...
Reference-space field values for a basis, designed to support typical vector-valued bases.
KOKKOS_INLINE_FUNCTION int numComponents() const
returns the number of components
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,...
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...