27    template<
short_t d,
class T>
 
   36    template<
short_t d,
class T>
 
   44    template<
short_t d,
class T>
 
   50    template<
short_t d,
class T>
 
   53        Base::defaultOptions();
 
   54        m_options.addInt(
"Pi",
"Pi matrix to be applied, 0: Non-negative, 1: Idempotent",0);
 
   55        m_options.addInt(
"RefLevel",
"Refinement level",0);
 
   56        m_options.addReal(
"Beta",
"Beta parameter",0.4);
 
 
   62    template<
short_t d,
class T>
 
   65        GISMO_ASSERT(m_mapModified.isFinalized(),
"Mapper is not finalized");
 
   70        for (
size_t p=0; p!=m_bases0.nBases(); p++) 
 
   73            if (m_tMatrices[p].rows()!=0 && m_tMatrices[p].cols()!=0)
 
   74                tmpCoefs = m_tMatrices[p]*patches.
patch(p).coefs();
 
   76                tmpCoefs = patches.
patch(p).coefs();
 
   78            size = m_mapModified.patchSize(p);
 
   81                if (m_mapModified.is_free(k,p,0))
 
   82                    coefs.row(m_mapModified.index(k,p,0)) = tmpCoefs.row(k);
 
   87        std::fill(m_vertCheck.begin(), m_vertCheck.end(), 
false);
 
   88        for (
size_t p=0; p!=m_bases0.nBases(); p++)
 
   92                index_t idx = this->_vertIndex(p,c);
 
   93                if(m_vertCheck[ idx] )
 
   97                std::pair<index_t,bool> vdata = this->_vertexData(pcorner); 
 
   99                if (std::count(m_C0s.begin(), m_C0s.end(), pcorner))
 
  101                if (vdata.first==3 && !vdata.second)
 
  103                    std::vector<patchCorner> otherCorners;
 
  104                    std::vector<patchSide> csides;
 
  106                    m_topology.getCornerList(pcorner,otherCorners);
 
  108                    std::vector<index_t> b11b;
 
  109                    for (std::vector<patchCorner>::iterator corner = otherCorners.begin(); corner != otherCorners.end(); corner++)
 
  111                        corner->getContainingSides(d,csides);
 
  112                        if ( m_topology.isBoundary(csides[0]) || m_topology.isBoundary(csides[1]) ) 
 
  113                            b11b.push_back(m_mapModified.index( this->_indexFromVert(m_bases0,1,*corner,csides[0],1) , corner->patch) );
 
  115                            b11i = m_mapModified.index( this->_indexFromVert(m_bases0,1,*corner,csides[0],1) , corner->patch);
 
  119                        if (corner==otherCorners.begin())
 
  121                            const gsBasis <T> * basis = &m_bases0.basis(corner->patch);
 
  122                            b00 = m_mapModified.index( basis->functionAtCorner(corner->corner()), corner->patch );
 
  125                        idx = this->_vertIndex(corner->patch,corner->corner());
 
  126                        m_vertCheck[ idx ] = 
true;
 
  128                    coefs.row(b00) = coefs.row(b11b[0]) + coefs.row(b11b[1]) - coefs.row(b11i);
 
  131                    m_vertCheck[ idx ] = 
true;
 
 
  143    template<
short_t d,
class T>
 
  147        for (
size_t k=0; k!=m_Bbases.nBases(); ++k)
 
  150            std::vector<gsKnotVector<T>> KVs(d);
 
  155                for (
short_t dim=0; dim!=d; dim++)
 
  157                    GISMO_ENSURE(tbasis0->degree(dim)>=2,
"Degree of the basis must be larger than or equal to 2, but is "<<tbasis0->degree(dim)<<
" (component "<<d<<
")");
 
  159                    KVs[dim] = tbasis0->knots(dim);
 
  160                    degree = KVs[dim].
degree();
 
  173                for (
short_t dim = 0; dim!=d; dim++)
 
  177                m_bases0.addBasis(thbBasis.
clone());
 
  180                GISMO_ERROR(
"Basis can only be constructed on gsTensorBSplineBasis");
 
  182        m_bases0.setTopology(m_topology);
 
 
  186    template <
