17 #ifndef __INTREPID2_HGRAD_TRI_CN_FEM_ORTH_DEF_HPP__
18 #define __INTREPID2_HGRAD_TRI_CN_FEM_ORTH_DEF_HPP__
25 template<
typename OutputViewType,
26 typename inputViewType,
27 typename workViewType,
29 KOKKOS_INLINE_FUNCTION
30 void OrthPolynomialTri<OutputViewType,inputViewType,workViewType,hasDeriv,0>::generate(
31 OutputViewType output,
32 const inputViewType input,
34 const ordinal_type order ) {
36 constexpr ordinal_type spaceDim = 2;
39 typedef typename OutputViewType::value_type value_type;
41 auto output0 = (hasDeriv) ? Kokkos::subview(output, Kokkos::ALL(), Kokkos::ALL(),0) : Kokkos::subview(output, Kokkos::ALL(), Kokkos::ALL());
44 npts = input.extent(0);
55 const ordinal_type loc = Intrepid2::getPnEnumeration<spaceDim>(0,0);
56 for (ordinal_type i=0;i<npts;++i) {
57 output0(loc, i) = 1.0;
59 output.access(loc,i,1) = 0;
60 output.access(loc,i,2) = 0;
66 value_type f1[maxNumPts]={},f2[maxNumPts]={}, df2_1[maxNumPts]={};
67 value_type df1_0, df1_1;
69 for (ordinal_type i=0;i<npts;++i) {
70 f1[i] = 0.5 * (1.0+2.0*(2.0*z(i,0)-1.0)+(2.0*z(i,1)-1.0));
71 f2[i] = pow(z(i,1)-1,2);
75 df2_1[i] = 2.0*(z(i,1)-1);
81 const ordinal_type loc = Intrepid2::getPnEnumeration<spaceDim>(1,0);
82 for (ordinal_type i=0;i<npts;++i) {
83 output0(loc, i) = f1[i];
85 output.access(loc,i,1) = df1_0;
86 output.access(loc,i,2) = df1_1;
92 for (ordinal_type p=1;p<order;p++) {
94 loc = Intrepid2::getPnEnumeration<spaceDim>(p,0),
95 loc_p1 = Intrepid2::getPnEnumeration<spaceDim>(p+1,0),
96 loc_m1 = Intrepid2::getPnEnumeration<spaceDim>(p-1,0);
99 a = (2.0*p+1.0)/(1.0+p),
102 for (ordinal_type i=0;i<npts;++i) {
103 output0(loc_p1,i) = ( a * f1[i] * output0(loc,i) -
104 b * f2[i] * output0(loc_m1,i) );
106 output.access(loc_p1,i,1) = a * (f1[i] * output.access(loc,i,1) + df1_0 * output0(loc,i)) -
107 b * f2[i] * output.access(loc_m1,i,1) ;
108 output.access(loc_p1,i,2) = a * (f1[i] * output.access(loc,i,2) + df1_1 * output0(loc,i)) -
109 b * (df2_1[i] * output0(loc_m1,i) + f2[i] * output.access(loc_m1,i,2)) ;
115 for (ordinal_type p=0;p<order;++p) {
117 loc_p_0 = Intrepid2::getPnEnumeration<spaceDim>(p,0),
118 loc_p_1 = Intrepid2::getPnEnumeration<spaceDim>(p,1);
120 for (ordinal_type i=0;i<npts;++i) {
121 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));
123 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));
124 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);
131 for (ordinal_type p=0;p<order-1;++p)
132 for (ordinal_type q=1;q<order-p;++q) {
134 loc_p_qp1 = Intrepid2::getPnEnumeration<spaceDim>(p,q+1),
135 loc_p_q = Intrepid2::getPnEnumeration<spaceDim>(p,q),
136 loc_p_qm1 = Intrepid2::getPnEnumeration<spaceDim>(p,q-1);
139 Intrepid2::getJacobyRecurrenceCoeffs(a,b,c, 2*p+1,0,q);
140 for (ordinal_type i=0;i<npts;++i) {
141 output0(loc_p_qp1,i) = (a*(2.0*z(i,1)-1.0)+b)*output0(loc_p_q,i)
142 - c*output0(loc_p_qm1,i) ;
144 output.access(loc_p_qp1,i,1) = (a*(2.0*z(i,1)-1.0)+b)*output.access(loc_p_q,i,1)
145 - c*output.access(loc_p_qm1,i,1) ;
146 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)
147 - c*output.access(loc_p_qm1,i,2) ;
154 for (ordinal_type p=0;p<=order;++p)
155 for (ordinal_type q=0;q<=order-p;++q)
156 for (ordinal_type i=0;i<npts;++i) {
157 output0(Intrepid2::getPnEnumeration<spaceDim>(p,q),i) *= std::sqrt( (p+0.5)*(p+q+1.0));
159 output.access(Intrepid2::getPnEnumeration<spaceDim>(p,q),i,1) *= std::sqrt( (p+0.5)*(p+q+1.0));
160 output.access(Intrepid2::getPnEnumeration<spaceDim>(p,q),i,2) *= std::sqrt( (p+0.5)*(p+q+1.0));
165 template<
typename OutputViewType,
166 typename inputViewType,
167 typename workViewType,
169 KOKKOS_INLINE_FUNCTION
170 void OrthPolynomialTri<OutputViewType,inputViewType,workViewType,hasDeriv,1>::generate(
171 OutputViewType output,
172 const inputViewType input,
174 const ordinal_type order ) {
175 constexpr ordinal_type spaceDim = 2;
177 npts = input.extent(0),
178 card = output.extent(0);
180 workViewType dummyView;
181 OrthPolynomialTri<workViewType,inputViewType,workViewType,hasDeriv,0>::generate(work, input, dummyView, order);
182 for (ordinal_type i=0;i<card;++i)
183 for (ordinal_type j=0;j<npts;++j)
184 for (ordinal_type k=0;k<spaceDim;++k)
185 output.access(i,j,k) = work(i,j,k+1);
190 template<
typename OutputViewType,
191 typename inputViewType,
192 typename workViewType,
195 KOKKOS_INLINE_FUNCTION
196 void OrthPolynomialTri<OutputViewType,inputViewType,workViewType,hasDeriv,n>::generate(
198 const inputViewType ,
200 const ordinal_type ) {
201 INTREPID2_TEST_FOR_ABORT(
true,
202 ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_Cn_FEM_ORTH::OrthPolynomialTri) Computing of second and higher-order derivatives is not currently supported");
207 template<EOperator opType>
208 template<
typename OutputViewType,
209 typename inputViewType,
210 typename workViewType>
211 KOKKOS_INLINE_FUNCTION
213 Basis_HGRAD_TRI_Cn_FEM_ORTH::Serial<opType>::
214 getValues( OutputViewType output,
215 const inputViewType input,
217 const ordinal_type order) {
219 case OPERATOR_VALUE: {
220 OrthPolynomialTri<OutputViewType,inputViewType,workViewType,false,0>::generate( output, input, work, order );
225 OrthPolynomialTri<OutputViewType,inputViewType,workViewType,true,1>::generate( output, input, work, order );
229 OrthPolynomialTri<OutputViewType,inputViewType,workViewType,true,2>::generate( output, input, work, order );
233 INTREPID2_TEST_FOR_ABORT(
true,
234 ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_Cn_FEM_ORTH::Serial::getValues) operator is not supported");
239 template<
typename DT, ordinal_type numPtsPerEval,
240 typename outputValueValueType,
class ...outputValueProperties,
241 typename inputPointValueType,
class ...inputPointProperties>
243 Basis_HGRAD_TRI_Cn_FEM_ORTH::
245 const typename DT::execution_space& space,
246 Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
247 const Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPoints,
248 const ordinal_type order,
249 const EOperator operatorType ) {
250 typedef Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValueViewType;
251 typedef Kokkos::DynRankView<inputPointValueType, inputPointProperties...> inputPointViewType;
252 typedef typename DT::execution_space ExecSpaceType;
255 const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
256 const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
257 const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
258 Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(space, 0, loopSize);
260 typedef typename inputPointViewType::value_type inputPointType;
261 const ordinal_type cardinality = outputValues.extent(0);
262 const ordinal_type spaceDim = 2;
264 auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
265 typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
267 switch (operatorType) {
268 case OPERATOR_VALUE: {
269 workViewType dummyWorkView;
270 typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_VALUE,numPtsPerEval> FunctorType;
271 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, dummyWorkView, order) );
276 workViewType work(Kokkos::view_alloc(space,
"Basis_HGRAD_TRI_In_FEM_ORTH::getValues::work", vcprop), cardinality, inputPoints.extent(0), spaceDim+1);
277 typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_D1,numPtsPerEval> FunctorType;
278 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, work, order) );
282 workViewType dummyWorkView;
283 typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_D2,numPtsPerEval> FunctorType;
284 Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints ,dummyWorkView, order) );
288 INTREPID2_TEST_FOR_EXCEPTION( !Intrepid2::isValidOperator(operatorType), std::invalid_argument,
289 ">>> ERROR (Basis_HGRAD_TRI_Cn_FEM_ORTH): invalid operator type");
298 template<
typename DT,
typename OT,
typename PT>
302 constexpr ordinal_type spaceDim = 2;
303 this->basisCardinality_ = Intrepid2::getPnCardinality<spaceDim>(order);
304 this->basisDegree_ = order;
305 this->basisCellTopologyKey_ = shards::Triangle<3>::key;
306 this->basisType_ = BASIS_FEM_HIERARCHICAL;
307 this->basisCoordinates_ = COORDINATES_CARTESIAN;
308 this->functionSpace_ = FUNCTION_SPACE_HGRAD;
313 constexpr ordinal_type tagSize = 4;
314 const ordinal_type posScDim = 0;
315 const ordinal_type posScOrd = 1;
316 const ordinal_type posDfOrd = 2;
318 constexpr ordinal_type maxCard = Intrepid2::getPnCardinality<spaceDim, Parameters::MaxOrder>();
319 ordinal_type tags[maxCard][tagSize];
320 const ordinal_type card = this->basisCardinality_;
321 for (ordinal_type i=0;i<card;++i) {
332 this->setOrdinalTagData(this->tagToOrdinal_,
335 this->basisCardinality_,
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.
Kokkos::View< ordinal_type *, typename ExecutionSpace::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array.