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