Merge branch 'master' of ssh://noisy/home/noisy2/OpenFOAM/OpenFOAM-dev

This commit is contained in:
henry
2008-07-09 09:43:42 +01:00
33 changed files with 3379 additions and 12586 deletions

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -33,12 +33,86 @@ Description
#include "argList.H"
#include "Time.H"
#include "fvMesh.H"
#include "autoHexMeshDriver.H"
#include "autoRefineDriver.H"
#include "autoSnapDriver.H"
#include "autoLayerDriver.H"
#include "searchableSurfaces.H"
#include "refinementSurfaces.H"
#include "shellSurfaces.H"
#include "decompositionMethod.H"
#include "fvMeshDistribute.H"
#include "wallPolyPatch.H"
#include "refinementParameters.H"
#include "snapParameters.H"
#include "layerParameters.H"
using namespace Foam;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Check writing tolerance before doing any serious work
scalar getMergeDistance(const polyMesh& mesh, const scalar mergeTol)
{
const boundBox& meshBb = mesh.bounds();
scalar mergeDist = mergeTol*mag(meshBb.max() - meshBb.min());
scalar writeTol = std::pow
(
scalar(10.0),
-scalar(IOstream::defaultPrecision())
);
Info<< nl
<< "Overall mesh bounding box : " << meshBb << nl
<< "Relative tolerance : " << mergeTol << nl
<< "Absolute matching distance : " << mergeDist << nl
<< endl;
if (mesh.time().writeFormat() == IOstream::ASCII && mergeTol < writeTol)
{
FatalErrorIn("getMergeDistance(const polyMesh&, const scalar)")
<< "Your current settings specify ASCII writing with "
<< IOstream::defaultPrecision() << " digits precision." << endl
<< "Your merging tolerance (" << mergeTol << ") is finer than this."
<< endl
<< "Please change your writeFormat to binary"
<< " or increase the writePrecision" << endl
<< "or adjust the merge tolerance (-mergeTol)."
<< exit(FatalError);
}
return mergeDist;
}
// Write mesh and additional information
void writeMesh
(
const string& msg,
const meshRefinement& meshRefiner,
const label debug
)
{
const fvMesh& mesh = meshRefiner.mesh();
meshRefiner.printMeshInfo(debug, msg);
Info<< "Writing mesh to time " << mesh.time().timeName() << endl;
meshRefiner.write(meshRefinement::MESH|meshRefinement::SCALARLEVELS, "");
if (debug & meshRefinement::OBJINTERSECTIONS)
{
meshRefiner.write
(
meshRefinement::OBJINTERSECTIONS,
mesh.time().path()/mesh.time().timeName()
);
}
Info<< "Written mesh in = "
<< mesh.time().cpuTimeIncrement() << " s." << endl;
}
int main(int argc, char *argv[])
{
# include "setRootCase.H"
@ -49,6 +123,11 @@ int main(int argc, char *argv[])
Info<< "Read mesh in = "
<< runTime.cpuTimeIncrement() << " s" << endl;
// Check patches and faceZones are synchronised
mesh.boundaryMesh().checkParallelSync(true);
meshRefinement::checkCoupledFaceZones(mesh);
// Read decomposePar dictionary
IOdictionary decomposeDict
(
@ -75,51 +154,282 @@ int main(int argc, char *argv[])
)
);
// refinement parameters
const dictionary& refineDict = meshDict.subDict("castellatedMeshControls");
// all surface geometry
const dictionary& geometryDict = meshDict.subDict("geometry");
// snap-to-surface parameters
const dictionary& snapDict = meshDict.subDict("snapControls");
// refinement parameters
const dictionary& refineDict = meshDict.subDict("castellatedMeshControls");
// mesh motion and mesh quality parameters
const dictionary& motionDict = meshDict.subDict("meshQualityControls");
// snap-to-surface parameters
const dictionary& snapDict = meshDict.subDict("snapControls");
// layer addition parameters
const dictionary& layerDict = meshDict.subDict("addLayersControls");
// Main meshing driver. Read surfaces. Determine initial intersections.
autoHexMeshDriver meshEngine
// Debug
// ~~~~~
const label debug(readLabel(meshDict.lookup("debug")));
if (debug > 0)
{
meshRefinement::debug = debug;
autoRefineDriver::debug = debug;
autoSnapDriver::debug = debug;
autoLayerDriver::debug = debug;
}
// Read geometry
// ~~~~~~~~~~~~~
searchableSurfaces allGeometry
(
IOobject
(
"abc", // dummy name
mesh.time().constant(), // directory
"triSurface", // instance
mesh.time(), // registry
IOobject::MUST_READ,
IOobject::NO_WRITE
),
geometryDict
);
// Read refinement surfaces
// ~~~~~~~~~~~~~~~~~~~~~~~~
Info<< "Reading refinement surfaces." << endl;
refinementSurfaces surfaces
(
allGeometry,
refineDict.subDict("refinementSurfaces")
);
Info<< "Read refinement surfaces in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
// Read refinement shells
// ~~~~~~~~~~~~~~~~~~~~~~
Info<< "Reading refinement shells." << endl;
shellSurfaces shells
(
allGeometry,
refineDict.subDict("refinementRegions")
);
Info<< "Read refinement shells in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
Info<< "Setting refinement level of surface to be consistent"
<< " with shells." << endl;
surfaces.setMinLevelFields(shells);
Info<< "Checked shell refinement in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
// Add all the surface regions as patches
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelList globalToPatch;
{
Info<< nl
<< "Adding patches for surface regions" << nl
<< "----------------------------------" << nl
<< endl;
// From global region number to mesh patch.
globalToPatch.setSize(surfaces.nRegions(), -1);
Info<< "Patch\tRegion" << nl
<< "-----\t------"
<< endl;
const labelList& surfaceGeometry = surfaces.surfaces();
forAll(surfaceGeometry, surfI)
{
label geomI = surfaceGeometry[surfI];
const wordList& regNames = allGeometry.regionNames()[geomI];
Info<< surfaces.names()[surfI] << ':' << nl << nl;
forAll(regNames, i)
{
label patchI = meshRefinement::addPatch
(
mesh,
regNames[i],
wallPolyPatch::typeName
);
Info<< patchI << '\t' << regNames[i] << nl;
globalToPatch[surfaces.globalRegion(surfI, i)] = patchI;
}
Info<< nl;
}
Info<< "Added patches in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
}
// Parallel
// ~~~~~~~~
// Decomposition
autoPtr<decompositionMethod> decomposerPtr
(
decompositionMethod::New
(
decomposeDict,
mesh
)
);
decompositionMethod& decomposer = decomposerPtr();
if (Pstream::parRun() && !decomposer.parallelAware())
{
FatalErrorIn(args.executable())
<< "You have selected decomposition method "
<< decomposer.typeName
<< " which is not parallel aware." << endl
<< "Please select one that is (hierarchical, parMetis)"
<< exit(FatalError);
}
const scalar mergeDist = getMergeDistance
(
mesh,
meshDict, // global control parameters
geometryDict,
refineDict, // refinement parameters
decomposeDict
readScalar(meshDict.lookup("mergeTolerance"))
);
// Mesh distribution engine (uses tolerance to reconstruct meshes)
fvMeshDistribute distributor(mesh, mergeDist);
// Refinement engine
// ~~~~~~~~~~~~~~~~~
Info<< nl
<< "Determining initial surface intersections" << nl
<< "-----------------------------------------" << nl
<< endl;
// Main refinement engine
meshRefinement meshRefiner
(
mesh,
mergeDist, // tolerance used in sorting coordinates
surfaces, // for surface intersection refinement
shells // for volume (inside/outside) refinement
);
Info<< "Calculated surface intersections in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
// Some stats
meshRefiner.printMeshInfo(debug, "Initial mesh");
meshRefiner.write
(
debug&meshRefinement::OBJINTERSECTIONS,
mesh.time().path()/mesh.time().timeName()
);
// Now do the real work -refinement -snapping -layers
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Switch wantRefine(meshDict.lookup("castellatedMesh"));
Switch wantSnap(meshDict.lookup("snap"));
Switch wantLayers(meshDict.lookup("addLayers"));
if (wantRefine)
{
meshEngine.doRefine(refineDict, wantSnap);
autoRefineDriver refineDriver
(
meshRefiner,
decomposer,
distributor,
globalToPatch
);
// Refinement parameters
refinementParameters refineParams(refineDict);
refineDriver.doRefine(refineDict, refineParams, wantSnap);
writeMesh
(
"Refined mesh",
meshRefiner,
debug
);
}
if (wantSnap)
{
meshEngine.doSnap(snapDict, motionDict);
autoSnapDriver snapDriver
(
meshRefiner,
globalToPatch
);
// Snap parameters
snapParameters snapParams(snapDict);
snapDriver.doSnap(snapDict, motionDict, snapParams);
writeMesh
(
"Snapped mesh",
meshRefiner,
debug
);
}
if (wantLayers)
{
meshEngine.doLayers(layerDict, motionDict);
autoLayerDriver layerDriver
(
meshRefiner,
globalToPatch
);
// Layer addition parameters
layerParameters layerParams(layerDict, mesh.boundaryMesh());
layerDriver.doLayers
(
layerDict,
motionDict,
layerParams,
decomposer,
distributor
);
writeMesh
(
"Layer mesh",
meshRefiner,
debug
);
}
Info<< "Finished meshing in = "
<< runTime.elapsedCpuTime() << " s." << endl;

View File

