G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsGridIterator.h
Go to the documentation of this file.
1
14#pragma once
15
16namespace gismo
17{
18
25{
26 CUBE = 0,
27 BDR = 1,
28 VERTEX = 2,
29 CWISE = 3
30};
31
32// note: default arguments are found in gsForwardDeclarations.h
33template<typename Z, int mode, short_t d, bool> class gsGridIterator
34{using Z::GISMO_ERROR_gsGridIterator_has_invalid_template_arguments;};
35
69template<class Z, int mode, short_t d>
70class gsGridIterator<Z,mode,d,true>
71{
72public:
73 typedef gsVector<Z,d> point;
74
75public:
76
81 {
82 GISMO_STATIC_ASSERT(std::numeric_limits<Z>::is_integer,"The template parameter needs to be an integer type.");
83 GISMO_STATIC_ASSERT(mode > -1 && mode < 3, "The mode of gsGridIterator needs to be 0, 1 or 2.");
84 }
85
93 gsGridIterator(point const & a, point const & b, bool open = true)
94 { reset(a, b, open); }
95
102 explicit gsGridIterator(point const & b, bool open = true)
103 { reset(point::Zero(b.size()), b, open); }
104
111 explicit gsGridIterator(gsMatrix<Z,d,2> const & ab, bool open = true)
112 { reset(ab.col(0), ab.col(1), open); }
113
121 inline void reset(point const & a, point const & b, bool open = true)
122 {
123 GISMO_ASSERT(a.rows() == b.rows(), "Invalid endpoint dimensions");
124 m_low = m_cur = a;
125 if (open) m_upp = b.array() - 1; else m_upp = b;
126 m_valid = ( (m_low.array() <= m_upp.array()).all() ? true : false );
127 }
128
133 void reset() { reset(m_low,m_upp, false); }
134
135 // See http://eigen.tuxfamily.org/dox-devel/group__TopicStructHavingEigenMembers.html
136 //EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF( (sizeof(point)%16)==0 );
137
138public:
139
140 operator bool() const {return m_valid;}
141
142 const point & operator*() const {return m_cur;}
143
144 const point * operator->() const {return &m_cur;}
145
146 inline gsGridIterator & operator++()
147 {
148 // Multiple implementations according to mode
149 switch (mode)
150 {
151 case 0: // ----------- Iteration over [m_low, m_upp]
152 case 2: // iteration over vertices of the cube [m_low, m_upp]
153 for (index_t i = 0; i != m_cur.size(); ++i)
154 if ( m_cur[i] != m_upp[i] )
155 {
156 if (0==mode) ++m_cur[i]; else m_cur[i] = m_upp[i];
157 return *this;
158 }
159 else
160 m_cur[i] = m_low[i];
161 m_valid = 0;//done
162 return *this;
163
164 case 1: // ----------- Iteration over boundary of [m_low, m_upp]
165 default:
166 for (index_t i = 0; i != m_cur.size(); ++i)
167 {
168 if ( m_cur[i] != m_upp[i] )
169 {
170 if ( m_cur[i] == m_low[i] && (i+1!=m_cur.size() || 1==m_cur.size()) )
171 {
172 index_t c = i+1;
173 for (index_t j = c; j!=m_cur.size(); ++j)
174 if ( (m_cur[j] == m_low[j]) ||
175 (m_cur[j] == m_upp[j]) )
176 ++c;
177
178 if ( c==1 )
179 m_cur[i] = m_upp[i];
180 else
181 ++m_cur[i];
182 }
183 else
184 m_cur[i]++;
185
186 m_cur.head(i) = m_low.head(i);
187 return *this;
188 }
189 }
190 /*fall through to default*/
191 m_valid = 0;//done
192 return *this;
193 }
194 }
195
199 inline bool isFloor(int i) const { return m_cur[i] == m_low[i];}
200
204 inline bool isCeil (int i) const
205 { return mode ? m_cur[i] == m_upp[i] : m_cur[i] + 1 == m_upp[i];}
206
210 bool isBoundary() const
211 {
212 return (m_cur.array() == m_low.array()).any() ||
213 (m_cur.array() == m_upp.array()).any() ;
214 }
215
220 {
221 switch (mode)
222 {
223 case 0: return ((m_upp-m_low).array() + 1).prod();
224 case 1: return ((m_upp-m_low).array() + 1).prod() - ((m_upp-m_low).array()-1).prod();
225 case 2: return ( 1 << m_low.rows() );
226 default: GISMO_ERROR("gsGridIterator::numPoints");
227 }
228 }
229
234 point numPointsCwise() const { return (m_upp-m_low).array() + 1;}
235
239 const point & lower() const {return m_low;}
240
244 const point & upper() const {return m_upp;}
245
263 {
264 point res(m_low.rows());
265 res[0] = 1;
266 for (index_t i = 1; i != res.size(); ++i )
267 res[i] = res[i-1] * ( m_upp[i-1] - m_low[i-1] + 1 );
268 return res;
269 }
270
271private:
272
273 point m_low, m_upp;
275 bool m_valid;
276};
277
278
307template<class T, int mode, short_t d>
308class gsGridIterator<T,mode,d,false>
309{
310public:
311
312 typedef gsVector<T,d> point;
313
314 typedef gsGridIterator<index_t, mode, d> integer_iterator;
315
316 typedef typename integer_iterator::point point_index;
317public:
318
329 point const & b,
330 point_index const & np)
331 : m_iter(np, 1)
332 {
333 reset(a, b);
334 GISMO_STATIC_ASSERT(mode > -1 && mode < 3, "The mode of gsGridIterator needs to be 0, 1 or 2.");
335 }
336
346 point_index const & np)
347 : m_iter(np, 1)
348 {
349 reset(ab.col(0), ab.col(1));
350 }
351
361 gsGridIterator(gsMatrix<T,d,2> const & ab, unsigned numPoints)
362 : m_low(ab.col(0)), m_upp(ab.col(1))
363 {
364 // deduce the number of points per direction for an approximately uniform grid
365 const gsVector<double,d> L = (ab.col(1) - ab.col(0)).template cast<double>();
366 const double h = std::pow(L.prod()/numPoints, 1.0 / m_low.rows());
367 const point_index npts = (L/h).unaryExpr((double(*)(double))std::ceil).template cast<index_t>();
368 m_iter = integer_iterator(npts, 1);
369 reset(ab.col(0), ab.col(1));
370 }
371
376 void reset() { m_cur = m_low; m_iter.reset(); }
377
384 void reset(point const & a,
385 point const & b)
386 {
387 m_cur = m_low = a;
388 m_upp = b;
389 m_step = (b-a).array() / (m_iter.numPointsCwise().array() - 1)
390 .matrix().cwiseMax(1).template cast<T>().array() ;
391 m_iter.reset();
392 }
393
394 gsMatrix<T> toMatrix() const
395 {
396 gsMatrix<T> res(m_cur.rows(), numPoints());
397 integer_iterator iter = m_iter;
398 iter.reset();
399
400 for(index_t c = 0; iter; ++iter, ++c)
401 update(*iter,res.col(c).data());
402
403 return res;
404 }
405
406 // See http://eigen.tuxfamily.org/dox-devel/group__TopicStructHavingEigenMembers.html
407 //EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF( (sizeof(point)%16)==0 );
408
409public:
410
411 operator bool() const {return m_iter;}
412
413 const gsMatrix<T> & operator*() const {return m_cur;}
414
415 const gsMatrix<T> * operator->() const {return &m_cur;}
416
417 inline gsGridIterator & operator++()
418 {
419 if ( ++m_iter ) update(*m_iter, m_cur.data());
420 return *this;
421 }
422
426 inline bool isFloor(int i) const { return m_iter.isFloor(i);}
427
431 inline bool isCeil (int i) const { return m_iter.isCeil(i);}
432
436 inline bool isBoundary() const { return m_iter.isBoundary();}
437
441 index_t numPoints() const {return m_iter.numPoints();}
442
447 point_index numPointsCwise() const {return m_iter.numPointsCwise();}
448
452 const point & lower() const {return m_low;}
453
457 const point & upper() const {return m_upp;}
458
462 const point_index & tensorIndex() const { return *m_iter;}
463
467 index_t index(const index_t i) const { return m_iter->at(i);}
468
472 const point & step() const {return m_step;}
473
478 const integer_iterator & index_iterator() const { return m_iter;}
479
489 inline const gsMatrix<T> operator [] (const point_index & ti) const
490 {
491 gsMatrix<T> res(m_low.rows(),1);
492 update(ti, res.data());
493 return res;
494 }
495
496private:
497
498 // Update the point \a pt to the position \a ti
499 inline void update(const point_index & ti, T * pt) const
500 {
501 for (index_t i = 0; i != m_low.size(); ++i)
502 if ( ti[i] == m_iter.lower()[i] )
503 *(pt++) = m_low[i]; // avoid numerical error at first val
504 else if ( ti[i] == m_iter.upper()[i] )
505 *(pt++) = m_upp[i]; // avoid numerical error at last val
506 else
507 *(pt++) = m_low[i] + static_cast<T>(ti[i]) * m_step[i];
508 }
509
510private:
511
512 point m_low, m_upp, m_step;
513
514 integer_iterator m_iter;
516};
517
518
538template<class T, short_t d> // mode == 3 == CWISE
539class gsGridIterator<T,CWISE,d,false>
540{
541public:
542
543 typedef gsGridIterator<index_t, 0, d> integer_iterator;
544
545 typedef typename integer_iterator::point point_index;
546
547 typedef gsVector<const T *,d, 2> CwiseData; //non-aligned array
548
549public:
550
557 template<class CwiseContainer>
558 explicit gsGridIterator(const CwiseContainer & cwise)
559 : m_cwise(cwise.size()), m_cur(m_cwise.size(),1)
560 {
561 point_index npts(m_cwise.size());
562 for (index_t i = 0; i != npts.size(); ++i)
563 {
564 m_cwise[i] = cwise[i].data();
565 npts[i] = cwise[i].size() - 1;
566 GISMO_ASSERT(cwise[i].cols()==1 || cwise[i].rows()==1, "Invalid input");
567 }
568 m_iter = integer_iterator(npts, 0);
569 //if (1==cwise.front().cols())
570 // m_cur.derived().resize(1, npts.size());
571 //else
572 //m_cur.derived().resize(npts.size(), 1);
573 update(*m_iter, m_cur.data());
574 }
575
576 template<class Matrix_t>
577 explicit gsGridIterator(const std::vector<Matrix_t*> & cwise)
578 : m_cwise(cwise.size()), m_cur(m_cwise.size(),1)
579 {
580 point_index npts(m_cwise.size());
581 for (index_t i = 0; i != npts.size(); ++i)
582 {
583 m_cwise[i] = cwise[i]->data();
584 npts[i] = cwise[i]->size() - 1;
585 GISMO_ASSERT(cwise[i]->cols()==1 || cwise[i]->rows()==1, "Invalid input");
586 }
587 m_iter = integer_iterator(npts, 0);
588 update(*m_iter, m_cur.data());
589 }
590
595 void reset() { m_iter.reset(); update(*m_iter, m_cur.data());}
596
597 //void restart() { m_iter.reset(); update(*m_iter, m_cur.data());}
598
599public:
600
601 operator bool() const {return m_iter;}
602
603 const gsMatrix<T> & operator*() const {return m_cur;}
604
605 const gsMatrix<T> * operator->() const {return &m_cur;}
606
607 inline gsGridIterator & operator++()
608 {
609 if (++m_iter) update(*m_iter, m_cur.data());
610 return *this;
611 }
612
616 inline bool isFloor(int i) const { return m_iter.isFloor(i);}
617
621 inline bool isCeil (int i) const { return m_iter.isCeil(i);}
622
626 inline bool isBoundary() const { return m_iter.isBoundary();}
627
631 index_t numPoints() const {return m_iter.numPoints();}
632
637 point_index numPointsCwise() const {return m_iter.numPointsCwise();}
638
642 const point_index & tensorIndex() const { return *m_iter;}
643
647 index_t index(const index_t i) const { return m_iter->at(i);}
648
653 const integer_iterator & index_iterator() const { return m_iter;}
654
664 inline const gsMatrix<T> operator [] (const point_index & ti) const
665 {
666 gsMatrix<T> res(m_cur.rows(),1);
667 update(ti, res.data());
668 return res;
669 }
670
671private:
672
673 // Update the point \a pt to the position \a ti
674 inline void update(const point_index & ti, T * pt)
675 {
676 for (index_t i = 0; i != m_cur.rows(); ++i)
677 *(pt++) = m_cwise[i][ti[i]];
678 }
679
680private:
681
683
684 integer_iterator m_iter;
686};
687
688
689} // namespace gismo
bool isCeil(int i) const
Returns true if the i-th coordinate has maximal value.
Definition gsGridIterator.h:621
bool isBoundary() const
Returns true if the current point lies on a boundary.
Definition gsGridIterator.h:626
const integer_iterator & index_iterator() const
Returns a reference to the underlying integer lattice iterator.
Definition gsGridIterator.h:653
integer_iterator m_iter
Underlying integer lattice iterator.
Definition gsGridIterator.h:684
bool isFloor(int i) const
Returns true if the i-th coordinate has minimal value.
Definition gsGridIterator.h:616
gsGridIterator(const CwiseContainer &cwise)
Constructor using references to the coordinate vectors.
Definition gsGridIterator.h:558
index_t numPoints() const
Returns the total number of points that are iterated.
Definition gsGridIterator.h:631
const point_index & tensorIndex() const
Returns the tensor index of the current point.
Definition gsGridIterator.h:642
index_t index(const index_t i) const
Returns the i-th index of the current point.
Definition gsGridIterator.h:647
gsMatrix< T > m_cur
Current point pointed at by the iterator.
Definition gsGridIterator.h:685
void reset()
Resets the iterator, so that a new iteration over the points may start.
Definition gsGridIterator.h:595
CwiseData m_cwise
List of coordinate-wise values.
Definition gsGridIterator.h:682
point_index numPointsCwise() const
Returns the total number of points per coordinate which are iterated.
Definition gsGridIterator.h:637
bool isCeil(int i) const
Returns true if the i-th coordinate has maximal value.
Definition gsGridIterator.h:431
bool isBoundary() const
Returns true if the current point lies on a boundary.
Definition gsGridIterator.h:436
gsGridIterator(gsMatrix< T, d, 2 > const &ab, point_index const &np)
Constructor using lower and upper limits.
Definition gsGridIterator.h:345
const integer_iterator & index_iterator() const
Returns a reference to the underlying integer lattice iterator.
Definition gsGridIterator.h:478
integer_iterator m_iter
Underlying integer lattice iterator.
Definition gsGridIterator.h:514
const point & step() const
Returns the coordinate-wise stepping between the samples.
Definition gsGridIterator.h:472
void reset(point const &a, point const &b)
Resets the iterator using new lower and upper limits.
Definition gsGridIterator.h:384
const point & upper() const
Returns the last point in the iteration.
Definition gsGridIterator.h:457
gsGridIterator(gsMatrix< T, d, 2 > const &ab, unsigned numPoints)
Constructor using lower and upper limits.
Definition gsGridIterator.h:361
bool isFloor(int i) const
Returns true if the i-th coordinate has minimal value.
Definition gsGridIterator.h:426
gsGridIterator(point const &a, point const &b, point_index const &np)
Constructor using lower and upper limits.
Definition gsGridIterator.h:328
index_t numPoints() const
Returns the total number of points that are iterated.
Definition gsGridIterator.h:441
point m_step
Iteration lower and upper limits and stepsize.
Definition gsGridIterator.h:512
const point_index & tensorIndex() const
Returns the tensor index of the current point.
Definition gsGridIterator.h:462
const point & lower() const
Returns the first point in the iteration.
Definition gsGridIterator.h:452
index_t index(const index_t i) const
Returns the i-th index of the current point.
Definition gsGridIterator.h:467
gsMatrix< T > m_cur
Current point pointed at by the iterator.
Definition gsGridIterator.h:515
void reset()
Resets the iterator, so that a new iteration over the points may start.
Definition gsGridIterator.h:376
point_index numPointsCwise() const
Returns the total number of points per coordinate which are iterated.
Definition gsGridIterator.h:447
void reset(point const &a, point const &b, bool open=true)
Resets the iterator using new lower and upper limits.
Definition gsGridIterator.h:121
bool isCeil(int i) const
Returns true if the i-th coordinate has maximal value.
Definition gsGridIterator.h:204
gsGridIterator()
Empty constructor.
Definition gsGridIterator.h:80
bool isBoundary() const
Returns true if the current point lies on a boundary.
Definition gsGridIterator.h:210
point m_cur
Current point pointed at by the iterator.
Definition gsGridIterator.h:274
point strides() const
Utility function which returns the vector of strides.
Definition gsGridIterator.h:262
gsGridIterator(point const &b, bool open=true)
Constructor using upper limit. The iteration starts from zero.
Definition gsGridIterator.h:102
const point & upper() const
Returns the last point in the iteration.
Definition gsGridIterator.h:244
point m_upp
Iteration lower and upper limits.
Definition gsGridIterator.h:273
bool isFloor(int i) const
Returns true if the i-th coordinate has minimal value.
Definition gsGridIterator.h:199
bool m_valid
Indicates the state of the iterator.
Definition gsGridIterator.h:275
index_t numPoints() const
Returns the total number of points that are iterated.
Definition gsGridIterator.h:219
gsGridIterator(point const &a, point const &b, bool open=true)
Constructor using lower and upper limits.
Definition gsGridIterator.h:93
const point & lower() const
Returns the first point in the iteration.
Definition gsGridIterator.h:239
gsGridIterator(gsMatrix< Z, d, 2 > const &ab, bool open=true)
Constructor using lower and upper limits.
Definition gsGridIterator.h:111
void reset()
Resets the iterator, so that a new iteration over the points may start.
Definition gsGridIterator.h:133
point numPointsCwise() const
Returns the total number of points per coordinate which are iterated.
Definition gsGridIterator.h:234
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition gsMatrix.h:41
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
#define index_t
Definition gsConfig.h:32
#define GISMO_ERROR(message)
Definition gsDebug.h:118
#define GISMO_ASSERT(cond, message)
Definition gsDebug.h:89
EIGEN_STRONG_INLINE mult_expr< E1, E2 > const operator*(_expr< E1 > const &u, _expr< E2 > const &v)
Multiplication operator for expressions.
Definition gsExpressions.h:4559
The G+Smo namespace, containing all definitions for the library.
gsGridIteratorMode
Specifies aliases describing the modes for gismo::gsGridIterator.
Definition gsGridIterator.h:25
@ VERTEX
Vertex mode iterates over cube vertices only.
Definition gsGridIterator.h:28
@ BDR
Boundary mode iterates over boundary lattice points only.
Definition gsGridIterator.h:27
@ CWISE
Coordinate-wise mode iterates over a grid given by coordinate vectors.
Definition gsGridIterator.h:29
@ CUBE
Cube mode iterates over all lattice points inside a cube.
Definition gsGridIterator.h:26