ENH: chtMultiRegionFoam: solve single h equation

This commit is contained in:
mattijs
2011-10-04 15:36:52 +01:00
parent 4b5049b0d2
commit ba308083ab
34 changed files with 1392 additions and 169 deletions

View File

@ -53,4 +53,6 @@ fi
wmake $makeType decompositionMethods
wmake $makeType decompose
# ----------------------------------------------------------------- end-of-file

View File

@ -0,0 +1,3 @@
fvFieldDecomposer.C
LIB = $(FOAM_LIBBIN)/libdecompose

View File

@ -0,0 +1,9 @@
EXE_INC = \
-I$(LIB_SRC)/finiteVolume/lnInclude \
-I$(LIB_SRC)/meshTools/lnInclude \
-I$(LIB_SRC)/lagrangian/basic/lnInclude
LIB_LIBS = \
-lfiniteVolume \
-lmeshTools \
-llagrangian

View File

@ -0,0 +1,216 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::fvFieldDecomposer::patchFieldDecomposer::patchFieldDecomposer
(
const labelUList& addressingSlice,
const label addressingOffset
)
:
directAddressing_(addressingSlice)
{
forAll(directAddressing_, i)
{
// Subtract one to align addressing.
directAddressing_[i] -= addressingOffset + 1;
}
}
Foam::fvFieldDecomposer::processorVolPatchFieldDecomposer::
processorVolPatchFieldDecomposer
(
const fvMesh& mesh,
const labelUList& addressingSlice
)
:
directAddressing_(addressingSlice.size())
{
const labelList& own = mesh.faceOwner();
const labelList& neighb = mesh.faceNeighbour();
forAll(directAddressing_, i)
{
// Subtract one to align addressing.
label ai = mag(addressingSlice[i]) - 1;
if (ai < neighb.size())
{
// This is a regular face. it has been an internal face
// of the original mesh and now it has become a face
// on the parallel boundary.
// Give face the value of the neighbour.
if (addressingSlice[i] >= 0)
{
// I have the owner so use the neighbour value
directAddressing_[i] = neighb[ai];
}
else
{
directAddressing_[i] = own[ai];
}
}
else
{
// This is a face that used to be on a cyclic boundary
// but has now become a parallel patch face. I cannot
// do the interpolation properly (I would need to look
// up the different (face) list of data), so I will
// just grab the value from the owner cell
directAddressing_[i] = own[ai];
}
}
}
Foam::fvFieldDecomposer::processorSurfacePatchFieldDecomposer::
processorSurfacePatchFieldDecomposer
(
const labelUList& addressingSlice
)
:
addressing_(addressingSlice.size()),
weights_(addressingSlice.size())
{
forAll(addressing_, i)
{
addressing_[i].setSize(1);
weights_[i].setSize(1);
addressing_[i][0] = mag(addressingSlice[i]) - 1;
weights_[i][0] = sign(addressingSlice[i]);
}
}
Foam::fvFieldDecomposer::fvFieldDecomposer
(
const fvMesh& completeMesh,
const fvMesh& procMesh,
const labelList& faceAddressing,
const labelList& cellAddressing,
const labelList& boundaryAddressing
)
:
completeMesh_(completeMesh),
procMesh_(procMesh),
faceAddressing_(faceAddressing),
cellAddressing_(cellAddressing),
boundaryAddressing_(boundaryAddressing),
patchFieldDecomposerPtrs_
(
procMesh_.boundary().size(),
static_cast<patchFieldDecomposer*>(NULL)
),
processorVolPatchFieldDecomposerPtrs_
(
procMesh_.boundary().size(),
static_cast<processorVolPatchFieldDecomposer*>(NULL)
),
processorSurfacePatchFieldDecomposerPtrs_
(
procMesh_.boundary().size(),
static_cast<processorSurfacePatchFieldDecomposer*>(NULL)
)
{
forAll(boundaryAddressing_, patchi)
{
if
(
boundaryAddressing_[patchi] >= 0
&& !isA<processorLduInterface>(procMesh.boundary()[patchi])
)
{
patchFieldDecomposerPtrs_[patchi] = new patchFieldDecomposer
(
procMesh_.boundary()[patchi].patchSlice(faceAddressing_),
completeMesh_.boundaryMesh()
[
boundaryAddressing_[patchi]
].start()
);
}
else
{
processorVolPatchFieldDecomposerPtrs_[patchi] =
new processorVolPatchFieldDecomposer
(
completeMesh_,
procMesh_.boundary()[patchi].patchSlice(faceAddressing_)
);
processorSurfacePatchFieldDecomposerPtrs_[patchi] =
new processorSurfacePatchFieldDecomposer
(
static_cast<const labelUList&>
(
procMesh_.boundary()[patchi].patchSlice
(
faceAddressing_
)
)
);
}
}
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::fvFieldDecomposer::~fvFieldDecomposer()
{
forAll(patchFieldDecomposerPtrs_, patchi)
{
if (patchFieldDecomposerPtrs_[patchi])
{
delete patchFieldDecomposerPtrs_[patchi];
}
}
forAll(processorVolPatchFieldDecomposerPtrs_, patchi)
{
if (processorVolPatchFieldDecomposerPtrs_[patchi])
{
delete processorVolPatchFieldDecomposerPtrs_[patchi];
}
}
forAll(processorSurfacePatchFieldDecomposerPtrs_, patchi)
{
if (processorSurfacePatchFieldDecomposerPtrs_[patchi])
{
delete processorSurfacePatchFieldDecomposerPtrs_[patchi];
}
}
}
// ************************************************************************* //

View File

@ -0,0 +1,275 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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::fvFieldDecomposer
Description
Finite Volume volume and surface field decomposer.
SourceFiles
fvFieldDecomposer.C
fvFieldDecomposerDecomposeFields.C
\*---------------------------------------------------------------------------*/
#ifndef fvFieldDecomposer_H
#define fvFieldDecomposer_H
#include "fvMesh.H"
#include "fvPatchFieldMapper.H"
#include "surfaceFields.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
class IOobjectList;
/*---------------------------------------------------------------------------*\
Class fvFieldDecomposer Declaration
\*---------------------------------------------------------------------------*/
class fvFieldDecomposer
{
public:
//- Patch field decomposer class
class patchFieldDecomposer
:
public fvPatchFieldMapper
{
// Private data
labelList directAddressing_;
public:
// Constructors
//- Construct given addressing
patchFieldDecomposer
(
const labelUList& addressingSlice,
const label addressingOffset
);
// Member functions
label size() const
{
return directAddressing_.size();
}
bool direct() const
{
return true;
}
const labelUList& directAddressing() const
{
return directAddressing_;
}
};
//- Processor patch field decomposer class. Maps either owner or
// neighbour data (no interpolate anymore - processorFvPatchField
// holds neighbour data)
class processorVolPatchFieldDecomposer
:
public fvPatchFieldMapper
{
// Private data
labelList directAddressing_;
public:
//- Construct given addressing
processorVolPatchFieldDecomposer
(
const fvMesh& mesh,
const labelUList& addressingSlice
);
// Member functions
label size() const
{
return directAddressing_.size();
}
bool direct() const
{
return true;
}
const labelUList& directAddressing() const
{
return directAddressing_;
}
};
//- Processor patch field decomposer class. Surface field is assumed
// to have direction (so manipulates sign when mapping)
class processorSurfacePatchFieldDecomposer
:
public fvPatchFieldMapper
{
labelListList addressing_;
scalarListList weights_;
public:
//- Construct given addressing
processorSurfacePatchFieldDecomposer
(
const labelUList& addressingSlice
);
// Member functions
label size() const
{
return addressing_.size();
}
bool direct() const
{
return false;
}
const labelListList& addressing() const
{
return addressing_;
}
const scalarListList& weights() const
{
return weights_;
}
};
private:
// Private data
//- Reference to complete mesh
const fvMesh& completeMesh_;
//- Reference to processor mesh
const fvMesh& procMesh_;
//- Reference to face addressing
const labelList& faceAddressing_;
//- Reference to cell addressing
const labelList& cellAddressing_;
//- Reference to boundary addressing
const labelList& boundaryAddressing_;
//- List of patch field decomposers
List<patchFieldDecomposer*> patchFieldDecomposerPtrs_;
List<processorVolPatchFieldDecomposer*>
processorVolPatchFieldDecomposerPtrs_;
List<processorSurfacePatchFieldDecomposer*>
processorSurfacePatchFieldDecomposerPtrs_;
// Private Member Functions
//- Disallow default bitwise copy construct
fvFieldDecomposer(const fvFieldDecomposer&);
//- Disallow default bitwise assignment
void operator=(const fvFieldDecomposer&);
public:
// Constructors
//- Construct from components
fvFieldDecomposer
(
const fvMesh& completeMesh,
const fvMesh& procMesh,
const labelList& faceAddressing,
const labelList& cellAddressing,
const labelList& boundaryAddressing
);
//- Destructor
~fvFieldDecomposer();
// Member Functions
//- Decompose volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
decomposeField
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const bool allowUnknownPatchFields = false
) const;
//- Decompose surface field
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
decomposeField
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
) const;
template<class GeoField>
void decomposeFields(const PtrList<GeoField>& fields) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
# include "fvFieldDecomposerDecomposeFields.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -0,0 +1,286 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011 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"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::fvFieldDecomposer::decomposeField
(
const GeometricField<Type, fvPatchField, volMesh>& field,
const bool allowUnknownPatchFields
) const
{
// Create and map the internal field values
Field<Type> internalField(field.internalField(), cellAddressing_);
// Create and map the patch field values
PtrList<fvPatchField<Type> > patchFields(boundaryAddressing_.size());
forAll(boundaryAddressing_, patchi)
{
if (patchFieldDecomposerPtrs_[patchi])
{
patchFields.set
(
patchi,
fvPatchField<Type>::New
(
field.boundaryField()[boundaryAddressing_[patchi]],
procMesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null(),
*patchFieldDecomposerPtrs_[patchi]
)
);
}
else if (isA<processorCyclicFvPatch>(procMesh_.boundary()[patchi]))
{
patchFields.set
(
patchi,
new processorCyclicFvPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null(),
Field<Type>
(
field.internalField(),
*processorVolPatchFieldDecomposerPtrs_[patchi]
)
)
);
}
else if (isA<processorFvPatch>(procMesh_.boundary()[patchi]))
{
patchFields.set
(
patchi,
new processorFvPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null(),
Field<Type>
(
field.internalField(),
*processorVolPatchFieldDecomposerPtrs_[patchi]
)
)
);
}
else if (allowUnknownPatchFields)
{
patchFields.set
(
patchi,
new emptyFvPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, volMesh>::null()
)
);
}
else
{
FatalErrorIn("fvFieldDecomposer::decomposeField()")
<< "Unknown type." << abort(FatalError);
}
}
// Create the field for the processor
return tmp<GeometricField<Type, fvPatchField, volMesh> >
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
field.name(),
procMesh_.time().timeName(),
procMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procMesh_,
field.dimensions(),
internalField,
patchFields
)
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::fvFieldDecomposer::decomposeField
(
const GeometricField<Type, fvsPatchField, surfaceMesh>& field
) const
{
labelList mapAddr
(
labelList::subList
(
faceAddressing_,
procMesh_.nInternalFaces()
)
);
forAll(mapAddr, i)
{
mapAddr[i] -= 1;
}
// Create and map the internal field values
Field<Type> internalField
(
field.internalField(),
mapAddr
);
// Problem with addressing when a processor patch picks up both internal
// faces and faces from cyclic boundaries. This is a bit of a hack, but
// I cannot find a better solution without making the internal storage
// mechanism for surfaceFields correspond to the one of faces in polyMesh
// (i.e. using slices)
Field<Type> allFaceField(field.mesh().nFaces());
forAll(field.internalField(), i)
{
allFaceField[i] = field.internalField()[i];
}
forAll(field.boundaryField(), patchi)
{
const Field<Type> & p = field.boundaryField()[patchi];
const label patchStart = field.mesh().boundaryMesh()[patchi].start();
forAll(p, i)
{
allFaceField[patchStart + i] = p[i];
}
}
// Create and map the patch field values
PtrList<fvsPatchField<Type> > patchFields(boundaryAddressing_.size());
forAll(boundaryAddressing_, patchi)
{
if (patchFieldDecomposerPtrs_[patchi])
{
patchFields.set
(
patchi,
fvsPatchField<Type>::New
(
field.boundaryField()[boundaryAddressing_[patchi]],
procMesh_.boundary()[patchi],
DimensionedField<Type, surfaceMesh>::null(),
*patchFieldDecomposerPtrs_[patchi]
)
);
}
else if (isA<processorCyclicFvPatch>(procMesh_.boundary()[patchi]))
{
patchFields.set
(
patchi,
new processorCyclicFvsPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, surfaceMesh>::null(),
Field<Type>
(
allFaceField,
*processorSurfacePatchFieldDecomposerPtrs_[patchi]
)
)
);
}
else if (isA<processorFvPatch>(procMesh_.boundary()[patchi]))
{
patchFields.set
(
patchi,
new processorFvsPatchField<Type>
(
procMesh_.boundary()[patchi],
DimensionedField<Type, surfaceMesh>::null(),
Field<Type>
(
allFaceField,
*processorSurfacePatchFieldDecomposerPtrs_[patchi]
)
)
);
}
else
{
FatalErrorIn("fvFieldDecomposer::decomposeField()")
<< "Unknown type." << abort(FatalError);
}
}
// Create the field for the processor
return tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
field.name(),
procMesh_.time().timeName(),
procMesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procMesh_,
field.dimensions(),
internalField,
patchFields
)
);
}
template<class GeoField>
void Foam::fvFieldDecomposer::decomposeFields
(
const PtrList<GeoField>& fields
) const
{
forAll(fields, fieldI)
{
decomposeField(fields[fieldI])().write();
}
}
// ************************************************************************* //