short_t d, 
class T>
 
  190        patchBoxes.resize(m_bases0.size());
 
  194        std::vector<index_t> boxes;
 
  199        std::vector<patchCorner> cornerList;
 
  200        std::vector<std::vector<patchCorner> > cornerLists;
 
  202        m_topology.getEVs(cornerLists);
 
  204        index_t N = cornerLists.size();
 
  208        mask.setConstant(
false);
 
  212            for (
size_t c = 0; c<cornerLists[v].size(); c++)
 
  214                corner = cornerLists[v].at(c);
 
  217                if (mask(corner.patch,corner.corner()-1))
 
  222                for (
short_t dim = 0; dim!=d; dim++)
 
  226                    nelements = (degree < 4) ? 2 : 1;
 
  227                    nelements *= std::pow(2,m_options.getInt(
"RefLevel"));
 
  229                    GISMO_ASSERT(nelements<=(
index_t)KV.
numElements(),
"Need more elements than available for refinement around corner "<<corner.corner()<<
" of patch "<<corner.patch<<
".\n"<<
"nelements = "<<nelements<<
"; KV.numElements() = "<<KV.
numElements()<<
"\n");
 
  231                    box.row(dim).setConstant(pars(dim)*(KV.
uSize()-1));
 
  232                    box(dim,!pars(dim)) += ( 1 - 2*pars(dim) ) * nelements; 
 
  240                        if      ((corner.
m_index==1 && dim==0) || (corner.
m_index==4 && dim==1)) 
 
  242                        else if ((corner.
m_index==1 && dim==1) || (corner.
m_index==4 && dim==0)) 
 
  244                        else if ((corner.
m_index==2 && dim==0) || (corner.
m_index==3 && dim==1)) 
 
  246                        else if ((corner.
m_index==2 && dim==1) || (corner.
m_index==3 && dim==0)) 
 
  254                        m_topology.getCornerList(otherPCorner,cornerList);
 
  255                        cornerLists.push_back(cornerList);
 
  262                boxes.insert(boxes.end(), box.data(), box.data()+box.size());
 
  263                patchBoxes.at(corner.patch).insert(patchBoxes.at(corner.patch).end(), boxes.begin(), boxes.end());
 
  265                mask(corner.patch,corner.corner()-1) = 
true;
 
  270    template<
short_t d,
class T>
 
  273        std::vector< std::vector<index_t> > elVec;
 
  274        this->_refBoxes(elVec);
 
  275        m_tMatrices.resize(m_bases0.nBases());
 
  276        for (
size_t p=0; p!=m_bases0.nBases(); p++)
 
  280            boxMat.row(0).array() += 1;
 
  281            boxMat.block(1,0,boxMat.rows()-1,boxMat.cols()).array() *= 2;
 
  285            std::vector< gsSortedVector< index_t > > xmat = basis->getXmatrix();
 
  286            basis->refineElements_withTransfer(elVec[p],m_tMatrices[p]);
 
 
  291    template<
short_t d,
class T>
 
  295        std::vector< std::vector<index_t> > elVec;
 
  296        this->_refBoxes(elVec);
 
  300        std::vector<gsEigen::Triplet<T,index_t>> tripletList;
 
  301        for (
size_t p=0; p!=m_bases0.nBases(); p++)
 
  305            boxMat.row(0).array() += 2;
 
  306            boxMat.block(1,0,boxMat.rows()-1,boxMat.cols()).array() *= 4;
 
  309            std::vector< gsSortedVector< index_t > > xmat = basis->getXmatrix();
 
  310            basis->refineElements_withTransfer(elVec[p],tmp);
 
  311            for (
index_t i = 0; i<tmp.outerSize(); ++i)
 
  313                    tripletList.push_back(gsEigen::Triplet<T,index_t>(it.row()+rows,it.col()+cols,it.value()));
 
  319        m_tMatrix.resize(rows,cols);
 
  320        m_tMatrix.setFromTriplets(tripletList.begin(), tripletList.end());
 
  322        m_tMatrix.makeCompressed();
 
  328        m_mapOriginal.finalize();
 
 
  331    template<
