mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Creation of OpenFOAM-dev repository 15/04/2008
This commit is contained in:
@ -0,0 +1,5 @@
|
||||
edgeStats.C
|
||||
selectCells.C
|
||||
|
||||
EXE = $(FOAM_APPBIN)/selectCells
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
EXE_INC = \
|
||||
-I$(LIB_SRC)/dynamicMesh/lnInclude \
|
||||
-I$(LIB_SRC)/meshTools/lnInclude \
|
||||
-I$(LIB_SRC)/triSurface/lnInclude \
|
||||
-I$(LIB_SRC)/lagrangian/basic/lnInclude
|
||||
|
||||
|
||||
EXE_LIBS = \
|
||||
-ldynamicMesh \
|
||||
-lmeshTools \
|
||||
-ltriSurface \
|
||||
-llagrangian
|
||||
222
applications/utilities/mesh/advanced/selectCells/edgeStats.C
Normal file
222
applications/utilities/mesh/advanced/selectCells/edgeStats.C
Normal file
@ -0,0 +1,222 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "edgeStats.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "Ostream.H"
|
||||
#include "twoDPointCorrector.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
const Foam::scalar Foam::edgeStats::edgeTol_ = 1E-3;
|
||||
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||
|
||||
Foam::direction Foam::edgeStats::getNormalDir
|
||||
(
|
||||
const twoDPointCorrector* correct2DPtr
|
||||
) const
|
||||
{
|
||||
direction dir = 3;
|
||||
|
||||
if (correct2DPtr)
|
||||
{
|
||||
const vector& normal = correct2DPtr->planeNormal();
|
||||
|
||||
if (mag(normal & vector(1, 0, 0)) > 1-edgeTol_)
|
||||
{
|
||||
dir = 0;
|
||||
}
|
||||
else if (mag(normal & vector(0, 1, 0)) > 1-edgeTol_)
|
||||
{
|
||||
dir = 1;
|
||||
}
|
||||
else if (mag(normal & vector(0, 0, 1)) > 1-edgeTol_)
|
||||
{
|
||||
dir = 2;
|
||||
}
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
// Construct from mesh
|
||||
Foam::edgeStats::edgeStats(const polyMesh& mesh)
|
||||
:
|
||||
mesh_(mesh),
|
||||
normalDir_(3)
|
||||
{
|
||||
IOobject motionObj
|
||||
(
|
||||
"motionProperties",
|
||||
mesh.time().constant(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
);
|
||||
|
||||
if (motionObj.headerOk())
|
||||
{
|
||||
Info<< "Reading " << mesh.time().constant() / "motionProperties"
|
||||
<< endl << endl;
|
||||
|
||||
IOdictionary motionProperties(motionObj);
|
||||
|
||||
Switch twoDMotion(motionProperties.lookup("twoDMotion"));
|
||||
|
||||
if (twoDMotion)
|
||||
{
|
||||
Info<< "Correcting for 2D motion" << endl << endl;
|
||||
|
||||
autoPtr<twoDPointCorrector> correct2DPtr
|
||||
(
|
||||
new twoDPointCorrector(mesh)
|
||||
);
|
||||
|
||||
normalDir_ = getNormalDir(&correct2DPtr());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Construct from components
|
||||
Foam::edgeStats::edgeStats
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const twoDPointCorrector* correct2DPtr
|
||||
)
|
||||
:
|
||||
mesh_(mesh),
|
||||
normalDir_(getNormalDir(correct2DPtr))
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
Foam::scalar Foam::edgeStats::minLen(Ostream& os) const
|
||||
{
|
||||
label nX = 0;
|
||||
label nY = 0;
|
||||
label nZ = 0;
|
||||
|
||||
scalar minX = GREAT;
|
||||
scalar maxX = -GREAT;
|
||||
vector x(1, 0, 0);
|
||||
|
||||
scalar minY = GREAT;
|
||||
scalar maxY = -GREAT;
|
||||
vector y(0, 1, 0);
|
||||
|
||||
scalar minZ = GREAT;
|
||||
scalar maxZ = -GREAT;
|
||||
vector z(0, 0, 1);
|
||||
|
||||
scalar minOther = GREAT;
|
||||
scalar maxOther = -GREAT;
|
||||
|
||||
const edgeList& edges = mesh_.edges();
|
||||
|
||||
forAll(edges, edgeI)
|
||||
{
|
||||
const edge& e = edges[edgeI];
|
||||
|
||||
vector eVec(e.vec(mesh_.points()));
|
||||
|
||||
scalar eMag = mag(eVec);
|
||||
|
||||
eVec /= eMag;
|
||||
|
||||
if (mag(eVec & x) > 1-edgeTol_)
|
||||
{
|
||||
minX = min(minX, eMag);
|
||||
maxX = max(maxX, eMag);
|
||||
nX++;
|
||||
}
|
||||
else if (mag(eVec & y) > 1-edgeTol_)
|
||||
{
|
||||
minY = min(minY, eMag);
|
||||
maxY = max(maxY, eMag);
|
||||
nY++;
|
||||
}
|
||||
else if (mag(eVec & z) > 1-edgeTol_)
|
||||
{
|
||||
minZ = min(minZ, eMag);
|
||||
maxZ = max(maxZ, eMag);
|
||||
nZ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
minOther = min(minOther, eMag);
|
||||
maxOther = max(maxOther, eMag);
|
||||
}
|
||||
}
|
||||
|
||||
os << "Mesh bounding box:" << boundBox(mesh_.points()) << nl << nl
|
||||
<< "Mesh edge statistics:" << nl
|
||||
<< " x aligned : number:" << nX << "\tminLen:" << minX
|
||||
<< "\tmaxLen:" << maxX << nl
|
||||
<< " y aligned : number:" << nY << "\tminLen:" << minY
|
||||
<< "\tmaxLen:" << maxY << nl
|
||||
<< " z aligned : number:" << nZ << "\tminLen:" << minZ
|
||||
<< "\tmaxLen:" << maxZ << nl
|
||||
<< " other : number:" << mesh_.nEdges() - nX - nY - nZ
|
||||
<< "\tminLen:" << minOther
|
||||
<< "\tmaxLen:" << maxOther << nl << endl;
|
||||
|
||||
if (normalDir_ == 0)
|
||||
{
|
||||
return min(minY, min(minZ, minOther));
|
||||
}
|
||||
else if (normalDir_ == 1)
|
||||
{
|
||||
return min(minX, min(minZ, minOther));
|
||||
}
|
||||
else if (normalDir_ == 2)
|
||||
{
|
||||
return min(minX, min(minY, minOther));
|
||||
}
|
||||
else
|
||||
{
|
||||
return min(minX, min(minY, min(minZ, minOther)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Functions * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
111
applications/utilities/mesh/advanced/selectCells/edgeStats.H
Normal file
111
applications/utilities/mesh/advanced/selectCells/edgeStats.H
Normal file
@ -0,0 +1,111 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Class
|
||||
Foam::edgeStats
|
||||
|
||||
Description
|
||||
Helper class to calculate minimum edge length on mesh.
|
||||
|
||||
SourceFiles
|
||||
edgeStats.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#ifndef edgeStats_H
|
||||
#define edgeStats_H
|
||||
|
||||
#include "direction.H"
|
||||
#include "scalar.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
{
|
||||
|
||||
// Forward declaration of classes
|
||||
class polyMesh;
|
||||
class Ostream;
|
||||
class twoDPointCorrector;
|
||||
|
||||
/*---------------------------------------------------------------------------*\
|
||||
Class edgeStats Declaration
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
class edgeStats
|
||||
{
|
||||
// Private data
|
||||
|
||||
//- Reference to mesh.
|
||||
const polyMesh& mesh_;
|
||||
|
||||
//- Component (0,1,2) of normal direction or 3 if 3D case.
|
||||
direction normalDir_;
|
||||
|
||||
// Private Member Functions
|
||||
|
||||
//- If 2d get component of normal dir.
|
||||
direction getNormalDir(const twoDPointCorrector*) const;
|
||||
|
||||
|
||||
//- Disallow default bitwise copy construct
|
||||
edgeStats(const edgeStats&);
|
||||
|
||||
//- Disallow default bitwise assignment
|
||||
void operator=(const edgeStats&);
|
||||
|
||||
|
||||
public:
|
||||
|
||||
// Static data members
|
||||
|
||||
// Max (cos of) angle for edges to be considered aligned with axis.
|
||||
static const scalar edgeTol_;
|
||||
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from mesh
|
||||
edgeStats(const polyMesh& mesh);
|
||||
|
||||
//- Construct from mesh and corrector
|
||||
edgeStats(const polyMesh& mesh, const twoDPointCorrector* );
|
||||
|
||||
|
||||
// Member Functions
|
||||
|
||||
//- Calculate minimum edge length and print
|
||||
scalar minLen(Ostream& os) const;
|
||||
};
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
} // End namespace Foam
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************* //
|
||||
527
applications/utilities/mesh/advanced/selectCells/selectCells.C
Normal file
527
applications/utilities/mesh/advanced/selectCells/selectCells.C
Normal file
@ -0,0 +1,527 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
========= |
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
|
||||
\\/ 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 2 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, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
Description
|
||||
Select cells in relation to surface.
|
||||
|
||||
Divides cells into three sets:
|
||||
- cutCells : cells cut by surface or close to surface.
|
||||
- outside : cells not in cutCells and reachable from set of
|
||||
user-defined points (outsidePoints)
|
||||
- inside : same but not reachable.
|
||||
|
||||
Finally the wanted sets are combined into a cellSet 'selected'. Apart
|
||||
from straightforward adding the contents there are a few extra rules to
|
||||
make sure that the surface of the 'outside' of the mesh is singly
|
||||
connected.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "argList.H"
|
||||
#include "Time.H"
|
||||
#include "polyMesh.H"
|
||||
#include "IOdictionary.H"
|
||||
#include "twoDPointCorrector.H"
|
||||
#include "OFstream.H"
|
||||
#include "meshTools.H"
|
||||
|
||||
#include "triSurface.H"
|
||||
#include "triSurfaceSearch.H"
|
||||
#include "meshSearch.H"
|
||||
#include "cellClassification.H"
|
||||
#include "cellSet.H"
|
||||
#include "cellInfo.H"
|
||||
#include "MeshWave.H"
|
||||
#include "edgeStats.H"
|
||||
#include "octreeDataTriSurface.H"
|
||||
#include "octree.H"
|
||||
|
||||
using namespace Foam;
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
// cellType for cells included/not included in mesh.
|
||||
static const label MESH = cellClassification::INSIDE;
|
||||
static const label NONMESH = cellClassification::OUTSIDE;
|
||||
|
||||
|
||||
void writeSet(const cellSet& cells, const string& msg)
|
||||
{
|
||||
Info<< "Writing " << msg << " (" << cells.size() << ") to cellSet "
|
||||
<< cells.instance()/cells.local()/cells.name()
|
||||
<< endl << endl;
|
||||
cells.write();
|
||||
}
|
||||
|
||||
|
||||
void getType(const labelList& elems, const label type, labelHashSet& set)
|
||||
{
|
||||
forAll(elems, i)
|
||||
{
|
||||
if (elems[i] == type)
|
||||
{
|
||||
set.insert(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void cutBySurface
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const meshSearch& queryMesh,
|
||||
const triSurfaceSearch& querySurf,
|
||||
|
||||
const pointField& outsidePts,
|
||||
const bool selectCut,
|
||||
const bool selectInside,
|
||||
const bool selectOutside,
|
||||
const scalar nearDist,
|
||||
|
||||
cellClassification& cellType
|
||||
)
|
||||
{
|
||||
// Cut with surface and classify as inside/outside/cut
|
||||
cellType =
|
||||
cellClassification
|
||||
(
|
||||
mesh,
|
||||
queryMesh,
|
||||
querySurf,
|
||||
outsidePts
|
||||
);
|
||||
|
||||
// Get inside/outside/cutCells cellSets.
|
||||
cellSet inside(mesh, "inside", mesh.nCells()/10);
|
||||
getType(cellType, cellClassification::INSIDE, inside);
|
||||
writeSet(inside, "inside cells");
|
||||
|
||||
cellSet outside(mesh, "outside", mesh.nCells()/10);
|
||||
getType(cellType, cellClassification::OUTSIDE, outside);
|
||||
writeSet(outside, "outside cells");
|
||||
|
||||
cellSet cutCells(mesh, "cutCells", mesh.nCells()/10);
|
||||
getType(cellType, cellClassification::CUT, cutCells);
|
||||
writeSet(cutCells, "cells cut by surface");
|
||||
|
||||
|
||||
// Change cellType to reflect selected part of mesh. Use
|
||||
// MESH to denote selected part, NONMESH for all
|
||||
// other cells.
|
||||
// Is a bit of a hack but allows us to reuse all the functionality
|
||||
// in cellClassification.
|
||||
|
||||
forAll(cellType, cellI)
|
||||
{
|
||||
label cType = cellType[cellI];
|
||||
|
||||
if (cType == cellClassification::CUT)
|
||||
{
|
||||
if (selectCut)
|
||||
{
|
||||
cellType[cellI] = MESH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellType[cellI] = NONMESH;
|
||||
}
|
||||
}
|
||||
else if (cType == cellClassification::INSIDE)
|
||||
{
|
||||
if (selectInside)
|
||||
{
|
||||
cellType[cellI] = MESH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellType[cellI] = NONMESH;
|
||||
}
|
||||
}
|
||||
else if (cType == cellClassification::OUTSIDE)
|
||||
{
|
||||
if (selectOutside)
|
||||
{
|
||||
cellType[cellI] = MESH;
|
||||
}
|
||||
else
|
||||
{
|
||||
cellType[cellI] = NONMESH;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
FatalErrorIn("cutBySurface")
|
||||
<< "Multiple mesh regions in original mesh" << endl
|
||||
<< "Please use splitMeshRegions to separate these"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (nearDist > 0)
|
||||
{
|
||||
Info<< "Removing cells with points closer than " << nearDist
|
||||
<< " to the surface ..." << nl << endl;
|
||||
|
||||
const pointField& pts = mesh.points();
|
||||
const octree<octreeDataTriSurface>& tree = querySurf.tree();
|
||||
|
||||
label nRemoved = 0;
|
||||
|
||||
forAll(pts, pointI)
|
||||
{
|
||||
const point& pt = pts[pointI];
|
||||
|
||||
// Search in tight bounding box around pt.
|
||||
treeBoundBox tightest
|
||||
(
|
||||
pt - vector(nearDist, nearDist, nearDist),
|
||||
pt + vector(nearDist, nearDist, nearDist)
|
||||
);
|
||||
scalar tightestDist = mag(tightest.max() - tightest.min());
|
||||
|
||||
label triI = tree.findNearest(pt, tightest, tightestDist);
|
||||
|
||||
if (triI != -1 && tightestDist < nearDist)
|
||||
{
|
||||
const labelList& pCells = mesh.pointCells()[pointI];
|
||||
|
||||
forAll(pCells, i)
|
||||
{
|
||||
if (cellType[pCells[i]] != NONMESH)
|
||||
{
|
||||
cellType[pCells[i]] = NONMESH;
|
||||
nRemoved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tmp<pointField> tnearest = querySurf.calcNearest(pts);
|
||||
// const pointField& nearest = tnearest();
|
||||
//
|
||||
// label nRemoved = 0;
|
||||
//
|
||||
// forAll(nearest, pointI)
|
||||
// {
|
||||
// if (mag(nearest[pointI] - pts[pointI]) < nearDist)
|
||||
// {
|
||||
// const labelList& pCells = mesh.pointCells()[pointI];
|
||||
//
|
||||
// forAll(pCells, i)
|
||||
// {
|
||||
// if (cellType[pCells[i]] != NONMESH)
|
||||
// {
|
||||
// cellType[pCells[i]] = NONMESH;
|
||||
// nRemoved++;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
Info<< "Removed " << nRemoved << " cells since too close to surface"
|
||||
<< nl << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// We're meshing the outside. Subset the currently selected mesh cells with the
|
||||
// ones reachable from the outsidepoints.
|
||||
label selectOutsideCells
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const meshSearch& queryMesh,
|
||||
const pointField& outsidePts,
|
||||
cellClassification& cellType
|
||||
)
|
||||
{
|
||||
//
|
||||
// Check all outsidePts and for all of them inside a mesh cell
|
||||
// collect the faces to start walking from
|
||||
//
|
||||
|
||||
// Outside faces
|
||||
labelHashSet outsideFacesMap(outsidePts.size() * 6 * 2);
|
||||
DynamicList<label> outsideFaces(outsideFacesMap.size());
|
||||
// CellInfo on outside faces
|
||||
DynamicList<cellInfo> outsideFacesInfo(outsideFacesMap.size());
|
||||
|
||||
// cellInfo for mesh cell
|
||||
const cellInfo meshInfo(MESH);
|
||||
|
||||
forAll(outsidePts, outsidePtI)
|
||||
{
|
||||
// Find cell containing point. Linear search.
|
||||
label cellI = queryMesh.findCell(outsidePts[outsidePtI], -1, false);
|
||||
|
||||
if (cellType[cellI] == MESH)
|
||||
{
|
||||
Info<< "Marking cell " << cellI << " containing outside point "
|
||||
<< outsidePts[outsidePtI] << " with type " << cellType[cellI]
|
||||
<< " ..." << endl;
|
||||
|
||||
//
|
||||
// Mark this cell and its faces to start walking from
|
||||
//
|
||||
|
||||
// Mark faces of cellI
|
||||
const labelList& cFaces = mesh.cells()[cellI];
|
||||
forAll(cFaces, i)
|
||||
{
|
||||
label faceI = cFaces[i];
|
||||
|
||||
if (outsideFacesMap.insert(faceI))
|
||||
{
|
||||
outsideFaces.append(faceI);
|
||||
outsideFacesInfo.append(meshInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Floodfill starting from outsideFaces (of type meshInfo)
|
||||
MeshWave<cellInfo> regionCalc
|
||||
(
|
||||
mesh,
|
||||
outsideFaces.shrink(),
|
||||
outsideFacesInfo.shrink(),
|
||||
mesh.nCells() // max iterations
|
||||
);
|
||||
|
||||
// Now regionCalc should hold info on cells that are reachable from
|
||||
// changedFaces. Use these to subset cellType
|
||||
const List<cellInfo>& allCellInfo = regionCalc.allCellInfo();
|
||||
|
||||
label nChanged = 0;
|
||||
|
||||
forAll(allCellInfo, cellI)
|
||||
{
|
||||
if (cellType[cellI] == MESH)
|
||||
{
|
||||
// Original cell was selected for meshing. Check if cell was
|
||||
// reached from outsidePoints
|
||||
if (allCellInfo[cellI].type() != MESH)
|
||||
{
|
||||
cellType[cellI] = NONMESH;
|
||||
nChanged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nChanged;
|
||||
}
|
||||
|
||||
|
||||
// Main program:
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
argList::noParallel();
|
||||
|
||||
# include "setRootCase.H"
|
||||
# include "createTime.H"
|
||||
# include "createPolyMesh.H"
|
||||
|
||||
// Mesh edge statistics calculator
|
||||
edgeStats edgeCalc(mesh);
|
||||
|
||||
|
||||
IOdictionary refineDict
|
||||
(
|
||||
IOobject
|
||||
(
|
||||
"selectCellsDict",
|
||||
runTime.system(),
|
||||
mesh,
|
||||
IOobject::MUST_READ,
|
||||
IOobject::NO_WRITE
|
||||
)
|
||||
);
|
||||
|
||||
fileName surfName(refineDict.lookup("surface"));
|
||||
pointField outsidePts(refineDict.lookup("outsidePoints"));
|
||||
bool useSurface(readBool(refineDict.lookup("useSurface")));
|
||||
bool selectCut(readBool(refineDict.lookup("selectCut")));
|
||||
bool selectInside(readBool(refineDict.lookup("selectInside")));
|
||||
bool selectOutside(readBool(refineDict.lookup("selectOutside")));
|
||||
scalar nearDist(readScalar(refineDict.lookup("nearDistance")));
|
||||
|
||||
|
||||
if (useSurface)
|
||||
{
|
||||
Info<< "Cells to be used for meshing (0=false, 1=true):" << nl
|
||||
<< " cells cut by surface : " << selectCut << nl
|
||||
<< " cells inside of surface : " << selectInside << nl
|
||||
<< " cells outside of surface : " << selectOutside << nl
|
||||
<< " cells with points further than : " << nearDist << nl
|
||||
<< endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
Info<< "Cells to be used for meshing (0=false, 1=true):" << nl
|
||||
<< " cells reachable from outsidePoints:" << selectOutside << nl
|
||||
<< endl;
|
||||
}
|
||||
|
||||
// Print edge stats on original mesh.
|
||||
(void)edgeCalc.minLen(Info);
|
||||
|
||||
// Search engine on mesh. Face decomposition since faces might be warped.
|
||||
meshSearch queryMesh(mesh, true);
|
||||
|
||||
// Check all 'outside' points
|
||||
forAll(outsidePts, outsideI)
|
||||
{
|
||||
const point& outsidePoint = outsidePts[outsideI];
|
||||
|
||||
if (queryMesh.findCell(outsidePoint, -1, false) == -1)
|
||||
{
|
||||
FatalErrorIn(args.executable())
|
||||
<< "outsidePoint " << outsidePoint
|
||||
<< " is not inside any cell"
|
||||
<< exit(FatalError);
|
||||
}
|
||||
}
|
||||
|
||||
// Cell status (compared to surface if provided): inside/outside/cut.
|
||||
// Start off from everything selected and cut later.
|
||||
cellClassification cellType
|
||||
(
|
||||
mesh,
|
||||
labelList
|
||||
(
|
||||
mesh.nCells(),
|
||||
cellClassification::MESH
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
// Surface
|
||||
autoPtr<triSurface> surf(NULL);
|
||||
// Search engine on surface.
|
||||
autoPtr<triSurfaceSearch> querySurf(NULL);
|
||||
|
||||
if (useSurface)
|
||||
{
|
||||
surf.reset(new triSurface(surfName));
|
||||
|
||||
// Dump some stats
|
||||
surf().writeStats(Info);
|
||||
|
||||
// Search engine on surface.
|
||||
querySurf.reset(new triSurfaceSearch(surf));
|
||||
|
||||
// Set cellType[cellI] according to relation to surface
|
||||
cutBySurface
|
||||
(
|
||||
mesh,
|
||||
queryMesh,
|
||||
querySurf,
|
||||
|
||||
outsidePts,
|
||||
selectCut,
|
||||
selectInside,
|
||||
selectOutside,
|
||||
nearDist,
|
||||
|
||||
cellType
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Now 'trim' all the corners from the mesh so meshing/surface extraction
|
||||
// becomes easier.
|
||||
|
||||
label nHanging, nRegionEdges, nRegionPoints, nOutside;
|
||||
|
||||
do
|
||||
{
|
||||
Info<< "Removing cells which after subsetting would have all points"
|
||||
<< " on outside ..." << nl << endl;
|
||||
|
||||
nHanging = cellType.fillHangingCells
|
||||
(
|
||||
MESH, // meshType
|
||||
NONMESH, // fill type
|
||||
mesh.nCells()
|
||||
);
|
||||
|
||||
|
||||
Info<< "Removing edges connecting cells unconnected by faces ..."
|
||||
<< nl << endl;
|
||||
|
||||
nRegionEdges = cellType.fillRegionEdges
|
||||
(
|
||||
MESH, // meshType
|
||||
NONMESH, // fill type
|
||||
mesh.nCells()
|
||||
);
|
||||
|
||||
|
||||
Info<< "Removing points connecting cells unconnected by faces ..."
|
||||
<< nl << endl;
|
||||
|
||||
nRegionPoints = cellType.fillRegionPoints
|
||||
(
|
||||
MESH, // meshType
|
||||
NONMESH, // fill type
|
||||
mesh.nCells()
|
||||
);
|
||||
|
||||
nOutside = 0;
|
||||
if (selectOutside)
|
||||
{
|
||||
// Since we're selecting the cells reachable from outsidePoints
|
||||
// and the set might have changed, redo the outsideCells
|
||||
// calculation
|
||||
nOutside = selectOutsideCells
|
||||
(
|
||||
mesh,
|
||||
queryMesh,
|
||||
outsidePts,
|
||||
cellType
|
||||
);
|
||||
}
|
||||
} while
|
||||
(
|
||||
nHanging != 0
|
||||
|| nRegionEdges != 0
|
||||
|| nRegionPoints != 0
|
||||
|| nOutside != 0
|
||||
);
|
||||
|
||||
cellSet selectedCells(mesh, "selected", mesh.nCells()/10);
|
||||
getType(cellType, MESH, selectedCells);
|
||||
|
||||
writeSet(selectedCells, "cells selected for meshing");
|
||||
|
||||
|
||||
Info << "End\n" << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -0,0 +1,50 @@
|
||||
/*---------------------------------------------------------------------------*\
|
||||
| ========= | |
|
||||
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||
| \\ / O peration | Version: 1.0 |
|
||||
| \\ / A nd | Web: http://www.openfoam.org |
|
||||
| \\/ M anipulation | |
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
FoamFile
|
||||
{
|
||||
version 2.0;
|
||||
format ascii;
|
||||
|
||||
root "/home/penfold/mattijs/foam/mattijs2.1/run/icoFoam";
|
||||
case "cavity";
|
||||
instance "system";
|
||||
local "";
|
||||
|
||||
class dictionary;
|
||||
object selectCellsDict;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
// Whether to use surface. If false no surface will be read and only
|
||||
// outsidePoints/selectOutside will be used to determine cells to keep.
|
||||
useSurface false;
|
||||
|
||||
// Surface to keep to
|
||||
surface "plexi.ftr";
|
||||
|
||||
// What is outside
|
||||
outsidePoints ((-1 -1 -1));
|
||||
|
||||
|
||||
//
|
||||
// Selection of final set
|
||||
//
|
||||
|
||||
// Select based on side of surface. Usually select inside cells and project
|
||||
// outwards or select outside cells and project inwards.
|
||||
selectCut false;
|
||||
selectInside false;
|
||||
selectOutside true;
|
||||
// Leave out cell closer than nearDistance to the surface. Usually
|
||||
// 0.5*of the cell size. Set to <0 to disable.
|
||||
nearDistance -1;
|
||||
|
||||
// ************************************************************************* //
|
||||
Reference in New Issue
Block a user