49 #ifndef __INTREPID2_HGRAD_HEX_CN_FEMDEF_HPP__
50 #define __INTREPID2_HGRAD_HEX_CN_FEMDEF_HPP__
57 template<EOperator opType>
58 template<
typename outputViewType,
59 typename inputViewType,
60 typename workViewType,
61 typename vinvViewType>
62 KOKKOS_INLINE_FUNCTION
64 Basis_HGRAD_HEX_Cn_FEM::Serial<opType>::
65 getValues( outputViewType output,
66 const inputViewType input,
68 const vinvViewType vinv,
69 const ordinal_type operatorDn ) {
70 ordinal_type opDn = operatorDn;
72 const ordinal_type cardLine = vinv.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: {
91 viewType work_line(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
92 viewType output_x(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts);
93 viewType output_y(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts);
94 viewType output_z(Kokkos::view_wrap(ptr3, vcprop), cardLine, npts);
96 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
97 getValues(output_x, input_x, work_line, vinv);
99 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
100 getValues(output_y, input_y, work_line, vinv);
102 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
103 getValues(output_z, input_z, work_line, vinv);
106 ordinal_type idx = 0;
107 for (ordinal_type k=0;k<cardLine;++k)
108 for (ordinal_type j=0;j<cardLine;++j)
109 for (ordinal_type i=0;i<cardLine;++i,++idx)
110 for (ordinal_type l=0;l<npts;++l)
111 output.access(idx,l) = output_x.access(i,l)*output_y.access(j,l)*output_z.access(k,l);
125 opDn = getOperatorOrder(opType);
127 const ordinal_type dkcard = opDn + 1;
130 for (ordinal_type l1=0;l1<dkcard;++l1)
131 for (ordinal_type l0=0;l0<(l1+1);++l0) {
132 const ordinal_type mult_x = (opDn - l1);
133 const ordinal_type mult_y = l1 - l0;
134 const ordinal_type mult_z = l0;
142 viewType work_line(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
143 decltype(work_line) output_x, output_y, output_z;
146 output_x = viewType(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts, 1);
147 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
148 getValues(output_x, input_x, work_line, vinv, mult_x);
150 output_x = viewType(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts);
151 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
152 getValues(output_x, input_x, work_line, vinv);
156 output_y = viewType(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts, 1);
157 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
158 getValues(output_y, input_y, work_line, vinv, mult_y);
160 output_y = viewType(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts);
161 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
162 getValues(output_y, input_y, work_line, vinv);
166 output_z = viewType(Kokkos::view_wrap(ptr3, vcprop), cardLine, npts, 1);
167 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
168 getValues(output_z, input_z, work_line, vinv, mult_z);
170 output_z = viewType(Kokkos::view_wrap(ptr3, vcprop), cardLine, npts);
171 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
172 getValues(output_z, input_z, work_line, vinv);
176 ordinal_type idx = 0;
177 for (ordinal_type k=0;k<cardLine;++k)
178 for (ordinal_type j=0;j<cardLine;++j)
179 for (ordinal_type i=0;i<cardLine;++i,++idx)
180 for (ordinal_type l=0;l<npts;++l)
181 output.access(idx,l,d) = output_x.access(i,l,0)*output_y.access(j,l,0)*output_z.access(k,l,0);
188 INTREPID2_TEST_FOR_ABORT(
true ,
189 ">>> ERROR (Basis_HGRAD_HEX_Cn_FEM): Operator type not implemented");
195 template<
typename SpT, ordinal_type numPtsPerEval,
196 typename outputValueValueType,
class ...outputValueProperties,
197 typename inputPointValueType,
class ...inputPointProperties,
198 typename vinvValueType,
class ...vinvProperties>
200 Basis_HGRAD_HEX_Cn_FEM::
201 getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
202 const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
203 const Kokkos::DynRankView<vinvValueType, vinvProperties...> vinv,
204 const EOperator operatorType ) {
205 typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
206 typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
207 typedef Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvViewType;
208 typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
211 const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
212 const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
213 const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
214 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
216 typedef typename inputPointViewType::value_type inputPointType;
218 const ordinal_type cardinality = outputValues.extent(0);
219 const ordinal_type cardLine = std::cbrt(cardinality);
220 const ordinal_type workSize = 4*cardLine;
222 auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
223 typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
224 workViewType work(Kokkos::view_alloc(
"Basis_HGRAD_HEX_Cn_FEM::getValues::work", vcprop), workSize, inputPoints.extent(0));
226 switch (operatorType) {
227 case OPERATOR_VALUE: {
228 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType,workViewType,
229 OPERATOR_VALUE,numPtsPerEval> FunctorType;
230 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work) );
233 case OPERATOR_CURL: {
234 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType,workViewType,
235 OPERATOR_CURL,numPtsPerEval> FunctorType;
236 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work) );
250 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType,workViewType,
251 OPERATOR_Dn,numPtsPerEval> FunctorType;
252 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work,
253 getOperatorOrder(operatorType)) );
257 INTREPID2_TEST_FOR_EXCEPTION(
true , std::invalid_argument,
258 ">>> ERROR (Basis_HGRAD_HEX_Cn_FEM): Operator type not implemented" );
266 template<
typename SpT,
typename OT,
typename PT>
269 const EPointType pointType ) {
275 this->vinv_ = Kokkos::DynRankView<typename scalarViewType::value_type,SpT>(
"Hgrad::HEX::Cn::vinv", cardLine, cardLine);
276 lineBasis.getVandermondeInverse(this->vinv_);
278 this->basisCardinality_ = cardLine*cardLine*cardLine;
279 this->basisDegree_ = order;
280 this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Hexahedron<8> >() );
281 this->basisType_ = BASIS_FEM_FIAT;
282 this->basisCoordinates_ = COORDINATES_CARTESIAN;
287 const ordinal_type tagSize = 4;
288 const ordinal_type posScDim = 0;
289 const ordinal_type posScOrd = 1;
290 const ordinal_type posDfOrd = 2;
294 ordinal_type tags[maxCardLine*maxCardLine*maxCardLine][4];
296 const ordinal_type vert[2][2][2] = { { {0,1}, {3,2} },
299 const ordinal_type edge_x[2][2] = { {0, 4}, {2, 6} };
300 const ordinal_type edge_y[2][2] = { {3, 7}, {1, 5} };
301 const ordinal_type edge_z[2][2] = { {8,11}, {9,10} };
303 const ordinal_type face_yz[2] = {3, 1};
304 const ordinal_type face_xz[2] = {0, 2};
305 const ordinal_type face_xy[2] = {4, 5};
308 ordinal_type idx = 0;
309 for (
auto k=0;k<cardLine;++k) {
310 const auto tag_z = lineBasis.
getDofTag(k);
311 for (ordinal_type j=0;j<cardLine;++j) {
312 const auto tag_y = lineBasis.
getDofTag(j);
313 for (ordinal_type i=0;i<cardLine;++i,++idx) {
314 const auto tag_x = lineBasis.
getDofTag(i);
316 if (tag_x(0) == 0 && tag_y(0) == 0 && tag_z(0) == 0) {
319 tags[idx][1] = vert[tag_z(1)][tag_y(1)][tag_x(1)];
322 }
else if (tag_x(0) == 1 && tag_y(0) == 0 && tag_z(0) == 0) {
325 tags[idx][1] = edge_x[tag_y(1)][tag_z(1)];
326 tags[idx][2] = tag_x(2);
327 tags[idx][3] = tag_x(3);
328 }
else if (tag_x(0) == 0 && tag_y(0) == 1 && tag_z(0) == 0) {
331 tags[idx][1] = edge_y[tag_x(1)][tag_z(1)];
332 tags[idx][2] = tag_y(2);
333 tags[idx][3] = tag_y(3);
334 }
else if (tag_x(0) == 0 && tag_y(0) == 0 && tag_z(0) == 1) {
337 tags[idx][1] = edge_z[tag_x(1)][tag_y(1)];
338 tags[idx][2] = tag_z(2);
339 tags[idx][3] = tag_z(3);
340 }
else if (tag_x(0) == 0 && tag_y(0) == 1 && tag_z(0) == 1) {
343 tags[idx][1] = face_yz[tag_x(1)];
344 tags[idx][2] = tag_y(2) + tag_y(3)*tag_z(2);
345 tags[idx][3] = tag_y(3)*tag_z(3);
346 }
else if (tag_x(0) == 1 && tag_y(0) == 0 && tag_z(0) == 1) {
349 tags[idx][1] = face_xz[tag_y(1)];
350 tags[idx][2] = tag_x(2) + tag_x(3)*tag_z(2);
351 tags[idx][3] = tag_x(3)*tag_z(3);
352 }
else if (tag_x(0) == 1 && tag_y(0) == 1 && tag_z(0) == 0) {
355 tags[idx][1] = face_xy[tag_z(1)];
356 tags[idx][2] = tag_x(2) + tag_x(3)*tag_y(2);
357 tags[idx][3] = tag_x(3)*tag_y(3);
362 tags[idx][2] = tag_x(2) + tag_x(3)*tag_y(2) + tag_x(3)*tag_y(3)*tag_z(2);
363 tags[idx][3] = tag_x(3)*tag_y(3)*tag_z(3);
374 this->setOrdinalTagData(this->tagToOrdinal_,
377 this->basisCardinality_,
385 Kokkos::DynRankView<typename scalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace>
386 dofCoordsHost(
"dofCoordsHost", this->basisCardinality_, this->basisCellTopology_.getDimension());
388 Kokkos::DynRankView<typename scalarViewType::value_type,SpT>
389 dofCoordsLine(
"dofCoordsLine", cardLine, 1);
392 auto dofCoordsLineHost = Kokkos::create_mirror_view(dofCoordsLine);
393 Kokkos::deep_copy(dofCoordsLineHost, dofCoordsLine);
395 ordinal_type idx = 0;
396 for (
auto k=0;k<cardLine;++k) {
397 for (ordinal_type j=0;j<cardLine;++j) {
398 for (ordinal_type i=0;i<cardLine;++i,++idx) {
399 dofCoordsHost(idx,0) = dofCoordsLineHost(i,0);
400 dofCoordsHost(idx,1) = dofCoordsLineHost(j,0);
401 dofCoordsHost(idx,2) = dofCoordsLineHost(k,0);
407 this->dofCoords_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), dofCoordsHost);
408 Kokkos::deep_copy(this->dofCoords_, dofCoordsHost);
Basis_HGRAD_HEX_Cn_FEM(const ordinal_type order, const EPointType pointType=POINTTYPE_EQUISPACED)
Constructor.
ordinal_type getCardinality() const
Returns cardinality of the basis.
Kokkos::View< ordinal_type *,typename ExecSpaceType::array_layout, Kokkos::HostSpace > ordinal_type_array_1d_host
View type for 1d host array.
const ordinal_type_array_stride_1d_host getDofTag(const ordinal_type dofOrd) const
DoF ordinal to DoF tag lookup.
Implementation of the locally H(grad)-compatible FEM basis of variable order on the [-1...
static constexpr ordinal_type MaxOrder
The maximum reconstruction order.
virtual void getDofCoords(scalarViewType dofCoords) const
Returns spatial locations (coordinates) of degrees of freedom on the reference cell.