33 #include "surfaceInterpolate.H" 44 namespace functionObjects
50 extractEulerianParticles,
72 const label nFaces = fz.
size();
73 const label allFaces =
returnReduce(nFaces, sumOp<label>());
79 <<
": Number of faceZone faces (" << allFaces
80 <<
") is less than the number of requested locations (" 87 <<
" faces : " << allFaces <<
nl 100 if (!nInjectorLocations_)
105 const faceZone& fz = mesh_.faceZones()[zoneID_];
114 const label nFaces = fz.
size();
115 label nLocations = nInjectorLocations_;
120 scalar fraction = scalar(nFaces)/scalar(nGlobalFaces);
121 nLocations = ceil(fraction*nInjectorLocations_);
124 Pout<<
"nFaces:" << nFaces
125 <<
", nGlobalFaces:" << nGlobalFaces
126 <<
", fraction:" << fraction
127 <<
", nLocations:" << nLocations
132 pairPatchAgglomeration ppa
145 label nCoarseFaces = 0;
148 fineToCoarseAddr_ = ppa.restrictTopBottomAddressing();
149 nCoarseFaces =
max(fineToCoarseAddr_) + 1;
152 globalCoarseFaces_ = globalIndex(nCoarseFaces);
155 <<
" coarse faces" <<
endl;
188 patchIDs_.setSize(fz.
size(), -1);
189 patchFaceIDs_.setSize(fz.
size(), -1);
191 label nBlockedFaces = 0;
194 const label facei = fz[localFacei];
196 if (mesh_.isInternalFace(facei))
198 if (alphaf[facei] > alphaThreshold_)
200 blockedFaces[localFacei] =
true;
205 label patchi = mesh_.boundaryMesh().whichPatch(facei);
206 label patchFacei = -1;
208 const polyPatch&
pp = mesh_.boundaryMesh()[patchi];
210 const auto* cpp = isA<coupledPolyPatch>(
pp);
214 patchFacei = (cpp->owner() ?
pp.whichFace(facei) : -1);
216 else if (!isA<emptyPolyPatch>(
pp))
218 patchFacei =
pp.whichFace(facei);
221 if (patchFacei == -1)
225 else if (alphafp[patchFacei] > alphaThreshold_)
227 blockedFaces[localFacei] =
true;
230 patchIDs_[localFacei] = patchi;
231 patchFaceIDs_[localFacei] = patchFacei;
247 const label particlei = regionToParticleMap_[regioni];
250 if (
p.faceIHit != -1 && nInjectorLocations_)
253 label coarseFacei = fineToCoarseAddr_[
p.faceIHit];
254 p.faceIHit = globalCoarseFaces_.toGlobal(coarseFacei);
257 reduce(
p, sumParticleOp<eulerianParticle>());
261 if ((pDiameter > minDiameter_) && (pDiameter < maxDiameter_))
266 const point position =
p.VC/(
p.V + ROOTVSMALL);
267 const vector U =
p.VU/(
p.V + ROOTVSMALL);
269 if (nInjectorLocations_)
274 injectedParticle* ip =
new injectedParticle
285 cloud_.addParticle(ip);
287 collectedVolume_ +=
p.V;
290 ++nCollectedParticles_;
295 ++nDiscardedParticles_;
296 discardedVolume_ +=
p.V;
303 const label nNewRegions,
312 labelList oldToNewRegion(particles_.size(), -1);
315 forAll(regionFaceIDs, facei)
317 label newRegioni = regionFaceIDs[facei];
318 label oldRegioni = regions0_[facei];
320 if (newRegioni != -1 && oldRegioni != -1)
324 newToNewRegion[newRegioni] =
325 max(newRegioni, oldToNewRegion[oldRegioni]);
326 oldToNewRegion[oldRegioni] = newRegioni;
334 label nParticle = -1;
336 Map<label> newRegionToParticleMap;
337 forAll(newToNewRegion, newRegioni0)
339 label newRegioni = newToNewRegion[newRegioni0];
340 if (newRegions.insert(newRegioni))
346 newRegionToParticleMap.insert(newRegioni0, nParticle);
353 List<eulerianParticle> newParticles(newRegionToParticleMap.size());
354 forAll(oldToNewRegion, oldRegioni)
356 label newRegioni = oldToNewRegion[oldRegioni];
357 if (newRegioni == -1)
361 <<
"Collecting particle from oldRegion:" << oldRegioni
364 collectParticle(time, oldRegioni);
369 label newParticlei = newRegionToParticleMap[newRegioni];
370 label oldParticlei = regionToParticleMap_[oldRegioni];
373 <<
"Combining newRegioni: " << newRegioni
374 <<
"(p:" << newParticlei <<
") and " 375 <<
"oldRegioni: " << oldRegioni
376 <<
"(p:" << oldParticlei <<
")" 379 newParticles[newParticlei] =
380 sumParticleOp<eulerianParticle>()
382 newParticles[newParticlei],
383 particles_[oldParticlei]
389 particles_.transfer(newParticles);
390 regionToParticleMap_ = newRegionToParticleMap;
394 regions0_ = regionFaceIDs;
411 const scalar deltaT = mesh_.time().deltaTValue();
412 const pointField& faceCentres = mesh_.faceCentres();
414 forAll(regionFaceIDs, localFacei)
416 const label newRegioni = regionFaceIDs[localFacei];
417 if (newRegioni != -1)
419 const label particlei = regionToParticleMap_[newRegioni];
420 const label meshFacei = fz[localFacei];
426 p.faceIHit = localFacei;
433 scalar magPhii =
mag(faceValue(
phi, localFacei, meshFacei));
434 vector Ufi = faceValue(
Uf, localFacei, meshFacei);
435 scalar dV = magPhii*deltaT;
437 p.VC += dV*faceCentres[meshFacei];
455 cloud_(mesh_,
"eulerianParticleCloud"),
461 alphaThreshold_(0.1),
465 nInjectorLocations_(0),
467 globalCoarseFaces_(),
470 regionToParticleMap_(),
471 minDiameter_(ROOTVSMALL),
473 nCollectedParticles_(getProperty<label>(
"nCollectedParticles", 0)),
474 collectedVolume_(getProperty<scalar>(
"collectedVolume", 0)),
475 nDiscardedParticles_(getProperty<label>(
"nDiscardedParticles", 0)),
476 discardedVolume_(getProperty<scalar>(
"discardedVolume", 0))
481 <<
name <<
" function object only applicable to 3-D cases" 500 dict.readEntry(
"faceZone", faceZoneName_);
501 dict.readEntry(
"alpha", alphaName_);
503 dict.readIfPresent(
"alphaThreshold", alphaThreshold_);
504 dict.readIfPresent(
"U", UName_);
505 dict.readIfPresent(
"rho", rhoName_);
506 dict.readIfPresent(
"phi", phiName_);
507 dict.readIfPresent(
"nLocations", nInjectorLocations_);
508 dict.readIfPresent(
"minDiameter", minDiameter_);
509 dict.readIfPresent(
"maxDiameter", maxDiameter_);
513 if (nInjectorLocations_)
541 const faceZone& fz = mesh_.faceZones()[zoneID_];
550 setBlockedFaces(talphaf(), fz, blockedFaces);
557 const label nRegionsNew = regionFaceIDs.
nRegions();
565 mesh_.time().value(),
571 accumulateParticleInfo(talphaf(), tphi(), regionFaceIDs, fz);
573 Log <<
" Collected particles : " << nCollectedParticles_ <<
nl 574 <<
" Collected volume : " << collectedVolume_ <<
nl 575 <<
" Discarded particles : " << nDiscardedParticles_ <<
nl 576 <<
" Discarded volume : " << discardedVolume_ <<
nl 577 <<
" Particles in progress : " << particles_.size() <<
nl 590 setProperty(
"nCollectedParticles", nCollectedParticles_);
591 setProperty(
"collectedVolume", collectedVolume_);
592 setProperty(
"nDiscardedParticles", nDiscardedParticles_);
593 setProperty(
"discardedVolume", discardedVolume_);
void size(const label n)
Older name for setAddressableSize.
virtual void checkFaceZone()
Check that the faceZone is valid.
defineTypeNameAndDebug(ObukhovLength, 0)
virtual void calculateAddressing(const label nRegionsNew, const scalar time, labelList ®ionFaceIDs)
Calculate the addressing between regions between iterations Returns the number of active regions (par...
virtual void collectParticle(const scalar time, const label regioni)
Collect particles that have passed through the faceZone.
errorManipArg< error, int > exit(error &err, const int errNo=1)
dimensioned< typename typeOfMag< Type >::type > mag(const dimensioned< Type > &dt)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
A list of keyword definitions, which are a keyword followed by a number of values (eg...
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Lightweight class to store particle data derived from VOF calculations, with special handling for inp...
label max(const labelHashSet &set, label maxValue=labelMin)
Find the max value in labelHashSet, optionally limited by second argument.
Splits a patch into regions based on a mask field. Result is a globally consistent label list of regi...
labelList regions0_
Region indices in faceZone faces from last iteration.
constexpr char nl
The newline '\n' character (0x0a)
Ostream & endl(Ostream &os)
Add newline and flush stream.
static bool & parRun() noexcept
Test if this a parallel run.
extractEulerianParticles(const word &name, const Time &runTime, const dictionary &dict)
Construct from components.
label zoneID_
Index of the faceZone.
T returnReduce(const T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Perform reduction on a copy, using specified binary operation.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Macros for easy insertion into run-time selection tables.
const word & name() const noexcept
Return the name of this functionObject.
#define forAll(list, i)
Loop across all elements in list.
HashSet< label, Hash< label > > labelHashSet
A HashSet of labels, uses label hasher.
word faceZoneName_
Name of faceZone to sample.
fileName::Type type(const fileName &name, const bool followLink=true)
Return the file type: DIRECTORY or FILE, normally following symbolic links.
A list of faces which address into the list of points.
static word scopedName(const std::string &scope, const word &name)
Create scope:name or scope_name string.
void setSize(const label n)
Alias for resize()
word name(const expressions::valueTypeCode typeCode)
A word representation of a valueTypeCode. Empty for expressions::valueTypeCode::INVALID.
virtual bool read(const dictionary &)
Read the field min/max data.
label findZoneID(const word &zoneName) const
Find zone index by name, return -1 if not found.
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...
virtual void initialiseBins()
Initialise the particle collection bins.
A class for handling words, derived from Foam::string.
Field< scalar > scalarField
Specialisation of Field<T> for scalar.
#define DebugInFunction
Report an information message using Foam::Info.
label size() const noexcept
The number of entries in the list.
dimensionedScalar cbrt(const dimensionedScalar &ds)
virtual const word & type() const =0
Runtime type information.
virtual void accumulateParticleInfo(const surfaceScalarField &alphaf, const surfaceScalarField &phi, const labelList ®ionFaceIDs, const faceZone &fz)
Process latest region information.
constexpr scalar pi(M_PI)
virtual bool write(const token &tok)=0
Write token to stream or otherwise handle it.
autoPtr< surfaceVectorField > Uf
#define DebugInfo
Report an information message using Foam::Info.
static tmp< GeometricField< scalar, fvsPatchField, surfaceMesh > > New(const word &name, IOobjectOption::registerOption regOpt, const Mesh &mesh, const dimensionSet &dims, const word &patchFieldType=fvsPatchField< scalar >::calculatedType())
Return tmp field (NO_READ, NO_WRITE) from name, mesh, dimensions and patch type. [Takes current timeN...
A Vector of values with scalar precision, where scalar is float/double depending on the compilation f...
int debug
Static debugging option.
const faceZoneMesh & faceZones() const noexcept
Return face zone mesh.
virtual bool execute()
Execute.
addToRunTimeSelectionTable(functionObject, ObukhovLength, dictionary)
virtual bool read(const dictionary &dict)
Read.
label nRegions() const noexcept
Return the global number of regions.
static tmp< GeometricField< Type, fvsPatchField, surfaceMesh > > interpolate(const GeometricField< Type, fvPatchField, volMesh > &tvf, const surfaceScalarField &faceFlux, Istream &schemeData)
Interpolate field onto faces using scheme given by Istream.
virtual void setBlockedFaces(const surfaceScalarField &alphaf, const faceZone &fz, boolList &blockedFaces)
Set the blocked faces, i.e. where alpha > alpha threshold value.
label nSolutionD() const
Return the number of valid solved-for dimensions in the mesh.
label nInjectorLocations_
Number of sample locations to generate.
vector point
Point is a vector.
virtual tmp< surfaceScalarField > phiU() const
Return the volumetric flux.
static bool master(const label communicator=worldComm)
True if process corresponds to the master rank in the communicator.
const std::string patch
OpenFOAM patch number as a std::string.
const dimensionSet dimTime(0, 0, 1, 0, 0, 0, 0)
wordList names() const
A list of the zone names.
messageStream Info
Information stream (stdout output on master, null elsewhere)
virtual bool read(const dictionary &dict)
Read optional controls.
A subset of mesh faces organised as a primitive patch.
const dimensionSet dimMass(1, 0, 0, 0, 0, 0, 0)
A class for managing temporary objects.
const dimensionedScalar alpha
Fine-structure constant: default SI units: [].
virtual bool write()
Write.
A List with indirect addressing.
const fvMesh & mesh_
Reference to the fvMesh.
const Boundary & boundaryField() const noexcept
Return const-reference to the boundary field.
prefixOSstream Pout
OSstream wrapped stdout (std::cout) with parallel prefix.
Do not request registration (bool: false)
void reduce(T &value, const BinaryOp &bop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Reduce inplace (cf. MPI Allreduce) using linear/tree communication schedule.
uindirectPrimitivePatch pp(UIndirectList< face >(mesh.faces(), faceLabels), mesh.points())
static void listCombineReduce(List< T > &values, const CombineOp &cop, const int tag=UPstream::msgType(), const label comm=UPstream::worldComm)
Combines List elements. After completion all processors have the same data.