short_t d,
class T>
 
  340        std::vector<std::vector<patchCorner> > cornerLists;
 
  341        m_topology.getEVs(cornerLists);
 
  343        if (cornerLists.size()!=0)
 
  346            m_matrix = m_matrix * m_tMatrix.transpose();
 
  351            std::vector<patchSide> sides(2);
 
  352            std::vector<patchSide> allSides;
 
  353            std::vector<std::vector<patchCorner> > cornerLists;
 
  354            std::vector<patchCorner> corners;
 
  355            std::vector<index_t> allPatches;
 
  356            std::map<index_t,index_t> patches;
 
  357            std::vector<boundaryInterface> interfaces;
 
  358            m_topology.getEVs(cornerLists);
 
  360            sparseEntry_t entries;
 
  362            if (cornerLists.size()!=0)
 
  364                for (
size_t v =0; v!=cornerLists.size(); v++) 
 
  367                    index_t N = cornerLists[v].size();
 
  369                    allPatches.resize(m_bases.nBases());
 
  371                    interfaces.resize(N);
 
  373                    std::vector<gsMatrix<index_t>> cij(3);
 
  377                    std::vector<gsMatrix<index_t>> cijo = cij;
 
  389                    std::vector<patchCorner> pcorners(2);
 
  394                        patches.insert(std::make_pair(side.patch,i));
 
  396                        bool isInterface = m_topology.getInterface(side,interfaces[i]);
 
  399                        std::vector<boxCorner> adjcorners;
 
  400                        m_topology.getNeighbour(side,otherSide);
 
  417                        if (otherSide == sides[0])
 
  418                            otherSide = sides[1];
 
  419                        else if (otherSide == sides[1])
 
  420                            otherSide = sides[0];
 
  424                        corner = otherCorner;
 
  431                        otherCorner = interfaces[i].mapCorner(corners[i]);
 
  433                        if (interfaces[i].first().patch==corners[i].patch)
 
  435                            otherSide = interfaces[i].second();
 
  436                            side = interfaces[i].first();
 
  440                            otherSide = interfaces[i].first();
 
  441                            side = interfaces[i].second();
 
  445                        cij[0](patches[side.patch],0) = this->_indexFromVert(m_bases,1,corners[i],side,1);
 
  447                        cij[1](patches[otherSide.
patch],0) = this->_indexFromVert(m_bases,2,otherCorner,otherSide,1);
 
  449                        cij[2](patches[side.patch],0) = this->_indexFromVert(m_bases,2,corners[i],side,1);
 
  452                        cijo[0](patches[side.patch],0) = this->_indexFromVert(m_bases0,1,corners[i],side,1);
 
  454                        cijo[1](patches[otherSide.
patch],0) = this->_indexFromVert(m_bases0,2,otherCorner,otherSide,1);
 
  456                        cijo[2](patches[side.patch],0) = this->_indexFromVert(m_bases0,2,corners[i],side,1);
 
  459                    std::vector<gsMatrix<index_t>> rowIndices(3);
 
  470                            GISMO_ASSERT(m_mapModified.is_free(cijo[k](i,0),corner.patch),
"Something went wrong in the indexing of the sparse matrix for EVs.\n corner = "<<corner.corner()<<
"\n patch = "<<corner.patch<<
"\n k = "<<k<<
"\n i = "<<i<<
"\n cijo[k](i,0) = "<<cijo[k](i,0)<<
"\n cijo[k] = "<<cijo[k]<<
"\n");
 
  471                            rowIndices[k](i,0) = m_mapModified.index(cijo[k](i,0),corner.patch);
 
  472                            GISMO_ASSERT(m_mapOriginal.is_free(cij[k](i,0),corner.patch),
"Something went wrong in the indexing of the sparse matrix for EVs");
 
  473                            cij[k](i,0) = m_mapOriginal.index(cij[k](i,0),corner.patch);
 
  486                                    c.
