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-2020 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<unsigned SizeInc, unsigned SizeMult, unsigned SizeDiv>
141 (
142  const pointField& points,
144 ) const
145 {
146  label triI = triFaces.size();
147  label quadI = 0;
148  faceList quadFaces;
149 
150  // adjust the addressable size (and allocate space if needed)
151  triFaces.setSize(triI + nTriangles());
152 
153  return split(SPLITTRIANGLE, points, triI, quadI, triFaces, quadFaces);
154 }
155 
156 
157 template<class Type>
159 (
160  const pointField& ps,
161  const Field<Type>& fld
162 ) const
163 {
164  // If the face is a triangle, do a direct calculation
165  if (size() == 3)
166  {
167  return
168  (1.0/3.0)
169  *(
170  fld[operator[](0)]
171  + fld[operator[](1)]
172  + fld[operator[](2)]
173  );
174  }
175 
176  // For more complex faces, decompose into triangles ...
177 
178  // Compute an estimate of the centre and the field average as the average
179  // of the point values
180  point pAvg = Zero;
181  Type fldAvg = Zero;
182  forAll(*this, pi)
183  {
184  pAvg += ps[operator[](pi)];
185  fldAvg += fld[operator[](pi)];
186  }
187  pAvg /= size();
188  fldAvg /= size();
189 
190  // Compute the face area normal and unit normal by summing up the
191  // normals of the triangles formed by connecting each edge to the
192  // point average.
193  vector sumA = Zero;
194  forAll(*this, pi)
195  {
196  const point& p = ps[operator[](pi)];
197  const point& pNext = ps[operator[](fcIndex(pi))];
198 
199  const vector a = (pNext - p)^(pAvg - p);
200 
201  sumA += a;
202  }
203  const vector sumAHat = normalised(sumA);
204 
205  // Compute the area-weighted sum of the average field values on each
206  // triangle
207  scalar sumAn = 0;
208  Type sumAnf = Zero;
209  forAll(*this, pi)
210  {
211  const point& p = ps[operator[](pi)];
212  const point& pNext = ps[operator[](fcIndex(pi))];
213 
214  const vector a = (pNext - p)^(pAvg - p);
215  const Type f =
216  fld[operator[](pi)]
217  + fld[operator[](fcIndex(pi))]
218  + fldAvg;
219 
220  const scalar an = a & sumAHat;
221 
222  sumAn += an;
223  sumAnf += an*f;
224  }
225 
226  // Complete calculating the average. If the face is too small for the sums
227  // to be reliably divided then just set the average to the initial
228  // estimate.
229  if (sumAn > vSmall)
230  {
231  return (1.0/3.0)*sumAnf/sumAn;
232  }
233  else
234  {
235  return fldAvg;
236  }
237 }
238 
239 
240 // ************************************************************************* //
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:434
intWM_LABEL_SIZE_t label
A label is an int32_t or int64_t as specified by the pre-processor macro WM_LABEL_SIZE.
Definition: label.H:59
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.
label triangles(const pointField &points, label &triI, faceList &triFaces) const
Split into triangles using existing points.
Definition: face.C:724
void setSize(const label)
Alter the addressed list size.
Definition: DynamicListI.H:175
Form normalised(const VectorSpace< Form, Cmpt, Ncmpts > &vs)
Definition: VectorSpaceI.H:413
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects...
Definition: DynamicList.H:56
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)
label nTriangles() const
Number of triangles after splitting.
Definition: faceI.H:130
volScalarField & p
label size() const
Return the number of elements in the UList.
Definition: ListI.H:171