Loading...
Searching...
No Matches
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-------------------------------------------------------------------------------
12License
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"
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
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;
334 }
335}
336
337
338// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
339
341(
342 const fvMesh& mesh
343)
344:
345 mesh_(mesh)
346{}
347
348
349// ************************************************************************* //
constexpr scalar pi(M_PI)
label n
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition DynamicList.H:68
void append(const T &val)
Copy append an element to the end of this list.
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
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
cutFace(const fvMesh &mesh)
Construct from fvMesh.
Definition cutFace.C:334
void calcSubFaceCentreAndArea(DynamicList< point > &subFacePoints, vector &subFaceCentre, vector &subFaceArea)
Calculates centre and normal of the face.
Definition cutFace.C:259
static int debug
Definition cutFace.H:143
A face is a list of labels corresponding to mesh vertices.
Definition face.H:71
Mesh data needed to do the Finite Volume discretisation.
Definition fvMesh.H:85
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
volScalarField & p
dynamicFvMesh & mesh
const pointField & points
label nPoints
const dimensionedScalar c
Speed of light in a vacuum.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
vector point
Point is a vector.
Definition point.H:37
static constexpr const zero Zero
Global zero (0).
Definition zero.H:127
vectorField pointField
pointField is a vectorField.
Vector< scalar > vector
Definition vector.H:57
List< scalar > scalarList
List of scalar.
Definition scalarList.H:32
labelList f(nPoints)