at(j+l*N) = m_matrix.coeff(rowIndices[k](i,0),cij[l](j,0));
 
  490                                    entries.push_back(std::make_tuple(rowIndices[k](i,0),cij[l](j,0),c.at(j+l*N)));
 
  494                    #pragma omp critical (_computeEV1) 
  506                                corners[j].getContainingSides(d,sides);
 
  508                                colIdx = this->_indexFromVert(m_bases,0,corners[j],sides[0],0); 
 
  509                                GISMO_ASSERT(m_mapOriginal.is_free(colIdx,corners[j].patch),
"Something went wrong in the indexing of the sparse matrix for EVs");
 
  510                                colIdx = m_mapOriginal.index(colIdx,corners[j].patch);
 
  511                                entries.push_back(std::make_tuple(rowIndices[k](i,0),colIdx,m_matrix.coeff(rowIndices[k](i,0),cij[0](j,0))));
 
  513                                colIdx = this->_indexFromVert(m_bases,1,corners[j],sides[0],0); 
 
  514                                GISMO_ASSERT(m_mapOriginal.is_free(colIdx,corners[j].patch),
"Something went wrong in the indexing of the sparse matrix for EVs");
 
  515                                colIdx = m_mapOriginal.index(colIdx,corners[j].patch);
 
  516                                entries.push_back(std::make_tuple(rowIndices[k](i,0),colIdx,m_matrix.coeff(rowIndices[k](i,0),cij[0](j,0))));
 
  518                                colIdx = this->_indexFromVert(m_bases,1,corners[j],sides[1],0); 
 
  519                                GISMO_ASSERT(m_mapOriginal.is_free(colIdx,corners[j].patch),
"Something went wrong in the indexing of the sparse matrix for EVs");
 
  520                                colIdx = m_mapOriginal.index(colIdx,corners[j].patch);
 
  521                                entries.push_back(std::make_tuple(rowIndices[k](i,0),colIdx,m_matrix.coeff(rowIndices[k](i,0),cij[0](j,0))));
 
  527                    #pragma omp critical (_computeEV2) 
  535                        patchCorner corner = corners[patches[interfaces[i].first().patch]];
 
  536                        patchCorner otherCorner = corners[patches[interfaces[i].second().patch]];
 
  538                        patchSide otherSide = interfaces[i].second();
 
  539                        for (
index_t k = 2; k!=4 ; k++)
 
  541                            idx = this->_indexFromVert(m_bases,k,corner,side,0);
 
  542                            GISMO_ASSERT(m_mapOriginal.is_free(idx,side.patch),
"Something went wrong in the indexing of the sparse matrix for EVs");
 
  543                            index_t j0k = m_mapOriginal.index(idx,side.patch);
 
  545                            idx = this->_indexFromVert(m_bases,k,otherCorner,otherSide,0);
 
  546                            GISMO_ASSERT(m_mapOriginal.is_free(idx,otherSide.
patch),
"Something went wrong in the indexing of the sparse matrix for EVs");
 
  549                            idx = this->_indexFromVert(m_bases,k,corner,side,1);         
 
  550                            GISMO_ASSERT(m_mapOriginal.is_free(idx,side.patch),
"Something went wrong in the indexing of the sparse matrix for EVs");
 
  551                            index_t jk1 = m_mapOriginal.index(idx,side.patch); 
 
  553                            idx = this->_indexFromVert(m_bases,k,otherCorner,otherSide,1);         
 
  554                            GISMO_ASSERT(m_mapOriginal.is_free(idx,otherSide.
patch),
"Something went wrong in the indexing of the sparse matrix for EVs");
 
  562                                    row = rowIndices[l](r,0);
 
  563                                    entries.push_back(std::make_tuple(rowIndices[l](r,0),j0k,0.5 * ( m_matrix.coeff(row,jk1) + m_matrix.coeff(row,j1k) )));
 
  564                                    entries.push_back(std::make_tuple(rowIndices[l](r,0),jk0,0.5 * ( m_matrix.coeff(row,jk1) + m_matrix.coeff(row,j1k) )));
 
  570                    #pragma omp critical (_computeEV3) 
  576        m_matrix.makeCompressed();
 
 
  580    template<
short_t d,
class T>
 
  587        T pi = 4*std::atan(1);
 
  588        T phi = 2*pi / valence;
 
  589        std::complex<T> I(0,1);
 
  590        T beta = m_options.getReal(
"Beta") * std::pow(0.5,m_options.getInt(
"RefLevel"));
 
  591        T psi = std::arg( std::complex<T>((T(1.0)+I*beta*T(math::sin(phi)))*math::exp( -I*phi / T(2.0) ) ));
 
  592        if (m_options.getInt(
"Pi")==0)
 
  594            for (
index_t j=0; j!=valence; j++)
 
  596                P(j,0) = P(j,1) = P(j,2) = P(j,3) = P(j,6) = 1.0 / (3.0 * valence);;
 
  597                P(j,4) = P(j,8) = 1.0 / (3.0 * valence) * ( 1.0 + 3.0*math::cos( j * phi ) );
 
  598                P(j,5) = 1.0 / (3.0 * valence) * ( 1.0 + 3.0*math::cos( 2.0 * psi + j * phi ) );
 
  599                P(j,7) = 1.0 / (3.0 * valence) * ( 1.0 + 3.0*math::cos( 2.0 * psi - j * phi ) );
 
  602        else if (m_options.getInt(
"Pi")==1) 
 
  604            for (
index_t j=0; j!=valence; j++)
 
  606                P(j,0) = P(j,3) = P(j,6) = 0;
 
  607                P(j,1) = P(j,2) = 1.0 / (2.0 * valence);
 
  608                P(j,4) = P(j,8) = 1.0 / (2.0 * valence) * ( 1.0 + math::cos( j * phi ) );
 
  609                P(j,5) = 1.0 / (2.0 * valence) * ( 1.0 + math::cos( 2.0 * psi + j * phi ) );
 
  610                P(j,7) = 1.0 / (2.0 * valence) * ( 1.0 + math::cos( 2.0 * psi - j * phi ) );
 
  620            offsetI = (i / 3)*valence;
 
  621            offsetJ = (i % 3)*valence;
 
  622            for (
index_t j=0; j!=valence; j++ )
 
  623                for (
index_t k=0; k!=valence; k++ )
 
  635            Pi.block(offsetI,offsetJ,valence, valence) = tmp;
 
 
  641    template<