@ -36,26 +36,26 @@ addLayers false;
// - to 'snap' the mesh boundary to the surface
geometry
{
// box1x1x1
// {
// type searchableBox;
// min (1.5 1 -0.5);
// max (3.5 2 0.5);
// }
//
// sphere.stl
// {
// type triSurfaceMesh;
//
// // Per region the patchname. If not provided will be <name>_<region>.
// regions
// {
// secondSolid
// {
// name mySecondPatch;
// }
// }
// }
box1x1x1
{
type searchableBox;
min (1.5 1 -0.5);
max (3.5 2 0.5);
}
sphere.stl
{
type triSurfaceMesh;
// Per region the patchname. If not provided will be <name>_<region>.
regions
{
secondSolid
{
name mySecondPatch;
}
}
}
sphere2
{
@ -159,11 +159,11 @@ castellatedMeshControls
refinementRegions
{
//box1x1x1
//{
// mode inside;
// levels ((1.0 4));
//}
box1x1x1
{
mode inside;
levels ((1.0 4));
}
//sphere.stl
//{
// mode distance;

View File

@ -1,6 +1,6 @@
<ParaViewReaders>
<Reader name="PV3FoamReader"
extensions="foam OpenFOAM"
extensions="OpenFOAM"
file_description="OpenFOAM">
</Reader>
</ParaViewReaders>

View File

@ -1,10 +1,12 @@
autoHexMesh = autoHexMesh
autoHexMeshDriver = $(autoHexMesh)/autoHexMeshDriver
$(autoHexMeshDriver)/autoLayerDriver.C
$(autoHexMeshDriver)/autoLayerDriverShrink.C
$(autoHexMeshDriver)/autoSnapDriver.C
$(autoHexMeshDriver)/autoRefineDriver.C
$(autoHexMeshDriver)/autoHexMeshDriver.C
$(autoHexMeshDriver)/autoHexMeshDriverLayers.C
$(autoHexMeshDriver)/autoHexMeshDriverShrink.C
$(autoHexMeshDriver)/autoHexMeshDriverSnap.C
$(autoHexMeshDriver)/layerParameters/layerParameters.C
$(autoHexMeshDriver)/refinementParameters/refinementParameters.C
$(autoHexMeshDriver)/snapParameters/snapParameters.C

File diff suppressed because it is too large Load Diff

View File

@ -30,10 +30,6 @@ Description
SourceFiles
autoHexMeshDriver.C
autoHexMeshDriverSnap.C
autoHexMeshDriverLayers.C
autoHexMeshDriverShrink.C
autoHexMeshDriverTemplates.C
\*---------------------------------------------------------------------------*/
@ -44,11 +40,7 @@ SourceFiles
#include "dictionary.H"
#include "pointField.H"
#include "boolList.H"
#include "Switch.H"
#include "PackedList.H"
#include "wallPoint.H"
#include "indirectPrimitivePatch.H"
#include "featureEdgeMesh.H"
#include "searchableSurfaces.H"
#include "refinementSurfaces.H"
#include "shellSurfaces.H"
@ -63,17 +55,6 @@ namespace Foam
// Class forward declarations
class fvMesh;
class pointMesh;
class motionSmoother;
class removePoints;
class pointSet;
class pointData;
class faceSet;
class addPatchCellLayer;
class mapDistributePolyMesh;
class snapParameters;
class layerParameters;
class refinementParameters;
/*---------------------------------------------------------------------------*\
Class autoHexMeshDriver Declaration
@ -147,13 +128,6 @@ class autoHexMeshDriver
const scalar mergeDist_;
// Refinement only
//- Explicit features
PtrList<featureEdgeMesh> featureMeshes_;
//- Per feature the refinement level
labelList featureLevels_;
//- All surface based geometry
autoPtr<searchableSurfaces> allGeometryPtr_;
@ -179,436 +153,10 @@ class autoHexMeshDriver
// Private Member Functions
// Refinement
//- Calculate merge distance. Check against writing tolerance.
scalar getMergeDistance(const scalar mergeTol) const;
static void orientOutside(PtrList<searchableSurface>&);
//- Read feature edges
label readFeatureEdges(const PtrList<dictionary>&);
// Snapping
//- Split surfaces into non-zoned and zones ones
void getZonedSurfaces(labelList&, labelList&) const;
//- Get faces to repatch. Returns map from face to patch.
Map<label> getZoneBafflePatches(const bool allowBoundary) const;
//- Calculates (geometric) shared points
static label getCollocatedPoints
(
const scalar tol,
const pointField&,
PackedList<1>&
);
//- Calculate displacement per patch point to smooth out patch.
// Quite complicated in determining which points to move where.
pointField smoothPatchDisplacement(const motionSmoother&) const;
//- Check that face zones are synced
void checkCoupledFaceZones() const;
//- Per edge distance to patch
static tmp<scalarField> edgePatchDist
(
const pointMesh&,
const indirectPrimitivePatch&
);
//- Write displacement as .obj file.
static void dumpMove
(
const fileName&,
const pointField&,
const pointField&
);
//- Check displacement is outwards pointing
static bool outwardsDisplacement
(
const indirectPrimitivePatch&,
const vectorField&
);
// Face merging
//- Merge patch faces. Undo until no checkMesh errors.
label mergePatchFacesUndo
(
const scalar minCos,
const scalar concaveCos,
const dictionary&
);
//- Remove points.
autoPtr<mapPolyMesh> doRemovePoints
(
removePoints& pointRemover,
const boolList& pointCanBeDeleted
);
//- Restore faces (which contain removed points)
autoPtr<mapPolyMesh> doRestorePoints
(
removePoints& pointRemover,
const labelList& facesToRestore
);
//- Return candidateFaces that are also in set.
labelList collectFaces
(
const labelList& candidateFaces,
const labelHashSet& set
) const;
//- Pick up faces of cells of faces in set.
labelList growFaceCellFace(const labelHashSet&) const;
//- Remove points not used by any face or points used by only
// two faces where the edges are in line
label mergeEdgesUndo(const scalar minCos, const dictionary&);
// Layers
//- For debugging: Dump displacement to .obj files
static void dumpDisplacement
(
const fileName&,
const indirectPrimitivePatch&,
const vectorField&,
const List<extrudeMode>&
);
//- Check that primitivePatch is not multiply connected.
// Collect non-manifold points in pointSet.
static void checkManifold
(
const indirectPrimitivePatch&,
pointSet& nonManifoldPoints
);
// Static extrusion setup
//- Unset extrusion on point. Returns true if anything unset.
static bool unmarkExtrusion
(
const label patchPointI,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Unset extrusion on face. Returns true if anything unset.
static bool unmarkExtrusion
(
const face& localFace,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- No extrusion at non-manifold points.
void handleNonManifolds
(
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- No extrusion on feature edges. Assumes non-manifold
// edges already handled.
void handleFeatureAngle
(
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
const scalar minCos,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- No extrusion on warped faces
void handleWarpedFaces
(
const indirectPrimitivePatch& pp,
const scalar faceRatio,
const scalar edge0Len,
const labelList& cellLevel,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Determine the number of layers per point from the number of
// layers per surface.
void setNumLayers
(
const labelList& patchToNLayers,
const labelList& patchIDs,
const indirectPrimitivePatch& pp,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Grow no-extrusion layer.
static void growNoExtrusion
(
const indirectPrimitivePatch& pp,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Calculate pointwise wanted and minimum thickness.
// thickness: wanted thickness
// minthickness: when to give up and not extrude
// Gets per patch parameters and determine pp pointwise
// parameters.
void calculateLayerThickness
(
const indirectPrimitivePatch& pp,
const labelList& patchIDs,
const scalarField& patchExpansionRatio,
const scalarField& patchFinalLayerRatio,
const scalarField& patchRelMinThickness,
const labelList& cellLevel,
const labelList& patchNLayers,
const scalar edge0Len,
scalarField& thickness,
scalarField& minThickness,
scalarField& expansionRatio
) const;
// Extrusion execution
//- Synchronize displacement among coupled patches.
void syncPatchDisplacement
(
const motionSmoother& meshMover,
const scalarField& minThickness,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Get nearest point on surface to snap to
void getPatchDisplacement
(
const motionSmoother& meshMover,
const scalarField& thickness,
const scalarField& minThickness,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Truncates displacement
// - for all patchFaces in the faceset displacement gets set
// to zero
// - all displacement < minThickness gets set to zero
label truncateDisplacement
(
const motionSmoother& meshMover,
const scalarField& minThickness,
const faceSet& illegalPatchFaces,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Setup layer information (at points and faces) to
// modify mesh topology in
// regions where layer mesh terminates. Guarantees an
// optional slow decreasing of the number of layers.
// Returns the number of layers per face and per point
// to go into the actual layer addition engine.
void setupLayerInfoTruncation
(
const motionSmoother& meshMover,
const labelList& patchNLayers,
const List<extrudeMode>& extrudeStatus,
const label nBufferCellsNoExtrude,
labelList& nPatchPointLayers,
labelList& nPatchFaceLayers
) const;
//- Does any of the cells use a face from faces?
static bool cellsUseFace
(
const polyMesh& mesh,
const labelList& cellLabels,
const labelHashSet& faces
);
//- Checks the newly added cells and locally unmarks points
// so they will not get extruded next time round. Returns
// global number of unmarked points (0 if all was fine)
static label checkAndUnmark
(
const addPatchCellLayer& addLayer,
const dictionary& motionDict,
const indirectPrimitivePatch& pp,
const fvMesh&,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Count global number of extruded faces
static label countExtrusion
(
const indirectPrimitivePatch& pp,
const List<extrudeMode>& extrudeStatus
);
//- Collect layer faces and layer cells into bools
// for ease of handling
static void getLayerCellsFaces
(
const polyMesh&,
const addPatchCellLayer&,
boolList&,
boolList&
);
// Mesh shrinking (to create space for layers)
//- Average field (over all subset of mesh points) by
// summing contribution from edges. Global parallel since only
// does master edges for coupled edges.
template<class Type>
void averageNeighbours
(
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const labelList& meshPoints,
const edgeList& edges,
const scalarField& invSumWeight,
const Field<Type>& data,
Field<Type>& average
) const;
//- Calculate inverse sum of edge weights (currently always 1.0)
void sumWeights
(
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const labelList& meshPoints,
const edgeList& edges,
scalarField& invSumWeight
) const;
//- Smooth scalar field on patch
void smoothField
(
const motionSmoother& meshMover,
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const scalarField& fieldMin,
const label& nSmoothDisp,
scalarField& field
) const;
//- Smooth normals on patch.
void smoothPatchNormals
(
const motionSmoother& meshMover,
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const label nSmoothDisp,
pointField& normals
) const;
//- Smooth normals in interior.
void smoothNormals
(
const label nSmoothDisp,
const PackedList<1>& isMasterEdge,
const labelList& fixedPoints,
pointVectorField& normals
) const;
bool isMaxEdge
(
const List<pointData>&,
const label edgeI,
const scalar minCos
) const;
//- Stop layer growth where mesh wraps around edge with a
// large feature angle
void handleFeatureAngleLayerTerminations
(
const indirectPrimitivePatch& pp,
const scalar minCos,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers,
label& nPointCounter
) const;
//- Find isolated islands (points, edges and faces and
// layer terminations)
// in the layer mesh and stop any layer growth at these points.
void findIsolatedRegions
(
const indirectPrimitivePatch& pp,
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const scalar minCosLayerTermination,
scalarField& field,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers
) const;
// Calculate medial axis fields
void medialAxisSmoothingInfo
(
const motionSmoother& meshMover,
const label nSmoothNormals,
const label nSmoothSurfaceNormals,
const scalar minMedianAxisAngleCos,
pointVectorField& dispVec,
pointScalarField& medialRatio,
pointScalarField& medialDist
) const;
//- Main routine to shrink mesh
void shrinkMeshMedialDistance
(
motionSmoother& meshMover,
const label nSmoothThickness,
const scalar maxThicknessToMedialRatio,
const label nAllowableErrors,
const label nSnap,
const scalar minCosLayerTermination,
const scalarField& layerThickness,
const scalarField& minThickness,
const pointVectorField& dispVec,
const pointScalarField& medialRatio,
const pointScalarField& medialDist,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers
) const;
//- Calculate merge distance. Check against writing tolerance.
scalar getMergeDistance(const scalar mergeTol) const;
//static void orientOutside(PtrList<searchableSurface>&);
//- Disallow default bitwise copy construct
autoHexMeshDriver(const autoHexMeshDriver&);
@ -624,22 +172,11 @@ public:
// Constructors
// //- Construct from dictionary and mesh to modify
// autoHexMeshDriver
// (
// fvMesh& mesh,
// const dictionary& meshDict,
// const dictionary& decomposeDict
// );
//- Alternative constructor from top-level controldictionary and
// refinement specific dictionary
//- Construct from dictionary and mesh to modify
autoHexMeshDriver
(
fvMesh& mesh,
const dictionary& controlDict,
const dictionary& geometryDict,
const dictionary& refineDict,
const dictionary& meshDict,
const dictionary& decomposeDict
);
@ -677,181 +214,11 @@ public:
}
// Refinement
//- Refine around explicit feature edges
label featureEdgeRefine
(
const refinementParameters& refineParams,
const PtrList<dictionary>& featDicts,
const label maxIter,
const label minRefine
);
//- Refine at surface intersections
label surfaceOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Remove cells not reachable from keep points
void removeInsideCells
(
const refinementParameters& refineParams,
const label nBufferLayers
);
//- Refine volume regions (interior of shells)
label shellRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Introduce baffles; remove unreachable mesh parts
// handleSnapProblems : whether to remove free floating cells
void baffleAndSplitMesh
(
const refinementParameters& refineParams,
const bool handleSnapProblems
);
//- Move cells to zones
void zonify(const refinementParameters&);
//- Split and recombine baffles to get rid of single face baffles.
void splitAndMergeBaffles
(
const refinementParameters& refineParams,
const bool handleSnapProblems
);
//- Merge multiple boundary faces on single cell
void mergePatchFaces(const refinementParameters&);
//- Redecompose according to cell count
// keepZoneFaces : find all faceZones from zoned surfaces and keep
// owner and neighbour together
// keepBaffles : find all baffles and keep them together
autoPtr<mapDistributePolyMesh> balance
(
const bool keepZoneFaces,
const bool keepBaffles
);
// Meshing
//- Write mesh
void writeMesh(const string&) const;
// Snapping
//- Create baffles for faces straddling zoned surfaces. Return
// baffles.
autoPtr<mapPolyMesh> createZoneBaffles(List<labelPair>&);
//- Merge baffles.
autoPtr<mapPolyMesh> mergeZoneBaffles(const List<labelPair>&);
//- Calculate edge length per patch point.
scalarField calcSnapDistance
(
const snapParameters& snapParams,
const indirectPrimitivePatch&
) const;
//- Get patches generated for surfaces.
labelList getSurfacePatches() const;
//- Smooth the mesh (patch and internal) to increase visibility
// of surface points (on castellated mesh) w.r.t. surface.
void preSmoothPatch
(
const snapParameters& snapParams,
const label nInitErrors,
const List<labelPair>& baffles,
motionSmoother&
) const;
//- Get points both on patch and facezone.
labelList getZoneSurfacePoints
(
const indirectPrimitivePatch&,
const word& zoneName
) const;
//- Per patch point calculate point on nearest surface. Set as
// boundary conditions of motionSmoother displacement field. Return
// displacement of patch points.
vectorField calcNearestSurface
(
const scalarField& snapDist,
motionSmoother& meshMover
) const;
//- Smooth the displacement field to the internal.
void smoothDisplacement
(
const snapParameters& snapParams,
motionSmoother&
) const;
//- Do the hard work: move the mesh according to displacement,
// locally relax the displacement.
void scaleMesh
(
const snapParameters& snapParams,
const label nInitErrors,
const List<labelPair>& baffles,
motionSmoother&
);
// Layers
//- Merge patch faces on same cell.
void mergePatchFacesUndo
(
const layerParameters& layerParams,
const dictionary& motionDict
);
//- Check that mesh outside is not multiply connected.
void checkMeshManifold() const;
//- Add cell layers
void addLayers
(
const layerParameters& layerParams,
const dictionary& motionDict,
const label nAllowableErrors,
motionSmoother&
);
// Other
//- Do all refinement.
void doRefine
(
const dictionary& refineDict,
const bool prepareForSnapping
);
//- Do all snapping.
void doSnap
(
const dictionary& snapDict,
const dictionary& motionDict
);
//- Do alllayer addition.
void doLayers
(
const dictionary& shrinkDict,
const dictionary& motionDict
);
//- Do all : refine, snap, layers
void doMesh();
};
@ -863,12 +230,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "autoHexMeshDriverTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,562 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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::autoLayerDriver
Description
All to do with adding layers
SourceFiles
autoLayerDriver.C
\*---------------------------------------------------------------------------*/
#ifndef autoLayerDriver_H
#define autoLayerDriver_H
#include "meshRefinement.H"
#include "wallPoint.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class removePoints;
class pointSet;
class motionSmoother;
class addPatchCellLayer;
class pointData;
class wallPoint;
class faceSet;
class layerParameters;
/*---------------------------------------------------------------------------*\
Class autoLayerDriver Declaration
\*---------------------------------------------------------------------------*/
class autoLayerDriver
{
// Static data members
//- Extrusion controls
enum extrudeMode
{
NOEXTRUDE, /*!< Do not extrude. No layers added. */
EXTRUDE, /*!< Extrude */
EXTRUDEREMOVE /*!< Extrude but afterwards remove added */
/*!< faces locally */
};
// Private classes
//- Combine operator class to combine normal with other normal.
class nomalsCombine
{
public:
void operator()(vector& x, const vector& y) const
{
if (y != wallPoint::greatPoint)
{
if (x == wallPoint::greatPoint)
{
x = y;
}
else
{
x *= (x&y);
}
}
}
};
// Private data
//- Mesh+surface
meshRefinement& meshRefiner_;
//- From surface region to patch
const labelList globalToPatch_;
// Private Member Functions
// Face merging
//- Merge patch faces. Undo until no checkMesh errors.
label mergePatchFacesUndo
(
const scalar minCos,
const scalar concaveCos,
const dictionary&
);
//- Remove points.
autoPtr<mapPolyMesh> doRemovePoints
(
removePoints& pointRemover,
const boolList& pointCanBeDeleted
);
//- Restore faces (which contain removed points)
autoPtr<mapPolyMesh> doRestorePoints
(
removePoints& pointRemover,
const labelList& facesToRestore
);
//- Return candidateFaces that are also in set.
labelList collectFaces
(
const labelList& candidateFaces,
const labelHashSet& set
) const;
//- Pick up faces of cells of faces in set.
labelList growFaceCellFace(const labelHashSet&) const;
//- Remove points not used by any face or points used by only
// two faces where the edges are in line
label mergeEdgesUndo(const scalar minCos, const dictionary&);
// Layers
//- For debugging: Dump displacement to .obj files
static void dumpDisplacement
(
const fileName&,
const indirectPrimitivePatch&,
const vectorField&,
const List<extrudeMode>&
);
//- Check that primitivePatch is not multiply connected.
// Collect non-manifold points in pointSet.
static void checkManifold
(
const indirectPrimitivePatch&,
pointSet& nonManifoldPoints
);
//- Check that mesh outside is not multiply connected.
void checkMeshManifold() const;
// Static extrusion setup
//- Unset extrusion on point. Returns true if anything unset.
static bool unmarkExtrusion
(
const label patchPointI,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Unset extrusion on face. Returns true if anything unset.
static bool unmarkExtrusion
(
const face& localFace,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- No extrusion at non-manifold points.
void handleNonManifolds
(
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- No extrusion on feature edges. Assumes non-manifold
// edges already handled.
void handleFeatureAngle
(
const indirectPrimitivePatch& pp,
const labelList& meshEdges,
const scalar minCos,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- No extrusion on warped faces
void handleWarpedFaces
(
const indirectPrimitivePatch& pp,
const scalar faceRatio,
const scalar edge0Len,
const labelList& cellLevel,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Determine the number of layers per point from the number of
// layers per surface.
void setNumLayers
(
const labelList& patchToNLayers,
const labelList& patchIDs,
const indirectPrimitivePatch& pp,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Grow no-extrusion layer.
static void growNoExtrusion
(
const indirectPrimitivePatch& pp,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Calculate pointwise wanted and minimum thickness.
// thickness: wanted thickness
// minthickness: when to give up and not extrude
// Gets per patch parameters and determine pp pointwise
// parameters.
void calculateLayerThickness
(
const indirectPrimitivePatch& pp,
const labelList& patchIDs,
const scalarField& patchExpansionRatio,
const scalarField& patchFinalLayerRatio,
const scalarField& patchRelMinThickness,
const labelList& cellLevel,
const labelList& patchNLayers,
const scalar edge0Len,
scalarField& thickness,
scalarField& minThickness,
scalarField& expansionRatio
) const;
// Extrusion execution
//- Synchronize displacement among coupled patches.
void syncPatchDisplacement
(
const motionSmoother& meshMover,
const scalarField& minThickness,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Get nearest point on surface to snap to
void getPatchDisplacement
(
const motionSmoother& meshMover,
const scalarField& thickness,
const scalarField& minThickness,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Truncates displacement
// - for all patchFaces in the faceset displacement gets set
// to zero
// - all displacement < minThickness gets set to zero
label truncateDisplacement
(
const motionSmoother& meshMover,
const scalarField& minThickness,
const faceSet& illegalPatchFaces,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
) const;
//- Setup layer information (at points and faces) to
// modify mesh topology in
// regions where layer mesh terminates. Guarantees an
// optional slow decreasing of the number of layers.
// Returns the number of layers per face and per point
// to go into the actual layer addition engine.
void setupLayerInfoTruncation
(
const motionSmoother& meshMover,
const labelList& patchNLayers,
const List<extrudeMode>& extrudeStatus,
const label nBufferCellsNoExtrude,
labelList& nPatchPointLayers,
labelList& nPatchFaceLayers
) const;
//- Does any of the cells use a face from faces?
static bool cellsUseFace
(
const polyMesh& mesh,
const labelList& cellLabels,
const labelHashSet& faces
);
//- Checks the newly added cells and locally unmarks points
// so they will not get extruded next time round. Returns
// global number of unmarked points (0 if all was fine)
static label checkAndUnmark
(
const addPatchCellLayer& addLayer,
const dictionary& motionDict,
const indirectPrimitivePatch& pp,
const fvMesh&,
pointField& patchDisp,
labelList& patchNLayers,
List<extrudeMode>& extrudeStatus
);
//- Count global number of extruded faces
static label countExtrusion
(
const indirectPrimitivePatch& pp,
const List<extrudeMode>& extrudeStatus
);
//- Collect layer faces and layer cells into bools
// for ease of handling
static void getLayerCellsFaces
(
const polyMesh&,
const addPatchCellLayer&,
boolList&,
boolList&
);
// Mesh shrinking (to create space for layers)
//- Average field (over all subset of mesh points) by
// summing contribution from edges. Global parallel since only
// does master edges for coupled edges.
template<class Type>
static void averageNeighbours
(
const polyMesh& mesh,
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const labelList& meshPoints,
const edgeList& edges,
const scalarField& invSumWeight,
const Field<Type>& data,
Field<Type>& average
);
//- Calculate inverse sum of edge weights (currently always 1.0)
void sumWeights
(
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const labelList& meshPoints,
const edgeList& edges,
scalarField& invSumWeight
) const;
//- Smooth scalar field on patch
void smoothField
(
const motionSmoother& meshMover,
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const scalarField& fieldMin,
const label& nSmoothDisp,
scalarField& field
) const;
//- Smooth normals on patch.
void smoothPatchNormals
(
const motionSmoother& meshMover,
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const label nSmoothDisp,
pointField& normals
) const;
//- Smooth normals in interior.
void smoothNormals
(
const label nSmoothDisp,
const PackedList<1>& isMasterEdge,
const labelList& fixedPoints,
pointVectorField& normals
) const;
bool isMaxEdge
(
const List<pointData>&,
const label edgeI,
const scalar minCos
) const;
//- Stop layer growth where mesh wraps around edge with a
// large feature angle
void handleFeatureAngleLayerTerminations
(
const indirectPrimitivePatch& pp,
const scalar minCos,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers,
label& nPointCounter
) const;
//- Find isolated islands (points, edges and faces and
// layer terminations)
// in the layer mesh and stop any layer growth at these points.
void findIsolatedRegions
(
const indirectPrimitivePatch& pp,
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const scalar minCosLayerTermination,
scalarField& field,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers
) const;
// Calculate medial axis fields
void medialAxisSmoothingInfo
(
const motionSmoother& meshMover,
const label nSmoothNormals,
const label nSmoothSurfaceNormals,
const scalar minMedianAxisAngleCos,
pointVectorField& dispVec,
pointScalarField& medialRatio,
pointScalarField& medialDist
) const;
//- Main routine to shrink mesh
void shrinkMeshMedialDistance
(
motionSmoother& meshMover,
const label nSmoothThickness,
const scalar maxThicknessToMedialRatio,
const label nAllowableErrors,
const label nSnap,
const scalar minCosLayerTermination,
const scalarField& layerThickness,
const scalarField& minThickness,
const pointVectorField& dispVec,
const pointScalarField& medialRatio,
const pointScalarField& medialDist,
List<extrudeMode>& extrudeStatus,
pointField& patchDisp,
labelList& patchNLayers
) const;
//- Disallow default bitwise copy construct
autoLayerDriver(const autoLayerDriver&);
//- Disallow default bitwise assignment
void operator=(const autoLayerDriver&);
public:
//- Runtime type information
ClassName("autoLayerDriver");
// Constructors
//- Construct from components
autoLayerDriver
(
meshRefinement& meshRefiner,
const labelList& globalToPatch
);
// Member Functions
//- Merge patch faces on same cell.
void mergePatchFacesUndo
(
const layerParameters& layerParams,
const dictionary& motionDict
);
//- Add cell layers
void addLayers
(
const layerParameters& layerParams,
const dictionary& motionDict,
const label nAllowableErrors,
motionSmoother& meshMover,
decompositionMethod& decomposer,
fvMeshDistribute& distributor
);
//- Add layers according to the dictionary settings
void doLayers
(
const dictionary& shrinkDict,
const dictionary& motionDict,
const layerParameters& layerParams,
decompositionMethod& decomposer,
fvMeshDistribute& distributor
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "autoLayerDriverTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -27,7 +27,7 @@ Description
\*----------------------------------------------------------------------------*/
#include "autoHexMeshDriver.H"
#include "autoLayerDriver.H"
#include "fvMesh.H"
#include "Time.H"
#include "pointFields.H"
@ -41,7 +41,7 @@ Description
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Calculate inverse sum of edge weights (currently always 1.0)
void Foam::autoHexMeshDriver::sumWeights
void Foam::autoLayerDriver::sumWeights
(
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
@ -67,7 +67,7 @@ void Foam::autoHexMeshDriver::sumWeights
syncTools::syncPointList
(
mesh_,
meshRefiner_.mesh(),
meshPoints,
invSumWeight,
plusEqOp<scalar>(),
@ -88,7 +88,7 @@ void Foam::autoHexMeshDriver::sumWeights
// Smooth field on moving patch
void Foam::autoHexMeshDriver::smoothField
void Foam::autoLayerDriver::smoothField
(
const motionSmoother& meshMover,
const PackedList<1>& isMasterEdge,
@ -120,6 +120,7 @@ void Foam::autoHexMeshDriver::smoothField
scalarField average(pp.nPoints());
averageNeighbours
(
meshMover.mesh(),
isMasterEdge,
meshEdges,
meshPoints,
@ -159,7 +160,7 @@ void Foam::autoHexMeshDriver::smoothField
// Smooth normals on moving patch.
void Foam::autoHexMeshDriver::smoothPatchNormals
void Foam::autoLayerDriver::smoothPatchNormals
(
const motionSmoother& meshMover,
const PackedList<1>& isMasterEdge,
@ -192,6 +193,7 @@ void Foam::autoHexMeshDriver::smoothPatchNormals
vectorField average(pp.nPoints());
averageNeighbours
(
meshMover.mesh(),
isMasterEdge,
meshEdges,
meshPoints,
@ -223,7 +225,7 @@ void Foam::autoHexMeshDriver::smoothPatchNormals
// Smooth normals in interior.
void Foam::autoHexMeshDriver::smoothNormals
void Foam::autoLayerDriver::smoothNormals
(
const label nSmoothDisp,
const PackedList<1>& isMasterEdge,
@ -234,10 +236,11 @@ void Foam::autoHexMeshDriver::smoothNormals
// Get smoothly varying internal normals field.
Info<< "shrinkMeshDistance : Smoothing normals ..." << endl;
const edgeList& edges = mesh_.edges();
const fvMesh& mesh = meshRefiner_.mesh();
const edgeList& edges = mesh.edges();
// Points that do not change.
PackedList<1> isFixedPoint(mesh_.nPoints(), 0);
PackedList<1> isFixedPoint(mesh.nPoints(), 0);
// Internal points that are fixed
forAll(fixedPoints, i)
@ -247,12 +250,12 @@ void Foam::autoHexMeshDriver::smoothNormals
}
// Correspondence between local edges/points and mesh edges/points
const labelList meshEdges(identity(mesh_.nEdges()));
const labelList meshPoints(identity(mesh_.nPoints()));
const labelList meshEdges(identity(mesh.nEdges()));
const labelList meshPoints(identity(mesh.nPoints()));
// Calculate inverse sum of weights
scalarField invSumWeight(mesh_.nPoints(), 0);
scalarField invSumWeight(mesh.nPoints(), 0);
sumWeights
(
isMasterEdge,
@ -266,9 +269,10 @@ void Foam::autoHexMeshDriver::smoothNormals
for (label iter = 0; iter < nSmoothDisp; iter++)
{
vectorField average(mesh_.nPoints());
vectorField average(mesh.nPoints());
averageNeighbours
(
mesh,
isMasterEdge,
meshEdges,
meshPoints,
@ -305,18 +309,19 @@ void Foam::autoHexMeshDriver::smoothNormals
// Tries and find a medial axis point. Done by comparing vectors to nearest
// wall point for both vertices of edge.
bool Foam::autoHexMeshDriver::isMaxEdge
bool Foam::autoLayerDriver::isMaxEdge
(
const List<pointData>& pointWallDist,
const label edgeI,
const scalar minCos
) const
{
const pointField& points = mesh_.points();
const fvMesh& mesh = meshRefiner_.mesh();
const pointField& points = mesh.points();
// Do not mark edges with one side on moving wall.
const edge& e = mesh_.edges()[edgeI];
const edge& e = mesh.edges()[edgeI];
vector v0(points[e[0]] - pointWallDist[e[0]].origin());
scalar magV0(mag(v0));
@ -351,7 +356,7 @@ bool Foam::autoHexMeshDriver::isMaxEdge
// Stop layer growth where mesh wraps around edge with a
// large feature angle
void Foam::autoHexMeshDriver::handleFeatureAngleLayerTerminations
void Foam::autoLayerDriver::handleFeatureAngleLayerTerminations
(
const indirectPrimitivePatch& pp,
const scalar minCos,
@ -444,7 +449,7 @@ void Foam::autoHexMeshDriver::handleFeatureAngleLayerTerminations
// Find isolated islands (points, edges and faces and layer terminations)
// in the layer mesh and stop any layer growth at these points.
void Foam::autoHexMeshDriver::findIsolatedRegions
void Foam::autoLayerDriver::findIsolatedRegions
(
const indirectPrimitivePatch& pp,
const PackedList<1>& isMasterEdge,
@ -456,6 +461,8 @@ void Foam::autoHexMeshDriver::findIsolatedRegions
labelList& patchNLayers
) const
{
const fvMesh& mesh = meshRefiner_.mesh();
Info<< "shrinkMeshDistance : Removing isolated regions ..." << endl;
// Keep count of number of points unextruded
@ -514,7 +521,7 @@ void Foam::autoHexMeshDriver::findIsolatedRegions
syncTools::syncPointList
(
mesh_,
mesh,
pp.meshPoints(),
keptPoints,
orEqOp<bool>(),
@ -582,7 +589,7 @@ void Foam::autoHexMeshDriver::findIsolatedRegions
syncTools::syncPointList
(
mesh_,
mesh,
pp.meshPoints(),
isolatedPoint,
plusEqOp<label>(),
@ -650,7 +657,7 @@ void Foam::autoHexMeshDriver::findIsolatedRegions
// medialDist : distance to medial axis
// medialRatio : ratio of medial distance to wall distance.
// (1 at wall, 0 at medial axis)
void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
void Foam::autoLayerDriver::medialAxisSmoothingInfo
(
const motionSmoother& meshMover,
const label nSmoothNormals,
@ -666,7 +673,8 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
Info<< "medialAxisSmoothingInfo :"
<< " Calculate distance to Medial Axis ..." << endl;
const pointField& points = mesh_.points();
const polyMesh& mesh = meshMover.mesh();
const pointField& points = mesh.points();
const pointMesh& pMesh = meshMover.pMesh();
const indirectPrimitivePatch& pp = meshMover.patch();
@ -677,7 +685,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
// ~~~~~~~~~~~~~~~~~~~~~~~
// Precalulate master edge (only relevant for shared edges)
PackedList<1> isMasterEdge(syncTools::getMasterEdges(mesh_));
PackedList<1> isMasterEdge(syncTools::getMasterEdges(mesh));
// Precalculate meshEdge per pp edge
labelList meshEdges(pp.nEdges());
@ -689,8 +697,8 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
label v1 = pp.meshPoints()[e[1]];
meshEdges[patchEdgeI] = meshTools::findEdge
(
mesh_.edges(),
mesh_.pointEdges()[v0],
mesh.edges(),
mesh.pointEdges()[v0],
v0,
v1
);
@ -717,7 +725,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
syncTools::syncPointList
(
mesh_,
mesh,
meshPoints,
pointNormals,
plusEqOp<vector>(),
@ -727,7 +735,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
syncTools::syncPointList
(
mesh_,
mesh,
meshPoints,
nPointFaces,
plusEqOp<label>(),
@ -756,7 +764,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Distance to wall
List<pointData> pointWallDist(mesh_.nPoints());
List<pointData> pointWallDist(mesh.nPoints());
// 1. Calculate distance to points where displacement is specified.
@ -777,7 +785,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
}
// Do all calculations
List<pointData> edgeWallDist(mesh_.nEdges());
List<pointData> edgeWallDist(mesh.nEdges());
PointEdgeWave<pointData> wallDistCalc
(
pMesh,
@ -785,15 +793,15 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
wallInfo,
pointWallDist,
edgeWallDist,
mesh_.nPoints() // max iterations
mesh.nPoints() // max iterations
);
}
// 2. Find points with max distance and transport information back to
// wall.
{
List<pointData> pointMedialDist(mesh_.nPoints());
List<pointData> edgeMedialDist(mesh_.nEdges());
List<pointData> pointMedialDist(mesh.nPoints());
List<pointData> edgeMedialDist(mesh.nEdges());
// Seed point data.
DynamicList<pointData> maxInfo(meshPoints.size());
@ -801,7 +809,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
// 1. Medial axis points
const edgeList& edges = mesh_.edges();
const edgeList& edges = mesh.edges();
forAll(edges, edgeI)
{
@ -836,7 +844,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
// 2. Seed non-adapt patches
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
const polyBoundaryMesh& patches = mesh.boundaryMesh();
labelHashSet adaptPatches(meshMover.adaptPatchIDs());
@ -890,7 +898,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
pointMedialDist,
edgeMedialDist,
mesh_.nPoints() // max iterations
mesh.nPoints() // max iterations
);
// Extract medial axis distance as pointScalarField
@ -925,7 +933,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
}
}
if (debug_)
if (debug)
{
Info<< "medialAxisSmoothingInfo :"
<< " Writing:" << nl
@ -943,7 +951,7 @@ void Foam::autoHexMeshDriver::medialAxisSmoothingInfo
}
void Foam::autoHexMeshDriver::shrinkMeshMedialDistance
void Foam::autoLayerDriver::shrinkMeshMedialDistance
(
motionSmoother& meshMover,
const label nSmoothThickness,
@ -973,7 +981,7 @@ void Foam::autoHexMeshDriver::shrinkMeshMedialDistance
const labelList& meshPoints = pp.meshPoints();
// Precalulate master edge (only relevant for shared edges)
PackedList<1> isMasterEdge(syncTools::getMasterEdges(mesh_));
PackedList<1> isMasterEdge(syncTools::getMasterEdges(mesh));
// Precalculate meshEdge per pp edge
labelList meshEdges(pp.nEdges());
@ -985,8 +993,8 @@ void Foam::autoHexMeshDriver::shrinkMeshMedialDistance
label v1 = pp.meshPoints()[e[1]];
meshEdges[patchEdgeI] = meshTools::findEdge
(
mesh_.edges(),
mesh_.pointEdges()[v0],
mesh.edges(),
mesh.pointEdges()[v0],
v0,
v1
);

View File

@ -24,14 +24,15 @@ License
\*---------------------------------------------------------------------------*/
#include "autoHexMeshDriver.H"
#include "autoLayerDriver.H"
#include "syncTools.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
void Foam::autoHexMeshDriver::averageNeighbours
void Foam::autoLayerDriver::averageNeighbours
(
const polyMesh& mesh,
const PackedList<1>& isMasterEdge,
const labelList& meshEdges,
const labelList& meshPoints,
@ -39,7 +40,7 @@ void Foam::autoHexMeshDriver::averageNeighbours
const scalarField& invSumWeight,
const Field<Type>& data,
Field<Type>& average
) const
)
{
average = pTraits<Type>::zero;
@ -60,7 +61,7 @@ void Foam::autoHexMeshDriver::averageNeighbours
syncTools::syncPointList
(
mesh_,
mesh,
meshPoints,
average,
plusEqOp<Type>(),

View File

@ -0,0 +1,776 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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 "autoRefineDriver.H"
#include "fvMesh.H"
#include "Time.H"
#include "boundBox.H"
#include "mapDistributePolyMesh.H"
#include "cellSet.H"
#include "syncTools.H"
#include "refinementParameters.H"
#include "featureEdgeMesh.H"
#include "refinementSurfaces.H"
#include "shellSurfaces.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(autoRefineDriver, 0);
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Read explicit feature edges
Foam::label Foam::autoRefineDriver::readFeatureEdges
(
const PtrList<dictionary>& featDicts,
PtrList<featureEdgeMesh>& featureMeshes,
labelList& featureLevels
) const
{
Info<< "Reading external feature lines." << endl;
const fvMesh& mesh = meshRefiner_.mesh();
featureMeshes.setSize(featDicts.size());
featureLevels.setSize(featDicts.size());
forAll(featDicts, i)
{
const dictionary& dict = featDicts[i];
fileName featFileName(dict.lookup("file"));
featureMeshes.set
(
i,
new featureEdgeMesh
(
IOobject
(
featFileName, // name
mesh.time().constant(), // directory
"triSurface", // instance
mesh.db(), // registry
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
)
)
);
featureMeshes[i].mergePoints(meshRefiner_.mergeDistance());
featureLevels[i] = readLabel(dict.lookup("level"));
Info<< "Refinement level " << featureLevels[i]
<< " for all cells crossed by feature " << featFileName
<< " (" << featureMeshes[i].points().size() << " points, "
<< featureMeshes[i].edges().size() << ")." << endl;
}
Info<< "Read feature lines in = "
<< mesh.time().cpuTimeIncrement() << " s" << nl << endl;
return featureMeshes.size();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::autoRefineDriver::autoRefineDriver
(
meshRefinement& meshRefiner,
decompositionMethod& decomposer,
fvMeshDistribute& distributor,
const labelList& globalToPatch
)
:
meshRefiner_(meshRefiner),
decomposer_(decomposer),
distributor_(distributor),
globalToPatch_(globalToPatch)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::autoRefineDriver::featureEdgeRefine
(
const refinementParameters& refineParams,
const PtrList<dictionary>& featDicts,
const label maxIter,
const label minRefine
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Read explicit feature edges
PtrList<featureEdgeMesh> featureMeshes;
// Per feature the refinement level
labelList featureLevels;
readFeatureEdges(featDicts, featureMeshes, featureLevels);
label iter = 0;
if (featureMeshes.size() > 0 && maxIter > 0)
{
for (; iter < maxIter; iter++)
{
Info<< nl
<< "Feature refinement iteration " << iter << nl
<< "------------------------------" << nl
<< endl;
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints()[0], // For now only use one.
refineParams.curvature(),
featureMeshes,
featureLevels,
true, // featureRefinement
false, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for feature refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
if (nCellsToRefine <= minRefine)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug > 0)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.refineAndBalance
(
"feature refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine
);
}
}
return iter;
}
Foam::label Foam::autoRefineDriver::surfaceOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Determine the maximum refinement level over all surfaces. This
// determines the minumum number of surface refinement iterations.
label overallMaxLevel = max(meshRefiner_.surfaces().maxLevel());
label iter;
for (iter = 0; iter < maxIter; iter++)
{
Info<< nl
<< "Surface refinement iteration " << iter << nl
<< "------------------------------" << nl
<< endl;
// Determine cells to refine
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// Only look at surface intersections (minLevel and surface curvature),
// do not do internal refinement (refinementShells)
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints()[0],
refineParams.curvature(),
PtrList<featureEdgeMesh>(0), // dummy featureMeshes;
labelList(0), // dummy featureLevels;
false, // featureRefinement
false, // internalRefinement
true, // surfaceRefinement
true, // curvatureRefinement
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
labelList cellsToRefine
(
meshRefiner_.meshCutter().consistentRefinement
(
candidateCells,
true
)
);
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum nessecary
// iterations and not enough cells to refine.
if
(
nCellsToRefine == 0
|| (
iter >= overallMaxLevel
&& nCellsToRefine <= refineParams.minRefineCells()
)
)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.refineAndBalance
(
"surface refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine
);
}
return iter;
}
void Foam::autoRefineDriver::removeInsideCells
(
const refinementParameters& refineParams,
const label nBufferLayers
)
{
Info<< nl
<< "Removing mesh beyond surface intersections" << nl
<< "------------------------------------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.splitMesh
(
nBufferLayers, // nBufferLayers
globalToPatch_,
refineParams.keepPoints()[0]
);
if (debug)
{
Pout<< "Writing subsetted mesh to time "
<< mesh.time().timeName() << '.' << endl;
meshRefiner_.write(debug, mesh.time().path()/mesh.time().timeName());
Pout<< "Dumped mesh in = "
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
}
}
Foam::label Foam::autoRefineDriver::shellRefine
(
const refinementParameters& refineParams,
const label maxIter
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Mark current boundary faces with 0. Have meshRefiner maintain them.
meshRefiner_.userFaceData().setSize(1);
// mark list to remove any refined faces
meshRefiner_.userFaceData()[0].first() = meshRefinement::REMOVE;
meshRefiner_.userFaceData()[0].second() = createWithValues<labelList>
(
mesh.nFaces(),
-1,
meshRefiner_.intersectedFaces(),
0
);
// Determine the maximum refinement level over all volume refinement
// regions. This determines the minumum number of shell refinement
// iterations.
label overallMaxShellLevel = meshRefiner_.shells().maxLevel();
label iter;
for (iter = 0; iter < maxIter; iter++)
{
Info<< nl
<< "Shell refinement iteration " << iter << nl
<< "----------------------------" << nl
<< endl;
labelList candidateCells
(
meshRefiner_.refineCandidates
(
refineParams.keepPoints()[0],
refineParams.curvature(),
PtrList<featureEdgeMesh>(0), // dummy featureMeshes;
labelList(0), // dummy featureLevels;
false, // featureRefinement
true, // internalRefinement
false, // surfaceRefinement
false, // curvatureRefinement
refineParams.maxGlobalCells(),
refineParams.maxLocalCells()
)
);
if (debug)
{
Pout<< "Dumping " << candidateCells.size()
<< " cells to cellSet candidateCellsFromShells." << endl;
cellSet(mesh, "candidateCellsFromShells", candidateCells).write();
}
// Problem choosing starting faces for bufferlayers (bFaces)
// - we can't use the current intersected boundary faces
// (intersectedFaces) since this grows indefinitely
// - if we use 0 faces we don't satisfy bufferLayers from the
// surface.
// - possibly we want to have bFaces only the initial set of faces
// and maintain the list while doing the refinement.
labelList bFaces
(
findIndices(meshRefiner_.userFaceData()[0].second(), 0)
);
//Info<< "Collected boundary faces : "
// << returnReduce(bFaces.size(), sumOp<label>()) << endl;
labelList cellsToRefine;
if (refineParams.nBufferLayers() <= 2)
{
cellsToRefine = meshRefiner_.meshCutter().consistentSlowRefinement
(
refineParams.nBufferLayers(),
candidateCells, // cells to refine
bFaces, // faces for nBufferLayers
1, // point difference
meshRefiner_.intersectedPoints() // points to check
);
}
else
{
cellsToRefine = meshRefiner_.meshCutter().consistentSlowRefinement2
(
refineParams.nBufferLayers(),
candidateCells, // cells to refine
bFaces // faces for nBufferLayers
);
}
Info<< "Determined cells to refine in = "
<< mesh.time().cpuTimeIncrement() << " s" << endl;
label nCellsToRefine = cellsToRefine.size();
reduce(nCellsToRefine, sumOp<label>());
Info<< "Selected for internal refinement : " << nCellsToRefine
<< " cells (out of " << mesh.globalData().nTotalCells()
<< ')' << endl;
// Stop when no cells to refine or have done minimum nessecary
// iterations and not enough cells to refine.
if
(
nCellsToRefine == 0
|| (
iter >= overallMaxShellLevel
&& nCellsToRefine <= refineParams.minRefineCells()
)
)
{
Info<< "Stopping refining since too few cells selected."
<< nl << endl;
break;
}
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.refineAndBalance
(
"shell refinement iteration " + name(iter),
decomposer_,
distributor_,
cellsToRefine
);
}
meshRefiner_.userFaceData().clear();
return iter;
}
void Foam::autoRefineDriver::baffleAndSplitMesh
(
const refinementParameters& refineParams,
const bool handleSnapProblems
)
{
Info<< nl
<< "Splitting mesh at surface intersections" << nl
<< "---------------------------------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
// Introduce baffles at surface intersections. Note:
// meshRefiment::surfaceIndex() will
// be like boundary face from now on so not coupled anymore.
meshRefiner_.baffleAndSplitMesh
(
handleSnapProblems,
!handleSnapProblems, // merge free standing baffles?
const_cast<Time&>(mesh.time()),
globalToPatch_,
refineParams.keepPoints()[0]
);
}
void Foam::autoRefineDriver::zonify
(
const refinementParameters& refineParams
)
{
// Mesh is at its finest. Do zoning
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// This puts all faces with intersection across a zoneable surface
// into that surface's faceZone. All cells inside faceZone get given the
// same cellZone.
if (meshRefiner_.surfaces().getNamedSurfaces().size() > 0)
{
Info<< nl
<< "Introducing zones for interfaces" << nl
<< "--------------------------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.zonify(refineParams.keepPoints()[0]);
if (debug)
{
Pout<< "Writing zoned mesh to time "
<< mesh.time().timeName() << '.' << endl;
meshRefiner_.write
(
debug,
mesh.time().path()/mesh.time().timeName()
);
}
// Check that all faces are synced
meshRefinement::checkCoupledFaceZones(mesh);
}
}
void Foam::autoRefineDriver::splitAndMergeBaffles
(
const refinementParameters& refineParams,
const bool handleSnapProblems
)
{
Info<< nl
<< "Handling cells with snap problems" << nl
<< "---------------------------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
// Introduce baffles and split mesh
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.baffleAndSplitMesh
(
handleSnapProblems,
false, // merge free standing baffles?
const_cast<Time&>(mesh.time()),
globalToPatch_,
refineParams.keepPoints()[0]
);
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
// Duplicate points on baffles that are on more than one cell
// region. This will help snapping pull them to separate surfaces.
meshRefiner_.dupNonManifoldPoints();
// Merge all baffles that are still remaining after duplicating points.
List<labelPair> couples
(
meshRefiner_.getDuplicateFaces // get all baffles
(
identity(mesh.nFaces()-mesh.nInternalFaces())
+ mesh.nInternalFaces()
)
);
label nCouples = returnReduce(couples.size(), sumOp<label>());
Info<< "Detected unsplittable baffles : "
<< nCouples << endl;
if (nCouples > 0)
{
// Actually merge baffles. Note: not exactly parallellized. Should
// convert baffle faces into processor faces if they resulted
// from them.
meshRefiner_.mergeBaffles(couples);
if (debug)
{
// Debug:test all is still synced across proc patches
meshRefiner_.checkData();
}
Info<< "Merged free-standing baffles in = "
<< mesh.time().cpuTimeIncrement() << " s." << endl;
}
if (debug)
{
Pout<< "Writing handleProblemCells mesh to time "
<< mesh.time().timeName() << '.' << endl;
meshRefiner_.write(debug, mesh.time().path()/mesh.time().timeName());
}
}
void Foam::autoRefineDriver::mergePatchFaces
(
const refinementParameters& refineParams
)
{
const fvMesh& mesh = meshRefiner_.mesh();
Info<< nl
<< "Merge refined boundary faces" << nl
<< "----------------------------" << nl
<< endl;
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
meshRefiner_.mergePatchFaces
(
Foam::cos(45*mathematicalConstant::pi/180.0),
Foam::cos(45*mathematicalConstant::pi/180.0),
meshRefinement::addedPatches(globalToPatch_)
);
if (debug)
{
meshRefiner_.checkData();
}
meshRefiner_.mergeEdges(Foam::cos(45*mathematicalConstant::pi/180.0));
if (debug)
{
meshRefiner_.checkData();
}
}
void Foam::autoRefineDriver::doRefine
(
const dictionary& refineDict,
const refinementParameters& refineParams,
const bool prepareForSnapping
)
{
Info<< nl
<< "Refinement phase" << nl
<< "----------------" << nl
<< endl;
const fvMesh& mesh = meshRefiner_.mesh();
const_cast<Time&>(mesh.time())++;
// Check that all the keep points are inside the mesh.
refineParams.findCells(mesh);
PtrList<dictionary> featDicts(refineDict.lookup("features"));
// Refine around feature edges
featureEdgeRefine
(
refineParams,
featDicts,
100, // maxIter
0 // min cells to refine
);
// Refine based on surface
surfaceOnlyRefine
(
refineParams,
100 // maxIter
);
// Remove cells (a certain distance) beyond surface intersections
removeInsideCells
(
refineParams,
1 // nBufferLayers
);
// Internal mesh refinement
shellRefine
(
refineParams,
100 // maxIter
);
// Introduce baffles at surface intersections
baffleAndSplitMesh(refineParams, prepareForSnapping);
// Mesh is at its finest. Do optional zoning.
zonify(refineParams);
// Pull baffles apart
splitAndMergeBaffles(refineParams, prepareForSnapping);
// Do something about cells with refined faces on the boundary
if (prepareForSnapping)
{
mergePatchFaces(refineParams);
}
if (Pstream::parRun())
{
Info<< nl
<< "Doing final balancing" << nl
<< "---------------------" << nl
<< endl;
if (debug)
{
const_cast<Time&>(mesh.time())++;
}
// Do final balancing. Keep zoned faces on one processor.
meshRefiner_.balance
(
true,
false,
decomposer_,
distributor_
);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,179 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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::autoRefineDriver
Description
SourceFiles
autoRefineDriver.C
\*---------------------------------------------------------------------------*/
#ifndef autoRefineDriver_H
#define autoRefineDriver_H
#include "meshRefinement.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class featureEdgeMesh;
class refinementParameters;
/*---------------------------------------------------------------------------*\
Class autoRefineDriver Declaration
\*---------------------------------------------------------------------------*/
class autoRefineDriver
{
// Private data
//- Mesh+surface
meshRefinement& meshRefiner_;
//- Reference to decomposition method
decompositionMethod& decomposer_;
//- Reference to mesh distribution engine
fvMeshDistribute& distributor_;
//- From surface region to patch
const labelList globalToPatch_;
// Private Member Functions
//- Read explicit feature edges
label readFeatureEdges
(
const PtrList<dictionary>& featDicts,
PtrList<featureEdgeMesh>& featureMeshes,
labelList& featureLevel
) const;
//- Refine all cells pierced by explicit feature edges
label featureEdgeRefine
(
const refinementParameters& refineParams,
const PtrList<dictionary>& featDicts,
const label maxIter,
const label minRefine
);
//- Refine all cells interacting with the surface
label surfaceOnlyRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Remove all cells within intersected region
void removeInsideCells
(
const refinementParameters& refineParams,
const label nBufferLayers
);
//- Remove all cells inside/outside shell
label shellRefine
(
const refinementParameters& refineParams,
const label maxIter
);
//- Add baffles and remove unreachable cells
void baffleAndSplitMesh
(
const refinementParameters& refineParams,
const bool handleSnapProblems
);
//- Add zones
void zonify(const refinementParameters& refineParams);
void splitAndMergeBaffles
(
const refinementParameters& refineParams,
const bool handleSnapProblems
);
//- Merge refined boundary faces (from exposing coarser cell)
void mergePatchFaces
(
const refinementParameters& refineParams
);
//- Disallow default bitwise copy construct
autoRefineDriver(const autoRefineDriver&);
//- Disallow default bitwise assignment
void operator=(const autoRefineDriver&);
public:
//- Runtime type information
ClassName("autoRefineDriver");
// Constructors
//- Construct from components
autoRefineDriver
(
meshRefinement& meshRefiner,
decompositionMethod& decomposer,
fvMeshDistribute& distributor,
const labelList& globalToPatch
);
// Member Functions
//- Do all the refinement
void doRefine
(
const dictionary& refineDict,
const refinementParameters& refineParams,
const bool prepareForSnapping
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -27,7 +27,12 @@ Description
\*----------------------------------------------------------------------------*/
#include "autoHexMeshDriver.H"
#include "autoSnapDriver.H"
#include "Time.H"
#include "pointFields.H"
#include "motionSmoother.H"
#include "polyTopoChange.H"
#include "OFstream.H"
#include "syncTools.H"
#include "fvMesh.H"
#include "Time.H"
@ -38,16 +43,28 @@ Description
#include "PointEdgeWave.H"
#include "mergePoints.H"
#include "snapParameters.H"
#include "refinementSurfaces.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(autoSnapDriver, 0);
} // End namespace Foam
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::autoHexMeshDriver::getZonedSurfaces
void Foam::autoSnapDriver::getZonedSurfaces
(
labelList& zonedSurfaces,
labelList& unzonedSurfaces
) const
{ // Surfaces with zone information
const wordList& faceZoneNames = surfaces().faceZoneNames();
const wordList& faceZoneNames = meshRefiner_.surfaces().faceZoneNames();
zonedSurfaces.setSize(faceZoneNames.size());
label zonedI = 0;
@ -71,15 +88,18 @@ void Foam::autoHexMeshDriver::getZonedSurfaces
// Get faces to repatch. Returns map from face to patch.
Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
Foam::Map<Foam::label> Foam::autoSnapDriver::getZoneBafflePatches
(
const bool allowBoundary
) const
{
Map<label> bafflePatch(mesh_.nFaces()/1000);
const fvMesh& mesh = meshRefiner_.mesh();
const refinementSurfaces& surfaces = meshRefiner_.surfaces();
const wordList& faceZoneNames = surfaces().faceZoneNames();
const faceZoneMesh& fZones = mesh_.faceZones();
Map<label> bafflePatch(mesh.nFaces()/1000);
const wordList& faceZoneNames = surfaces.faceZoneNames();
const faceZoneMesh& fZones = mesh.faceZones();
forAll(faceZoneNames, surfI)
{
@ -93,12 +113,12 @@ Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
//// Get patch allocated for zone
//label patchI = surfaceToCyclicPatch_[surfI];
// Get patch of (first region) of surface
label patchI = globalToPatch_[surfaces().globalRegion(surfI, 0)];
label patchI = globalToPatch_[surfaces.globalRegion(surfI, 0)];
Info<< "For surface "
<< surfaces().names()[surfI]
<< surfaces.names()[surfI]
<< " found faceZone " << fZone.name()
<< " and patch " << mesh_.boundaryMesh()[patchI].name()
<< " and patch " << mesh.boundaryMesh()[patchI].name()
<< endl;
@ -106,7 +126,7 @@ Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
{
label faceI = fZone[i];
if (allowBoundary || mesh_.isInternalFace(faceI))
if (allowBoundary || mesh.isInternalFace(faceI))
{
if (!bafflePatch.insert(faceI, patchI))
{
@ -116,11 +136,11 @@ Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
{
FatalErrorIn("getZoneBafflePatches(const bool)")
<< "Face " << faceI
<< " fc:" << mesh_.faceCentres()[faceI]
<< " fc:" << mesh.faceCentres()[faceI]
<< " is in faceZone "
<< mesh_.boundaryMesh()[oldPatchI].name()
<< mesh.boundaryMesh()[oldPatchI].name()
<< " and in faceZone "
<< mesh_.boundaryMesh()[patchI].name()
<< mesh.boundaryMesh()[patchI].name()
<< abort(FatalError);
}
}
@ -134,7 +154,7 @@ Foam::Map<Foam::label> Foam::autoHexMeshDriver::getZoneBafflePatches
// Calculate geometrically collocated points, Requires PackedList to be
// sizes and initalised!
Foam::label Foam::autoHexMeshDriver::getCollocatedPoints
Foam::label Foam::autoSnapDriver::getCollocatedPoints
(
const scalar tol,
const pointField& points,
@ -196,7 +216,7 @@ Foam::label Foam::autoHexMeshDriver::getCollocatedPoints
// Calculate displacement as average of patch points.
Foam::pointField Foam::autoHexMeshDriver::smoothPatchDisplacement
Foam::pointField Foam::autoSnapDriver::smoothPatchDisplacement
(
const motionSmoother& meshMover
) const
@ -483,7 +503,7 @@ Foam::pointField Foam::autoHexMeshDriver::smoothPatchDisplacement
}
Foam::tmp<Foam::scalarField> Foam::autoHexMeshDriver::edgePatchDist
Foam::tmp<Foam::scalarField> Foam::autoSnapDriver::edgePatchDist
(
const pointMesh& pMesh,
const indirectPrimitivePatch& pp
@ -565,7 +585,7 @@ Foam::tmp<Foam::scalarField> Foam::autoHexMeshDriver::edgePatchDist
}
void Foam::autoHexMeshDriver::dumpMove
void Foam::autoSnapDriver::dumpMove
(
const fileName& fName,
const pointField& meshPts,
@ -596,7 +616,7 @@ void Foam::autoHexMeshDriver::dumpMove
// Check whether all displacement vectors point outwards of patch. Return true
// if so.
bool Foam::autoHexMeshDriver::outwardsDisplacement
bool Foam::autoSnapDriver::outwardsDisplacement
(
const indirectPrimitivePatch& pp,
const vectorField& patchDisp
@ -637,9 +657,22 @@ bool Foam::autoHexMeshDriver::outwardsDisplacement
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::autoSnapDriver::autoSnapDriver
(
meshRefinement& meshRefiner,
const labelList& globalToPatch
)
:
meshRefiner_(meshRefiner),
globalToPatch_(globalToPatch)
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::createZoneBaffles
Foam::autoPtr<Foam::mapPolyMesh> Foam::autoSnapDriver::createZoneBaffles
(
List<labelPair>& baffles
)
@ -653,6 +686,8 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::createZoneBaffles
// No need to sync; all processors will have all same zonedSurfaces.
if (zonedSurfaces.size() > 0)
{
fvMesh& mesh = meshRefiner_.mesh();
// Split internal faces on interface surfaces
Info<< "Converting zoned faces into baffles ..." << endl;
@ -664,14 +699,14 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::createZoneBaffles
if (nZoneFaces > 0)
{
// Convert into labelLists
labelList ownPatch(mesh_.nFaces(), -1);
labelList ownPatch(mesh.nFaces(), -1);
forAllConstIter(Map<label>, faceToPatch, iter)
{
ownPatch[iter.key()] = iter();
}
// Create baffles. both sides same patch.
map = meshRefinerPtr_().createBaffles(ownPatch, ownPatch);
map = meshRefiner_.createBaffles(ownPatch, ownPatch);
// Get pairs of faces created.
// Just loop over faceMap and store baffle if we encounter a slave
@ -702,29 +737,29 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::createZoneBaffles
if (baffleI != faceToPatch.size())
{
FatalErrorIn("autoHexMeshDriver::createZoneBaffles(..)")
FatalErrorIn("autoSnapDriver::createZoneBaffles(..)")
<< "Had " << faceToPatch.size() << " patches to create "
<< " but encountered " << baffleI
<< " slave faces originating from patcheable faces."
<< abort(FatalError);
}
if (debug_)
if (debug)
{
const_cast<Time&>(mesh_.time())++;
const_cast<Time&>(mesh.time())++;
Pout<< "Writing baffled mesh to time "
<< mesh_.time().timeName() << endl;
mesh_.write();
<< mesh.time().timeName() << endl;
mesh.write();
}
}
Info<< "Created " << nZoneFaces << " baffles in = "
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
}
return map;
}
Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::mergeZoneBaffles
Foam::autoPtr<Foam::mapPolyMesh> Foam::autoSnapDriver::mergeZoneBaffles
(
const List<labelPair>& baffles
)
@ -743,17 +778,18 @@ Foam::autoPtr<Foam::mapPolyMesh> Foam::autoHexMeshDriver::mergeZoneBaffles
Info<< "Converting " << nBaffles << " baffles back into zoned faces ..."
<< endl;
map = meshRefinerPtr_().mergeBaffles(baffles);
map = meshRefiner_.mergeBaffles(baffles);
Info<< "Converted baffles in = "
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
<< meshRefiner_.mesh().time().cpuTimeIncrement()
<< " s\n" << nl << endl;
}
return map;
}
Foam::scalarField Foam::autoHexMeshDriver::calcSnapDistance
Foam::scalarField Foam::autoSnapDriver::calcSnapDistance
(
const snapParameters& snapParams,
const indirectPrimitivePatch& pp
@ -762,6 +798,7 @@ Foam::scalarField Foam::autoHexMeshDriver::calcSnapDistance
const edgeList& edges = pp.edges();
const labelListList& pointEdges = pp.pointEdges();
const pointField& localPoints = pp.localPoints();
const fvMesh& mesh = meshRefiner_.mesh();
scalarField maxEdgeLen(localPoints.size(), -GREAT);
@ -781,7 +818,7 @@ Foam::scalarField Foam::autoHexMeshDriver::calcSnapDistance
syncTools::syncPointList
(
mesh_,
mesh,
pp.meshPoints(),
maxEdgeLen,
maxEqOp<scalar>(), // combine op
@ -793,34 +830,36 @@ Foam::scalarField Foam::autoHexMeshDriver::calcSnapDistance
}
// Invert globalToPatch_ to get the patches related to surfaces.
Foam::labelList Foam::autoHexMeshDriver::getSurfacePatches() const
{
// Set of patches originating from surface
labelHashSet surfacePatchSet(globalToPatch_.size());
forAll(globalToPatch_, i)
{
if (globalToPatch_[i] != -1)
{
surfacePatchSet.insert(globalToPatch_[i]);
}
}
DynamicList<label> surfacePatches(surfacePatchSet.size());
for (label patchI = 0; patchI < mesh_.boundaryMesh().size(); patchI++)
{
if (surfacePatchSet.found(patchI))
{
surfacePatches.append(patchI);
}
}
return surfacePatches.shrink();
}
//// Invert globalToPatch_ to get the patches related to surfaces.
//Foam::labelList Foam::autoSnapDriver::getSurfacePatches() const
//{
// // Set of patches originating from surface
// labelHashSet surfacePatchSet(globalToPatch_.size());
//
// forAll(globalToPatch_, i)
// {
// if (globalToPatch_[i] != -1)
// {
// surfacePatchSet.insert(globalToPatch_[i]);
// }
// }
//
// const fvMesh& mesh = meshRefiner_.mesh();
//
// DynamicList<label> surfacePatches(surfacePatchSet.size());
//
// for (label patchI = 0; patchI < mesh.boundaryMesh().size(); patchI++)
// {
// if (surfacePatchSet.found(patchI))
// {
// surfacePatches.append(patchI);
// }
// }
// return surfacePatches.shrink();
//}
void Foam::autoHexMeshDriver::preSmoothPatch
void Foam::autoSnapDriver::preSmoothPatch
(
const snapParameters& snapParams,
const label nInitErrors,
@ -828,6 +867,8 @@ void Foam::autoHexMeshDriver::preSmoothPatch
motionSmoother& meshMover
) const
{
const fvMesh& mesh = meshRefiner_.mesh();
labelList checkFaces;
Info<< "Smoothing patch points ..." << endl;
@ -839,7 +880,7 @@ void Foam::autoHexMeshDriver::preSmoothPatch
)
{
Info<< "Smoothing iteration " << smoothIter << endl;
checkFaces.setSize(mesh_.nFaces());
checkFaces.setSize(mesh.nFaces());
forAll(checkFaces, faceI)
{
checkFaces[faceI] = faceI;
@ -884,39 +925,41 @@ void Foam::autoHexMeshDriver::preSmoothPatch
// The current mesh is the starting mesh to smooth from.
meshMover.correct();
if (debug_)
if (debug)
{
const_cast<Time&>(mesh_.time())++;
Pout<< "Writing patch smoothed mesh to time " << mesh_.time().timeName()
const_cast<Time&>(mesh.time())++;
Pout<< "Writing patch smoothed mesh to time " << mesh.time().timeName()
<< endl;
mesh_.write();
mesh.write();
}
Info<< "Patch points smoothed in = "
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
}
// Get (pp-local) indices of points that are both on zone and on patched surface
Foam::labelList Foam::autoHexMeshDriver::getZoneSurfacePoints
Foam::labelList Foam::autoSnapDriver::getZoneSurfacePoints
(
const indirectPrimitivePatch& pp,
const word& zoneName
) const
{
label zoneI = mesh_.faceZones().findZoneID(zoneName);
const fvMesh& mesh = meshRefiner_.mesh();
label zoneI = mesh.faceZones().findZoneID(zoneName);
if (zoneI == -1)
{
FatalErrorIn
(
"autoHexMeshDriver::getZoneSurfacePoints"
"autoSnapDriver::getZoneSurfacePoints"
"(const indirectPrimitivePatch&, const word&)"
) << "Cannot find zone " << zoneName
<< exit(FatalError);
}
const faceZone& fZone = mesh_.faceZones()[zoneI];
const faceZone& fZone = mesh.faceZones()[zoneI];
// Could use PrimitivePatch & localFaces to extract points but might just
@ -926,7 +969,7 @@ Foam::labelList Foam::autoHexMeshDriver::getZoneSurfacePoints
forAll(fZone, i)
{
const face& f = mesh_.faces()[fZone[i]];
const face& f = mesh.faces()[fZone[i]];
forAll(f, fp)
{
@ -947,7 +990,7 @@ Foam::labelList Foam::autoHexMeshDriver::getZoneSurfacePoints
}
Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
Foam::vectorField Foam::autoSnapDriver::calcNearestSurface
(
const scalarField& snapDist,
motionSmoother& meshMover
@ -958,6 +1001,8 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
const indirectPrimitivePatch& pp = meshMover.patch();
const pointField& localPoints = pp.localPoints();
const refinementSurfaces& surfaces = meshRefiner_.surfaces();
const fvMesh& mesh = meshRefiner_.mesh();
// Divide surfaces into zoned and unzoned
labelList zonedSurfaces;
@ -974,7 +1019,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
{
List<pointIndexHit> hitInfo;
labelList hitSurface;
surfaces().findNearest
surfaces.findNearest
(
unzonedSurfaces,
localPoints,
@ -993,7 +1038,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
}
//else
//{
// WarningIn("autoHexMeshDriver::calcNearestSurface(..)")
// WarningIn("autoSnapDriver::calcNearestSurface(..)")
// << "For point:" << pointI
// << " coordinate:" << localPoints[pointI]
// << " did not find any surface within:"
@ -1009,7 +1054,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Surfaces with zone information
const wordList& faceZoneNames = surfaces().faceZoneNames();
const wordList& faceZoneNames = surfaces.faceZoneNames();
forAll(zonedSurfaces, i)
{
@ -1036,7 +1081,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
// Find nearest for points both on faceZone and pp.
List<pointIndexHit> hitInfo;
labelList hitSurface;
surfaces().findNearest
surfaces.findNearest
(
labelList(1, zoneSurfI),
zonePoints,
@ -1055,7 +1100,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
}
else
{
WarningIn("autoHexMeshDriver::calcNearestSurface(..)")
WarningIn("autoSnapDriver::calcNearestSurface(..)")
<< "For point:" << pointI
<< " coordinate:" << localPoints[pointI]
<< " did not find any surface within:"
@ -1076,7 +1121,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
}
Info<< "Calculated surface displacement in = "
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
// Limit amount of movement.
@ -1098,7 +1143,7 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
// will not do condition 2 on all. Sync explicitly.
syncTools::syncPointList
(
mesh_,
mesh,
pp.meshPoints(),
patchDisp,
minMagEqOp(), // combine op
@ -1115,11 +1160,11 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
// pointVectorField.
meshMover.setDisplacement(patchDisp);
if (debug_)
if (debug)
{
dumpMove
(
mesh_.time().path()/"patchDisplacement.obj",
mesh.time().path()/"patchDisplacement.obj",
pp.localPoints(),
pp.localPoints() + patchDisp
);
@ -1129,12 +1174,13 @@ Foam::vectorField Foam::autoHexMeshDriver::calcNearestSurface
}
void Foam::autoHexMeshDriver::smoothDisplacement
void Foam::autoSnapDriver::smoothDisplacement
(
const snapParameters& snapParams,
motionSmoother& meshMover
) const
{
const fvMesh& mesh = meshRefiner_.mesh();
const pointMesh& pMesh = meshMover.pMesh();
const indirectPrimitivePatch& pp = meshMover.patch();
@ -1142,7 +1188,7 @@ void Foam::autoHexMeshDriver::smoothDisplacement
// Set edge diffusivity as inverse of distance to patch
scalarField edgeGamma(1.0/(edgePatchDist(pMesh, pp) + SMALL));
//scalarField edgeGamma(mesh_.nEdges(), 1.0);
//scalarField edgeGamma(mesh.nEdges(), 1.0);
//scalarField edgeGamma(wallGamma(mesh, pp, 10, 1));
// Get displacement field
@ -1159,14 +1205,14 @@ void Foam::autoHexMeshDriver::smoothDisplacement
meshMover.smooth(oldDisp, edgeGamma, false, disp);
}
Info<< "Displacement smoothed in = "
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
if (debug_)
if (debug)
{
const_cast<Time&>(mesh_.time())++;
Pout<< "Writing smoothed mesh to time " << mesh_.time().timeName()
const_cast<Time&>(mesh.time())++;
Pout<< "Writing smoothed mesh to time " << mesh.time().timeName()
<< endl;
mesh_.write();
mesh.write();
Pout<< "Writing displacement field ..." << endl;
disp.write();
@ -1180,7 +1226,7 @@ void Foam::autoHexMeshDriver::smoothDisplacement
);
dumpMove
(
mesh_.time().path()/"actualPatchDisplacement.obj",
mesh.time().path()/"actualPatchDisplacement.obj",
pp.localPoints(),
pp.localPoints() + actualPatchDisp
);
@ -1188,7 +1234,7 @@ void Foam::autoHexMeshDriver::smoothDisplacement
}
void Foam::autoHexMeshDriver::scaleMesh
void Foam::autoSnapDriver::scaleMesh
(
const snapParameters& snapParams,
const label nInitErrors,
@ -1196,9 +1242,11 @@ void Foam::autoHexMeshDriver::scaleMesh
motionSmoother& meshMover
)
{
const fvMesh& mesh = meshRefiner_.mesh();
// Relax displacement until correct mesh
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
labelList checkFaces(identity(mesh_.nFaces()));
labelList checkFaces(identity(mesh.nFaces()));
scalar oldErrorReduction = -1;
@ -1219,12 +1267,12 @@ void Foam::autoHexMeshDriver::scaleMesh
break;
}
if (debug_)
if (debug)
{
const_cast<Time&>(mesh_.time())++;
Pout<< "Writing scaled mesh to time " << mesh_.time().timeName()
const_cast<Time&>(mesh.time())++;
Pout<< "Writing scaled mesh to time " << mesh.time().timeName()
<< endl;
mesh_.write();
mesh.write();
Pout<< "Writing displacement field ..." << endl;
meshMover.displacement().write();
@ -1238,7 +1286,99 @@ void Foam::autoHexMeshDriver::scaleMesh
meshMover.setErrorReduction(oldErrorReduction);
}
Info<< "Moved mesh in = "
<< mesh_.time().cpuTimeIncrement() << " s\n" << nl << endl;
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
}
void Foam::autoSnapDriver::doSnap
(
const dictionary& snapDict,
const dictionary& motionDict,
const snapParameters& snapParams
)
{
fvMesh& mesh = meshRefiner_.mesh();
Info<< nl
<< "Morphing phase" << nl
<< "--------------" << nl
<< endl;
const_cast<Time&>(mesh.time())++;
// Get the labels of added patches.
labelList adaptPatchIDs(meshRefinement::addedPatches(globalToPatch_));
// Create baffles (pairs of faces that share the same points)
// Baffles stored as owner and neighbour face that have been created.
List<labelPair> baffles;
createZoneBaffles(baffles);
{
autoPtr<indirectPrimitivePatch> ppPtr
(
meshRefinement::makePatch
(
mesh,
adaptPatchIDs
)
);
indirectPrimitivePatch& pp = ppPtr();
// Distance to attact to nearest feature on surface
const scalarField snapDist(calcSnapDistance(snapParams, pp));
// Construct iterative mesh mover.
Info<< "Constructing mesh displacer ..." << endl;
Info<< "Using mesh parameters " << motionDict << nl << endl;
pointMesh pMesh(mesh);
motionSmoother meshMover
(
mesh,
pp,
adaptPatchIDs,
meshRefinement::makeDisplacementField(pMesh, adaptPatchIDs),
motionDict
);
// Check initial mesh
Info<< "Checking initial mesh ..." << endl;
labelHashSet wrongFaces(mesh.nFaces()/100);
motionSmoother::checkMesh(false, mesh, motionDict, wrongFaces);
const label nInitErrors = returnReduce
(
wrongFaces.size(),
sumOp<label>()
);
Info<< "Detected " << nInitErrors << " illegal faces"
<< " (concave, zero area or negative cell pyramid volume)"
<< endl;
Info<< "Checked initial mesh in = "
<< mesh.time().cpuTimeIncrement() << " s\n" << nl << endl;
// Pre-smooth patch vertices (so before determining nearest)
preSmoothPatch(snapParams, nInitErrors, baffles, meshMover);
// Calculate displacement at every patch point. Insert into
// meshMover.
calcNearestSurface(snapDist, meshMover);
// Get smoothly varying internal displacement field.
smoothDisplacement(snapParams, meshMover);
// Apply internal displacement to mesh.
scaleMesh(snapParams, nInitErrors, baffles, meshMover);
}
// Merge any introduced baffles.
mergeZoneBaffles(baffles);
}

View File

@ -0,0 +1,236 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2008 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::autoSnapDriver
Description
All to do with snapping to surface
SourceFiles
autoSnapDriver.C
\*---------------------------------------------------------------------------*/
#ifndef autoSnapDriver_H
#define autoSnapDriver_H
#include "meshRefinement.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of classes
class motionSmoother;
class snapParameters;
/*---------------------------------------------------------------------------*\
Class autoSnapDriver Declaration
\*---------------------------------------------------------------------------*/
class autoSnapDriver
{
// Private classes
//- Combine operator class for equalizing displacements.
class minMagEqOp
{
public:
void operator()(vector& x, const vector& y) const
{
if (magSqr(y) < magSqr(x))
{
x = y;
}
}
};
// Private data
//- Mesh+surface
meshRefinement& meshRefiner_;
//- From surface region to patch
const labelList globalToPatch_;
// Private Member Functions
// Snapping
//- Split surfaces into non-zoned and zones ones
void getZonedSurfaces(labelList&, labelList&) const;
//- Get faces to repatch. Returns map from face to patch.
Map<label> getZoneBafflePatches(const bool allowBoundary) const;
//- Calculates (geometric) shared points
static label getCollocatedPoints
(
const scalar tol,
const pointField&,
PackedList<1>&
);
//- Calculate displacement per patch point to smooth out patch.
// Quite complicated in determining which points to move where.
pointField smoothPatchDisplacement(const motionSmoother&) const;
//- Check that face zones are synced
void checkCoupledFaceZones() const;
//- Per edge distance to patch
static tmp<scalarField> edgePatchDist
(
const pointMesh&,
const indirectPrimitivePatch&
);
//- Write displacement as .obj file.
static void dumpMove
(
const fileName&,
const pointField&,
const pointField&
);
//- Check displacement is outwards pointing
static bool outwardsDisplacement
(
const indirectPrimitivePatch&,
const vectorField&
);
//- Disallow default bitwise copy construct
autoSnapDriver(const autoSnapDriver&);
//- Disallow default bitwise assignment
void operator=(const autoSnapDriver&);
public:
//- Runtime type information
ClassName("autoSnapDriver");
// Constructors
//- Construct from components
autoSnapDriver
(
meshRefinement& meshRefiner,
const labelList& globalToPatch
);
// Member Functions
// Snapping
//- Create baffles for faces straddling zoned surfaces. Return
// baffles.
autoPtr<mapPolyMesh> createZoneBaffles(List<labelPair>&);
//- Merge baffles.
autoPtr<mapPolyMesh> mergeZoneBaffles(const List<labelPair>&);
//- Calculate edge length per patch point.
scalarField calcSnapDistance
(
const snapParameters& snapParams,
const indirectPrimitivePatch&
) const;
////- Get patches generated for surfaces.
//labelList getSurfacePatches() const;
//- Smooth the mesh (patch and internal) to increase visibility
// of surface points (on castellated mesh) w.r.t. surface.
void preSmoothPatch
(
const snapParameters& snapParams,
const label nInitErrors,
const List<labelPair>& baffles,
motionSmoother&
) const;
//- Get points both on patch and facezone.
labelList getZoneSurfacePoints
(
const indirectPrimitivePatch&,
const word& zoneName
) const;
//- Per patch point calculate point on nearest surface. Set as
// boundary conditions of motionSmoother displacement field. Return
// displacement of patch points.
vectorField calcNearestSurface
(
const scalarField& snapDist,
motionSmoother& meshMover
) const;
//- Smooth the displacement field to the internal.
void smoothDisplacement
(
const snapParameters& snapParams,
motionSmoother&
) const;
//- Do the hard work: move the mesh according to displacement,
// locally relax the displacement.
void scaleMesh
(
const snapParameters& snapParams,
const label nInitErrors,
const List<labelPair>& baffles,
motionSmoother&
);
void doSnap
(
const dictionary& snapDict,
const dictionary& motionDict,
const snapParameters& snapParams
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -27,22 +27,136 @@ License
#include "layerParameters.H"
#include "polyBoundaryMesh.H"
#include "mathematicalConstants.H"
#include "refinementSurfaces.H"
#include "searchableSurfaces.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
const Foam::scalar Foam::layerParameters::defaultConcaveAngle = 90;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
// Read the number of layers from dictionary. Per patch 0 or the number
// of layers.
Foam::labelList Foam::layerParameters::readNumLayers
(
const PtrList<dictionary>& surfaceDicts,
const refinementSurfaces& refineSurfaces,
const labelList& globalToPatch,
const polyBoundaryMesh& boundaryMesh
)
{
// Per surface the number of layers
labelList globalSurfLayers(surfaceDicts.size());
// Per surface, per region the number of layers
List<Map<label> > regionSurfLayers(surfaceDicts.size());
const labelList& surfaceIndices = refineSurfaces.surfaces();
forAll(surfaceDicts, surfI)
{
const dictionary& dict = surfaceDicts[surfI];
globalSurfLayers[surfI] = readLabel(dict.lookup("surfaceLayers"));
if (dict.found("regions"))
{
// Per-region layer information
PtrList<dictionary> regionDicts(dict.lookup("regions"));
const wordList& regionNames =
refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
forAll(regionDicts, dictI)
{
const dictionary& regionDict = regionDicts[dictI];
const word regionName(regionDict.lookup("name"));
label regionI = findIndex(regionNames, regionName);
label nLayers = readLabel(regionDict.lookup("surfaceLayers"));
Info<< " region " << regionName << ':'<< nl
<< " surface layers:" << nLayers << nl;
regionSurfLayers[surfI].insert(regionI, nLayers);
}
}
}
// Transfer per surface/region information into patchwise region info
labelList nLayers(boundaryMesh.size(), 0);
forAll(surfaceIndices, surfI)
{
const wordList& regionNames =
refineSurfaces.geometry()[surfaceIndices[surfI]].regions();
forAll(regionNames, regionI)
{
const word& regionName = regionNames[regionI];
label global = refineSurfaces.globalRegion(surfI, regionI);
label patchI = globalToPatch[global];
// Initialise to surface-wise layers
nLayers[patchI] = globalSurfLayers[surfI];
// Override with region specific data if available
Map<label>::const_iterator iter =
regionSurfLayers[surfI].find(regionI);
if (iter != regionSurfLayers[surfI].end())
{
nLayers[patchI] = iter();
}
// Check
if (nLayers[patchI] < 0)
{
FatalErrorIn
(
"layerParameters::readNumLayers(..)"
) << "Illegal number of layers " << nLayers[patchI]
<< " for surface "
<< refineSurfaces.names()[surfI]
<< " region " << regionName << endl
<< exit(FatalError);
}
}
}
return nLayers;
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from dictionary
Foam::layerParameters::layerParameters
(
const PtrList<dictionary>& surfaceDicts,
const refinementSurfaces& refineSurfaces,
const labelList& globalToPatch,
const dictionary& dict,
const labelList& numLayers
const polyBoundaryMesh& boundaryMesh
)
:
numLayers_(numLayers),
numLayers_
(
readNumLayers
(
surfaceDicts,
refineSurfaces,
globalToPatch,
boundaryMesh
)
),
expansionRatio_
(
numLayers_.size(),

View File

@ -47,6 +47,7 @@ namespace Foam
// Class forward declarations
class polyBoundaryMesh;
class refinementSurfaces;
/*---------------------------------------------------------------------------*\
Class layerParameters Declaration
@ -107,6 +108,15 @@ class layerParameters
// Private Member Functions
//- Extract patch-wise number of layers
static labelList readNumLayers
(
const PtrList<dictionary>& surfaceDicts,
const refinementSurfaces& refineSurfaces,
const labelList& globalToPatch,
const polyBoundaryMesh& boundaryMesh
);
//- Disallow default bitwise copy construct
layerParameters(const layerParameters&);
@ -119,7 +129,14 @@ public:
// Constructors
//- Construct from dictionary - old syntax
layerParameters(const dictionary& dict, const labelList& numLayers);
layerParameters
(
const PtrList<dictionary>& surfaceDicts,
const refinementSurfaces& refineSurfaces,
const labelList& globalToPatch,
const dictionary& dict,
const polyBoundaryMesh& boundaryMesh
);
//- Construct from dictionary - new syntax
layerParameters(const dictionary& dict, const polyBoundaryMesh&);

View File

@ -224,7 +224,7 @@ void Foam::meshRefinement::checkData()
// Compare
testSyncBoundaryFaceList
(
tol_,
mergeDistance_,
"testing faceCentres : ",
boundaryFc,
neiBoundaryFc
@ -489,13 +489,13 @@ void Foam::meshRefinement::getRegionMaster
Foam::meshRefinement::meshRefinement
(
fvMesh& mesh,
const scalar tol,
const scalar mergeDistance,
const refinementSurfaces& surfaces,
const shellSurfaces& shells
)
:
mesh_(mesh),
tol_(tol),
mergeDistance_(mergeDistance),
surfaces_(surfaces),
shells_(shells),
meshCutter_
@ -718,6 +718,141 @@ Foam::labelList Foam::meshRefinement::decomposeCombineRegions
}
Foam::autoPtr<Foam::mapDistributePolyMesh> Foam::meshRefinement::balance
(
const bool keepZoneFaces,
const bool keepBaffles,
decompositionMethod& decomposer,
fvMeshDistribute& distributor
)
{
autoPtr<mapDistributePolyMesh> map;
if (Pstream::parRun())
{
//Info<< nl
// << "Doing final balancing" << nl
// << "---------------------" << nl
// << endl;
//
//if (debug_)
//{
// const_cast<Time&>(mesh_.time())++;
//}
// Wanted distribution
labelList distribution;
if (keepZoneFaces || keepBaffles)
{
// Faces where owner and neighbour are not 'connected' so can
// go to different processors.
boolList blockedFace(mesh_.nFaces(), true);
// Pairs of baffles
List<labelPair> couples;
if (keepZoneFaces)
{
label nNamed = surfaces().getNamedSurfaces().size();
Info<< "Found " << nNamed << " surfaces with faceZones."
<< " Applying special decomposition to keep those together."
<< endl;
// Determine decomposition to keep/move surface zones
// on one processor. The reason is that snapping will make these
// into baffles, move and convert them back so if they were
// proc boundaries after baffling&moving the points might be no
// longer snychronised so recoupling will fail. To prevent this
// keep owner&neighbour of such a surface zone on the same
// processor.
const wordList& fzNames = surfaces().faceZoneNames();
const faceZoneMesh& fZones = mesh_.faceZones();
// Get faces whose owner and neighbour should stay together,
// i.e. they are not 'blocked'.
label nZoned = 0;
forAll(fzNames, surfI)
{
if (fzNames[surfI].size() > 0)
{
// Get zone
label zoneI = fZones.findZoneID(fzNames[surfI]);
const faceZone& fZone = fZones[zoneI];
forAll(fZone, i)
{
if (blockedFace[fZone[i]])
{
blockedFace[fZone[i]] = false;
nZoned++;
}
}
}
}
Info<< "Found " << returnReduce(nZoned, sumOp<label>())
<< " zoned faces to keep together."
<< endl;
}
if (keepBaffles)
{
// Get boundary baffles that need to stay together.
couples = getDuplicateFaces // all baffles
(
identity(mesh_.nFaces()-mesh_.nInternalFaces())
+mesh_.nInternalFaces()
);
Info<< "Found " << returnReduce(couples.size(), sumOp<label>())
<< " baffles to keep together."
<< endl;
}
distribution = decomposeCombineRegions
(
blockedFace,
couples,
decomposer
);
labelList nProcCells(distributor.countCells(distribution));
Pstream::listCombineGather(nProcCells, plusEqOp<label>());
Pstream::listCombineScatter(nProcCells);
Info<< "Calculated decomposition:" << endl;
forAll(nProcCells, procI)
{
Info<< " " << procI << '\t' << nProcCells[procI] << endl;
}
Info<< endl;
}
else
{
// Normal decomposition
distribution = decomposer.decompose(mesh_.cellCentres());
}
if (debug)
{
Pout<< "Wanted distribution:"
<< distributor.countCells(distribution)
<< endl;
}
// Do actual sending/receiving of mesh
map = distributor.distribute(distribution);
// Update numbering of meshRefiner
distribute(map);
}
return map;
}
// Helper function to get intersected faces
Foam::labelList Foam::meshRefinement::intersectedFaces() const
{
@ -941,6 +1076,101 @@ Foam::tmp<Foam::pointVectorField> Foam::meshRefinement::makeDisplacementField
}
void Foam::meshRefinement::checkCoupledFaceZones(const polyMesh& mesh)
{
const faceZoneMesh& fZones = mesh.faceZones();
// Check any zones are present anywhere and in same order
{
List<wordList> zoneNames(Pstream::nProcs());
zoneNames[Pstream::myProcNo()] = fZones.names();
Pstream::gatherList(zoneNames);
Pstream::scatterList(zoneNames);
// All have same data now. Check.
forAll(zoneNames, procI)
{
if (procI != Pstream::myProcNo())
{
if (zoneNames[procI] != zoneNames[Pstream::myProcNo()])
{
FatalErrorIn
(
"meshRefinement::checkCoupledFaceZones(const polyMesh&)"
) << "faceZones are not synchronised on processors." << nl
<< "Processor " << procI << " has faceZones "
<< zoneNames[procI] << nl
<< "Processor " << Pstream::myProcNo()
<< " has faceZones "
<< zoneNames[Pstream::myProcNo()] << nl
<< exit(FatalError);
}
}
}
}
// Check that coupled faces are present on both sides.
labelList faceToZone(mesh.nFaces()-mesh.nInternalFaces(), -1);
forAll(fZones, zoneI)
{
const faceZone& fZone = fZones[zoneI];
forAll(fZone, i)
{
label bFaceI = fZone[i]-mesh.nInternalFaces();
if (bFaceI >= 0)
{
if (faceToZone[bFaceI] == -1)
{
faceToZone[bFaceI] = zoneI;
}
else if (faceToZone[bFaceI] == zoneI)
{
FatalErrorIn
(
"meshRefinement::checkCoupledFaceZones(const polyMesh&)"
) << "Face " << fZone[i] << " in zone "
<< fZone.name()
<< " is twice in zone!"
<< abort(FatalError);
}
else
{
FatalErrorIn
(
"meshRefinement::checkCoupledFaceZones(const polyMesh&)"
) << "Face " << fZone[i] << " in zone "
<< fZone.name()
<< " is also in zone "
<< fZones[faceToZone[bFaceI]].name()
<< abort(FatalError);
}
}
}
}
labelList neiFaceToZone(faceToZone);
syncTools::swapBoundaryFaceList(mesh, neiFaceToZone, false);
forAll(faceToZone, i)
{
if (faceToZone[i] != neiFaceToZone[i])
{
FatalErrorIn
(
"meshRefinement::checkCoupledFaceZones(const polyMesh&)"
) << "Face " << mesh.nInternalFaces()+i
<< " is in zone " << faceToZone[i]
<< ", its coupled face is in zone " << neiFaceToZone[i]
<< abort(FatalError);
}
}
}
// Adds patch if not yet there. Returns patchID.
Foam::label Foam::meshRefinement::addPatch
(

View File

@ -94,7 +94,7 @@ public:
{
MASTERONLY = 1, /*!< maintain master only */
KEEPALL = 2, /*!< have slaves (upon refinement) from master */
REMOVE = 4 /*!< set value to -1 any face that has been refined */
REMOVE = 4 /*!< set value to -1 any face that was refined */
};
@ -106,7 +106,7 @@ private:
fvMesh& mesh_;
//- tolerance used for sorting coordinates (used in 'less' routine)
const scalar tol_;
const scalar mergeDistance_;
//- All surface-intersection interaction
const refinementSurfaces& surfaces_;
@ -383,7 +383,7 @@ public:
meshRefinement
(
fvMesh& mesh,
const scalar tol,
const scalar mergeDistance,
const refinementSurfaces&,
const shellSurfaces&
);
@ -403,12 +403,23 @@ public:
return mesh_;
}
scalar mergeDistance() const
{
return mergeDistance_;
}
//- reference to surface search engines
const refinementSurfaces& surfaces() const
{
return surfaces_;
}
//- reference to refinement shells (regions)
const shellSurfaces& shells() const
{
return shells_;
}
//- reference to meshcutting engine
const hexRef8& meshCutter() const
{
@ -458,6 +469,18 @@ public:
decompositionMethod&
) const;
//- Redecompose according to cell count
// keepZoneFaces : find all faceZones from zoned surfaces and keep
// owner and neighbour together
// keepBaffles : find all baffles and keep them together
autoPtr<mapDistributePolyMesh> balance
(
const bool keepZoneFaces,
const bool keepBaffles,
decompositionMethod& decomposer,
fvMeshDistribute& distributor
);
//- Get faces with intersection.
labelList intersectedFaces() const;
@ -486,6 +509,9 @@ public:
const labelList& adaptPatchIDs
);
//- Helper function: check that face zones are synced
static void checkCoupledFaceZones(const polyMesh&);
// Refinement
@ -626,7 +652,7 @@ public:
template<class T>
void testSyncBoundaryFaceList
(
const scalar tol,
const scalar mergeDistance,
const string&,
const UList<T>&,
const UList<T>&

View File

@ -26,8 +26,8 @@ Class
Foam::refinementSurfaces
Description
Container for triSurfaces used for surface-driven refinement.
These contain all the data about the level of refinement needed per
Container for data on surfaces used for surface-driven refinement.
Contains all the data about the level of refinement needed per
surface.
SourceFiles
@ -126,6 +126,11 @@ public:
// Access
const searchableSurfaces& geometry() const
{
return allGeometry_;
}
const labelList& surfaces() const
{
return surfaces_;

View File

@ -361,7 +361,7 @@ public:
// Member Functions
//- Helper funntion: count cells per processor in wanted distribution
//- Helper function: count cells per processor in wanted distribution
static labelList countCells(const labelList&);
//- Send cells to neighbours according to distribution

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 1991-2007 OpenCFD Ltd.
\\ / A nd | Copyright (C) 1991-2008 OpenCFD Ltd.
\\/ M anipulation |
-------------------------------------------------------------------------------
License

File diff suppressed because it is too large Load Diff