edgeI.H
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2011 OpenFOAM Foundation
9  Copyright (C) 2017-2025 OpenCFD Ltd.
10 -------------------------------------------------------------------------------
11 License
12  This file is part of OpenFOAM.
13 
14  OpenFOAM is free software: you can redistribute it and/or modify it
15  under the terms of the GNU General Public License as published by
16  the Free Software Foundation, either version 3 of the License, or
17  (at your option) any later version.
18 
19  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22  for more details.
23 
24  You should have received a copy of the GNU General Public License
25  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26 
27 \*---------------------------------------------------------------------------*/
28 
29 #include "IOstreams.H"
30 
31 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
32 
33 inline int Foam::edge::compare(const edge& a, const edge& b)
34 {
35  return labelPair::compare(a, b);
36 }
37 
38 
39 inline Foam::edge Foam::edge::sorted(label from, label to)
40 {
41  return (from < to) ? edge(from, to) : edge(to, from);
42 }
43 
44 
45 inline Foam::edge Foam::edge::sorted(const labelPair& pair)
46 {
47  return
48  (
49  pair.first() < pair.second()
50  ? edge(pair.first(), pair.second())
51  : edge(pair.second(), pair.first())
52  );
53 }
54 
55 
57 {
58  return
59  (
60  (pair.get<0>() < pair.get<1>())
61  ? edge(pair.get<0>(), pair.get<1>())
62  : edge(pair.get<1>(), pair.get<0>())
63  );
64 }
65 
66 
67 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
68 
69 inline Foam::edge::edge()
70 :
71  labelPair(-1, -1)
72 {}
73 
74 
75 inline Foam::edge::edge(label from, label to)
76 :
77  labelPair(from, to)
78 {}
79 
80 
81 inline Foam::edge::edge(const labelPair& pair)
82 :
83  labelPair(pair.first(), pair.second())
84 {}
85 
86 
88 :
89  labelPair(pair.get<0>(), pair.get<1>())
90 {}
91 
92 
93 inline Foam::edge::edge
94 (
95  const labelUList& list,
96  const FixedList<label, 2>& indices
97 )
98 :
99  labelPair(list[indices.get<0>()], list[indices.get<1>()])
100 {}
101 
102 
103 inline Foam::edge::edge(Istream& is)
104 :
105  labelPair(is)
106 {}
107 
108 
109 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
111 inline Foam::label Foam::edge::min() const noexcept
112 {
113  return (first() < second() ? first() : second());
114 }
115 
117 inline Foam::label Foam::edge::max() const noexcept
118 {
119  return (second() < first() ? first() : second());
120 }
121 
123 inline bool Foam::edge::good() const noexcept
124 {
125  return (first() != second() && first() >= 0 && second() >= 0);
126 }
127 
128 
129 inline bool Foam::edge::contains(const label vertex) const noexcept
130 {
131  // -1: always false
132  return
133  (
134  vertex >= 0
135  && (vertex == first() || vertex == second())
136  );
137 }
138 
139 
140 inline Foam::label Foam::edge::which(const label vertex) const
141 {
142  // -1: always false
143  if (vertex >= 0)
144  {
145  if (vertex == first())
146  {
147  return 0;
148  }
149  if (vertex == second())
150  {
151  return 1;
152  }
153  }
154 
155  return -1;
156 }
157 
159 inline bool Foam::edge::connected(const edge& other) const
160 {
161  return (other.contains(first()) || other.contains(second()));
162 }
163 
164 
165 inline Foam::label Foam::edge::commonVertex(const edge& other) const
166 {
167  if (other.contains(first()))
168  {
169  return first();
170  }
171  if (other.contains(second()))
172  {
173  return second();
174  }
175 
176  // No shared vertex.
177  return -1;
178 }
179 
180 
181 inline Foam::label Foam::edge::otherVertex(const label vertex) const
182 {
183  if (vertex == first())
184  {
185  return second();
186  }
187  if (vertex == second())
188  {
189  return first();
190  }
191 
192  // The given vertex is not on the edge in the first place.
193  return -1;
194 }
195 
196 
197 inline Foam::label Foam::edge::collapse()
198 {
199  // Cannot resize FixedList, so mark duplicates with '-1'
200  // (the lower vertex is retained)
201  // catch any '-1' (eg, if called multiple times)
202 
203  label n = 2;
204  if (first() == second() || second() < 0)
205  {
206  second() = -1;
207  --n;
208  }
209  if (first() < 0)
210  {
211  --n;
212  }
213 
214  return n;
215 }
216 
218 inline Foam::edge Foam::edge::reverseEdge() const
219 {
220  return Foam::edge(second(), first());
221 }
222 
223 
224 inline void Foam::edge::clear()
225 {
226  first() = -1;
227  second() = -1;
228 }
229 
230 
231 inline Foam::label Foam::edge::count() const
232 {
233  label n = 2;
234  if (first() == second() || second() < 0)
235  {
236  --n;
237  }
238  if (first() < 0)
239  {
240  --n;
241  }
242 
243  return n;
244 }
245 
247 inline bool Foam::edge::empty() const noexcept
248 {
249  return (first() < 0 && second() < 0);
250 }
251 
252 
253 inline bool Foam::edge::insert(const label vertex)
254 {
255  if (vertex < 0)
256  {
257  // Cannot insert invalid vertex labels (use direct assignment for that)
258  return false;
259  }
260 
261  if (first() < 0)
262  {
263  // Store at first, if not duplicate of second
264  if (vertex != second())
265  {
266  first() = vertex;
267  return true;
268  }
269  }
270  else if (second() < 0)
271  {
272  // Store at second, if not duplicate of first
273  if (vertex != first())
274  {
275  second() = vertex;
276  return true;
277  }
278  }
280  return false;
281 }
282 
283 
284 template<class InputIterator>
285 inline Foam::label Foam::edge::insert
286 (
287  InputIterator begIter,
288  InputIterator endIter
289 )
290 {
291  // Available slots.
292  // Don't use count() since it has special treatment for duplicates
293  const int maxChange = ((first() < 0 ? 1 : 0) + (second() < 0 ? 1 : 0));
294 
295  int changed = 0;
296  for (; changed < maxChange && begIter != endIter; ++begIter)
297  {
298  if (insert(*begIter))
299  {
300  ++changed;
301  }
302  }
303 
304  return changed;
305 }
306 
307 
308 inline Foam::label Foam::edge::insert(std::initializer_list<label> list)
309 {
310  return insert(list.begin(), list.end());
311 }
312 
313 
314 template<unsigned N>
315 inline Foam::label Foam::edge::insert(const FixedList<label, N>& list)
316 {
317  return insert(list.begin(), list.end());
318 }
319 
321 inline Foam::label Foam::edge::insert(const labelUList& list)
322 {
323  return insert(list.begin(), list.end());
324 }
325 
326 
327 inline Foam::label Foam::edge::erase(const label vertex)
328 {
329  if (vertex < 0)
330  {
331  // Can never remove invalid point labels!
332  return 0;
333  }
334 
335  label n = 0;
336  if (vertex == first())
337  {
338  first() = -1;
339  ++n;
340  }
341 
342  // Automatically handle duplicates, which should not have been there anyhow
343  if (vertex == second())
344  {
345  second() = -1;
346  ++n;
347  }
349  return n;
350 }
351 
352 
353 template<class InputIterator>
354 inline Foam::label Foam::edge::erase
355 (
356  InputIterator begIter,
357  InputIterator endIter
358 )
359 {
360  // Occupied slots.
361  // Don't use count() since it has special treatment for duplicates
362  const int maxChange = ((first() >= 0 ? 1 : 0) + (second() >= 0 ? 1 : 0));
363 
364  int changed = 0;
365  for (; changed < maxChange && begIter != endIter; ++begIter)
366  {
367  changed += erase(*begIter);
368  }
369 
370  return changed;
371 }
372 
373 
374 inline Foam::label Foam::edge::erase(std::initializer_list<label> list)
375 {
376  return erase(list.begin(), list.end());
377 }
378 
379 
380 template<unsigned N>
381 inline Foam::label Foam::edge::erase(const FixedList<label, N>& list)
382 {
383  return erase(list.begin(), list.end());
384 }
385 
386 
387 inline Foam::label Foam::edge::erase(const labelUList& list)
388 {
389  return erase(list.begin(), list.end());
390 }
391 
392 
393 // Geometric
394 
395 inline Foam::point Foam::edge::centre(const UList<point>& pts) const
396 {
397  #ifdef FULLDEBUG
398  if (first() < 0 || second() < 0)
399  {
401  << "negative point index on edge " << *this
402  << abort(FatalError);
403  }
404  #endif
405 
406  return 0.5*(pts[first()] + pts[second()]);
407 }
408 
409 
410 inline Foam::vector Foam::edge::vec(const UList<point>& pts) const
411 {
412  #ifdef FULLDEBUG
413  if (first() < 0 || second() < 0)
414  {
416  << "negative point index on edge " << *this
417  << abort(FatalError);
418  }
419  #endif
420 
421  return pts[second()] - pts[first()];
422 }
423 
424 
425 inline Foam::vector Foam::edge::unitVec(const UList<point>& pts) const
426 {
427  #ifdef FULLDEBUG
428  if (first() < 0 || second() < 0)
429  {
431  << "negative point index on edge " << *this
432  << abort(FatalError);
433  }
434  #endif
436  vector v = (pts[second()] - pts[first()]);
437  (void) v.normalise(ROOTVSMALL);
438  return v;
439 }
440 
442 inline Foam::scalar Foam::edge::mag(const UList<point>& pts) const
443 {
444  return pts[first()].dist(pts[second()]);
445 }
446 
447 
448 inline Foam::scalar Foam::edge::magSqr(const UList<point>& pts) const
449 {
450  return pts[first()].distSqr(pts[second()]);
451 }
452 
453 
455 Foam::edge::box(const UList<point>& pts) const
456 {
457  #ifdef FULLDEBUG
458  if (first() < 0 || second() < 0)
459  {
461  << "negative point index on edge " << *this
462  << abort(FatalError);
463  }
464  #endif
465 
466  return linePointRef::box(pts[first()], pts[second()]);
467 }
468 
469 
470 inline Foam::linePointRef Foam::edge::line(const UList<point>& pts) const
471 {
472  #ifdef FULLDEBUG
473  if (first() < 0 || second() < 0)
474  {
476  << "negative point index on edge " << *this
477  << abort(FatalError);
478  }
479  #endif
481  return linePointRef(pts[first()], pts[second()]);
482 }
483 
484 
485 // * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
486 
487 inline Foam::label& Foam::edge::operator[](const label i)
488 {
489  #ifdef FULLDEBUG
490  if (i < 0 || i > 1)
491  {
493  << "Index " << i << " out of range [0,1]" << abort(FatalError);
494  }
495  #endif
496  return (i ? second() : first());
497 }
498 
499 
500 inline const Foam::label& Foam::edge::operator[](const label i) const
501 {
502  #ifdef FULLDEBUG
503  if (i < 0 || i > 1)
504  {
506  << "Index " << i << " out of range [0,1]" << abort(FatalError);
507  }
508  #endif
509  return (i ? second() : first());
510 }
511 
513 inline bool Foam::edge::operator==(const edge& other) const
514 {
515  return (labelPair::compare(*this, other) != 0);
516 }
517 
518 
519 inline bool Foam::edge::operator!=(const edge& other) const
520 {
521  return (labelPair::compare(*this, other) == 0);
522 }
523 
524 
525 // ************************************************************************* //
label count() const
Return the number of unique, valid (non -1) vertex labels.
Definition: edgeI.H:224
const T & first() const noexcept
Access the first element.
Definition: Pair.H:167
A line primitive.
Definition: line.H:52
scalar mag(const UList< point > &pts) const
The length (L2-norm) of the edge vector.
Definition: edgeI.H:435
iterator begin() noexcept
Return an iterator to begin traversing the FixedList.
Definition: FixedListI.H:461
srcOptions erase("case")
error FatalError
Error stream (stdout output on all processes), with additional &#39;FOAM FATAL ERROR&#39; header text and sta...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:652
edge reverseEdge() const
Return reverse edge as copy.
Definition: edgeI.H:211
linePointRef line(const UList< point > &pts) const
Return edge line.
Definition: edgeI.H:463
srcOptions insert("case", fileName(rootDirSource/caseDirSource))
An Istream is an abstract base class for all input systems (streams, files, token lists etc)...
Definition: Istream.H:57
bool operator!=(const edge &other) const
Compare edges for non-equal content, ignoring orientation.
Definition: edgeI.H:512
iterator end() noexcept
Return an iterator to end traversing the FixedList.
Definition: FixedListI.H:509
label b() const noexcept
The second vertex.
Definition: edge.H:168
bool connected(const edge &other) const
True if the edge has at least one vertex in common with other.
Definition: edgeI.H:152
Pair< Point > box() const
The enclosing (bounding) box for the line.
Definition: lineI.H:166
bool empty() const noexcept
Return true if edge has no valid vertex labels.
Definition: edgeI.H:240
vector unitVec(const UList< point > &pts) const
Return the unit vector (from first to second).
Definition: edgeI.H:418
Useful combination of include files which define Sin, Sout and Serr and the use of IO streams general...
label erase(const label vertex)
Remove an existing vertex from the edge and set its location to &#39;-1&#39;. A negative vertex label never r...
Definition: edgeI.H:320
void clear()
&#39;Clears&#39; edge by setting both ends to invalid vertex labels.
Definition: edgeI.H:217
line< point, const point & > linePointRef
A line using referred points.
Definition: line.H:66
label commonVertex(const edge &other) const
Return vertex common with other edge or -1 on failure.
Definition: edgeI.H:158
static int compare(const Pair< label > &a, const Pair< label > &b)
Compare Pairs.
Definition: PairI.H:24
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
Definition: edge.H:59
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:27
constexpr T & get(FixedList< T, N > &list) noexcept
Definition: FixedList.H:887
label which(const label vertex) const
Return local index (0,1) of vertex label in edge -1 on failure.
Definition: edgeI.H:133
label collapse()
&#39;Collapse&#39; edge by marking duplicate vertex labels as &#39;-1&#39;, the lower vertex is retained.
Definition: edgeI.H:190
vector vec(const UList< point > &pts) const
Return the vector (from first to second).
Definition: edgeI.H:403
errorManip< error > abort(error &err)
Definition: errorManip.H:139
iterator begin() noexcept
Return an iterator to begin traversing the UList.
Definition: UListI.H:403
Pair< point > box(const UList< point > &pts) const
The enclosing (bounding) box for the edge.
Definition: edgeI.H:448
bool operator==(const edge &other) const
Compare edges for equal content, ignoring orientation.
Definition: edgeI.H:506
const direction noexcept
Definition: scalarImpl.H:265
bool good() const noexcept
True if the vertices are unique and non-negative.
Definition: edgeI.H:116
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
const wordList edge
Standard (finite-area) edge field types (scalar, vector, tensor, etc)
label a() const noexcept
The first vertex.
Definition: edge.H:158
label otherVertex(const label vertex) const
Given one vertex label, return the other one.
Definition: edgeI.H:174
bool insert(const label vertex)
Fill any open slot with the vertex label (if not previously contained in the edge).
Definition: edgeI.H:246
constexpr T & get() noexcept
Element access using compile-time indexing.
Definition: FixedListI.H:136
edge()
Default construct, with invalid vertex labels (-1)
Definition: edgeI.H:62
scalar magSqr(const UList< point > &pts) const
The length (L2-norm) squared of the edge vector.
Definition: edgeI.H:441
bool contains(const label vertex) const noexcept
Return true if the vertex label is contained in the edge.
Definition: edgeI.H:122
point centre(const UList< point > &pts) const
Return centre point (centroid) of the edge.
Definition: edgeI.H:388
label n
static edge sorted(label from, label to)
Create (in ascending order) from two vertex labels.
Definition: edgeI.H:32
iterator end() noexcept
Return an iterator to end traversing the UList.
Definition: UListI.H:447
const T & second() const noexcept
Access the second element.
Definition: Pair.H:177
label max() const noexcept
Return the largest vertex label used by the edge.
Definition: edgeI.H:110
label min() const noexcept
Return the smallest vertex label used by the edge.
Definition: edgeI.H:104
label & operator[](const label i)
Return edge element. Index should be limited to 0/1.
Definition: edgeI.H:480
static int compare(const edge &a, const edge &b)
Compare edges.
Definition: edgeI.H:26
const pointField & pts