ENH: Add modifications in existing files of foam-extend

- also removed the include of adiosControl.H
This commit is contained in:
Gregor Weiss 2023-09-25 21:51:57 +02:00
parent 6fe6145d97
commit 5f7d2716bd
98 changed files with 3060 additions and 1507 deletions

View file

@ -119,6 +119,7 @@ int main(int argc, char *argv[])
bool writeCellDist = args.optionFound("cellDist");
bool copyUniform = args.optionFound("copyUniform");
bool decomposeMeshOnly = args.optionFound("mesh");
bool decomposeFieldsOnly = args.optionFound("fields");
bool filterPatches = args.optionFound("filterPatches");
bool forceOverwrite = args.optionFound("force");
@ -136,9 +137,9 @@ int main(int argc, char *argv[])
(
runTime.path()
/(word("processor") + name(nProcs))
/runTime.constant()
/regionDir
/polyMesh::meshSubDir
///runTime.constant()
///regionDir
///polyMesh::meshSubDir
)
)
{
@ -263,7 +264,6 @@ int main(int argc, char *argv[])
)
);
// Decompose the mesh
if (!decomposeFieldsOnly)
{
@ -271,61 +271,11 @@ int main(int argc, char *argv[])
meshDecomp.writeDecomposition();
if (writeCellDist)
{
const labelList& procIds = meshDecomp.cellToProc();
// Write the decomposition as labelList for use with 'manual'
// decomposition method.
labelIOList cellDecomposition
(
IOobject
(
"cellDecomposition",
mesh.facesInstance(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE,
false
),
procIds
);
cellDecomposition.write();
Info<< nl << "Wrote decomposition to "
<< cellDecomposition.objectPath()
<< " for use in manual decomposition." << endl;
// Write as volScalarField for post-processing
volScalarField cellDist
(
IOobject
(
"cellDist",
runTime.timeName(),
mesh.dbDir(),
mesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
mesh,
dimensionedScalar("cellDist", dimless, 0),
zeroGradientFvPatchScalarField::typeName
);
forAll(procIds, celli)
{
cellDist[celli] = procIds[celli];
}
cellDist.write();
Info<< nl << "Wrote decomposition as volScalarField to "
<< cellDist.name() << " for use in post-processing."
<< endl;
}
SliceStreamRepo::instance()->clear();
}
if (!decomposeMeshOnly)
{
// Search for list of objects for this time
IOobjectList objects(mesh, runTime.timeName());
@ -361,242 +311,6 @@ int main(int argc, char *argv[])
PtrList<surfaceTensorField> surfaceTensorFields;
readFields(mesh, objects, surfaceTensorFields);
// Construct the point fields
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
const pointMesh& pMesh = pointMesh::New(mesh);
PtrList<pointScalarField> pointScalarFields;
readFields(pMesh, objects, pointScalarFields);
PtrList<pointVectorField> pointVectorFields;
readFields(pMesh, objects, pointVectorFields);
PtrList<pointSphericalTensorField> pointSphericalTensorFields;
readFields(pMesh, objects, pointSphericalTensorFields);
PtrList<pointSymmTensorField> pointSymmTensorFields;
readFields(pMesh, objects, pointSymmTensorFields);
PtrList<pointTensorField> pointTensorFields;
readFields(pMesh, objects, pointTensorFields);
// Construct the tetPoint fields
// ~~~~~~~~~~~~~~~~~~~~~~~~~~
tetPolyMesh* tetMeshPtr = nullptr;
PtrList<tetPointScalarField> tetPointScalarFields;
PtrList<tetPointVectorField> tetPointVectorFields;
PtrList<tetPointSphericalTensorField> tetPointSphericalTensorFields;
PtrList<tetPointSymmTensorField> tetPointSymmTensorFields;
PtrList<tetPointTensorField> tetPointTensorFields;
PtrList<elementScalarField> elementScalarFields;
PtrList<elementVectorField> elementVectorFields;
if
(
objects.lookupClass("tetPointScalarField").size() > 0
|| objects.lookupClass("tetPointVectorField").size() > 0
|| objects.lookupClass("tetPointSphericalTensorField").size() > 0
|| objects.lookupClass("tetPointSymmTensorField").size() > 0
|| objects.lookupClass("tetPointTensorField").size() > 0
|| objects.lookupClass("elementScalarField").size() > 0
|| objects.lookupClass("elementVectorField").size() > 0
)
{
tetMeshPtr = new tetPolyMesh(mesh);
tetPolyMesh& tetMesh = *tetMeshPtr;
readFields(tetMesh, objects, tetPointScalarFields);
readFields(tetMesh, objects, tetPointVectorFields);
readFields(tetMesh, objects, tetPointSphericalTensorFields);
readFields(tetMesh, objects, tetPointSymmTensorFields);
readFields(tetMesh, objects, tetPointTensorFields);
readFields(tetMesh, objects, elementScalarFields);
readFields(tetMesh, objects, elementVectorFields);
}
// Construct the Lagrangian fields
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
fileNameList cloudDirs
(
readDir(runTime.timePath()/cloud::prefix, fileName::DIRECTORY)
);
// Particles
PtrList<Cloud<indexedParticle> > lagrangianPositions(cloudDirs.size());
// Particles per cell
PtrList< List<SLList<indexedParticle*>*> > cellParticles(cloudDirs.size());
PtrList<PtrList<labelIOField> > lagrangianLabelFields(cloudDirs.size());
PtrList<PtrList<scalarIOField> > lagrangianScalarFields(cloudDirs.size());
PtrList<PtrList<vectorIOField> > lagrangianVectorFields(cloudDirs.size());
PtrList<PtrList<sphericalTensorIOField> > lagrangianSphericalTensorFields
(
cloudDirs.size()
);
PtrList<PtrList<symmTensorIOField> > lagrangianSymmTensorFields
(
cloudDirs.size()
);
PtrList<PtrList<tensorIOField> > lagrangianTensorFields
(
cloudDirs.size()
);
label cloudI = 0;
forAll(cloudDirs, i)
{
IOobjectList sprayObjs
(
mesh,
runTime.timeName(),
cloud::prefix/cloudDirs[i]
);
IOobject* positionsPtr = sprayObjs.lookup("positions");
if (positionsPtr)
{
// Read lagrangian particles
// ~~~~~~~~~~~~~~~~~~~~~~~~~
Info<< "Identified lagrangian data set: " << cloudDirs[i] << endl;
lagrangianPositions.set
(
cloudI,
new Cloud<indexedParticle>
(
mesh,
cloudDirs[i],
false
)
);
// Sort particles per cell
// ~~~~~~~~~~~~~~~~~~~~~~~
cellParticles.set
(
cloudI,
new List<SLList<indexedParticle*>*>
(
mesh.nCells(),
static_cast<SLList<indexedParticle*>*>(nullptr)
)
);
label i = 0;
forAllIter
(
Cloud<indexedParticle>,
lagrangianPositions[cloudI],
iter
)
{
iter().index() = i++;
label celli = iter().cell();
// Check
if (celli < 0 || celli >= mesh.nCells())
{
FatalErrorIn(args.executable())
<< "Illegal cell number " << celli
<< " for particle with index " << iter().index()
<< " at position " << iter().position() << nl
<< "Cell number should be between 0 and "
<< mesh.nCells()-1 << nl
<< "On this mesh the particle should be in cell "
<< mesh.findCell(iter().position())
<< exit(FatalError);
}
if (!cellParticles[cloudI][celli])
{
cellParticles[cloudI][celli] =
new SLList<indexedParticle*>();
}
cellParticles[cloudI][celli]->append(&iter());
}
// Read fields
// ~~~~~~~~~~~
IOobjectList lagrangianObjects
(
mesh,
runTime.timeName(),
cloud::prefix/cloudDirs[cloudI]
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianLabelFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianScalarFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianVectorFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianSphericalTensorFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianSymmTensorFields
);
lagrangianFieldDecomposer::readFields
(
cloudI,
lagrangianObjects,
lagrangianTensorFields
);
cloudI++;
}
}
lagrangianPositions.setSize(cloudI);
cellParticles.setSize(cloudI);
lagrangianLabelFields.setSize(cloudI);
lagrangianScalarFields.setSize(cloudI);
lagrangianVectorFields.setSize(cloudI);
lagrangianSphericalTensorFields.setSize(cloudI);
lagrangianSymmTensorFields.setSize(cloudI);
lagrangianTensorFields.setSize(cloudI);
// Any uniform data to copy/link?
fileName uniformDir("uniform");
@ -613,6 +327,72 @@ int main(int argc, char *argv[])
Info<< endl;
if ( mesh.time().writeFormat() == IOstream::COHERENT ) {
Time myDb( Time::controlDictName,
mesh.time().rootPath(),
mesh.time().caseName(),
"system",
"constant",
true );
// Read the mesh
fvMesh coherentMesh
(
IOobject
(
regionName,
myDb.timeName(),
myDb
)
);
auto coherentFaceAddressing = meshDecomp.coherentFaceAddressing();
auto coherentCellAddressing = meshDecomp.coherentCellAddressing();
auto coherentBoundaryAddressing = meshDecomp.blankAddressing( mesh.boundaryMesh().size() );
// Old format of face addressing requires a plus one.
for ( auto& faceId : coherentFaceAddressing ) { ++faceId; }
// FV fields
if
(
volScalarFields.size()
|| volVectorFields.size()
|| volSphericalTensorFields.size()
|| volSymmTensorFields.size()
|| volTensorFields.size()
|| surfaceScalarFields.size()
|| surfaceVectorFields.size()
|| surfaceSphericalTensorFields.size()
|| surfaceSymmTensorFields.size()
|| surfaceTensorFields.size()
)
{
fvFieldDecomposer fieldDecomposer
(
mesh,
coherentMesh,
coherentFaceAddressing,
coherentCellAddressing,
coherentBoundaryAddressing
);
fieldDecomposer.decomposeFields(volScalarFields);
fieldDecomposer.decomposeFields(volVectorFields);
fieldDecomposer.decomposeFields(volSphericalTensorFields);
fieldDecomposer.decomposeFields(volSymmTensorFields);
fieldDecomposer.decomposeFields(volTensorFields);
fieldDecomposer.decomposeFields(surfaceScalarFields);
fieldDecomposer.decomposeFields(surfaceVectorFields);
fieldDecomposer.decomposeFields(surfaceSphericalTensorFields);
fieldDecomposer.decomposeFields(surfaceSymmTensorFields);
fieldDecomposer.decomposeFields(surfaceTensorFields);
}
}
else
{
// Split the fields over processors
for (label procI = 0; procI < meshDecomp.nProcs(); procI++)
{
@ -741,123 +521,6 @@ int main(int argc, char *argv[])
fieldDecomposer.decomposeFields(surfaceTensorFields);
}
// Point fields
if
(
pointScalarFields.size()
|| pointVectorFields.size()
|| pointSphericalTensorFields.size()
|| pointSymmTensorFields.size()
|| pointTensorFields.size()
)
{
const pointMesh& procPMesh = pointMesh::New(procMesh, true);
pointFieldDecomposer fieldDecomposer
(
pMesh,
procPMesh,
pointProcAddressing,
boundaryProcAddressing
);
fieldDecomposer.decomposeFields(pointScalarFields);
fieldDecomposer.decomposeFields(pointVectorFields);
fieldDecomposer.decomposeFields(pointSphericalTensorFields);
fieldDecomposer.decomposeFields(pointSymmTensorFields);
fieldDecomposer.decomposeFields(pointTensorFields);
}
// tetPoint fields
if (tetMeshPtr)
{
const tetPolyMesh& tetMesh = *tetMeshPtr;
tetPolyMesh procTetMesh(procMesh);
tetPointFieldDecomposer fieldDecomposer
(
tetMesh,
procTetMesh,
pointProcAddressing,
faceProcAddressing,
cellProcAddressing,
boundaryProcAddressing
);
fieldDecomposer.decomposeFields(tetPointScalarFields);
fieldDecomposer.decomposeFields(tetPointVectorFields);
fieldDecomposer.decomposeFields(tetPointSphericalTensorFields);
fieldDecomposer.decomposeFields(tetPointSymmTensorFields);
fieldDecomposer.decomposeFields(tetPointTensorFields);
fieldDecomposer.decomposeFields(elementScalarFields);
fieldDecomposer.decomposeFields(elementVectorFields);
}
// If there is lagrangian data write it out
forAll(lagrangianPositions, cloudI)
{
if (lagrangianPositions[cloudI].size())
{
lagrangianFieldDecomposer fieldDecomposer
(
mesh,
procMesh,
cellProcAddressing,
cloudDirs[cloudI],
lagrangianPositions[cloudI],
cellParticles[cloudI]
);
// Lagrangian fields
if
(
lagrangianLabelFields[cloudI].size()
|| lagrangianScalarFields[cloudI].size()
|| lagrangianVectorFields[cloudI].size()
|| lagrangianSphericalTensorFields[cloudI].size()
|| lagrangianSymmTensorFields[cloudI].size()
|| lagrangianTensorFields[cloudI].size()
)
{
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianLabelFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianScalarFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianVectorFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianSphericalTensorFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianSymmTensorFields[cloudI]
);
fieldDecomposer.decomposeFields
(
cloudDirs[cloudI],
lagrangianTensorFields[cloudI]
);
}
}
}
// Any non-decomposed data to copy?
if (uniformDir.size())
{
@ -889,176 +552,10 @@ int main(int argc, char *argv[])
}
}
}
}
if (tetMeshPtr)
{
delete tetMeshPtr;
tetMeshPtr = nullptr;
}
// Finite area mesh and field decomposition
IOobject faMeshBoundaryIOobj
(
"faBoundary",
mesh.time().findInstance
(
mesh.meshDir(),
"boundary"
),
faMesh::meshSubDir,
mesh,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
);
if(faMeshBoundaryIOobj.headerOk())
{
Info << "\nFinite area mesh decomposition" << endl;
faMeshDecomposition aMesh(mesh);
aMesh.decomposeMesh(filterPatches);
aMesh.writeDecomposition();
// Construct the area fields
// ~~~~~~~~~~~~~~~~~~~~~~~~
PtrList<areaScalarField> areaScalarFields;
readFields(aMesh, objects, areaScalarFields);
PtrList<areaVectorField> areaVectorFields;
readFields(aMesh, objects, areaVectorFields);
PtrList<areaSphericalTensorField> areaSphericalTensorFields;
readFields(aMesh, objects, areaSphericalTensorFields);
PtrList<areaSymmTensorField> areaSymmTensorFields;
readFields(aMesh, objects, areaSymmTensorFields);
PtrList<areaTensorField> areaTensorFields;
readFields(aMesh, objects, areaTensorFields);
// Construct the edge fields
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
PtrList<edgeScalarField> edgeScalarFields;
readFields(aMesh, objects, edgeScalarFields);
Info << endl;
// Split the fields over processors
for (label procI = 0; procI < meshDecomp.nProcs(); procI++)
{
Info<< "Processor " << procI
<< ": finite area field transfer" << endl;
// open the database
Time processorDb
(
Time::controlDictName,
args.rootPath(),
args.caseName()/fileName(word("processor") + name(procI))
);
processorDb.setTime(runTime);
// Read the mesh
fvMesh procFvMesh
(
IOobject
(
regionName,
processorDb.timeName(),
processorDb
)
);
faMesh procMesh(procFvMesh);
word faceLabelsInstance =
procMesh.time().findInstance
(
procMesh.meshDir(),
"faceLabels"
);
labelIOList faceProcAddressing
(
IOobject
(
"faceProcAddressing",
faceLabelsInstance,
procMesh.meshSubDir,
procFvMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
labelIOList boundaryProcAddressing
(
IOobject
(
"boundaryProcAddressing",
faceLabelsInstance,
procMesh.meshSubDir,
procFvMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
// FA fields
if
(
areaScalarFields.size()
|| areaVectorFields.size()
|| areaSphericalTensorFields.size()
|| areaSymmTensorFields.size()
|| areaTensorFields.size()
|| edgeScalarFields.size()
)
{
labelIOList edgeProcAddressing
(
IOobject
(
"edgeProcAddressing",
faceLabelsInstance,
procMesh.meshSubDir,
procFvMesh,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
faFieldDecomposer fieldDecomposer
(
aMesh,
procMesh,
edgeProcAddressing,
faceProcAddressing,
boundaryProcAddressing
);
fieldDecomposer.decomposeFields(areaScalarFields);
fieldDecomposer.decomposeFields(areaVectorFields);
fieldDecomposer.decomposeFields(areaSphericalTensorFields);
fieldDecomposer.decomposeFields(areaSymmTensorFields);
fieldDecomposer.decomposeFields(areaTensorFields);
fieldDecomposer.decomposeFields(edgeScalarFields);
}
}
}
} // for-loop on procI
} // if ( IOstream::COHERENT )
Info<< "\nEnd.\n" << endl;

View file

@ -34,36 +34,35 @@
export WM_PROJECT=foam
export WM_FORK=extend
export WM_PROJECT_VERSION=4.1
export WM_PROJECT_VERSION=4.1r
# helps to easily write #ifdefs to detect a dev-version
export FOAM_DEV=1
###############################################################################
# USER EDITABLE PART
#------------------------------------------------------------------------------
# (advanced / legacy)
# [projectDir] - directory containing this OpenFOAM version.
# \- When this file is located as $WM_PROJECT_DIR/etc/bashrc, the next lines
# should work when sourced by BASH or ZSH shells. If this however fails,
# set one of the fallback values to an appropriate path.
#
# either set $FOAM_INST_DIR before sourcing this file or set
# $foamInstall below to where FOAM is installed
#
# Location of FOAM installation
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
foamInstall=$HOME/$WM_PROJECT
# foamInstall=~$WM_PROJECT
# foamInstall=/usr/local/$WM_PROJECT
# foamInstall=/opt/$WM_PROJECT
# foamInstall=/usr/lib
#
# END OF (NORMAL) USER EDITABLE PART
# This can be removed if an absolute path is provided for WM_PROJECT_DIR
# later on in this file
# --
projectDir="${BASH_SOURCE:-${ZSH_NAME:+$0}}";
[ -n "$projectDir" ] && projectDir="$(\cd $(dirname $projectDir)/.. && \pwd -L)" ||\
projectDir="$HOME/openfoam/foam-extend-$WM_PROJECT_VERSION"
################################################################################
# Set $USER if it has not been set (eg. on Windows/MSYS systems)
if [ -z $USER ]
if [ -z "$USER" ]
then
export USER=`whoami`
export USER="$(whoami)"
fi
# note the location for later use (eg, in job scripts)
: ${FOAM_INST_DIR:=$foamInstall}; export FOAM_INST_DIR
: ${FOAM_INST_DIR:=$(dirname $projectDir)}; export FOAM_INST_DIR
# The old dirs to be cleaned from the various environment variables
# - remove anything under top-level directory.
@ -74,16 +73,17 @@ then
foamOldDirs="$WM_PROJECT_INST_DIR $foamOldDirs"
fi
# Location of site/user files
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~
export WM_PROJECT_INST_DIR=$FOAM_INST_DIR
export WM_PROJECT_DIR=$WM_PROJECT_INST_DIR/$WM_PROJECT-$WM_FORK-$WM_PROJECT_VERSION
export WM_PROJECT_DIR="$projectDir"
export WM_PROJECT_USER_DIR=$HOME/$WM_PROJECT/$USER-$WM_PROJECT_VERSION
# Location of third-party software
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#: ${WM_THIRD_PARTY_DIR=$WM_PROJECT_INST_DIR/ThirdParty-$WM_PROJECT_VERSION}; export WM_THIRD_PARTY_DIR
# Use external ThirdParty directory, e.g., from the standard installation of foam-extend.
#export WM_THIRD_PARTY_DIR=$HOME/$WM_PROJECT/$WM_PROJECT-$WM_FORK-4.1/ThirdParty
export WM_THIRD_PARTY_DIR=$WM_PROJECT_DIR/ThirdParty
# Enabling the usage of third-party software
@ -101,15 +101,15 @@ export WM_THIRD_PARTY_DIR=$WM_PROJECT_DIR/ThirdParty
#
# For AllMake.stage3
export METIS_SYSTEM=1
#export WM_THIRD_PARTY_USE_METIS_510=1
#export METIS_SYSTEM=1
export WM_THIRD_PARTY_USE_METIS_510=1
export WM_THIRD_PARTY_USE_PARMGRIDGEN_10=1
#export WM_THIRD_PARTY_USE_LIBCCMIO_261=1
export WM_THIRD_PARTY_USE_MESQUITE_230=1
export SCOTCH_SYSTEM=1
#export WM_THIRD_PARTY_USE_SCOTCH_604=1
export PARMETIS_SYSTEM=1
#export WM_THIRD_PARTY_USE_PARMETIS_403=1
#export SCOTCH_SYSTEM=1
export WM_THIRD_PARTY_USE_SCOTCH_604=1
#export PARMETIS_SYSTEM=1
export WM_THIRD_PARTY_USE_PARMETIS_403=1
export WM_THIRD_PARTY_USE_PYFOAM_069=1
export WM_THIRD_PARTY_USE_HWLOC_201=1
export WM_THIRD_PARTY_USE_ADIOS2_291=1
@ -187,7 +187,7 @@ export WM_COMPILER_LIB_ARCH=
: ${WM_PRECISION_OPTION:=DP}; export WM_PRECISION_OPTION
# WM_LABEL_SIZE = 32 | 64
: ${WM_LABEL_SIZE:=32}; export WM_LABEL_SIZE
: ${WM_LABEL_SIZE:=64}; export WM_LABEL_SIZE
# WM_COMPILE_OPTION = Opt | Debug | Prof
: ${WM_COMPILE_OPTION:=Opt}; export WM_COMPILE_OPTION
@ -601,7 +601,7 @@ fi
# cleanup environment:
# ~~~~~~~~~~~~~~~~~~~~
unset cleanEnv cleanProg foamInstall foamOldDirs
unset cleanEnv cleanProg projectDir foamInstall foamOldDirs
unset _foamSource
# -----------------------------------------------------------------------------

View file

@ -128,14 +128,6 @@ void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
Pout<< "\nCalculating original mesh data" << endl;
}
// Set references to the original mesh
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Access all faces to grab the zones
const faceList& allFaces = mesh_.allFaces();
const labelList& owner = mesh_.faceOwner();
const labelList& neighbour = mesh_.faceNeighbour();
// loop through the list of processor labels for the cell and add the
// cell shape to the list of cells for the appropriate processor
@ -164,17 +156,32 @@ void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
}
// Convert linked lists into normal lists
forAll (procCellList, procI)
#pragma omp parallel for
for (label procI = 0; procI < procCellList.size(); ++procI)
{
procCellAddressing_[procI] = procCellList[procI];
}
}
if (mesh_.time().writeFormat() == IOstream::COHERENT)
{
Info << "Skipping stones." << endl;
}
if (mesh_.time().writeFormat() != IOstream::COHERENT)
{
if (debug)
{
Pout << "\nDistributing faces to processors" << endl;
}
// Set references to the original mesh
const polyBoundaryMesh& patches = mesh_.boundaryMesh();
// Access all faces to grab the zones
const faceList& allFaces = mesh_.allFaces();
const labelList& owner = mesh_.faceOwner();
const labelList& neighbour = mesh_.faceNeighbour();
// Loop through internal faces and decide which processor they belong to
// First visit all internal faces. If cells at both sides belong to the
// same processor, the face is an internal face. If they are different,
@ -1217,6 +1224,7 @@ void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
globallySharedPoints_ = gSharedPoints.toc();
sort(globallySharedPoints_);
}
}
}