short_t d,
class T>
 
  647        for (
size_t p=0; p!=m_bases.nBases(); p++)
 
  649            tmp += m_bases.basis(p).size();
 
  652                tmp -= m_bases.basis(p).boundaryOffset(
boxSide(1),k).size();
 
  653                tmp -= m_bases.basis(p).boundaryOffset(
boxSide(2),k).size();
 
  654                tmp -= m_bases.basis(p).boundaryOffset(
boxSide(3),k).size()-4;
 
  655                tmp -= m_bases.basis(p).boundaryOffset(
boxSide(4),k).size()-4;
 
  667        for(gsBoxTopology::const_iiterator iit = m_topology.iBegin(); iit!= m_topology.iEnd(); iit++)
 
  669            basis1 = &m_bases.
basis(iit->first().patch);
 
  670            basis2 = &m_bases.
basis(iit->second().patch);
 
  671            tmp += basis1->
boundary(iit->first().side()).size() - 4;
 
  672            tmp += basis2->
boundary(iit->second().side()).size() - 4;
 
  679        for(gsBoxTopology::const_biterator bit = m_topology.bBegin(); bit!= m_topology.bEnd(); bit++)
 
  681            basis1 = &m_bases.
basis(bit->patch);
 
  690        std::vector<bool> passed(m_bases.nBases()*4);
 
  691        std::fill(passed.begin(), passed.end(), 
false);
 
  693        std::vector<patchCorner> corners;
 
  695        for (
size_t p=0; p!=m_bases.nBases(); p++)
 
  698                index_t idx = this->_vertIndex(p,c);
 
  701                    m_topology.getCornerList(
patchCorner(p,c),corners);
 
  703                    for (
size_t k=0; k!=corners.size(); k++)
 
  704                        passed.at(this->_vertIndex(corners[k].patch,corners[k])) = 
true;
 
  706                    std::pair<index_t,bool> vdata = this->_vertexData(
patchCorner(p,c)); 
 
  707                    bool C0 = m_C0s[idx];
 
  708                    if ((!vdata.second) && vdata.first==1) 
 
  710                    else if ((!vdata.second) && vdata.first==2 && !C0)
 
  712                    else if ((!vdata.second) && vdata.first>2 && !C0)
 
  714                    else if ((!vdata.second) && vdata.first==2 && C0)
 
  716                    else if ((!vdata.second) && vdata.first>2 && C0)
 
 
  731    template<
short_t d,
class T>
 
  915        std::vector<boundaryInterface> ifaces;
 
  917        std::vector<patchSide> boundaries;
 
  919        std::vector<patchCorner> temp_corners, corners;
 
  920        std::vector<patchSide> psides;
 
  921        std::vector<index_t> colIndices,rowIndices, patches;
 
  923        sparseEntry_t entries;
 
  925        m_topology.getCornerList(pcorner,corners);
 
  929        if ((std::count(m_C0s.begin(), m_C0s.end(), pcorner)))
 
  930            gsWarn<<
