decomposePar, reconstructPar: Do all regions simultaneously

DecomposePar and reconstructPar now interleave the processing of
multiple regions. This means that with the -allRegions option, the
earlier times are completed in their entirety before later times are
considered. It also lets regions to access each other during
decomposition and reconstruction, which will be important for
non-conformal region interfaces.

To aid interpretation of the log, region prefixing is now used by both
utilities in the same way as is done by foamMultiRun.

DecomposePar has been overhauled so that it matches reconstructPar much
more closely, both in terms of output and of iteration sequence. All
meshes and addressing are loaded simultaneously and each field is
considered in turn. Previously, all the fields were loaded, and each
process and addressing set was considered in turn. This new strategy
optimises memory usage for cases with lots of fields.
This commit is contained in:
Will Bainbridge
2023-07-20 11:42:18 +01:00
parent 58e15f296c
commit 71ccf51ba5
43 changed files with 4246 additions and 4028 deletions

View File

@ -1,5 +1,4 @@
decomposePar.C
dimFieldDecomposer.C
fvFieldDecomposer.C
pointFieldDecomposer.C
lagrangianFieldDecomposer.C

View File

@ -1,49 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2021 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 "dimFieldDecomposer.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::dimFieldDecomposer::dimFieldDecomposer
(
const fvMesh& completeMesh,
const fvMesh& procMesh,
const labelList& faceAddressing,
const labelList& cellAddressing
)
:
procMesh_(procMesh),
cellAddressing_(cellAddressing)
{}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::dimFieldDecomposer::~dimFieldDecomposer()
{}
// ************************************************************************* //

View File

