/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022-2023 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;
const UPtrList fieldObjects
(
selectedFields.empty()
? objects.csorted()
: objects.csorted(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_.good())
{
if (isWriteProc_)
{
tfld().write();
}
}
else if (writeHandler_ && writeHandler_->good())
{
auto oldHandler = fileOperation::fileHandler(writeHandler_);
const label oldComm = UPstream::commWorld(fileHandler().comm());
tfld().write();
writeHandler_ = fileOperation::fileHandler(oldHandler);
UPstream::commWorld(oldComm);
}
}
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);
}
}
// ************************************************************************* //