"C0 handling for boundary corners with valence 3 has not yet been implemented\n";
 
  942        for (
size_t k=0; k!=corners.size(); k++)
 
  943            lowest = (corners[k].patch < lowest.patch ) ? corners[k] : lowest;
 
  947        extraRow = this->_indexFromVert(0,lowest,psides[0],0);
 
  948        extraRow = m_mapModified.index(extraRow,lowest.patch);
 
  954        for (std::vector<patchCorner>::iterator it = corners.begin(); it!=corners.end(); ++it)
 
  958            it->getContainingSides(d,psides);
 
  961            colIndices.push_back( this->_indexFromVert(0,*it,psides[0],0) );
 
  962            rowIndices.push_back( this->_indexFromVert(1,*it,psides[0],1) );
 
  963            patches.push_back(it->patch);
 
  967                if ( m_topology.getInterface(psides[k],iface) ) 
 
  969                    ifaces.push_back(iface);
 
  974                    index_t colIdx = m_mapOriginal.index(this->_indexFromVert(1,*it,psides[k],0),it->patch);
 
  975                    index_t rowIdx = m_mapModified.index(this->_indexFromVert(1,*it,psides[k],1),it->patch);
 
  979                    entries.push_back(std::make_tuple(rowIdx,colIdx,0.5));
 
  980                    entries.push_back(std::make_tuple(extraRow,colIdx,0.5));
 
  993        for (
size_t k = 0; k!=colIndices.size(); k++)
 
  995            index_t colIdx = m_mapOriginal.index(colIndices[k],patches[k]);
 
  997            entries.push_back(std::make_tuple(extraRow,colIdx,0.25));
 
 1001        for (
size_t k = 0; k!=rowIndices.size(); k++)
 
 1003            index_t rowIdx = m_mapModified.index(rowIndices[k],patches[k]);
 
 1004            index_t colIdx = m_mapOriginal.index(rowIndices[k],patches[k]);
 
 1006            entries.push_back(std::make_tuple(rowIdx,colIdx,1.0));
 
 1009            for (
size_t l = 0; l!=colIndices.size(); l++)
 
 1012                colIdx = m_mapOriginal.index(colIndices[l],patches[l]);
 
 1014                entries.push_back(std::make_tuple(rowIdx,colIdx,0.25));
 
 1020        rowIndices.resize(2);
 
 1021        colIndices.resize(2);
 
 1025        colIndices.resize(2);
 
 1026        for (std::vector<patchSide>::iterator it = boundaries.begin(); it!=boundaries.end(); ++it)
 
 1029            it->getContainedCorners(d,temp_corners);
 
 1030            for (std::vector<patchCorner>::iterator corn = temp_corners.begin(); corn!=temp_corners.end(); ++corn)
 
 1032                if ( std::find(corners.begin(), corners.end(), *corn) == corners.end() ) 
 
 1035                index_t colIdx = this->_indexFromVert(1,*corn,*it,0);
 
 1036                colIdx = m_mapOriginal.index(colIdx,corn->patch);
 
 1037                entries.push_back(std::make_tuple(extraRow,colIdx,0.5));
 
 1046        for (std::vector<boundaryInterface>::iterator it = ifaces.begin(); it!=ifaces.end(); ++it)
 
 1052            it->first().getContainedCorners(d,temp_corners);
 
 1054            std::vector<patchSide> isides(2);
 
 1055            std::vector<patchCorner> icorners(2);
 
 1057            for (std::vector<patchCorner>::iterator corn = temp_corners.begin(); corn!=temp_corners.end(); ++corn)
 
 1059                if ( std::find(corners.begin(), corners.end(), *corn) == corners.end() ) 
 
 1065                icorners[0] = *corn;
 
 1066                icorners[1] = it->mapCorner(*corn);
 
 1067                isides[0] = it->first();
 
 1068                isides[1] = it->second();
 
 1071                for (
size_t k=0; k!=icorners.size(); k++)
 
 1073                    rowIndices[k] = this->_indexFromVert(1,icorners[k],isides[k],1);
 
 1074                    colIndices[k] = this->_indexFromVert(1,icorners[k],isides[k],0);
 
 1075                    patches[k] = icorners[k].patch;
 
 1078                for (
size_t k = 0; k!=rowIndices.size(); k++)
 
 1080                    index_t rowIdx = m_mapModified.index(rowIndices[k],patches[k]);
 
 1082                    for (
size_t l = 0; l!=colIndices.size(); l++)
 
 1084                        index_t colIdx = m_mapOriginal.index(colIndices[l],patches[l]);
 
 1085                        entries.push_back(std::make_tuple(rowIdx,colIdx,0.5));
 
 1094        #pragma omp critical (handle_boundary_vertex_ff) 
 1096            _pushAndCheck(entries);
 
 1099            for (std::vector<patchCorner>::iterator it = corners.begin(); it!=corners.end(); ++it)
 
 1100                m_vertCheck[ this->_vertIndex(it->patch, it->corner()) ] = 
true;
 
 
 1104    template<
short_t d,
class T>
 
 1107        gsWarn<<
"C0 handling for boundary corners with valence 3 has not yet been implemented. Using the default approach\n";
 
 1108        this->_handleIrregularBoundaryVertexSmooth(pcorner,valence);
 
 1111    template<
short_t d,
class T>
 
 1112    void gsDPatch<d,T>::_computeVertexMapper(patchCorner pcorner)
 
 1114        index_t cidx = _vertIndex(pcorner.patch,pcorner.corner());
 
 1115        if (m_vertCheck.at(cidx))
 
 1118        bool C0 = m_C0s[cidx];
 
 1122        std::tie(valence,interior) = _vertexData(pcorner); 
 
 1123        if (!interior && valence==1) 
 
 1124            _computeMapperRegularCorner_v1(pcorner,valence);
 
 1125        else if (!interior && valence==2 && C0)
 
 1126            _computeMapperRegularBoundaryVertexNonSmooth_v2(pcorner,valence);
 
 1127        else if (!interior && valence==2 && !C0)
 
 1128            _computeMapperRegularBoundaryVertexSmooth_v2(pcorner,valence);
 
 1129        else if (!interior && valence==3 && C0)
 
 1130            _computeMapperIrregularBoundaryVertexNonSmooth_v3(pcorner,valence);
 
 1131        else if (!interior && valence==3 && !C0)
 
 1132            _computeMapperIrregularBoundaryVertexSmooth_v3(pcorner,valence);
 
 1133        else if (!interior && valence >3 && C0)
 
 1134            _computeMapperIrregularBoundaryVertexNonSmooth_v(pcorner,valence);
 
 1135        else if (!interior && valence >3 && !C0)
 
 1136            _computeMapperIrregularBoundaryVertexSmooth_v(pcorner,valence);
 
 1138            _computeMapperInteriorVertex_v(pcorner,valence);
 
 1140            GISMO_ERROR(
"Something went terribly wrong, interior="<<interior<<
"; valence="<<valence);
 
 1143        m_vertCheck[ cidx ] = 
