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