ENH: extractEulerianParticles function object parallel and usability updates

This commit is contained in:
Andrew Heather
2016-12-14 15:28:55 +00:00
parent 76023b38ad
commit 730231446a
5 changed files with 31 additions and 61 deletions

View File

@ -32,7 +32,7 @@ using namespace Foam::constant;
Foam::functionObjects::eulerianParticle::eulerianParticle() Foam::functionObjects::eulerianParticle::eulerianParticle()
: :
globalFaceIHit(-1), faceIHit(-1),
VC(vector::zero), VC(vector::zero),
VU(vector::zero), VU(vector::zero),
V(0), V(0),
@ -48,7 +48,7 @@ Foam::Ostream& Foam::operator<<
const functionObjects::eulerianParticle& p const functionObjects::eulerianParticle& p
) )
{ {
os << p.globalFaceIHit << token::SPACE os << p.faceIHit << token::SPACE
<< p.VC << token::SPACE << p.VC << token::SPACE
<< p.VU << token::SPACE << p.VU << token::SPACE
<< p.V << token::SPACE << p.V << token::SPACE
@ -64,7 +64,7 @@ Foam::Istream& Foam::operator>>
functionObjects::eulerianParticle& p functionObjects::eulerianParticle& p
) )
{ {
is >> p.globalFaceIHit is >> p.faceIHit
>> p.VC >> p.VC
>> p.VU >> p.VU
>> p.V >> p.V
@ -81,7 +81,7 @@ void Foam::functionObjects::eulerianParticle::write(Ostream& os) const
vector C = VC/(V + ROOTVSMALL); vector C = VC/(V + ROOTVSMALL);
os << time << token::SPACE os << time << token::SPACE
<< globalFaceIHit << token::SPACE << faceIHit << token::SPACE
<< C << token::SPACE << C << token::SPACE
<< pDiameter << token::SPACE << pDiameter << token::SPACE
<< U << token::SPACE << U << token::SPACE
@ -97,7 +97,7 @@ Foam::dictionary Foam::functionObjects::eulerianParticle::writeDict() const
dictionary dict; dictionary dict;
dict.add("time", time); dict.add("time", time);
dict.add("meshFace", globalFaceIHit); dict.add("meshFace", faceIHit);
dict.add("position", C); dict.add("position", C);
dict.add("diameter", pDiameter); dict.add("diameter", pDiameter);
dict.add("U", U); dict.add("U", U);

View File

@ -78,7 +78,7 @@ public:
// identify the index of the coarse face of the surface agglomeration // identify the index of the coarse face of the surface agglomeration
// Note: value of -1 used to indicate that the particle has not // Note: value of -1 used to indicate that the particle has not
// been initialised // been initialised
label globalFaceIHit; label faceIHit;
//- Volume multiplied by face centres [m4] //- Volume multiplied by face centres [m4]
vector VC; vector VC;
@ -115,7 +115,7 @@ public:
) )
{ {
return return
a.globalFaceIHit == b.globalFaceIHit a.faceIHit == b.faceIHit
&& a.VC == b.VC && a.VC == b.VC
&& a.VU == b.VU && a.VU == b.VU
&& a.V == b.V && a.V == b.V

View File

@ -40,15 +40,15 @@ class sumParticleOp
const eulerianParticle& p1 const eulerianParticle& p1
) const ) const
{ {
if ((p0.globalFaceIHit != -1) && (p1.globalFaceIHit == -1)) if ((p0.faceIHit != -1) && (p1.faceIHit == -1))
{ {
return p0; return p0;
} }
else if ((p0.globalFaceIHit == -1) && (p1.globalFaceIHit != -1)) else if ((p0.faceIHit == -1) && (p1.faceIHit != -1))
{ {
return p1; return p1;
} }
else if ((p0.globalFaceIHit != -1) && (p1.globalFaceIHit != -1)) else if ((p0.faceIHit != -1) && (p1.faceIHit != -1))
{ {
// Choose particle with the largest collected volume and // Choose particle with the largest collected volume and
// accumulate total volume // accumulate total volume

View File

@ -57,7 +57,7 @@ namespace functionObjects
Foam::fileName Foam::fileName
Foam::functionObjects::extractEulerianParticles::dictBaseFileDir() const Foam::functionObjects::extractEulerianParticles::dictBaseFileDir() const
{ {
fileName baseDir(".."); // = obr_.time().path(); fileName baseDir(".."); // = mesh_.time().path();
if (Pstream::parRun()) if (Pstream::parRun())
{ {
@ -83,7 +83,7 @@ void Foam::functionObjects::extractEulerianParticles::checkFaceZone()
{ {
FatalErrorInFunction FatalErrorInFunction
<< "Unable to find faceZone " << faceZoneName_ << "Unable to find faceZone " << faceZoneName_
<< ". Available faceZones are: " << ". Available faceZones are: " << mesh_.faceZones().names()
<< exit(FatalError); << exit(FatalError);
} }
@ -109,9 +109,6 @@ void Foam::functionObjects::extractEulerianParticles::checkFaceZone()
// Initialise old iteration blocked faces // Initialise old iteration blocked faces
// Note: for restart, this info needs to be written/read // Note: for restart, this info needs to be written/read
regions0_.setSize(fz.size(), -1); regions0_.setSize(fz.size(), -1);
// Create global addressing for faceZone
globalFaces_ = globalIndex(fz.size());
} }
@ -169,26 +166,8 @@ void Foam::functionObjects::extractEulerianParticles::initialiseBins()
{ {
fineToCoarseAddr_ = ppa.restrictTopBottomAddressing(); fineToCoarseAddr_ = ppa.restrictTopBottomAddressing();
nCoarseFaces = max(fineToCoarseAddr_) + 1; nCoarseFaces = max(fineToCoarseAddr_) + 1;
// Set coarse face centres as area average of fine face centres
const vectorField& faceCentres = mesh_.faceCentres();
const vectorField& faceAreas = mesh_.faceAreas();
coarsePosition_.setSize(nCoarseFaces);
coarsePosition_ = vector::zero;
scalarField coarseArea(nCoarseFaces, 0);
forAll(fz, i)
{
const label facei = fz[i];
const label coarseFacei = fineToCoarseAddr_[i];
const scalar magSf = mag(faceAreas[facei]);
coarseArea[coarseFacei] += magSf;
coarsePosition_[coarseFacei] += magSf*faceCentres[facei];
} }
coarsePosition_ /= coarseArea + ROOTVSMALL;
}
// Create global addressing for coarse face addressing
globalCoarseFaces_ = globalIndex(nCoarseFaces); globalCoarseFaces_ = globalIndex(nCoarseFaces);
Info<< "Created " << returnReduce(nCoarseFaces, sumOp<label>()) Info<< "Created " << returnReduce(nCoarseFaces, sumOp<label>())
@ -302,20 +281,15 @@ void Foam::functionObjects::extractEulerianParticles::collectParticles
} }
Map<label>::const_iterator iter = regionToParticleMap_.find(regioni); Map<label>::const_iterator iter = regionToParticleMap_.find(regioni);
eulerianParticle p = particles_[iter()];
eulerianParticle p; if (p.faceIHit != -1 && nInjectorLocations_)
if (iter != Map<label>::end())
{ {
// Particle on local processor // Use coarse face index for tag output
p = particles_[iter()]; label coarseFacei = fineToCoarseAddr_[p.faceIHit];
p.faceIHit = globalCoarseFaces_.toGlobal(coarseFacei);
}
if (nInjectorLocations_)
{
// Use coarse face index and position for output
p.globalFaceIHit = fineToCoarseAddr_[p.globalFaceIHit];
p.VC = p.V*coarsePosition_[p.globalFaceIHit];
}
}
reduce(p, sumParticleOp<eulerianParticle>()); reduce(p, sumParticleOp<eulerianParticle>());
const scalar pDiameter = cbrt(6.0*p.V/constant::mathematical::pi); const scalar pDiameter = cbrt(6.0*p.V/constant::mathematical::pi);
@ -330,8 +304,9 @@ void Foam::functionObjects::extractEulerianParticles::collectParticles
label tag = -1; label tag = -1;
if (nInjectorLocations_) if (nInjectorLocations_)
{ {
tag = p.globalFaceIHit; tag = p.faceIHit;
} }
injectedParticle* ip = new injectedParticle injectedParticle* ip = new injectedParticle
( (
mesh_, mesh_,
@ -525,10 +500,10 @@ void Foam::functionObjects::extractEulerianParticles::accumulateParticleInfo
const label meshFacei = fz[localFacei]; const label meshFacei = fz[localFacei];
eulerianParticle& p = particles_[particlei]; eulerianParticle& p = particles_[particlei];
if (p.globalFaceIHit < 0) if (p.faceIHit < 0)
{ {
// New particle - does not exist in particles_ list // New particle - does not exist in particles_ list
p.globalFaceIHit = globalFaces_.toGlobal(localFacei); p.faceIHit = localFacei;
p.V = 0; p.V = 0;
p.VC = vector::zero; p.VC = vector::zero;
p.VU = vector::zero; p.VU = vector::zero;
@ -569,7 +544,6 @@ Foam::functionObjects::extractEulerianParticles::extractEulerianParticles
phiName_("phi"), phiName_("phi"),
nInjectorLocations_(0), nInjectorLocations_(0),
fineToCoarseAddr_(), fineToCoarseAddr_(),
coarsePosition_(),
globalCoarseFaces_(), globalCoarseFaces_(),
regions0_(), regions0_(),
nRegions0_(0), nRegions0_(0),
@ -610,13 +584,13 @@ bool Foam::functionObjects::extractEulerianParticles::read
if (fvMeshFunctionObject::read(dict) && writeFile::read(dict)) if (fvMeshFunctionObject::read(dict) && writeFile::read(dict))
{ {
dict.lookup("faceZone") >> faceZoneName_; dict.lookup("faceZone") >> faceZoneName_;
dict.readIfPresent("nLocations", nInjectorLocations_);
dict.lookup("alpha") >> alphaName_; dict.lookup("alpha") >> alphaName_;
dict.readIfPresent("alphaThreshold", alphaThreshold_);
dict.lookup("U") >> UName_;
dict.lookup("rho") >> rhoName_;
dict.lookup("phi") >> phiName_;
dict.readIfPresent("alphaThreshold", alphaThreshold_);
dict.readIfPresent("U", UName_);
dict.readIfPresent("rho", rhoName_);
dict.readIfPresent("phi", phiName_);
dict.readIfPresent("nLocations", nInjectorLocations_);
dict.readIfPresent("minDiameter", minDiameter_); dict.readIfPresent("minDiameter", minDiameter_);
dict.readIfPresent("maxDiameter", maxDiameter_); dict.readIfPresent("maxDiameter", maxDiameter_);
@ -641,7 +615,7 @@ bool Foam::functionObjects::extractEulerianParticles::execute()
Log << type() << " " << name() << " output:" << nl; Log << type() << " " << name() << " output:" << nl;
const volScalarField& alpha = const volScalarField& alpha =
obr_.lookupObject<volScalarField>(alphaName_); mesh_.lookupObject<volScalarField>(alphaName_);
const surfaceScalarField alphaf const surfaceScalarField alphaf
( (
@ -663,6 +637,8 @@ bool Foam::functionObjects::extractEulerianParticles::execute()
// Split the faceZone according to the blockedFaces // Split the faceZone according to the blockedFaces
// - Returns a list of (disconnected) region index per face zone face // - Returns a list of (disconnected) region index per face zone face
regionSplit2D regionFaceIDs(mesh_, patch, blockedFaces); regionSplit2D regionFaceIDs(mesh_, patch, blockedFaces);
// Global number of regions
const label nRegionsNew = regionFaceIDs.nRegions(); const label nRegionsNew = regionFaceIDs.nRegions();
// Calculate the addressing between the old and new region information // Calculate the addressing between the old and new region information

View File

@ -113,9 +113,6 @@ protected:
//- Patch face indices where faceZone face intersect patch //- Patch face indices where faceZone face intersect patch
labelList patchFaceIDs_; labelList patchFaceIDs_;
//- Global face addressing
globalIndex globalFaces_;
// Field names // Field names
@ -140,12 +137,9 @@ protected:
//- Number of sample locations to generate //- Number of sample locations to generate
label nInjectorLocations_; label nInjectorLocations_;
//- Agglomeration addressing from fine to coarse //- Agglomeration addressing from fine to coarse (local proc only)
labelList fineToCoarseAddr_; labelList fineToCoarseAddr_;
//- Coarse face positions
vectorField coarsePosition_;
//- Global coarse face addressing //- Global coarse face addressing
globalIndex globalCoarseFaces_; globalIndex globalCoarseFaces_;