View file

@ -36,6 +36,9 @@ License
#include "DynamicList.H"
#include "globalMeshData.H"
#include "sliceMeshHelper.H"
#include "sliceWritePrimitives.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::domainDecomposition, 0);
@ -87,6 +90,162 @@ Foam::domainDecomposition::~domainDecomposition()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::autoPtr<Foam::fvMesh> Foam::domainDecomposition::parallelMesh
(
const Time& processorDb,
const word& regionName
)
{
// Create cell lookup
coherentCellAddressing_.resize(mesh_.nCells(), -1);
label start = 0;
label gCellI = 0;
labelList partitionStarts( procCellAddressing_.size() + 1 );
for (label procI = 0; procI < nProcs_; procI++) {
const labelList& curCellLabels = procCellAddressing_[procI];
// Fill partitionStarts
partitionStarts[ procI ] = start;
start += curCellLabels.size();
partitionStarts[ procI+1 ] = start;
// Fill the permutation from new to old cell numbering
forAll (curCellLabels, cellI) {
coherentCellAddressing_[curCellLabels[cellI]] = gCellI;
++gCellI;
}
}
auto path = mesh_.pointsInstance()/mesh_.meshDir();
sliceWritePrimitives
(
"mesh",
path,
"partitionStarts",
partitionStarts.size(),
partitionStarts.cdata()
);
// Get complete owner-neighour addressing in the mesh
const labelList& own = mesh_.faceOwner();
const labelList& nei = mesh_.faceNeighbour();
labelList procOwner(own.size(), -1);
labelList procNeighbour(nei.size(), -1);
coherentFaceAddressing_.resize(own.size(), 0);
faceList procFaces = mesh_.allFaces();
// Packaging mesh data to apply permutations
std::vector
<
std::tuple<label, label, label, face>
>
owner_neighbour_face(nei.size());
#pragma omp parallel for
for (Foam::label faceI = 0; faceI < nei.size(); ++faceI)
{
auto ownCellId = own[faceI];
auto neiCellId = nei[faceI];
auto owner = coherentCellAddressing_[ownCellId];
auto neighbour = coherentCellAddressing_[neiCellId];
auto face = procFaces[faceI];
if ( owner > neighbour )
{
std::swap(owner, neighbour);
face = face.reverseFace();
}
owner_neighbour_face[faceI] =
std::make_tuple
(
owner,
neighbour,
faceI,
face
);
procNeighbour[faceI] = neighbour;
}
labelList indices(procNeighbour.size());
permutationOfSorted(indices.begin(), indices.end(), procNeighbour);
applyPermutation(owner_neighbour_face, indices);
#pragma omp parallel for
for (Foam::label faceI = 0; faceI < owner_neighbour_face.size(); ++faceI)
{
procOwner[faceI] = std::get<0>
(
std::move(owner_neighbour_face[faceI])
);
procNeighbour[faceI] = std::get<1>
(
std::move(owner_neighbour_face[faceI])
);
coherentFaceAddressing_[faceI] = std::get<2>
(
std::move(owner_neighbour_face[faceI])
);
procFaces[faceI] = std::get<3>
(
std::move(owner_neighbour_face[faceI])
);
}
// Filling owners for patch faces
#pragma omp parallel for
for (Foam::label faceI = nei.size(); faceI < own.size(); ++faceI)
{
auto cellId = own[faceI];
procOwner[faceI] = coherentCellAddressing_[cellId];
}
// Filling face IDs for patch faces
std::iota
(
coherentFaceAddressing_.begin() + procNeighbour.size(),
coherentFaceAddressing_.end(),
procNeighbour.size()
);
// Create processor mesh without a boundary
pointField procPoints = mesh_.allPoints();
autoPtr<fvMesh> procMeshPtr
(
new fvMesh
(
IOobject
(
regionName,
mesh_.pointsInstance(),
processorDb
),
xferMove(procPoints),
xferMove(procFaces),
xferMove(procOwner),
xferMove(procNeighbour),
false // Do not sync par
)
);
fvMesh& procMesh = procMeshPtr();
const polyPatchList& meshPatches = mesh_.boundaryMesh();
List<polyPatch*> procPatches( meshPatches.size(), nullptr );
forAll ( meshPatches, patchi )
{
procPatches[patchi] =
meshPatches[patchi].clone
(
procMesh.boundaryMesh()
).ptr();
}
procMesh.addFvPatches( procPatches, false );
procMesh.write();
// TODO: Remove or insert as desired
//procMesh.checkMesh( true );
// REMOVED: "Create processor boundary patches"
// Because will be identified through extended neighbour list while reading.
return procMeshPtr;
}
Foam::autoPtr<Foam::fvMesh> Foam::domainDecomposition::processorMesh
(
const label procI,
@ -530,6 +689,21 @@ bool Foam::domainDecomposition::writeDecomposition()
{
Info<< "\nConstructing processor meshes" << endl;
if ( mesh_.time().writeFormat() == IOstream::COHERENT ) {
Time myDb
(
Time::controlDictName,
mesh_.time().rootPath(),
mesh_.time().caseName(),
"system",
"constant",
true
);
parallelMesh( myDb, mesh_.polyMesh::name() );
} else {
// Make a lookup map for globally shared points
Map<label> sharedPointLookup(2*globallySharedPoints_.size());
@ -577,186 +751,187 @@ bool Foam::domainDecomposition::writeDecomposition()
labelField(mesh_.nPoints(), 0)
);
// Write out the meshes
for (label procI = 0; procI < nProcs_; procI++)
{
fileName processorCasePath
(
mesh_.time().caseName()/fileName(word("processor") + name(procI))
);
// make the processor directory
mkDir(mesh_.time().rootPath()/processorCasePath);
// create a database
Time processorDb
(
Time::controlDictName,
mesh_.time().rootPath(),
processorCasePath,
"system",
"constant",
true
);
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
autoPtr<fvMesh> procMeshPtr = processorMesh
(
procI,
processorDb,
mesh_.polyMesh::name() // region name of undecomposed mesh
);
fvMesh& procMesh = procMeshPtr();
procMesh.write();
Info<< endl
<< "Processor " << procI << nl
<< " Number of cells = " << procMesh.nCells()
<< endl;
label nBoundaryFaces = 0;
label nProcPatches = 0;
label nProcFaces = 0;
forAll (procMesh.boundaryMesh(), patchi)
// Write out the meshes
for (label procI = 0; procI < nProcs_; procI++)
{
if
fileName processorCasePath
(
procMesh.boundaryMesh()[patchi].type()
== processorPolyPatch::typeName
)
mesh_.time().caseName()/fileName(word("processor") + name(procI))
);
// make the processor directory
mkDir(mesh_.time().rootPath()/processorCasePath);
// create a database
Time processorDb
(
Time::controlDictName,
mesh_.time().rootPath(),
processorCasePath,
"system",
"constant",
true
);
// Set the precision of the points data to 10
IOstream::defaultPrecision(10);
autoPtr<fvMesh> procMeshPtr = processorMesh
(
procI,
processorDb,
mesh_.polyMesh::name() // region name of undecomposed mesh
);
fvMesh& procMesh = procMeshPtr();
procMesh.write();
Info<< endl
<< "Processor " << procI << nl
<< " Number of cells = " << procMesh.nCells()
<< endl;
label nBoundaryFaces = 0;
label nProcPatches = 0;
label nProcFaces = 0;
forAll (procMesh.boundaryMesh(), patchi)
{
const processorPolyPatch& ppp =
refCast<const processorPolyPatch>
if
(
procMesh.boundaryMesh()[patchi]
);
procMesh.boundaryMesh()[patchi].type()
== processorPolyPatch::typeName
)
{
const processorPolyPatch& ppp =
refCast<const processorPolyPatch>
(
procMesh.boundaryMesh()[patchi]
);
Info<< " Number of faces shared with processor "
<< ppp.neighbProcNo() << " = " << ppp.size() << endl;
Info<< " Number of faces shared with processor "
<< ppp.neighbProcNo() << " = " << ppp.size() << endl;
nProcPatches++;
nProcFaces += ppp.size();
}
else
{
nBoundaryFaces += procMesh.boundaryMesh()[patchi].size();
nProcPatches++;
nProcFaces += ppp.size();
}
else
{
nBoundaryFaces += procMesh.boundaryMesh()[patchi].size();
}
}
Info<< " Number of processor patches = " << nProcPatches << nl
<< " Number of processor faces = " << nProcFaces << nl
<< " Number of boundary faces = " << nBoundaryFaces << endl;
totProcFaces += nProcFaces;
maxProcPatches = max(maxProcPatches, nProcPatches);
maxProcFaces = max(maxProcFaces, nProcFaces);
// create and write the addressing information
labelIOList pointProcAddressing
(
IOobject
(
"pointProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procPointAddressing_[procI]
);
pointProcAddressing.write();
labelIOList faceProcAddressing
(
IOobject
(
"faceProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFaceAddressing_[procI]
);
faceProcAddressing.write();
labelIOList cellProcAddressing
(
IOobject
(
"cellProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procCellAddressing_[procI]
);
cellProcAddressing.write();
labelIOList boundaryProcAddressing
(
IOobject
(
"boundaryProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procBoundaryAddressing_[procI]
);
boundaryProcAddressing.write();
// Create and write cellLevel and pointLevel information
const unallocLabelList& cellMap = cellProcAddressing;
labelIOField procCellLevel
(
IOobject
(
"cellLevel",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
labelField(globalCellLevel, cellMap)
);
procCellLevel.write();
const unallocLabelList& pointMap = pointProcAddressing;
labelIOField procPointLevel
(
IOobject
(
"pointLevel",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
labelField(globalPointLevel, pointMap)
);
procPointLevel.write();
}
Info<< " Number of processor patches = " << nProcPatches << nl
<< " Number of processor faces = " << nProcFaces << nl
<< " Number of boundary faces = " << nBoundaryFaces << endl;
totProcFaces += nProcFaces;
maxProcPatches = max(maxProcPatches, nProcPatches);
maxProcFaces = max(maxProcFaces, nProcFaces);
// create and write the addressing information
labelIOList pointProcAddressing
(
IOobject
(
"pointProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procPointAddressing_[procI]
);
pointProcAddressing.write();
labelIOList faceProcAddressing
(
IOobject
(
"faceProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procFaceAddressing_[procI]
);
faceProcAddressing.write();
labelIOList cellProcAddressing
(
IOobject
(
"cellProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procCellAddressing_[procI]
);
cellProcAddressing.write();
labelIOList boundaryProcAddressing
(
IOobject
(
"boundaryProcAddressing",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
procBoundaryAddressing_[procI]
);
boundaryProcAddressing.write();
// Create and write cellLevel and pointLevel information
const unallocLabelList& cellMap = cellProcAddressing;
labelIOField procCellLevel
(
IOobject
(
"cellLevel",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
labelField(globalCellLevel, cellMap)
);
procCellLevel.write();
const unallocLabelList& pointMap = pointProcAddressing;
labelIOField procPointLevel
(
IOobject
(
"pointLevel",
procMesh.facesInstance(),
procMesh.meshSubDir,
procMesh,
IOobject::NO_READ,
IOobject::NO_WRITE
),
labelField(globalPointLevel, pointMap)
);
procPointLevel.write();
}
Info<< nl
<< "Number of processor faces = " << totProcFaces/2 << nl
<< "Max number of processor patches = " << maxProcPatches << nl
<< "Max number of faces between processors = " << maxProcFaces
<< endl;
}
return true;
}

View file

@ -45,6 +45,8 @@ SourceFiles
#include "globalProcFaceIndex.H"
#include "globalProcPointIndex.H"
#include "sliceMeshHelper.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -113,6 +115,12 @@ class domainDecomposition
//- Original patch index for every processor patch
labelListList procBoundaryAddressing_;
//- Labels of cells for coherent mesh format
labelList coherentCellAddressing_;
//- Labels of faces for coherent mesh format
labelList coherentFaceAddressing_;
//- Sizes for processor mesh patches
// Excludes inter-processor boundaries
labelListList procPatchSize_;
@ -217,6 +225,12 @@ public:
// Decomposed mesh and addressing
autoPtr<fvMesh> parallelMesh
(
const Time& procDb,
const word& regionName
);
//- Create a decomposed mesh for a given processor index
// Note: at the point of construction, the boundary is marked
// as invalid. If the mesh should be used immediately upon
@ -257,6 +271,26 @@ public:
return procBoundaryAddressing_;
}
//- Return coherent cell addressing
const labelList& coherentCellAddressing() const
{
return coherentCellAddressing_;
}
//- Return coherent cell addressing
const labelList& coherentFaceAddressing() const
{
return coherentFaceAddressing_;
}
//- Return coherent boundary addressing
labelList blankAddressing( label size ) const
{
Foam::labelList iota{};
indexIota( iota, size, 0 );
return iota;
}
//- Write decomposition
bool writeDecomposition();

View file

@ -48,6 +48,14 @@ defineTemplateTypeNameAndDebug(surfaceSymmTensor4thOrderField, 0);
defineTemplateTypeNameAndDebug(surfaceDiagTensorField, 0);
defineTemplateTypeNameAndDebug(surfaceTensorField, 0);
template<>
label IFCstream::coherentFieldSize<fvsPatchField, surfaceMesh>()
{
return coherentMesh_.internalSurfaceFieldOffsets().size();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View file

@ -45,6 +45,67 @@ SourceFiles
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<>
label IFCstream::coherentFieldSize<fvsPatchField, surfaceMesh>();
template<class Type>
class IFCstream::reader<Type, fvsPatchField, surfaceMesh>
{
public:
static void read(IFCstream&);
};
template<class Type>
class OFCstream<Type, fvsPatchField, surfaceMesh>
:
public OFCstreamBase
{
// Private data
//- Internal field of the coherent format with processor patch fields
// mapped into it
List<Type> consolidatedData_;
// Private member functions
void combineCoherentInternal();
public:
//- Constructor
OFCstream
(
const fileName& pathname,
const objectRegistry& registry,
ios_base::openmode mode = ios_base::out|ios_base::trunc,
IOstreamOption streamOpt = IOstreamOption()
);
//- Destructor
virtual ~OFCstream();
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "surfaceFieldsI.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View file

@ -68,6 +68,25 @@ void GeometricField<scalar, fvPatchField, volMesh>::replace
*this == gsf;
}
template<>
void IFCstream::addProcessorPatchField<fvPatchField, volMesh>
(
dictionary& bfDict,
const word& patchName,
const word& fieldTypeName
)
{
dictionary dict;
dict.add("type", "processor");
bfDict.add(patchName, dict);
}
template<>
label IFCstream::coherentFieldSize<fvPatchField, volMesh>()
{
return coherentMesh_.mesh().nCells();
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace Foam

View file

@ -42,6 +42,7 @@ SourceFiles
#include "volFieldsFwd.H"
#include "calculatedFvPatchFields.H"
#include "fvMatrices.H"
#include "IFCstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -64,6 +65,16 @@ void GeometricField<scalar, fvPatchField, volMesh>::replace
const GeometricField<scalar, fvPatchField, volMesh>& sf
);
template<>
void IFCstream::addProcessorPatchField<fvPatchField, volMesh>
(
dictionary& bfDict,
const word& patchName,
const word& fieldTypeName
);
template<>
label IFCstream::coherentFieldSize<fvPatchField, volMesh>();
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -1,6 +1,7 @@
global/global.Cver
global/dimensionedConstants/dimensionedConstants.C
global/argList/argList.C
global/argList/parRun.C
global/clock/clock.C
global/controlSwitches/debugSwitch.C
@ -99,6 +100,9 @@ coordinateSystems/coordinateRotation/axisCoordinateRotation.C
primitives/random/Random.C
containers/Lists/UList/DebugIOUList.C
containers/Lists/List/DebugIOList.C
containers/HashTables/HashTable/HashTableCore.C
containers/HashTables/StaticHashTable/StaticHashTableCore.C
containers/Lists/ListOps/ListOps.C
@ -126,6 +130,7 @@ $(Streams)/token/tokenIO.C
IOstreams = $(Streams)/IOstreams
$(IOstreams)/IOstream.C
$(IOstreams)/IOstreamOption.C
$(IOstreams)/Istream.C
$(IOstreams)/Ostream.C
@ -609,11 +614,16 @@ $(meshTools)/meshTools.C
$(meshTools)/matchPoints.C
$(meshTools)/mergePoints.C
fields/DimensionedFields/DimensionedField/DebugIODimensionedField.C
fields/UniformDimensionedFields/uniformDimensionedFields.C
fields/cloud/cloud.C
fields/cloudDistribute/cloudDistribute.C
Fields = fields/Fields
$(Fields)/Field/DebugIOField.C
$(Fields)/labelField/labelField.C
$(Fields)/scalarField/scalarField.C
$(Fields)/vectorField/vectorField.C

View file

@ -73,7 +73,7 @@ Foam::Ostream& Foam::FaceCellWave<Type>::writeFaces
os << ' ' << faceInfo[i];
}
}
else
else if (os.format() == IOstream::BINARY)
{
os << nFaces;
@ -86,6 +86,9 @@ Foam::Ostream& Foam::FaceCellWave<Type>::writeFaces
os << faceInfo[i];
}
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in FaceCellWave.C\n"; }
return os;
}

View file

@ -204,7 +204,7 @@ public:
os << pHit.hit_ << token::SPACE << pHit.hitPoint_
<< token::SPACE << pHit.index_;
}
else
else if (os.format() == IOstream::BINARY)
{
os.write
(
@ -212,6 +212,8 @@ public:
sizeof(PointIndexHit)
);
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in PointIndexHitTemplate.H"; }
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const PointIndexHit&)");
@ -225,7 +227,7 @@ public:
{
return is >> pHit.hit_ >> pHit.hitPoint_ >> pHit.index_;
}
else
else if (is.format() == IOstream::BINARY)
{
is.read
(
@ -233,6 +235,8 @@ public:
sizeof(PointIndexHit)
);
}
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in PointIndexHitTemplate.H"; }
// Check state of Istream
is.check("Istream& operator>>(Istream&, PointIndexHit&)");

View file

@ -116,7 +116,7 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L)
// Read end of contents
is.readEndList("FixedList");
}
else
else if (is.format() == IOstream::BINARY)
{
is.read(reinterpret_cast<char*>(L.data()), Size*sizeof(T));
@ -126,6 +126,8 @@ Foam::Istream& Foam::operator>>(Foam::Istream& is, FixedList<T, Size>& L)
"reading the binary block"
);
}
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in FixedListIO.C\n"; }
return is;
}
@ -228,10 +230,12 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const FixedList<T, Size>& L)
os << nl << token::END_LIST << nl;
}
}
else
else if (os.format() == IOstream::BINARY)
{
os.write(reinterpret_cast<const char*>(L.cdata()), Size*sizeof(T));
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in FixedListIO.C\n"; }
// Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const FixedList&)");

View file

@ -257,6 +257,12 @@ Foam::List<T>::List(const BiIndirectList<T>& lst)
allocCopyList(lst);
}
// Construct from std::initializer_list
template<class T>
Foam::List<T>::List(std::initializer_list<T>&& lst)
:
List<T>(lst.begin(), lst.end())
{}
// * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //

View file

@ -44,11 +44,17 @@ SourceFiles
#include "autoPtr.H"
#include "Xfer.H"
#include "className.H"
#include <initializer_list>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
TemplateName(DebugIOList);
class Istream;
class Ostream;
@ -170,6 +176,9 @@ public:
//- Construct from Istream.
List(Istream&);
//- Construct from std::initializer_list.
List(std::initializer_list<T>&& lst);
//- Clone
inline autoPtr<List<T> > clone() const;

View file

@ -126,7 +126,7 @@ inline void Foam::List<T>::clear()
if (this->v_)
{
delete[] this->v_;
this->v_ = 0;
this->v_ = nullptr;
}
this->size_ = 0;

View file

@ -28,14 +28,27 @@ License
#include "token.H"
#include "SLList.H"
#include "contiguous.H"
#include <iostream>
#include "Ostream.H"
#include "prefixOSstream.H"
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
namespace Foam {
extern prefixOSstream Pout;
}
template<class T>
Foam::List<T>::List(Istream& is)
:
UList<T>(nullptr, 0)
{
if (List<T>::debug)
{
Pout<< "List<T>::List(Istream& is)" << endl;
}
operator>>(is, *this);
}
@ -43,6 +56,11 @@ Foam::List<T>::List(Istream& is)
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
{
if (List<T>::debug)
{
Pout<< "ListIO: operator>>, start" << endl;
}
// Anull list
list.resize(0);
@ -55,6 +73,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
// Compound: simply transfer contents
if (firstToken.isCompound())
{
if (List<T>::debug)
{
Pout<< "ListIO: operator>>, transfering compound token" << endl;
}
list.transfer
(
dynamicCast<token::Compound<List<T> > >
@ -72,55 +95,89 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
{
const label len = firstToken.labelToken();
// Resize to length read
list.resize(len);
if (List<T>::debug)
{
Pout<< "ListIO: operator>>, reading a list of size " << len << endl;
}
if (is.format() != IOstream::COHERENT)
{
// Resize to length read
list.resize(len);
}
// Read list contents depending on data format
if (is.format() == IOstream::ASCII || !contiguous<T>())
{
// Read beginning of contents
const char delimiter = is.readBeginList("List");
if (len)
if (is.format() == IOstream::COHERENT)
{
if (delimiter == token::BEGIN_LIST)
// Read the id of list contents
string id;
is >> id;
// TODO: Re-enable reading non-contiguous data.
//Istream& iss = is.readToStringStream(id);
//for (label i=0; i<len; ++i)
//{
//iss >> list[i];
//iss.fatalCheck
//(
//"operator>>(Istream&, List<T>&) : "
//"reading entry"
//);
//}
if (List<T>::debug > 1)
{
for (label i=0; i<len; ++i)
Pout<< "List read via COHERENT = " << nl << list << endl;
}
}
else
{
// Read beginning of contents
const char delimiter = is.readBeginList("List");
if (len)
{
if (delimiter == token::BEGIN_LIST)
{
is >> list[i];
for (label i=0; i<len; ++i)
{
is >> list[i];
is.fatalCheck
(
"operator>>(Istream&, List<T>&) : "
"reading entry"
);
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T element;
is >> element;
is.fatalCheck
(
"operator>>(Istream&, List<T>&) : "
"reading entry"
"reading the single entry"
);
for (label i=0; i<len; ++i)
{
list[i] = element; // Copy the value
}
}
}
else
{
// Uniform content (delimiter == token::BEGIN_BLOCK)
T element;
is >> element;
is.fatalCheck
(
"operator>>(Istream&, List<T>&) : "
"reading the single entry"
);
for (label i=0; i<len; ++i)
{
list[i] = element; // Copy the value
}
}
// Read end of contents
is.readEndList("List");
}
// Read end of contents
is.readEndList("List");
}
else if (len)
else if (len && is.format() == IOstream::BINARY)
{
// Non-empty, binary, contiguous
@ -132,6 +189,22 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
"reading the binary block"
);
}
else if (len && is.format() == IOstream::COHERENT)
{
string id;
is >> id;
if (List<T>::debug)
{
Pout<< "Reading via COHERENT id = " << id << endl;
}
if (UList<T>::debug > 1)
{
Pout<< "List read via COHERENT = " << nl << list << endl;
}
}
return is;
}

View file

@ -320,7 +320,7 @@ Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
// Read end of contents
is.readEndList("PackedList<nBits>");
}
else
else if (is.format() == IOstream::BINARY)
{
if (sz)
{
@ -337,6 +337,8 @@ Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
);
}
}
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in PackedList.C\n"; }
}
else if (firstTok.isPunctuation())
{
@ -485,7 +487,7 @@ Foam::Ostream& Foam::PackedList<nBits>::write
os << nl << token::END_LIST << nl;
}
}
else
else if (os.format() == IOstream::BINARY)
{
os << nl << sz << nl;
if (sz)
@ -497,6 +499,8 @@ Foam::Ostream& Foam::PackedList<nBits>::write
);
}
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in PackedList.C\n"; }
return os;
}

View file

@ -97,7 +97,7 @@ Foam::Ostream& Foam::operator<<
os << nl << token::END_LIST << nl;
}
}
else
else if (os.format() == IOstream::BINARY)
{
// this is annoying, and wasteful, but there's currently no alternative
@ -114,6 +114,8 @@ Foam::Ostream& Foam::operator<<
);
}
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in UIndirectedListIO.C\n"; }
// Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const UIndirectList&)");

View file

@ -47,11 +47,15 @@ SourceFiles
#include "uLabel.H"
#include "nullObject.H"
#include "className.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
TemplateName(DebugIOUList);
// Forward declaration of friend classes
template<class T> class List;
template<class T> class SubList;
@ -69,6 +73,8 @@ typedef UList<label> labelUList;
template<class T>
class UList
:
public DebugIOUListName
{
// Private data
@ -159,7 +165,6 @@ public:
// i.e. contiguous<T>() == true
label byteSize() const;
//- Return a const pointer to the first data element,
// similar to the STL front() method and the string::data() method
// This can be used (with caution) when interfacing with C code.
@ -372,6 +377,8 @@ inline void reverse(UList<T>&, const label n);
template<class T>
inline void reverse(UList<T>&);
template<class T>
void swap( UList<T>& a, UList<T>& b );
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -342,6 +342,7 @@ inline void Foam::reverse(UList<T>& ul, const label n)
}
}
template<class T>
inline void Foam::reverse(UList<T>& ul)
{
@ -349,4 +350,10 @@ inline void Foam::reverse(UList<T>& ul)
}
template<class T>
void Foam::swap( UList<T>& a, UList<T>& b )
{
a.swap(b);
}
// ************************************************************************* //

View file

@ -28,12 +28,25 @@ License
#include "token.H"
#include "SLList.H"
#include "contiguous.H"
#include <iostream>
#include "prefixOSstream.H"
#include "UListProxy.H"
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
namespace Foam {
extern prefixOSstream Pout;
}
template<class T>
void Foam::UList<T>::writeEntry(Ostream& os) const
{
if (debug)
{
Pout<< "UList<T>::writeEntry(Ostream&): List< ... >" << endl;
}
if
(
size()
@ -53,6 +66,11 @@ void Foam::UList<T>::writeEntry(Ostream& os) const
template<class T>
void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const
{
if (debug)
{
Pout<< "UListIO::writeEntry keyword = " << keyword << endl;
}
os.writeKeyword(keyword);
writeEntry(os);
os << token::END_STATEMENT << endl;
@ -62,9 +80,29 @@ void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const
template<class T>
Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
{
// Do not print this debug info if a UList is printed to the screen
// by testing whether the stream is prefixOSstream (e.g. Pout)
if (UList<T>::debug && !isA<class prefixOSstream>(os))
{
Pout<< "UListIO: operator<<(); id = " << os.getBlockId() << endl;
}
// Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>())
{
if (UList<T>::debug && !isA<class prefixOSstream>(os))
{
Pout<< "UListIO: writing ASCII because";
if (!contiguous<T>())
{
Pout<< " the template parameter T is non-contiguous" << endl;
}
else
{
Pout<< " streamFormat is ASCII" << endl;
}
}
bool uniform = false;
if (L.size() > 1 && contiguous<T>())
@ -107,6 +145,25 @@ Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
// Write end delimiter
os << token::END_LIST;
}
else if (os.format() == IOstream::COHERENT) // is also non-contiguous
{
if (UList<T>::debug && !isA<class prefixOSstream>(os))
{
Pout<< "UListIO: writing non-contiguous data as string via"
<< " COHERENT" << endl;
}
// Write size and identifier
os << nl << L.size() << os.getBlockId() << nl;
// Write contents to a stringStream which is written by ADIOS
// at destruction of os
Ostream& oss = os.stringStream();
forAll(L, i)
{
oss << nl << L[i];
}
}
else
{
// Write size and start delimiter
@ -122,7 +179,7 @@ Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
os << nl << token::END_LIST << nl;
}
}
else
else if (os.format() == IOstream::BINARY)
{
os << nl << L.size() << nl;
if (L.size())
@ -130,6 +187,21 @@ Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
os.write(reinterpret_cast<const char*>(L.v_), L.byteSize());
}
}
else if (os.format() == IOstream::COHERENT)
{
if(UList<T>::debug)
{
const string id = os.getBlockId();
Pout<< "Writing a field of size " << L.byteSize()
<< " via COHERENT IO with identifier:\n "
<< id << endl;
Pout<< "L = " << L << endl;
}
std::unique_ptr<UListProxy<T>> proxy(new UListProxy<T>(L));
os.parwrite(std::move(proxy));
//assert(proxy == nullptr);
}
// Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const UList&)");
@ -141,6 +213,12 @@ Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L)
template<class T>
Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
{
if (UList<T>::debug)
{
Pout<< "UListIO: in operator>>(Istream& is, UList<T>& L), id = "
<< endl;
}
is.fatalCheck("operator>>(Istream&, UList<T>&)");
token firstToken(is);
@ -189,6 +267,12 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
if (is.format() == IOstream::ASCII || !contiguous<T>())
{
if(UList<T>::debug)
{
Pout<< "Writing a field as ASCII of size "
<< L.byteSize() << endl;
}
// Read beginning of contents
char delimiter = is.readBeginList("List");
@ -227,7 +311,7 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
// Read end of contents
is.readEndList("List");
}
else
else if (is.format() == IOstream::BINARY)
{
if (s)
{
@ -239,6 +323,8 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
);
}
}
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in UListIO.C\n"; }
}
else if (firstToken.isPunctuation())
{

View file

@ -26,6 +26,7 @@ License
#include "IOobject.H"
#include "foamTime.H"
#include "IFstream.H"
#include "Pstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -445,6 +446,29 @@ Foam::Istream* Foam::IOobject::objectStream(const fileName& fName)
}
Foam::Istream* Foam::IOobject::objectStreamPar(const fileName& fName)
{
if (fName.size())
{
IFstream* isPtr = new IFstream(fName, IOstream::COHERENT);
if (isPtr->good())
{
return isPtr;
}
else
{
delete isPtr;
return nullptr;
}
}
else
{
return nullptr;
}
}
bool Foam::IOobject::headerOk()
{
bool ok = true;
@ -486,6 +510,30 @@ bool Foam::IOobject::headerOk()
}
bool Foam::IOobject::headerOkPar()
{
const word writeFormat(time().controlDict().lookup("writeFormat"));
const bool isCoherentFormat =
(IOstream::formatEnum(writeFormat) == IOstream::COHERENT);
if (isCoherentFormat)
{
bool ok;
if (Pstream::master())
{
ok = headerOk();
}
Pstream::scatter(ok);
return ok;
}
else
{
return headerOk();
}
}
void Foam::IOobject::setBad(const string& s)
{
if (objState_ != GOOD)

View file

@ -173,6 +173,10 @@ protected:
// exact file. The results is nullptr if the stream construction failed
Istream* objectStream(const fileName&);
//- Construct and return an IFsteam with initialized ADIOS instance
// and the underlying stream being std::istringstream
virtual Istream* objectStreamPar(const fileName&);
//- Set the object state to bad
void setBad(const string&);
@ -397,6 +401,7 @@ public:
//- Read and check header info
bool headerOk();
bool headerOkPar();
// Writing

View file

@ -127,7 +127,10 @@ bool Foam::IOobject::readHeader(Istream& is)
if (IOobject::debug)
{
Info<< " .... read" << endl;
Info<< " .... read." << nl
<< " Istream format: " << is.format() << nl
<< " headerClassName: " << headerClassName_
<< endl;
}
return true;

View file

@ -28,6 +28,8 @@ Description
\*---------------------------------------------------------------------------*/
#include "IOobject.H"
#include "IOstreams.H"
#include "messageStream.H"
#include "objectRegistry.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -43,6 +45,14 @@ bool Foam::IOobject::writeHeader(Ostream& os, const word& type) const
return false;
}
DebugIO2
<< " version " << os.version() << ";\n"
<< " format " << os.format() << ";\n"
<< " class " << type << ";\n"
<< " location " << instance()/local() << ";\n"
<< " object " << name() << ";\n"
<< endl;
writeBanner(os, false, true)
<< "FoamFile\n{\n"
<< " version " << os.version() << ";\n"

View file

@ -181,10 +181,15 @@ bool Foam::CompactIOField<T, BaseType>::writeObject
return good;
}
else
else if (fmt == IOstream::BINARY)
{
return regIOobject::writeObject(fmt, ver, cmp);
}
else if (fmt == IOstream::COHERENT)
{
cout << "Parallel IO not yet implemented in CompactIOField.C\n";
return false;
}
}
@ -259,7 +264,7 @@ Foam::Ostream& Foam::operator<<
{
os << static_cast<const Field<T>&>(L);
}
else
else if (os.format() == IOstream::BINARY)
{
// Convert to compact format
labelList start(L.size()+1);
@ -284,6 +289,8 @@ Foam::Ostream& Foam::operator<<
}
os << start << elems;
}
else if (os.format() == IOstream::BINARY)
{ cout << "Parallel IO not yet implemented in CompactIOField.C\n"; }
return os;
}

View file

@ -182,10 +182,15 @@ bool Foam::CompactIOList<T, BaseType>::writeObject
return good;
}
else
else if (fmt == IOstream::BINARY)
{
return regIOobject::writeObject(fmt, ver, cmp);
}
else if (fmt == IOstream::COHERENT)
{
cout << "Parallel IO not yet implemented in CompactIOList.C\n";
return false;
}
}
@ -260,7 +265,7 @@ Foam::Ostream& Foam::operator<<
{
os << static_cast<const List<T>&>(L);
}
else
else if (os.format() == IOstream::BINARY)
{
// Convert to compact format
labelList start(L.size()+1);
@ -285,6 +290,8 @@ Foam::Ostream& Foam::operator<<
}
os << start << elems;
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in CompactIOList.C\n"; }
return os;
}

View file

@ -52,11 +52,11 @@ Foam::IOField<Type>::IOField(const IOobject& io)
io.readOpt() == IOobject::MUST_READ
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
)
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
|| (io.readOpt() == IOobject::READ_IF_PRESENT_IF_MODIFIED && headerOk())
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOkPar())
|| (io.readOpt() == IOobject::READ_IF_PRESENT_IF_MODIFIED && headerOkPar())
)
{
readStream(typeName) >> *this;
readStreamPar(typeName) >> *this;
close();
}
}

View file

@ -51,11 +51,11 @@ Foam::IOList<T>::IOList(const IOobject& io)
io.readOpt() == IOobject::MUST_READ
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
)
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk())
|| (io.readOpt() == IOobject::READ_IF_PRESENT_IF_MODIFIED && headerOk())
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOkPar())
|| (io.readOpt() == IOobject::READ_IF_PRESENT_IF_MODIFIED && headerOkPar())
)
{
readStream(typeName) >> *this;
readStreamPar(typeName) >> *this;
close();
}
}

View file

