triSurfaceCloseness.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) 2017 OpenCFD Ltd.
9 -------------------------------------------------------------------------------
10 License
11  This file is part of OpenFOAM.
12 
13  OpenFOAM is free software: you can redistribute it and/or modify it
14  under the terms of the GNU General Public License as published by
15  the Free Software Foundation, either version 3 of the License, or
16  (at your option) any later version.
17 
18  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21  for more details.
22 
23  You should have received a copy of the GNU General Public License
24  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25 
26 \*---------------------------------------------------------------------------*/
27 
28 #include "triSurfaceTools.H"
29 
30 #include "triSurface.H"
31 #include "triSurfaceMesh.H"
32 #include "triSurfaceFields.H"
33 #include "MeshedSurface.H"
34 #include "OFstream.H"
35 #include "unitConversion.H"
36 #include "meshTools.H"
37 
38 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
39 
40 namespace Foam
41 {
42 
43 static void drawHitProblem
44 (
45  label fI,
46  const triSurface& surf,
47  const pointField& start,
48  const pointField& faceCentres,
49  const pointField& end,
50  const List<pointIndexHit>& hitInfo
51 )
52 {
53  Info<< nl << "# findLineAll did not hit its own face."
54  << nl << "# fI " << fI
55  << nl << "# start " << start[fI]
56  << nl << "# f centre " << faceCentres[fI]
57  << nl << "# end " << end[fI]
58  << nl << "# hitInfo " << hitInfo
59  << endl;
60 
61  meshTools::writeOBJ(Info, start[fI]);
62  meshTools::writeOBJ(Info, faceCentres[fI]);
64 
65  Info<< "l 1 2 3" << endl;
66 
67  meshTools::writeOBJ(Info, surf.points()[surf[fI][0]]);
68  meshTools::writeOBJ(Info, surf.points()[surf[fI][1]]);
69  meshTools::writeOBJ(Info, surf.points()[surf[fI][2]]);
70 
71  Info<< "f 4 5 6" << endl;
72 
73  forAll(hitInfo, hI)
74  {
75  label hFI = hitInfo[hI].index();
76 
77  meshTools::writeOBJ(Info, surf.points()[surf[hFI][0]]);
78  meshTools::writeOBJ(Info, surf.points()[surf[hFI][1]]);
79  meshTools::writeOBJ(Info, surf.points()[surf[hFI][2]]);
80 
81  Info<< "f "
82  << 3*hI + 7 << " "
83  << 3*hI + 8 << " "
84  << 3*hI + 9
85  << endl;
86  }
87 }
88 
89 } // End namespace Foam
90 
91 
92 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
93 
96 (
97  const Time& runTime,
98  const word& basename,
99  const triSurface& surf,
100  const scalar internalAngleTolerance,
101  const scalar externalAngleTolerance
102 )
103 {
104  Pair<tmp<scalarField>> tpair
105  (
106  tmp<scalarField>(new scalarField(surf.size(), GREAT)),
107  tmp<scalarField>(new scalarField(surf.size(), GREAT))
108  );
109 
110  Info<< "Extracting internal and external closeness of surface." << endl;
111 
112  triSurfaceMesh searchSurf
113  (
114  IOobject
115  (
116  basename + ".closeness",
117  runTime.constant(),
118  "triSurface",
119  runTime,
120  IOobject::NO_READ,
121  IOobject::NO_WRITE
122  ),
123  surf
124  );
125 
126  // Prepare start and end points for intersection tests
127 
128  const vectorField& normals = searchSurf.faceNormals();
129  const scalar span = searchSurf.bounds().mag();
130 
131  const scalar externalToleranceCosAngle =
132  Foam::cos
133  (
134  degToRad(180 - externalAngleTolerance)
135  );
136 
137  const scalar internalToleranceCosAngle =
138  Foam::cos
139  (
140  degToRad(180 - internalAngleTolerance)
141  );
142 
143  Info<< "externalToleranceCosAngle: " << externalToleranceCosAngle << nl
144  << "internalToleranceCosAngle: " << internalToleranceCosAngle << endl;
145 
146  // Info<< "span " << span << endl;
147 
148  const pointField start(searchSurf.faceCentres() - span*normals);
149  const pointField end(searchSurf.faceCentres() + span*normals);
150  const pointField& faceCentres = searchSurf.faceCentres();
151 
152  List<List<pointIndexHit>> allHitInfo;
153 
154  // Find all intersections (in order)
155  searchSurf.findLineAll(start, end, allHitInfo);
156 
157  scalarField& internalCloseness = tpair[0].ref();
158  scalarField& externalCloseness = tpair[1].ref();
159 
160  forAll(allHitInfo, fI)
161  {
162  const List<pointIndexHit>& hitInfo = allHitInfo[fI];
163 
164  if (hitInfo.size() < 1)
165  {
166  drawHitProblem(fI, surf, start, faceCentres, end, hitInfo);
167 
168  // FatalErrorInFunction
169  // << "findLineAll did not hit its own face."
170  // << exit(FatalError);
171  }
172  else if (hitInfo.size() == 1)
173  {
174  if (!hitInfo[0].hit())
175  {
176  // FatalErrorInFunction
177  // << "findLineAll did not hit any face."
178  // << exit(FatalError);
179  }
180  else if (hitInfo[0].index() != fI)
181  {
183  (
184  fI,
185  surf,
186  start,
187  faceCentres,
188  end,
189  hitInfo
190  );
191 
192  // FatalErrorInFunction
193  // << "findLineAll did not hit its own face."
194  // << exit(FatalError);
195  }
196  }
197  else
198  {
199  label ownHitI = -1;
200 
201  forAll(hitInfo, hI)
202  {
203  // Find the hit on the triangle that launched the ray
204 
205  if (hitInfo[hI].index() == fI)
206  {
207  ownHitI = hI;
208 
209  break;
210  }
211  }
212 
213  if (ownHitI < 0)
214  {
216  (
217  fI,
218  surf,
219  start,
220  faceCentres,
221  end,
222  hitInfo
223  );
224 
225  // FatalErrorInFunction
226  // << "findLineAll did not hit its own face."
227  // << exit(FatalError);
228  }
229  else if (ownHitI == 0)
230  {
231  // There are no internal hits, the first hit is the
232  // closest external hit
233 
234  if
235  (
236  (
237  normals[fI]
238  & normals[hitInfo[ownHitI + 1].index()]
239  )
240  < externalToleranceCosAngle
241  )
242  {
243  externalCloseness[fI] =
244  mag
245  (
246  faceCentres[fI]
247  - hitInfo[ownHitI + 1].hitPoint()
248  );
249  }
250  }
251  else if (ownHitI == hitInfo.size() - 1)
252  {
253  // There are no external hits, the last but one hit is
254  // the closest internal hit
255 
256  if
257  (
258  (
259  normals[fI]
260  & normals[hitInfo[ownHitI - 1].index()]
261  )
262  < internalToleranceCosAngle
263  )
264  {
265  internalCloseness[fI] =
266  mag
267  (
268  faceCentres[fI]
269  - hitInfo[ownHitI - 1].hitPoint()
270  );
271  }
272  }
273  else
274  {
275  if
276  (
277  (
278  normals[fI]
279  & normals[hitInfo[ownHitI + 1].index()]
280  )
281  < externalToleranceCosAngle
282  )
283  {
284  externalCloseness[fI] =
285  mag
286  (
287  faceCentres[fI]
288  - hitInfo[ownHitI + 1].hitPoint()
289  );
290  }
291 
292  if
293  (
294  (
295  normals[fI]
296  & normals[hitInfo[ownHitI - 1].index()]
297  )
298  < internalToleranceCosAngle
299  )
300  {
301  internalCloseness[fI] =
302  mag
303  (
304  faceCentres[fI]
305  - hitInfo[ownHitI - 1].hitPoint()
306  );
307  }
308  }
309  }
310  }
311 
312  // write as 'internalCloseness'
313  {
314  triSurfaceScalarField outputField
315  (
316  IOobject
317  (
318  basename + ".internalCloseness",
319  runTime.constant(),
320  "triSurface",
321  runTime,
322  IOobject::NO_READ,
323  IOobject::NO_WRITE
324  ),
325  surf,
326  dimLength,
327  scalarField()
328  );
329 
330  outputField.swap(internalCloseness);
331  outputField.write();
332  outputField.swap(internalCloseness);
333  }
334 
335  // write as 'externalCloseness'
336  {
337  triSurfaceScalarField outputField
338  (
339  IOobject
340  (
341  basename + ".externalCloseness",
342  runTime.constant(),
343  "triSurface",
344  runTime,
345  IOobject::NO_READ,
346  IOobject::NO_WRITE
347  ),
348  surf,
349  dimLength,
350  scalarField()
351  );
352 
353  outputField.swap(externalCloseness);
354  outputField.write();
355  outputField.swap(externalCloseness);
356  }
357 
358  return tpair;
359 }
360 
361 
362 // ************************************************************************* //
Foam::PrimitivePatch::points
const Field< point_type > & points() const noexcept
Return reference to global points.
Definition: PrimitivePatch.H:299
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::scalarField
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Definition: primitiveFieldsFwd.H:52
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
meshTools.H
Foam::boundBox::mag
scalar mag() const
The magnitude of the bounding box span.
Definition: boundBoxI.H:133
Foam::Time
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:73
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::dimLength
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:52
Foam::tmp
A class for managing temporary objects.
Definition: PtrList.H:61
Foam::meshTools::writeOBJ
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
unitConversion.H
Unit conversion functions.
triSurfaceFields.H
Fields for triSurface.
Foam::triSurfaceMesh
IOoject and searching on triSurface.
Definition: triSurfaceMesh.H:106
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
triSurface.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
OFstream.H
Foam::Field< vector >
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:76
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
stdFoam::end
constexpr auto end(C &c) -> decltype(c.end())
Return iterator to the end of the container c.
Definition: stdFoam.H:121
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::degToRad
constexpr scalar degToRad(const scalar deg) noexcept
Conversion from degrees to radians.
Definition: unitConversion.H:48
Foam::triSurfaceTools::writeCloseness
static Pair< tmp< scalarField > > writeCloseness(const Time &runTime, const word &basename, const triSurface &surf, const scalar internalAngleTolerance=45, const scalar externalAngleTolerance=10)
Check and write internal/external closeness fields.
Definition: triSurfaceCloseness.C:96
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::Pair
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:54
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: BitOps.H:63
Foam::mag
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Foam::drawHitProblem
static void drawHitProblem(label fI, const triSurface &surf, const pointField &start, const pointField &faceCentres, const pointField &end, const List< pointIndexHit > &hitInfo)
Definition: triSurfaceCloseness.C:44
Foam::PrimitivePatch::faceNormals
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
Definition: PrimitivePatch.C:445
Foam::searchableSurface::bounds
virtual const boundBox & bounds() const
Return const reference to boundBox.
Definition: searchableSurface.H:179
triSurfaceMesh.H
triSurfaceTools.H
Foam::PrimitivePatch::faceCentres
const Field< point_type > & faceCentres() const
Return face centres for patch.
Definition: PrimitivePatch.C:400
Foam::triSurfaceMesh::findLineAll
virtual void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit >> &) const
Get all intersections in order from start to end.
Definition: triSurfaceMesh.C:898
Foam::DimensionedField
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Definition: DimensionedField.H:54
MeshedSurface.H
Foam::cos
dimensionedScalar cos(const dimensionedScalar &ds)
Definition: dimensionedScalar.C:265