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();
164 KVs[dim].insert(*knot,degree-KV.multiplicity(*knot)-1);
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][0].patch]];
536 patchCorner otherCorner = corners[patches[interfaces[i][1].patch]];
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");
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");
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>
913 std::vector<boundaryInterface> ifaces;
915 std::vector<patchSide> boundaries;
917 std::vector<patchCorner> temp_corners, corners;
918 std::vector<patchSide> psides;
919 std::vector<index_t> colIndices,rowIndices, patches;
921 sparseEntry_t entries;
923 m_topology.getCornerList(pcorner,corners);
927 if ((std::count(m_C0s.begin(), m_C0s.end(), pcorner)))
928 gsWarn<<
"C0 handling for boundary corners with valence 3 has not yet been implemented\n";
940 for (
size_t k=0; k!=corners.size(); k++)
941 lowest = (corners[k].patch < lowest.patch ) ? corners[k] : lowest;
945 extraRow = this->_indexFromVert(0,lowest,psides[0],0);
946 extraRow = m_mapModified.index(extraRow,lowest.patch);
952 for (std::vector<patchCorner>::iterator it = corners.begin(); it!=corners.end(); ++it)
956 it->getContainingSides(d,psides);
959 colIndices.push_back( this->_indexFromVert(0,*it,psides[0],0) );
960 rowIndices.push_back( this->_indexFromVert(1,*it,psides[0],1) );
961 patches.push_back(it->patch);
965 if ( m_topology.getInterface(psides[k],iface) )
967 ifaces.push_back(iface);
972 index_t colIdx = m_mapOriginal.index(this->_indexFromVert(1,*it,psides[k],0),it->patch);
973 index_t rowIdx = m_mapModified.index(this->_indexFromVert(1,*it,psides[k],1),it->patch);
977 entries.push_back(std::make_tuple(rowIdx,colIdx,0.5));
978 entries.push_back(std::make_tuple(extraRow,colIdx,0.5));
991 for (
size_t k = 0; k!=colIndices.size(); k++)
993 index_t colIdx = m_mapOriginal.index(colIndices[k],patches[k]);
995 entries.push_back(std::make_tuple(extraRow,colIdx,0.25));
999 for (
size_t k = 0; k!=rowIndices.size(); k++)
1001 index_t rowIdx = m_mapModified.index(rowIndices[k],patches[k]);
1002 index_t colIdx = m_mapOriginal.index(rowIndices[k],patches[k]);
1004 entries.push_back(std::make_tuple(rowIdx,colIdx,1.0));
1007 for (
size_t l = 0; l!=colIndices.size(); l++)
1010 colIdx = m_mapOriginal.index(colIndices[l],patches[l]);
1012 entries.push_back(std::make_tuple(rowIdx,colIdx,0.25));
1018 rowIndices.resize(2);
1019 colIndices.resize(2);
1023 colIndices.resize(2);
1024 for (std::vector<patchSide>::iterator it = boundaries.begin(); it!=boundaries.end(); ++it)
1027 it->getContainedCorners(d,temp_corners);
1028 for (std::vector<patchCorner>::iterator corn = temp_corners.begin(); corn!=temp_corners.end(); ++corn)
1030 if ( std::find(corners.begin(), corners.end(), *corn) == corners.end() )
1033 index_t colIdx = this->_indexFromVert(1,*corn,*it,0);
1034 colIdx = m_mapOriginal.index(colIdx,corn->patch);
1035 entries.push_back(std::make_tuple(extraRow,colIdx,0.5));
1044 for (std::vector<boundaryInterface>::iterator it = ifaces.begin(); it!=ifaces.end(); ++it)
1050 it->first().getContainedCorners(d,temp_corners);
1052 std::vector<patchSide> isides(2);
1053 std::vector<patchCorner> icorners(2);
1055 for (std::vector<patchCorner>::iterator corn = temp_corners.begin(); corn!=temp_corners.end(); ++corn)
1057 if ( std::find(corners.begin(), corners.end(), *corn) == corners.end() )
1063 icorners[0] = *corn;
1064 icorners[1] = it->mapCorner(*corn);
1065 isides[0] = it->first();
1066 isides[1] = it->second();
1069 for (
size_t k=0; k!=icorners.size(); k++)
1071 rowIndices[k] = this->_indexFromVert(1,icorners[k],isides[k],1);
1072 colIndices[k] = this->_indexFromVert(1,icorners[k],isides[k],0);
1073 patches[k] = icorners[k].patch;
1076 for (
size_t k = 0; k!=rowIndices.size(); k++)
1078 index_t rowIdx = m_mapModified.index(rowIndices[k],patches[k]);
1080 for (
size_t l = 0; l!=colIndices.size(); l++)
1082 index_t colIdx = m_mapOriginal.index(colIndices[l],patches[l]);
1083 entries.push_back(std::make_tuple(rowIdx,colIdx,0.5));
1092 #pragma omp critical (handle_boundary_vertex_ff)
1094 _pushAndCheck(entries);
1097 for (std::vector<patchCorner>::iterator it = corners.begin(); it!=corners.end(); ++it)
1098 m_vertCheck[ this->_vertIndex(it->patch, it->corner()) ] =
true;
1102 template<
short_t d,
class T>
1105 gsWarn<<
"C0 handling for boundary corners with valence 3 has not yet been implemented. Using the default approach\n";
1106 this->_handleIrregularBoundaryVertexSmooth(pcorner,valence);
1109 template<
short_t d,
class T>
1110 void gsDPatch<d,T>::_computeVertexMapper(patchCorner pcorner)
1112 index_t cidx = _vertIndex(pcorner.patch,pcorner.corner());
1113 if (m_vertCheck.at(cidx))
1116 bool C0 = m_C0s[cidx];
1120 std::tie(valence,interior) = _vertexData(pcorner);
1121 if (!interior && valence==1)
1122 _computeMapperRegularCorner_v1(pcorner,valence);
1123 else if (!interior && valence==2 && C0)
1124 _computeMapperRegularBoundaryVertexNonSmooth_v2(pcorner,valence);
1125 else if (!interior && valence==2 && !C0)
1126 _computeMapperRegularBoundaryVertexSmooth_v2(pcorner,valence);
1127 else if (!interior && valence==3 && C0)
1128 _computeMapperIrregularBoundaryVertexNonSmooth_v3(pcorner,valence);
1129 else if (!interior && valence==3 && !C0)
1130 _computeMapperIrregularBoundaryVertexSmooth_v3(pcorner,valence);
1131 else if (!interior && valence >3 && C0)
1132 _computeMapperIrregularBoundaryVertexNonSmooth_v(pcorner,valence);
1133 else if (!interior && valence >3 && !C0)
1134 _computeMapperIrregularBoundaryVertexSmooth_v(pcorner,valence);
1136 _computeMapperInteriorVertex_v(pcorner,valence);
1138 GISMO_ERROR(
"Something went terribly wrong, interior="<<interior<<
"; valence="<<valence);
1141 m_vertCheck[ cidx ] =
true;
1145 template<
short_t d,
class T>
1146 void gsDPatch<d,T>::_computeMapperIrregularBoundaryVertexSmooth_v3(patchCorner pcorner,
index_t valence)
1148 std::vector<patchSide> psides(2);
1149 std::vector<patchCorner> pcorners;
1170 m_topology.getCornerList(pcorner,pcorners);
1172 for (
size_t c=0; c!=pcorners.size(); c++)
1175 pcorners[c].getContainingSides(d,psides);
1176 m_mapModified.eliminateDof(this->_indexFromVert(1,pcorners[c],psides[0]),pcorners[c].patch);
1177 m_mapModified.eliminateDof(this->_indexFromVert(1,pcorners[c],psides[1]),pcorners[c].patch);
1182 m_mapModified.matchDof(pcorners[0].patch,this->_indexFromVert(0,pcorners[0],pseudo,0),pcorners[c].patch,this->_indexFromVert(0,pcorners[c],pseudo,0));
1184 m_vertCheck[ this->_vertIndex(pcorners[c].patch, pcorners[c].corner()) ] =
true;
1201 template<
short_t d,
class T>
1202 void gsDPatch<d,T>::_computeMapperIrregularBoundaryVertexNonSmooth_v3(patchCorner pcorner,
index_t valence)
1204 gsWarn<<
"C0 handling for boundary corners with valence 3 has not yet been implemented. Using the default approach\n";
1205 this->_computeMapperIrregularBoundaryVertexSmooth_v3(pcorner,valence);
1208 template<
short_t d,
class T>
1209 void gsDPatch<d,T>::_computeMapperIrregularBoundaryVertexSmooth_v(patchCorner pcorner,
index_t valence)
1211 GISMO_ERROR(
"Boundary vertex on patch"<<pcorner.patch<<
" with index "<<pcorner.corner()<<
" with valence = "<<valence<<
" has no implementation");
1214 template<
short_t d,
class T>
1215 void gsDPatch<d,T>::_computeMapperIrregularBoundaryVertexNonSmooth_v(patchCorner pcorner,
index_t valence)
1217 GISMO_ERROR(
"Boundary vertex on patch"<<pcorner.patch<<
" with index "<<pcorner.corner()<<
" with valence = "<<valence<<
" has no implementation");
void _handleIrregularBoundaryVertexSmooth(patchCorner pcorner, index_t valence) override
Handles a vertex in the global matrix.
Definition: gsDPatch.hpp:732
Provides definition of HTensorBasis abstract interface.
internal::gsUKnotIterator< T > uiterator
Definition: gsKnotVector.h:102
short_t degree(short_t i) const
Returns the degree of the basis wrt variable i.
Definition: gsTensorBasis.h:465
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 side of a patch.
Definition: gsBoundary.h:231
Creates a mapped object or data pointer to a matrix without copying data.
Definition: gsLinearAlgebra.h:126
short_t geoDim() const
Dimension of the geometry (must match for all patches).
Definition: gsMultiPatch.hpp:149
#define short_t
Definition: gsConfig.h:35
Simple class create a block preconditioner structure.
size_t numElements() const
Number of knot intervals inside domain.
Definition: gsKnotVector.h:268
void getContainedCorners(short_t dim, std::vector< patchCorner > &corners) const
returns the vector of the corners contained in the side
Definition: gsBoundary.cpp:35
Provides declaration of THBSplineBasis class.
#define index_t
Definition: gsConfig.h:32
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
void getContainingSides(short_t dim, std::vector< patchSide > &sides) const
returns a vector of patchSides that contain this corner
Definition: gsBoundary.h:416
virtual void uniformRefine(int numKnots=1, int mul=1, int dir=-1)
Refine the basis uniformly by inserting numKnots new knots with multiplicity mul on each knot span...
Definition: gsTensorBasis.h:315
Provides declaration of functions writing Paraview files.
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
Struct which represents a certain corner of a patch.
Definition: gsBoundary.h:392
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Maintains a mapping from patch-local dofs to global dof indices and allows the elimination of individ...
Definition: gsDofMapper.h:68
gsDPatch()
Empty constructor.
Definition: gsDPatch.h:48
Provides declaration of THBSplineBasis class.
Class representing a (scalar) hierarchical tensor basis of functions .
Definition: gsHTensorBasis.h:74
#define gsWarn
Definition: gsDebug.h:50
Holds a set of patch-wise bases and their topology information.
Definition: gsMultiBasis.h:36
void _countDoFs() override
Initializes the matrix, the basis and the mappers.
Definition: gsDPatch.hpp:642
gsGeometry< T > & patch(size_t i) const
Return the i-th patch.
Definition: gsMultiPatch.h:226
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
void addLevel(const gsTensorBSplineBasis< d, T > &next_basis)
Adds a level, only if manual levels are activated.
Definition: gsHTensorBasis.hpp:35
void defaultOptions() override
Sets the default options.
Definition: gsDPatch.hpp:51
Constructs the D-Patch, from which the transformation matrix can be called.
Definition: gsDPatchBase.h:36
T at(index_t i) const
Returns the i-th element of the vector.
Definition: gsVector.h:177
Container class for a set of geometry patches and their topology, that is, the interface connections ...
Definition: gsMultiPatch.h:33
Struct which represents a certain side of a box.
Definition: gsBoundary.h:84
uPtr clone()
Clone methode. Produceds a deep copy inside a uPtr.
Constructs the D-Patch, from which the transformation matrix can be called.
Definition: gsDPatch.h:33
void _computeEVs() override
Corrects the EVs.
Definition: gsDPatch.hpp:332
virtual gsMatrix< index_t > boundaryOffset(boxSide const &s, index_t offset) const
Definition: gsBasis.hpp:316
const gsBasis< T > & basis(const size_t i) const
Return the i-th basis block.
Definition: gsMultiBasis.h:267
tensorBasis & tensorLevel(index_t i) const
Returns the tensor basis member of level i.
Definition: gsHTensorBasis.h:668
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
Class for representing a knot vector.
Definition: gsKnotVector.h:79
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
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
size_t uSize() const
Number of unique knots (i.e., without repetitions).
Definition: gsKnotVector.h:245
Truncated hierarchical B-spline basis.
Definition: gsTHBSplineBasis.h:35
void _makeTHB() override
Prints which DoFs have been handled and which have been eliminated.
Definition: gsDPatch.hpp:292
int degree() const
Returns the degree of the knot vector.
Definition: gsKnotVector.hpp:700
index_t patch
The index of the patch.
Definition: gsBoundary.h:234
index_t m_index
Index of the corner.
Definition: gsBoundary.h:298
Struct which represents a certain corner of a hyper-cube.
Definition: gsBoundary.h:291
Simple adapter classes to use matrices or linear solvers as gsLinearOperators.
gsMatrix< T > _makePi(index_t valence)
Makes the Pi matrix.
Definition: gsDPatch.hpp:581
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
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78