49 #ifndef __INTREPID2_HCURL_HEX_IN_FEM_DEF_HPP__
50 #define __INTREPID2_HCURL_HEX_IN_FEM_DEF_HPP__
57 template<EOperator opType>
58 template<
typename OutputViewType,
59 typename inputViewType,
60 typename workViewType,
61 typename vinvViewType>
62 KOKKOS_INLINE_FUNCTION
64 Basis_HCURL_HEX_In_FEM::Serial<opType>::
65 getValues( OutputViewType output,
66 const inputViewType input,
68 const vinvViewType vinvLine,
69 const vinvViewType vinvBubble) {
70 const ordinal_type cardLine = vinvLine.extent(0);
71 const ordinal_type cardBubble = vinvBubble.extent(0);
73 const ordinal_type npts = input.extent(0);
75 typedef Kokkos::pair<ordinal_type,ordinal_type> range_type;
76 const auto input_x = Kokkos::subview(input, Kokkos::ALL(), range_type(0,1));
77 const auto input_y = Kokkos::subview(input, Kokkos::ALL(), range_type(1,2));
78 const auto input_z = Kokkos::subview(input, Kokkos::ALL(), range_type(2,3));
80 const ordinal_type dim_s = get_dimension_scalar(work);
81 auto ptr0 = work.data();
82 auto ptr1 = work.data() + cardLine*npts*dim_s;
83 auto ptr2 = work.data() + 2*cardLine*npts*dim_s;
84 auto ptr3 = work.data() + 3*cardLine*npts*dim_s;
86 typedef typename Kokkos::DynRankView<typename workViewType::value_type, typename workViewType::memory_space> viewType;
87 auto vcprop = Kokkos::common_view_alloc_prop(work);
90 case OPERATOR_VALUE: {
92 viewType workLine(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
93 viewType outputLine_A(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts);
94 viewType outputLine_B(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts);
95 viewType outputBubble(Kokkos::view_wrap(ptr3, vcprop), cardBubble, npts);
100 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
101 getValues(outputBubble, input_x, workLine, vinvBubble);
103 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
104 getValues(outputLine_A, input_y, workLine, vinvLine);
106 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
107 getValues(outputLine_B, input_z, workLine, vinvLine);
110 const auto output_x = outputBubble;
111 const auto output_y = outputLine_A;
112 const auto output_z = outputLine_B;
114 for (ordinal_type k=0;k<cardLine;++k)
115 for (ordinal_type j=0;j<cardLine;++j)
116 for (ordinal_type i=0;i<cardBubble;++i,++idx)
117 for (ordinal_type l=0;l<npts;++l) {
118 output.access(idx,l,0) = output_x.access(i,l)*output_y.access(j,l)*output_z.access(k,l);
119 output.access(idx,l,1) = 0.0;
120 output.access(idx,l,2) = 0.0;
124 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
125 getValues(outputLine_A, input_x, workLine, vinvLine);
127 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
128 getValues(outputBubble, input_y, workLine, vinvBubble);
134 const auto output_x = outputLine_A;
135 const auto output_y = outputBubble;
136 const auto output_z = outputLine_B;
138 for (ordinal_type k=0;k<cardLine;++k)
139 for (ordinal_type j=0;j<cardBubble;++j)
140 for (ordinal_type i=0;i<cardLine;++i,++idx)
141 for (ordinal_type l=0;l<npts;++l) {
142 output.access(idx,l,0) = 0.0;
143 output.access(idx,l,1) = output_x.access(i,l)*output_y.access(j,l)*output_z.access(k,l);
144 output.access(idx,l,2) = 0.0;
151 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
152 getValues(outputLine_B, input_y, workLine, vinvLine);
154 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
155 getValues(outputBubble, input_z, workLine, vinvBubble);
158 const auto output_x = outputLine_A;
159 const auto output_y = outputLine_B;
160 const auto output_z = outputBubble;
162 for (ordinal_type k=0;k<cardBubble;++k)
163 for (ordinal_type j=0;j<cardLine;++j)
164 for (ordinal_type i=0;i<cardLine;++i,++idx)
165 for (ordinal_type l=0;l<npts;++l) {
166 output.access(idx,l,0) = 0.0;
167 output.access(idx,l,1) = 0.0;
168 output.access(idx,l,2) = output_x.access(i,l)*output_y.access(j,l)*output_z.access(k,l);
173 case OPERATOR_CURL: {
175 auto ptr4 = work.data() + 4*cardLine*npts*dim_s;
176 auto ptr5 = work.data() + 5*cardLine*npts*dim_s;
178 viewType workLine(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
179 viewType outputLine_A(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts);
180 viewType outputLine_B(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts);
181 viewType outputLine_DA(Kokkos::view_wrap(ptr3, vcprop), cardLine, npts, 1);
182 viewType outputLine_DB(Kokkos::view_wrap(ptr4, vcprop), cardLine, npts, 1);
183 viewType outputBubble(Kokkos::view_wrap(ptr5, vcprop), cardBubble, npts);
186 ordinal_type idx = 0;
189 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
190 getValues(outputBubble, input_x, workLine, vinvBubble);
192 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
193 getValues(outputLine_A, input_y, workLine, vinvLine);
195 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
196 getValues(outputLine_DA, input_y, workLine, vinvLine, 1);
198 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
199 getValues(outputLine_B, input_z, workLine, vinvLine);
201 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
202 getValues(outputLine_DB, input_z, workLine, vinvLine, 1);
205 const auto output_x = outputBubble;
206 const auto output_y = outputLine_A;
207 const auto output_dy = outputLine_DA;
208 const auto output_z = outputLine_B;
209 const auto output_dz = outputLine_DB;
211 for (ordinal_type k=0;k<cardLine;++k)
212 for (ordinal_type j=0;j<cardLine;++j)
213 for (ordinal_type i=0;i<cardBubble;++i,++idx)
214 for (ordinal_type l=0;l<npts;++l) {
215 output.access(idx,l,0) = 0.0;
216 output.access(idx,l,1) = output_x.access(i,l)*output_y.access (j,l) *output_dz.access(k,l,0);
217 output.access(idx,l,2) = -output_x.access(i,l)*output_dy.access(j,l,0)*output_z.access (k,l);
221 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
222 getValues(outputLine_A, input_x, workLine, vinvLine);
224 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
225 getValues(outputLine_DA, input_x, workLine, vinvLine, 1);
227 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
228 getValues(outputBubble, input_y, workLine, vinvBubble);
237 const auto output_x = outputLine_A;
238 const auto output_dx = outputLine_DA;
239 const auto output_y = outputBubble;
240 const auto output_z = outputLine_B;
241 const auto output_dz = outputLine_DB;
243 for (ordinal_type k=0;k<cardLine;++k)
244 for (ordinal_type j=0;j<cardBubble;++j)
245 for (ordinal_type i=0;i<cardLine;++i,++idx)
246 for (ordinal_type l=0;l<npts;++l) {
247 output.access(idx,l,0) = -output_x.access (i,l) *output_y.access(j,l)*output_dz.access(k,l,0);
248 output.access(idx,l,1) = 0.0;
249 output.access(idx,l,2) = output_dx(i,l,0)*output_y.access(j,l)*output_z.access (k,l);
259 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
260 getValues(outputLine_B, input_y, workLine, vinvLine);
262 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
263 getValues(outputLine_DB, input_y, workLine, vinvLine, 1);
265 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
266 getValues(outputBubble, input_z, workLine, vinvBubble);
269 const auto output_x = outputLine_A;
270 const auto output_dx = outputLine_DA;
271 const auto output_y = outputLine_B;
272 const auto output_dy = outputLine_DB;
273 const auto output_z = outputBubble;
275 for (ordinal_type k=0;k<cardBubble;++k)
276 for (ordinal_type j=0;j<cardLine;++j)
277 for (ordinal_type i=0;i<cardLine;++i,++idx)
278 for (ordinal_type l=0;l<npts;++l) {
279 output.access(idx,l,0) = output_x.access (i,l) *output_dy.access(j,l,0)*output_z.access(k,l);
280 output.access(idx,l,1) = -output_dx(i,l,0)*output_y.access (j,l) *output_z.access(k,l);
281 output.access(idx,l,2) = 0.0;
287 INTREPID2_TEST_FOR_ABORT(
true,
288 ">>> ERROR: (Intrepid2::Basis_HCURL_HEX_In_FEM::Serial::getValues) operator is not supported" );
292 template<
typename DT, ordinal_type numPtsPerEval,
293 typename outputValueValueType,
class ...outputValueProperties,
294 typename inputPointValueType,
class ...inputPointProperties,
295 typename vinvValueType,
class ...vinvProperties>
297 Basis_HCURL_HEX_In_FEM::
298 getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
299 const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
300 const Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvLine,
301 const Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvBubble,
302 const EOperator operatorType ) {
303 typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
304 typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
305 typedef Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvViewType;
306 typedef typename ExecSpace<typename inputPointViewType::execution_space,typename DT::execution_space>::ExecSpaceType ExecSpaceType;
309 const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
310 const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
311 const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
312 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
314 typedef typename inputPointViewType::value_type inputPointType;
316 const ordinal_type cardinality = outputValues.extent(0);
318 ordinal_type order = 0;
319 ordinal_type cardBubble;
320 ordinal_type cardLine;
322 cardBubble = Intrepid2::getPnCardinality<1>(order);
323 cardLine = Intrepid2::getPnCardinality<1>(++order);
325 auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
326 typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
328 switch (operatorType) {
329 case OPERATOR_VALUE: {
330 auto workSize = Serial<OPERATOR_VALUE>::getWorkSizePerPoint(order);
331 workViewType work(Kokkos::view_alloc(
"Basis_CURL_HEX_In_FEM::getValues::work", vcprop), workSize, inputPoints.extent(0));
332 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
333 OPERATOR_VALUE,numPtsPerEval> FunctorType;
334 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinvLine, vinvBubble, work) );
337 case OPERATOR_CURL: {
338 auto workSize = Serial<OPERATOR_CURL>::getWorkSizePerPoint(order);
339 workViewType work(Kokkos::view_alloc(
"Basis_CURL_HEX_In_FEM::getValues::work", vcprop), workSize, inputPoints.extent(0));
340 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
341 OPERATOR_CURL,numPtsPerEval> FunctorType;
342 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinvLine, vinvBubble, work) );
346 INTREPID2_TEST_FOR_EXCEPTION(
true , std::invalid_argument,
347 ">>> ERROR (Basis_HCURL_HEX_In_FEM): Operator type not implemented" );
356 template<
typename DT,
typename OT,
typename PT>
359 const EPointType pointType ) {
361 INTREPID2_TEST_FOR_EXCEPTION( !(pointType == POINTTYPE_EQUISPACED ||
362 pointType == POINTTYPE_WARPBLEND), std::invalid_argument,
363 ">>> ERROR (Basis_HCURL_HEX_In_FEM): pointType must be either equispaced or warpblend.");
373 this->vinvLine_ = Kokkos::DynRankView<typename ScalarViewType::value_type,DT>(
"Hcurl::Hex::In::vinvLine", cardLine, cardLine);
374 this->vinvBubble_ = Kokkos::DynRankView<typename ScalarViewType::value_type,DT>(
"Hcurl::Hex::In::vinvBubble", cardBubble, cardBubble);
376 lineBasis.getVandermondeInverse(this->vinvLine_);
377 bubbleBasis.getVandermondeInverse(this->vinvBubble_);
379 this->basisCardinality_ = 3*cardLine*cardLine*cardBubble;
380 this->basisDegree_ = order;
381 this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() );
382 this->basisType_ = BASIS_FEM_LAGRANGIAN;
383 this->basisCoordinates_ = COORDINATES_CARTESIAN;
384 this->functionSpace_ = FUNCTION_SPACE_HCURL;
385 pointType_ = pointType;
390 const ordinal_type tagSize = 4;
391 const ordinal_type posScDim = 0;
392 const ordinal_type posScOrd = 1;
393 const ordinal_type posDfOrd = 2;
397 INTREPID2_TEST_FOR_EXCEPTION( order >
Parameters::MaxOrder, std::invalid_argument,
"polynomial order exceeds the max supported by this class");
401 ordinal_type tags[3*maxCardLine*maxCardLine*maxCardLine][4];
403 const ordinal_type edge_x[2][2] = { {0, 4}, {2, 6} };
404 const ordinal_type edge_y[2][2] = { {3, 7}, {1, 5} };
405 const ordinal_type edge_z[2][2] = { {8,11}, {9,10} };
407 const ordinal_type face_yz[2] = {3, 1};
408 const ordinal_type face_xz[2] = {0, 2};
409 const ordinal_type face_xy[2] = {4, 5};
412 ordinal_type idx = 0;
422 face_ndofs_per_direction = (cardLine-2)*cardBubble,
423 face_ndofs = 2*face_ndofs_per_direction,
424 intr_ndofs_per_direction = (cardLine-2)*(cardLine-2)*cardBubble,
425 intr_ndofs = 3*intr_ndofs_per_direction;
428 for (ordinal_type k=0;k<cardLine;++k) {
429 const auto tag_z = lineBasis.
getDofTag(k);
430 for (ordinal_type j=0;j<cardLine;++j) {
431 const auto tag_y = lineBasis.
getDofTag(j);
432 for (ordinal_type i=0;i<cardBubble;++i,++idx) {
433 const auto tag_x = bubbleBasis.
getDofTag(i);
435 if (tag_x(0) == 1 && tag_y(0) == 0 && tag_z(0) == 0) {
438 tags[idx][1] = edge_x[tag_y(1)][tag_z(1)];
439 tags[idx][2] = tag_x(2);
440 tags[idx][3] = tag_x(3);
441 }
else if (tag_x(0) == 1 && tag_y(0) == 0 && tag_z(0) == 1) {
444 tags[idx][1] = face_xz[tag_y(1)];
445 tags[idx][2] = tag_x(2) + tag_x(3)*tag_z(2);
446 tags[idx][3] = face_ndofs;
447 }
else if (tag_x(0) == 1 && tag_y(0) == 1 && tag_z(0) == 0) {
450 tags[idx][1] = face_xy[tag_z(1)];
451 tags[idx][2] = tag_x(2) + tag_x(3)*tag_y(2);
452 tags[idx][3] = face_ndofs;
457 tags[idx][2] = tag_x(2) + tag_x(3)*tag_y(2) + tag_x(3)*tag_y(3)*tag_z(2);
458 tags[idx][3] = intr_ndofs;
465 for (ordinal_type k=0;k<cardLine;++k) {
466 const auto tag_z = lineBasis.
getDofTag(k);
467 for (ordinal_type j=0;j<cardBubble;++j) {
468 const auto tag_y = bubbleBasis.
getDofTag(j);
469 for (ordinal_type i=0;i<cardLine;++i,++idx) {
470 const auto tag_x = lineBasis.
getDofTag(i);
472 if (tag_x(0) == 0 && tag_y(0) == 1 && tag_z(0) == 0) {
475 tags[idx][1] = edge_y[tag_x(1)][tag_z(1)];
476 tags[idx][2] = tag_y(2);
477 tags[idx][3] = tag_y(3);
478 }
else if (tag_x(0) == 0 && tag_y(0) == 1 && tag_z(0) == 1) {
481 tags[idx][1] = face_yz[tag_x(1)];
482 tags[idx][2] = tag_y(2) + tag_y(3)*tag_z(2);
483 tags[idx][3] = face_ndofs;
484 }
else if (tag_x(0) == 1 && tag_y(0) == 1 && tag_z(0) == 0) {
487 tags[idx][1] = face_xy[tag_z(1)];
488 tags[idx][2] = face_ndofs_per_direction + tag_x(2) + tag_x(3)*tag_y(2);
489 tags[idx][3] = face_ndofs;
494 tags[idx][2] = intr_ndofs_per_direction + tag_x(2) + tag_x(3)*tag_y(2) + tag_x(3)*tag_y(3)*tag_z(2);
495 tags[idx][3] = intr_ndofs;
502 for (ordinal_type k=0;k<cardBubble;++k) {
503 const auto tag_z = bubbleBasis.
getDofTag(k);
504 for (ordinal_type j=0;j<cardLine;++j) {
505 const auto tag_y = lineBasis.
getDofTag(j);
506 for (ordinal_type i=0;i<cardLine;++i,++idx) {
507 const auto tag_x = lineBasis.
getDofTag(i);
509 if (tag_x(0) == 0 && tag_y(0) == 0 && tag_z(0) == 1) {
512 tags[idx][1] = edge_z[tag_x(1)][tag_y(1)];
513 tags[idx][2] = tag_z(2);
514 tags[idx][3] = tag_z(3);
515 }
else if (tag_x(0) == 0 && tag_y(0) == 1 && tag_z(0) == 1) {
518 tags[idx][1] = face_yz[tag_x(1)];
519 tags[idx][2] = face_ndofs_per_direction + tag_y(2) + tag_y(3)*tag_z(2);
520 tags[idx][3] = face_ndofs;
521 }
else if (tag_x(0) == 1 && tag_y(0) == 0 && tag_z(0) == 1) {
524 tags[idx][1] = face_xz[tag_y(1)];
525 tags[idx][2] = face_ndofs_per_direction + tag_x(2) + tag_x(3)*tag_z(2);
526 tags[idx][3] = face_ndofs;
531 tags[idx][2] = 2*intr_ndofs_per_direction + tag_x(2) + tag_x(3)*tag_y(2) + tag_x(3)*tag_y(3)*tag_z(2);
532 tags[idx][3] = intr_ndofs;
538 INTREPID2_TEST_FOR_EXCEPTION( idx != this->basisCardinality_ , std::runtime_error,
539 ">>> ERROR (Basis_HCURL_HEX_In_FEM): " \
540 "counted tag index is not same as cardinality." );
543 OrdinalTypeArray1DHost tagView(&tags[0][0], this->basisCardinality_*4);
547 this->setOrdinalTagData(this->tagToOrdinal_,
550 this->basisCardinality_,
558 Kokkos::DynRankView<typename ScalarViewType::value_type,typename DT::execution_space::array_layout,Kokkos::HostSpace>
559 dofCoordsHost(
"dofCoordsHost", this->basisCardinality_, this->basisCellTopology_.getDimension());
562 Kokkos::DynRankView<typename ScalarViewType::value_type,typename DT::execution_space::array_layout,Kokkos::HostSpace>
563 dofCoeffsHost(
"dofCoeffsHost", this->basisCardinality_, this->basisCellTopology_.getDimension());
565 Kokkos::DynRankView<typename ScalarViewType::value_type,DT>
566 dofCoordsLine(
"dofCoordsLine", cardLine, 1),
567 dofCoordsBubble(
"dofCoordsBubble", cardBubble, 1);
570 auto dofCoordsLineHost = Kokkos::create_mirror_view(Kokkos::HostSpace(), dofCoordsLine);
571 Kokkos::deep_copy(dofCoordsLineHost, dofCoordsLine);
573 bubbleBasis.getDofCoords(dofCoordsBubble);
574 auto dofCoordsBubbleHost = Kokkos::create_mirror_view(Kokkos::HostSpace(), dofCoordsBubble);
575 Kokkos::deep_copy(dofCoordsBubbleHost, dofCoordsBubble);
578 ordinal_type idx = 0;
581 for (ordinal_type k=0;k<cardLine;++k) {
582 for (ordinal_type j=0;j<cardLine;++j) {
583 for (ordinal_type i=0;i<cardBubble;++i,++idx) {
584 dofCoordsHost(idx,0) = dofCoordsBubbleHost(i,0);
585 dofCoordsHost(idx,1) = dofCoordsLineHost(j,0);
586 dofCoordsHost(idx,2) = dofCoordsLineHost(k,0);
587 dofCoeffsHost(idx,0) = 1.0;
593 for (ordinal_type k=0;k<cardLine;++k) {
594 for (ordinal_type j=0;j<cardBubble;++j) {
595 for (ordinal_type i=0;i<cardLine;++i,++idx) {
596 dofCoordsHost(idx,0) = dofCoordsLineHost(i,0);
597 dofCoordsHost(idx,1) = dofCoordsBubbleHost(j,0);
598 dofCoordsHost(idx,2) = dofCoordsLineHost(k,0);
599 dofCoeffsHost(idx,1) = 1.0;
605 for (ordinal_type k=0;k<cardBubble;++k) {
606 for (ordinal_type j=0;j<cardLine;++j) {
607 for (ordinal_type i=0;i<cardLine;++i,++idx) {
608 dofCoordsHost(idx,0) = dofCoordsLineHost(i,0);
609 dofCoordsHost(idx,1) = dofCoordsLineHost(j,0);
610 dofCoordsHost(idx,2) = dofCoordsBubbleHost(k,0);
611 dofCoeffsHost(idx,2) = 1.0;
617 this->dofCoords_ = Kokkos::create_mirror_view(
typename DT::memory_space(), dofCoordsHost);
618 Kokkos::deep_copy(this->dofCoords_, dofCoordsHost);
620 this->dofCoeffs_ = Kokkos::create_mirror_view(
typename DT::memory_space(), dofCoeffsHost);
621 Kokkos::deep_copy(this->dofCoeffs_, dofCoeffsHost);
const OrdinalTypeArrayStride1DHost getDofTag(const ordinal_type dofOrd) const
DoF ordinal to DoF tag lookup.
ordinal_type getCardinality() const
Returns cardinality of the basis.
virtual void getDofCoords(ScalarViewType dofCoords) const override
Returns spatial locations (coordinates) of degrees of freedom on the reference cell.
Implementation of the locally H(grad)-compatible FEM basis of variable order on the [-1...
Implementation of the locally HVOL-compatible FEM basis of variable order on the [-1,1] reference line cell, using Lagrange polynomials.
Basis_HCURL_HEX_In_FEM(const ordinal_type order, const EPointType pointType=POINTTYPE_EQUISPACED)
Constructor.
static constexpr ordinal_type MaxOrder
The maximum reconstruction order.