PLB with particles + accumulated bugfixes/backports. Author: Henrik Rusche.

This commit is contained in:
Hrvoje Jasak 2018-09-25 12:30:18 +01:00
commit 32d3595ded
44 changed files with 1019 additions and 74 deletions

View file

@ -155,6 +155,9 @@ fvFieldDecomposer::fvFieldDecomposer
static_cast<processorSurfacePatchFieldDecomposer*>(NULL)
)
{
// HR 25.06.18: Weights may be required for some mappings and might hang in parallel.
completeMesh_.weights();
forAll (boundaryAddressing_, patchi)
{
if (boundaryAddressing_[patchi] >= 0)

View file

@ -1147,7 +1147,7 @@ Foam::processorMeshesReconstructor::reconstructMesh(const Time& db)
!= masterPpAddr[curMF[pointI]]
)
{
WarningIn
FatalErrorIn
(
"autoPtr<fvMesh> "
"processorMeshesReconstructor::"
@ -1213,7 +1213,7 @@ Foam::processorMeshesReconstructor::reconstructMesh(const Time& db)
!= ppAddr[curSpl[splI]]
)
{
WarningIn
FatalErrorIn
(
"autoPtr<fvMesh> "
"processorMeshesReconstructor::"

View file

@ -115,21 +115,32 @@ Foam::processorMeshesReconstructor::readUpdate()
{
stat = procStat;
}
else
else if (stat != procStat)
{
if (stat != procStat)
if (
(
stat == polyMesh::TOPO_CHANGE
&& procStat == polyMesh::TOPO_PATCH_CHANGE
)
|| (
procStat == polyMesh::TOPO_CHANGE
&& stat == polyMesh::TOPO_PATCH_CHANGE
)
)
{
FatalErrorIn("processorMeshesReconstructor::readUpdate()")
<< "Processor " << procI
<< " has a different polyMesh at time "
<< meshes_[procI].time().timeName()
<< " compared to any previous processors." << nl
<< "Please check time "
<< meshes_[procI].time().timeName()
<< " directories on all processors for consistent"
<< " mesh files."
<< exit(FatalError);
continue;
}
FatalErrorIn("processorMeshesReconstructor::readUpdate()")
<< "Processor " << procI
<< " has a different polyMesh at time "
<< meshes_[procI].time().timeName()
<< " compared to any previous processors." << nl
<< "Please check time "
<< meshes_[procI].time().timeName()
<< " directories on all processors for consistent"
<< " mesh files."
<< exit(FatalError);
}
}
}

View file

@ -318,7 +318,7 @@ void Foam::sharedPoints::calcSharedPoints()
forAll (curMarkedPoints, pointI)
{
if (curMarkedPoints[pointI] > 2)
if (curMarkedPoints[pointI] > 1)
{
nShared++;
}
@ -332,7 +332,7 @@ void Foam::sharedPoints::calcSharedPoints()
forAll (curMarkedPoints, pointI)
{
if (curMarkedPoints[pointI] > 2)
if (curMarkedPoints[pointI] > 1)
{
curShared[nShared] = pointI;
nShared++;

View file

@ -30,6 +30,8 @@ License
#include "fvFieldReconstructor.H"
#include "passiveProcessorPolyPatch.H"
#include "addToRunTimeSelectionTable.H"
#include "cloud.H"
#include "cloudDistribute.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -87,7 +89,7 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
// forAll(cellToProc, celli)
// {
// cellDist[celli] = cellToProc[celli];
// cellDist[celli] = cellToProc[celli];
// }
// cellDist.write();
@ -102,8 +104,29 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
Pstream::gatherList(migratedCells);
Pstream::scatterList(migratedCells);
Info<< "Migrated cells per processor: " << migratedCells << endl;
// Reading through second index now tells how many cells will arrive
// from which processor
forAll (migratedCells, i)
{
bool allZero = true;
forAll (migratedCells, j)
{
if (migratedCells[j][i] > 0)
{
allZero = false;
break;
}
}
if (allZero)
{
FatalErrorIn("bool topoChangerFvMesh::loadBalance()")
<< "Reconstructed mesh must have at least one cell "
"on each processor"
<< abort(FatalError);
}
}
// Find out which processor faces will become local internal faces
// by comparing decomposition index from the other side
@ -135,6 +158,14 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
HashTable<const surfaceVectorField*> surfaceVectorFields =
thisDb().lookupClass<surfaceVectorField>();
// Particles
HashTable<const cloud*> clouds = thisDb().lookupClass<cloud>();
forAllConstIter(HashTable<const cloud*>, clouds, iter)
{
cloud& c = const_cast<cloud&>(*iter());
}
//HJ, HERE: remove the fields that should not be load balanced
// Prepare fields for reconstruction
@ -180,6 +211,26 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
receivedSurfaceVectorFields[fieldI].setSize(Pstream::nProcs());
}
PtrList<cloudDistribute> cloudDistributes(clouds.size());
{
label cloudI = 0;
forAllConstIter(HashTable<const cloud*>, clouds, iter)
{
cloud& c = const_cast<cloud&>(*iter());
cloudDistributes.set
(
cloudI++,
c.cloudDist
(
meshDecomp.cellToProc(),
meshDecomp.procCellAddressing(),
meshDecomp.procFaceAddressing()
)
);
}
}
for (label procI = 0; procI < meshDecomp.nProcs(); procI++)
{
// Check if there is a mesh to send
@ -225,6 +276,12 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
sendFields(volVectorFields, fieldDecomposer, toProc);
sendFields(surfaceScalarFields, fieldDecomposer, toProc);
sendFields(surfaceVectorFields, fieldDecomposer, toProc);
// Send clouds
forAll(cloudDistributes, cloudI)
{
cloudDistributes[cloudI].send(toProc, procI);
}
}
else
{
@ -343,6 +400,11 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
procMeshes[procI],
fromProc
);
forAll(cloudDistributes, cloudI)
{
cloudDistributes[cloudI].receive(fromProc, procI);
}
}
}
}
@ -368,6 +430,8 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
Pout<< "Reconstructed mesh stats: "
<< " nCells: " << reconMesh.nCells()
<< " nFaces: " << reconMesh.nFaces()
<< " nIntFaces: " << reconMesh.nInternalFaces()
<< " polyPatches: "
<< reconMesh.boundaryMesh().size()
<< " patches: "
@ -623,7 +687,6 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
oldPatchNMeshPoints // oldPatchNMeshPoints
);
// Reset fvMesh and patches
resetFvPrimitives
(
@ -681,6 +744,15 @@ bool Foam::topoChangerFvMesh::loadBalance(const dictionary& decompDict)
meshMap
);
forAll(cloudDistributes, cloudI)
{
cloudDistributes[cloudI].rebuild
(
meshRecon.cellProcAddressing(),
meshRecon.faceProcAddressing()
);
}
// Debug
checkMesh(true);

