57static const scalar defaultMergeTol = 1
e-6;
60scalar getMergeDistance
67 const scalar mergeTol =
68 args.getOrDefault<scalar>(
"mergeTol", defaultMergeTol);
70 const scalar writeTol =
73 Info<<
"Merge tolerance : " << mergeTol <<
nl
74 <<
"Write tolerance : " << writeTol <<
endl;
79 <<
"Your current settings specify ASCII writing with "
81 <<
"Your merging tolerance (" << mergeTol <<
") is finer than this."
83 <<
"Please change your writeFormat to binary"
84 <<
" or increase the writePrecision" <<
endl
85 <<
"or adjust the merge tolerance (-mergeTol)."
89 scalar mergeDist = mergeTol * bb.
mag();
91 Info<<
"Overall meshes bounding box : " << bb <<
nl
92 <<
"Relative tolerance : " << mergeTol <<
nl
93 <<
"Absolute matching distance : " << mergeDist <<
nl
107 const labelList& pPatches =
mesh.globalData().processorPatches();
114 mesh.boundaryMesh()[pPatches[i]]
127 label maxProcCells = 0;
128 label totProcFaces = 0;
129 label maxProcPatches = 0;
130 label totProcPatches = 0;
131 label maxProcFaces = 0;
136 <<
"Processor " << proci <<
nl
137 <<
" Number of cells = " << globalCells.localSize(proci)
140 label nProcFaces = 0;
142 const labelList& nei = patchNeiProcNo[proci];
144 forAll(patchNeiProcNo[proci], i)
146 Info<<
" Number of faces shared with processor "
147 << patchNeiProcNo[proci][i] <<
" = " << patchSize[proci][i]
150 nProcFaces += patchSize[proci][i];
153 Info<<
" Number of processor patches = " << nei.
size() <<
nl
154 <<
" Number of processor faces = " << nProcFaces <<
nl
155 <<
" Number of boundary faces = "
156 << globalBoundaryFaces.localSize(proci) <<
endl;
158 maxProcCells =
max(maxProcCells, globalCells.localSize(proci));
159 totProcFaces += nProcFaces;
160 totProcPatches += nei.
size();
161 maxProcPatches =
max(maxProcPatches, nei.
size());
162 maxProcFaces =
max(maxProcFaces, nProcFaces);
172 if (totProcPatches == 0)
176 if (totProcFaces == 0)
182 <<
"Number of processor faces = " << totProcFaces/2 <<
nl
183 <<
"Max number of cells = " << maxProcCells
184 <<
" (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
185 <<
"% above average " << avgProcCells <<
")" <<
nl
186 <<
"Max number of processor patches = " << maxProcPatches
187 <<
" (" << 100.0*(maxProcPatches-avgProcPatches)/avgProcPatches
188 <<
"% above average " << avgProcPatches <<
")" <<
nl
189 <<
"Max number of faces between processors = " << maxProcFaces
190 <<
" (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces
191 <<
"% above average " << avgProcFaces <<
")" <<
nl
205 return i*nCells[1]*nCells[2]+j*nCells[2]+
k;
235 if (nCells[0]+nCells[1]+nCells[2] > 0)
237 points.setSize((nCells[0]+1)*(nCells[1]+1)*(nCells[2]+1));
240 for (label i = 0; i <= nCells[0]; i++)
242 for (label j = 0; j <= nCells[1]; j++)
244 for (label
k = 0;
k <= nCells[2];
k++)
247 pt.
x() += i*cellSize[0];
248 pt.
y() += j*cellSize[1];
249 pt.
z() +=
k*cellSize[2];
250 points[vtxLabel(nCells, i, j,
k)] = pt;
262 for (label i = 0; i < nCells[0]; i++)
264 for (label j = 0; j < nCells[1]; j++)
266 for (label
k = 0;
k < nCells[2];
k++)
268 hexPoints[0] = vtxLabel(nCells, i, j,
k);
269 hexPoints[1] = vtxLabel(nCells, i+1, j,
k);
270 hexPoints[2] = vtxLabel(nCells, i+1, j+1,
k);
271 hexPoints[3] = vtxLabel(nCells, i, j+1,
k);
272 hexPoints[4] = vtxLabel(nCells, i, j,
k+1);
273 hexPoints[5] = vtxLabel(nCells, i+1, j,
k+1);
274 hexPoints[6] = vtxLabel(nCells, i+1, j+1,
k+1);
275 hexPoints[7] = vtxLabel(nCells, i, j+1,
k+1);
314 auto&
fld = tfld.ref();
317 List<pointIndexHit> nearest;
338 forAll(nearestSurfaces, i)
340 if (nearestSurfaces[i] == surfI)
342 surfPoints.append(
points[i]);
343 surfIndices.append(i);
348 label geomI = surfaces[surfI];
349 List<volumeType> volType;
350 geometry[geomI].getVolumeType(surfPoints, volType);
355 label pointi = surfIndices[i];
356 scalar dist =
points[pointi].dist(nearest[pointi].hitPoint());
371 <<
"getVolumeType failure, neither INSIDE or OUTSIDE"
384int main(
int argc,
char *argv[])
388 "Generate foamyHexMesh-consistent representation of surfaces"
393 "Write the resulting mesh and distance fields"
399 "The merge distance relative to the bounding box size (default 1e-6)"
407 const bool writeMesh =
args.found(
"writeMesh");
411 Info<<
"Writing resulting mesh and cellDistance, pointDistance fields."
433 "cvSearchableSurfaces",
440 foamyHexMeshDict.subDict(
"geometry"),
441 foamyHexMeshDict.getOrDefault(
"singleRegionName",
true)
451 foamyHexMeshDict.subDict(
"surfaceConformation")
457 foamyHexMeshDict.subDict(
"motionControl"),
466 const treeBoundBox& bb = geometryToConformTo.globalBounds();
470 vector nScalarCells = span/cellShapeControls.defaultCellSize();
476 label(nScalarCells.x())+2,
477 label(nScalarCells.y())+2,
478 label(nScalarCells.z())+2
487 Info<<
"Generating initial hex mesh with" <<
nl
488 <<
" bounding box : " << bb <<
nl
489 <<
" nCells : " << nCells <<
nl
490 <<
" cellSize : " << cellSize <<
nl
512 Info<<
"Writing initial hex mesh to " <<
meshPtr().instance() <<
nl
532 ).decomposer().decompose(
mesh,
mesh.cellCentres());
545 Info<<
"Wanted distribution:"
546 << distributor.countCells(decomp) <<
nl <<
endl;
556 Info<<
"Writing redistributed mesh" <<
nl <<
endl;
561 Info<<
"Refining background mesh according to cell size specification" <<
nl
565 foamyHexMeshDict.
subDict(
"backgroundMeshDecomposition");
579 backgroundMesh.mesh().write();
582 const scalar tolDim = getMergeDistance
586 backgroundMesh.mesh().bounds()
595 const fvMesh&
fvm = backgroundMesh.mesh();
602 fvm.time().timeName(),
613 const labelList& surfaces = geometryToConformTo.surfaces();
619 const labelList& cellLevel = backgroundMesh.cellLevel();
624 distSqr[celli] =
magSqr(cellSize)/
pow(2, cellLevel[celli]);
629 cellDistance.primitiveFieldRef() = signedDistance
639 cellDistance.boundaryFieldRef();
646 fld.patch().patchInternalField(distSqr)
648 fld = signedDistance(patchDistSqr, cc, geometry, surfaces);
656 cellDistance.write();
667 fvm.time().timeName(),
678 for (label facei = 0; facei <
fvm.nInternalFaces(); facei++)
680 label own =
fvm.faceOwner()[facei];
681 label ownDistSqr = distSqr[own];
686 pointDistSqr[
f[fp]] =
max(pointDistSqr[
f[fp]], ownDistSqr);
697 pointDistance.primitiveFieldRef() = signedDistance
707 pointDistance.write();
722 isoFaces[i] = iso[i];
724 isoPoints = iso.points();
Info<< nl;Info<< "Write faMesh in vtk format:"<< nl;{ vtk::uindirectPatchWriter writer(aMesh.patch(), fileName(aMesh.time().globalPath()/vtkBaseFileName));writer.writeGeometry();globalIndex procAddr(aMesh.nFaces());labelList cellIDs;if(UPstream::master()) { cellIDs.resize(procAddr.totalSize());for(const labelRange &range :procAddr.ranges()) { auto slice=cellIDs.slice(range);slice=identity(range);} } writer.beginCellData(4);writer.writeProcIDs();writer.write("cellID", cellIDs);writer.write("area", aMesh.S().field());writer.write("normal", aMesh.faceAreaNormals());writer.beginPointData(1);writer.write("normal", aMesh.pointAreaNormals());Info<< " "<< writer.output().name()<< nl;}{ vtk::lineWriter writer(aMesh.points(), aMesh.edges(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edges")));writer.writeGeometry();writer.beginCellData(4);writer.writeProcIDs();{ Field< scalar > fld(faMeshTools::flattenEdgeField(aMesh.magLe(), true))
vtk::lineWriter writer(edgeCentres, edgeList::null(), fileName(aMesh.time().globalPath()/(vtkBaseFileName+"-edgesCentres")))
Dynamically sized Field. Similar to DynamicList, but inheriting from a Field instead of a List.
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
GeometricBoundaryField< scalar, fvPatchField, volMesh > Boundary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
@ NO_REGISTER
Do not request registration (bool: false).
@ NO_READ
Nothing to be read.
@ MUST_READ
Reading required.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
@ ASCII
"ascii" (normal default)
static unsigned int defaultPrecision() noexcept
Return the default precision.
void setSize(label n)
Alias for resize().
static FOAM_NO_DANGLING_REFERENCE const pointMesh & New(const polyMesh &mesh, Args &&... args)
static void gatherList(UList< T > &values, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Gather data, but keep individual values separate.
A non-owning sub-view of a List (allocated or unallocated storage).
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
void size(const label n)
Older name for setAddressableSize.
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.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
static label nProcs(const label communicator=worldComm)
Number of ranks in parallel run (for given communicator). It is 1 for serial run.
static rangeType allProcs(const label communicator=worldComm)
Range of process indices for all processes.
Templated 3D Vector derived from VectorSpace adding construction from 3 components,...
const Cmpt & x() const noexcept
Access to the vector x component.
const Cmpt & z() const noexcept
Access to the vector z component.
const Cmpt & y() const noexcept
Access to the vector y component.
Extract command arguments and options from the supplied argc and argv parameters.
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
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.
static autoPtr< T > New(Args &&... args)
Construct autoPtr with forwarding arguments.
Store a background polyMesh to use for the decomposition of space and queries for parallel conformalV...
A bounding box defined in terms of min/max extrema points.
const point & min() const noexcept
Minimum describing the bounding box.
scalar mag() const
The magnitude/length of the bounding box diagonal.
vector span() const
The bounding box span (from minimum to maximum).
Maps a geometry to a set of cell primitives.
static const cellModel & ref(const modelType model)
Look up reference to cellModel by enumeration. Fatal on failure.
static const decompositionModel & New(const polyMesh &mesh, const fileName &decompDictFile="", const dictionary *fallback=nullptr)
Read and register on mesh, optionally with alternative decomposeParDict path/name or with fallback co...
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
A face is a list of labels corresponding to mesh vertices.
A class for handling file names.
Sends/receives parts of mesh+fvfields to neighbouring processors. Used in load balancing.
Mesh data needed to do the Finite Volume discretisation.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
A surface formed by the iso value. After "Polygonising A Scalar Field Using Tetrahedrons",...
Mesh consisting of general polyhedral cells.
static word defaultRegion
Return the default region name.
Neighbour processor patch.
int neighbProcNo() const noexcept
Return neighbour processor number.
static void findNearest(const PtrList< searchableSurface > &, const labelList &surfacesToTest, const pointField &, const scalarField &nearestDistSqr, labelList &surfaces, List< pointIndexHit > &)
Find nearest. Return -1 (and a miss()) or surface and nearest.
Container for searchableSurfaces. The collection is specified as a dictionary. For example,...
A class for managing temporary objects.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
Standard boundBox with extra functionality for use in octree.
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
An enumeration wrapper for classification of a location as being inside/outside of a volume.
@ OUTSIDE
A location outside the volume.
@ INSIDE
A location inside the volume.
Write faces/points (optionally with fields) as a vtp file or a legacy vtk file.
A class for handling words, derived from Foam::string.
Foam::autoPtr< Foam::dynamicFvMesh > meshPtr
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Namespace of functions to calculate implicit derivatives returning a matrix.
Type & refCast(U &obj)
A dynamic_cast (for references) to Type reference.
List< word > wordList
List of word.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
List< labelList > labelListList
List of labelList.
GeometricField< scalar, pointPatchField, pointMesh > pointScalarField
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
const dimensionSet dimLength(0, 1, 0, 0, 0, 0, 0)
GeometricField< scalar, fvPatchField, volMesh > volScalarField
messageStream Info
Information stream (stdout output on master, null elsewhere).
PrimitivePatch< SubList< face >, const pointField & > primitivePatch
A PrimitivePatch with a SubList addressing for the faces, const reference for the point field.
List< face > faceList
List of faces.
IOstream & hex(IOstream &io)
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
dimensionedScalar pow(const dimensionedScalar &ds, const dimensionedScalar &expt)
Ostream & endl(Ostream &os)
Add newline and flush stream.
List< faceList > faceListList
List of faceList.
vector point
Point is a vector.
static constexpr const zero Zero
Global zero (0).
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
vectorField pointField
pointField is a vectorField.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
List< cellShape > cellShapeList
List of cellShape.
fvPatchField< scalar > fvPatchScalarField
constexpr char nl
The newline '\n' character (0x0a).
wordList patchTypes(nPatches)
wordList patchNames(nPatches)
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.