surfaceToCell.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) 2011-2016 OpenFOAM Foundation
9 Copyright (C) 2017-2020 OpenCFD Ltd.
10-------------------------------------------------------------------------------
11License
12 This file is part of OpenFOAM.
13
14 OpenFOAM is free software: you can redistribute it and/or modify it
15 under the terms of the GNU General Public License as published by
16 the Free Software Foundation, either version 3 of the License, or
17 (at your option) any later version.
18
19 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
20 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 for more details.
23
24 You should have received a copy of the GNU General Public License
25 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
26
27\*---------------------------------------------------------------------------*/
28
29#include "surfaceToCell.H"
30#include "polyMesh.H"
31#include "meshSearch.H"
32#include "triSurface.H"
33#include "triSurfaceSearch.H"
34#include "cellClassification.H"
35#include "cpuTime.H"
36#include "demandDrivenData.H"
38
39// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
40
41namespace Foam
42{
48}
49
50
51Foam::topoSetSource::addToUsageTable Foam::surfaceToCell::usage_
52(
53 surfaceToCell::typeName,
54 "\n Usage: surfaceToCell"
55 "<surface> <outsidePoints> <cut> <inside> <outside> <near> <curvature>\n\n"
56 " <surface> name of triSurface\n"
57 " <outsidePoints> list of points that define outside\n"
58 " <cut> boolean whether to include cells cut by surface\n"
59 " <inside> ,, ,, inside surface\n"
60 " <outside> ,, ,, outside surface\n"
61 " <near> scalar; include cells with centre <= near to surface\n"
62 " <curvature> scalar; include cells close to strong curvature"
63 " on surface\n"
64 " (curvature defined as difference in surface normal at nearest"
65 " point on surface for each vertex of cell)\n\n"
66);
67
68
69// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
70
71Foam::label Foam::surfaceToCell::getNearest
72(
73 const triSurfaceSearch& querySurf,
74 const label pointi,
75 const point& pt,
76 const vector& span,
77 Map<label>& cache
78)
79{
80 const auto iter = cache.cfind(pointi);
81
82 if (iter.found())
83 {
84 return *iter; // Return cached value
85 }
86
87 pointIndexHit inter = querySurf.nearest(pt, span);
88
89 // Triangle label (can be -1)
90 const label trii = inter.index();
91
92 // Store triangle on point
93 cache.insert(pointi, trii);
94
95 return trii;
96}
97
98
99bool Foam::surfaceToCell::differingPointNormals
100(
101 const triSurfaceSearch& querySurf,
102
103 const vector& span, // Current search span
104 const label celli,
105 const label cellTriI, // Nearest (to cell centre) surface triangle
106
107 Map<label>& pointToNearest // Cache for nearest triangle to point
108) const
109{
110 const triSurface& surf = querySurf.surface();
111 const vectorField& normals = surf.faceNormals();
112
113 const faceList& faces = mesh().faces();
114 const pointField& points = mesh().points();
115
116 const labelList& cFaces = mesh().cells()[celli];
117
118 for (const label facei : cFaces)
119 {
120 const face& f = faces[facei];
121
122 for (const label pointi : f)
123 {
124 label pointTriI =
125 getNearest
126 (
127 querySurf,
128 pointi,
129 points[pointi],
130 span,
131 pointToNearest
132 );
133
134 if (pointTriI != -1 && pointTriI != cellTriI)
135 {
136 scalar cosAngle = normals[pointTriI] & normals[cellTriI];
137
138 if (cosAngle < 0.9)
139 {
140 return true;
141 }
142 }
143 }
144 }
145 return false;
146}
147
148
149void Foam::surfaceToCell::combine(topoSet& set, const bool add) const
150{
151 cpuTime timer;
152
153 if (useSurfaceOrientation_ && (includeInside_ || includeOutside_))
154 {
155 const meshSearch queryMesh(mesh_);
156
157 //- Calculate for each searchPoint inside/outside status.
158 boolList isInside(querySurf().calcInside(mesh_.cellCentres()));
159
160 if (verbose_)
161 {
162 Info<< " Marked inside/outside using surface orientation in = "
163 << timer.cpuTimeIncrement() << " s" << nl << endl;
164 }
165
166 forAll(isInside, celli)
167 {
168 if (isInside[celli] ? includeInside_ : includeOutside_)
169 {
170 addOrDelete(set, celli, add);
171 }
172 }
173 }
174 else if (includeCut_ || includeInside_ || includeOutside_)
175 {
176 //
177 // Cut cells with surface and classify cells
178 //
179
180
181 // Construct search engine on mesh
182
183 const meshSearch queryMesh(mesh_);
184
185
186 // Check all 'outside' points
187 for (const point& outsidePoint : outsidePoints_)
188 {
189 // Find cell point is in. Linear search.
190 label celli = queryMesh.findCell(outsidePoint, -1, false);
191 if (returnReduce(celli, maxOp<label>()) == -1)
192 {
194 << "outsidePoint " << outsidePoint
195 << " is not inside any cell"
196 << exit(FatalError);
197 }
198 }
199
200 // Cut faces with surface and classify cells
201
202 cellClassification cellType
203 (
204 mesh_,
205 queryMesh,
206 querySurf(),
207 outsidePoints_
208 );
209
210
211 if (verbose_)
212 {
213 Info<< " Marked inside/outside using surface intersection in = "
214 << timer.cpuTimeIncrement() << " s" << nl << endl;
215 }
216
217 //- Add/remove cells using set
218 forAll(cellType, celli)
219 {
220 label cType = cellType[celli];
221
222 if
223 (
224 (
225 includeCut_
226 && (cType == cellClassification::CUT)
227 )
228 || (
229 includeInside_
230 && (cType == cellClassification::INSIDE)
231 )
232 || (
233 includeOutside_
234 && (cType == cellClassification::OUTSIDE)
235 )
236 )
237 {
238 addOrDelete(set, celli, add);
239 }
240 }
241 }
242
243
244 if (nearDist_ > 0)
245 {
246 //
247 // Determine distance to surface
248 //
249
250 const pointField& ctrs = mesh_.cellCentres();
251
252 // Box dimensions to search in octree.
253 const vector span(nearDist_, nearDist_, nearDist_);
254
255
256 if (curvature_ < -1)
257 {
258 if (verbose_)
259 {
260 Info<< " Selecting cells with cellCentre closer than "
261 << nearDist_ << " to surface" << endl;
262 }
263
264 // No need to test curvature. Insert near cells into set.
265
266 forAll(ctrs, celli)
267 {
268 const point& c = ctrs[celli];
269
270 pointIndexHit inter = querySurf().nearest(c, span);
271
272 if (inter.hit() && (mag(inter.hitPoint() - c) < nearDist_))
273 {
274 addOrDelete(set, celli, add);
275 }
276 }
277
278 if (verbose_)
279 {
280 Info<< " Determined nearest surface point in = "
281 << timer.cpuTimeIncrement() << " s" << nl << endl;
282 }
283 }
284 else
285 {
286 // Test near cells for curvature
287
288 if (verbose_)
289 {
290 Info<< " Selecting cells with cellCentre closer than "
291 << nearDist_ << " to surface and curvature factor"
292 << " less than " << curvature_ << endl;
293 }
294
295 // Cache for nearest surface triangle for a point
296 Map<label> pointToNearest(mesh_.nCells()/10);
297
298 forAll(ctrs, celli)
299 {
300 const point& c = ctrs[celli];
301
302 pointIndexHit inter = querySurf().nearest(c, span);
303
304 if (inter.hit() && (mag(inter.hitPoint() - c) < nearDist_))
305 {
306 if
307 (
308 differingPointNormals
309 (
310 querySurf(),
311 span,
312 celli,
313 inter.index(), // nearest surface triangle
314 pointToNearest
315 )
316 )
317 {
318 addOrDelete(set, celli, add);
319 }
320 }
321 }
322
323 if (verbose_)
324 {
325 Info<< " Determined nearest surface point in = "
326 << timer.cpuTimeIncrement() << " s" << nl << endl;
327 }
328 }
329 }
330}
331
332
333void Foam::surfaceToCell::checkSettings() const
334{
335 if
336 (
337 (nearDist_ < 0)
338 && (curvature_ < -1)
339 && (
340 (includeCut_ && includeInside_ && includeOutside_)
341 || (!includeCut_ && !includeInside_ && !includeOutside_)
342 )
343 )
344 {
346 << "Illegal include cell specification."
347 << " Result would be either all or no cells." << endl
348 << "Please set one of includeCut, includeInside, includeOutside"
349 << " to true, set nearDistance to a value > 0"
350 << " or set curvature to a value -1 .. 1."
351 << exit(FatalError);
352 }
353
354 if (useSurfaceOrientation_ && includeCut_)
355 {
357 << "Illegal include cell specification."
358 << " You cannot specify both 'useSurfaceOrientation'"
359 << " and 'includeCut'"
360 << " since 'includeCut' specifies a topological split"
361 << exit(FatalError);
362 }
363}
364
365
366// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
367
369(
370 const polyMesh& mesh,
371 const fileName& surfName,
372 const pointField& outsidePoints,
373 const bool includeCut,
374 const bool includeInside,
375 const bool includeOutside,
376 const bool useSurfaceOrientation,
377 const scalar nearDist,
378 const scalar curvature
379)
380:
382 surfName_(surfName),
383 outsidePoints_(outsidePoints),
384 includeCut_(includeCut),
385 includeInside_(includeInside),
386 includeOutside_(includeOutside),
387 useSurfaceOrientation_(useSurfaceOrientation),
388 nearDist_(nearDist),
389 curvature_(curvature),
390 surfPtr_(new triSurface(surfName_)),
391 querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
392 IOwnPtrs_(true)
393{
394 checkSettings();
395}
396
397
399(
400 const polyMesh& mesh,
401 const fileName& surfName,
402 const triSurface& surf,
403 const triSurfaceSearch& querySurf,
404 const pointField& outsidePoints,
405 const bool includeCut,
406 const bool includeInside,
407 const bool includeOutside,
408 const bool useSurfaceOrientation,
409 const scalar nearDist,
410 const scalar curvature
411)
412:
414 surfName_(surfName),
415 outsidePoints_(outsidePoints),
416 includeCut_(includeCut),
417 includeInside_(includeInside),
418 includeOutside_(includeOutside),
419 useSurfaceOrientation_(useSurfaceOrientation),
420 nearDist_(nearDist),
421 curvature_(curvature),
422 surfPtr_(&surf),
423 querySurfPtr_(&querySurf),
424 IOwnPtrs_(false)
425{
426 checkSettings();
427}
428
429
431(
432 const polyMesh& mesh,
433 const dictionary& dict
434)
435:
437 surfName_(dict.get<fileName>("file").expand()),
438 outsidePoints_(dict.get<pointField>("outsidePoints")),
439 includeCut_(dict.get<bool>("includeCut")),
440 includeInside_(dict.get<bool>("includeInside")),
441 includeOutside_(dict.get<bool>("includeOutside")),
442 useSurfaceOrientation_
443 (
444 dict.getOrDefault("useSurfaceOrientation", false)
445 ),
446 nearDist_(dict.get<scalar>("nearDistance")),
447 curvature_(dict.get<scalar>("curvature")),
448 surfPtr_
449 (
450 new triSurface
451 (
452 surfName_,
453 dict.getOrDefault<word>("fileType", word::null),
454 dict.getOrDefault<scalar>("scale", -1)
455 )
456 ),
457 querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
458 IOwnPtrs_(true)
459{
460 checkSettings();
461}
462
463
465(
466 const polyMesh& mesh,
467 Istream& is
468)
469:
471 surfName_(checkIs(is)),
472 outsidePoints_(checkIs(is)),
473 includeCut_(readBool(checkIs(is))),
474 includeInside_(readBool(checkIs(is))),
475 includeOutside_(readBool(checkIs(is))),
476 useSurfaceOrientation_(false),
477 nearDist_(readScalar(checkIs(is))),
478 curvature_(readScalar(checkIs(is))),
479 surfPtr_(new triSurface(surfName_)),
480 querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
481 IOwnPtrs_(true)
482{
483 checkSettings();
484}
485
486
487// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
488
490{
491 if (IOwnPtrs_)
492 {
493 deleteDemandDrivenData(surfPtr_);
494 deleteDemandDrivenData(querySurfPtr_);
495 }
496}
497
498
499// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
500
502(
503 const topoSetSource::setAction action,
504 topoSet& set
505) const
506{
507 if (action == topoSetSource::ADD || action == topoSetSource::NEW)
508 {
509 if (verbose_)
510 {
511 Info<< " Adding cells in relation to surface " << surfName_
512 << " ..." << endl;
513 }
514
515 combine(set, true);
516 }
517 else if (action == topoSetSource::SUBTRACT)
518 {
519 if (verbose_)
520 {
521 Info<< " Removing cells in relation to surface " << surfName_
522 << " ..." << endl;
523 }
524
525 combine(set, false);
526 }
527}
528
529
530// ************************************************************************* //
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:64
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
A class for handling file names.
Definition: fileName.H:76
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:81
virtual const faceList & faces() const
Return raw faces.
Definition: polyMesh.C:1108
virtual const pointField & points() const
Return raw points.
Definition: polyMesh.C:1083
const cellList & cells() const
A topoSetCellSource to select cells based on relation to a surface given by an external file.
virtual void applyToSet(const topoSetSource::setAction action, topoSet &) const
Apply specified action to the topoSet.
virtual ~surfaceToCell()
Destructor.
The topoSetCellSource is a intermediate class for handling topoSet sources for selecting cells.
Class with constructor to add usage string to table.
Base class of a source for a topoSet.
Definition: topoSetSource.H:68
setAction
Enumeration defining various actions.
@ SUBTRACT
Subtract elements from current set.
@ ADD
Add elements to current set.
@ NEW
Create a new set and ADD elements to it.
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:67
Helper class to search on triSurface.
Triangulated surface description with patch information.
Definition: triSurface.H:79
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
Definition: word.H:68
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
Definition: className.H:121
bool
Definition: EEqn.H:20
dynamicFvMesh & mesh
Template functions to aid in the implementation of demand driven data.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
const pointField & points
const dimensionedScalar c
Speed of light in a vacuum.
cellType
Equivalent to enumeration in "vtkCellType.h" (should be uint8_t)
Definition: foamVtkCore.H:90
Namespace for OpenFOAM.
List< label > labelList
A List of labels.
Definition: List.H:66
PointIndexHit< point > pointIndexHit
A PointIndexHit for 3D points.
Definition: pointIndexHit.H:46
messageStream Info
Information stream (stdout output on master, null elsewhere)
vectorField pointField
pointField is a vectorField.
Definition: pointFieldFwd.H:44
vector point
Point is a vector.
Definition: point.H:43
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Field< vector > vectorField
Specialisation of Field<T> for vector.
List< bool > boolList
A List of bools.
Definition: List.H:64
error FatalError
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
List< face > faceList
A List of faces.
Definition: faceListFwd.H:47
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
void deleteDemandDrivenData(DataPtr &dataPtr)
cpuTimeCxx cpuTime
Selection of preferred clock mechanism for the elapsed cpu time.
Definition: cpuTimeFwd.H:43
bool readBool(Istream &is)
Read bool from stream using Foam::Switch(Istream&)
Definition: bool.C:69
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
labelList f(nPoints)
dictionary dict
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333