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-------------------------------------------------------------------------------
10License
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
40namespace Foam
41{
42
43static 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]);
63 meshTools::writeOBJ(Info, end[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{
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 (
115 (
116 basename + ".closeness",
118 "triSurface",
119 runTime,
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 =
133 (
134 degToRad(180 - externalAngleTolerance)
135 );
136
137 const scalar internalToleranceCosAngle =
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 (
317 (
318 basename + ".internalCloseness",
320 "triSurface",
321 runTime,
324 ),
325 surf,
326 dimLength,
328 );
329
330 outputField.swap(internalCloseness);
331 outputField.write();
332 outputField.swap(internalCloseness);
333 }
334
335 // write as 'externalCloseness'
336 {
337 triSurfaceScalarField outputField
338 (
340 (
341 basename + ".externalCloseness",
343 "triSurface",
344 runTime,
347 ),
348 surf,
349 dimLength,
351 );
352
353 outputField.swap(externalCloseness);
354 outputField.write();
355 outputField.swap(externalCloseness);
356 }
357
358 return tpair;
359}
360
361
362// ************************************************************************* //
Field with dimensions and associated with geometry type GeoMesh which is used to size the field and a...
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: List.H:77
An ordered pair of two objects of type <T> with first() and second() elements.
Definition: Pair.H:69
const Field< point_type > & faceNormals() const
Return face unit normals for patch.
const Field< point_type > & points() const noexcept
Return reference to global points.
const Field< point_type > & faceCentres() const
Return face centres for patch.
const word & constant() const
Return constant name.
Definition: TimePathsI.H:96
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:80
void swap(UList< T > &list)
Swap content with another UList of the same type in constant time.
Definition: UListI.H:434
void size(const label n)
Older name for setAddressableSize.
Definition: UList.H:114
scalar mag() const
The magnitude of the bounding box span.
Definition: boundBoxI.H:133
virtual bool write(const bool valid=true) const
Write using setting from DB.
virtual const boundBox & bounds() const
Return const reference to boundBox.
A class for managing temporary objects.
Definition: tmp.H:65
IOoject and searching on triSurface.
virtual void findLineAll(const pointField &start, const pointField &end, List< List< pointIndexHit > > &) const
Get all intersections in order from start to end.
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.
Triangulated surface description with patch information.
Definition: triSurface.H:79
A class for handling words, derived from Foam::string.
Definition: word.H:68
engineTime & runTime
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition: meshTools.C:203
Namespace for OpenFOAM.
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
Definition: dimensionSets.H:52
messageStream Info
Information stream (stdout output on master, null elsewhere)
static void drawHitProblem(label fI, const triSurface &surf, const pointField &start, const pointField &faceCentres, const pointField &end, const List< pointIndexHit > &hitInfo)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
dimensionedScalar cos(const dimensionedScalar &ds)
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
Fields for triSurface.
Unit conversion functions.