34 template<
short_t d,
class T>
37 GISMO_ENSURE(m_manualLevels,
"Add level only works when m_manualLevels==true");
39 std::vector<std::vector<index_t>> lvlIndices(d);
41 std::vector<T> difference, intersection;
42 std::vector<T> knots1, knots2;
43 std::vector<index_t> dirIndices;
45 for (
short_t dim=0; dim!=d; dim++)
47 dirIndices = m_uIndices.back()[dim];
49 tmpknots= tb2->knots(dim);
53 knots1 = tb2->knots(dim).unique();
54 knots2 = next_basis.knots(dim).unique();
60 std::set_intersection( knots2.begin(), knots2.end(),
61 knots1.begin(), knots1.end(),
62 std::back_inserter(intersection) );
64 std::set_difference( knots1.begin(), knots1.end(),
65 intersection.begin(), intersection.end(),
66 std::back_inserter(difference) );
67 GISMO_ASSERT(difference.size()==0,
"Knot vector is not nested!");
71 std::set_difference(knots2.begin(), knots2.end(),
72 knots1.begin(), knots1.end(),
73 std::back_inserter(difference) );
76 std::reverse(difference.begin(),difference.end());
78 std::transform(dirIndices.begin(), dirIndices.end(), dirIndices.begin(), [=](
index_t& i){
return 2*i;});
81 while (difference.size()!=0)
84 typename std::vector<T>::iterator diff_ptr = difference.begin();
86 i = tmpknots.
uFind(*diff_ptr).uIndex();
89 for (n = 0, diff_ptr = difference.begin(); diff_ptr!=difference.end() && tmpknots.
uFind(*diff_ptr).uIndex()==i; n++, diff_ptr++);
91 GISMO_ENSURE(n < dirIndices[i+1] - dirIndices[i],
"Trying to insert more knots than available in the tensor structure");
97 diff_ptr = std::next(difference.begin(),(n-1)/2);
98 newIdx = (dirIndices[i] + dirIndices[i+1]) / 2;
103 diff_ptr = difference.begin();
104 newIdx = dirIndices[i] + 1;
108 dirIndices.insert(std::upper_bound( dirIndices.begin(), dirIndices.end(), newIdx ),newIdx);
110 tmpknots.
insert(*diff_ptr);
112 difference.erase(diff_ptr);
115 lvlIndices[dim] = dirIndices;
117 m_uIndices.push_back(lvlIndices);
120 m_bases.push_back( next_basis.
clone().release() );
123 template<
short_t d,
class T>
126 return m_bases[0]->support();
130 template<
short_t d,
class T>
134 int lvl = levelOf(i);
136 return m_bases[lvl]->support( this->flatTensorIndexOf(i) );
140 template<
short_t d,
class T>
inline
143 GISMO_ASSERT(Pt.cols() == 1,
"Waiting for single point");
146 const int maxLevel = m_tree.getMaxInsLevel();
150 for(
int i =0; i < Dim; i++)
151 loIdx[i] = m_bases[maxLevel]->knots(i).uFind( Pt(i,0) ).uIndex();
154 this->_knotIndexToDiadicIndex(maxLevel,loIdx);
156 return m_tree.levelOf( loIdx, maxLevel);
159 template<
short_t d,
class T>
inline
162 const int maxLevel = m_tree.getMaxInsLevel();
166 return m_tree.levelOf( Pt, maxLevel);
169 template<
short_t d,
class T>
inline
174 lvl.resize( Pt.cols() );
175 loIdx.resize( Pt.rows(), Pt.cols() );
178 for(
index_t i = 0; i < Pt.cols(); i++)
180 lvl[i] = getLevelAtPoint( Pt.col(i) );
181 for(
index_t j = 0; j < Pt.rows(); j++)
182 loIdx(j,i) = m_bases[ lvl[i] ]->knots(j).uFind( Pt(j,i) ).uIndex() ;
186 template<
short_t d,
class T>
inline
189 result.resize( u.cols() );
193 const int maxLevel = m_tree.getMaxInsLevel();
195 for(
index_t p = 0; p < u.cols(); p++ )
197 for(
short_t i = 0; i != d; ++i)
198 low[i] = m_bases[maxLevel]->knots(i).uFind(u(i,p)).uIndex();
201 const int lvl = m_tree.levelOf(low, maxLevel);
203 for(
int i = 0; i <= lvl; i++)
205 m_bases[i]->active_cwise(u.col(p), low, upp);
209 CMatrix::const_iterator it =
210 m_xmatrix[i].find_it_or_fail( m_bases[i]->index(cur) );
212 if( it != m_xmatrix[i].end() )
220 template<
short_t d,
class T>
226 const CMatrix & cmat = m_xmatrix[lvl];
230 for (
index_t i = 0; i < d; ++i)
235 for (
index_t i = 0; i < d; ++i)
245 for (
index_t j = 0; j != end[i]; ++j)
247 if (cmat.bContains(k) && cmat.bContains(k + s))
250 const index_t kInd = m_xmatrix_offset[lvl] +
251 (std::lower_bound(cmat.begin(), cmat.end(), k)
255 const index_t kNextInd = m_xmatrix_offset[lvl] +
256 (std::lower_bound(cmat.begin(), cmat.end(), k + s)
259 mesh.addEdge(kInd, kNextInd);
267 template<
short_t d,
class T>
274 for (
index_t i = 0; i< sz; ++i)
275 mesh.addVertex(nodes.row(i).transpose());
277 addConnectivity(level, mesh);
280 template<
short_t d,
class T>
287 for(
index_t i = 0; i< sz; ++i )
288 mesh.addVertex( nodes.row(i).transpose() );
291 for(
size_t lvl = 0; lvl <= maxLevel(); lvl++)
293 addConnectivity(lvl, mesh);
297 template<
short_t d,
class T>
300 return m_xmatrix_offset.back();
302 template<
short_t d,
class T>
305 std::vector<gsSortedVector<index_t> > OX = m_xmatrix;
308 this->transfer(OX, transf);
309 gsDebug<<
"tranf orig:\n"<<transf<<std::endl;
310 coefs = transf*coefs;
313 template<
short_t d,
class T>
317 this->refineElements_withTransfer(boxes,transf);
319 coefs = transf*coefs;
322 template<
short_t d,
class T>
325 std::vector<gsSortedVector<index_t> > OX = m_xmatrix;
326 this->refineElements(boxes);
327 this->transfer(OX, tran);
330 template<
short_t d,
class T>
331 void gsHTensorBasis<d,T>::refineElements_withTransfer2(std::vector<index_t>
const & boxes, gsSparseMatrix<T> & tran)
333 std::vector<gsSortedVector<index_t> > OX = m_xmatrix;
334 this->refineElements(boxes);
335 this->transfer2(OX, tran);
338 template<
short_t d,
class T>
339 void gsHTensorBasis<d,T>::refineElements_withCoefs2(gsMatrix<T> & coefs,std::vector<index_t>
const & boxes)
341 std::vector<gsSortedVector<index_t> > OX = m_xmatrix;
342 refineElements(boxes);
343 gsSparseMatrix<> transf;
344 this->transfer2(OX, transf);
346 coefs = transf*coefs;
360 template<
short_t d,
class T>
361 void gsHTensorBasis<d,T>::unrefineElements_withCoefs(gsMatrix<T> & coefs,std::vector<index_t>
const & boxes)
363 gsSparseMatrix<> transf;
364 this->unrefineElements_withTransfer(boxes,transf);
367 typename gsSparseSolver<T>::QR solver(transf);
368 coefs=solver.solve(coefs);
371 template<
short_t d,
class T>
372 void gsHTensorBasis<d,T>::unrefineElements_withTransfer(std::vector<index_t>
const & boxes, gsSparseMatrix<T> & tran)
374 typename gsHTensorBasis<d,T>::uPtr cp = this->clone();
375 this->unrefineElements(boxes);
376 cp->transfer(this->m_xmatrix,tran);
379 template<
short_t d,
class T>
384 std::vector<gsSortedVector<index_t> > OX = m_xmatrix;
392 std::vector<index_t> boxes;
400 lvl = it.level() + 1;
401 const point & l = it.lowerCorner();
402 const point & u = it.upperCorner();
404 boxes.push_back(lvl);
405 for(
short_t i = 0; i < d; i++)
406 boxes.push_back( l(i) * 2);
407 for(
short_t i = 0; i < d; i++)
408 boxes.push_back( u(i) * 2);
411 this->clone()->refineElements_withCoefs(coefs, boxes);
412 this->uniformRefine(numKnots, mul);
417 template<
short_t d,
class T>
420 std::vector<gsSortedVector<index_t> > OX = m_xmatrix;
421 std::vector<index_t> boxes;
427 lvl = it.level() - 1;
428 const point & l = it.lowerCorner();
429 const point & u = it.upperCorner();
431 boxes.push_back(lvl);
432 for(
short_t i = 0; i < d; i++)
433 boxes.push_back( l(i) / 2);
434 for(
short_t i = 0; i < d; i++)
435 boxes.push_back( u(i)/2 + (
index_t)(u(i)%2!=0));
438 this->clone()->unrefineElements_withCoefs(coefs, boxes);
439 this->uniformCoarsen(numKnots);
443 template<
short_t d,
class T>
446 GISMO_ASSERT(boxes.rows() == d,
"refine() needs d rows of boxes.");
447 GISMO_ASSERT(boxes.cols()%2 == 0,
"Each box needs two corners but you don't provide refine() with them.");
451 for(
int i = 0; i < boxes.cols()/2; i++)
453 for(
short_t j = 0; j < d; j++ )
456 "In refine() the first corner is outside the computational domain.");
458 "In refine() the second corner is outside the computational domain." );
467 this->refine( boxes );
470 needLevel( m_tree.getMaxInsLevel() );
475 std::vector<index_t> refVector = this->asElements(boxes, refExt);
478 this->refineElements( refVector );
485 template<
short_t d,
class T>
488 GISMO_ASSERT(boxes.rows() == d,
"refine() needs d rows of boxes.");
489 GISMO_ASSERT(boxes.cols()%2 == 0,
"Each box needs two corners but you don't provide refine() with them.");
493 for(
int i = 0; i < boxes.cols()/2; i++)
495 for(
short_t j = 0; j < d; j++ )
498 "In refine() the first corner is outside the computational domain.");
500 "In refine() the second corner is outside the computational domain." );
506 std::vector<index_t> refVector = this->asElementsUnrefine(boxes, refExt);
509 this->unrefineElements( refVector );
539 template<
short_t d,
class T>
540 std::vector<index_t> gsHTensorBasis<d,T>::asElements(gsMatrix<T>
const & boxes,
int refExt)
const
547 const int offset = 2*d+1;
551 std::vector<index_t> refVector( offset * boxes.cols()/2 );
552 gsMatrix<T> ctr(d,1);
555 for(
index_t i = 0; i < boxes.cols()/2; i++)
557 ctr = ( boxes.col( 2*i ) + boxes.col( 2*i+1) )/2;
562 const int refLevel = getLevelAtPoint( ctr ) + 1;
565 needLevel( refLevel );
567 for(
index_t j = 0; j < boxes.rows();j++)
570 const gsKnotVector<T> & kv = m_bases[refLevel]->knots(j);
571 index_t k1 = (std::upper_bound(kv.domainUBegin(), kv.domainUEnd(),
572 boxes(j,2*i ) ) - 1).uIndex();
573 index_t k2 = (std::upper_bound(kv.domainUBegin(), kv.domainUEnd()+1,
574 boxes(j,2*i+1) ) - 1).uIndex();
583 index_t maxKtIndex = kv.size();
586 _knotIndexToDiadicIndex(refLevel,j,k1);
587 _knotIndexToDiadicIndex(refLevel,j,k2);
589 _knotIndexToDiadicIndex(refLevel,j,maxKtIndex);
594 ( k1 < 2*refExt ? k1=0 : k1-=2*refExt );
595 ( k2 + 2*refExt >= maxKtIndex ? k2=maxKtIndex-1 : k2+=2*refExt);
598 refVector[i*offset] = refLevel;
599 refVector[i*offset+1+j] = k1;
600 refVector[i*offset+1+j+d] = k2;
611 template<
short_t d,
class T>
612 std::vector<index_t> gsHTensorBasis<d,T>::asElementsUnrefine(gsMatrix<T>
const & boxes,
int refExt)
const
619 const int offset = 2*d+1;
623 std::vector<index_t> refVector;
624 refVector.reserve( offset * boxes.cols()/2 );
625 gsMatrix<T> ctr(d,1);
631 for(
index_t i = 0; i < boxes.cols()/2; i++)
633 ctr = ( boxes.col( 2*i ) + boxes.col( 2*i+1) )/2;
638 const int refLevel = getLevelAtPoint( ctr ) - 1;
641 if (refLevel < 0)
continue;
643 refVector.resize(refVector.size() + offset);
645 for(
index_t j = 0; j < boxes.rows();j++)
648 const gsKnotVector<T> & kv = m_bases[refLevel+1]->knots(j);
649 index_t k1 = (std::upper_bound(kv.domainUBegin(), kv.domainUEnd(),
650 boxes(j,2*i ) ) - 1).uIndex();
651 index_t k2 = (std::upper_bound(kv.domainUBegin(), kv.domainUEnd()+1,
652 boxes(j,2*i+1) ) - 1).uIndex();
661 index_t maxKtIndexd = kv.size();
664 _knotIndexToDiadicIndex(refLevel,j,k1);
665 _knotIndexToDiadicIndex(refLevel,j,k2);
667 _knotIndexToDiadicIndex(refLevel,j,maxKtIndexd);
671 ( k1 < refExt ? k1=0 : k1-=refExt );
672 ( k2 + refExt >= maxKtIndexd ? k2=maxKtIndexd-1 : k2+=refExt);
676 k2 = k2/2 + (
index_t)(k2%2 != 0);
679 refVector[I*offset] = refLevel;
680 refVector[I*offset+1+j] = k1;
681 refVector[I*offset+1+j+d] = k2;
690 template<
short_t d,
class T>
693 GISMO_ASSERT(boxes.rows() == d,
"refine() needs d rows of boxes.");
694 GISMO_ASSERT(boxes.cols()%2 == 0,
"Each box needs two corners but you don't provide refine() with them.");
698 for(
int i = 0; i < boxes.cols()/2; i++)
700 for(
short_t j = 0; j < d; j++ )
703 "In refine() the first corner is outside the computational domain.");
705 "In refine() the second corner is outside the computational domain." );
711 for(
index_t i = 0; i < boxes.cols()/2; i++)
714 const int fLevel = m_bases.size()-1;
716 for(
index_t j = 0; j < k1.size();j++)
720 boxes(j,2*i ) ) - 1).uIndex();
722 boxes(j,2*i+1) ) - 1).uIndex();
727 if (0!=k1[j]) {--k1[j];}
734 _knotIndexToDiadicIndex(fLevel,k1);
735 _knotIndexToDiadicIndex(fLevel,k2);
745 m_tree.sinkBox(k1, k2, fLevel);
747 needLevel( m_tree.getMaxInsLevel() );
810 template<
short_t d,
class T>
814 const index_t lvl = this->levelOf(i);
817 m_bases[lvl]->elementSupport_into(m_xmatrix[lvl][ i - m_xmatrix_offset[lvl] ],
819 point low = elements.col(0);
820 point upp = elements.col(1);
822 for (
short_t k = 0; k!=d; ++k )
824 low[k] = low[k] << 1;
825 upp[k] = upp[k] << 1;
828 m_tree.insertBox(low,upp,lvl+1);
842 template<
short_t d,
class T>
849 "The points did not define boxes properly. The boxes were not added to the basis.");
850 for(
size_t i = 0; i < (boxes.size())/(2*d+1); i++)
852 for(
short_t j = 0; j < d; j++ )
854 i1[j] = boxes[(i*(2*d+1))+j+1];
855 i2[j] = boxes[(i*(2*d+1))+d+j+1];
857 insert_box(i1,i2,boxes[i*(2*d+1)]);
863 template<
short_t d,
class T>
870 "The points did not define boxes properly. The boxes were not added to the basis.");
872 for(
size_t i = 0; i < (boxes.size())/(2*d+1); i++)
874 for(
short_t j = 0; j < d; j++ )
876 i1[j] = boxes[(i*(2*d+1))+j+1];
877 i2[j] = boxes[(i*(2*d+1))+d+j+1];
880 m_tree.clearBox(i1,i2, boxes[i*(2*d+1)]);
886 auto leafIt = m_tree.beginLeafIterator();
887 for (; leafIt.good(); leafIt.next())
889 if ( leafIt.level()>0 )
890 newtree.insertBox(leafIt.lowerCorner(),
896 m_tree.computeMaxInsLevel();
900 template<
short_t d,
class T>
906 rf(dir,!par) = rf(dir,par);
907 for (
index_t i = 0; i!=lvl; ++i)
911 template<
short_t d,
class T>
918 if(
const Self_t * _other = dynamic_cast<const Self_t*>( &other) )
929 bndThis = this->boundaryOffset( bi.
first().side(), offset );
933 bndOther= _other->boundaryOffset( bi.
second().side(), offset );
935 "Input error, sizes do not match: "
936 <<bndThis.rows()<<
"!="<<bndOther.rows() );
940 for(
index_t i=0; i < bndThis.rows(); i++)
943 index_t L = this->levelOf( bndThis(i,0) );
946 index_t flat0 = this->flatTensorIndexOf( bndThis(i,0) );
948 tens0 = this->tensorLevel(L).tensorIndex( flat0 );
960 N[j] = _other->tensorLevel(L).component(j).size();
970 tens1[jj] = tens0[j];
978 tens1[jj] = N[jj]-(1+offset);
987 tens1[jj] = N[jj]-1 - tens1[jj];
992 flat1 = _other->tensorLevel(L).index( tens1 );
996 cont1 = _other->flatTensorIndexToHierachicalIndex( flat1, L );
998 bndOther( i, 0 ) = cont1;
1002 gsWarn<<
"Cannot match with "<< other <<
"\n";
1005 template<
short_t d,
class T>
1011 matchWith(bi,other,bndThis,bndOther,0);
1020 template<
short_t d,
class T>
1021 void gsHTensorBasis<d,T>::set_activ1(
int level)
1023 typedef typename gsKnotVector<T>::smart_iterator knotIter;
1028 CMatrix & cmat = m_xmatrix[level];
1035 if ( level > static_cast<int>(m_tree.getMaxInsLevel() ) )
1039 gsVector<knotIter,d> starts, ends, curr;
1043 for(
short_t i = 0; i != d; ++i)
1046 starts[i] = m_bases[level]->knots(i).sbegin() ;
1048 ends [i] = m_bases[level]->knots(i).send()-m_deg[i]-1;
1054 for(
short_t i = 0; i != d; ++i)
1056 low[i] = curr[i].uIndex();
1057 upp[i] = (curr[i]+m_deg[i]+1).uIndex();
1058 ind[i] = curr[i].index();
1064 _knotIndexToDiadicIndex(level,low);
1065 _knotIndexToDiadicIndex(level,upp);
1068 if ( m_tree.query3(low, upp,level) == level)
1069 cmat.push_unsorted( m_bases[level]->index( ind ) );
1078 template<
short_t d,
class T>
1080 const int level,
point & actLow,
point & actUpp)
1083 for(
short_t i = 0; i != d; ++i)
1085 actLow[i] = tb.knots(i).lastKnotIndex (boxLow[i]) - m_deg[i];
1086 actUpp[i] = tb.knots(i).firstKnotIndex(boxUpp[i]) - 1 ;
1094 template<
short_t d,
class T>
1112 for (
typename hdomain_type::literator it = m_tree.beginLeafIterator();
1113 it.good(); it.next() )
1115 const int lvl = it.level();
1116 CMatrix & cmat = m_xmatrix[lvl];
1119 functionOverlap(it.lowerCorner(), it.upperCorner(), lvl, curr, actUpp);
1123 const index_t gi = m_bases[lvl]->index( curr );
1126 m_bases[lvl]->elementSupport_into(gi, elSupp);
1128 if ( (elSupp.col(0).array() >= it.lowerCorner().array()).all() &&
1129 (elSupp.col(1).array() <= it.upperCorner().array()).all() )
1132 cmat.push_unsorted( gi );
1137 if ( m_tree.query3(elSupp.col(0), elSupp.col(1), lvl) == lvl)
1138 cmat.push_unsorted( gi );
1144 for(
size_t lvl = 0; lvl != m_xmatrix.size(); ++lvl)
1146 m_xmatrix[lvl].sort();
1147 m_xmatrix[lvl].erase( std::unique( m_xmatrix[lvl].begin(), m_xmatrix[lvl].end() ),
1148 m_xmatrix[lvl].end() );
1152 template<
short_t d,
class T>
1154 std::vector<CMatrix> & x_matrix_lvl)
const
1156 x_matrix_lvl.resize(level+1);
1163 for(
int j =0; j < level+1; j++)
1166 x_matrix_lvl[j].clear();
1168 for(
index_t i = 0; i != d; ++i)
1171 starts[i] = m_bases[j]->knots(i).sbegin() ;
1173 ends [i] = m_bases[j]->knots(i).send()-m_deg[i]-1;
1179 for(
index_t i = 0; i != d; ++i)
1181 low[i] = curr[i].uIndex();
1182 upp[i] = (curr[i]+m_deg[i]+1).uIndex();
1183 ind[i] = curr[i].index();
1187 if ( m_tree.query3(low, upp,j) == j)
1189 x_matrix_lvl[j].push_unsorted( m_bases[j]->index( ind ) );
1192 if ( m_tree.query3(low, upp,j) >= j)
1194 x_matrix_lvl[j].push_unsorted( m_bases[j]->index( ind ) );
1200 x_matrix_lvl[j].sort();
1206 template<
short_t d,
class T>
inline
1214 m_tree.insertBox(k1,k2, lvl);
1215 needLevel( m_tree.getMaxInsLevel() );
1218 template<
short_t d,
class T>
1224 while ( ! m_xmatrix_offset[1] )
1226 delete m_bases.front();
1227 m_bases.erase( m_bases.begin() );
1228 m_tree.decrementLevel();
1229 m_xmatrix.erase( m_xmatrix.begin() );
1230 m_xmatrix_offset.erase( m_xmatrix_offset.begin() );
1235 template<
short_t d,
class T>
1238 GISMO_ASSERT( static_cast<size_t>(level) < m_xmatrix.size(),
"Requested level does not exist.\n");
1240 CMatrix::const_iterator xmat_pointer = m_xmatrix[level].begin();
1241 CMatrix::const_iterator xmat_end = m_xmatrix[level].end();
1242 gsSortedVector< int >::iterator ind_pointer = indexes.begin();
1243 gsSortedVector< int >::iterator ind_end = indexes.end();
1245 while(ind_pointer!=ind_end&&xmat_pointer!=xmat_end)
1247 if(*ind_pointer<static_cast<int>(*xmat_pointer))
1252 else if(*ind_pointer==static_cast<int>(*xmat_pointer))
1254 (*ind_pointer)=m_xmatrix_offset[level]+index;
1265 while(ind_pointer!=ind_end)
1272 template<
short_t d,
class T>
1275 if( m_xmatrix.size()<=
static_cast<size_t>(level) )
1277 CMatrix::const_iterator it = std::lower_bound(m_xmatrix[level].begin(), m_xmatrix[level].end(), index );
1278 if(it == m_xmatrix[level].end() || *it != index)
1281 return m_xmatrix_offset[level] + ( it - m_xmatrix[level].begin() );
1284 template<
short_t d,
class T>
1290 const index_t sz = bound.rows();
1293 indexes.resize(sz,-1);
1294 if(level<=maxLevel())
1297 indexes[i]=(bound)(i,0);
1298 flatTensorIndexesToHierachicalIndexes(indexes,level);
1300 actives.resize(indexes.size(),
false);
1301 std::fill (actives.begin(),actives.end(),
false);
1302 for(
size_t i = 0;i<indexes.size();i++)
1307 template<
short_t d,
class T>
1311 needLevel( m_tree.getMaxInsLevel() );
1315 m_xmatrix.resize( m_tree.getMaxInsLevel()+1 );
1317 m_tree.makeCompressed();
1319 for(
size_t i = 0; i != m_xmatrix.size(); i ++)
1326 m_xmatrix_offset.clear();
1327 m_xmatrix_offset.reserve(m_xmatrix.size()+1);
1328 m_xmatrix_offset.push_back(0);
1329 for (
size_t i = 0; i != m_xmatrix.size(); i++)
1331 m_xmatrix_offset.push_back(
1332 m_xmatrix_offset.back() + m_xmatrix[i].size() );
1336 template<
short_t d,
class T>
1339 GISMO_ENSURE(!m_manualLevels || (
size_t)(maxLevel)<m_uIndices.size(),
"Maximum manual level reached, maxLevel = "<<maxLevel<<
", m_uIndices.size() = "<<m_uIndices.size());
1341 const int extraLevels = maxLevel + 1 - m_bases.size();
1342 for (
int i = 0; i < extraLevels; ++i )
1346 m_bases.push_back (next_basis);
1350 template<
short_t d,
class T>
1356 for(
index_t i = 0; i < d; i++)
1357 m_deg[i] = tbasis.
degree(i);
1360 if (
const tensorBasis * tb2 =
1361 dynamic_cast<const tensorBasis*>(&tbasis) )
1363 m_bases.push_back(tb2->clone().release());
1367 GISMO_ERROR(
"Cannot construct a Hierarchical basis from "<< tbasis );
1372 for (
index_t i = 0; i!=d; ++i )
1373 upp[i] = m_bases[0]->knots(i).numElements();
1382 template<
short_t d,
class T>
1386 point low, upp, cur;
1387 const int maxLevel = m_tree.getMaxInsLevel();
1389 std::vector<std::vector<index_t> > temp_output;
1390 temp_output.resize( u.cols() );
1395 for(
index_t p = 0; p < u.cols(); p++)
1397 currPoint = u.col(p);
1398 for(
short_t i = 0; i != d; ++i)
1399 low[i] = m_bases[maxLevel]->knots(i).uFind( currPoint(i,0) ).uIndex();
1402 this->_knotIndexToDiadicIndex(maxLevel,low);
1405 const int lvl = m_tree.levelOf(low, maxLevel);
1406 for(
int i = 0; i <= lvl; i++)
1417 m_bases[i]->active_cwise(currPoint, low, upp);
1421 CMatrix::const_iterator it =
1422 m_xmatrix[i].find_it_or_fail( m_bases[i]->index(cur) );
1424 if( it != m_xmatrix[i].end() )
1426 temp_output[p].push_back(
1427 this->m_xmatrix_offset[i] + (it - m_xmatrix[i].begin() )
1435 if ( temp_output[p].size() > sz )
1436 sz = temp_output[p].size();
1439 result.resize(sz, u.cols() );
1440 for(
index_t i = 0; i < result.cols(); i++)
1442 result.col(i).topRows(temp_output[i].size())
1444 result.col(i).bottomRows(sz-temp_output[i].size()).setZero();
1448 template<
short_t d,
class T>
1451 std::vector<index_t> temp;
1453 for(
size_t i = 0; i != m_xmatrix[i].size(); i++)
1454 for (CMatrix::const_iterator it = m_xmatrix[i].begin();
1455 it != m_xmatrix[i].end(); it++)
1457 ind = this->m_bases[i]->tensorIndex(*it);
1458 for (
unsigned j=0; j!=d; ++j )
1459 if ( (ind[j]==0) || (ind[j]==(this->m_bases[i]->size(j)-1)) )
1461 temp.push_back(m_xmatrix_offset[i] + (it-m_xmatrix[i].begin()) );
1465 return makeMatrix<index_t>(temp.begin(),temp.size(),1 );
1468 template<
short_t d,
class T>
1476 std::vector<index_t> temp;
1479 GISMO_ASSERT(this->maxLevel() < this->m_bases.size(),
"Something went wrong: maxLevel() < m_bases.size(), "<<this->maxLevel()<<
" < "<<m_bases.size());
1480 needLevel(m_xmatrix.size()-1);
1482 for(
size_t i = 0; i != m_xmatrix.size(); i++)
1484 GISMO_ASSERT(static_cast<int>(offset)<this->m_bases[i]->size(k),
1485 "Offset ("<<offset<<
") cannot be bigger than the amount of basis"
1486 "functions orthogonal to Boxside s! ("<<this->m_bases[i]->size(k)<<
")");
1488 index_t r = ( par ? this->m_bases[i]->size(k) - 1 -offset : offset);
1489 for (CMatrix::const_iterator it = m_xmatrix[i].begin();
1490 it != m_xmatrix[i].end(); it++)
1492 ind = this->m_bases[i]->tensorIndex(*it);
1495 m_xmatrix_offset[i] + (it - m_xmatrix[i].begin() )
1499 return makeMatrix<index_t>(temp.begin(),temp.size(),1 );
1502 template<
short_t d,
class T>
1512 template<
short_t d,
class T>
1514 levelAtCorner(boxCorner
const & c)
const
1517 gsVector<bool> pars;
1518 c.parameters_into(d,pars);
1520 gsMatrix<T> supp = m_bases.front()->support();
1522 gsVector<T> vec(supp.rows());
1523 for (
index_t r = 0; r!=supp.rows(); r++)
1524 vec(r) = supp(r,pars(r));
1526 return getLevelAtPoint(vec);
1529 template<
short_t d,
class T>
1531 functionAtCorner(boxCorner
const & c)
const
1533 index_t lvl = this->levelAtCorner(c);
1536 index_t index = m_bases[lvl]->functionAtCorner(c);
1539 return this->flatTensorIndexToHierachicalIndex(index,lvl);
1542 template<
short_t d,
class T>
1544 functionAtCorner(boxCorner
const & c,
index_t level)
const
1547 index_t index = m_bases[level]->functionAtCorner(c);
1550 return this->flatTensorIndexToHierachicalIndex(index,level);
1563 template<
short_t d,
class T>
1567 GISMO_ASSERT(numKnots == 1,
"Only implemented for numKnots = 1");
1569 GISMO_ASSERT( m_tree.getMaxInsLevel() <
static_cast<unsigned>(m_bases.size()),
1570 "Problem with max inserted levels: "<< m_tree.getMaxInsLevel()
1571 <<
"<" << m_bases.size() <<
"\n");
1575 last_basis->uniformRefine(1,mul,dir);
1576 m_bases.push_back( last_basis );
1579 delete m_bases.front();
1580 m_bases.erase( m_bases.begin() );
1583 m_tree.multiplyByTwo();
1588 template<
short_t d,
class T>
1592 GISMO_ASSERT(numKnots == 1,
"Only implemented for numKnots = 1");
1596 m_bases.insert( m_bases.begin(), first_basis );
1599 delete m_bases.back();
1603 m_tree.divideByTwo();
1610 template<
short_t d,
class T>
1613 std::vector< std::vector< std::vector< std::vector<index_t > > > > dummy;
1614 return domainBoundariesGeneric( dummy, result,
false );
1617 template<
short_t d,
class T>
1620 std::vector< std::vector< std::vector< std::vector< T > > > > dummy;
1621 return domainBoundariesGeneric( result, dummy,
true );
1625 template<
short_t d,
class T>
1627 std::vector< std::vector< std::vector< std::vector< T > > > >& params,
1628 bool indicesFlag )
const
1632 std::vector< std::vector< std::vector< int > > > res_aabb;
1633 std::vector< std::vector< std::vector<index_t > > > res_aabb_unsigned;
1634 std::vector< std::vector< std::vector< std::vector< index_t > > > > polylines;
1636 polylines = this->m_tree.getPolylines();
1637 res_aabb.resize( polylines.size() );
1644 indices.resize( polylines.size() );
1647 params.resize(polylines.size());
1649 int maxLevel =
static_cast<int>( this->maxLevel() );
1652 std::vector<T> x_dir(m_bases[maxLevel]->knots(0).unique());
1653 std::vector<T> y_dir(m_bases[maxLevel]->knots(1).unique());
1655 for(
unsigned int i0 = 0; i0 < polylines.size(); i0++)
1658 indices[i0].resize( polylines[i0].size() );
1660 params[i0].resize( polylines[i0].size() );
1662 res_aabb[i0].resize( polylines[i0].size() );
1663 for(
unsigned int i1 = 0; i1 < polylines[i0].size(); i1++)
1666 indices[i0][i1].resize( polylines[i0][i1].size() );
1668 params[i0][i1].resize( polylines[i0][i1].size() );
1670 res_aabb[i0][i1].resize( 4 );
1671 res_aabb[i0][i1][0] = 1000000;
1672 res_aabb[i0][i1][1] = 1000000;
1673 res_aabb[i0][i1][2] = -10000000;
1674 res_aabb[i0][i1][3] = -10000000;
1675 for(
unsigned int i2 = 0; i2 < polylines[i0][i1].size(); i2++)
1679 indices[i0][i1][i2].resize(4);
1680 indices[i0][i1][i2][0] = polylines[i0][i1][i2][0];
1681 indices[i0][i1][i2][1] = polylines[i0][i1][i2][1];
1682 indices[i0][i1][i2][2] = polylines[i0][i1][i2][2];
1683 indices[i0][i1][i2][3] = polylines[i0][i1][i2][3];
1688 params[i0][i1][i2].resize(4);
1690 params[i0][i1][i2][0] = (x_dir[polylines[i0][i1][i2][0]]);
1691 params[i0][i1][i2][1] = (y_dir[polylines[i0][i1][i2][1]]);
1692 params[i0][i1][i2][2] = (x_dir[polylines[i0][i1][i2][2]]);
1693 params[i0][i1][i2][3] = (y_dir[polylines[i0][i1][i2][3]]);
1695 if(res_aabb[i0][i1][0]>
signed(polylines[i0][i1][i2][0]))
1697 res_aabb[i0][i1][0] = polylines[i0][i1][i2][0];
1699 if(res_aabb[i0][i1][1]>
signed(polylines[i0][i1][i2][1]))
1701 res_aabb[i0][i1][1] = polylines[i0][i1][i2][1];
1703 if(res_aabb[i0][i1][2]<
signed(polylines[i0][i1][i2][2]))
1705 res_aabb[i0][i1][2] = polylines[i0][i1][i2][2];
1707 if(res_aabb[i0][i1][3]<
signed(polylines[i0][i1][i2][3]))
1709 res_aabb[i0][i1][3] = polylines[i0][i1][i2][3];
1715 res_aabb_unsigned.resize(res_aabb.size());
1716 for (
unsigned int i = 0; i < res_aabb.size(); i++)
1718 res_aabb_unsigned[i].resize(res_aabb[i].size());
1719 for (
unsigned int j = 0; j < res_aabb[i].size(); j++)
1721 res_aabb_unsigned[i][j].resize(res_aabb[i][j].size());
1722 for (
unsigned int k = 0; k < res_aabb[i][j].size(); k++)
1724 if(res_aabb[i][j][k]<0)
1725 gsWarn <<
"conversion form signed to unsigned\n";
1726 res_aabb_unsigned[i][j][k] = res_aabb[i][j][k];
1730 return res_aabb_unsigned;
1734 template<
short_t d,
class T>
1738 needLevel( old.size() );
1742 std::vector< gsSparseMatrix<T,RowMajor> > transfer(m_bases.size()-1);
1743 std::vector<std::vector<T> > knots(d);
1745 for(
size_t i = 1; i < m_bases.size(); ++i)
1748 for(
unsigned dim = 0; dim != d; ++dim)
1761 T_0_copy.refine_withTransfer(transfer[i-1], knots);
1765 while ( old.size() >= m_xmatrix.size() )
1768 result = this->coarsening_direct(old, m_xmatrix, transfer);
1775 while( m_xmatrix.back().size() == 0 )
1776 m_xmatrix.pop_back();
1779 const int sizeDiff =
static_cast<int>( m_bases.size() - m_xmatrix.size() );
1782 freeAll(m_bases.end() - sizeDiff, m_bases.end());
1783 m_bases.resize(m_xmatrix.size());
1786 result.makeCompressed();
1789 template<
short_t d,
class T>
1793 needLevel( old.size() );
1795 tensorBasis T_0_copy = this->tensorLevel(0);
1796 std::vector< gsSparseMatrix<T,RowMajor> > transfer( m_bases.size()-1 );
1797 std::vector<std::vector<T> > knots(d);
1799 for(
size_t i = 1; i < m_bases.size(); ++i)
1802 for(
short_t dim = 0; dim != d; ++dim)
1814 T_0_copy.refine_withTransfer(transfer[i-1], knots);
1818 while ( old.size() >= m_xmatrix.size())
1819 m_xmatrix.push_back( gsSortedVector<index_t>() );
1821 result = this->coarsening_direct2(old, m_xmatrix, transfer);
1823 result.makeCompressed();
1827 template<
short_t d,
class T>
1830 GISMO_ASSERT( static_cast<size_t>(lvl) < m_xmatrix.size(),
1831 "Requested level does not exist.\n");
1833 if (m_bases[lvl]->knots(dir).has(knotValue))
1835 for(
unsigned int i =lvl;i < m_bases.size();i++)
1836 m_bases[i]->component(dir).insertKnot(knotValue,mult);
1840 gsWarn<<
"Knot value not in the given knot vector."<<std::endl;
1847 template<
short_t d,
class T>
1850 for(
unsigned int k =0; k < knotValue.size(); ++k)
1852 if (m_bases[lvl]->knots(dir).has(knotValue[k]))
1854 for(
unsigned int i =lvl;i < m_bases.size(); ++i)
1855 m_bases[i]->component(dir).insertKnot(knotValue[k],mult);
1859 gsWarn<<
"Knot value not in the given knot vector."<<std::endl;
1865 template<
short_t d,
class T>
1870 m_tree.getBoxesInLevelIndex(b1,b2,level);
1872 for(
index_t i = 0;i<level.rows();i++)
1877 const index_t par_index = m_bases[l]->knots(dir).uFind(par).uIndex();
1878 if(l>0 && (par_index>=min(dir)) && (par_index<=max(dir)))
1881 for(
index_t j=0;j<min.rows();++j)
1883 boxes.push_back(min(j));
1884 for(
index_t j=0;j<max.rows();++j)
1886 boxes.push_back(max(j));
1891 template<
short_t d,
class T>
1894 GISMO_ASSERT(m_manualLevels,
"Only works for manual levels");
1895 knotIndex = m_uIndices[level][dir][knotIndex];
1898 template<
short_t d,
class T>
1901 for (
index_t r = 0; r != d; r++)
1902 this->_knotIndexToDiadicIndex(level,r,knotIndex[r]);
1905 template<
short_t d,
class T>
1908 GISMO_ASSERT(m_manualLevels,
"Only works for manual levels");
1909 typename std::vector<index_t>::const_iterator it = std::find_if(m_uIndices[level][dir].begin(),m_uIndices[level][dir].end(),[&diadicIndex](
const index_t i) {
return i >= diadicIndex; });
1910 GISMO_ASSERT(it!=m_uIndices[level][dir].end(),
"Index not found");
1911 diadicIndex =
std::distance(m_uIndices[level][dir].begin(),it);
1914 template<
short_t d,
class T>
1917 for (
index_t r = 0; r != d; r++)
1918 this->_diadicIndexToKnotIndex(level,r,diadicIndex[r]);
1922 template<
short_t d,
class T>
1925 for (
size_t level=0;level<m_bases.size();++level)
1926 m_bases[level]->degreeElevate(i,dir);
1928 for(
unsigned c=0; c<d; ++c)
1929 m_deg[c]=m_bases[0]->degree(c);
1931 this->update_structure();
1934 template<
short_t d,
class T>
1935 void gsHTensorBasis<d,T>::degreeReduce(
int const & i,
int const dir)
1937 for (
size_t level=0;level<m_bases.size();++level)
1938 m_bases[level]->degreeReduce(i,dir);
1940 for(
unsigned c=0; c<d; ++c)
1941 m_deg[c]=m_bases[0]->degree(c);
1943 this->update_structure();
1946 template<
short_t d,
class T>
1947 void gsHTensorBasis<d,T>::degreeIncrease(
int const & i,
int const dir)
1949 for (
size_t level=0;level<m_bases.size();++level)
1950 m_bases[level]->degreeIncrease(i,dir);
1952 for(
unsigned c=0; c<d; ++c)
1953 m_deg[c]=m_bases[0]->degree(c);
1955 this->update_structure();
1958 template<
short_t d,
class T>
1959 void gsHTensorBasis<d,T>::degreeDecrease(
int const & i,
int const dir)
1961 for (
size_t level=0;level<m_bases.size();++level)
1962 m_bases[level]->degreeDecrease(i,dir);
1964 for(
unsigned c=0; c<d; ++c)
1965 m_deg[c]=m_bases[0]->degree(c);
1967 this->update_structure();
1970 template<
short_t d,
class T>
1974 np.setConstant(npts);
1976 gsMatrix<T> grid = gsPointGrid<T>(supp.col(0),supp.col(1),np);
1978 this->eval_into(grid,res);
1980 return ((sums.array()>1-tol && sums.array()<1+tol).all());
1988 template<
short_t d,
class T>
1994 GSXML_COMMON_FUNCTIONS(gsHTensorBasis<TMPLA2(d,T)>);
1995 static std::string tag () {
return "Basis"; }
1996 static std::string type () {
return ""; }
1998 static gsHTensorBasis<d,T> *
get (gsXmlNode * node)
2000 gsXmlAttribute * btype = node->first_attribute(
"type");
2003 gsWarn<<
"Basis without a type in the xml file.\n";
2006 std::string s = btype->value() ;
2007 if ( s.compare(0, 9,
"HBSplineB" , 9 ) == 0 )
2008 return gsXml< gsHBSplineBasis<d,T> >::
get(node);
2009 if ( s.compare(0, 10,
"THBSplineB", 10) == 0 )
2010 return gsXml< gsTHBSplineBasis<d,T> >::
get(node);
2012 gsWarn<<
"gsXmlUtils: gsHTensorBasis: No known basis \""<<s<<
"\". Error.\n";
2016 static gsXmlNode * put (
const gsHTensorBasis<d,T> & obj,
2019 const gsBasis<T> * ptr = & obj;
2022 if (
const gsHBSplineBasis<d,T> * g =
2023 dynamic_cast<const gsHBSplineBasis<d,T> *
>( ptr ) )
2024 return gsXml< gsHBSplineBasis<d,T> >::put(*g,data);
2027 if (
const gsTHBSplineBasis<d,T> * g =
2028 dynamic_cast<const gsTHBSplineBasis<d,T> *
>( ptr ) )
2029 return gsXml< gsTHBSplineBasis<d,T> >::put(*g,data);
2031 gsWarn<<
"gsXmlUtils put: getBasis: No known basis \""<<obj<<
"\". Error.\n";
void insert_box(point const &k1, point const &k2, int lvl)
Inserts a domain into the basis.
Definition: gsHTensorBasis.hpp:1207
index_t getLevelAtIndex(const point &Pt) const
Returns the level(s) at indexes in the parameter domain.
Definition: gsHTensorBasis.hpp:160
virtual void connectivity(const gsMatrix< T > &nodes, gsMesh< T > &mesh) const
Definition: gsHTensorBasis.hpp:281
void refineElements_withCoefs(gsMatrix< T > &coefs, std::vector< index_t > const &boxes)
Definition: gsHTensorBasis.hpp:314
T distance(gsMatrix< T > const &A, gsMatrix< T > const &B, index_t i=0, index_t j=0, bool cols=false)
compute a distance between the point number in the set and the point number <j> in the set ; by def...
Iterates over the leaves of an gsHDomain (tree).
Definition: gsHDomainLeafIter.h:29
mult_t maxInteriorMultiplicity() const
Returns the maximum multiplicity in the interior.
Definition: gsKnotVector.hpp:724
bool nextCubePoint(Vec &cur, const Vec &end)
Iterate in lexigographic order through the points of the integer lattice contained in the cube [0...
Definition: gsCombinatorics.h:327
#define gsDebug
Definition: gsDebug.h:61
void getBoxesAlongSlice(int dir, T par, std::vector< index_t > &boxes) const
Definition: gsHTensorBasis.hpp:1866
#define short_t
Definition: gsConfig.h:35
void uniformRefine_withCoefs(gsMatrix< T > &coefs, int numKnots=1, int mul=1, int dir=-1)
Refine the basis uniformly.
Definition: gsHTensorBasis.hpp:380
void _diadicIndexToKnotIndex(const index_t level, gsVector< index_t, d > &diadicIndex) const
Transfers the diadicIndex in the knot span in direction on level level to knot indices.
Definition: gsHTensorBasis.hpp:1915
void setActiveToLvl(int level, std::vector< CMatrix > &x_matrix_lvl) const
Creates characteristic matrices for basis where "level" is the maximum level i.e. ignoring higher lev...
Definition: gsHTensorBasis.hpp:1153
virtual short_t degree(short_t i) const
Degree with respect to the i-th variable. If the basis is a tensor product of (piecewise) polynomial ...
Definition: gsBasis.hpp:650
bool parameter() const
Returns the parameter value (false=0=start, true=1=end) that corresponds to this side.
Definition: gsBoundary.h:128
std::vector< std::vector< std::vector< index_t > > > domainBoundariesGeneric(std::vector< std::vector< std::vector< std::vector< index_t > > > > &indices, std::vector< std::vector< std::vector< std::vector< T > > > > ¶ms, bool indicesFlag) const
Implementation of the features common to domainBoundariesParams and domainBoundariesIndices. It takes both.
Definition: gsHTensorBasis.hpp:1626
virtual void increaseMultiplicity(index_t lvl, int dir, T knotValue, int mult=1)
Increases the multiplicity of a knot with the value knotValue in level lvl in direction dir by mult...
Definition: gsHTensorBasis.hpp:1828
uiterator domainUEnd() const
Returns a unique iterator pointing to the ending knot of the domain.
Definition: gsKnotVector.h:367
#define index_t
Definition: gsConfig.h:32
virtual void uniformCoarsen(int numKnots=1)
Coarsen the basis uniformly by removing groups of numKnots consecutive knots, each knot removed mul t...
Definition: gsTensorBasis.h:349
#define GISMO_ENSURE(cond, message)
Definition: gsDebug.h:102
This class is derived from std::vector, and adds sort tracking.
Definition: gsSortedVector.h:109
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
void insert(T knot, mult_t mult=1)
Inserts knot knot into the knot vector with multiplicity mult.
Definition: gsKnotVector.hpp:325
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Provides implementation of generic XML functions.
bool testPartitionOfUnity(const index_t npts=100, const T tol=1e-12) const
Test the partition of unity.
Definition: gsHTensorBasis.hpp:1971
virtual void unrefineElements(std::vector< index_t > const &boxes)
Clear the given boxes into the quadtree.
Definition: gsHTensorBasis.hpp:864
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition: gsSparseMatrix.h:140
uiterator uFind(const T u) const
Returns the uiterator pointing to the knot at the beginning of the knot interval containing u...
Definition: gsKnotVector.hpp:747
void makeCompressed()
Cleans the basis, removing any inactive levels.
Definition: gsHTensorBasis.hpp:1219
void _knotIndexToDiadicIndex(const index_t level, const index_t dir, index_t &knotIndex) const
Transfers the knotIndex in the knot span in direction dir on level level to diadic indices...
Definition: gsHTensorBasis.hpp:1892
Class Representing a triangle mesh with 3D vertices.
Definition: gsMesh.h:31
index_t getLevelAtPoint(const gsMatrix< T > &Pt) const
Returns the level(s) at point(s) in the parameter domain.
Definition: gsHTensorBasis.hpp:141
index_t size() const
The number of basis functions in this basis.
Definition: gsHTensorBasis.hpp:298
void activeBoundaryFunctionsOfLevel(const unsigned level, const boxSide &s, std::vector< bool > &actives) const
Definition: gsHTensorBasis.hpp:1285
gsMatrix< T > support() const
Returns the boundary basis for side s.
Definition: gsHTensorBasis.hpp:124
Class representing a (scalar) hierarchical tensor basis of functions .
Definition: gsHTensorBasis.h:74
#define gsWarn
Definition: gsDebug.h:50
uiterator domainUBegin() const
Returns a unique iterator pointing to the starting knot of the domain.
Definition: gsKnotVector.h:359
void functionOverlap(const point &boxLow, const point &boxUpp, const int level, point &actLow, point &actUpp)
Returns the basis functions of level which have support on box, represented as an index box...
Definition: gsHTensorBasis.hpp:1079
void numActive_into(const gsMatrix< T > &u, gsVector< index_t > &result) const
The number of active basis functions at points u.
Definition: gsHTensorBasis.hpp:187
virtual void refineElements(std::vector< index_t > const &boxes)
Insert the given boxes into the quadtree.
Definition: gsHTensorBasis.hpp:843
void addLevel(const gsTensorBSplineBasis< d, T > &next_basis)
Adds a level, only if manual levels are activated.
Definition: gsHTensorBasis.hpp:35
virtual void active_into(const gsMatrix< T > &u, gsMatrix< index_t > &result) const
Returns the indices of active basis functions at points u, as a list of indices, in result...
Definition: gsHTensorBasis.hpp:1383
int flatTensorIndexToHierachicalIndex(index_t index, const int level) const
takes a flat tensor index of the bspline basis of level and gives back the hierachical index...
Definition: gsHTensorBasis.hpp:1273
void symDifference(const gsKnotVector< T > &other, std::vector< T > &result) const
Computes the symmetric difference between this knot-vector and other.
Definition: gsKnotVector.hpp:172
void refineSide(const boxSide side, index_t lvl)
Refines all the cells on the side side up to level lvl.
Definition: gsHTensorBasis.hpp:901
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
gsMatrix< index_t > allBoundary() const
Returns the indices of the basis functions that are nonzero at the domain boundary.
Definition: gsHTensorBasis.hpp:1449
virtual void refine(gsMatrix< T > const &boxes, int refExt)
Refine the basis to levels and in the areas defined by boxes with an extension.
Definition: gsHTensorBasis.hpp:444
Struct which represents a certain side of a box.
Definition: gsBoundary.h:84
void getLevelUniqueSpanAtPoints(const gsMatrix< T > &Pt, gsVector< index_t > &lvl, gsMatrix< index_t > &loIdx) const
Returns the level(s) and knot span(s) at point(s) in the parameter domain.
Definition: gsHTensorBasis.hpp:170
virtual void update_structure()
Updates the basis structure (eg. charact. matrices, etc), to be called after any modifications.
Definition: gsHTensorBasis.hpp:1308
virtual gsMatrix< index_t > boundaryOffset(boxSide const &s, index_t offset) const
Definition: gsHTensorBasis.hpp:1470
virtual void uniformCoarsen(int numKnots=1)
Coarsen the basis uniformly by removing groups of numKnots consecutive knots, each knot removed mul t...
Definition: gsHTensorBasis.hpp:1589
unsigned index(unsigned i, unsigned j, unsigned k=0) const
Definition: gsTensorBasis.h:882
Provides declaration of the Mesh class.
uPtr clone()
Clone methode. Produceds a deep copy inside a uPtr.
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: gsHTensorBasis.hpp:1564
void uniformCoarsen_withCoefs(gsMatrix< T > &coefs, int numKnots=1)
Coarsen the basis uniformly.
Definition: gsHTensorBasis.hpp:418
const point & upperCorner() const
Accessor for gsHDomain::m_upperIndex.
Definition: gsHDomain.h:249
unsigned stride(short_t dir) const
Returns the stride for dimension dir.
Definition: gsTensorBasis.h:889
bool nextLexicographic(Vec &cur, const Vec &size)
Iterates through a tensor lattice with the given size. Updates cur and returns true if another entry ...
Definition: gsCombinatorics.h:196
#define GISMO_UNUSED(x)
Definition: gsDebug.h:112
Provides functions to generate structured point data.
void needLevel(int maxLevel) const
Makes sure that there are numLevels grids computed in the hierarachy.
Definition: gsHTensorBasis.hpp:1337
void flatTensorIndexesToHierachicalIndexes(gsSortedVector< int > &indexes, const int level) const
transformes a sortedVector indexes of flat tensor index of the bspline basis of level to hierachical ...
Definition: gsHTensorBasis.hpp:1236
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
Class for representing a knot vector.
Definition: gsKnotVector.h:79
void refineBasisFunction(const index_t i)
Refines the basis function with (hierarchical) index i.
Definition: gsHTensorBasis.hpp:811
Creates a mapped object or data pointer to a const vector without copying data.
Definition: gsLinearAlgebra.h:130
patchSide & second()
second, returns the second patchSide of this interface
Definition: gsBoundary.h:782
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
std::vector< std::vector< std::vector< index_t > > > domainBoundariesIndices(std::vector< std::vector< std::vector< std::vector< index_t > > > > &result) const
Gives polylines on the boundaries between different levels of the mesh.
Definition: gsHTensorBasis.hpp:1618
void transfer(const std::vector< gsSortedVector< index_t > > &old, gsSparseMatrix< T > &result)
Returns transfer matrix between the hirarchical spline given by the characteristic matrix "old" and t...
Definition: gsHTensorBasis.hpp:1735
const Basis_t & component(short_t dir) const
For a tensor product basis, return the (const) 1-d basis for the i-th parameter component.
Definition: gsTensorBSplineBasis.h:202
int degree() const
Returns the degree of the knot vector.
Definition: gsKnotVector.hpp:700
std::vector< std::vector< std::vector< index_t > > > domainBoundariesParams(std::vector< std::vector< std::vector< std::vector< T > > > > &result) const
Gives polylines on the boundaries between different levels of the mesh.
Definition: gsHTensorBasis.hpp:1611
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition: gsBoundary.h:113
Provides declaration of input/output XML utilities struct.
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
bool good() const
Returns true iff we are still pointing at a valid leaf.
Definition: gsHDomainLeafIter.h:81
patchSide & first()
first, returns the first patchSide of this interface
Definition: gsBoundary.h:776