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:
@ -1,5 +1,4 @@
|
|||||||
decomposePar.C
|
decomposePar.C
|
||||||
dimFieldDecomposer.C
|
|
||||||
fvFieldDecomposer.C
|
fvFieldDecomposer.C
|
||||||
pointFieldDecomposer.C
|
pointFieldDecomposer.C
|
||||||
lagrangianFieldDecomposer.C
|
lagrangianFieldDecomposer.C
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -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()
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -29,10 +29,11 @@ License
|
|||||||
|
|
||||||
Foam::label Foam::fvFieldDecomposer::completePatchID
|
Foam::label Foam::fvFieldDecomposer::completePatchID
|
||||||
(
|
(
|
||||||
|
const label proci,
|
||||||
const label procPatchi
|
const label procPatchi
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
const fvPatch& procPatch = procMesh_.boundary()[procPatchi];
|
const fvPatch& procPatch = procMeshes_[proci].boundary()[procPatchi];
|
||||||
|
|
||||||
if (procPatchi < completeMesh_.boundary().size())
|
if (procPatchi < completeMesh_.boundary().size())
|
||||||
{
|
{
|
||||||
@ -64,37 +65,48 @@ Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer
|
|||||||
Foam::fvFieldDecomposer::fvFieldDecomposer
|
Foam::fvFieldDecomposer::fvFieldDecomposer
|
||||||
(
|
(
|
||||||
const fvMesh& completeMesh,
|
const fvMesh& completeMesh,
|
||||||
const fvMesh& procMesh,
|
const PtrList<fvMesh>& procMeshes,
|
||||||
const labelList& faceAddressing,
|
const labelListList& faceProcAddressing,
|
||||||
const labelList& cellAddressing,
|
const labelListList& cellProcAddressing,
|
||||||
const surfaceLabelField::Boundary& faceAddressingBf
|
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
completeMesh_(completeMesh),
|
completeMesh_(completeMesh),
|
||||||
procMesh_(procMesh),
|
procMeshes_(procMeshes),
|
||||||
faceAddressing_(faceAddressing),
|
faceProcAddressing_(faceProcAddressing),
|
||||||
cellAddressing_(cellAddressing),
|
cellProcAddressing_(cellProcAddressing),
|
||||||
faceAddressingBf_(faceAddressingBf),
|
faceProcAddressingBf_(faceProcAddressingBf),
|
||||||
patchFieldDecomposers_(procMesh_.boundary().size())
|
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>
|
||||||
|
(
|
||||||
|
procMeshes_[proci].boundary().size()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(procMeshes_[proci].boundary(), procPatchi)
|
||||||
|
{
|
||||||
|
const label completePatchi = completePatchID(proci, procPatchi);
|
||||||
|
|
||||||
|
if (completePatchi >= 0)
|
||||||
|
{
|
||||||
|
patchFieldDecomposers_[proci].set
|
||||||
(
|
(
|
||||||
procPatchi,
|
procPatchi,
|
||||||
new patchFieldDecomposer
|
new patchFieldDecomposer
|
||||||
(
|
(
|
||||||
faceAddressingBf[completePatchi]
|
faceProcAddressingBf[proci][completePatchi]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -29,7 +29,7 @@ Description
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
fvFieldDecomposer.C
|
fvFieldDecomposer.C
|
||||||
fvFieldDecomposerDecomposeFields.C
|
fvFieldDecomposerTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -37,8 +37,10 @@ SourceFiles
|
|||||||
#define fvFieldDecomposer_H
|
#define fvFieldDecomposer_H
|
||||||
|
|
||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "directFvPatchFieldMapper.H"
|
#include "IOobjectList.H"
|
||||||
|
#include "volFields.H"
|
||||||
#include "surfaceFields.H"
|
#include "surfaceFields.H"
|
||||||
|
#include "directFvPatchFieldMapper.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -79,26 +81,26 @@ private:
|
|||||||
//- Reference to complete mesh
|
//- Reference to complete mesh
|
||||||
const fvMesh& completeMesh_;
|
const fvMesh& completeMesh_;
|
||||||
|
|
||||||
//- Reference to processor mesh
|
//- List of processor meshes
|
||||||
const fvMesh& procMesh_;
|
const PtrList<fvMesh>& procMeshes_;
|
||||||
|
|
||||||
//- Reference to face addressing
|
//- Reference to face addressing
|
||||||
const labelList& faceAddressing_;
|
const labelListList& faceProcAddressing_;
|
||||||
|
|
||||||
//- Reference to cell addressing
|
//- Reference to cell addressing
|
||||||
const labelList& cellAddressing_;
|
const labelListList& cellProcAddressing_;
|
||||||
|
|
||||||
//- Reference to face addressing boundary field
|
//- Reference to face addressing boundary field
|
||||||
const surfaceLabelField::Boundary& faceAddressingBf_;
|
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf_;
|
||||||
|
|
||||||
//- List of patch field decomposers
|
//- List of patch field decomposers
|
||||||
PtrList<patchFieldDecomposer> patchFieldDecomposers_;
|
PtrList<PtrList<patchFieldDecomposer>> patchFieldDecomposers_;
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
//- Convert a processor patch to the corresponding complete patch index
|
//- 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
|
//- Map cell values to faces
|
||||||
template<class Type>
|
template<class Type>
|
||||||
@ -119,6 +121,21 @@ private:
|
|||||||
const bool isFlux
|
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:
|
public:
|
||||||
|
|
||||||
@ -128,10 +145,10 @@ public:
|
|||||||
fvFieldDecomposer
|
fvFieldDecomposer
|
||||||
(
|
(
|
||||||
const fvMesh& completeMesh,
|
const fvMesh& completeMesh,
|
||||||
const fvMesh& procMesh,
|
const PtrList<fvMesh>& procMeshes,
|
||||||
const labelList& faceAddressing,
|
const labelListList& faceProcAddressing,
|
||||||
const labelList& cellAddressing,
|
const labelListList& cellProcAddressing,
|
||||||
const surfaceLabelField::Boundary& faceAddressingBf
|
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Disallow default bitwise copy construction
|
//- Disallow default bitwise copy construction
|
||||||
@ -144,25 +161,20 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Decompose volume field
|
//- Return whether anything in the object list gets decomposed
|
||||||
template<class Type>
|
static bool decomposes(const IOobjectList& objects);
|
||||||
tmp<VolField<Type>>
|
|
||||||
decomposeField
|
|
||||||
(
|
|
||||||
const VolField<Type>& field
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Decompose surface field
|
//- Read, decompose and write all volume internal fields
|
||||||
template<class Type>
|
template<class Type>
|
||||||
tmp<SurfaceField<Type>>
|
void decomposeVolInternalFields(const IOobjectList& objects);
|
||||||
decomposeField
|
|
||||||
(
|
|
||||||
const SurfaceField<Type>& field
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Decompose a list of fields
|
//- Read, decompose and write all volume fields
|
||||||
template<class GeoField>
|
template<class Type>
|
||||||
void decomposeFields(const PtrList<GeoField>& fields) const;
|
void decomposeVolFields(const IOobjectList& objects);
|
||||||
|
|
||||||
|
//- Read, decompose and write all surface fields
|
||||||
|
template<class Type>
|
||||||
|
void decomposeFvSurfaceFields(const IOobjectList& objects);
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
@ -179,7 +191,7 @@ public:
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
#ifdef NoRepository
|
||||||
#include "fvFieldDecomposerDecomposeFields.C"
|
#include "fvFieldDecomposerTemplates.C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -21,83 +21,161 @@ License
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Description
|
|
||||||
Lagrangian field decomposer.
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "lagrangianFieldDecomposer.H"
|
#include "lagrangianFieldDecomposer.H"
|
||||||
|
#include "passiveParticleCloud.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
Foam::lagrangianFieldDecomposer::lagrangianFieldDecomposer
|
Foam::lagrangianFieldDecomposer::lagrangianFieldDecomposer
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const fvMesh& completeMesh,
|
||||||
const polyMesh& procMesh,
|
const PtrList<fvMesh>& procMeshes,
|
||||||
const labelList& faceProcAddressing,
|
const labelListList& faceProcAddressing,
|
||||||
const labelList& cellProcAddressing,
|
const labelListList& cellProcAddressing,
|
||||||
const word& cloudName,
|
const word& cloudName
|
||||||
const Cloud<indexedParticle>& lagrangianPositions,
|
|
||||||
const List<SLList<indexedParticle*>*>& cellParticles
|
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
procMesh_(procMesh),
|
completeMesh_(completeMesh),
|
||||||
positions_(procMesh, cloudName, IDLList<passiveParticle>()),
|
procMeshes_(procMeshes),
|
||||||
particleIndices_(lagrangianPositions.size())
|
particleProcAddressing_(procMeshes_.size()),
|
||||||
|
cloudName_(cloudName)
|
||||||
{
|
{
|
||||||
label pi = 0;
|
// Create reverse cell addressing
|
||||||
|
List<remote> cellProcCell(completeMesh_.nCells());
|
||||||
labelList decodedProcFaceAddressing(faceProcAddressing.size());
|
forAll(cellProcAddressing, proci)
|
||||||
|
|
||||||
forAll(faceProcAddressing, i)
|
|
||||||
{
|
{
|
||||||
decodedProcFaceAddressing[i] = mag(faceProcAddressing[i]) - 1;
|
forAll(cellProcAddressing[proci], procCelli)
|
||||||
|
{
|
||||||
|
cellProcCell[cellProcAddressing[proci][procCelli]] =
|
||||||
|
remote(proci, procCelli);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
forAll(cellProcAddressing, procCelli)
|
// Create reverse face addressing
|
||||||
|
List<remote> faceOwnerProcFace(completeMesh_.nFaces());
|
||||||
|
List<remote> faceNeighbourProcFace(completeMesh_.nFaces());
|
||||||
|
forAll(faceProcAddressing, proci)
|
||||||
{
|
{
|
||||||
label celli = cellProcAddressing[procCelli];
|
forAll(faceProcAddressing[proci], procFacei)
|
||||||
|
|
||||||
if (cellParticles[celli])
|
|
||||||
{
|
{
|
||||||
SLList<indexedParticle*>& particlePtrs = *cellParticles[celli];
|
const bool owner = faceProcAddressing[proci][procFacei] > 0;
|
||||||
|
const label facei = mag(faceProcAddressing[proci][procFacei]) - 1;
|
||||||
|
|
||||||
forAllConstIter(SLList<indexedParticle*>, particlePtrs, iter)
|
(owner ? faceOwnerProcFace : faceNeighbourProcFace)[facei] =
|
||||||
{
|
remote(proci, procFacei);
|
||||||
const indexedParticle& ppi = *iter();
|
}
|
||||||
particleIndices_[pi++] = ppi.index();
|
}
|
||||||
|
|
||||||
label mappedTetFace = findIndex
|
// Read the complete positions
|
||||||
|
const passiveParticleCloud completePositions
|
||||||
(
|
(
|
||||||
decodedProcFaceAddressing,
|
completeMesh_,
|
||||||
ppi.tetFace()
|
cloudName_,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
if (mappedTetFace == -1)
|
// Construct empty clouds for processor positions
|
||||||
|
PtrList<passiveParticleCloud> procPositions(procMeshes_.size());
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
{
|
{
|
||||||
FatalErrorInFunction
|
procPositions.set
|
||||||
<< "Face lookup failure." << nl
|
(
|
||||||
<< abort(FatalError);
|
proci,
|
||||||
|
new passiveParticleCloud
|
||||||
|
(
|
||||||
|
procMeshes_[proci],
|
||||||
|
cloudName_,
|
||||||
|
IDLList<passiveParticle>()
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
positions_.append
|
// 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
|
new passiveParticle
|
||||||
(
|
(
|
||||||
procMesh,
|
procMeshes_[proci],
|
||||||
ppi.coordinates(),
|
p.coordinates(),
|
||||||
procCelli,
|
procCelli,
|
||||||
mappedTetFace,
|
procFacei,
|
||||||
ppi.procTetPt(mesh, procMesh, procCelli, mappedTetFace)
|
p.procTetPt
|
||||||
|
(
|
||||||
|
completeMesh_,
|
||||||
|
procMeshes_[proci],
|
||||||
|
procCelli,
|
||||||
|
procFacei
|
||||||
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
completeParticlei ++;
|
||||||
|
procParticlei[proci] ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write
|
||||||
|
forAll(procPositions, proci)
|
||||||
|
{
|
||||||
|
IOPosition<passiveParticleCloud>(procPositions[proci]).write();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
particleIndices_.setSize(pi);
|
|
||||||
|
|
||||||
IOPosition<Cloud<passiveParticle>>(positions_).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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -29,17 +29,15 @@ Description
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
lagrangianFieldDecomposer.C
|
lagrangianFieldDecomposer.C
|
||||||
lagrangianFieldDecomposerDecomposeFields.C
|
lagrangianFieldDecomposerTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#ifndef lagrangianFieldDecomposer_H
|
#ifndef lagrangianFieldDecomposer_H
|
||||||
#define lagrangianFieldDecomposer_H
|
#define lagrangianFieldDecomposer_H
|
||||||
|
|
||||||
#include "Cloud.H"
|
#include "cloud.H"
|
||||||
#include "CompactIOField.H"
|
#include "fvMesh.H"
|
||||||
#include "indexedParticle.H"
|
|
||||||
#include "passiveParticle.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -56,14 +54,34 @@ class lagrangianFieldDecomposer
|
|||||||
{
|
{
|
||||||
// Private Data
|
// Private Data
|
||||||
|
|
||||||
//- Reference to processor mesh
|
//- Reference to complete mesh
|
||||||
const polyMesh& procMesh_;
|
const fvMesh& completeMesh_;
|
||||||
|
|
||||||
//- Lagrangian positions for this processor
|
//- List of processor meshes
|
||||||
Cloud<passiveParticle> positions_;
|
const PtrList<fvMesh>& procMeshes_;
|
||||||
|
|
||||||
//- The indices of the particles on this processor
|
//- For each processor, for each particle, the global particle index
|
||||||
labelList particleIndices_;
|
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:
|
public:
|
||||||
@ -73,68 +91,29 @@ public:
|
|||||||
//- Construct from components
|
//- Construct from components
|
||||||
lagrangianFieldDecomposer
|
lagrangianFieldDecomposer
|
||||||
(
|
(
|
||||||
const polyMesh& mesh,
|
const fvMesh& completeMesh,
|
||||||
const polyMesh& procMesh,
|
const PtrList<fvMesh>& procMeshes,
|
||||||
const labelList& faceProcAddressing,
|
const labelListList& faceProcAddressing,
|
||||||
const labelList& cellProcAddressing,
|
const labelListList& cellProcAddressing,
|
||||||
const word& cloudName,
|
const word& cloudName
|
||||||
const Cloud<indexedParticle>& lagrangianPositions,
|
|
||||||
const List<SLList<indexedParticle*>*>& cellParticles
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Disallow default bitwise copy construction
|
//- Disallow default bitwise copy construction
|
||||||
lagrangianFieldDecomposer(const lagrangianFieldDecomposer&) = delete;
|
lagrangianFieldDecomposer(const lagrangianFieldDecomposer&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~lagrangianFieldDecomposer();
|
||||||
|
|
||||||
|
|
||||||
// Member Functions
|
// 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>
|
template<class Type>
|
||||||
static void readFields
|
void decomposeFields(const IOobjectList& objects);
|
||||||
(
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
@ -151,7 +130,7 @@ public:
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
#ifdef NoRepository
|
||||||
#include "lagrangianFieldDecomposerDecomposeFields.C"
|
#include "lagrangianFieldDecomposerTemplates.C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -24,6 +24,7 @@ License
|
|||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "pointFieldDecomposer.H"
|
#include "pointFieldDecomposer.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -77,32 +78,43 @@ Foam::pointFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer
|
|||||||
Foam::pointFieldDecomposer::pointFieldDecomposer
|
Foam::pointFieldDecomposer::pointFieldDecomposer
|
||||||
(
|
(
|
||||||
const pointMesh& completeMesh,
|
const pointMesh& completeMesh,
|
||||||
const pointMesh& procMesh,
|
const PtrList<fvMesh>& procMeshes,
|
||||||
const labelList& pointAddressing
|
const labelListList& pointProcAddressing
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
completeMesh_(completeMesh),
|
completeMesh_(completeMesh),
|
||||||
procMesh_(procMesh),
|
procMeshes_(procMeshes),
|
||||||
pointAddressing_(pointAddressing),
|
pointProcAddressing_(pointProcAddressing),
|
||||||
patchFieldDecomposers_(procMesh_.boundary().size())
|
patchFieldDecomposers_(procMeshes_.size())
|
||||||
{
|
{
|
||||||
forAll(procMesh_.boundary(), patchi)
|
forAll(procMeshes_, proci)
|
||||||
{
|
|
||||||
if (patchi < completeMesh_.boundary().size())
|
|
||||||
{
|
{
|
||||||
|
const pointMesh& procMesh = pointMesh::New(procMeshes_[proci]);
|
||||||
|
|
||||||
patchFieldDecomposers_.set
|
patchFieldDecomposers_.set
|
||||||
(
|
(
|
||||||
patchi,
|
proci,
|
||||||
|
new PtrList<patchFieldDecomposer>(procMesh.boundary().size())
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(procMesh.boundary(), procPatchi)
|
||||||
|
{
|
||||||
|
if (procPatchi < completeMesh_.boundary().size())
|
||||||
|
{
|
||||||
|
patchFieldDecomposers_[proci].set
|
||||||
|
(
|
||||||
|
procPatchi,
|
||||||
new patchFieldDecomposer
|
new patchFieldDecomposer
|
||||||
(
|
(
|
||||||
completeMesh_.boundary()[patchi],
|
completeMesh_.boundary()[procPatchi],
|
||||||
procMesh_.boundary()[patchi],
|
procMesh.boundary()[procPatchi],
|
||||||
pointAddressing_
|
pointProcAddressing_[proci]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -29,7 +29,7 @@ Description
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
pointFieldDecomposer.C
|
pointFieldDecomposer.C
|
||||||
pointFieldDecomposerDecomposeFields.C
|
pointFieldDecomposerTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -37,14 +37,17 @@ SourceFiles
|
|||||||
#define pointFieldDecomposer_H
|
#define pointFieldDecomposer_H
|
||||||
|
|
||||||
#include "pointMesh.H"
|
#include "pointMesh.H"
|
||||||
#include "pointPatchFieldMapperPatchRef.H"
|
|
||||||
#include "pointFields.H"
|
#include "pointFields.H"
|
||||||
|
#include "pointPatchFieldMapperPatchRef.H"
|
||||||
|
#include "IOobjectList.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class fvMesh;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class pointFieldDecomposer Declaration
|
Class pointFieldDecomposer Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -111,14 +114,22 @@ private:
|
|||||||
//- Reference to complete mesh
|
//- Reference to complete mesh
|
||||||
const pointMesh& completeMesh_;
|
const pointMesh& completeMesh_;
|
||||||
|
|
||||||
//- Reference to processor mesh
|
//- Reference to processor meshes
|
||||||
const pointMesh& procMesh_;
|
const PtrList<fvMesh>& procMeshes_;
|
||||||
|
|
||||||
//- Reference to point addressing
|
//- Reference to point addressing
|
||||||
const labelList& pointAddressing_;
|
const labelListList& pointProcAddressing_;
|
||||||
|
|
||||||
//- List of patch field decomposers
|
//- 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:
|
public:
|
||||||
@ -129,8 +140,8 @@ public:
|
|||||||
pointFieldDecomposer
|
pointFieldDecomposer
|
||||||
(
|
(
|
||||||
const pointMesh& completeMesh,
|
const pointMesh& completeMesh,
|
||||||
const pointMesh& procMesh,
|
const PtrList<fvMesh>& procMeshes,
|
||||||
const labelList& pointAddressing
|
const labelListList& pointAddressing
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Disallow default bitwise copy construction
|
//- Disallow default bitwise copy construction
|
||||||
@ -143,17 +154,12 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Decompose point field
|
//- Return whether anything in the object list gets decomposed
|
||||||
template<class Type>
|
static bool decomposes(const IOobjectList& objects);
|
||||||
tmp<PointField<Type>>
|
|
||||||
decomposeField
|
|
||||||
(
|
|
||||||
const PointField<Type>&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Decompose a list of fields
|
//- Read, decompose and write all fields
|
||||||
template<class GeoField>
|
template<class Type>
|
||||||
void decomposeFields(const PtrList<GeoField>& fields) const;
|
void decomposeFields(const IOobjectList& objects);
|
||||||
|
|
||||||
|
|
||||||
// Member Operators
|
// Member Operators
|
||||||
@ -170,7 +176,7 @@ public:
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
#ifdef NoRepository
|
||||||
#include "pointFieldDecomposerDecomposeFields.C"
|
#include "pointFieldDecomposerTemplates.C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -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();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -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
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
reconstructPar.C
|
reconstructPar.C
|
||||||
fvFieldReconstructor.C
|
fvFieldReconstructor.C
|
||||||
pointFieldReconstructor.C
|
pointFieldReconstructor.C
|
||||||
reconstructLagrangianPositions.C
|
lagrangianFieldReconstructor.C
|
||||||
|
|
||||||
EXE = $(FOAM_APPBIN)/reconstructPar
|
EXE = $(FOAM_APPBIN)/reconstructPar
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -66,8 +66,7 @@ Foam::fvFieldReconstructor::fvFieldReconstructor
|
|||||||
procMeshes_(procMeshes),
|
procMeshes_(procMeshes),
|
||||||
faceProcAddressing_(faceProcAddressing),
|
faceProcAddressing_(faceProcAddressing),
|
||||||
cellProcAddressing_(cellProcAddressing),
|
cellProcAddressing_(cellProcAddressing),
|
||||||
faceProcAddressingBf_(faceProcAddressingBf),
|
faceProcAddressingBf_(faceProcAddressingBf)
|
||||||
nReconstructed_(0)
|
|
||||||
{
|
{
|
||||||
forAll(procMeshes_, proci)
|
forAll(procMeshes_, proci)
|
||||||
{
|
{
|
||||||
@ -93,4 +92,26 @@ Foam::fvFieldReconstructor::fvFieldReconstructor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::fvFieldReconstructor::reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
#define DO_FV_FIELDS_TYPE(Type, nullArg) \
|
||||||
|
result = result \
|
||||||
|
|| reconstructs<VolField<Type>::Internal>(objects, selectedFields) \
|
||||||
|
|| reconstructs<VolField<Type>>(objects, selectedFields) \
|
||||||
|
|| reconstructs<SurfaceField<Type>>(objects, selectedFields);
|
||||||
|
FOR_ALL_FIELD_TYPES(DO_FV_FIELDS_TYPE)
|
||||||
|
#undef DO_FV_FIELDS_TYPE
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -29,7 +29,7 @@ Description
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
fvFieldReconstructor.C
|
fvFieldReconstructor.C
|
||||||
fvFieldReconstructorReconstructFields.C
|
fvFieldReconstructorTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -71,12 +71,17 @@ class fvFieldReconstructor
|
|||||||
//- Boundary field of face addressing
|
//- Boundary field of face addressing
|
||||||
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf_;
|
const PtrList<surfaceLabelField::Boundary>& faceProcAddressingBf_;
|
||||||
|
|
||||||
//- Number of fields reconstructed
|
|
||||||
label nReconstructed_;
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Return whether anything in the object list gets reconstructed
|
||||||
|
template<class FieldType>
|
||||||
|
static bool reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
);
|
||||||
|
|
||||||
//- Convert a processor patch to the corresponding complete patch index
|
//- Convert a processor patch to the corresponding complete patch index
|
||||||
label completePatchID(const label proci, const label procPatchi) const;
|
label completePatchID(const label proci, const label procPatchi) const;
|
||||||
|
|
||||||
@ -90,6 +95,21 @@ class fvFieldReconstructor
|
|||||||
const bool isFlux
|
const bool isFlux
|
||||||
);
|
);
|
||||||
|
|
||||||
|
//- Read and reconstruct a volume internal field
|
||||||
|
template<class Type>
|
||||||
|
tmp<DimensionedField<Type, volMesh>>
|
||||||
|
reconstructVolInternalField(const IOobject& fieldIoObject) const;
|
||||||
|
|
||||||
|
//- Read and reconstruct a volume field
|
||||||
|
template<class Type>
|
||||||
|
tmp<VolField<Type>>
|
||||||
|
reconstructVolField(const IOobject& fieldIoObject) const;
|
||||||
|
|
||||||
|
//- Read and reconstruct a surface field
|
||||||
|
template<class Type>
|
||||||
|
tmp<SurfaceField<Type>>
|
||||||
|
reconstructFvSurfaceField(const IOobject& fieldIoObject) const;
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -111,59 +131,16 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Return number of fields reconstructed
|
//- Return whether anything in the object list gets reconstructed
|
||||||
label nReconstructed() const
|
static bool reconstructs
|
||||||
{
|
|
||||||
return nReconstructed_;
|
|
||||||
}
|
|
||||||
|
|
||||||
//- Reconstruct volume internal field
|
|
||||||
template<class Type>
|
|
||||||
tmp<DimensionedField<Type, volMesh>>
|
|
||||||
reconstructFvVolumeInternalField
|
|
||||||
(
|
(
|
||||||
const IOobject& fieldIoObject,
|
const IOobjectList& objects,
|
||||||
const PtrList<DimensionedField<Type, volMesh>>& procFields
|
const HashSet<word>& selectedFields
|
||||||
) const;
|
);
|
||||||
|
|
||||||
//- Read and reconstruct volume internal field
|
|
||||||
template<class Type>
|
|
||||||
tmp<DimensionedField<Type, volMesh>>
|
|
||||||
reconstructFvVolumeInternalField(const IOobject& fieldIoObject) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Reconstruct volume field
|
|
||||||
template<class Type>
|
|
||||||
tmp<VolField<Type>>
|
|
||||||
reconstructFvVolumeField
|
|
||||||
(
|
|
||||||
const IOobject& fieldIoObject,
|
|
||||||
const PtrList<VolField<Type>>&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Read and reconstruct volume field
|
|
||||||
template<class Type>
|
|
||||||
tmp<VolField<Type>>
|
|
||||||
reconstructFvVolumeField(const IOobject& fieldIoObject) const;
|
|
||||||
|
|
||||||
|
|
||||||
//- Reconstruct surface field
|
|
||||||
template<class Type>
|
|
||||||
tmp<SurfaceField<Type>>
|
|
||||||
reconstructFvSurfaceField
|
|
||||||
(
|
|
||||||
const IOobject& fieldIoObject,
|
|
||||||
const PtrList<SurfaceField<Type>>&
|
|
||||||
) const;
|
|
||||||
|
|
||||||
//- Read and reconstruct surface field
|
|
||||||
template<class Type>
|
|
||||||
tmp<SurfaceField<Type>>
|
|
||||||
reconstructFvSurfaceField(const IOobject& fieldIoObject) const;
|
|
||||||
|
|
||||||
//- Read, reconstruct and write all/selected volume internal fields
|
//- Read, reconstruct and write all/selected volume internal fields
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void reconstructFvVolumeInternalFields
|
void reconstructVolInternalFields
|
||||||
(
|
(
|
||||||
const IOobjectList& objects,
|
const IOobjectList& objects,
|
||||||
const HashSet<word>& selectedFields
|
const HashSet<word>& selectedFields
|
||||||
@ -171,7 +148,7 @@ public:
|
|||||||
|
|
||||||
//- Read, reconstruct and write all/selected volume fields
|
//- Read, reconstruct and write all/selected volume fields
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void reconstructFvVolumeFields
|
void reconstructVolFields
|
||||||
(
|
(
|
||||||
const IOobjectList& objects,
|
const IOobjectList& objects,
|
||||||
const HashSet<word>& selectedFields
|
const HashSet<word>& selectedFields
|
||||||
@ -200,7 +177,7 @@ public:
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
#ifdef NoRepository
|
||||||
#include "fvFieldReconstructorReconstructFields.C"
|
#include "fvFieldReconstructorTemplates.C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -34,7 +34,33 @@ License
|
|||||||
#include "reverseFvPatchFieldMapper.H"
|
#include "reverseFvPatchFieldMapper.H"
|
||||||
#include "stringOps.H"
|
#include "stringOps.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class FieldType>
|
||||||
|
bool Foam::fvFieldReconstructor::reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IOobjectList fields = objects.lookupClass(FieldType::typeName);
|
||||||
|
|
||||||
|
if (fields.size() && selectedFields.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||||
|
{
|
||||||
|
if (selectedFields.found(fieldIter()->name()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::fvFieldReconstructor::rmapFaceToFace
|
void Foam::fvFieldReconstructor::rmapFaceToFace
|
||||||
@ -53,54 +79,15 @@ void Foam::fvFieldReconstructor::rmapFaceToFace
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
|
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
|
||||||
Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
|
Foam::fvFieldReconstructor::reconstructVolInternalField
|
||||||
(
|
|
||||||
const IOobject& fieldIoObject,
|
|
||||||
const PtrList<DimensionedField<Type, volMesh>>& procFields
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Create the internalField
|
|
||||||
Field<Type> internalField(completeMesh_.nCells());
|
|
||||||
|
|
||||||
forAll(procMeshes_, proci)
|
|
||||||
{
|
|
||||||
const DimensionedField<Type, volMesh>& procField = procFields[proci];
|
|
||||||
|
|
||||||
// Set the cell values in the reconstructed field
|
|
||||||
internalField.rmap
|
|
||||||
(
|
|
||||||
procField.field(),
|
|
||||||
cellProcAddressing_[proci]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return tmp<DimensionedField<Type, volMesh>>
|
|
||||||
(
|
|
||||||
new DimensionedField<Type, volMesh>
|
|
||||||
(
|
|
||||||
fieldIoObject,
|
|
||||||
completeMesh_,
|
|
||||||
procFields[0].dimensions(),
|
|
||||||
internalField
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh>>
|
|
||||||
Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
|
|
||||||
(
|
(
|
||||||
const IOobject& fieldIoObject
|
const IOobject& fieldIoObject
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
PtrList<DimensionedField<Type, volMesh>>
|
// Read the field for all the processors
|
||||||
procFields(procMeshes_.size());
|
PtrList<DimensionedField<Type, volMesh>> procFields(procMeshes_.size());
|
||||||
|
|
||||||
forAll(procMeshes_, proci)
|
forAll(procMeshes_, proci)
|
||||||
{
|
{
|
||||||
procFields.set
|
procFields.set
|
||||||
@ -122,7 +109,24 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reconstructFvVolumeInternalField
|
// Create the internalField
|
||||||
|
Field<Type> internalField(completeMesh_.nCells());
|
||||||
|
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
const DimensionedField<Type, volMesh>& procField = procFields[proci];
|
||||||
|
|
||||||
|
// Set the cell values in the reconstructed field
|
||||||
|
internalField.rmap
|
||||||
|
(
|
||||||
|
procField.field(),
|
||||||
|
cellProcAddressing_[proci]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmp<DimensionedField<Type, volMesh>>
|
||||||
|
(
|
||||||
|
new DimensionedField<Type, volMesh>
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
@ -133,19 +137,44 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
|
|||||||
IOobject::NO_WRITE,
|
IOobject::NO_WRITE,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
procFields
|
completeMesh_,
|
||||||
|
procFields[0].dimensions(),
|
||||||
|
internalField
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::VolField<Type>>
|
Foam::tmp<Foam::VolField<Type>>
|
||||||
Foam::fvFieldReconstructor::reconstructFvVolumeField
|
Foam::fvFieldReconstructor::reconstructVolField
|
||||||
(
|
(
|
||||||
const IOobject& fieldIoObject,
|
const IOobject& fieldIoObject
|
||||||
const PtrList<VolField<Type>>& procFields
|
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
// Read the field for all the processors
|
||||||
|
PtrList<VolField<Type>> procFields(procMeshes_.size());
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
procFields.set
|
||||||
|
(
|
||||||
|
proci,
|
||||||
|
new VolField<Type>
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
fieldIoObject.name(),
|
||||||
|
procMeshes_[proci].time().name(),
|
||||||
|
procMeshes_[proci],
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
|
procMeshes_[proci]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Create the internalField
|
// Create the internalField
|
||||||
Field<Type> internalField(completeMesh_.nCells());
|
Field<Type> internalField(completeMesh_.nCells());
|
||||||
|
|
||||||
@ -251,7 +280,15 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
|
|||||||
(
|
(
|
||||||
new VolField<Type>
|
new VolField<Type>
|
||||||
(
|
(
|
||||||
fieldIoObject,
|
IOobject
|
||||||
|
(
|
||||||
|
fieldIoObject.name(),
|
||||||
|
completeMesh_.time().name(),
|
||||||
|
completeMesh_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
|
),
|
||||||
completeMesh_,
|
completeMesh_,
|
||||||
procFields[0].dimensions(),
|
procFields[0].dimensions(),
|
||||||
internalField,
|
internalField,
|
||||||
@ -262,21 +299,20 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
|
|||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::VolField<Type>>
|
Foam::tmp<Foam::SurfaceField<Type>>
|
||||||
Foam::fvFieldReconstructor::reconstructFvVolumeField
|
Foam::fvFieldReconstructor::reconstructFvSurfaceField
|
||||||
(
|
(
|
||||||
const IOobject& fieldIoObject
|
const IOobject& fieldIoObject
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
PtrList<VolField<Type>>
|
// Read the field for all the processors
|
||||||
procFields(procMeshes_.size());
|
PtrList<SurfaceField<Type>> procFields(procMeshes_.size());
|
||||||
|
|
||||||
forAll(procMeshes_, proci)
|
forAll(procMeshes_, proci)
|
||||||
{
|
{
|
||||||
procFields.set
|
procFields.set
|
||||||
(
|
(
|
||||||
proci,
|
proci,
|
||||||
new VolField<Type>
|
new SurfaceField<Type>
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
@ -292,30 +328,6 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return reconstructFvVolumeField
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fieldIoObject.name(),
|
|
||||||
completeMesh_.time().name(),
|
|
||||||
completeMesh_,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
procFields
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::tmp<Foam::SurfaceField<Type>>
|
|
||||||
Foam::fvFieldReconstructor::reconstructFvSurfaceField
|
|
||||||
(
|
|
||||||
const IOobject& fieldIoObject,
|
|
||||||
const PtrList<SurfaceField<Type>>& procFields
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
// Create the internalField
|
// Create the internalField
|
||||||
Field<Type> internalField(completeMesh_.nInternalFaces());
|
Field<Type> internalField(completeMesh_.nInternalFaces());
|
||||||
|
|
||||||
@ -419,49 +431,6 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
|
|||||||
return tmp<SurfaceField<Type>>
|
return tmp<SurfaceField<Type>>
|
||||||
(
|
(
|
||||||
new SurfaceField<Type>
|
new SurfaceField<Type>
|
||||||
(
|
|
||||||
fieldIoObject,
|
|
||||||
completeMesh_,
|
|
||||||
procFields[0].dimensions(),
|
|
||||||
internalField,
|
|
||||||
patchFields
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::tmp<Foam::SurfaceField<Type>>
|
|
||||||
Foam::fvFieldReconstructor::reconstructFvSurfaceField
|
|
||||||
(
|
|
||||||
const IOobject& fieldIoObject
|
|
||||||
) const
|
|
||||||
{
|
|
||||||
PtrList<SurfaceField<Type>>
|
|
||||||
procFields(procMeshes_.size());
|
|
||||||
|
|
||||||
forAll(procMeshes_, proci)
|
|
||||||
{
|
|
||||||
procFields.set
|
|
||||||
(
|
|
||||||
proci,
|
|
||||||
new SurfaceField<Type>
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fieldIoObject.name(),
|
|
||||||
procMeshes_[proci].time().name(),
|
|
||||||
procMeshes_[proci],
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE,
|
|
||||||
false
|
|
||||||
),
|
|
||||||
procMeshes_[proci]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return reconstructFvSurfaceField
|
|
||||||
(
|
(
|
||||||
IOobject
|
IOobject
|
||||||
(
|
(
|
||||||
@ -472,13 +441,19 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
|
|||||||
IOobject::NO_WRITE,
|
IOobject::NO_WRITE,
|
||||||
false
|
false
|
||||||
),
|
),
|
||||||
procFields
|
completeMesh_,
|
||||||
|
procFields[0].dimensions(),
|
||||||
|
internalField,
|
||||||
|
patchFields
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields
|
void Foam::fvFieldReconstructor::reconstructVolInternalFields
|
||||||
(
|
(
|
||||||
const IOobjectList& objects,
|
const IOobjectList& objects,
|
||||||
const HashSet<word>& selectedFields
|
const HashSet<word>& selectedFields
|
||||||
@ -490,7 +465,8 @@ void Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields
|
|||||||
|
|
||||||
if (fields.size())
|
if (fields.size())
|
||||||
{
|
{
|
||||||
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
|
Info<< nl << " Reconstructing " << fieldClassName << "s"
|
||||||
|
<< nl << endl;
|
||||||
|
|
||||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||||
{
|
{
|
||||||
@ -502,18 +478,15 @@ void Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields
|
|||||||
{
|
{
|
||||||
Info<< " " << fieldIter()->name() << endl;
|
Info<< " " << fieldIter()->name() << endl;
|
||||||
|
|
||||||
reconstructFvVolumeInternalField<Type>(*fieldIter())().write();
|
reconstructVolInternalField<Type>(*fieldIter())().write();
|
||||||
|
|
||||||
nReconstructed_++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Info<< endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::fvFieldReconstructor::reconstructFvVolumeFields
|
void Foam::fvFieldReconstructor::reconstructVolFields
|
||||||
(
|
(
|
||||||
const IOobjectList& objects,
|
const IOobjectList& objects,
|
||||||
const HashSet<word>& selectedFields
|
const HashSet<word>& selectedFields
|
||||||
@ -526,7 +499,8 @@ void Foam::fvFieldReconstructor::reconstructFvVolumeFields
|
|||||||
|
|
||||||
if (fields.size())
|
if (fields.size())
|
||||||
{
|
{
|
||||||
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
|
Info<< nl << " Reconstructing " << fieldClassName << "s"
|
||||||
|
<< nl << endl;
|
||||||
|
|
||||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||||
{
|
{
|
||||||
@ -538,12 +512,9 @@ void Foam::fvFieldReconstructor::reconstructFvVolumeFields
|
|||||||
{
|
{
|
||||||
Info<< " " << fieldIter()->name() << endl;
|
Info<< " " << fieldIter()->name() << endl;
|
||||||
|
|
||||||
reconstructFvVolumeField<Type>(*fieldIter())().write();
|
reconstructVolField<Type>(*fieldIter())().write();
|
||||||
|
|
||||||
nReconstructed_++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Info<< endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -562,7 +533,8 @@ void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
|
|||||||
|
|
||||||
if (fields.size())
|
if (fields.size())
|
||||||
{
|
{
|
||||||
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
|
Info<< nl << " Reconstructing " << fieldClassName << "s"
|
||||||
|
<< nl << endl;
|
||||||
|
|
||||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||||
{
|
{
|
||||||
@ -575,11 +547,8 @@ void Foam::fvFieldReconstructor::reconstructFvSurfaceFields
|
|||||||
Info<< " " << fieldIter()->name() << endl;
|
Info<< " " << fieldIter()->name() << endl;
|
||||||
|
|
||||||
reconstructFvSurfaceField<Type>(*fieldIter())().write();
|
reconstructFvSurfaceField<Type>(*fieldIter())().write();
|
||||||
|
|
||||||
nReconstructed_++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Info<< endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -0,0 +1,124 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "lagrangianFieldReconstructor.H"
|
||||||
|
#include "passiveParticleCloud.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::lagrangianFieldReconstructor::lagrangianFieldReconstructor
|
||||||
|
(
|
||||||
|
const fvMesh& completeMesh,
|
||||||
|
const PtrList<fvMesh>& procMeshes,
|
||||||
|
const labelListList& faceProcAddressing,
|
||||||
|
const labelListList& cellProcAddressing,
|
||||||
|
const word& cloudName
|
||||||
|
)
|
||||||
|
:
|
||||||
|
completeMesh_(completeMesh),
|
||||||
|
procMeshes_(procMeshes),
|
||||||
|
cloudName_(cloudName)
|
||||||
|
{
|
||||||
|
// Construct and empty cloud for the complete positions
|
||||||
|
passiveParticleCloud completePositions
|
||||||
|
(
|
||||||
|
completeMesh_,
|
||||||
|
cloudName_,
|
||||||
|
IDLList<passiveParticle>()
|
||||||
|
);
|
||||||
|
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
// Read the processor positions
|
||||||
|
Cloud<passiveParticle> procPositions
|
||||||
|
(
|
||||||
|
procMeshes_[proci],
|
||||||
|
cloudName_,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
// Combine the processor's positions into the complete cloud
|
||||||
|
forAllConstIter(Cloud<passiveParticle>, procPositions, iter)
|
||||||
|
{
|
||||||
|
const passiveParticle& p = iter();
|
||||||
|
const label completeCelli = cellProcAddressing[proci][p.cell()];
|
||||||
|
const label completeFacei =
|
||||||
|
mag(faceProcAddressing[proci][p.tetFace()]) - 1;
|
||||||
|
|
||||||
|
completePositions.append
|
||||||
|
(
|
||||||
|
new passiveParticle
|
||||||
|
(
|
||||||
|
completeMesh_,
|
||||||
|
p.coordinates(),
|
||||||
|
completeCelli,
|
||||||
|
completeFacei,
|
||||||
|
p.procTetPt
|
||||||
|
(
|
||||||
|
procMeshes_[proci],
|
||||||
|
completeMesh_,
|
||||||
|
completeCelli,
|
||||||
|
completeFacei
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write
|
||||||
|
IOPosition<Cloud<passiveParticle>>(completePositions).write();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::lagrangianFieldReconstructor::~lagrangianFieldReconstructor()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::lagrangianFieldReconstructor::reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
#define DO_LAGRANGIAN_FIELDS_TYPE(Type, nullArg) \
|
||||||
|
result = result \
|
||||||
|
|| reconstructs<IOField<Type>>(objects, selectedFields) \
|
||||||
|
|| reconstructs<IOField<Field<Type>>>(objects, selectedFields) \
|
||||||
|
|| reconstructs<CompactIOField<Field<Type>>>(objects, selectedFields);
|
||||||
|
DO_LAGRANGIAN_FIELDS_TYPE(label, )
|
||||||
|
FOR_ALL_FIELD_TYPES(DO_LAGRANGIAN_FIELDS_TYPE)
|
||||||
|
#undef DO_LAGRANGIAN_FIELDS_TYPE
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,165 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::lagrangianFieldReconstructor
|
||||||
|
|
||||||
|
Description
|
||||||
|
Lagrangian field reconstructor.
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
lagrangianFieldReconstructor.C
|
||||||
|
lagrangianFieldReconstructorTemplates.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef lagrangianFieldReconstructor_H
|
||||||
|
#define lagrangianFieldReconstructor_H
|
||||||
|
|
||||||
|
#include "cloud.H"
|
||||||
|
#include "fvMesh.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
class IOobjectList;
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class lagrangianFieldReconstructor Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class lagrangianFieldReconstructor
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Reference to complete mesh
|
||||||
|
const fvMesh& completeMesh_;
|
||||||
|
|
||||||
|
//- List of processor meshes
|
||||||
|
const PtrList<fvMesh>& procMeshes_;
|
||||||
|
|
||||||
|
//- The name of the cloud
|
||||||
|
const word cloudName_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Return whether anything in the object list gets reconstructed
|
||||||
|
template<class FieldType>
|
||||||
|
static bool reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reconstruct a field
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class Type,
|
||||||
|
template<class> class IOContainer,
|
||||||
|
template<class> class IOContainerType
|
||||||
|
>
|
||||||
|
tmp<IOContainer<Type>>
|
||||||
|
reconstructField(const IOobject& fieldIoObject) const;
|
||||||
|
|
||||||
|
//- Read, reconstruct and write all fields
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class Type,
|
||||||
|
template<class> class IOContainer,
|
||||||
|
template<class> class IOContainerType
|
||||||
|
>
|
||||||
|
void reconstructFields
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
lagrangianFieldReconstructor
|
||||||
|
(
|
||||||
|
const fvMesh& completeMesh,
|
||||||
|
const PtrList<fvMesh>& procMeshes,
|
||||||
|
const labelListList& faceProcAddressing,
|
||||||
|
const labelListList& cellProcAddressing,
|
||||||
|
const word& cloudName
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Disallow default bitwise copy construction
|
||||||
|
lagrangianFieldReconstructor
|
||||||
|
(
|
||||||
|
const lagrangianFieldReconstructor&
|
||||||
|
) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~lagrangianFieldReconstructor();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Return whether anything in the object list gets reconstructed
|
||||||
|
static bool reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Read, reconstruct and write all fields
|
||||||
|
template<class Type>
|
||||||
|
void reconstructFields
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// Member Operators
|
||||||
|
|
||||||
|
//- Disallow default bitwise assignment
|
||||||
|
void operator=(const lagrangianFieldReconstructor&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#ifdef NoRepository
|
||||||
|
#include "lagrangianFieldReconstructorTemplates.C"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,179 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "lagrangianFieldReconstructor.H"
|
||||||
|
#include "IOobjectList.H"
|
||||||
|
#include "CompactIOField.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class FieldType>
|
||||||
|
bool Foam::lagrangianFieldReconstructor::reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IOobjectList fields = objects.lookupClass(FieldType::typeName);
|
||||||
|
|
||||||
|
if (fields.size() && selectedFields.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||||
|
{
|
||||||
|
if (selectedFields.found(fieldIter()->name()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class Type,
|
||||||
|
template<class> class IOContainer,
|
||||||
|
template<class> class IOContainerType
|
||||||
|
>
|
||||||
|
Foam::tmp<IOContainer<Type>>
|
||||||
|
Foam::lagrangianFieldReconstructor::reconstructField
|
||||||
|
(
|
||||||
|
const IOobject& fieldIoObject
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
// Construct the complete field
|
||||||
|
tmp<IOContainer<Type>> tfield
|
||||||
|
(
|
||||||
|
new IOContainer<Type>
|
||||||
|
(
|
||||||
|
IOobject
|
||||||
|
(
|
||||||
|
fieldIoObject.name(),
|
||||||
|
completeMesh_.time().name(),
|
||||||
|
cloud::prefix/cloudName_,
|
||||||
|
completeMesh_,
|
||||||
|
IOobject::NO_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
),
|
||||||
|
Field<Type>(0)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
Field<Type>& field = tfield.ref();
|
||||||
|
|
||||||
|
// Combine the processor fields into the complete field
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
typeIOobject<IOContainerType<Type>> localIOobject
|
||||||
|
(
|
||||||
|
fieldIoObject.name(),
|
||||||
|
procMeshes_[proci].time().name(),
|
||||||
|
cloud::prefix/cloudName_,
|
||||||
|
procMeshes_[proci],
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE
|
||||||
|
);
|
||||||
|
|
||||||
|
if (localIOobject.headerOk())
|
||||||
|
{
|
||||||
|
IOContainer<Type> fieldi(localIOobject);
|
||||||
|
|
||||||
|
label offset = field.size();
|
||||||
|
field.setSize(offset + fieldi.size());
|
||||||
|
|
||||||
|
forAll(fieldi, j)
|
||||||
|
{
|
||||||
|
field[offset + j] = fieldi[j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tfield;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template
|
||||||
|
<
|
||||||
|
class Type,
|
||||||
|
template<class> class IOContainer,
|
||||||
|
template<class> class IOContainerType
|
||||||
|
>
|
||||||
|
void Foam::lagrangianFieldReconstructor::reconstructFields
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word& fieldClassName = IOContainerType<Type>::typeName;
|
||||||
|
|
||||||
|
IOobjectList fields = objects.lookupClass(fieldClassName);
|
||||||
|
|
||||||
|
if (fields.size())
|
||||||
|
{
|
||||||
|
Info<< nl << " Reconstructing lagrangian "
|
||||||
|
<< fieldClassName << "s" << nl << endl;
|
||||||
|
|
||||||
|
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
selectedFields.empty()
|
||||||
|
|| selectedFields.found(fieldIter()->name())
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< " " << fieldIter()->name() << endl;
|
||||||
|
|
||||||
|
reconstructField<Type, IOContainer, IOContainerType>
|
||||||
|
(
|
||||||
|
*fieldIter()
|
||||||
|
)().write();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void Foam::lagrangianFieldReconstructor::reconstructFields
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
reconstructFields<Type, IOField, IOField>
|
||||||
|
(objects, selectedFields);
|
||||||
|
reconstructFields<Field<Type>, CompactIOField, IOField>
|
||||||
|
(objects, selectedFields);
|
||||||
|
reconstructFields<Field<Type>, CompactIOField, CompactIOField>
|
||||||
|
(objects, selectedFields);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -2,7 +2,7 @@
|
|||||||
========= |
|
========= |
|
||||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
\\ / O peration | Website: https://openfoam.org
|
\\ / O peration | Website: https://openfoam.org
|
||||||
\\ / A nd | Copyright (C) 2011-2022 OpenFOAM Foundation
|
\\ / A nd | Copyright (C) 2011-2023 OpenFOAM Foundation
|
||||||
\\/ M anipulation |
|
\\/ M anipulation |
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
License
|
License
|
||||||
@ -38,8 +38,7 @@ Foam::pointFieldReconstructor::pointFieldReconstructor
|
|||||||
completeMesh_(completeMesh),
|
completeMesh_(completeMesh),
|
||||||
procMeshes_(procMeshes),
|
procMeshes_(procMeshes),
|
||||||
pointProcAddressing_(pointProcAddressing),
|
pointProcAddressing_(pointProcAddressing),
|
||||||
patchPointAddressing_(procMeshes.size()),
|
patchPointAddressing_(procMeshes.size())
|
||||||
nReconstructed_(0)
|
|
||||||
{
|
{
|
||||||
// Inverse-addressing of the patch point labels.
|
// Inverse-addressing of the patch point labels.
|
||||||
labelList pointMap(completeMesh_.size(), -1);
|
labelList pointMap(completeMesh_.size(), -1);
|
||||||
@ -91,4 +90,24 @@ Foam::pointFieldReconstructor::pointFieldReconstructor
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::pointFieldReconstructor::reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
#define DO_POINT_FIELDS_TYPE(Type, nullArg) \
|
||||||
|
result = result \
|
||||||
|
|| reconstructs<PointField<Type>>(objects, selectedFields);
|
||||||
|
FOR_ALL_FIELD_TYPES(DO_POINT_FIELDS_TYPE)
|
||||||
|
#undef DO_POINT_FIELDS_TYPE
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
@ -29,6 +29,7 @@ Description
|
|||||||
|
|
||||||
SourceFiles
|
SourceFiles
|
||||||
pointFieldReconstructor.C
|
pointFieldReconstructor.C
|
||||||
|
pointFieldReconstructorTemplates.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -68,8 +69,21 @@ class pointFieldReconstructor
|
|||||||
//- Point patch addressing
|
//- Point patch addressing
|
||||||
labelListListList patchPointAddressing_;
|
labelListListList patchPointAddressing_;
|
||||||
|
|
||||||
//- Number of fields reconstructed
|
|
||||||
label nReconstructed_;
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Return whether anything in the object list gets reconstructed
|
||||||
|
template<class FieldType>
|
||||||
|
static bool reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reconstruct field
|
||||||
|
template<class Type>
|
||||||
|
tmp<PointField<Type>>
|
||||||
|
reconstructField(const IOobject& fieldIoObject);
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -90,16 +104,12 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
//- Return number of fields reconstructed
|
//- Return whether anything in the object list gets reconstructed
|
||||||
label nReconstructed() const
|
static bool reconstructs
|
||||||
{
|
(
|
||||||
return nReconstructed_;
|
const IOobjectList& objects,
|
||||||
}
|
const HashSet<word>& selectedFields
|
||||||
|
);
|
||||||
//- Reconstruct field
|
|
||||||
template<class Type>
|
|
||||||
tmp<PointField<Type>>
|
|
||||||
reconstructField(const IOobject& fieldIoObject);
|
|
||||||
|
|
||||||
//- Reconstruct and write all fields
|
//- Reconstruct and write all fields
|
||||||
template<class Type>
|
template<class Type>
|
||||||
@ -124,7 +134,7 @@ public:
|
|||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
#ifdef NoRepository
|
#ifdef NoRepository
|
||||||
#include "pointFieldReconstructorReconstructFields.C"
|
#include "pointFieldReconstructorTemplates.C"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|||||||
@ -27,17 +27,40 @@ License
|
|||||||
#include "fvMesh.H"
|
#include "fvMesh.H"
|
||||||
#include "reversePointPatchFieldMapper.H"
|
#include "reversePointPatchFieldMapper.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class FieldType>
|
||||||
|
bool Foam::pointFieldReconstructor::reconstructs
|
||||||
|
(
|
||||||
|
const IOobjectList& objects,
|
||||||
|
const HashSet<word>& selectedFields
|
||||||
|
)
|
||||||
|
{
|
||||||
|
IOobjectList fields = objects.lookupClass(FieldType::typeName);
|
||||||
|
|
||||||
|
if (fields.size() && selectedFields.empty())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||||
|
{
|
||||||
|
if (selectedFields.found(fieldIter()->name()))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
Foam::tmp<Foam::PointField<Type>>
|
Foam::tmp<Foam::PointField<Type>>
|
||||||
Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
|
Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
|
||||||
{
|
{
|
||||||
// Read the field for all the processors
|
// Read the field for all the processors
|
||||||
PtrList<PointField<Type>> procFields
|
PtrList<PointField<Type>> procFields(procMeshes_.size());
|
||||||
(
|
|
||||||
procMeshes_.size()
|
|
||||||
);
|
|
||||||
|
|
||||||
forAll(procMeshes_, proci)
|
forAll(procMeshes_, proci)
|
||||||
{
|
{
|
||||||
@ -59,14 +82,12 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Create the internalField
|
// Create the internalField
|
||||||
Field<Type> internalField(completeMesh_.size());
|
Field<Type> internalField(completeMesh_.size());
|
||||||
|
|
||||||
// Create the patch fields
|
// Create the patch fields
|
||||||
PtrList<pointPatchField<Type>> patchFields(completeMesh_.boundary().size());
|
PtrList<pointPatchField<Type>> patchFields(completeMesh_.boundary().size());
|
||||||
|
|
||||||
|
|
||||||
forAll(procMeshes_, proci)
|
forAll(procMeshes_, proci)
|
||||||
{
|
{
|
||||||
const PointField<Type>&
|
const PointField<Type>&
|
||||||
@ -122,8 +143,7 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct and write the field
|
// Construct and return the field
|
||||||
// setting the internalField and patchFields
|
|
||||||
return tmp<PointField<Type>>
|
return tmp<PointField<Type>>
|
||||||
(
|
(
|
||||||
new PointField<Type>
|
new PointField<Type>
|
||||||
@ -145,7 +165,8 @@ Foam::pointFieldReconstructor::reconstructField(const IOobject& fieldIoObject)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Reconstruct and write all point fields
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::pointFieldReconstructor::reconstructFields
|
void Foam::pointFieldReconstructor::reconstructFields
|
||||||
(
|
(
|
||||||
@ -162,7 +183,8 @@ void Foam::pointFieldReconstructor::reconstructFields
|
|||||||
|
|
||||||
if (fields.size())
|
if (fields.size())
|
||||||
{
|
{
|
||||||
Info<< " Reconstructing " << fieldClassName << "s\n" << endl;
|
Info<< nl << " Reconstructing " << fieldClassName << "s"
|
||||||
|
<< nl << endl;
|
||||||
|
|
||||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
forAllConstIter(IOobjectList, fields, fieldIter)
|
||||||
{
|
{
|
||||||
@ -175,12 +197,8 @@ void Foam::pointFieldReconstructor::reconstructFields
|
|||||||
Info<< " " << fieldIter()->name() << endl;
|
Info<< " " << fieldIter()->name() << endl;
|
||||||
|
|
||||||
reconstructField<Type>(*fieldIter())().write();
|
reconstructField<Type>(*fieldIter())().write();
|
||||||
|
|
||||||
nReconstructed_++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,117 +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/>.
|
|
||||||
|
|
||||||
InClass
|
|
||||||
Foam::reconstructLagrangian
|
|
||||||
|
|
||||||
Description
|
|
||||||
|
|
||||||
SourceFiles
|
|
||||||
reconstructLagrangianPositions.C
|
|
||||||
reconstructLagrangianFields.C
|
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef reconstructLagrangian_H
|
|
||||||
#define reconstructLagrangian_H
|
|
||||||
|
|
||||||
#include "cloud.H"
|
|
||||||
#include "polyMesh.H"
|
|
||||||
#include "IOobjectList.H"
|
|
||||||
#include "CompactIOField.H"
|
|
||||||
#include "fvMesh.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
namespace Foam
|
|
||||||
{
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void reconstructLagrangianPositions
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const word& cloudName,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const labelListList& faceProcAddressing,
|
|
||||||
const labelListList& cellProcAddressing
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
tmp<IOField<Type>> reconstructLagrangianField
|
|
||||||
(
|
|
||||||
const word& cloudName,
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const word& fieldName
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
tmp<CompactIOField<Field<Type>>> reconstructLagrangianFieldField
|
|
||||||
(
|
|
||||||
const word& cloudName,
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const word& fieldName
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void reconstructLagrangianFields
|
|
||||||
(
|
|
||||||
const word& cloudName,
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const IOobjectList& objects,
|
|
||||||
const HashSet<word>& selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void reconstructLagrangianFieldFields
|
|
||||||
(
|
|
||||||
const word& cloudName,
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const IOobjectList& objects,
|
|
||||||
const HashSet<word>& selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
} // End namespace Foam
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#ifdef NoRepository
|
|
||||||
#include "reconstructLagrangianFields.C"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,273 +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 "IOField.H"
|
|
||||||
#include "CompactIOField.H"
|
|
||||||
#include "Time.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::tmp<Foam::IOField<Type>> Foam::reconstructLagrangianField
|
|
||||||
(
|
|
||||||
const word& cloudName,
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const word& fieldName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Construct empty field on mesh
|
|
||||||
tmp<IOField<Type>> tfield
|
|
||||||
(
|
|
||||||
new IOField<Type>
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
mesh.time().name(),
|
|
||||||
cloud::prefix/cloudName,
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
),
|
|
||||||
Field<Type>(0)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Field<Type>& field = tfield.ref();
|
|
||||||
|
|
||||||
forAll(meshes, i)
|
|
||||||
{
|
|
||||||
// Check object on local mesh
|
|
||||||
typeIOobject<IOField<Type>> localIOobject
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
meshes[i].time().name(),
|
|
||||||
cloud::prefix/cloudName,
|
|
||||||
meshes[i],
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
);
|
|
||||||
|
|
||||||
if (localIOobject.headerOk())
|
|
||||||
{
|
|
||||||
IOField<Type> fieldi(localIOobject);
|
|
||||||
|
|
||||||
label offset = field.size();
|
|
||||||
field.setSize(offset + fieldi.size());
|
|
||||||
|
|
||||||
forAll(fieldi, j)
|
|
||||||
{
|
|
||||||
field[offset + j] = fieldi[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
Foam::tmp<Foam::CompactIOField<Foam::Field<Type>>>
|
|
||||||
Foam::reconstructLagrangianFieldField
|
|
||||||
(
|
|
||||||
const word& cloudName,
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const word& fieldName
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// Construct empty field on mesh
|
|
||||||
tmp<CompactIOField<Field<Type>>> tfield
|
|
||||||
(
|
|
||||||
new CompactIOField<Field<Type>>
|
|
||||||
(
|
|
||||||
IOobject
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
mesh.time().name(),
|
|
||||||
cloud::prefix/cloudName,
|
|
||||||
mesh,
|
|
||||||
IOobject::NO_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
),
|
|
||||||
Field<Field<Type>>(0)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
Field<Field<Type>>& field = tfield.ref();
|
|
||||||
|
|
||||||
forAll(meshes, i)
|
|
||||||
{
|
|
||||||
// No type checking is done to handle CompactIOField and IOField
|
|
||||||
IOobject localIOobject
|
|
||||||
(
|
|
||||||
fieldName,
|
|
||||||
meshes[i].time().name(),
|
|
||||||
cloud::prefix/cloudName,
|
|
||||||
meshes[i],
|
|
||||||
IOobject::MUST_READ,
|
|
||||||
IOobject::NO_WRITE
|
|
||||||
);
|
|
||||||
|
|
||||||
if (localIOobject.headerOk())
|
|
||||||
{
|
|
||||||
CompactIOField<Field<Type>> fieldi(localIOobject);
|
|
||||||
|
|
||||||
label offset = field.size();
|
|
||||||
field.setSize(offset + fieldi.size());
|
|
||||||
|
|
||||||
forAll(fieldi, j)
|
|
||||||
{
|
|
||||||
field[offset + j] = fieldi[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tfield;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::reconstructLagrangianFields
|
|
||||||
(
|
|
||||||
const word& cloudName,
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const IOobjectList& objects,
|
|
||||||
const HashSet<word>& selectedFields
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const word fieldClassName(IOField<Type>::typeName);
|
|
||||||
|
|
||||||
IOobjectList fields = objects.lookupClass(fieldClassName);
|
|
||||||
|
|
||||||
if (fields.size())
|
|
||||||
{
|
|
||||||
Info<< " Reconstructing lagrangian "
|
|
||||||
<< fieldClassName << "s\n" << endl;
|
|
||||||
|
|
||||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
selectedFields.empty()
|
|
||||||
|| selectedFields.found(fieldIter()->name())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Info<< " " << fieldIter()->name() << endl;
|
|
||||||
reconstructLagrangianField<Type>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
mesh,
|
|
||||||
meshes,
|
|
||||||
fieldIter()->name()
|
|
||||||
)().write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
|
||||||
void Foam::reconstructLagrangianFieldFields
|
|
||||||
(
|
|
||||||
const word& cloudName,
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const IOobjectList& objects,
|
|
||||||
const HashSet<word>& selectedFields
|
|
||||||
)
|
|
||||||
{
|
|
||||||
{
|
|
||||||
const word fieldClassName(CompactIOField<Field<Type>>::typeName);
|
|
||||||
|
|
||||||
IOobjectList fields = objects.lookupClass(fieldClassName);
|
|
||||||
|
|
||||||
if (fields.size())
|
|
||||||
{
|
|
||||||
Info<< " Reconstructing lagrangian "
|
|
||||||
<< fieldClassName << "s\n" << endl;
|
|
||||||
|
|
||||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
selectedFields.empty()
|
|
||||||
|| selectedFields.found(fieldIter()->name())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Info<< " " << fieldIter()->name() << endl;
|
|
||||||
reconstructLagrangianFieldField<Type>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
mesh,
|
|
||||||
meshes,
|
|
||||||
fieldIter()->name()
|
|
||||||
)().write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
const word fieldClassName(IOField<Field<Type>>::typeName);
|
|
||||||
|
|
||||||
IOobjectList fields = objects.lookupClass(fieldClassName);
|
|
||||||
|
|
||||||
if (fields.size())
|
|
||||||
{
|
|
||||||
Info<< " Reconstructing lagrangian "
|
|
||||||
<< fieldClassName << "s\n" << endl;
|
|
||||||
|
|
||||||
forAllConstIter(IOobjectList, fields, fieldIter)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
selectedFields.empty()
|
|
||||||
|| selectedFields.found(fieldIter()->name())
|
|
||||||
)
|
|
||||||
{
|
|
||||||
Info<< " " << fieldIter()->name() << endl;
|
|
||||||
reconstructLagrangianFieldField<Type>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
mesh,
|
|
||||||
meshes,
|
|
||||||
fieldIter()->name()
|
|
||||||
)().write();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Info<< endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -1,83 +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 "reconstructLagrangian.H"
|
|
||||||
#include "labelIOList.H"
|
|
||||||
#include "passiveParticleCloud.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::reconstructLagrangianPositions
|
|
||||||
(
|
|
||||||
const polyMesh& mesh,
|
|
||||||
const word& cloudName,
|
|
||||||
const PtrList<fvMesh>& meshes,
|
|
||||||
const labelListList& faceProcAddressing,
|
|
||||||
const labelListList& cellProcAddressing
|
|
||||||
)
|
|
||||||
{
|
|
||||||
passiveParticleCloud lagrangianPositions
|
|
||||||
(
|
|
||||||
mesh,
|
|
||||||
cloudName,
|
|
||||||
IDLList<passiveParticle>()
|
|
||||||
);
|
|
||||||
|
|
||||||
forAll(meshes, i)
|
|
||||||
{
|
|
||||||
const labelList& cellMap = cellProcAddressing[i];
|
|
||||||
const labelList& faceMap = faceProcAddressing[i];
|
|
||||||
|
|
||||||
Cloud<passiveParticle> lpi(meshes[i], cloudName, false);
|
|
||||||
|
|
||||||
forAllConstIter(Cloud<passiveParticle>, lpi, iter)
|
|
||||||
{
|
|
||||||
const passiveParticle& ppi = iter();
|
|
||||||
|
|
||||||
const label mappedCell = cellMap[ppi.cell()];
|
|
||||||
|
|
||||||
// Inverting sign if necessary and subtracting 1 from
|
|
||||||
// faceProcAddressing
|
|
||||||
label mappedTetFace = mag(faceMap[ppi.tetFace()]) - 1;
|
|
||||||
|
|
||||||
lagrangianPositions.append
|
|
||||||
(
|
|
||||||
new passiveParticle
|
|
||||||
(
|
|
||||||
mesh,
|
|
||||||
ppi.coordinates(),
|
|
||||||
mappedCell,
|
|
||||||
mappedTetFace,
|
|
||||||
ppi.procTetPt(meshes[i], mesh, mappedCell, mappedTetFace)
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IOPosition<Cloud<passiveParticle>>(lagrangianPositions).write();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
|
||||||
@ -34,10 +34,10 @@ Description
|
|||||||
#include "timeSelector.H"
|
#include "timeSelector.H"
|
||||||
#include "IOobjectList.H"
|
#include "IOobjectList.H"
|
||||||
#include "processorRunTimes.H"
|
#include "processorRunTimes.H"
|
||||||
#include "domainDecomposition.H"
|
#include "multiDomainDecomposition.H"
|
||||||
#include "fvFieldReconstructor.H"
|
#include "fvFieldReconstructor.H"
|
||||||
#include "pointFieldReconstructor.H"
|
#include "pointFieldReconstructor.H"
|
||||||
#include "reconstructLagrangian.H"
|
#include "lagrangianFieldReconstructor.H"
|
||||||
|
|
||||||
using namespace Foam;
|
using namespace Foam;
|
||||||
|
|
||||||
@ -46,21 +46,37 @@ using namespace Foam;
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
bool haveAllTimes
|
bool haveUniform
|
||||||
(
|
(
|
||||||
const HashSet<word>& masterTimeDirSet,
|
const processorRunTimes& runTimes,
|
||||||
const instantList& timeDirs
|
const word& regionDir = word::null
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// Loop over all times
|
return
|
||||||
forAll(timeDirs, timei)
|
fileHandler().isDir
|
||||||
{
|
(
|
||||||
if (!masterTimeDirSet.found(timeDirs[timei].name()))
|
fileHandler().filePath
|
||||||
{
|
(
|
||||||
return false;
|
runTimes.procTimes()[0].timePath()/regionDir/"uniform"
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
void reconstructUniform
|
||||||
|
(
|
||||||
|
const processorRunTimes& runTimes,
|
||||||
|
const word& regionDir = word::null
|
||||||
|
)
|
||||||
|
{
|
||||||
|
fileHandler().cp
|
||||||
|
(
|
||||||
|
fileHandler().filePath
|
||||||
|
(
|
||||||
|
runTimes.procTimes()[0].timePath()/regionDir/"uniform"
|
||||||
|
),
|
||||||
|
runTimes.completeTime().timePath()/regionDir
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -85,14 +101,41 @@ void writeDecomposition(const domainDecomposition& meshes)
|
|||||||
cellProc.write();
|
cellProc.write();
|
||||||
|
|
||||||
Info<< "Wrote decomposition as volScalarField::Internal to "
|
Info<< "Wrote decomposition as volScalarField::Internal to "
|
||||||
<< cellProc.name() << " for use in postprocessing."
|
<< cellProc.name() << " for use in postprocessing"
|
||||||
<< nl << endl;
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
class delayedNewLine
|
||||||
|
{
|
||||||
|
mutable bool first_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
delayedNewLine()
|
||||||
|
:
|
||||||
|
first_(true)
|
||||||
|
{}
|
||||||
|
|
||||||
|
friend Ostream& operator<<(Ostream& os, const delayedNewLine& dnl)
|
||||||
|
{
|
||||||
|
if (!dnl.first_) os << nl;
|
||||||
|
dnl.first_ = false;
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -102,9 +145,6 @@ int main(int argc, char *argv[])
|
|||||||
"Reconstruct fields of a parallel case"
|
"Reconstruct fields of a parallel case"
|
||||||
);
|
);
|
||||||
|
|
||||||
// Enable -constant ... if someone really wants it
|
|
||||||
// Enable -withZero to prevent accidentally trashing the initial fields
|
|
||||||
timeSelector::addOptions(true, true);
|
|
||||||
argList::noParallel();
|
argList::noParallel();
|
||||||
#include "addRegionOption.H"
|
#include "addRegionOption.H"
|
||||||
#include "addAllRegionsOption.H"
|
#include "addAllRegionsOption.H"
|
||||||
@ -112,7 +152,7 @@ int main(int argc, char *argv[])
|
|||||||
(
|
(
|
||||||
"cellProc",
|
"cellProc",
|
||||||
"write cell processor indices as a volScalarField::Internal for "
|
"write cell processor indices as a volScalarField::Internal for "
|
||||||
"post-processing."
|
"post-processing"
|
||||||
);
|
);
|
||||||
argList::addOption
|
argList::addOption
|
||||||
(
|
(
|
||||||
@ -132,7 +172,7 @@ int main(int argc, char *argv[])
|
|||||||
"list",
|
"list",
|
||||||
"specify a list of lagrangian fields to be reconstructed. Eg, '(U d)' -"
|
"specify a list of lagrangian fields to be reconstructed. Eg, '(U d)' -"
|
||||||
"regular expressions not currently supported, "
|
"regular expressions not currently supported, "
|
||||||
"positions always included."
|
"positions always included"
|
||||||
);
|
);
|
||||||
argList::addBoolOption
|
argList::addBoolOption
|
||||||
(
|
(
|
||||||
@ -150,6 +190,10 @@ int main(int argc, char *argv[])
|
|||||||
"only reconstruct new times (i.e. that do not exist already)"
|
"only reconstruct new times (i.e. that do not exist already)"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Include explicit constant options, and explicit zero option (to prevent
|
||||||
|
// the user accidentally trashing the initial fields)
|
||||||
|
timeSelector::addOptions(true, true);
|
||||||
|
|
||||||
#include "setRootCase.H"
|
#include "setRootCase.H"
|
||||||
|
|
||||||
const bool writeCellProc = args.optionFound("cellProc");
|
const bool writeCellProc = args.optionFound("cellProc");
|
||||||
@ -164,8 +208,7 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
if (noFields)
|
if (noFields)
|
||||||
{
|
{
|
||||||
Info<< "Skipping reconstructing fields"
|
Info<< "Skipping reconstructing fields" << nl << endl;
|
||||||
<< nl << endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool noLagrangian = args.optionFound("noLagrangian");
|
const bool noLagrangian = args.optionFound("noLagrangian");
|
||||||
@ -191,7 +234,7 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
FatalErrorInFunction
|
FatalErrorInFunction
|
||||||
<< "Cannot specify noLagrangian and lagrangianFields "
|
<< "Cannot specify noLagrangian and lagrangianFields "
|
||||||
<< "options together."
|
<< "options together"
|
||||||
<< exit(FatalError);
|
<< exit(FatalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,11 +242,11 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set time from database
|
// Set time from database
|
||||||
Info<< "Create time\n" << endl;
|
Info<< "Create time" << nl << endl;
|
||||||
processorRunTimes runTimes(Foam::Time::controlDictName, args);
|
processorRunTimes runTimes(Foam::Time::controlDictName, args);
|
||||||
|
|
||||||
// Allow override of time
|
// Get the times to reconstruct
|
||||||
const instantList times = runTimes.selectProc(args);
|
instantList times = runTimes.selectProc(args);
|
||||||
|
|
||||||
const Time& runTime = runTimes.procTimes()[0];
|
const Time& runTime = runTimes.procTimes()[0];
|
||||||
|
|
||||||
@ -228,70 +271,67 @@ int main(int argc, char *argv[])
|
|||||||
// Warn fileHandler of number of processors
|
// Warn fileHandler of number of processors
|
||||||
const_cast<fileOperation&>(fileHandler()).setNProcs(nProcs);
|
const_cast<fileOperation&>(fileHandler()).setNProcs(nProcs);
|
||||||
|
|
||||||
// Note that we do not set the runTime time so it is still the
|
// Quit if no times
|
||||||
// one set through the controlDict. The -time option
|
|
||||||
// only affects the selected set of times from processor0.
|
|
||||||
// - can be illogical
|
|
||||||
// + any point motion handled through mesh.readUpdate
|
|
||||||
if (times.empty())
|
if (times.empty())
|
||||||
{
|
{
|
||||||
WarningInFunction << "No times selected" << endl;
|
WarningInFunction << "No times selected" << nl << endl;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get current times if -newTimes
|
// If only reconstructing new times then filter out existing times
|
||||||
const bool newTimes = args.optionFound("newTimes");
|
if (args.optionFound("newTimes"))
|
||||||
instantList masterTimeDirs;
|
|
||||||
if (newTimes)
|
|
||||||
{
|
{
|
||||||
masterTimeDirs = runTimes.completeTime().times();
|
// Get all existing times
|
||||||
|
const instantList existingTimes = runTimes.completeTime().times();
|
||||||
|
|
||||||
|
// Put into a set
|
||||||
|
HashSet<word> existingTimesSet;
|
||||||
|
existingTimesSet.resize(2*existingTimes.size());
|
||||||
|
forAll(existingTimes, i)
|
||||||
|
{
|
||||||
|
existingTimesSet.insert(existingTimes[i].name());
|
||||||
}
|
}
|
||||||
HashSet<word> masterTimeDirSet(2*masterTimeDirs.size());
|
|
||||||
forAll(masterTimeDirs, i)
|
// Remove times from the existing time set by shuffling up
|
||||||
|
label timei = 0;
|
||||||
|
forAll(times, timej)
|
||||||
{
|
{
|
||||||
masterTimeDirSet.insert(masterTimeDirs[i].name());
|
if (!existingTimesSet.found(times[timej].name()))
|
||||||
|
{
|
||||||
|
times[timei ++] = times[timej];
|
||||||
}
|
}
|
||||||
if
|
}
|
||||||
(
|
times.resize(timei);
|
||||||
newTimes
|
}
|
||||||
&& regionNames.size() == 1
|
|
||||||
&& regionNames[0] == fvMesh::defaultRegion
|
// Quit if no times
|
||||||
&& haveAllTimes(masterTimeDirSet, times)
|
if (times.empty())
|
||||||
)
|
|
||||||
{
|
{
|
||||||
Info<< "All times already reconstructed.\n\nEnd\n" << endl;
|
Info<< "All times already reconstructed" << nl << nl
|
||||||
|
<< "End" << nl << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reconstruct all regions
|
// Create meshes
|
||||||
|
multiDomainDecomposition regionMeshes(runTimes, regionNames);
|
||||||
|
if (regionMeshes.readReconstruct(!noReconstructSets))
|
||||||
|
{
|
||||||
|
Info<< endl;
|
||||||
|
|
||||||
|
if (writeCellProc)
|
||||||
|
{
|
||||||
forAll(regionNames, regioni)
|
forAll(regionNames, regioni)
|
||||||
{
|
{
|
||||||
const word& regionName = regionNames[regioni];
|
writeDecomposition(regionMeshes.meshes(regioni)());
|
||||||
|
Info<< endl;
|
||||||
const word& regionDir =
|
|
||||||
regionName == polyMesh::defaultRegion
|
|
||||||
? word::null
|
|
||||||
: regionName;
|
|
||||||
|
|
||||||
// Create meshes
|
|
||||||
Info<< "\n\nReconstructing mesh " << regionName << nl << endl;
|
|
||||||
domainDecomposition meshes(runTimes, regionName);
|
|
||||||
if (meshes.readReconstruct(!noReconstructSets) && writeCellProc)
|
|
||||||
{
|
|
||||||
writeDecomposition(meshes);
|
|
||||||
fileHandler().flush();
|
fileHandler().flush();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Loop over all times
|
// Loop over all times
|
||||||
forAll(times, timei)
|
forAll(times, timei)
|
||||||
{
|
{
|
||||||
if (newTimes && masterTimeDirSet.found(times[timei].name()))
|
|
||||||
{
|
|
||||||
Info<< "Skipping time " << times[timei].name()
|
|
||||||
<< endl << endl;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the time
|
// Set the time
|
||||||
runTimes.setTime(times[timei], timei);
|
runTimes.setTime(times[timei], timei);
|
||||||
|
|
||||||
@ -299,413 +339,267 @@ int main(int argc, char *argv[])
|
|||||||
<< nl << endl;
|
<< nl << endl;
|
||||||
|
|
||||||
// Update the meshes
|
// Update the meshes
|
||||||
const fvMesh::readUpdateState state =
|
const fvMesh::readUpdateState stat =
|
||||||
meshes.readUpdateReconstruct();
|
regionMeshes.readUpdateReconstruct();
|
||||||
|
if (stat >= fvMesh::TOPO_CHANGE) Info<< endl;
|
||||||
|
|
||||||
// Write the mesh out, if necessary
|
// Write the mesh out (if anything has changed)
|
||||||
if (state != fvMesh::UNCHANGED)
|
regionMeshes.writeComplete(!noReconstructSets);
|
||||||
{
|
|
||||||
meshes.writeComplete(!noReconstructSets);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write the decomposition, if necessary
|
// Write the decomposition, if necessary
|
||||||
if
|
forAll(regionNames, regioni)
|
||||||
(
|
|
||||||
writeCellProc
|
|
||||||
&& meshes.completeMesh().facesInstance()
|
|
||||||
== runTimes.completeTime().name()
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
writeDecomposition(meshes);
|
if (writeCellProc && stat >= fvMesh::TOPO_CHANGE)
|
||||||
|
{
|
||||||
|
writeDecomposition(regionMeshes.meshes(regioni)());
|
||||||
|
Info<< endl;
|
||||||
fileHandler().flush();
|
fileHandler().flush();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get list of objects from processor0 database
|
// Do a region-by-region reconstruction of all the available fields
|
||||||
|
forAll(regionNames, regioni)
|
||||||
|
{
|
||||||
|
const word& regionName = regionNames[regioni];
|
||||||
|
const word regionDir =
|
||||||
|
regionName == polyMesh::defaultRegion ? word::null : regionName;
|
||||||
|
|
||||||
|
const delayedNewLine dnl;
|
||||||
|
|
||||||
|
// Prefixed scope
|
||||||
|
{
|
||||||
|
const RegionConstRef<domainDecomposition> meshes =
|
||||||
|
regionMeshes.meshes(regioni);
|
||||||
|
|
||||||
|
// Search for objects at this time
|
||||||
IOobjectList objects
|
IOobjectList objects
|
||||||
(
|
(
|
||||||
meshes.procMeshes()[0],
|
meshes().procMeshes()[0],
|
||||||
runTimes.procTimes()[0].name()
|
runTimes.procTimes()[0].name()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!noFields)
|
if (!noFields)
|
||||||
{
|
{
|
||||||
// If there are any FV fields, reconstruct them
|
Info<< dnl << "Reconstructing FV fields" << endl;
|
||||||
Info<< "Reconstructing FV fields" << nl << endl;
|
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
fvFieldReconstructor::reconstructs
|
||||||
|
(
|
||||||
|
objects,
|
||||||
|
selectedFields
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
fvFieldReconstructor fvReconstructor
|
fvFieldReconstructor fvReconstructor
|
||||||
(
|
(
|
||||||
meshes.completeMesh(),
|
meshes().completeMesh(),
|
||||||
meshes.procMeshes(),
|
meshes().procMeshes(),
|
||||||
meshes.procFaceAddressing(),
|
meshes().procFaceAddressing(),
|
||||||
meshes.procCellAddressing(),
|
meshes().procCellAddressing(),
|
||||||
meshes.procFaceAddressingBf()
|
meshes().procFaceAddressingBf()
|
||||||
);
|
);
|
||||||
|
|
||||||
fvReconstructor.reconstructFvVolumeInternalFields<scalar>
|
#define DO_FV_VOL_INTERNAL_FIELDS_TYPE(Type, nullArg) \
|
||||||
(
|
fvReconstructor.reconstructVolInternalFields<Type> \
|
||||||
objects,
|
(objects, selectedFields);
|
||||||
selectedFields
|
FOR_ALL_FIELD_TYPES(DO_FV_VOL_INTERNAL_FIELDS_TYPE)
|
||||||
);
|
#undef DO_FV_VOL_INTERNAL_FIELDS_TYPE
|
||||||
fvReconstructor.reconstructFvVolumeInternalFields<vector>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvVolumeInternalFields
|
|
||||||
<sphericalTensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvVolumeInternalFields<symmTensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvVolumeInternalFields<tensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
fvReconstructor.reconstructFvVolumeFields<scalar>
|
#define DO_FV_VOL_FIELDS_TYPE(Type, nullArg) \
|
||||||
(
|
fvReconstructor.reconstructVolFields<Type> \
|
||||||
objects,
|
(objects, selectedFields);
|
||||||
selectedFields
|
FOR_ALL_FIELD_TYPES(DO_FV_VOL_FIELDS_TYPE)
|
||||||
);
|
#undef DO_FV_VOL_FIELDS_TYPE
|
||||||
fvReconstructor.reconstructFvVolumeFields<vector>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvVolumeFields<sphericalTensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvVolumeFields<symmTensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvVolumeFields<tensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
fvReconstructor.reconstructFvSurfaceFields<scalar>
|
#define DO_FV_SURFACE_FIELDS_TYPE(Type, nullArg) \
|
||||||
(
|
fvReconstructor.reconstructFvSurfaceFields<Type> \
|
||||||
objects,
|
(objects, selectedFields);
|
||||||
selectedFields
|
FOR_ALL_FIELD_TYPES(DO_FV_SURFACE_FIELDS_TYPE)
|
||||||
);
|
#undef DO_FV_SURFACE_FIELDS_TYPE
|
||||||
fvReconstructor.reconstructFvSurfaceFields<vector>
|
}
|
||||||
(
|
else
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvSurfaceFields<sphericalTensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvSurfaceFields<symmTensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
fvReconstructor.reconstructFvSurfaceFields<tensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
if (fvReconstructor.nReconstructed() == 0)
|
|
||||||
{
|
{
|
||||||
Info<< "No FV fields" << nl << endl;
|
Info<< dnl << " (no FV fields)" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!noFields)
|
if (!noFields)
|
||||||
{
|
{
|
||||||
Info<< "Reconstructing point fields" << nl << endl;
|
Info<< dnl << "Reconstructing point fields" << endl;
|
||||||
|
|
||||||
const pointMesh& completePMesh =
|
|
||||||
pointMesh::New(meshes.completeMesh());
|
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
pointFieldReconstructor::reconstructs
|
||||||
|
(
|
||||||
|
objects,
|
||||||
|
selectedFields
|
||||||
|
)
|
||||||
|
)
|
||||||
|
{
|
||||||
pointFieldReconstructor pointReconstructor
|
pointFieldReconstructor pointReconstructor
|
||||||
(
|
(
|
||||||
completePMesh,
|
pointMesh::New(meshes().completeMesh()),
|
||||||
meshes.procMeshes(),
|
meshes().procMeshes(),
|
||||||
meshes.procPointAddressing()
|
meshes().procPointAddressing()
|
||||||
);
|
);
|
||||||
|
|
||||||
pointReconstructor.reconstructFields<scalar>
|
#define DO_POINT_FIELDS_TYPE(Type, nullArg) \
|
||||||
(
|
pointReconstructor.reconstructFields<Type> \
|
||||||
objects,
|
(objects, selectedFields);
|
||||||
selectedFields
|
FOR_ALL_FIELD_TYPES(DO_POINT_FIELDS_TYPE)
|
||||||
);
|
#undef DO_POINT_FIELDS_TYPE
|
||||||
pointReconstructor.reconstructFields<vector>
|
}
|
||||||
(
|
else
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
pointReconstructor.reconstructFields<sphericalTensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
pointReconstructor.reconstructFields<symmTensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
pointReconstructor.reconstructFields<tensor>
|
|
||||||
(
|
|
||||||
objects,
|
|
||||||
selectedFields
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pointReconstructor.nReconstructed() == 0)
|
|
||||||
{
|
{
|
||||||
Info<< "No point fields" << nl << endl;
|
Info<< dnl << " (no point fields)" << endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// If there are any clouds, reconstruct them.
|
|
||||||
// The problem is that a cloud of size zero will not get written so
|
|
||||||
// in pass 1 we determine the cloud names and per cloud name the
|
|
||||||
// fields. Note that the fields are stored as IOobjectList from
|
|
||||||
// the first processor that has them. They are in pass2 only used
|
|
||||||
// for name and type (scalar, vector etc).
|
|
||||||
|
|
||||||
if (!noLagrangian)
|
if (!noLagrangian)
|
||||||
{
|
{
|
||||||
HashTable<IOobjectList> cloudObjects;
|
// Search for clouds that exist on any processor and add
|
||||||
|
// them into this table of cloud objects
|
||||||
|
HashTable<IOobjectList> cloudsObjects;
|
||||||
forAll(runTimes.procTimes(), proci)
|
forAll(runTimes.procTimes(), proci)
|
||||||
{
|
{
|
||||||
fileName lagrangianDir
|
// Find cloud directories
|
||||||
|
fileNameList cloudDirs
|
||||||
|
(
|
||||||
|
fileHandler().readDir
|
||||||
(
|
(
|
||||||
fileHandler().filePath
|
fileHandler().filePath
|
||||||
(
|
(
|
||||||
runTimes.procTimes()[proci].timePath()
|
runTimes.procTimes()[proci].timePath()
|
||||||
/regionDir
|
/regionDir
|
||||||
/cloud::prefix
|
/cloud::prefix
|
||||||
|
),
|
||||||
|
fileType::directory
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
fileNameList cloudDirs;
|
// Add objects in any found cloud directories
|
||||||
if (!lagrangianDir.empty())
|
|
||||||
{
|
|
||||||
cloudDirs = fileHandler().readDir
|
|
||||||
(
|
|
||||||
lagrangianDir,
|
|
||||||
fileType::directory
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
forAll(cloudDirs, i)
|
forAll(cloudDirs, i)
|
||||||
{
|
{
|
||||||
// Check if we already have cloud objects for this
|
// Pass if we already have an objects for this name
|
||||||
// cloudname
|
|
||||||
HashTable<IOobjectList>::const_iterator iter =
|
HashTable<IOobjectList>::const_iterator iter =
|
||||||
cloudObjects.find(cloudDirs[i]);
|
cloudsObjects.find(cloudDirs[i]);
|
||||||
|
if (iter != cloudsObjects.end()) continue;
|
||||||
|
|
||||||
if (iter == cloudObjects.end())
|
|
||||||
{
|
|
||||||
// Do local scan for valid cloud objects
|
// Do local scan for valid cloud objects
|
||||||
IOobjectList sprayObjs
|
IOobjectList cloudObjs
|
||||||
(
|
(
|
||||||
meshes.procMeshes()[proci],
|
meshes().procMeshes()[proci],
|
||||||
runTimes.procTimes()[proci].name(),
|
runTimes.procTimes()[proci].name(),
|
||||||
cloud::prefix/cloudDirs[i]
|
cloud::prefix/cloudDirs[i],
|
||||||
|
IOobject::MUST_READ,
|
||||||
|
IOobject::NO_WRITE,
|
||||||
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
IOobject* positionsPtr =
|
// If "positions" is present, then add to the table
|
||||||
sprayObjs.lookup(word("positions"));
|
if (cloudObjs.lookup(word("positions")))
|
||||||
|
|
||||||
if (positionsPtr)
|
|
||||||
{
|
{
|
||||||
cloudObjects.insert(cloudDirs[i], sprayObjs);
|
cloudsObjects.insert(cloudDirs[i], cloudObjs);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cloudObjects.size())
|
// Reconstruct the objects found above
|
||||||
|
if (cloudsObjects.size())
|
||||||
{
|
{
|
||||||
// Pass2: reconstruct the cloud
|
forAllConstIter
|
||||||
forAllConstIter(HashTable<IOobjectList>, cloudObjects, iter)
|
(
|
||||||
|
HashTable<IOobjectList>,
|
||||||
|
cloudsObjects,
|
||||||
|
iter
|
||||||
|
)
|
||||||
{
|
{
|
||||||
const word cloudName =
|
const word cloudName =
|
||||||
string::validate<word>(iter.key());
|
string::validate<word>(iter.key());
|
||||||
|
|
||||||
// Objects (on arbitrary processor)
|
const IOobjectList& cloudObjects = iter();
|
||||||
const IOobjectList& sprayObjs = iter();
|
|
||||||
|
|
||||||
Info<< "Reconstructing lagrangian fields for cloud "
|
Info<< dnl << "Reconstructing lagrangian fields "
|
||||||
<< cloudName << nl << endl;
|
<< "for cloud " << cloudName << endl;
|
||||||
|
|
||||||
reconstructLagrangianPositions
|
if
|
||||||
(
|
(
|
||||||
meshes.completeMesh(),
|
lagrangianFieldReconstructor::reconstructs
|
||||||
cloudName,
|
|
||||||
meshes.procMeshes(),
|
|
||||||
meshes.procFaceAddressing(),
|
|
||||||
meshes.procCellAddressing()
|
|
||||||
);
|
|
||||||
reconstructLagrangianFields<label>
|
|
||||||
(
|
(
|
||||||
cloudName,
|
cloudObjects,
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
selectedLagrangianFields
|
||||||
);
|
)
|
||||||
reconstructLagrangianFieldFields<label>
|
)
|
||||||
|
{
|
||||||
|
lagrangianFieldReconstructor
|
||||||
|
lagrangianReconstructor
|
||||||
(
|
(
|
||||||
cloudName,
|
meshes().completeMesh(),
|
||||||
meshes.completeMesh(),
|
meshes().procMeshes(),
|
||||||
meshes.procMeshes(),
|
meshes().procFaceAddressing(),
|
||||||
sprayObjs,
|
meshes().procCellAddressing(),
|
||||||
selectedLagrangianFields
|
cloudName
|
||||||
);
|
);
|
||||||
reconstructLagrangianFields<scalar>
|
|
||||||
(
|
#define DO_CLOUD_FIELDS_TYPE(Type, nullArg) \
|
||||||
cloudName,
|
lagrangianReconstructor \
|
||||||
meshes.completeMesh(),
|
.reconstructFields<Type> \
|
||||||
meshes.procMeshes(),
|
(cloudObjects, selectedLagrangianFields);
|
||||||
sprayObjs,
|
DO_CLOUD_FIELDS_TYPE(label, );
|
||||||
selectedLagrangianFields
|
FOR_ALL_FIELD_TYPES(DO_CLOUD_FIELDS_TYPE)
|
||||||
);
|
#undef DO_CLOUD_FIELDS_TYPE
|
||||||
reconstructLagrangianFieldFields<scalar>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
reconstructLagrangianFields<vector>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
reconstructLagrangianFieldFields<vector>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
reconstructLagrangianFields<sphericalTensor>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
reconstructLagrangianFieldFields<sphericalTensor>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
reconstructLagrangianFields<symmTensor>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
reconstructLagrangianFieldFields<symmTensor>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
reconstructLagrangianFields<tensor>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
reconstructLagrangianFieldFields<tensor>
|
|
||||||
(
|
|
||||||
cloudName,
|
|
||||||
meshes.completeMesh(),
|
|
||||||
meshes.procMeshes(),
|
|
||||||
sprayObjs,
|
|
||||||
selectedLagrangianFields
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Info<< "No lagrangian fields" << nl << endl;
|
Info<< dnl << " (no lagrangian fields)"
|
||||||
|
<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a "uniform" directory in the time region
|
Info<< dnl;
|
||||||
// directory copy from the master processor
|
}
|
||||||
|
|
||||||
|
// Collect the uniform directory
|
||||||
|
if (haveUniform(runTimes))
|
||||||
{
|
{
|
||||||
fileName uniformDir0
|
Info<< "Collecting uniform files" << endl;
|
||||||
(
|
|
||||||
fileHandler().filePath
|
|
||||||
(
|
|
||||||
runTimes.procTimes()[0].timePath()/regionDir/"uniform"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!uniformDir0.empty() && fileHandler().isDir(uniformDir0))
|
reconstructUniform(runTimes);
|
||||||
|
|
||||||
|
Info<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regionNames == wordList(1, polyMesh::defaultRegion)) continue;
|
||||||
|
|
||||||
|
// Collect the region uniform directories
|
||||||
|
forAll(regionNames, regioni)
|
||||||
{
|
{
|
||||||
fileHandler().cp
|
const word& regionName = regionNames[regioni];
|
||||||
(
|
const word regionDir =
|
||||||
uniformDir0,
|
regionName == polyMesh::defaultRegion ? word::null : regionName;
|
||||||
runTimes.completeTime().timePath()/regionDir
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// For the first region of a multi-region case additionally
|
if (haveUniform(runTimes, regionDir))
|
||||||
// copy the "uniform" directory in the time directory
|
|
||||||
if (regioni == 0 && regionDir != word::null)
|
|
||||||
{
|
{
|
||||||
fileName uniformDir0
|
// Prefixed scope
|
||||||
(
|
|
||||||
fileHandler().filePath
|
|
||||||
(
|
|
||||||
runTimes.procTimes()[0].timePath()/"uniform"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!uniformDir0.empty() && fileHandler().isDir(uniformDir0))
|
|
||||||
{
|
{
|
||||||
fileHandler().cp
|
const RegionConstRef<domainDecomposition> meshes =
|
||||||
(
|
regionMeshes.meshes(regioni);
|
||||||
uniformDir0,
|
|
||||||
runTimes.completeTime().timePath()
|
Info<< "Collecting uniform files" << endl;
|
||||||
);
|
|
||||||
|
reconstructUniform(runTimes, regionDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info<< endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "\nEnd\n" << endl;
|
Info<< "End" << nl << endl;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,5 +2,8 @@ processorRunTimes.C
|
|||||||
domainDecomposition.C
|
domainDecomposition.C
|
||||||
domainDecompositionDecompose.C
|
domainDecompositionDecompose.C
|
||||||
domainDecompositionReconstruct.C
|
domainDecompositionReconstruct.C
|
||||||
|
domainDecompositionNonConformal.C
|
||||||
|
multiRegionPrefixer.C
|
||||||
|
multiDomainDecomposition.C
|
||||||
|
|
||||||
LIB = $(FOAM_LIBBIN)/libparallel
|
LIB = $(FOAM_LIBBIN)/libparallel
|
||||||
|
|||||||
@ -32,9 +32,7 @@ License
|
|||||||
#include "hexRef8Data.H"
|
#include "hexRef8Data.H"
|
||||||
#include "cyclicFvPatch.H"
|
#include "cyclicFvPatch.H"
|
||||||
#include "processorCyclicFvPatch.H"
|
#include "processorCyclicFvPatch.H"
|
||||||
#include "nonConformalCyclicFvPatch.H"
|
#include "nonConformalFvPatch.H"
|
||||||
#include "nonConformalProcessorCyclicFvPatch.H"
|
|
||||||
#include "nonConformalErrorFvPatch.H"
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
@ -46,471 +44,6 @@ namespace Foam
|
|||||||
|
|
||||||
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
void Foam::domainDecomposition::decomposePoints()
|
|
||||||
{
|
|
||||||
for (label proci = 0; proci < nProcs(); proci++)
|
|
||||||
{
|
|
||||||
fvMesh& procMesh = procMeshes_[proci];
|
|
||||||
|
|
||||||
const label pointsCompare =
|
|
||||||
compareInstances
|
|
||||||
(
|
|
||||||
completeMesh().pointsInstance(),
|
|
||||||
procMeshes_[proci].pointsInstance()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pointsCompare == -1)
|
|
||||||
{
|
|
||||||
procMesh.setPoints
|
|
||||||
(
|
|
||||||
pointField
|
|
||||||
(
|
|
||||||
completeMesh().points(),
|
|
||||||
procPointAddressing_[proci]
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::domainDecomposition::reconstructPoints()
|
|
||||||
{
|
|
||||||
const label pointsCompare =
|
|
||||||
compareInstances
|
|
||||||
(
|
|
||||||
completeMesh().pointsInstance(),
|
|
||||||
procMeshes_[0].pointsInstance()
|
|
||||||
);
|
|
||||||
|
|
||||||
if (pointsCompare == 1)
|
|
||||||
{
|
|
||||||
pointField completePoints(completeMesh().nPoints());
|
|
||||||
|
|
||||||
for (label proci = 0; proci < nProcs(); proci++)
|
|
||||||
{
|
|
||||||
const fvMesh& procMesh = procMeshes_[proci];
|
|
||||||
|
|
||||||
completePoints.rmap(procMesh.points(), procPointAddressing_[proci]);
|
|
||||||
}
|
|
||||||
|
|
||||||
completeMesh_->setPoints(completePoints);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::domainDecomposition::completeConformal() const
|
|
||||||
{
|
|
||||||
return completeMesh().conformal();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Foam::domainDecomposition::procsConformal() const
|
|
||||||
{
|
|
||||||
forAll(procMeshes_, proci)
|
|
||||||
{
|
|
||||||
if (!procMeshes_[proci].conformal())
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Foam::domainDecomposition::unconform()
|
|
||||||
{
|
|
||||||
// ...
|
|
||||||
auto checkNonConformalCoupledPatchOrdering = []
|
|
||||||
(
|
|
||||||
const labelPair& procs,
|
|
||||||
const fvPatch& fvp,
|
|
||||||
const fvPatch& nbrFvp,
|
|
||||||
const labelList& polyFacesPf,
|
|
||||||
const labelList& nbrPolyFacesPf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (fvp.size() != nbrFvp.size())
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Coupled patches " << fvp.name() << " and "
|
|
||||||
<< nbrFvp.name() << " are not the same size"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fvp.size())
|
|
||||||
{
|
|
||||||
for (label i = 1; i < fvp.size(); ++ i)
|
|
||||||
{
|
|
||||||
if
|
|
||||||
(
|
|
||||||
polyFacesPf[i - 1] > polyFacesPf[i]
|
|
||||||
? true
|
|
||||||
: polyFacesPf[i - 1] == polyFacesPf[i]
|
|
||||||
? nbrPolyFacesPf[i - 1] >= nbrPolyFacesPf[i]
|
|
||||||
: false
|
|
||||||
)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Coupled patches " << fvp.name()
|
|
||||||
<< " and " << nbrFvp.name()
|
|
||||||
<< " are not in order";
|
|
||||||
|
|
||||||
if (procs[0] == procs[1])
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< " on process #" << procs[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoInFunction
|
|
||||||
<< "Coupled patches " << fvp.name()
|
|
||||||
<< " and " << nbrFvp.name()
|
|
||||||
<< " are in order" << endl;
|
|
||||||
};
|
|
||||||
|
|
||||||
// ...
|
|
||||||
auto checkNonConformalErrorPatchOrdering = []
|
|
||||||
(
|
|
||||||
const label& proci,
|
|
||||||
const fvPatch& fvp,
|
|
||||||
const labelList& polyFacesPf
|
|
||||||
)
|
|
||||||
{
|
|
||||||
if (fvp.size())
|
|
||||||
{
|
|
||||||
for (label i = 1; i < fvp.size(); ++ i)
|
|
||||||
{
|
|
||||||
if (polyFacesPf[i - 1] > polyFacesPf[i])
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Error patch " << fvp.name()
|
|
||||||
<< " is not in order";
|
|
||||||
|
|
||||||
if (proci > 0)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< " on process #" << proci;
|
|
||||||
}
|
|
||||||
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
InfoInFunction
|
|
||||||
<< "Error patch " << fvp.name()
|
|
||||||
<< " is in order" << endl;
|
|
||||||
};
|
|
||||||
|
|
||||||
if (completeConformal() && procsConformal())
|
|
||||||
{
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
else if (!completeConformal() && procsConformal())
|
|
||||||
{
|
|
||||||
// Construct the reverse of proc-face-face addressing
|
|
||||||
labelList faceProcFace(completeMesh().nFaces(), -labelMax);
|
|
||||||
forAll(procMeshes_, proci)
|
|
||||||
{
|
|
||||||
forAll(procFaceAddressing()[proci], procFacei)
|
|
||||||
{
|
|
||||||
const label facei =
|
|
||||||
mag(procFaceAddressing()[proci][procFacei]) - 1;
|
|
||||||
|
|
||||||
faceProcFace[facei] =
|
|
||||||
faceProcFace[facei] == -labelMax ? procFacei : -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Map the polyFacesBf from the complete to the processor meshes and
|
|
||||||
// unconform the processor meshes. Set dummy data for the face
|
|
||||||
// geometry. This should not be used during decomposition.
|
|
||||||
forAll(procMeshes_, proci)
|
|
||||||
{
|
|
||||||
fvMesh& procMesh = procMeshes_[proci];
|
|
||||||
|
|
||||||
const surfaceLabelField::Boundary& faceAddressingBf =
|
|
||||||
procFaceAddressingBf()[proci];
|
|
||||||
|
|
||||||
surfaceLabelField::Boundary polyFacesBf
|
|
||||||
(
|
|
||||||
surfaceLabelField::null(),
|
|
||||||
procMesh.polyFacesBf()
|
|
||||||
);
|
|
||||||
surfaceVectorField Sf(procMesh.Sf().cloneUnSliced());
|
|
||||||
surfaceVectorField Cf(procMesh.Cf().cloneUnSliced());
|
|
||||||
|
|
||||||
forAll(procMesh.boundary(), procNccPatchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp = procMesh.boundary()[procNccPatchi];
|
|
||||||
|
|
||||||
if (isA<nonConformalFvPatch>(fvp))
|
|
||||||
{
|
|
||||||
const label completeNccPatchi =
|
|
||||||
isA<processorCyclicFvPatch>(fvp)
|
|
||||||
? refCast<const processorCyclicFvPatch>(fvp)
|
|
||||||
.referPatchID()
|
|
||||||
: procNccPatchi;
|
|
||||||
|
|
||||||
polyFacesBf[procNccPatchi] =
|
|
||||||
labelField
|
|
||||||
(
|
|
||||||
faceProcFace,
|
|
||||||
labelField
|
|
||||||
(
|
|
||||||
completeMesh().polyFacesBf()[completeNccPatchi],
|
|
||||||
mag(faceAddressingBf[procNccPatchi]) - 1
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
const label size = polyFacesBf[procNccPatchi].size();
|
|
||||||
|
|
||||||
Sf.boundaryFieldRef()[procNccPatchi].resize(size, Zero);
|
|
||||||
Cf.boundaryFieldRef()[procNccPatchi].resize(size, Zero);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
procMesh.unconform
|
|
||||||
(
|
|
||||||
polyFacesBf,
|
|
||||||
Sf,
|
|
||||||
Cf,
|
|
||||||
NullObjectRef<surfaceScalarField>(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check ordering
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
forAll(procMeshes_, proci)
|
|
||||||
{
|
|
||||||
forAll(procMeshes_[proci].boundary(), patchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp =
|
|
||||||
procMeshes_[proci].boundary()[patchi];
|
|
||||||
|
|
||||||
// Coupled patches
|
|
||||||
if
|
|
||||||
(
|
|
||||||
isA<nonConformalCoupledFvPatch>(fvp)
|
|
||||||
&& refCast<const nonConformalCoupledFvPatch>(fvp).owner()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const label nccPatchi = patchi;
|
|
||||||
|
|
||||||
label nbrProci = -1, nbrNccPatchi = -1;
|
|
||||||
if (isA<cyclicFvPatch>(fvp))
|
|
||||||
{
|
|
||||||
nbrProci = proci;
|
|
||||||
nbrNccPatchi =
|
|
||||||
refCast<const cyclicFvPatch>(fvp).nbrPatchID();
|
|
||||||
}
|
|
||||||
else if (isA<processorCyclicFvPatch>(fvp))
|
|
||||||
{
|
|
||||||
typedef processorCyclicFvPatch PcFvp;
|
|
||||||
|
|
||||||
const PcFvp& pcFvp = refCast<const PcFvp>(fvp);
|
|
||||||
|
|
||||||
nbrProci = pcFvp.neighbProcNo();
|
|
||||||
|
|
||||||
const fvBoundaryMesh& nbrFvPatches =
|
|
||||||
procMeshes_[nbrProci].boundary();
|
|
||||||
|
|
||||||
forAll(nbrFvPatches, nbrNccPatchj)
|
|
||||||
{
|
|
||||||
const fvPatch& nbrFvp =
|
|
||||||
nbrFvPatches[nbrNccPatchj];
|
|
||||||
|
|
||||||
if (isA<PcFvp>(nbrFvp))
|
|
||||||
{
|
|
||||||
const PcFvp& nbrPcFvp =
|
|
||||||
refCast<const PcFvp>(nbrFvp);
|
|
||||||
|
|
||||||
if
|
|
||||||
(
|
|
||||||
nbrPcFvp.neighbProcNo()
|
|
||||||
== proci
|
|
||||||
&& nbrPcFvp.referPatchID()
|
|
||||||
== pcFvp.referPatch().nbrPatchID()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
nbrNccPatchi = nbrNccPatchj;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nbrNccPatchi == -1)
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Opposite processor patch not found for "
|
|
||||||
<< "patch " << fvp.name() << " on proc #"
|
|
||||||
<< proci << exit(FatalError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "Non-conformal-coupled type not recognised "
|
|
||||||
<< "for patch " << fvp.name() << " on proc #"
|
|
||||||
<< proci << exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
checkNonConformalCoupledPatchOrdering
|
|
||||||
(
|
|
||||||
{proci, nbrProci},
|
|
||||||
procMeshes_[proci].boundary()[nccPatchi],
|
|
||||||
procMeshes_[nbrProci].boundary()[nbrNccPatchi],
|
|
||||||
procMeshes_[proci].polyFacesBf()[nccPatchi],
|
|
||||||
procMeshes_[nbrProci].polyFacesBf()[nbrNccPatchi]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error patches
|
|
||||||
if (isA<nonConformalErrorFvPatch>(fvp))
|
|
||||||
{
|
|
||||||
const label ncePatchi = patchi;
|
|
||||||
|
|
||||||
checkNonConformalErrorPatchOrdering
|
|
||||||
(
|
|
||||||
proci,
|
|
||||||
procMeshes_[proci].boundary()[ncePatchi],
|
|
||||||
procMeshes_[proci].polyFacesBf()[ncePatchi]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (completeConformal() && !procsConformal())
|
|
||||||
{
|
|
||||||
// Map the polyFacesBf from the processor to the complete meshes and
|
|
||||||
// unconform the complete mesh. Set dummy data for the face
|
|
||||||
// geometry. This should not be used during decomposition.
|
|
||||||
surfaceLabelField::Boundary polyFacesBf
|
|
||||||
(
|
|
||||||
surfaceLabelField::null(),
|
|
||||||
completeMesh().polyFacesBf()
|
|
||||||
);
|
|
||||||
surfaceVectorField Sf(completeMesh().Sf().cloneUnSliced());
|
|
||||||
surfaceVectorField Cf(completeMesh().Cf().cloneUnSliced());
|
|
||||||
|
|
||||||
forAll(procMeshes_, proci)
|
|
||||||
{
|
|
||||||
const fvMesh& procMesh = procMeshes_[proci];
|
|
||||||
|
|
||||||
const surfaceLabelField::Boundary& faceAddressingBf =
|
|
||||||
procFaceAddressingBf()[proci];
|
|
||||||
|
|
||||||
forAll(procMesh.boundary(), procNccPatchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp = procMesh.boundary()[procNccPatchi];
|
|
||||||
|
|
||||||
if (isA<nonConformalFvPatch>(fvp))
|
|
||||||
{
|
|
||||||
const label completeNccPatchi =
|
|
||||||
isA<processorCyclicFvPatch>(fvp)
|
|
||||||
? refCast<const processorCyclicFvPatch>(fvp)
|
|
||||||
.referPatchID()
|
|
||||||
: procNccPatchi;
|
|
||||||
|
|
||||||
const label size =
|
|
||||||
max
|
|
||||||
(
|
|
||||||
max(mag(faceAddressingBf[procNccPatchi])),
|
|
||||||
polyFacesBf[completeNccPatchi].size()
|
|
||||||
);
|
|
||||||
|
|
||||||
polyFacesBf[completeNccPatchi].resize(size, -1);
|
|
||||||
Sf.boundaryFieldRef()[completeNccPatchi].resize(size, Zero);
|
|
||||||
Cf.boundaryFieldRef()[completeNccPatchi].resize(size, Zero);
|
|
||||||
|
|
||||||
polyFacesBf[completeNccPatchi].labelField::rmap
|
|
||||||
(
|
|
||||||
mag
|
|
||||||
(
|
|
||||||
labelField
|
|
||||||
(
|
|
||||||
procFaceAddressing_[proci],
|
|
||||||
procMesh.polyFacesBf()[procNccPatchi]
|
|
||||||
)
|
|
||||||
) - 1,
|
|
||||||
mag(faceAddressingBf[procNccPatchi]) - 1
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
completeMesh_->unconform
|
|
||||||
(
|
|
||||||
polyFacesBf,
|
|
||||||
Sf,
|
|
||||||
Cf,
|
|
||||||
NullObjectRef<surfaceScalarField>(),
|
|
||||||
false
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check ordering
|
|
||||||
if (debug)
|
|
||||||
{
|
|
||||||
forAll(completeMesh().boundary(), patchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp = completeMesh().boundary()[patchi];
|
|
||||||
|
|
||||||
// Coupled patches
|
|
||||||
if
|
|
||||||
(
|
|
||||||
isA<nonConformalCyclicFvPatch>(fvp)
|
|
||||||
&& refCast<const nonConformalCoupledFvPatch>(fvp).owner()
|
|
||||||
)
|
|
||||||
{
|
|
||||||
const label nccPatchi = patchi;
|
|
||||||
|
|
||||||
const label nbrNccPatchi =
|
|
||||||
refCast<const nonConformalCyclicFvPatch>(fvp)
|
|
||||||
.nbrPatchID();
|
|
||||||
|
|
||||||
checkNonConformalCoupledPatchOrdering
|
|
||||||
(
|
|
||||||
{-labelMax, labelMax},
|
|
||||||
completeMesh().boundary()[nccPatchi],
|
|
||||||
completeMesh().boundary()[nbrNccPatchi],
|
|
||||||
completeMesh().polyFacesBf()[nccPatchi],
|
|
||||||
completeMesh().polyFacesBf()[nbrNccPatchi]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error patches
|
|
||||||
if (isA<nonConformalErrorFvPatch>(fvp))
|
|
||||||
{
|
|
||||||
const label ncePatchi = patchi;
|
|
||||||
|
|
||||||
checkNonConformalErrorPatchOrdering
|
|
||||||
(
|
|
||||||
-labelMax,
|
|
||||||
completeMesh().boundary()[ncePatchi],
|
|
||||||
completeMesh().polyFacesBf()[ncePatchi]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // if (!completeConformal() && !procsConformal())
|
|
||||||
{
|
|
||||||
// Assume everything is consistent and do nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Foam::label Foam::domainDecomposition::compareInstances
|
Foam::label Foam::domainDecomposition::compareInstances
|
||||||
(
|
(
|
||||||
const fileName& a,
|
const fileName& a,
|
||||||
@ -1284,277 +817,9 @@ Foam::domainDecomposition::procFaceAddressingBf() const
|
|||||||
|
|
||||||
if (procFaceAddressingBf_.empty())
|
if (procFaceAddressingBf_.empty())
|
||||||
{
|
{
|
||||||
// Map from reference patch and processors to the interface patch
|
// Get any non-conformal proc-face addressing
|
||||||
typedef HashTable<label, labelPair, Hash<labelPair>> labelPairTable;
|
List<List<DynamicList<label>>> nonConformalProcFaceAddressingBf =
|
||||||
List<labelPairTable> refPatchProcPatchTable
|
this->nonConformalProcFaceAddressingBf();
|
||||||
(
|
|
||||||
completeMesh().boundary().size()
|
|
||||||
);
|
|
||||||
forAll(procMeshes_, proci)
|
|
||||||
{
|
|
||||||
const fvMesh& procMesh = procMeshes_[proci];
|
|
||||||
|
|
||||||
forAll(procMesh.boundary(), procPatchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp = procMesh.boundary()[procPatchi];
|
|
||||||
|
|
||||||
if (isA<cyclicFvPatch>(fvp))
|
|
||||||
{
|
|
||||||
refPatchProcPatchTable[procPatchi].insert
|
|
||||||
(
|
|
||||||
labelPair(proci, proci),
|
|
||||||
procPatchi
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (isA<processorCyclicFvPatch>(fvp))
|
|
||||||
{
|
|
||||||
const processorCyclicFvPatch& pcFvp =
|
|
||||||
refCast<const processorCyclicFvPatch>(fvp);
|
|
||||||
|
|
||||||
refPatchProcPatchTable[pcFvp.referPatchID()].insert
|
|
||||||
(
|
|
||||||
labelPair(proci, pcFvp.neighbProcNo()),
|
|
||||||
procPatchi
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build non-conformal finite volume face addressing for each processor
|
|
||||||
List<List<DynamicList<label>>>
|
|
||||||
nonConformalProcFaceAddressingBf(nProcs());
|
|
||||||
forAll(nonConformalProcFaceAddressingBf, proci)
|
|
||||||
{
|
|
||||||
nonConformalProcFaceAddressingBf[proci].resize
|
|
||||||
(
|
|
||||||
procMeshes_[proci].boundary().size()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (completeConformal() && procsConformal())
|
|
||||||
{
|
|
||||||
// Nothing to do
|
|
||||||
}
|
|
||||||
else if (!completeConformal())
|
|
||||||
{
|
|
||||||
// Decompose non-conformal addressing
|
|
||||||
|
|
||||||
const surfaceLabelField::Boundary& polyFacesBf =
|
|
||||||
completeMesh().polyFacesBf();
|
|
||||||
|
|
||||||
// Cyclic patches
|
|
||||||
forAll(completeMesh().boundary(), nccPatchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp = completeMesh().boundary()[nccPatchi];
|
|
||||||
|
|
||||||
if (!isA<nonConformalCyclicFvPatch>(fvp)) continue;
|
|
||||||
|
|
||||||
const nonConformalCyclicFvPatch& nccFvp =
|
|
||||||
refCast<const nonConformalCyclicFvPatch>(fvp);
|
|
||||||
|
|
||||||
if (!nccFvp.owner()) continue;
|
|
||||||
|
|
||||||
const label nccNbrPatchi = nccFvp.nbrPatchID();
|
|
||||||
|
|
||||||
forAll(polyFacesBf[nccPatchi], nccPatchFacei)
|
|
||||||
{
|
|
||||||
const label facei = polyFacesBf[nccPatchi][nccPatchFacei];
|
|
||||||
const label celli = completeMesh().faceOwner()[facei];
|
|
||||||
const label proci = cellProc_[celli];
|
|
||||||
|
|
||||||
const label nbrFacei =
|
|
||||||
polyFacesBf[nccNbrPatchi][nccPatchFacei];
|
|
||||||
const label nbrCelli =
|
|
||||||
completeMesh().faceOwner()[nbrFacei];
|
|
||||||
const label nbrProci = cellProc_[nbrCelli];
|
|
||||||
|
|
||||||
const label procNccPatchi =
|
|
||||||
refPatchProcPatchTable
|
|
||||||
[nccPatchi][labelPair(proci, nbrProci)];
|
|
||||||
const label nbrProcNccPatchi =
|
|
||||||
refPatchProcPatchTable
|
|
||||||
[nccNbrPatchi][labelPair(nbrProci, proci)];
|
|
||||||
|
|
||||||
nonConformalProcFaceAddressingBf[proci][procNccPatchi]
|
|
||||||
.append(nccPatchFacei + 1);
|
|
||||||
nonConformalProcFaceAddressingBf[nbrProci][nbrProcNccPatchi]
|
|
||||||
.append(nccPatchFacei + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error patches
|
|
||||||
forAll(completeMesh().boundary(), ncePatchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp = completeMesh().boundary()[ncePatchi];
|
|
||||||
|
|
||||||
if (!isA<nonConformalErrorFvPatch>(fvp)) continue;
|
|
||||||
|
|
||||||
forAll(polyFacesBf[ncePatchi], ncePatchFacei)
|
|
||||||
{
|
|
||||||
const label facei = polyFacesBf[ncePatchi][ncePatchFacei];
|
|
||||||
const label celli = completeMesh().faceOwner()[facei];
|
|
||||||
const label proci = cellProc_[celli];
|
|
||||||
|
|
||||||
nonConformalProcFaceAddressingBf[proci][ncePatchi]
|
|
||||||
.append(ncePatchFacei + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // if (!procsConformal())
|
|
||||||
{
|
|
||||||
// Reconstruct non-conformal addressing
|
|
||||||
|
|
||||||
// Cyclic patches
|
|
||||||
forAll(completeMesh().boundary(), nccPatchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp = completeMesh().boundary()[nccPatchi];
|
|
||||||
|
|
||||||
if (!isA<nonConformalCyclicFvPatch>(fvp)) continue;
|
|
||||||
|
|
||||||
const nonConformalCyclicFvPatch& nccFvp =
|
|
||||||
refCast<const nonConformalCyclicFvPatch>(fvp);
|
|
||||||
|
|
||||||
if (!nccFvp.owner()) continue;
|
|
||||||
|
|
||||||
const label nccNbrPatchi = nccFvp.nbrPatchID();
|
|
||||||
|
|
||||||
label count = 0;
|
|
||||||
labelPairTable procCounts;
|
|
||||||
forAllConstIter
|
|
||||||
(
|
|
||||||
labelPairTable,
|
|
||||||
refPatchProcPatchTable[nccPatchi],
|
|
||||||
iter
|
|
||||||
)
|
|
||||||
{
|
|
||||||
procCounts.insert(iter.key(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
labelPair procNbrProc(labelMax, labelMax);
|
|
||||||
labelPair faceNbrFace(labelMax, labelMax);
|
|
||||||
|
|
||||||
forAllConstIter(labelPairTable, procCounts, iter)
|
|
||||||
{
|
|
||||||
const label proci = iter.key().first();
|
|
||||||
const label nbrProci = iter.key().second();
|
|
||||||
|
|
||||||
const labelPair procNbrProcStar(proci, nbrProci);
|
|
||||||
const labelPair nbrProcProcStar(nbrProci, proci);
|
|
||||||
|
|
||||||
const label procNccPatchi =
|
|
||||||
refPatchProcPatchTable
|
|
||||||
[nccPatchi][procNbrProcStar];
|
|
||||||
const label nbrProcNccPatchi =
|
|
||||||
refPatchProcPatchTable
|
|
||||||
[nccNbrPatchi][nbrProcProcStar];
|
|
||||||
|
|
||||||
const label size =
|
|
||||||
procMeshes_[proci]
|
|
||||||
.polyFacesBf()[procNccPatchi]
|
|
||||||
.size();
|
|
||||||
|
|
||||||
if (iter() >= size) continue;
|
|
||||||
|
|
||||||
const label procFacei =
|
|
||||||
procMeshes_[proci].polyFacesBf()
|
|
||||||
[procNccPatchi][iter()];
|
|
||||||
const label nbrProcFacei =
|
|
||||||
procMeshes_[nbrProci].polyFacesBf()
|
|
||||||
[nbrProcNccPatchi][iter()];
|
|
||||||
|
|
||||||
const labelPair faceNbrFaceStar
|
|
||||||
(
|
|
||||||
procFaceAddressing_[proci][procFacei] - 1,
|
|
||||||
procFaceAddressing_[nbrProci][nbrProcFacei] - 1
|
|
||||||
);
|
|
||||||
|
|
||||||
if (faceNbrFace > faceNbrFaceStar)
|
|
||||||
{
|
|
||||||
procNbrProc = procNbrProcStar;
|
|
||||||
faceNbrFace = faceNbrFaceStar;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (faceNbrFace == labelPair(labelMax, labelMax))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const label proci = procNbrProc.first();
|
|
||||||
const label nbrProci = procNbrProc.second();
|
|
||||||
|
|
||||||
const labelPair nbrProcProc(nbrProci, proci);
|
|
||||||
|
|
||||||
const label procNccPatchi =
|
|
||||||
refPatchProcPatchTable[nccPatchi][procNbrProc];
|
|
||||||
const label nbrProcNccPatchi =
|
|
||||||
refPatchProcPatchTable[nccNbrPatchi][nbrProcProc];
|
|
||||||
|
|
||||||
nonConformalProcFaceAddressingBf
|
|
||||||
[proci][procNccPatchi].append(count + 1);
|
|
||||||
nonConformalProcFaceAddressingBf
|
|
||||||
[nbrProci][nbrProcNccPatchi].append(count + 1);
|
|
||||||
|
|
||||||
count ++;
|
|
||||||
procCounts[procNbrProc] ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Error patches
|
|
||||||
forAll(completeMesh().boundary(), ncePatchi)
|
|
||||||
{
|
|
||||||
const fvPatch& fvp = completeMesh().boundary()[ncePatchi];
|
|
||||||
|
|
||||||
if (!isA<nonConformalErrorFvPatch>(fvp)) continue;
|
|
||||||
|
|
||||||
label count = 0;
|
|
||||||
labelList procCounts(nProcs(), 0);
|
|
||||||
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
label facei = labelMax, proci = labelMax;
|
|
||||||
|
|
||||||
forAll(procCounts, procStari)
|
|
||||||
{
|
|
||||||
const label size =
|
|
||||||
procMeshes_[procStari]
|
|
||||||
.polyFacesBf()[ncePatchi]
|
|
||||||
.size();
|
|
||||||
|
|
||||||
if (procCounts[procStari] >= size) continue;
|
|
||||||
|
|
||||||
const label procFacei =
|
|
||||||
procMeshes_[procStari].polyFacesBf()
|
|
||||||
[ncePatchi][procCounts[procStari]];
|
|
||||||
|
|
||||||
const label faceStari =
|
|
||||||
procFaceAddressing_[procStari][procFacei] - 1;
|
|
||||||
|
|
||||||
if (facei > faceStari)
|
|
||||||
{
|
|
||||||
facei = faceStari;
|
|
||||||
proci = procStari;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (facei == labelMax)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nonConformalProcFaceAddressingBf
|
|
||||||
[proci][ncePatchi].append(count + 1);
|
|
||||||
|
|
||||||
count ++;
|
|
||||||
procCounts[proci] ++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build finite volume face addressing boundary fields
|
// Build finite volume face addressing boundary fields
|
||||||
procFaceAddressingBf_.resize(nProcs());
|
procFaceAddressingBf_.resize(nProcs());
|
||||||
|
|||||||
@ -31,6 +31,7 @@ SourceFiles
|
|||||||
domainDecomposition.C
|
domainDecomposition.C
|
||||||
domainDecompositionDecompose.C
|
domainDecompositionDecompose.C
|
||||||
domainDecompositionReconstruct.C
|
domainDecompositionReconstruct.C
|
||||||
|
domainDecompositionReconstruct.C
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
@ -47,6 +48,8 @@ SourceFiles
|
|||||||
namespace Foam
|
namespace Foam
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class faceCoupleInfo;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*\
|
/*---------------------------------------------------------------------------*\
|
||||||
Class domainDecomposition Declaration
|
Class domainDecomposition Declaration
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
@ -100,8 +103,6 @@ class domainDecomposition
|
|||||||
mutable PtrList<surfaceLabelField::Boundary> procFaceAddressingBf_;
|
mutable PtrList<surfaceLabelField::Boundary> procFaceAddressingBf_;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Private Member Functions
|
// Private Member Functions
|
||||||
|
|
||||||
// Decomposition
|
// Decomposition
|
||||||
@ -145,26 +146,63 @@ class domainDecomposition
|
|||||||
BinaryOp bop
|
BinaryOp bop
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
//- Decompose the complete mesh to create the processor meshes and
|
||||||
|
// populate the addressing
|
||||||
|
void decompose();
|
||||||
|
|
||||||
//- Decompose the complete mesh's points and apply the result to the
|
//- Decompose the complete mesh's points and apply the result to
|
||||||
// processor meshes
|
// the processor meshes
|
||||||
void decomposePoints();
|
void decomposePoints();
|
||||||
|
|
||||||
//- Reconstruct the processor meshes' points and apply the result to
|
|
||||||
// the complete mesh
|
// Reconstruction
|
||||||
|
|
||||||
|
//- Find shared points and faces between two meshes that are to be
|
||||||
|
// added together
|
||||||
|
static autoPtr<faceCoupleInfo> determineCoupledFaces
|
||||||
|
(
|
||||||
|
const label masterMeshProcStart,
|
||||||
|
const label masterMeshProcEnd,
|
||||||
|
const polyMesh& masterMesh,
|
||||||
|
const label meshToAddProcStart,
|
||||||
|
const label meshToAddProcEnd,
|
||||||
|
const polyMesh& meshToAdd
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Reconstruct the processor meshes to create the complete mesh
|
||||||
|
// and populate the addressing
|
||||||
|
void reconstruct();
|
||||||
|
|
||||||
|
//- Reconstruct the processor meshes' points and apply the result
|
||||||
|
// to the complete mesh
|
||||||
void reconstructPoints();
|
void reconstructPoints();
|
||||||
|
|
||||||
|
|
||||||
|
// Non conformal
|
||||||
|
|
||||||
//- Is the complete mesh conformal?
|
//- Is the complete mesh conformal?
|
||||||
bool completeConformal() const;
|
bool completeConformal() const;
|
||||||
|
|
||||||
//- Are the processor meshes conformal?
|
//- Are the processor meshes conformal?
|
||||||
bool procsConformal() const;
|
bool procsConformal() const;
|
||||||
|
|
||||||
//- If the complete mesh is non-conformal and the processor meshes are
|
//- ...
|
||||||
// not, then map the non-conformal addressing across and unconform the
|
List<List<DynamicList<label>>>
|
||||||
// processor meshes. And vice versa.
|
nonConformalProcFaceAddressingBf() const;
|
||||||
|
|
||||||
|
// Map the polyFacesBf from the processor to the complete meshes and
|
||||||
|
// unconform the complete mesh
|
||||||
|
void unconformComplete();
|
||||||
|
|
||||||
|
// Map the polyFacesBf from the complete to the processor meshes and
|
||||||
|
// unconform the processor meshes
|
||||||
|
void unconformProcs();
|
||||||
|
|
||||||
|
//- If the complete mesh is non-conformal and the processor meshes
|
||||||
|
// are not, then unconform the processor meshes. And vice versa.
|
||||||
void unconform();
|
void unconform();
|
||||||
|
|
||||||
|
|
||||||
//- Compare two instances. A return value of -1 means a is newer than b
|
//- Compare two instances. A return value of -1 means a is newer than b
|
||||||
// (i.e., the arguments are in reverse order), 0 means a is equal to
|
// (i.e., the arguments are in reverse order), 0 means a is equal to
|
||||||
// b, and +1 means a is older than b (in order).
|
// b, and +1 means a is older than b (in order).
|
||||||
@ -194,14 +232,6 @@ class domainDecomposition
|
|||||||
//- Read-update the complete and processor meshes for a change in time
|
//- Read-update the complete and processor meshes for a change in time
|
||||||
fvMesh::readUpdateState readUpdate();
|
fvMesh::readUpdateState readUpdate();
|
||||||
|
|
||||||
//- Decompose the complete mesh to create the processor meshes and
|
|
||||||
// populate the addressing
|
|
||||||
void decompose();
|
|
||||||
|
|
||||||
//- Reconstruct the processor meshes to create the complete mesh and
|
|
||||||
// populate the addressing
|
|
||||||
void reconstruct();
|
|
||||||
|
|
||||||
//- Write the decomposition addressing
|
//- Write the decomposition addressing
|
||||||
void writeCompleteAddressing() const;
|
void writeCompleteAddressing() const;
|
||||||
|
|
||||||
@ -244,22 +274,34 @@ public:
|
|||||||
|
|
||||||
// Member Functions
|
// Member Functions
|
||||||
|
|
||||||
|
//- Access the run times
|
||||||
|
inline const processorRunTimes& procRunTimes() const
|
||||||
|
{
|
||||||
|
return runTimes_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Access the region name
|
||||||
|
inline const word& regionName() const
|
||||||
|
{
|
||||||
|
return regionName_;
|
||||||
|
}
|
||||||
|
|
||||||
//- Access the global mesh
|
//- Access the global mesh
|
||||||
const fvMesh& completeMesh() const
|
inline const fvMesh& completeMesh() const
|
||||||
{
|
{
|
||||||
validateComplete();
|
validateComplete();
|
||||||
return completeMesh_();
|
return completeMesh_();
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Access the processor meshes
|
//- Access the processor meshes
|
||||||
const PtrList<fvMesh>& procMeshes() const
|
inline const PtrList<fvMesh>& procMeshes() const
|
||||||
{
|
{
|
||||||
validateProcs();
|
validateProcs();
|
||||||
return procMeshes_;
|
return procMeshes_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Return the number of processors in the decomposition
|
//- Return the number of processors in the decomposition
|
||||||
label nProcs() const
|
inline label nProcs() const
|
||||||
{
|
{
|
||||||
return runTimes_.nProcs();
|
return runTimes_.nProcs();
|
||||||
}
|
}
|
||||||
@ -281,27 +323,27 @@ public:
|
|||||||
fvMesh::readUpdateState readUpdateReconstruct();
|
fvMesh::readUpdateState readUpdateReconstruct();
|
||||||
|
|
||||||
//- Return the distribution as an FV field for writing
|
//- Return the distribution as an FV field for writing
|
||||||
const labelList& cellProc() const
|
inline const labelList& cellProc() const
|
||||||
{
|
{
|
||||||
return cellProc_;
|
return cellProc_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Access the labels of points for each processor
|
//- Access the labels of points for each processor
|
||||||
const labelListList& procPointAddressing() const
|
inline const labelListList& procPointAddressing() const
|
||||||
{
|
{
|
||||||
validateProcs();
|
validateProcs();
|
||||||
return procPointAddressing_;
|
return procPointAddressing_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Access the labels of faces for each processor (see notes above)
|
//- Access the labels of faces for each processor (see notes above)
|
||||||
const labelListList& procFaceAddressing() const
|
inline const labelListList& procFaceAddressing() const
|
||||||
{
|
{
|
||||||
validateProcs();
|
validateProcs();
|
||||||
return procFaceAddressing_;
|
return procFaceAddressing_;
|
||||||
}
|
}
|
||||||
|
|
||||||
//- Access the labels of cells for each processor
|
//- Access the labels of cells for each processor
|
||||||
const labelListList& procCellAddressing() const
|
inline const labelListList& procCellAddressing() const
|
||||||
{
|
{
|
||||||
validateProcs();
|
validateProcs();
|
||||||
return procCellAddressing_;
|
return procCellAddressing_;
|
||||||
|
|||||||
@ -133,7 +133,7 @@ void Foam::domainDecomposition::addInterProcFace
|
|||||||
|
|
||||||
Foam::labelList Foam::domainDecomposition::distributeCells()
|
Foam::labelList Foam::domainDecomposition::distributeCells()
|
||||||
{
|
{
|
||||||
Info<< "\nCalculating distribution of cells" << endl;
|
Info<< "Calculating distribution of cells" << nl << endl;
|
||||||
|
|
||||||
cpuTime decompositionTime;
|
cpuTime decompositionTime;
|
||||||
|
|
||||||
@ -167,7 +167,7 @@ Foam::labelList Foam::domainDecomposition::distributeCells()
|
|||||||
cellWeights
|
cellWeights
|
||||||
);
|
);
|
||||||
|
|
||||||
Info<< "\nFinished decomposition in "
|
Info<< nl << "Finished decomposition in "
|
||||||
<< decompositionTime.elapsedCpuTime()
|
<< decompositionTime.elapsedCpuTime()
|
||||||
<< " s" << endl;
|
<< " s" << endl;
|
||||||
|
|
||||||
@ -269,17 +269,16 @@ inline void Foam::domainDecomposition::processInterCyclics
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::domainDecomposition::decompose()
|
void Foam::domainDecomposition::decompose()
|
||||||
{
|
{
|
||||||
// Decide which cell goes to which processor
|
// Decide which cell goes to which processor
|
||||||
cellProc_ = distributeCells();
|
cellProc_ = distributeCells();
|
||||||
|
Info<< nl;
|
||||||
|
|
||||||
// Distribute the cells according to the given processor label
|
// Distribute the cells according to the given processor label
|
||||||
|
|
||||||
// calculate the addressing information for the original mesh
|
// calculate the addressing information for the original mesh
|
||||||
Info<< "\nCalculating original mesh data" << endl;
|
Info<< "Calculating original mesh data" << nl << endl;
|
||||||
|
|
||||||
// set references to the original mesh
|
// set references to the original mesh
|
||||||
const polyBoundaryMesh& patches = completeMesh().boundaryMesh();
|
const polyBoundaryMesh& patches = completeMesh().boundaryMesh();
|
||||||
@ -290,12 +289,12 @@ void Foam::domainDecomposition::decompose()
|
|||||||
// loop through the list of processor labels for the cell and add the
|
// loop through the list of processor labels for the cell and add the
|
||||||
// cell shape to the list of cells for the appropriate processor
|
// cell shape to the list of cells for the appropriate processor
|
||||||
|
|
||||||
Info<< "\nDistributing cells to processors" << endl;
|
Info<< "Distributing cells to processors" << nl << endl;
|
||||||
|
|
||||||
// Cells per processor
|
// Cells per processor
|
||||||
procCellAddressing_ = invertOneToMany(nProcs(), cellProc_);
|
procCellAddressing_ = invertOneToMany(nProcs(), cellProc_);
|
||||||
|
|
||||||
Info<< "\nDistributing faces to processors" << endl;
|
Info<< "Distributing faces to processors" << nl << endl;
|
||||||
|
|
||||||
// Loop through all internal faces and decide which processor they belong to
|
// Loop through all internal faces and decide which processor they belong to
|
||||||
// First visit all internal faces. If cells at both sides belong to the
|
// First visit all internal faces. If cells at both sides belong to the
|
||||||
@ -606,7 +605,7 @@ void Foam::domainDecomposition::decompose()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "\nDistributing points to processors" << endl;
|
Info<< "Distributing points to processors" << nl << endl;
|
||||||
|
|
||||||
// For every processor, loop through the list of faces for the processor.
|
// For every processor, loop through the list of faces for the processor.
|
||||||
// For every face, loop through the list of points and mark the point as
|
// For every face, loop through the list of points and mark the point as
|
||||||
@ -653,7 +652,7 @@ void Foam::domainDecomposition::decompose()
|
|||||||
procPointLabels.setSize(nUsedPoints);
|
procPointLabels.setSize(nUsedPoints);
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< "\nConstructing processor meshes" << endl;
|
Info<< "Constructing processor meshes" << nl << endl;
|
||||||
|
|
||||||
// Mark point/faces/cells that are in zones.
|
// Mark point/faces/cells that are in zones.
|
||||||
// -1 : not in zone
|
// -1 : not in zone
|
||||||
@ -1150,8 +1149,7 @@ void Foam::domainDecomposition::decompose()
|
|||||||
|
|
||||||
// Report processor and update global statistics
|
// Report processor and update global statistics
|
||||||
{
|
{
|
||||||
Info<< endl
|
Info<< "Processor " << proci << nl
|
||||||
<< "Processor " << proci << nl
|
|
||||||
<< " Number of cells = " << procMesh.nCells()
|
<< " Number of cells = " << procMesh.nCells()
|
||||||
<< endl;
|
<< endl;
|
||||||
|
|
||||||
@ -1185,7 +1183,8 @@ void Foam::domainDecomposition::decompose()
|
|||||||
|
|
||||||
Info<< " Number of processor patches = " << nProcPatches << nl
|
Info<< " Number of processor patches = " << nProcPatches << nl
|
||||||
<< " Number of processor faces = " << nProcFaces << nl
|
<< " Number of processor faces = " << nProcFaces << nl
|
||||||
<< " Number of boundary faces = " << nBoundaryFaces << endl;
|
<< " Number of boundary faces = " << nBoundaryFaces << nl
|
||||||
|
<< endl;
|
||||||
|
|
||||||
totProcFaces += nProcFaces;
|
totProcFaces += nProcFaces;
|
||||||
totProcPatches += nProcPatches;
|
totProcPatches += nProcPatches;
|
||||||
@ -1209,8 +1208,7 @@ void Foam::domainDecomposition::decompose()
|
|||||||
avgProcFaces = 1;
|
avgProcFaces = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Info<< nl
|
Info<< "Number of processor faces = " << totProcFaces/2 << nl
|
||||||
<< "Number of processor faces = " << totProcFaces/2 << nl
|
|
||||||
<< "Max number of cells = " << maxProcCells
|
<< "Max number of cells = " << maxProcCells
|
||||||
<< " (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
|
<< " (" << 100.0*(maxProcCells-avgProcCells)/avgProcCells
|
||||||
<< "% above average " << avgProcCells << ")" << nl
|
<< "% above average " << avgProcCells << ")" << nl
|
||||||
@ -1219,8 +1217,7 @@ void Foam::domainDecomposition::decompose()
|
|||||||
<< "% above average " << avgProcPatches << ")" << nl
|
<< "% above average " << avgProcPatches << ")" << nl
|
||||||
<< "Max number of faces between processors = " << maxProcFaces
|
<< "Max number of faces between processors = " << maxProcFaces
|
||||||
<< " (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces
|
<< " (" << 100.0*(maxProcFaces-avgProcFaces)/avgProcFaces
|
||||||
<< "% above average " << avgProcFaces << ")" << nl
|
<< "% above average " << avgProcFaces << ")" << endl;
|
||||||
<< endl;
|
|
||||||
|
|
||||||
// Clear (and thus trigger re-generation) of finite volume face addressing
|
// Clear (and thus trigger re-generation) of finite volume face addressing
|
||||||
procFaceAddressingBf_.clear();
|
procFaceAddressingBf_.clear();
|
||||||
@ -1230,4 +1227,32 @@ void Foam::domainDecomposition::decompose()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::domainDecomposition::decomposePoints()
|
||||||
|
{
|
||||||
|
for (label proci = 0; proci < nProcs(); proci++)
|
||||||
|
{
|
||||||
|
fvMesh& procMesh = procMeshes_[proci];
|
||||||
|
|
||||||
|
const label pointsCompare =
|
||||||
|
compareInstances
|
||||||
|
(
|
||||||
|
completeMesh().pointsInstance(),
|
||||||
|
procMeshes_[proci].pointsInstance()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pointsCompare == -1)
|
||||||
|
{
|
||||||
|
procMesh.setPoints
|
||||||
|
(
|
||||||
|
pointField
|
||||||
|
(
|
||||||
|
completeMesh().points(),
|
||||||
|
procPointAddressing_[proci]
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// ************************************************************************* //
|
// ************************************************************************* //
|
||||||
|
|||||||
744
src/parallel/parallel/domainDecompositionNonConformal.C
Normal file
744
src/parallel/parallel/domainDecompositionNonConformal.C
Normal file
@ -0,0 +1,744 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / 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 "domainDecomposition.H"
|
||||||
|
#include "cyclicFvPatch.H"
|
||||||
|
#include "processorCyclicFvPatch.H"
|
||||||
|
#include "nonConformalCyclicFvPatch.H"
|
||||||
|
#include "nonConformalProcessorCyclicFvPatch.H"
|
||||||
|
#include "nonConformalErrorFvPatch.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
void checkNonConformalCoupledPatchOrdering
|
||||||
|
(
|
||||||
|
const labelPair& procs,
|
||||||
|
const fvPatch& fvp,
|
||||||
|
const fvPatch& nbrFvp,
|
||||||
|
const labelList& polyFacesPf,
|
||||||
|
const labelList& nbrPolyFacesPf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (fvp.size() != nbrFvp.size())
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Coupled patches " << fvp.name() << " and "
|
||||||
|
<< nbrFvp.name() << " are not the same size"
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fvp.size())
|
||||||
|
{
|
||||||
|
for (label i = 1; i < fvp.size(); ++ i)
|
||||||
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
polyFacesPf[i - 1] > polyFacesPf[i]
|
||||||
|
? true
|
||||||
|
: polyFacesPf[i - 1] == polyFacesPf[i]
|
||||||
|
? nbrPolyFacesPf[i - 1] >= nbrPolyFacesPf[i]
|
||||||
|
: false
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Coupled patches " << fvp.name()
|
||||||
|
<< " and " << nbrFvp.name()
|
||||||
|
<< " are not in order";
|
||||||
|
|
||||||
|
if (procs[0] == procs[1])
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< " on process #" << procs[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoInFunction
|
||||||
|
<< "Coupled patches " << fvp.name()
|
||||||
|
<< " and " << nbrFvp.name()
|
||||||
|
<< " are in order" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void checkNonConformalErrorPatchOrdering
|
||||||
|
(
|
||||||
|
const label& proci,
|
||||||
|
const fvPatch& fvp,
|
||||||
|
const labelList& polyFacesPf
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (fvp.size())
|
||||||
|
{
|
||||||
|
for (label i = 1; i < fvp.size(); ++ i)
|
||||||
|
{
|
||||||
|
if (polyFacesPf[i - 1] > polyFacesPf[i])
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Error patch " << fvp.name()
|
||||||
|
<< " is not in order";
|
||||||
|
|
||||||
|
if (proci > 0)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< " on process #" << proci;
|
||||||
|
}
|
||||||
|
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
InfoInFunction
|
||||||
|
<< "Error patch " << fvp.name()
|
||||||
|
<< " is in order" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::domainDecomposition::completeConformal() const
|
||||||
|
{
|
||||||
|
return completeMesh().conformal();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::domainDecomposition::procsConformal() const
|
||||||
|
{
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
if (!procMeshes_[proci].conformal())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::List<Foam::List<Foam::DynamicList<Foam::label>>>
|
||||||
|
Foam::domainDecomposition::nonConformalProcFaceAddressingBf() const
|
||||||
|
{
|
||||||
|
validateComplete();
|
||||||
|
validateProcs();
|
||||||
|
|
||||||
|
// Map from reference patch and processors to the interface patch
|
||||||
|
typedef HashTable<label, labelPair, Hash<labelPair>> labelPairTable;
|
||||||
|
List<labelPairTable> refPatchProcPatchTable
|
||||||
|
(
|
||||||
|
completeMesh().boundary().size()
|
||||||
|
);
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
const fvMesh& procMesh = procMeshes_[proci];
|
||||||
|
|
||||||
|
forAll(procMesh.boundary(), procPatchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp = procMesh.boundary()[procPatchi];
|
||||||
|
|
||||||
|
if (isA<cyclicFvPatch>(fvp))
|
||||||
|
{
|
||||||
|
refPatchProcPatchTable[procPatchi].insert
|
||||||
|
(
|
||||||
|
labelPair(proci, proci),
|
||||||
|
procPatchi
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else if (isA<processorCyclicFvPatch>(fvp))
|
||||||
|
{
|
||||||
|
const processorCyclicFvPatch& pcFvp =
|
||||||
|
refCast<const processorCyclicFvPatch>(fvp);
|
||||||
|
|
||||||
|
refPatchProcPatchTable[pcFvp.referPatchID()].insert
|
||||||
|
(
|
||||||
|
labelPair(proci, pcFvp.neighbProcNo()),
|
||||||
|
procPatchi
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build non-conformal finite volume face addressing for each processor
|
||||||
|
List<List<DynamicList<label>>> result(nProcs());
|
||||||
|
forAll(result, proci)
|
||||||
|
{
|
||||||
|
result[proci].resize
|
||||||
|
(
|
||||||
|
procMeshes_[proci].boundary().size()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (completeConformal() && procsConformal())
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
else if (!completeConformal())
|
||||||
|
{
|
||||||
|
// Decompose non-conformal addressing
|
||||||
|
|
||||||
|
const surfaceLabelField::Boundary& polyFacesBf =
|
||||||
|
completeMesh().polyFacesBf();
|
||||||
|
|
||||||
|
// Cyclic patches
|
||||||
|
forAll(completeMesh().boundary(), nccPatchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp = completeMesh().boundary()[nccPatchi];
|
||||||
|
|
||||||
|
if (!isA<nonConformalCyclicFvPatch>(fvp)) continue;
|
||||||
|
|
||||||
|
const nonConformalCyclicFvPatch& nccFvp =
|
||||||
|
refCast<const nonConformalCyclicFvPatch>(fvp);
|
||||||
|
|
||||||
|
if (!nccFvp.owner()) continue;
|
||||||
|
|
||||||
|
const label nccNbrPatchi = nccFvp.nbrPatchID();
|
||||||
|
|
||||||
|
forAll(polyFacesBf[nccPatchi], nccPatchFacei)
|
||||||
|
{
|
||||||
|
const label facei = polyFacesBf[nccPatchi][nccPatchFacei];
|
||||||
|
const label celli = completeMesh().faceOwner()[facei];
|
||||||
|
const label proci = cellProc_[celli];
|
||||||
|
|
||||||
|
const label nbrFacei =
|
||||||
|
polyFacesBf[nccNbrPatchi][nccPatchFacei];
|
||||||
|
const label nbrCelli =
|
||||||
|
completeMesh().faceOwner()[nbrFacei];
|
||||||
|
const label nbrProci = cellProc_[nbrCelli];
|
||||||
|
|
||||||
|
const label procNccPatchi =
|
||||||
|
refPatchProcPatchTable
|
||||||
|
[nccPatchi][labelPair(proci, nbrProci)];
|
||||||
|
const label nbrProcNccPatchi =
|
||||||
|
refPatchProcPatchTable
|
||||||
|
[nccNbrPatchi][labelPair(nbrProci, proci)];
|
||||||
|
|
||||||
|
result[proci][procNccPatchi].append(nccPatchFacei + 1);
|
||||||
|
result[nbrProci][nbrProcNccPatchi].append(nccPatchFacei + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error patches
|
||||||
|
forAll(completeMesh().boundary(), ncePatchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp = completeMesh().boundary()[ncePatchi];
|
||||||
|
|
||||||
|
if (!isA<nonConformalErrorFvPatch>(fvp)) continue;
|
||||||
|
|
||||||
|
forAll(polyFacesBf[ncePatchi], ncePatchFacei)
|
||||||
|
{
|
||||||
|
const label facei = polyFacesBf[ncePatchi][ncePatchFacei];
|
||||||
|
const label celli = completeMesh().faceOwner()[facei];
|
||||||
|
const label proci = cellProc_[celli];
|
||||||
|
|
||||||
|
result[proci][ncePatchi].append(ncePatchFacei + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else // if (!procsConformal())
|
||||||
|
{
|
||||||
|
// Reconstruct non-conformal addressing
|
||||||
|
|
||||||
|
// Cyclic patches
|
||||||
|
forAll(completeMesh().boundary(), nccPatchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp = completeMesh().boundary()[nccPatchi];
|
||||||
|
|
||||||
|
if (!isA<nonConformalCyclicFvPatch>(fvp)) continue;
|
||||||
|
|
||||||
|
const nonConformalCyclicFvPatch& nccFvp =
|
||||||
|
refCast<const nonConformalCyclicFvPatch>(fvp);
|
||||||
|
|
||||||
|
if (!nccFvp.owner()) continue;
|
||||||
|
|
||||||
|
const label nccNbrPatchi = nccFvp.nbrPatchID();
|
||||||
|
|
||||||
|
label nccPatchFacei = 0;
|
||||||
|
labelPairTable procNccPatchFaceis;
|
||||||
|
forAllConstIter
|
||||||
|
(
|
||||||
|
labelPairTable,
|
||||||
|
refPatchProcPatchTable[nccPatchi],
|
||||||
|
iter
|
||||||
|
)
|
||||||
|
{
|
||||||
|
procNccPatchFaceis.insert(iter.key(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
labelPair procNbrProc(labelMax, labelMax);
|
||||||
|
labelPair faceNbrFace(labelMax, labelMax);
|
||||||
|
|
||||||
|
forAllConstIter(labelPairTable, procNccPatchFaceis, iter)
|
||||||
|
{
|
||||||
|
const label proci = iter.key().first();
|
||||||
|
const label nbrProci = iter.key().second();
|
||||||
|
|
||||||
|
const labelPair procNbrProcStar(proci, nbrProci);
|
||||||
|
const labelPair nbrProcProcStar(nbrProci, proci);
|
||||||
|
|
||||||
|
const label procNccPatchi =
|
||||||
|
refPatchProcPatchTable
|
||||||
|
[nccPatchi][procNbrProcStar];
|
||||||
|
const label nbrProcNccPatchi =
|
||||||
|
refPatchProcPatchTable
|
||||||
|
[nccNbrPatchi][nbrProcProcStar];
|
||||||
|
|
||||||
|
const label size =
|
||||||
|
procMeshes_[proci]
|
||||||
|
.polyFacesBf()[procNccPatchi]
|
||||||
|
.size();
|
||||||
|
|
||||||
|
if (iter() >= size) continue;
|
||||||
|
|
||||||
|
const label procFacei =
|
||||||
|
procMeshes_[proci].polyFacesBf()
|
||||||
|
[procNccPatchi][iter()];
|
||||||
|
const label nbrProcFacei =
|
||||||
|
procMeshes_[nbrProci].polyFacesBf()
|
||||||
|
[nbrProcNccPatchi][iter()];
|
||||||
|
|
||||||
|
const labelPair faceNbrFaceStar
|
||||||
|
(
|
||||||
|
procFaceAddressing_[proci][procFacei] - 1,
|
||||||
|
procFaceAddressing_[nbrProci][nbrProcFacei] - 1
|
||||||
|
);
|
||||||
|
|
||||||
|
if (faceNbrFace > faceNbrFaceStar)
|
||||||
|
{
|
||||||
|
procNbrProc = procNbrProcStar;
|
||||||
|
faceNbrFace = faceNbrFaceStar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (faceNbrFace == labelPair(labelMax, labelMax))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const label proci = procNbrProc.first();
|
||||||
|
const label nbrProci = procNbrProc.second();
|
||||||
|
|
||||||
|
const labelPair nbrProcProc(nbrProci, proci);
|
||||||
|
|
||||||
|
const label procNccPatchi =
|
||||||
|
refPatchProcPatchTable[nccPatchi][procNbrProc];
|
||||||
|
const label nbrProcNccPatchi =
|
||||||
|
refPatchProcPatchTable[nccNbrPatchi][nbrProcProc];
|
||||||
|
|
||||||
|
result[proci][procNccPatchi]
|
||||||
|
.append(nccPatchFacei + 1);
|
||||||
|
result[nbrProci][nbrProcNccPatchi]
|
||||||
|
.append(nccPatchFacei + 1);
|
||||||
|
|
||||||
|
nccPatchFacei ++;
|
||||||
|
procNccPatchFaceis[procNbrProc] ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error patches
|
||||||
|
forAll(completeMesh().boundary(), ncePatchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp = completeMesh().boundary()[ncePatchi];
|
||||||
|
|
||||||
|
if (!isA<nonConformalErrorFvPatch>(fvp)) continue;
|
||||||
|
|
||||||
|
label ncePatchFacei = 0;
|
||||||
|
labelList procNcePatchFaceis(nProcs(), 0);
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
label facei = labelMax, proci = labelMax;
|
||||||
|
|
||||||
|
forAll(procNcePatchFaceis, procStari)
|
||||||
|
{
|
||||||
|
const label size =
|
||||||
|
procMeshes_[procStari]
|
||||||
|
.polyFacesBf()[ncePatchi]
|
||||||
|
.size();
|
||||||
|
|
||||||
|
if (procNcePatchFaceis[procStari] >= size) continue;
|
||||||
|
|
||||||
|
const label procFacei =
|
||||||
|
procMeshes_[procStari].polyFacesBf()
|
||||||
|
[ncePatchi][procNcePatchFaceis[procStari]];
|
||||||
|
|
||||||
|
const label faceStari =
|
||||||
|
procFaceAddressing_[procStari][procFacei] - 1;
|
||||||
|
|
||||||
|
if (facei > faceStari)
|
||||||
|
{
|
||||||
|
facei = faceStari;
|
||||||
|
proci = procStari;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (facei == labelMax)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result[proci][ncePatchi].append(ncePatchFacei + 1);
|
||||||
|
|
||||||
|
ncePatchFacei ++;
|
||||||
|
procNcePatchFaceis[proci] ++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::domainDecomposition::unconformComplete()
|
||||||
|
{
|
||||||
|
surfaceLabelField::Boundary polyFacesBf
|
||||||
|
(
|
||||||
|
surfaceLabelField::null(),
|
||||||
|
completeMesh().polyFacesBf()
|
||||||
|
);
|
||||||
|
surfaceVectorField Sf(completeMesh().Sf().cloneUnSliced());
|
||||||
|
surfaceVectorField Cf(completeMesh().Cf().cloneUnSliced());
|
||||||
|
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
const fvMesh& procMesh = procMeshes_[proci];
|
||||||
|
|
||||||
|
const surfaceLabelField::Boundary& faceAddressingBf =
|
||||||
|
procFaceAddressingBf()[proci];
|
||||||
|
|
||||||
|
forAll(procMesh.boundary(), procNccPatchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp = procMesh.boundary()[procNccPatchi];
|
||||||
|
|
||||||
|
if (isA<nonConformalFvPatch>(fvp))
|
||||||
|
{
|
||||||
|
const label completeNccPatchi =
|
||||||
|
isA<processorCyclicFvPatch>(fvp)
|
||||||
|
? refCast<const processorCyclicFvPatch>(fvp)
|
||||||
|
.referPatchID()
|
||||||
|
: procNccPatchi;
|
||||||
|
|
||||||
|
const label size =
|
||||||
|
max
|
||||||
|
(
|
||||||
|
max(mag(faceAddressingBf[procNccPatchi])),
|
||||||
|
polyFacesBf[completeNccPatchi].size()
|
||||||
|
);
|
||||||
|
|
||||||
|
polyFacesBf[completeNccPatchi].resize(size, -1);
|
||||||
|
polyFacesBf[completeNccPatchi].labelField::rmap
|
||||||
|
(
|
||||||
|
mag
|
||||||
|
(
|
||||||
|
labelField
|
||||||
|
(
|
||||||
|
procFaceAddressing_[proci],
|
||||||
|
procMesh.polyFacesBf()[procNccPatchi]
|
||||||
|
)
|
||||||
|
) - 1,
|
||||||
|
mag(faceAddressingBf[procNccPatchi]) - 1
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set dummy data for the face geometry. This should not be
|
||||||
|
// used during decomposition.
|
||||||
|
Sf.boundaryFieldRef()[completeNccPatchi].resize(size, Zero);
|
||||||
|
Cf.boundaryFieldRef()[completeNccPatchi].resize(size, Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
completeMesh_->unconform
|
||||||
|
(
|
||||||
|
polyFacesBf,
|
||||||
|
Sf,
|
||||||
|
Cf,
|
||||||
|
NullObjectRef<surfaceScalarField>(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
// Check ordering
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
forAll(completeMesh().boundary(), patchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp = completeMesh().boundary()[patchi];
|
||||||
|
|
||||||
|
// Coupled patches
|
||||||
|
if
|
||||||
|
(
|
||||||
|
isA<nonConformalCyclicFvPatch>(fvp)
|
||||||
|
&& refCast<const nonConformalCoupledFvPatch>(fvp).owner()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label nccPatchi = patchi;
|
||||||
|
|
||||||
|
const label nbrNccPatchi =
|
||||||
|
refCast<const nonConformalCyclicFvPatch>(fvp)
|
||||||
|
.nbrPatchID();
|
||||||
|
|
||||||
|
checkNonConformalCoupledPatchOrdering
|
||||||
|
(
|
||||||
|
{-labelMax, labelMax},
|
||||||
|
completeMesh().boundary()[nccPatchi],
|
||||||
|
completeMesh().boundary()[nbrNccPatchi],
|
||||||
|
completeMesh().polyFacesBf()[nccPatchi],
|
||||||
|
completeMesh().polyFacesBf()[nbrNccPatchi]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error patches
|
||||||
|
if (isA<nonConformalErrorFvPatch>(fvp))
|
||||||
|
{
|
||||||
|
const label ncePatchi = patchi;
|
||||||
|
|
||||||
|
checkNonConformalErrorPatchOrdering
|
||||||
|
(
|
||||||
|
-labelMax,
|
||||||
|
completeMesh().boundary()[ncePatchi],
|
||||||
|
completeMesh().polyFacesBf()[ncePatchi]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::domainDecomposition::unconformProcs()
|
||||||
|
{
|
||||||
|
// Construct the reverse of proc-face-face addressing. -1 indicates a face
|
||||||
|
// that is on a (conformal) processor boundary and hence has multiple
|
||||||
|
// associated proc-face indices.
|
||||||
|
labelList faceProcFace(completeMesh().nFaces(), -labelMax);
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
forAll(procFaceAddressing()[proci], procFacei)
|
||||||
|
{
|
||||||
|
const label facei =
|
||||||
|
mag(procFaceAddressing()[proci][procFacei]) - 1;
|
||||||
|
|
||||||
|
faceProcFace[facei] =
|
||||||
|
faceProcFace[facei] == -labelMax ? procFacei : -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
fvMesh& procMesh = procMeshes_[proci];
|
||||||
|
|
||||||
|
const surfaceLabelField::Boundary& faceAddressingBf =
|
||||||
|
procFaceAddressingBf()[proci];
|
||||||
|
|
||||||
|
surfaceLabelField::Boundary polyFacesBf
|
||||||
|
(
|
||||||
|
surfaceLabelField::null(),
|
||||||
|
procMesh.polyFacesBf()
|
||||||
|
);
|
||||||
|
surfaceVectorField Sf(procMesh.Sf().cloneUnSliced());
|
||||||
|
surfaceVectorField Cf(procMesh.Cf().cloneUnSliced());
|
||||||
|
|
||||||
|
forAll(procMesh.boundary(), procNccPatchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp = procMesh.boundary()[procNccPatchi];
|
||||||
|
|
||||||
|
if (isA<nonConformalFvPatch>(fvp))
|
||||||
|
{
|
||||||
|
const label completeNccPatchi =
|
||||||
|
isA<processorCyclicFvPatch>(fvp)
|
||||||
|
? refCast<const processorCyclicFvPatch>(fvp)
|
||||||
|
.referPatchID()
|
||||||
|
: procNccPatchi;
|
||||||
|
|
||||||
|
polyFacesBf[procNccPatchi] =
|
||||||
|
labelField
|
||||||
|
(
|
||||||
|
faceProcFace,
|
||||||
|
labelField
|
||||||
|
(
|
||||||
|
completeMesh().polyFacesBf()[completeNccPatchi],
|
||||||
|
mag(faceAddressingBf[procNccPatchi]) - 1
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
const label size = polyFacesBf[procNccPatchi].size();
|
||||||
|
|
||||||
|
// Set dummy data for the face geometry. This should not be
|
||||||
|
// used during decomposition.
|
||||||
|
Sf.boundaryFieldRef()[procNccPatchi].resize(size, Zero);
|
||||||
|
Cf.boundaryFieldRef()[procNccPatchi].resize(size, Zero);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
procMesh.unconform
|
||||||
|
(
|
||||||
|
polyFacesBf,
|
||||||
|
Sf,
|
||||||
|
Cf,
|
||||||
|
NullObjectRef<surfaceScalarField>(),
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debug)
|
||||||
|
{
|
||||||
|
forAll(procMeshes_, proci)
|
||||||
|
{
|
||||||
|
forAll(procMeshes_[proci].boundary(), patchi)
|
||||||
|
{
|
||||||
|
const fvPatch& fvp =
|
||||||
|
procMeshes_[proci].boundary()[patchi];
|
||||||
|
|
||||||
|
// Coupled patches
|
||||||
|
if
|
||||||
|
(
|
||||||
|
isA<nonConformalCoupledFvPatch>(fvp)
|
||||||
|
&& refCast<const nonConformalCoupledFvPatch>(fvp).owner()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const label nccPatchi = patchi;
|
||||||
|
|
||||||
|
label nbrProci = -1, nbrNccPatchi = -1;
|
||||||
|
if (isA<cyclicFvPatch>(fvp))
|
||||||
|
{
|
||||||
|
nbrProci = proci;
|
||||||
|
nbrNccPatchi =
|
||||||
|
refCast<const cyclicFvPatch>(fvp).nbrPatchID();
|
||||||
|
}
|
||||||
|
else if (isA<processorCyclicFvPatch>(fvp))
|
||||||
|
{
|
||||||
|
typedef processorCyclicFvPatch PcFvp;
|
||||||
|
|
||||||
|
const PcFvp& pcFvp = refCast<const PcFvp>(fvp);
|
||||||
|
|
||||||
|
nbrProci = pcFvp.neighbProcNo();
|
||||||
|
|
||||||
|
const fvBoundaryMesh& nbrFvPatches =
|
||||||
|
procMeshes_[nbrProci].boundary();
|
||||||
|
|
||||||
|
forAll(nbrFvPatches, nbrNccPatchj)
|
||||||
|
{
|
||||||
|
const fvPatch& nbrFvp =
|
||||||
|
nbrFvPatches[nbrNccPatchj];
|
||||||
|
|
||||||
|
if (isA<PcFvp>(nbrFvp))
|
||||||
|
{
|
||||||
|
const PcFvp& nbrPcFvp =
|
||||||
|
refCast<const PcFvp>(nbrFvp);
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
nbrPcFvp.neighbProcNo()
|
||||||
|
== proci
|
||||||
|
&& nbrPcFvp.referPatchID()
|
||||||
|
== pcFvp.referPatch().nbrPatchID()
|
||||||
|
)
|
||||||
|
{
|
||||||
|
nbrNccPatchi = nbrNccPatchj;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nbrNccPatchi == -1)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Opposite processor patch not found for "
|
||||||
|
<< "patch " << fvp.name() << " on proc #"
|
||||||
|
<< proci << exit(FatalError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Non-conformal-coupled type not recognised "
|
||||||
|
<< "for patch " << fvp.name() << " on proc #"
|
||||||
|
<< proci << exit(FatalError);
|
||||||
|
}
|
||||||
|
|
||||||
|
checkNonConformalCoupledPatchOrdering
|
||||||
|
(
|
||||||
|
{proci, nbrProci},
|
||||||
|
procMeshes_[proci].boundary()[nccPatchi],
|
||||||
|
procMeshes_[nbrProci].boundary()[nbrNccPatchi],
|
||||||
|
procMeshes_[proci].polyFacesBf()[nccPatchi],
|
||||||
|
procMeshes_[nbrProci].polyFacesBf()[nbrNccPatchi]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Error patches
|
||||||
|
if (isA<nonConformalErrorFvPatch>(fvp))
|
||||||
|
{
|
||||||
|
const label ncePatchi = patchi;
|
||||||
|
|
||||||
|
checkNonConformalErrorPatchOrdering
|
||||||
|
(
|
||||||
|
proci,
|
||||||
|
procMeshes_[proci].boundary()[ncePatchi],
|
||||||
|
procMeshes_[proci].polyFacesBf()[ncePatchi]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::domainDecomposition::unconform()
|
||||||
|
{
|
||||||
|
if (completeConformal() && procsConformal())
|
||||||
|
{
|
||||||
|
// Nothing to do
|
||||||
|
}
|
||||||
|
else if (!completeConformal() && procsConformal())
|
||||||
|
{
|
||||||
|
unconformProcs();
|
||||||
|
}
|
||||||
|
else if (completeConformal() && !procsConformal())
|
||||||
|
{
|
||||||
|
unconformComplete();
|
||||||
|
}
|
||||||
|
else // if (!completeConformal() && !procsConformal())
|
||||||
|
{
|
||||||
|
// Assume everything is consistent and do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -28,12 +28,10 @@ License
|
|||||||
#include "processorPolyPatch.H"
|
#include "processorPolyPatch.H"
|
||||||
#include "processorCyclicPolyPatch.H"
|
#include "processorCyclicPolyPatch.H"
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
Foam::autoPtr<Foam::faceCoupleInfo>
|
||||||
{
|
Foam::domainDecomposition::determineCoupledFaces
|
||||||
|
|
||||||
autoPtr<faceCoupleInfo> determineCoupledFaces
|
|
||||||
(
|
(
|
||||||
const label masterMeshProcStart,
|
const label masterMeshProcStart,
|
||||||
const label masterMeshProcEnd,
|
const label masterMeshProcEnd,
|
||||||
@ -136,9 +134,6 @@ autoPtr<faceCoupleInfo> determineCoupledFaces
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
|
||||||
|
|
||||||
void Foam::domainDecomposition::reconstruct()
|
void Foam::domainDecomposition::reconstruct()
|
||||||
{
|
{
|
||||||
@ -225,7 +220,7 @@ void Foam::domainDecomposition::reconstruct()
|
|||||||
Info<< indent << "Merging mesh " << proci
|
Info<< indent << "Merging mesh " << proci
|
||||||
<< " with " << procj << endl;
|
<< " with " << procj << endl;
|
||||||
|
|
||||||
// Find shared points/faces
|
// Find shared points and faces
|
||||||
autoPtr<faceCoupleInfo> couples = determineCoupledFaces
|
autoPtr<faceCoupleInfo> couples = determineCoupledFaces
|
||||||
(
|
(
|
||||||
proci,
|
proci,
|
||||||
@ -521,7 +516,32 @@ void Foam::domainDecomposition::reconstruct()
|
|||||||
completeMesh_->setInstance(procMeshes()[0].facesInstance());
|
completeMesh_->setInstance(procMeshes()[0].facesInstance());
|
||||||
completeMesh_->setPointsInstance(procMeshes()[0].pointsInstance());
|
completeMesh_->setPointsInstance(procMeshes()[0].pointsInstance());
|
||||||
|
|
||||||
Info<< decrIndent << endl;
|
Info<< decrIndent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::domainDecomposition::reconstructPoints()
|
||||||
|
{
|
||||||
|
const label pointsCompare =
|
||||||
|
compareInstances
|
||||||
|
(
|
||||||
|
completeMesh().pointsInstance(),
|
||||||
|
procMeshes_[0].pointsInstance()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (pointsCompare == 1)
|
||||||
|
{
|
||||||
|
pointField completePoints(completeMesh().nPoints());
|
||||||
|
|
||||||
|
for (label proci = 0; proci < nProcs(); proci++)
|
||||||
|
{
|
||||||
|
const fvMesh& procMesh = procMeshes_[proci];
|
||||||
|
|
||||||
|
completePoints.rmap(procMesh.points(), procPointAddressing_[proci]);
|
||||||
|
}
|
||||||
|
|
||||||
|
completeMesh_->setPoints(completePoints);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
180
src/parallel/parallel/multiDomainDecomposition.C
Normal file
180
src/parallel/parallel/multiDomainDecomposition.C
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 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 "multiDomainDecomposition.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(multiDomainDecomposition, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::multiDomainDecomposition::multiDomainDecomposition
|
||||||
|
(
|
||||||
|
const processorRunTimes& runTimes,
|
||||||
|
const wordList& regionNames
|
||||||
|
)
|
||||||
|
:
|
||||||
|
multiRegionPrefixer(false, regionNames),
|
||||||
|
runTimes_(runTimes),
|
||||||
|
regionNames_(regionNames),
|
||||||
|
regionMeshes_(regionNames.size())
|
||||||
|
{
|
||||||
|
forAll(regionMeshes_, regioni)
|
||||||
|
{
|
||||||
|
regionMeshes_.set
|
||||||
|
(
|
||||||
|
regioni,
|
||||||
|
new domainDecomposition(runTimes, regionNames[regioni])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::multiDomainDecomposition::~multiDomainDecomposition()
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::multiDomainDecomposition::readDecompose(const bool doSets)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
forAll(regionMeshes_, regioni)
|
||||||
|
{
|
||||||
|
if (meshes(regioni)().readDecompose(doSets))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
if (regioni != regionMeshes_.size() - 1)
|
||||||
|
{
|
||||||
|
Info<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::multiDomainDecomposition::readReconstruct(const bool doSets)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
forAll(regionMeshes_, regioni)
|
||||||
|
{
|
||||||
|
if (meshes(regioni)().readReconstruct(doSets))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
|
||||||
|
if (regioni != regionMeshes_.size() - 1)
|
||||||
|
{
|
||||||
|
Info<< endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fvMesh::readUpdateState
|
||||||
|
Foam::multiDomainDecomposition::readUpdateDecompose()
|
||||||
|
{
|
||||||
|
fvMesh::readUpdateState result = fvMesh::UNCHANGED;
|
||||||
|
|
||||||
|
forAll(regionMeshes_, regioni)
|
||||||
|
{
|
||||||
|
const fvMesh::readUpdateState regionResult =
|
||||||
|
meshes(regioni)().readUpdateDecompose();
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
regioni != regionMeshes_.size() - 1
|
||||||
|
&& regionResult >= fvMesh::TOPO_CHANGE
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result > regionResult ? result : regionResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::fvMesh::readUpdateState
|
||||||
|
Foam::multiDomainDecomposition::readUpdateReconstruct()
|
||||||
|
{
|
||||||
|
fvMesh::readUpdateState result = fvMesh::UNCHANGED;
|
||||||
|
|
||||||
|
forAll(regionMeshes_, regioni)
|
||||||
|
{
|
||||||
|
const fvMesh::readUpdateState regionResult =
|
||||||
|
meshes(regioni)().readUpdateReconstruct();
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
regioni != regionMeshes_.size() - 1
|
||||||
|
&& regionResult >= fvMesh::TOPO_CHANGE
|
||||||
|
)
|
||||||
|
{
|
||||||
|
Info<< endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = result > regionResult ? result : regionResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::multiDomainDecomposition::writeComplete(const bool doSets) const
|
||||||
|
{
|
||||||
|
forAll(regionMeshes_, regioni)
|
||||||
|
{
|
||||||
|
meshes(regioni)().writeComplete(doSets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Foam::multiDomainDecomposition::writeProcs(const bool doSets) const
|
||||||
|
{
|
||||||
|
forAll(regionMeshes_, regioni)
|
||||||
|
{
|
||||||
|
meshes(regioni)().writeProcs(doSets);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
156
src/parallel/parallel/multiDomainDecomposition.H
Normal file
156
src/parallel/parallel/multiDomainDecomposition.H
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::multiDomainDecomposition
|
||||||
|
|
||||||
|
Description
|
||||||
|
...
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
multiDomainDecomposition.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef multiDomainDecomposition_H
|
||||||
|
#define multiDomainDecomposition_H
|
||||||
|
|
||||||
|
#include "domainDecomposition.H"
|
||||||
|
#include "multiRegionPrefixer.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class multiDomainDecomposition Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class multiDomainDecomposition
|
||||||
|
:
|
||||||
|
private multiRegionPrefixer
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Run times
|
||||||
|
const processorRunTimes& runTimes_;
|
||||||
|
|
||||||
|
//- Region names
|
||||||
|
const wordList& regionNames_;
|
||||||
|
|
||||||
|
//- The region complete and processor meshes
|
||||||
|
PtrList<domainDecomposition> regionMeshes_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("multiDomainDecomposition");
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from processor run times and region names
|
||||||
|
multiDomainDecomposition
|
||||||
|
(
|
||||||
|
const processorRunTimes& procRunTimes,
|
||||||
|
const wordList& regionNames
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~multiDomainDecomposition();
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Access the meshes for a region
|
||||||
|
inline RegionConstRef<domainDecomposition> meshes
|
||||||
|
(
|
||||||
|
const label regioni
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
return
|
||||||
|
RegionConstRef<domainDecomposition>
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
regioni,
|
||||||
|
regionMeshes_[regioni]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Access the meshes for a region
|
||||||
|
inline RegionRef<domainDecomposition> meshes
|
||||||
|
(
|
||||||
|
const label regioni
|
||||||
|
)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
RegionRef<domainDecomposition>
|
||||||
|
(
|
||||||
|
*this,
|
||||||
|
regioni,
|
||||||
|
regionMeshes_[regioni]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Return the number of processors in the decomposition
|
||||||
|
inline label nProcs() const
|
||||||
|
{
|
||||||
|
return runTimes_.nProcs();
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Read in the complete mesh. Read the processor meshes if they are
|
||||||
|
// available and up to date relative to the complete mesh, or
|
||||||
|
// decompose if not. Return whether or not decomposition happened.
|
||||||
|
bool readDecompose(const bool doSets);
|
||||||
|
|
||||||
|
//- Read in the processor meshes. Read the complete mesh if it is
|
||||||
|
// available and up to date relative to the processor meshes, or
|
||||||
|
// reconstruct if not. Return whether or not reconstruction happened.
|
||||||
|
bool readReconstruct(const bool doSets);
|
||||||
|
|
||||||
|
//- Read-update for decomposition
|
||||||
|
fvMesh::readUpdateState readUpdateDecompose();
|
||||||
|
|
||||||
|
//- Read-update for reconstruction
|
||||||
|
fvMesh::readUpdateState readUpdateReconstruct();
|
||||||
|
|
||||||
|
//- Write the decomposed meshes and associated data
|
||||||
|
void writeComplete(const bool doSets) const;
|
||||||
|
|
||||||
|
//- Write the decomposed meshes and associated data
|
||||||
|
void writeProcs(const bool doSets) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
123
src/parallel/parallel/multiRegionPrefixer.C
Normal file
123
src/parallel/parallel/multiRegionPrefixer.C
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 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 "multiRegionPrefixer.H"
|
||||||
|
#include "IOstreams.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::multiRegionPrefixer::prefixes() const
|
||||||
|
{
|
||||||
|
return prefixSingleRegion_ || regionNames_.size() > 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::string::size_type Foam::multiRegionPrefixer::prefixWidth() const
|
||||||
|
{
|
||||||
|
string::size_type n = 0;
|
||||||
|
|
||||||
|
if (prefixes())
|
||||||
|
{
|
||||||
|
forAll(regionNames_, regionj)
|
||||||
|
{
|
||||||
|
n = max(n, regionNames_[regionj].size() + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::multiRegionPrefixer::regionPrefixer::regionPrefixer
|
||||||
|
(
|
||||||
|
const multiRegionPrefixer& mrp,
|
||||||
|
const label regioni
|
||||||
|
)
|
||||||
|
:
|
||||||
|
mrp_(mrp),
|
||||||
|
regioni_(regioni)
|
||||||
|
{
|
||||||
|
if (mrp_.prefixes() && regioni_ != -1)
|
||||||
|
{
|
||||||
|
const string::size_type dn =
|
||||||
|
mrp_.prefixWidth()
|
||||||
|
- mrp_.regionNames_[regioni].size();
|
||||||
|
|
||||||
|
Sout.prefix() =
|
||||||
|
mrp_.regionNames_[regioni] + string(dn, ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::multiRegionPrefixer::regionPrefixer::regionPrefixer
|
||||||
|
(
|
||||||
|
regionPrefixer&& rp
|
||||||
|
)
|
||||||
|
:
|
||||||
|
regionPrefixer(rp.mrp_, rp.regioni_)
|
||||||
|
{
|
||||||
|
rp.regioni_ = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::multiRegionPrefixer::multiRegionPrefixer
|
||||||
|
(
|
||||||
|
const bool prefixSingleRegion,
|
||||||
|
const wordList& regionNames
|
||||||
|
)
|
||||||
|
:
|
||||||
|
prefixSingleRegion_(prefixSingleRegion),
|
||||||
|
regionNames_(regionNames)
|
||||||
|
{
|
||||||
|
if (prefixes())
|
||||||
|
{
|
||||||
|
Sout.prefix() = string(prefixWidth(), ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::multiRegionPrefixer::regionPrefixer::~regionPrefixer()
|
||||||
|
{
|
||||||
|
if (mrp_.prefixes() && regioni_ != -1)
|
||||||
|
{
|
||||||
|
Sout.prefix() = string(mrp_.prefixWidth(), ' ');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::multiRegionPrefixer::~multiRegionPrefixer()
|
||||||
|
{
|
||||||
|
if (prefixes())
|
||||||
|
{
|
||||||
|
Sout.prefix() = string::null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
241
src/parallel/parallel/multiRegionPrefixer.H
Normal file
241
src/parallel/parallel/multiRegionPrefixer.H
Normal file
@ -0,0 +1,241 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||||
|
\\ / O peration | Website: https://openfoam.org
|
||||||
|
\\ / A nd | Copyright (C) 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/>.
|
||||||
|
|
||||||
|
Class
|
||||||
|
Foam::multiRegionPrefixer
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
multiRegionPrefixer.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef multiRegionPrefixer_H
|
||||||
|
#define multiRegionPrefixer_H
|
||||||
|
|
||||||
|
#include "wordList.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class multiRegionPrefixer Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class multiRegionPrefixer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Should we prefix a single region?
|
||||||
|
const bool prefixSingleRegion_;
|
||||||
|
|
||||||
|
//- Region names
|
||||||
|
const wordList& regionNames_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Member Functions
|
||||||
|
|
||||||
|
//- Are we prefixing?
|
||||||
|
bool prefixes() const;
|
||||||
|
|
||||||
|
//- Width of the write prefix
|
||||||
|
string::size_type prefixWidth() const;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Public classes
|
||||||
|
|
||||||
|
//- Prefixer for a single region
|
||||||
|
class regionPrefixer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private data
|
||||||
|
|
||||||
|
//- The multi-region prefixing engine
|
||||||
|
const multiRegionPrefixer& mrp_;
|
||||||
|
|
||||||
|
//- The region index
|
||||||
|
label regioni_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
regionPrefixer
|
||||||
|
(
|
||||||
|
const multiRegionPrefixer& mrp,
|
||||||
|
const label regioni
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Disallow copy construct
|
||||||
|
regionPrefixer(const regionPrefixer& rp) = delete;
|
||||||
|
|
||||||
|
//- Move construct
|
||||||
|
regionPrefixer(regionPrefixer&& rp);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~regionPrefixer();
|
||||||
|
|
||||||
|
|
||||||
|
// Member operators
|
||||||
|
|
||||||
|
//- Disallow copy assign
|
||||||
|
regionPrefixer& operator=(const regionPrefixer&) = delete;
|
||||||
|
|
||||||
|
//- Disallow move assign
|
||||||
|
regionPrefixer& operator=(regionPrefixer&&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct from components
|
||||||
|
multiRegionPrefixer
|
||||||
|
(
|
||||||
|
const bool prefixSingleRegion,
|
||||||
|
const wordList& regionNames
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
~multiRegionPrefixer();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class RegionConstRef Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class Region>
|
||||||
|
class RegionConstRef
|
||||||
|
:
|
||||||
|
private multiRegionPrefixer::regionPrefixer
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Reference to the region object
|
||||||
|
const Region& r_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct form components
|
||||||
|
inline RegionConstRef
|
||||||
|
(
|
||||||
|
const multiRegionPrefixer& mrp,
|
||||||
|
const label regioni,
|
||||||
|
const Region& r
|
||||||
|
)
|
||||||
|
:
|
||||||
|
multiRegionPrefixer::regionPrefixer(mrp, regioni),
|
||||||
|
r_(r)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Member operators
|
||||||
|
|
||||||
|
//- Cast to reference
|
||||||
|
inline operator const Region&() const
|
||||||
|
{
|
||||||
|
return r_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Obtain the reference
|
||||||
|
inline const Region& operator()() const
|
||||||
|
{
|
||||||
|
return r_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class RegionRef Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
template<class Region>
|
||||||
|
class RegionRef
|
||||||
|
:
|
||||||
|
public RegionConstRef<Region>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- Reference to the region object
|
||||||
|
Region& r_;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// Constructors
|
||||||
|
|
||||||
|
//- Construct form components
|
||||||
|
inline RegionRef
|
||||||
|
(
|
||||||
|
const multiRegionPrefixer& mrp,
|
||||||
|
const label regioni,
|
||||||
|
Region& r
|
||||||
|
)
|
||||||
|
:
|
||||||
|
RegionConstRef<Region>(mrp, regioni, r),
|
||||||
|
r_(r)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// Member operators
|
||||||
|
|
||||||
|
//- Cast to reference
|
||||||
|
inline operator Region&() const
|
||||||
|
{
|
||||||
|
return r_;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- Obtain the reference
|
||||||
|
inline Region& operator()()
|
||||||
|
{
|
||||||
|
return r_;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user