@ -24,8 +24,32 @@ License
\*---------------------------------------------------------------------------*/
#include "IFstream.H"
#include "IOstream.H"
#include "OSspecific.H"
#include "debug.H"
#include "gzstream.h"
#include "SliceStream.H"
#include "IStringStream.H"
#include <fstream>
bool readLocalString( std::string& buf,
const Foam::string strName ) {
//TODO : Parallel implementation. Only master reading and distributing.
std::ifstream inFile;
inFile.open( "fields/" + strName );
bool found = inFile.good();
if ( found ) {
inFile.seekg(0, std::ios::end);
size_t size = inFile.tellg();
buf.resize( size );
inFile.seekg(0);
inFile.read( &buf[0], size );
inFile.close();
}
return found;
}
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -34,9 +58,15 @@ defineTypeNameAndDebug(Foam::IFstream, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::IFstreamAllocator::IFstreamAllocator(const fileName& pathname)
Foam::IFstreamAllocator::IFstreamAllocator
(
const fileName& pathname,
IOstream::streamFormat format
)
:
ifPtr_(nullptr),
bufStr_(),
sliceStreamPtr_(nullptr),
compression_(IOstream::UNCOMPRESSED)
{
if (pathname.empty())
@ -48,7 +78,34 @@ Foam::IFstreamAllocator::IFstreamAllocator(const fileName& pathname)
}
}
ifPtr_ = new ifstream(pathname.c_str());
if (format == IOstream::COHERENT)
{
ifPtr_ = new std::istringstream();
if ( !sliceStreamPtr_ )
{
allocateAdios();
}
// Get state from ADIOS
const bool dataFound =
readLocalString(bufStr_, pathname.name()); //pathname.caseName(""));
if (!dataFound)
{
// Invalidate stream if the variable is not found
ifPtr_->setstate(std::ios::failbit);
}
else
{
// Assign the buffer of string bufStr_ to the buffer of the stream
ifPtr_->rdbuf()->pubsetbuf(&bufStr_[0], bufStr_.size());
}
}
else
{
ifPtr_ = new ifstream(pathname.c_str());
}
// If the file is compressed, decompress it before reading.
if (!ifPtr_->good() && isFile(pathname + ".gz", false))
@ -68,6 +125,7 @@ Foam::IFstreamAllocator::IFstreamAllocator(const fileName& pathname)
compression_ = IOstream::COMPRESSED;
}
}
}
@ -77,6 +135,12 @@ Foam::IFstreamAllocator::~IFstreamAllocator()
}
void Foam::IFstreamAllocator::allocateAdios()
{
sliceStreamPtr_ = SliceReading{}.createStream();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::IFstream::IFstream
@ -86,7 +150,7 @@ Foam::IFstream::IFstream
versionNumber version
)
:
IFstreamAllocator(pathname),
IFstreamAllocator(pathname, format),
ISstream
(
*ifPtr_,
@ -95,7 +159,8 @@ Foam::IFstream::IFstream
version,
IFstreamAllocator::compression_
),
pathname_(pathname)
pathname_(pathname),
tmpIssPtr_(nullptr)
{
setClosed();
@ -123,10 +188,15 @@ Foam::IFstream::IFstream
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
Foam::IFstream::~IFstream()
{}
{
if (tmpIssPtr_)
{
delete tmpIssPtr_;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -142,6 +212,25 @@ std::istream& Foam::IFstream::stdStream()
}
// read binary block from second stream
Foam::Istream& Foam::IFstream::parread(parIOType* buf, const string& blockId)
{
if (format() != COHERENT)
{
FatalIOErrorIn("ISstream::parread(parIOType*, std::streamsize)", *this)
<< "stream format not parallel"
<< exit(FatalIOError);
}
if ( !sliceStreamPtr_ )
{
allocateAdios();
}
return *this;
}
const std::istream& Foam::IFstream::stdStream() const
{
if (!ifPtr_)
@ -161,6 +250,18 @@ void Foam::IFstream::print(Ostream& os) const
}
Foam::Istream& Foam::IFstream::readToStringStream(string& id)
{
if (tmpIssPtr_)
{
}
readLocalString(tmpIssBuf_, id);
tmpIssPtr_ = new IStringStream(tmpIssBuf_);
return *tmpIssPtr_;
}
// * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
Foam::IFstream& Foam::IFstream::operator()() const

View file

@ -40,6 +40,7 @@ SourceFiles
#include "className.H"
#include <fstream>
#include <memory>
using std::ifstream;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -48,6 +49,7 @@ namespace Foam
{
class IFstream;
class SliceStream;
/*---------------------------------------------------------------------------*\
Class IFstreamAllocator Declaration
@ -61,17 +63,32 @@ class IFstreamAllocator
// Private data
istream* ifPtr_;
//- String serves as buffer for ADIOS variable in case the format is
// COHERENT. It is then assigned to isrteam buffer.
std::string bufStr_;
std::unique_ptr<SliceStream> sliceStreamPtr_;
IOstream::compressionType compression_;
// Constructors
//- Construct from pathname
IFstreamAllocator(const fileName& pathname);
IFstreamAllocator
(
const fileName& pathname,
const IOstream::streamFormat format
);
//- Destructor
~IFstreamAllocator();
// Member functions
//- Allocate ADIOS object if not already present
void allocateAdios();
};
@ -87,6 +104,8 @@ class IFstream
// Private data
fileName pathname_;
Istream* tmpIssPtr_;
string tmpIssBuf_;
public:
@ -126,6 +145,11 @@ public:
}
// Read functions
//- Read binary block from second stream
virtual Istream& parread(parIOType*, const string&);
// STL stream
//- Access to underlying std::istream
@ -140,6 +164,7 @@ public:
//- Print description of IOstream to Ostream
virtual void print(Ostream&) const;
virtual Istream& readToStringStream(string&);
// Member operators

View file

@ -25,7 +25,16 @@ License
#include "OFstream.H"
#include "OSspecific.H"
#include "OStringStream.H"
#include "UList.H"
#include "Pstream.H"
#include "gzstream.h"
#include "messageStream.H"
#include <iostream>
#include <memory>
#include "SliceStreamRepo.H"
#include "sliceWritePrimitives.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -38,6 +47,7 @@ Foam::OFstreamAllocator::OFstreamAllocator
(
const fileName& pathname,
ios_base::openmode mode,
IOstream::streamFormat format,
IOstream::compressionType compression
)
:
@ -52,25 +62,34 @@ Foam::OFstreamAllocator::OFstreamAllocator
}
}
if (compression == IOstream::COMPRESSED)
if (format == IOstream::COHERENT)
{
// get identically named uncompressed version out of the way
if (isFile(pathname, false))
{
rm(pathname);
}
ofPtr_ = new ogzstream((pathname + ".gz").c_str(), mode);
// The file pointer is a buffer pointer in this case.
// The buffer is written to ADIOS in the destructor.
ofPtr_ = new std::ostringstream();
}
else
{
// get identically named compressed version out of the way
if (isFile(pathname + ".gz", false))
if (compression == IOstream::COMPRESSED)
{
rm(pathname + ".gz");
}
// get identically named uncompressed version out of the way
if (isFile(pathname, false))
{
rm(pathname);
}
ofPtr_ = new ofstream(pathname.c_str(), mode);
ofPtr_ = new ogzstream((pathname + ".gz").c_str(), mode);
}
else
{
// get identically named compressed version out of the way
if (isFile(pathname + ".gz", false))
{
rm(pathname + ".gz");
}
ofPtr_ = new ofstream(pathname.c_str(), mode);
}
}
}
@ -87,15 +106,27 @@ Foam::OFstream::OFstream
(
const fileName& pathname,
ios_base::openmode mode,
streamFormat format,
versionNumber version,
compressionType compression
IOstreamOption streamOpt
)
:
OFstreamAllocator(pathname, mode, compression),
OSstream(*ofPtr_, "OFstream.sinkFile_", format, version, compression),
pathname_(pathname)
OFstreamAllocator
(
pathname,
mode,
streamOpt.format(),
streamOpt.compression()
),
OSstream(*ofPtr_, "OFstream.sinkFile_", streamOpt),
pathname_(pathname),
blockNamesStack_(),
tmpOssPtr_(nullptr)
{
if (debug)
{
InfoInFunction
<< "Constructing a stream with format " << streamOpt.format()
<< Foam::endl;
}
setClosed();
setState(ofPtr_->rdstate());
@ -122,13 +153,63 @@ Foam::OFstream::OFstream
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
Foam::OFstream::~OFstream()
{}
{
if (isA<std::ostringstream>(*ofPtr_) && format() == IOstream::COHERENT)
{
std::ostringstream& os = dynamic_cast<std::ostringstream&>(*ofPtr_);
if (!os.str().empty())
{
writeLocalString( getRelativeFileName(),
os.str().data(),
os.str().size() );
}
}
if (tmpOssPtr_)
{
writeLocalString( getBlockId(),
tmpOssPtr_->str().data(),
tmpOssPtr_->str().size() );
delete tmpOssPtr_;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
Foam::string Foam::OFstream::getBlockId() const
{
fileName id;
bool firstEntry = true;
forAllConstIter(SLList<word>, blockNamesStack_, iter)
{
if (firstEntry)
{
id = iter();
firstEntry = false;
}
else
{
id = iter() + '/' + id;
}
}
id = getRelativeFileName() + '/' + id;
if(debug > 1)
{
Pout
<< "Block id = " << id << "; blockNamesStack_.size() = "
<< blockNamesStack_.size() << '\n';
}
return id;
}
std::ostream& Foam::OFstream::stdStream()
{
if (!ofPtr_)
@ -158,4 +239,164 @@ void Foam::OFstream::print(Ostream& os) const
}
Foam::word Foam::OFstream::incrBlock(const word name)
{
blockNamesStack_.push(name);
if(debug > 1)
{
Pout
<< "Add word to the block name LIFO stack: " << name << '\n';
}
OSstream::indent();
OSstream::write(name);
OSstream::write(nl);
OSstream::indent();
OSstream::write(char(token::BEGIN_BLOCK));
OSstream::write(nl);
OSstream::incrIndent();
return name;
}
void Foam::OFstream::decrBlock()
{
if (debug > 1)
{
Info<< "OFsteam::decrBlock" << '\n';
}
popBlockNamesStack();
OSstream::decrIndent();
OSstream::indent();
OSstream::write(char(token::END_BLOCK));
}
Foam::Ostream& Foam::OFstream::writeKeyword(const keyType& kw)
{
if (debug > 1)
{
Pout
<< "Add keyType to the block name LIFO stack: " << kw << "\n";
}
blockNamesStack_.push(kw);
// Inform SliceStreamRepo that n'th boundary is being written.
if( kw == "type" ) {
++boundaryCounter_;
Foam::SliceStreamRepo* repo = Foam::SliceStreamRepo::instance();
repo->push( boundaryCounter_ );
}
return this->Ostream::writeKeyword(kw);
}
void Foam::OFstream::popBlockNamesStack()
{
if (blockNamesStack_.empty())
{
WarningInFunction
<< "Tried to pop the stack although its empty.\n";
}
else
{
if(debug > 1)
{
Pout
<< "Pop block name LIFO stack: "
<< blockNamesStack_.first() << '\n';
}
blockNamesStack_.pop();
}
}
Foam::Ostream& Foam::OFstream::write
(
const char* data,
std::streamsize byteSize
)
{
if (format() == COHERENT)
{
sliceWritePrimitives
(
"fields",
"",
this->getBlockId(),
byteSize/sizeof(scalar),
reinterpret_cast<const scalar*>(data)
);
}
else
{
OSstream::write(data, byteSize);
}
return *this;
}
Foam::Ostream& Foam::OFstream::parwrite(std::unique_ptr<uListProxyBase> uListProxyPtr)
{
if (format() != COHERENT)
{
FatalIOErrorIn("Ostream::parwrite(const parIOType*, const label)", *this)
<< "stream format not parallel"
<< abort(FatalIOError);
}
string blockId = getBlockId();
return *this;
}
Foam::Ostream& Foam::OFstream::stringStream()
{
if (format() != COHERENT)
{
FatalIOErrorIn("Ostream::stringStream()", *this)
<< " stream format not parallel"
<< abort(FatalIOError);
}
if (tmpOssPtr_)
{
FatalIOErrorIn("Ostream::stringStream()", *this)
<< " a string stream object already exists"
<< abort(FatalIOError);
}
tmpOssPtr_ = new OStringStream();
return *tmpOssPtr_;
}
void Foam::OFstream::writeLocalString
(
const Foam::fileName& varName,
const Foam::string& str,
const Foam::label size
)
{
if (Foam::Pstream::master())
{
std::ofstream outFile;
outFile.open
(
varName, ios_base::out|ios_base::trunc
);
outFile << str;
outFile.close();
}
}
// ************************************************************************* //

View file

@ -42,6 +42,10 @@ SourceFiles
#include <fstream>
using std::ofstream;
template<class T> class SLList;
#include "LIFOStack.H"
#include "uListProxyBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -67,8 +71,8 @@ class OFstreamAllocator
(
const fileName& pathname,
ios_base::openmode mode,
IOstream::streamFormat format = IOstream::ASCII,
IOstream::compressionType compression = IOstream::UNCOMPRESSED
);
//- Destructor
@ -89,7 +93,12 @@ class OFstream
// Private data
fileName pathname_;
LIFOStack<word> blockNamesStack_;
//- String stream for temporary data written by ADIOS at destruction
OStringStream* tmpOssPtr_;
label boundaryCounter_{0};
public:
@ -99,20 +108,36 @@ public:
// Constructors
//- Construct from pathname
//- Default construct
OFstream
(
const fileName& pathname,
ios_base::openmode mode = ios_base::out|ios_base::trunc,
IOstreamOption streamOpt = IOstreamOption()
);
//- Construct from pathname
OFstream
(
const fileName& pathname,
ios_base::openmode mode,
streamFormat format = ASCII,
versionNumber version = currentVersion,
compressionType compression = UNCOMPRESSED
);
)
:
OFstream
(
pathname,
mode,
IOstreamOption(format, version, compression)
)
{}
// Destructor
~OFstream();
virtual ~OFstream();
// Member functions
@ -131,6 +156,19 @@ public:
return pathname_;
}
//- Return the file name as a path relative to the root case
inline string getRelativeFileName() const
{
return pathname_.caseName("");
}
//- Get block identifier
virtual string getBlockId() const;
inline ostream& getStreamBuffer()
{
return *ofPtr_;
}
// STL stream
@ -145,6 +183,28 @@ public:
//- Print description of IOstream to Ostream
void print(Ostream&) const;
// Write
//- Incrememt the indent level and add a new block with name
virtual word incrBlock(const word);
//- Decrememt the indent level and close the current block
virtual void decrBlock();
//- Write the keyword followed by an appropriate indentation
virtual Ostream& writeKeyword(const keyType&);
virtual void popBlockNamesStack();
//- Write field with the scalar primitive type
virtual Ostream& write(const char*, std::streamsize);
virtual Ostream& parwrite(std::unique_ptr<uListProxyBase>);
virtual Ostream& stringStream();
void writeLocalString(const fileName&, const string&, const label);
};

View file

@ -34,8 +34,8 @@ namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// Define the default IOstream versions and precision
const IOstream::versionNumber IOstream::originalVersion(0.5);
const IOstream::versionNumber IOstream::currentVersion(2.0);
const IOstream::versionNumber IOstreamOption::originalVersion(0.5);
const IOstream::versionNumber IOstreamOption::currentVersion(2.0);
Foam::debug::infoSwitch
IOstream::precision_

View file

@ -207,6 +207,10 @@ inline Omanip<int> setprecision(const int i)
return Omanip<int>(&Ostream::precision, i);
}
inline Omanip<word> incrBlock(const word name)
{
return Omanip<word>(&Ostream::incrBlock, name);
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -25,7 +25,6 @@ License
#include "IOstream.H"
#include "error.H"
#include "Switch.H"
#include <sstream>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -35,57 +34,6 @@ Foam::fileName Foam::IOstream::name_("IOstream");
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * //
Foam::IOstream::streamFormat
Foam::IOstream::formatEnum(const word& format)
{
if (format == "ascii")
{
return IOstream::ASCII;
}
else if (format == "binary")
{
return IOstream::BINARY;
}
else
{
WarningIn("IOstream::formatEnum(const word&)")
<< "bad format specifier '" << format << "', using 'ascii'"
<< endl;
return IOstream::ASCII;
}
}
Foam::IOstream::compressionType
Foam::IOstream::compressionEnum(const word& compression)
{
// get Switch (bool) value, but allow it to fail
Switch sw(compression, true);
if (sw.valid())
{
return sw ? IOstream::COMPRESSED : IOstream::UNCOMPRESSED;
}
else if (compression == "uncompressed")
{
return IOstream::UNCOMPRESSED;
}
else if (compression == "compressed")
{
return IOstream::COMPRESSED;
}
else
{
WarningIn("IOstream::compressionEnum(const word&)")
<< "bad compression specifier '" << compression
<< "', using 'uncompressed'"
<< endl;
return IOstream::UNCOMPRESSED;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -129,20 +77,8 @@ Foam::string Foam::IOstream::versionNumber::str() const
void Foam::IOstream::print(Ostream& os) const
{
os << "IOstream: " << "Version " << version_ << ", format ";
switch (format_)
{
case ASCII:
os << "ASCII";
break;
case BINARY:
os << "BINARY";
break;
}
os << ", line " << lineNumber();
os << "IOstream: " << "Version " << version() << ", format "
<< format() << ", line " << lineNumber();
if (opened())
{
@ -205,29 +141,6 @@ void Foam::IOstream::print(Ostream& os, const int streamState) const
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * //
Foam::Ostream& Foam::operator<<(Ostream& os, const IOstream::streamFormat& sf)
{
if (sf == IOstream::ASCII)
{
os << "ascii";
}
else
{
os << "binary";
}
return os;
}
Foam::Ostream& Foam::operator<<(Ostream& os, const IOstream::versionNumber& vn)
{
os << vn.str().c_str();
return os;
}
namespace Foam
{

View file

@ -42,14 +42,9 @@ SourceFiles
#ifndef IOstream_H
#define IOstream_H
#include "char.H"
#include "bool.H"
#include "label.H"
#include "uLabel.H"
#include "scalar.H"
#include "fileName.H"
#include "InfoProxy.H"
#include "infoSwitch.H"
#include "IOstreamOption.H"
#include <iostream>
@ -66,6 +61,8 @@ using std::cin;
using std::cout;
using std::cerr;
typedef char parIOType;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -76,6 +73,8 @@ namespace Foam
\*---------------------------------------------------------------------------*/
class IOstream
:
public IOstreamOption
{
public:
@ -83,138 +82,19 @@ public:
// Public data types
//- Enumeration for whether the stream open or closed
enum streamAccess
enum streamAccess : char
{
OPENED,
CLOSED
};
//- Enumeration for the format of data in the stream
enum streamFormat
{
ASCII,
BINARY
};
//- Ostream operator
friend Ostream& operator<<(Ostream& os, const streamFormat& sf);
//- Version number type
class versionNumber
{
//- The version number
scalar versionNumber_;
//- The version number as an integer
int index_;
public:
// Constructors
//- Construct from number
versionNumber(const scalar num)
:
versionNumber_(num),
index_(numberToIndex(num))
{}
//- Construct from Istream
versionNumber(Istream& is)
:
versionNumber_(readScalar(is)),
index_(numberToIndex(versionNumber_))
{}
// Member functions
//- Convert a version number into an index
int numberToIndex(const scalar num) const
{
return int(10*num + SMALL);
}
//- Return major version
int majorVersion() const
{
return int(versionNumber_);
}
//- Return minor version
int minorVersion() const
{
return int(10.0*(versionNumber_ - majorVersion()));
}
//- Return the versionNumber as a character string
string str() const;
// Member operators
//- Are these versionNumbers the same?
bool operator==(const versionNumber& vn)
{
return index_ == vn.index_;
}
//- Are these versionNumbers different?
bool operator!=(const versionNumber& vn)
{
return index_ != vn.index_;
}
//- Is this version older than the one given
bool operator<(const versionNumber& vn)
{
return index_ < vn.index_;
}
//- Is this version the same as or older than the one given
bool operator<=(const versionNumber& vn)
{
return index_ <= vn.index_;
}
//- Is this version newer than the one given
bool operator>(const versionNumber& vn)
{
return index_ > vn.index_;
}
//- this version the same as or newer than the one given
bool operator>=(const versionNumber& vn)
{
return index_ >= vn.index_;
}
//- Ostream operator
friend Ostream& operator<<(Ostream& os, const versionNumber& vn);
};
//- Enumeration for the format of data in the stream
enum compressionType
{
UNCOMPRESSED,
COMPRESSED
};
// Public static data
//- Original version number
static const versionNumber originalVersion;
//- Current version number
static const versionNumber currentVersion;
//- Default precision
static debug::infoSwitch precision_;
private:
// Private data
@ -222,10 +102,6 @@ private:
//- Name of the stream
static fileName name_;
streamFormat format_;
versionNumber version_;
compressionType compression_;
streamAccess openClosed_;
ios_base::iostate ioState_;
@ -270,17 +146,10 @@ public:
// Constructors
//- Construct setting format and version
IOstream
(
streamFormat format,
versionNumber version,
compressionType compression=UNCOMPRESSED
)
//- Default construct
IOstream(IOstreamOption streamOpt = IOstreamOption())
:
format_(format),
version_(version),
compression_(compression),
IOstreamOption(streamOpt),
openClosed_(CLOSED),
ioState_(ios_base::iostate(0)),
lineNumber_(0)
@ -288,6 +157,17 @@ public:
setBad();
}
//- Construct setting format and version
IOstream
(
IOstreamOption::streamFormat fmt,
IOstreamOption::versionNumber ver,
IOstreamOption::compressionType cmp = IOstreamOption::UNCOMPRESSED
)
:
IOstream(IOstreamOption(fmt, ver, cmp))
{}
// Destructor
@ -377,70 +257,6 @@ public:
// Stream state functions
//- Return stream format of given format name
static streamFormat formatEnum(const word&);
//- Return current stream format
streamFormat format() const
{
return format_;
}
//- Set the stream format
streamFormat format(const streamFormat fmt)
{
streamFormat fmt0 = format_;
format_ = fmt;
return fmt0;
}
//- Set the stream format from word
streamFormat format(const word& fmt)
{
streamFormat fmt0 = format_;
format_ = formatEnum(fmt);
return fmt0;
}
//- Return the stream version
versionNumber version() const
{
return version_;
}
//- Set the stream version
versionNumber version(const versionNumber ver)
{
versionNumber ver0 = version_;
version_ = ver;
return ver0;
}
//- Return compression of given compression name
static compressionType compressionEnum(const word&);
//- Return the stream compression
compressionType compression() const
{
return compression_;
}
//- Set the stream compression
compressionType compression(const compressionType cmp)
{
compressionType cmp0 = compression_;
compression_ = cmp;
return cmp0;
}
//- Set the stream compression from word
compressionType compression(const word& cmp)
{
compressionType cmp0 = compression_;
compression_ = compressionEnum(cmp);
return cmp0;
}
//- Return current stream line number
label lineNumber() const
{
@ -542,10 +358,6 @@ public:
};
Ostream& operator<<(Ostream& os, const IOstream::streamFormat& sf);
Ostream& operator<<(Ostream& os, const IOstream::versionNumber& vn);
// --------------------------------------------------------------------
// ------ Manipulators (not taking arguments)
// --------------------------------------------------------------------

View file

@ -134,9 +134,14 @@ public:
//- Read binary block
virtual Istream& read(char*, std::streamsize) = 0;
//- Read binary block from second stream
virtual Istream& parread(parIOType*, const string&) = 0;
//- Rewind and return the stream so that it may be read again
virtual Istream& rewind() = 0;
virtual Istream& readToStringStream(string&) = 0;
// Read List punctuation tokens

View file

@ -28,6 +28,11 @@ License
#include "token.H"
#include "keyType.H"
#include "IOstreams.H"
#include <iostream>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::Ostream, 0);
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -58,6 +63,14 @@ Foam::Ostream& Foam::Ostream::write(const keyType& kw)
// Write the keyword followed by appropriate indentation
Foam::Ostream& Foam::Ostream::writeKeyword(const keyType& kw)
{
if (Ostream::debug)
{
Pout<< "From function " << __PRETTY_FUNCTION__ << nl
<< " in file " << __FILE__ << nl
<< " at line " << __LINE__
<< " keyword: " << kw << '\n';
}
indent();
write(kw);

View file

@ -39,6 +39,11 @@ SourceFiles
#include "IOstream.H"
#include "keyType.H"
#include "className.H"
#include "uListProxyBase.H"
#include <memory>
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -67,23 +72,31 @@ protected:
static const unsigned short entryIndentation_ = 16;
//- Current indent level
unsigned short indentLevel_;
unsigned short indentLevel_ = 0;
public:
// Declare name of the class and its debug switch
ClassName("Ostream");
// Constructors
//- Default construct
Ostream(IOstreamOption streamOpt = IOstreamOption())
:
IOstream(streamOpt)
{}
//- Set stream status
Ostream
(
streamFormat format = ASCII,
streamFormat format,
versionNumber version = currentVersion,
compressionType compression=UNCOMPRESSED
compressionType compression = UNCOMPRESSED
)
:
IOstream(format, version, compression),
indentLevel_(0)
Ostream(IOstreamOption(format, version, compression))
{}
@ -137,6 +150,11 @@ public:
//- Write binary block
virtual Ostream& write(const char*, std::streamsize) = 0;
//- Write binary block into second stream
virtual Ostream& parwrite(std::unique_ptr<uListProxyBase>) = 0;
virtual Ostream& stringStream() = 0;
//- Add indentation characters
virtual void indent() = 0;
@ -158,11 +176,30 @@ public:
indentLevel_++;
}
//- Incrememt the indent level and add new block with name
virtual word incrBlock(const word name)
{
return name;
}
//- Decrememt the indent level
void decrIndent();
virtual void decrIndent();
//- Decrememt the indent level and close the current block
virtual void decrBlock()
{}
//- Get block identifier
virtual string getBlockId() const
{
return "none (called Ostream Member)";
}
//- Write the keyword followed by an appropriate indentation
Ostream& writeKeyword(const keyType&);
virtual Ostream& writeKeyword(const keyType&);
virtual void popBlockNamesStack()
{}
// Stream state functions
@ -232,6 +269,7 @@ inline Ostream& incrIndent(Ostream& os)
return os;
}
//- Decrement the indent level
inline Ostream& decrIndent(Ostream& os)
{
@ -240,6 +278,13 @@ inline Ostream& decrIndent(Ostream& os)
}
//- Decrement the indent level
inline Ostream& decrBlock(Ostream& os)
{
os.decrBlock();
return os;
}
//- Flush stream
inline Ostream& flush(Ostream& os)
{

View file

@ -317,6 +317,13 @@ Foam::Istream& Foam::IPstream::read(char* data, std::streamsize count)
}
Foam::Istream& Foam::IPstream::parread(parIOType* data, const string& id)
{
notImplemented("Istream& IPstream::parread(parIOType*, std::streamsize)");
return *this;
}
Foam::Istream& Foam::IPstream::rewind()
{
bufPosition_ = 0;

View file

@ -155,9 +155,17 @@ public:
//- Read binary block
Istream& read(char*, std::streamsize);
//- Read binary block from second stream
Istream& parread(parIOType*, const string&);
//- Rewind and return the stream so that it may be read again
Istream& rewind();
Istream& readToStringStream(string&)
{
return *this;
}
// Edit

View file

@ -237,6 +237,22 @@ Foam::Ostream& Foam::OPstream::write(const char* data, std::streamsize count)
}
Foam::Ostream& Foam::OPstream::parwrite(std::unique_ptr<uListProxyBase> uListProxyPtr)
{
notImplemented("Ostream& OPstream::parwrite(const parIOType*, const label)");
setBad();
return *this;
}
Foam::Ostream& Foam::OPstream::stringStream()
{
notImplemented("Ostream& OPstream::stringStream()");
setBad();
return *this;
}
void Foam::OPstream::print(Ostream& os) const
{
os << "Writing from processor " << toProcNo_

View file

@ -38,6 +38,7 @@ SourceFiles
#define OPstream_H
#include "Ostream.H"
#include "uListProxyBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -167,6 +168,11 @@ public:
//- Write binary block
Ostream& write(const char*, std::streamsize);
//- Write binary block into second stream
virtual Ostream& parwrite(std::unique_ptr<uListProxyBase>);
Ostream& stringStream();
//- Add indentation characters
void indent()
{}

View file

@ -67,7 +67,7 @@ bool Foam::OPstream::write
const label comm
)
{
if (debug)
if (Pstream::debug)
{
Pout<< "OPstream::write : starting write to:" << toProcNo
<< " tag:" << tag
@ -104,7 +104,7 @@ bool Foam::OPstream::write
PstreamGlobals::MPICommunicators_[comm] // MPI_COMM_WORLD
);
if (debug)
if (Pstream::debug)
{
Pout<< "OPstream::write : finished write to:" << toProcNo
<< " tag:" << tag << " size:" << label(bufSize)
@ -124,7 +124,7 @@ bool Foam::OPstream::write
PstreamGlobals::MPICommunicators_[comm] // MPI_COMM_WORLD
);
if (debug)
if (Pstream::debug)
{
Pout<< "OPstream::write : finished write to:" << toProcNo
<< " tag:" << tag << " size:" << label(bufSize)
@ -147,7 +147,7 @@ bool Foam::OPstream::write
&request
);
if (debug)
if (Pstream::debug)
{
Pout<< "OPstream::write : started write to:" << toProcNo
<< " tag:" << tag << " size:" << label(bufSize)

View file

@ -97,164 +97,6 @@ void Foam::Pstream::setParRun(const label nProcs)
}
Foam::List<Foam::Pstream::commsStruct> Foam::Pstream::calcLinearComm
(
const label nProcs
)
{
List<commsStruct> linearCommunication(nProcs);
// Master
labelList belowIDs(nProcs - 1);
forAll (belowIDs, i)
{
belowIDs[i] = i + 1;
}
linearCommunication[0] = commsStruct
(
nProcs,
0,
-1,
belowIDs,
labelList()
);
// Slaves. Have no below processors, only communicate up to master
for (label procID = 1; procID < nProcs; procID++)
{
linearCommunication[procID] = commsStruct
(
nProcs,
procID,
0,
labelList(),
labelList()
);
}
return linearCommunication;
}
// Tree like schedule. For 8 procs:
// (level 0)
// 0 receives from 1
// 2 receives from 3
// 4 receives from 5
// 6 receives from 7
// (level 1)
// 0 receives from 2
// 4 receives from 6
// (level 2)
// 0 receives from 4
//
// The sends/receives for all levels are collected per processor (one send per
// processor; multiple receives possible) creating a table:
//
// So per processor:
// proc receives from sends to
// ---- ------------- --------
// 0 1,2,4 -
// 1 - 0
// 2 3 0
// 3 - 2
// 4 5 0
// 5 - 4
// 6 7 4
// 7 - 6
Foam::List<Foam::Pstream::commsStruct> Foam::Pstream::calcTreeComm
(
const label nProcs
)
{
label nLevels = 1;
while ((1 << nLevels) < nProcs)
{
nLevels++;
}
List<dynamicLabelList> receives(nProcs);
labelList sends(nProcs, -1);
label offset = 2;
label childOffset = offset/2;
for (label level = 0; level < nLevels; level++)
{
label receiveID = 0;
while (receiveID < nProcs)
{
// Determine processor that sends and we receive from
label sendID = receiveID + childOffset;
if (sendID < nProcs)
{
receives[receiveID].append(sendID);
sends[sendID] = receiveID;
}
receiveID += offset;
}
offset <<= 1;
childOffset <<= 1;
}
// For all processors find the processors it receives data from
// (and the processors they receive data from etc.)
List<dynamicLabelList> allReceives(nProcs);
for (label procID = 0; procID < nProcs; procID++)
{
collectReceives(procID, receives, allReceives[procID]);
}
List<commsStruct> treeCommunication(nProcs);
for (label procID = 0; procID < nProcs; procID++)
{
treeCommunication[procID] = commsStruct
(
nProcs,
procID,
sends[procID],
receives[procID].shrink(),
allReceives[procID].shrink()
);
}
return treeCommunication;
}
// Append my children (and my children;s children etc.) to allReceives.
void Foam::Pstream::collectReceives
(
const label procID,
const List<dynamicLabelList>& receives,
dynamicLabelList& allReceives
)
{
const dynamicLabelList& myChildren = receives[procID];
forAll (myChildren, childI)
{
allReceives.append(myChildren[childI]);
collectReceives(myChildren[childI], receives, allReceives);
}
}
// Callback from Pstream::init() : initialize linear and tree communication
// schedules now that nProcs is known.
void Foam::Pstream::initCommunicationSchedule()
{
calcLinearComm(nProcs());
calcTreeComm(nProcs());
}
void Foam::Pstream::allocatePstreamCommunicator
(
const label parentIndex,
@ -445,9 +287,9 @@ Foam::label Foam::Pstream::allocateCommunicator
}
parentCommunicator_[index] = parentIndex;
linearCommunication_[index] = calcLinearComm(procIDs_[index].size());
treeCommunication_[index] = calcTreeComm(procIDs_[index].size());
// Size but do not fill structure - this is done on-the-fly
linearCommunication_[index] = List<commsStruct>(procIDs_[index].size());
treeCommunication_[index] = List<commsStruct>(procIDs_[index].size());
if (doPstream && parRun())
{
@ -879,6 +721,115 @@ void Foam::Pstream::freeTag(const word& s, const int tag)
}
template<>
Foam::Pstream::commsStruct&
Foam::UList<Foam::Pstream::commsStruct>::operator[](const label procID)
{
Pstream::commsStruct& t = v_[procID];
if (t.allBelow().size() + t.allNotBelow().size() + 1 != size())
{
// Not yet allocated
label above(-1);
labelList below;
labelList allBelow;
if (size() < Pstream::nProcsSimpleSum())
{
// Linear schedule
if (procID == 0)
{
below.setSize(size()-1);
for (label procI = 1; procI < size(); procI++)
{
below[procI-1] = procI;
}
}
else
{
above = 0;
}
}
else
{
// Use tree like schedule. For 8 procs:
// (level 0)
// 0 receives from 1
// 2 receives from 3
// 4 receives from 5
// 6 receives from 7
// (level 1)
// 0 receives from 2
// 4 receives from 6
// (level 2)
// 0 receives from 4
//
// The sends/receives for all levels are collected per processor
// (one send per processor; multiple receives possible) creating
// a table:
//
// So per processor:
// proc receives from sends to
// ---- ------------- --------
// 0 1,2,4 -
// 1 - 0
// 2 3 0
// 3 - 2
// 4 5 0
// 5 - 4
// 6 7 4
// 7 - 6
label mod = 0;
for (label step = 1; step < size(); step = mod)
{
mod = step * 2;
if (procID % mod)
{
above = procID - (procID % mod);
break;
}
else
{
for
(
label j = procID + step;
j < size() && j < procID + mod;
j += step
)
{
below.append(j);
}
for
(
label j = procID + step;
j < size() && j < procID + mod;
j++
)
{
allBelow.append(j);
}
}
}
}
t = Pstream::commsStruct(size(), procID, above, below, allBelow);
}
return t;
}
template<>
const Foam::Pstream::commsStruct&
Foam::UList<Foam::Pstream::commsStruct>::operator[](const label procID) const
{
return const_cast<UList<Pstream::commsStruct>&>(*this).operator[](procID);
}
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// By default this is not a parallel run

View file

@ -212,25 +212,6 @@ private:
//- Set data for parallel running
static void setParRun(const label nProcs);
//- Calculate linear communication schedule
static List<commsStruct> calcLinearComm(const label nProcs);
//- Calculate tree communication schedule
static List<commsStruct> calcTreeComm(const label nProcs);
//- Helper function for tree communication schedule determination
// Collects all processorIDs below a processor
static void collectReceives
(
const label procID,
const dynamicLabelListList& receives,
dynamicLabelList& allReceives
);
//- Initialize all communication schedules. Callback from
// Pstream::init()
static void initCommunicationSchedule();
//- Allocate a communicator with index
static void allocatePstreamCommunicator
(
@ -775,6 +756,16 @@ inline void Pstream::enlargeBuffer(size_t count)
Ostream& operator<<(Ostream&, const Pstream::commsStruct&);
// Template specialisation for access of commsStruct from the commucator list.
// Evaluates commsStruct on the fly if this is not present in the list.
template<>
Pstream::commsStruct&
UList<Pstream::commsStruct>::operator[](const label);
template<>
const Pstream::commsStruct&
UList<Pstream::commsStruct>::operator[](const label) const;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -100,7 +100,8 @@ struct is_vectorspace
decltype(std::declval<T>().operator+=(std::declval<T>())),
decltype(std::declval<T>().operator-=(std::declval<T>())),
decltype(std::declval<T>().operator*=(std::declval<scalar>())),
decltype(std::declval<T>().operator/=(std::declval<scalar>()))
decltype(std::declval<T>().operator/=(std::declval<scalar>())),
decltype(T::nComponents) // TODO port: was added because of error from lnInclude/Field.H:46, from lnInclude/labelField.H:39, from lnInclude/lduInterface.H:39, from lnInclude/SAMGInterface.H:42, from matrices/lduMatrix/solvers/AMG/interfaces/SAMGInterfaces/ggiSAMGInterface/ggiSAMGInterface.H
>
>
:

View file

@ -28,6 +28,10 @@ License
#include "token.H"
#include <cctype>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::ISstream, 0);
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
char Foam::ISstream::nextValid()
@ -119,7 +123,18 @@ void Foam::ISstream::readWordToken(token& t)
}
else if (token::compound::isCompound(*wPtr))
{
if (debug)
{
Pout<< "Start constructing compound token" << endl;
}
t = token::compound::New(*wPtr, *this).ptr();
if (debug)
{
Pout<< "End constructing compound token" << endl;
}
delete wPtr;
}
else
@ -137,6 +152,10 @@ Foam::Istream& Foam::ISstream::read(token& t)
// Return the put back token if it exists
if (Istream::getBack(t))
{
if (debug)
{
Pout<< "ISstream returns put back token: " << t << endl;
}
return *this;
}
@ -151,6 +170,12 @@ Foam::Istream& Foam::ISstream::read(token& t)
// Set the line number of this token to the current stream line number
t.lineNumber() = lineNumber();
if (debug > 1)
{
Pout<< "ISstream::read(token& t) with next valid char c = "
<< c << " on line number " << t.lineNumber() << "\n";
}
// return on error
if (!c)
{
@ -178,6 +203,14 @@ Foam::Istream& Foam::ISstream::read(token& t)
case token::MULTIPLY :
case token::DIVIDE :
{
if (debug)
{
if (c == token::BEGIN_BLOCK || c == token::END_BLOCK)
{
Pout<< "ISstream returns BLOCK token: " << c << endl;
}
}
t = token::punctuationToken(c);
return *this;
}
@ -199,6 +232,11 @@ Foam::Istream& Foam::ISstream::read(token& t)
t = sPtr;
}
if (debug)
{
Pout<< "ISstream returns string: " << t << endl;
}
return *this;
}
// Possible verbatim string or dictionary functionEntry
@ -384,6 +422,11 @@ Foam::Istream& Foam::ISstream::read(token& t)
}
}
if (debug > 1)
{
Pout<< "ISstream returns number token: " << t << endl;
}
return *this;
}
@ -394,6 +437,11 @@ Foam::Istream& Foam::ISstream::read(token& t)
putback(c);
readWordToken(t);
if (debug)
{
Pout<< "ISstream returns word token: " << t << endl;
}
return *this;
}
}
@ -474,6 +522,12 @@ Foam::Istream& Foam::ISstream::read(word& str)
str = buf;
putback(c);
if (debug > 1)
{
Pout<< "ISstream::read(word& str) returns word = "
<< str << endl;
}
return *this;
}

