49 #ifndef __INTREPID2_HCURL_TRI_IN_FEM_DEF_HPP__ 
   50 #define __INTREPID2_HCURL_TRI_IN_FEM_DEF_HPP__ 
   61     template<EOperator opType>
 
   62     template<
typename OutputViewType,
 
   63              typename inputViewType,
 
   64              typename workViewType,
 
   65              typename vinvViewType>
 
   66     KOKKOS_INLINE_FUNCTION
 
   68     Basis_HCURL_TRI_In_FEM::Serial<opType>::
 
   69     getValues(       OutputViewType output,
 
   70                const inputViewType  input,
 
   72                const vinvViewType   coeffs ) {
 
   74       constexpr ordinal_type spaceDim = 2;
 
   76         cardPn = coeffs.extent(0)/spaceDim,
 
   77         card = coeffs.extent(1),
 
   78         npts = input.extent(0);
 
   81       ordinal_type order = 0;
 
   83         if (card == CardinalityHCurlTri(p)) {
 
   89       typedef typename Kokkos::DynRankView<typename workViewType::value_type, typename workViewType::memory_space> viewType;
 
   90       auto vcprop = Kokkos::common_view_alloc_prop(work);
 
   91       auto ptr = work.data();
 
   94       case OPERATOR_VALUE: {
 
   95         const viewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts);
 
   96         workViewType dummyView;
 
   98         Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::
 
   99           Serial<opType>::getValues(phis, input, dummyView, order);
 
  101         for (ordinal_type i=0;i<card;++i)
 
  102           for (ordinal_type j=0;j<npts;++j)
 
  103             for (ordinal_type d=0;d<spaceDim;++d) {
 
  104               output.access(i,j,d) = 0.0;
 
  105               for (ordinal_type k=0;k<cardPn;++k)
 
  106                 output.access(i,j,d) += coeffs(k+d*cardPn,i) * phis(k,j);
 
  110       case OPERATOR_CURL: {
 
  111         const viewType phis(Kokkos::view_wrap(ptr, vcprop), card, npts, spaceDim);
 
  112         ptr += card*npts*spaceDim*get_dimension_scalar(work);
 
  113         const viewType workView(Kokkos::view_wrap(ptr, vcprop), card, npts, spaceDim+1);
 
  115         Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::
 
  116           Serial<OPERATOR_GRAD>::getValues(phis, input, workView, order);
 
  118         for (ordinal_type i=0;i<card;++i)
 
  119           for (ordinal_type j=0;j<npts;++j) {
 
  120             output.access(i,j) = 0.0;
 
  121             for (ordinal_type k=0; k<cardPn; ++k)
 
  122               output.access(i,j) += - coeffs(k,i)*phis(k,j,1)              
 
  123                 + coeffs(k+cardPn,i)*phis(k,j,0);      
 
  128         INTREPID2_TEST_FOR_ABORT( 
true,
 
  129                                   ">>> ERROR (Basis_HCURL_TRI_In_FEM): Operator type not implemented");
 
  134     template<
typename SpT, ordinal_type numPtsPerEval,
 
  135              typename outputValueValueType, 
class ...outputValueProperties,
 
  136              typename inputPointValueType,  
class ...inputPointProperties,
 
  137              typename vinvValueType,        
class ...vinvProperties>
 
  139     Basis_HCURL_TRI_In_FEM::
 
  140     getValues(       Kokkos::DynRankView<outputValueValueType,outputValueProperties...> outputValues,
 
  141                const Kokkos::DynRankView<inputPointValueType, inputPointProperties...>  inputPoints,
 
  142                const Kokkos::DynRankView<vinvValueType,       vinvProperties...>        coeffs,
 
  143                const EOperator operatorType) {
 
  144       typedef          Kokkos::DynRankView<outputValueValueType,outputValueProperties...>         outputValueViewType;
 
  145       typedef          Kokkos::DynRankView<inputPointValueType, inputPointProperties...>          inputPointViewType;
 
  146       typedef          Kokkos::DynRankView<vinvValueType,       vinvProperties...>                vinvViewType;
 
  147       typedef typename ExecSpace<typename inputPointViewType::execution_space,SpT>::ExecSpaceType ExecSpaceType;
 
  150       const auto loopSizeTmp1 = (inputPoints.extent(0)/numPtsPerEval);
 
  151       const auto loopSizeTmp2 = (inputPoints.extent(0)%numPtsPerEval != 0);
 
  152       const auto loopSize = loopSizeTmp1 + loopSizeTmp2;
 
  153       Kokkos::RangePolicy<ExecSpaceType,Kokkos::Schedule<Kokkos::Static> > policy(0, loopSize);
 
  155       typedef typename inputPointViewType::value_type inputPointType;
 
  157       const ordinal_type cardinality = outputValues.extent(0);
 
  158       const ordinal_type spaceDim = 2;
 
  160       auto vcprop = Kokkos::common_view_alloc_prop(inputPoints);
 
  161       typedef typename Kokkos::DynRankView< inputPointType, typename inputPointViewType::memory_space> workViewType;
 
  163       switch (operatorType) {
 
  164       case OPERATOR_VALUE: {
 
  165         workViewType  work(Kokkos::view_alloc(
"Basis_HCURL_TRI_In_FEM::getValues::work", vcprop), cardinality, inputPoints.extent(0));
 
  166         typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
 
  167           OPERATOR_VALUE,numPtsPerEval> FunctorType;
 
  168         Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, coeffs, work) );
 
  171       case OPERATOR_CURL: {
 
  172         workViewType  work(Kokkos::view_alloc(
"Basis_HCURL_TRI_In_FEM::getValues::work", vcprop), cardinality*(2*spaceDim+1), inputPoints.extent(0));
 
  173         typedef Functor<outputValueViewType,inputPointViewType,vinvViewType, workViewType,
 
  174           OPERATOR_CURL,numPtsPerEval> FunctorType;
 
  175         Kokkos::parallel_for( policy, FunctorType(outputValues, inputPoints, coeffs, work) );
 
  179         INTREPID2_TEST_FOR_EXCEPTION( 
true , std::invalid_argument,
 
  180                                       ">>> ERROR (Basis_HCURL_TRI_In_FEM): Operator type not implemented" );
 
  187   template<
typename SpT, 
typename OT, 
typename PT>
 
  190                           const EPointType   pointType ) {
 
  192     constexpr ordinal_type spaceDim = 2;
 
  193     this->basisCardinality_  = CardinalityHCurlTri(order);
 
  194     this->basisDegree_       = order; 
 
  195     this->basisCellTopology_ = shards::CellTopology(shards::getCellTopologyData<shards::Triangle<3> >() );
 
  196     this->basisType_         = BASIS_FEM_FIAT;
 
  197     this->basisCoordinates_  = COORDINATES_CARTESIAN;
 
  198     this->functionSpace_     = FUNCTION_SPACE_HCURL;
 
  200     const ordinal_type card = this->basisCardinality_;
 
  202     const ordinal_type  cardPn = Intrepid2::getPnCardinality<spaceDim>(order); 
 
  203     const ordinal_type  cardPnm1 = Intrepid2::getPnCardinality<spaceDim>(order-1);  
 
  204     const ordinal_type  cardPnm2 = Intrepid2::getPnCardinality<spaceDim>(order-2); 
 
  205     const ordinal_type  cardVecPn = spaceDim*cardPn;  
 
  206     const ordinal_type  cardVecPnm1 = spaceDim*cardPnm1;   
 
  210     constexpr ordinal_type tagSize  = 4;        
 
  212     ordinal_type tags[maxCard][tagSize];
 
  215     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  216       dofCoords(
"Hcurl::Tri::In::dofCoords", card, spaceDim);
 
  218     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  219       coeffs(
"Hcurl::Tri::In::coeffs", cardVecPn, card);
 
  221     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  222       dofCoeffs(
"Hcurl::Tri::In::dofCoeffs", card, spaceDim);
 
  228     const ordinal_type lwork = card*card;
 
  229     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  230       V1(
"Hcurl::Tri::In::V1", cardVecPn, card);
 
  241     for (ordinal_type i=0;i<cardPnm1;i++)
 
  242       for (ordinal_type d=0;d<spaceDim;d++)
 
  243         V1(d*cardPn+i,d*cardPnm1+i) = 1.0;
 
  249     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> cubPoints(
"Hcurl::Tri::In::cubPoints", myCub.
getNumPoints() , spaceDim );
 
  250     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> cubWeights(
"Hcurl::Tri::In::cubWeights", myCub.
getNumPoints() );
 
  254     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> phisAtCubPoints(
"Hcurl::Tri::In::phisAtCubPoints", cardPn , myCub.
getNumPoints() );
 
  255     Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>(phisAtCubPoints, cubPoints, order, OPERATOR_VALUE);
 
  258     for (ordinal_type i=0;i<order;i++) {
 
  259       for (ordinal_type j=0;j<cardPn;j++) { 
 
  261           V1(j,cardVecPnm1+i) -=
 
  262             cubWeights(k) * cubPoints(k,1)
 
  263             * phisAtCubPoints(cardPnm2+i,k)
 
  264             * phisAtCubPoints(j,k);
 
  265           V1(j+cardPn,cardVecPnm1+i) +=
 
  266             cubWeights(k) * cubPoints(k,0)
 
  267             * phisAtCubPoints(cardPnm2+i,k)
 
  268             * phisAtCubPoints(j,k);
 
  274     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  275       V2(
"Hcurl::Tri::In::V2", card ,cardVecPn);
 
  277     const ordinal_type numEdges = this->basisCellTopology_.getEdgeCount();
 
  279     shards::CellTopology edgeTop(shards::getCellTopologyData<shards::Line<2> >() );
 
  287     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> linePts(
"Hcurl::Tri::In::linePts", numPtsPerEdge , 1 );
 
  290     const ordinal_type offset = 1;
 
  297     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> edgePts(
"Hcurl::Tri::In::edgePts", numPtsPerEdge , spaceDim );
 
  298     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> phisAtEdgePoints(
"Hcurl::Tri::In::phisAtEdgePoints", cardPn , numPtsPerEdge );
 
  299     Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace> edgeTan(
"Hcurl::Tri::In::edgeTan", spaceDim );
 
  302     for (ordinal_type edge=0;edge<numEdges;edge++) {  
 
  305                                                                               this->basisCellTopology_ );
 
  307       const scalarType refEdgeMeasure = 2.0;
 
  308       for (ordinal_type j=0;j<spaceDim;j++)
 
  309         edgeTan(j) *= refEdgeMeasure;
 
  315                                                                             this->basisCellTopology_ );
 
  317       Impl::Basis_HGRAD_TRI_Cn_FEM_ORTH::getValues<Kokkos::HostSpace::execution_space,Parameters::MaxNumPtsPerBasisEval>(phisAtEdgePoints , edgePts, order, OPERATOR_VALUE);
 
  320       for (ordinal_type j=0;j<numPtsPerEdge;j++) {
 
  322         const ordinal_type i_card = numPtsPerEdge*edge+j;
 
  325         for (ordinal_type k=0;k<cardPn;k++) {
 
  326           V2(i_card,k) = edgeTan(0) * phisAtEdgePoints(k,j);
 
  327           V2(i_card,k+cardPn) = edgeTan(1) * phisAtEdgePoints(k,j);
 
  332         for(ordinal_type k=0; k<spaceDim; ++k) {
 
  333           dofCoords(i_card,k) = edgePts(j,k);
 
  334           dofCoeffs(i_card,k) = edgeTan(k);
 
  338         tags[i_card][1] = edge; 
 
  340         tags[i_card][3] = numPtsPerEdge; 
 
  356     if (numPtsPerCell > 0) {
 
  357       Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  358         internalPoints( 
"Hcurl::Tri::In::internalPoints", numPtsPerCell , spaceDim );
 
  360                               this->basisCellTopology_ ,
 
  365       Kokkos::DynRankView<scalarType,typename SpT::array_layout,Kokkos::HostSpace>
 
  366         phisAtInternalPoints(
"Hcurl::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++) {
 
  376           V2(i_card,k) = phisAtInternalPoints(k,j);
 
  378           V2(i_card+1,cardPn+k) = phisAtInternalPoints(k,j);
 
  382         for(ordinal_type d=0; d<spaceDim; ++d) {
 
  383           for(ordinal_type dim=0; dim<spaceDim; ++dim) {
 
  384             dofCoords(i_card+d,dim) = internalPoints(j,dim);
 
  385             dofCoeffs(i_card+d,dim) = (d==dim);
 
  388           tags[i_card+d][0] = spaceDim; 
 
  389           tags[i_card+d][1] = 0; 
 
  390           tags[i_card+d][2] = spaceDim*j+d; 
 
  391           tags[i_card+d][3] = spaceDim*numPtsPerCell; 
 
  398     Kokkos::DynRankView<scalarType,Kokkos::LayoutLeft,Kokkos::HostSpace>
 
  399       vmat(
"Hcurl::Tri::In::vmat", card, card),
 
  400       work(
"Hcurl::Tri::In::work", lwork),
 
  401       ipiv(
"Hcurl::Tri::In::ipiv", card);
 
  404     for(ordinal_type i=0; i< card; ++i) {
 
  405       for(ordinal_type j=0; j< card; ++j) {
 
  407         for(ordinal_type k=0; k< cardVecPn; ++k)
 
  408           s += V2(i,k)*V1(k,j);
 
  413     ordinal_type info = 0;
 
  414     Teuchos::LAPACK<ordinal_type,scalarType> lapack;
 
  416     lapack.GETRF(card, card,
 
  417                  vmat.data(), vmat.stride_1(),
 
  418                  (ordinal_type*)ipiv.data(),
 
  421     INTREPID2_TEST_FOR_EXCEPTION( info != 0,
 
  423                                   ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_In_FEM) lapack.GETRF returns nonzero info." );
 
  426                  vmat.data(), vmat.stride_1(),
 
  427                  (ordinal_type*)ipiv.data(),
 
  431     INTREPID2_TEST_FOR_EXCEPTION( info != 0,
 
  433                                   ">>> ERROR: (Intrepid2::Basis_HCURL_TRI_In_FEM) lapack.GETRI returns nonzero info." );
 
  435     for (ordinal_type i=0;i<cardVecPn;++i)
 
  436       for (ordinal_type j=0;j<card;++j){
 
  438         for(ordinal_type k=0; k< card; ++k)
 
  439           s += V1(i,k)*vmat(k,j);
 
  443     this->coeffs_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), coeffs);
 
  444     Kokkos::deep_copy(this->coeffs_ , coeffs);
 
  446     this->dofCoords_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), dofCoords);
 
  447     Kokkos::deep_copy(this->dofCoords_, dofCoords);
 
  449     this->dofCoeffs_ = Kokkos::create_mirror_view(
typename SpT::memory_space(), dofCoeffs);
 
  450     Kokkos::deep_copy(this->dofCoeffs_, dofCoeffs);
 
  456       const ordinal_type posScDim = 0;        
 
  457       const ordinal_type posScOrd = 1;        
 
  458       const ordinal_type posDfOrd = 2;        
 
  464       this->setOrdinalTagData(this->tagToOrdinal_,
 
  467                               this->basisCardinality_,
 
Kokkos::View< ordinal_type *, typename ExecSpaceType::array_layout, Kokkos::HostSpace > OrdinalTypeArray1DHost
View type for 1d host array. 
 
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). 
 
Basis_HCURL_TRI_In_FEM(const ordinal_type order, const EPointType pointType=POINTTYPE_EQUISPACED)
Constructor. 
 
static constexpr ordinal_type MaxOrder
The maximum reconstruction order. 
 
virtual ordinal_type getNumPoints() const 
Returns the number of cubature points.