Intrepid2
Intrepid2_HGRAD_TET_Cn_FEMDef.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_HGRAD_TET_CN_FEM_DEF_HPP__
17#define __INTREPID2_HGRAD_TET_CN_FEM_DEF_HPP__
18
21
22namespace Intrepid2 {
23
24// -------------------------------------------------------------------------------------
25namespace Impl {
26
27template<EOperator OpType>
28template<typename OutputViewType,
29typename InputViewType,
30typename WorkViewType,
31typename VinvViewType>
32KOKKOS_INLINE_FUNCTION
33void
34Basis_HGRAD_TET_Cn_FEM::Serial<OpType>::
35getValues( OutputViewType output,
36 const InputViewType input,
37 WorkViewType work,
38 const VinvViewType vinv,
39 const ordinal_type order ) {
40
41 constexpr ordinal_type spaceDim = 3;
42 const ordinal_type
43 card = vinv.extent(0),
44 npts = input.extent(0);
45
46 typedef typename Kokkos::DynRankView<typename InputViewType::value_type, typename WorkViewType::memory_space> ViewType;
47 auto vcprop = Kokkos::common_view_alloc_prop(input);
48 auto ptr = work.data();
49
50 switch (OpType) {
51 case OPERATOR_VALUE: {
52 const ViewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts);
53 ViewType dummyView;
54
55 Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::
56 Serial<OpType>::getValues(phis, input, dummyView, order);
57
58 for (ordinal_type i=0;i<card;++i)
59 for (ordinal_type j=0;j<npts;++j) {
60 output.access(i,j) = 0.0;
61 for (ordinal_type k=0;k<card;++k)
62 output.access(i,j) += vinv(k,i)*phis.access(k,j);
63 }
64 break;
65 }
66 case OPERATOR_GRAD:
67 case OPERATOR_D1: {
68 const ViewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts, spaceDim);
69 ptr += card*npts*spaceDim*get_dimension_scalar(input);
70 const ViewType workView(Kokkos::view_wrap(ptr, vcprop), card, npts, spaceDim+1);
71 Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::
72 Serial<OpType>::getValues(phis, input, workView, order);
73
74 // loop order interchanged to workaround nvcc compiler issues with sems-cuda/11.4.2
75 // nvcc error : 'ptxas' died due to signal 11 (Invalid memory reference)
76 for (ordinal_type j=0;j<npts;++j)
77 for (ordinal_type k=0;k<spaceDim;++k)
78 for (ordinal_type i=0;i<card;++i)
79 {
80 output.access(i,j,k) = 0.0;
81 for (ordinal_type l=0;l<card;++l)
82 output.access(i,j,k) += vinv(l,i)*phis.access(l,j,k);
83 }
84 break;
85 }
86 case OPERATOR_D2:
87 case OPERATOR_D3:
88 case OPERATOR_D4:
89 case OPERATOR_D5:
90 case OPERATOR_D6:
91 case OPERATOR_D7:
92 case OPERATOR_D8:
93 case OPERATOR_D9:
94 case OPERATOR_D10: {
95 const ordinal_type dkcard = getDkCardinality<OpType,spaceDim>(); //(orDn + 1);
96 const ViewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts, dkcard);
97 ViewType dummyView;
98
99 Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::
100 Serial<OpType>::getValues(phis, input, dummyView, order);
101
102 for (ordinal_type i=0;i<card;++i)
103 for (ordinal_type j=0;j<npts;++j)
104 for (ordinal_type k=0;k<dkcard;++k) {
105 output.access(i,j,k) = 0.0;
106 for (ordinal_type l=0;l<card;++l)
107 output.access(i,j,k) += vinv(l,i)*phis.access(l,j,k);
108 }
109 break;
110 }
111 default: {
112 INTREPID2_TEST_FOR_ABORT( true,
113 ">>> ERROR (Basis_HGRAD_TET_Cn_FEM): Operator type not implemented");
114 }
115 }
116}
117
118template<typename DT, ordinal_type numPtsPerEval,
119typename outputValueValueType, class ...outputValueProperties,
120typename inputPointValueType, class ...inputPointProperties,
121typename vinvValueType, class ...vinvProperties>
122void
123Basis_HGRAD_TET_Cn_FEM::
124getValues(
125 const typename DT::execution_space& space,
126 Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
127 const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
128 const Kokkos::DynRankView<vinvValueType, vinvProperties...> vinv,
129 const ordinal_type order,
130 const EOperator operatorType) {
131 typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
132 typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
133 typedef Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvViewType;
134 typedef typename ExecSpace<typename inputPointViewType::execution_space,typename DT::execution_space>::ExecSpaceType ExecSpaceType;
135
136 // loopSize corresponds to cardinality
137 const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
138 const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
139 const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
140 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(space, 0, loopSize);
141
142 typedef typename inputPointViewType::value_type inputPointType;
143
144 const ordinal_type cardinality = outputValues.extent(0);
145 const ordinal_type spaceDim = 3;
146
147 auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
148 typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
149
150 switch (operatorType) {
151 case OPERATOR_VALUE: {
152 workViewType work(Kokkos::view_alloc(space, "Basis_HGRAD_TET_Cn_FEM::getValues::work", vcprop), cardinality, inputPoints.extent(0));
153 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
154 OPERATOR_VALUE,numPtsPerEval> FunctorType;
155 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work, order) );
156 break;
157 }
158 case OPERATOR_GRAD:
159 case OPERATOR_D1: {
160 workViewType work(Kokkos::view_alloc(space, "Basis_HGRAD_TET_Cn_FEM::getValues::work", vcprop), cardinality*(2*spaceDim+1), inputPoints.extent(0));
161 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
162 OPERATOR_D1,numPtsPerEval> FunctorType;
163 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work, order) );
164 break;
165 }
166 case OPERATOR_D2: {
167 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
168 OPERATOR_D2,numPtsPerEval> FunctorType;
169 workViewType work(Kokkos::view_alloc(space, "Basis_HGRAD_TET_Cn_FEM::getValues::work", vcprop), cardinality*outputValues.extent(2), inputPoints.extent(0));
170 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work, order) );
171 break;
172 }
173 default: {
174 INTREPID2_TEST_FOR_EXCEPTION( true , std::invalid_argument,
175 ">>> ERROR (Basis_HGRAD_TET_Cn_FEM): Operator type not implemented" );
176 }
177 }
178}
179}
180
181// -------------------------------------------------------------------------------------
182template<typename DT, typename OT, typename PT>
184Basis_HGRAD_TET_Cn_FEM( const ordinal_type order,
185 const EPointType pointType ) {
186 constexpr ordinal_type spaceDim = 3;
187
188 this->basisCardinality_ = Intrepid2::getPnCardinality<spaceDim>(order); // bigN
189 this->basisDegree_ = order; // small n
190 this->basisCellTopologyKey_ = shards::Tetrahedron<4>::key;
191 this->basisType_ = BASIS_FEM_LAGRANGIAN;
192 this->basisCoordinates_ = COORDINATES_CARTESIAN;
193 this->functionSpace_ = FUNCTION_SPACE_HGRAD;
194 pointType_ = (pointType == POINTTYPE_DEFAULT) ? POINTTYPE_EQUISPACED : pointType;
195
196 const ordinal_type card = this->basisCardinality_;
197
198 // points are computed in the host and will be copied
199 Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
200 dofCoords("Hgrad::Tet::Cn::dofCoords", card, spaceDim);
201
202 // Note: the only reason why equispaced can't support higher order than Parameters::MaxOrder appears to be the fact that the tags below get stored into a fixed-length array.
203 // TODO: relax the maximum order requirement by setting up tags in a different container, perhaps directly into an OrdinalTypeArray1DHost (tagView, below). (As of this writing (1/25/22), looks like other nodal bases do this in a similar way -- those should be fixed at the same time; maybe search for Parameters::MaxOrder.)
204 INTREPID2_TEST_FOR_EXCEPTION( order > Parameters::MaxOrder, std::invalid_argument, "polynomial order exceeds the max supported by this class");
205
206 // Basis-dependent initializations
207 constexpr ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag
208 constexpr ordinal_type maxCard = Intrepid2::getPnCardinality<spaceDim, Parameters::MaxOrder>();
209 ordinal_type tags[maxCard][tagSize];
210
211 // construct lattice
212
213 shards::CellTopology cellTopo(shards::getCellTopologyData<shards::Tetrahedron<4> >() );
214 const ordinal_type numEdges = cellTopo.getEdgeCount();
215 const ordinal_type numFaces = cellTopo.getFaceCount();
216
217 shards::CellTopology edgeTopo(shards::getCellTopologyData<shards::Line<2> >() );
218 shards::CellTopology faceTopo(shards::getCellTopologyData<shards::Triangle<3> >() );
219
220 const int numVertexes = PointTools::getLatticeSize( cellTopo ,
221 1 ,
222 0 );
223
224 const int numPtsPerEdge = PointTools::getLatticeSize( edgeTopo ,
225 order ,
226 1 );
227
228 const int numPtsPerFace = PointTools::getLatticeSize( faceTopo ,
229 order ,
230 1 );
231
232 const int numPtsPerCell = PointTools::getLatticeSize( cellTopo ,
233 order ,
234 1 );
235
236 Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> vertexes("Hcurl::Tet::In::vertexes", numVertexes , spaceDim );
237 Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> linePts("Hcurl::Tet::In::linePts", numPtsPerEdge , 1 );
238 Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> triPts("Hcurl::Tet::In::triPts", numPtsPerFace , 2 );
239
240 // construct lattice
241 const ordinal_type offset = 1;
242
243
244 PointTools::getLattice( vertexes,
245 cellTopo ,
246 1, 0,
247 this->pointType_ );
248
249 PointTools::getLattice( linePts,
250 edgeTopo,
251 order, offset,
252 this->pointType_ );
253
255 faceTopo,
256 order, offset,
257 this->pointType_ );
258
259 // holds the image of the line points
260 Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> edgePts("Hcurl::Tet::In::edgePts", numPtsPerEdge , spaceDim );
261 Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> facePts("Hcurl::Tet::In::facePts", numPtsPerFace , spaceDim );
262
263 for (ordinal_type i=0;i<numVertexes;i++) {
264 auto i_card=i;
265 for(ordinal_type k=0; k<spaceDim; ++k)
266 dofCoords(i_card,k) = vertexes(i,k);
267 tags[i_card][0] = 0; // vertex dof
268 tags[i_card][1] = i; // vertex id
269 tags[i_card][2] = 0; // local dof id
270 tags[i_card][3] = 1; // total vert dof
271 }
272
273
274 // these are tangents scaled by the appropriate edge lengths.
275 for (ordinal_type i=0;i<numEdges;i++) { // loop over edges
277 linePts ,
278 1 ,
279 i ,
280 cellTopo );
281
282
283 // loop over points (rows of V2)
284 for (ordinal_type j=0;j<numPtsPerEdge;j++) {
285
286 const ordinal_type i_card = numVertexes + numPtsPerEdge*i+j;
287
288 //save dof coordinates and coefficients
289 for(ordinal_type k=0; k<spaceDim; ++k)
290 dofCoords(i_card,k) = edgePts(j,k);
291
292 tags[i_card][0] = 1; // edge dof
293 tags[i_card][1] = i; // edge id
294 tags[i_card][2] = j; // local dof id
295 tags[i_card][3] = numPtsPerEdge; // total edge dof
296
297 }
298 }
299
300 if(numPtsPerFace >0) {//handle faces if needed (order >1)
301
302 for (ordinal_type i=0;i<numFaces;i++) { // loop over faces
303
305 triPts ,
306 2 ,
307 i ,
308 cellTopo );
309 for (ordinal_type j=0;j<numPtsPerFace;j++) {
310
311 const ordinal_type i_card = numVertexes+numEdges*numPtsPerEdge+numPtsPerFace*i+j;
312
313 //save dof coordinates
314 for(ordinal_type k=0; k<spaceDim; ++k)
315 dofCoords(i_card,k) = facePts(j,k);
316
317 tags[i_card][0] = 2; // face dof
318 tags[i_card][1] = i; // face id
319 tags[i_card][2] = j; // local face id
320 tags[i_card][3] = numPtsPerFace; // total face dof
321 }
322 }
323 }
324
325
326 // internal dof, if needed
327 if (numPtsPerCell > 0) {
328 Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
329 cellPoints( "Hcurl::Tet::In::cellPoints", numPtsPerCell , spaceDim );
330 PointTools::getLattice( cellPoints ,
331 cellTopo ,
332 order,
333 1 ,
334 this->pointType_ );
335
336 // copy values into right positions of V2
337 for (ordinal_type j=0;j<numPtsPerCell;j++) {
338
339 const ordinal_type i_card = numVertexes+numEdges*numPtsPerEdge+numFaces*numPtsPerFace+j;
340
341 //save dof coordinates
342 for(ordinal_type dim=0; dim<spaceDim; ++dim)
343 dofCoords(i_card,dim) = cellPoints(j,dim);
344
345 tags[i_card][0] = spaceDim; // elem dof
346 tags[i_card][1] = 0; // elem id
347 tags[i_card][2] = j; // local dof id
348 tags[i_card][3] = numPtsPerCell; // total vert dof
349 }
350 }
351
352 this->dofCoords_ = Kokkos::create_mirror_view(typename DT::memory_space(), dofCoords);
353 Kokkos::deep_copy(this->dofCoords_, dofCoords);
354
355 // form Vandermonde matrix. Actually, this is the transpose of the VDM,
356 // so we transpose on copy below.
357 const ordinal_type lwork = card*card;
358 Kokkos::DynRankView<scalarType,Kokkos::LayoutLeft,Kokkos::HostSpace>
359 vmat("Hgrad::Tet::Cn::vmat", card, card),
360 work("Hgrad::Tet::Cn::work", lwork),
361 ipiv("Hgrad::Tet::Cn::ipiv", card);
362
363 Impl::Basis_HGRAD_TET_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>(typename Kokkos::HostSpace::execution_space{},
364 vmat,
365 dofCoords,
366 order,
367 OPERATOR_VALUE);
368
369 ordinal_type info = 0;
370 Teuchos::LAPACK<ordinal_type,scalarType> lapack;
371
372 lapack.GETRF(card, card,
373 vmat.data(), vmat.stride(1),
374 (ordinal_type*)ipiv.data(),
375 &info);
376
377 INTREPID2_TEST_FOR_EXCEPTION( info != 0,
378 std::runtime_error ,
379 ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_Cn_FEM) lapack.GETRF returns nonzero info." );
380
381 lapack.GETRI(card,
382 vmat.data(), vmat.stride(1),
383 (ordinal_type*)ipiv.data(),
384 work.data(), lwork,
385 &info);
386
387 INTREPID2_TEST_FOR_EXCEPTION( info != 0,
388 std::runtime_error ,
389 ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_Cn_FEM) lapack.GETRI returns nonzero info." );
390
391 // create host mirror
392 Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
393 vinv("Hgrad::Line::Cn::vinv", card, card);
394
395 for (ordinal_type i=0;i<card;++i)
396 for (ordinal_type j=0;j<card;++j)
397 vinv(i,j) = vmat(j,i);
398
399 this->vinv_ = Kokkos::create_mirror_view(typename DT::memory_space(), vinv);
400 Kokkos::deep_copy(this->vinv_ , vinv);
401
402 // initialize tags
403 {
404 // Basis-dependent initializations
405 const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim
406 const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal
407 const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell
408
409 OrdinalTypeArray1DHost tagView(&tags[0][0], card*tagSize);
410
411 // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays:
412 // tags are constructed on host
413 this->setOrdinalTagData(this->tagToOrdinal_,
414 this->ordinalToTag_,
415 tagView,
416 this->basisCardinality_,
417 tagSize,
418 posScDim,
419 posScOrd,
420 posDfOrd);
421 }
422}
423
424 template<typename DT, typename OT, typename PT>
425 void
427 ordinal_type& perTeamSpaceSize,
428 ordinal_type& perThreadSpaceSize,
429 const PointViewType inputPoints,
430 const EOperator operatorType) const {
431 perTeamSpaceSize = 0;
432 perThreadSpaceSize = getWorkSizePerPoint(operatorType)*get_dimension_scalar(inputPoints)*sizeof(typename BasisBase::scalarType);
433 }
434
435 template<typename DT, typename OT, typename PT>
436 KOKKOS_INLINE_FUNCTION
437 void
439 OutputViewType outputValues,
440 const PointViewType inputPoints,
441 const EOperator operatorType,
442 const typename Kokkos::TeamPolicy<typename DT::execution_space>::member_type& team_member,
443 const typename DT::execution_space::scratch_memory_space & scratchStorage,
444 const ordinal_type subcellDim,
445 const ordinal_type subcellOrdinal) const {
446
447 INTREPID2_TEST_FOR_ABORT( !((subcellDim == -1) && (subcellOrdinal == -1)),
448 ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_Cn_FEM::getValues), The capability of selecting subsets of basis functions has not been implemented yet.");
449
450 const int numPoints = inputPoints.extent(0);
451 using ScalarType = typename ScalarTraits<typename PointViewType::value_type>::scalar_type;
452 using WorkViewType = Kokkos::DynRankView< ScalarType,typename DT::execution_space::scratch_memory_space,Kokkos::MemoryTraits<Kokkos::Unmanaged> >;
453 constexpr ordinal_type spaceDim = 3;
454 auto sizePerPoint = (operatorType==OPERATOR_VALUE) ?
455 this->vinv_.extent(0)*get_dimension_scalar(inputPoints) :
456 (2*spaceDim+1)*this->vinv_.extent(0)*get_dimension_scalar(inputPoints);
457 WorkViewType workView(scratchStorage, sizePerPoint*team_member.team_size());
458 using range_type = Kokkos::pair<ordinal_type,ordinal_type>;
459 switch(operatorType) {
460 case OPERATOR_VALUE:
461 Kokkos::parallel_for (Kokkos::TeamThreadRange (team_member, numPoints), [=, &vinv_ = this->vinv_, basisDegree_ = this->basisDegree_] (ordinal_type& pt) {
462 auto output = Kokkos::subview( outputValues, Kokkos::ALL(), range_type (pt,pt+1), Kokkos::ALL() );
463 const auto input = Kokkos::subview( inputPoints, range_type(pt, pt+1), Kokkos::ALL() );
464 WorkViewType work(workView.data() + sizePerPoint*team_member.team_rank(), sizePerPoint);
465 Impl::Basis_HGRAD_TET_Cn_FEM::Serial<OPERATOR_VALUE>::getValues( output, input, work, vinv_, basisDegree_);
466 });
467 break;
468 case OPERATOR_GRAD:
469 Kokkos::parallel_for (Kokkos::TeamThreadRange (team_member, numPoints), [=, &vinv_ = this->vinv_, basisDegree_ = this->basisDegree_] (ordinal_type& pt) {
470 auto output = Kokkos::subview( outputValues, Kokkos::ALL(), range_type(pt,pt+1), Kokkos::ALL() );
471 const auto input = Kokkos::subview( inputPoints, range_type(pt,pt+1), Kokkos::ALL() );
472 WorkViewType work(workView.data() + sizePerPoint*team_member.team_rank(), sizePerPoint);
473 Impl::Basis_HGRAD_TET_Cn_FEM::Serial<OPERATOR_GRAD>::getValues( output, input, work, vinv_, basisDegree_);
474 });
475 break;
476 default: {
477 INTREPID2_TEST_FOR_ABORT( true,
478 ">>> ERROR (Basis_HGRAD_TET_Cn_FEM): getValues not implemented for this operator");
479 }
480 }
481 }
482
483} // namespace Intrepid2
484#endif
Header file for the Intrepid2::Basis_HGRAD_TET_Cn_FEM class.
Header file for the Intrepid2::Basis_HGRAD_TET_Cn_FEM_ORTH class.
virtual void getScratchSpaceSize(ordinal_type &perTeamSpaceSize, ordinal_type &perThreadSpaceSize, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Return the size of the scratch space, in bytes, needed for using the team-level implementation of get...
virtual void getValues(const ExecutionSpace &space, OutputViewType outputValues, const PointViewType inputPoints, const EOperator operatorType=OPERATOR_VALUE) const override
Evaluation of a FEM basis on a reference cell.
Basis_HGRAD_TET_Cn_FEM(const ordinal_type order, const EPointType pointType=POINTTYPE_EQUISPACED)
Constructor.
Kokkos::DynRankView< PointValueType, Kokkos::LayoutStride, DeviceType > PointViewType
View type for input points.
ScalarTraits< pointValueType >::scalar_type scalarType
Scalar type for point values.
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
static void mapToReferenceSubcell(refSubcellViewType refSubcellPoints, const paramPointViewType paramPoints, const ordinal_type subcellDim, const ordinal_type subcellOrd, const shards::CellTopology parentCell)
Computes parameterization maps of 1- and 2-subcells of reference cells.
static constexpr ordinal_type MaxOrder
The maximum reconstruction order.
static ordinal_type getLatticeSize(const shards::CellTopology cellType, const ordinal_type order, const ordinal_type offset=0)
Computes the number of points in a lattice of a given order on a simplex (currently disabled for othe...
static void getLattice(Kokkos::DynRankView< pointValueType, pointProperties... > points, const shards::CellTopology cellType, const ordinal_type order, const ordinal_type offset=0, const EPointType pointType=POINTTYPE_EQUISPACED)
Computes a lattice of points of a given order on a reference simplex, quadrilateral or hexahedron (cu...