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