Files
OpenFOAM-12/src/dynamicMesh/fvMeshDistribute/fvMeshDistributeTemplates.C
Henry Weller 5f7993dab4 Replaced inconsistently named local typedefs with VolField, SurfaceField and PointField
making the code more consistent and readable.
2022-12-02 10:54:21 +00:00

413 lines
11 KiB
C++

/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
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 "polyTopoChangeMap.H"
#include "processorFvPatchField.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class GeoField>
void Foam::fvMeshDistribute::printFieldInfo(const fvMesh& mesh)
{
HashTable<const GeoField*> flds
(
mesh.objectRegistry::lookupClass<GeoField>()
);
forAllConstIter(typename HashTable<const GeoField*>, flds, iter)
{
const GeoField& fld = *iter();
Pout<< "Field:" << iter.key() << " internal size:" << fld.size()
<< endl;
forAll(fld.boundaryField(), patchi)
{
Pout<< " " << patchi
<< ' ' << fld.boundaryField()[patchi].patch().name()
<< ' ' << fld.boundaryField()[patchi].type()
<< ' ' << fld.boundaryField()[patchi].size()
<< endl;
}
}
}
template<class Type, class Mesh>
void Foam::fvMeshDistribute::saveBoundaryFields
(
PtrList<FieldField<fvsPatchField, Type>>& bflds
) const
{
// Save whole boundary field
HashTable<const SurfaceField<Type>*> flds
(
static_cast<const fvMesh&>(mesh_)
.objectRegistry::lookupClass<SurfaceField<Type>>()
);
bflds.setSize(flds.size());
label i = 0;
forAllConstIter(typename HashTable<const SurfaceField<Type>*>, flds, iter)
{
const SurfaceField<Type>& fld = *iter();
bflds.set(i, fld.boundaryField().clone().ptr());
i++;
}
}
template<class Type, class Mesh>
void Foam::fvMeshDistribute::mapBoundaryFields
(
const polyTopoChangeMap& map,
const PtrList<FieldField<fvsPatchField, Type>>& oldBflds
)
{
// Map boundary field
const labelList& oldPatchStarts = map.oldPatchStarts();
const labelList& faceMap = map.faceMap();
HashTable<SurfaceField<Type>*> flds
(
mesh_.objectRegistry::lookupClass<SurfaceField<Type>>()
);
if (flds.size() != oldBflds.size())
{
FatalErrorInFunction
<< abort(FatalError);
}
label fieldi = 0;
forAllIter(typename HashTable<SurfaceField<Type>*>, flds, iter)
{
SurfaceField<Type>& fld = *iter();
typename SurfaceField<Type>::Boundary& bfld =
fld.boundaryFieldRef();
const FieldField<fvsPatchField, Type>& oldBfld = oldBflds[fieldi++];
// Pull from old boundary field into bfld.
forAll(bfld, patchi)
{
fvsPatchField<Type>& patchFld = bfld[patchi];
label facei = patchFld.patch().start();
forAll(patchFld, i)
{
label oldFacei = faceMap[facei++];
// Find patch and local patch face oldFacei was in.
forAll(oldPatchStarts, oldPatchi)
{
label oldLocalI = oldFacei - oldPatchStarts[oldPatchi];
if (oldLocalI >= 0 && oldLocalI < oldBfld[oldPatchi].size())
{
patchFld[i] = oldBfld[oldPatchi][oldLocalI];
}
}
}
}
}
}
template<class Type>
void Foam::fvMeshDistribute::initMapExposedFaces
(
PtrList<Field<Type>>& iflds
) const
{
HashTable<const SurfaceField<Type>*> flds
(
static_cast<const fvMesh&>(mesh_).lookupClass<SurfaceField<Type>>()
);
iflds.setSize(flds.size());
label fieldi = 0;
forAllConstIter(typename HashTable<const SurfaceField<Type>*>, flds, iter)
{
iflds.set(fieldi, Field<Type>(mesh_.nFaces()));
const SurfaceField<Type>& fld = *iter();
SubList<Type>(iflds[fieldi], fld.primitiveField().size()) =
fld.primitiveField();
forAll(fld.boundaryField(), patchi)
{
const fvsPatchField<Type>& pfld = fld.boundaryField()[patchi];
SubList<Type>(iflds[fieldi], pfld.size(), pfld.patch().start()) =
pfld;
}
fieldi++;
}
}
template<class Type>
void Foam::fvMeshDistribute::mapExposedFaces
(
const polyTopoChangeMap& map,
const PtrList<Field<Type>>& oldFlds
)
{
HashTable<SurfaceField<Type>*> flds
(
mesh_.objectRegistry::lookupClass<SurfaceField<Type>>()
);
label fieldi = 0;
forAllIter(typename HashTable<SurfaceField<Type>*>, flds, iter)
{
SurfaceField<Type>& fld = *iter();
const Field<Type>& oldFld = oldFlds[fieldi];
const bool negateIfFlipped = isFlux(fld);
forAll(fld.boundaryField(), patchi)
{
fvsPatchField<Type>& patchFld = fld.boundaryFieldRef()[patchi];
forAll(patchFld, i)
{
const label facei = patchFld.patch().start()+i;
const label oldFacei = map.faceMap()[facei];
if (oldFacei < map.nOldInternalFaces())
{
if (negateIfFlipped && map.flipFaceFlux().found(facei))
{
patchFld[i] = flipOp()(oldFld[oldFacei]);
}
else
{
patchFld[i] = oldFld[oldFacei];
}
}
else
{
patchFld[i] = oldFld[oldFacei];
}
}
}
fieldi++;
}
}
template<class GeoField>
void Foam::fvMeshDistribute::correctCoupledPatchFields()
{
HashTable<GeoField*> flds
(
mesh_.objectRegistry::lookupClass<GeoField>()
);
forAllIter(typename HashTable<GeoField*>, flds, iter)
{
GeoField& fld = *iter();
typename GeoField::Boundary& bfld = fld.boundaryFieldRef();
if
(
Pstream::defaultCommsType == Pstream::commsTypes::blocking
|| Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
label nReq = Pstream::nRequests();
forAll(bfld, patchi)
{
if (bfld[patchi].coupled())
{
bfld[patchi].initEvaluate(Pstream::defaultCommsType);
}
}
// Block for any outstanding requests
if
(
Pstream::parRun()
&& Pstream::defaultCommsType == Pstream::commsTypes::nonBlocking
)
{
Pstream::waitRequests(nReq);
}
forAll(bfld, patchi)
{
if (bfld[patchi].coupled())
{
bfld[patchi].evaluate(Pstream::defaultCommsType);
}
}
}
else if (Pstream::defaultCommsType == Pstream::commsTypes::scheduled)
{
const lduSchedule& patchSchedule =
mesh_.globalData().patchSchedule();
forAll(patchSchedule, patchEvali)
{
if (bfld[patchEvali].coupled())
{
if (patchSchedule[patchEvali].init)
{
bfld[patchSchedule[patchEvali].patch]
.initEvaluate(Pstream::commsTypes::scheduled);
}
else
{
bfld[patchSchedule[patchEvali].patch]
.evaluate(Pstream::commsTypes::scheduled);
}
}
}
}
}
}
template<class GeoField>
void Foam::fvMeshDistribute::sendFields
(
const label domain,
const wordList& fieldNames,
const fvMeshSubset& subsetter,
Ostream& toNbr
)
{
// Send fields. Note order supplied so we can receive in exactly the same
// order.
// Note that field gets written as entry in dictionary so we
// can construct from subdictionary.
// (since otherwise the reading as-a-dictionary mixes up entries from
// consecutive fields)
// The dictionary constructed is:
// volScalarField
// {
// p {internalField ..; boundaryField ..;}
// k {internalField ..; boundaryField ..;}
// }
// volVectorField
// {
// U {internalField ... }
// }
// volVectorField {U {internalField ..; boundaryField ..;}}
toNbr << GeoField::typeName << token::NL << token::BEGIN_BLOCK << token::NL;
forAll(fieldNames, i)
{
if (debug)
{
Pout<< "Subsetting field " << fieldNames[i]
<< " for domain:" << domain << endl;
}
// Send all fieldNames. This has to be exactly the same set as is
// being received!
const GeoField& fld =
subsetter.baseMesh().lookupObject<GeoField>(fieldNames[i]);
tmp<GeoField> tsubfld = subsetter.interpolate(fld);
toNbr
<< fieldNames[i] << token::NL << token::BEGIN_BLOCK
<< tsubfld
<< token::NL << token::END_BLOCK << token::NL;
}
toNbr << token::END_BLOCK << token::NL;
}
template<class GeoField>
void Foam::fvMeshDistribute::receiveFields
(
const label domain,
const wordList& fieldNames,
typename GeoField::Mesh& mesh,
PtrList<GeoField>& fields,
const dictionary& fieldDicts
)
{
if (debug)
{
Pout<< "Receiving fields " << fieldNames
<< " from domain:" << domain << endl;
}
fields.setSize(fieldNames.size());
forAll(fieldNames, i)
{
if (debug)
{
Pout<< "Constructing field " << fieldNames[i]
<< " from domain:" << domain << endl;
}
fields.set
(
i,
new GeoField
(
IOobject
(
fieldNames[i],
mesh.thisDb().time().name(),
mesh.thisDb(),
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
mesh,
fieldDicts.subDict(fieldNames[i])
)
);
}
}
// ************************************************************************* //