Intrepid2
Intrepid2_LegendreBasis_HVOL_LINE.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
15#ifndef Intrepid2_LegendreBasis_HVOL_LINE_h
16#define Intrepid2_LegendreBasis_HVOL_LINE_h
17
18#include <Kokkos_DynRankView.hpp>
19
20#include <Intrepid2_config.h>
21
22// Sacado header that defines some fad sizing…
23#ifdef HAVE_INTREPID2_SACADO
24#include <KokkosExp_View_Fad.hpp>
25#endif
26
27#include "Intrepid2_Basis.hpp"
30
31namespace Intrepid2
32{
38 template<class DeviceType, class OutputScalar, class PointScalar,
39 class OutputFieldType, class InputPointsType>
41 {
42 using ExecutionSpace = typename DeviceType::execution_space;
43 using ScratchSpace = typename ExecutionSpace::scratch_memory_space;
44 using OutputScratchView = Kokkos::View<OutputScalar*,ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
45 using PointScratchView = Kokkos::View<PointScalar*, ScratchSpace,Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
46
47 using TeamPolicy = Kokkos::TeamPolicy<ExecutionSpace>;
48 using TeamMember = typename TeamPolicy::member_type;
49
50 OutputFieldType output_; // F,P
51 InputPointsType inputPoints_; // P,D
52
53 int polyOrder_;
54 int numFields_, numPoints_;
55
56 EOperator op_;
57
58 size_t fad_size_output_;
59
60 Hierarchical_HVOL_LINE_Functor(OutputFieldType output, InputPointsType inputPoints,
61 int polyOrder, EOperator op)
62 : output_(output), inputPoints_(inputPoints), polyOrder_(polyOrder), op_(op),
63 fad_size_output_(getScalarDimensionForView(output))
64 {
65 numFields_ = output.extent_int(0);
66 numPoints_ = output.extent_int(1);
67 INTREPID2_TEST_FOR_EXCEPTION(numPoints_ != inputPoints.extent_int(0), std::invalid_argument, "point counts need to match!");
68 INTREPID2_TEST_FOR_EXCEPTION(numFields_ != polyOrder_+1, std::invalid_argument, "output field size does not match basis cardinality");
69 }
70
71 KOKKOS_INLINE_FUNCTION
72 void operator()( const TeamMember & teamMember ) const
73 {
74 auto pointOrdinal = teamMember.league_rank();
75 OutputScratchView field_values_at_point;
76 if (fad_size_output_ > 0) {
77 field_values_at_point = OutputScratchView(teamMember.team_shmem(), numFields_, fad_size_output_);
78 }
79 else {
80 field_values_at_point = OutputScratchView(teamMember.team_shmem(), numFields_);
81 }
82
83 const PointScalar x = inputPoints_(pointOrdinal,0);
84
85 switch (op_)
86 {
87 case OPERATOR_VALUE:
88 Polynomials::legendreValues(field_values_at_point, polyOrder_, x);
89
90 // note that because legendreValues determines field values recursively, there is not much
91 // opportunity at that level for further parallelism
92 break;
93 case OPERATOR_GRAD:
94 case OPERATOR_D1:
95 case OPERATOR_D2:
96 case OPERATOR_D3:
97 case OPERATOR_D4:
98 case OPERATOR_D5:
99 case OPERATOR_D6:
100 case OPERATOR_D7:
101 case OPERATOR_D8:
102 case OPERATOR_D9:
103 case OPERATOR_D10:
104 {
105 auto derivativeOrder = getOperatorOrder(op_);
106 Polynomials::legendreDerivativeValues(field_values_at_point, polyOrder_, x, derivativeOrder);
107 break;
108 }
109 default:
110 // unsupported operator type
111 device_assert(false);
112 }
113 // copy the values into the output container
114 for (int fieldOrdinal=0; fieldOrdinal<numFields_; fieldOrdinal++)
115 {
116 output_.access(fieldOrdinal,pointOrdinal,0) = field_values_at_point(fieldOrdinal);
117 }
118 }
119
120 // Provide the shared memory capacity.
121 // This function takes the team_size as an argument,
122 // which allows team_size-dependent allocations.
123 size_t team_shmem_size (int team_size) const
124 {
125 // we want to use shared memory to create a fast buffer that we can use for basis computations
126 size_t shmem_size = 0;
127 if (fad_size_output_ > 0)
128 shmem_size += OutputScratchView::shmem_size(numFields_, fad_size_output_);
129 else
130 shmem_size += OutputScratchView::shmem_size(numFields_);
131
132 return shmem_size;
133 }
134 };
135
147 template<typename DeviceType,
148 typename OutputScalar = double,
149 typename PointScalar = double>
151 : public Basis<DeviceType,OutputScalar,PointScalar>
152 {
153 public:
156
159
160 using typename BasisBase::OutputViewType;
161 using typename BasisBase::PointViewType;
162 using typename BasisBase::ScalarViewType;
163
164 using typename BasisBase::ExecutionSpace;
165
166 protected:
167 int polyOrder_; // the maximum order of the polynomial
168 EPointType pointType_;
169 public:
178 LegendreBasis_HVOL_LINE(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
179 :
180 polyOrder_(polyOrder),
181 pointType_(pointType)
182 {
183 INTREPID2_TEST_FOR_EXCEPTION(pointType!=POINTTYPE_DEFAULT,std::invalid_argument,"PointType not supported");
184 this->basisCardinality_ = polyOrder+1;
185 this->basisDegree_ = polyOrder;
186 this->basisCellTopologyKey_ = shards::Line<2>::key;
187 this->basisType_ = BASIS_FEM_HIERARCHICAL;
188 this->basisCoordinates_ = COORDINATES_CARTESIAN;
189 this->functionSpace_ = FUNCTION_SPACE_HVOL;
190
191 const int degreeLength = 1;
192 this->fieldOrdinalPolynomialDegree_ = OrdinalTypeArray2DHost("Integrated Legendre H(grad) line polynomial degree lookup", this->basisCardinality_, degreeLength);
193 this->fieldOrdinalH1PolynomialDegree_ = OrdinalTypeArray2DHost("Integrated Legendre H(grad) line polynomial degree lookup", this->basisCardinality_, degreeLength);
194
195 for (int i=0; i<this->basisCardinality_; i++)
196 {
197 // for H(vol) line, first basis member is constant, second is first-degree, etc.
198 this->fieldOrdinalPolynomialDegree_ (i,0) = i;
199 this->fieldOrdinalH1PolynomialDegree_(i,0) = i+1; // H^1 degree is one greater
200 }
201
202 // initialize tags
203 {
204 const auto & cardinality = this->basisCardinality_;
205
206 // Basis-dependent initializations
207 const ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag
208 const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim
209 const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal
210 const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell
211
212 OrdinalTypeArray1DHost tagView("tag view", cardinality*tagSize);
213
214 for (ordinal_type i=0;i<cardinality;++i) {
215 tagView(i*tagSize+0) = 1; // edge dof
216 tagView(i*tagSize+1) = 0; // edge id
217 tagView(i*tagSize+2) = i; // local dof id
218 tagView(i*tagSize+3) = cardinality; // total number of dofs in this edge
219 }
220
221 // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays:
222 // tags are constructed on host
224 this->ordinalToTag_,
225 tagView,
226 this->basisCardinality_,
227 tagSize,
228 posScDim,
229 posScOrd,
230 posDfOrd);
231 }
232 }
233
234 // since the getValues() below only overrides the FEM variant, we specify that
235 // we use the base class's getValues(), which implements the FVD variant by throwing an exception.
236 // (It's an error to use the FVD variant on this basis.)
238
243 virtual
244 const char*
245 getName() const override {
246 return "Intrepid2_LegendreBasis_HVOL_LINE";
247 }
248
267 virtual void getValues( OutputViewType outputValues, const PointViewType inputPoints,
268 const EOperator operatorType = OPERATOR_VALUE ) const override
269 {
270 auto numPoints = inputPoints.extent_int(0);
271
273
274 FunctorType functor(outputValues, inputPoints, polyOrder_, operatorType);
275
276 const int outputVectorSize = getVectorSizeForHierarchicalParallelism<OutputScalar>();
277 const int pointVectorSize = getVectorSizeForHierarchicalParallelism<PointScalar>();
278 const int vectorSize = std::max(outputVectorSize,pointVectorSize);
279 const int teamSize = 1; // because of the way the basis functions are computed, we don't have a second level of parallelism...
280
281 auto policy =
282 Kokkos::TeamPolicy<ExecutionSpace>(numPoints, teamSize, vectorSize);
283 Kokkos::parallel_for("Hierarchical_HVOL_LINE_Functor", policy , functor);
284 }
285
291 getHostBasis() const override {
292 using HostDeviceType = typename Kokkos::HostSpace::device_type;
294 return Teuchos::rcp( new HostBasisType(polyOrder_, pointType_) );
295 }
296 };
297} // end namespace Intrepid2
298
299#endif /* Intrepid2_LegendreBasis_HVOL_LINE_h */
Header file for the abstract base class Intrepid2::Basis.
KOKKOS_INLINE_FUNCTION ordinal_type getOperatorOrder(const EOperator operatorType)
Returns order of an operator.
Teuchos::RCP< Basis< DeviceType, OutputType, PointType > > BasisPtr
Basis Pointer.
Implementation of an assert that can safely be called from device code.
KOKKOS_INLINE_FUNCTION void device_assert(bool val)
Free functions, callable from device code, that implement various polynomials useful in basis definit...
KOKKOS_INLINE_FUNCTION constexpr unsigned getScalarDimensionForView(const ViewType &view)
Returns the size of the Scalar dimension for the View. This is 0 for non-AD types....
An abstract base class that defines interface for concrete basis implementations for Finite Element (...
ECoordinates basisCoordinates_
The coordinate system for which the basis is defined.
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, DeviceType > PointViewType
View type for input points.
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.
EBasis basisType_
Type of the basis.
ordinal_type basisDegree_
Degree of the largest complete polynomial space that can be represented by 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.
Kokkos::DynRankView< scalarType, Kokkos::LayoutStride, DeviceType > ScalarViewType
View type for scalars.
OrdinalTypeArray2DHost ordinalToTag_
"true" if tagToOrdinal_ and ordinalToTag_ have been initialized
OrdinalTypeArray2DHost fieldOrdinalH1PolynomialDegree_
H^1 polynomial degree for each degree of freedom. Only defined for hierarchical bases right now....
Kokkos::View< ordinal_type **, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray2DHost
View type for 2d host array.
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.
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...
typename DeviceType::execution_space ExecutionSpace
(Kokkos) Execution space for basis.
OrdinalTypeArray2DHost fieldOrdinalPolynomialDegree_
Polynomial degree for each degree of freedom. Only defined for hierarchical bases right now....
EFunctionSpace functionSpace_
The function space in which the basis is defined.
Basis defining Legendre basis on the line, a polynomial subspace of L^2 (a.k.a. H(vol)) on the line.
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.
virtual const char * getName() const override
Returns basis name.
virtual BasisPtr< typename Kokkos::HostSpace::device_type, OutputScalar, PointScalar > getHostBasis() const override
Creates and returns a Basis object whose DeviceType template argument is Kokkos::HostSpace::device_ty...
virtual void getValues(OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell.
Kokkos::View< ordinal_type **, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray2DHost
View type for 2d host array.
LegendreBasis_HVOL_LINE(int polyOrder, const EPointType pointType=POINTTYPE_DEFAULT)
Constructor.
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
Functor for computing values for the LegendreBasis_HVOL_LINE class.