faceTemplates.C
Go to the documentation of this file.
1 /*---------------------------------------------------------------------------*\
2  ========= |
3  \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4  \\ / O peration | Website: https://openfoam.org
5  \\ / A nd | Copyright (C) 2011-2021 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 "DynamicList.H"
28 
29 // * * * * * * * * * * * * * * * Static Functions * * * * * * * * * * * * * //
30 
31 template<class PointField>
33 {
34  // If the face is a triangle, do a direct calculation
35  if (ps.size() == 3)
36  {
37  return (1.0/3.0)*(ps[0] + ps[1] + ps[2]);
38  }
39 
40  // For more complex faces, decompose into triangles ...
41 
42  // Compute an estimate of the centre as the average of the points
43  point pAvg = Zero;
44  forAll(ps, pi)
45  {
46  pAvg += ps[pi];
47  }
48  pAvg /= ps.size();
49 
50  // Compute the face area normal and unit normal by summing up the
51  // normals of the triangles formed by connecting each edge to the
52  // point average.
53  vector sumA = Zero;
54  forAll(ps, pi)
55  {
56  const point& p = ps[pi];
57  const point& pNext = ps[ps.fcIndex(pi)];
58 
59  const vector a = (pNext - p)^(pAvg - p);
60 
61  sumA += a;
62  }
63  const vector sumAHat = normalised(sumA);
64 
65  // Compute the area-weighted sum of the triangle centres. Note use
66  // the triangle area projected in the direction of the face normal
67  // as the weight, *not* the triangle area magnitude. Only the
68  // former makes the calculation independent of the initial estimate.
69  scalar sumAn = 0;
70  vector sumAnc = Zero;
71  forAll(ps, pi)
72  {
73  const point& p = ps[pi];
74  const point& pNext = ps[ps.fcIndex(pi)];
75 
76  const vector a = (pNext - p)^(pAvg - p);
77  const vector c = p + pNext + pAvg;
78 
79  const scalar an = a & sumAHat;
80 
81  sumAn += an;
82  sumAnc += an*c;
83  }
84 
85  // Complete calculating centres and areas. If the face is too small
86  // for the sums to be reliably divided then just set the centre to
87  // the initial estimate.
88  if (sumAn > vSmall)
89  {
90  return (1.0/3.0)*sumAnc/sumAn;
91  }
92  else
93  {
94  return pAvg;
95  }
96 }
97 
98 
99 template<class PointField>
101 {
102  // If the face is a triangle, do a direct calculation
103  if (ps.size() == 3)
104  {
105  return 0.5*((ps[1] - ps[0])^(ps[2] - ps[0]));
106  }
107 
108  // For more complex faces, decompose into triangles ...
109 
110  // Compute an estimate of the centre as the average of the points
111  point pAvg = Zero;
112  forAll(ps, pi)
113  {
114  pAvg += ps[pi];
115  }
116  pAvg /= ps.size();
117 
118  // Compute the face area normal and unit normal by summing up the
119  // normals of the triangles formed by connecting each edge to the
120  // point average.
121  vector sumA = Zero;
122  forAll(ps, pi)
123  {
124  const point& p = ps[pi];
125  const point& pNext = ps[ps.fcIndex(pi)];
126 
127  const vector a = (pNext - p)^(pAvg - p);
128 
129  sumA += a;
130  }
131 
132  return 0.5*sumA;
133 }
134 
135 
136 
137 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
138 
139 template<class Type>
141 (
142  const pointField& ps,
143  const Field<Type>& fld
144 ) const
145 {
146  // If the face is a triangle, do a direct calculation
147  if (size() == 3)
148  {
149  return
150  (1.0/3.0)
151  *(
152  fld[operator[](0)]
153  + fld[operator[](1)]
154  + fld[operator[](2)]
155  );
156  }
157 
158  // For more complex faces, decompose into triangles ...
159 
160  // Compute an estimate of the centre and the field average as the average
161  // of the point values
162  point pAvg = Zero;
163  Type fldAvg = Zero;
164  forAll(*this, pi)
165  {
166  pAvg += ps[operator[](pi)];
167  fldAvg += fld[operator[](pi)];
168  }
169  pAvg /= size();
170  fldAvg /= size();
171 
172  // Compute the face area normal and unit normal by summing up the
173  // normals of the triangles formed by connecting each edge to the
174  // point average.
175  vector sumA = Zero;
176  forAll(*this, pi)
177  {
178  const point& p = ps[operator[](pi)];
179  const point& pNext = ps[operator[](fcIndex(pi))];
180 
181  const vector a = (pNext - p)^(pAvg - p);
182 
183  sumA += a;
184  }
185  const vector sumAHat = normalised(sumA);
186 
187  // Compute the area-weighted sum of the average field values on each
188  // triangle
189  scalar sumAn = 0;
190  Type sumAnf = Zero;
191  forAll(*this, pi)
192  {
193  const point& p = ps[operator[](pi)];
194  const point& pNext = ps[operator[](fcIndex(pi))];
195 
196  const vector a = (pNext - p)^(pAvg - p);
197  const Type f =
198  fld[operator[](pi)]
199  + fld[operator[](fcIndex(pi))]
200  + fldAvg;
201 
202  const scalar an = a & sumAHat;
203 
204  sumAn += an;
205  sumAnf += an*f;
206  }
207 
208  // Complete calculating the average. If the face is too small for the sums
209  // to be reliably divided then just set the average to the initial
210  // estimate.
211  if (sumAn > vSmall)
212  {
213  return (1.0/3.0)*sumAnf/sumAn;
214  }
215  else
216  {
217  return fldAvg;
218  }
219 }
220 
221 
222 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
T & operator[](const label)
Return element of UList.
Definition: UListI.H:167
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
label fcIndex(const label i) const
Return the forward circular index, i.e. the next index.
Definition: UListI.H:58
static vector area(const PointField &ps)
Return vector area given face points.
const dimensionedScalar c
Speed of light in a vacuum.
Form normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:413
static const zero Zero
Definition: zero.H:97
Type average(const pointField &, const Field< Type > &) const
Calculate average value at centroid of face.
static vector centre(const PointField &ps)
Return centre point given face points.
labelList f(nPoints)
volScalarField & p
label size() const
Return the number of elements in the UList.
Definition: ListI.H:171