true;
 
 1147    template<
short_t d,
class T>
 
 1148    void gsDPatch<d,T>::_computeMapperIrregularBoundaryVertexSmooth_v3(patchCorner pcorner, 
index_t valence)
 
 1152        std::vector<patchSide> psides(2);
 
 1153        std::vector<patchCorner> pcorners;
 
 1174        m_topology.getCornerList(pcorner,pcorners);
 
 1176        for (
size_t c=0; c!=pcorners.size(); c++)
 
 1179            pcorners[c].getContainingSides(d,psides);
 
 1180            m_mapModified.eliminateDof(this->_indexFromVert(1,pcorners[c],psides[0]),pcorners[c].patch);
 
 1181            m_mapModified.eliminateDof(this->_indexFromVert(1,pcorners[c],psides[1]),pcorners[c].patch);
 
 1186                m_mapModified.matchDof(pcorners[0].patch,this->_indexFromVert(0,pcorners[0],pseudo,0),pcorners[c].patch,this->_indexFromVert(0,pcorners[c],pseudo,0));
 
 1188            m_vertCheck[ this->_vertIndex(pcorners[c].patch, pcorners[c].corner()) ] = 
true;
 
 1205    template<
short_t d,
class T>
 
 1206    void gsDPatch<d,T>::_computeMapperIrregularBoundaryVertexNonSmooth_v3(patchCorner pcorner, 
index_t valence)
 
 1208        gsWarn<<
"C0 handling for boundary corners with valence 3 has not yet been implemented. Using the default approach\n";
 
 1209        this->_computeMapperIrregularBoundaryVertexSmooth_v3(pcorner,valence);
 
 1212    template<
short_t d,
class T>
 
 1213    void gsDPatch<d,T>::_computeMapperIrregularBoundaryVertexSmooth_v(patchCorner pcorner, 
index_t valence)
 
 1215        GISMO_ERROR(
"Boundary vertex on patch"<<pcorner.patch<<
" with index "<<pcorner.corner()<<
" with valence = "<<valence<<
" has no implementation");
 
 1218    template<
short_t d,
class T>
 
 1219    void gsDPatch<d,T>::_computeMapperIrregularBoundaryVertexNonSmooth_v(patchCorner pcorner, 
index_t valence)
 
 1221        GISMO_ERROR(
"Boundary vertex on patch"<<pcorner.patch<<
" with index "<<pcorner.corner()<<
" with valence = "<<valence<<
" has no implementation");
 
Struct which represents a certain side of a box.
Definition gsBoundary.h:85
 
Creates a mapped object or data pointer to a matrix without copying data.
Definition gsAsMatrix.h:32
 
A basis represents a family of scalar basis functions defined over a common parameter domain.
Definition gsBasis.h:79
 
gsMatrix< index_t > boundary(boxSide const &s) const
Returns the indices of the basis functions that are nonzero at the domain boundary as single-column-m...
Definition gsBasis.h:520
 
virtual gsMatrix< index_t > boundaryOffset(boxSide const &s, index_t offset) const
Definition gsBasis.hpp:339
 
Constructs the D-Patch, from which the transformation matrix can be called.
Definition gsDPatchBase.h:37
 
Constructs the D-Patch, from which the transformation matrix can be called.
Definition gsDPatch.h:34
 
gsMatrix< T > _makePi(index_t valence)
Makes the Pi matrix.
Definition gsDPatch.hpp:581
 
void _makeTHB() override
Prints which DoFs have been handled and which have been eliminated.
Definition gsDPatch.hpp:292
 
gsDPatch()
Empty constructor.
Definition gsDPatch.h:48
 
void _countDoFs() override
Initializes the matrix, the basis and the mappers.
Definition gsDPatch.hpp:642
 
void _computeEVs() override
Corrects the EVs.
Definition gsDPatch.hpp:332
 
void _handleIrregularBoundaryVertexSmooth(patchCorner pcorner, index_t valence) override
Handles a vertex in the global matrix.
Definition gsDPatch.hpp:732
 
