G+Smo  24.08.0
Geometry + Simulation Modules
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
gsHDomainIterator.h
Go to the documentation of this file.
1 
14 #pragma once
15 
16 #include <gsHSplines/gsHDomain.h>
17 #include <gsHSplines/gsKdNode.h>
19 
21 
22 namespace gismo
23 {
24 
25 // Documentation in gsDomainIterator
37 template<typename T, unsigned d>
38 class gsHDomainIterator: public gsDomainIterator<T>
39 {
40 public:
41 
42  typedef gsKdNode<d, index_t> node;
43 
44  typedef typename node::point point;
45 
46  typedef typename std::vector<T>::const_iterator uiter;
47 
48  typedef gsHDomain<d,index_t> hDomain;
49 
50  typedef typename hDomain::const_literator leafIterator;
51 
52 public:
53 
54  gsHDomainIterator(const gsHTensorBasis<d, T> & hbs)
55  : gsDomainIterator<T>(hbs)
56  {
57  // Initialize mesh data
58  m_meshStart.resize(d);
59  m_meshEnd .resize(d);
60 
61  // Initialize cell data
62  m_curElement.resize(d);
63  m_lower .resize(d);
64  m_upper .resize(d);
65 
66  // Allocate breaks
67  m_breaks = std::vector<std::vector<T> >(d, std::vector<T>());
68 
69  m_leaf = hbs.tree().beginLeafIterator();
70  updateLeaf();
71  updateElement();
72  }
73 
74  // ---> Documentation in gsDomainIterator.h
75  bool next()
76  {
77  this->m_isGood = nextLexicographic(m_curElement, m_meshStart, m_meshEnd);
78 
79  if (this->m_isGood) // new element in m_leaf
80  updateElement();
81  else // went through all elements in m_leaf
82  {
83  this->m_isGood = nextLeaf();
84  if (this->m_isGood)
85  updateElement();
86  }
87 
88  ++m_id; //increment id
89  return this->m_isGood;
90  }
91 
92  // ---> Documentation in gsDomainIterator.h
93  bool next(index_t increment)
94  {
95  for (index_t i = 0; i != increment && this->m_isGood; ++i)
96  {
97  this->m_isGood = nextLexicographic(m_curElement, m_meshStart, m_meshEnd);
98  if (!this->m_isGood)
99  this->m_isGood = nextLeaf();
100  }
101 
102  if (this->m_isGood)
103  updateElement();
104 
105  m_id += increment; //increment id
106  return this->m_isGood;
107  }
108 
111  void reset()
112  {
113  m_id = 0;
114  const gsHTensorBasis<d, T>* hbs = dynamic_cast<const gsHTensorBasis<d, T> *>(m_basis);
115  m_leaf = hbs->tree().beginLeafIterator();
116  updateLeaf();
117  updateElement();
118  }
119 
120  const gsVector<T>& lowerCorner() const { return m_lower; }
121 
122  const gsVector<T>& upperCorner() const { return m_upper; }
123 
124  int getLevel() const
125  {
126  return m_leaf.level();
127  }
128 
129  // Returns the element multi-index at the current level
130  // If you need the element at the level above, divide this all indices by 2
131  gsVector<index_t> elementMultiIndex() const
132  {
133  gsVector<index_t> res(d);
134  for (index_t i = 0; i!=d; ++i)
135  {
136  res[i] = std::distance(m_breaks[i].begin(), m_curElement[i]);
137  }
138  return res;
139  }
140 
141 private:
142 
143  gsHDomainIterator();
144 
146  bool nextLeaf()
147  {
148  this->m_isGood = m_leaf.next();
149 
150  if ( m_leaf.good() )
151  updateLeaf();
152 
153  return this->m_isGood;
154  }
155 
159  void updateLeaf()
160  {
161  const point & lower = m_leaf.lowerCorner();
162  const point & upper = m_leaf.upperCorner();
163  // gsDebug<<"leaf "<< lower.transpose() <<", "
164  // << upper.transpose() <<"\n";
165 
166  const int level2 = m_leaf.level();
167 
168  // Update leaf box
169  for (unsigned dim = 0; dim < d; ++dim)
170  {
171  index_t start = lower(dim);
172  index_t end = upper(dim) ;
173 
174  if (basis().manualLevels() )
175  {
176  static_cast<const gsHTensorBasis<d,T>*>(m_basis)->
177  _diadicIndexToKnotIndex(level2,dim,start);
178  static_cast<const gsHTensorBasis<d,T>*>(m_basis)->
179  _diadicIndexToKnotIndex(level2,dim,end);
180  }
181 
182  const gsKnotVector<T> & kv =
183  static_cast<const gsHTensorBasis<d,T>*>(m_basis)
184  ->tensorLevel(level2).component(dim).knots();
185 
186  // knotVals = kv.unique()
187 
188  m_breaks[dim].clear();
189  for (index_t index = start; index <= end; ++index)
190  m_breaks[dim].push_back( kv(index) );// unique index
191 
192  m_curElement(dim) =
193  m_meshStart(dim) = m_breaks[dim].begin();
194 
195  // for n breaks, we have n - 1 elements (spans)
196  m_meshEnd(dim) = m_breaks[dim].end() - 1;
197  }
198  }
199 
204  {
205  // Update cell data
206  for (unsigned i = 0; i < d ; ++i)
207  {
208  m_lower[i] = *m_curElement[i];
209  m_upper[i] = *(m_curElement[i]+1);
210  center[i] = (T)(0.5) * (m_lower[i] + m_upper[i]);
211  }
212  }
213 
214 // =============================================================================
215 // members
216 // =============================================================================
217 
218  const gsHTensorBasis<d,T> & basis() const { return *static_cast<const gsHTensorBasis<d,T>*>(m_basis); }
219 
220 public:
221 
222  using gsDomainIterator<T>::center;
223  using gsDomainIterator<T>::m_basis;
224 
225 # define Eigen gsEigen
226  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
227 # undef Eigen
228 
229 protected:
230  using gsDomainIterator<T>::m_id;
231 
232 private:
233 
234  // The current leaf node of the tree
235  leafIterator m_leaf;
236 
237  // Coordinates of the grid cell boundaries
238  // \todo remove this member
239  std::vector< std::vector<T> > m_breaks;
240 
241  // Extent of the tensor grid
242  gsVector<uiter, d> m_meshStart, m_meshEnd;
243 
244  // Current element as pointers to it's supporting mesh-lines
245  gsVector<uiter, d> m_curElement;
246 
247  // parameter coordinates of current grid cell
248  gsVector<T> m_lower, m_upper;
249 };
250 
251 } // end namespace gismo
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 &lt;j&gt; in the set ; by def...
bool nextLeaf()
returns true if there is a another leaf with a boundary element
Definition: gsHDomainIterator.h:146
short_t dim() const
Return dimension of the elements.
Definition: gsDomainIterator.h:115
#define index_t
Definition: gsConfig.h:32
const gsHDomain< d > & tree() const
Returns a reference to m_tree.
Definition: gsHTensorBasis.h:601
Provides declaration of the HDomain class.
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
Class representing a (scalar) hierarchical tensor basis of functions .
Definition: gsHTensorBasis.h:74
void reset()
Definition: gsHDomainIterator.h:111
bool next(index_t increment)
Proceeds to the next element (skipping increment elements).
Definition: gsHDomainIterator.h:93
Provides declaration of DomainIterator abstract interface.
bool m_isGood
Definition: gsDomainIterator.h:223
const gsVector< T > & upperCorner() const
Returns the upper corner of the current element.
Definition: gsHDomainIterator.h:122
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
const gsBasis< T > * m_basis
The basis on which the domain iterator is defined.
Definition: gsDomainIterator.h:219
gsVector< T > center
Coordinates of a central point in the element (in the parameter domain).
Definition: gsDomainIterator.h:215
Class for representing a knot vector.
Definition: gsKnotVector.h:79
void updateLeaf()
Definition: gsHDomainIterator.h:159
void updateElement()
Definition: gsHDomainIterator.h:203
Provides declaration of the tree node.
bool next()
Proceeds to the next element.
Definition: gsHDomainIterator.h:75
bool good() const
Returns true iff we are still pointing at a valid leaf.
Definition: gsHDomainLeafIter.h:81
const gsVector< T > & lowerCorner() const
Returns the lower corner of the current element.
Definition: gsHDomainIterator.h:120
Provides declaration of TensorBSplineBasis abstract interface.