49 #ifndef __INTREPID2_HCURL_QUAD_IN_FEM_DEF_HPP__
50 #define __INTREPID2_HCURL_QUAD_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_QUAD_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));
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 workLine(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
90 viewType outputLine(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts);
91 viewType outputBubble(Kokkos::view_wrap(ptr2, vcprop), cardBubble, npts);
96 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
97 getValues(outputBubble, input_x, workLine, vinvBubble);
99 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
100 getValues(outputLine, input_y, workLine, vinvLine);
103 const auto output_x = outputBubble;
104 const auto output_y = outputLine;
106 for (ordinal_type j=0;j<cardLine;++j)
107 for (ordinal_type i=0;i<cardBubble;++i,++idx)
108 for (ordinal_type k=0;k<npts;++k) {
109 output.access(idx,k,0) = output_x.access(i,k)*output_y.access(j,k);
110 output.access(idx,k,1) = 0.0;
115 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
116 getValues(outputBubble, input_y, workLine, vinvBubble);
118 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
119 getValues(outputLine, input_x, workLine, vinvLine);
122 const auto output_x = outputLine;
123 const auto output_y = outputBubble;
124 for (ordinal_type j=0;j<cardBubble;++j)
125 for (ordinal_type i=0;i<cardLine;++i,++idx)
126 for (ordinal_type k=0;k<npts;++k) {
127 output.access(idx,k,0) = 0.0;
128 output.access(idx,k,1) = output_x.access(i,k)*output_y.access(j,k);
134 case OPERATOR_CURL: {
135 ordinal_type idx = 0;
137 viewType workLine(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
139 viewType output_x(Kokkos::view_wrap(ptr2, vcprop), cardBubble, npts);
141 viewType output_y(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts,1);
143 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
144 getValues(output_x, input_x, workLine, vinvBubble);
146 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
147 getValues(output_y, input_y, workLine, vinvLine, 1);
150 for (ordinal_type j=0;j<cardLine;++j)
151 for (ordinal_type i=0;i<cardBubble;++i,++idx)
152 for (ordinal_type k=0;k<npts;++k)
153 output.access(idx,k) = -output_x.access(i,k)*output_y.access(j,k,0);
156 viewType workLine(Kokkos::view_wrap(ptr0, vcprop), cardLine, npts);
158 viewType output_x(Kokkos::view_wrap(ptr1, vcprop), cardLine, npts,1);
160 viewType output_y(Kokkos::view_wrap(ptr2, vcprop), cardBubble, npts);
162 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_VALUE>::
163 getValues(output_y, input_y, workLine, vinvBubble);
165 Impl::Basis_HGRAD_LINE_Cn_FEM::Serial<OPERATOR_Dn>::
166 getValues(output_x, input_x, workLine, vinvLine, 1);
169 for (ordinal_type j=0;j<cardBubble;++j)
170 for (ordinal_type i=0;i<cardLine;++i,++idx)
171 for (ordinal_type k=0;k<npts;++k)
172 output.access(idx,k) = output_x.access(i,k,0)*output_y.access(j,k);
177 INTREPID2_TEST_FOR_ABORT(
true,
178 ">>> ERROR: (Intrepid2::Basis_HCURL_QUAD_In_FEM::Serial::getValues) operator is not supported" );
183 template<
typename SpT, ordinal_type numPtsPerEval,
184 typename outputValueValueType,
class ...outputValueProperties,
185 typename inputPointValueType,
class ...inputPointProperties,
186 typename vinvValueType,
class ...vinvProperties>
188 Basis_HCURL_QUAD_In_FEM::
189 getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
190 const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
191 const Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvLine,
192 const Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvBubble,
193 const EOperator operatorType ) {
194 typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
195 typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
196 typedef Kokkos::DynRankView<vinvValueType, vinvProperties...> vinvViewType;
197 typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
200 const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
201 const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
202 const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
203 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
205 typedef typename inputPointViewType::value_type inputPointType;
207 const ordinal_type cardinality = outputValues.extent(0);
209 ordinal_type order = 0;
210 ordinal_type cardBubble;
211 ordinal_type cardLine;
213 cardBubble = Intrepid2::getPnCardinality<1>(order);
214 cardLine = Intrepid2::getPnCardinality<1>(++order);
217 auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
218 typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
220 switch (operatorType) {
221 case OPERATOR_VALUE: {
222 auto workSize = Serial<OPERATOR_VALUE>::getWorkSizePerPoint(order);
223 workViewType work(Kokkos::view_alloc(
"Basis_HCURL_QUAD_In_FEM::getValues::work", vcprop), workSize, inputPoints.extent(0));
224 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
225 OPERATOR_VALUE,numPtsPerEval> FunctorType;
226 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinvLine, vinvBubble, work) );
229 case OPERATOR_CURL: {
230 auto workSize = Serial<OPERATOR_CURL>::getWorkSizePerPoint(order);
231 workViewType work(Kokkos::view_alloc(
"Basis_HCURL_QUAD_In_FEM::getValues::work", vcprop), workSize, inputPoints.extent(0));
232 typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
233 OPERATOR_CURL,numPtsPerEval> FunctorType;
234 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, vinvLine, vinvBubble, work) );
238 INTREPID2_TEST_FOR_EXCEPTION(
true , std::invalid_argument,
239 ">>> ERROR (Basis_HCURL_QUAD_In_FEM): Operator type not implemented" );
246 template<
typename SpT,
typename OT,
typename PT>
249 const EPointType pointType ) {
251 INTREPID2_TEST_FOR_EXCEPTION( !(pointType == POINTTYPE_EQUISPACED ||
252 pointType == POINTTYPE_WARPBLEND), std::invalid_argument,
253 ">>> ERROR (Basis_HCURL_QUAD_In_FEM): pointType must be either equispaced or warpblend.");
263 this->vinvLine_ = Kokkos::DynRankView<typename ScalarViewType::value_type,SpT>(
"Hcurl::Quad::In::vinvLine", cardLine, cardLine);
264 this->vinvBubble_ = Kokkos::DynRankView<typename ScalarViewType::value_type,SpT>(
"Hcurl::Quad::In::vinvBubble", cardBubble, cardBubble);
266 lineBasis.getVandermondeInverse(this->vinvLine_);
267 bubbleBasis.getVandermondeInverse(this->vinvBubble_);
269 this->basisCardinality_ = 2*cardLine*cardBubble;
270 this->basisDegree_ = order;
271 this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Quadrilateral<4> >() );
272 this->basisType_ = BASIS_FEM_FIAT;
273 this->basisCoordinates_ = COORDINATES_CARTESIAN;
274 this->functionSpace_ = FUNCTION_SPACE_HCURL;
279 const ordinal_type tagSize = 4;
280 const ordinal_type posScDim = 0;
281 const ordinal_type posScOrd = 1;
282 const ordinal_type posDfOrd = 2;
287 ordinal_type tags[2*maxCardLine*maxCardBubble][4];
289 const ordinal_type edge_x[2] = {0,2};
290 const ordinal_type edge_y[2] = {3,1};
292 ordinal_type idx = 0;
302 intr_ndofs_per_direction = (cardLine-2)*cardBubble,
303 intr_ndofs = 2*intr_ndofs_per_direction;
306 for (ordinal_type j=0;j<cardLine;++j) {
307 const auto tag_y = lineBasis.
getDofTag(j);
308 for (ordinal_type i=0;i<cardBubble;++i,++idx) {
309 const auto tag_x = bubbleBasis.
getDofTag(i);
311 if (tag_x(0) == 1 && tag_y(0) == 0) {
314 tags[idx][1] = edge_x[tag_y(1)];
315 tags[idx][2] = tag_x(2);
316 tags[idx][3] = tag_x(3);
321 tags[idx][2] = tag_x(2) + tag_x(3)*tag_y(2);
322 tags[idx][3] = intr_ndofs;
328 for (ordinal_type j=0;j<cardBubble;++j) {
329 const auto tag_y = bubbleBasis.
getDofTag(j);
330 for (ordinal_type i=0;i<cardLine;++i,++idx) {
331 const auto tag_x = lineBasis.
getDofTag(i);
333 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] = intr_ndofs_per_direction + tag_x(2) + tag_x(3)*tag_y(2);
344 tags[idx][3] = intr_ndofs;
348 INTREPID2_TEST_FOR_EXCEPTION( idx != this->basisCardinality_ , std::runtime_error,
349 ">>> ERROR (Basis_HCURL_QUAD_In_FEM): " \
350 "counted tag index is not same as cardinality." );
357 this->setOrdinalTagData(this->tagToOrdinal_,
360 this->basisCardinality_,
368 Kokkos::DynRankView<typename ScalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace>
369 dofCoordsHost(
"dofCoordsHost", this->basisCardinality_, this->basisCellTopology_.getDimension());
372 Kokkos::DynRankView<typename ScalarViewType::value_type,typename SpT::array_layout,Kokkos::HostSpace>
373 dofCoeffsHost(
"dofCoeffsHost", this->basisCardinality_, this->basisCellTopology_.getDimension());
375 Kokkos::DynRankView<typename ScalarViewType::value_type,SpT>
376 dofCoordsLine(
"dofCoordsLine", cardLine, 1),
377 dofCoordsBubble(
"dofCoordsBubble", cardBubble, 1);
379 lineBasis.getDofCoords(dofCoordsLine);
380 auto dofCoordsLineHost = Kokkos::create_mirror_view(Kokkos::HostSpace(), dofCoordsLine);
381 Kokkos::deep_copy(dofCoordsLineHost, dofCoordsLine);
383 bubbleBasis.getDofCoords(dofCoordsBubble);
384 auto dofCoordsBubbleHost = Kokkos::create_mirror_view(Kokkos::HostSpace(), dofCoordsBubble);
385 Kokkos::deep_copy(dofCoordsBubbleHost, dofCoordsBubble);
388 ordinal_type idx = 0;
391 for (ordinal_type j=0;j<cardLine;++j) {
392 for (ordinal_type i=0;i<cardBubble;++i,++idx) {
393 dofCoordsHost(idx,0) = dofCoordsBubbleHost(i,0);
394 dofCoordsHost(idx,1) = dofCoordsLineHost(j,0);
395 dofCoeffsHost(idx,0) = 1.0;
400 for (ordinal_type j=0;j<cardBubble;++j) {
401 for (ordinal_type i=0;i<cardLine;++i,++idx) {
402 dofCoordsHost(idx,0) = dofCoordsLineHost(i,0);
403 dofCoordsHost(idx,1) = dofCoordsBubbleHost(j,0);
404 dofCoeffsHost(idx,1) = 1.0;
409 this->dofCoords_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), dofCoordsHost);
410 Kokkos::deep_copy(this->dofCoords_, dofCoordsHost);
412 this->dofCoeffs_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), dofCoeffsHost);
413 Kokkos::deep_copy(this->dofCoeffs_, dofCoeffsHost);
Kokkos::View< ordinal_type *, typename ExecSpaceType::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
Basis_HCURL_QUAD_In_FEM(const ordinal_type order, const EPointType pointType=POINTTYPE_EQUISPACED)
Constructor.
ordinal_type getCardinality() const
Returns cardinality of the basis.
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.