50void Foam::autoDensity::writeOBJ
58 Pout<<
"Writing " << str.name() <<
endl;
62 for (
const point& pt : bbPoints)
69 str <<
"l " <<
e[0] + 1 <<
' ' <<
e[1] + 1 <<
nl;
74bool Foam::autoDensity::combinedOverlaps(
const treeBoundBox& box)
const
79 decomposition().overlapsThisProcessor(box)
80 || geometryToConformTo().overlaps(box);
83 return geometryToConformTo().overlaps(box);
87bool Foam::autoDensity::combinedInside(
const point&
p)
const
92 decomposition().positionOnThisProcessor(
p)
93 && geometryToConformTo().inside(
p);
96 return geometryToConformTo().inside(
p);
100Foam::Field<bool> Foam::autoDensity::combinedWellInside
108 return geometryToConformTo().wellInside
111 minimumSurfaceDistanceCoeffSqr_*
sqr(sizes)
122 geometryToConformTo().wellInside
125 minimumSurfaceDistanceCoeffSqr_*
sqr(sizes)
131 decomposition().positionOnThisProcessor(
pts)
150 inside[i] = (insideA[i] && insideB[i]);
157bool Foam::autoDensity::combinedWellInside
167 inside = decomposition().positionOnThisProcessor(
p);
174 && geometryToConformTo().wellInside
177 minimumSurfaceDistanceCoeffSqr_*
sqr(size)
184Foam::label Foam::autoDensity::recurseAndFill
202 if (combinedOverlaps(subBB))
226 word(newName +
"_overlap")
229 Pout<< newName +
"_overlap " << subBB <<
endl;
232 if (!fillBox(initialPoints, subBB,
true))
249 else if (combinedInside(subBB.centre()))
259 Pout<< newName +
"_inside " << subBB <<
endl;
262 if (!fillBox(initialPoints, subBB,
false))
291 return treeDepth + 1;
295bool Foam::autoDensity::fillBox
304 label initialSize = initialPoints.size();
306 scalar maxCellSize = -GREAT;
308 scalar minCellSize = GREAT;
310 scalar maxDensity = 1/
pow3(minCellSize);
312 scalar volumeAdded = 0.0;
318 scalar totalVolume = bb.volume();
320 label trialPoints = 0;
322 bool wellInside =
false;
334 geometry.findSurfaceNearest
346 Pout<<
"box wellInside, no need to sample surface." <<
endl;
353 if (!overlapping && !wellInside)
362 scalarField cornerSizes = cellShapeControls().cellSize(corners);
364 Field<bool> insideCorners = combinedWellInside(corners, cornerSizes);
371 scalar
s = cornerSizes[i];
380 minCellSize =
max(
s, minCellSizeLimit_);
383 if (maxCellSize/minCellSize > maxSizeRatio_)
387 Pout<<
"Abort fill at corner sample stage,"
388 <<
" minCellSize " << minCellSize
389 <<
" maxCellSize " << maxCellSize
390 <<
" maxSizeRatio " << maxCellSize/minCellSize
397 if (!insideCorners[i])
404 Pout<<
"Inside box found to have some non-wellInside "
405 <<
"corners, using overlapping fill."
419 label nLine = 6*(surfRes_ - 2);
425 for (label i = 0; i < surfRes_; i++)
429 for (label j = 1; j < surfRes_ - 1 ; j++)
439 delta.x()*(surfRes_ - 1),
453 delta.y()*(surfRes_ - 1),
467 delta.z()*(surfRes_ - 1)
471 lineSizes = cellShapeControls().cellSize(
linePoints);
482 scalar
s = lineSizes[i];
491 minCellSize =
max(
s, minCellSizeLimit_);
494 if (maxCellSize/minCellSize > maxSizeRatio_)
498 Pout<<
"Abort fill at surface sample stage, "
499 <<
" minCellSize " << minCellSize
500 <<
" maxCellSize " << maxCellSize
501 <<
" maxSizeRatio " << maxCellSize/minCellSize
516 Pout<<
"Inside box found to have some non-"
517 <<
"wellInside surface points, using "
518 <<
"overlapping fill."
536 volRes_*volRes_*volRes_,
544 for (label i = 0; i < volRes_; i++)
546 for (label j = 0; j < volRes_; j++)
548 for (label
k = 0;
k < volRes_;
k++)
558 *(i + 0.5 + 0.1*(
rndGen().sample01<scalar>() - 0.5)),
560 *(j + 0.5 + 0.1*(
rndGen().sample01<scalar>() - 0.5)),
562 *(
k + 0.5 + 0.1*(
rndGen().sample01<scalar>() - 0.5))
573 scalarField sampleSizes = cellShapeControls().cellSize(samplePoints);
589 scalar
s = sampleSizes[i];
598 minCellSize =
max(
s, minCellSizeLimit_);
601 if (maxCellSize/minCellSize > maxSizeRatio_)
605 Pout<<
"Abort fill at sample stage,"
606 <<
" minCellSize " << minCellSize
607 <<
" maxCellSize " << maxCellSize
608 <<
" maxSizeRatio " << maxCellSize/minCellSize
621 Pout<<
"No sample points found inside box" <<
endl;
629 Pout<< scalar(nInside)/scalar(samplePoints.size())
630 <<
" full overlapping box" <<
endl;
633 totalVolume *= scalar(nInside)/scalar(samplePoints.size());
637 Pout<<
"Total volume to fill = " << totalVolume <<
endl;
644 maxDensity = 1/
pow3(
max(minCellSize, SMALL));
652 const point&
p = samplePoints[i];
654 scalar localSize = sampleSizes[i];
656 scalar localDensity = 1/
pow3(localSize);
667 if (localDensity/maxDensity >
rndGen().sample01<scalar>())
669 scalar localVolume = 1/localDensity;
671 if (volumeAdded + localVolume > totalVolume)
677 scalar addProbability =
678 (totalVolume - volumeAdded)/localVolume;
684 Pout<<
"totalVolume " << totalVolume <<
nl
685 <<
"volumeAdded " << volumeAdded <<
nl
686 <<
"localVolume " << localVolume <<
nl
687 <<
"addProbability " << addProbability <<
nl
692 if (addProbability > r)
705 volumeAdded += localVolume;
713 volumeAdded += localVolume;
719 if (volumeAdded < totalVolume)
723 Pout<<
"Adding random points, remaining volume "
724 << totalVolume - volumeAdded
728 maxDensity = 1/
pow3(
max(minCellSize, SMALL));
736 scalar localSize = cellShapeControls().cellSize(
p);
738 bool insidePoint =
false;
747 insidePoint = combinedWellInside(
p, localSize);
752 if (localSize > maxCellSize)
754 maxCellSize = localSize;
757 if (localSize < minCellSize)
759 minCellSize =
max(localSize, minCellSizeLimit_);
761 localSize = minCellSize;
765 maxDensity = 1/
pow3(
max(minCellSize, SMALL));
768 if (maxCellSize/minCellSize > maxSizeRatio_)
772 Pout<<
"Abort fill at random fill stage,"
773 <<
" minCellSize " << minCellSize
774 <<
" maxCellSize " << maxCellSize
775 <<
" maxSizeRatio " << maxCellSize/minCellSize
781 initialPoints.resize(initialSize);
786 scalar localDensity = 1/
pow3(
max(localSize, SMALL));
790 if (localDensity/maxDensity >
rndGen().sample01<scalar>())
792 scalar localVolume = 1/localDensity;
794 if (volumeAdded + localVolume > totalVolume)
800 scalar addProbability =
801 (totalVolume - volumeAdded)/localVolume;
807 Pout<<
"totalVolume " << totalVolume <<
nl
808 <<
"volumeAdded " << volumeAdded <<
nl
809 <<
"localVolume " << localVolume <<
nl
810 <<
"addProbability " << addProbability <<
nl
815 if (addProbability > r)
828 volumeAdded += localVolume;
836 volumeAdded += localVolume;
842 globalTrialPoints_ += trialPoints;
847 <<
" locations queried, " << initialPoints.size() - initialSize
848 <<
" points placed, ("
849 << scalar(initialPoints.size() - initialSize)
850 /scalar(
max(trialPoints, 1))
851 <<
" success rate)." <<
nl
852 <<
"minCellSize " << minCellSize
853 <<
", maxCellSize " << maxCellSize
854 <<
", ratio " << maxCellSize/minCellSize
884 globalTrialPoints_(0),
887 detailsDict().getOrDefault<scalar>(
"minCellSizeLimit", 0)
889 minLevels_(detailsDict().
get<label>(
"minLevels")),
890 maxSizeRatio_(detailsDict().
get<scalar>(
"maxSizeRatio")),
891 volRes_(detailsDict().
get<label>(
"sampleResolution")),
894 detailsDict().getOrDefault<label>(
"surfaceSampleResolution", volRes_)
897 if (maxSizeRatio_ <= 1.0)
902 <<
"The maxSizeRatio must be greater than one to be sensible, "
903 <<
"setting to " << maxSizeRatio_
911List<Vb::Point> autoDensity::initialPoints()
const
917 if (Pstream::parRun())
919 hierBB = decomposition().procBounds();
924 hierBB = geometryToConformTo().globalBounds().extend
931 DynamicList<Vb::Point> initialPoints;
937 Pout<<
" Filling box " << hierBB <<
endl;
940 label treeDepth = recurseAndFill
948 initialPoints.shrink();
950 label nInitialPoints = initialPoints.size();
952 if (Pstream::parRun())
954 reduce(nInitialPoints, sumOp<label>());
955 reduce(globalTrialPoints_, sumOp<label>());
959 <<
indent << nInitialPoints <<
" points placed" <<
nl
960 <<
indent << globalTrialPoints_ <<
" locations queried" <<
nl
962 << scalar(nInitialPoints)/scalar(
max(globalTrialPoints_, 1))
963 <<
" success rate" <<
nl
966 <<
" levels of recursion (maximum)"
970 return initialPoints;
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
CGAL::Triangulation_vertex_base_2< K >::Point Point
A 1D vector of objects of type <T> that resizes itself as necessary to accept the new objects.
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
Output to file stream as an OSstream, normally using std::ofstream for the actual output.
Type sample01()
Return a sample whose components lie in the range [0,1].
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
void size(const label n)
Older name for setAddressableSize.
static bool parRun(const bool on) noexcept
Set as parallel run on/off.
Choose random points inside the domain and place them with a probability proportional to the target d...
autoDensity(const dictionary &initialPointsDict, const Time &runTime, Random &rndGen, const conformationSurfaces &geometryToConformTo, const cellShapeControl &cellShapeControls, const autoPtr< backgroundMeshDecomposition > &decomposition)
Construct from components.
Pointer management similar to std::unique_ptr, with some additional methods and type checking.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
An edge is a list of two vertex labels. This can correspond to a directed graph edge or an edge on a ...
A class for handling file names.
Abstract base class for generating initial points for a conformalVoronoiMesh.
Line point storage. Default constructable (line is not).
Standard boundBox with extra functionality for use in octree.
static const edgeList edges
Edge to point addressing, using octant corner points.
treeBoundBox subBbox(const direction octant) const
Sub-box of given octant. Midpoint calculated.
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
fileName path(UMean.rootPath()/UMean.caseName()/"graphs"/UMean.instance())
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))
return returnReduce(nRefine-oldNRefine, sumOp< label >())
#define WarningInFunction
Report a warning using Foam::Warning.
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 handling debugging switches.
void shuffle(UList< T > &list)
Randomise the list order.
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
dimensionedScalar pow3(const dimensionedScalar &ds)
messageStream Info
Information stream (stdout output on master, null elsewhere).
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & incrIndent(Ostream &os)
Increment the indent level.
const word GlobalIOList< Tuple2< scalar, vector > >::typeName("scalarVectorTable")
Ostream & endl(Ostream &os)
Add newline and flush stream.
Ostream & indent(Ostream &os)
Indent stream.
void reduce(T &value, BinaryOp bop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce).
label min(const labelHashSet &set, label minValue=labelMax)
Find the min value in labelHashSet, optionally limited by second argument.
vector point
Point is a vector.
static constexpr const zero Zero
Global zero (0).
dimensioned< Type > cmptMultiply(const dimensioned< Type > &, const dimensioned< Type > &)
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.
PointIndexHit< point > pointIndexHit
A PointIndexHit with a 3D point.
Ostream & decrIndent(Ostream &os)
Decrement the indent level.
dimensioned< typename typeOfMag< Type >::type > magSqr(const dimensioned< Type > &dt)
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.