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 | Copyright (C) 2011-2015 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 
26 #include "surfaceToCell.H"
27 #include "polyMesh.H"
28 #include "meshSearch.H"
29 #include "triSurface.H"
30 #include "triSurfaceSearch.H"
31 #include "cellClassification.H"
32 #include "cpuTime.H"
33 #include "demandDrivenData.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(surfaceToCell, 0);
41  addToRunTimeSelectionTable(topoSetSource, surfaceToCell, word);
42  addToRunTimeSelectionTable(topoSetSource, surfaceToCell, istream);
43 }
44 
45 
47 (
48  surfaceToCell::typeName,
49  "\n Usage: surfaceToCell"
50  "<surface> <outsidePoints> <cut> <inside> <outside> <near> <curvature>\n\n"
51  " <surface> name of triSurface\n"
52  " <outsidePoints> list of points that define outside\n"
53  " <cut> boolean whether to include cells cut by surface\n"
54  " <inside> ,, ,, inside surface\n"
55  " <outside> ,, ,, outside surface\n"
56  " <near> scalar; include cells with centre <= near to surface\n"
57  " <curvature> scalar; include cells close to strong curvature"
58  " on surface\n"
59  " (curvature defined as difference in surface normal at nearest"
60  " point on surface for each vertex of cell)\n\n"
61 );
62 
63 
64 // * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
65 
67 (
68  const triSurfaceSearch& querySurf,
69  const label pointI,
70  const point& pt,
71  const vector& span,
72  Map<label>& cache
73 )
74 {
75  Map<label>::const_iterator iter = cache.find(pointI);
76 
77  if (iter != cache.end())
78  {
79  // Found cached answer
80  return iter();
81  }
82  else
83  {
84  pointIndexHit inter = querySurf.nearest(pt, span);
85 
86  // Triangle label (can be -1)
87  label triI = inter.index();
88 
89  // Store triangle on point
90  cache.insert(pointI, triI);
91 
92  return triI;
93  }
94 }
95 
96 
98 (
99  const triSurfaceSearch& querySurf,
100 
101  const vector& span, // Current search span
102  const label cellI,
103  const label cellTriI, // Nearest (to cell centre) surface triangle
104 
105  Map<label>& pointToNearest // Cache for nearest triangle to point
106 ) const
107 {
108  const triSurface& surf = querySurf.surface();
109  const vectorField& normals = surf.faceNormals();
110 
111  const faceList& faces = mesh().faces();
112  const pointField& points = mesh().points();
113 
114  const labelList& cFaces = mesh().cells()[cellI];
115 
116  forAll(cFaces, cFaceI)
117  {
118  const face& f = faces[cFaces[cFaceI]];
119 
120  forAll(f, fp)
121  {
122  label pointI = f[fp];
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 
149 void Foam::surfaceToCell::combine(topoSet& set, const bool add) const
150 {
151  cpuTime timer;
152 
153 
155  {
156  const meshSearch queryMesh(mesh_);
157 
158  //- Calculate for each searchPoint inside/outside status.
159  boolList isInside(querySurf().calcInside(mesh_.cellCentres()));
160 
161  Info<< " Marked inside/outside using surface orientation in = "
162  << timer.cpuTimeIncrement() << " s" << endl << endl;
163 
164  forAll(isInside, cellI)
165  {
166  if (isInside[cellI] && includeInside_)
167  {
168  addOrDelete(set, cellI, add);
169  }
170  else if (!isInside[cellI] && includeOutside_)
171  {
172  addOrDelete(set, cellI, add);
173  }
174  }
175  }
177  {
178  //
179  // Cut cells with surface and classify cells
180  //
181 
182 
183  // Construct search engine on mesh
184 
185  const meshSearch queryMesh(mesh_);
186 
187 
188  // Check all 'outside' points
189  forAll(outsidePoints_, outsideI)
190  {
191  const point& outsidePoint = outsidePoints_[outsideI];
192 
193  // Find cell point is in. Linear search.
194  label cellI = queryMesh.findCell(outsidePoint, -1, false);
195  if (returnReduce(cellI, maxOp<label>()) == -1)
196  {
198  << "outsidePoint " << outsidePoint
199  << " is not inside any cell"
200  << exit(FatalError);
201  }
202  }
203 
204  // Cut faces with surface and classify cells
205 
206  cellClassification cellType
207  (
208  mesh_,
209  queryMesh,
210  querySurf(),
212  );
213 
214 
215  Info<< " Marked inside/outside using surface intersection in = "
216  << timer.cpuTimeIncrement() << " s" << endl << endl;
217 
218  //- Add/remove cells using set
219  forAll(cellType, cellI)
220  {
221  label cType = cellType[cellI];
222 
223  if
224  (
225  (
227  && (cType == cellClassification::CUT)
228  )
229  || (
231  && (cType == cellClassification::INSIDE)
232  )
233  || (
235  && (cType == cellClassification::OUTSIDE)
236  )
237  )
238  {
239  addOrDelete(set, cellI, add);
240  }
241  }
242  }
243 
244 
245  if (nearDist_ > 0)
246  {
247  //
248  // Determine distance to surface
249  //
250 
251  const pointField& ctrs = mesh_.cellCentres();
252 
253  // Box dimensions to search in octree.
254  const vector span(nearDist_, nearDist_, nearDist_);
255 
256 
257  if (curvature_ < -1)
258  {
259  Info<< " Selecting cells with cellCentre closer than "
260  << nearDist_ << " to surface" << endl;
261 
262  // No need to test curvature. Insert near cells into set.
263 
264  forAll(ctrs, cellI)
265  {
266  const point& c = ctrs[cellI];
267 
268  pointIndexHit inter = querySurf().nearest(c, span);
269 
270  if (inter.hit() && (mag(inter.hitPoint() - c) < nearDist_))
271  {
272  addOrDelete(set, cellI, add);
273  }
274  }
275 
276  Info<< " Determined nearest surface point in = "
277  << timer.cpuTimeIncrement() << " s" << endl << endl;
278 
279  }
280  else
281  {
282  // Test near cells for curvature
283 
284  Info<< " Selecting cells with cellCentre closer than "
285  << nearDist_ << " to surface and curvature factor"
286  << " less than " << curvature_ << endl;
287 
288  // Cache for nearest surface triangle for a point
289  Map<label> pointToNearest(mesh_.nCells()/10);
290 
291  forAll(ctrs, cellI)
292  {
293  const point& c = ctrs[cellI];
294 
295  pointIndexHit inter = querySurf().nearest(c, span);
296 
297  if (inter.hit() && (mag(inter.hitPoint() - c) < nearDist_))
298  {
299  if
300  (
302  (
303  querySurf(),
304  span,
305  cellI,
306  inter.index(), // nearest surface triangle
307  pointToNearest
308  )
309  )
310  {
311  addOrDelete(set, cellI, add);
312  }
313  }
314  }
315 
316  Info<< " Determined nearest surface point in = "
317  << timer.cpuTimeIncrement() << " s" << endl << endl;
318  }
319  }
320 }
321 
322 
324 {
325  if
326  (
327  (nearDist_ < 0)
328  && (curvature_ < -1)
329  && (
330  (includeCut_ && includeInside_ && includeOutside_)
331  || (!includeCut_ && !includeInside_ && !includeOutside_)
332  )
333  )
334  {
336  << "Illegal include cell specification."
337  << " Result would be either all or no cells." << endl
338  << "Please set one of includeCut, includeInside, includeOutside"
339  << " to true, set nearDistance to a value > 0"
340  << " or set curvature to a value -1 .. 1."
341  << exit(FatalError);
342  }
343 
344  if (useSurfaceOrientation_ && includeCut_)
345  {
347  << "Illegal include cell specification."
348  << " You cannot specify both 'useSurfaceOrientation'"
349  << " and 'includeCut'"
350  << " since 'includeCut' specifies a topological split"
351  << exit(FatalError);
352  }
353 }
354 
355 
356 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
357 
359 (
360  const polyMesh& mesh,
361  const fileName& surfName,
362  const pointField& outsidePoints,
363  const bool includeCut,
364  const bool includeInside,
365  const bool includeOutside,
366  const bool useSurfaceOrientation,
367  const scalar nearDist,
368  const scalar curvature
369 )
370 :
372  surfName_(surfName),
373  outsidePoints_(outsidePoints),
374  includeCut_(includeCut),
375  includeInside_(includeInside),
376  includeOutside_(includeOutside),
377  useSurfaceOrientation_(useSurfaceOrientation),
378  nearDist_(nearDist),
379  curvature_(curvature),
380  surfPtr_(new triSurface(surfName_)),
381  querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
382  IOwnPtrs_(true)
383 {
384  checkSettings();
385 }
386 
387 
389 (
390  const polyMesh& mesh,
391  const fileName& surfName,
392  const triSurface& surf,
393  const triSurfaceSearch& querySurf,
394  const pointField& outsidePoints,
395  const bool includeCut,
396  const bool includeInside,
397  const bool includeOutside,
398  const bool useSurfaceOrientation,
399  const scalar nearDist,
400  const scalar curvature
401 )
402 :
404  surfName_(surfName),
405  outsidePoints_(outsidePoints),
406  includeCut_(includeCut),
407  includeInside_(includeInside),
408  includeOutside_(includeOutside),
409  useSurfaceOrientation_(useSurfaceOrientation),
410  nearDist_(nearDist),
411  curvature_(curvature),
412  surfPtr_(&surf),
413  querySurfPtr_(&querySurf),
414  IOwnPtrs_(false)
415 {
416  checkSettings();
417 }
418 
419 
421 (
422  const polyMesh& mesh,
423  const dictionary& dict
424 )
425 :
427  surfName_(fileName(dict.lookup("file")).expand()),
428  outsidePoints_(dict.lookup("outsidePoints")),
429  includeCut_(readBool(dict.lookup("includeCut"))),
430  includeInside_(readBool(dict.lookup("includeInside"))),
431  includeOutside_(readBool(dict.lookup("includeOutside"))),
432  useSurfaceOrientation_
433  (
434  dict.lookupOrDefault<bool>("useSurfaceOrientation", false)
435  ),
436  nearDist_(readScalar(dict.lookup("nearDistance"))),
437  curvature_(readScalar(dict.lookup("curvature"))),
438  surfPtr_(new triSurface(surfName_)),
439  querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
440  IOwnPtrs_(true)
441 {
442  checkSettings();
443 }
444 
445 
447 (
448  const polyMesh& mesh,
449  Istream& is
450 )
451 :
453  surfName_(checkIs(is)),
454  outsidePoints_(checkIs(is)),
455  includeCut_(readBool(checkIs(is))),
456  includeInside_(readBool(checkIs(is))),
457  includeOutside_(readBool(checkIs(is))),
458  useSurfaceOrientation_(false),
459  nearDist_(readScalar(checkIs(is))),
460  curvature_(readScalar(checkIs(is))),
461  surfPtr_(new triSurface(surfName_)),
462  querySurfPtr_(new triSurfaceSearch(*surfPtr_)),
463  IOwnPtrs_(true)
464 {
465  checkSettings();
466 }
467 
468 
469 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
470 
472 {
473  if (IOwnPtrs_)
474  {
475  deleteDemandDrivenData(surfPtr_);
476  deleteDemandDrivenData(querySurfPtr_);
477  }
478 }
479 
480 
481 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
482 
484 (
485  const topoSetSource::setAction action,
486  topoSet& set
487 ) const
488 {
489  if ((action == topoSetSource::NEW) || (action == topoSetSource::ADD))
490  {
491  Info<< " Adding cells in relation to surface " << surfName_
492  << " ..." << endl;
493 
494  combine(set, true);
495  }
496  else if (action == topoSetSource::DELETE)
497  {
498  Info<< " Removing cells in relation to surface " << surfName_
499  << " ..." << endl;
500 
501  combine(set, false);
502  }
503 }
504 
505 
506 // ************************************************************************* //
cellClassification.H
Foam::cpuTime
Starts timing CPU usage and return elapsed time from start.
Definition: cpuTime.H:52
Foam::maxOp
Definition: ops.H:172
Foam::surfaceToCell::checkSettings
void checkSettings() const
Check values at construction time.
Definition: surfaceToCell.C:323
Foam::topoSetSource::ADD
@ ADD
Definition: topoSetSource.H:87
Foam::PointIndexHit::index
label index() const
Return index.
Definition: PointIndexHit.H:111
Foam::meshSearch
Various (local, not parallel) searches on polyMesh; uses (demand driven) octree to search.
Definition: meshSearch.H:57
Foam::fileName
A class for handling file names.
Definition: fileName.H:69
Foam::returnReduce
T returnReduce(const T &Value, const BinaryOp &bop, const int tag=Pstream::msgType(), const label comm=UPstream::worldComm)
Definition: PstreamReduceOps.H:86
Foam::surfaceToCell::nearDist_
const scalar nearDist_
If > 0 : include cells with distance from cellCentre to surface.
Definition: surfaceToCell.H:91
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: UList.H:406
Foam::triSurfaceSearch::nearest
pointIndexHit nearest(const point &, const vector &span) const
Calculate nearest point on surface for single searchPoint. Returns.
Definition: triSurfaceSearch.C:312
Foam::addToRunTimeSelectionTable
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
demandDrivenData.H
Template functions to aid in the implementation of demand driven data.
Foam::ListListOps::combine
AccessType combine(const List< T > &, AccessOp aop=accessOp< T >())
Combines sublists into one big list.
Definition: ListListOps.C:34
Foam::surfaceToCell::getNearest
static label getNearest(const triSurfaceSearch &querySurf, const label pointI, const point &pt, const vector &searchSpan, Map< label > &cache)
Find index of nearest triangle to point. Returns triangle or -1 if.
Definition: surfaceToCell.C:67
Foam::topoSetSource::addToUsageTable
Class with constructor to add usage string to table.
Definition: topoSetSource.H:100
Foam::cellClassification::CUT
@ CUT
Definition: cellClassification.H:130
Foam::dictionary::lookup
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:449
Foam::PointIndexHit::hit
bool hit() const
Is there a hit.
Definition: PointIndexHit.H:105
Foam::dictionary::lookupOrDefault
T lookupOrDefault(const word &, const T &, bool recursive=false, bool patternMatch=true) const
Find and return a T,.
Definition: dictionaryTemplates.C:33
Foam::surfaceToCell::combine
void combine(topoSet &set, const bool add) const
Depending on surface add to or delete from cellSet.
Definition: surfaceToCell.C:149
Foam::Map< label >
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:251
Foam::topoSetSource::setAction
setAction
Enumeration defining the valid actions.
Definition: topoSetSource.H:82
Foam::topoSetSource::NEW
@ NEW
Definition: topoSetSource.H:85
Foam::surfaceToCell::includeCut_
const bool includeCut_
Include cut cells.
Definition: surfaceToCell.H:77
Foam::cellClassification::INSIDE
@ INSIDE
Definition: cellClassification.H:128
Foam::mag
dimensioned< scalar > mag(const dimensioned< Type > &)
polyMesh.H
Foam::triSurfaceSearch
Helper class to search on triSurface.
Definition: triSurfaceSearch.H:55
surfaceToCell.H
Foam::polyMesh
Mesh consisting of general polyhedral cells.
Definition: polyMesh.H:74
Foam::surfaceToCell::differingPointNormals
bool differingPointNormals(const triSurfaceSearch &querySurf, const vector &span, const label cellI, const label cellTriI, Map< label > &pointToNearest) const
Return true if surface normal of nearest points to vertices on.
Definition: surfaceToCell.C:98
Foam::primitiveMesh::nCells
label nCells() const
Definition: primitiveMeshI.H:64
Foam::deleteDemandDrivenData
void deleteDemandDrivenData(DataPtr &dataPtr)
Definition: demandDrivenData.H:40
Foam::surfaceToCell::curvature_
const scalar curvature_
If > -1 : include cells with normals at nearest surface points.
Definition: surfaceToCell.H:95
Foam::PointIndexHit
This class describes the interaction of (usually) a face and a point. It carries the info of a succes...
Definition: PointIndexHit.H:53
Foam::label
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
Foam::Field
Pre-declare SubField and related Field type.
Definition: Field.H:57
Foam::triSurface
Triangulated surface description with patch information.
Definition: triSurface.H:57
Foam::Istream
An Istream is an abstract base class for all input systems (streams, files, token lists etc)....
Definition: Istream.H:57
Foam::Info
messageStream Info
Foam::PointIndexHit::hitPoint
const Point & hitPoint() const
Return hit point.
Definition: PointIndexHit.H:117
Foam::cellClassification::OUTSIDE
@ OUTSIDE
Definition: cellClassification.H:129
Foam::topoSetSource::DELETE
@ DELETE
Definition: topoSetSource.H:88
Foam::topoSet
General set of labels of mesh quantity (points, cells, faces).
Definition: topoSet.H:61
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::surfaceToCell::includeInside_
const bool includeInside_
Include inside cells.
Definition: surfaceToCell.H:80
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by any number of values (e....
Definition: dictionary.H:137
Foam::add
void add(FieldField< Field1, typename typeOfSum< Type1, Type2 >::type > &f, const FieldField< Field1, Type1 > &f1, const FieldField< Field2, Type2 > &f2)
Definition: FieldFieldFunctions.C:870
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:18
addToRunTimeSelectionTable.H
Macros for easy insertion into run-time selection tables.
Foam::surfaceToCell::usage_
static addToUsageTable usage_
Add usage string.
Definition: surfaceToCell.H:68
Foam
Namespace for OpenFOAM.
Definition: combustionModel.C:30
Foam::topoSetSource
Base class of a source for a topoSet.
Definition: topoSetSource.H:63
cpuTime.H
Foam::cellClassification
'Cuts' a mesh with a surface.
Definition: cellClassification.H:115
Foam::surfaceToCell::useSurfaceOrientation_
const bool useSurfaceOrientation_
Determine inside/outside purely using geometric test.
Definition: surfaceToCell.H:87
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:124
Foam::primitiveMesh::cellCentres
const vectorField & cellCentres() const
Definition: primitiveMeshCellCentresAndVols.C:211
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:318
meshSearch.H
Foam::readScalar
bool readScalar(const char *buf, doubleScalar &s)
Read whole of buf as a scalar. Return true if succesful.
Definition: doubleScalar.H:63
Foam::PrimitivePatch::faceNormals
const Field< PointType > & faceNormals() const
Return face normals for patch.
Definition: PrimitivePatchTemplate.C:520
f
labelList f(nPoints)
Foam::surfaceToCell::includeOutside_
const bool includeOutside_
Include outside cells.
Definition: surfaceToCell.H:83
Foam::Vector< scalar >
Foam::List
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
Definition: HashTable.H:59
Foam::meshSearch::findCell
label findCell(const point &location, const label seedCellI=-1, const bool useTreeSearch=true) const
Find cell containing location.
Definition: meshSearch.C:788
Foam::surfaceToCell::surfaceToCell
surfaceToCell(const polyMesh &mesh, const fileName &surfName, const pointField &outsidePoints, const bool includeCut, const bool includeInside, const bool includeOutside, const bool useSurfaceOrientation, const scalar nearDist, const scalar curvature)
Construct from components.
Definition: surfaceToCell.C:359
Foam::string::expand
string & expand(const bool allowEmpty=false)
Expand initial tildes and all occurences of environment variables.
Definition: string.C:98
Foam::timer
Implements a timeout mechanism via sigalarm.
Definition: timer.H:81
Foam::triSurfaceSearch::surface
const triSurface & surface() const
Return reference to the surface.
Definition: triSurfaceSearch.H:125
points
const pointField & points
Definition: gmvOutputHeader.H:1
triSurfaceSearch.H
Foam::constant::universal::c
const dimensionedScalar c
Speed of light in a vacuum.
Foam::face
A face is a list of labels corresponding to mesh vertices.
Definition: face.H:75
Foam::readBool
bool readBool(Istream &)
Definition: boolIO.C:60
Foam::surfaceToCell::outsidePoints_
const pointField outsidePoints_
Points which are outside.
Definition: surfaceToCell.H:74
Foam::topoSetSource::mesh_
const polyMesh & mesh_
Definition: topoSetSource.H:126
Foam::surfaceToCell::querySurf
const triSurfaceSearch & querySurf() const
Definition: surfaceToCell.H:141
Foam::defineTypeNameAndDebug
defineTypeNameAndDebug(combustionModel, 0)
Foam::topoSetSource::addOrDelete
void addOrDelete(topoSet &set, const label cellI, const bool) const
Add (if bool) cellI to set or delete cellI from set.
Definition: topoSetSource.C:140
Foam::surfaceToCell::~surfaceToCell
virtual ~surfaceToCell()
Destructor.
Definition: surfaceToCell.C:471
Foam::surfaceToCell::applyToSet
virtual void applyToSet(const topoSetSource::setAction action, topoSet &) const
Definition: surfaceToCell.C:484