View file

@ -33,7 +33,12 @@ scalar CoNum = 0.0;
scalar meanCoNum = 0.0;
scalar velMag = 0.0;
if (mesh.nInternalFaces())
// HR 26.06.28: A parallel run has at least two cells and therefore at least
// one internal face in the global mesh. It may be a processor boundary, but
// this is captured by max(mag(phi)).
// Old formulation hangs on parallel cases where one partition is degenerated
// to a single cell.
if (mesh.nInternalFaces() || Pstream::parRun())
{
surfaceScalarField magPhi = mag(phi);
@ -48,6 +53,20 @@ if (mesh.nInternalFaces())
velMag = max(magPhi/mesh.magSf()).value();
}
else
{
// Single cell mesh: Co is still defined; use cell formulation
const scalar deltaT = runTime.deltaT().value();
const scalar deltaX = Foam::cbrt(mesh.V()[0]);
velMag = mag(U[0]);
CoNum = velMag*deltaT/deltaX;
meanCoNum = CoNum;
}
Info<< "Courant Number mean: " << meanCoNum
<< " max: " << CoNum

View file

@ -712,6 +712,7 @@ list(APPEND SOURCES
${meshTools}/mergePoints.C
fields/UniformDimensionedFields/uniformDimensionedFields.C
fields/cloud/cloud.C
fields/cloudDistribute/cloudDistribute.C
)
set(Fields fields/Fields)

View file

@ -567,6 +567,7 @@ $(meshTools)/mergePoints.C
fields/UniformDimensionedFields/uniformDimensionedFields.C
fields/cloud/cloud.C
fields/cloudDistribute/cloudDistribute.C
Fields = fields/Fields
$(Fields)/labelField/labelField.C

View file

@ -52,10 +52,37 @@ Foam::cloud::cloud(const objectRegistry& obr, const word& cloudName)
{}
Foam::autoPtr<Foam::cloudDistribute> Foam::cloud::cloudDist
(
const labelList& cellToProc,
const labelListList& procCellAddressing,
const labelListList& procFaceAddressing
)
{
NotImplemented;
return autoPtr<cloudDistribute>(NULL);
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cloud::~cloud()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::cloud::size() const
{
NotImplemented;
return 0;
}
void Foam::cloud::autoMap(const mapPolyMesh&)
{
NotImplemented;
}
// ************************************************************************* //

View file

@ -36,6 +36,7 @@ SourceFiles
#define cloud_H
#include "objectRegistry.H"
#include "cloudDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -44,6 +45,7 @@ namespace Foam
// Forward declaration of classes
class mapPolyMesh;
class polyMesh;
/*---------------------------------------------------------------------------*\
Class cloud Declaration
@ -80,6 +82,13 @@ public:
//- Construct for the given objectRegistry and named cloud instance
cloud(const objectRegistry&, const word& cloudName = "");
virtual autoPtr<cloudDistribute> cloudDist
(
const labelList& cellToProc,
const labelListList& procCellAddressing,
const labelListList& procFaceAddressing
);
//- Destructor
virtual ~cloud();
@ -87,11 +96,17 @@ public:
// Member Functions
// Access
//- Return size of the cloud
virtual label size() const;
// Edit
//- Remap the cells of particles corresponding to the
// mesh topology change
virtual void autoMap(const mapPolyMesh&) = 0;
virtual void autoMap(const mapPolyMesh&);
};

View file

@ -0,0 +1,77 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.1
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Description
Lagrangian field decomposer.
\*---------------------------------------------------------------------------*/
#include "cloudDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
cloudDistribute::cloudDistribute()
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
cloudDistribute::~cloudDistribute()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void cloudDistribute::send(Ostream& toProc, const label procIndex)
{
NotImplemented;
}
void cloudDistribute::receive(Istream& fromProc, const label procIndex)
{
NotImplemented;
}
void cloudDistribute::rebuild
(
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& faceProcAddressing
)
{
NotImplemented;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// ************************************************************************* //

View file

@ -0,0 +1,98 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.1
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::cloudDistribute
Description
Lagrangian field decomposer.
SourceFiles
cloudDistribute.C
\*---------------------------------------------------------------------------*/
#ifndef cloudDistribute_H
#define cloudDistribute_H
#include "labelIOList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
/*---------------------------------------------------------------------------*\
Class cloudDistribute Declaration
\*---------------------------------------------------------------------------*/
class cloudDistribute
{
// Private Member Functions
//- Disallow default bitwise copy construct
cloudDistribute(const cloudDistribute&);
//- Disallow default bitwise assignment
void operator=(const cloudDistribute&);
public:
// Constructors
//- Null constructor
cloudDistribute();
//- Destructor
virtual ~cloudDistribute();
// Member Functions
// Send particles
virtual void send(Ostream& toProc, const label procIndex);
// Receive particles
virtual void receive(Istream& fromProc, const label procIndex);
// Receive particles
virtual void rebuild
(
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& faceProcAddressing
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -739,15 +739,24 @@ void Foam::polyMesh::resetPrimitives
// Faces will be reset in initMesh(), using size of owner list
}
// HR 25.06.18: A mesh with a single cell has an empty neighbour list and
// we need to be able reset to such a mesh eg. during load balancing
if (!own().empty())
{
// Mesh has at least one face in owner list. Reset both lists even if
// neighbours are empty (single cell mesh).
owner_.transfer(own());
}
if (!nei().empty())
{
neighbour_.transfer(nei());
}
else
{
if (!nei().empty())
{
// This mesh is invalid, but the operation was valid before.
// Therefore we do what was done before.
neighbour_.transfer(nei());
}
}
// Reset patch sizes and starts

View file

@ -294,7 +294,7 @@ inline Cmpt det(const DiagTensor<Cmpt>& t)
}
//- Return the inverse of a symmetric tensor
//- Return the inverse of a diagonal tensor as a diagonal tensor
template <class Cmpt>
inline DiagTensor<Cmpt> inv(const DiagTensor<Cmpt>& dt)
{
@ -302,6 +302,14 @@ inline DiagTensor<Cmpt> inv(const DiagTensor<Cmpt>& dt)
}
//- Return the diagonal of a symmetric tensor as a diagonal tensor
template <class Cmpt>
inline DiagTensor<Cmpt> diag(const SymmTensor<Cmpt>& t)
{
return DiagTensor<Cmpt>(t.xx(), t.yy(), t.zz());
}
//- Return the diagonal of a tensor as a diagonal tensor
template <class Cmpt>
inline DiagTensor<Cmpt> diag(const Tensor<Cmpt>& t)

View file

@ -0,0 +1,107 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.1
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "CloudDistributeTemplate.H"
#include "CloudTemplate.H"
#include "cloud.H"
#include "polyMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class ParticleType>
Foam::CloudDistribute<ParticleType>::CloudDistribute
(
const labelList& cellToProc,
const labelListList& procCellAddressing,
const labelListList& procFaceAddressing,
cloud& cloud
)
:
cloudDistribute(),
cloud_(reinterpret_cast<Cloud<ParticleType>& >(cloud)),
transferList_(Pstream::nProcs())
{
cloud_.split
(
cellToProc,
procCellAddressing,
procFaceAddressing,
transferList_
);
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class ParticleType>
void Foam::CloudDistribute<ParticleType>::send
(
Ostream& toProc,
const label procIndex
)
{
// Send transfer list prepared in constructor
toProc << transferList_[procIndex] << nl;
// Clear the list for particles to be received
transferList_[procIndex].clear();
}
template<class ParticleType>
void Foam::CloudDistribute<ParticleType>::receive
(
Istream& fromProc,
const label procIndex
)
{
// Receive particles and transfer into transfer list
IDLList<ParticleType> newParticles
(
fromProc,
typename ParticleType::iNew(cloud_)
);
transferList_[procIndex].DLListBase::transfer(newParticles);
}
template<class ParticleType>
void Foam::CloudDistribute<ParticleType>::rebuild
(
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& faceProcAddressing
)
{
cloud_.rebuild
(
transferList_,
cellProcAddressing,
faceProcAddressing
);
}
// ************************************************************************* //

View file

@ -0,0 +1,114 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.1
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation, either version 3 of the License, or (at your
option) any later version.
foam-extend is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with foam-extend. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::Cloud
Description
SourceFiles
CloudDistributeTemplate.C
\*---------------------------------------------------------------------------*/
#ifndef CloudDistributeTemplate_H
#define CloudDistributeTemplate_H
#include "CloudTemplate.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward declaration of functions
template<class ParticleType>
class Cloud;
class polyMesh;
class cloud;
/*---------------------------------------------------------------------------*\
Class Cloud Declaration
\*---------------------------------------------------------------------------*/
template<class ParticleType>
class CloudDistribute
:
public cloudDistribute
{
// Private data
//- Reference to the cloud
Cloud<ParticleType>& cloud_;
//- Transfer buffer for ordering by procID (for sending) and receiving
List<IDLList<ParticleType> > transferList_;
public:
// Constructors
//- Construct from components and fill the transfer list
CloudDistribute
(
const labelList& cellToProc,
const labelListList& procCellAddressing,
const labelListList& procFaceAddressing,
cloud& cloud
);
// Member Functions
//- Send particles in the transfer list
void send(Ostream& toProc, const label procIndex);
//- Receive particles into the transfer list
void receive(Istream& fromProc, const label procIndex);
//- Rebuild the cloud by adding the particles in the transfer list
void rebuild
(
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& faceProcAddressing
);
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "CloudDistributeTemplate.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -339,6 +339,173 @@ void Foam::Cloud<ParticleType>::autoMap(const mapPolyMesh& mapper)
}
template<class ParticleType>
void Foam::Cloud<ParticleType>::split
(
const labelList& cellToProc,
const labelListList& procCellAddressing,
const labelListList& procFaceAddressing,
List<IDLList<ParticleType> >& procParticles
)
{
// Create addressing old cell ID to new cell ID from procCellAddressing
labelList reverseCellMap(cellToProc.size());
forAll(procCellAddressing, procI)
{
const labelList& procCell = procCellAddressing[procI];
forAll(procCell, cellI)
{
reverseCellMap[procCell[cellI]] = cellI;
}
}
labelList reverseFaceMap(polyMesh_.nFaces());
forAll(procFaceAddressing, procI)
{
const labelList& procFace = procFaceAddressing[procI];
forAll(procFace, faceI)
{
reverseFaceMap[mag(procFace[faceI])-1] = faceI;
}
}
if (cloud::debug)
{
Pout << "printing cloud before splitting" << endl;
forAllConstIter(typename Cloud<ParticleType>, *this, pIter)
{
const ParticleType& p = pIter();
Pout << p.celli_ << " "
<< p.facei_ << " "
<< p.position() << " "
<< p.inCell() << endl;
}
}
// Loop over all particles
forAllIter(typename Cloud<ParticleType>, *this, pIter)
{
ParticleType& p = pIter();
const label newProc = cellToProc[p.celli_];
// Map cellID and faceID of the particle to new mesh
p.celli_ = reverseCellMap[p.celli_];
if (p.facei_ >= 0)
{
// HR 29.06.17: face mapping not tested. Did not occur in test cases.
p.facei_ = reverseFaceMap[p.facei_];
}
if (newProc != Pstream::myProcNo())
{
// Add for transfer to new processor and delete from local cloud
procParticles[newProc].append(this->remove(&p));
}
}
}
template<class ParticleType>
void Foam::Cloud<ParticleType>::rebuild
(
List<IDLList<ParticleType> >& receivedClouds,
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& faceProcAddressing
)
{
if (cellProcAddressing.set(Pstream::myProcNo()))
{
const labelList& procCell = cellProcAddressing[Pstream::myProcNo()];
const labelList& procFace = faceProcAddressing[Pstream::myProcNo()];
// Particles in local cloud. Map cellID and faceID in-place
forAllIter
(
typename Cloud<ParticleType>,
*this,
pIter
)
{
ParticleType& p = pIter();
// Map cellID and faceID of the particle to new mesh
p.celli_ = procCell[p.celli_];
if (p.facei_ >= 0)
{
// HR 29.06.17: face mapping not tested. Did not occur in test cases.
p.facei_ = procFace[p.facei_];
}
}
}
forAll(cellProcAddressing, procI)
{
if (!cellProcAddressing.set(procI))
{
continue;
}
const labelList& procCell = cellProcAddressing[procI];
const labelList& procFace = faceProcAddressing[procI];
IDLList<ParticleType>& receivedCloud = receivedClouds[procI];
// Particles received from other processors. To be added to local cloud
forAllIter
(
typename Cloud<ParticleType>,
receivedCloud,
newpIter
)
{
ParticleType& newp = newpIter();
// Map cellID and faceID of the particle to new mesh
newp.celli_ = procCell[newp.celli_];
if (newp.facei_ >= 0)
{
// HR 29.06.17: face mapping not tested. Did not occur in test cases.
newp.facei_ = procFace[newp.facei_];
}
// Add to cloud and remove from transfer list
this->addParticle(receivedCloud.remove(&newp));
}
}
if (cloud::debug)
{
Pout << "printing cloud after rebuild" << endl;
forAllIter
(
typename Cloud<ParticleType>,
*this,
pIter
)
{
const ParticleType& p = pIter();
Pout << p.celli_ << " "
<< p.facei_ << " "
<< p.position() << " "
<< p.inCell() << endl;
}
}
this->updateMesh();
}
template<class ParticleType>
void Foam::Cloud<ParticleType>::writePositions() const
{

View file

@ -39,6 +39,7 @@ SourceFiles
#include "IDLList.H"
#include "IOField.H"
#include "polyMesh.H"
#include "CloudDistributeTemplate.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -150,6 +151,25 @@ public:
const bool checkClass = true
);
autoPtr<cloudDistribute> cloudDist
(
const labelList& cellToProc,
const labelListList& procCellAddressing,
const labelListList& procFaceAddressing
)
{
return autoPtr<cloudDistribute>
(
new CloudDistribute<ParticleType>
(
cellToProc,
procCellAddressing,
procFaceAddressing,
*this
)
);
}
// Member Functions
@ -245,10 +265,31 @@ public:
template<class TrackingData>
void move(TrackingData& td);
//- Update mesh
virtual void updateMesh()
{}
//- Remap the cells of particles corresponding to the
// mesh topology change
virtual void autoMap(const mapPolyMesh&);
//- Split cloud in load balancing
virtual void split
(
const labelList& cellToProc,
const labelListList& procCellAddressing,
const labelListList& procFaceAddressing,
List<IDLList<ParticleType> >& procClouds
);
//- Rebuild cloud in load balancing
virtual void rebuild
(
List<IDLList<ParticleType> >& receivedClouds,
const PtrList<labelIOList>& cellProcAddressing,
const PtrList<labelIOList>& faceProcAddressing
);
// Read

View file

@ -266,6 +266,24 @@ void Foam::KinematicCloud<ParcelType>::evolve()
}
template<class CloudType>
void Foam::KinematicCloud<CloudType>::updateMesh()
{
UTrans_.setSize(this->pMesh().nCells());
injection().updateMesh();
}
template<class CloudType>
void Foam::KinematicCloud<CloudType>::autoMap(const mapPolyMesh& mapper)
{
Cloud<parcelType>::autoMap(mapper);
this->updateMesh();
}
template<class ParcelType>
void Foam::KinematicCloud<ParcelType>::info() const
{

View file

@ -375,6 +375,15 @@ public:
//- Evolve the spray (inject, inject)
void evolve();
// Mapping
//- Update mesh
virtual void updateMesh();
//- Remap the cells of particles corresponding to the
// mesh topology change with a default tracking data object
virtual void autoMap(const mapPolyMesh&);
};

View file

@ -278,6 +278,15 @@ void Foam::ReactingCloud<ParcelType>::evolve()
}
template<class CloudType>
void Foam::ReactingCloud<CloudType>::autoMap(const mapPolyMesh& mapper)
{
Cloud<parcelType>::autoMap(mapper);
this->updateMesh();
}
template<class ParcelType>
void Foam::ReactingCloud<ParcelType>::info() const
{

View file

@ -239,6 +239,12 @@ public:
//- Evolve the spray (inject, move)
void evolve();
// Mapping
//- Remap the cells of particles corresponding to the
// mesh topology change with a default tracking data object
virtual void autoMap(const mapPolyMesh&);
};

View file

@ -234,6 +234,18 @@ void Foam::ReactingMultiphaseCloud<ParcelType>::evolve()
}
template<class ParcelType>
void Foam::ReactingMultiphaseCloud<ParcelType>::autoMap
(
const mapPolyMesh& mapper
)
{
Cloud<parcelType>::autoMap(mapper);
this->updateMesh();
}
template<class ParcelType>
void Foam::ReactingMultiphaseCloud<ParcelType>::info() const
{

View file

@ -202,7 +202,12 @@ public:
//- Evolve the spray (inject, move)
void evolve();
};
// Mapping
//- Remap the cells of particles corresponding to the
// mesh topology change with a default tracking data object
virtual void autoMap(const mapPolyMesh&);};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -225,6 +225,15 @@ void Foam::ThermoCloud<ParcelType>::evolve()
}
template<class ParcelType>
void Foam::ThermoCloud<ParcelType>::autoMap(const mapPolyMesh& mapper)
{
Cloud<parcelType>::autoMap(mapper);
this->updateMesh();
}
template<class ParcelType>
void Foam::ThermoCloud<ParcelType>::info() const
{

View file

@ -227,6 +227,13 @@ public:
//- Evolve the spray (inject, move)
void evolve();
// Mapping
//- Remap the cells of particles corresponding to the
// mesh topology change with a default tracking data object
virtual void autoMap(const mapPolyMesh&);
};

View file

@ -147,8 +147,7 @@ Foam::ConeInjection<CloudType>::ConeInjection
// Set total volume to inject
this->volumeTotal_ = volumeFlowRate_().integrate(0.0, duration_);
// Set/cache the injector cell
this->findCellAtPosition(injectorCell_, position_);
updateMesh();
}
@ -168,6 +167,14 @@ bool Foam::ConeInjection<CloudType>::active() const
}
template<class CloudType>
void Foam::ConeInjection<CloudType>::updateMesh()
{
// Set/cache the injector cell
this->findCellAtPosition(injectorCell_, position_);
}
template<class CloudType>
Foam::scalar Foam::ConeInjection<CloudType>::timeEnd() const
{

View file

@ -152,6 +152,9 @@ public:
//- Flag to indicate whether model activates injection model
bool active() const;
//- Set injector locations when mesh is updated
virtual void updateMesh();
//- Return the end-of-injection time
scalar timeEnd() const;

View file

@ -182,15 +182,7 @@ Foam::ConeInjectionMP<CloudType>::ConeInjectionMP
// Set total volume to inject
this->volumeTotal_ = volumeFlowRate_().integrate(0.0, duration_);
// Set/cache the injector cells
forAll(positions_, i)
{
this->findCellAtPosition
(
injectorCells_[i],
positions_[i]
);
}
this->updateMesh();
}
@ -210,6 +202,17 @@ bool Foam::ConeInjectionMP<CloudType>::active() const
}
template<class CloudType>
void Foam::ConeInjectionMP<CloudType>::updateMesh()
{
// Set/cache the injector cell
forAll(positions_, i)
{
this->findCellAtPosition(injectorCells_[i], positions_[i]);
}
}
template<class CloudType>
Foam::scalar Foam::ConeInjectionMP<CloudType>::timeEnd() const
{

View file

@ -162,6 +162,9 @@ public:
//- Flag to indicate whether model activates injection model
bool active() const;
//- Set injector locations when mesh is updated
virtual void updateMesh();
//- Return the end-of-injection time
scalar timeEnd() const;

View file

@ -131,15 +131,7 @@ Foam::FieldActivatedInjection<CloudType>::FieldActivatedInjection
this->volumeTotal_ =
nParcelsPerInjector_*sum(pow3(diameters_))*mathematicalConstant::pi/6.0;
// Set/cache the injector cells
forAll(positions_, i)
{
this->findCellAtPosition
(
injectorCells_[i],
positions_[i]
);
}
updateMesh();
}
@ -159,6 +151,17 @@ bool Foam::FieldActivatedInjection<CloudType>::active() const
}
template<class CloudType>
void Foam::FieldActivatedInjection<CloudType>::updateMesh()
{
// Set/cache the injector cell
forAll(positions_, i)
{
this->findCellAtPosition(injectorCells_[i], positions_[i]);
}
}
template<class CloudType>
Foam::scalar Foam::FieldActivatedInjection<CloudType>::timeEnd() const
{

View file

@ -152,6 +152,9 @@ public:
//- Flag to indicate whether model activates injection model
bool active() const;
//- Set injector locations when mesh is updated
virtual void updateMesh();
//- Return the end-of-injection time
scalar timeEnd() const;

View file

@ -347,6 +347,12 @@ Foam::InjectionModel<CloudType>::~InjectionModel()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class CloudType>
void Foam::InjectionModel<CloudType>::updateMesh()
{
// do nothing
}
template<class CloudType>
template<class TrackData>
void Foam::InjectionModel<CloudType>::inject(TrackData& td)
@ -360,6 +366,11 @@ void Foam::InjectionModel<CloudType>::inject(TrackData& td)
const scalar carrierDt = owner_.db().time().deltaTValue();
const polyMesh& mesh = owner_.mesh();
// BUGFIX HR 23.06.18: Force recalculation of global data because
// constrainToMeshCentre is inside of an if-statement
mesh.geometricD();
mesh.bounds();
// Prepare for next time step
label parcelsAdded = 0;
scalar massAdded = 0.0;

View file

@ -260,6 +260,12 @@ public:
virtual bool active() const = 0;
// Mapping
//- Update mesh
virtual void updateMesh();
// Global information
//- Return the start-of-injection time

View file

@ -97,10 +97,8 @@ Foam::KinematicLookupTableInjection<CloudType>::KinematicLookupTableInjection
{
// Set/cache the injector cells
injectorCells_.setSize(injectors_.size());
forAll(injectors_, i)
{
this->findCellAtPosition(injectorCells_[i], injectors_[i].x());
}
this->updateMesh();
// Determine volume of particles to inject
this->volumeTotal_ = 0.0;
@ -128,6 +126,17 @@ bool Foam::KinematicLookupTableInjection<CloudType>::active() const
}
template<class CloudType>
void Foam::KinematicLookupTableInjection<CloudType>::updateMesh()
{
// Set/cache the injector cell
forAll(injectors_, i)
{
this->findCellAtPosition(injectorCells_[i], injectors_[i].x());
}
}
template<class CloudType>
Foam::scalar Foam::KinematicLookupTableInjection<CloudType>::timeEnd() const
{

View file

@ -129,6 +129,9 @@ public:
//- Flag to indicate whether model activates injection model
bool active() const;
//- Set injector locations when mesh is updated
virtual void updateMesh();
//- Return the end-of-injection time
scalar timeEnd() const;

View file

@ -117,18 +117,7 @@ Foam::PatchInjection<CloudType>::PatchInjection
<< nl << exit(FatalError);
}
const polyPatch& patch = owner.mesh().boundaryMesh()[patchId];
cellOwners_ = patch.faceCells();
label patchSize = cellOwners_.size();
label totalPatchSize = patchSize;
reduce(totalPatchSize, sumOp<label>());
fraction_ = scalar(patchSize)/totalPatchSize;
// Set total volume/mass to inject
this->volumeTotal_ = fraction_*volumeFlowRate_().integrate(0.0, duration_);
this->massTotal_ *= fraction_;
updateMesh();
}
@ -148,6 +137,27 @@ bool Foam::PatchInjection<CloudType>::active() const
}
template<class CloudType>
void Foam::PatchInjection<CloudType>::updateMesh()
{
label patchId =
this->owner().mesh().boundaryMesh().findPatchID(patchName_);
const polyPatch& patch = this->owner().mesh().boundaryMesh()[patchId];
cellOwners_ = patch.faceCells();
label patchSize = cellOwners_.size();
label totalPatchSize = patchSize;
reduce(totalPatchSize, sumOp<label>());
fraction_ = scalar(patchSize)/totalPatchSize;
// Set total volume/mass to inject
this->volumeTotal_ = fraction_*volumeFlowRate_().integrate(0.0, duration_);
this->massTotal_ *= fraction_;
}
template<class CloudType>
Foam::scalar Foam::PatchInjection<CloudType>::timeEnd() const
{

View file

@ -136,6 +136,9 @@ public:
//- Flag to indicate whether model activates injection model
bool active() const;
//- Set injector locations when mesh is updated
virtual void updateMesh();
//- Return the end-of-injection time
scalar timeEnd() const;

View file

@ -96,10 +96,8 @@ Foam::ReactingLookupTableInjection<CloudType>::ReactingLookupTableInjection
{
// Set/cache the injector cells
injectorCells_.setSize(injectors_.size());
forAll(injectors_, i)
{
this->findCellAtPosition(injectorCells_[i], injectors_[i].x());
}
this->updateMesh();
// Determine volume of particles to inject
this->volumeTotal_ = 0.0;
@ -127,6 +125,17 @@ bool Foam::ReactingLookupTableInjection<CloudType>::active() const
}
template<class CloudType>
void Foam::ReactingLookupTableInjection<CloudType>::updateMesh()
{
// Set/cache the injector cell
forAll(injectors_, i)
{
this->findCellAtPosition(injectorCells_[i], injectors_[i].x());
}
}
template<class CloudType>
Foam::scalar Foam::ReactingLookupTableInjection<CloudType>::timeEnd() const
{

View file

@ -132,6 +132,9 @@ public:
//- Flag to indicate whether model activates injection model
bool active() const;
//- Set injector locations when mesh is updated
virtual void updateMesh();
//- Return the end-of-injection time
scalar timeEnd() const;

View file

@ -99,10 +99,8 @@ ReactingMultiphaseLookupTableInjection
{
// Set/cache the injector cells
injectorCells_.setSize(injectors_.size());
forAll(injectors_, i)
{
this->findCellAtPosition(injectorCells_[i], injectors_[i].x());
}
this->updateMesh();
// Determine volume of particles to inject
this->volumeTotal_ = 0.0;
@ -131,6 +129,17 @@ bool Foam::ReactingMultiphaseLookupTableInjection<CloudType>::active() const
}
template<class CloudType>
void Foam::ReactingMultiphaseLookupTableInjection<CloudType>::updateMesh()
{
// Set/cache the injector cell
forAll(injectors_, i)
{
this->findCellAtPosition(injectorCells_[i], injectors_[i].x());
}
}
template<class CloudType>
Foam::scalar
Foam::ReactingMultiphaseLookupTableInjection<CloudType>::timeEnd() const

View file

@ -135,6 +135,9 @@ public:
//- Flag to indicate whether model activates injection model
bool active() const;
//- Set injector locations when mesh is updated
virtual void updateMesh();
//- Return the end-of-injection time
scalar timeEnd() const;

View file

@ -97,10 +97,8 @@ Foam::ThermoLookupTableInjection<CloudType>::ThermoLookupTableInjection
{
// Set/cache the injector cells
injectorCells_.setSize(injectors_.size());
forAll(injectors_, i)
{
this->findCellAtPosition(injectorCells_[injectorI], injectors_[i].x());
}
updateMesh();
// Determine volume of particles to inject
this->volumeTotal_ = 0.0;
@ -128,6 +126,17 @@ bool Foam::ThermoLookupTableInjection<CloudType>::active() const
}
template<class CloudType>
void Foam::ThermoLookupTableInjection<CloudType>::updateMesh()
{
// Set/cache the injector cells
forAll(injectors_, i)
{
this->findCellAtPosition(injectorCells_[injectorI], injectors_[i].x());
}
}
template<class CloudType>
Foam::scalar Foam::ThermoLookupTableInjection<CloudType>::timeEnd() const
{

View file

@ -131,6 +131,9 @@ public:
//- Flag to indicate whether model activates injection model
bool active() const;
//- Set injector locations when mesh is updated
virtual void updateMesh();
//- Return the end-of-injection time
scalar timeEnd() const;