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 -------------------------------------------------------------------------------
13 License
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 
35 int Foam::cutCell::debug = 0;
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 // ************************************************************************* //
cutCell.H
p
volScalarField & p
Definition: createFieldRefs.H:8
Foam::Zero
static constexpr const zero Zero
Global zero (0)
Definition: zero.H:131
Foam::DynamicList< point >
Foam::atan2
dimensionedScalar atan2(const dimensionedScalar &x, const dimensionedScalar &y)
Definition: dimensionedScalar.C:312
Foam::cutCell::calcCellData
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
Foam::Vector::normalise
Vector< Cmpt > & normalise()
Normalise the vector by its magnitude.
Definition: VectorI.H:123
Foam::sign
dimensionedScalar sign(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:166
Foam::DynamicList::clear
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
Definition: DynamicListI.H:391
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
nPoints
label nPoints
Definition: gmvOutputHeader.H:2
n
label n
Definition: TABSMDCalcMethod2.H:31
Foam::fac::average
tmp< GeometricField< Type, faPatchField, areaMesh > > average(const GeometricField< Type, faePatchField, edgeMesh > &ssf)
Area-weighted average a edgeField creating a areaField.
Definition: facAverage.C:47
Foam::DynamicList::append
DynamicList< T, SizeMin > & append(const T &val)
Append an element to the end of this list.
Definition: DynamicListI.H:511
Foam::max
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Definition: hashSets.C:47
Foam::cutCell::debug
static int debug
Definition: cutCell.H:95
Foam::cutCell::calcIsoFacePointsFromEdges
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
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
Foam::fvMesh
Mesh data needed to do the Finite Volume discretisation.
Definition: fvMesh.H:85
Foam::cutCell::cutCell
cutCell(const fvMesh &mesh)
Construct from fvMesh.
Definition: cutCell.C:41
Foam::normalised
VectorSpace< Form, Cmpt, Ncmpts > normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:487
Foam::cutCell::calcGeomDataCutFace
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
Foam::constant::mathematical::pi
constexpr scalar pi(M_PI)
Foam::Vector< scalar >
Foam::List< label >
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::constant::electromagnetic::e
const dimensionedScalar e
Elementary charge.
Definition: createFields.H:11
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::sortedOrder
labelList sortedOrder(const UList< T > &input)
Return the (stable) sort order for the list.