Skip to content
Snippets Groups Projects
Commit 7872ed89 authored by Mark OLESEN's avatar Mark OLESEN
Browse files

ENH: faMeshDistributor for handling redistribution of finiteArea (#2436)

parent dbbb8543
No related branches found
No related tags found
No related merge requests found
...@@ -24,6 +24,9 @@ $(faPatches)/constraint/wedge/wedgeFaPatch.C ...@@ -24,6 +24,9 @@ $(faPatches)/constraint/wedge/wedgeFaPatch.C
$(faPatches)/constraint/cyclic/cyclicFaPatch.C $(faPatches)/constraint/cyclic/cyclicFaPatch.C
$(faPatches)/constraint/symmetry/symmetryFaPatch.C $(faPatches)/constraint/symmetry/symmetryFaPatch.C
distributed/faMeshDistributor.C
distributed/faMeshDistributorNew.C
ensight = output/ensight ensight = output/ensight
$(ensight)/ensightFaMesh.C $(ensight)/ensightFaMesh.C
......
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "faMeshDistributor.H"
#include "BitOps.H"
#include "fileOperation.H"
#include "areaFields.H"
#include "edgeFields.H"
#include "faMeshTools.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
int Foam::faMeshDistributor::verbose_ = 0;
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::faMeshDistributor::createPatchMaps() const
{
const faBoundaryMesh& oldPatches = srcMesh_.boundary();
const faBoundaryMesh& newPatches = tgtMesh_.boundary();
patchEdgeMaps_.clear();
patchEdgeMaps_.resize(oldPatches.size());
// area: edgeMap (volume: faceMap)
const auto& faEdgeMap = distMap_.faceMap();
// The logical edge ranges per patch [target mesh]
List<labelRange> ranges = newPatches.patchRanges();
forAll(oldPatches, patchi)
{
if (!isA<processorFaPatch>(oldPatches[patchi]))
{
// Map non-processor only
// Copy full map
patchEdgeMaps_.set
(
patchi,
new mapDistributeBase(faEdgeMap)
);
// Retain patch elements
patchEdgeMaps_[patchi].compactRemoteData
(
bitSet(ranges[patchi]),
UPstream::msgType(),
true // Also renumber/resize the compact maps
);
}
}
}
void Foam::faMeshDistributor::createInternalEdgeMap() const
{
// area: edgeMap (volume: faceMap)
const auto& faEdgeMap = distMap_.faceMap();
// Copy full map
internalEdgeMap_.reset(new mapDistributeBase(faEdgeMap));
// Retain internal edges
internalEdgeMap_->compactRemoteData
(
bitSet(tgtMesh_.nInternalEdges(), true),
UPstream::msgType(),
true // Also renumber/resize the compact maps
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::faMeshDistributor::faMeshDistributor
(
const faMesh& srcMesh,
const faMesh& tgtMesh,
const mapDistributePolyMesh& distMap,
const bool isWriteProc
)
:
srcMesh_(srcMesh),
tgtMesh_(tgtMesh),
distMap_(distMap),
internalEdgeMap_(),
patchEdgeMaps_(),
isWriteProc_(isWriteProc)
{
#ifdef FULLDEBUG
{
Pout<< "Create from nFaces:" << srcMesh.faceLabels().size()
<< " to:" << tgtMesh.faceLabels().size() << endl;
vectorField oldFaceCentres(srcMesh_.areaCentres());
vectorField newFaceCentres(tgtMesh_.areaCentres());
// volume: cells, area: faces
distMap_.distributeCellData(oldFaceCentres);
vectorField diff(newFaceCentres - oldFaceCentres);
Pout<< "diff faces: " << diff << endl;
vectorField oldEdgeCentres
(
faMeshTools::flattenEdgeField(srcMesh_.edgeCentres())
);
vectorField newEdgeCentres
(
faMeshTools::flattenEdgeField(tgtMesh_.edgeCentres())
);
Pout<< "distributed edges: " << oldEdgeCentres.size() << " from "
<< srcMesh.nEdges() << " to " << tgtMesh.nEdges() << endl;
// volume: faces, area: edges
distMap_.distributeFaceData(oldEdgeCentres);
diff = (newEdgeCentres - oldEdgeCentres);
Pout<< "diff edges: " << diff << endl;
Info<< "Patch edge maps" << endl;
forAll(patchEdgeMaps_, patchi)
{
if (patchEdgeMaps_.set(patchi))
{
Pout<< "patch " << patchi << " : "
<< patchEdgeMaps_[patchi].info() << endl;
}
}
Info<< nl << "Detailed patch maps" << endl;
forAll(patchEdgeMaps_, patchi)
{
if (patchEdgeMaps_.set(patchi))
{
Info<< "patch " << patchi << " : "
<< patchEdgeMaps_[patchi] << endl;
}
}
}
#endif
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::label Foam::faMeshDistributor::distributeAllFields
(
const IOobjectList& objects,
const wordRes& selected
) const
{
label nTotal = 0;
nTotal += distributeAreaFields<scalar>(objects, selected);
nTotal += distributeAreaFields<vector>(objects, selected);
nTotal += distributeAreaFields<symmTensor>(objects, selected);
nTotal += distributeAreaFields<sphericalTensor>(objects, selected);
nTotal += distributeAreaFields<tensor>(objects, selected);
nTotal += distributeEdgeFields<scalar>(objects, selected);
nTotal += distributeEdgeFields<vector>(objects, selected);
nTotal += distributeEdgeFields<symmTensor>(objects, selected);
nTotal += distributeEdgeFields<sphericalTensor>(objects, selected);
nTotal += distributeEdgeFields<tensor>(objects, selected);
return nTotal;
}
// ************************************************************************* //
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
Class
Foam::faMeshDistributor
Description
Holds a reference to the original mesh (the baseMesh)
and optionally to a subset of that mesh (the subMesh)
with mapping lists for points, faces, and cells.
SourceFiles
faMeshDistributor.C
faMeshDistributorNew.C
faMeshDistributorTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_faMeshDistributor_H
#define Foam_faMeshDistributor_H
#include "faMesh.H"
#include "mapDistributePolyMesh.H"
#include "areaFieldsFwd.H"
#include "edgeFieldsFwd.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class IOobjectList;
/*---------------------------------------------------------------------------*\
Class faMeshDistributor Declaration
\*---------------------------------------------------------------------------*/
class faMeshDistributor
{
// Private Data
//- The source mesh reference
const faMesh& srcMesh_;
//- The destination mesh reference
const faMesh& tgtMesh_;
//- Distribution map reference (faMesh)
const mapDistributePolyMesh& distMap_;
//- Internal edge mapper
mutable std::unique_ptr<mapDistributeBase> internalEdgeMap_;
//- Patch edge mappers
mutable PtrList<mapDistributeBase> patchEdgeMaps_;
//- Do I need to write (eg, master only for reconstruct)
bool isWriteProc_;
// Private Member Functions
//- Construct internal edge mapping
void createInternalEdgeMap() const;
//- Construct per-patch edge mapping
void createPatchMaps() const;
static mapDistributePolyMesh createReconstructMap
(
const faMesh& mesh,
const autoPtr<faMesh>& baseMeshPtr,
const labelUList& faceProcAddr,
const labelUList& edgeProcAddr,
const labelUList& pointProcAddr,
const labelUList& boundaryProcAddr
);
//- No copy construct
faMeshDistributor(const faMeshDistributor&) = delete;
//- No copy assignment
void operator=(const faMeshDistributor&) = delete;
public:
//- Output verbosity when writing
static int verbose_;
// Constructors
//- Construct from components
faMeshDistributor
(
const faMesh& srcMesh,
const faMesh& tgtMesh,
const mapDistributePolyMesh& faDistMap,
const bool isWriteProc = false
);
// Static Methods
//- Distribute mesh according to the given (volume) mesh distribution.
// Uses 'tgtPolyMesh' for the new mesh
static mapDistributePolyMesh distribute
(
const faMesh& oldMesh,
const mapDistributePolyMesh& distMap, //! From polyMesh
const polyMesh& tgtPolyMesh,
autoPtr<faMesh>& newMeshPtr
);
//- Distribute mesh according to the given (volume) mesh distribution.
// Re-uses polyMesh from oldMesh for the new mesh
static mapDistributePolyMesh distribute
(
const faMesh& oldMesh,
const mapDistributePolyMesh& distMap, //! From polyMesh
autoPtr<faMesh>& newMeshPtr
);
// Member Functions
//- 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 area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh>>
distributeField
(
const GeometricField<Type, faPatchField, areaMesh>& fld
) const;
//- Distribute edge field
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh>>
distributeField
(
const GeometricField<Type, faePatchField, edgeMesh>& fld
) const;
//- Read and distribute area field
template<class Type>
tmp<GeometricField<Type, faPatchField, areaMesh>>
distributeAreaField
(
const IOobject& fieldObject
) const;
//- Read and distribute edge field
template<class Type>
tmp<GeometricField<Type, faePatchField, edgeMesh>>
distributeEdgeField
(
const IOobject& fieldObject
) const;
//- Read, distribute and write all/selected area fields
template<class Type>
label distributeAreaFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
//- Read, distribute and write all/selected area fields
template<class Type>
label distributeEdgeFields
(
const IOobjectList& objects,
const wordRes& selectedFields = wordRes()
) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "faMeshDistributorTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //
This diff is collapsed.
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "Time.H"
#include "emptyFaPatchField.H"
#include "emptyFaePatchField.H"
#include "IOobjectList.H"
#include "polyMesh.H"
#include "polyPatch.H"
#include "processorFaPatch.H"
#include "mapDistribute.H"
#include "mapDistributePolyMesh.H"
#include "areaFields.H"
#include "edgeFields.H"
#include "distributedFieldMapper.H"
#include "distributedFaPatchFieldMapper.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>>
Foam::faMeshDistributor::distributeField
(
const GeometricField<Type, faPatchField, areaMesh>& fld
) const
{
typedef typename
GeometricField<Type, faPatchField, areaMesh>::Patch
PatchFieldType;
if (tgtMesh_.boundary().size() && patchEdgeMaps_.empty())
{
createPatchMaps();
}
// Create internalField by remote mapping
const distributedFieldMapper mapper
(
labelUList::null(),
distMap_.cellMap() // area: faceMap (volume: cellMap)
);
DimensionedField<Type, areaMesh> internalField
(
IOobject
(
fld.name(),
tgtMesh_.time().timeName(),
fld.local(),
tgtMesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh_,
fld.dimensions(),
Field<Type>(fld.internalField(), mapper)
);
internalField.oriented() = fld.oriented();
// Create patchFields by remote mapping
PtrList<PatchFieldType> newPatchFields(tgtMesh_.boundary().size());
const auto& bfld = fld.boundaryField();
forAll(bfld, patchi)
{
if (patchEdgeMaps_.set(patchi))
{
// Clone local patch field
const distributedFaPatchFieldMapper mapper
(
labelUList::null(),
patchEdgeMaps_[patchi]
);
// Map into local copy
newPatchFields.set
(
patchi,
PatchFieldType::New
(
bfld[patchi],
tgtMesh_.boundary()[patchi],
DimensionedField<Type, areaMesh>::null(),
mapper
)
);
}
}
// Add 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,
PatchFieldType::New
(
emptyFaPatchField<Type>::typeName,
tgtMesh_.boundary()[patchi],
DimensionedField<Type, areaMesh>::null()
)
);
}
}
auto tresult = tmp<GeometricField<Type, faPatchField, areaMesh>>::New
(
std::move(internalField),
newPatchFields
);
auto& result = tresult.ref();
result.boundaryFieldRef().template evaluateCoupled<processorFaPatch>();
return tresult;
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>>
Foam::faMeshDistributor::distributeField
(
const GeometricField<Type, faePatchField, edgeMesh>& fld
) const
{
typedef typename
GeometricField<Type, faePatchField, edgeMesh>::Patch
PatchFieldType;
if (!internalEdgeMap_)
{
createInternalEdgeMap();
}
// Create internalField by remote mapping
const distributedFieldMapper mapper
(
labelUList::null(),
*(internalEdgeMap_)
);
DimensionedField<Type, edgeMesh> internalField
(
IOobject
(
fld.name(),
tgtMesh_.time().timeName(),
fld.local(),
tgtMesh_.thisDb(),
IOobject::NO_READ,
IOobject::NO_WRITE
),
tgtMesh_,
fld.dimensions(),
Field<Type>(fld.internalField(), mapper)
);
internalField.oriented() = fld.oriented();
// Create patchFields by remote mapping
PtrList<PatchFieldType> newPatchFields(tgtMesh_.boundary().size());
const auto& bfld = fld.boundaryField();
forAll(bfld, patchi)
{
if (patchEdgeMaps_.set(patchi))
{
// Clone local patch field
const distributedFaPatchFieldMapper mapper
(
labelUList::null(),
patchEdgeMaps_[patchi]
);
// Map into local copy
newPatchFields.set
(
patchi,
PatchFieldType::New
(
bfld[patchi],
tgtMesh_.boundary()[patchi],
DimensionedField<Type, edgeMesh>::null(),
mapper
)
);
}
}
// Add 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,
PatchFieldType::New
(
emptyFaePatchField<Type>::typeName,
tgtMesh_.boundary()[patchi],
DimensionedField<Type, edgeMesh>::null()
)
);
}
}
return tmp<GeometricField<Type, faePatchField, edgeMesh>>::New
(
std::move(internalField),
newPatchFields
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faPatchField, Foam::areaMesh>>
Foam::faMeshDistributor::distributeAreaField
(
const IOobject& fieldObject
) const
{
// Read field
GeometricField<Type, faPatchField, areaMesh> fld
(
fieldObject,
srcMesh_
);
// Redistribute
return distributeField(fld);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::faePatchField, Foam::edgeMesh>>
Foam::faMeshDistributor::distributeEdgeField
(
const IOobject& fieldObject
) const
{
// Read field
GeometricField<Type, faePatchField, edgeMesh> fld
(
fieldObject,
srcMesh_
);
// Redistribute
return distributeField(fld);
}
template<class Type>
Foam::label Foam::faMeshDistributor::distributeAreaFields
(
const IOobjectList& objects,
const wordRes& selectedFields
) const
{
typedef GeometricField<Type, faPatchField, areaMesh> fieldType;
label nFields = 0;
for
(
const IOobject& io :
(
selectedFields.empty()
? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
)
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << nl;
}
++nFields;
tmp<fieldType> tfld(distributeAreaField<Type>(io));
if (isWriteProc_)
{
tfld().write();
}
}
if (nFields && verbose_) Info<< endl;
return nFields;
}
template<class Type>
Foam::label Foam::faMeshDistributor::distributeEdgeFields
(
const IOobjectList& objects,
const wordRes& selectedFields
) const
{
typedef GeometricField<Type, faePatchField, edgeMesh> fieldType;
label nFields = 0;
for
(
const IOobject& io :
(
selectedFields.empty()
? objects.sorted<fieldType>()
: objects.sorted<fieldType>(selectedFields)
)
)
{
if (verbose_)
{
if (!nFields)
{
Info<< " Reconstructing "
<< fieldType::typeName << "s\n" << nl;
}
Info<< " " << io.name() << nl;
}
++nFields;
tmp<fieldType> tfld(distributeEdgeField<Type>(io));
if (isWriteProc_)
{
tfld().write();
}
}
if (nFields && verbose_) Info<< endl;
return nFields;
}
#if 0
template<class Type>
void Foam::faMeshDistributor::redistributeAndWrite
(
PtrList<GeometricField<Type, faPatchField, areaMesh>>& flds
) const
{
for (auto& fld : flds)
{
Pout<< "process: " << fld.name() << endl;
tmp<GeometricField<Type, faPatchField, areaMesh>> tfld =
this->distributeField(fld);
if (isWriteProc_)
{
tfld().write();
}
}
}
template<class Type>
void Foam::faMeshDistributor::redistributeAndWrite
(
PtrList<GeometricField<Type, faePatchField, edgeMesh>>& flds
) const
{
for (auto& fld : flds)
{
tmp<GeometricField<Type, faePatchField, edgeMesh>> tfld =
this->distributeField(fld);
if (isWriteProc_)
{
tfld().write();
}
}
}
#endif
// ************************************************************************* //
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment