73 template<
short_t d,
class T>
78 typedef memory::shared_ptr< gsHTensorBasis >
Ptr;
81 typedef memory::unique_ptr< gsHTensorBasis >
uPtr;
93 typedef std::vector< box > boxHistory;
97 typedef typename CMatrix::const_iterator cmatIterator;
115 m_manualLevels(false)
123 m_manualLevels(manualLevels)
127 initialize_class(tbasis);
134 for(
index_t i = 0; i < d; i++)
135 m_deg[i] = tbasis.
degree(i);
139 if (
const tensorBasis * tb2 = dynamic_cast<const tensorBasis*>(&tbasis) )
141 m_bases.push_back(tb2->clone().release());
143 std::vector<std::vector<index_t>> lvlIndices(d);
144 std::vector<index_t> dirIndices;
145 for (
short_t dim=0; dim!=d; dim++)
147 dirIndices.resize(tb2->knots(dim).uSize());
148 std::iota(dirIndices.begin(),dirIndices.end(),0);
149 lvlIndices[dim] = dirIndices;
151 m_uIndices.push_back(lvlIndices);
155 GISMO_ERROR(
"Cannot construct a Hierarchical basis from "<< tbasis );
160 for (
index_t i = 0; i!=d; ++i )
161 upp[i] = m_bases[0]->knots(i).numElements();
168 gsHTensorBasis( gsTensorBSplineBasis<d,T>
const& tbasis,
169 const std::vector<index_t> & boxes)
171 m_manualLevels(false)
173 initialize_class(tbasis);
180 "The points did not define boxes properly. The basis was created without any domain structure.");
182 for(
size_t i = 0; i < (boxes.size()/(2*d+1)); i++)
184 for(
short_t j = 0; j < d; j++)
186 i1[j] = boxes[(2*d+1)*i+j+1];
187 i2[j] = boxes[(2*d+1)*i+j+d+1];
189 insert_box(i1,i2,boxes[i*(2*d+1)]);
208 m_manualLevels(false)
211 GISMO_ASSERT(boxes.rows() == d,
"Points in boxes need to be of dimension d.");
212 GISMO_ASSERT(boxes.cols()%2 == 0,
"Each box needs two corners but you don't provied gsHTensorBasis constructor with them.");
213 initialize_class(tbasis);
218 for(
index_t i = 0; i < boxes.cols()/2; i++)
222 k1[j] = this->m_bases.back()->knots(j).uFind(boxes(j,2*i)).uIndex();
223 k2[j] = this->m_bases.back()->knots(j).uFind(boxes(j,2*i+1)).uIndex()+1;
225 int level = m_tree.query3(k1,k2,m_bases.size()-1);
228 k1[j] = this->m_bases[level+1]->knots(j).uFind(boxes(j,2*i)).uIndex();
229 k2[j] = this->m_bases[level+1]->knots(j).uFind(boxes(j,2*i+1)).uIndex()+1;
232 insert_box(k1,k2,level+1);
249 const std::vector<index_t> & levels)
251 m_manualLevels(false)
253 GISMO_ASSERT(boxes.rows() == d,
"Points in boxes need to be of dimension d.");
254 GISMO_ASSERT(boxes.cols()%2 == 0,
"Each box needs two corners but you don't provied gsHTensorBasis constructor with them.");
255 GISMO_ASSERT(
unsigned (boxes.cols()/2) <= levels.size(),
"We don't have enough levels for the boxes.");
257 initialize_class(tbasis);
262 const size_t mLevel = *std::max_element(levels.begin(), levels.end() );
265 for(
index_t i = 0; i < boxes.cols()/2; i++)
269 k1[j] = m_bases[levels[i]]->knots(j).uFind(boxes(j,2*i)).uIndex();
270 k2[j] = m_bases[levels[i]]->knots(j).uFind(boxes(j,2*i+1)).uIndex()+1;
274 this->m_tree.insertBox(k1,k2, levels[i]);
295 m_manualLevels = o.m_manualLevels;
299 m_bases.resize( o.
m_bases.size() );
305 #if EIGEN_HAS_RVALUE_REFERENCES
306 gsHTensorBasis(gsHTensorBasis&& other)
308 this->operator=(other);
311 gsHTensorBasis & operator=(gsHTensorBasis&& other)
313 m_deg = std::move(other.m_deg);
315 m_bases = std::move(other.m_bases);
316 m_xmatrix = std::move(other.m_xmatrix);
317 m_tree = std::move(other.m_tree);
318 m_xmatrix_offset = std::move(other.m_xmatrix_offset);
319 m_manualLevels = std::move(other.m_manualLevels);
320 m_uIndices = std::move(other.m_uIndices);
341 void only_insert_box(point
const & k1, point
const & k2,
int lvl);
346 std::vector<int> m_deg;
395 # define Eigen gsEigen
396 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
417 const std::vector< CMatrix >& getXmatrix()
const
438 return m_tree.numBreaks(lvl,k);
446 return m_bases[lvl]->knots(k).size();
450 T
knot(
int lvl,
int k,
int i)
const
454 return m_bases[lvl]->component(k).knot(i);
462 result.resize( d, this->size()) ;
466 for(
size_t i = 0; i < m_xmatrix.size(); i++)
468 for( CMatrix::const_iterator it =
469 m_xmatrix[i].begin(); it != m_xmatrix[i].end(); it++)
471 ind = m_bases[i]->tensorIndex(*it);
472 for (
short_t r = 0; r!=d; ++r )
473 result(r,k) = m_bases[i]->knots(r).greville( ind[r] );
482 index_t ind = flatTensorIndexOf(i);
484 m_bases[lvl]->anchor_into(ind,result);
492 void printCharMatrix(std::ostream &os =
gsInfo)
const
494 os<<
"Characteristic matrix:\n";
495 for(
size_t i = 0; i!= m_xmatrix.size(); i++)
497 if ( m_xmatrix[i].size() )
500 ", size="<<m_xmatrix[i].size() <<
":\n";
501 os <<
"("<< m_bases[i]->tensorIndex(*m_xmatrix[i].begin()).transpose() <<
")";
502 for( CMatrix::const_iterator it =
503 m_xmatrix[i].begin()+1; it != m_xmatrix[i].end(); it++)
505 os <<
", ("<< m_bases[i]->tensorIndex(*it).transpose() <<
")";
511 os<<
"- level="<<i<<
" is empty.\n";
519 os<<
"Spline-space hierarchy:\n";
520 for(
size_t i = 0; i!= m_xmatrix.size(); i++)
522 if ( m_xmatrix[i].size() )
525 ", size="<<m_xmatrix[i].size() <<
":\n";
526 os <<
"Space: "<< * m_bases[i] <<
")\n";
530 for (
size_t dim=0; dim!=d; dim++)
536 os<<
"- level="<<i<<
" is empty.\n";
544 os<<
"Spline-space hierarchy:\n";
545 for(
unsigned i = 0; i< m_bases.size(); i++)
548 ", size="<<m_bases[i]->size() <<
":\n";
549 os <<
"Space: "<< * m_bases[i] <<
")\n";
553 for (
size_t dim=0; dim!=d; dim++)
562 os <<
"basis of dimension " <<this->dim()<<
563 ",\nlevels="<< this->m_tree.getMaxInsLevel()+1 <<
", size="
564 << this->size()<<
", tree_nodes="<< this->m_tree.size()
570 os <<
"Domain: ["<< supp.col(0).transpose()<<
"]..["<<
571 supp.col(1).transpose()<<
"].\n";
572 os <<
"Size per level: ";
573 for(
size_t i = 0; i!= m_xmatrix.size(); i++)
574 os << this->m_xmatrix[i].size()<<
" ";
607 void makeCompressed();
621 m_bases[lvl]->elementSupport_into(m_xmatrix[lvl][ i - m_xmatrix_offset[lvl] ],
629 m_bases[lvl]->elementSupport_into(m_xmatrix[lvl][j-m_xmatrix_offset[lvl]], sup);
630 std::pair<point,point>
box = m_tree.queryLevelCell(sup.col(0),sup.col(1),lvl);
631 for (
short_t i = 0; i!=d; ++i)
633 box.first[i] = ( sup(i,0) >= box.first[i] ? sup(i,0) : box.first[i] );
634 box.second[i] = ( sup(i,1) <= box.second[i] ? sup(i,1) : box.second[i]);
636 sup.col(0) = (box.first+box.second)/2;
637 sup.col(1) = sup.col(0).array() + 1;
638 return m_bases[lvl]->elementDom(sup);
649 return m_tree.size();
658 return m_bases[ this->maxLevel() ]->component(i);
664 return m_bases[ this->maxLevel() ]->component(i);
671 return *this->m_bases[i];
675 virtual void uniformRefine(
int numKnots = 1,
int mul=1,
int dir=-1);
685 void uniformRefine_withCoefs(
gsMatrix<T>& coefs,
int numKnots = 1,
int mul = 1,
int dir = -1);
697 void refineElements_withCoefs (
gsMatrix<T> & coefs,std::vector<index_t>
const & boxes);
698 void refineElements_withTransfer(std::vector<index_t>
const & boxes,
gsSparseMatrix<T> &transfer);
699 void refineElements_withTransfer2(std::vector<index_t>
const & boxes,
gsSparseMatrix<T> &transfer);
701 void refineElements_withCoefs2(
gsMatrix<T> & coefs,std::vector<index_t>
const & boxes);
703 void unrefineElements_withCoefs (
gsMatrix<T> & coefs,std::vector<index_t>
const & boxes);
704 void unrefineElements_withTransfer(std::vector<index_t>
const & boxes,
gsSparseMatrix<T> &transfer);
707 virtual void uniformCoarsen(
int numKnots = 1);
710 void uniformCoarsen_withCoefs(
gsMatrix<T>& coefs,
int numKnots = 1);
722 short_t td = m_bases[0]->degree(0);
725 td = math::max(td, m_bases[0]->degree(k));
731 short_t td = m_bases[0]->degree(0);
734 td = math::min(td, m_bases[0]->degree(k));
741 for (
unsigned int lvl = 0; lvl <= maxLevel(); lvl++)
743 for (
unsigned int dir = 0; dir < d; dir++)
751 m_bases[lvl]->knots(dir).ubegin() + 1;
752 it < m_bases[lvl]->knots(dir).uend() - 1;
753 it += (lvl == 0? 1 : 2))
755 for(
unsigned int j =lvl;j < m_bases.size();j++)
756 m_bases[j]->component(dir).insertKnot(*it,i);
768 {
return m_bases[0]->degree(i);}
792 index_t getLevelAtIndex(
const point & Pt )
const;
806 void getLevelUniqueSpanAtPoints(
const gsMatrix<T> & Pt,
813 return m_tree.getMaxInsLevel();
819 return std::upper_bound(m_xmatrix_offset.begin(),
820 m_xmatrix_offset.end(), i)
821 - m_xmatrix_offset.begin() - 1;
831 void degreeElevate(
int const & i = 1,
int const dir = -1);
832 void degreeReduce(
int const & i = 1,
int const dir = -1);
834 void degreeIncrease(
int const & i= 1,
int const dir = -1);
835 void degreeDecrease(
int const & i = 1,
int const dir = -1);
848 virtual void refine(
gsMatrix<T> const & boxes,
int refExt);
849 virtual void unrefine(
gsMatrix<T> const & boxes,
int refExt);
851 std::vector<index_t> asElements(
gsMatrix<T> const & boxes,
int refExt = 0)
const;
852 std::vector<index_t> asElementsUnrefine(
gsMatrix<T> const & boxes,
int refExt = 0)
const;
891 virtual void refineElements(std::vector<index_t>
const & boxes);
899 virtual void unrefineElements(std::vector<index_t>
const & boxes);
905 void refineBasisFunction(
const index_t i);
917 return ( s == boundary::none ?
934 return flatTensorIndexOf(i, this->levelOf(i) );
949 const index_t offset = this->m_xmatrix_offset[level];
950 const index_t ind_in_level = this->m_xmatrix[level][i - offset];
961 std::vector< std::vector< std::vector<index_t > > > domainBoundariesParams( std::vector< std::vector< std::vector< std::vector< T > > > >& result)
const;
970 std::vector< std::vector< std::vector<index_t > > > domainBoundariesIndices( std::vector< std::vector< std::vector< std::vector<index_t > > > >& result)
const;
974 typename gsBasis<T>::domainIter domIter =
975 s == boundary::none ?
980 for (; domIter->good(); domIter->next())
1003 int flatTensorIndexToHierachicalIndex(
index_t index,
const int level)
const;
1012 void activeBoundaryFunctionsOfLevel(
const unsigned level,
const boxSide & s,std::vector<bool>& actives)
const;
1023 virtual void increaseMultiplicity(
index_t lvl,
int dir, T knotValue,
int mult = 1);
1033 virtual void increaseMultiplicity(
index_t lvl,
int dir,
const std::vector<T> & knotValue,
int mult = 1);
1039 virtual void update_structure();
1043 void needLevel(
int maxLevel)
const;
1046 void createMoreLevels(
int numLevels)
const;
1051 void getBoxesAlongSlice(
int dir, T par,std::vector<index_t>& boxes )
const;
1077 void insert_box(point
const & k1, point
const & k2,
int lvl);
1079 void initialize_class(
gsBasis<T> const& tbasis);
1083 void functionOverlap(
const point & boxLow,
const point & boxUpp,
1084 const int level, point & actLow, point & actUpp);
1087 void set_activ1(
int level);
1093 void addConnectivity(
int level,
gsMesh<T> & mesh)
const;
1097 const std::vector<CMatrix>& n,
1110 std::vector< std::vector< std::vector<index_t > > > domainBoundariesGeneric(std::vector< std::vector< std::vector< std::vector<index_t > > > >& indices,
1111 std::vector< std::vector< std::vector< std::vector< T > > > >& params,
1112 bool indicesFlag )
const;
1123 void setActiveToLvl(
int level, std::vector<CMatrix>& x_matrix_lvl)
const;
1133 bool testPartitionOfUnity(
const index_t npts = 100,
const T tol = 1e-12)
const;
1148 template<
typename T>
class gsHTensorBasis<0,T>
1149 {
using T::GISMO_ERROR_gsHTensorBasis_cannot_have_dimension_zero;};
1152 #ifdef GISMO_WITH_PYBIND11
1157 void pybind11_init_gsHTensorBasis2(pybind11::module &m);
1158 void pybind11_init_gsHTensorBasis3(pybind11::module &m);
1159 void pybind11_init_gsHTensorBasis4(pybind11::module &m);
1161 #endif // GISMO_WITH_PYBIND11
1169 #ifndef GISMO_BUILD_LIB
1170 #include GISMO_HPP_HEADER(gsHTensorBasis.hpp)
Re-implements gsDomainIterator for iteration over all boundary elements of a hierarchical parameter d...
Definition: gsHDomain.h:24
bool manualLevels() const
Returns true if levels are assigned manually.
Definition: gsHTensorBasis.h:332
internal::gsUKnotIterator< T > uiterator
Definition: gsKnotVector.h:102
index_t flatTensorIndexOf(const index_t i) const
Returns the tensor index of the function indexed i (in continued indices).
Definition: gsHTensorBasis.h:932
size_t numElements(boxSide const &s=0) const
The number of elements on side s.
Definition: gsHTensorBasis.h:972
Provides declaration of iterator of hierarchical domain.
Traits for BSplineBasis in more dimensions.
Definition: gsBSplineBasis.h:31
virtual void anchors_into(gsMatrix< T > &result) const
Definition: gsHTensorBasis.h:460
virtual const gsBSplineBasis< T > & component(short_t i) const
The 1-d basis for the i-th parameter component at the highest level.
Definition: gsHTensorBasis.h:662
memory::unique_ptr< gsHTensorBasis > uPtr
Unique pointer for gsHTensorBasis.
Definition: gsHTensorBasis.h:81
#define short_t
Definition: gsConfig.h:35
Provides structs and classes related to interfaces and boundaries.
short_t minDegree() const
If the basis is of polynomial or piecewise polynomial type, then this function returns the minimum po...
Definition: gsHTensorBasis.h:729
virtual ~gsHTensorBasis()
Destructor.
Definition: gsHTensorBasis.h:326
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
index_t flatTensorIndexOf(const index_t i, const index_t level) const
Returns the tensor index of the function indexed i (in continued indices).
Definition: gsHTensorBasis.h:947
std::vector< tensorBasis * > m_bases
The list of nested spaces.
Definition: gsHTensorBasis.h:361
Provides declaration of Basis abstract interface.
gsHTensorBasis()
Default empty constructor.
Definition: gsHTensorBasis.h:113
gsHDomain< d > & tree()
Returns a reference to m_tree.
Definition: gsHTensorBasis.h:604
#define index_t
Definition: gsConfig.h:32
void reduceContinuity(int const &i=1)
Reduces spline continuity at interior knots by i.
Definition: gsHTensorBasis.h:739
void printBasic(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition: gsHTensorBasis.h:560
This class is derived from std::vector, and adds sort tracking.
Definition: gsSortedVector.h:109
const std::vector< tensorBasis * > & getBases() const
Returns the tensor B-spline space of all levels.
Definition: gsHTensorBasis.h:425
const gsHDomain< d > & tree() const
Returns a reference to m_tree.
Definition: gsHTensorBasis.h:601
short_t maxDegree() const
If the basis is of polynomial or piecewise polynomial type, then this function returns the maximum po...
Definition: gsHTensorBasis.h:720
A tensor product B-spline basis.
Definition: gsTensorBSplineBasis.h:36
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
void cloneAll(It start, It end, ItOut out)
Clones all pointers in the range [start end) and stores new raw pointers in iterator out...
Definition: gsMemory.h:295
Provides declaration of the HDomain class.
gsHTensorBasis(const gsHTensorBasis &o)
Copy constructor.
Definition: gsHTensorBasis.h:282
T knot(int lvl, int k, int i) const
Returns the i-th knot in direction k at level lvl.
Definition: gsHTensorBasis.h:450
index_t numLevels() const
Returns the number of levels.
Definition: gsHTensorBasis.h:335
A univariate B-spline basis.
Definition: gsBSplineBasis.h:694
virtual gsBSplineBasis< T > & component(short_t i)
The 1-d basis for the i-th parameter component at the highest level.
Definition: gsHTensorBasis.h:656
gsHTensorBasis(gsTensorBSplineBasis< d, T > const &tbasis, gsMatrix< T > const &boxes, const std::vector< index_t > &levels)
gsHTensorBasis
Definition: gsHTensorBasis.h:247
Class Representing a triangle mesh with 3D vertices.
Definition: gsMesh.h:31
std::vector< CMatrix > m_xmatrix
The characteristic matrices for each level.
Definition: gsHTensorBasis.h:377
Class representing a (scalar) hierarchical tensor basis of functions .
Definition: gsHTensorBasis.h:74
Re-implements gsDomainIterator for iteration over all boundary elements of a hierarchical parameter d...
Definition: gsHDomainBoundaryIterator.h:40
Provides declaration of BSplineBasis class.
gsBasis< T >::domainIter makeDomainIterator(const boxSide &s) const
Create a boundary domain iterator for the computational mesh this basis, that points to the first ele...
Definition: gsHTensorBasis.h:915
gsMatrix< T > elementInSupportOf(index_t j) const
Returns (the coordinates of) an element in the support of basis function j.
Definition: gsHTensorBasis.h:625
#define gsInfo
Definition: gsDebug.h:43
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition: gsMemory.h:312
Struct which represents a certain side of a box.
Definition: gsBoundary.h:84
std::vector< index_t > m_xmatrix_offset
Stores the offsets of active functions for all levels.
Definition: gsHTensorBasis.h:411
virtual short_t dim() const
Returns the dimension of the parameter space.
Definition: gsHTensorBasis.h:431
gsBasis< T >::domainIter makeDomainIterator() const
Create a domain iterator for the computational mesh of this basis, that points to the first element o...
Definition: gsHTensorBasis.h:910
virtual void anchor_into(index_t i, gsMatrix< T > &result) const
Returns the anchor point for member i of the basis.
Definition: gsHTensorBasis.h:479
hdomain_type m_tree
The tree structure of the index space.
Definition: gsHTensorBasis.h:380
int numKnots(int lvl, int k) const
Returns the number of knots in direction k of level lvl.
Definition: gsHTensorBasis.h:442
index_t levelOf(index_t i) const
Returns the level of the function indexed i (in continued indices)
Definition: gsHTensorBasis.h:817
unsigned maxLevel() const
Returns the level in which the indices are stored internally.
Definition: gsHTensorBasis.h:811
tensorBasis & tensorLevel(index_t i) const
Returns the tensor basis member of level i.
Definition: gsHTensorBasis.h:668
An std::vector with sorting capabilities.
void printBases(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition: gsHTensorBasis.h:542
#define GISMO_ERROR(message)
Definition: gsDebug.h:118
Struct of for an Axis-aligned bounding box.
Definition: gsAABB.h:30
Class for representing a knot vector.
Definition: gsKnotVector.h:79
Creates a mapped object or data pointer to a const vector without copying data.
Definition: gsLinearAlgebra.h:130
Struct which represents an interface between two patches.
Definition: gsBoundary.h:649
Provides declaration of iterator on boundary of hierarchical basis.
std::vector< std::vector< std::vector< index_t > > > m_uIndices
Store the indices of the element boundaries for each level (only if m_manualLevels==true) ...
Definition: gsHTensorBasis.h:389
virtual short_t degree(short_t i) const
If the basis is a tensor product of (piecewise) polynomial bases, then this function returns the poly...
Definition: gsHTensorBasis.h:767
Struct which represents a certain corner of a hyper-cube.
Definition: gsBoundary.h:291
A basis represents a family of scalar basis functions defined over a common parameter domain...
Definition: gsBasis.h:78
gsHTensorBasis(gsTensorBSplineBasis< d, T > const &tbasis, gsMatrix< T > const &boxes)
gsHTensorBasis
Definition: gsHTensorBasis.h:205
int numBreaks(int lvl, int k) const
Definition: gsHTensorBasis.h:436
memory::shared_ptr< gsHTensorBasis > Ptr
Shared pointer for gsHTensorBasis.
Definition: gsHTensorBasis.h:78
Provides declaration of TensorBSplineBasis abstract interface.
void printSpaces(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition: gsHTensorBasis.h:517