80 { ExtrudeMode::MESH,
"mesh" },
81 { ExtrudeMode::PATCH,
"patch" },
82 { ExtrudeMode::SURFACE,
"surface" },
93 <<
"Cannot find patch " <<
name
94 <<
" in the source mesh.\n"
95 <<
"Valid patch names are " <<
patches.names()
120 faceLabels[
n++] = pp.
start()+j;
140 const auto& pp = fzs[fzs.
findZoneID(names[i])];
148 const auto& pp = fzs[fzs.
findZoneID(names[i])];
149 const boolList& ppFlip = pp.flipMap();
152 faceLabels[
n] = pp[i];
153 faceFlip[
n] = ppFlip[i];
169 label oldFacei = faceLabels[i];
171 if (reverseMap[oldFacei] >= 0)
173 newFaceLabels[newI++] = reverseMap[oldFacei];
189 label oldCelli = cellLabels[i];
191 if (reverseMap[oldCelli] >= 0)
193 newCellLabels.
insert(reverseMap[oldCelli]);
200template<
class PatchType>
201void changeFrontBackPatches
204 const word& frontPatchName,
205 const word& backPatchName
210 label frontPatchi = findPatchID(
patches, frontPatchName);
211 label backPatchi = findPatchID(
patches, backPatchName);
219 if (patchi == frontPatchi || patchi == backPatchi)
236 newPatches.append(pp.
clone(
mesh.boundaryMesh()).ptr());
241 mesh.removeBoundary();
242 mesh.addPatches(newPatches,
true);
246int main(
int argc,
char *argv[])
250 "Extrude mesh from existing patch."
254 argList::addOption(
"dict",
"file",
"Alternative extrudeMeshDict");
263 << runTimeExtruded.timeName() <<
nl <<
endl;
267 Info<<
"Create mesh for time = "
268 << runTimeExtruded.timeName() <<
nl <<
endl;
279 runTimeExtruded.system(),
281 IOobject::MUST_READ_IF_MODIFIED,
292 const bool flipNormals(
dict.get<
bool>(
"flipNormals"));
295 const ExtrudeMode
mode = ExtrudeModeNames.get(
"constructFrom",
dict);
298 const scalar mergeTol(
dict.getOrDefault<scalar>(
"mergeTol", 1
e-4));
300 Info<<
"Extruding from " << ExtrudeModeNames[
mode]
301 <<
" using model " << model().type() <<
endl;
304 Info<<
"Flipping normals before extruding" <<
endl;
308 Info<<
"Collapsing edges < " << mergeTol <<
" of bounding box" <<
endl;
312 Info<<
"Not collapsing any edges after extrusion" <<
endl;
333 if (mode ==
PATCH || mode == MESH)
335 if (flipNormals && mode == MESH)
338 <<
"Flipping normals not supported for extrusions from mesh."
345 if (Pstream::parRun())
348 sourceCaseDir/(
"processor" +
Foam::name(Pstream::myProcNo()));
362 if (sourcePatches.
size() == 1)
364 frontPatchName = sourcePatches[0];
367 Info<<
"Extruding patches " << sourcePatches
368 <<
" on mesh " << sourceCasePath <<
nl
373 dict.readEntry(
"sourceFaceZones", sourceFaceZones);
374 Info<<
"Extruding faceZones " << sourceFaceZones
375 <<
" on mesh " << sourceCasePath <<
nl
382 Time::controlDictName,
398 if (sourceFaceZones.
size())
400 zoneFaces(
mesh.faceZones(), sourceFaceZones, meshFaces, faceFlips);
404 meshFaces = patchFaces(
patches, sourcePatches);
408 if (mode ==
PATCH && flipNormals)
415 label meshFacei = meshFaces[i];
417 label patchi =
patches.whichPatch(meshFacei);
418 label own =
mesh.faceOwner()[meshFacei];
422 nei =
mesh.faceNeighbour()[meshFacei];
425 label zoneI =
mesh.faceZones().whichZone(meshFacei);
426 bool zoneFlip =
false;
429 label index =
mesh.faceZones()[zoneI].whichFace(meshFacei);
430 zoneFlip =
mesh.faceZones()[zoneI].flipMap()[index];
435 mesh.faces()[meshFacei].reverseFace(),
450 mesh.updateMesh(map());
453 if (map().hasMotionPoints())
455 mesh.movePoints(map().preMotionPoints());
473 PatchTools::pointNormals(
mesh, extrudePatch, faceFlips)
480 extrudePatch.meshEdges
494 addPatchCellLayer::globalEdgeFaces
519 addPatchCellLayer::calcExtrudeInfo
544 Info<<
"Adding overall " << nAdded <<
" processor patches." <<
endl;
553 mesh.boundaryMesh()[patchi].clone
561 label patchi =
mesh.boundaryMesh().size();
566 label nbrProci = patchToNbrProc[patchi];
568 Pout<<
"Adding patch " << patchi
569 <<
" between " << Pstream::myProcNo()
570 <<
" and " << nbrProci
588 mesh.removeFvBoundary();
589 mesh.addFvPatches(newPatches,
true);
598 dict.readEntry(
"exposedPatchName", backPatchName);
602 findPatchID(
patches, backPatchName)
607 pointField layer0Points(extrudePatch.nPoints());
608 pointField displacement(extrudePatch.nPoints());
609 forAll(displacement, pointi)
611 const vector& patchNormal = extrudePatchPointNormals[pointi];
614 layer0Points[pointi] = model()
616 extrudePatch.localPoints()[pointi],
621 point extrudePt = model()
623 extrudePatch.localPoints()[pointi],
627 displacement[pointi] = extrudePt - layer0Points[pointi];
633 if (
gMax(
mag(layer0Points-extrudePatch.localPoints())) > SMALL)
635 Info<<
"Moving mesh to layer0 points since differ from original"
636 <<
" points - this can happen for wedge extrusions." <<
nl
640 forAll(extrudePatch.meshPoints(), i)
642 newPoints[extrudePatch.meshPoints()[i]] = layer0Points[i];
644 mesh.movePoints(newPoints);
649 labelList nFaceLayers(extrudePatch.size(), model().nLayers());
652 labelList nPointLayers(extrudePatch.nPoints(), model().nLayers());
655 vectorField firstLayerDisp(displacement*model().sumThickness(1));
674 mesh.facesInstance(),
675 polyMesh::meshSubDir,
677 IOobject::READ_IF_PRESENT,
697 layerExtrude.setRefinement
719 forAll(layerExtrude.addedPoints(), pointi)
721 const labelList& pPoints = layerExtrude.addedPoints()[pointi];
724 label meshPointi = pPoints[pPointi];
730 extrudePatch.localPoints()[pointi],
731 extrudePatchPointNormals[pointi],
739 )[meshPointi] = modelPt;
748 forAll(backPatchFaces, patchFacei)
750 backPatchFaces[patchFacei] = layerFaces[patchFacei].
first();
751 frontPatchFaces[patchFacei] = layerFaces[patchFacei].
last();
756 fvMeshTools::createDummyFvMeshFiles
770 runTimeExtruded.constant(),
772 IOobject::READ_IF_PRESENT,
773 IOobject::AUTO_WRITE,
779 layerExtrude.updateMesh
789 map().reverseFaceMap(),
794 map().reverseFaceMap(),
801 refDataPtr->updateMesh(map());
809 layerExtrude.addedCells
812 layerExtrude.layerFaces()
817 const labelList& aCells = addedCells[facei];
818 addedCellsSet.
insert(aCells);
827 Info<<
"Extruding surfaceMesh read from file " << surfName <<
nl
838 faces[i] = fMesh[i].reverseFace();
842 Info<<
"Extruding surface with :" <<
nl
843 <<
" points : " << fMesh.points().size() <<
nl
844 <<
" faces : " << fMesh.size() <<
nl
845 <<
" normals[0] : " << fMesh.faceNormals()[0]
849 meshFromSurface.
reset
855 extrudedMesh::defaultRegion,
856 runTimeExtruded.constant(),
866 frontPatchName =
"originalPatch";
867 frontPatchFaces = patchFaces
872 backPatchName =
"otherSide";
873 backPatchFaces = patchFaces
891 const scalar mergeDim = mergeTol * bb.
minDim();
893 Info<<
"Mesh bounding box : " << bb <<
nl
894 <<
" with span : " << span <<
nl
895 <<
"Merge distance : " << mergeDim <<
nl
904 Info<<
"Collapsing edges < " << mergeDim <<
" ..." <<
nl <<
endl;
917 const edge&
e = edges[edgeI];
923 Info<<
"Merging edge " <<
e <<
" since length " << d
924 <<
" << " << mergeDim <<
nl;
927 collapsePointToLocation.set(
e[1],
points[
e[0]]);
935 collapser.consistentCollapse
939 collapsePointToLocation,
948 bool anyChange = collapser.setRefinement(allPointInfo, meshMod);
957 mesh.updateMesh(map());
960 updateFaceLabels(map(), frontPatchFaces);
961 updateFaceLabels(map(), backPatchFaces);
962 updateCellSet(map(), addedCellsSet);
966 refDataPtr->updateMesh(map());
970 if (map().hasMotionPoints())
972 mesh.movePoints(map().preMotionPoints());
983 if (isType<extrudeModels::wedge>(model()))
985 changeFrontBackPatches<wedgePolyPatch>
992 else if (isType<extrudeModels::plane>(model()))
994 changeFrontBackPatches<emptyPolyPatch>
1006 if (
dict.get<
bool>(
"mergeFaces"))
1011 <<
"Cannot stitch front and back of extrusion since"
1012 <<
" in 'mesh' mode (extrusion appended to mesh)."
1013 <<
exit(FatalError);
1016 Info<<
"Assuming full 360 degree axisymmetric case;"
1017 <<
" stitching faces on patches "
1018 << frontPatchName <<
" and "
1019 << backPatchName <<
" together ..." <<
nl <<
endl;
1021 if (frontPatchFaces.
size() != backPatchFaces.
size())
1024 <<
"Differing number of faces on front ("
1025 << frontPatchFaces.
size() <<
") and back ("
1026 << backPatchFaces.
size() <<
")"
1027 <<
exit(FatalError);
1032 stitcher.setSize(1);
1034 const word cutZoneName(
"originalCutFaceZone");
1065 perfectStitcher.setRefinement
1092 mesh.updateMesh(map());
1095 updateCellSet(map(), addedCellsSet);
1099 refDataPtr->updateMesh(map());
1103 if (map().hasMotionPoints())
1105 mesh.movePoints(map().preMotionPoints());
1109 mesh.setInstance(runTimeExtruded.constant());
1115 <<
exit(FatalError);
1118 processorMeshes::removeFiles(
mesh);
1124 cellSet addedCells(
mesh,
"addedCells", addedCellsSet);
1125 Info<<
"Writing added cells to cellSet " << addedCells.name()
1127 if (!addedCells.write())
1130 << addedCells.name()
1131 <<
exit(FatalError);
1137 refDataPtr->write();
reduce(hasMovingMesh, orOp< bool >())
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Enum is a wrapper around a list of names/values that represent particular enumeration (or int) values...
bool insert(const Key &key)
Insert a new entry, not overwriting existing entries.
void transfer(HashTable< T, Key, Hash > &rhs)
Transfer contents into this table.
label size() const noexcept
The number of elements in table.
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Defines the attributes of an object for which implicit objectRegistry management is supported,...
A List with indirect addressing.
void transfer(List< T > &list)
void setSize(const label n)
Alias for resize()
A HashTable to objects of type <T> with a label key.
A surface geometry mesh with zone information, not to be confused with the similarly named surfaceMes...
Bookkeeping for patch definitions.
void setSize(const label n, unsigned int val=0u)
Alias for resize()
A list of faces which address into the list of points.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
T & first()
Return the first element of the list.
void size(const label n)
Older name for setAddressableSize.
T & last()
Return the last element of the list.
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
Adds layers of cells to outside of polyPatch. Can optionally create stand-alone extruded mesh (addToM...
bool readIfPresent(const word &optName, T &val) const
Read a value from the named option if present.
T getOrDefault(const word &optName, const T &deflt) const
Get a value from the named option if present, or return default.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
void reset(autoPtr< T > &&other) noexcept
Delete managed object and set to new given pointer.
A bitSet stores bits (elements with only two states) in packed internal format and supports a variety...
A bounding box defined in terms of min/max extrema points.
scalar minDim() const
Smallest length/height/width dimension.
vector span() const
The bounding box span (from minimum to maximum)
Addressing for all faces on surface of mesh. Can either be read from polyMesh or from triSurface....
A collection of cell labels.
Does polyTopoChanges to remove edges. Can remove faces due to edge collapse but can not remove cells ...
An edge is a list of two point labels. The functionality it provides supports the discretisation on a...
A subset of mesh faces organised as a primitive patch.
A class for handling file names.
static std::string path(const std::string &str)
Return directory path name (part before last /)
static std::string name(const std::string &str)
Return basename (part beyond last /), including its extension.
Calculates a unique integer (label so might not have enough room - 2G max) for processor + local inde...
Calculates points shared by more than two processor patches or cyclic patches.
Various for reading/decomposing/reconstructing/distributing refinement data.
Class containing mesh-to-mesh mapping information after a change in polyMesh topology.
const labelList & reverseCellMap() const
Reverse cell map.
const labelList & reverseFaceMap() const
Reverse face map.
label index() const noexcept
The index of this patch in the boundaryMesh.
const word & name() const noexcept
The patch name.
Hack of attachDetach to couple patches when they perfectly align. Does not decouple....
A polyBoundaryMesh is a polyPatch list with additional search methods and registered IO.
Mesh consisting of general polyhedral cells.
A patch is a list of labels that address the faces in the global face list.
virtual autoPtr< polyPatch > clone(const labelList &faceCells) const
Construct and return a clone, setting faceCells.
label start() const
Return start label of this patch in the polyMesh face list.
Direct mesh changes based on v1.3 polyTopoChange syntax.
List of mesh modifiers defining the mesh dynamics.
Neighbour processor patch.
string & expand(const bool allowEmpty=false)
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A class for handling words, derived from Foam::string.
label collapseEdge(triSurface &surf, const scalar minLen)
Keep collapsing all edges < minLen.
const polyBoundaryMesh & patches
Foam::word regionName(Foam::polyMesh::defaultRegion)
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i)
messageStream Info
Information stream (stdout output on master, null elsewhere)
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values (not the indices) of a list.
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for INVALID.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce (copy) and return value.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
errorManipArg< error, int > exit(error &err, const int errNo=1)
Type gMax(const FieldField< Field, Type > &f)
constexpr char nl
The newline '\n' character (0x0a)
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.