G+Smo  25.01.0
Geometry + Simulation Modules
 
Loading...
Searching...
No Matches
gsTensorDomainBoundaryIterator.h
Go to the documentation of this file.
1
14#pragma once
15
17
19
21
22namespace gismo
23{
24
32// Class which enables iteration over all elements of a tensor product parameter domain
33// Documentation in gsDomainIterator.h
34
35template<class T, int D, typename uiter>
36//template<class T, int D=Dynamic, typename uiter = typename gsKnotVector<T>::const_uiterator>
38{
39public:
40
47 gsTensorDomainBoundaryIterator( const std::vector< std::vector<T> > & breaks_, const boxSide & s )
48 : d( breaks_.size() ),
49 lower ( gsVector<T, D>::Zero(d) ),
50 upper ( gsVector<T, D>::Zero(d) )
51 {
53 par = s.parameter();
54 dir = s.direction();
55 meshBegin.resize(d);
56 meshEnd.resize(d);
57 curElement.resize(d);
58 breaks = breaks_;
59
60 for (int i=0; i < dir; ++i)
61 {
62 meshEnd[i] = breaks[i].end() - 1;
63 meshBegin[i] = curElement[i] = breaks[i].begin();
64 if (meshEnd[i] == curElement[i])
65 m_isGood = false;
66 }
67
68 meshEnd[dir] = ( par ? breaks[dir].end() - 1 : breaks[dir].begin() + 1 );
69 curElement[dir] =
70 meshBegin[dir] = ( par ? breaks[dir].end() - 2 : breaks[dir].begin() );
71 tindex = curElement[dir] - breaks[dir].begin();
72
73 for (int i=dir+1; i < d; ++i)
74 {
75 meshEnd[i] = breaks[i].end() - 1;
76 meshBegin[i] = curElement[i] = breaks[i].begin();
77
78 if (meshEnd[i] == curElement[i])
79 m_isGood = false;
80 }
81
82 // Set to one quadrature point by default
83 m_quadrature.setNodes( gsVector<index_t>::Ones(d) );
84
85 if (m_isGood)
86 update();
87 }
88
96 : gsDomainIterator<T>(b, s),
97 d( m_basis->dim() ),
98 lower ( gsVector<T, D>::Zero(d) ),
99 upper ( gsVector<T, D>::Zero(d) )
100 {
102 par = s.parameter();
103 dir = s.direction();
104 meshBegin.resize(d);
105 meshEnd.resize(d);
106 curElement.resize(d);
107 breaks.reserve(d);
108
109 for (int i=0; i < dir; ++i)
110 {
111 breaks.push_back( m_basis->component(i).domain()->breaks() );
112 meshEnd[i] = breaks[i].end() - 1;
113 meshBegin[i] = curElement[i] = breaks[i].begin();
114 //meshEnd[i] = m_basis->component(i).domain()->uend() - 1;
115 //meshBegin[i] =
116 //curElement[i] = m_basis->component(i).knots().ubegin();
117
118 if (meshEnd[i] == curElement[i])
119 m_isGood = false;
120 }
121
122 // Fixed direction
123 breaks.push_back( m_basis->component(dir).domain()->breaks() );
124
125 meshEnd[dir] = ( par ? breaks[dir].end() - 1 : breaks[dir].begin() + 1 );
126 curElement[dir] =
127 meshBegin[dir] = ( par ? breaks[dir].end() - 2 : breaks[dir].begin() );
128 tindex = curElement[dir] - breaks[dir].begin();
129 //meshEnd[dir] = ( par ? m_basis->component(dir).knots().uend() - 1 :
130 // m_basis->component(dir).knots().ubegin() + 1 );
131 //curElement[dir] =
132 //meshBegin[dir] = ( par ?
133 // m_basis->component(dir).knots().uend() - 2 :
134 // m_basis->component(dir).knots().ubegin() );
135 //tindex = curElement[dir] - m_basis->component(i).knots().ubegin();
136
137 for (int i=dir+1; i < d; ++i)
138 {
139 breaks.push_back( m_basis->component(i).domain()->breaks() );
140 meshEnd[i] = breaks[i].end() - 1;
141 meshBegin[i] = curElement[i] = breaks[i].begin();
142 //meshEnd[i] = m_basis->component(i).knots().uend() - 1;
143 //meshBegin[i] =
144 //curElement[i] = m_basis->component(i).knots().ubegin();
145
146 if (meshEnd[i] == curElement[i])
147 m_isGood = false;
148 }
149
150 // Set to one quadrature point by default
151 m_quadrature.setNodes( gsVector<index_t>::Ones(d) );
152
153 if (m_isGood)
154 update();
155 }
156
157 // ---> Documentation in gsDomainIterator.h
158 // proceed to the next element; returns true if end not reached yet
159 bool next()
160 {
161 m_isGood = m_isGood && nextLexicographic(curElement, meshBegin, meshEnd);
162 if (m_isGood)
163 update();
164 return m_isGood;
165 }
166
167 // ---> Documentation in gsDomainIterator.h
168 // proceed to the next element (skipping #increment elements);
169 // returns true if end not reached yet
170 bool next(index_t increment)
171 {
172 for (index_t i = 0; i < increment; i++)
173 m_isGood = m_isGood && nextLexicographic(curElement, meshBegin, meshEnd);
174 if (m_isGood)
175 update();
176 return m_isGood;
177 }
178
182 void reset()
183 {
184 curElement=meshBegin;
185 m_isGood = true;
186 for(int i=0; i < d; ++i)
187 {
188 if (i!=dir && curElement[i]==meshEnd[i])
189 m_isGood=false;
190 }
191 if (m_isGood)
192 update();
193 }
194
197 {
198 gsVector<unsigned, D> curr_index(d);
199 for (int i = 0; i < dir; ++i)
200 curr_index[i] = curElement[i] - meshBegin[i];
201 for (int i = dir+1; i < d; ++i)
202 curr_index[i] = curElement[i] - meshBegin[i];
203 curr_index[dir] = tindex;
204 return curr_index;
205 }
206
207 const gsVector<T> & lowerCorner() const
208 { return lower; }
209
210 const gsVector<T> & upperCorner() const
211 { return upper; }
212
214 {
215 return *(curElement[dir]+1) - *curElement[dir];
216 }
217
219 size_t numElements() const
220 {
221 size_t result = 1;
222 for (short_t i = 0; i < dir; ++i)
223 result *= breaks[i].size() - 1;
224 for (short_t i = dir+1; i < d; ++i)
225 result *= breaks[i].size() - 1;
226
227 return result;
228 }
229
230 void adjacent( const gsVector<bool> & orient,
231 gsDomainIterator<T> & other )
232 {
233 // 2D only for now
234
236 static_cast< gsTensorDomainBoundaryIterator &>(other);
237
238 int a1 = !dir;
239 int a2 = !other_.dir;
240
241 other_.curElement[a2] = std::lower_bound(
242 other_.breaks[a2].begin(), other_.breaks[a2].end(),
243 orient[0] ? *curElement[a1] : *(curElement[a1]+1) );
244 other_.update();
245 }
246
248 void setBreaks(std::vector<T> newBreaks, index_t i) // i: direction
249 {
250 breaks[i].swap(newBreaks);
251 meshEnd[i] = breaks[i].end() - 1;
252 meshBegin[i] = curElement[i] = breaks[i].begin();
253 reset();
254 }
255
256private:
257
261 void update()
262 {
263 for (int i = 0; i < dir ; ++i)
264 {
265 lower[i] = *curElement[i];
266 upper[i] = *(curElement[i]+1);
267 center[i] = (T)(0.5) * (lower[i] + upper[i]);
268 }
269 lower[dir] =
270 upper[dir] =
271 center[dir] = (par ? *(curElement[dir]+1) : *curElement[dir] );
272 for (int i = dir+1; i < d; ++i)
273 {
274 lower[i] = *curElement[i];
275 upper[i] = *(curElement[i]+1);
276 center[i] = (T)(0.5) * (lower[i] + upper[i]);
277 }
278
279 //gsDebug<<"lower: "<< lower.transpose() <<", upper="<<upper.transpose() <<"\n";
280 }
281
282// Data members
283protected:
287 using gsDomainIterator<T>::m_side;
288
289private:
290
291 // the dimension of the parameter space
292 short_t d;
293
294 // Boundary parameters
295 short_t dir;
296 bool par;
297 unsigned tindex;
298
299 // coordinates of the grid cell boundaries
300 std::vector< std::vector<T> > breaks;
301
302 // Quadrature rule
303 gsGaussRule<T> m_quadrature;
304
305 // First mesh-line on the tensor grid
306 gsVector<uiter, D> meshBegin;
307
308 // Last mesh-line on the tensor grid
309 gsVector<uiter, D> meshEnd;
310
311 // Current element as pointers to it's supporting mesh-lines
312 gsVector<uiter, D> curElement;
313
314 // parameter coordinates of current grid cell
315 gsVector<T> lower, upper;
316
317public:
318# define Eigen gsEigen
319 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
320# undef Eigen
321}; // class gsTensorDomainBoundaryIterator
322
323
324} // 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
A basis represents a family of scalar basis functions defined over a common parameter domain.
Definition gsBasis.h:79
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
Class that represents the (tensor) Gauss-Legendre quadrature rule.
Definition gsGaussRule.h:28
Re-implements gsDomainIterator for iteration over all elements of the boundary of a tensor product pa...
Definition gsTensorDomainBoundaryIterator.h:38
const gsVector< T > & upperCorner() const
Returns the upper corner of the current element.
Definition gsTensorDomainBoundaryIterator.h:210
gsVector< unsigned, D > index() const
Return the tensor index of the current element.
Definition gsTensorDomainBoundaryIterator.h:196
bool next(index_t increment)
Proceeds to the next element (skipping increment elements).
Definition gsTensorDomainBoundaryIterator.h:170
const gsVector< T > & lowerCorner() const
Returns the lower corner of the current element.
Definition gsTensorDomainBoundaryIterator.h:207
void setBreaks(std::vector< T > newBreaks, index_t i)
Function to set the breakpoints in direction i manually.
Definition gsTensorDomainBoundaryIterator.h:248
const T getPerpendicularCellSize() const
Returns the perpendicular cell size of boundary iterator.
Definition gsTensorDomainBoundaryIterator.h:213
bool next()
Proceeds to the next element.
Definition gsTensorDomainBoundaryIterator.h:159
void update()
Definition gsTensorDomainBoundaryIterator.h:261
void reset()
Definition gsTensorDomainBoundaryIterator.h:182
gsTensorDomainBoundaryIterator(const gsBasis< T > &b, const boxSide &s)
Constructs a new instance.
Definition gsTensorDomainBoundaryIterator.h:95
gsTensorDomainBoundaryIterator(const std::vector< std::vector< T > > &breaks_, const boxSide &s)
Constructor using explicitly defined breaks.
Definition gsTensorDomainBoundaryIterator.h:47
size_t numElements() const
Returns the number of elements.
Definition gsTensorDomainBoundaryIterator.h:219
A vector with arbitrary coefficient type and fixed or dynamic size.
Definition gsVector.h:37
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
Provides combinatorial unitilies.
#define short_t
Definition gsConfig.h:35
#define index_t
Definition gsConfig.h:32
Provides declaration of DomainIterator abstract interface.
Provides the Gauss-Legendre quadrature rule.
The G+Smo namespace, containing all definitions for the library.