extractCloseness.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) 2018-2026 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 
27 #include "meshTools.H"
28 #include "Time.H"
29 
30 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
31 
32 void Foam::searchableSurfaces::triSurface::drawHitProblem
33 (
34  const label fi,
35  const point& start,
36  const point& p,
37  const point& end,
38  const pointIndexHitList& hitInfo
39 ) const
40 {
41  if (debug)
42  {
43  const List<labelledTri>& tris = *this;
44  tmp<pointField> tpoints = points();
45  const pointField& points = tpoints();
46 
47  Info<< nl << "# findLineAll did not hit its own face."
48  << nl << "# fi " << fi
49  << nl << "# start " << start
50  << nl << "# point " << p
51  << nl << "# end " << end
52  << nl << "# hitInfo " << hitInfo
53  << endl;
54 
55  meshTools::writeOBJ(Info, start);
58 
59  Info<< "l 1 2 3" << endl;
60 
61  meshTools::writeOBJ(Info, points[tris[fi][0]]);
62  meshTools::writeOBJ(Info, points[tris[fi][1]]);
63  meshTools::writeOBJ(Info, points[tris[fi][2]]);
64 
65  Info<< "f 4 5 6" << endl;
66 
67  forAll(hitInfo, hi)
68  {
69  label hfi = hitInfo[hi].index();
70 
71  meshTools::writeOBJ(Info, points[tris[hfi][0]]);
72  meshTools::writeOBJ(Info, points[tris[hfi][1]]);
73  meshTools::writeOBJ(Info, points[tris[hfi][2]]);
74 
75  Info<< "f "
76  << 3*hi + 7 << " "
77  << 3*hi + 8 << " "
78  << 3*hi + 9
79  << endl;
80  }
81  }
82 }
83 
84 
85 void Foam::searchableSurfaces::triSurface::processHit
86 (
87  scalar& internalCloseness,
88  scalar& externalCloseness,
89  const scalar internalToleranceCosAngle,
90  const scalar externalToleranceCosAngle,
91  const label fi,
92  const point& start,
93  const point& p,
94  const point& end,
95  const vector& normal,
96  const vectorField& normals,
97  const pointIndexHitList& hitInfo
98 ) const
99 {
100  if (hitInfo.size() < 1)
101  {
102  drawHitProblem(fi, start, p, end, hitInfo);
103  }
104  else if (hitInfo.size() == 1)
105  {
106  if (!hitInfo[0].hit())
107  {
108  }
109  else if (hitInfo[0].index() != fi)
110  {
111  drawHitProblem(fi, start, p, end, hitInfo);
112  }
113  }
114  else
115  {
116  label ownHiti = -1;
117 
118  forAll(hitInfo, hI)
119  {
120  // Find the hit on the triangle that launched the ray
121 
122  if (hitInfo[hI].index() == fi)
123  {
124  ownHiti = hI;
125  break;
126  }
127  }
128 
129  if (ownHiti < 0)
130  {
131  drawHitProblem(fi, start, p, end, hitInfo);
132  }
133  else if (ownHiti == 0)
134  {
135  // There are no internal hits, the first hit is the
136  // closest external hit
137 
138  if
139  (
140  (normal & normals[hitInfo[ownHiti + 1].index()])
141  < externalToleranceCosAngle
142  )
143  {
144  externalCloseness = min
145  (
146  externalCloseness,
147  mag(p - hitInfo[ownHiti + 1].hitPoint())
148  );
149  }
150  }
151  else if (ownHiti == hitInfo.size() - 1)
152  {
153  // There are no external hits, the last but one hit is
154  // the closest internal hit
155 
156  if
157  (
158  (normal & normals[hitInfo[ownHiti - 1].index()])
159  < internalToleranceCosAngle
160  )
161  {
162  internalCloseness = min
163  (
164  internalCloseness,
165  mag(p - hitInfo[ownHiti - 1].hitPoint())
166  );
167  }
168  }
169  else
170  {
171  if
172  (
173  (normal & normals[hitInfo[ownHiti + 1].index()])
174  < externalToleranceCosAngle
175  )
176  {
177  externalCloseness = min
178  (
179  externalCloseness,
180  mag(p - hitInfo[ownHiti + 1].hitPoint())
181  );
182  }
183 
184  if
185  (
186  (normal & normals[hitInfo[ownHiti - 1].index()])
187  < internalToleranceCosAngle
188  )
189  {
190  internalCloseness = min
191  (
192  internalCloseness,
193  mag(p - hitInfo[ownHiti - 1].hitPoint())
194  );
195  }
196  }
197  }
198 }
199 
200 
203 (
204  const scalar internalAngleTolerance,
205  const scalar externalAngleTolerance
206 ) const
207 {
208  const scalar internalToleranceCosAngle
209  (
210  cos(degToRad(180) - internalAngleTolerance)
211  );
212 
213  const scalar externalToleranceCosAngle
214  (
215  cos(degToRad(180) - externalAngleTolerance)
216  );
217 
218  const Time& runTime = objectRegistry::time();
219 
220  // Prepare start and end points for intersection tests
221 
222  const vectorField& normals = faceNormals();
223 
224  const scalar span = bounds().mag();
225 
226  const pointField start(faceCentres() - span*normals);
227  const pointField end(faceCentres() + span*normals);
228  const pointField& faceCentres = this->faceCentres();
229 
230  List<List<pointIndexHit>> allHitinfo;
231 
232  // Find all intersections (in order)
233  findLineAll(start, end, allHitinfo);
234 
235  scalarField internalCloseness(start.size(), great);
236  scalarField externalCloseness(start.size(), great);
237 
238  forAll(allHitinfo, fi)
239  {
240  const List<pointIndexHit>& hitInfo = allHitinfo[fi];
241 
242  processHit
243  (
244  internalCloseness[fi],
245  externalCloseness[fi],
246  internalToleranceCosAngle,
247  externalToleranceCosAngle,
248  fi,
249  start[fi],
250  faceCentres[fi],
251  end[fi],
252  normals[fi],
253  normals,
254  hitInfo
255  );
256  }
257 
259  (
261  (
262  new scalarIOField
263  (
264  IOobject
265  (
266  objectRegistry::name() + ".internalCloseness",
267  runTime.constant(),
269  runTime
270  ),
271  internalCloseness
272  )
273  ),
274 
276  (
277  new scalarIOField
278  (
279  IOobject
280  (
281  objectRegistry::name() + ".externalCloseness",
282  runTime.constant(),
284  runTime
285  ),
286  externalCloseness
287  )
288  )
289  );
290 }
291 
292 
295 (
296  const scalar internalAngleTolerance,
297  const scalar externalAngleTolerance
298 ) const
299 {
300  const scalar internalToleranceCosAngle
301  (
302  cos(degToRad(180) - internalAngleTolerance)
303  );
304 
305  const scalar externalToleranceCosAngle
306  (
307  cos(degToRad(180) - externalAngleTolerance)
308  );
309 
310  const Time& runTime = objectRegistry::time();
311 
312  // Prepare start and end points for intersection tests
313 
314  tmp<pointField> tpoints = points();
315  const pointField& points = tpoints();
316  const labelList& meshPoints = this->meshPoints();
317  const pointField& faceCentres = this->faceCentres();
318  const vectorField& normals = this->faceNormals();
319  const labelListList& pointFaces = this->pointFaces();
320 
321  const scalar span = bounds().mag();
322 
323  label nPointFaces = 0;
324  forAll(pointFaces, pfi)
325  {
326  nPointFaces += pointFaces[pfi].size();
327  }
328 
329  pointField facePoints(nPointFaces);
330  pointField start(nPointFaces);
331  pointField end(nPointFaces);
332 
333  label i = 0;
334  forAll(points, pi)
335  {
336  forAll(pointFaces[pi], pfi)
337  {
338  const label fi = pointFaces[pi][pfi];
339 
340  facePoints[i] = (0.9*points[meshPoints[pi]] + 0.1*faceCentres[fi]);
341  const vector& n = normals[fi];
342 
343  start[i] = facePoints[i] - span*n;
344  end[i] = facePoints[i] + span*n;
345 
346  i++;
347  }
348  }
349 
350  List<pointIndexHitList> allHitinfo;
351 
352  // Find all intersections (in order)
353  findLineAll(start, end, allHitinfo);
354 
355  scalarField internalCloseness(points.size(), great);
356  scalarField externalCloseness(points.size(), great);
357 
358  i = 0;
359  forAll(points, pi)
360  {
361  forAll(pointFaces[pi], pfi)
362  {
363  const label fi = pointFaces[pi][pfi];
364  const pointIndexHitList& hitInfo = allHitinfo[i];
365 
366  processHit
367  (
368  internalCloseness[pi],
369  externalCloseness[pi],
370  internalToleranceCosAngle,
371  externalToleranceCosAngle,
372  fi,
373  start[i],
374  facePoints[i],
375  end[i],
376  normals[fi],
377  normals,
378  hitInfo
379  );
380 
381  i++;
382  }
383  }
384 
386  (
388  (
389  new scalarIOField
390  (
391  IOobject
392  (
393  objectRegistry::name() + ".internalPointCloseness",
394  runTime.constant(),
396  runTime
397  ),
398  internalCloseness
399  )
400  ),
401 
403  (
404  new scalarIOField
405  (
406  IOobject
407  (
408  objectRegistry::name() + ".externalPointCloseness",
409  runTime.constant(),
411  runTime
412  ),
413  externalCloseness
414  )
415  )
416  );
417 }
418 
419 
420 // ************************************************************************* //
label n
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:449
A primitive field of type <Type> with automated input and output.
Definition: IOField.H:53
IOobject defines the attributes of an object for which implicit objectRegistry management is supporte...
Definition: IOobject.H:99
const word & name() const
Return name.
Definition: IOobject.H:307
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
void size(const label)
Override size to be inconsistent with allocated storage.
Definition: ListI.H:164
An ordered pair of two objects of type <Type> with first() and second() elements.
Definition: Pair.H:67
static const word & constant()
Return constant name.
Definition: TimePaths.H:122
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:76
const Time & time() const
Return time.
Motion of the mesh specified as a list of pointMeshMovers.
static const word & geometryDir()
Return the geometry directory name.
Pair< tmp< scalarIOField > > extractCloseness(const scalar internalAngleTolerance=degToRad(80), const scalar externalAngleTolerance=degToRad(80)) const
Return a pair of scalarIOFields representing the.
Pair< tmp< scalarIOField > > extractPointCloseness(const scalar internalAngleTolerance=degToRad(80), const scalar externalAngleTolerance=degToRad(80)) const
Return a pair of scalarIOFields representing the.
virtual tmp< pointField > points() const
Get the points that define the surface.
A class for managing temporary objects.
Definition: tmp.H:55
const pointField & points
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of point.
Definition: meshTools.C:203
scalar degToRad(const scalar deg)
Convert degrees to radians.
Definition: units.C:364
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
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:288
messageStream Info
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:42
vector point
Point is a vector.
Definition: point.H:41
Vector< scalar > vector
A scalar version of the templated Vector.
Definition: vector.H:49
dimensioned< Type > min(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
Field< vector > vectorField
Specialisation of Field<T> for vector.
tmp< DimensionedField< scalar, GeoMesh, Field > > mag(const DimensionedField< Type, GeoMesh, PrimitiveField > &df)
List< pointIndexHit > pointIndexHitList
List of pointIndexHits and associated functions.
static const char nl
Definition: Ostream.H:297
dimensionedScalar cos(const dimensionedScalar &ds)
volScalarField & p
static iteratorEnd end()
iteratorEnd set to beyond the end of any HashTable
Definition: HashTable.H:112