face.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration |
5  \\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "face.H"
27 #include "triFace.H"
28 #include "triPointRef.H"
29 #include "mathematicalConstants.H"
30 #include "Swap.H"
31 #include "ConstCirculator.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 const char* const Foam::face::typeName = "face";
36 
37 
38 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
39 
42 {
43  tmp<vectorField> tedges(new vectorField(size()));
44  vectorField& edges = tedges();
45 
46  forAll(*this, i)
47  {
48  label ni = fcIndex(i);
49 
50  point thisPt = points[operator[](i)];
51  point nextPt = points[operator[](ni)];
52 
53  vector vec(nextPt - thisPt);
54  vec /= Foam::mag(vec) + VSMALL;
55 
56  edges[i] = vec;
57  }
58 
59  return tedges;
60 }
61 
62 
63 Foam::scalar Foam::face::edgeCos
64 (
65  const vectorField& edges,
66  const label index
67 ) const
68 {
69  label leftEdgeI = left(index);
70  label rightEdgeI = right(index);
71 
72  // Note negate on left edge to get correct left-pointing edge.
73  return -(edges[leftEdgeI] & edges[rightEdgeI]);
74 }
75 
76 
78 (
79  const pointField& points,
80  const vectorField& edges,
81  scalar& maxAngle
82 ) const
83 {
85 
86  label index = 0;
87  maxAngle = -GREAT;
88 
89  forAll(edges, i)
90  {
91  label leftEdgeI = left(i);
92  label rightEdgeI = right(i);
93 
94  vector edgeNormal = edges[rightEdgeI] ^ edges[leftEdgeI];
95 
96  scalar edgeCos = edges[leftEdgeI] & edges[rightEdgeI];
97  scalar edgeAngle = acos(max(-1.0, min(1.0, edgeCos)));
98 
99  scalar angle;
100 
101  if ((edgeNormal & n) > 0)
102  {
103  // Concave angle.
104  angle = constant::mathematical::pi + edgeAngle;
105  }
106  else
107  {
108  // Convex angle. Note '-' to take into account that rightEdge
109  // and leftEdge are head-to-tail connected.
110  angle = constant::mathematical::pi - edgeAngle;
111  }
112 
113  if (angle > maxAngle)
114  {
115  maxAngle = angle;
116  index = i;
117  }
118  }
119 
120  return index;
121 }
122 
123 
125 (
126  const face::splitMode mode,
127  const pointField& points,
128  label& triI,
129  label& quadI,
130  faceList& triFaces,
131  faceList& quadFaces
132 ) const
133 {
134  label oldIndices = (triI + quadI);
135 
136  if (size() <= 2)
137  {
139  << "Serious problem: asked to split a face with < 3 vertices"
140  << abort(FatalError);
141  }
142  if (size() == 3)
143  {
144  // Triangle. Just copy.
145  if (mode == COUNTTRIANGLE || mode == COUNTQUAD)
146  {
147  triI++;
148  }
149  else
150  {
151  triFaces[triI++] = *this;
152  }
153  }
154  else if (size() == 4)
155  {
156  if (mode == COUNTTRIANGLE)
157  {
158  triI += 2;
159  }
160  if (mode == COUNTQUAD)
161  {
162  quadI++;
163  }
164  else if (mode == SPLITTRIANGLE)
165  {
166  // Start at point with largest internal angle.
167  const vectorField edges(calcEdges(points));
168 
169  scalar minAngle;
170  label startIndex = mostConcaveAngle(points, edges, minAngle);
171 
172  label nextIndex = fcIndex(startIndex);
173  label splitIndex = fcIndex(nextIndex);
174 
175  // Create triangles
176  face triFace(3);
177  triFace[0] = operator[](startIndex);
178  triFace[1] = operator[](nextIndex);
179  triFace[2] = operator[](splitIndex);
180 
181  triFaces[triI++] = triFace;
182 
183  triFace[0] = operator[](splitIndex);
184  triFace[1] = operator[](fcIndex(splitIndex));
185  triFace[2] = operator[](startIndex);
186 
187  triFaces[triI++] = triFace;
188  }
189  else
190  {
191  quadFaces[quadI++] = *this;
192  }
193  }
194  else
195  {
196  // General case. Like quad: search for largest internal angle.
197 
198  const vectorField edges(calcEdges(points));
199 
200  scalar minAngle = 1;
201  label startIndex = mostConcaveAngle(points, edges, minAngle);
202 
203  scalar bisectAngle = minAngle/2;
204  vector rightEdge = edges[right(startIndex)];
205 
206  //
207  // Look for opposite point which as close as possible bisects angle
208  //
209 
210  // split candidate starts two points away.
211  label index = fcIndex(fcIndex(startIndex));
212 
213  label minIndex = index;
214  scalar minDiff = constant::mathematical::pi;
215 
216  for (label i = 0; i < size() - 3; i++)
217  {
218  vector splitEdge
219  (
220  points[operator[](index)]
221  - points[operator[](startIndex)]
222  );
223  splitEdge /= Foam::mag(splitEdge) + VSMALL;
224 
225  const scalar splitCos = splitEdge & rightEdge;
226  const scalar splitAngle = acos(max(-1.0, min(1.0, splitCos)));
227  const scalar angleDiff = fabs(splitAngle - bisectAngle);
228 
229  if (angleDiff < minDiff)
230  {
231  minDiff = angleDiff;
232  minIndex = index;
233  }
234 
235  // Go to next candidate
236  index = fcIndex(index);
237  }
238 
239 
240  // Split into two subshapes.
241  // face1: startIndex to minIndex
242  // face2: minIndex to startIndex
243 
244  // Get sizes of the two subshapes
245  label diff = 0;
246  if (minIndex > startIndex)
247  {
248  diff = minIndex - startIndex;
249  }
250  else
251  {
252  // Folded around
253  diff = minIndex + size() - startIndex;
254  }
255 
256  label nPoints1 = diff + 1;
257  label nPoints2 = size() - diff + 1;
258 
259  // Collect face1 points
260  face face1(nPoints1);
261 
262  index = startIndex;
263  for (label i = 0; i < nPoints1; i++)
264  {
265  face1[i] = operator[](index);
266  index = fcIndex(index);
267  }
268 
269  // Collect face2 points
270  face face2(nPoints2);
271 
272  index = minIndex;
273  for (label i = 0; i < nPoints2; i++)
274  {
275  face2[i] = operator[](index);
276  index = fcIndex(index);
277  }
278 
279  // Split faces
280  face1.split(mode, points, triI, quadI, triFaces, quadFaces);
281  face2.split(mode, points, triI, quadI, triFaces, quadFaces);
282  }
283 
284  return (triI + quadI - oldIndices);
285 }
286 
287 
288 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
289 
291 :
292  labelList(f)
293 {}
294 
295 
296 // * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
297 
298 int Foam::face::compare(const face& a, const face& b)
299 {
300  // Basic rule: we assume that the sequence of labels in each list
301  // will be circular in the same order (but not necessarily in the
302  // same direction or from the same starting point).
303 
304  // Trivial reject: faces are different size
305  label sizeA = a.size();
306  label sizeB = b.size();
307 
308  if (sizeA != sizeB || sizeA == 0)
309  {
310  return 0;
311  }
312  else if (sizeA == 1)
313  {
314  if (a[0] == b[0])
315  {
316  return 1;
317  }
318  else
319  {
320  return 0;
321  }
322  }
323 
324  ConstCirculator<face> aCirc(a);
325  ConstCirculator<face> bCirc(b);
326 
327  // Rotate face b until its element matches the starting element of face a.
328  do
329  {
330  if (aCirc() == bCirc())
331  {
332  // Set bCirc fulcrum to its iterator and increment the iterators
333  bCirc.setFulcrumToIterator();
334  ++aCirc;
335  ++bCirc;
336 
337  break;
338  }
339  } while (bCirc.circulate(CirculatorBase::CLOCKWISE));
340 
341  // If the circulator has stopped then faces a and b do not share a matching
342  // point. Doesn't work on matching, single element face.
343  if (!bCirc.circulate())
344  {
345  return 0;
346  }
347 
348  // Look forwards around the faces for a match
349  do
350  {
351  if (aCirc() != bCirc())
352  {
353  break;
354  }
355  }
356  while
357  (
360  );
361 
362  // If the circulator has stopped then faces a and b matched.
363  if (!aCirc.circulate())
364  {
365  return 1;
366  }
367  else
368  {
369  // Reset the circulators back to their fulcrum
370  aCirc.setIteratorToFulcrum();
371  bCirc.setIteratorToFulcrum();
372  ++aCirc;
373  --bCirc;
374  }
375 
376  // Look backwards around the faces for a match
377  do
378  {
379  if (aCirc() != bCirc())
380  {
381  break;
382  }
383  }
384  while
385  (
388  );
389 
390  // If the circulator has stopped then faces a and b matched.
391  if (!aCirc.circulate())
392  {
393  return -1;
394  }
395 
396  return 0;
397 }
398 
399 
400 bool Foam::face::sameVertices(const face& a, const face& b)
401 {
402  label sizeA = a.size();
403  label sizeB = b.size();
404 
405  // Trivial reject: faces are different size
406  if (sizeA != sizeB)
407  {
408  return false;
409  }
410  // Check faces with a single vertex
411  else if (sizeA == 1)
412  {
413  if (a[0] == b[0])
414  {
415  return true;
416  }
417  else
418  {
419  return false;
420  }
421  }
422 
423  forAll(a, i)
424  {
425  // Count occurrences of a[i] in a
426  label aOcc = 0;
427  forAll(a, j)
428  {
429  if (a[i] == a[j]) aOcc++;
430  }
431 
432  // Count occurrences of a[i] in b
433  label bOcc = 0;
434  forAll(b, j)
435  {
436  if (a[i] == b[j]) bOcc++;
437  }
438 
439  // Check if occurrences of a[i] in a and b are the same
440  if (aOcc != bOcc) return false;
441  }
442 
443  return true;
444 }
445 
446 
447 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
448 
450 {
451  if (size() > 1)
452  {
453  label ci = 0;
454  for (label i=1; i<size(); i++)
455  {
456  if (operator[](i) != operator[](ci))
457  {
458  operator[](++ci) = operator[](i);
459  }
460  }
461 
462  if (operator[](ci) != operator[](0))
463  {
464  ci++;
465  }
466 
467  setSize(ci);
468  }
469 
470  return size();
471 }
472 
473 
475 {
476  const label n = size();
477 
478  if (n > 2)
479  {
480  for (label i=1; i < (n+1)/2; ++i)
481  {
482  Swap(operator[](i), operator[](n-i));
483  }
484  }
485 }
486 
487 
489 {
490  // Calculate the centre by breaking the face into triangles and
491  // area-weighted averaging their centres
492 
493  const label nPoints = size();
494 
495  // If the face is a triangle, do a direct calculation
496  if (nPoints == 3)
497  {
498  return
499  (1.0/3.0)
500  *(
501  points[operator[](0)]
502  + points[operator[](1)]
503  + points[operator[](2)]
504  );
505  }
506 
507 
508  point centrePoint = point::zero;
509  for (label pI=0; pI<nPoints; ++pI)
510  {
511  centrePoint += points[operator[](pI)];
512  }
513  centrePoint /= nPoints;
514 
515  scalar sumA = 0;
516  vector sumAc = vector::zero;
517 
518  for (label pI=0; pI<nPoints; ++pI)
519  {
520  const point& nextPoint = points[operator[]((pI + 1) % nPoints)];
521 
522  // Calculate 3*triangle centre
523  const vector ttc
524  (
525  points[operator[](pI)]
526  + nextPoint
527  + centrePoint
528  );
529 
530  // Calculate 2*triangle area
531  const scalar ta = Foam::mag
532  (
533  (points[operator[](pI)] - centrePoint)
534  ^ (nextPoint - centrePoint)
535  );
536 
537  sumA += ta;
538  sumAc += ta*ttc;
539  }
540 
541  if (sumA > VSMALL)
542  {
543  return sumAc/(3.0*sumA);
544  }
545  else
546  {
547  return centrePoint;
548  }
549 }
550 
551 
553 {
554  const label nPoints = size();
555 
556  // Calculate the normal by summing the face triangle normals.
557  // Changed to deal with small concavity by using a central decomposition
558  //
559 
560  // If the face is a triangle, do a direct calculation to avoid round-off
561  // error-related problems
562  //
563  if (nPoints == 3)
564  {
565  return triPointRef
566  (
567  p[operator[](0)],
568  p[operator[](1)],
569  p[operator[](2)]
570  ).normal();
571  }
572 
573  label pI;
574 
575  point centrePoint = vector::zero;
576  for (pI = 0; pI < nPoints; ++pI)
577  {
578  centrePoint += p[operator[](pI)];
579  }
580  centrePoint /= nPoints;
581 
583 
584  point nextPoint = centrePoint;
585 
586  for (pI = 0; pI < nPoints; ++pI)
587  {
588  if (pI < nPoints - 1)
589  {
590  nextPoint = p[operator[](pI + 1)];
591  }
592  else
593  {
594  nextPoint = p[operator[](0)];
595  }
596 
597  // Note: for best accuracy, centre point always comes last
598  //
599  n += triPointRef
600  (
601  p[operator[](pI)],
602  nextPoint,
603  centrePoint
604  ).normal();
605  }
606 
607  return n;
608 }
609 
610 
612 {
613  // Reverse the label list and return
614  // The starting points of the original and reverse face are identical.
615 
616  const labelList& f = *this;
617  labelList newList(size());
618 
619  newList[0] = f[0];
620 
621  for (label pointI = 1; pointI < newList.size(); pointI++)
622  {
623  newList[pointI] = f[size() - pointI];
624  }
625 
626  return face(xferMove(newList));
627 }
628 
629 
631 {
632  const labelList& f = *this;
633 
634  forAll(f, localIdx)
635  {
636  if (f[localIdx] == globalIndex)
637  {
638  return localIdx;
639  }
640  }
641 
642  return -1;
643 }
644 
645 
646 Foam::scalar Foam::face::sweptVol
647 (
648  const pointField& oldPoints,
649  const pointField& newPoints
650 ) const
651 {
652  // This Optimization causes a small discrepancy between the swept-volume of
653  // opposite faces of complex cells with triangular faces opposing polygons.
654  // It could be used without problem for tetrahedral cells
655  // if (size() == 3)
656  // {
657  // return
658  // (
659  // triPointRef
660  // (
661  // oldPoints[operator[](0)],
662  // oldPoints[operator[](1)],
663  // oldPoints[operator[](2)]
664  // ).sweptVol
665  // (
666  // triPointRef
667  // (
668  // newPoints[operator[](0)],
669  // newPoints[operator[](1)],
670  // newPoints[operator[](2)]
671  // )
672  // )
673  // );
674  // }
675 
676  scalar sv = 0;
677 
678  // Calculate the swept volume by breaking the face into triangles and
679  // summing their swept volumes.
680  // Changed to deal with small concavity by using a central decomposition
681 
682  point centreOldPoint = centre(oldPoints);
683  point centreNewPoint = centre(newPoints);
684 
685  label nPoints = size();
686 
687  for (label pi=0; pi<nPoints-1; ++pi)
688  {
689  // Note: for best accuracy, centre point always comes last
690  sv += triPointRef
691  (
692  centreOldPoint,
693  oldPoints[operator[](pi)],
694  oldPoints[operator[](pi + 1)]
695  ).sweptVol
696  (
698  (
699  centreNewPoint,
700  newPoints[operator[](pi)],
701  newPoints[operator[](pi + 1)]
702  )
703  );
704  }
705 
706  sv += triPointRef
707  (
708  centreOldPoint,
709  oldPoints[operator[](nPoints-1)],
710  oldPoints[operator[](0)]
711  ).sweptVol
712  (
714  (
715  centreNewPoint,
716  newPoints[operator[](nPoints-1)],
717  newPoints[operator[](0)]
718  )
719  );
720 
721  return sv;
722 }
723 
724 
726 (
727  const pointField& p,
728  const point& refPt,
729  scalar density
730 ) const
731 {
732  // If the face is a triangle, do a direct calculation
733  if (size() == 3)
734  {
735  return triPointRef
736  (
737  p[operator[](0)],
738  p[operator[](1)],
739  p[operator[](2)]
740  ).inertia(refPt, density);
741  }
742 
743  const point ctr = centre(p);
744 
745  tensor J = tensor::zero;
746 
747  forAll(*this, i)
748  {
749  J += triPointRef
750  (
751  p[operator[](i)],
752  p[operator[](fcIndex(i))],
753  ctr
754  ).inertia(refPt, density);
755  }
756 
757  return J;
758 }
759 
760 
762 {
763  const labelList& points = *this;
764 
765  edgeList e(points.size());
766 
767  for (label pointI = 0; pointI < points.size() - 1; ++pointI)
768  {
769  e[pointI] = edge(points[pointI], points[pointI + 1]);
770  }
771 
772  // Add last edge
773  e.last() = edge(points.last(), points[0]);
774 
775  return e;
776 }
777 
778 
780 {
781  forAll(*this, i)
782  {
783  if (operator[](i) == e.start())
784  {
785  if (operator[](rcIndex(i)) == e.end())
786  {
787  // Reverse direction
788  return -1;
789  }
790  else if (operator[](fcIndex(i)) == e.end())
791  {
792  // Forward direction
793  return 1;
794  }
795 
796  // No match
797  return 0;
798  }
799  else if (operator[](i) == e.end())
800  {
801  if (operator[](rcIndex(i)) == e.start())
802  {
803  // Forward direction
804  return 1;
805  }
806  else if (operator[](fcIndex(i)) == e.start())
807  {
808  // Reverse direction
809  return -1;
810  }
811 
812  // No match
813  return 0;
814  }
815  }
816 
817  // Not found
818  return 0;
819 }
820 
821 
822 // Number of triangles directly known from number of vertices
824 {
825  return nTriangles();
826 }
827 
828 
830 (
831  const pointField& points,
832  label& triI,
833  faceList& triFaces
834 ) const
835 {
836  label quadI = 0;
837  faceList quadFaces;
838 
839  return split(SPLITTRIANGLE, points, triI, quadI, triFaces, quadFaces);
840 }
841 
842 
844 (
845  const pointField& points,
846  label& triI,
847  label& quadI
848 ) const
849 {
850  faceList triFaces;
851  faceList quadFaces;
852 
853  return split(COUNTQUAD, points, triI, quadI, triFaces, quadFaces);
854 }
855 
856 
858 (
859  const pointField& points,
860  label& triI,
861  label& quadI,
862  faceList& triFaces,
863  faceList& quadFaces
864 ) const
865 {
866  return split(SPLITQUAD, points, triI, quadI, triFaces, quadFaces);
867 }
868 
869 
871 {
872  const edgeList& eds = f.edges();
873 
874  label longestEdgeI = -1;
875  scalar longestEdgeLength = -SMALL;
876 
877  forAll(eds, edI)
878  {
879  scalar edgeLength = eds[edI].mag(pts);
880 
881  if (edgeLength > longestEdgeLength)
882  {
883  longestEdgeI = edI;
884  longestEdgeLength = edgeLength;
885  }
886  }
887 
888  return longestEdgeI;
889 }
890 
891 
892 // ************************************************************************* //
Foam::longestEdge
label longestEdge(const face &f, const pointField &pts)
Find the longest edge on a face. Face point labels index into pts.
Definition: face.C:870
Foam::face::normal
vector normal(const pointField &) const
Vector normal; magnitude is equal to area of face.
Definition: face.C:552
Foam::face::typeName
static const char *const typeName
Definition: face.H:143
Foam::Tensor
Templated 3D tensor derived from VectorSpace adding construction from 9 components,...
Definition: complexI.H:224
setSize
points setSize(newPointi)
Foam::face::edgeDirection
int edgeDirection(const edge &) const
Return the edge direction on the face.
Definition: face.C:779
mathematicalConstants.H
Foam::face::reverseFace
face reverseFace() const
Return face with reverse direction.
Definition: face.C:611
Foam::face::trianglesQuads
label trianglesQuads(const pointField &points, label &triI, label &quadI, faceList &triFaces, faceList &quadFaces) const
Split into triangles and quads.
Definition: face.C:858
Foam::Vector< scalar >::zero
static const Vector zero
Definition: Vector.H:80
p
p
Definition: pEqn.H:62
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:118
Foam::ConstCirculator
Walks over a container as if it were circular. The container must have the following members defined:
Definition: ConstCirculator.H:91
Foam::face::split
label split(const splitMode mode, const pointField &points, label &triI, label &quadI, faceList &triFaces, faceList &quadFaces) const
Split face into triangles or triangles&quads.
Definition: face.C:125
Foam::face::centre
point centre(const pointField &) const
Centre point of face.
Definition: face.C:488
Foam::edge
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
Definition: edge.H:58
face.H
ConstCirculator.H
Foam::ConstCirculator::setIteratorToFulcrum
void setIteratorToFulcrum()
Set the iterator to the current position of the fulcrum.
Definition: ConstCirculatorI.H:126
Foam::face::nTriangles
label nTriangles() const
Number of triangles after splitting.
Definition: faceI.H:130
Foam::face::triangles
label triangles(const pointField &points, label &triI, faceList &triFaces) const
Split into triangles using existing points.
Definition: face.C:830
Foam::face::edgeCos
scalar edgeCos(const vectorField &edges, const label index) const
Cos between neighbouring edges.
Definition: face.C:64
triPointRef.H
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
triFace.H
Foam::face::sweptVol
scalar sweptVol(const pointField &oldPoints, const pointField &newPoints) const
Return the volume swept out by the face when its points move.
Definition: face.C:647
Foam::mode
mode_t mode(const fileName &)
Return the file mode.
Definition: POSIX.C:573
Foam::face::which
label which(const label globalIndex) const
Navigation through face vertices.
Definition: face.C:630
Foam::vectorField
Field< vector > vectorField
Specialisation of Field<T> for vector.
Definition: primitiveFieldsFwd.H:49
Swap.H
Swap its arguments.
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
Foam::diff
scalar diff(const triad &A, const triad &B)
Return a quantity of the difference between two triads.
Definition: triad.C:407
Foam::triangle
A triangle primitive used to calculate face normals and swept volumes.
Definition: triangle.H:59
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::face::calcEdges
tmp< vectorField > calcEdges(const pointField &points) const
Construct list of edge vectors for face.
Definition: face.C:41
Foam::label
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
Foam::face::nTrianglesQuads
label nTrianglesQuads(const pointField &points, label &nTris, label &nQuads) const
Number of triangles and quads after splitting.
Definition: face.C:844
Foam::constant::physicoChemical::b
const dimensionedScalar b
Wien displacement law constant: default SI units: [m.K].
Definition: createFields.H:28
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::face::inertia
tensor inertia(const pointField &, const point &refPt=vector::zero, scalar density=1.0) const
Return the inertia tensor, with optional reference.
Definition: face.C:726
Foam::face::mostConcaveAngle
label mostConcaveAngle(const pointField &points, const vectorField &edges, scalar &edgeCos) const
Find index of largest internal angle on face.
Definition: face.C:78
Foam::FatalError
error FatalError
Foam::face::flip
void flip()
Flip the face in-place.
Definition: face.C:474
Foam::face::edges
edgeList edges() const
Return edges in face point ordering,.
Definition: face.C:761
Foam::Tensor::zero
static const Tensor zero
Definition: Tensor.H:80
Foam::abort
errorManip< error > abort(error &err)
Definition: errorManip.H:131
Foam::globalIndex
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Definition: globalIndex.H:63
Foam::face::points
pointField points(const pointField &) const
Return the points corresponding to this face.
Definition: faceI.H:80
Foam::e
const double e
Elementary charge.
Definition: doubleFloat.H:94
Foam::List::size
label size() const
Return the number of elements in the UList.
Foam::max
dimensioned< Type > max(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::CirculatorBase::CLOCKWISE
@ CLOCKWISE
Definition: CirculatorBase.H:54
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
Foam::xferMove
Xfer< T > xferMove(T &)
Construct by transferring the contents of the arg.
Foam::triFace
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition: triFace.H:68
f
labelList f(nPoints)
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::face::splitMode
splitMode
Enumeration listing the modes for split()
Definition: face.H:109
Foam::acos
dimensionedScalar acos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:259
points
const pointField & points
Definition: gmvOutputHeader.H:1
Foam::constant::mathematical::pi
const scalar pi(M_PI)
Foam::face::collapse
label collapse()
Collapse face by removing duplicate point labels.
Definition: face.C:449
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::ConstCirculator::setFulcrumToIterator
void setFulcrumToIterator()
Set the fulcrum to the current position of the iterator.
Definition: ConstCirculatorI.H:119
Foam::face::compare
static int compare(const face &, const face &)
Compare faces.
Definition: face.C:298
Foam::face::face
face()
Construct null.
Definition: faceI.H:44
Foam::List::size
void size(const label)
Override size to be inconsistent with allocated storage.
Foam::face::sameVertices
static bool sameVertices(const face &, const face &)
Return true if the faces have the same vertices.
Definition: face.C:400
Foam::Swap
void Swap(T &a, T &b)
Definition: Swap.H:43
Foam::CirculatorBase::ANTICLOCKWISE
@ ANTICLOCKWISE
Definition: CirculatorBase.H:55
Foam::min
dimensioned< Type > min(const dimensioned< Type > &, const dimensioned< Type > &)
Foam::ConstCirculator::circulate
bool circulate(const CirculatorBase::direction dir=NONE)
Circulate around the list in the given direction.
Definition: ConstCirculatorI.H:101
triFace
face triFace(3)
normal
A normal distribution model.
Foam::triPointRef
triangle< point, const point & > triPointRef
Definition: triangle.H:75