49 #ifndef __INTREPID2_HDIV_TRI_IN_FEM_DEF_HPP__ 
   50 #define __INTREPID2_HDIV_TRI_IN_FEM_DEF_HPP__ 
   60 template<EOperator opType>
 
   61 template<
typename OutputViewType,
 
   62 typename inputViewType,
 
   63 typename workViewType,
 
   64 typename vinvViewType>
 
   65 KOKKOS_INLINE_FUNCTION
 
   67 Basis_HDIV_TRI_In_FEM::Serial<opType>::
 
   68 getValues(  OutputViewType output,
 
   69     const inputViewType  input,
 
   71     const vinvViewType   coeffs ) {
 
   73   constexpr ordinal_type spaceDim = 2;
 
   75   cardPn = coeffs.extent(0)/spaceDim,
 
   76   card = coeffs.extent(1),
 
   77   npts = input.extent(0);
 
   80   ordinal_type order = 0;
 
   82     if (card == CardinalityHDivTri(p)) {
 
   88   typedef typename Kokkos::DynRankView<typename workViewType::value_type, typename workViewType::memory_space> viewType;
 
   89   auto vcprop = Kokkos::common_view_alloc_prop(work);
 
   90   auto ptr = work.data();
 
   93   case OPERATOR_VALUE: {
 
   94     const viewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts);
 
   95     workViewType dummyView;
 
   97     Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::
 
   98     Serial<opType>::getValues(phis, input, dummyView, order);
 
  100     for (ordinal_type i=0;i<card;++i)
 
  101       for (ordinal_type j=0;j<npts;++j)
 
  102         for (ordinal_type d=0;d<spaceDim;++d) {
 
  103           output.access(i,j,d) = 0.0;
 
  104           for (ordinal_type k=0;k<cardPn;++k)
 
  105             output.access(i,j,d) += coeffs(k+d*cardPn,i) * phis.access(k,j);
 
  110     const viewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts, spaceDim);
 
  111     ptr += card*npts*spaceDim*get_dimension_scalar(work);
 
  112     const viewType workView(Kokkos::view_wrap(ptr, vcprop), card, npts, spaceDim+1);
 
  114     Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::
 
  115     Serial<OPERATOR_GRAD>::getValues(phis, input, workView, order);
 
  117     for (ordinal_type i=0;i<card;++i)
 
  118       for (ordinal_type j=0;j<npts;++j) {
 
  119         output.access(i,j) = 0.0;
 
  120         for (ordinal_type k=0; k<cardPn; ++k)
 
  121           for (ordinal_type d=0; d<spaceDim; ++d)
 
  122             output.access(i,j) += coeffs(k+d*cardPn,i)*phis.access(k,j,d);
 
  127     INTREPID2_TEST_FOR_ABORT( 
true,
 
  128         ">>> ERROR (Basis_HDIV_TRI_In_FEM): Operator type not implemented");
 
  133 template<
typename SpT, ordinal_type numPtsPerEval,
 
  134 typename outputValueValueType, 
class ...outputValueProperties,
 
  135 typename inputPointValueType,  
class ...inputPointProperties,
 
  136 typename vinvValueType,        
class ...vinvProperties>
 
  138 Basis_HDIV_TRI_In_FEM::
 
  139 getValues(  Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
 
  140     const Kokkos::DynRankView<inputPointValueType, inputPointProperties...>  inputPoints,
 
  141     const Kokkos::DynRankView<vinvValueType,       vinvProperties...>        coeffs,
 
  142     const EOperator operatorType) {
 
  143   typedef          Kokkos::DynRankView<outputValueValueType,outputValueProperties...>         outputValueViewType;
 
  144   typedef          Kokkos::DynRankView<inputPointValueType, inputPointProperties...>          inputPointViewType;
 
  145   typedef          Kokkos::DynRankView<vinvValueType,       vinvProperties...>                vinvViewType;
 
  146   typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
 
  149   const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
 
  150   const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
 
  151   const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
 
  152   Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
 
  154   typedef typename inputPointViewType::value_type inputPointType;
 
  156   const ordinal_type cardinality = outputValues.extent(0);
 
  157   const ordinal_type spaceDim = 2;
 
  159   auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
 
  160   typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
 
  162   switch (operatorType) {
 
  163   case OPERATOR_VALUE: {
 
  164     workViewType  work(Kokkos::view_alloc(
"Basis_HDIV_TRI_In_FEM::getValues::work", vcprop), cardinality, inputPoints.extent(0));
 
  165     typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
 
  166         OPERATOR_VALUE,numPtsPerEval> FunctorType;
 
  167     Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, coeffs, work) );
 
  171     workViewType  work(Kokkos::view_alloc(
"Basis_HDIV_TRI_In_FEM::getValues::work", vcprop), cardinality*(2*spaceDim+1), inputPoints.extent(0));
 
  172     typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
 
  173         OPERATOR_DIV,numPtsPerEval> FunctorType;
 
  174     Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, coeffs, work) );
 
  178     INTREPID2_TEST_FOR_EXCEPTION( 
true , std::invalid_argument,
 
  179         ">>> ERROR (Basis_HDIV_TRI_In_FEM): Operator type not implemented" );
 
  186 template<
typename SpT, 
typename OT, 
typename PT>
 
  189     const EPointType   pointType ) {
 
  191   constexpr ordinal_type spaceDim = 2;
 
  192   this->basisCardinality_  = CardinalityHDivTri(order);
 
  193   this->basisDegree_       = order; 
 
  194   this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() );
 
  195   this->basisType_         = BASIS_FEM_FIAT;
 
  196   this->basisCoordinates_  = COORDINATES_CARTESIAN;
 
  197   this->functionSpace_     = FUNCTION_SPACE_HDIV;
 
  199   const ordinal_type card = this->basisCardinality_;
 
  201   const ordinal_type  cardPn = Intrepid2::getPnCardinality<spaceDim>(order); 
 
  202   const ordinal_type  cardPnm1 = Intrepid2::getPnCardinality<spaceDim>(order-1);  
 
  203   const ordinal_type  cardPnm2 = Intrepid2::getPnCardinality<spaceDim>(order-2); 
 
  204   const ordinal_type  cardVecPn = spaceDim*cardPn;  
 
  205   const ordinal_type  cardVecPnm1 = spaceDim*cardPnm1;   
 
  209   constexpr ordinal_type tagSize  = 4;        
 
  211   ordinal_type tags[maxCard][tagSize];
 
  214   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  215   dofCoords(
"Hdiv::Tri::In::dofCoords", card, spaceDim);
 
  217   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  218   dofCoeffs(
"Hdiv::Tri::In::dofCoeffs", card, spaceDim);
 
  220   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  221   coeffs(
"Hdiv::Tri::In::coeffs", cardVecPn, card);
 
  227   const ordinal_type lwork = card*card;
 
  228   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  229   V1(
"Hdiv::Tri::In::V1", cardVecPn, card);
 
  239   for (ordinal_type i=0;i<cardPnm1;i++) {
 
  241     V1(cardPn+i,cardPnm1+i) = 1.0;
 
  247   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> cubPoints(
"Hdiv::Tri::In::cubPoints", myCub.
getNumPoints() , spaceDim );
 
  248   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> cubWeights(
"Hdiv::Tri::In::cubWeights", myCub.
getNumPoints() );
 
  252   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> phisAtCubPoints(
"Hdiv::Tri::In::phisAtCubPoints", cardPn , myCub.
getNumPoints() );
 
  253   Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>(phisAtCubPoints, cubPoints, order, OPERATOR_VALUE);
 
  256   for (ordinal_type i=0;i<order;i++) {
 
  257     for (ordinal_type j=0;j<cardPn;j++) { 
 
  258       V1(j,cardVecPnm1+i) = 0.0;
 
  259       for (ordinal_type d=0; d< spaceDim; ++d)
 
  261           V1(j+d*cardPn,cardVecPnm1+i) +=
 
  262               cubWeights(k) * cubPoints(k,d)
 
  263               * phisAtCubPoints(cardPnm2+i,k)
 
  264               * phisAtCubPoints(j,k);
 
  270   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  271   V2(
"Hdiv::Tri::In::V2", card ,cardVecPn);
 
  273   const ordinal_type numEdges = this->basisCellTopology_.getEdgeCount();
 
  275   shards::CellTopology edgeTop(shards::getCellTopologyData<shards::Line<2> >() );
 
  283   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> linePts(
"Hdiv::Tri::In::linePts", numPtsPerEdge , 1 );
 
  286   const ordinal_type offset = 1;
 
  293   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> edgePts(
"Hdiv::Tri::In::edgePts", numPtsPerEdge , spaceDim );
 
  294   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> phisAtEdgePoints(
"Hdiv::Tri::In::phisAtEdgePoints", cardPn , numPtsPerEdge );
 
  295   Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> edgeNormal(
"Hcurl::Tri::In::edgeNormal", spaceDim );
 
  298   for (ordinal_type edge=0;edge<numEdges;edge++) {  
 
  301         this->basisCellTopology_ );
 
  304     const scalarType refEdgeMeasure = 2.0;
 
  305     for (ordinal_type j=0;j<spaceDim;j++)
 
  306       edgeNormal(j) *= refEdgeMeasure;
 
  313         this->basisCellTopology_ );
 
  315     Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>(phisAtEdgePoints , edgePts, order, OPERATOR_VALUE);
 
  318     for (ordinal_type j=0;j<numPtsPerEdge;j++) {
 
  320       const ordinal_type i_card = numPtsPerEdge*edge+j;
 
  323       for (ordinal_type k=0;k<cardPn;k++) {
 
  325         for (ordinal_type l=0; l<spaceDim; l++)
 
  326           V2(i_card,k+l*cardPn) = edgeNormal(l) * phisAtEdgePoints(k,j);
 
  331       for(ordinal_type l=0; l<spaceDim; ++l) {
 
  332         dofCoords(i_card,l) = edgePts(j,l);
 
  333         dofCoeffs(i_card,l) = edgeNormal(l);
 
  337       tags[i_card][1] = edge; 
 
  339       tags[i_card][3] = numPtsPerEdge; 
 
  356   if (numPtsPerCell > 0) {
 
  357     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  358     internalPoints( 
"Hdiv::Tri::In::internalPoints", numPtsPerCell , spaceDim );
 
  360         this->basisCellTopology_ ,
 
  365     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  366     phisAtInternalPoints(
"Hdiv::Tri::In::phisAtInternalPoints", cardPn , numPtsPerCell );
 
  367     Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>( phisAtInternalPoints , internalPoints , order, OPERATOR_VALUE );
 
  370     for (ordinal_type j=0;j<numPtsPerCell;j++) {
 
  372       const ordinal_type i_card = numEdges*order+spaceDim*j;
 
  374       for (ordinal_type k=0;k<cardPn;k++) {
 
  375         for (ordinal_type l=0;l<spaceDim;l++) {
 
  376           V2(i_card+l,l*cardPn+k) = phisAtInternalPoints(k,j);
 
  381       for(ordinal_type d=0; d<spaceDim; ++d) {
 
  382         for(ordinal_type l=0; l<spaceDim; ++l) {
 
  383           dofCoords(i_card+d,l) = internalPoints(j,l);
 
  384           dofCoeffs(i_card+d,l) = (l==d);
 
  387         tags[i_card+d][0] = spaceDim; 
 
  388         tags[i_card+d][1] = 0; 
 
  389         tags[i_card+d][2] = spaceDim*j+d; 
 
  390         tags[i_card+d][3] = spaceDim*numPtsPerCell; 
 
  397   Kokkos::DynRankView<scalarType,Kokkos::LayoutLeft,Kokkos::HostSpace>
 
  398   vmat(
"Hdiv::Tri::In::vmat", card, card),
 
  399   work(
"Hdiv::Tri::In::work", lwork),
 
  400   ipiv(
"Hdiv::Tri::In::ipiv", card);
 
  403   for(ordinal_type i=0; i< card; ++i) {
 
  404     for(ordinal_type j=0; j< card; ++j) {
 
  406       for(ordinal_type k=0; k< cardVecPn; ++k)
 
  407         s += V2(i,k)*V1(k,j);
 
  412   ordinal_type info = 0;
 
  413   Teuchos::LAPACK<ordinal_type,scalarType> lapack;
 
  415   lapack.GETRF(card, card,
 
  416       vmat.data(), vmat.stride_1(),
 
  417       (ordinal_type*)ipiv.data(),
 
  420   INTREPID2_TEST_FOR_EXCEPTION( info != 0,
 
  422       ">>> ERROR: (Intrepid2::Basis_HDIV_TRI_In_FEM) lapack.GETRF returns nonzero info." );
 
  425       vmat.data(), vmat.stride_1(),
 
  426       (ordinal_type*)ipiv.data(),
 
  430   INTREPID2_TEST_FOR_EXCEPTION( info != 0,
 
  432       ">>> ERROR: (Intrepid2::Basis_HDIV_TRI_In_FEM) lapack.GETRI returns nonzero info." );
 
  434   for (ordinal_type i=0;i<cardVecPn;++i)
 
  435     for (ordinal_type j=0;j<card;++j){
 
  437       for(ordinal_type k=0; k< card; ++k)
 
  438         s += V1(i,k)*vmat(k,j);
 
  442   this->coeffs_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), coeffs);
 
  443   Kokkos::deep_copy(this->coeffs_ , coeffs);
 
  445   this->dofCoords_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), dofCoords);
 
  446   Kokkos::deep_copy(this->dofCoords_, dofCoords);
 
  448   this->dofCoeffs_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), dofCoeffs);
 
  449   Kokkos::deep_copy(this->dofCoeffs_, dofCoeffs);
 
  455     const ordinal_type posScDim = 0;        
 
  456     const ordinal_type posScOrd = 1;        
 
  457     const ordinal_type posDfOrd = 2;        
 
  463     this->setOrdinalTagData(this->tagToOrdinal_,
 
  466         this->basisCardinality_,
 
Kokkos::View< ordinal_type *, typename ExecSpaceType::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array. 
 
Basis_HDIV_TRI_In_FEM(const ordinal_type order, const EPointType pointType=POINTTYPE_EQUISPACED)
Constructor. 
 
Header file for the Intrepid2::Basis_HGRAD_TRI_Cn_FEM_ORTH class. 
 
Header file for the Intrepid2::CubatureDirectTriDefault class. 
 
Defines direct integration rules on a triangle. 
 
virtual void getCubature(PointViewType cubPoints, weightViewType cubWeights) const 
Returns cubature points and weights (return arrays must be pre-sized/pre-allocated). 
 
static constexpr ordinal_type MaxOrder
The maximum reconstruction order. 
 
virtual ordinal_type getNumPoints() const 
Returns the number of cubature points.