View file

@ -40,6 +40,8 @@ SourceFiles
#include "fileName.H"
#include <iostream>
#include "className.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
@ -59,14 +61,9 @@ class ISstream
istream& is_;
// Private member functions
char nextValid();
void readWordToken(token&);
// Private Member Functions
char nextValid();
//- Read a verbatim string (excluding block delimiters).
Istream& readVerbatim(string&);
@ -78,8 +75,19 @@ class ISstream
void operator=(const ISstream&);
protected:
// Protected Member Functions
virtual void readWordToken(token&);
public:
// Declare name of the class and its debug switch
ClassName("ISstream");
// Constructors
//- Construct as wrapper around istream
@ -166,9 +174,20 @@ public:
//- Read binary block
virtual Istream& read(char*, std::streamsize);
//- Read binary block from second stream
virtual Istream& parread(parIOType*, const string&)
{
return *this;
}
//- Rewind and return the stream so that it may be read again
virtual Istream& rewind();
Istream& readToStringStream(string&)
{
return *this;
}
// Stream state functions

View file

@ -40,6 +40,12 @@ inline Foam::ISstream::ISstream
name_(name),
is_(is)
{
if (debug)
{
Pout<< "ISstream construction with name " << name
<< " and format " << format
<< endl;
}
if (is_.good())
{
setOpened();

View file

@ -25,12 +25,36 @@ License
#include "error.H"
#include "OSstream.H"
#include "messageStream.H"
#include "token.H"
#include "Pstream.H"
#include <iostream>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::OSstream, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::Ostream& Foam::OSstream::write(const token& t)
{
if (debug)
{
std::cout
<< "From function " << __PRETTY_FUNCTION__ << nl
<< " in file " << __FILE__ << nl
<< " at line " << __LINE__
<< " Token: " << t.info() << '\n';
}
if (t.isPunctuation())
{
if (t.pToken() == token::punctuationToken::BEGIN_BLOCK)
{
Pout << "OSstream::write(token): BEGIN_BLOCK\n";
}
}
if (t.type() == token::VERBATIMSTRING)
{
write(char(token::HASH));
@ -49,6 +73,15 @@ Foam::Ostream& Foam::OSstream::write(const token& t)
Foam::Ostream& Foam::OSstream::write(const char c)
{
if (debug > 1)
{
std::cout
<< "From function " << __PRETTY_FUNCTION__ << nl
<< " in file " << __FILE__ << nl
<< " at line " << __LINE__
<< ": '" << c << "'\n";
}
os_ << c;
if (c == token::NL)
{
@ -61,6 +94,16 @@ Foam::Ostream& Foam::OSstream::write(const char c)
Foam::Ostream& Foam::OSstream::write(const char* str)
{
// Assign higher debug level since mostly file headers are written here
if (debug > 2)
{
std::cout
<< "From function " << __PRETTY_FUNCTION__ << nl
<< " in file " << __FILE__ << nl
<< " at line " << __LINE__
<< ": " << str << "\n";
}
lineNumber_ += string(str).count(token::NL);
os_ << str;
setState(os_.rdstate());
@ -70,6 +113,15 @@ Foam::Ostream& Foam::OSstream::write(const char* str)
Foam::Ostream& Foam::OSstream::write(const word& str)
{
if (debug)
{
std::cout
<< "From function " << __PRETTY_FUNCTION__ << nl
<< " in file " << __FILE__ << nl
<< " at line " << __LINE__
<< ": " << str << "\n";
}
os_ << str;
setState(os_.rdstate());
return *this;
@ -78,6 +130,15 @@ Foam::Ostream& Foam::OSstream::write(const word& str)
Foam::Ostream& Foam::OSstream::write(const string& str)
{
if (debug)
{
std::cout
<< "From function " << __PRETTY_FUNCTION__ << nl
<< " in file " << __FILE__ << nl
<< " at line " << __LINE__
<< ": " << str << "\n";
}
os_ << token::BEGIN_STRING;
int backslash = 0;
@ -127,6 +188,15 @@ Foam::Ostream& Foam::OSstream::writeQuoted
const bool quoted
)
{
if (debug > 2)
{
std::cout
<< "From function " << __PRETTY_FUNCTION__ << nl
<< " in file " << __FILE__ << nl
<< " at line " << __LINE__
<< ": " << str << "\n";
}
if (quoted)
{
os_ << token::BEGIN_STRING;
@ -234,6 +304,22 @@ Foam::Ostream& Foam::OSstream::write(const char* buf, std::streamsize count)
}
Foam::Ostream& Foam::OSstream::parwrite(std::unique_ptr<uListProxyBase> uListProxyPtr)
{
notImplemented("Ostream& OSstream::parwrite(const parIOType*, const label)");
setBad();
return *this;
}
Foam::Ostream& Foam::OSstream::stringStream()
{
notImplemented("Ostream& OSstream::stringStream()");
setBad();
return *this;
}
void Foam::OSstream::indent()
{
for (unsigned short i = 0; i < indentLevel_*indentSize_; i++)
@ -243,6 +329,12 @@ void Foam::OSstream::indent()
}
Foam::word Foam::OSstream::incrBlock(const word name)
{
return name;
}
void Foam::OSstream::flush()
{
os_.flush();

View file

@ -39,6 +39,10 @@ SourceFiles
#include "Ostream.H"
#include "fileName.H"
#include <iostream>
#include <memory>
#include "className.H"
#include "uListProxyBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,6 +60,7 @@ class OSstream
// Private data
fileName name_;
// FIFOStack<word> blockNamesStack_;
ostream& os_;
@ -82,17 +87,31 @@ protected:
public:
// Declare name of the class and its debug switch
ClassName("OSstream");
// Constructors
//- Construct using stream option
inline OSstream
(
std::ostream& os,
const string& name,
IOstreamOption streamOpt = IOstreamOption()
);
//- Set stream status
OSstream
(
ostream& os,
const string& name,
streamFormat format = ASCII,
streamFormat format,
versionNumber version = currentVersion,
compressionType compression=UNCOMPRESSED
);
compressionType compression = UNCOMPRESSED
)
:
OSstream(os, name, IOstreamOption(format, version, compression))
{}
// Member functions
@ -160,9 +179,17 @@ public:
//- Write binary block
virtual Ostream& write(const char*, std::streamsize);
//- Write binary block into paros_
virtual Ostream& parwrite(std::unique_ptr<uListProxyBase>);
virtual Ostream& stringStream();
//- Add indentation characters
virtual void indent();
//- Incrememt the indent level and add new block with name
virtual word incrBlock(const word);
// Stream state functions

View file

@ -31,12 +31,10 @@ inline Foam::OSstream::OSstream
(
ostream& os,
const string& name,
streamFormat format,
versionNumber version,
compressionType compression
IOstreamOption streamOpt
)
:
Ostream(format, version, compression),
Ostream(streamOpt),
name_(name),
os_(os)
{

View file

@ -162,6 +162,13 @@ Foam::Istream& Foam::ITstream::read(char*, std::streamsize)
}
Foam::Istream& Foam::ITstream::parread(parIOType*, const string& id)
{
notImplemented("Istream& ITstream::parread(parIOType*, const string& id)");
return *this;
}
Foam::Istream& Foam::ITstream::rewind()
{
tokenIndex_ = 0;

View file

@ -191,9 +191,17 @@ public:
//- Read binary block
virtual Istream& read(char*, std::streamsize);
//- Read binary block from second stream
virtual Istream& parread(parIOType*, const string&);
//- Rewind and return the stream so that it may be read again
virtual Istream& rewind();
Istream& readToStringStream(string&)
{
return *this;
}
// Edit

View file

@ -32,6 +32,7 @@ Foam::token Foam::token::undefinedToken;
defineTypeNameAndDebug(Foam::token::compound, 0);
defineRunTimeSelectionTable(Foam::token::compound, Istream);
defineRunTimeSelectionTable(Foam::token::compound, label);
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * //
@ -74,6 +75,31 @@ Foam::autoPtr<Foam::token::compound> Foam::token::compound::New
}
Foam::autoPtr<Foam::token::compound> Foam::token::compound::New
(
const word& compoundType,
label size
)
{
labelConstructorTable::iterator cstrIter =
labelConstructorTablePtr_->find(compoundType);
if (cstrIter == labelConstructorTablePtr_->end())
{
FatalErrorInFunction
<< "Unknown compound type " << compoundType << nl << nl
<< "Valid compound types:" << endl
<< IstreamConstructorTablePtr_->sortedToc()
<< abort(FatalIOError);
}
autoPtr<Foam::token::compound> ptr =
autoPtr<Foam::token::compound>(cstrIter()(size));
return ptr;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::token::compound::isCompound(const word& name)

View file

@ -49,6 +49,7 @@ SourceFiles
#include "runTimeSelectionTables.H"
#include <iostream>
#include "primitives_traits.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -155,6 +156,16 @@ public:
(is)
);
//- Declare run-time constructor selection table for a sized T
declareRunTimeSelectionTable
(
autoPtr,
compound,
label,
(label size),
(size)
);
// Constructors
@ -170,6 +181,9 @@ public:
//- Select null constructed
static autoPtr<compound> New(const word& type, Istream&);
//- Select constructed with size
static autoPtr<compound> New(const word& type, label);
//- Destructor
@ -195,11 +209,20 @@ public:
virtual label size() const = 0;
virtual label nComponents() const = 0;
// Check
// Edit
virtual void read(Istream&) = 0;
virtual void resize(const label newSize) = 0;
virtual char* data() = 0;
// Write
virtual void write(Ostream&) const = 0;
@ -229,15 +252,40 @@ public:
T(is)
{}
Compound(label size)
:
T(size)
{}
label size() const
{
return T::size();
}
label nComponents() const
{
return nComponentsOf<typename T::value_type>();
}
void resize(const label newSize)
{
return T::resize(newSize);
}
char* data()
{
return reinterpret_cast<char*>(T::data());
}
void write(Ostream& os) const
{
operator<<(os, static_cast<const T&>(*this));
}
void read(Istream& is)
{
operator>>(is, static_cast<T&>(*this));
}
};
@ -365,6 +413,7 @@ public:
inline bool isCompound() const;
inline const compound& compoundToken() const;
inline compound& compoundToken();
compound& transferCompoundToken(const Istream& is);
inline label lineNumber() const;
@ -460,7 +509,9 @@ Ostream& operator<<(Ostream& os, const InfoProxy<token>& ip);
#define addCompoundToRunTimeSelectionTable(Type, Name) \
token::compound::addIstreamConstructorToTable<token::Compound<Type > > \
add##Name##IstreamConstructorToTable_;
add##Name##IstreamConstructorToTable_; \
token::compound::addlabelConstructorToTable<token::Compound<Type > > \
add##Name##labelConstructorToTable_;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -324,7 +324,6 @@ inline bool Foam::token::isLongDoubleScalar() const
return (type_ == LONG_DOUBLE_SCALAR);
}
inline Foam::longDoubleScalar Foam::token::longDoubleScalarToken() const
{
if (type_ == LONG_DOUBLE_SCALAR)
@ -338,7 +337,6 @@ inline Foam::longDoubleScalar Foam::token::longDoubleScalarToken() const
}
}
inline bool Foam::token::isScalar() const
{
return (type_ == FLOAT_SCALAR || type_ == DOUBLE_SCALAR || type_ == LONG_DOUBLE_SCALAR);
@ -405,6 +403,18 @@ inline const Foam::token::compound& Foam::token::compoundToken() const
}
}
inline Foam::token::compound& Foam::token::compoundToken()
{
if (type_ == COMPOUND)
{
return *compoundTokenPtr_;
}
else
{
parseError("compound");
return *compoundTokenPtr_;
}
}
inline Foam::label Foam::token::lineNumber() const
{

View file

@ -29,9 +29,6 @@ Description
#include "error.H"
#include "token.H"
#include "IOstreams.H"
#include "scalar.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::token::token(Istream& is)
@ -121,6 +118,23 @@ ostream& Foam::operator<<(ostream& os, const token::punctuationToken& pt)
Foam::Ostream& Foam::operator<<(Ostream& os, const token::punctuationToken& pt)
{
if
(
(pt == token::END_STATEMENT || pt == token::NL)
&& os.format() == Ostream::streamFormat::COHERENT
)
{
if (Ostream::debug)
{
Pout<< "Found token END_STATEMENT."
<< " Poping stack with block names.\n";
}
// ToDoIO Remove old handling of the id
// os.popBlockNamesStack();
os.write(static_cast<const token>(pt));
// return os;
}
return os << char(pt);
}

View file

@ -29,8 +29,10 @@ Description
\*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "foamTime.H"
#include "IOobject.H"
#include "SliceStreamPaths.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -44,6 +46,11 @@ Foam::word Foam::Time::findInstance
{
// Note: if name is empty, just check the directory itself
SliceStreamPaths paths;
if ( paths.meshPresent() )
{
return constant();
}
const fileName tPath(path());
const fileName dirPath(tPath/timeName()/dir);

View file

@ -101,9 +101,23 @@ bool Foam::dictionary::read(Istream& is, const bool keepHeader)
is.putBack(currToken);
}
if (debug)
{
Pout<< "Start loop for entries construction of dictionary " << name()
<< endl;
}
while (!is.eof() && entry::New(*this, is))
{}
if (debug)
{
Pout<< "End loop for entries construction of dictionary " << name()
<< nl
<< "The dictionary TOC is " << nl
<< this->toc() << endl;
}
// normally remove the FoamFile header entry if it exists
if (!keepHeader)
{

View file

@ -232,6 +232,13 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
if (nextToken == token::BEGIN_BLOCK)
{
if (dictionary::debug)
{
Pout<< "entry::New(dictionary& parentDict, Istream& is):"
<< nl
<< " Add dictionaryEntry (a subdict) with keyword: "
<< keyword << '\n';
}
return parentDict.add
(
new dictionaryEntry(keyword, parentDict, is),
@ -240,6 +247,13 @@ bool Foam::entry::New(dictionary& parentDict, Istream& is)
}
else
{
if (dictionary::debug)
{
Pout<< "entry::New(dictionary& parentDict, Istream& is):"
<< nl
<< " Add primitiveEntry with keyword: "
<< keyword << '\n';
}
return parentDict.add
(
new primitiveEntry(keyword, parentDict, is),

View file

@ -122,7 +122,7 @@ public:
template<class T>
primitiveEntry(const keyType&, const T&);
autoPtr<entry> clone(const dictionary&) const
virtual autoPtr<entry> clone(const dictionary&) const
{
return autoPtr<entry>(new primitiveEntry(*this));
}
@ -172,7 +172,7 @@ public:
virtual bool read(const dictionary&, Istream&);
//- Write
void write(Ostream&) const;
virtual void write(Ostream&) const;
//- Write, optionally with contents only (no keyword, etc)
void write(Ostream&, const bool contentsOnly) const;

View file

@ -109,6 +109,15 @@ bool Foam::primitiveEntry::read(const dictionary& dict, Istream& is)
&& currToken != token::END_STATEMENT
)
{
if (dictionary::debug)
{
Pout<< "primitiveEntry::read(const dictionary&, Istream&),"
<< nl << " 1st append, token = '" << currToken << "'"
<< nl
<< " to a primitiveEntry of dictionary " << dict.name()
<< endl;
}
append(currToken, dict, is);
if
@ -127,6 +136,15 @@ bool Foam::primitiveEntry::read(const dictionary& dict, Istream& is)
&& !(currToken == token::END_STATEMENT && blockCount == 0)
)
{
if (dictionary::debug > 1)
{
Pout<< "primitiveEntry::read(const dictionary&, Istream&),"
<< nl << " consecutive append, token = '"
<< currToken << "'" << nl
<< " to a primitiveEntry of dictionary " << dict.name()
<< endl;
}
if
(
currToken == token::BEGIN_BLOCK
@ -146,6 +164,13 @@ bool Foam::primitiveEntry::read(const dictionary& dict, Istream& is)
append(currToken, dict, is);
}
if (dictionary::debug)
{
Pout<<
"End of primitiveEntry::readData(const dictionary&, Istream&)"
<< endl;
}
}
is.fatalCheck

View file

@ -305,6 +305,21 @@ extern messageStream Info;
#define DebugInFunction \
if (debug) InfoInFunction
//- Report an information message using Foam::Info
// for FUNCTION_NAME in file __FILE__ at line __LINE__
// if the local debug switch is true
#define DebugIO2 \
if (debug >= 2) ::Foam::Pout<< "From function " << FUNCTION_NAME << nl \
<< " in file " << __FILE__ << " at line " << __LINE__ << nl
//- Report an information message using Foam::Info
// for FUNCTION_NAME in file __FILE__ at line __LINE__
// if the local debug switch is true
#define DebugRegIO2 \
if (::Foam::regIOobject::debug >= 2) ::Foam::Pout<< "From function " \
<< FUNCTION_NAME << nl \
<< " in file " << __FILE__ << " at line " << __LINE__ << nl
//- Report a variable name and value
// using Foam::Pout in file __FILE__ at line __LINE__
#define DebugVar(var) \

View file

@ -26,6 +26,8 @@ License
#include "objectRegistry.H"
#include "foamTime.H"
#include "SliceStreamRepo.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::objectRegistry, 0);
@ -254,6 +256,12 @@ Foam::label Foam::objectRegistry::getEvent() const
}
Foam::IOstreamOption::streamMode Foam::objectRegistry::streamMode() const
{
return streamMode_;
}
bool Foam::objectRegistry::checkIn(regIOobject& io) const
{
if (objectRegistry::debug)
@ -322,6 +330,12 @@ bool Foam::objectRegistry::checkOut(regIOobject& io) const
}
void Foam::objectRegistry::streamMode(IOstreamOption::streamMode md)
{
streamMode_ = md;
}
void Foam::objectRegistry::rename(const word& newName)
{
regIOobject::rename(newName);
@ -377,12 +391,58 @@ bool Foam::objectRegistry::readIfModified()
}
bool Foam::objectRegistry::write() const
{
bool writeBulkData = false;
auto destination = IOstreamOption::TIME;
if (time().controlDict().lookupOrDefault("writeBulkData", false))
{
writeBulkData = true;
destination = IOstreamOption::CASE;
}
IOstreamOption streamOpt
(
time().writeFormat(),
IOstream::currentVersion,
time().writeCompression(),
streamMode_, // ToDoIO Store this default in foamTime?
destination
);
if (time().writeFormat() == IOstreamOption::COHERENT)
{
auto repo = SliceStreamRepo::instance();
repo->open(writeBulkData);
}
bool ok = writeObject(streamOpt);
if (time().writeFormat() == IOstreamOption::COHERENT)
{
auto repo = SliceStreamRepo::instance();
repo->close(writeBulkData);
}
return ok;
}
bool Foam::objectRegistry::writeObject
(
IOstream::streamFormat fmt,
IOstream::versionNumber ver,
IOstream::compressionType cmp
) const
{
return writeObject(IOstreamOption(fmt, ver, cmp));
}
bool Foam::objectRegistry::writeObject
(
IOstreamOption streamOpt
) const
{
bool ok = true;
@ -395,13 +455,15 @@ bool Foam::objectRegistry::writeObject
<< iter.key()
<< " of type " << iter()->type()
<< " with writeOpt " << iter()->writeOpt()
<< ", streamFormat " << streamOpt.format()
<< " and streamMode " << streamOpt.mode()
<< " to file " << iter()->objectPath()
<< endl;
}
if (iter()->writeOpt() != NO_WRITE)
{
ok = iter()->writeObject(fmt, ver, cmp) && ok;
ok = iter()->writeObject(streamOpt) && ok;
}
}

View file

@ -67,6 +67,9 @@ class objectRegistry
//- Current event
mutable label event_;
//- I/O stream mode propagated to the objects
IOstreamOption::streamMode streamMode_ = IOstreamOption::DEFERRED;
// Private Member Functions
@ -201,6 +204,9 @@ public:
//- Return new event number.
label getEvent() const;
//- Return stream mode
IOstreamOption::streamMode streamMode() const;
// Edit
@ -213,6 +219,8 @@ public:
//- Remove an regIOobject from registry
virtual bool checkOut(regIOobject&) const;
//- Alter stream mode
void streamMode(IOstreamOption::streamMode);
// Reading
@ -228,6 +236,9 @@ public:
// Writing
//- Write using setting from DB and current stream mode
virtual bool write() const;
//- writeData function required by regIOobject but not used
// for this class, write is used instead
virtual bool writeData(Ostream&) const
@ -244,6 +255,9 @@ public:
IOstream::versionNumber ver,
IOstream::compressionType cmp
) const;
//- Write the objects using stream option
virtual bool writeObject(IOstreamOption streamOpt) const;
};

View file

@ -243,6 +243,8 @@ public:
//- Return Istream and check object type against that given
Istream& readStream(const word&);
Istream& readStreamPar(const word&);
//- Close Istream
void close();
@ -282,9 +284,30 @@ public:
IOstream::compressionType
) const;
//- Write using stream option
virtual bool writeObject(IOstreamOption streamOpt) const;
//- Write using setting from DB
virtual bool write() const;
//- Write to file stream
virtual bool writeToStream
(
const fileName& pathname,
ios_base::openmode mode,
IOstream::streamFormat format,
IOstream::versionNumber version,
IOstream::compressionType compression
) const;
//- Write to file stream with stream option
virtual bool writeToStream
(
const fileName &pathname,
ios_base::openmode mode,
IOstreamOption streamOpt
) const;
// Member operators

View file

@ -27,6 +27,7 @@ License
#include "IFstream.H"
#include "objectRegistry.H"
#include "PstreamReduceOps.H"
#include <string>
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -145,6 +146,78 @@ Foam::Istream& Foam::regIOobject::readStream(const word& expectName)
}
Foam::Istream& Foam::regIOobject::readStreamPar(const word& expectName)
{
const word writeFormat(time().controlDict().lookup("writeFormat"));
const bool isCoherentFormat =
(IOstream::formatEnum(writeFormat) == IOstream::COHERENT);
if (!isCoherentFormat)
{
return readStream(expectName);
}
fileName objPath = objectPath();
Info<< "Reading from " << objPath << nl
<< " via coherent format, since writeFormat is set to '"
<< writeFormat << "'" << nl
<< " and format mixing is not allowed."
<< endl;
if (IFstream::debug)
{
Info<< "regIOobject::readStreamPar(const word&) : "
<< "reading object " << name()
<< " from " << objPath
<< endl;
}
// Construct IFstream if not already constructed
if (!isPtr_)
{
if (!(isPtr_ = objectStreamPar(objPath)))
{
FatalIOError
(
"regIOobject::readStreamPar()",
__FILE__,
__LINE__,
objPath,
0
) << "cannot open file"
<< exit(FatalIOError);
}
else if (!readHeader(*isPtr_))
{
FatalIOErrorIn("regIOobject::readStreamPar()", *isPtr_)
<< "problem while reading header for object " << name()
<< exit(FatalIOError);
}
// Check the className of the regIOobject
// dictionary is an allowable name in case the actual class
// instantiated is a dictionary
if
(
expectName.size()
&& headerClassName() != expectName
&& headerClassName() != dictionary::typeName
&& headerClassName() != IOdictionary::typeName
)
{
FatalIOErrorIn("regIOobject::readStreamPar(const word&)", *isPtr_)
<< "unexpected class name " << headerClassName()
<< " expected " << expectName << endl
<< " while reading object " << name()
<< exit(FatalIOError);
}
}
return *isPtr_;
}
void Foam::regIOobject::close()
{
if (IFstream::debug)

View file

@ -30,6 +30,10 @@ Description
#include "objectRegistry.H"
#include "OSspecific.H"
#include "OFstream.H"
#include "SliceStream.H"
#include "Pstream.H"
#include "profiling.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -39,6 +43,12 @@ bool Foam::regIOobject::writeObject
IOstream::versionNumber ver,
IOstream::compressionType cmp
) const
{
return writeObject(IOstreamOption(fmt, ver, cmp));
}
bool Foam::regIOobject::writeObject(IOstreamOption streamOpt) const
{
if (!good())
{
@ -70,50 +80,33 @@ bool Foam::regIOobject::writeObject
const_cast<regIOobject&>(*this).instance() = time().timeName();
}
mkDir(path());
if (time().writeFormat() == IOstream::COHERENT)
{
if (Pstream::master())
{
mkDir(path());
}
}
else
{
mkDir(path());
}
if (OFstream::debug)
{
Info<< "regIOobject::write() : "
<< "writing file " << objectPath();
<< "writing file " << objectPath() << " ..." << nl;
}
// Try opening an OFstream for object.
// May open different streams in the derived classes.
bool osGood = writeToStream
(
objectPath(),
ios_base::out|ios_base::trunc,
streamOpt
);
bool osGood = false;
{
// Try opening an OFstream for object
// Stream open for over-write. HJ, 17/Aug/2010
OFstream os
(
objectPath(),
ios_base::out|ios_base::trunc,
fmt,
ver,
cmp
);
// If any of these fail, return (leave error handling to Ostream class)
if (!os.good())
{
return false;
}
if (!writeHeader(os))
{
return false;
}
// Write the data to the Ostream
if (!writeData(os))
{
return false;
}
writeEndDivider(os);
osGood = os.good();
}
if (OFstream::debug)
{
@ -133,12 +126,92 @@ bool Foam::regIOobject::writeObject
bool Foam::regIOobject::write() const
{
return writeObject
addProfile2(io, "Foam::regIOobject::write()");
bool writeBulkData = false;
auto destination = IOstreamOption::TIME;
if (time().controlDict().lookupOrDefault("writeBulkData", false))
{
writeBulkData = true;
destination = IOstreamOption::CASE;
}
IOstreamOption streamOpt
(
time().writeFormat(),
IOstream::currentVersion,
time().writeCompression()
time().writeCompression(),
IOstreamOption::SYNC, // ToDoIO Store this default in foamTime?
destination
);
if (time().writeFormat() == IOstream::COHERENT)
{
auto repo = SliceStreamRepo::instance();
repo->open(writeBulkData);
}
bool ok = writeObject(streamOpt);
if (time().writeFormat() == IOstream::COHERENT)
{
auto repo = SliceStreamRepo::instance();
repo->close(writeBulkData);
}
return ok;
}
bool Foam::regIOobject::writeToStream
(
const fileName& pathname,
ios_base::openmode mode,
IOstream::streamFormat fmt,
IOstream::versionNumber ver,
IOstream::compressionType cmp
) const
{
return writeToStream(pathname, mode, IOstreamOption(fmt, ver, cmp));
}
bool Foam::regIOobject::writeToStream
(
const fileName& pathname,
ios_base::openmode mode,
IOstreamOption streamOpt
) const
{
// Try opening an OFstream for object
// Stream open for over-write. HJ, 17/Aug/2010
OFstream os
(
objectPath(),
ios_base::out|ios_base::trunc,
streamOpt
);
// If any of these fail, return (leave error handling to Ostream class)
if (!os.good())
{
return false;
}
if (!writeHeader(os))
{
return false;
}
// Write the data to the Ostream
if (!writeData(os))
{
return false;
}
writeEndDivider(os);
return os.good();
}
// ************************************************************************* //

View file

@ -48,6 +48,8 @@ SourceFiles
namespace Foam
{
TemplateName(DebugIODimensionedField);
// Forward declaration of friend functions and operators
template<class Type, class GeoMesh> class DimensionedField;
@ -72,6 +74,7 @@ template<class Type, class GeoMesh> Ostream& operator<<
template<class Type, class GeoMesh>
class DimensionedField
:
public DebugIODimensionedFieldName,
public regIOobject,
public Field<Type>
{

View file

@ -25,6 +25,7 @@ License
#include "DimensionedField.H"
#include "IOstreams.H"
#include "Ostream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -75,6 +76,11 @@ bool DimensionedField<Type, GeoMesh>::writeData
const word& fieldDictEntry
) const
{
if (debug)
{
Pout<< "dimensions = " << endl;
}
os.writeKeyword("dimensions") << dimensions() << token::END_STATEMENT
<< nl << nl;

View file

@ -212,6 +212,14 @@ Field<Type>::Field
const label s
)
{
if (debug)
{
Info<< "Field<Type>::Field"
<< "(const word& keyword, const dictionary& dict, const label s)"
<< " : keyword = " << keyword
<< endl;
}
if (s)
{
ITstream& is = dict.lookup(keyword);
@ -597,6 +605,14 @@ void Field<Type>::writeEntry(const word& keyword, Ostream& os) const
{
os.writeKeyword(keyword);
if (os.format() == IOstream::COHERENT)
{
// Trigger write, the uniformity check will be performed later
List<Type>::writeEntry(os);
return;
}
bool uniform = false;
if (this->size() && contiguous<Type>())

View file

@ -52,6 +52,8 @@ SourceFiles
namespace Foam
{
TemplateName(DebugIOField);
// Forward declaration of friend functions and operators
template<class Type>
@ -77,6 +79,7 @@ class dictionary;
template<class Type>
class Field
:
public DebugIOFieldName,
public refCount,
public List<Type>
{

View file

@ -27,6 +27,8 @@ License
#include "commSchedule.H"
#include "globalMeshData.H"
#include "IOmanip.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>
@ -523,17 +525,18 @@ template<class Type, template<class> class PatchField, class GeoMesh>
void Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricBoundaryField::
writeEntry(const word& keyword, Ostream& os) const
{
os << keyword << nl << token::BEGIN_BLOCK << incrIndent << nl;
// os << keyword << nl << token::BEGIN_BLOCK << incrIndent << nl;
os << incrBlock(keyword);
forAll(*this, patchi)
{
os << indent << this->operator[](patchi).patch().name() << nl
<< indent << token::BEGIN_BLOCK << nl
<< incrIndent << this->operator[](patchi) << decrIndent
<< indent << token::END_BLOCK << endl;
os << incrBlock(this->operator[](patchi).patch().name())
<< this->operator[](patchi)
<< decrBlock << endl;
}
os << decrIndent << token::END_BLOCK << endl;
os << decrBlock << endl;
// os << decrIndent << token::END_BLOCK << endl;
// Check state of IOstream
os.check

View file

@ -27,6 +27,8 @@ License
#include "foamTime.H"
#include "demandDrivenData.H"
#include "dictionary.H"
#include "OFCstream.H"
#include "IFCstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,6 +58,14 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::readField
const dictionary& fieldDict
)
{
if (debug)
{
Info<< "Foam::GeometricField<Type, PatchField, GeoMesh>"
<< "::readField(const dictionary& fieldDict)"
<< "\n dict =\n" << fieldDict << nl
<< endl;
}
DimensionedField<Type, GeoMesh>::readField(fieldDict, "internalField");
tmp<GeometricBoundaryField> tboundaryField
@ -94,6 +104,13 @@ Foam::tmp
>
Foam::GeometricField<Type, PatchField, GeoMesh>::readField(Istream& is)
{
if (debug)
{
Info<< "Foam::GeometricField<Type, PatchField, GeoMesh>"
<< "::readField(Istream& is) with stream format " << is.format()
<< endl;
}
if (is.version() < 2.0)
{
FatalIOErrorIn
@ -104,7 +121,26 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::readField(Istream& is)
<< exit(FatalIOError);
}
return readField(dictionary(is));
if (is.format() == IOstream::COHERENT)
{
if (!isA<IFCstream>(is))
{
FatalErrorInFunction
<< "Stream is set to IO Format COHERENT but " << is.name()
<< " is initialized with a different format"
<< exit(FatalError);
}
IFCstream& ifc = dynamic_cast<IFCstream&>(is);
return readField
(
ifc.readToDict<Type, PatchField, GeoMesh>()
);
}
else
{
return readField(dictionary(is));
}
}
@ -120,9 +156,9 @@ bool Foam::GeometricField<Type, PatchField, GeoMesh>::readIfPresent()
<< "suggests that a read constructor for field " << this->name()
<< " would be more appropriate." << endl;
}
else if (this->readOpt() == IOobject::READ_IF_PRESENT && this->headerOk())
else if (this->readOpt() == IOobject::READ_IF_PRESENT && this->headerOkPar())
{
boundaryField_.transfer(readField(this->readStream(typeName))());
boundaryField_.transfer(readField(this->readStreamPar(typeName))());
this->close();
// Check compatibility between field and mesh
@ -348,7 +384,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
timeIndex_(this->time().timeIndex()),
field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr),
boundaryField_(*this, readField(this->readStream(typeName)))
boundaryField_(*this, readField(this->readStreamPar(typeName)))
{
this->close();
@ -980,6 +1016,50 @@ void Foam::GeometricField<Type, PatchField, GeoMesh>::writeMinMax
}
template<class Type, template<class> class PatchField, class GeoMesh>
bool Foam::GeometricField<Type, PatchField, GeoMesh>::writeToStream
(
const fileName& pathname,
ios_base::openmode mode,
IOstreamOption streamOpt
) const
{
if (streamOpt.format() != IOstream::COHERENT)
{
return regIOobject::writeToStream(pathname, mode, streamOpt);
}
OFCstream<Type, PatchField, GeoMesh> os
(
pathname,
this->mesh().thisDb(),
mode,
streamOpt
);
// If any of these fail, return (leave error handling to Ostream class)
if (!os.good())
{
return false;
}
if (!this->writeHeader(os))
{
return false;
}
// Write the data to the Ostream
if (!this->writeData(os))
{
return false;
}
this->writeEndDivider(os);
return os.good();
}
// writeData member function required by regIOobject
template<class Type, template<class> class PatchField, class GeoMesh>
bool Foam::GeometricField<Type, PatchField, GeoMesh>::
@ -990,6 +1070,44 @@ writeData(Ostream& os) const
}
template<class Type, template<class> class PatchField, class GeoMesh>
Foam::Istream*
Foam::GeometricField<Type, PatchField, GeoMesh>::objectStreamPar
(
const fileName& fName
)
{
if (debug)
{
Info<< "GeometricField<Type, PatchField, GeoMesh>::objectStreamPar : "
"Constructing object stream IFCstream"
<< endl << this->info() << endl;
}
// Forbid format mixing, i.e. no reading with COHERENT when the write
// format is different
if (fName.size() && this->mesh().time().writeFormat() == IOstream::COHERENT)
{
IFCstream* isPtr =
new IFCstream(fName, this->mesh().thisDb(), IOstream::COHERENT);
if (isPtr->good())
{
return isPtr;
}
else
{
delete isPtr;
return nullptr;
}
}
else
{
return nullptr;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh>

View file

@ -492,9 +492,20 @@ public:
const direction
) const;
//- Create a file stream and write
virtual bool writeToStream
(
const fileName&,
ios_base::openmode,
IOstreamOption
) const;
//- WriteData member function required by regIOobject
bool writeData(Ostream&) const;
//- Construct an IFCsteam
virtual Istream* objectStreamPar(const fileName&);
//- Return transpose (only if it is a tensor field)
tmp<GeometricField<Type, PatchField, GeoMesh> > T() const;

View file

@ -492,6 +492,7 @@ Foam::argList::argList
)
:
parRunControl_(args.parRunControl_),
//adiosControl_(args.adiosControl_),
args_(args.args_),
options_(options),
executable_(args.executable_),
@ -596,12 +597,31 @@ void Foam::argList::parse
// If this actually is a parallel run
if (parRunControl_.parRun())
{
bool isCoherentFormat = false;
// For the master
if (Pstream::master())
{
// Establish rootPath_/globalCase_/case_ for master
getRootCase();
// Check the IO write format
fileName ctrlDictName = rootPath_/globalCase_/"system/controlDict";
IFstream controlDictStream(ctrlDictName);
if (!controlDictStream.good())
{
FatalError
<< "Cannot read "
<< controlDictStream.name()
<< exit(FatalError);
}
const dictionary controlDict(controlDictStream);
const word writeFormat(controlDict.lookup("writeFormat"));
isCoherentFormat =
(IOstream::formatEnum(writeFormat) == IOstream::COHERENT);
// See if running distributed (different roots for different procs)
label dictNProcs = -1;
fileName source;
@ -669,12 +689,28 @@ void Foam::argList::parse
// - decomposition to fewer processors : nProcs = nProcDirs
if (dictNProcs > Pstream::nProcs())
{
FatalError
<< source
<< " specifies " << dictNProcs
<< " processors but job was started with "
<< Pstream::nProcs() << " processors."
<< exit(FatalError);
if (isCoherentFormat)
{
Warning
<< source
<< " specifies " << dictNProcs
<< " processors but job was started with "
<< Pstream::nProcs() << " processors." << nl
<< " " << IOstream::formatEnum(writeFormat)
<< " format allows restart with variable number of"
<< " processors but the decomposition may not be"
<< " optimal."
<< endl;
}
else
{
FatalError
<< source
<< " specifies " << dictNProcs
<< " processors but job was started with "
<< Pstream::nProcs() << " processors."
<< exit(FatalError);
}
}
@ -708,7 +744,7 @@ void Foam::argList::parse
options_.set("case", roots[slave-1]/globalCase_);
OPstream toSlave(Pstream::scheduled, slave);
toSlave << args_ << options_;
toSlave << args_ << options_ << isCoherentFormat;
}
options_.erase("case");
@ -722,7 +758,7 @@ void Foam::argList::parse
{
// Possibly going to fewer processors.
// Check if all procDirs are there.
if (dictNProcs < Pstream::nProcs())
if (!isCoherentFormat && dictNProcs < Pstream::nProcs())
{
label nProcDirs = 0;
while
@ -755,7 +791,7 @@ void Foam::argList::parse
)
{
OPstream toSlave(Pstream::scheduled, slave);
toSlave << args_ << options_;
toSlave << args_ << options_ << isCoherentFormat;
}
}
}
@ -763,14 +799,32 @@ void Foam::argList::parse
{
// Collect the master's argument list
IPstream fromMaster(Pstream::scheduled, Pstream::masterNo());
fromMaster >> args_ >> options_;
fromMaster >> args_ >> options_ >> isCoherentFormat;
// Establish rootPath_/globalCase_/case_ for slave
getRootCase();
}
nProcs = Pstream::nProcs();
case_ = globalCase_/(word("processor") + name(Pstream::myProcNo()));
if (isCoherentFormat)
{
case_ = globalCase_;
if (Pstream::master() && isDir(rootPath_/globalCase_/"processor0"))
{
WarningInFunction
<< "The I/O is set to the coherent format (writeFormat in"
<< " controlDict) but 'processor0' directory is present"
<< " indicating usage of a conventional I/O format."
<< " Note that the coherent format does not use"
<< " 'processor' directories."
<< nl << endl;
}
}
else
{
case_ = globalCase_/(word("processor") + name(Pstream::myProcNo()));
}
}
else
{
@ -1299,6 +1353,7 @@ bool Foam::argList::checkRootCase() const
return false;
}
/* Disabled this check to allow restarts from TARs
if (!isDir(path()) && Pstream::master())
{
// Allow slaves on non-existing processor directories, created later
@ -1309,6 +1364,7 @@ bool Foam::argList::checkRootCase() const
return false;
}
*/
return true;
}

View file

@ -0,0 +1,50 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | foam-extend: Open Source CFD
\\ / O peration | Version: 4.1
\\ / A nd | Web: http://www.foam-extend.org
\\/ M anipulation | For copyright notice see file Copyright
-------------------------------------------------------------------------------
License
This file is part of foam-extend.
foam-extend 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.
foam-extend 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 foam-extend. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "parRun.H"
#include "SliceStreamRepo.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::ParRunControl::~ParRunControl()
{
auto repo = SliceStreamRepo::instance();
repo->open();
repo->close();
if (RunPar)
{
Info<< "Finalising parallel run" << endl;
Pstream::exit(0);
}
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
// End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -56,14 +56,7 @@ public:
RunPar(false)
{}
~ParRunControl()
{
if (RunPar)
{
Info<< "Finalising parallel run" << endl;
Pstream::exit(0);
}
}
~ParRunControl();
void runPar(int& argc, char**& argv)
{

View file

@ -116,7 +116,7 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<Form, Type>& M)
// Read end of contents
is.readEndList("Matrix");
}
else
else if (is.format() == IOstream::BINARY)
{
if (nm)
{
@ -132,6 +132,8 @@ Foam::Istream& Foam::operator>>(Istream& is, Matrix<Form, Type>& M)
);
}
}
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not implemented in MatrixIO.C.\n"; }
}
else
{
@ -243,13 +245,15 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<Form, Type>& M)
os << token::BEGIN_LIST << token::END_LIST << nl;
}
}
else
else if (os.format() == IOstream::BINARY)
{
if (nm)
{
os.write(reinterpret_cast<const char*>(M.v_[0]), nm*sizeof(Type));
}
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not implemented in MatrixIO.C.\n"; }
// Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const Matrix&)");

View file

@ -117,7 +117,7 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const boundBox& bb)
{
os << bb.min_ << token::SPACE << bb.max_;
}
else
else if (os.format() == IOstream::BINARY)
{
os.write
(
@ -125,6 +125,8 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const boundBox& bb)
sizeof(boundBox)
);
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in boundBox.C\n"; }
// Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const boundBox&)");
@ -138,7 +140,7 @@ Foam::Istream& Foam::operator>>(Istream& is, boundBox& bb)
{
return is >> bb.min_ >> bb.max_;
}
else
else if (is.format() == IOstream::BINARY)
{
is.read
(
@ -146,6 +148,8 @@ Foam::Istream& Foam::operator>>(Istream& is, boundBox& bb)
sizeof(boundBox)
);
}
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in boundBox.C\n"; }
// Check state of Istream
is.check("Istream& operator>>(Istream&, boundBox&)");

View file

@ -27,7 +27,7 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::globalIndex::globalIndex(const label localSize)
Foam::globalIndex::globalIndex(const label localSize, const bool reduce)
:
offsets_(Pstream::nProcs())
{
@ -36,21 +36,28 @@ Foam::globalIndex::globalIndex(const label localSize)
Pstream::gatherList(localSizes);
Pstream::scatterList(localSizes); // just to balance out comms
label offset = 0;
forAll(offsets_, procI)
if (reduce)
{
label oldOffset = offset;
offset += localSizes[procI];
if (offset < oldOffset)
label offset = 0;
forAll(offsets_, procI)
{
FatalErrorIn("globalIndex::globalIndex(const label)")
<< "Overflow : sum of sizes " << localSizes
<< " exceeds capability of label (" << labelMax
<< "). Please recompile with larger datatype for label."
<< exit(FatalError);
label oldOffset = offset;
offset += localSizes[procI];
if (offset < oldOffset)
{
FatalErrorIn("globalIndex::globalIndex(const label)")
<< "Overflow : sum of sizes " << localSizes
<< " exceeds capability of label (" << labelMax
<< "). Please recompile with larger datatype for label."
<< exit(FatalError);
}
offsets_[procI] = offset;
}
offsets_[procI] = offset;
}
else
{
std::copy(localSizes.begin(), localSizes.end(), offsets_.begin());
}
}

View file

@ -71,7 +71,11 @@ public:
// Constructors
//- Construct from local max size
globalIndex(const label localSize);
globalIndex
(
const label localSize,
const bool reduce = true
);
//- Construct from Istream
globalIndex(Istream& is);
@ -122,7 +126,6 @@ public:
inline label offset(const label procI) const;
// IOstream Operators
friend Istream& operator>>(Istream& is, globalIndex& gi);

View file

@ -65,7 +65,7 @@ Foam::polyBoundaryMesh::polyBoundaryMesh
polyPatchList& patches = *this;
// Read polyPatchList
Istream& is = readStream(typeName);
Istream& is = readStreamPar(typeName);
PtrList<entry> patchEntries(is);
patches.setSize(patchEntries.size());

View file

@ -34,6 +34,18 @@ License
#include "treeDataCell.H"
#include "MeshObject.H"
#include "pointMesh.H"
#include "SliceWriting.H"
#include "SliceStream.H"
#include "sliceWritePrimitives.H"
#include "DynamicList.H"
#include <numeric>
#include <set>
#include <map>
#include <array>
#include "SlicePermutation.H"
#include "CoherentMesh.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -200,6 +212,7 @@ void Foam::polyMesh::calcDirections() const
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::polyMesh::polyMesh(const IOobject& io)
:
objectRegistry(io),
@ -212,9 +225,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
time().findInstance(meshDir(), "points"),
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
pointField(0)
),
// To be re-sliced later. HJ, 19/oct/2008
points_(allPoints_, allPoints_.size()),
@ -226,9 +240,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
time().findInstance(meshDir(), "faces"),
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
faceList(0)
),
// To be re-sliced later. HJ, 19/oct/2008
faces_(allFaces_, allFaces_.size()),
@ -240,9 +255,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
time().findInstance(meshDir(), "faces"),
meshSubDir,
*this,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
)
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
labelList(0)
),
neighbour_
(
@ -252,9 +268,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
time().findInstance(meshDir(), "faces"),
meshSubDir,
*this,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
)
IOobject::NO_READ,
IOobject::AUTO_WRITE
),
labelList(0)
),
syncPar_(true), // Reading mesh from IOobject: must be valid
clearedPrimitives_(false),
@ -267,9 +284,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
IOobject::AUTO_WRITE
),
*this
*this,
0
),
bounds_(allPoints_), // Reading mesh from IOobject: syncPar
geometricD_(Vector<label>::zero),
@ -336,7 +354,118 @@ Foam::polyMesh::polyMesh(const IOobject& io)
oldAllPointsPtr_(nullptr),
oldPointsPtr_(nullptr)
{
if (exists(owner_.objectPath()))
if (time().writeFormat() == IOstream::COHERENT)
{
this->checkOut( allPoints_ );
this->checkOut( allFaces_ );
this->checkOut( owner_ );
this->checkOut( neighbour_ );
this->checkOut( boundary_ );
// Clear addressing. Keep geometric props for mapping.
clearAddressing();
// Clear everything
clearOut();
// Create a CoherentMesh object and transfer the ownership to the registry
// in order to enable access later on
const CoherentMesh& coherentMeshConst = CoherentMesh::New(*(this));
CoherentMesh& coherentMesh = const_cast<CoherentMesh&>(coherentMeshConst);
coherentMesh.polyNeighbours(neighbour_);
coherentMesh.polyOwner(owner_);
coherentMesh.polyFaces(allFaces_);
coherentMesh.polyPoints(allPoints_);
faces_.reset( allFaces_, allFaces_.size() );
points_.reset( allPoints_, allPoints_.size() );
Foam::List<Foam::polyPatch*> procPatches = coherentMesh.polyPatches( boundary_ );
addPatches(procPatches, false);
bounds_ = boundBox( allPoints_ );
}
else
{
allPoints_ = pointIOField
(
IOobject
(
"points",
time().findInstance(meshDir(), "points"),
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
allFaces_ = faceIOList
(
IOobject
(
"faces",
time().findInstance(meshDir(), "faces"),
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
owner_ = labelIOList
(
IOobject
(
"owner",
time().findInstance(meshDir(), "owner"),
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
neighbour_ = labelIOList
(
IOobject
(
"neighbour",
time().findInstance(meshDir(), "neighbour"),
meshSubDir,
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE
)
);
faces_.reset( allFaces_, allFaces_.size() );
points_.reset( allPoints_, allPoints_.size() );
bounds_ = boundBox( allPoints_ );
Istream& is = boundary_.readStream("polyBoundaryMesh");
PtrList<entry> patchEntries(is);
boundary_.setSize(patchEntries.size());
forAll(patchEntries, patchI)
{
boundary_.set
(
patchI,
polyPatch::New
(
patchEntries[patchI].keyword(),
patchEntries[patchI].dict(),
patchI,
boundary_
)
);
}
// TODO: Is this what we want, for instance, for dynamic meshes?
this->checkOut( allPoints_ );
this->checkOut( allFaces_ );
this->checkOut( owner_ );
this->checkOut( neighbour_ );
this->checkOut( boundary_ );
}
// if (exists(owner_.objectPath()))
if (owner_.headerOkPar() || (time().writeFormat() == IOstream::COHERENT))
{
initMesh();
}
@ -382,6 +511,11 @@ Foam::polyMesh::polyMesh(const IOobject& io)
WarningIn("polyMesh(const IOobject&)")
<< "no cells in mesh" << endl;
}
if (debug)
{
checkMesh( true );
}
}
@ -522,6 +656,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr),
oldPointsPtr_(nullptr)
{
if (time().writeFormat() == IOstream::COHERENT)
{
this->checkOut( allPoints_ );
this->checkOut( allFaces_ );
this->checkOut( owner_ );
this->checkOut( neighbour_ );
}
// Check if the faces and cells are valid
forAll (allFaces_, faceI)
{
@ -684,6 +826,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr),
oldPointsPtr_(nullptr)
{
if (time().writeFormat() == IOstream::COHERENT)
{
this->checkOut( allPoints_ );
this->checkOut( allFaces_ );
this->checkOut( owner_ );
this->checkOut( neighbour_ );
}
// Check if the faces and cells are valid
forAll (allFaces_, faceI)
{
@ -1419,5 +1569,133 @@ Foam::label Foam::polyMesh::findCell
}
}
template<typename T>
Foam::labelList determineOffsets2D( const T& input2DList )
{
Foam::label offset = 0;
Foam::labelList offsets( input2DList.size() + 1, 0 );
forAll( input2DList, i )
{
offset += input2DList[i].size();
offsets[ i+1 ] = offset;
}
return offsets;
}
bool Foam::polyMesh::write() const
{
if (time().writeFormat() == IOstream::COHERENT)
{
// Write mesh to a separate file
auto path = pointsInstance()/meshDir();
auto sliceStreamPtr = SliceWriting{}.createStream();
sliceStreamPtr->access("mesh", path);
SlicePermutation sliceablePermutation{ *this };
faceList sliceFaces = sliceablePermutation.retrieveFaces();
// Linearize faces and points
label k = 0;
Foam::label linearSizeOfFaces =
std::accumulate
(
allFaces_.begin(),
allFaces_.end(),
0,
[] (label size, Foam::face input)
{
return std::move(size) + input.size();
}
);
Foam::List<Foam::label> linearizedFaces( linearSizeOfFaces, 0 );
forAll( sliceFaces, i )
{
forAll( sliceFaces[i], j )
{
linearizedFaces[k] = sliceFaces[i][j];
++k;
}
}
auto faceStarts = determineOffsets2D( sliceFaces ); // Generate offsets of linearized face list
sliceStreamPtr->put
(
"faceStarts",
{faceStarts.size()},
{0},
{faceStarts.size()},
faceStarts.cdata()
);
sliceStreamPtr->put
(
"faces",
{linearizedFaces.size()},
{0},
{linearizedFaces.size()},
linearizedFaces.cdata()
);
sliceFaces.clear();
Foam::labelList sliceOwner(owner_);
sliceablePermutation.apply(sliceOwner);
// Generate ownerStarts
// - Takes into account if cell is not owning any faces.
labelList ownerStarts( cells().size() + 1, 0 );
for (const auto& ownerId : sliceOwner )
{
ownerStarts[ownerId+1] += 1;
}
for ( label ownerId = 1; ownerId < ownerStarts.size(); ++ownerId )
{
ownerStarts[ownerId] += ownerStarts[ownerId-1];
}
sliceStreamPtr->put
(
"ownerStarts",
{ownerStarts.size()},
{0},
{ownerStarts.size()},
ownerStarts.cdata()
);
sliceOwner.clear();
// Generate local neighbours
Foam::labelList sliceNeighbours;
sliceablePermutation.retrieveNeighbours( sliceNeighbours, *this );
sliceStreamPtr->put
(
"neighbours",
{sliceNeighbours.size()},
{0},
{sliceNeighbours.size()},
sliceNeighbours.cdata()
);
sliceStreamPtr->bufferSync();
sliceNeighbours.clear();
ownerStarts.clear();
linearizedFaces.clear();
faceStarts.clear();
Foam::pointField slicePoints( allPoints_ );
sliceablePermutation.apply( slicePoints );
sliceWritePrimitives
(
"mesh",
path,
"points",
slicePoints.size(),
slicePoints.cdata()
);
slicePoints.clear();
auto repo = SliceStreamRepo::instance();
repo->close();
}
return regIOobject::write();
}
// ************************************************************************* //

View file

@ -615,6 +615,11 @@ public:
// IOstream Operators
friend Ostream& operator<<(Ostream&, const polyMesh&);
// Writing
//- Write using setting from DB
bool write() const;
};

View file

@ -557,6 +557,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr),
oldPointsPtr_(nullptr)
{
if (time().writeFormat() == IOstream::COHERENT)
{
this->checkOut( allPoints_ );
this->checkOut( allFaces_ );
this->checkOut( owner_ );
this->checkOut( neighbour_ );
}
if (debug)
{
Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
@ -843,6 +851,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr),
oldPointsPtr_(nullptr)
{
//if (time().writeFormat() == IOstream::COHERENT)
//{
//this->checkOut( allPoints_ );
//this->checkOut( allFaces_ );
//this->checkOut( owner_ );
//this->checkOut( neighbour_ );
//}
if (debug)
{
Info<<"Constructing polyMesh from cell and boundary shapes." << endl;

View file

@ -166,6 +166,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr),
oldPointsPtr_(nullptr)
{
if (time().writeFormat() == IOstream::COHERENT)
{
this->checkOut( allPoints_ );
this->checkOut( allFaces_ );
this->checkOut( owner_ );
this->checkOut( neighbour_ );
}
// Check if the faces and cells are valid
forAll (allFaces_, faceI)
{

View file

@ -188,7 +188,7 @@ void Foam::PackedBoolList::set(const PackedList<1>& lst)
}
Foam::label Foam::PackedBoolList::set(const UList<label>& indices)
Foam::label Foam::PackedBoolList::set(const Foam::UList<label>& indices)
{
return setIndices(indices);
}
@ -216,7 +216,7 @@ void Foam::PackedBoolList::unset(const PackedList<1>& lst)
}
Foam::label Foam::PackedBoolList::unset(const UList<label>& indices)
Foam::label Foam::PackedBoolList::unset(const Foam::UList<label>& indices)
{
return unsetIndices(indices);
}
@ -249,7 +249,7 @@ void Foam::PackedBoolList::subset(const PackedList<1>& lst)
}
Foam::label Foam::PackedBoolList::subset(const UList<label>& indices)
Foam::label Foam::PackedBoolList::subset(const Foam::UList<label>& indices)
{
return subsetIndices(indices);
}

View file

@ -119,7 +119,7 @@ public:
//- Construct from a list of labels
// using the labels as indices to indicate which bits are set
explicit inline PackedBoolList(const UList<label>& indices);
explicit inline PackedBoolList(const Foam::UList<label>& indices);
//- Construct from a list of labels
// using the labels as indices to indicate which bits are set
@ -141,7 +141,7 @@ public:
//- Set the listed indices. Return number of elements changed.
// Does auto-vivify for non-existent entries.
label set(const UList<label>& indices);
label set(const Foam::UList<label>& indices);
//- Set the listed indices. Return number of elements changed.
// Does auto-vivify for non-existent entries.
@ -152,7 +152,7 @@ public:
//- Unset the listed indices. Return number of elements changed.
// Never auto-vivify entries.
label unset(const UList<label>& indices);
label unset(const Foam::UList<label>& indices);
//- Unset the listed indices. Return number of elements changed.
// Never auto-vivify entries.
@ -163,7 +163,7 @@ public:
//- Subset with the listed indices.
// Return number of elements subsetted.
label subset(const UList<label>& indices);
label subset(const Foam::UList<label>& indices);
//- Subset with the listed indices.
// Return number of elements subsetted.
@ -204,7 +204,7 @@ public:
//- Assignment operator,
// using the labels as indices to indicate which bits are set
inline PackedBoolList& operator=(const UList<label>& indices);
inline PackedBoolList& operator=(const Foam::UList<label>& indices);
//- Assignment operator,
// using the labels as indices to indicate which bits are set
@ -218,7 +218,7 @@ public:
//- And operator (lists may be dissimilar sizes)
// using the labels as indices to indicate which bits are set
inline PackedBoolList& operator&=(const UList<label>& indices);
inline PackedBoolList& operator&=(const Foam::UList<label>& indices);
//- And operator (lists may be dissimilar sizes)
// using the labels as indices to indicate which bits are set
@ -233,7 +233,7 @@ public:
//- Or operator (lists may be dissimilar sizes),
// using the labels as indices to indicate which bits are set
inline PackedBoolList& operator|=(const UList<label>& indices);
inline PackedBoolList& operator|=(const Foam::UList<label>& indices);
//- Or operator (lists may be dissimilar sizes),
// using the labels as indices to indicate which bits are set
@ -244,7 +244,7 @@ public:
inline PackedBoolList& operator+=(const PackedList<1>&);
//- Add entries to this list, synonymous with the or operator
inline PackedBoolList& operator+=(const UList<label>& indices);
inline PackedBoolList& operator+=(const Foam::UList<label>& indices);
//- Add entries to this list, synonymous with the or operator
inline PackedBoolList& operator+=(const UIndirectList<label>&);
@ -253,7 +253,7 @@ public:
inline PackedBoolList& operator-=(const PackedList<1>&);
//- Remove entries from this list - unset the specified bits
inline PackedBoolList& operator-=(const UList<label>& indices);
inline PackedBoolList& operator-=(const Foam::UList<label>& indices);
//- Remove entries from this list - unset the specified bits
inline PackedBoolList& operator-=(const UIndirectList<label>&);

View file

@ -81,7 +81,7 @@ inline Foam::PackedBoolList::PackedBoolList(const Foam::UList<bool>& lst)
}
inline Foam::PackedBoolList::PackedBoolList(const UList<label>& indices)
inline Foam::PackedBoolList::PackedBoolList(const Foam::UList<label>& indices)
:
PackedList<1>(indices.size(), 0u)
{
@ -151,7 +151,7 @@ Foam::PackedBoolList::operator=(const PackedList<1>& lst)
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator=(const UList<label>& indices)
Foam::PackedBoolList::operator=(const Foam::UList<label>& indices)
{
clear();
set(indices);
@ -189,7 +189,7 @@ Foam::PackedBoolList::operator&=(const PackedList<1>& lst)
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator&=(const UList<label>& indices)
Foam::PackedBoolList::operator&=(const Foam::UList<label>& indices)
{
subset(indices);
return *this;
@ -213,7 +213,7 @@ Foam::PackedBoolList::operator|=(const PackedList<1>& lst)
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator|=(const UList<label>& indices)
Foam::PackedBoolList::operator|=(const Foam::UList<label>& indices)
{
set(indices);
return *this;
@ -236,7 +236,7 @@ Foam::PackedBoolList::operator+=(const PackedList<1>& lst)
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator+=(const UList<label>& indices)
Foam::PackedBoolList::operator+=(const Foam::UList<label>& indices)
{
return operator|=(indices);
}
@ -258,7 +258,7 @@ Foam::PackedBoolList::operator-=(const PackedList<1>& lst)
inline Foam::PackedBoolList&
Foam::PackedBoolList::operator-=(const UList<label>& indices)
Foam::PackedBoolList::operator-=(const Foam::UList<label>& indices)
{
unset(indices);
return *this;

View file

@ -390,6 +390,24 @@ public:
}
};
template<class T>
class eqEqTuple2
{
public:
T operator()(const T& x, const T& y) const
{
if(!x.first() || !y.first())
{
return T(false, x.second());
}
else
{
return T(x.second() == y.second(), x.second());
}
}
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View file

@ -200,7 +200,7 @@ Foam::word Foam::fileName::name() const
}
Foam::string Foam::fileName::caseName() const
Foam::string Foam::fileName::caseName(const string prefix) const
{
string cName = *this;
@ -214,7 +214,15 @@ Foam::string Foam::fileName::caseName() const
}
else
{
return cName.replace(i, caseStr.size(), string("$FOAM_CASE"));
if (prefix.empty())
{
// Additionaly remove the leading delimeter
return cName.erase(i, caseStr.size()+1);
}
else
{
return cName.replace(i, caseStr.size(), prefix);
}
}
}

View file

@ -180,7 +180,7 @@ public:
word name() const;
//- Return file name (part beyond last /), subsitute for FOAM_CASE
string caseName() const;
string caseName(const string prefix="$FOAM_CASE") const;
//- Return file name, optionally without extension
word name(const bool noExt) const;

View file

@ -60,7 +60,7 @@ Foam::Particle<ParticleType>::Particle
is >> origProc_ >> origId_;
}
}
else
else if (is.format() == IOstream::BINARY)
{
// In binary read all particle data - needed for parallel transfer
if (readFields)
@ -88,6 +88,8 @@ Foam::Particle<ParticleType>::Particle
);
}
}
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in ParticleIO.C\n"; }
if (celli_ == -1)
{
@ -187,7 +189,7 @@ void Foam::Particle<ParticleType>::write(Ostream& os, bool writeFields) const
<< token::SPACE << celli_;
}
}
else
else if (os.format() == IOstream::BINARY)
{
// In binary write both celli_ and facei_, needed for parallel transfer
if (writeFields)
@ -215,6 +217,8 @@ void Foam::Particle<ParticleType>::write(Ostream& os, bool writeFields) const
);
}
}
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in ParticleIO.C\n"; }
// Check state of Ostream
os.check("Particle<ParticleType>::write(Ostream& os, bool) const");