50 const labelUList& toProc
61 label proci = toProc[i];
71 sendMap[proci].resize_nocopy(nSend[proci]);
78 label proci = toProc[i];
79 sendMap[proci][nSend[proci]++] = i;
88void Foam::backgroundMeshDecomposition::initialRefinement()
95 mesh_.time().timeName(),
125 forAll(volumeStatus, celli)
131 if (geometry.overlaps(cellBb))
135 else if (geometry.inside(cellBb.centre()))
147 labelList refCells = selectRefinementCells
156 meshCutter_.consistentRefinement
163 forAll(newCellsToRefine, nCTRI)
165 label celli = newCellsToRefine[nCTRI];
172 icellWeights[celli] =
max
175 icellWeights[celli]/8.0
188 meshCutter_.setRefinement(newCellsToRefine, meshMod);
201 mesh_.updateMesh(map());
204 meshCutter_.updateMesh(map());
209 const labelList& cellMap = map().cellMap();
215 label oldCelli = cellMap[newCelli];
223 newVolumeStatus[newCelli] = volumeStatus[oldCelli];
227 volumeStatus.transfer(newVolumeStatus);
230 Info<<
" Background mesh refined from "
232 <<
" to " << mesh_.globalData().nTotalCells()
233 <<
" cells." <<
endl;
237 forAll(volumeStatus, celli)
243 if (geometry.overlaps(cellBb))
247 else if (geometry.inside(cellBb.centre()))
259 bool removeOutsideCells =
false;
261 if (removeOutsideCells)
265 forAll(volumeStatus, celli)
269 cellsToRemove.append(celli);
278 labelList exposedFaces = cellRemover.getExposedFaces
284 cellRemover.setRefinement
303 mesh_.updateMesh(map());
306 meshCutter_.updateMesh(map());
307 cellRemover.updateMesh(map());
312 const labelList& cellMap = map().cellMap();
318 label oldCelli = cellMap[newCelli];
326 newVolumeStatus[newCelli] = volumeStatus[oldCelli];
330 volumeStatus.transfer(newVolumeStatus);
335 - mesh_.globalData().nTotalCells()
336 <<
" cells." <<
endl;
348 labelList newDecomp = decomposer.decompose
362 meshCutter_.distribute(mapDist());
364 mapDist().distributeCellData(volumeStatus);
368 printMeshData(mesh_);
391void Foam::backgroundMeshDecomposition::printMeshData
423 Info<<
"Processor " << proci <<
" "
424 <<
"Number of cells = " << globalCells.localSize(proci)
448bool Foam::backgroundMeshDecomposition::refineCell
452 scalar& weightEstimate
462 weightEstimate = 1.0;
565Foam::labelList Foam::backgroundMeshDecomposition::selectRefinementCells
576 forAll(volumeStatus, celli)
580 if (meshCutter_.cellLevel()[celli] < minLevels_)
582 cellsToRefine.insert(celli);
598 cellsToRefine.insert(celli);
603 return cellsToRefine.toc();
607void Foam::backgroundMeshDecomposition::buildPatchAndTree()
611 mesh_.boundaryMesh().faces(),
615 boundaryFacesPtr_.reset
619 tmpBoundaryFaces.localFaces(),
620 tmpBoundaryFaces.localPoints()
625 treeBoundBox overallBb(boundaryFacesPtr_().localPoints());
639 overallBb.extend(rnd, 1
e-4),
652 globalBackgroundBounds_.reset();
653 forAll(allBackgroundMeshBounds_, proci)
655 globalBackgroundBounds_.add(allBackgroundMeshBounds_[proci]);
663 /
"backgroundMeshDecomposition_proc_"
665 +
"_boundaryFaces.obj"
668 const faceList& faces = boundaryFacesPtr_().localFaces();
677 const face&
f = faces[i];
681 if (foamToObj.insert(
f[fPI], vertI))
692 fStr<<
' ' << foamToObj[
f[fPI]] + 1;
703Foam::backgroundMeshDecomposition::backgroundMeshDecomposition
713 geometryToConformTo_(geometryToConformTo),
719 "backgroundMeshDecomposition",
735 allBackgroundMeshBounds_(
Pstream::nProcs()),
736 globalBackgroundBounds_(),
738 spanScale_(coeffsDict.
get<scalar>(
"spanScale")),
741 coeffsDict.getOrDefault<scalar>(
"minCellSizeLimit", 0)
743 minLevels_(coeffsDict.
get<label>(
"minLevels")),
744 volRes_(coeffsDict.
get<label>(
"sampleResolution")),
745 maxCellWeightCoeff_(coeffsDict.
get<scalar>(
"maxCellWeightCoeff"))
747 if (!Pstream::parRun())
750 <<
"This cannot be used when not running in parallel."
754 const decompositionMethod& decomposer =
755 decompositionModel::New(mesh_, decompDictFile).decomposer();
757 if (!decomposer.parallelAware())
760 <<
"You have selected decomposition method "
761 << decomposer.typeName
762 <<
" which is not parallel aware." <<
endl
766 Info<<
nl <<
"Building initial background mesh decomposition" <<
endl;
777 volScalarField& cellWeights
794 label nOccupiedCells = 0;
798 if (icellWeights[cI] > 1 - SMALL)
808 scalar cellWeightLimit =
max
811 *
sum(cellWeights).value()
818 Info<<
" cellWeightLimit " << cellWeightLimit <<
endl;
820 Pout<<
" sum(cellWeights) " <<
sum(cellWeights.primitiveField())
821 <<
" max(cellWeights) " <<
max(cellWeights.primitiveField())
829 if (icellWeights[cWI] > cellWeightLimit)
831 cellsToRefine.insert(cWI);
843 meshCutter_.consistentRefinement
850 if (debug && !cellsToRefine.empty())
852 Pout<<
" cellWeights too large in " << cellsToRefine.size()
856 forAll(newCellsToRefine, nCTRI)
858 label celli = newCellsToRefine[nCTRI];
860 icellWeights[celli] /= 8.0;
864 polyTopoChange meshMod(mesh_);
867 meshCutter_.setRefinement(newCellsToRefine, meshMod);
870 autoPtr<mapPolyMesh> map = meshMod.changeMesh
880 mesh_.updateMesh(map());
883 meshCutter_.updateMesh(map());
885 Info<<
" Background mesh refined from "
887 <<
" to " << mesh_.globalData().nTotalCells()
888 <<
" cells." <<
endl;
901 printMeshData(mesh_);
903 Pout<<
" Pre distribute sum(cellWeights) "
905 <<
" max(cellWeights) "
910 decompositionMethod& decomposer =
913 labelList newDecomp = decomposer.decompose
920 Info<<
" Redistributing background mesh cells" <<
endl;
922 fvMeshDistribute distributor(mesh_);
924 autoPtr<mapDistributePolyMesh> mapDist = distributor.distribute(newDecomp);
926 meshCutter_.distribute(mapDist());
930 printMeshData(mesh_);
932 Pout<<
" Post distribute sum(cellWeights) "
934 <<
" max(cellWeights) "
970 posProc[pI] = positionOnThisProcessor(
pts[pI]);
983 return !bFTreePtr_().findBox(box).empty();
990 const scalar radiusSqr
995 return bFTreePtr_().findNearest(centre, radiusSqr).hit();
1005 return bFTreePtr_().findLine(start, end);
1015 return bFTreePtr_().findLineAny(start, end);
1029 label nTotalCandidates = 0;
1035 label nCandidates = 0;
1037 forAll(allBackgroundMeshBounds_, proci)
1041 if (allBackgroundMeshBounds_[proci].overlaps(pt,
sqr(SMALL*100)))
1043 toCandidateProc.append(proci);
1044 testPoints.append(pt);
1050 ptBlockStart[pI] = nTotalCandidates;
1051 ptBlockSize[pI] = nCandidates;
1053 nTotalCandidates += nCandidates;
1057 label preDistributionToCandidateProcSize = toCandidateProc.
size();
1061 map().distribute(testPoints);
1076 distanceSqrToCandidate[tPI] = info.point().distSqr(testPoints[tPI]);
1080 map().reverseDistribute
1082 preDistributionToCandidateProcSize,
1083 distanceSqrToCandidate
1094 distanceSqrToCandidate,
1099 scalar nearestProcDistSqr = GREAT;
1101 forAll(ptNearestProcResults, pPRI)
1103 if (ptNearestProcResults[pPRI] < nearestProcDistSqr)
1105 nearestProcDistSqr = ptNearestProcResults[pPRI];
1107 ptNearestProc[pI] = toCandidateProc[ptBlockStart[pI] + pPRI];
1113 Pout<<
pts[pI] <<
" nearestProcDistSqr " << nearestProcDistSqr
1114 <<
" ptNearestProc[pI] " << ptNearestProc[pI] <<
endl;
1117 if (ptNearestProc[pI] < 0)
1120 <<
"The position " <<
pts[pI]
1121 <<
" did not find a nearest point on the background mesh."
1126 return ptNearestProc;
1131Foam::List<Foam::List<Foam::pointIndexHit>>
1136 bool includeOwnProcessor
1142 labelList segmentBlockStart(starts.size(), -1);
1143 labelList segmentBlockSize(starts.size(), -1);
1145 label nTotalCandidates = 0;
1149 const point&
s = starts[sI];
1150 const point&
e = ends[sI];
1155 label nCandidates = 0;
1157 forAll(allBackgroundMeshBounds_, proci)
1164 && allBackgroundMeshBounds_[proci].intersects(
s,
e,
p)
1167 toCandidateProc.append(proci);
1168 testStarts.append(
s);
1175 segmentBlockStart[sI] = nTotalCandidates;
1176 segmentBlockSize[sI] = nCandidates;
1178 nTotalCandidates += nCandidates;
1182 label preDistributionToCandidateProcSize = toCandidateProc.size();
1186 map().distribute(testStarts);
1187 map().distribute(testEnds);
1194 const point&
s = testStarts[sI];
1195 const point&
e = testEnds[sI];
1198 segmentIntersectsCandidate[sI] = bFTreePtr_().findLine(
s,
e);
1201 map().reverseDistribute
1203 preDistributionToCandidateProcSize,
1204 segmentIntersectsCandidate
1214 tmpProcHits.
clear();
1220 segmentIntersectsCandidate,
1221 segmentBlockSize[sI],
1222 segmentBlockStart[sI]
1225 forAll(segmentProcResults, sPRI)
1227 if (segmentProcResults[sPRI].hit())
1229 tmpProcHits.append(segmentProcResults[sPRI]);
1231 tmpProcHits.last().setIndex
1233 toCandidateProc[segmentBlockStart[sI] + sPRI]
1238 segmentHitProcs[sI] = tmpProcHits;
1241 return segmentHitProcs;
1247 const point& centre,
1248 const scalar& radiusSqr
1251 forAll(allBackgroundMeshBounds_, proci)
1253 if (bFTreePtr_().findNearest(centre, radiusSqr).hit())
1265 const point& centre,
1266 const scalar radiusSqr
1271 forAll(allBackgroundMeshBounds_, proci)
1277 && allBackgroundMeshBounds_[proci].overlaps(centre, radiusSqr)
1283 toProc.append(proci);
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
void clear() noexcept
Clear the addressed list, i.e. set the size to zero.
DimensionedField< scalar, volMesh > Internal
@ NO_READ
Nothing to be read.
@ NO_WRITE
Ignore writing from objectRegistry::writeObject().
Defines the attributes of an object for which implicit objectRegistry management is supported,...
A 1D array of objects of type <T>, where the size of the vector is known and used for subscript bound...
A HashTable to objects of type <T> with a label key.
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
Inter-processor communications stream.
static void allGatherList(UList< T > &values, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Gather data, but keep individual values separate. Uses MPI_Allgather or manual communication.
void reset(const label seedValue)
Reset the random number generator seed.
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 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.
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...
labelList processorNearestPosition(const List< point > &pts) const
What is the nearest processor to the given position?
pointIndexHit findLineAny(const point &start, const point &end) const
Find any intersection of line between start and end, (exposing.
bool overlapsThisProcessor(const treeBoundBox &box) const
Does the given box overlap the faces of the boundary of this.
bool positionOnThisProcessor(const point &pt) const
Is the given position inside the domain of this decomposition.
autoPtr< mapDistributePolyMesh > distribute(volScalarField &cellWeights)
Redistribute the background mesh based on a supplied weight field,.
List< List< pointIndexHit > > intersectsProcessors(const List< point > &starts, const List< point > &ends, bool includeOwnProcessor=false) const
Which processors are intersected by the line segment, returns all.
static autoPtr< mapDistribute > buildMap(const labelUList &toProc)
Build a mapDistribute for the supplied destination processor data.
pointIndexHit findLine(const point &start, const point &end) const
Find nearest intersection of line between start and end, (exposing.
bool overlapsOtherProcessors(const point ¢re, const scalar &radiusSqr) const
labelList overlapProcessors(const point ¢re, const scalar radiusSqr) const
Abstract base class for domain decomposition.
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...
decompositionMethod & decomposer() const
Return demand-driven decomposition method.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
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.
static const word & zeroGradientType() noexcept
The type name for zeroGradient patch fields.
Calculates a non-overlapping list of offsets based on an input size (eg, number of cells) from differ...
static scalar & perturbTol() noexcept
Get the perturbation tolerance.
Non-pointer based hierarchical recursive searching.
Mesh consisting of general polyhedral cells.
Direct mesh changes based on v1.3 polyTopoChange syntax.
label nCells() const noexcept
Number of mesh cells.
Container with cells to refine. Refinement given as single direction.
Given list of cells to remove, insert all the topology changes.
Standard boundBox with extra functionality for use in octree.
An enumeration wrapper for classification of a location as being inside/outside of a volume.
@ OUTSIDE
A location outside the volume.
@ MIXED
A location that is partly inside and outside.
@ INSIDE
A location inside the volume.
static const word null
An empty word.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
gmvFile<< "tracers "<< particles.size()<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().x()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().y()<< " ";}gmvFile<< nl;for(const passiveParticle &p :particles){ gmvFile<< p.position().z()<< " ";}gmvFile<< nl;forAll(lagrangianScalarNames, i){ word name=lagrangianScalarNames[i];IOField< scalar > s(IOobject(name, runTime.timeName(), cloud::prefix, mesh, IOobject::MUST_READ, IOobject::NO_WRITE))
List< ReturnType > get(const UPtrList< T > &list, const AccessOp &aop)
List of values generated by applying the access operation to each list item.
Namespace for bounding specifications. At the moment, mostly for tables.
Namespace for handling debugging switches.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
const dimensionSet dimless
Dimensionless.
List< labelList > labelListList
List of labelList.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
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.
treeDataPrimitivePatch< bPatch > treeDataBPatch
T returnReduce(const T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
bool returnReduceAnd(const bool value, const int communicator=UPstream::worldComm)
Perform logical (and) MPI Allreduce on a copy. Uses UPstream::reduceAnd.
vector point
Point is a vector.
List< bool > boolList
A List of bools.
dimensioned< Type > sum(const DimensionedField< Type, GeoMesh > &f1, const label comm)
static constexpr const zero Zero
Global zero (0).
PrimitivePatch<::Foam::List< face >, const pointField > bPatch
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.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
errorManipArg< error, int > exit(error &err, const int errNo=1)
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.