From 2047a69115fd72044c24b36d0ddcf6f3dcb1743c Mon Sep 17 00:00:00 2001 From: mattijs Date: Wed, 12 Jan 2022 11:36:05 +0000 Subject: [PATCH] BUG: reconstructPar: delay locating positions. Fixes #2205. --- src/lagrangian/basic/particle/particle.H | 18 +- src/lagrangian/basic/particle/particleIO.C | 45 +++-- .../reconstruct/reconstruct/Make/files | 1 + .../reconstruct/lagrangianReconstructor.C | 76 ++++++-- .../reconstruct/passivePositionParticle.H | 182 ++++++++++++++++++ .../passivePositionParticleCloud.C | 66 +++++++ .../passivePositionParticleCloud.H | 96 +++++++++ 7 files changed, 449 insertions(+), 35 deletions(-) create mode 100644 src/parallel/reconstruct/reconstruct/passivePositionParticle.H create mode 100644 src/parallel/reconstruct/reconstruct/passivePositionParticleCloud.C create mode 100644 src/parallel/reconstruct/reconstruct/passivePositionParticleCloud.H diff --git a/src/lagrangian/basic/particle/particle.H b/src/lagrangian/basic/particle/particle.H index f48c0c405a..ae2edec37b 100644 --- a/src/lagrangian/basic/particle/particle.H +++ b/src/lagrangian/basic/particle/particle.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017, 2020 OpenFOAM Foundation - Copyright (C) 2017-2020 OpenCFD Ltd. + Copyright (C) 2017-2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -295,6 +295,17 @@ protected: // Patch interactions + //- Read particle from stream. Optionally (for old format) return + // read position. Used by construct-from-Istream + void readData + ( + Istream& is, + point& position, + const bool readFields, + const bool newFormat, + const bool doLocate + ); + //- Overridable function to handle the particle hitting a patch. // Executed before other patch-hitting functions. template @@ -399,8 +410,9 @@ public: ( const polyMesh& mesh, Istream&, - bool readFields = true, - bool newFormat = true + const bool readFields = true, + const bool newFormat = true, + const bool doLocate = true ); //- Construct as a copy diff --git a/src/lagrangian/basic/particle/particleIO.C b/src/lagrangian/basic/particle/particleIO.C index bf8e9ac30a..afaaa8c78f 100644 --- a/src/lagrangian/basic/particle/particleIO.C +++ b/src/lagrangian/basic/particle/particleIO.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2016-2019 OpenCFD Ltd. + Copyright (C) 2016-2019,2022 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -50,8 +50,9 @@ Foam::particle::particle ( const polyMesh& mesh, Istream& is, - bool readFields, - bool newFormat + const bool readFields, + const bool newFormat, + const bool doLocate ) : mesh_(mesh), @@ -63,6 +64,22 @@ Foam::particle::particle stepFraction_(0.0), origProc_(Pstream::myProcNo()), origId_(-1) +{ + point position; + readData(is, position, readFields, newFormat, doLocate); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +void Foam::particle::readData +( + Istream& is, + point& position, + const bool readFields, + const bool newFormat, + const bool doLocate +) { if (newFormat) { @@ -178,14 +195,20 @@ Foam::particle::particle origId_ = p.origId; } - locate - ( - p.position, - nullptr, - p.celli, - false, - "Particle initialised with a location outside of the mesh." - ); + // Preserve read position + position = p.position; + + if (doLocate) + { + locate + ( + p.position, + nullptr, + p.celli, + false, + "Particle initialised with a location outside of the mesh." + ); + } } // Check state of Istream diff --git a/src/parallel/reconstruct/reconstruct/Make/files b/src/parallel/reconstruct/reconstruct/Make/files index 784519c5c6..2dbe299bfd 100644 --- a/src/parallel/reconstruct/reconstruct/Make/files +++ b/src/parallel/reconstruct/reconstruct/Make/files @@ -1,6 +1,7 @@ processorMeshes.C fvFieldReconstructor.C pointFieldReconstructor.C +passivePositionParticleCloud.C lagrangianReconstructor.C LIB = $(FOAM_LIBBIN)/libreconstruct diff --git a/src/parallel/reconstruct/reconstruct/lagrangianReconstructor.C b/src/parallel/reconstruct/reconstruct/lagrangianReconstructor.C index f7a578f4cb..285d9364cf 100644 --- a/src/parallel/reconstruct/reconstruct/lagrangianReconstructor.C +++ b/src/parallel/reconstruct/reconstruct/lagrangianReconstructor.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2018 OpenCFD Ltd. + Copyright (C) 2018,2021 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -27,8 +27,7 @@ License \*---------------------------------------------------------------------------*/ #include "lagrangianReconstructor.H" -#include "labelIOList.H" -#include "passiveParticleCloud.H" +#include "passivePositionParticleCloud.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // @@ -54,11 +53,11 @@ Foam::label Foam::lagrangianReconstructor::reconstructPositions const word& cloudName ) const { - passiveParticleCloud lagrangianPositions + passivePositionParticleCloud lagrangianPositions ( mesh_, cloudName, - IDLList() + IDLList() ); forAll(procMeshes_, meshi) @@ -66,38 +65,73 @@ Foam::label Foam::lagrangianReconstructor::reconstructPositions const labelList& cellMap = cellProcAddressing_[meshi]; const labelList& faceMap = faceProcAddressing_[meshi]; - Cloud lpi(procMeshes_[meshi], cloudName, false); + // Use a special particle that does not try to find the particle on + // the mesh. This is to be able to handle particles originating + // from a different processor. This can happen with some + // functionObjects - e.g. extractEulerianParticles. + // These particles should be + // - written in the old format + passivePositionParticleCloud lpi(procMeshes_[meshi], cloudName, false); forAllConstIters(lpi, iter) { - const passiveParticle& ppi = *iter; + const passivePositionParticle& ppi = *iter; - const label mappedCell = cellMap[ppi.cell()]; + const label mappedCell = + ( + (ppi.cell() >= 0) + ? cellMap[ppi.cell()] + : -1 + ); // Inverting sign if necessary and subtracting 1 from // faceProcAddressing - const label mappedTetFace = mag(faceMap[ppi.tetFace()]) - 1; - - lagrangianPositions.append + const label mappedTetFace = ( - new passiveParticle - ( - mesh_, - ppi.coordinates(), - mappedCell, - mappedTetFace, - ppi.procTetPt(mesh_, mappedCell, mappedTetFace) - ) + (ppi.tetFace() >= 0) + ? mag(faceMap[ppi.tetFace()]) - 1 + : -1 ); + + if ((ppi.cell() >= 0) && (ppi.tetFace() >= 0)) + { + // cell,face succesfully mapped. Coordinates inside the cell + // should be same + lagrangianPositions.append + ( + new passivePositionParticle + ( + mesh_, + ppi.coordinates(), + mappedCell, + mappedTetFace, + ppi.procTetPt(mesh_, mappedCell, mappedTetFace) + ) + ); + } + else + { + // No valid coordinates. Use built-in locating from cell -1 + lagrangianPositions.append + ( + new passivePositionParticle + ( + mesh_, + ppi.location(), + mappedCell + ) + ); + } } } - IOPosition>(lagrangianPositions).write(); + + IOPosition(lagrangianPositions).write(); // Force writing of "positions" too, if specified via the InfoSwitch if (particle::writeLagrangianPositions) { - IOPosition> + IOPosition ( lagrangianPositions, cloud::geometryType::POSITIONS diff --git a/src/parallel/reconstruct/reconstruct/passivePositionParticle.H b/src/parallel/reconstruct/reconstruct/passivePositionParticle.H new file mode 100644 index 0000000000..8612c632a2 --- /dev/null +++ b/src/parallel/reconstruct/reconstruct/passivePositionParticle.H @@ -0,0 +1,182 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM 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. + + OpenFOAM 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 OpenFOAM. If not, see . + +Class + Foam::passivePositionParticle + +Description + Copy of base particle but without particle locating and preserving + read location. + + Used in reconstructing lagrangian positions generated outside the + mesh domain (can happen in extractEulerianParticles functionObject) + +SourceFiles + passivePositionParticle.H + +\*---------------------------------------------------------------------------*/ + +#ifndef passivePositionParticle_H +#define passivePositionParticle_H + +#include "particle.H" +#include "IOstream.H" +#include "autoPtr.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class passivePositionParticle Declaration +\*---------------------------------------------------------------------------*/ + +class passivePositionParticle +: + public particle +{ + // Private Data + + //- Raw location + point location_; + + +public: + + // Constructors + + //- Construct from components + passivePositionParticle + ( + const polyMesh& mesh, + const barycentric& coordinates, + const label celli, + const label tetFacei, + const label tetPti + ) + : + particle(mesh, coordinates, celli, tetFacei, tetPti), + location_(position()) + {} + + + //- Construct from a position and a cell. + // Searches for the rest of the required topology. + passivePositionParticle + ( + const polyMesh& mesh, + const vector& position, + const label celli = -1 + ) + : + particle(mesh, position, celli), + location_(position) + {} + + + //- Construct from Istream + passivePositionParticle + ( + const polyMesh& mesh, + Istream& is, + const bool readFields = true, + const bool newFormat = true + ) + : + //particle(mesh, is, readFields, newFormat) + particle + ( + mesh, + Zero, // position + -1, // celli + -1, // tetFacei + -1, // tetPti + false // doLocate + ) + { + readData + ( + is, + location_, + readFields, + newFormat, + false //doLocate + ); + } + + + //- Construct as copy + passivePositionParticle(const passivePositionParticle& p) + : + particle(p) + {} + + + //- Construct and return a clone + virtual autoPtr clone() const + { + return autoPtr(new passivePositionParticle(*this)); + } + + + //- Factory class to read-construct particles (for parallel transfer) + class iNew + { + const polyMesh& mesh_; + + public: + + iNew(const polyMesh& mesh) + : + mesh_(mesh) + {} + + autoPtr operator()(Istream& is) const + { + return autoPtr::New(mesh_, is, true); + } + }; + + + // Member Functions + + //- Return current particle position + inline const point& location() const + { + return location_; + } +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/parallel/reconstruct/reconstruct/passivePositionParticleCloud.C b/src/parallel/reconstruct/reconstruct/passivePositionParticleCloud.C new file mode 100644 index 0000000000..4f714ad287 --- /dev/null +++ b/src/parallel/reconstruct/reconstruct/passivePositionParticleCloud.C @@ -0,0 +1,66 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM 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. + + OpenFOAM 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 OpenFOAM. If not, see . + +\*---------------------------------------------------------------------------*/ + +#include "passivePositionParticleCloud.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTemplateTypeNameAndDebug(Cloud, 0); +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::passivePositionParticleCloud::passivePositionParticleCloud +( + const polyMesh& mesh, + const word& cloudName, + bool readFields +) +: + Cloud(mesh, cloudName, false) +{ + if (readFields) + { + passivePositionParticle::readFields(*this); + } +} + + +Foam::passivePositionParticleCloud::passivePositionParticleCloud +( + const polyMesh& mesh, + const word& cloudName, + const IDLList& particles +) +: + Cloud(mesh, cloudName, particles) +{} + + +// ************************************************************************* // diff --git a/src/parallel/reconstruct/reconstruct/passivePositionParticleCloud.H b/src/parallel/reconstruct/reconstruct/passivePositionParticleCloud.H new file mode 100644 index 0000000000..dab774fcfc --- /dev/null +++ b/src/parallel/reconstruct/reconstruct/passivePositionParticleCloud.H @@ -0,0 +1,96 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2021 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM 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. + + OpenFOAM 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 OpenFOAM. If not, see . + +Class + Foam::passivePositionParticleCloud + +Description + A Cloud of passive particles + +SourceFiles + passivePositionParticleCloud.C + +\*---------------------------------------------------------------------------*/ + +#ifndef passivePositionParticleCloud_H +#define passivePositionParticleCloud_H + +#include "Cloud.H" +#include "passivePositionParticle.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class passivePositionParticleCloud Declaration +\*---------------------------------------------------------------------------*/ + +class passivePositionParticleCloud +: + public Cloud +{ + // Private Member Functions + + //- No copy construct + passivePositionParticleCloud(const passivePositionParticleCloud&) = + delete; + + //- No copy assignment + void operator=(const passivePositionParticleCloud&) = delete; + + +public: + + // Constructors + + //- Construct given mesh + explicit passivePositionParticleCloud + ( + const polyMesh& mesh, + const word& cloudName = cloud::defaultName, + bool readFields = true + ); + + //- Construct from mesh, cloud name, and a list of particles + passivePositionParticleCloud + ( + const polyMesh& mesh, + const word& cloudName, + const IDLList& particles + ); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* //