50 #ifndef __INTREPID2_HGRAD_TRI_CN_FEM_ORTH_DEF_HPP__
51 #define __INTREPID2_HGRAD_TRI_CN_FEM_ORTH_DEF_HPP__
58 template<
typename OutputViewType,
59 typename inputViewType,
60 typename workViewType,
62 KOKKOS_INLINE_FUNCTION
63 void OrthPolynomialTri<OutputViewType,inputViewType,workViewType,hasDeriv,0>::generate(
64 OutputViewType output,
65 const inputViewType input,
67 const ordinal_type order ) {
69 constexpr ordinal_type spaceDim = 2;
72 typedef typename OutputViewType::value_type value_type;
74 auto output0 = (hasDeriv) ? Kokkos::subview(output, Kokkos::ALL(), Kokkos::ALL(),0) : Kokkos::subview(output, Kokkos::ALL(), Kokkos::ALL());
77 npts = input.extent(0);
88 const ordinal_type loc = Intrepid2::getPnEnumeration<spaceDim>(0,0);
89 for (ordinal_type i=0;i<npts;++i) {
90 output0(loc, i) = 1.0;
92 output.access(loc,i,1) = 0;
93 output.access(loc,i,2) = 0;
99 value_type f1[maxNumPts]={},f2[maxNumPts]={}, df2_1[maxNumPts]={};
100 value_type df1_0, df1_1;
102 for (ordinal_type i=0;i<npts;++i) {
103 f1[i] = 0.5 * (1.0+2.0*(2.0*z(i,0)-1.0)+(2.0*z(i,1)-1.0));
104 f2[i] = std::pow(z(i,1)-1,2);
108 df2_1[i] = 2.0*(z(i,1)-1);
114 const ordinal_type loc = Intrepid2::getPnEnumeration<spaceDim>(1,0);
115 for (ordinal_type i=0;i<npts;++i) {
116 output0(loc, i) = f1[i];
118 output.access(loc,i,1) = df1_0;
119 output.access(loc,i,2) = df1_1;
125 for (ordinal_type p=1;p<order;p++) {
127 loc = Intrepid2::getPnEnumeration<spaceDim>(p,0),
128 loc_p1 = Intrepid2::getPnEnumeration<spaceDim>(p+1,0),
129 loc_m1 = Intrepid2::getPnEnumeration<spaceDim>(p-1,0);
132 a = (2.0*p+1.0)/(1.0+p),
135 for (ordinal_type i=0;i<npts;++i) {
136 output0(loc_p1,i) = ( a * f1[i] * output0(loc,i) -
137 b * f2[i] * output0(loc_m1,i) );
139 output.access(loc_p1,i,1) = a * (f1[i] * output.access(loc,i,1) + df1_0 * output0(loc,i)) -
140 b * f2[i] * output.access(loc_m1,i,1) ;
141 output.access(loc_p1,i,2) = a * (f1[i] * output.access(loc,i,2) + df1_1 * output0(loc,i)) -
142 b * (df2_1[i] * output0(loc_m1,i) + f2[i] * output.access(loc_m1,i,2)) ;
148 for (ordinal_type p=0;p<order;++p) {
150 loc_p_0 = Intrepid2::getPnEnumeration<spaceDim>(p,0),
151 loc_p_1 = Intrepid2::getPnEnumeration<spaceDim>(p,1);
153 for (ordinal_type i=0;i<npts;++i) {
154 output0(loc_p_1,i) = output0(loc_p_0,i)*0.5*(1.0+2.0*p+(3.0+2.0*p)*(2.0*z(i,1)-1.0));
156 output.access(loc_p_1,i,1) = output.access(loc_p_0,i,1)*0.5*(1.0+2.0*p+(3.0+2.0*p)*(2.0*z(i,1)-1.0));
157 output.access(loc_p_1,i,2) = output.access(loc_p_0,i,2)*0.5*(1.0+2.0*p+(3.0+2.0*p)*(2.0*z(i,1)-1.0)) + output0(loc_p_0,i)*(3.0+2.0*p);
164 for (ordinal_type p=0;p<order-1;++p)
165 for (ordinal_type q=1;q<order-p;++q) {
167 loc_p_qp1 = Intrepid2::getPnEnumeration<spaceDim>(p,q+1),
168 loc_p_q = Intrepid2::getPnEnumeration<spaceDim>(p,q),
169 loc_p_qm1 = Intrepid2::getPnEnumeration<spaceDim>(p,q-1);
172 Intrepid2::getJacobyRecurrenceCoeffs(a,b,c, 2*p+1,0,q);
173 for (ordinal_type i=0;i<npts;++i) {
174 output0(loc_p_qp1,i) = (a*(2.0*z(i,1)-1.0)+b)*output0(loc_p_q,i)
175 - c*output0(loc_p_qm1,i) ;
177 output.access(loc_p_qp1,i,1) = (a*(2.0*z(i,1)-1.0)+b)*output.access(loc_p_q,i,1)
178 - c*output.access(loc_p_qm1,i,1) ;
179 output.access(loc_p_qp1,i,2) = (a*(2.0*z(i,1)-1.0)+b)*output.access(loc_p_q,i,2) +2*a*output0(loc_p_q,i)
180 - c*output.access(loc_p_qm1,i,2) ;
187 for (ordinal_type p=0;p<=order;++p)
188 for (ordinal_type q=0;q<=order-p;++q)
189 for (ordinal_type i=0;i<npts;++i) {
190 output0(Intrepid2::getPnEnumeration<spaceDim>(p,q),i) *= std::sqrt( (p+0.5)*(p+q+1.0));
192 output.access(Intrepid2::getPnEnumeration<spaceDim>(p,q),i,1) *= std::sqrt( (p+0.5)*(p+q+1.0));
193 output.access(Intrepid2::getPnEnumeration<spaceDim>(p,q),i,2) *= std::sqrt( (p+0.5)*(p+q+1.0));
198 template<
typename OutputViewType,
199 typename inputViewType,
200 typename workViewType,
202 KOKKOS_INLINE_FUNCTION
203 void OrthPolynomialTri<OutputViewType,inputViewType,workViewType,hasDeriv,1>::generate(
204 OutputViewType output,
205 const inputViewType input,
207 const ordinal_type order ) {
208 constexpr ordinal_type spaceDim = 2;
210 npts = input.extent(0),
211 card = output.extent(0);
213 workViewType dummyView;
214 OrthPolynomialTri<workViewType,inputViewType,workViewType,hasDeriv,0>::generate(work, input, dummyView, order);
215 for (ordinal_type i=0;i<card;++i)
216 for (ordinal_type j=0;j<npts;++j)
217 for (ordinal_type k=0;k<spaceDim;++k)
218 output.access(i,j,k) = work(i,j,k+1);
223 template<
typename OutputViewType,
224 typename inputViewType,
225 typename workViewType,
228 KOKKOS_INLINE_FUNCTION
229 void OrthPolynomialTri<OutputViewType,inputViewType,workViewType,hasDeriv,n>::generate(
231 const inputViewType ,
233 const ordinal_type ) {
234 #if 0 //#ifdef HAVE_INTREPID2_SACADO
236 constexpr ordinal_type spaceDim = 2;
237 constexpr ordinal_type maxCard = Intrepid2::getPnCardinality<spaceDim, Parameters::MaxOrder>();
239 typedef typename OutputViewType::value_type value_type;
240 typedef Sacado::Fad::SFad<value_type,spaceDim> fad_type;
243 npts = input.extent(0),
244 card = output.extent(0);
250 typedef typename inputViewType::memory_space memory_space;
251 typedef typename Kokkos::View<fad_type***, memory_space> outViewType;
252 typedef typename Kokkos::View<fad_type**, memory_space> inViewType;
253 auto vcprop = Kokkos::common_view_alloc_prop(input);
255 inViewType in(Kokkos::view_wrap((value_type*)&inBuf[0][0], vcprop), npts, spaceDim);
256 outViewType out(Kokkos::view_wrap((value_type*)&outBuf[0][0][0], vcprop), card, npts, n);
258 for (ordinal_type i=0;i<npts;++i)
259 for (ordinal_type j=0;j<spaceDim;++j) {
260 in(i,j) = input(i,j);
261 in(i,j).diff(j,spaceDim);
264 typedef typename Kokkos::DynRankView<fad_type, memory_space> outViewType_;
265 outViewType_ workView;
269 auto vcprop = Kokkos::common_view_alloc_prop(in);
270 workView = outViewType_( Kokkos::view_wrap((value_type*)&outBuf[0][0][0], vcprop), card, npts, spaceDim+1);
272 OrthPolynomialTri<outViewType,inViewType,outViewType_,hasDeriv,n-1>::generate(out, in, workView, order);
274 for (ordinal_type i=0;i<card;++i)
275 for (ordinal_type j=0;j<npts;++j) {
276 for (ordinal_type i_dx = 0; i_dx <= n; ++i_dx) {
277 ordinal_type i_dy = n-i_dx;
278 ordinal_type i_Dn = i_dy;
282 ordinal_type i_Dnm1 = i_dy;
283 output.access(i,j,i_Dn) = out(i,j,i_Dnm1).dx(0);
288 ordinal_type i_Dnm1 = i_dy-1;
289 output.access(i,j,i_Dn) = out(i,j,i_Dnm1).dx(1);
294 INTREPID2_TEST_FOR_ABORT(
true,
295 ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_Cn_FEM_ORTH::OrthPolynomialTri) Computing of second and higher-order derivatives is not currently supported");
301 template<EOperator opType>
302 template<
typename OutputViewType,
303 typename inputViewType,
304 typename workViewType>
305 KOKKOS_INLINE_FUNCTION
307 Basis_HGRAD_TRI_Cn_FEM_ORTH::Serial<opType>::
308 getValues( OutputViewType output,
309 const inputViewType input,
311 const ordinal_type order) {
313 case OPERATOR_VALUE: {
314 OrthPolynomialTri<OutputViewType,inputViewType,workViewType,false,0>::generate( output, input, work, order );
319 OrthPolynomialTri<OutputViewType,inputViewType,workViewType,true,1>::generate( output, input, work, order );
323 OrthPolynomialTri<OutputViewType,inputViewType,workViewType,true,2>::generate( output, input, work, order );
327 INTREPID2_TEST_FOR_ABORT(
true,
328 ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_Cn_FEM_ORTH::Serial::getValues) operator is not supported");
333 template<
typename SpT, ordinal_type numPtsPerEval,
334 typename outputValueValueType,
class ...outputValueProperties,
335 typename inputPointValueType,
class ...inputPointProperties>
337 Basis_HGRAD_TRI_Cn_FEM_ORTH::
338 getValues( Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
339 const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
340 const ordinal_type order,
341 const EOperator operatorType ) {
342 typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
343 typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
344 typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
347 const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
348 const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
349 const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
350 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
352 typedef typename inputPointViewType::value_type inputPointType;
353 const ordinal_type cardinality = outputValues.extent(0);
354 const ordinal_type spaceDim = 2;
356 auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
357 typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
359 switch (operatorType) {
360 case OPERATOR_VALUE: {
361 workViewType dummyWorkView;
362 typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_VALUE,numPtsPerEval> FunctorType;
363 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, dummyWorkView, order) );
368 workViewType work(Kokkos::view_alloc(
"Basis_HGRAD_TRI_In_FEM_ORTH::getValues::work", vcprop), cardinality, inputPoints.extent(0), spaceDim+1);
369 typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_D1,numPtsPerEval> FunctorType;
370 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, work, order) );
374 workViewType dummyWorkView;
375 typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_D2,numPtsPerEval> FunctorType;
376 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints ,dummyWorkView, order) );
380 INTREPID2_TEST_FOR_EXCEPTION( !Intrepid2::isValidOperator(operatorType), std::invalid_argument,
381 ">>> ERROR (Basis_HGRAD_TRI_Cn_FEM_ORTH): invalid operator type");
390 template<
typename SpT,
typename OT,
typename PT>
394 constexpr ordinal_type spaceDim = 2;
395 this->basisCardinality_ = Intrepid2::getPnCardinality<spaceDim>(order);
396 this->basisDegree_ = order;
397 this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() );
398 this->basisType_ = BASIS_FEM_HIERARCHICAL;
399 this->basisCoordinates_ = COORDINATES_CARTESIAN;
400 this->functionSpace_ = FUNCTION_SPACE_HGRAD;
405 constexpr ordinal_type tagSize = 4;
406 const ordinal_type posScDim = 0;
407 const ordinal_type posScOrd = 1;
408 const ordinal_type posDfOrd = 2;
410 constexpr ordinal_type maxCard = Intrepid2::getPnCardinality<spaceDim, Parameters::MaxOrder>();
411 ordinal_type tags[maxCard][tagSize];
412 const ordinal_type card = this->basisCardinality_;
413 for (ordinal_type i=0;i<card;++i) {
424 this->setOrdinalTagData(this->tagToOrdinal_,
427 this->basisCardinality_,
Kokkos::View< ordinal_type *, typename ExecSpaceType::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.
static constexpr ordinal_type MaxNumPtsPerBasisEval
The maximum number of points to eval in serial mode.
Basis_HGRAD_TRI_Cn_FEM_ORTH(const ordinal_type order)
Constructor.