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  const gsHTensorBasis<d, T>* hbs = dynamic_cast<const gsHTensorBasis<d, T> *>(m_basis);
114  m_leaf = hbs->tree().beginLeafIterator();
115  updateLeaf();
116  updateElement();
117  }
118 
119  const gsVector<T>& lowerCorner() const { return m_lower; }
120 
121  const gsVector<T>& upperCorner() const { return m_upper; }
122 
123  int getLevel() const
124  {
125  return m_leaf.level();
126  }
127 
128  // Returns the element multi-index at the current level
129  // If you need the element at the level above, divide this all indices by 2
130  gsVector<index_t> elementMultiIndex() const
131  {
132  gsVector<index_t> res(d);
133  for (index_t i = 0; i!=d; ++i)
134  {
135  res[i] = std::distance(m_breaks[i].begin(), m_curElement[i]);
136  }
137  return res;
138  }
139 
140 private:
141 
142  gsHDomainIterator();
143 
145  bool nextLeaf()
146  {
147  this->m_isGood = m_leaf.next();
148 
149  if ( m_leaf.good() )
150  updateLeaf();
151 
152  return this->m_isGood;
153  }
154 
158  void updateLeaf()
159  {
160  const point & lower = m_leaf.lowerCorner();
161  const point & upper = m_leaf.upperCorner();
162  // gsDebug<<"leaf "<< lower.transpose() <<", "
163  // << upper.transpose() <<"\n";
164 
165  const int level2 = m_leaf.level();
166 
167  // Update leaf box
168  for (unsigned dim = 0; dim < d; ++dim)
169  {
170  index_t start = lower(dim);
171  index_t end = upper(dim) ;
172 
173  if (basis().manualLevels() )
174  {
175  static_cast<const gsHTensorBasis<d,T>*>(m_basis)->
176  _diadicIndexToKnotIndex(level2,dim,start);
177  static_cast<const gsHTensorBasis<d,T>*>(m_basis)->
178  _diadicIndexToKnotIndex(level2,dim,end);
179  }
180 
181  const gsKnotVector<T> & kv =
182  static_cast<const gsHTensorBasis<d,T>*>(m_basis)
183  ->tensorLevel(level2).component(dim).knots();
184 
185  // knotVals = kv.unique()
186 
187  m_breaks[dim].clear();
188  for (index_t index = start; index <= end; ++index)
189  m_breaks[dim].push_back( kv(index) );// unique index
190 
191  m_curElement(dim) =
192  m_meshStart(dim) = m_breaks[dim].begin();
193 
194  // for n breaks, we have n - 1 elements (spans)
195  m_meshEnd(dim) = m_breaks[dim].end() - 1;
196  }
197  }
198 
203  {
204  // Update cell data
205  for (unsigned i = 0; i < d ; ++i)
206  {
207  m_lower[i] = *m_curElement[i];
208  m_upper[i] = *(m_curElement[i]+1);
209  center[i] = (T)(0.5) * (m_lower[i] + m_upper[i]);
210  }
211  }
212 
213 // =============================================================================
214 // members
215 // =============================================================================
216 
217  const gsHTensorBasis<d,T> & basis() const { return *static_cast<const gsHTensorBasis<d,T>*>(m_basis); }
218 
219 public:
220 
221  using gsDomainIterator<T>::center;
222  using gsDomainIterator<T>::m_basis;
223 
224 # define Eigen gsEigen
225  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
226 # undef Eigen
227 
228 protected:
229  using gsDomainIterator<T>::m_id;
230 
231 private:
232 
233  // The current leaf node of the tree
234  leafIterator m_leaf;
235 
236  // Coordinates of the grid cell boundaries
237  // \todo remove this member
238  std::vector< std::vector<T> > m_breaks;
239 
240  // Extent of the tensor grid
241  gsVector<uiter, d> m_meshStart, m_meshEnd;
242 
243  // Current element as pointers to it's supporting mesh-lines
244  gsVector<uiter, d> m_curElement;
245 
246  // parameter coordinates of current grid cell
247  gsVector<T> m_lower, m_upper;
248 };
249 
250 } // 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:145
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:121
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:158
void updateElement()
Definition: gsHDomainIterator.h:202
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:119
Provides declaration of TensorBSplineBasis abstract interface.