G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsHDomainBoundaryIterator.h
Go to the documentation of this file.
1
14#pragma once
15
17#include <gsHSplines/gsKdNode.h>
19
21
22namespace gismo
23{
24
25// Documentation in gsDomainIterator
39template<typename T, unsigned d>
41{
42public:
43
45
46 typedef typename node::point point;
47
48 typedef typename std::vector<T>::const_iterator uiter;
49
51
53
54public:
55
57 const boxSide & s )
59 {
60 // Initialize mesh data
61 m_meshStart.resize(d);
62 m_meshEnd .resize(d);
63
64 // Initialize cell data
65 m_curElement.resize(d);
66 m_lower .resize(d);
67 m_upper .resize(d);
68
69 // Allocate breaks
70 m_breaks = std::vector<std::vector<T> >(d, std::vector<T>());
71
72 // Set to one quadrature point by default
73 m_quadrature.setNodes( gsVector<index_t>::Ones(d) );
74
75 // Get the side information
76 par = s.parameter();
77 dir = s.direction();
78
79 initLeaf(hbs.tree());
80 }
81
82 // ---> Documentation in gsDomainIterator.h
83 bool next()
84 {
85 this->m_isGood = nextLexicographic(m_curElement, m_meshStart, m_meshEnd);
86
87 if (this->m_isGood) // new element in m_leaf
89 else // went through all elements in m_leaf
90 this->m_isGood = nextLeaf();
91
92 return this->m_isGood;
93 }
94
95 // ---> Documentation in gsDomainIterator.h
96 bool next(index_t increment)
97 {
98 for (index_t i = 0; i < increment; i++)
99 this->m_isGood = nextLexicographic(m_curElement, m_meshStart, m_meshEnd);
100
101 if (this->m_isGood) // new element in m_leaf
103 else // went through all elements in m_leaf
104 this->m_isGood = nextLeaf();
105
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 initLeaf(hbs->tree());
115 }
116
117 const gsVector<T>& lowerCorner() const { return m_lower; }
118
119 const gsVector<T>& upperCorner() const { return m_upper; }
120
121 int getLevel() const
122 {
123 return m_leaf.level();
124 }
125
126private:
127
128 gsHDomainBoundaryIterator();
129
131 void initLeaf(const hDomain & tree_domain)
132 {
133 // Get the first leaf
134 m_leaf = tree_domain.beginLeafIterator();
135
136 for (; m_leaf.good(); m_leaf.next() )
137 {
138 // Check if this leaf is on our side
139 if ( leafOnBoundary() )
140 {
141 updateLeaf();
142 return;
143 }
144 }
145 GISMO_ERROR("No leaves.\n");
146 }
147
148
150 bool nextLeaf()
151 {
152 for (m_leaf.next(); m_leaf.good(); m_leaf.next() )
153 {
154 // Check if this leaf is on our side
155 if ( leafOnBoundary() )
156 {
157 updateLeaf();
158 return true;
159 }
160 }
161 return false;
162 }
163
165 bool leafOnBoundary() const
166 {
167 if ( par )
168 {
169 // AM: a little ugly for now, to be improved
170 size_t diadicSize;
171 const gsHTensorBasis<d,T> * hbasis = dynamic_cast<const gsHTensorBasis<d,T> * >(m_basis);
172 if (basis().manualLevels() )
173 {
174 gsKnotVector<T> kv = hbasis->tensorLevel(m_leaf.level()).knots(dir);
175 index_t start = 0;
176 index_t end = kv.uSize()-1;
177 hbasis->_knotIndexToDiadicIndex(m_leaf.level(),dir,start);
178 hbasis->_knotIndexToDiadicIndex(m_leaf.level(),dir,end);
179 diadicSize = end - start;
180 }
181 else
182 diadicSize = static_cast<const gsHTensorBasis<d,T>*>(m_basis)->tensorLevel(m_leaf.level()).knots(dir).uSize() - 1;
183
184 return static_cast<size_t>(m_leaf.upperCorner().at(dir) ) == diadicSize;// todo: more efficient
185 }
186 else
187 {
188 return m_leaf.lowerCorner().at(dir) == 0;
189 }
190 }
191
196 {
197 const point & lower = m_leaf.lowerCorner();
198 const point & upper = m_leaf.upperCorner();
199 // gsDebug<<"leaf "<< lower.transpose() <<", "
200 // << upper.transpose() <<"\n";
201
202 const int level2 = m_leaf.level();
203
204 // Update leaf box
205 for (unsigned dim = 0; dim < d; ++dim)
206 {
207 index_t start = lower(dim);
208 index_t end = upper(dim) ;
209
210 if (basis().manualLevels() )
211 {
212 static_cast<const gsHTensorBasis<d,T>*>(m_basis)->
213 _diadicIndexToKnotIndex(level2,dim,start);
214 static_cast<const gsHTensorBasis<d,T>*>(m_basis)->
215 _diadicIndexToKnotIndex(level2,dim,end);
216 }
217
218 const gsKnotVector<T> & kv =
219 static_cast<const gsHTensorBasis<d,T>*>(m_basis)
220 ->tensorLevel(level2).component(dim).knots();
221
222 m_breaks[dim].clear();
223 if ( dim == dir )
224 {
225 if ( par )
226 {
227 m_breaks[dim].push_back( kv(end-1) );
228 m_breaks[dim].push_back( kv(end ) );
229 }
230 else
231 {
232 m_breaks[dim].push_back( kv(start) );
233 m_breaks[dim].push_back( kv(start+1) );
234 }
235 }
236 else
237 {
238 for (index_t index = start; index <= end; ++index)
239 m_breaks[dim].push_back( kv(index) );// unique index
240 }
241
242 m_curElement(dim) =
243 m_meshStart(dim) = m_breaks[dim].begin();
244
245
246 // for n breaks, we have n - 1 elements (spans)
247 m_meshEnd(dim) = m_breaks[dim].end() - 1;
248 }
249
250 // We are at a new element, so update cell data
252 }
253
258 {
259 // Update cell data
260 for (unsigned i = 0; i < dir ; ++i)
261 {
262 m_lower[i] = *m_curElement[i];
263 m_upper[i] = *(m_curElement[i]+1);
264 center[i] = (T)(0.5) * (m_lower[i] + m_upper[i]);
265 }
266 m_lower[dir] =
267 m_upper[dir] =
268 center [dir] = (par ? *(m_curElement[dir]+1) : *m_curElement[dir] );
269 for (unsigned i = dir+1; i < d; ++i)
270 {
271 m_lower[i] = *m_curElement[i];
272 m_upper[i] = *(m_curElement[i]+1);
273 center [i] = (T)(0.5) * (m_lower[i] + m_upper[i]);
274 }
275 }
276
277// =============================================================================
278// members
279// =============================================================================
280
281 const gsHTensorBasis<d,T> & basis() const { return *static_cast<const gsHTensorBasis<d,T>*>(m_basis); }
282
283public:
284
285 using gsDomainIterator<T>::center;
286 using gsDomainIterator<T>::m_basis;
287
288# define Eigen gsEigen
289 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
290# undef Eigen
291
292private:
293
294 // Boundary parameters
295 unsigned dir; // direction normal to the boundary
296 bool par; // parameter value
297
298 // The current leaf node of the tree
299 leafIterator m_leaf;
300
301 // Coordinates of the grid cell boundaries
302 // \todo remove this member
303 std::vector< std::vector<T> > m_breaks;
304
305 // Extent of the tensor grid
306 gsVector<uiter, d> m_meshStart, m_meshEnd;
307
308 // Current element as pointers to it's supporting mesh-lines
309 gsVector<uiter, d> m_curElement;
310
311 // parameter coordinates of current grid cell
312 gsVector<T> m_lower, m_upper;
313
314 // Quadrature rule
315 gsGaussRule<T> m_quadrature;
316
317};
318
319} // end namespace gismo
Struct which represents a certain side of a box.
Definition gsBoundary.h:85
bool parameter() const
Returns the parameter value (false=0=start, true=1=end) that corresponds to this side.
Definition gsBoundary.h:128
short_t direction() const
Returns the parametric direction orthogonal to this side.
Definition gsBoundary.h:113
Class which enables iteration over all elements of a parameter domain.
Definition gsDomainIterator.h:68
bool m_isGood
Definition gsDomainIterator.h:223
gsVector< T > center
Coordinates of a central point in the element (in the parameter domain).
Definition gsDomainIterator.h:215
const gsBasis< T > * m_basis
The basis on which the domain iterator is defined.
Definition gsDomainIterator.h:219
short_t dim() const
Return dimension of the elements.
Definition gsDomainIterator.h:115
Re-implements gsDomainIterator for iteration over all boundary elements of a hierarchical parameter d...
Definition gsHDomainBoundaryIterator.h:41
const gsVector< T > & upperCorner() const
Returns the upper corner of the current element.
Definition gsHDomainBoundaryIterator.h:119
void updateLeaf()
Definition gsHDomainBoundaryIterator.h:195
bool next(index_t increment)
Proceeds to the next element (skipping increment elements).
Definition gsHDomainBoundaryIterator.h:96
const gsVector< T > & lowerCorner() const
Returns the lower corner of the current element.
Definition gsHDomainBoundaryIterator.h:117
bool nextLeaf()
returns true if there is a another leaf with a boundary element
Definition gsHDomainBoundaryIterator.h:150
bool next()
Proceeds to the next element.
Definition gsHDomainBoundaryIterator.h:83
void initLeaf(const hDomain &tree_domain)
Navigates to the first leaf on our side.
Definition gsHDomainBoundaryIterator.h:131
void reset()
Definition gsHDomainBoundaryIterator.h:111
bool leafOnBoundary() const
returns true if the current leaf is on our side
Definition gsHDomainBoundaryIterator.h:165
void updateElement()
Definition gsHDomainBoundaryIterator.h:257
Iterates over the leaves of an gsHDomain (tree).
Definition gsHDomainLeafIter.h:30
bool good() const
Returns true iff we are still pointing at a valid leaf.
Definition gsHDomainLeafIter.h:81
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
const gsHDomain< d > & tree() const
Returns a reference to m_tree.
Definition gsHTensorBasis.h:601
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:1893
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
tensorBasis & tensorLevel(index_t i) const
Returns the tensor basis member of level i.
Definition gsHTensorBasis.h:668
Class for representing a knot vector.
Definition gsKnotVector.h:80
T at(index_t i) const
Returns the i-th element of the vector.
Definition gsVector.h:177
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 index_t
Definition gsConfig.h:32
#define GISMO_ERROR(message)
Definition gsDebug.h:118
Provides declaration of DomainIterator abstract interface.
Provides declaration of the HDomain class.
Provides declaration of the tree node.
Provides declaration of TensorBSplineBasis abstract interface.
The G+Smo namespace, containing all definitions for the library.
Struct representing a kd-tree node.
Definition gsKdNode.h:35