View File

@ -42,7 +42,40 @@ Foam::fvFieldReconstructor::fvFieldReconstructor
cellProcAddressing_(cellProcAddressing),
boundaryProcAddressing_(boundaryProcAddressing),
nReconstructed_(0)
{}
{
forAll(procMeshes_, procI)
{
const fvMesh& procMesh = procMeshes_[procI];
if
(
faceProcAddressing[procI].size() != procMesh.nFaces()
|| cellProcAddressing[procI].size() != procMesh.nCells()
|| boundaryProcAddressing[procI].size() != procMesh.boundary().size()
)
{
FatalErrorIn
(
"fvFieldReconstructor::fvFieldReconstructor\n"
"(\n"
" fvMesh&,\n"
" const PtrList<fvMesh>&,\n"
" const PtrList<labelIOList>&,\n"
" const PtrList<labelIOList>&,\n"
" const PtrList<labelIOList>&\n"
")"
) << "Size of maps does not correspond to size of mesh"
<< " for processor " << procI << endl
<< "faceProcAddressing : " << faceProcAddressing[procI].size()
<< " nFaces : " << procMesh.nFaces() << endl
<< "cellProcAddressing : " << cellProcAddressing[procI].size()
<< " nCell : " << procMesh.nCells() << endl
<< "boundaryProcAddressing : "
<< boundaryProcAddressing[procI].size()
<< " nFaces : " << procMesh.boundary().size()
<< exit(FatalError);
}
}
}
// ************************************************************************* //

