diff --git a/applications/utilities/parallelProcessing/redistributePar/Make/files b/applications/utilities/parallelProcessing/redistributePar/Make/files
index 3447baa3d8..6e45d2d8cc 100644
--- a/applications/utilities/parallelProcessing/redistributePar/Make/files
+++ b/applications/utilities/parallelProcessing/redistributePar/Make/files
@@ -1,6 +1,8 @@
passivePositionParticleCloud.C
parLagrangianRedistributor.C
+parPointFieldDistributor.C
parFvFieldReconstructor.C
+
loadOrCreateMesh.C
redistributePar.C
diff --git a/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributor.C b/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributor.C
new file mode 100644
index 0000000000..ade2b7a237
--- /dev/null
+++ b/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributor.C
@@ -0,0 +1,238 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 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 "parPointFieldDistributor.H"
+#include "processorPointPatch.H"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+int Foam::parPointFieldDistributor::verbose_ = 0;
+
+
+// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
+
+Foam::parPointFieldDistributor::parPointFieldDistributor
+(
+ const pointMesh& srcMesh,
+ const bool savePoints,
+ const bool isWriteProc
+)
+:
+ srcMesh_(srcMesh),
+ nOldPoints_(srcMesh.size()),
+ patchMeshPoints_(),
+ tgtMeshRef_(nullptr),
+ distMapRef_(nullptr),
+ patchPointMaps_(),
+ isWriteProc_(isWriteProc)
+{
+ if (savePoints)
+ {
+ saveMeshPoints();
+ }
+}
+
+
+Foam::parPointFieldDistributor::parPointFieldDistributor
+(
+ const pointMesh& srcMesh,
+ const pointMesh& tgtMesh,
+ const mapDistributePolyMesh& distMap,
+ const bool savePoints,
+ const bool isWriteProc
+)
+:
+ srcMesh_(srcMesh),
+ nOldPoints_(srcMesh.size()),
+ patchMeshPoints_(),
+ tgtMeshRef_(tgtMesh),
+ distMapRef_(distMap),
+ patchPointMaps_(),
+ isWriteProc_(isWriteProc)
+{
+ if (savePoints)
+ {
+ saveMeshPoints();
+ }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+bool Foam::parPointFieldDistributor::hasMeshPoints() const
+{
+ return !patchMeshPoints_.empty();
+}
+
+
+bool Foam::parPointFieldDistributor::hasPatchPointMaps() const
+{
+ return !patchPointMaps_.empty();
+}
+
+
+bool Foam::parPointFieldDistributor::hasTarget() const
+{
+ return (tgtMeshRef_ && distMapRef_);
+}
+
+
+void Foam::parPointFieldDistributor::clearMeshPoints()
+{
+ patchMeshPoints_.clear();
+}
+
+void Foam::parPointFieldDistributor::clearPatchPointMaps()
+{
+ patchPointMaps_.clear();
+}
+
+
+void Foam::parPointFieldDistributor::saveMeshPoints()
+{
+ const pointBoundaryMesh& patches = srcMesh_.boundary();
+
+ patchMeshPoints_.clear();
+ patchMeshPoints_.resize(patches.size());
+
+ forAll(patches, patchi)
+ {
+ if (!isA(patches[patchi]))
+ {
+ // Copy meshPoints
+ patchMeshPoints_.set
+ (
+ patchi,
+ new labelList(patches[patchi].meshPoints())
+ );
+ }
+ }
+}
+
+
+void Foam::parPointFieldDistributor::createPatchPointMaps()
+{
+ if (!tgtMeshRef_ || !distMapRef_)
+ {
+ FatalErrorInFunction
+ << "Cannot create maps without target mesh and/or distribution!"
+ << abort(FatalError);
+ }
+
+ const auto& tgtMesh = tgtMeshRef_();
+ const auto& distMap = distMapRef_();
+
+ const auto& newPatches = tgtMesh.boundary();
+ const auto& oldPatches = srcMesh_.boundary();
+
+ patchPointMaps_.clear();
+ patchPointMaps_.resize(oldPatches.size());
+
+ // if (patchPointMaps_.size() != patchMeshPoints_.size())
+ // {
+ // // Warn?
+ // }
+
+ forAll(oldPatches, patchi)
+ {
+ if (!isA(oldPatches[patchi]))
+ {
+ // Create map for patch points only
+ labelList oldToNewSub;
+ labelList oldToNewConstruct;
+
+ // Copy point map
+ patchPointMaps_.set
+ (
+ patchi,
+ new mapDistributeBase(distMap.pointMap())
+ );
+
+ const labelList& oldMeshPoints =
+ (
+ patchMeshPoints_.test(patchi)
+ ? patchMeshPoints_[patchi]
+ : oldPatches[patchi].meshPoints() // <- Questionable!
+ );
+
+ patchPointMaps_[patchi].compactData
+ (
+ oldMeshPoints,
+ newPatches[patchi].meshPoints(),
+ oldToNewSub,
+ oldToNewConstruct,
+ nOldPoints_,
+ UPstream::msgType()
+ );
+ }
+ }
+}
+
+
+void Foam::parPointFieldDistributor::resetTarget()
+{
+ tgtMeshRef_.reset(nullptr);
+ distMapRef_.reset(nullptr);
+
+ // Old maps are now invalid
+ clearPatchPointMaps();
+}
+
+
+void Foam::parPointFieldDistributor::resetTarget
+(
+ const pointMesh& tgtMesh,
+ const mapDistributePolyMesh& distMap
+)
+{
+ tgtMeshRef_.cref(tgtMesh);
+ distMapRef_.cref(distMap);
+
+ // Old maps are now invalid
+ clearPatchPointMaps();
+}
+
+
+Foam::label Foam::parPointFieldDistributor::distributeAllFields
+(
+ const IOobjectList& objects,
+ const wordRes& selected
+) const
+{
+ label nTotal = 0;
+
+ nTotal += distributePointFields(objects, selected);
+ nTotal += distributePointFields(objects, selected);
+ nTotal += distributePointFields(objects, selected);
+ nTotal += distributePointFields(objects, selected);
+ nTotal += distributePointFields(objects, selected);
+
+ return nTotal;
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributor.H b/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributor.H
new file mode 100644
index 0000000000..70307d7e28
--- /dev/null
+++ b/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributor.H
@@ -0,0 +1,255 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 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::parPointFieldDistributor
+
+Description
+ Distributor/redistributor for point fields,
+ uses a two (or three) stage construction.
+
+ The inconvenient multi-stage construction is needed since the
+ pointMesh is directly associated with a polyMesh, which will probably
+ have changed while creating the target mesh. This means that it is
+ necessary to save the size of the source mesh and all of its
+ patch meshPoints prior to making any changes (eg, creating the target
+ mesh).
+
+ -# Create with specified source mesh
+ -# Save the meshPoints (per boundary) for the source mesh
+ -# Attach a target mesh and mesh distribution
+ -# Map the point fields
+ .
+
+ Runs in parallel. Redistributes from srcMesh to tgtMesh.
+
+SourceFiles
+ parPointFieldDistributor.C
+ parPointFieldDistributorTemplates.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef Foam_parPointFieldDistributor_H
+#define Foam_parPointFieldDistributor_H
+
+#include "PtrList.H"
+#include "pointMesh.H"
+#include "pointFieldsFwd.H"
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+
+// Forward Declarations
+class mapDistributePolyMesh;
+class mapDistributeBase;
+class IOobjectList;
+
+/*---------------------------------------------------------------------------*\
+ Class parPointFieldDistributor Declaration
+\*---------------------------------------------------------------------------*/
+
+class parPointFieldDistributor
+{
+ // Private Data
+
+ //- The source mesh reference
+ const pointMesh& srcMesh_;
+
+ //- Number of points in the old (source) mesh
+ const label nOldPoints_;
+
+ //- The pointPatch mesh points
+ PtrList patchMeshPoints_;
+
+ //- The target (destination) mesh reference
+ refPtr tgtMeshRef_;
+
+ //- Distribution map reference
+ refPtr distMapRef_;
+
+ //- Point patch mappers
+ PtrList patchPointMaps_;
+
+ //- Do I need to write (eg, master only for reconstruct)
+ bool isWriteProc_;
+
+
+ // Private Member Functions
+
+ //- No copy construct
+ parPointFieldDistributor(const parPointFieldDistributor&) = delete;
+
+ //- No copy assignment
+ void operator=(const parPointFieldDistributor&) = delete;
+
+
+public:
+
+ //- Output verbosity when writing
+ static int verbose_;
+
+
+ // Constructors
+
+ //- Basic construction
+ //
+ // \param srcMesh The source pointMesh
+ // \param savePoints Call saveMeshPoints() immediately
+ // \param isWriteProc Tagged for output writing (on this proc)
+ explicit parPointFieldDistributor
+ (
+ const pointMesh& srcMesh,
+ const bool savePoints = false,
+ const bool isWriteProc = false
+ );
+
+ //- Full construction of source/target
+ //
+ // \param srcMesh The source pointMesh
+ // \param tgtMesh The target pointMesh
+ // \param distMap The distribution map
+ // \param savePoints Call saveMeshPoints() immediately
+ // \param isWriteProc Tagged for output writing (on this proc)
+ explicit parPointFieldDistributor
+ (
+ const pointMesh& srcMesh,
+ const pointMesh& tgtMesh,
+ const mapDistributePolyMesh& distMap,
+ const bool savePoints = false,
+ const bool isWriteProc = false
+ );
+
+
+ // Member Functions
+
+ //- True if meshPoints (per boundary) for the source mesh
+ //- have been saved
+ bool hasMeshPoints() const;
+
+ //- True if patch maps (per boundary) exist
+ bool hasPatchPointMaps() const;
+
+ //- True if a target mesh/distribution map has been attached
+ bool hasTarget() const;
+
+ //- Clear out meshPoints (per boundary) for the source mesh
+ void clearMeshPoints();
+
+ //- Clear out patch maps (per boundary)
+ void clearPatchPointMaps();
+
+ //- Create/recreate meshPoints (per boundary) for the source mesh
+ void saveMeshPoints();
+
+ //- Construct per-patch addressing
+ void createPatchPointMaps();
+
+ //- Clear target mesh / distribution map
+ void resetTarget();
+
+ //- Reset target mesh / distribution map
+ void resetTarget
+ (
+ const pointMesh& tgtMesh,
+ const mapDistributePolyMesh& distMap
+ );
+
+ //- Get status of write enabled (on this proc)
+ bool isWriteProc() const noexcept
+ {
+ return isWriteProc_;
+ }
+
+ //- Change status of write enabled (on this proc)
+ bool isWriteProc(const bool on) noexcept
+ {
+ bool old(isWriteProc_);
+ isWriteProc_ = on;
+ return old;
+ }
+
+
+ // Field Mapping
+
+ //- Read, distribute and write all/selected point field types
+ //- (scalar, vector, ... types)
+ label distributeAllFields
+ (
+ const IOobjectList& objects,
+ const wordRes& selectedFields = wordRes()
+ ) const;
+
+
+ //- Distribute point field
+ template
+ tmp>
+ distributeField
+ (
+ const GeometricField& fld
+ ) const;
+
+ //- Read and distribute point field
+ template
+ tmp>
+ distributePointField
+ (
+ const IOobject& fieldObject
+ ) const;
+
+ //- Read, distribute and write all/selected point fields
+ template
+ label distributePointFields
+ (
+ const IOobjectList& objects,
+ const wordRes& selectedFields = wordRes()
+ ) const;
+
+ //- Distributed each (unregistered!) point field
+ //- and store the result on its objectRegistry
+ template
+ void distributeAndStore
+ (
+ const PtrList>&
+ ) const;
+};
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#ifdef NoRepository
+# include "parPointFieldDistributorTemplates.C"
+#endif
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributorTemplates.C b/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributorTemplates.C
new file mode 100644
index 0000000000..d7c73ea218
--- /dev/null
+++ b/applications/utilities/parallelProcessing/redistributePar/parPointFieldDistributorTemplates.C
@@ -0,0 +1,239 @@
+/*---------------------------------------------------------------------------*\
+ ========= |
+ \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
+ \\ / O peration |
+ \\ / A nd | www.openfoam.com
+ \\/ M anipulation |
+-------------------------------------------------------------------------------
+ Copyright (C) 2022 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 "Time.H"
+#include "emptyPointPatchField.H"
+#include "IOobjectList.H"
+#include "mapDistributePolyMesh.H"
+#include "distributedFieldMapper.H"
+#include "distributedPointPatchFieldMapper.H"
+#include "pointFields.H"
+
+// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
+
+template
+Foam::tmp>
+Foam::parPointFieldDistributor::distributeField
+(
+ const GeometricField& fld
+) const
+{
+ if (!tgtMeshRef_ || !distMapRef_)
+ {
+ FatalErrorInFunction
+ << "Cannot map field without target mesh and/or distribution!"
+ << abort(FatalError);
+ }
+ if (!hasPatchPointMaps())
+ {
+ const_cast(*this).createPatchPointMaps();
+ }
+
+ const auto& tgtMesh = tgtMeshRef_();
+ const auto& distMap = distMapRef_();
+
+ // Create internalField by remote mapping
+ distributedFieldMapper mapper
+ (
+ labelUList::null(),
+ distMap.pointMap()
+ );
+
+ DimensionedField internalField
+ (
+ IOobject
+ (
+ fld.name(),
+ tgtMesh.time().timeName(),
+ fld.local(),
+ tgtMesh.thisDb(),
+ IOobject::NO_READ,
+ IOobject::NO_WRITE
+ ),
+ tgtMesh,
+ fld.dimensions(),
+ Field(fld.internalField(), mapper)
+ );
+
+ internalField.oriented() = fld.oriented();
+
+
+ // Create patchFields by remote mapping
+
+ PtrList> newPatchFields(tgtMesh.boundary().size());
+
+ const auto& bfld = fld.boundaryField();
+
+ forAll(bfld, patchi)
+ {
+ if (patchPointMaps_.set(patchi))
+ {
+ // Clone local patch field
+
+ const distributedPointPatchFieldMapper mapper
+ (
+ labelUList::null(),
+ patchPointMaps_[patchi]
+ );
+
+ // Map into local copy
+ newPatchFields.set
+ (
+ patchi,
+ pointPatchField::New
+ (
+ bfld[patchi],
+ tgtMesh.boundary()[patchi], // pointPatch
+ DimensionedField::null(),
+ mapper
+ )
+ );
+
+ // Note: below alternative, 'clone' method will not work since
+ // there is no clone to reset both internalField reference and
+ // patch reference. TBD.
+ //newPatchFields.set
+ //(
+ // patchi,
+ // bfld[patchi].clone
+ // (
+ // tgtMesh.boundary()[patchi],
+ // DimensionedField::null(),
+ // mapper
+ // )
+ //);
+ }
+ }
+
+ // Add some empty patchFields on remaining patches (this also handles
+ // e.g. processorPatchFields or any other constraint type patches)
+ forAll(newPatchFields, patchi)
+ {
+ if (!newPatchFields.set(patchi))
+ {
+ newPatchFields.set
+ (
+ patchi,
+ pointPatchField::New
+ (
+ emptyPointPatchField::typeName,
+ tgtMesh.boundary()[patchi],
+ DimensionedField::null()
+ )
+ );
+ }
+ }
+
+ return
+ tmp>::New
+ (
+ std::move(internalField),
+ newPatchFields
+ );
+}
+
+
+template
+Foam::tmp>
+Foam::parPointFieldDistributor::distributePointField
+(
+ const IOobject& fieldObject
+) const
+{
+ // Read field
+ GeometricField fld
+ (
+ fieldObject,
+ srcMesh_
+ );
+
+ // Redistribute
+ return distributeField(fld);
+}
+
+
+template
+Foam::label Foam::parPointFieldDistributor::distributePointFields
+(
+ const IOobjectList& objects,
+ const wordRes& selectedFields
+) const
+{
+ typedef GeometricField fieldType;
+
+ UPtrList fieldObjects
+ (
+ selectedFields.empty()
+ ? objects.sorted()
+ : objects.sorted(selectedFields)
+ );
+
+ label nFields = 0;
+ for (const IOobject& io : fieldObjects)
+ {
+ if (verbose_)
+ {
+ if (!nFields)
+ {
+ Info<< " Reconstructing "
+ << fieldType::typeName << "s\n" << nl;
+ }
+ Info<< " " << io.name() << nl;
+ }
+ ++nFields;
+
+ tmp tfld(distributePointField(io));
+ if (isWriteProc_)
+ {
+ tfld().write();
+ }
+ }
+
+ if (nFields && verbose_) Info<< endl;
+ return nFields;
+}
+
+
+template
+void Foam::parPointFieldDistributor::distributeAndStore
+(
+ const PtrList>& fields
+) const
+{
+ for (const auto& fld : fields)
+ {
+ // Distribute and store
+ auto tfld = distributeField(fld);
+
+ tfld.ref().writeOpt(IOobject::AUTO_WRITE);
+
+ tfld().mesh().thisDb().store(tfld);
+ }
+}
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
index 01ae1c7338..c148c3d9e8 100644
--- a/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
+++ b/applications/utilities/parallelProcessing/redistributePar/redistributePar.C
@@ -95,6 +95,7 @@ Usage
#include "regionProperties.H"
#include "parFvFieldReconstructor.H"
+#include "parPointFieldDistributor.H"
#include "parLagrangianRedistributor.H"
#include "unmappedPassivePositionParticleCloud.H"
#include "hexRef8Data.H"
@@ -535,7 +536,7 @@ void determineDecomposition
// Variant of GeometricField::correctBoundaryConditions that only
// evaluates selected patch fields
-template
+template
void correctCoupledBoundaryConditions(fvMesh& mesh)
{
HashTable flds
@@ -576,6 +577,7 @@ autoPtr redistributeAndWrite
//Info<< "Before distribution:" << endl;
//printMeshData(mesh);
+ // Storage of fields
PtrList volScalarFields;
PtrList volVectorFields;
@@ -595,7 +597,24 @@ autoPtr redistributeAndWrite
PtrList> dimSymmTensorFields;
PtrList> dimTensorFields;
- DynamicList pointFieldNames;
+ PtrList pointScalarFields;
+ PtrList pointVectorFields;
+ PtrList pointTensorFields;
+ PtrList pointSphTensorFields;
+ PtrList pointSymmTensorFields;
+
+ // Self-contained pointMesh for reading pointFields
+ const pointMesh oldPointMesh(mesh);
+
+ // Track how many (if any) pointFields are read/mapped
+ label nPointFields = 0;
+
+ parPointFieldDistributor pointDistributor
+ (
+ oldPointMesh, // source mesh
+ false, // savePoints=false (ie, delay until later)
+ false // Do not write
+ );
if (doReadFields)
@@ -656,190 +675,68 @@ autoPtr redistributeAndWrite
}
- // volFields
-
if (Pstream::master() && decompose)
{
runTime.caseName() = baseRunTime.caseName();
runTime.processorCase(false);
}
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- volScalarFields
- );
+ // Field reading
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- volVectorFields
- );
+ #undef doFieldReading
+ #define doFieldReading(Storage) \
+ { \
+ fieldsDistributor::readFields \
+ ( \
+ haveMesh, mesh, subsetterPtr, objects, Storage \
+ ); \
+ }
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- volSphereTensorFields
- );
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- volSymmTensorFields
- );
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- volTensorFields
- );
-
-
- // surfaceFields
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- surfScalarFields
- );
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- surfVectorFields
- );
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- surfSphereTensorFields
- );
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- surfSymmTensorFields
- );
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- surfTensorFields
- );
+ // volField
+ doFieldReading(volScalarFields);
+ doFieldReading(volVectorFields);
+ doFieldReading(volSphereTensorFields);
+ doFieldReading(volSymmTensorFields);
+ doFieldReading(volTensorFields);
+ // surfaceField
+ doFieldReading(surfScalarFields);
+ doFieldReading(surfVectorFields);
+ doFieldReading(surfSphereTensorFields);
+ doFieldReading(surfSymmTensorFields);
+ doFieldReading(surfTensorFields);
// Dimensioned internal fields
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- dimScalarFields
- );
+ doFieldReading(dimScalarFields);
+ doFieldReading(dimVectorFields);
+ doFieldReading(dimSphereTensorFields);
+ doFieldReading(dimSymmTensorFields);
+ doFieldReading(dimTensorFields);
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- dimVectorFields
- );
+ // pointFields
+ nPointFields = 0;
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- dimSphereTensorFields
- );
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- dimSymmTensorFields
- );
-
- fieldsDistributor::readFields
- (
- haveMesh,
- mesh,
- subsetterPtr,
- objects,
- dimTensorFields
- );
-
-
- // pointFields currently not supported. Read their names so we
- // can delete them.
- {
- // Get my objects of type
- pointFieldNames.append
- (
- objects.lookupClass(pointScalarField::typeName).sortedNames()
- );
- pointFieldNames.append
- (
- objects.lookupClass(pointVectorField::typeName).sortedNames()
- );
- pointFieldNames.append
- (
- objects.lookupClass
- (
- pointSphericalTensorField::typeName
- ).sortedNames()
- );
- pointFieldNames.append
- (
- objects.lookupClass
- (
- pointSymmTensorField::typeName
- ).sortedNames()
- );
- pointFieldNames.append
- (
- objects.lookupClass(pointTensorField::typeName).sortedNames()
- );
-
- // Make sure all processors have the same set
- Pstream::scatter(pointFieldNames);
+ #undef doFieldReading
+ #define doFieldReading(Storage) \
+ { \
+ fieldsDistributor::readFields \
+ ( \
+ haveMesh, oldPointMesh, subsetterPtr, objects, Storage, \
+ true /* (deregister field) */ \
+ ); \
+ nPointFields += Storage.size(); \
}
+ doFieldReading(pointScalarFields);
+ doFieldReading(pointVectorFields);
+ doFieldReading(pointSphTensorFields);
+ doFieldReading(pointSymmTensorFields);
+ doFieldReading(pointTensorFields);
+ #undef doFieldReading
+
+
+ // Done reading
+
if (Pstream::master() && decompose)
{
runTime.caseName() = proc0CaseName;
@@ -847,6 +744,12 @@ autoPtr redistributeAndWrite
}
}
+ // Save pointMesh information before any topology changes occur!
+ if (nPointFields)
+ {
+ pointDistributor.saveMeshPoints();
+ }
+
// Mesh distribution engine
fvMeshDistribute distributor(mesh);
@@ -859,34 +762,40 @@ autoPtr redistributeAndWrite
printMeshData(mesh);
// Get other side of processor boundaries
- correctCoupledBoundaryConditions
- <
- volScalarField,
- processorFvPatch
- >(mesh);
- correctCoupledBoundaryConditions
- <
- volVectorField,
- processorFvPatch
- >(mesh);
- correctCoupledBoundaryConditions
- <
- volSphericalTensorField,
- processorFvPatch
- >(mesh);
- correctCoupledBoundaryConditions
- <
- volSymmTensorField,
- processorFvPatch
- >(mesh);
- correctCoupledBoundaryConditions
- <
- volTensorField,
- processorFvPatch
- >(mesh);
+ do
+ {
+ #undef doCorrectCoupled
+ #define doCorrectCoupled(FieldType) \
+ correctCoupledBoundaryConditions(mesh);
+
+ doCorrectCoupled(volScalarField);
+ doCorrectCoupled(volVectorField);
+ doCorrectCoupled(volSphericalTensorField);
+ doCorrectCoupled(volSymmTensorField);
+ doCorrectCoupled(volTensorField);
+ #undef doCorrectCoupled
+ }
+ while (false);
+
// No update surface fields
+ // Map pointFields
+ if (nPointFields)
+ {
+ // Construct new pointMesh from distributed mesh
+ const pointMesh& newPointMesh = pointMesh::New(mesh);
+
+ pointDistributor.resetTarget(newPointMesh, rawMap());
+
+ pointDistributor.distributeAndStore(pointScalarFields);
+ pointDistributor.distributeAndStore(pointVectorFields);
+ pointDistributor.distributeAndStore(pointSphTensorFields);
+ pointDistributor.distributeAndStore(pointSymmTensorFields);
+ pointDistributor.distributeAndStore(pointTensorFields);
+ }
+
+
// Set the minimum write precision
IOstream::defaultPrecision(max(10u, IOstream::defaultPrecision()));
@@ -925,24 +834,9 @@ autoPtr redistributeAndWrite
<< " to write reconstructed mesh and fields." << endl;
runTime.caseName() = baseRunTime.caseName();
const bool oldProcCase(runTime.processorCase(false));
- const bool oldParRun = Pstream::parRun(false);
mesh.write();
topoSet::removeFiles(mesh);
- for (const word& fieldName : pointFieldNames)
- {
- IOobject io
- (
- fieldName,
- runTime.timeName(),
- mesh
- );
-
- const fileName fieldFile(io.objectPath());
- if (topoSet::debug) DebugVar(fieldFile);
- rm(fieldFile);
- }
- Pstream::parRun(oldParRun);
// Now we've written all. Reset caseName on master
Info<< "Restoring caseName to " << proc0CaseName << endl;
@@ -965,19 +859,6 @@ autoPtr redistributeAndWrite
writeHandler = fileHandler(std::move(defaultHandler));
}
topoSet::removeFiles(mesh);
- for (const word& fieldName : pointFieldNames)
- {
- IOobject io
- (
- fieldName,
- runTime.timeName(),
- mesh
- );
-
- const fileName fieldFile(io.objectPath());
- if (topoSet::debug) DebugVar(fieldFile);
- rm(fieldFile);
- }
}
Info<< "Written redistributed mesh to " << mesh.facesInstance() << nl
<< endl;
@@ -1724,6 +1605,7 @@ int main(int argc, char *argv[])
#include "addOverwriteOption.H"
argList::addBoolOption("decompose", "Decompose case");
argList::addBoolOption("reconstruct", "Reconstruct case");
+ argList::addVerboseOption("Additional verbosity");
argList::addDryRunOption
(
"Test without writing the decomposition. "
@@ -1794,6 +1676,12 @@ int main(int argc, char *argv[])
const bool dryrun = args.dryRun();
const bool newTimes = args.found("newTimes");
+ if (args.verbose())
+ {
+ // Report on output
+ parPointFieldDistributor::verbose_ = 1;
+ }
+
bool decompose = args.found("decompose");
bool overwrite = args.found("overwrite");
@@ -2240,17 +2128,28 @@ int main(int argc, char *argv[])
distMap = fvMeshTools::readProcAddressing(mesh, baseMeshPtr);
// Construct field mapper
- autoPtr fvReconstructorPtr
- (
- new parFvFieldReconstructor
+ auto fvReconstructorPtr =
+ autoPtr::New
(
baseMeshPtr(),
mesh,
distMap(),
Pstream::master() // do I need to write?
- )
- );
+ );
+ // Construct point field mapper
+ const auto& basePointMesh = pointMesh::New(baseMeshPtr());
+ const auto& procPointMesh = pointMesh::New(mesh);
+
+ auto pointFieldDistributorPtr =
+ autoPtr::New
+ (
+ procPointMesh, // source
+ basePointMesh, // target
+ distMap(),
+ false, // delay
+ UPstream::master() // Write reconstructed on master
+ );
// Since we start from Times[0] and not runTime.timeName() we
@@ -2324,7 +2223,8 @@ int main(int argc, char *argv[])
distMap =
fvMeshTools::readProcAddressing(mesh, baseMeshPtr);
- // Reset field mapper
+ // Reset field mappers
+
fvReconstructorPtr.reset
(
new parFvFieldReconstructor
@@ -2335,6 +2235,23 @@ int main(int argc, char *argv[])
Pstream::master()
)
);
+
+ // Construct point field mapper
+ const auto& basePointMesh = pointMesh::New(baseMeshPtr());
+ const auto& procPointMesh = pointMesh::New(mesh);
+
+ pointFieldDistributorPtr.reset
+ (
+ new parPointFieldDistributor
+ (
+ procPointMesh, // source
+ basePointMesh, // target
+ distMap(),
+ false, // delay until later
+ UPstream::master() // Write reconstruct on master
+ )
+ );
+
lagrangianReconstructorPtr.clear();
}
@@ -2351,6 +2268,12 @@ int main(int argc, char *argv[])
selectedFields
);
+ // pointfields
+ // - distribute and write (verbose)
+ pointFieldDistributorPtr()
+ .distributeAllFields(objects, selectedFields);
+
+
// Clouds (note: might not be present on all processors)
reconstructLagrangian
(