Refactoring polyhedral AMR

Written out interface for polyhedralRefinement class derived from
polyMeshModifier.
This commit is contained in:
Vuko Vukcevic 2018-01-05 11:03:02 +01:00
parent d633af22a0
commit 15fc87e5dd
2 changed files with 1022 additions and 0 deletions

View file

@ -0,0 +1,560 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
Cell layer addition/removal mesh modifier
\*---------------------------------------------------------------------------*/
#include "layerAdditionRemoval.H"
#include "polyTopoChanger.H"
#include "polyMesh.H"
#include "foamTime.H"
#include "primitiveMesh.H"
#include "polyTopoChange.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(layerAdditionRemoval, 0);
addToRunTimeSelectionTable
(
polyMeshModifier,
layerAdditionRemoval,
dictionary
);
}
const Foam::scalar Foam::layerAdditionRemoval::addDelta_ = 0.3;
const Foam::scalar Foam::layerAdditionRemoval::removeDelta_ = 0.1;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::layerAdditionRemoval::checkDefinition()
{
if (!faceZoneID_.active())
{
FatalErrorIn
(
"void Foam::layerAdditionRemoval::checkDefinition()"
) << "Master face zone named " << faceZoneID_.name()
<< " cannot be found."
<< abort(FatalError);
}
const polyMesh& mesh = topoChanger().mesh();
if (debug > 1)
{
fileName fvPath(mesh.time().path()/"VTK");
mkDir(fvPath);
Info<< "Writing VTK files master face zone"
<< "Layer addition/removal " << name()
<< ", face zone " << faceZoneID_.name()
<< "into " << fvPath
<< endl;
primitiveFacePatch::writeVTK
(
fvPath/fileName(faceZoneID_.name() + "FaceZone"),
mesh.faceZones()[faceZoneID_.index()]().localFaces(),
mesh.faceZones()[faceZoneID_.index()]().localPoints()
);
primitiveFacePatch::writeVTKNormals
(
fvPath/fileName(faceZoneID_.name() + "FaceZoneNormals"),
mesh.faceZones()[faceZoneID_.index()]().localFaces(),
mesh.faceZones()[faceZoneID_.index()]().localPoints()
);
}
if
(
minLayerThickness_ < VSMALL
|| maxLayerThickness_ < minLayerThickness_
)
{
FatalErrorIn
(
"void Foam::layerAdditionRemoval::checkDefinition()"
) << "Incorrect layer thickness definition."
<< abort(FatalError);
}
// Check size of zones
label globalZoneSize =
returnReduce
(
mesh.faceZones()[faceZoneID_.index()].size(),
sumOp<label>()
);
if (globalZoneSize == 0)
{
FatalErrorIn
(
"void Foam::layerAdditionRemoval::checkDefinition()"
) << "Face extrusion zone contains no faces. Please check your "
<< "mesh definition."
<< abort(FatalError);
}
if (debug)
{
Pout<< "Cell layer addition/removal object " << name() << " :" << nl
<< " faceZoneID: " << faceZoneID_ << endl;
}
}
Foam::scalar Foam::layerAdditionRemoval::readOldThickness
(
const dictionary& dict
)
{
if (dict.found("oldLayerThickness"))
{
return readScalar(dict.lookup("oldLayerThickness"));
}
else
{
return -1.0;
}
}
void Foam::layerAdditionRemoval::clearAddressing() const
{
// Layer removal data
deleteDemandDrivenData(pointsPairingPtr_);
deleteDemandDrivenData(facesPairingPtr_);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// Construct from components
Foam::layerAdditionRemoval::layerAdditionRemoval
(
const word& name,
const label index,
const polyTopoChanger& mme,
const word& zoneName,
const scalar minThickness,
const scalar maxThickness,
const label cellZone
)
:
polyMeshModifier(name, index, mme, true),
faceZoneID_(zoneName, mme.mesh().faceZones()),
minLayerThickness_(minThickness),
maxLayerThickness_(maxThickness),
oldLayerThickness_(-1.0),
pointsPairingPtr_(NULL),
facesPairingPtr_(NULL),
triggerRemoval_(-1),
triggerAddition_(-1),
cellZone_(cellZone)
{
checkDefinition();
}
// Construct from dictionary
Foam::layerAdditionRemoval::layerAdditionRemoval
(
const word& name,
const dictionary& dict,
const label index,
const polyTopoChanger& mme
)
:
polyMeshModifier(name, index, mme, Switch(dict.lookup("active"))),
faceZoneID_(dict.lookup("faceZoneName"), mme.mesh().faceZones()),
minLayerThickness_(readScalar(dict.lookup("minLayerThickness"))),
maxLayerThickness_(readScalar(dict.lookup("maxLayerThickness"))),
oldLayerThickness_(readOldThickness(dict)),
pointsPairingPtr_(NULL),
facesPairingPtr_(NULL),
triggerRemoval_(-1),
triggerAddition_(-1),
cellZone_(-1)
{
checkDefinition();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::layerAdditionRemoval::~layerAdditionRemoval()
{
clearAddressing();
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::layerAdditionRemoval::setRemoval()
{
triggerRemoval_ = topoChanger().morphIndex();
}
void Foam::layerAdditionRemoval::setAddition()
{
triggerAddition_ = topoChanger().morphIndex();
}
bool Foam::layerAdditionRemoval::changeTopology() const
{
// Protect from multiple calculation in the same time-step
if (triggerRemoval_ > -1 || triggerAddition_ > -1)
{
return true;
}
// Go through all the cells in the master layer and calculate
// approximate layer thickness as the ratio of the cell volume and
// face area in the face zone.
// Layer addition:
// When the max thickness exceeds the threshold, trigger refinement.
// Layer removal:
// When the min thickness falls below the threshold, trigger removal.
const faceZone& fz = topoChanger().mesh().faceZones()[faceZoneID_.index()];
const labelList& mc = fz.masterCells();
if (debug)
{
// Check master cell addressing
if (min(mc) < 0)
{
const polyMesh& mesh = topoChanger().mesh();
fileName fvPath(mesh.time().path()/"VTK");
mkDir(fvPath);
Info<< "Writing VTK files master face zone"
<< "Layer addition/removal " << name()
<< ", face zone " << faceZoneID_.name()
<< "into " << fvPath
<< endl;
primitiveFacePatch::writeVTK
(
fvPath/fileName(faceZoneID_.name() + "FaceZone"),
mesh.faceZones()[faceZoneID_.index()]().localFaces(),
mesh.faceZones()[faceZoneID_.index()]().localPoints()
);
primitiveFacePatch::writeVTKNormals
(
fvPath/fileName(faceZoneID_.name() + "FaceZoneNormals"),
mesh.faceZones()[faceZoneID_.index()]().localFaces(),
mesh.faceZones()[faceZoneID_.index()]().localPoints()
);
FatalErrorIn("bool layerAdditionRemoval::changeTopology() const")
<< "Error in master cell addressing for face zone "
<< faceZoneID_.name()
<< abort(FatalError);
}
}
const scalarField& V = topoChanger().mesh().cellVolumes();
const vectorField& S = topoChanger().mesh().faceAreas();
if (min(V) < -VSMALL)
{
FatalErrorIn("bool layerAdditionRemoval::changeTopology() const")
<< "negative cell volume. Error in mesh motion before "
<< "topological change."
<< abort(FatalError);
}
scalar minDelta = GREAT;
scalar maxDelta = 0;
scalar avgDelta = 0;
scalar nAvg = 0;
if (fz.size())
{
forAll (fz, faceI)
{
scalar curDelta = V[mc[faceI]]/mag(S[fz[faceI]]);
avgDelta += curDelta;
minDelta = min(minDelta, curDelta);
maxDelta = max(maxDelta, curDelta);
}
nAvg += fz.size();
}
// If the patch is empty on a processor in a parallel simulation,
// original values will be preserved. HJ, 7/Mar/2011
reduce(minDelta, minOp<scalar>());
reduce(maxDelta, maxOp<scalar>());
reduce(avgDelta, sumOp<scalar>());
reduce(nAvg, sumOp<scalar>());
avgDelta /= nAvg;
if (debug)
{
Info<< "bool layerAdditionRemoval::changeTopology() const "
<< " for object " << name() << " : " << nl
<< "Layer thickness: min: " << minDelta
<< " max: " << maxDelta << " avg: " << avgDelta
<< " old thickness: " << oldLayerThickness_ << nl
<< "Removal threshold: " << minLayerThickness_
<< " addition threshold: " << maxLayerThickness_ << endl;
}
bool topologicalChange = false;
// If the thickness is decreasing and crosses the min thickness,
// trigger removal
if (oldLayerThickness_ < 0)
{
if (debug)
{
Info<< "First step. No addition/removal" << endl;
}
// No topological changes allowed before first mesh motion
// HJ, 8/Oct/2002
oldLayerThickness_ = avgDelta;
topologicalChange = false;
}
else if (avgDelta < oldLayerThickness_)
{
// Layers moving towards removal
if (minDelta < minLayerThickness_)
{
// Check layer pairing
if (setLayerPairing())
{
// A mesh layer detected. Check that collapse is valid
if (validCollapse())
{
// At this point, info about moving the old mesh
// in a way to collapse the cells in the removed
// layer is available. Not sure what to do with
// it. HJ, 3/Nov/2003
if (debug)
{
Info<< "bool layerAdditionRemoval::changeTopology() "
<< " const for object " << name() << " : "
<< "Triggering layer removal" << endl;
}
triggerRemoval_ = topoChanger().morphIndex();
// Old thickness looses meaning.
// Set it up to indicate layer removal
oldLayerThickness_ = GREAT;
topologicalChange = true;
}
else
{
// No removal, clear addressing
clearAddressing();
}
}
}
else
{
oldLayerThickness_ = avgDelta;
}
}
else
{
// Layers moving towards addition
if (maxDelta > maxLayerThickness_)
{
if (debug)
{
Info<< "bool layerAdditionRemoval::changeTopology() const "
<< " for object " << name() << " : "
<< "Triggering layer addition" << endl;
}
triggerAddition_ = topoChanger().morphIndex();
// Old thickness looses meaning.
// Set it up to indicate layer removal
oldLayerThickness_ = 0;
topologicalChange = true;
}
else
{
oldLayerThickness_ = avgDelta;
}
}
return topologicalChange;
}
void Foam::layerAdditionRemoval::setRefinement(polyTopoChange& ref) const
{
// Insert the layer addition/removal instructions
// into the topological change
if (triggerRemoval_ == topoChanger().morphIndex())
{
removeCellLayer(ref);
// Clear addressing. This also resets the addition/removal data
if (debug)
{
Info<< "layerAdditionRemoval::setRefinement(polyTopoChange& ref) "
<< " for object " << name() << " : "
<< "Clearing addressing after layer removal. " << endl;
}
triggerRemoval_ = -1;
clearAddressing();
}
if (triggerAddition_ == topoChanger().morphIndex())
{
addCellLayer(ref);
// Clear addressing. This also resets the addition/removal data
if (debug)
{
Info<< "layerAdditionRemoval::setRefinement(polyTopoChange& ref) "
<< " for object " << name() << " : "
<< "Clearing addressing after layer addition. " << endl;
}
triggerAddition_ = -1;
clearAddressing();
}
}
void Foam::layerAdditionRemoval::updateMesh(const mapPolyMesh&)
{
if (debug)
{
Info<< "layerAdditionRemoval::updateMesh(const mapPolyMesh&) "
<< " for object " << name() << " : "
<< "Clearing addressing on external request. ";
if (pointsPairingPtr_ || facesPairingPtr_)
{
Info << "Pointers set." << endl;
}
else
{
Info << "Pointers not set." << endl;
}
}
// Mesh has changed topologically. Update local topological data
faceZoneID_.update(topoChanger().mesh().faceZones());
clearAddressing();
}
void Foam::layerAdditionRemoval::setMinLayerThickness(const scalar t) const
{
if
(
t < VSMALL
|| maxLayerThickness_ < t
)
{
FatalErrorIn
(
"void layerAdditionRemoval::setMinLayerThickness("
"const scalar t) const"
) << "Incorrect layer thickness definition."
<< abort(FatalError);
}
minLayerThickness_ = t;
}
void Foam::layerAdditionRemoval::setMaxLayerThickness(const scalar t) const
{
if (t < minLayerThickness_)
{
FatalErrorIn
(
"void layerAdditionRemoval::setMaxLayerThickness("
"const scalar t) const"
) << "Incorrect layer thickness definition."
<< abort(FatalError);
}
maxLayerThickness_ = t;
}
void Foam::layerAdditionRemoval::write(Ostream& os) const
{
os << nl << type() << nl
<< name()<< nl
<< faceZoneID_ << nl
<< minLayerThickness_ << nl
<< oldLayerThickness_ << nl
<< maxLayerThickness_ << endl;
}
void Foam::layerAdditionRemoval::writeDict(Ostream& os) const
{
os << nl << name() << nl << token::BEGIN_BLOCK << nl
<< " type " << type()
<< token::END_STATEMENT << nl
<< " faceZoneName " << faceZoneID_.name()
<< token::END_STATEMENT << nl
<< " minLayerThickness " << minLayerThickness_
<< token::END_STATEMENT << nl
<< " maxLayerThickness " << maxLayerThickness_
<< token::END_STATEMENT << nl
<< " oldLayerThickness " << oldLayerThickness_
<< token::END_STATEMENT << nl
<< " active " << active()
<< token::END_STATEMENT << nl
<< token::END_BLOCK << endl;
}
// ************************************************************************* //

View file

@ -0,0 +1,462 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.0
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::polyhedralRefinement
Description
Isotropic refinement of polyhedral cells using the mesh modifier engine
Each polyhedral cell is split by the following procedure:
1. Adding points at the edge centre, face centre and cell centre,
2. Adding cells n cells where n is the number of points of the cell,
3. Splitting each face into multiple faces going from:
existing corner point -> new edge centre point -> new face centre
point -> other new edge centre point (sharing the same corner point)
4. Adding internal faces going from:
new edge centre point -> new face centre point -> new cell centre
point -> other new face centre point (sharing the same edge)
SourceFiles
polyhedralRefinement.C
Author
Vuko Vukcevic, Wikki Ltd. All rights reserved.
Notes
Generalisation of hexRef8 for polyhedral cells and refactorisation into mesh
modifier engine.
\*---------------------------------------------------------------------------*/
#ifndef polyhedralRefinement_H
#define polyhedralRefinement_H
#include "polyMeshModifier.H"
#include "labelIOList.H"
#include "polyRefinementHistory.H"
#include "removeFaces.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class polyhedralRefinement Declaration
\*---------------------------------------------------------------------------*/
class polyhedralRefinement
:
public polyMeshModifier
{
// Private data
//- Cell refinement level
labelIOList cellLevel_;
//- Point refinement level
labelIOList pointLevel_;
//- Typical edge length between unrefined points
const scalar level0EdgeLength_;
//- Refinement history
polyRefinementHistory history_;
//- Face remover engine
removeFaces faceRemover_;
//- List of cells to refine in this time step
labelList cellsToRefine_;
//- List of split point labels to unrefine in this time step
labelList splitPointLabels_;
// Private Member Functions
// Helper functions
//- Set patch and zone info for a face
void setFaceInfo
(
const label faceI,
label& patchID,
label& zoneID,
label& zoneFlip
) const;
//- Get least cell level such that the face has at least three
// points smaller than the level
label getAnchorLevel(const label faceI) const;
//- Get points of a cell by going through its faces (without using
// cellPoints addressing)
Xfer<labelList> cellPoints(const label cellI) const;
//- Calculate level0EdgeLength_ (constructor helper)
void calcLevel0EdgeLength() const;
// Global topology modification functions (operate on whole polyMesh)
// and directly use local topology modification functions below
//- Refine polyhedral cells. All cellsToRefine_ cells will be split
// into n cells where n is the number of points per cell.
// Guarantees that the 0th element is the original cell label.
// Mapping:
// -split cells: n new ones get added from original
// -split faces: original gets modified; n - 1 new ones get added
// from original
// -added internal faces: added from original cell face (if
// that was internal) or created out-of-nothing (so will not
// get mapped!). Note: could make this inflate from point but
// that will allocate interpolation.
// -points added to split edge: added from edge start()
// -midpoints added: added from cellPoints[0].
void setPolyhedralRefinement() const;
//- Remove some of the previously performed refinement. Uses
// splitPointLabels_ to determine the unrefinement.
// All n pointCells of a split point will be combined into
// the lowest numbered cell of those n.
void setUnrefinement() const;
// Local topology modification functions (operate on cells/faces)
//- Adds a face on top of existing faceI. Reverses if nessecary
label addFace
(
polyTopoChange& meshMod,
const label faceI,
const face& newFace,
const label own,
const label nei
) const;
//- Adds internal face from point. No checks on reversal
label addInternalFace
(
polyTopoChange& meshMod,
const label meshFaceI,
const label meshPointI,
const face& newFace,
const label own,
const label nei
) const;
//- Modifies existing faceI for either new owner/neighbour or new face
// points. Reverses if nessecary
void modifyFace
(
polyTopoChange& meshMod,
const label faceI,
const face& newFace,
const label own,
const label nei
) const;
//- Create all internal faces of split cellI into n cells where n is the
// number of cell points
void createInternalFaces
(
const labelListList& cellAnchorPoints,
const labelListList& cellAddedCells,
const labelList& cellMidPoint,
const labelList& faceMidPoint,
const labelList& faceAnchorLevel,
const labelList& edgeMidPoint,
const label cellI,
polyTopoChange& meshMod
) const;
// Topological change helper functions
//- Get cell added to point of cellI (if any)
label getAnchorCell
(
const labelListList& cellAnchorPoints,
const labelListList& cellAddedCells,
const label cellI,
const label faceI,
const label pointI
) const;
//- Set new owner and neighbour (in unspecified order) of pointI
// on faceI
void setNewFaceNeighbours
(
const labelListList& cellAnchorPoints,
const labelListList& cellAddedCells,
const label faceI,
const label pointI,
label& own,
label& nei
) const;
//- Store vertices from startFp up to face split point.
// Used when splitting face into n faces where n is the number of
// points in a face (or number of edges)
void walkFaceToMid
(
const labelList& edgeMidPoint,
const label cLevel,
const label faceI,
const label startFp,
dynamicLabelList& faceVerts
) const;
//- Same as walkFaceToMid but now walk back
void walkFaceFromMid
(
const labelList& edgeMidPoint,
const label cLevel,
const label faceI,
const label startFp,
dynamicLabelList& faceVerts
) const;
//- Get index of point with minimum or maximum point level
template<class BinaryOp>
label findMinMaxLevel(const labelList& f) const;
//- Count number of vertices <= anchorLevel for a given face
label countAnchors
(
const labelList& f,
const label anchorLevel
) const;
//- Find index of point with wantedLevel, starting from fp
label findLevel
(
const face& f,
const label startFp,
const bool searchForward,
const label wantedLevel
) const;
//- Store in maps correspondence from midpoint to anchors and
// faces. Used when creating internal faces
label storeMidPointInfo
(
const labelListList& cellAnchorPoints,
const labelListList& cellAddedCells,
const labelList& cellMidPoint,
const labelList& edgeMidPoint,
const label cellI,
const label faceI,
const bool faceOrder,
const label midPointI,
const label anchorPointI,
const label faceMidPointI,
Map<edge>& midPointToAnchors,
Map<edge>& midPointToFaceMids,
polyTopoChange& meshMod
) const;
//- If p0 and p1 are existing vertices check if edge is split and insert
// splitPoint. Used with storing mid point
void insertEdgeSplit
(
const labelList& edgeMidPoint,
const label p0,
const label p1,
dynamicLabelList& verts
) const;
// Debug functions
//- Check orientation of added internal face
void checkInternalOrientation
(
polyTopoChange& meshMod,
const label cellI,
const label faceI,
const point& ownPt,
const point& neiPt,
const face& newFace
) const;
//- Check orientation of a new boundary face
void checkBoundaryOrientation
(
polyTopoChange& meshMod,
const label cellI,
const label faceI,
const point& ownPt,
const point& boundaryPt,
const face& newFace
) const;
// Refinement/unrefinement consistency checks
//- Given valid mesh, current cell level and proposed
// cells to refine calculate any clashes (due to 2:1) and return
// ok list of cells to refine.
Xfer<labelList> consistentRefinement
(
const labelList& cellsToRefine,
const bool pointBasedRefinement
) const;
//- Given proposed splitPoints to unrefine calculate
// any clashes (due to 2:1) and return ok list of points to
// unrefine.
Xfer<labelList> consistentUnrefinement
(
const labelList& pointsToUnrefine,
const bool pointBasedUnrefinement
) const;
//- Updates refineCell such that a face consistent 2:1 refinement
// is obtained. Returns local number of cells changed
label faceConsistentRefinement(PackedBoolList& refineCell) const;
//- Updates refineCell such that a point consistent 4:1 refinement
// is obtained. Returns local number of cells changed
label pointConsistentRefinement(PackedBoolList& refineCell) const;
//- Updates unrefineCell such that a face consistent 2:1
// unrefinement is obtained. Returns local number of cells changed
label faceConsistentUnrefinement
(
PackedBoolList& unrefineCell
) const;
//- Updates unrefineCell such that a point consistent 4:1
// unrefinement is obtained. Returns local number of cells changed
label pointConsistentUnrefinement
(
const PackedBoolList& unrefinePoints,
PackedBoolList& unrefineCell
) const;
// Copy control
//- Disallow default bitwise copy construct
polyhedralRefinement(const polyhedralRefinement&);
//- Disallow default bitwise assignment
void operator=(const polyhedralRefinement&);
public:
//- Runtime type information
ClassName("polyhedralRefinement");
// Constructors
//- Construct from dictionary
polyhedralRefinement
(
const word& name,
const dictionary& dict,
const label index,
const polyTopoChanger& mme
);
// Destructor
virtual ~polyhedralRefinement();
// Member Functions
// Access
const labelIOList& cellLevel() const
{
return cellLevel_;
}
const labelIOList& pointLevel() const
{
return pointLevel_;
}
const polyRefinementHistory& history() const
{
return history_;
}
//- Typical edge length between unrefined points
scalar level0EdgeLength() const
{
return level0Edge_;
}
// Edit
//- Set cells to refine
void setCellsToRefine(const labelList& cellsToRefine);
//- Update split points to unrefine
void updateSplitPointsToUnrefine();
// polyMeshModifier interface
//- Check for topology change
virtual bool changeTopology() const;
//- Insert the polyhedral refinement/unrefinement into the
// topological change
virtual void setRefinement(polyTopoChange&) const;
//- Modify motion points to comply with the topological change
virtual void modifyMotionPoints(pointField& motionPoints) const;
//- Force recalculation of locally stored data on topological change
virtual void updateMesh(const mapPolyMesh&);
//- Write
virtual void write(Ostream&) const;
//- Write dictionary
virtual void writeDict(Ostream&) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //