68 const label regioni = regions[celli];
69 regionToSum(regioni, Type(
Zero)) +=
fld[celli];
83 for (label celli = 0; celli < nCells; ++celli)
85 const label regioni = regions[celli];
86 ++regionToSum(regioni);
98 List<Type> sortedData(keys.
size());
102 sortedData[i] = regionData[keys[i]];
112void Foam::functionObjects::regionSizeDistribution::writeAlphaFields
136 obr_.time().timeName(),
149 obr_.time().timeName(),
161 const label regioni = regions[celli];
162 if (keepRegions.
found(regioni))
164 backgroundAlpha[celli] = 0;
168 liquidCore[celli] = 0;
170 const scalar regionVol = regionVolume[regioni];
171 if (regionVol < maxDropletVol)
173 backgroundAlpha[celli] = 0;
177 liquidCore.correctBoundaryConditions();
178 backgroundAlpha.correctBoundaryConditions();
182 Info<<
" Volume of liquid-core = "
185 <<
" Volume of background = "
190 Log <<
" Writing liquid-core field to " << liquidCore.
name() <<
endl;
193 Log<<
" Writing background field to " << backgroundAlpha.name() <<
endl;
194 backgroundAlpha.
write();
199Foam::functionObjects::regionSizeDistribution::findPatchRegions
201 const regionSplit& regions
209 labelHashSet patchSet(mesh_.boundaryMesh().patchSet(patchNames_));
211 for (
const label patchi : patchSet)
213 const polyPatch&
pp = mesh_.boundaryMesh()[patchi];
216 for (
const label celli :
pp.faceCells())
218 patchRegions.insert(regions[celli]);
229Foam::tmp<Foam::scalarField>
230Foam::functionObjects::regionSizeDistribution::divide
237 auto& result = tresult.ref();
243 result[i] = num[i]/denom[i];
250void Foam::functionObjects::regionSizeDistribution::writeGraphs
252 const word& fieldName,
257 const coordSet& coords
266 binSum[indices[i]] += sortedField[i];
275 binSqrSum[indices[i]] +=
Foam::sqr(sortedField[i]);
283 auto&
writer = formatterPtr_();
313 Log <<
" Writing distribution of "
314 << fieldName <<
" to " <<
writer.path() <<
endl;
317 writer.write(fieldName +
"_avg", binAvg);
318 writer.write(fieldName +
"_dev", binDev);
324void Foam::functionObjects::regionSizeDistribution::writeGraphs
326 const word& fieldName,
328 const regionSplit& regions,
334 const coordSet& coords
338 Map<scalar> regionField(
regionSum(regions, cellField));
370 alphaName_(
dict.get<
word>(
"field")),
372 isoPlanes_(
dict.getOrDefault(
"isoPlanes", false))
385 dict.readEntry(
"nBins", nBins_);
386 dict.readEntry(
"field", alphaName_);
387 dict.readEntry(
"threshold", threshold_);
388 dict.readEntry(
"maxDiameter", maxDiam_);
390 dict.readIfPresent(
"minDiameter", minDiam_);
391 dict.readEntry(
"patches", patchNames_);
392 dict.readEntry(
"fields", fields_);
398 dict.subOrEmptyDict(
"formatOptions").optionalSubDict(
setFormat)
401 csysPtr_ = coordinateSystem::NewIfPresent(obr_,
dict);
405 Info<<
"Transforming all vectorFields with coordinate system "
406 << csysPtr_->name() <<
endl;
411 dict.readEntry(
"origin", origin_);
412 dict.readEntry(
"direction", direction_);
413 dict.readEntry(
"maxD", maxDiameter_);
414 dict.readEntry(
"nDownstreamBins", nDownstreamBins_);
415 dict.readEntry(
"maxDownstream", maxDownstream_);
416 direction_.normalise();
437 Log <<
" Looking up field " << alphaName_ <<
endl;
441 Info<<
" Reading field " << alphaName_ <<
endl;
449 mesh_.time().timeName(),
459 const auto&
alpha = talpha();
461 Log <<
" Volume of alpha = "
465 const scalar meshVol =
gSum(mesh_.V());
467 const scalar
delta = (maxDiam_-minDiam_)/nBins_;
469 Log <<
" Mesh volume = " << meshVol <<
nl
470 <<
" Maximum droplet diameter = " << maxDiam_ <<
nl
471 <<
" Maximum droplet volume = " << maxDropletVol
476 boolList blockedFace(mesh_.nFaces(),
false);
480 for (label facei = 0; facei < mesh_.nInternalFaces(); facei++)
482 scalar ownVal =
alpha[mesh_.faceOwner()[facei]];
483 scalar neiVal =
alpha[mesh_.faceNeighbour()[facei]];
487 (ownVal < threshold_ && neiVal > threshold_)
488 || (ownVal > threshold_ && neiVal < threshold_)
491 blockedFace[facei] =
true;
504 const auto& ownFld = townFld();
505 const auto& nbrFld = tnbrFld();
511 scalar ownVal = ownFld[i];
512 scalar neiVal = nbrFld[i];
516 (ownVal < threshold_ && neiVal > threshold_)
517 || (ownVal > threshold_ && neiVal < threshold_)
520 blockedFace[start+i] =
true;
529 regionSplit regions(mesh_, blockedFace);
532 <<
" disconnected regions" <<
endl;
539 mesh_.newIOobject(
"region"),
544 Info<<
" Dumping region as volScalarField to "
545 << region.name() <<
endl;
549 region[celli] = regions[celli];
551 region.correctBoundaryConditions();
557 const labelHashSet patchRegions(findPatchRegions(regions));
561 Map<scalar> allRegionVolume(
regionSum(regions, mesh_.V()));
562 Map<scalar> allRegionAlphaVolume(
regionSum(regions, alphaVol));
563 Map<label> allRegionNumCells(
regionSum(regions, mesh_.nCells()));
572 scalar meshSumVol = 0.0;
573 scalar alphaSumVol = 0.0;
576 auto vIter = allRegionVolume.cbegin();
577 auto aIter = allRegionAlphaVolume.cbegin();
578 auto numIter = allRegionNumCells.cbegin();
582 vIter.good() && aIter.good();
583 ++vIter, ++aIter, ++numIter
592 meshSumVol += vIter();
593 alphaSumVol += aIter();
606 Info<<
" Patch connected regions (liquid core):" <<
nl;
612 for (
const label regioni : patchRegions.sortedToc())
624 Info<<
" Background regions:" <<
nl;
630 auto vIter = allRegionVolume.cbegin();
631 auto aIter = allRegionAlphaVolume.cbegin();
636 vIter.good() && aIter.good();
642 !patchRegions.found(vIter.key())
643 && vIter() >= maxDropletVol
662 writeAlphaFields(regions, patchRegions, allRegionVolume,
alpha);
673 const label regioni = vIter.key();
676 patchRegions.found(regioni)
677 || vIter() >= maxDropletVol
678 || (allRegionAlphaVolume[regioni]/vIter() < threshold_)
681 allRegionVolume.erase(vIter);
682 allRegionAlphaVolume.erase(regioni);
683 allRegionNumCells.erase(regioni);
687 if (allRegionVolume.size())
701 const coordSet coords(
"diameter",
"x", xBin,
mag(xBin));
707 const labelList sortedRegions = allRegionAlphaVolume.sortedToc();
721 (
alpha.primitiveField()*mesh_.V())
722 *(mesh_.C().primitiveField() - origin_)()
725 Map<vector> allRegionAlphaDistance
740 centroids = sortedMoment/sortedVols + origin_;
743 scalarField distToPlane((centroids - origin_) & direction_);
747 (centroids - origin_) - (distToPlane*direction_)
750 const scalar deltaX = maxDownstream_/nDownstreamBins_;
751 labelList downstreamIndices(distToPlane.size(), -1);
756 (
mag(radialDistToOrigin[i]) < maxDiameter_)
757 && (distToPlane[i] < maxDownstream_)
760 downstreamIndices[i] = distToPlane[i]/deltaX;
767 if (downstreamIndices[i] != -1)
769 binDownCount[downstreamIndices[i]] += 1.0;
780 scalar
x = 0.5*deltaX;
788 const coordSet coords(
"distance",
"x", xBin,
mag(xBin));
790 auto&
writer = formatterPtr_();
799 writer.write(
"isoPlanes", binDownCount);
806 Info<<
" Iso-planes Bins:" <<
nl
813 forAll(binDownCount, bini)
827 forAll(sortedDiameters, i)
837 labelList indices(sortedDiameters.size());
838 forAll(sortedDiameters, i)
840 indices[i] = (sortedDiameters[i]-minDiam_)/
delta;
845 forAll(sortedDiameters, i)
847 binCount[indices[i]] += 1.0;
853 auto&
writer = formatterPtr_();
862 writer.write(
"count", binCount);
908 const word& fldName = vfield.name();
910 Log <<
" Scalar field " << fldName <<
endl;
912 tmp<Field<scalar>> tfld(vfield.primitiveField());
913 const auto&
fld = tfld();
938 const word& fldName = vfield.name();
940 Log <<
" Vector field " << fldName <<
endl;
942 tmp<Field<vector>> tfld(vfield.primitiveField());
946 Log <<
"Transforming vector field " << fldName
947 <<
" with coordinate system "
948 << csysPtr_->name() <<
endl;
950 tfld = csysPtr_->localVector(tfld());
952 const auto&
fld = tfld();
961 alphaVol*
fld.component(cmpt),
Macros for easy insertion into run-time selection tables.
#define addToRunTimeSelectionTable(baseType, thisType, argNames)
Add to construction table with typeName as the key.
word setFormat(propsDict.getOrDefault< word >("setFormat", "vtk"))
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")))
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
Generic templated field type that is much like a Foam::List except that it is expected to hold numeri...
void correctBoundaryConditions()
Correct boundary field.
List< Key > sortedToc() const
The table of contents (the keys) in sorted order.
const_iterator cbegin() const
const_iterator set to the beginning of the HashTable
bool found(const Key &key) const
Same as contains().
label size() const noexcept
The number of elements in table.
bool erase(const iterator &iter)
Erase an entry specified by given iterator.
@ 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,...
const word & name() const noexcept
Return the object name.
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.
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
static void combineReduce(T &value, CombineOp cop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) applying cop to inplace combine value from different processors.
static void mapCombineReduce(Container &values, CombineOp cop, const int tag=UPstream::msgType(), const int communicator=UPstream::worldComm)
Forwards to Pstream::mapReduce with an in-place cop.
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 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 const char *const componentNames[]
static constexpr direction nComponents
Number of components in this vector space.
static autoPtr< coordSetWriter > New(const word &writeFormat)
Return a reference to the selected writer.
static word suffix(const word &fldName, const word &fileExt=word::null)
Name suffix based on fieldName (underscore separator).
Holds list of sampling positions.
const word & name() const noexcept
The coord-set name.
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Abstract base-class for Time/database function objects.
virtual bool read(const dictionary &dict)
Read and set the function object if its data have changed.
word scopedName(const word &name) const
Return a scoped (prefixed) name.
bool log
Flag to write log into Info.
Specialization of Foam::functionObject for an Foam::fvMesh, providing a reference to the Foam::fvMesh...
const fvMesh & mesh_
Reference to the fvMesh.
fvMeshFunctionObject(const fvMeshFunctionObject &)=delete
No copy construct.
Computes the natural logarithm of an input volScalarField.
const objectRegistry & obr_
Reference to the region objectRegistry.
Creates a droplet size distribution via interrogating a continuous phase fraction field.
regionSizeDistribution(const word &name, const Time &runTime, const dictionary &)
Construct for given objectRegistry and dictionary.
virtual bool read(const dictionary &dict)
Read the function-object dictionary.
virtual bool execute()
Execute the function-object operations.
virtual bool write()
Write the function-object results.
Base class for writing single files from the function objects.
writeFile(const objectRegistry &obr, const fileName &prefix, const word &name="undefined", const bool writeToFile=true, const string &ext=".dat")
Construct from objectRegistry, prefix, fileName.
virtual bool read(const dictionary &dict)
Read.
fileName baseTimeDir() const
Return the base directory for the current time value.
virtual bool coupled() const
True if the patch field is coupled.
static const word & calculatedType() noexcept
The type name for calculated patch fields.
const fvPatch & patch() const noexcept
Return the patch.
virtual tmp< Field< Type > > patchNeighbourField() const
Return patchField on the opposite patch of a coupled patch.
virtual tmp< Field< Type > > patchInternalField() const
Return internal field next to patch.
const polyPatch & patch() const noexcept
Return the polyPatch.
label start() const noexcept
Return start label of this patch in the polyMesh face list.
virtual bool write(const bool writeOnProc=true) const
Write using setting from DB.
This class separates the mesh into distinct unconnected regions, each of which is then given a label ...
label nRegions() const
Return total number of regions.
A class for managing temporary objects.
const T & cref() const
Return const reference to the object or to the contents of a (non-null) managed pointer.
void reset(tmp< T > &&other) noexcept
Clear existing and transfer ownership.
static tmp< T > New(Args &&... args)
Construct tmp with forwarding arguments.
A List of wordRe with additional matching capabilities.
A class for handling words, derived from Foam::string.
#define defineTypeNameAndDebug(Type, DebugSwitch)
Define the typeName and debug information.
word outputName("finiteArea-edges.obj")
Volume integrate volField creating a volField.
constexpr scalar pi(M_PI)
Different types of constants.
Namespace for handling debugging switches.
Function objects are OpenFOAM utilities to ease workflow configurations and enhance workflows.
dimensioned< Type > domainIntegrate(const GeometricField< Type, fvPatchField, volMesh > &vf)
List< word > wordList
List of word.
Type gSum(const FieldField< Field, Type > &f)
GeometricField< vector, fvPatchField, volMesh > volVectorField
const dimensionSet dimless
Dimensionless.
bool read(const char *buf, int32_t &val)
Same as readInt32.
List< label > labelList
A List of labels.
dimensionedSymmTensor sqr(const dimensionedVector &dv)
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
dimensionedScalar pow3(const dimensionedScalar &ds)
GeometricField< scalar, fvPatchField, volMesh > volScalarField
messageStream Info
Information stream (stdout output on master, null elsewhere).
void divide(DimensionedField< Type, GeoMesh > &result, const DimensionedField< Type, GeoMesh > &f1, const DimensionedField< scalar, GeoMesh > &f2)
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
Ostream & endl(Ostream &os)
Add newline and flush stream.
dimensionedScalar sqrt(const dimensionedScalar &ds)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
Field< vector > vectorField
Specialisation of Field<T> for vector.
static Map< Type > regionSum(const regionSplit ®ions, const Field< Type > &fld)
vector point
Point is a vector.
List< bool > boolList
A List of bools.
static constexpr const zero Zero
Global zero (0).
static List< Type > extractData(const labelUList &keys, const Map< Type > ®ionData)
dimensionedScalar cbrt(const dimensionedScalar &ds)
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
vectorField pointField
pointField is a vectorField.
dimensioned< scalar > dimensionedScalar
Dimensioned scalar obtained from generic dimensioned type.
UList< label > labelUList
A UList of labels.
fvPatchField< scalar > fvPatchScalarField
constexpr char nl
The newline '\n' character (0x0a).
#define forAll(list, i)
Loop across all elements in list.
#define forAllIters(container, iter)
Iterate across all elements in the container object.