cutFace.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 | www.openfoam.com
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8  Copyright (C) 2016-2017 DHI
9  Copyright (C) 2018-2019 Johan Roenby
10  Copyright (C) 2019-2020 DLR
11 -------------------------------------------------------------------------------
12 License
13  This file is part of OpenFOAM.
14 
15  OpenFOAM is free software: you can redistribute it and/or modify it
16  under the terms of the GNU General Public License as published by
17  the Free Software Foundation, either version 3 of the License, or
18  (at your option) any later version.
19 
20  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
21  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
22  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23  for more details.
24 
25  You should have received a copy of the GNU General Public License
26  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
27 
28 \*---------------------------------------------------------------------------*/
29 
30 #include "cutFace.H"
31 #include "triangle.H"
32 
33 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34 
35 int Foam::cutFace::debug = 0;
36 
37 // * * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * *
38 
40 (
41  const label faceI,
42  const scalarList& pointStatus,
43  label firstFullySubmergedPoint,
44  DynamicList<point>& subFacePoints,
45  DynamicList<point>& surfacePoints,
46  label& faceStatus,
47  vector& subFaceCentre,
48  vector& subFaceArea
49 )
50 {
51  const pointField& points = mesh_.points();
52  const face& f = mesh_.faces()[faceI];
53 
54  if (firstFullySubmergedPoint == -1) // is in gasPhase
55  {
56  faceStatus = 1;
57  subFaceCentre = Zero;
58  subFaceArea = Zero;
59  return;
60  }
61 
62  // loop face and append the cuts
63  // loop starts at firstFullySubmergedPoint
64  for
65  (
66  label i = firstFullySubmergedPoint;
67  i < firstFullySubmergedPoint + f.size();
68  ++i
69  )
70  {
71  // max two points are appended during one cycle
72  label idx = i % f.size();
73  label nextIdx = (i + 1) % f.size();
74 
75  if (pointStatus[idx] > 0) // append fluid point
76  {
77  subFacePoints.append(points[f[idx]]);
78  }
79  else if (pointStatus[idx] == 0) // append cut point
80  {
81  subFacePoints.append(points[f[idx]]);
82  surfacePoints.append(points[f[idx]]);
83  }
84 
85  if
86  (
87  (pointStatus[idx] < 0 && pointStatus[nextIdx] > 0)
88  || (pointStatus[idx] > 0 && pointStatus[nextIdx] < 0)
89  ) // cut on edge cut Value is zero
90  {
91  label nextP = f.nextLabel(idx);
92  vector dir = points[nextP] - points[f[idx]];
93  scalar weight =
94  (0.0 - pointStatus[idx]) /
95  (pointStatus[nextIdx] - pointStatus[idx]); // cutValue is zero
96 
97  point p = points[f[idx]] + weight * dir;
98 
99  subFacePoints.append(p);
100  surfacePoints.append(p);
101  }
102  }
103 
104  if (subFacePoints.size() >= 3)
105  {
106  faceStatus = 0;
107  calcSubFaceCentreAndArea(subFacePoints, subFaceCentre, subFaceArea);
108  }
109  else
110  {
111  faceStatus = -1;
112  }
113 }
114 
115 
117 (
118  const label faceI,
119  const scalarList& pointStatus,
120  const scalarList& weights,
121  label firstFullySubmergedPoint,
122  DynamicList<point>& subFacePoints,
123  DynamicList<point>& surfacePoints,
124  label& faceStatus,
125  vector& subFaceCentre,
126  vector& subFaceArea
127 )
128 {
129  const pointField& points = mesh_.points();
130  const face& f = mesh_.faces()[faceI];
131 
132  if (firstFullySubmergedPoint == -1) // is in gasPhase
133  {
134  faceStatus = 1;
135  subFaceCentre = Zero;
136  subFaceArea = Zero;
137  return;
138  }
139 
140  // loop face and append the cuts
141  // loop starts at firstFullySubmergedPoint
142  for
143  (
144  label i = firstFullySubmergedPoint;
145  i < firstFullySubmergedPoint + f.size();
146  ++i
147  )
148  {
149  // max two points are appended during one cycle
150  label idx = i % f.size();
151  label nextIdx = (i + 1) % f.size();
152 
153  if (pointStatus[idx] > 0) // append fluid point
154  {
155  subFacePoints.append(points[f[idx]]);
156  }
157  else if (pointStatus[idx] == 0) // append cut point
158  {
159  subFacePoints.append(points[f[idx]]);
160  surfacePoints.append(points[f[idx]]);
161  }
162 
163  if
164  (
165  (pointStatus[idx] < 0 && pointStatus[nextIdx] > 0)
166  || (pointStatus[idx] > 0 && pointStatus[nextIdx] < 0)
167  ) // cut on edge cut Value is zero
168  {
169  label nextP = f.nextLabel(idx);
170  vector dir = points[nextP] - points[f[idx]];
171 
172  point p = points[f[idx]] + weights[idx] * dir;
173 
174  subFacePoints.append(p);
175  surfacePoints.append(p);
176  }
177  }
178 
179  if (subFacePoints.size() >= 3)
180  {
181  faceStatus = 0;
182  calcSubFaceCentreAndArea(subFacePoints, subFaceCentre, subFaceArea);
183  }
184  else
185  {
186  faceStatus = -1;
187  }
188 }
189 
190 
192 (
193  const face& f,
194  const pointField& points,
195  const scalarList& pointStatus,
196  label firstFullySubmergedPoint,
197  DynamicList<point>& subFacePoints,
198  DynamicList<point>& surfacePoints,
199  label& faceStatus,
200  vector& subFaceCentre,
201  vector& subFaceArea
202 )
203 {
204  if (firstFullySubmergedPoint == -1) // in Gas
205  {
206  faceStatus = 1;
207  subFaceCentre = Zero;
208  subFaceArea = Zero;
209  return;
210  }
211 
212  // loop face and append the cuts
213  for
214  (
215  label i = firstFullySubmergedPoint;
216  i < firstFullySubmergedPoint + f.size();
217  ++i
218  )
219  {
220  // max two points are appended during one cycle
221  label idx = i % f.size();
222  label nextIdx = (i + 1) % f.size();
223 
224  if (pointStatus[idx] > 0) // append fluid point
225  {
226  subFacePoints.append(points[f[idx]]);
227  }
228  else if (pointStatus[idx] == 0) // append cut point
229  {
230  subFacePoints.append(points[f[idx]]);
231  surfacePoints.append(points[f[idx]]);
232  }
233 
234  if
235  (
236  (pointStatus[idx] < 0 && pointStatus[nextIdx] > 0)
237  || (pointStatus[idx] > 0 && pointStatus[nextIdx] < 0)
238  )
239  {
240  label nextP = f.nextLabel(idx);
241  vector dir = points[nextP] - points[f[idx]];
242  scalar weight =
243  (0.0 - pointStatus[idx]) /
244  (pointStatus[nextIdx] - pointStatus[idx]);
245 
246  point p = points[f[idx]] + weight * dir;
247 
248  subFacePoints.append(p);
249  surfacePoints.append(p);
250  }
251  }
252 
253  if (subFacePoints.size() >= 3)
254  {
255  faceStatus = 0;
256  calcSubFaceCentreAndArea(subFacePoints, subFaceCentre, subFaceArea);
257  }
258  else
259  {
260  faceStatus = -1;
261  }
262 }
263 
264 
266 (
267  DynamicList<point>& subFacePoints,
268  vector& subFaceCentre,
269  vector& subFaceArea
270 )
271 {
272  const label nPoints = subFacePoints.size();
273 
274  // If the face is a triangle, do a direct calculation for efficiency
275  // and to avoid round-off error-related problems
276  if (nPoints == 3)
277  {
278  subFaceCentre = triPointRef::centre
279  (
280  subFacePoints[0],
281  subFacePoints[1],
282  subFacePoints[2]
283  );
284 
285  subFaceArea = triPointRef::areaNormal
286  (
287  subFacePoints[0],
288  subFacePoints[1],
289  subFacePoints[2]
290  );
291  }
292  else if (nPoints > 0)
293  {
294  vector sumN{Zero};
295  scalar sumA{0};
296  vector sumAc{Zero};
297 
298  point fCentre = subFacePoints[0];
299  // initial guess of centre as average of subFacePoints
300  for (label pi = 1; pi < nPoints; pi++)
301  {
302  fCentre += subFacePoints[pi];
303  }
304 
305  fCentre /= nPoints;
306 
307  // loop sub triangles
308  for (label pi = 0; pi < nPoints; pi++)
309  {
310  const point& nextPoint = subFacePoints[(pi + 1) % nPoints];
311 
312  vector c = subFacePoints[pi] + nextPoint + fCentre;
313  vector n =
314  (nextPoint - subFacePoints[pi]) ^ (fCentre - subFacePoints[pi]);
315  scalar a = mag(n);
316 
317  sumN += n;
318  sumA += a;
319  sumAc += a * c;
320  }
321 
322  // This is to deal with zero-area faces. Mark very small faces
323  // to be detected in e.g., processorPolyPatch.
324  if (sumA < ROOTVSMALL)
325  {
326  subFaceCentre = fCentre;
327  subFaceArea = Zero;
328  }
329  else
330  {
331  subFaceCentre = (1.0 / 3.0) * sumAc / sumA;
332  subFaceArea = 0.5 * sumN;
333  }
334  }
335 }
336 
337 
338 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
339 
341 (
342  const fvMesh& mesh
343 )
344 :
345  mesh_(mesh)
346 {}
347 
348 
349 // ************************************************************************* //
List< scalar > scalarList
List of scalar.
Definition: scalarList.H:32
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:116
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:68
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void append(const T &val)
Append an element at the end of the list.
Definition: List.H:517
void calcSubFaceCentreAndArea(DynamicList< point > &subFacePoints, vector &subFaceCentre, vector &subFaceArea)
Calculates centre and normal of the face.
Definition: cutFace.C:259
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1078
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:38
dynamicFvMesh & mesh
const pointField & points
label nPoints
Point centre() const
Return centre (centroid)
Definition: triangleI.H:126
constexpr scalar pi(M_PI)
Vector< scalar > vector
Definition: vector.H:57
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicList.H:584
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1103
static int debug
Definition: cutFace.H:143
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
labelList f(nPoints)
cutFace(const fvMesh &mesh)
Construct from fvMesh.
Definition: cutFace.C:334
vector point
Point is a vector.
Definition: point.H:37
const dimensionedScalar c
Speed of light in a vacuum.
label n
volScalarField & p
void calcSubFace(const label faceI, const scalarList &pointStatus, label firstFullySubmergedPoint, DynamicList< point > &subFacePoints, DynamicList< point > &surfacePoints, label &faceStatus, vector &subFaceCentre, vector &subFaceArea)
Calculate cut points along edges of face with pointStatus, pointfield and computes geometric informat...
Definition: cutFace.C:33
vector areaNormal() const
The area normal - with magnitude equal to area of triangle.
Definition: triangleI.H:151
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:127