void defaultOptions() override
Sets the default options.
Definition gsDPatch.hpp:51
 
void _initTHB() override
Initializes the matrix, the basis and the mappers.
Definition gsDPatch.hpp:144
 
void _initBasis() override
Initializes the basis.
Definition gsDPatch.hpp:271
 
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition gsDofMapper.h:69
 
uPtr clone()
Clone methode. Produceds a deep copy inside a uPtr.
 
const gsBasis< T > & basis(const index_t k) const
Helper which casts and returns the k-th piece of this function set as a gsBasis.
Definition gsFunctionSet.hpp:33
 
Class representing a (scalar) hierarchical tensor basis of functions .
Definition gsHTensorBasis.h:75
 
void addLevel(const gsTensorBSplineBasis< d, T > &next_basis)
Adds a level, only if manual levels are activated.
Definition gsHTensorBasis.hpp:35
 
Class for representing a knot vector.
Definition gsKnotVector.h:80
 
uiterator ubegin() const
Returns unique iterator pointing to the beginning of the unique knots.
Definition gsKnotVector.hpp:235
 
int degree() const
Returns the degree of the knot vector.
Definition gsKnotVector.hpp:700
 
uiterator uend() const
Returns unique iterator pointing past the end of the unique knots.
Definition gsKnotVector.hpp:241
 
size_t uSize() const
Number of unique knots (i.e., without repetitions).
Definition gsKnotVector.h:245
 
mult_t multiplicity(T u) const
Definition gsKnotVector.hpp:421
 
internal::gsUKnotIterator< T > uiterator
Definition gsKnotVector.h:102
 
size_t numElements() const
Number of knot intervals inside domain.
Definition gsKnotVector.h:268
 
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
 
Holds a set of patch-wise bases and their topology information.
Definition gsMultiBasis.h:37
 
const gsBasis< T > & basis(const size_t i) const
Return the i-th basis block.
Definition gsMultiBasis.h:267
 
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition gsMultiPatch.h:100
 
short_t geoDim() const
Dimension of the geometry (must match for all patches).
Definition gsMultiPatch.hpp:150
 
gsGeometry< T > & patch(size_t i) const
Return the i-th patch.
Definition gsMultiPatch.h:292
 
Iterator over the non-zero entries of a sparse matrix.
Definition gsSparseMatrix.h:74
 
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
 
Truncated hierarchical B-spline basis.
Definition gsTHBSplineBasis.h:36
 
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
 
virtual void uniformRefine(int numKnots=1, int mul=1, short_t dir=-1)
Refine the basis uniformly by inserting numKnots new knots with multiplicity mul on each knot span.
Definition gsTensorBasis.h:315
 
short_t degree(short_t i) const
Returns the degree of the basis wrt variable i.
Definition gsTensorBasis.h:465
 
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
 
T at(index_t i) const
Returns the i-th element of the vector.
Definition gsVector.h:177
 
Simple class create a block preconditioner structure.
 
#define short_t
Definition gsConfig.h:35
 
#define index_t
Definition gsConfig.h:32
 
#define GISMO_ERROR(message)
Definition gsDebug.h:118
 
#define gsWarn
Definition gsDebug.h:50
 
#define GISMO_UNUSED(x)
Definition gsDebug.h:112
 
#define GISMO_ENSURE(cond, message)
Definition gsDebug.h:102
 
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
 
Provides definition of HTensorBasis abstract interface.
 
Simple adapter classes to use matrices or linear solvers as gsLinearOperators.
 
Provides declaration of THBSplineBasis class.
 
Provides declaration of THBSplineBasis class.
 
Provides declaration of functions writing Paraview files.
 
The G+Smo namespace, containing all definitions for the library.
 
Struct which represents an interface between two patches.
Definition gsBoundary.h:650
 
Struct which represents a certain corner of a hyper-cube.
Definition gsBoundary.h:292
 
index_t m_index
Index of the corner.
Definition gsBoundary.h:298
 
void parameters_into(index_t dim, gsVector< bool > ¶m) const
returns a vector of parameters describing the position of the corner
Definition gsBoundary.h:322
 
Struct which represents a certain corner of a patch.
Definition gsBoundary.h:393
 
void getContainingSides(short_t dim, std::vector< patchSide > &sides) const
returns a vector of patchSides that contain this corner
Definition gsBoundary.h:416
 
Struct which represents a certain side of a patch.
Definition gsBoundary.h:232
 
index_t patch
The index of the patch.
Definition gsBoundary.h:234
 
void getContainedCorners(short_t dim, std::vector< patchCorner > &corners) const
returns the vector of the corners contained in the side
Definition gsBoundary.cpp:35