cutCell.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 OpenCFD Ltd.
9 Copyright (C) 2016-2017 DHI
10 Copyright (C) 2018-2019 Johan Roenby
11 Copyright (C) 2019-2020 DLR
12-------------------------------------------------------------------------------
13License
14 This file is part of OpenFOAM.
15
16 OpenFOAM is free software: you can redistribute it and/or modify it
17 under the terms of the GNU General Public License as published by
18 the Free Software Foundation, either version 3 of the License, or
19 (at your option) any later version.
20
21 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
22 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
24 for more details.
25
26 You should have received a copy of the GNU General Public License
27 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
28
29\*---------------------------------------------------------------------------*/
30
31#include "cutCell.H"
32
33// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
34
36
37
38// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
39
41(
42 const fvMesh& mesh
43)
44{
45 // required as otherwise setAlphaFields might not work in parallel
46 mesh.C();
47 mesh.V();
48 mesh.Cf();
49 mesh.magSf();
50}
51
52
53// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
54
56(
57 const DynamicList<point>& cutFaceCentres,
58 const DynamicList<vector>& cutFaceAreas,
59 vector& subCellCentre,
60 scalar& subCellVolume
61)
62{
63 // Clear the fields for accumulation
64 subCellCentre = Zero;
65 subCellVolume = Zero;
66
67 // first estimate the approximate cell centre as the average of
68 // face centres
69
70 vector cEst = average(cutFaceCentres);
71
72 // Contribution to subcell centre and volume from cut faces
73 forAll(cutFaceCentres, facei)
74 {
75 // Calculate 3*face-pyramid volume
76 scalar pyr3Vol = max(
77 mag(cutFaceAreas[facei] & (cutFaceCentres[facei] - cEst)), VSMALL);
78
79 // Calculate face-pyramid centre
80 vector pc = 0.75 * cutFaceCentres[facei] + 0.25 * cEst;
81
82 // Accumulate volume-weighted face-pyramid centre
83 subCellCentre += pyr3Vol * pc;
84
85 // Accumulate face-pyramid volume
86 subCellVolume += pyr3Vol;
87 }
88
89 subCellCentre /= subCellVolume;
90 subCellVolume /= 3; // formula of pyramid
91}
92
93
95(
96 const DynamicList<DynamicList<point>>& faceEdges,
97 const vector& subCellCentre,
98 vector& faceArea,
99 vector& faceCentre
100)
101{
102 // Initial guess of face centre from edge points
103 point fCentre{Zero};
104 label nEdgePoints{0};
105 for (const DynamicList<point>& edgePoints : faceEdges)
106 {
107 for (const point& p : edgePoints)
108 {
109 fCentre += p;
110 nEdgePoints++;
111 }
112 }
113 if (nEdgePoints > 0)
114 {
115 fCentre /= nEdgePoints;
116 }
117
118 vector sumN{Zero};
119 scalar sumA{0};
120 vector sumAc{Zero};
121
122 // calculate area and centre
123 forAll(faceEdges, ei)
124 {
125 const DynamicList<point>& edgePoints = faceEdges[ei];
126 const label nPoints = edgePoints.size();
127 for (label pi = 0; pi < nPoints - 1; pi++)
128 {
129 const point& nextPoint = edgePoints[pi + 1];
130
131 vector c = edgePoints[pi] + nextPoint + fCentre;
132 vector n =
133 (nextPoint - edgePoints[pi]) ^ (fCentre - edgePoints[pi]);
134 scalar a = mag(n);
135
136 // Edges may have different orientation
137 sumN += Foam::sign(n & sumN) * n;
138 sumA += a;
139 sumAc += a * c;
140 }
141 }
142
143 // This is to deal with zero-area faces. Mark very small faces
144 // to be detected in e.g., processorPolyPatch.
145 if (sumA < ROOTVSMALL)
146 {
147 faceCentre = fCentre;
148 faceArea = Zero;
149 }
150 else
151 {
152 faceCentre = (1.0/3.0)*sumAc/sumA;
153 faceArea = 0.5*sumN;
154 }
155
156 // Check faceArea direction and change if not pointing in the subcell
157 if ((faceArea & (faceCentre - subCellCentre)) >= 0)
158 {
159 faceArea *= (-1);
160 }
161}
162
163
165(
166 const vector& faceArea,
167 const vector& faceCentre,
168 const DynamicList<DynamicList<point>>& faceEdges,
169 DynamicList<point>& facePoints
170)
171{
172 if (mag(faceArea) < VSMALL)
173 {
174 facePoints.clear();
175 return;
176 }
177 const vector zhat = normalised(faceArea);
178 vector xhat = faceEdges[0][0] - faceCentre;
179 xhat = (xhat - (xhat & zhat)*zhat);
180 xhat.normalise();
181 if (mag(xhat) == 0)
182 {
183 facePoints.clear();
184 return;
185 }
186 vector yhat = normalised(zhat ^ xhat);
187 if (mag(yhat) == 0)
188 {
189 facePoints.clear();
190 return;
191 }
192 yhat.normalise();
193
194 // Calculating all intersection points
195 DynamicList<point> unsortedFacePoints(3 * faceEdges.size());
196 DynamicList<scalar> unsortedFacePointAngles(3 * faceEdges.size());
197 for (const DynamicList<point>& edgePoints : faceEdges)
198 {
199 for (const point& p : edgePoints)
200 {
201 unsortedFacePoints.append(p);
202 unsortedFacePointAngles.append
203 (
205 (
206 ((p - faceCentre) & yhat),
207 ((p - faceCentre) & xhat)
208 )
209 );
210 }
211 }
212
213 // Sorting face points by angle and inserting into facePoints
214 labelList order(Foam::sortedOrder(unsortedFacePointAngles));
215 facePoints.append(unsortedFacePoints[order[0]]);
216 for (label pi = 1; pi < order.size(); ++pi)
217 {
218 if
219 (
220 mag
221 (
222 unsortedFacePointAngles[order[pi]]
223 - unsortedFacePointAngles[order[pi - 1]]
224 ) > 1e-8)
225 {
226 facePoints.append(unsortedFacePoints[order[pi]]);
227 }
228 }
229}
230
231
232// ************************************************************************* //
label n
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Definition: DynamicList.H:72
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:391
void append(const T &val)
Copy append an element to the end of this list.
Definition: DynamicListI.H:503
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
Vector< Cmpt > & normalise(const scalar tol=ROOTVSMALL)
Inplace normalise the vector by its magnitude.
Definition: VectorI.H:123
Service routines for cutting a cell, celli, of an fvMesh, mesh_, at its intersection with a surface.
Definition: cutCell.H:60
static void calcCellData(const DynamicList< point > &cutFaceCentres, const DynamicList< vector > &cutFaceAreas, vector &subCellCentre, scalar &subCellVolume)
Calculates volume and centre of the cutted cell.
Definition: cutCell.C:56
static int debug
Definition: cutCell.H:95
static void calcIsoFacePointsFromEdges(const vector &faceArea, const vector &faceCentre, const DynamicList< DynamicList< point > > &faceEdges, DynamicList< point > &facePoints)
Calculates the point of the cutting face.
Definition: cutCell.C:165
static void calcGeomDataCutFace(const DynamicList< DynamicList< point > > &faceEdges, const vector &subCellCentre, vector &faceArea, vector &faceCentre)
Calculates area and centre of the cutting face.
Definition: cutCell.C:95
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:91
const volVectorField & C() const
Return cell centres as volVectorField.
const DimensionedField< scalar, volMesh > & V() const
Return cell volumes.
const surfaceVectorField & Cf() const
Return face centres as surfaceVectorField.
const surfaceScalarField & magSf() const
Return cell face area magnitudes.
volScalarField & p
dynamicFvMesh & mesh
label nPoints
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
dimensionedScalar sign(const dimensionedScalar &ds)
quaternion normalised(const quaternion &q)
Return the normalised (unit) quaternion of the given quaternion.
Definition: quaternionI.H:680
dimensioned< Type > average(const DimensionedField< Type, GeoMesh > &df)
dimensionedScalar atan2(const dimensionedScalar &x, const dimensionedScalar &y)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
volScalarField & e
Definition: createFields.H:11
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333