49 #ifndef __INTREPID2_HGRAD_QUAD_CN_FEM_DEF_HPP__
50 #define __INTREPID2_HGRAD_QUAD_CN_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_HGRAD_QUAD_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));
79 const int dim_s = get_dimension_scalar(work);
80 auto ptr0 = work.data();
81 auto ptr1 = work.data()+cardLine*npts*dim_s;
82 auto ptr2 = work.data()+2*cardLine*npts*dim_s;
84 typedef typename Kokkos::DynRankView<typename workViewType::value_type, typename workViewType::memory_space> viewType;
85 auto vcprop = Kokkos::common_view_alloc_prop(work);
88 case OPERATOR_VALUE: {
89 viewType work_line(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
90 viewType output_x(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts);
91 viewType output_y(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts);
93 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
94 getValues(output_x, input_x, work_line, vinv);
96 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
97 getValues(output_y, input_y, work_line, vinv);
100 ordinal_type idx = 0;
101 for (ordinal_type j=0;j<cardLine;++j)
102 for (ordinal_type i=0;i<cardLine;++i,++idx)
103 for (ordinal_type k=0;k<npts;++k)
104 output.access(idx,k) = output_x.access(i,k)*output_y.access(j,k);
107 case OPERATOR_CURL: {
108 for (
auto l=0;l<2;++l) {
109 viewType work_line(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
111 viewType output_x, output_y;
113 typename workViewType::value_type s = 0.0;
116 output_x = viewType(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts, 1);
117 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
118 getValues(output_x, input_x, work_line, vinv, 1);
120 output_y = viewType(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts);
121 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
122 getValues(output_y, input_y, work_line, vinv);
127 output_x = viewType(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts);
128 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
129 getValues(output_x, input_x, work_line, vinv);
131 output_y = viewType(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts, 1);
132 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
133 getValues(output_y, input_y, work_line, vinv, 1);
139 ordinal_type idx = 0;
140 for (ordinal_type j=0;j<cardLine;++j)
141 for (ordinal_type i=0;i<cardLine;++i,++idx)
142 for (ordinal_type k=0;k<npts;++k)
143 output.access(idx,k,l) = s*output_x.access(i,k,0)*output_y.access(j,k,0);
158 opDn = getOperatorOrder(opType);
160 const auto dkcard = opDn + 1;
161 for (
auto l=0;l<dkcard;++l) {
162 viewType work_line(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
164 viewType output_x, output_y;
166 const auto mult_x = opDn - l;
167 const auto mult_y = l;
170 output_x = viewType(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts, 1);
171 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
172 getValues(output_x, input_x, work_line, vinv, mult_x);
174 output_x = viewType(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts);
175 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
176 getValues(output_x, input_x, work_line, vinv);
180 output_y = viewType(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts, 1);
181 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
182 getValues(output_y, input_y, work_line, vinv, mult_y);
184 output_y = viewType(Kokkos::view_wrap(ptr2, vcprop), cardLine, npts);
185 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
186 getValues(output_y, input_y, work_line, vinv);
190 ordinal_type idx = 0;
191 for (ordinal_type j=0;j<cardLine;++j)
192 for (ordinal_type i=0;i<cardLine;++i,++idx)
193 for (ordinal_type k=0;k<npts;++k)
194 output.access(idx,k,l) = output_x.access(i,k,0)*output_y.access(j,k,0);
199 INTREPID2_TEST_FOR_ABORT(
true,
200 ">>> ERROR: (Intrepid2::Basis_HGRAD_QUAD_Cn_FEM::Serial::getValues) operator is not supported" );
205 template<
typename SpT, ordinal_type numPtsPerEval,
206 typename outputValueValueType,
class ...outputValueProperties,
207 typename inputPointValueType,
class ...inputPointProperties,
208 typename vinvValueType,
class ...vinvProperties>
210 Basis_HGRAD_QUAD_Cn_FEM::
211 getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
212 const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
213 const Kokkos::DynRankView<vinvValueType, vinvProperties...> vinv,
214 const EOperator operatorType ) {
215 typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
216 typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
217 typedef Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvViewType;
218 typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
221 const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
222 const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
223 const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
224 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
226 typedef typename inputPointViewType::value_type inputPointType;
228 const ordinal_type cardinality = outputValues.extent(0);
229 const ordinal_type cardLine = std::sqrt(cardinality);
230 const ordinal_type workSize = 3*cardLine;
232 auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
233 typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
234 workViewType work(Kokkos::view_alloc(
"Basis_HGRAD_QUAD_Cn_FEM::getValues::work", vcprop), workSize, inputPoints.extent(0));
236 switch (operatorType) {
237 case OPERATOR_VALUE: {
238 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType,workViewType,
239 OPERATOR_VALUE,numPtsPerEval> FunctorType;
240 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work) );
243 case OPERATOR_CURL: {
244 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType,workViewType,
245 OPERATOR_CURL,numPtsPerEval> FunctorType;
246 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work) );
260 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType,workViewType,
261 OPERATOR_Dn,numPtsPerEval> FunctorType;
262 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinv, work,
263 getOperatorOrder(operatorType)) );
267 INTREPID2_TEST_FOR_EXCEPTION(
true , std::invalid_argument,
268 ">>> ERROR (Basis_HGRAD_QUAD_Cn_FEM): Operator type not implemented" );
276 template<
typename SpT,
typename OT,
typename PT>
279 const EPointType pointType ) {
288 this->vinv_ = Kokkos::DynRankView<typename ScalarViewType::value_type,SpT>(
"Hgrad::Quad::Cn::vinv", cardLine, cardLine);
289 lineBasis.getVandermondeInverse(this->vinv_);
291 this->basisCardinality_ = cardLine*cardLine;
292 this->basisDegree_ = order;
293 this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() );
294 this->basisType_ = BASIS_FEM_FIAT;
295 this->basisCoordinates_ = COORDINATES_CARTESIAN;
296 this->functionSpace_ = FUNCTION_SPACE_HGRAD;
301 const ordinal_type tagSize = 4;
302 const ordinal_type posScDim = 0;
303 const ordinal_type posScOrd = 1;
304 const ordinal_type posDfOrd = 2;
308 ordinal_type tags[maxCardLine*maxCardLine][4];
310 const ordinal_type vert[2][2] = { {0,1}, {3,2} };
312 const ordinal_type edge_x[2] = {0,2};
313 const ordinal_type edge_y[2] = {3,1};
315 ordinal_type idx = 0;
316 for (ordinal_type j=0;j<cardLine;++j) {
317 const auto tag_y = lineBasis.
getDofTag(j);
318 for (ordinal_type i=0;i<cardLine;++i,++idx) {
319 const auto tag_x = lineBasis.
getDofTag(i);
321 if (tag_x(0) == 0 && tag_y(0) == 0) {
324 tags[idx][1] = vert[tag_y(1)][tag_x(1)];
327 }
else if (tag_x(0) == 1 && tag_y(0) == 0) {
330 tags[idx][1] = edge_x[tag_y(1)];
331 tags[idx][2] = tag_x(2);
332 tags[idx][3] = tag_x(3);
333 }
else if (tag_x(0) == 0 && tag_y(0) == 1) {
336 tags[idx][1] = edge_y[tag_x(1)];
337 tags[idx][2] = tag_y(2);
338 tags[idx][3] = tag_y(3);
343 tags[idx][2] = tag_x(2) + tag_x(3)*tag_y(2);
344 tags[idx][3] = tag_x(3)*tag_y(3);
354 this->setOrdinalTagData(this->tagToOrdinal_,
357 this->basisCardinality_,
365 Kokkos::DynRankView<typename ScalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace>
366 dofCoordsHost(
"dofCoordsHost", this->basisCardinality_, this->basisCellTopology_.getDimension());
368 Kokkos::DynRankView<typename ScalarViewType::value_type,SpT>
369 dofCoordsLine(
"dofCoordsLine", cardLine, 1);
371 lineBasis.getDofCoords(dofCoordsLine);
372 auto dofCoordsLineHost = Kokkos::create_mirror_view(dofCoordsLine);
373 Kokkos::deep_copy(dofCoordsLineHost, dofCoordsLine);
375 ordinal_type idx = 0;
376 for (ordinal_type j=0;j<cardLine;++j) {
377 for (ordinal_type i=0;i<cardLine;++i,++idx) {
378 dofCoordsHost(idx,0) = dofCoordsLineHost(i,0);
379 dofCoordsHost(idx,1) = dofCoordsLineHost(j,0);
384 this->dofCoords_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), dofCoordsHost);
385 Kokkos::deep_copy(this->dofCoords_, dofCoordsHost);
Kokkos::View< ordinal_type *, typename ExecSpaceType::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
ordinal_type getCardinality() const
Returns cardinality of the basis.
Basis_HGRAD_QUAD_Cn_FEM(const ordinal_type order, const EPointType pointType=POINTTYPE_EQUISPACED)
Constructor.
Implementation of the locally H(grad)-compatible FEM basis of variable order on the [-1...
const OrdinalTypeArrayStride1DHost getDofTag(const ordinal_type dofOrd) const
DoF ordinal to DoF tag lookup.
static constexpr ordinal_type MaxOrder
The maximum reconstruction order.