@ -1,121 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2020 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/>.
Class
Foam::dimFieldDecomposer
Description
Dimensioned field decomposer.
SourceFiles
dimFieldDecomposer.C
dimFieldDecomposerDecomposeFields.C
\*---------------------------------------------------------------------------*/
#ifndef dimFieldDecomposer_H
#define dimFieldDecomposer_H
#include "fvMesh.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class IOobjectList;
/*---------------------------------------------------------------------------*\
Class fvFieldDecomposer Declaration
\*---------------------------------------------------------------------------*/
class dimFieldDecomposer
{
// Private Data
//- Reference to processor mesh
const fvMesh& procMesh_;
//- Reference to cell addressing
const labelList& cellAddressing_;
public:
// Constructors
//- Construct from components
dimFieldDecomposer
(
const fvMesh& completeMesh,
const fvMesh& procMesh,
const labelList& faceAddressing,
const labelList& cellAddressing
);
//- Disallow default bitwise copy construction
dimFieldDecomposer(const dimFieldDecomposer&) = delete;
//- Destructor
~dimFieldDecomposer();
// Member Functions
//- Decompose field
template<class Type>
tmp<DimensionedField<Type, volMesh>> decomposeField
(
const DimensionedField<Type, volMesh>& field
) const;
//- Decompose llist of fields
template<class GeoField>
void decomposeFields(const PtrList<GeoField>& fields) const;
// Member Operators
//- Disallow default bitwise assignment
void operator=(const dimFieldDecomposer&) = delete;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "dimFieldDecomposerDecomposeFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,75 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "dimFieldDecomposer.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
Foam::dimFieldDecomposer::decomposeField
(
const DimensionedField<Type, volMesh>& field
) const
{
// Create and map the internal field values
Field<Type> mappedField(field, cellAddressing_);
// Create the field for the processor
return tmp<DimensionedField<Type, volMesh>>
(
new DimensionedField<Type, volMesh>
(
IOobject
(
field.name(),
procMesh_.time().name(),
procMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procMesh_,
field.dimensions(),
mappedField
)
);
}
template<class GeoField>
void Foam::dimFieldDecomposer::decomposeFields
(
const PtrList<GeoField>& fields
) const
{
forAll(fields, fieldi)
{
decomposeField(fields[fieldi])().write();
}
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -29,10 +29,11 @@ License
Foam::label Foam::fvFieldDecomposer::completePatchID
(
const label proci,
const label procPatchi
) const
{
const fvPatch& procPatch = procMesh_.boundary()[procPatchi];
const fvPatch& procPatch = procMeshes_[proci].boundary()[procPatchi];
if (procPatchi < completeMesh_.boundary().size())
{
@ -64,34 +65,45 @@ Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer
Foam::fvFieldDecomposer::fvFieldDecomposer
(
const fvMesh& completeMesh,
const fvMesh& procMesh,
const labelList& faceAddressing,
const labelList& cellAddressing,
const surfaceLabelField::Boundary& faceAddressingBf
const PtrList<fvMesh>& procMeshes,
const labelListList& faceProcAddressing,
const labelListList& cellProcAddressing,
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf
)
:
completeMesh_(completeMesh),
procMesh_(procMesh),
faceAddressing_(faceAddressing),
cellAddressing_(cellAddressing),
faceAddressingBf_(faceAddressingBf),
patchFieldDecomposers_(procMesh_.boundary().size())
procMeshes_(procMeshes),
faceProcAddressing_(faceProcAddressing),
cellProcAddressing_(cellProcAddressing),
faceProcAddressingBf_(faceProcAddressingBf),
patchFieldDecomposers_(procMeshes_.size())
{
forAll(procMesh_.boundary(), procPatchi)
forAll(procMeshes_, proci)
{
const label completePatchi = completePatchID(procPatchi);
// If there is a corresponding complete patch then create a patch mapper
if (completePatchi >= 0)
{
patchFieldDecomposers_.set
patchFieldDecomposers_.set
(
proci,
new PtrList<patchFieldDecomposer>
(
procPatchi,
new patchFieldDecomposer
procMeshes_[proci].boundary().size()
)
);
forAll(procMeshes_[proci].boundary(), procPatchi)
{
const label completePatchi = completePatchID(proci, procPatchi);
if (completePatchi >= 0)
{
patchFieldDecomposers_[proci].set
(
faceAddressingBf[completePatchi]
)
);
procPatchi,
new patchFieldDecomposer
(
faceProcAddressingBf[proci][completePatchi]
)
);
}
}
}
}
@ -103,4 +115,22 @@ Foam::fvFieldDecomposer::~fvFieldDecomposer()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::fvFieldDecomposer::decomposes(const IOobjectList& objects)
{
bool result = false;
#define DO_FV_FIELDS_TYPE(Type, nullArg) \
result = result \
|| !objects.lookupClass(VolField<Type>::Internal::typeName).empty() \
|| !objects.lookupClass(VolField<Type>::typeName).empty() \
|| !objects.lookupClass(SurfaceField<Type>::typeName).empty();
FOR_ALL_FIELD_TYPES(DO_FV_FIELDS_TYPE)
#undef DO_FV_FIELDS_TYPE
return result;
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -29,7 +29,7 @@ Description
SourceFiles
fvFieldDecomposer.C
fvFieldDecomposerDecomposeFields.C
fvFieldDecomposerTemplates.C
\*---------------------------------------------------------------------------*/
@ -37,8 +37,10 @@ SourceFiles
#define fvFieldDecomposer_H
#include "fvMesh.H"
#include "directFvPatchFieldMapper.H"
#include "IOobjectList.H"
#include "volFields.H"
#include "surfaceFields.H"
#include "directFvPatchFieldMapper.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -79,26 +81,26 @@ private:
//- Reference to complete mesh
const fvMesh& completeMesh_;
//- Reference to processor mesh
const fvMesh& procMesh_;
//- List of processor meshes
const PtrList<fvMesh>& procMeshes_;
//- Reference to face addressing
const labelList& faceAddressing_;
const labelListList& faceProcAddressing_;
//- Reference to cell addressing
const labelList& cellAddressing_;
const labelListList& cellProcAddressing_;
//- Reference to face addressing boundary field
const surfaceLabelField::Boundary& faceAddressingBf_;
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf_;
//- List of patch field decomposers
PtrList<patchFieldDecomposer> patchFieldDecomposers_;
PtrList<PtrList<patchFieldDecomposer>> patchFieldDecomposers_;
// Private Member Functions
//- Convert a processor patch to the corresponding complete patch index
label completePatchID(const label procPatchi) const;
label completePatchID(const label proci, const label procPatchi) const;
//- Map cell values to faces
template<class Type>
@ -119,6 +121,21 @@ private:
const bool isFlux
);
//- Decompose a volume internal field
template<class Type>
PtrList<typename VolField<Type>::Internal>
decomposeVolInternalField(const IOobject& fieldIoObject) const;
//- Decompose a volume field
template<class Type>
PtrList<VolField<Type>>
decomposeVolField(const IOobject& fieldIoObject) const;
//- Decompose a surface field
template<class Type>
PtrList<SurfaceField<Type>>
decomposeFvSurfaceField(const IOobject& fieldIoObject) const;
public:
@ -128,10 +145,10 @@ public:
fvFieldDecomposer
(
const fvMesh& completeMesh,
const fvMesh& procMesh,
const labelList& faceAddressing,
const labelList& cellAddressing,
const surfaceLabelField::Boundary& faceAddressingBf
const PtrList<fvMesh>& procMeshes,
const labelListList& faceProcAddressing,
const labelListList& cellProcAddressing,
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf
);
//- Disallow default bitwise copy construction
@ -144,25 +161,20 @@ public:
// Member Functions
//- Decompose volume field
template<class Type>
tmp<VolField<Type>>
decomposeField
(
const VolField<Type>& field
) const;
//- Return whether anything in the object list gets decomposed
static bool decomposes(const IOobjectList& objects);
//- Decompose surface field
//- Read, decompose and write all volume internal fields
template<class Type>
tmp<SurfaceField<Type>>
decomposeField
(
const SurfaceField<Type>& field
) const;
void decomposeVolInternalFields(const IOobjectList& objects);
//- Decompose a list of fields
template<class GeoField>
void decomposeFields(const PtrList<GeoField>& fields) const;
//- Read, decompose and write all volume fields
template<class Type>
void decomposeVolFields(const IOobjectList& objects);
//- Read, decompose and write all surface fields
template<class Type>
void decomposeFvSurfaceFields(const IOobjectList& objects);
// Member Operators
@ -179,7 +191,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "fvFieldDecomposerDecomposeFields.C"
#include "fvFieldDecomposerTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -1,364 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 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 "fvFieldDecomposer.H"
#include "processorFvPatchField.H"
#include "processorFvsPatchField.H"
#include "processorCyclicFvPatchField.H"
#include "processorCyclicFvsPatchField.H"
#include "emptyFvPatchFields.H"
#include "stringOps.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::fvFieldDecomposer::mapCellToFace
(
const labelUList& owner,
const labelUList& neighbour,
const Field<Type>& field,
const labelUList& addressing
)
{
tmp<Field<Type>> tfld(new Field<Type>(addressing.size()));
Field<Type>& fld = tfld.ref();
forAll(addressing, i)
{
fld[i] =
field
[
addressing[i] > 0
? neighbour[addressing[i] - 1]
: owner[- addressing[i] - 1]
];
}
return tfld;
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::fvFieldDecomposer::mapFaceToFace
(
const Field<Type>& field,
const labelUList& addressing,
const bool isFlux
)
{
tmp<Field<Type>> tfld(new Field<Type>(addressing.size()));
Field<Type>& fld = tfld.ref();
forAll(addressing, i)
{
fld[i] =
(isFlux && addressing[i] < 0 ? -1 : +1)
*field[mag(addressing[i]) - 1];
}
return tfld;
}
template<class Type>
Foam::tmp<Foam::VolField<Type>>
Foam::fvFieldDecomposer::decomposeField
(
const VolField<Type>& field
) const
{
// Create dummy patch fields
PtrList<fvPatchField<Type>> patchFields(procMesh_.boundary().size());
forAll(procMesh_.boundary(), procPatchi)
{
patchFields.set
(
procPatchi,
fvPatchField<Type>::New
(
calculatedFvPatchField<Type>::typeName,
procMesh_.boundary()[procPatchi],
DimensionedField<Type, volMesh>::null()
)
);
}
// Create the processor field with the dummy patch fields
tmp<VolField<Type>> tresF
(
new VolField<Type>
(
IOobject
(
field.name(),
procMesh_.time().name(),
procMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procMesh_,
field.dimensions(),
Field<Type>(field.primitiveField(), cellAddressing_),
patchFields
)
);
VolField<Type>& resF = tresF.ref();
// Change the patch fields to the correct type using a mapper constructor
// (with reference to the now correct internal field)
typename VolField<Type>::
Boundary& bf = resF.boundaryFieldRef();
forAll(bf, procPatchi)
{
const fvPatch& procPatch = procMesh_.boundary()[procPatchi];
const label completePatchi = completePatchID(procPatchi);
if (completePatchi == procPatchi)
{
bf.set
(
procPatchi,
fvPatchField<Type>::New
(
field.boundaryField()[completePatchi],
procPatch,
resF(),
patchFieldDecomposers_[procPatchi]
)
);
}
else if (isA<processorCyclicFvPatch>(procPatch))
{
if (field.boundaryField()[completePatchi].overridesConstraint())
{
OStringStream str;
str << "\nThe field \"" << field.name()
<< "\" on cyclic patch \""
<< field.boundaryField()[completePatchi].patch().name()
<< "\" cannot be decomposed as it is not a cyclic "
<< "patch field. A \"patchType cyclic;\" setting has "
<< "been used to override the cyclic patch type.\n\n"
<< "Cyclic patches like this with non-cyclic boundary "
<< "conditions should be confined to a single "
<< "processor using decomposition constraints.";
FatalErrorInFunction
<< stringOps::breakIntoIndentedLines(str.str()).c_str()
<< exit(FatalError);
}
const label nbrCompletePatchi =
refCast<const processorCyclicFvPatch>(procPatch)
.referPatch().nbrPatchID();
bf.set
(
procPatchi,
new processorCyclicFvPatchField<Type>
(
procPatch,
resF(),
mapCellToFace
(
labelUList(),
completeMesh_.lduAddr().patchAddr(nbrCompletePatchi),
field.primitiveField(),
faceAddressingBf_[procPatchi]
)
)
);
}
else if (isA<processorFvPatch>(procPatch))
{
bf.set
(
procPatchi,
new processorFvPatchField<Type>
(
procPatch,
resF(),
mapCellToFace
(
completeMesh_.owner(),
completeMesh_.neighbour(),
field.primitiveField(),
faceAddressingBf_[procPatchi]
)
)
);
}
else
{
FatalErrorInFunction
<< "Unknown type." << abort(FatalError);
}
}
return tresF;
}
template<class Type>
Foam::tmp<Foam::SurfaceField<Type>>
Foam::fvFieldDecomposer::decomposeField
(
const SurfaceField<Type>& field
) const
{
const SubList<label> faceAddressingIf
(
faceAddressing_,
procMesh_.nInternalFaces()
);
// Create dummy patch fields
PtrList<fvsPatchField<Type>> patchFields(procMesh_.boundary().size());
forAll(procMesh_.boundary(), procPatchi)
{
patchFields.set
(
procPatchi,
fvsPatchField<Type>::New
(
calculatedFvsPatchField<Type>::typeName,
procMesh_.boundary()[procPatchi],
DimensionedField<Type, surfaceMesh>::null()
)
);
}
// Create the processor field with the dummy patch fields
tmp<SurfaceField<Type>> tresF
(
new SurfaceField<Type>
(
IOobject
(
field.name(),
procMesh_.time().name(),
procMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procMesh_,
field.dimensions(),
mapFaceToFace
(
field,
faceAddressingIf,
isFlux(field)
),
patchFields
)
);
SurfaceField<Type>& resF = tresF.ref();
// Change the patch fields to the correct type using a mapper constructor
// (with reference to the now correct internal field)
typename SurfaceField<Type>::
Boundary& bf = resF.boundaryFieldRef();
forAll(procMesh_.boundary(), procPatchi)
{
const fvPatch& procPatch = procMesh_.boundary()[procPatchi];
const label completePatchi = completePatchID(procPatchi);
if (completePatchi == procPatchi)
{
bf.set
(
procPatchi,
fvsPatchField<Type>::New
(
field.boundaryField()[procPatchi],
procPatch,
resF(),
patchFieldDecomposers_[procPatchi]
)
);
}
else if (isA<processorCyclicFvPatch>(procPatch))
{
bf.set
(
procPatchi,
new processorCyclicFvsPatchField<Type>
(
procPatch,
resF(),
mapFaceToFace
(
field.boundaryField()[completePatchi],
faceAddressingBf_[procPatchi],
isFlux(field)
)
)
);
}
else if (isA<processorFvPatch>(procPatch))
{
bf.set
(
procPatchi,
new processorFvsPatchField<Type>
(
procPatch,
resF(),
mapFaceToFace
(
field.primitiveField(),
faceAddressingBf_[procPatchi],
isFlux(field)
)
)
);
}
else
{
FatalErrorInFunction
<< "Unknown type." << abort(FatalError);
}
}
return tresF;
}
template<class GeoField>
void Foam::fvFieldDecomposer::decomposeFields
(
const PtrList<GeoField>& fields
) const
{
forAll(fields, fieldi)
{
decomposeField(fields[fieldi])().write();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,550 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 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 "fvFieldDecomposer.H"
#include "processorFvPatchField.H"
#include "processorFvsPatchField.H"
#include "processorCyclicFvPatchField.H"
#include "processorCyclicFvsPatchField.H"
#include "emptyFvPatchFields.H"
#include "stringOps.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::fvFieldDecomposer::mapCellToFace
(
const labelUList& owner,
const labelUList& neighbour,
const Field<Type>& field,
const labelUList& addressing
)
{
tmp<Field<Type>> tfld(new Field<Type>(addressing.size()));
Field<Type>& fld = tfld.ref();
forAll(addressing, i)
{
fld[i] =
field
[
addressing[i] > 0
? neighbour[addressing[i] - 1]
: owner[- addressing[i] - 1]
];
}
return tfld;
}
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::fvFieldDecomposer::mapFaceToFace
(
const Field<Type>& field,
const labelUList& addressing,
const bool isFlux
)
{
tmp<Field<Type>> tfld(new Field<Type>(addressing.size()));
Field<Type>& fld = tfld.ref();
forAll(addressing, i)
{
fld[i] =
(isFlux && addressing[i] < 0 ? -1 : +1)
*field[mag(addressing[i]) - 1];
}
return tfld;
}
template<class Type>
Foam::PtrList<typename Foam::VolField<Type>::Internal>
Foam::fvFieldDecomposer::decomposeVolInternalField
(
const IOobject& fieldIoObject
) const
{
// Read the field
const typename VolField<Type>::Internal field
(
IOobject
(
fieldIoObject.name(),
completeMesh_.time().name(),
completeMesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
completeMesh_
);
// Construct the processor fields
PtrList<typename VolField<Type>::Internal> procFields(procMeshes_.size());
forAll(procMeshes_, proci)
{
// Create the processor field with the dummy patch fields
procFields.set
(
proci,
new typename VolField<Type>::Internal
(
IOobject
(
fieldIoObject.name(),
procMeshes_[proci].time().name(),
procMeshes_[proci],
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procMeshes_[proci],
field.dimensions(),
Field<Type>(field.field(), cellProcAddressing_[proci])
)
);
}
return procFields;
}
template<class Type>
Foam::PtrList<Foam::VolField<Type>>
Foam::fvFieldDecomposer::decomposeVolField
(
const IOobject& fieldIoObject
) const
{
// Read the field
const VolField<Type> field
(
IOobject
(
fieldIoObject.name(),
completeMesh_.time().name(),
completeMesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
completeMesh_
);
// Construct the processor fields
PtrList<VolField<Type>> procFields(procMeshes_.size());
forAll(procMeshes_, proci)
{
// Create dummy patch fields
PtrList<fvPatchField<Type>> patchFields
(
procMeshes_[proci].boundary().size()
);
forAll(procMeshes_[proci].boundary(), procPatchi)
{
patchFields.set
(
procPatchi,
fvPatchField<Type>::New
(
calculatedFvPatchField<Type>::typeName,
procMeshes_[proci].boundary()[procPatchi],
DimensionedField<Type, volMesh>::null()
)
);
}
// Create the processor field with the dummy patch fields
procFields.set
(
proci,
new VolField<Type>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[proci].time().name(),
procMeshes_[proci],
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procMeshes_[proci],
field.dimensions(),
Field<Type>(field.primitiveField(), cellProcAddressing_[proci]),
patchFields
)
);
// Alias the created proc field
VolField<Type>& vf = procFields[proci];
// Change the patch fields to the correct type using a mapper
// constructor (with reference to the now correct internal field)
typename VolField<Type>::Boundary& bf = vf.boundaryFieldRef();
forAll(bf, procPatchi)
{
const fvPatch& procPatch =
procMeshes_[proci].boundary()[procPatchi];
const label completePatchi = completePatchID(proci, procPatchi);
if (completePatchi == procPatchi)
{
bf.set
(
procPatchi,
fvPatchField<Type>::New
(
field.boundaryField()[completePatchi],
procPatch,
vf(),
patchFieldDecomposers_[proci][procPatchi]
)
);
}
else if (isA<processorCyclicFvPatch>(procPatch))
{
if (field.boundaryField()[completePatchi].overridesConstraint())
{
OStringStream str;
str << "\nThe field \"" << field.name()
<< "\" on cyclic patch \""
<< field.boundaryField()[completePatchi].patch().name()
<< "\" cannot be decomposed as it is not a cyclic "
<< "patch field. A \"patchType cyclic;\" setting has "
<< "been used to override the cyclic patch type.\n\n"
<< "Cyclic patches like this with non-cyclic boundary "
<< "conditions should be confined to a single "
<< "processor using decomposition constraints.";
FatalErrorInFunction
<< stringOps::breakIntoIndentedLines(str.str()).c_str()
<< exit(FatalError);
}
const label nbrCompletePatchi =
refCast<const processorCyclicFvPatch>(procPatch)
.referPatch().nbrPatchID();
bf.set
(
procPatchi,
new processorCyclicFvPatchField<Type>
(
procPatch,
vf(),
mapCellToFace
(
labelUList(),
completeMesh_.lduAddr().patchAddr
(
nbrCompletePatchi
),
field.primitiveField(),
faceProcAddressingBf_[proci][procPatchi]
)
)
);
}
else if (isA<processorFvPatch>(procPatch))
{
bf.set
(
procPatchi,
new processorFvPatchField<Type>
(
procPatch,
vf(),
mapCellToFace
(
completeMesh_.owner(),
completeMesh_.neighbour(),
field.primitiveField(),
faceProcAddressingBf_[proci][procPatchi]
)
)
);
}
else
{
FatalErrorInFunction
<< "Unknown type." << abort(FatalError);
}
}
}
return procFields;
}
template<class Type>
Foam::PtrList<Foam::SurfaceField<Type>>
Foam::fvFieldDecomposer::decomposeFvSurfaceField
(
const IOobject& fieldIoObject
) const
{
// Read the field
const SurfaceField<Type> field
(
IOobject
(
fieldIoObject.name(),
completeMesh_.time().name(),
completeMesh_,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
completeMesh_
);
// Construct the processor fields
PtrList<SurfaceField<Type>> procFields(procMeshes_.size());
forAll(procMeshes_, proci)
{
const SubList<label> faceAddressingIf
(
faceProcAddressing_[proci],
procMeshes_[proci].nInternalFaces()
);
// Create dummy patch fields
PtrList<fvsPatchField<Type>> patchFields
(
procMeshes_[proci].boundary().size()
);
forAll(procMeshes_[proci].boundary(), procPatchi)
{
patchFields.set
(
procPatchi,
fvsPatchField<Type>::New
(
calculatedFvsPatchField<Type>::typeName,
procMeshes_[proci].boundary()[procPatchi],
DimensionedField<Type, surfaceMesh>::null()
)
);
}
// Create the processor field with the dummy patch fields
procFields.set
(
proci,
new SurfaceField<Type>
(
IOobject
(
field.name(),
procMeshes_[proci].time().name(),
procMeshes_[proci],
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procMeshes_[proci],
field.dimensions(),
mapFaceToFace
(
field,
faceAddressingIf,
isFlux(field)
),
patchFields
)
);
// Alias the created proc field
SurfaceField<Type>& sf = procFields[proci];
// Change the patch fields to the correct type using a mapper
// constructor (with reference to the now correct internal field)
typename SurfaceField<Type>::Boundary& bf = sf.boundaryFieldRef();
forAll(procMeshes_[proci].boundary(), procPatchi)
{
const fvPatch& procPatch =
procMeshes_[proci].boundary()[procPatchi];
const label completePatchi = completePatchID(proci, procPatchi);
if (completePatchi == procPatchi)
{
bf.set
(
procPatchi,
fvsPatchField<Type>::New
(
field.boundaryField()[procPatchi],
procPatch,
sf(),
patchFieldDecomposers_[proci][procPatchi]
)
);
}
else if (isA<processorCyclicFvPatch>(procPatch))
{
bf.set
(
procPatchi,
new processorCyclicFvsPatchField<Type>
(
procPatch,
sf(),
mapFaceToFace
(
field.boundaryField()[completePatchi],
faceProcAddressingBf_[proci][procPatchi],
isFlux(field)
)
)
);
}
else if (isA<processorFvPatch>(procPatch))
{
bf.set
(
procPatchi,
new processorFvsPatchField<Type>
(
procPatch,
sf(),
mapFaceToFace
(
field.primitiveField(),
faceProcAddressingBf_[proci][procPatchi],
isFlux(field)
)
)
);
}
else
{
FatalErrorInFunction
<< "Unknown type." << abort(FatalError);
}
}
}
return procFields;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::fvFieldDecomposer::decomposeVolInternalFields
(
const IOobjectList& objects
)
{
const word& fieldClassName = VolField<Type>::Internal::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< nl << " Decomposing " << fieldClassName << "s" << nl << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
Info<< " " << fieldIter()->name() << endl;
PtrList<typename VolField<Type>::Internal> procFields =
decomposeVolInternalField<Type>(*fieldIter());
forAll(procFields, proci)
{
procFields[proci].write();
}
}
}
}
template<class Type>
void Foam::fvFieldDecomposer::decomposeVolFields
(
const IOobjectList& objects
)
{
const word& fieldClassName = VolField<Type>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< nl << " Decomposing " << fieldClassName << "s" << nl << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
Info<< " " << fieldIter()->name() << endl;
PtrList<VolField<Type>> procFields =
decomposeVolField<Type>(*fieldIter());
forAll(procFields, proci)
{
procFields[proci].write();
}
}
}
}
template<class Type>
void Foam::fvFieldDecomposer::decomposeFvSurfaceFields
(
const IOobjectList& objects
)
{
const word& fieldClassName = SurfaceField<Type>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< nl << " Decomposing " << fieldClassName << "s" << nl << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
Info<< " " << fieldIter()->name() << endl;
PtrList<SurfaceField<Type>> procFields =
decomposeFvSurfaceField<Type>(*fieldIter());
forAll(procFields, proci)
{
procFields[proci].write();
}
}
}
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -21,83 +21,161 @@ License
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Description
Lagrangian field decomposer.
\*---------------------------------------------------------------------------*/
#include "lagrangianFieldDecomposer.H"
#include "passiveParticleCloud.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::lagrangianFieldDecomposer::lagrangianFieldDecomposer
(
const polyMesh& mesh,
const polyMesh& procMesh,
const labelList& faceProcAddressing,
const labelList& cellProcAddressing,
const word& cloudName,
const Cloud<indexedParticle>& lagrangianPositions,
const List<SLList<indexedParticle*>*>& cellParticles
const fvMesh& completeMesh,
const PtrList<fvMesh>& procMeshes,
const labelListList& faceProcAddressing,
const labelListList& cellProcAddressing,
const word& cloudName
)
:
procMesh_(procMesh),
positions_(procMesh, cloudName, IDLList<passiveParticle>()),
particleIndices_(lagrangianPositions.size())
completeMesh_(completeMesh),
procMeshes_(procMeshes),
particleProcAddressing_(procMeshes_.size()),
cloudName_(cloudName)
{
label pi = 0;
labelList decodedProcFaceAddressing(faceProcAddressing.size());
forAll(faceProcAddressing, i)
// Create reverse cell addressing
List<remote> cellProcCell(completeMesh_.nCells());
forAll(cellProcAddressing, proci)
{
decodedProcFaceAddressing[i] = mag(faceProcAddressing[i]) - 1;
}
forAll(cellProcAddressing, procCelli)
{
label celli = cellProcAddressing[procCelli];
if (cellParticles[celli])
forAll(cellProcAddressing[proci], procCelli)
{
SLList<indexedParticle*>& particlePtrs = *cellParticles[celli];
forAllConstIter(SLList<indexedParticle*>, particlePtrs, iter)
{
const indexedParticle& ppi = *iter();
particleIndices_[pi++] = ppi.index();
label mappedTetFace = findIndex
(
decodedProcFaceAddressing,
ppi.tetFace()
);
if (mappedTetFace == -1)
{
FatalErrorInFunction
<< "Face lookup failure." << nl
<< abort(FatalError);
}
positions_.append
(
new passiveParticle
(
procMesh,
ppi.coordinates(),
procCelli,
mappedTetFace,
ppi.procTetPt(mesh, procMesh, procCelli, mappedTetFace)
)
);
}
cellProcCell[cellProcAddressing[proci][procCelli]] =
remote(proci, procCelli);
}
}
particleIndices_.setSize(pi);
// Create reverse face addressing
List<remote> faceOwnerProcFace(completeMesh_.nFaces());
List<remote> faceNeighbourProcFace(completeMesh_.nFaces());
forAll(faceProcAddressing, proci)
{
forAll(faceProcAddressing[proci], procFacei)
{
const bool owner = faceProcAddressing[proci][procFacei] > 0;
const label facei = mag(faceProcAddressing[proci][procFacei]) - 1;
IOPosition<Cloud<passiveParticle>>(positions_).write();
(owner ? faceOwnerProcFace : faceNeighbourProcFace)[facei] =
remote(proci, procFacei);
}
}
// Read the complete positions
const passiveParticleCloud completePositions
(
completeMesh_,
cloudName_,
false
);
// Construct empty clouds for processor positions
PtrList<passiveParticleCloud> procPositions(procMeshes_.size());
forAll(procMeshes_, proci)
{
procPositions.set
(
proci,
new passiveParticleCloud
(
procMeshes_[proci],
cloudName_,
IDLList<passiveParticle>()
)
);
}
// Count the number of particles on each processor
labelList procNParticles(procMeshes_.size(), 0);
forAllConstIter(passiveParticleCloud, completePositions, iter)
{
const passiveParticle& p = iter();
const label proci = cellProcCell[p.cell()].proci;
procNParticles[proci] ++;
}
// Resize the addressing
forAll(procMeshes_, proci)
{
particleProcAddressing_[proci].resize(procNParticles[proci], -1);
}
// Distribute positions to the processor meshes
label completeParticlei = 0;
labelList procParticlei(procMeshes_.size(), 0);
forAllConstIter(passiveParticleCloud, completePositions, iter)
{
const passiveParticle& p = iter();
const label proci = cellProcCell[p.cell()].proci;
const label procCelli = cellProcCell[p.cell()].elementi;
const label procFacei =
faceOwnerProcFace[p.tetFace()].proci == proci
? faceOwnerProcFace[p.tetFace()].elementi
: faceNeighbourProcFace[p.tetFace()].elementi;
particleProcAddressing_[proci][procParticlei[proci]] =
completeParticlei;
procPositions[proci].append
(
new passiveParticle
(
procMeshes_[proci],
p.coordinates(),
procCelli,
procFacei,
p.procTetPt
(
completeMesh_,
procMeshes_[proci],
procCelli,
procFacei
)
)
);
completeParticlei ++;
procParticlei[proci] ++;
}
// Write
forAll(procPositions, proci)
{
IOPosition<passiveParticleCloud>(procPositions[proci]).write();
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::lagrangianFieldDecomposer::~lagrangianFieldDecomposer()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::lagrangianFieldDecomposer::decomposes(const IOobjectList& objects)
{
bool result = false;
#define DO_LAGRANGIAN_FIELDS_TYPE(Type, nullArg) \
result = result \
|| !objects.lookupClass(IOField<Type>::typeName).empty() \
|| !objects.lookupClass(IOField<Field<Type>>::typeName).empty() \
|| !objects.lookupClass(CompactIOField<Field<Type>>::typeName).empty();
DO_LAGRANGIAN_FIELDS_TYPE(label, )
FOR_ALL_FIELD_TYPES(DO_LAGRANGIAN_FIELDS_TYPE)
#undef DO_LAGRANGIAN_FIELDS_TYPE
return result;
}

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -29,17 +29,15 @@ Description
SourceFiles
lagrangianFieldDecomposer.C
lagrangianFieldDecomposerDecomposeFields.C
lagrangianFieldDecomposerTemplates.C
\*---------------------------------------------------------------------------*/
#ifndef lagrangianFieldDecomposer_H
#define lagrangianFieldDecomposer_H
#include "Cloud.H"
#include "CompactIOField.H"
#include "indexedParticle.H"
#include "passiveParticle.H"
#include "cloud.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,14 +54,34 @@ class lagrangianFieldDecomposer
{
// Private Data
//- Reference to processor mesh
const polyMesh& procMesh_;
//- Reference to complete mesh
const fvMesh& completeMesh_;
//- Lagrangian positions for this processor
Cloud<passiveParticle> positions_;
//- List of processor meshes
const PtrList<fvMesh>& procMeshes_;
//- The indices of the particles on this processor
labelList particleIndices_;
//- For each processor, for each particle, the global particle index
labelListList particleProcAddressing_;
//- The name of the cloud
const word cloudName_;
// Private Member Functions
//- Decompose a field
template<class Type, template<class> class IOContainer>
PtrList<IOContainer<Type>>
decomposeField(const IOobject& fieldIoObject) const;
//- Read, decompose and write all fields
template
<
class Type,
template<class> class IOContainer,
template<class> class IOContainerType
>
void decomposeFields(const IOobjectList& objects);
public:
@ -73,68 +91,29 @@ public:
//- Construct from components
lagrangianFieldDecomposer
(
const polyMesh& mesh,
const polyMesh& procMesh,
const labelList& faceProcAddressing,
const labelList& cellProcAddressing,
const word& cloudName,
const Cloud<indexedParticle>& lagrangianPositions,
const List<SLList<indexedParticle*>*>& cellParticles
const fvMesh& completeMesh,
const PtrList<fvMesh>& procMeshes,
const labelListList& faceProcAddressing,
const labelListList& cellProcAddressing,
const word& cloudName
);
//- Disallow default bitwise copy construction
lagrangianFieldDecomposer(const lagrangianFieldDecomposer&) = delete;
//- Destructor
~lagrangianFieldDecomposer();
// Member Functions
// Read the fields and hold on the pointer list
//- Return whether anything in the object list gets decomposed
static bool decomposes(const IOobjectList& objects);
//- Read, decompose and write all fields
template<class Type>
static void readFields
(
const label cloudI,
const IOobjectList& lagrangianObjects,
PtrList<PtrList<IOField<Type>>>& lagrangianFields
);
template<class Type>
static void readFieldFields
(
const label cloudI,
const IOobjectList& lagrangianObjects,
PtrList<PtrList<CompactIOField<Field<Type>>>>& lagrangianFields
);
//- Decompose volume field
template<class Type>
tmp<IOField<Type>> decomposeField
(
const word& cloudName,
const IOField<Type>& field
) const;
template<class Type>
tmp<CompactIOField<Field<Type>>> decomposeFieldField
(
const word& cloudName,
const CompactIOField<Field<Type>>& field
) const;
template<class GeoField>
void decomposeFields
(
const word& cloudName,
const PtrList<GeoField>& fields
) const;
template<class GeoField>
void decomposeFieldFields
(
const word& cloudName,
const PtrList<GeoField>& fields
) const;
void decomposeFields(const IOobjectList& objects);
// Member Operators
@ -151,7 +130,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "lagrangianFieldDecomposerDecomposeFields.C"
#include "lagrangianFieldDecomposerTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -1,213 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "lagrangianFieldDecomposer.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::lagrangianFieldDecomposer::readFields
(
const label cloudI,
const IOobjectList& lagrangianObjects,
PtrList<PtrList<IOField<Type>>>& lagrangianFields
)
{
// Search list of objects for lagrangian fields
IOobjectList lagrangianTypeObjects
(
lagrangianObjects.lookupClass(IOField<Type>::typeName)
);
lagrangianFields.set
(
cloudI,
new PtrList<IOField<Type>>
(
lagrangianTypeObjects.size()
)
);
label lagrangianFieldi = 0;
forAllIter(IOobjectList, lagrangianTypeObjects, iter)
{
lagrangianFields[cloudI].set
(
lagrangianFieldi++,
new IOField<Type>(*iter())
);
}
}
template<class Type>
void Foam::lagrangianFieldDecomposer::readFieldFields
(
const label cloudI,
const IOobjectList& lagrangianObjects,
PtrList<PtrList<CompactIOField<Field<Type>>>>& lagrangianFields
)
{
// Search list of objects for lagrangian fields
IOobjectList lagrangianTypeObjectsA
(
lagrangianObjects.lookupClass(IOField<Field<Type>>::typeName)
);
IOobjectList lagrangianTypeObjectsB
(
lagrangianObjects.lookupClass
(
CompactIOField<Field<Type>>::typeName
)
);
lagrangianFields.set
(
cloudI,
new PtrList<CompactIOField<Field<Type>>>
(
lagrangianTypeObjectsA.size() + lagrangianTypeObjectsB.size()
)
);
label lagrangianFieldi = 0;
forAllIter(IOobjectList, lagrangianTypeObjectsA, iter)
{
lagrangianFields[cloudI].set
(
lagrangianFieldi++,
new CompactIOField<Field<Type>>(*iter())
);
}
forAllIter(IOobjectList, lagrangianTypeObjectsB, iter)
{
lagrangianFields[cloudI].set
(
lagrangianFieldi++,
new CompactIOField<Field<Type>>(*iter())
);
}
}
template<class Type>
Foam::tmp<Foam::IOField<Type>>
Foam::lagrangianFieldDecomposer::decomposeField
(
const word& cloudName,
const IOField<Type>& field
) const
{
// Create and map the internal field values
Field<Type> procField(field, particleIndices_);
// Create the field for the processor
return tmp<IOField<Type>>
(
new IOField<Type>
(
IOobject
(
field.name(),
procMesh_.time().name(),
cloud::prefix/cloudName,
procMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procField
)
);
}
template<class Type>
Foam::tmp<Foam::CompactIOField<Foam::Field<Type>>>
Foam::lagrangianFieldDecomposer::decomposeFieldField
(
const word& cloudName,
const CompactIOField<Field<Type>>& field
) const
{
// Create and map the internal field values
Field<Field<Type>> procField(field, particleIndices_);
// Create the field for the processor
return tmp<CompactIOField<Field<Type>>>
(
new CompactIOField<Field<Type>>
(
IOobject
(
field.name(),
procMesh_.time().name(),
cloud::prefix/cloudName,
procMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procField
)
);
}
template<class GeoField>
void Foam::lagrangianFieldDecomposer::decomposeFields
(
const word& cloudName,
const PtrList<GeoField>& fields
) const
{
const bool write = particleIndices_.size() > 0;
forAll(fields, fieldi)
{
decomposeField(cloudName, fields[fieldi])().write(write);
}
}
template<class GeoField>
void Foam::lagrangianFieldDecomposer::decomposeFieldFields
(
const word& cloudName,
const PtrList<GeoField>& fields
) const
{
const bool write = particleIndices_.size() > 0;
forAll(fields, fieldi)
{
decomposeFieldField(cloudName, fields[fieldi])().write(write);
}
}
// ************************************************************************* //

View File

@ -0,0 +1,119 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 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 "lagrangianFieldDecomposer.H"
#include "IOobjectList.H"
#include "CompactIOField.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type, template<class> class IOContainer>
Foam::PtrList<IOContainer<Type>>
Foam::lagrangianFieldDecomposer::decomposeField
(
const IOobject& fieldIoObject
) const
{
// Read the complete field
const IOContainer<Type> field(fieldIoObject);
// Construct the processor fields
PtrList<IOContainer<Type>> procFields(procMeshes_.size());
forAll(procMeshes_, proci)
{
procFields.set
(
proci,
new IOContainer<Type>
(
IOobject
(
field.name(),
procMeshes_[proci].time().name(),
cloud::prefix/cloudName_,
procMeshes_[proci],
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
Field<Type>(field, particleProcAddressing_[proci])
)
);
}
return procFields;
}
template
<
class Type,
template<class> class IOContainer,
template<class> class IOContainerType
>
void Foam::lagrangianFieldDecomposer::decomposeFields
(
const IOobjectList& objects
)
{
const word& fieldClassName = IOContainerType<Type>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< nl << " Decomposing " << fieldClassName << "s" << nl << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
Info<< " " << fieldIter()->name() << endl;
PtrList<IOContainer<Type>> procFields =
decomposeField<Type, IOContainer>(*fieldIter());
forAll(procFields, proci)
{
procFields[proci].write();
}
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::lagrangianFieldDecomposer::decomposeFields
(
const IOobjectList& objects
)
{
decomposeFields<Type, IOField, IOField>(objects);
decomposeFields<Field<Type>, CompactIOField, IOField>(objects);
decomposeFields<Field<Type>, CompactIOField, CompactIOField>(objects);
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -24,6 +24,7 @@ License
\*---------------------------------------------------------------------------*/
#include "pointFieldDecomposer.H"
#include "fvMesh.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -77,29 +78,40 @@ Foam::pointFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer
Foam::pointFieldDecomposer::pointFieldDecomposer
(
const pointMesh& completeMesh,
const pointMesh& procMesh,
const labelList& pointAddressing
const PtrList<fvMesh>& procMeshes,
const labelListList& pointProcAddressing
)
:
completeMesh_(completeMesh),
procMesh_(procMesh),
pointAddressing_(pointAddressing),
patchFieldDecomposers_(procMesh_.boundary().size())
procMeshes_(procMeshes),
pointProcAddressing_(pointProcAddressing),
patchFieldDecomposers_(procMeshes_.size())
{
forAll(procMesh_.boundary(), patchi)
forAll(procMeshes_, proci)
{
if (patchi < completeMesh_.boundary().size())
const pointMesh& procMesh = pointMesh::New(procMeshes_[proci]);
patchFieldDecomposers_.set
(
proci,
new PtrList<patchFieldDecomposer>(procMesh.boundary().size())
);
forAll(procMesh.boundary(), procPatchi)
{
patchFieldDecomposers_.set
(
patchi,
new patchFieldDecomposer
if (procPatchi < completeMesh_.boundary().size())
{
patchFieldDecomposers_[proci].set
(
completeMesh_.boundary()[patchi],
procMesh_.boundary()[patchi],
pointAddressing_
)
);
procPatchi,
new patchFieldDecomposer
(
completeMesh_.boundary()[procPatchi],
procMesh.boundary()[procPatchi],
pointProcAddressing_[proci]
)
);
}
}
}
}
@ -111,4 +123,20 @@ Foam::pointFieldDecomposer::~pointFieldDecomposer()
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::pointFieldDecomposer::decomposes(const IOobjectList& objects)
{
bool result = false;
#define DO_POINT_FIELDS_TYPE(Type, nullArg) \
result = result \
|| !objects.lookupClass(PointField<Type>::typeName).empty();
FOR_ALL_FIELD_TYPES(DO_POINT_FIELDS_TYPE)
#undef DO_POINT_FIELDS_TYPE
return result;
}
// ************************************************************************* //

View File

@ -2,7 +2,7 @@
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
@ -29,7 +29,7 @@ Description
SourceFiles
pointFieldDecomposer.C
pointFieldDecomposerDecomposeFields.C
pointFieldDecomposerTemplates.C
\*---------------------------------------------------------------------------*/
@ -37,14 +37,17 @@ SourceFiles
#define pointFieldDecomposer_H
#include "pointMesh.H"
#include "pointPatchFieldMapperPatchRef.H"
#include "pointFields.H"
#include "pointPatchFieldMapperPatchRef.H"
#include "IOobjectList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class fvMesh;
/*---------------------------------------------------------------------------*\
Class pointFieldDecomposer Declaration
\*---------------------------------------------------------------------------*/
@ -111,14 +114,22 @@ private:
//- Reference to complete mesh
const pointMesh& completeMesh_;
//- Reference to processor mesh
const pointMesh& procMesh_;
//- Reference to processor meshes
const PtrList<fvMesh>& procMeshes_;
//- Reference to point addressing
const labelList& pointAddressing_;
const labelListList& pointProcAddressing_;
//- List of patch field decomposers
PtrList<patchFieldDecomposer> patchFieldDecomposers_;
PtrList<PtrList<patchFieldDecomposer>> patchFieldDecomposers_;
// Private Member Functions
//- Decompose a field
template<class Type>
PtrList<PointField<Type>>
decomposeField(const IOobject& fieldIoObject) const;
public:
@ -129,8 +140,8 @@ public:
pointFieldDecomposer
(
const pointMesh& completeMesh,
const pointMesh& procMesh,
const labelList& pointAddressing
const PtrList<fvMesh>& procMeshes,
const labelListList& pointAddressing
);
//- Disallow default bitwise copy construction
@ -143,17 +154,12 @@ public:
// Member Functions
//- Decompose point field
template<class Type>
tmp<PointField<Type>>
decomposeField
(
const PointField<Type>&
) const;
//- Return whether anything in the object list gets decomposed
static bool decomposes(const IOobjectList& objects);
//- Decompose a list of fields
template<class GeoField>
void decomposeFields(const PtrList<GeoField>& fields) const;
//- Read, decompose and write all fields
template<class Type>
void decomposeFields(const IOobjectList& objects);
// Member Operators
@ -170,7 +176,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "pointFieldDecomposerDecomposeFields.C"
#include "pointFieldDecomposerTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -1,111 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "pointFieldDecomposer.H"
#include "processorPointPatchFields.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::PointField<Type>>
Foam::pointFieldDecomposer::decomposeField
(
const PointField<Type>& field
) const
{
// Create and map the internal field values
Field<Type> internalField(field.primitiveField(), pointAddressing_);
// Create a list of pointers for the patchFields
PtrList<pointPatchField<Type>> patchFields(procMesh_.boundary().size());
// Create and map the patch field values
forAll(procMesh_.boundary(), patchi)
{
if (patchi < completeMesh_.boundary().size())
{
patchFields.set
(
patchi,
pointPatchField<Type>::New
(
field.boundaryField()[patchi],
procMesh_.boundary()[patchi],
DimensionedField<Type, pointMesh>::null(),
patchFieldDecomposers_[patchi]
)
);
}
else
{
patchFields.set
(
patchi,
new processorPointPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, pointMesh>::null()
)
);
}
}
// Create the field for the processor
return tmp<PointField<Type>>
(
new PointField<Type>
(
IOobject
(
field.name(),
procMesh_().time().name(),
procMesh_(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procMesh_,
field.dimensions(),
internalField,
patchFields
)
);
}
template<class GeoField>
void Foam::pointFieldDecomposer::decomposeFields
(
const PtrList<GeoField>& fields
) const
{
forAll(fields, fieldi)
{
decomposeField(fields[fieldi])().write();
}
}
// ************************************************************************* //

View File

@ -0,0 +1,163 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2023 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 "pointFieldDecomposer.H"
#include "fvMesh.H"
#include "processorPointPatchFields.H"
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
template<class Type>
Foam::PtrList<Foam::PointField<Type>>
Foam::pointFieldDecomposer::decomposeField
(
const IOobject& fieldIoObject
) const
{
// Read the field
const PointField<Type> field
(
IOobject
(
fieldIoObject.name(),
completeMesh_.db().time().name(),
completeMesh_.db(),
IOobject::MUST_READ,
IOobject::NO_WRITE,
false
),
completeMesh_
);
// Construct the processor fields
PtrList<PointField<Type>> procFields(procMeshes_.size());
forAll(procMeshes_, proci)
{
const pointMesh& procMesh = pointMesh::New(procMeshes_[proci]);
// Create and map the internal field values
Field<Type> internalField
(
field.primitiveField(),
pointProcAddressing_[proci]
);
// Create a list of pointers for the patchFields
PtrList<pointPatchField<Type>> patchFields
(
procMesh.boundary().size()
);
// Create and map the patch field values
forAll(procMesh.boundary(), patchi)
{
if (patchi < completeMesh_.boundary().size())
{
patchFields.set
(
patchi,
pointPatchField<Type>::New
(
field.boundaryField()[patchi],
procMesh.boundary()[patchi],
DimensionedField<Type, pointMesh>::null(),
patchFieldDecomposers_[proci][patchi]
)
);
}
else
{
patchFields.set
(
patchi,
new processorPointPatchField<Type>
(
procMesh.boundary()[patchi],
DimensionedField<Type, pointMesh>::null()
)
);
}
}
// Create the field for the processor
procFields.set
(
proci,
new PointField<Type>
(
IOobject
(
field.name(),
procMesh().time().name(),
procMesh(),
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procMesh,
field.dimensions(),
internalField,
patchFields
)
);
}
return procFields;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::pointFieldDecomposer::decomposeFields
(
const IOobjectList& objects
)
{
const word& fieldClassName = PointField<Type>::typeName;
IOobjectList fields = objects.lookupClass(fieldClassName);
if (fields.size())
{
Info<< nl << " Decomposing " << fieldClassName << "s" << nl << endl;
forAllConstIter(IOobjectList, fields, fieldIter)
{
Info<< " " << fieldIter()->name() << endl;
PtrList<PointField<Type>> procFields =
decomposeField<Type>(*fieldIter());
forAll(procFields, proci)
{
procFields[proci].write();
}
}
}
}
// ************************************************************************* //

View File

@ -1,107 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / 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 "readFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::readFields
(
const typename GeoMesh::Mesh& mesh,
const IOobjectList& objects,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields,
const bool readOldTime
)
{
// Search list of objects for fields
IOobjectList fieldObjects(objects.lookupClass
(
GeometricField<Type, PatchField, GeoMesh>::typeName)
);
// Remove the cellProc field
IOobjectList::iterator cellProcIter = fieldObjects.find("cellProc");
if (cellProcIter != fieldObjects.end())
{
fieldObjects.erase(cellProcIter);
}
// Get sorted set of names (different processors might read objects in
// different order)
const wordList masterNames(fieldObjects.sortedNames());
// Construct the fields
fields.setSize(masterNames.size());
forAll(masterNames, i)
{
const IOobject& io = *fieldObjects[masterNames[i]];
fields.set
(
i,
new GeometricField<Type, PatchField, GeoMesh>
(
io,
mesh,
readOldTime
)
);
}
}
template<class Mesh, class GeoField>
void Foam::readFields
(
const Mesh& mesh,
const IOobjectList& objects,
PtrList<GeoField>& fields
)
{
// Search list of objects for fields of type GeomField
IOobjectList fieldObjects(objects.lookupClass(GeoField::typeName));
// Construct the fields
fields.setSize(fieldObjects.size());
// Get sorted set of names (different processors might read objects in
// different order)
const wordList masterNames(fieldObjects.sortedNames());
// Construct the fields
fields.setSize(masterNames.size());
forAll(masterNames, i)
{
const IOobject& io = *fieldObjects[masterNames[i]];
fields.set(i, new GeoField(io, mesh));
}
}
// ************************************************************************* //

View File

@ -1,75 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration | Website: https://openfoam.org
\\ / A nd | Copyright (C) 2011-2018 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/>.
Global
readFields
Description
SourceFiles
readFields.C
\*---------------------------------------------------------------------------*/
#ifndef readFields_H
#define readFields_H
#include "IOobjectList.H"
#include "PtrList.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Read the fields and hold on the pointer list
template<class Type, template<class> class PatchField, class GeoMesh>
void readFields
(
const typename GeoMesh::Mesh& mesh,
const IOobjectList& objects,
PtrList<GeometricField<Type, PatchField, GeoMesh>>& fields,
const bool readOldTime
);
// Read the fields and hold on the pointer list
template<class Mesh, class GeoField>
void readFields
(
const Mesh& mesh,
const IOobjectList& objects,
PtrList<GeoField>& fields
);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "readFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //