PLB with clouds

This commit is contained in:
Henrik Rusche 2018-07-03 22:26:12 +02:00
parent 6cdc361218
commit 8d356e7456
22 changed files with 843 additions and 24 deletions

View file

@ -155,6 +155,9 @@ fvFieldDecomposer::fvFieldDecomposer
static_cast<processorSurfacePatchFieldDecomposer*>(NULL) 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) forAll (boundaryAddressing_, patchi)
{ {
if (boundaryAddressing_[patchi] >= 0) if (boundaryAddressing_[patchi] >= 0)

View file

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

View file

@ -115,10 +115,22 @@ Foam::processorMeshesReconstructor::readUpdate()
{ {
stat = procStat; 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
)
)
{ {
continue;
}
FatalErrorIn("processorMeshesReconstructor::readUpdate()") FatalErrorIn("processorMeshesReconstructor::readUpdate()")
<< "Processor " << procI << "Processor " << procI
<< " has a different polyMesh at time " << " has a different polyMesh at time "
@ -132,7 +144,6 @@ Foam::processorMeshesReconstructor::readUpdate()
} }
} }
} }
}
if if
( (

View file

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

View file

@ -33,7 +33,12 @@ scalar CoNum = 0.0;
scalar meanCoNum = 0.0; scalar meanCoNum = 0.0;
scalar velMag = 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); surfaceScalarField magPhi = mag(phi);
@ -48,6 +53,20 @@ if (mesh.nInternalFaces())
velMag = max(magPhi/mesh.magSf()).value(); 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 Info<< "Courant Number mean: " << meanCoNum
<< " max: " << CoNum << " max: " << CoNum

View file

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

View file

@ -567,6 +567,7 @@ $(meshTools)/mergePoints.C
fields/UniformDimensionedFields/uniformDimensionedFields.C fields/UniformDimensionedFields/uniformDimensionedFields.C
fields/cloud/cloud.C fields/cloud/cloud.C
fields/cloudDistribute/cloudDistribute.C
Fields = fields/Fields Fields = fields/Fields
$(Fields)/labelField/labelField.C $(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 * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::cloud::~cloud() 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 #define cloud_H
#include "objectRegistry.H" #include "objectRegistry.H"
#include "cloudDistribute.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -44,6 +45,7 @@ namespace Foam
// Forward declaration of classes // Forward declaration of classes
class mapPolyMesh; class mapPolyMesh;
class polyMesh;
/*---------------------------------------------------------------------------*\ /*---------------------------------------------------------------------------*\
Class cloud Declaration Class cloud Declaration
@ -80,6 +82,13 @@ public:
//- Construct for the given objectRegistry and named cloud instance //- Construct for the given objectRegistry and named cloud instance
cloud(const objectRegistry&, const word& cloudName = ""); cloud(const objectRegistry&, const word& cloudName = "");
virtual autoPtr<cloudDistribute> cloudDist
(
const labelList& cellToProc,
const labelListList& procCellAddressing,
const labelListList& procFaceAddressing
);
//- Destructor //- Destructor
virtual ~cloud(); virtual ~cloud();
@ -87,11 +96,17 @@ public:
// Member Functions // Member Functions
// Access
//- Return size of the cloud
virtual label size() const;
// Edit // Edit
//- Remap the cells of particles corresponding to the //- Remap the cells of particles corresponding to the
// mesh topology change // 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 // 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()) 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()); owner_.transfer(own());
neighbour_.transfer(nei());
} }
else
{
if (!nei().empty()) if (!nei().empty())
{ {
// This mesh is invalid, but the operation was valid before.
// Therefore we do what was done before.
neighbour_.transfer(nei()); neighbour_.transfer(nei());
} }
}
// Reset patch sizes and starts // Reset patch sizes and starts

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,172 @@ 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
)
{
{
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> template<class ParticleType>
void Foam::Cloud<ParticleType>::writePositions() const void Foam::Cloud<ParticleType>::writePositions() const
{ {

View file

@ -39,6 +39,7 @@ SourceFiles
#include "IDLList.H" #include "IDLList.H"
#include "IOField.H" #include "IOField.H"
#include "polyMesh.H" #include "polyMesh.H"
#include "CloudDistributeTemplate.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -150,6 +151,25 @@ public:
const bool checkClass = true 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 // Member Functions
@ -245,10 +265,31 @@ public:
template<class TrackingData> template<class TrackingData>
void move(TrackingData& td); void move(TrackingData& td);
//- Update mesh
virtual void updateMesh()
{}
//- Remap the cells of particles corresponding to the //- Remap the cells of particles corresponding to the
// mesh topology change // mesh topology change
virtual void autoMap(const mapPolyMesh&); 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 // Read

View file

@ -266,6 +266,28 @@ 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)
{
//typedef typename particle::TrackingData<KinematicCloud<CloudType>> tdType;
//tdType td(*this);
//Cloud<parcelType>::template autoMap<tdType>(td, mapper);
updateMesh();
}
template<class ParcelType> template<class ParcelType>
void Foam::KinematicCloud<ParcelType>::info() const void Foam::KinematicCloud<ParcelType>::info() const
{ {

View file

@ -375,6 +375,15 @@ public:
//- Evolve the spray (inject, inject) //- Evolve the spray (inject, inject)
void evolve(); 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

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

View file

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

View file

@ -347,6 +347,12 @@ Foam::InjectionModel<CloudType>::~InjectionModel()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class CloudType>
void Foam::InjectionModel<CloudType>::updateMesh()
{
// do nothing
}
template<class CloudType> template<class CloudType>
template<class TrackData> template<class TrackData>
void Foam::InjectionModel<CloudType>::inject(TrackData& td) 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 scalar carrierDt = owner_.db().time().deltaTValue();
const polyMesh& mesh = owner_.mesh(); 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 // Prepare for next time step
label parcelsAdded = 0; label parcelsAdded = 0;
scalar massAdded = 0.0; scalar massAdded = 0.0;

View file

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