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.