View File

@ -86,6 +86,7 @@ class fvFieldReconstructor
public:
//- Mapper for sizing only - does not do any actual mapping.
class fvPatchFieldReconstructor
:
public fvPatchFieldMapper
@ -146,19 +147,48 @@ public:
//- Reconstruct volume internal field
template<class Type>
tmp<DimensionedField<Type, volMesh> >
reconstructFvVolumeInternalField(const IOobject& fieldIoObject);
reconstructFvVolumeInternalField
(
const IOobject& fieldIoObject,
const PtrList<DimensionedField<Type, volMesh> >& procFields
) 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<GeometricField<Type, fvPatchField, volMesh> >
reconstructFvVolumeField(const IOobject& fieldIoObject);
reconstructFvVolumeField
(
const IOobject& fieldIoObject,
const PtrList<GeometricField<Type, fvPatchField, volMesh> >&
) const;
//- Read and reconstruct volume field
template<class Type>
tmp<GeometricField<Type, fvPatchField, volMesh> >
reconstructFvVolumeField(const IOobject& fieldIoObject) const;
//- Reconstruct surface field
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
reconstructFvSurfaceField(const IOobject& fieldIoObject);
reconstructFvSurfaceField
(
const IOobject& fieldIoObject,
const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >&
) const;
//- Reconstruct and write all/selected volume internal fields
//- Read and reconstruct surface field
template<class Type>
tmp<GeometricField<Type, fvsPatchField, surfaceMesh> >
reconstructFvSurfaceField(const IOobject& fieldIoObject) const;
//- Read, reconstruct and write all/selected volume internal fields
template<class Type>
void reconstructFvVolumeInternalFields
(
@ -166,7 +196,7 @@ public:
const HashSet<word>& selectedFields
);
//- Reconstruct and write all/selected volume fields
//- Read, reconstruct and write all/selected volume fields
template<class Type>
void reconstructFvVolumeFields
(
@ -174,7 +204,7 @@ public:
const HashSet<word>& selectedFields
);
//- Reconstruct and write all/selected surface fields
//- Read, reconstruct and write all/selected surface fields
template<class Type>
void reconstructFvSurfaceFields
(

View File

@ -33,12 +33,48 @@ License
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
(
const IOobject& fieldIoObject,
const PtrList<DimensionedField<Type, volMesh> >& procFields
) const
{
// Create the internalField
Field<Type> internalField(mesh_.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,
mesh_,
procFields[0].dimensions(),
internalField
)
);
}
template<class Type>
Foam::tmp<Foam::DimensionedField<Type, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
(
const IOobject& fieldIoObject
)
) const
{
// Read the field for all the processors
PtrList<DimensionedField<Type, volMesh> > procFields
@ -67,37 +103,17 @@ Foam::fvFieldReconstructor::reconstructFvVolumeInternalField
}
// Create the internalField
Field<Type> internalField(mesh_.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> >
return reconstructFvVolumeInternalField
(
new DimensionedField<Type, volMesh>
IOobject
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
procFields[0].dimensions(),
internalField
)
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
@ -106,44 +122,17 @@ template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeField
(
const IOobject& fieldIoObject
)
const IOobject& fieldIoObject,
const PtrList<GeometricField<Type, fvPatchField, volMesh> >& procFields
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
(
procMeshes_.size()
);
forAll(procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
// Create the internalField
Field<Type> internalField(mesh_.nCells());
// Create the patch fields
PtrList<fvPatchField<Type> > patchFields(mesh_.boundary().size());
forAll(procMeshes_, procI)
forAll(procFields, procI)
{
const GeometricField<Type, fvPatchField, volMesh>& procField =
procFields[procI];
@ -163,7 +152,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
// Get addressing slice for this patch
const labelList::subList cp =
procMeshes_[procI].boundary()[patchI].patchSlice
procField.mesh().boundary()[patchI].patchSlice
(
faceProcAddressing_[procI]
);
@ -198,11 +187,32 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
forAll(cp, faceI)
{
// Check
if (cp[faceI] <= 0)
{
FatalErrorIn
(
"fvFieldReconstructor::reconstructFvVolumeField\n"
"(\n"
" const IOobject&,\n"
" const PtrList<GeometricField<Type,"
" fvPatchField, volMesh> >&\n"
") const\n"
) << "Processor " << procI
<< " patch "
<< procField.mesh().boundary()[patchI].name()
<< " face " << faceI
<< " originates from reversed face since "
<< cp[faceI]
<< exit(FatalError);
}
// Subtract one to take into account offsets for
// face direction.
reverseAddressing[faceI] = cp[faceI] - 1 - curPatchStart;
}
patchFields[curBPatch].rmap
(
procField.boundaryField()[patchI],
@ -283,14 +293,7 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
(
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
fieldIoObject,
mesh_,
procFields[0].dimensions(),
internalField,
@ -301,14 +304,14 @@ Foam::fvFieldReconstructor::reconstructFvVolumeField
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::fvFieldReconstructor::reconstructFvSurfaceField
Foam::tmp<Foam::GeometricField<Type, Foam::fvPatchField, Foam::volMesh> >
Foam::fvFieldReconstructor::reconstructFvVolumeField
(
const IOobject& fieldIoObject
)
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
PtrList<GeometricField<Type, fvPatchField, volMesh> > procFields
(
procMeshes_.size()
);
@ -318,7 +321,7 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
procFields.set
(
procI,
new GeometricField<Type, fvsPatchField, surfaceMesh>
new GeometricField<Type, fvPatchField, volMesh>
(
IOobject
(
@ -333,7 +336,29 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
);
}
return reconstructFvVolumeField
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::fvFieldReconstructor::reconstructFvSurfaceField
(
const IOobject& fieldIoObject,
const PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> >& procFields
) const
{
// Create the internalField
Field<Type> internalField(mesh_.nInternalFaces());
@ -503,14 +528,7 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
(
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
fieldIoObject,
mesh_,
procFields[0].dimensions(),
internalField,
@ -520,6 +538,54 @@ Foam::fvFieldReconstructor::reconstructFvSurfaceField
}
template<class Type>
Foam::tmp<Foam::GeometricField<Type, Foam::fvsPatchField, Foam::surfaceMesh> >
Foam::fvFieldReconstructor::reconstructFvSurfaceField
(
const IOobject& fieldIoObject
) const
{
// Read the field for all the processors
PtrList<GeometricField<Type, fvsPatchField, surfaceMesh> > procFields
(
procMeshes_.size()
);
forAll(procMeshes_, procI)
{
procFields.set
(
procI,
new GeometricField<Type, fvsPatchField, surfaceMesh>
(
IOobject
(
fieldIoObject.name(),
procMeshes_[procI].time().timeName(),
procMeshes_[procI],
IOobject::MUST_READ,
IOobject::NO_WRITE
),
procMeshes_[procI]
)
);
}
return reconstructFvSurfaceField
(
IOobject
(
fieldIoObject.name(),
mesh_.time().timeName(),
mesh_,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFields
);
}
template<class Type>
void Foam::fvFieldReconstructor::reconstructFvVolumeInternalFields
(