cellPoint_interpolationI.H
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-2025 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 
28 
29 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
30 
31 template<class Type>
33 (
34  const tetIndices& tetIs,
35  vector& x0,
36  scalar& detA,
38 ) const
39 {
40  const triFace triIs(tetIs.faceTriIs(this->mesh_));
41 
42  const vectorField& ccs = this->mesh_.cellCentres();
43  const pointField& ps = this->mesh_.points();
44 
45  const barycentricTensor A
46  (
47  ccs[tetIs.cell()],
48  ps[triIs[0]],
49  ps[triIs[1]],
50  ps[triIs[2]]
51  );
52 
53  const vector ba = A.a() - A.b();
54  const vector bc = A.c() - A.b();
55  const vector bd = A.d() - A.b();
56  const vector ac = A.c() - A.a();
57  const vector ad = A.d() - A.a();
58 
59  x0 = A.b();
60 
61  detA = ba & (bc ^ bd);
62 
63  T = barycentricTensor(bc ^ bd, ad ^ ac, bd ^ ba, ba ^ bc);
64 }
65 
66 
67 template<class Type>
69 (
70  const tetIndices& tetIs,
71  vector& x0,
72  scalar& detA,
74 ) const
75 {
76  const triFace triIs(tetIs.faceTriIs(this->mesh_));
77 
78  const vectorField& ccs = this->mesh_.cellCentres();
79  const pointField& ps = this->mesh_.points();
80 
81  const barycentricTensor A
82  (
83  ccs[tetIs.cell()],
84  ps[triIs[0]],
85  ps[triIs[1]],
86  ps[triIs[2]]
87  );
88 
89  const vector bc = A.c() - A.b();
90  const vector bd = A.d() - A.b();
91  const vector dc = A.c() - A.d();
92 
93  x0 = A.b();
94 
95  const vector bc_bd = bc ^ bd;
96 
97  detA = mag(bc_bd);
98 
99  const vector n = detA != 0 ? bc_bd/detA : vector::zero;
100 
101  T = barycentricTensor(vector::zero, dc ^ n, bd ^ n, n ^ bc);
102 }
103 
104 
105 template<class Type>
107 {
108  return barycentric(0, 1, 0, 0);
109 }
110 
111 
112 template<class Type>
114 (
115  const point& x,
116  const label celli,
117  const label facei,
118  vector& x0,
119  scalar& detA,
121 ) const
122 {
123  const List<tetIndices> tetIss =
124  facei == -1
125  ? polyMeshTetDecomposition::cellTetIndices
126  (
127  this->mesh_,
128  celli
129  )
130  : polyMeshTetDecomposition::faceTetIndices
131  (
132  this->mesh_,
133  facei,
134  this->mesh_.faceOwner()[facei]
135  );
136 
137  // Find the containing tetrahedron
138  forAll(tetIss, teti)
139  {
140  if (facei == -1)
141  {
142  tetTransform(tetIss[teti], x0, detA, T);
143  }
144  else
145  {
146  tetFaceTriTransform(tetIss[teti], x0, detA, T);
147  }
148 
149  if (detA <= 0) continue;
150 
151  const barycentric detAY = detA*y0() + ((x - x0) & T);
152 
153  if (cmptMin(detAY) + detA*small > 0)
154  {
155  return tetIss[teti];
156  }
157  }
158 
159  // A containing tet/tri was not found, so look instead for the nearest
160  scalar minDist = vGreat;
161  label minTeti = -1;
162  forAll(tetIss, teti)
163  {
164  const scalar dist =
165  facei == -1
166  ? tetIss[teti].tet(this->mesh_).nearestPoint(x).distance()
167  : tetIss[teti].faceTri(this->mesh_).nearestPoint(x).distance();
168 
169  if (dist < minDist)
170  {
171  minDist = dist;
172  minTeti = teti;
173  }
174  }
175 
176  // Get the transform for the nearest tetrahedron
177  if (facei == -1)
178  {
179  tetTransform(tetIss[minTeti], x0, detA, T);
180  }
181  else
182  {
183  tetFaceTriTransform(tetIss[minTeti], x0, detA, T);
184  }
185 
186  return tetIss[minTeti];
187 }
188 
189 
190 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
191 
192 template<class Type>
194 (
195  const vector& position,
196  const label celli,
197  const label facei
198 ) const
199 {
200  vector x0;
201  scalar detA;
203 
204  // Find the tetrahedron
205  const tetIndices tetIs = this->findTet(position, celli, facei, x0, detA, T);
206 
207  // Determine the barycentric coordinates. If the tetrahedron is degenerate
208  // then just take the centre.
209  const barycentric y =
210  detA == 0
211  ? barycentric::uniform(0.25)
212  : y0() + ((position - x0) & T)/detA;
213 
214  // Defer to the barycentric interpolation overload. Note that the face
215  // index is not needed.
216  return cellPointBase<Type>::interpolate(y, tetIs, -1);
217 }
218 
219 
220 template<class Type>
222 (
223  const barycentric& coordinates,
224  const tetIndices& tetIs,
225  const label facei
226 ) const
227 {
228  // Ignore the face index. If the location is on the face then the first
229  // component of the barycentric coordinates should be zero, meaning we get
230  // interpolation in the face anyway.
231 
232  const triFace triIs = tetIs.faceTriIs(this->mesh_);
233 
234  return
235  this->psi_[tetIs.cell()]*coordinates[0]
236  + this->psip_[triIs[0]]*coordinates[1]
237  + this->psip_[triIs[1]]*coordinates[2]
238  + this->psip_[triIs[2]]*coordinates[3];
239 }
240 
241 
242 template<class Type>
245 (
246  const tetIndices& tetIs,
247  const scalar detA,
248  const barycentricTensor T
249 ) const
250 {
251  const triFace triIs = tetIs.faceTriIs(this->mesh_);
252 
253  const Type& psia = this->psi_[tetIs.cell()];
254  const Type& psib = this->psip_[triIs[0]];
255  const Type& psic = this->psip_[triIs[1]];
256  const Type& psid = this->psip_[triIs[2]];
257 
258  return
260  (
261  T.x().a()*psia + T.x().b()*psib + T.x().c()*psic + T.x().d()*psid,
262  T.y().a()*psia + T.y().b()*psib + T.y().c()*psic + T.y().d()*psid,
263  T.z().a()*psia + T.z().b()*psib + T.z().c()*psic + T.z().d()*psid
264  )/detA;
265 }
266 
267 
268 template<class Type>
271 (
272  const vector& position,
273  const label celli,
274  const label facei
275 ) const
276 {
277  vector x0;
278  scalar detA;
280 
281  const tetIndices tetIs = this->findTet(position, celli, facei, x0, detA, T);
282 
283  return interpolateGrad(tetIs, detA, T);
284 }
285 
286 
287 template<class Type>
290 (
291  const barycentric&,
292  const tetIndices& tetIs,
293  const label
294 ) const
295 {
296  vector x0;
297  scalar detA;
299 
300  this->tetTransform(tetIs, x0, detA, T);
301 
302  return interpolateGrad(tetIs, detA, T);
303 }
304 
305 
306 // ************************************************************************* //
scalar y
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
Templated 4x3 tensor derived from VectorSpace. Has 12 components. Can represent a barycentric transfo...
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:91
barycentric y0() const
Return the barycentric origin for the above transforms.
void tetFaceTriTransform(const tetIndices &tetIs, vector &x0, scalar &detA, barycentricTensor &T) const
Return the transform associated with the face-triangle of the given.
tetIndices findTet(const point &x, const label celli, const label facei, vector &x0, scalar &detA, barycentricTensor &T) const
Find the tetrahedron (or triangle) containing the given point, and.
Type interpolate(const vector &position, const label celli, const label facei=-1) const
Interpolate to the given point in the given cell.
void tetTransform(const tetIndices &tetIs, vector &x0, scalar &detA, barycentricTensor &T) const
Return the transform associated with the given tetrahedron.
interpolationGradType< Type > interpolateGrad(const tetIndices &tetIs, const scalar detA, const barycentricTensor T) const
Interpolate the gradient to the given point in the given cell.
Storage and named access for the indices of a tet which is part of the decomposition of a cell.
Definition: tetIndices.H:82
label cell() const
Return the cell.
Definition: tetIndicesI.H:31
triFace faceTriIs(const polyMesh &mesh) const
Return the indices corresponding to the tri on the face for.
Definition: tetIndicesI.H:67
A triangular face using a FixedList of labels corresponding to mesh vertices.
Definition: triFace.H:71
static tmp< SurfaceField< Type > > interpolate(const VolField< Type > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
static const coefficient A("A", dimPressure, 611.21)
barycentric coordinates(const polyMesh &mesh, const point &position, const label celli, const label facei, const label faceTrii, const scalar stepFraction)
Return the coordinates given the position and tet topology.
Definition: tracking.C:1258
point position(const polyMesh &mesh, const barycentric &coordinates, const label celli, const label facei, const label faceTrii, const scalar stepFraction)
Return the position given the coordinates and tet topology.
Definition: trackingI.H:224
Barycentric< scalar > barycentric
A scalar version of the templated Barycentric.
Definition: barycentric.H:45
scalar minDist(const List< pointIndexHit > &hitList)
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
dimensionedScalar y0(const dimensionedScalar &ds)
typename outerProduct< Type, vector >::type interpolationGradType
Definition: interpolation.H:52
void cmptMin(Field< typename Field< Type >::cmptType > &res, const UList< Type > &f)
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
BarycentricTensor< scalar > barycentricTensor
A scalar version of the templated BarycentricTensor.
void T(GeometricField< Type, GeoMesh, PrimitiveField1 > &gf, const GeometricField< Type, GeoMesh, PrimitiveField2 > &gf1)