Loading...
Searching...
No Matches
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-2022 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}
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(surf.size(), GREAT),
107 tmp<scalarField>::New(surf.size(), GREAT)
108 );
109
110 Info<< "Extracting internal and external closeness of surface." << endl;
111
112 triSurfaceMesh searchSurf
113 (
115 (
116 basename + ".closeness",
117 runTime.constant(),
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 faceCentres[fI].dist(hitInfo[ownHitI + 1].point());
245 }
246 }
247 else if (ownHitI == hitInfo.size() - 1)
248 {
249 // There are no external hits, the last but one hit is
250 // the closest internal hit
251
252 if
253 (
254 (
255 normals[fI]
256 & normals[hitInfo[ownHitI - 1].index()]
257 )
258 < internalToleranceCosAngle
259 )
260 {
261 internalCloseness[fI] =
262 faceCentres[fI].dist(hitInfo[ownHitI - 1].point());
263 }
264 }
265 else
266 {
267 if
268 (
269 (
270 normals[fI]
271 & normals[hitInfo[ownHitI + 1].index()]
272 )
273 < externalToleranceCosAngle
274 )
275 {
276 externalCloseness[fI] =
277 faceCentres[fI].dist(hitInfo[ownHitI + 1].point());
278 }
279
280 if
281 (
282 (
283 normals[fI]
284 & normals[hitInfo[ownHitI - 1].index()]
285 )
286 < internalToleranceCosAngle
287 )
288 {
289 internalCloseness[fI] =
290 faceCentres[fI].dist(hitInfo[ownHitI - 1].point());
291 }
292 }
293 }
294 }
295
296 // write as 'internalCloseness'
297 {
298 triSurfaceScalarField outputField
299 (
300 IOobject
301 (
302 basename + ".internalCloseness",
303 runTime.constant(),
304 "triSurface",
305 runTime,
308 ),
309 surf,
310 dimLength,
312 );
313
314 outputField.swap(internalCloseness);
315 outputField.write();
316 outputField.swap(internalCloseness);
317 }
318
319 // write as 'externalCloseness'
320 {
321 triSurfaceScalarField outputField
322 (
323 IOobject
324 (
325 basename + ".externalCloseness",
326 runTime.constant(),
327 "triSurface",
328 runTime,
331 ),
332 surf,
333 dimLength,
335 );
336
337 outputField.swap(externalCloseness);
338 outputField.write();
339 outputField.swap(externalCloseness);
340 }
341
342 return tpair;
343}
344
345
346// ************************************************************************* //
void swap(List< T > &other)
Swap with plain List content. Implies shrink_to_fit().
@ NO_READ
Nothing to be read.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition IOobject.H:191
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition List.H:72
An ordered pair of two objects of type <T> with first() and second() elements.
Definition Pair.H:66
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.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition Time.H:75
void size(const label n)
Older name for setAddressableSize.
Definition UList.H:118
scalar mag() const
The magnitude/length of the bounding box diagonal.
Definition boundBoxI.H:198
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
virtual const boundBox & bounds() const
Return const reference to boundBox.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Definition tmp.H:215
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:74
A class for handling words, derived from Foam::string.
Definition word.H:66
engineTime & runTime
void writeOBJ(Ostream &os, const point &pt)
Write obj representation of a point.
Definition meshTools.C:196
Namespace for OpenFOAM.
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
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:519
constexpr scalar degToRad() noexcept
Multiplication factor for degrees to radians conversion.
Field< vector > vectorField
Specialisation of Field<T> for vector.
vector point
Point is a vector.
Definition point.H:37
vectorField pointField
pointField is a vectorField.
dimensionedScalar cos(const dimensionedScalar &ds)
DimensionedField< scalar, triSurfaceGeoMesh > triSurfaceScalarField
constexpr char nl
The newline '\n' character (0x0a).
Definition Ostream.H:50
#define forAll(list, i)
Loop across all elements in list.
Definition stdFoam.H:299
Fields for triSurface.
Unit conversion functions.