G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsHTensorBasis.h
Go to the documentation of this file.
1
14#pragma once
15
16#include <gsCore/gsBasis.h>
17
21
22#include <gsCore/gsBoundary.h>
23
25#include <gsNurbs/gsBSplineBasis.h> // for gsBasis::component(short_t)
26
28
29namespace gismo
30{
31
32struct lvl_coef
33{
34 int pos; // flat index at grid of level \a lvl
35 int unsigned lvl; // level
36 real_t coef; // value of the coefficient (lvl,pos)
37};
38
73template<short_t d, class T>
74class GISMO_DEFAULT_VIS gsHTensorBasis: public gsBasis<T>
75{
76public:
78 typedef memory::shared_ptr< gsHTensorBasis > Ptr;
79
81 typedef memory::unique_ptr< gsHTensorBasis > uPtr;
82
84
85 typedef T Scalar_t;
86
87 typedef gsHDomain<d> hdomain_type;
88
89 typedef typename hdomain_type::point point;
90
91 typedef typename hdomain_type::box box;
92
93 typedef std::vector< box > boxHistory;
94
95 typedef gsSortedVector< index_t > CMatrix; // charMatrix_
96
97 typedef typename CMatrix::const_iterator cmatIterator;
98
99 typedef gsKnotVector<T> KnotVectorType;
100
101 typedef typename gsBSplineTraits<static_cast<short_t>(d-1),T>::Basis BoundaryBasisType;
102
104
106 static const short_t Dim = d;
107
108 friend class gsHDomainIterator<T,d>;
109 friend class gsHDomainBoundaryIterator<T,d>;
110public:
111
114 :
115 m_manualLevels(false)
116 {
117 initialize_class(tensorBasis());
118 update_structure();
119 }
120
121 gsHTensorBasis( gsBasis<T> const& tbasis, bool manualLevels)
122 :
123 m_manualLevels(manualLevels)
124 {
125 if (!m_manualLevels)
126 {
127 initialize_class(tbasis);
128 // Build the characteristic matrices
129 }
130 else
131 {
132 // Degrees
133 m_deg.resize(d);
134 for( index_t i = 0; i < d; i++)
135 m_deg[i] = tbasis.degree(i);
136
137 // Construct the initial basis
138 m_bases.reserve(3);
139 if ( const tensorBasis * tb2 = dynamic_cast<const tensorBasis*>(&tbasis) )
140 {
141 m_bases.push_back(tb2->clone().release());
142 // For the tbasis, count the unique knot values
143 std::vector<std::vector<index_t>> lvlIndices(d);
144 std::vector<index_t> dirIndices;
145 for (short_t dim=0; dim!=d; dim++)
146 {
147 dirIndices.resize(tb2->knots(dim).uSize());
148 std::iota(dirIndices.begin(),dirIndices.end(),0);
149 lvlIndices[dim] = dirIndices;
150 }
151 m_uIndices.push_back(lvlIndices);
152 }
153 else
154 {
155 GISMO_ERROR("Cannot construct a Hierarchical basis from "<< tbasis );
156 }
157
158 // Initialize the binary tree
159 point upp;
160 for ( index_t i = 0; i!=d; ++i )
161 upp[i] = m_bases[0]->knots(i).numElements();
162
163 m_tree.init(upp);
164 }
165 update_structure();
166 }
167
168 gsHTensorBasis( gsTensorBSplineBasis<d,T> const& tbasis,
169 const std::vector<index_t> & boxes)
170 :
171 m_manualLevels(false)
172 {
173 initialize_class(tbasis);
174 point i1;
175 point i2;
176 //i1.resize(d);
177 //i2.resize(d);
178 // Set all functions to active
179 GISMO_ASSERT( (boxes.size()%(2*d+1))==0,
180 "The points did not define boxes properly. The basis was created without any domain structure.");
181
182 for( size_t i = 0; i < (boxes.size()/(2*d+1)); i++)
183 {
184 for( short_t j = 0; j < d; j++)
185 {
186 i1[j] = boxes[(2*d+1)*i+j+1];
187 i2[j] = boxes[(2*d+1)*i+j+d+1];
188 }
189 insert_box(i1,i2,boxes[i*(2*d+1)]);
190 }
191
192 // Build the characteristic matrices (note: call is non-vritual)
193 update_structure();
194 }
195
206 gsMatrix<T> const & boxes)
207 :
208 m_manualLevels(false)
209 {
210 //assert(boxes.rows() == 2); //can accept only 2D coordinates- Delete during the generalization of the lac to nD
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);
214
215 point k1;
216 point k2;
217
218 for(index_t i = 0; i < boxes.cols()/2; i++)
219 {
220 for(short_t j = 0; j < d; j++)
221 {
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;
224 }
225 int level = m_tree.query3(k1,k2,m_bases.size()-1);
226 for(short_t j = 0; j < d; j++)
227 {
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;
230 }
231
232 insert_box(k1,k2,level+1);
233
234 // Build the characteristic matrices (note: call is non-vritual)
235 update_structure();
236
237 }
238 }
239
248 gsMatrix<T> const & boxes,
249 const std::vector<index_t> & levels)
250 :
251 m_manualLevels(false)
252 {
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.");
256
257 initialize_class(tbasis);
258
261
262 const size_t mLevel = *std::max_element(levels.begin(), levels.end() );
263 needLevel( mLevel );
264
265 for(index_t i = 0; i < boxes.cols()/2; i++)
266 {
267 for(short_t j = 0; j < d; j++)
268 {
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;
271 }
272
273 /* m_boxHistory.push_back( box(k1,k2,levels[i]) ); */
274 this->m_tree.insertBox(k1,k2, levels[i]);
275
276 // Build the characteristic matrices (note: call is non-vritual)
277 update_structure();
278 }
279 }
280
283 {
284 this->operator=(o);
285 }
286
287 gsHTensorBasis& operator=(const gsHTensorBasis & o)
288 {
289 if ( this != &o )
290 {
291 m_xmatrix_offset = o.m_xmatrix_offset;
292 m_deg = o.m_deg;
293 m_tree = o.m_tree;
294 m_xmatrix = o.m_xmatrix;
295 m_manualLevels = o.m_manualLevels;
296 m_uIndices = o.m_uIndices;
297
298 freeAll( m_bases );
299 m_bases.resize( o.m_bases.size() );
300 cloneAll(o.m_bases.begin(), o.m_bases.end(), m_bases.begin());
301 }
302 return *this;
303 }
304
305#if EIGEN_HAS_RVALUE_REFERENCES
306 gsHTensorBasis(gsHTensorBasis&& other)
307 {
308 this->operator=(other);
309 }
310
311 gsHTensorBasis & operator=(gsHTensorBasis&& other)
312 {
313 m_deg = std::move(other.m_deg);
314 freeAll( m_bases );
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);
321 return *this;
322 }
323#endif
324
327 {
328 freeAll( m_bases );
329 }
330
332 bool manualLevels() const { return m_manualLevels; }
333
335 index_t numLevels() const { return m_bases.size(); }
336
338 void addLevel( const gsTensorBSplineBasis<d, T>& next_basis);
339
341 void only_insert_box(point const & k1, point const & k2, int lvl);
342
343protected:
344
345 // TO DO: remove these members after they are not used anymore
346 std::vector<int> m_deg;
347
348protected:
349
361 mutable std::vector<tensorBasis*> m_bases;
362
377 std::vector< CMatrix > m_xmatrix;
378
380 hdomain_type m_tree;
381
382 // // Stores the coordinates of all inserted boxes
383 // (for debugging purposes)
384 // boxHistory m_boxHistory;
385
386 bool m_manualLevels;
387
389 std::vector<std::vector<std::vector<index_t>>> m_uIndices;
390
391
392
393public:
394 // Needed since m_tree is 16B aligned
395# define Eigen gsEigen
396 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
397# undef Eigen
398 protected:
399
411 std::vector<index_t> m_xmatrix_offset;
412
413 //------------------------------------
414
415public:
416
417 const std::vector< CMatrix >& getXmatrix() const
418 {
419 return m_xmatrix;
420 }
421
425 const std::vector<tensorBasis*>& getBases() const
426 {
427 return m_bases;
428 }
429
431 virtual short_t dim() const
432 { return d; }
433
436 int numBreaks(int lvl, int k) const
437 {
438 return m_tree.numBreaks(lvl,k);
439 }
440
442 int numKnots(int lvl, int k) const
443 {
444 needLevel(lvl);
445
446 return m_bases[lvl]->knots(k).size();
447 }
448
450 T knot(int lvl, int k, int i) const
451 {
452 needLevel(lvl);
453
454 return m_bases[lvl]->component(k).knot(i);
455 //return m_bases[lvl]->knot(k,i);
456 }
457
460 virtual void anchors_into(gsMatrix<T> & result) const
461 {
462 result.resize( d, this->size()) ;
463 unsigned k(0);
464
466 for(size_t i = 0; i < m_xmatrix.size(); i++)
467 {
468 for( CMatrix::const_iterator it =
469 m_xmatrix[i].begin(); it != m_xmatrix[i].end(); it++)
470 {
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] );
474 k++;
475 }
476 }
477 }
478
479 virtual void anchor_into(index_t i, gsMatrix<T> & result) const
480 {
481 index_t lvl = levelOf(i);
482 index_t ind = flatTensorIndexOf(i);
483
484 m_bases[lvl]->anchor_into(ind,result);
485 }
486
487 virtual void connectivity(const gsMatrix<T> & nodes, gsMesh<T> & mesh) const;
488 void connectivity(const gsMatrix<T> & nodes, int level, gsMesh<T> & mesh) const;
489
490 // Prints the characteristic matrices (ie. the indices of all basis
491 // functions in the basis)
492 void printCharMatrix(std::ostream &os = gsInfo) const
493 {
494 os<<"Characteristic matrix:\n";
495 for(size_t i = 0; i!= m_xmatrix.size(); i++)
496 {
497 if ( m_xmatrix[i].size() )
498 {
499 os<<"- level="<<i<<
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++)
504 {
505 os << ", ("<< m_bases[i]->tensorIndex(*it).transpose() <<")";
506 }
507 os <<"\n";
508 }
509 else
510 {
511 os<<"- level="<<i<<" is empty.\n";
512 }
513 }
514 }
515
517 void printSpaces(std::ostream &os = gsInfo) const
518 {
519 os<<"Spline-space hierarchy:\n";
520 for(size_t i = 0; i!= m_xmatrix.size(); i++)
521 {
522 if ( m_xmatrix[i].size() )
523 {
524 os<<"- level="<<i<<
525 ", size="<<m_xmatrix[i].size() << ":\n";
526 os << "Space: "<< * m_bases[i] <<")\n";
527 if (m_manualLevels)
528 {
529 os << "Indices:\n";
530 for (size_t dim=0; dim!=d; dim++)
531 os << "Dir "<<dim<<": "<<gsAsConstVector<index_t>(m_uIndices[i][dim]).transpose()<<"\n";
532 }
533 }
534 else
535 {
536 os<<"- level="<<i<<" is empty.\n";
537 }
538 }
539 }
540
542 void printBases(std::ostream &os = gsInfo) const
543 {
544 os<<"Spline-space hierarchy:\n";
545 for(unsigned i = 0; i< m_bases.size(); i++)
546 {
547 os<<"- level="<<i<<
548 ", size="<<m_bases[i]->size() << ":\n";
549 os << "Space: "<< * m_bases[i] <<")\n";
550 if (m_manualLevels)
551 {
552 os << "Indices:\n";
553 for (size_t dim=0; dim!=d; dim++)
554 os << "Dir "<<dim<<": "<<gsAsConstVector<index_t>(m_uIndices[i][dim]).transpose()<<"\n";
555 }
556 }
557 }
558
560 void printBasic(std::ostream &os = gsInfo) const
561 {
562 os << "basis of dimension " <<this->dim()<<
563 ",\nlevels="<< this->m_tree.getMaxInsLevel()+1 <<", size="
564 << this->size()<<", tree_nodes="<< this->m_tree.size()
565 // << ", leaf_nodes="<< this->m_tree.leafSize();
566 //const std::pair<int,int> paths = this->m_tree.minMaxPath();
567 //os << ", path lengths=("<<paths.first<<", "<<paths.second
568 << ").\n";
569 const gsMatrix<T> supp = this->support();
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()<< " ";
575 os<<"\n";
576 }
577
578 // Look at gsBasis.h for the documentation of this function
579 virtual void active_into(const gsMatrix<T> & u, gsMatrix<index_t>& result) const;
580
581
582 // Look at gsBasis.h for the documentation of this function
583 gsMatrix<index_t> allBoundary( ) const;
584
585 // Look at gsBasis.h for the documentation of this function
586 virtual gsMatrix<index_t> boundaryOffset(boxSide const & s, index_t offset ) const;
587
588 virtual gsMatrix<index_t> boundaryOffsetLevel(boxSide const & s, index_t offset , index_t level) const;
589
590 virtual index_t levelAtCorner(boxCorner const & c) const;
591
592 virtual index_t functionAtCorner(boxCorner const & c) const;
593 virtual index_t functionAtCorner(boxCorner const & c, index_t level) const;//..
594
595
596 // Look at gsBasis.h for the documentation of this function
597 //void evalAllDers_into(const gsMatrix<T> & u, int n,
598 // std::vector<gsMatrix<T> >& result, bool sameElement) const;
599
601 const gsHDomain<d> & tree() const { return m_tree; }
602
604 gsHDomain<d> & tree() { return m_tree; }
605
607 void makeCompressed();
608
609
611 // GISMO_UPTR_FUNCTION_DEC(gsHTensorBasis<d,T>, boundaryBasis, boxSide const &)
612
614 gsMatrix<T> support() const;
615
616 gsMatrix<T> support(const index_t & i) const;
617
618 void elementSupport_into(const index_t i, gsMatrix<index_t, d, 2>& result) const
619 {
620 index_t lvl = levelOf(i);
621 m_bases[lvl]->elementSupport_into(m_xmatrix[lvl][ i - m_xmatrix_offset[lvl] ],
622 result);
623 }
624
626 {
627 index_t lvl = levelOf(j);
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) //get intersection
632 {
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]);
635 }
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);
639 }
640
641 GISMO_UPTR_FUNCTION_PURE(gsHTensorBasis, clone)
642
643
644 index_t size() const;
645
647 int treeSize() const
648 {
649 return m_tree.size();
650 }
651
653 void numActive_into(const gsMatrix<T> & u, gsVector<index_t>& result) const;
654
657 {
658 return m_bases[ this->maxLevel() ]->component(i);
659 }
660
662 virtual const gsBSplineBasis<T> & component(short_t i) const
663 {
664 return m_bases[ this->maxLevel() ]->component(i);
665 }
666
669 {
670 needLevel( i );
671 return *this->m_bases[i];
672 }
673
674 // Refine the basis uniformly by inserting \a numKnots new knots on each knot span
675 virtual void uniformRefine(int numKnots = 1, int mul=1, int dir=-1);
676
677 // Refine the basis uniformly and adjust the given matrix of coefficients accordingly
678 //virtual void uniformRefine_withCoefs(gsMatrix<T>& coefs, int numKnots = 1, int mul = 1)
679
680 // Refine the basis uniformly and produce a sparse matrix which
681 // maps coarse coefficient vectors to refined ones
682 //virtual void uniformRefine_withTransfer(gsSparseMatrix<T,RowMajor> & transfer, int numKnots = 1, int mul = 1)
683
684 // Refine the basis uniformly and adjust the given matrix of coefficients accordingly
685 void uniformRefine_withCoefs(gsMatrix<T>& coefs, int numKnots = 1, int mul = 1, short_t const dir = -1);
686
687 // Refine the basis and adjust the given matrix of coefficients accordingly
688 void refine_withCoefs(gsMatrix<T> & coefs, gsMatrix<T> const & boxes);
689 // void unrefine_withCoefs(gsMatrix<T> & coefs, gsMatrix<T> const & boxes);
690
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);
700
701 void refineElements_withCoefs2(gsMatrix<T> & coefs,std::vector<index_t> const & boxes);
702
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);
705
706 // Coarsens the basis uniformly by removing \a numKnots knots on each knot span
707 virtual void uniformCoarsen(int numKnots = 1);
708
709 // Coarsen the basis uniformly and adjust the given matrix of coefficients accordingly
710 void uniformCoarsen_withCoefs(gsMatrix<T>& coefs, int numKnots = 1);
711
712 // see gsBasis for documentation
713 void matchWith(const boundaryInterface & bi, const gsBasis<T> & other,
714 gsMatrix<index_t> & bndThis, gsMatrix<index_t> & bndOther) const;
715
716 // see gsBasis for documentation
717 void matchWith(const boundaryInterface & bi, const gsBasis<T> & other,
718 gsMatrix<index_t> & bndThis, gsMatrix<index_t> & bndOther, index_t offset) const;
719
721 {
722 short_t td = m_bases[0]->degree(0);
723 // take maximum of coordinate bases degrees
724 for (short_t k=1; k!=d; ++k)
725 td = math::max(td, m_bases[0]->degree(k));
726 return td;
727 }
728
730 {
731 short_t td = m_bases[0]->degree(0);
732 // take maximum of coordinate bases degrees
733 for (short_t k=1; k!=d; ++k)
734 td = math::min(td, m_bases[0]->degree(k));
735 return td;
736 }
737
739 void reduceContinuity(int const & i = 1)
740 {
741 for (unsigned int lvl = 0; lvl <= maxLevel(); lvl++)
742 {
743 for (unsigned int dir = 0; dir < d; dir++)
744 {
745 // TODO check: max interior mult + i <= m_p+1
746
747 // We iterate through unique knots, skipping the first and last knot
748 // At level 0 we iterate through all unique knots,
749 // At level >0 we iterate through all knots that are new, i.e. every other knot starting from 1
750 for (typename gsKnotVector<T>::uiterator it =
751 m_bases[lvl]->knots(dir).ubegin() + 1;
752 it < m_bases[lvl]->knots(dir).uend() - 1;
753 it += (lvl == 0? 1 : 2))
754 {
755 for(unsigned int j =lvl;j < m_bases.size();j++)
756 m_bases[j]->component(dir).insertKnot(*it,i);
757
758 }
759 }
760 }
761 update_structure();
762 }
763
767 virtual inline short_t degree(short_t i) const
768 { return m_bases[0]->degree(i);}
769
770
771
772 // S.K.
781 index_t getLevelAtPoint(const gsMatrix<T> & Pt ) const;
782
783 // S.K.
792 index_t getLevelAtIndex(const point & Pt ) const;
793
794 // S.K.
806 void getLevelUniqueSpanAtPoints(const gsMatrix<T> & Pt,
807 gsVector<index_t> & lvl,
808 gsMatrix<index_t> & loIdx ) const;
809
811 unsigned maxLevel() const
812 {
813 return m_tree.getMaxInsLevel();
814 }
815
817 inline index_t levelOf(index_t i) const
818 {
819 return std::upper_bound(m_xmatrix_offset.begin(),
820 m_xmatrix_offset.end(), i)
821 - m_xmatrix_offset.begin() - 1;
822 }
823
824/*
825 const boxHistory & get_inserted_boxes() const
826 {
827 return m_boxHistory;
828 }
829*/
830
831 void degreeElevate(int const & i = 1, int const dir = -1);
832 void degreeReduce(int const & i = 1, int const dir = -1);
833
834 void degreeIncrease(int const & i= 1, int const dir = -1);
835 void degreeDecrease(int const & i = 1, int const dir = -1);
836
848 virtual void refine(gsMatrix<T> const & boxes, int refExt);
849 virtual void unrefine(gsMatrix<T> const & boxes, int refExt);
850
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;
853
854 // std::vector<index_t> asElements(gsMatrix<T> const & boxes, int refExt = 0) const;
855
863 virtual void refine(gsMatrix<T> const & boxes);
864 // virtual void unrefine(gsMatrix<T> const & boxes);
865
891 virtual void refineElements(std::vector<index_t> const & boxes);
892
899 virtual void unrefineElements(std::vector<index_t> const & boxes);
900
902 void refineSide(const boxSide side, index_t lvl);
903
905 void refineBasisFunction(const index_t i);
906
907 // Look at gsBasis.h for the documentation of this function
908 //virtual void uniformRefine(int numKnots = 1);
909
910 typename gsBasis<T>::domainIter makeDomainIterator() const
911 {
912 return typename gsBasis<T>::domainIter(new gsHDomainIterator<T, d>(*this));
913 }
914
915 typename gsBasis<T>::domainIter makeDomainIterator(const boxSide & s) const
916 {
917 return ( s == boundary::none ?
918 typename gsBasis<T>::domainIter(new gsHDomainIterator<T, d>(*this)) :
919 typename gsBasis<T>::domainIter(new gsHDomainBoundaryIterator<T, d>(*this,s) )
920 );
921 }
922
931 inline
933 {
934 return flatTensorIndexOf(i, this->levelOf(i) );
935 }
936
946 inline
947 index_t flatTensorIndexOf(const index_t i, const index_t level) const
948 {
949 const index_t offset = this->m_xmatrix_offset[level];
950 const index_t ind_in_level = this->m_xmatrix[level][i - offset];
951 return ind_in_level;
952 }
953
961 std::vector< std::vector< std::vector<index_t > > > domainBoundariesParams( std::vector< std::vector< std::vector< std::vector< T > > > >& result) const;
962
970 std::vector< std::vector< std::vector<index_t > > > domainBoundariesIndices( std::vector< std::vector< std::vector< std::vector<index_t > > > >& result) const;
971 // TO DO: use gsHDomainLeafIterator for a better implementation
972 size_t numElements(boxSide const & s = 0) const
973 {
974 typename gsBasis<T>::domainIter domIter =
975 s == boundary::none ?
976 typename gsBasis<T>::domainIter(new gsHDomainIterator<T, d>(*this)) :
977 typename gsBasis<T>::domainIter(new gsHDomainBoundaryIterator<T, d>(*this,s) );
978
979 size_t numEl = 0;
980 for (; domIter->good(); domIter->next())
981 {
982 numEl++;
983 }
984
985 return numEl;
986 }
987
994 void flatTensorIndexesToHierachicalIndexes(gsSortedVector< int > & indexes,const int level) const;
995
1003 int flatTensorIndexToHierachicalIndex(index_t index,const int level) const;
1004
1012 void activeBoundaryFunctionsOfLevel(const unsigned level,const boxSide & s,std::vector<bool>& actives) const;
1013
1022
1023 virtual void increaseMultiplicity(index_t lvl, int dir, T knotValue, int mult = 1);
1024
1033 virtual void increaseMultiplicity(index_t lvl, int dir, const std::vector<T> & knotValue, int mult = 1);
1034
1035protected:
1036
1039 virtual void update_structure(); // to do: rename as updateCharMatrices
1040
1043 void needLevel(int maxLevel) const;
1044
1046 void createMoreLevels(int numLevels) const;
1047
1051 void getBoxesAlongSlice( int dir, T par,std::vector<index_t>& boxes ) const;
1052
1053protected:
1054
1062 void _knotIndexToDiadicIndex(const index_t level, const index_t dir, index_t & knotIndex) const;
1063 void _knotIndexToDiadicIndex(const index_t level, gsVector<index_t,d> & diadicIndex) const;
1064
1071 void _diadicIndexToKnotIndex(const index_t level, gsVector<index_t,d> & diadicIndex) const;
1072 void _diadicIndexToKnotIndex(const index_t level, const index_t dir, index_t & diadicIndex) const;
1073
1074private:
1075
1077 void insert_box(point const & k1, point const & k2, int lvl);
1078
1079 void initialize_class(gsBasis<T> const& tbasis);
1080
1083 void functionOverlap(const point & boxLow, const point & boxUpp,
1084 const int level, point & actLow, point & actUpp);
1085
1086 // \brief Sets all functions of \a level to active or passive- one by one
1087 void set_activ1(int level);
1088
1089 // \brief Computes the set of active basis functions in the basis
1090 void setActive();
1091
1092 // \brief Computes the connectivity for a level on a mesh that has all vertices
1093 void addConnectivity(int level, gsMesh<T> & mesh) const;
1094
1096 virtual gsSparseMatrix<T> coarsening(const std::vector<CMatrix>& old,
1097 const std::vector<CMatrix>& n,
1098 const gsSparseMatrix<T,RowMajor> & transfer) const = 0;
1099
1100 virtual gsSparseMatrix<T> coarsening_direct(const std::vector<gsSortedVector<index_t> >& old,
1101 const std::vector<gsSortedVector<index_t> >& n,
1102 const std::vector<gsSparseMatrix<T,RowMajor> >& transfer) const = 0;
1103
1104 virtual gsSparseMatrix<T> coarsening_direct2(const std::vector<gsSortedVector<index_t> >& old,
1105 const std::vector<gsSortedVector<index_t> >& n,
1106 const std::vector<gsSparseMatrix<T,RowMajor> >& transfer) const = 0;
1107
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;
1113
1114public:
1117 void transfer (const std::vector<gsSortedVector<index_t> > &old, gsSparseMatrix<T>& result);
1118
1119 void transfer2 (const std::vector<gsSortedVector<index_t> > &old, gsSparseMatrix<T>& result);
1120
1123 void setActiveToLvl(int level, std::vector<CMatrix>& x_matrix_lvl) const;
1124
1125public:
1133 bool testPartitionOfUnity(const index_t npts = 100, const T tol = 1e-12) const;
1134
1135// void local2globalIndex( gsVector<index_t,d> const & index,
1136// index_t lvl,
1137// gsVector<index_t,d> & result
1138// ) const;
1139
1140// void global2localIndex( gsVector<index_t,d> const & index,
1141// index_t lvl,
1142// gsVector<index_t,d> & result
1143// ) const;
1144
1145}; // class gsHTensorBasis
1146
1147// Next line disallows instantization of gsTensorBasis<0,T>
1148template<typename T> class gsHTensorBasis<0,T>
1149{using T::GISMO_ERROR_gsHTensorBasis_cannot_have_dimension_zero;};
1150
1151
1152#ifdef GISMO_WITH_PYBIND11
1153
1157 void pybind11_init_gsHTensorBasis2(pybind11::module &m);
1158 void pybind11_init_gsHTensorBasis3(pybind11::module &m);
1159 void pybind11_init_gsHTensorBasis4(pybind11::module &m);
1160
1161#endif // GISMO_WITH_PYBIND11
1162
1163
1164} // namespace gismo
1165
1166// ************************************************
1167// ************************************************
1168
1169#ifndef GISMO_BUILD_LIB
1170#include GISMO_HPP_HEADER(gsHTensorBasis.hpp)
1171#endif
Struct which represents a certain side of a box.
Definition gsBoundary.h:85
Creates a mapped object or data pointer to a const vector without copying data.
Definition gsAsMatrix.h:285
A univariate B-spline basis.
Definition gsBSplineBasis.h:700
A basis represents a family of scalar basis functions defined over a common parameter domain.
Definition gsBasis.h:79
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:699
Re-implements gsDomainIterator for iteration over all boundary elements of a hierarchical parameter d...
Definition gsHDomainBoundaryIterator.h:41
Re-implements gsDomainIterator for iteration over all boundary elements of a hierarchical parameter d...
Definition gsHDomainIterator.h:39
Class with a hierarchical domain structure represented by a box k-d-tree.
Definition gsHDomain.h:76
Class representing a (scalar) hierarchical tensor basis of functions .
Definition gsHTensorBasis.h:75
index_t flatTensorIndexOf(const index_t i) const
Returns the tensor index of the function indexed i (in continued indices).
Definition gsHTensorBasis.h:932
int numBreaks(int lvl, int k) const
Definition gsHTensorBasis.h:436
memory::unique_ptr< gsHTensorBasis > uPtr
Unique pointer for gsHTensorBasis.
Definition gsHTensorBasis.h:81
T knot(int lvl, int k, int i) const
Returns the i-th knot in direction k at level lvl.
Definition gsHTensorBasis.h:450
const gsHDomain< d > & tree() const
Returns a reference to m_tree.
Definition gsHTensorBasis.h:601
int treeSize() const
The number of nodes in the tree representation.
Definition gsHTensorBasis.h:647
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
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
index_t numLevels() const
Returns the number of levels.
Definition gsHTensorBasis.h:335
void reduceContinuity(int const &i=1)
Reduces spline continuity at interior knots by i.
Definition gsHTensorBasis.h:739
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
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
std::vector< index_t > m_xmatrix_offset
Stores the offsets of active functions for all levels.
Definition gsHTensorBasis.h:411
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::shared_ptr< gsHTensorBasis > Ptr
Shared pointer for gsHTensorBasis.
Definition gsHTensorBasis.h:78
void printBases(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition gsHTensorBasis.h:542
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
std::vector< tensorBasis * > m_bases
The list of nested spaces.
Definition gsHTensorBasis.h:361
virtual short_t dim() const
Returns the dimension of the parameter space.
Definition gsHTensorBasis.h:431
void createMoreLevels(int numLevels) const
Creates numLevels extra grids in the hierarchy.
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
gsHTensorBasis(gsTensorBSplineBasis< d, T > const &tbasis, gsMatrix< T > const &boxes, const std::vector< index_t > &levels)
gsHTensorBasis
Definition gsHTensorBasis.h:247
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
unsigned maxLevel() const
Returns the level in which the indices are stored internally.
Definition gsHTensorBasis.h:811
int numKnots(int lvl, int k) const
Returns the number of knots in direction k of level lvl.
Definition gsHTensorBasis.h:442
std::vector< CMatrix > m_xmatrix
The characteristic matrices for each level.
Definition gsHTensorBasis.h:377
void only_insert_box(point const &k1, point const &k2, int lvl)
Inserts a domain into the basis.
index_t levelOf(index_t i) const
Returns the level of the function indexed i (in continued indices)
Definition gsHTensorBasis.h:817
const std::vector< tensorBasis * > & getBases() const
Returns the tensor B-spline space of all levels.
Definition gsHTensorBasis.h:425
virtual ~gsHTensorBasis()
Destructor.
Definition gsHTensorBasis.h:326
void printBasic(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition gsHTensorBasis.h:560
gsHDomain< d > & tree()
Returns a reference to m_tree.
Definition gsHTensorBasis.h:604
gsHTensorBasis()
Default empty constructor.
Definition gsHTensorBasis.h:113
gsHTensorBasis(const gsHTensorBasis &o)
Copy constructor.
Definition gsHTensorBasis.h:282
tensorBasis & tensorLevel(index_t i) const
Returns the tensor basis member of level i.
Definition gsHTensorBasis.h:668
void printSpaces(std::ostream &os=gsInfo) const
Prints the spline-space hierarchy.
Definition gsHTensorBasis.h:517
virtual void anchors_into(gsMatrix< T > &result) const
Definition gsHTensorBasis.h:460
bool manualLevels() const
Returns true if levels are assigned manually.
Definition gsHTensorBasis.h:332
size_t numElements(boxSide const &s=0) const
The number of elements on side s.
Definition gsHTensorBasis.h:972
gsHTensorBasis(gsTensorBSplineBasis< d, T > const &tbasis, gsMatrix< T > const &boxes)
gsHTensorBasis
Definition gsHTensorBasis.h:205
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
gsMatrix< T > elementInSupportOf(index_t j) const
Returns (the coordinates of) an element in the support of basis function j.
Definition gsHTensorBasis.h:625
virtual gsSparseMatrix< T > coarsening(const std::vector< CMatrix > &old, const std::vector< CMatrix > &n, const gsSparseMatrix< T, RowMajor > &transfer) const =0
returns a transfer matrix using the characteristic matrix of the old and new basis
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
hdomain_type m_tree
The tree structure of the index space.
Definition gsHTensorBasis.h:380
Class for representing a knot vector.
Definition gsKnotVector.h:80
internal::gsUKnotIterator< T > uiterator
Definition gsKnotVector.h:102
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
Class Representing a triangle mesh with 3D vertices.
Definition gsMesh.h:32
This class is derived from std::vector, and adds sort tracking.
Definition gsSortedVector.h:110
Sparse matrix class, based on gsEigen::SparseMatrix.
Definition gsSparseMatrix.h:139
A tensor product B-spline basis.
Definition gsTensorBSplineBasis.h:37
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
Provides declaration of BSplineBasis class.
Provides declaration of Basis abstract interface.
Provides structs and classes related to interfaces and boundaries.
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
#define GISMO_ERROR(message)
Definition gsDebug.h:118
#define gsInfo
Definition gsDebug.h:43
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
Provides declaration of iterator on boundary of hierarchical basis.
Provides declaration of iterator of hierarchical domain.
Provides declaration of the HDomain class.
An std::vector with sorting capabilities.
Provides declaration of TensorBSplineBasis abstract interface.
The G+Smo namespace, containing all definitions for the library.
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
void freeAll(It begin, It end)
Frees all pointers in the range [begin end)
Definition gsMemory.h:312
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
Traits for BSplineBasis in more dimensions.
Definition gsBSplineBasis.h:32