49 #ifndef __INTREPID2_HGRAD_TET_CN_FEM_ORTH_DEF_HPP__ 
   50 #define __INTREPID2_HGRAD_TET_CN_FEM_ORTH_DEF_HPP__ 
   57 template<
typename OutputViewType,
 
   58 typename inputViewType,
 
   59 typename workViewType,
 
   61 KOKKOS_INLINE_FUNCTION
 
   62 void OrthPolynomialTet<OutputViewType,inputViewType,workViewType,hasDeriv,0>::generate(
 
   63     OutputViewType output,
 
   64     const inputViewType input,
 
   66     const ordinal_type order ) {
 
   68   constexpr ordinal_type spaceDim = 3;
 
   71   typedef typename OutputViewType::value_type value_type;
 
   73   auto output0 = (hasDeriv) ? Kokkos::subview(output,  Kokkos::ALL(), Kokkos::ALL(),0) : Kokkos::subview(output,  Kokkos::ALL(), Kokkos::ALL());
 
   76   npts = input.extent(0);
 
   86     const ordinal_type loc = Intrepid2::getPnEnumeration<spaceDim>(0,0,0);
 
   87     for (ordinal_type i=0;i<npts;++i) {
 
   88       output0(loc, i) = 1.0;
 
   90         output.access(loc,i,1) = 0;
 
   91         output.access(loc,i,2) = 0;
 
   92         output.access(loc,i,3) = 0;
 
   98     value_type f1[maxNumPts]={},f2[maxNumPts]={}, f3[maxNumPts]={}, f4[maxNumPts]={},f5[maxNumPts]={},
 
   99         df2_1[maxNumPts]={}, df2_2[maxNumPts]={}, df5_2[maxNumPts]={};
 
  100     value_type df1_0, df1_1, df1_2, df3_1, df3_2, df4_2;
 
  102     for (
int i=0;i<npts;i++) {
 
  103       f1[i] = 2.0*z(i,0) + z(i,1) + z(i,2)- 1.0;
 
  104       f2[i] = pow(z(i,1) + z(i,2) -1.0, 2);
 
  105       f3[i] = 2.0*z(i,1) + z(i,2) -1.0;
 
  106       f4[i] = 1.0 - z(i,2);
 
  107       f5[i] = f4[i] * f4[i];
 
  109         df2_1[i] = 2*(z(i,1) + z(i,2) -1.0);
 
  124       const ordinal_type loc = Intrepid2::getPnEnumeration<spaceDim>(1,0,0);
 
  125       for (ordinal_type i=0;i<npts;++i) {
 
  126         output0(loc, i) = f1[i];
 
  128           output.access(loc,i,1) = df1_0;
 
  129           output.access(loc,i,2) = df1_1;
 
  130           output.access(loc,i,3) = df1_2;
 
  137         for (ordinal_type p=1;p<order;p++) {
 
  139           loc = Intrepid2::getPnEnumeration<spaceDim>(p,0,0),
 
  140           loc_p1 = Intrepid2::getPnEnumeration<spaceDim>(p+1,0,0),
 
  141           loc_m1 = Intrepid2::getPnEnumeration<spaceDim>(p-1,0,0);
 
  144           a = (2.0*p+1.0)/(1.0+p),
 
  147           for (ordinal_type i=0;i<npts;++i) {
 
  148             output0(loc_p1,i) = ( a * f1[i] * output0(loc,i) -
 
  149                 b * f2[i] * output0(loc_m1,i) );
 
  151               output.access(loc_p1,i,1) =  a * (f1[i] * output.access(loc,i,1) + df1_0 * output0(loc,i))  -
 
  152                   b * f2[i] * output.access(loc_m1,i,1) ;
 
  153               output.access(loc_p1,i,2) =  a * (f1[i] * output.access(loc,i,2) + df1_1 * output0(loc,i))  -
 
  154                   b * (df2_1[i] * output0(loc_m1,i) + f2[i] * output.access(loc_m1,i,2)) ;
 
  155               output.access(loc_p1,i,3) =  a * (f1[i] * output.access(loc,i,3) + df1_2 * output0(loc,i))  -
 
  156                   b * (df2_2[i] * output0(loc_m1,i) + f2[i] * output.access(loc_m1,i,3)) ;
 
  162         for (ordinal_type p=0;p<order;++p) {
 
  164           loc_p_0 = Intrepid2::getPnEnumeration<spaceDim>(p,0,0),
 
  165           loc_p_1 = Intrepid2::getPnEnumeration<spaceDim>(p,1,0);
 
  167           for (ordinal_type i=0;i<npts;++i) {
 
  168             const value_type coeff = (2.0 * p + 3.0) * z(i,1) + z(i,2)-1.0;
 
  169             output0(loc_p_1,i) = output0(loc_p_0,i)*coeff;
 
  171               output.access(loc_p_1,i,1) = output.access(loc_p_0,i,1)*coeff;
 
  172               output.access(loc_p_1,i,2) = output.access(loc_p_0,i,2)*coeff + output0(loc_p_0,i)*(2.0 * p + 3.0);
 
  173               output.access(loc_p_1,i,3) = output.access(loc_p_0,i,3)*coeff + output0(loc_p_0,i);
 
  181         for (ordinal_type p=0;p<order-1;++p)
 
  182           for (ordinal_type q=1;q<order-p;++q) {
 
  184             loc_p_qp1 = Intrepid2::getPnEnumeration<spaceDim>(p,q+1,0),
 
  185             loc_p_q = Intrepid2::getPnEnumeration<spaceDim>(p,q,0),
 
  186             loc_p_qm1 = Intrepid2::getPnEnumeration<spaceDim>(p,q-1,0);
 
  188             value_type a,b,c, coeff, dcoeff_1, dcoeff_2;
 
  189             Intrepid2::getJacobyRecurrenceCoeffs(a,b,c, 2*p+1,0,q);
 
  190             for (ordinal_type i=0;i<npts;++i) {
 
  191               coeff = a * f3[i] + b * f4[i];
 
  192               dcoeff_1 = a * df3_1;
 
  193               dcoeff_2 = a * df3_2 + b * df4_2;
 
  194               output0(loc_p_qp1,i) =  coeff * output0(loc_p_q,i)
 
  195               - c* f5[i] * output0(loc_p_qm1,i) ;
 
  197                 output.access(loc_p_qp1,i,1) =  coeff * output.access(loc_p_q,i,1) +
 
  198                     - c * f5[i] * output.access(loc_p_qm1,i,1) ;
 
  199                 output.access(loc_p_qp1,i,2) =  coeff * output.access(loc_p_q,i,2)  + dcoeff_1 * output0(loc_p_q,i)
 
  200                 - c * f5[i] * output.access(loc_p_qm1,i,2) ;
 
  201                 output.access(loc_p_qp1,i,3) =  coeff * output.access(loc_p_q,i,3)  + dcoeff_2 * output0(loc_p_q,i)
 
  202                 - c * f5[i] * output.access(loc_p_qm1,i,3) - c * df5_2[i] * output0(loc_p_qm1,i);
 
  209         for (ordinal_type p=0;p<order;++p)
 
  210           for (ordinal_type q=0;q<order-p;++q) {
 
  213             loc_p_q_0 = Intrepid2::getPnEnumeration<spaceDim>(p,q,0),
 
  214             loc_p_q_1 = Intrepid2::getPnEnumeration<spaceDim>(p,q,1);
 
  216             for (ordinal_type i=0;i<npts;++i) {
 
  217               const value_type coeff =  2.0 * ( 2.0 + q + p ) * z(i,2) - 1.0;
 
  218               output0(loc_p_q_1,i) = output0(loc_p_q_0,i) * coeff;
 
  220                 output.access(loc_p_q_1,i,1) = output.access(loc_p_q_0,i,1) * coeff;
 
  221                 output.access(loc_p_q_1,i,2) = output.access(loc_p_q_0,i,2) * coeff;
 
  222                 output.access(loc_p_q_1,i,3) = output.access(loc_p_q_0,i,3) * coeff + 2.0 * ( 2.0 + q + p ) * output0(loc_p_q_0,i);
 
  229         for (ordinal_type p=0;p<order-1;++p)
 
  230           for (ordinal_type q=0;q<order-p-1;++q)
 
  231             for (ordinal_type r=1;r<order-p-q;++r) {
 
  233               loc_p_q_rp1 = Intrepid2::getPnEnumeration<spaceDim>(p,q,r+1),
 
  234               loc_p_q_r = Intrepid2::getPnEnumeration<spaceDim>(p,q,r),
 
  235               loc_p_q_rm1 = Intrepid2::getPnEnumeration<spaceDim>(p,q,r-1);
 
  237               value_type a,b,c, coeff;
 
  238               Intrepid2::getJacobyRecurrenceCoeffs(a,b,c, 2*p+2*q+2,0,r);
 
  239               for (ordinal_type i=0;i<npts;++i) {
 
  240                 coeff = 2.0 * a * z(i,2) - a + b;
 
  241                 output0(loc_p_q_rp1,i) =  coeff * output0(loc_p_q_r,i) - c * output0(loc_p_q_rm1,i) ;
 
  243                   output.access(loc_p_q_rp1,i,1) =  coeff * output.access(loc_p_q_r,i,1) - c * output.access(loc_p_q_rm1,i,1);
 
  244                   output.access(loc_p_q_rp1,i,2) =  coeff * output.access(loc_p_q_r,i,2) - c * output.access(loc_p_q_rm1,i,2);
 
  245                   output.access(loc_p_q_rp1,i,3) =  coeff * output.access(loc_p_q_r,i,3) + 2 * a * output0(loc_p_q_r,i) - c * output.access(loc_p_q_rm1,i,3);
 
  253   for (ordinal_type p=0;p<=order;++p)
 
  254     for (ordinal_type q=0;q<=order-p;++q)
 
  255       for (ordinal_type r=0;r<=order-p-q;++r) {
 
  256         ordinal_type loc_p_q_r = Intrepid2::getPnEnumeration<spaceDim>(p,q,r);
 
  257         value_type scal = std::sqrt( (p+0.5)*(p+q+1.0)*(p+q+r+1.5) );
 
  258         for (ordinal_type i=0;i<npts;++i) {
 
  259           output0(loc_p_q_r,i) *= scal;
 
  261             output.access(loc_p_q_r,i,1) *= scal;
 
  262             output.access(loc_p_q_r,i,2) *= scal;
 
  263             output.access(loc_p_q_r,i,3) *= scal;
 
  269 template<
typename OutputViewType,
 
  270 typename inputViewType,
 
  271 typename workViewType,
 
  273 KOKKOS_INLINE_FUNCTION
 
  274 void OrthPolynomialTet<OutputViewType,inputViewType,workViewType,hasDeriv,1>::generate(
 
  275     OutputViewType output,
 
  276     const inputViewType  input,
 
  278     const ordinal_type   order ) {
 
  279   constexpr ordinal_type spaceDim = 3;
 
  281   npts = input.extent(0),
 
  282   card = output.extent(0);
 
  284   workViewType dummyView;
 
  285   OrthPolynomialTet<workViewType,inputViewType,workViewType,hasDeriv,0>::generate(work, input, dummyView, order);
 
  286   for (ordinal_type i=0;i<card;++i)
 
  287     for (ordinal_type j=0;j<npts;++j)
 
  288       for (ordinal_type k=0;k<spaceDim;++k)
 
  289         output.access(i,j,k) = work(i,j,k+1);
 
  294 template<
typename OutputViewType,
 
  295 typename inputViewType,
 
  296 typename workViewType,
 
  299 KOKKOS_INLINE_FUNCTION
 
  300 void OrthPolynomialTet<OutputViewType,inputViewType,workViewType,hasDeriv,n>::generate(
 
  302     const inputViewType  ,
 
  304     const ordinal_type    ) {
 
  305 #if 0 //#ifdef HAVE_INTREPID2_SACADO 
  307 constexpr ordinal_type spaceDim = 3;
 
  308 constexpr ordinal_type maxCard = Intrepid2::getPnCardinality<spaceDim, Parameters::MaxOrder>();
 
  310 typedef typename OutputViewType::value_type value_type;
 
  311 typedef Sacado::Fad::SFad<value_type,spaceDim> fad_type;
 
  314 npts = input.extent(0),
 
  315 card = output.extent(0);
 
  321 typedef typename inputViewType::memory_space memory_space;
 
  322 typedef typename inputViewType::memory_space memory_space;
 
  323 typedef typename Kokkos::View<fad_type***, memory_space> outViewType;
 
  324 typedef typename Kokkos::View<fad_type**, memory_space> inViewType;
 
  325 auto vcprop = Kokkos::common_view_alloc_prop(input);
 
  327 inViewType in(Kokkos::view_wrap((value_type*)&inBuf[0][0], vcprop), npts, spaceDim);
 
  328 outViewType out(Kokkos::view_wrap((value_type*)&outBuf[0][0][0], vcprop), card, npts, n*(n+1)/2);
 
  330 for (ordinal_type i=0;i<npts;++i)
 
  331   for (ordinal_type j=0;j<spaceDim;++j) {
 
  332     in(i,j) = input(i,j);
 
  333     in(i,j).diff(j,spaceDim);
 
  336 typedef typename Kokkos::DynRankView<fad_type, memory_space> outViewType_;
 
  337 outViewType_ workView;
 
  341   auto vcprop = Kokkos::common_view_alloc_prop(in);
 
  342   workView = outViewType_( Kokkos::view_wrap((value_type*)&outBuf[0][0][0], vcprop), card, npts, spaceDim+1);
 
  344 OrthPolynomialTet<outViewType,inViewType,outViewType_,hasDeriv,n-1>::generate(out, in, workView, order);
 
  346 for (ordinal_type i=0;i<card;++i)
 
  347   for (ordinal_type j=0;j<npts;++j) {
 
  348     for (ordinal_type i_dx = 0; i_dx <= n; ++i_dx)
 
  349       for (ordinal_type i_dy = 0; i_dy <= n-i_dx; ++i_dy) {
 
  350         ordinal_type i_dz = n - i_dx - i_dy;
 
  351         ordinal_type i_Dn = Intrepid2::getDkEnumeration<spaceDim>(i_dx,i_dy,i_dz);
 
  355           ordinal_type i_Dnm1 = Intrepid2::getDkEnumeration<spaceDim>(i_dx-1, i_dy, i_dz);
 
  356           output.access(i,j,i_Dn) = out(i,j,i_Dnm1).dx(0);
 
  361           ordinal_type i_Dnm1 = Intrepid2::getDkEnumeration<spaceDim>(i_dx, i_dy-1, i_dz);
 
  362           output.access(i,j,i_Dn) = out(i,j,i_Dnm1).dx(1);
 
  367           ordinal_type i_Dnm1 = Intrepid2::getDkEnumeration<spaceDim>(i_dx, i_dy, i_dz-1);
 
  368           output.access(i,j,i_Dn) = out(i,j,i_Dnm1).dx(2);
 
  373 INTREPID2_TEST_FOR_ABORT( 
true,
 
  374     ">>> ERROR: (Intrepid2::Basis_HGRAD_TRI_Cn_FEM_ORTH::OrthPolynomialTri) Computing of second and higher-order derivatives is not currently supported");
 
  379 template<EOperator opType>
 
  380 template<
typename OutputViewType,
 
  381 typename inputViewType,
 
  382 typename workViewType>
 
  383 KOKKOS_INLINE_FUNCTION
 
  385 Basis_HGRAD_TET_Cn_FEM_ORTH::Serial<opType>::
 
  386 getValues( OutputViewType output,
 
  387     const inputViewType  input,
 
  389     const ordinal_type   order) {
 
  391   case OPERATOR_VALUE: {
 
  392     OrthPolynomialTet<OutputViewType,inputViewType,workViewType,false,0>::generate( output, input, work, order );
 
  397     OrthPolynomialTet<OutputViewType,inputViewType,workViewType,true,1>::generate( output, input, work, order );
 
  401     OrthPolynomialTet<OutputViewType,inputViewType,workViewType,true,2>::generate( output, input, work, order );
 
  405     INTREPID2_TEST_FOR_ABORT( 
true,
 
  406         ">>> ERROR: (Intrepid2::Basis_HGRAD_TET_Cn_FEM_ORTH::Serial::getValues) operator is not supported");
 
  413 template<
typename SpT, ordinal_type numPtsPerEval,
 
  414 typename outputValueValueType, 
class ...outputValueProperties,
 
  415 typename inputPointValueType,  
class ...inputPointProperties>
 
  417 Basis_HGRAD_TET_Cn_FEM_ORTH::
 
  418 getValues(       Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
 
  419     const Kokkos::DynRankView<inputPointValueType, inputPointProperties...>  inputPoints,
 
  420     const ordinal_type order,
 
  421     const EOperator operatorType ) {
 
  422   typedef          Kokkos::DynRankView<outputValueValueType,outputValueProperties...>         outputValueViewType;
 
  423   typedef          Kokkos::DynRankView<inputPointValueType, inputPointProperties...>          inputPointViewType;
 
  424   typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
 
  427   const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
 
  428   const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
 
  429   const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
 
  430   Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
 
  432   typedef typename inputPointViewType::value_type inputPointType;
 
  433   const ordinal_type cardinality = outputValues.extent(0);
 
  434   const ordinal_type spaceDim = 3;
 
  436   auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
 
  437   typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
 
  439   switch (operatorType) {
 
  440   case OPERATOR_VALUE: {
 
  441     workViewType  dummyWorkView;
 
  442     typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_VALUE,numPtsPerEval> FunctorType;
 
  443     Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, dummyWorkView, order) );
 
  448     workViewType  work(Kokkos::view_alloc(
"Basis_HGRAD_TET_In_FEM_ORTH::getValues::work", vcprop), cardinality, inputPoints.extent(0), spaceDim+1);
 
  449     typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_D1,numPtsPerEval> FunctorType;
 
  450     Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, work, order) );
 
  454     workViewType  dummyWorkView;
 
  455     typedef Functor<outputValueViewType,inputPointViewType,workViewType,OPERATOR_D2,numPtsPerEval> FunctorType;
 
  456     Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints ,dummyWorkView, order) );
 
  460     INTREPID2_TEST_FOR_EXCEPTION( !Intrepid2::isValidOperator(operatorType), std::invalid_argument,
 
  461         ">>> ERROR (Basis_HGRAD_TET_Cn_FEM_ORTH): invalid operator type");
 
  469 template<
typename SpT, 
typename OT, 
typename PT>
 
  473   constexpr ordinal_type spaceDim = 3;
 
  474   this->basisCardinality_  = Intrepid2::getPnCardinality<spaceDim>(order);
 
  475   this->basisDegree_       = order;
 
  476   this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Tetrahedron<4> >() );
 
  477   this->basisType_         = BASIS_FEM_HIERARCHICAL;
 
  478   this->basisCoordinates_  = COORDINATES_CARTESIAN;
 
  479   this->functionSpace_     = FUNCTION_SPACE_HGRAD;
 
  484     constexpr ordinal_type tagSize  = 4;    
 
  485     const ordinal_type posScDim = 0;        
 
  486     const ordinal_type posScOrd = 1;        
 
  487     const ordinal_type posDfOrd = 2;        
 
  489     constexpr ordinal_type maxCard = Intrepid2::getPnCardinality<spaceDim, Parameters::MaxOrder>();
 
  490     ordinal_type tags[maxCard][tagSize];
 
  491     const ordinal_type card = this->basisCardinality_;
 
  492     for (ordinal_type i=0;i<card;++i) {
 
  503     this->setOrdinalTagData(this->tagToOrdinal_,
 
  506         this->basisCardinality_,
 
Kokkos::View< ordinal_type *, typename ExecSpaceType::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array. 
 
Basis_HGRAD_TET_Cn_FEM_ORTH(const ordinal_type order)
Constructor. 
 
static constexpr ordinal_type MaxNumPtsPerBasisEval
The maximum number of points to eval in serial mode.