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()
142 n += fzs[zonei].
size();
149 const auto&
pp = fzs[zonei];
154 faceFlip[
n] = ppFlip[i];
172 if (reverseMap[oldFacei] >= 0)
174 newFaceLabels[newI++] = reverseMap[oldFacei];
177 newFaceLabels.setSize(newI);
190 label oldCelli = cellLabels[i];
192 if (reverseMap[oldCelli] >= 0)
194 newCellLabels.insert(reverseMap[oldCelli]);
201template<
class PatchType>
202void changeFrontBackPatches
205 const word& frontPatchName,
206 const word& backPatchName
211 label frontPatchi = findPatchID(
patches, frontPatchName);
212 label backPatchi = findPatchID(
patches, backPatchName);
220 if (patchi == frontPatchi || patchi == backPatchi)
237 newPatches.append(
pp.clone(
mesh.boundaryMesh()).ptr());
242 mesh.removeBoundary();
243 mesh.addPatches(newPatches,
true);
247int main(
int argc,
char *argv[])
251 "Extrude mesh from existing patch."
263 Info<<
"Create mesh";
268 Info<<
" for time = " << runTimeExtruded.timeName() <<
nl <<
nl;
278 runTimeExtruded.system(),
291 const bool flipNormals(
dict.get<
bool>(
"flipNormals"));
294 const ExtrudeMode
mode = ExtrudeModeNames.
get(
"constructFrom",
dict);
297 const scalar mergeTol(
dict.getOrDefault<scalar>(
"mergeTol", 1
e-4));
299 Info<<
"Extruding from " << ExtrudeModeNames[
mode]
300 <<
" using model " << model().type() <<
endl;
303 Info<<
"Flipping normals before extruding" <<
endl;
307 Info<<
"Collapsing edges < " << mergeTol <<
" of bounding box" <<
endl;
311 Info<<
"Not collapsing any edges after extrusion" <<
endl;
334 if (flipNormals &&
mode == MESH)
337 <<
"Flipping normals not supported for extrusions from mesh."
361 if (sourcePatches.
size() == 1)
363 frontPatchName = sourcePatches[0];
366 Info<<
"Extruding patches " << sourcePatches
367 <<
" on mesh " << sourceCasePath <<
nl
372 dict.readEntry(
"sourceFaceZones", sourceFaceZones);
373 Info<<
"Extruding faceZones " << sourceFaceZones
374 <<
" on mesh " << sourceCasePath <<
nl
397 if (sourceFaceZones.
size())
399 zoneFaces(
mesh.faceZones(), sourceFaceZones, meshFaces, faceFlips);
403 meshFaces = patchFaces(
patches, sourcePatches);
414 label meshFacei = meshFaces[i];
416 label patchi =
patches.whichPatch(meshFacei);
417 label own =
mesh.faceOwner()[meshFacei];
421 nei =
mesh.faceNeighbour()[meshFacei];
424 label zoneI =
mesh.faceZones().whichZone(meshFacei);
425 bool zoneFlip =
false;
428 label index =
mesh.faceZones()[zoneI].whichFace(meshFacei);
429 zoneFlip =
mesh.faceZones()[zoneI].flipMap()[index];
434 mesh.faces()[meshFacei].reverseFace(),
449 mesh.updateMesh(map());
452 if (map().hasMotionPoints())
454 mesh.movePoints(map().preMotionPoints());
536 Info<<
"Adding overall " << nAdded <<
" processor patches." <<
endl;
545 mesh.boundaryMesh()[patchi].clone
553 label patchi =
mesh.boundaryMesh().size();
558 label nbrProci = patchToNbrProc[patchi];
560 Pout<<
"Adding patch " << patchi
562 <<
" and " << nbrProci
580 mesh.removeFvBoundary();
581 mesh.addFvPatches(newPatches,
true);
590 dict.readEntry(
"exposedPatchName", backPatchName);
594 findPatchID(
patches, backPatchName)
599 pointField layer0Points(extrudePatch.nPoints());
600 pointField displacement(extrudePatch.nPoints());
601 forAll(displacement, pointi)
603 const vector& patchNormal = extrudePatchPointNormals[pointi];
606 layer0Points[pointi] = model()
608 extrudePatch.localPoints()[pointi],
613 point extrudePt = model()
615 extrudePatch.localPoints()[pointi],
619 displacement[pointi] = extrudePt - layer0Points[pointi];
625 if (
gMax(
mag(layer0Points-extrudePatch.localPoints())) > SMALL)
627 Info<<
"Moving mesh to layer0 points since differ from original"
628 <<
" points - this can happen for wedge extrusions." <<
nl
632 forAll(extrudePatch.meshPoints(), i)
634 newPoints[extrudePatch.meshPoints()[i]] = layer0Points[i];
636 mesh.movePoints(newPoints);
641 labelList nFaceLayers(extrudePatch.size(), model().nLayers());
644 labelList nPointLayers(extrudePatch.nPoints(), model().nLayers());
647 vectorField firstLayerDisp(displacement*model().sumThickness(1));
666 mesh.facesInstance(),
689 layerExtrude.setRefinement
711 forAll(layerExtrude.addedPoints(), pointi)
713 const labelList& pPoints = layerExtrude.addedPoints()[pointi];
716 label meshPointi = pPoints[pPointi];
722 extrudePatch.localPoints()[pointi],
723 extrudePatchPointNormals[pointi],
731 )[meshPointi] = modelPt;
740 forAll(backPatchFaces, patchFacei)
742 backPatchFaces[patchFacei] = layerFaces[patchFacei].
first();
743 frontPatchFaces[patchFacei] = layerFaces[patchFacei].
last();
762 runTimeExtruded.constant(),
771 layerExtrude.updateMesh
781 map().reverseFaceMap(),
786 map().reverseFaceMap(),
793 refDataPtr->updateMesh(map());
801 layerExtrude.addedCells
804 layerExtrude.layerFaces()
809 const labelList& aCells = addedCells[facei];
810 addedCellsSet.
insert(aCells);
819 Info<<
"Extruding surfaceMesh read from file " << surfName <<
nl
830 faces[i] = fMesh[i].reverseFace();
834 Info<<
"Extruding surface with :" <<
nl
835 <<
" points : " << fMesh.points().size() <<
nl
836 <<
" faces : " << fMesh.size() <<
nl
837 <<
" normals[0] : " << fMesh.faceNormals()[0]
841 meshFromSurface.
reset
848 runTimeExtruded.constant(),
858 frontPatchName =
"originalPatch";
859 frontPatchFaces = patchFaces
864 backPatchName =
"otherSide";
865 backPatchFaces = patchFaces
882 const scalar mergeDim = mergeTol * bb.
minDim();
884 Info<<
"Mesh bounding box : " << bb <<
nl
885 <<
" with span : " << bb.
span() <<
nl
886 <<
"Merge distance : " << mergeDim <<
nl
895 Info<<
"Collapsing edges < " << mergeDim <<
" ..." <<
nl <<
endl;
908 const edge&
e = edges[edgeI];
914 Info<<
"Merging edge " <<
e <<
" since length " << d
915 <<
" << " << mergeDim <<
nl;
918 collapsePointToLocation.set(
e[1],
points[
e[0]]);
922 List<pointEdgeCollapse> allPointInfo;
926 collapser.consistentCollapse
930 collapsePointToLocation,
939 bool anyChange = collapser.setRefinement(allPointInfo, meshMod);
947 mesh.updateMesh(map());
950 updateFaceLabels(map(), frontPatchFaces);
951 updateFaceLabels(map(), backPatchFaces);
952 updateCellSet(map(), addedCellsSet);
956 refDataPtr->updateMesh(map());
960 if (map().hasMotionPoints())
962 mesh.movePoints(map().preMotionPoints());
975 changeFrontBackPatches<wedgePolyPatch>
984 changeFrontBackPatches<emptyPolyPatch>
996 if (
dict.get<
bool>(
"mergeFaces"))
1001 <<
"Cannot stitch front and back of extrusion since"
1002 <<
" in 'mesh' mode (extrusion appended to mesh)."
1006 Info<<
"Assuming full 360 degree axisymmetric case;"
1007 <<
" stitching faces on patches "
1008 << frontPatchName <<
" and "
1009 << backPatchName <<
" together ..." <<
nl <<
endl;
1011 if (frontPatchFaces.
size() != backPatchFaces.
size())
1014 <<
"Differing number of faces on front ("
1015 << frontPatchFaces.
size() <<
") and back ("
1016 << backPatchFaces.
size() <<
")"
1022 stitcher.setSize(1);
1024 const word cutZoneName(
"originalCutFaceZone");
1039 mesh.addZones(List<pointZone*>(0), fz, List<cellZone*>(0));
1055 perfectStitcher.setRefinement
1082 mesh.updateMesh(map());
1085 updateCellSet(map(), addedCellsSet);
1089 refDataPtr->updateMesh(map());
1093 if (map().hasMotionPoints())
1095 mesh.movePoints(map().preMotionPoints());
1099 mesh.setInstance(runTimeExtruded.constant());
1113 cellSet addedCells(
mesh,
"addedCells", addedCellsSet);
1114 Info<<
"Writing added cells to cellSet " << addedCells.name()
1116 if (!addedCells.write())
1119 << addedCells.name()
1126 refDataPtr->write();
labelList faceLabels(nFaceLabels)
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
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...
EnumType get(const word &enumName) const
The enumeration corresponding to the given name.
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...
@ NO_REGISTER
Do not request registration (bool: false).
@ READ_IF_PRESENT
Reading is optional [identical to LAZY_READ].
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
@ AUTO_WRITE
Automatically write from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
static IOobject selectIO(const IOobject &io, const fileName &altFile, const word &ioName="")
Return the IOobject, but also consider an alternative file name.
A List with indirect addressing.
void setSize(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...
void setSize(const label n, unsigned int val=0u)
Alias for resize().
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
static word controlDictName
The default control dictionary name (normally "controlDict").
T & first()
Access first element of the list, position [0].
void size(const label n)
Older name for setAddressableSize.
T & last()
Access last element of the list, position [size()-1].
static int myProcNo(const label communicator=worldComm)
Rank of this process in the communicator (starting from masterNo()). Negative if the process is not a...
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
label size() const noexcept
The number of entries in the list.
labelList indices(const wordRe &matcher, const bool useGroups=true) const
The (sorted) patch indices for all matches, optionally matching zone groups.
Adds layers of cells to outside (or inside) of polyMesh. Can optionally create stand-alone extruded m...
static labelListList globalEdgeFaces(const polyMesh &, const globalIndex &globalFaces, const indirectPrimitivePatch &pp, const bitSet &orientation)
Per patch edge the pp faces (in global indices) using it.
static void calcExtrudeInfo(const bool zoneFromAnyFace, const polyMesh &, const globalIndex &globalFaces, const labelListList &globalEdgeFaces, const indirectPrimitivePatch &pp, labelList &edgePatchID, label &nPatches, Map< label > &nbrProcToPatch, Map< label > &patchToNbrProc, labelList &edgeZoneID, boolList &edgeFlip, labelList &inflateFaceID)
Determine extrude information per patch edge:
static void addOption(const word &optName, const string ¶m="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
static void addNote(const string ¬e)
Add extra notes for the usage information.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
void reset(T *p=nullptr) noexcept
Delete managed object and set to new given pointer.
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 vertex labels. This can correspond to a directed graph edge or an edge on a ...
static autoPtr< extrudeModel > New(const dictionary &dict)
Select null constructed.
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 non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
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 noexcept
Reverse cell map.
const labelList & reverseFaceMap() const noexcept
Reverse face map.
Hack of attachDetach to couple patches when they perfectly align. Does not decouple....
A polyBoundaryMesh is a polyPatch list with registered IO, a reference to the associated polyMesh,...
Mesh consisting of general polyhedral cells.
static const word & regionName(const word ®ion)
The mesh region name or word::null if polyMesh::defaultRegion.
static word defaultRegion
Return the default region name.
static word meshSubDir
Return the mesh sub-directory name (usually "polyMesh").
A patch is a list of labels that address the faces in the global face list.
Direct mesh changes based on v1.3 polyTopoChange syntax.
List of mesh modifiers defining the mesh dynamics.
static void removeFiles(const polyMesh &mesh)
Helper: remove all procAddressing files from mesh instance.
Neighbour processor patch.
string & expand(const bool allowEmpty=false)
Inplace expand initial tags, tildes, and all occurrences of environment variables as per stringOps::e...
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
A List of wordRe with additional matching capabilities.
A class for handling words, derived from Foam::string.
static const word null
An empty word.
label collapseEdge(triSurface &surf, const scalar minLen)
Keep collapsing all edges < minLen.
const polyBoundaryMesh & patches
Foam::word regionName(args.getOrDefault< word >("region", Foam::polyMesh::defaultRegion))
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
const labelIOList & zoneIDs
return returnReduce(nRefine-oldNRefine, sumOp< label >())
List< edge > edgeList
List of edge.
bool returnReduceOr(const bool value, const int communicator=UPstream::worldComm)
Perform logical (or) MPI Allreduce on a copy. Uses UPstream::reduceOr.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
messageStream Info
Information stream (stdout output on master, null elsewhere).
IntListType renumber(const labelUList &oldToNew, const IntListType &input)
Renumber the values within a list.
mode_t mode(const fileName &name, const bool followLink=true)
Return the file mode, normally following symbolic links.
ZoneMesh< faceZone, polyMesh > faceZoneMesh
A ZoneMesh with faceZone content on a polyMesh.
List< face > faceList
List of faces.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
PrimitivePatch< IndirectList< face >, const pointField & > indirectPrimitivePatch
A PrimitivePatch with an IndirectList for the faces, const reference for the point field.
labelList identity(const label len, label start=0)
Return an identity map of the given length with (map[i] == i), works like std::iota() but returning a...
Field< vector > vectorField
Specialisation of Field<T> for vector.
vector point
Point is a vector.
List< bool > boolList
A List of bools.
static constexpr const zero Zero
Global zero (0).
bool isType(const U &obj)
Check if typeid of the object and Type are identical.
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
vectorField pointField
pointField is a vectorField.
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.