Permalink
Cannot retrieve contributors at this time
Join GitHub today
GitHub is home to over 40 million developers working together to host and review code, manage projects, and build software together.
Sign up
Find file
Copy path
OpenFOAM-6/src/meshTools/sets/cellSources/surfaceToCell/surfaceToCell.C
Find file
Copy path
Fetching contributors…

/*---------------------------------------------------------------------------*\ | |
========= | | |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox | |
\\ / O peration | Website: https://openfoam.org | |
\\ / A nd | Copyright (C) 2011-2018 OpenFOAM Foundation | |
\\/ M anipulation | | |
------------------------------------------------------------------------------- | |
License | |
This file is part of OpenFOAM. | |
OpenFOAM is free software: you can redistribute it and/or modify it | |
under the terms of the GNU General Public License as published by | |
the Free Software Foundation, either version 3 of the License, or | |
(at your option) any later version. | |
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT | |
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
for more details. | |
You should have received a copy of the GNU General Public License | |
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. | |
\*---------------------------------------------------------------------------*/ | |
#include "surfaceToCell.H" | |
#include "polyMesh.H" | |
#include "meshSearch.H" | |
#include "triSurface.H" | |
#include "triSurfaceSearch.H" | |
#include "cellClassification.H" | |
#include "cpuTime.H" | |
#include "demandDrivenData.H" | |
#include "addToRunTimeSelectionTable.H" | |
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // | |
namespace Foam | |
{ | |
defineTypeNameAndDebug(surfaceToCell, 0); | |
addToRunTimeSelectionTable(topoSetSource, surfaceToCell, word); | |
addToRunTimeSelectionTable(topoSetSource, surfaceToCell, istream); | |
} | |
Foam::topoSetSource::addToUsageTable Foam::surfaceToCell::usage_ | |
( | |
surfaceToCell::typeName, | |
"\n Usage: surfaceToCell" | |
"<surface> <outsidePoints> <cut> <inside> <outside> <near> <curvature>\n\n" | |
" <surface> name of triSurface\n" | |
" <outsidePoints> list of points that define outside\n" | |
" <cut> boolean whether to include cells cut by surface\n" | |
" <inside> ,, ,, inside surface\n" | |
" <outside> ,, ,, outside surface\n" | |
" <near> scalar; include cells with centre <= near to surface\n" | |
" <curvature> scalar; include cells close to strong curvature" | |
" on surface\n" | |
" (curvature defined as difference in surface normal at nearest" | |
" point on surface for each vertex of cell)\n\n" | |
); | |
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * // | |
Foam::label Foam::surfaceToCell::getNearest | |
( | |
const triSurfaceSearch& querySurf, | |
const label pointi, | |
const point& pt, | |
const vector& span, | |
Map<label>& cache | |
) | |
{ | |
Map<label>::const_iterator iter = cache.find(pointi); | |
if (iter != cache.end()) | |
{ | |
// Found cached answer | |
return iter(); | |
} | |
else | |
{ | |
pointIndexHit inter = querySurf.nearest(pt, span); | |
// Triangle label (can be -1) | |
label triI = inter.index(); | |
// Store triangle on point | |
cache.insert(pointi, triI); | |
return triI; | |
} | |
} | |
bool Foam::surfaceToCell::differingPointNormals | |
( | |
const triSurfaceSearch& querySurf, | |
const vector& span, // Current search span | |
const label celli, | |
const label cellTriI, // Nearest (to cell centre) surface triangle | |
Map<label>& pointToNearest // Cache for nearest triangle to point | |
) const | |
{ | |
const triSurface& surf = querySurf.surface(); | |
const vectorField& normals = surf.faceNormals(); | |
const faceList& faces = mesh().faces(); | |
const pointField& points = mesh().points(); | |
const labelList& cFaces = mesh().cells()[celli]; | |
forAll(cFaces, cFacei) | |
{ | |
const face& f = faces[cFaces[cFacei]]; | |
forAll(f, fp) | |
{ | |
label pointi = f[fp]; | |
label pointTriI = | |
getNearest | |
( | |
querySurf, | |
pointi, | |
points[pointi], | |
span, | |
pointToNearest | |
); | |
if (pointTriI != -1 && pointTriI != cellTriI) | |
{ | |
scalar cosAngle = normals[pointTriI] & normals[cellTriI]; | |
if (cosAngle < 0.9) | |
{ | |
return true; | |
} | |
} | |
} | |
} | |
return false; | |
} | |
void Foam::surfaceToCell::combine(topoSet& set, const bool add) const | |
{ | |
cpuTime timer; | |
if (useSurfaceOrientation_ && (includeInside_ || includeOutside_)) | |
{ | |
const meshSearch queryMesh(mesh_); | |
//- Calculate for each searchPoint inside/outside status. | |
boolList isInside(querySurf().calcInside(mesh_.cellCentres())); | |
Info<< " Marked inside/outside using surface orientation in = " | |
<< timer.cpuTimeIncrement() << " s" << endl << endl; | |
forAll(isInside, celli) | |
{ | |
if (isInside[celli] && includeInside_) | |
{ | |
addOrDelete(set, celli, add); | |
} | |
else if (!isInside[celli] && includeOutside_) | |
{ | |
addOrDelete(set, celli, add); | |
} | |
} | |
} | |
else if (includeCut_ || includeInside_ || includeOutside_) | |
{ | |
// | |
// Cut cells with surface and classify cells | |
// | |
// Construct search engine on mesh | |
const meshSearch queryMesh(mesh_); | |
// Check all 'outside' points | |
forAll(outsidePoints_, outsideI) | |
{ | |
const point& outsidePoint = outsidePoints_[outsideI]; | |
// Find cell point is in. Linear search. | |
label celli = queryMesh.findCell(outsidePoint, -1, false); | |
if (returnReduce(celli, maxOp<label>()) == -1) | |
{ | |
FatalErrorInFunction | |
<< "outsidePoint " << outsidePoint | |
<< " is not inside any cell" | |
<< exit(FatalError); | |
} | |
} | |
// Cut faces with surface and classify cells | |
cellClassification cellType | |
( | |
mesh_, | |
queryMesh, | |
querySurf(), | |
outsidePoints_ | |
); | |
Info<< " Marked inside/outside using surface intersection in = " | |
<< timer.cpuTimeIncrement() << " s" << endl << endl; | |
//- Add/remove cells using set | |
forAll(cellType, celli) | |
{ | |
label cType = cellType[celli]; | |
if | |
( | |
( | |
includeCut_ | |
&& (cType == cellClassification::CUT) | |
) | |
|| ( | |
includeInside_ | |
&& (cType == cellClassification::INSIDE) | |
) | |
|| ( | |
includeOutside_ | |
&& (cType == cellClassification::OUTSIDE) | |
) | |
) | |
{ | |
addOrDelete(set, celli, add); | |
} | |
} | |
} | |
if (nearDist_ > 0) | |
{ | |
// | |
// Determine distance to surface | |
// | |
const pointField& ctrs = mesh_.cellCentres(); | |
// Box dimensions to search in octree. | |
const vector span(nearDist_, nearDist_, nearDist_); | |
if (curvature_ < -1) | |
{ | |
Info<< " Selecting cells with cellCentre closer than " | |
<< nearDist_ << " to surface" << endl; | |
// No need to test curvature. Insert near cells into set. | |
forAll(ctrs, celli) | |
{ | |
const point& c = ctrs[celli]; | |
pointIndexHit inter = querySurf().nearest(c, span); | |
if (inter.hit() && (mag(inter.hitPoint() - c) < nearDist_)) | |
{ | |
addOrDelete(set, celli, add); | |
} | |
} | |
Info<< " Determined nearest surface point in = " | |
<< timer.cpuTimeIncrement() << " s" << endl << endl; | |
} | |
else | |
{ | |
// Test near cells for curvature | |
Info<< " Selecting cells with cellCentre closer than " | |
<< nearDist_ << " to surface and curvature factor" | |
<< " less than " << curvature_ << endl; | |
// Cache for nearest surface triangle for a point | |
Map<label> pointToNearest(mesh_.nCells()/10); | |
forAll(ctrs, celli) | |
{ | |
const point& c = ctrs[celli]; | |
pointIndexHit inter = querySurf().nearest(c, span); | |
if (inter.hit() && (mag(inter.hitPoint() - c) < nearDist_)) | |
{ | |
if | |
( | |
differingPointNormals | |
( | |
querySurf(), | |
span, | |
celli, | |
inter.index(), // nearest surface triangle | |
pointToNearest | |
) | |
) | |
{ | |
addOrDelete(set, celli, add); | |
} | |
} | |
} | |
Info<< " Determined nearest surface point in = " | |
<< timer.cpuTimeIncrement() << " s" << endl << endl; | |
} | |
} | |
} | |
void Foam::surfaceToCell::checkSettings() const | |
{ | |
if | |
( | |
(nearDist_ < 0) | |
&& (curvature_ < -1) | |
&& ( | |
(includeCut_ && includeInside_ && includeOutside_) | |
|| (!includeCut_ && !includeInside_ && !includeOutside_) | |
) | |
) | |
{ | |
FatalErrorInFunction | |
<< "Illegal include cell specification." | |
<< " Result would be either all or no cells." << endl | |
<< "Please set one of includeCut, includeInside, includeOutside" | |
<< " to true, set nearDistance to a value > 0" | |
<< " or set curvature to a value -1 .. 1." | |
<< exit(FatalError); | |
} | |
if (useSurfaceOrientation_ && includeCut_) | |
{ | |
FatalErrorInFunction | |
<< "Illegal include cell specification." | |
<< " You cannot specify both 'useSurfaceOrientation'" | |
<< " and 'includeCut'" | |
<< " since 'includeCut' specifies a topological split" | |
<< exit(FatalError); | |
} | |
} | |
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // | |
Foam::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 | |
) | |
: | |
topoSetSource(mesh), | |
surfName_(surfName), | |
outsidePoints_(outsidePoints), | |
includeCut_(includeCut), | |
includeInside_(includeInside), | |
includeOutside_(includeOutside), | |
useSurfaceOrientation_(useSurfaceOrientation), | |
nearDist_(nearDist), | |
curvature_(curvature), | |
surfPtr_(new triSurface(surfName_)), | |
querySurfPtr_(new triSurfaceSearch(*surfPtr_)), | |
IOwnPtrs_(true) | |
{ | |
checkSettings(); | |
} | |
Foam::surfaceToCell::surfaceToCell | |
( | |
const polyMesh& mesh, | |
const fileName& surfName, | |
const triSurface& surf, | |
const triSurfaceSearch& querySurf, | |
const pointField& outsidePoints, | |
const bool includeCut, | |
const bool includeInside, | |
const bool includeOutside, | |
const bool useSurfaceOrientation, | |
const scalar nearDist, | |
const scalar curvature | |
) | |
: | |
topoSetSource(mesh), | |
surfName_(surfName), | |
outsidePoints_(outsidePoints), | |
includeCut_(includeCut), | |
includeInside_(includeInside), | |
includeOutside_(includeOutside), | |
useSurfaceOrientation_(useSurfaceOrientation), | |
nearDist_(nearDist), | |
curvature_(curvature), | |
surfPtr_(&surf), | |
querySurfPtr_(&querySurf), | |
IOwnPtrs_(false) | |
{ | |
checkSettings(); | |
} | |
Foam::surfaceToCell::surfaceToCell | |
( | |
const polyMesh& mesh, | |
const dictionary& dict | |
) | |
: | |
topoSetSource(mesh), | |
surfName_(fileName(dict.lookup("file")).expand()), | |
outsidePoints_(dict.lookup("outsidePoints")), | |
includeCut_(readBool(dict.lookup("includeCut"))), | |
includeInside_(readBool(dict.lookup("includeInside"))), | |
includeOutside_(readBool(dict.lookup("includeOutside"))), | |
useSurfaceOrientation_ | |
( | |
dict.lookupOrDefault<bool>("useSurfaceOrientation", false) | |
), | |
nearDist_(readScalar(dict.lookup("nearDistance"))), | |
curvature_(readScalar(dict.lookup("curvature"))), | |
surfPtr_(new triSurface(surfName_)), | |
querySurfPtr_(new triSurfaceSearch(*surfPtr_)), | |
IOwnPtrs_(true) | |
{ | |
checkSettings(); | |
} | |
Foam::surfaceToCell::surfaceToCell | |
( | |
const polyMesh& mesh, | |
Istream& is | |
) | |
: | |
topoSetSource(mesh), | |
surfName_(checkIs(is)), | |
outsidePoints_(checkIs(is)), | |
includeCut_(readBool(checkIs(is))), | |
includeInside_(readBool(checkIs(is))), | |
includeOutside_(readBool(checkIs(is))), | |
useSurfaceOrientation_(false), | |
nearDist_(readScalar(checkIs(is))), | |
curvature_(readScalar(checkIs(is))), | |
surfPtr_(new triSurface(surfName_)), | |
querySurfPtr_(new triSurfaceSearch(*surfPtr_)), | |
IOwnPtrs_(true) | |
{ | |
checkSettings(); | |
} | |
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * // | |
Foam::surfaceToCell::~surfaceToCell() | |
{ | |
if (IOwnPtrs_) | |
{ | |
deleteDemandDrivenData(surfPtr_); | |
deleteDemandDrivenData(querySurfPtr_); | |
} | |
} | |
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // | |
void Foam::surfaceToCell::applyToSet | |
( | |
const topoSetSource::setAction action, | |
topoSet& set | |
) const | |
{ | |
if ((action == topoSetSource::NEW) || (action == topoSetSource::ADD)) | |
{ | |
Info<< " Adding cells in relation to surface " << surfName_ | |
<< " ..." << endl; | |
combine(set, true); | |
} | |
else if (action == topoSetSource::DELETE) | |
{ | |
Info<< " Removing cells in relation to surface " << surfName_ | |
<< " ..." << endl; | |
combine(set, false); | |
} | |
} | |
// ************************************************************************* // |