Intrepid2
Intrepid2_HCURL_TRI_In_FEMDef.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), or
38 // Mauro Perego (mperego@sandia.gov)
39 //
40 // ************************************************************************
41 // @HEADER
42 
49 #ifndef __INTREPID2_HCURL_TRI_IN_FEM_DEF_HPP__
50 #define __INTREPID2_HCURL_TRI_IN_FEM_DEF_HPP__
51 
54 
55 namespace Intrepid2 {
56 
57  // -------------------------------------------------------------------------------------
58 
59  namespace Impl {
60 
61  template<EOperator opType>
62  template<typename OutputViewType,
63  typename inputViewType,
64  typename workViewType,
65  typename vinvViewType>
66  KOKKOS_INLINE_FUNCTION
67  void
68  Basis_HCURL_TRI_In_FEM::Serial<opType>::
69  getValues( OutputViewType output,
70  const inputViewType input,
71  workViewType work,
72  const vinvViewType coeffs ) {
73 
74  constexpr ordinal_type spaceDim = 2;
75  const ordinal_type
76  cardPn = coeffs.extent(0)/spaceDim,
77  card = coeffs.extent(1),
78  npts = input.extent(0);
79 
80  // compute order
81  ordinal_type order = 0;
82  for (ordinal_type p=0;p<=Parameters::MaxOrder;++p) {
83  if (card == CardinalityHCurlTri(p)) {
84  order = p;
85  break;
86  }
87  }
88 
89  typedef typename Kokkos::DynRankView<typename workViewType::value_type, typename workViewType::memory_space> viewType;
90  auto vcprop = Kokkos::common_view_alloc_prop(work);
91  auto ptr = work.data();
92 
93  switch (opType) {
94  case OPERATOR_VALUE: {
95  const viewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts);
96  workViewType dummyView;
97 
98  Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::
99  Serial<opType>::getValues(phis, input, dummyView, order);
100 
101  for (ordinal_type i=0;i<card;++i)
102  for (ordinal_type j=0;j<npts;++j)
103  for (ordinal_type d=0;d<spaceDim;++d) {
104  output.access(i,j,d) = 0.0;
105  for (ordinal_type k=0;k<cardPn;++k)
106  output.access(i,j,d) += coeffs(k+d*cardPn,i) * phis(k,j);
107  }
108  break;
109  }
110  case OPERATOR_CURL: {
111  const viewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts, spaceDim);
112  ptr += card*npts*spaceDim*get_dimension_scalar(work);
113  const viewType workView(Kokkos::view_wrap(ptr, vcprop), card, npts, spaceDim+1);
114 
115  Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::
116  Serial<OPERATOR_GRAD>::getValues(phis, input, workView, order);
117 
118  for (ordinal_type i=0;i<card;++i)
119  for (ordinal_type j=0;j<npts;++j) {
120  output.access(i,j) = 0.0;
121  for (ordinal_type k=0; k<cardPn; ++k)
122  output.access(i,j) += - coeffs(k,i)*phis(k,j,1) // - dy of x component
123  + coeffs(k+cardPn,i)*phis(k,j,0); // dx of y component
124  }
125  break;
126  }
127  default: {
128  INTREPID2_TEST_FOR_ABORT( true,
129  ">>> ERROR (Basis_HCURL_TRI_In_FEM): Operator type not implemented");
130  }
131  }
132  }
133 
134  template<typename DT, ordinal_type numPtsPerEval,
135  typename outputValueValueType, class ...outputValueProperties,
136  typename inputPointValueType, class ...inputPointProperties,
137  typename vinvValueType, class ...vinvProperties>
138  void
139  Basis_HCURL_TRI_In_FEM::
140  getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
141  const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
142  const Kokkos::DynRankView<vinvValueType, vinvProperties...> coeffs,
143  const EOperator operatorType) {
144  typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
145  typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
146  typedef Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvViewType;
147  typedef typename ExecSpace<typename inputPointViewType::execution_space,typename DT::execution_space>::ExecSpaceType ExecSpaceType;
148 
149  // loopSize corresponds to cardinality
150  const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
151  const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
152  const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
153  Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
154 
155  typedef typename inputPointViewType::value_type inputPointType;
156 
157  const ordinal_type cardinality = outputValues.extent(0);
158  const ordinal_type spaceDim = 2;
159 
160  auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
161  typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
162 
163  switch (operatorType) {
164  case OPERATOR_VALUE: {
165  workViewType work(Kokkos::view_alloc("Basis_HCURL_TRI_In_FEM::getValues::work", vcprop), cardinality, inputPoints.extent(0));
166  typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
167  OPERATOR_VALUE,numPtsPerEval> FunctorType;
168  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, coeffs, work) );
169  break;
170  }
171  case OPERATOR_CURL: {
172  workViewType work(Kokkos::view_alloc("Basis_HCURL_TRI_In_FEM::getValues::work", vcprop), cardinality*(2*spaceDim+1), inputPoints.extent(0));
173  typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
174  OPERATOR_CURL,numPtsPerEval> FunctorType;
175  Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, coeffs, work) );
176  break;
177  }
178  default: {
179  INTREPID2_TEST_FOR_EXCEPTION( true , std::invalid_argument,
180  ">>> ERROR (Basis_HCURL_TRI_In_FEM): Operator type not implemented" );
181  }
182  }
183  }
184  }
185 
186  // -------------------------------------------------------------------------------------
187  template<typename DT, typename OT, typename PT>
189  Basis_HCURL_TRI_In_FEM( const ordinal_type order,
190  const EPointType pointType ) {
191 
192  constexpr ordinal_type spaceDim = 2;
193  this->basisCardinality_ = CardinalityHCurlTri(order);
194  this->basisDegree_ = order; // small n
195  this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() );
196  this->basisType_ = BASIS_FEM_LAGRANGIAN;
197  this->basisCoordinates_ = COORDINATES_CARTESIAN;
198  this->functionSpace_ = FUNCTION_SPACE_HCURL;
199  pointType_ = pointType;
200 
201  const ordinal_type card = this->basisCardinality_;
202 
203  const ordinal_type cardPn = Intrepid2::getPnCardinality<spaceDim>(order); // dim of (P_{n}) -- smaller space
204  const ordinal_type cardPnm1 = Intrepid2::getPnCardinality<spaceDim>(order-1); // dim of (P_{n-1}) -- smaller space
205  const ordinal_type cardPnm2 = Intrepid2::getPnCardinality<spaceDim>(order-2); // dim of (P_{n-2}) -- smaller space
206  const ordinal_type cardVecPn = spaceDim*cardPn; // dim of (P_{n})^2 -- larger space
207  const ordinal_type cardVecPnm1 = spaceDim*cardPnm1; // dim of (P_{n-1})^2 -- smaller space
208 
209 
210  // Basis-dependent initializations
211  constexpr ordinal_type tagSize = 4; // size of DoF tag, i.e., number of fields in the tag
212  constexpr ordinal_type maxCard = CardinalityHCurlTri(Parameters::MaxOrder);
213  ordinal_type tags[maxCard][tagSize];
214 
215  // points are computed in the host and will be copied
216  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
217  dofCoords("Hcurl::Tri::In::dofCoords", card, spaceDim);
218 
219  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
220  coeffs("Hcurl::Tri::In::coeffs", cardVecPn, card);
221 
222  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
223  dofCoeffs("Hcurl::Tri::In::dofCoeffs", card, spaceDim);
224 
225  // first, need to project the basis for RT space onto the
226  // orthogonal basis of degree n
227  // get coefficients of PkHx
228 
229  const ordinal_type lwork = card*card;
230  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
231  V1("Hcurl::Tri::In::V1", cardVecPn, card);
232 
233  // basis for the space is
234  // { (phi_i,0) }_{i=0}^{cardPnm1-1} ,
235  // { (0,phi_i) }_{i=0}^{cardPnm1-1} ,
236  // { (x,y) \times phi_i}_{i=cardPnm2}^{cardPnm1-1}
237  // { (x,y) \times phi = (y phi , -x \phi)
238  // columns of V1 are expansion of this basis in terms of the basis
239  // for P_{n}^2
240 
241  // these two loops get the first two sets of basis functions
242  for (ordinal_type i=0;i<cardPnm1;i++)
243  for (ordinal_type d=0;d<spaceDim;d++)
244  V1(d*cardPn+i,d*cardPnm1+i) = 1.0;
245 
246 
247  // now I need to integrate { (x,y) \times phi } against the big basis
248  // first, get a cubature rule.
250  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> cubPoints("Hcurl::Tri::In::cubPoints", myCub.getNumPoints() , spaceDim );
251  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> cubWeights("Hcurl::Tri::In::cubWeights", myCub.getNumPoints() );
252  myCub.getCubature( cubPoints , cubWeights );
253 
254  // tabulate the scalar orthonormal basis at cubature points
255  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> phisAtCubPoints("Hcurl::Tri::In::phisAtCubPoints", cardPn , myCub.getNumPoints() );
256  Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>(phisAtCubPoints, cubPoints, order, OPERATOR_VALUE);
257 
258  // now do the integration
259  for (ordinal_type i=0;i<order;i++) {
260  for (ordinal_type j=0;j<cardPn;j++) { // int (x,y) phi_i \cdot (phi_j,phi_{j+cardPn})
261  for (ordinal_type k=0;k<myCub.getNumPoints();k++) {
262  V1(j,cardVecPnm1+i) -=
263  cubWeights(k) * cubPoints(k,1)
264  * phisAtCubPoints(cardPnm2+i,k)
265  * phisAtCubPoints(j,k);
266  V1(j+cardPn,cardVecPnm1+i) +=
267  cubWeights(k) * cubPoints(k,0)
268  * phisAtCubPoints(cardPnm2+i,k)
269  * phisAtCubPoints(j,k);
270  }
271  }
272  }
273 
274  // next, apply the RT nodes (rows) to the basis for (P_n)^2 (columns)
275  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
276  V2("Hcurl::Tri::In::V2", card ,cardVecPn);
277 
278  const ordinal_type numEdges = this->basisCellTopology_.getEdgeCount();
279 
280  shards::CellTopology edgeTop(shards::getCellTopologyData<shards::Line<2> >() );
281 
282  const int numPtsPerEdge = PointTools::getLatticeSize( edgeTop ,
283  order+1 ,
284  1 );
285 
286  // first numEdges * degree nodes are tangents at each edge
287  // get the points on the line
288  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> linePts("Hcurl::Tri::In::linePts", numPtsPerEdge , 1 );
289 
290  // construct lattice
291  const ordinal_type offset = 1;
292  PointTools::getLattice( linePts,
293  edgeTop,
294  order+1, offset,
295  pointType );
296 
297  // holds the image of the line points
298  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> edgePts("Hcurl::Tri::In::edgePts", numPtsPerEdge , spaceDim );
299  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> phisAtEdgePoints("Hcurl::Tri::In::phisAtEdgePoints", cardPn , numPtsPerEdge );
300  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace> edgeTan("Hcurl::Tri::In::edgeTan", spaceDim );
301 
302  // these are tangents scaled by the appropriate edge lengths.
303  for (ordinal_type edge=0;edge<numEdges;edge++) { // loop over edges
305  edge ,
306  this->basisCellTopology_ );
307 
309  linePts ,
310  1 ,
311  edge ,
312  this->basisCellTopology_ );
313 
314  Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>(phisAtEdgePoints , edgePts, order, OPERATOR_VALUE);
315 
316  // loop over points (rows of V2)
317  for (ordinal_type j=0;j<numPtsPerEdge;j++) {
318 
319  const ordinal_type i_card = numPtsPerEdge*edge+j;
320 
321  // loop over orthonormal basis functions (columns of V2)
322  for (ordinal_type k=0;k<cardPn;k++) {
323  V2(i_card,k) = edgeTan(0) * phisAtEdgePoints(k,j);
324  V2(i_card,k+cardPn) = edgeTan(1) * phisAtEdgePoints(k,j);
325  }
326 
327 
328  //save dof coordinates
329  for(ordinal_type k=0; k<spaceDim; ++k) {
330  dofCoords(i_card,k) = edgePts(j,k);
331  dofCoeffs(i_card,k) = edgeTan(k);
332  }
333 
334  tags[i_card][0] = 1; // edge dof
335  tags[i_card][1] = edge; // edge id
336  tags[i_card][2] = j; // local dof id
337  tags[i_card][3] = numPtsPerEdge; // total edge dof
338 
339  }
340 
341 
342  }
343 
344  // remaining nodes are x- and y- components at internal points (this code is same as HDIV).
345  //These are evaluated at the interior of a lattice of degree + 1, For then
346  // the degree == 1 space corresponds classicaly to RT0 and so gets
347  // no internal nodes, and degree == 2 corresponds to RT1 and needs
348  // one internal node per vector component.
349  const ordinal_type numPtsPerCell = PointTools::getLatticeSize( this->basisCellTopology_ ,
350  order + 1 ,
351  1 );
352 
353  if (numPtsPerCell > 0) {
354  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
355  internalPoints( "Hcurl::Tri::In::internalPoints", numPtsPerCell , spaceDim );
356  PointTools::getLattice( internalPoints ,
357  this->basisCellTopology_ ,
358  order + 1 ,
359  1 ,
360  pointType );
361 
362  Kokkos::DynRankView<scalarType,typename DT::execution_space::array_layout,Kokkos::HostSpace>
363  phisAtInternalPoints("Hcurl::Tri::In::phisAtInternalPoints", cardPn , numPtsPerCell );
364  Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>( phisAtInternalPoints , internalPoints , order, OPERATOR_VALUE );
365 
366  // copy values into right positions of V2
367  for (ordinal_type j=0;j<numPtsPerCell;j++) {
368 
369  const ordinal_type i_card = numEdges*order+spaceDim*j;
370 
371  for (ordinal_type k=0;k<cardPn;k++) {
372  // x component
373  V2(i_card,k) = phisAtInternalPoints(k,j);
374  // y component
375  V2(i_card+1,cardPn+k) = phisAtInternalPoints(k,j);
376  }
377 
378  //save dof coordinates
379  for(ordinal_type d=0; d<spaceDim; ++d) {
380  for(ordinal_type dim=0; dim<spaceDim; ++dim) {
381  dofCoords(i_card+d,dim) = internalPoints(j,dim);
382  dofCoeffs(i_card+d,dim) = (d==dim);
383  }
384 
385  tags[i_card+d][0] = spaceDim; // elem dof
386  tags[i_card+d][1] = 0; // elem id
387  tags[i_card+d][2] = spaceDim*j+d; // local dof id
388  tags[i_card+d][3] = spaceDim*numPtsPerCell; // total vert dof
389  }
390  }
391  }
392 
393  // form Vandermonde matrix. Actually, this is the transpose of the VDM,
394  // so we transpose on copy below.
395  Kokkos::DynRankView<scalarType,Kokkos::LayoutLeft,Kokkos::HostSpace>
396  vmat("Hcurl::Tri::In::vmat", card, card),
397  work("Hcurl::Tri::In::work", lwork),
398  ipiv("Hcurl::Tri::In::ipiv", card);
399 
400  //vmat' = V2*V1;
401  for(ordinal_type i=0; i< card; ++i) {
402  for(ordinal_type j=0; j< card; ++j) {
403  scalarType s=0;
404  for(ordinal_type k=0; k< cardVecPn; ++k)
405  s += V2(i,k)*V1(k,j);
406  vmat(i,j) = s;
407  }
408  }
409 
410  ordinal_type info = 0;
411  Teuchos::LAPACK<ordinal_type,scalarType> lapack;
412 
413  lapack.GETRF(card, card,
414  vmat.data(), vmat.stride_1(),
415  (ordinal_type*)ipiv.data(),
416  &info);
417 
418  INTREPID2_TEST_FOR_EXCEPTION( info != 0,
419  std::runtime_error ,
420  ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_In_FEM) lapack.GETRF returns nonzero info." );
421 
422  lapack.GETRI(card,
423  vmat.data(), vmat.stride_1(),
424  (ordinal_type*)ipiv.data(),
425  work.data(), lwork,
426  &info);
427 
428  INTREPID2_TEST_FOR_EXCEPTION( info != 0,
429  std::runtime_error ,
430  ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_In_FEM) lapack.GETRI returns nonzero info." );
431 
432  for (ordinal_type i=0;i<cardVecPn;++i)
433  for (ordinal_type j=0;j<card;++j){
434  scalarType s=0;
435  for(ordinal_type k=0; k< card; ++k)
436  s += V1(i,k)*vmat(k,j);
437  coeffs(i,j) = s;
438  }
439 
440  this->coeffs_ = Kokkos::create_mirror_view(typename DT::memory_space(), coeffs);
441  Kokkos::deep_copy(this->coeffs_ , coeffs);
442 
443  this->dofCoords_ = Kokkos::create_mirror_view(typename DT::memory_space(), dofCoords);
444  Kokkos::deep_copy(this->dofCoords_, dofCoords);
445 
446  this->dofCoeffs_ = Kokkos::create_mirror_view(typename DT::memory_space(), dofCoeffs);
447  Kokkos::deep_copy(this->dofCoeffs_, dofCoeffs);
448 
449 
450  // set tags
451  {
452  // Basis-dependent initializations
453  const ordinal_type posScDim = 0; // position in the tag, counting from 0, of the subcell dim
454  const ordinal_type posScOrd = 1; // position in the tag, counting from 0, of the subcell ordinal
455  const ordinal_type posDfOrd = 2; // position in the tag, counting from 0, of DoF ordinal relative to the subcell
456 
457  OrdinalTypeArray1DHost tagView(&tags[0][0], card*tagSize);
458 
459  // Basis-independent function sets tag and enum data in tagToOrdinal_ and ordinalToTag_ arrays:
460  // tags are constructed on host
461  this->setOrdinalTagData(this->tagToOrdinal_,
462  this->ordinalToTag_,
463  tagView,
464  this->basisCardinality_,
465  tagSize,
466  posScDim,
467  posScOrd,
468  posDfOrd);
469  }
470  }
471 } // namespace Intrepid2
472 #endif
Header file for the Intrepid2::Basis_HGRAD_TRI_Cn_FEM_ORTH class.
static void getReferenceEdgeTangent(Kokkos::DynRankView< refEdgeTangentValueType, refEdgeTangentProperties... > refEdgeTangent, const ordinal_type edgeOrd, const shards::CellTopology parentCell)
Computes constant tangent vectors to edges of 2D or 3D reference cells.
virtual void getCubature(PointViewType cubPoints, weightViewType cubWeights) const override
Returns cubature points and weights (return arrays must be pre-sized/pre-allocated).
Basis_HCURL_TRI_In_FEM(const ordinal_type order, const EPointType pointType=POINTTYPE_EQUISPACED)
Constructor.
Header file for the Intrepid2::CubatureDirectTriDefault class.
Defines direct integration rules on a triangle.
virtual ordinal_type getNumPoints() const override
Returns the number of cubature points.
static void mapToReferenceSubcell(Kokkos::DynRankView< refSubcellPointValueType, refSubcellPointProperties... > refSubcellPoints, const Kokkos::DynRankView< paramPointValueType, paramPointProperties... > paramPoints, const ordinal_type subcellDim, const ordinal_type subcellOrd, const shards::CellTopology parentCell)
Computes parameterization maps of 1- and 2-subcells of reference cells.
EPointType
Enumeration of types of point distributions in Intrepid.
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...
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...