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 writeCellDist = args.optionFound("cellDist");
bool copyUniform = args.optionFound("copyUniform"); bool copyUniform = args.optionFound("copyUniform");
bool decomposeMeshOnly = args.optionFound("mesh");
bool decomposeFieldsOnly = args.optionFound("fields"); bool decomposeFieldsOnly = args.optionFound("fields");
bool filterPatches = args.optionFound("filterPatches"); bool filterPatches = args.optionFound("filterPatches");
bool forceOverwrite = args.optionFound("force"); bool forceOverwrite = args.optionFound("force");
@ -136,9 +137,9 @@ int main(int argc, char *argv[])
( (
runTime.path() runTime.path()
/(word("processor") + name(nProcs)) /(word("processor") + name(nProcs))
/runTime.constant() ///runTime.constant()
/regionDir ///regionDir
/polyMesh::meshSubDir ///polyMesh::meshSubDir
) )
) )
{ {
@ -263,7 +264,6 @@ int main(int argc, char *argv[])
) )
); );
// Decompose the mesh // Decompose the mesh
if (!decomposeFieldsOnly) if (!decomposeFieldsOnly)
{ {
@ -271,61 +271,11 @@ int main(int argc, char *argv[])
meshDecomp.writeDecomposition(); meshDecomp.writeDecomposition();
if (writeCellDist) SliceStreamRepo::instance()->clear();
}
if (!decomposeMeshOnly)
{ {
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;
}
}
// Search for list of objects for this time // Search for list of objects for this time
IOobjectList objects(mesh, runTime.timeName()); IOobjectList objects(mesh, runTime.timeName());
@ -361,242 +311,6 @@ int main(int argc, char *argv[])
PtrList<surfaceTensorField> surfaceTensorFields; PtrList<surfaceTensorField> surfaceTensorFields;
readFields(mesh, objects, 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? // Any uniform data to copy/link?
fileName uniformDir("uniform"); fileName uniformDir("uniform");
@ -613,6 +327,72 @@ int main(int argc, char *argv[])
Info<< endl; 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 // Split the fields over processors
for (label procI = 0; procI < meshDecomp.nProcs(); procI++) for (label procI = 0; procI < meshDecomp.nProcs(); procI++)
{ {
@ -741,123 +521,6 @@ int main(int argc, char *argv[])
fieldDecomposer.decomposeFields(surfaceTensorFields); 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? // Any non-decomposed data to copy?
if (uniformDir.size()) if (uniformDir.size())
{ {
@ -889,176 +552,10 @@ int main(int argc, char *argv[])
} }
} }
} }
} }
} // for-loop on procI
} // if ( IOstream::COHERENT )
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);
}
}
}
Info<< "\nEnd.\n" << endl; Info<< "\nEnd.\n" << endl;

View file

@ -34,36 +34,35 @@
export WM_PROJECT=foam export WM_PROJECT=foam
export WM_FORK=extend 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 # helps to easily write #ifdefs to detect a dev-version
export FOAM_DEV=1 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 # This can be removed if an absolute path is provided for WM_PROJECT_DIR
# $foamInstall below to where FOAM is installed # later on in this file
# # --
# Location of FOAM installation projectDir="${BASH_SOURCE:-${ZSH_NAME:+$0}}";
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ [ -n "$projectDir" ] && projectDir="$(\cd $(dirname $projectDir)/.. && \pwd -L)" ||\
foamInstall=$HOME/$WM_PROJECT projectDir="$HOME/openfoam/foam-extend-$WM_PROJECT_VERSION"
# foamInstall=~$WM_PROJECT
# foamInstall=/usr/local/$WM_PROJECT
# foamInstall=/opt/$WM_PROJECT
# foamInstall=/usr/lib
#
# END OF (NORMAL) USER EDITABLE PART
################################################################################ ################################################################################
# Set $USER if it has not been set (eg. on Windows/MSYS systems) # Set $USER if it has not been set (eg. on Windows/MSYS systems)
if [ -z $USER ] if [ -z "$USER" ]
then then
export USER=`whoami` export USER="$(whoami)"
fi fi
# note the location for later use (eg, in job scripts) # 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 # The old dirs to be cleaned from the various environment variables
# - remove anything under top-level directory. # - remove anything under top-level directory.
@ -74,16 +73,17 @@ then
foamOldDirs="$WM_PROJECT_INST_DIR $foamOldDirs" foamOldDirs="$WM_PROJECT_INST_DIR $foamOldDirs"
fi fi
# Location of site/user files # Location of site/user files
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~
export WM_PROJECT_INST_DIR=$FOAM_INST_DIR 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 export WM_PROJECT_USER_DIR=$HOME/$WM_PROJECT/$USER-$WM_PROJECT_VERSION
# Location of third-party software # Location of third-party software
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#: ${WM_THIRD_PARTY_DIR=$WM_PROJECT_INST_DIR/ThirdParty-$WM_PROJECT_VERSION}; export WM_THIRD_PARTY_DIR #: ${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 export WM_THIRD_PARTY_DIR=$WM_PROJECT_DIR/ThirdParty
# Enabling the usage of third-party software # Enabling the usage of third-party software
@ -101,15 +101,15 @@ export WM_THIRD_PARTY_DIR=$WM_PROJECT_DIR/ThirdParty
# #
# For AllMake.stage3 # For AllMake.stage3
export METIS_SYSTEM=1 #export METIS_SYSTEM=1
#export WM_THIRD_PARTY_USE_METIS_510=1 export WM_THIRD_PARTY_USE_METIS_510=1
export WM_THIRD_PARTY_USE_PARMGRIDGEN_10=1 export WM_THIRD_PARTY_USE_PARMGRIDGEN_10=1
#export WM_THIRD_PARTY_USE_LIBCCMIO_261=1 #export WM_THIRD_PARTY_USE_LIBCCMIO_261=1
export WM_THIRD_PARTY_USE_MESQUITE_230=1 export WM_THIRD_PARTY_USE_MESQUITE_230=1
export SCOTCH_SYSTEM=1 #export SCOTCH_SYSTEM=1
#export WM_THIRD_PARTY_USE_SCOTCH_604=1 export WM_THIRD_PARTY_USE_SCOTCH_604=1
export PARMETIS_SYSTEM=1 #export PARMETIS_SYSTEM=1
#export WM_THIRD_PARTY_USE_PARMETIS_403=1 export WM_THIRD_PARTY_USE_PARMETIS_403=1
export WM_THIRD_PARTY_USE_PYFOAM_069=1 export WM_THIRD_PARTY_USE_PYFOAM_069=1
export WM_THIRD_PARTY_USE_HWLOC_201=1 export WM_THIRD_PARTY_USE_HWLOC_201=1
export WM_THIRD_PARTY_USE_ADIOS2_291=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_PRECISION_OPTION:=DP}; export WM_PRECISION_OPTION
# WM_LABEL_SIZE = 32 | 64 # 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 | Debug | Prof
: ${WM_COMPILE_OPTION:=Opt}; export WM_COMPILE_OPTION : ${WM_COMPILE_OPTION:=Opt}; export WM_COMPILE_OPTION
@ -601,7 +601,7 @@ fi
# cleanup environment: # cleanup environment:
# ~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~
unset cleanEnv cleanProg foamInstall foamOldDirs unset cleanEnv cleanProg projectDir foamInstall foamOldDirs
unset _foamSource unset _foamSource
# ----------------------------------------------------------------------------- # -----------------------------------------------------------------------------

View file

@ -128,14 +128,6 @@ void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
Pout<< "\nCalculating original mesh data" << endl; 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 // loop through the list of processor labels for the cell and add the
// cell shape to the list of cells for the appropriate processor // cell shape to the list of cells for the appropriate processor
@ -164,17 +156,32 @@ void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
} }
// Convert linked lists into normal lists // 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]; procCellAddressing_[procI] = procCellList[procI];
} }
} }
if (mesh_.time().writeFormat() == IOstream::COHERENT)
{
Info << "Skipping stones." << endl;
}
if (mesh_.time().writeFormat() != IOstream::COHERENT)
{
if (debug) if (debug)
{ {
Pout << "\nDistributing faces to processors" << endl; 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 // Loop through internal faces and decide which processor they belong to
// First visit all internal faces. If cells at both sides belong to the // First visit all internal faces. If cells at both sides belong to the
// same processor, the face is an internal face. If they are different, // same processor, the face is an internal face. If they are different,
@ -1218,6 +1225,7 @@ void Foam::domainDecomposition::decomposeMesh(const bool filterEmptyPatches)
sort(globallySharedPoints_); sort(globallySharedPoints_);
} }
} }
}
// ************************************************************************* // // ************************************************************************* //

View file

@ -36,6 +36,9 @@ License
#include "DynamicList.H" #include "DynamicList.H"
#include "globalMeshData.H" #include "globalMeshData.H"
#include "sliceMeshHelper.H"
#include "sliceWritePrimitives.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::domainDecomposition, 0); defineTypeNameAndDebug(Foam::domainDecomposition, 0);
@ -87,6 +90,162 @@ Foam::domainDecomposition::~domainDecomposition()
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * 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 Foam::autoPtr<Foam::fvMesh> Foam::domainDecomposition::processorMesh
( (
const label procI, const label procI,
@ -530,6 +689,21 @@ bool Foam::domainDecomposition::writeDecomposition()
{ {
Info<< "\nConstructing processor meshes" << endl; 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 // Make a lookup map for globally shared points
Map<label> sharedPointLookup(2*globallySharedPoints_.size()); Map<label> sharedPointLookup(2*globallySharedPoints_.size());
@ -577,7 +751,6 @@ bool Foam::domainDecomposition::writeDecomposition()
labelField(mesh_.nPoints(), 0) labelField(mesh_.nPoints(), 0)
); );
// Write out the meshes // Write out the meshes
for (label procI = 0; procI < nProcs_; procI++) for (label procI = 0; procI < nProcs_; procI++)
{ {
@ -757,6 +930,8 @@ bool Foam::domainDecomposition::writeDecomposition()
<< "Max number of faces between processors = " << maxProcFaces << "Max number of faces between processors = " << maxProcFaces
<< endl; << endl;
}
return true; return true;
} }

View file

@ -45,6 +45,8 @@ SourceFiles
#include "globalProcFaceIndex.H" #include "globalProcFaceIndex.H"
#include "globalProcPointIndex.H" #include "globalProcPointIndex.H"
#include "sliceMeshHelper.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -113,6 +115,12 @@ class domainDecomposition
//- Original patch index for every processor patch //- Original patch index for every processor patch
labelListList procBoundaryAddressing_; 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 //- Sizes for processor mesh patches
// Excludes inter-processor boundaries // Excludes inter-processor boundaries
labelListList procPatchSize_; labelListList procPatchSize_;
@ -217,6 +225,12 @@ public:
// Decomposed mesh and addressing // Decomposed mesh and addressing
autoPtr<fvMesh> parallelMesh
(
const Time& procDb,
const word& regionName
);
//- Create a decomposed mesh for a given processor index //- Create a decomposed mesh for a given processor index
// Note: at the point of construction, the boundary is marked // Note: at the point of construction, the boundary is marked
// as invalid. If the mesh should be used immediately upon // as invalid. If the mesh should be used immediately upon
@ -257,6 +271,26 @@ public:
return procBoundaryAddressing_; 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 //- Write decomposition
bool writeDecomposition(); bool writeDecomposition();

View file

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

View file

@ -68,6 +68,25 @@ void GeometricField<scalar, fvPatchField, volMesh>::replace
*this == gsf; *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 } // End namespace Foam

View file

@ -42,6 +42,7 @@ SourceFiles
#include "volFieldsFwd.H" #include "volFieldsFwd.H"
#include "calculatedFvPatchFields.H" #include "calculatedFvPatchFields.H"
#include "fvMatrices.H" #include "fvMatrices.H"
#include "IFCstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -64,6 +65,16 @@ void GeometricField<scalar, fvPatchField, volMesh>::replace
const GeometricField<scalar, fvPatchField, volMesh>& sf 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/global.Cver
global/dimensionedConstants/dimensionedConstants.C global/dimensionedConstants/dimensionedConstants.C
global/argList/argList.C global/argList/argList.C
global/argList/parRun.C
global/clock/clock.C global/clock/clock.C
global/controlSwitches/debugSwitch.C global/controlSwitches/debugSwitch.C
@ -99,6 +100,9 @@ coordinateSystems/coordinateRotation/axisCoordinateRotation.C
primitives/random/Random.C primitives/random/Random.C
containers/Lists/UList/DebugIOUList.C
containers/Lists/List/DebugIOList.C
containers/HashTables/HashTable/HashTableCore.C containers/HashTables/HashTable/HashTableCore.C
containers/HashTables/StaticHashTable/StaticHashTableCore.C containers/HashTables/StaticHashTable/StaticHashTableCore.C
containers/Lists/ListOps/ListOps.C containers/Lists/ListOps/ListOps.C
@ -126,6 +130,7 @@ $(Streams)/token/tokenIO.C
IOstreams = $(Streams)/IOstreams IOstreams = $(Streams)/IOstreams
$(IOstreams)/IOstream.C $(IOstreams)/IOstream.C
$(IOstreams)/IOstreamOption.C
$(IOstreams)/Istream.C $(IOstreams)/Istream.C
$(IOstreams)/Ostream.C $(IOstreams)/Ostream.C
@ -609,11 +614,16 @@ $(meshTools)/meshTools.C
$(meshTools)/matchPoints.C $(meshTools)/matchPoints.C
$(meshTools)/mergePoints.C $(meshTools)/mergePoints.C
fields/DimensionedFields/DimensionedField/DebugIODimensionedField.C
fields/UniformDimensionedFields/uniformDimensionedFields.C fields/UniformDimensionedFields/uniformDimensionedFields.C
fields/cloud/cloud.C fields/cloud/cloud.C
fields/cloudDistribute/cloudDistribute.C fields/cloudDistribute/cloudDistribute.C
Fields = fields/Fields Fields = fields/Fields
$(Fields)/Field/DebugIOField.C
$(Fields)/labelField/labelField.C $(Fields)/labelField/labelField.C
$(Fields)/scalarField/scalarField.C $(Fields)/scalarField/scalarField.C
$(Fields)/vectorField/vectorField.C $(Fields)/vectorField/vectorField.C

View file

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

View file

@ -204,7 +204,7 @@ public:
os << pHit.hit_ << token::SPACE << pHit.hitPoint_ os << pHit.hit_ << token::SPACE << pHit.hitPoint_
<< token::SPACE << pHit.index_; << token::SPACE << pHit.index_;
} }
else else if (os.format() == IOstream::BINARY)
{ {
os.write os.write
( (
@ -212,6 +212,8 @@ public:
sizeof(PointIndexHit) sizeof(PointIndexHit)
); );
} }
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in PointIndexHitTemplate.H"; }
// Check state of Ostream // Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const PointIndexHit&)"); os.check("Ostream& operator<<(Ostream&, const PointIndexHit&)");
@ -225,7 +227,7 @@ public:
{ {
return is >> pHit.hit_ >> pHit.hitPoint_ >> pHit.index_; return is >> pHit.hit_ >> pHit.hitPoint_ >> pHit.index_;
} }
else else if (is.format() == IOstream::BINARY)
{ {
is.read is.read
( (
@ -233,6 +235,8 @@ public:
sizeof(PointIndexHit) sizeof(PointIndexHit)
); );
} }
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in PointIndexHitTemplate.H"; }
// Check state of Istream // Check state of Istream
is.check("Istream& operator>>(Istream&, PointIndexHit&)"); 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 // Read end of contents
is.readEndList("FixedList"); is.readEndList("FixedList");
} }
else else if (is.format() == IOstream::BINARY)
{ {
is.read(reinterpret_cast<char*>(L.data()), Size*sizeof(T)); 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" "reading the binary block"
); );
} }
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in FixedListIO.C\n"; }
return is; return is;
} }
@ -228,10 +230,12 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const FixedList<T, Size>& L)
os << nl << token::END_LIST << nl; os << nl << token::END_LIST << nl;
} }
} }
else else if (os.format() == IOstream::BINARY)
{ {
os.write(reinterpret_cast<const char*>(L.cdata()), Size*sizeof(T)); 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 // Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const FixedList&)"); os.check("Ostream& operator<<(Ostream&, const FixedList&)");

View file

@ -257,6 +257,12 @@ Foam::List<T>::List(const BiIndirectList<T>& lst)
allocCopyList(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 * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * * //

View file

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

View file

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

View file

@ -28,14 +28,27 @@ License
#include "token.H" #include "token.H"
#include "SLList.H" #include "SLList.H"
#include "contiguous.H" #include "contiguous.H"
#include <iostream>
#include "Ostream.H"
#include "prefixOSstream.H"
// * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * // // * * * * * * * * * * * * * * * IOstream Operators * * * * * * * * * * * * //
namespace Foam {
extern prefixOSstream Pout;
}
template<class T> template<class T>
Foam::List<T>::List(Istream& is) Foam::List<T>::List(Istream& is)
: :
UList<T>(nullptr, 0) UList<T>(nullptr, 0)
{ {
if (List<T>::debug)
{
Pout<< "List<T>::List(Istream& is)" << endl;
}
operator>>(is, *this); operator>>(is, *this);
} }
@ -43,6 +56,11 @@ Foam::List<T>::List(Istream& is)
template<class T> template<class T>
Foam::Istream& Foam::operator>>(Istream& is, List<T>& list) Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
{ {
if (List<T>::debug)
{
Pout<< "ListIO: operator>>, start" << endl;
}
// Anull list // Anull list
list.resize(0); list.resize(0);
@ -55,6 +73,11 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
// Compound: simply transfer contents // Compound: simply transfer contents
if (firstToken.isCompound()) if (firstToken.isCompound())
{ {
if (List<T>::debug)
{
Pout<< "ListIO: operator>>, transfering compound token" << endl;
}
list.transfer list.transfer
( (
dynamicCast<token::Compound<List<T> > > dynamicCast<token::Compound<List<T> > >
@ -72,12 +95,45 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
{ {
const label len = firstToken.labelToken(); const label len = firstToken.labelToken();
if (List<T>::debug)
{
Pout<< "ListIO: operator>>, reading a list of size " << len << endl;
}
if (is.format() != IOstream::COHERENT)
{
// Resize to length read // Resize to length read
list.resize(len); list.resize(len);
}
// Read list contents depending on data format // Read list contents depending on data format
if (is.format() == IOstream::ASCII || !contiguous<T>()) if (is.format() == IOstream::ASCII || !contiguous<T>())
{
if (is.format() == IOstream::COHERENT)
{
// 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)
{
Pout<< "List read via COHERENT = " << nl << list << endl;
}
}
else
{ {
// Read beginning of contents // Read beginning of contents
const char delimiter = is.readBeginList("List"); const char delimiter = is.readBeginList("List");
@ -120,7 +176,8 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
// Read end of contents // Read end of contents
is.readEndList("List"); is.readEndList("List");
} }
else if (len) }
else if (len && is.format() == IOstream::BINARY)
{ {
// Non-empty, binary, contiguous // Non-empty, binary, contiguous
@ -132,6 +189,22 @@ Foam::Istream& Foam::operator>>(Istream& is, List<T>& list)
"reading the binary block" "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; return is;
} }

View file

@ -320,7 +320,7 @@ Foam::Istream& Foam::PackedList<nBits>::read(Istream& is)
// Read end of contents // Read end of contents
is.readEndList("PackedList<nBits>"); is.readEndList("PackedList<nBits>");
} }
else else if (is.format() == IOstream::BINARY)
{ {
if (sz) 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()) else if (firstTok.isPunctuation())
{ {
@ -485,7 +487,7 @@ Foam::Ostream& Foam::PackedList<nBits>::write
os << nl << token::END_LIST << nl; os << nl << token::END_LIST << nl;
} }
} }
else else if (os.format() == IOstream::BINARY)
{ {
os << nl << sz << nl; os << nl << sz << nl;
if (sz) 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; return os;
} }

View file

@ -97,7 +97,7 @@ Foam::Ostream& Foam::operator<<
os << nl << token::END_LIST << nl; os << nl << token::END_LIST << nl;
} }
} }
else else if (os.format() == IOstream::BINARY)
{ {
// this is annoying, and wasteful, but there's currently no alternative // 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 // Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const UIndirectList&)"); os.check("Ostream& operator<<(Ostream&, const UIndirectList&)");

View file

@ -47,11 +47,15 @@ SourceFiles
#include "uLabel.H" #include "uLabel.H"
#include "nullObject.H" #include "nullObject.H"
#include "className.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
{ {
TemplateName(DebugIOUList);
// Forward declaration of friend classes // Forward declaration of friend classes
template<class T> class List; template<class T> class List;
template<class T> class SubList; template<class T> class SubList;
@ -69,6 +73,8 @@ typedef UList<label> labelUList;
template<class T> template<class T>
class UList class UList
:
public DebugIOUListName
{ {
// Private data // Private data
@ -159,7 +165,6 @@ public:
// i.e. contiguous<T>() == true // i.e. contiguous<T>() == true
label byteSize() const; label byteSize() const;
//- Return a const pointer to the first data element, //- Return a const pointer to the first data element,
// similar to the STL front() method and the string::data() method // similar to the STL front() method and the string::data() method
// This can be used (with caution) when interfacing with C code. // 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> template<class T>
inline void reverse(UList<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> template<class T>
inline void Foam::reverse(UList<T>& ul) 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 "token.H"
#include "SLList.H" #include "SLList.H"
#include "contiguous.H" #include "contiguous.H"
#include <iostream>
#include "prefixOSstream.H"
#include "UListProxy.H"
// * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Ostream Operator * * * * * * * * * * * * * //
namespace Foam {
extern prefixOSstream Pout;
}
template<class T> template<class T>
void Foam::UList<T>::writeEntry(Ostream& os) const void Foam::UList<T>::writeEntry(Ostream& os) const
{ {
if (debug)
{
Pout<< "UList<T>::writeEntry(Ostream&): List< ... >" << endl;
}
if if
( (
size() size()
@ -53,6 +66,11 @@ void Foam::UList<T>::writeEntry(Ostream& os) const
template<class T> template<class T>
void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const
{ {
if (debug)
{
Pout<< "UListIO::writeEntry keyword = " << keyword << endl;
}
os.writeKeyword(keyword); os.writeKeyword(keyword);
writeEntry(os); writeEntry(os);
os << token::END_STATEMENT << endl; os << token::END_STATEMENT << endl;
@ -62,9 +80,29 @@ void Foam::UList<T>::writeEntry(const word& keyword, Ostream& os) const
template<class T> template<class T>
Foam::Ostream& Foam::operator<<(Foam::Ostream& os, const Foam::UList<T>& L) 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 // Write list contents depending on data format
if (os.format() == IOstream::ASCII || !contiguous<T>()) 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; bool uniform = false;
if (L.size() > 1 && contiguous<T>()) 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 // Write end delimiter
os << token::END_LIST; 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 else
{ {
// Write size and start delimiter // 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; os << nl << token::END_LIST << nl;
} }
} }
else else if (os.format() == IOstream::BINARY)
{ {
os << nl << L.size() << nl; os << nl << L.size() << nl;
if (L.size()) 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()); 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 // Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const UList&)"); 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> template<class T>
Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L) 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>&)"); is.fatalCheck("operator>>(Istream&, UList<T>&)");
token firstToken(is); token firstToken(is);
@ -189,6 +267,12 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
if (is.format() == IOstream::ASCII || !contiguous<T>()) 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 // Read beginning of contents
char delimiter = is.readBeginList("List"); char delimiter = is.readBeginList("List");
@ -227,7 +311,7 @@ Foam::Istream& Foam::operator>>(Istream& is, UList<T>& L)
// Read end of contents // Read end of contents
is.readEndList("List"); is.readEndList("List");
} }
else else if (is.format() == IOstream::BINARY)
{ {
if (s) 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()) else if (firstToken.isPunctuation())
{ {

View file

@ -26,6 +26,7 @@ License
#include "IOobject.H" #include "IOobject.H"
#include "foamTime.H" #include "foamTime.H"
#include "IFstream.H" #include "IFstream.H"
#include "Pstream.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * 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 Foam::IOobject::headerOk()
{ {
bool ok = true; 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) void Foam::IOobject::setBad(const string& s)
{ {
if (objState_ != GOOD) if (objState_ != GOOD)

View file

@ -173,6 +173,10 @@ protected:
// exact file. The results is nullptr if the stream construction failed // exact file. The results is nullptr if the stream construction failed
Istream* objectStream(const fileName&); 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 //- Set the object state to bad
void setBad(const string&); void setBad(const string&);
@ -397,6 +401,7 @@ public:
//- Read and check header info //- Read and check header info
bool headerOk(); bool headerOk();
bool headerOkPar();
// Writing // Writing

View file

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

View file

@ -28,6 +28,8 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "IOobject.H" #include "IOobject.H"
#include "IOstreams.H"
#include "messageStream.H"
#include "objectRegistry.H" #include "objectRegistry.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -43,6 +45,14 @@ bool Foam::IOobject::writeHeader(Ostream& os, const word& type) const
return false; 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) writeBanner(os, false, true)
<< "FoamFile\n{\n" << "FoamFile\n{\n"
<< " version " << os.version() << ";\n" << " version " << os.version() << ";\n"

View file

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

View file

@ -182,10 +182,15 @@ bool Foam::CompactIOList<T, BaseType>::writeObject
return good; return good;
} }
else else if (fmt == IOstream::BINARY)
{ {
return regIOobject::writeObject(fmt, ver, cmp); 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); os << static_cast<const List<T>&>(L);
} }
else else if (os.format() == IOstream::BINARY)
{ {
// Convert to compact format // Convert to compact format
labelList start(L.size()+1); labelList start(L.size()+1);
@ -285,6 +290,8 @@ Foam::Ostream& Foam::operator<<
} }
os << start << elems; os << start << elems;
} }
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in CompactIOList.C\n"; }
return os; 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
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED || io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
) )
|| (io.readOpt() == IOobject::READ_IF_PRESENT && headerOk()) || (io.readOpt() == IOobject::READ_IF_PRESENT && headerOkPar())
|| (io.readOpt() == IOobject::READ_IF_PRESENT_IF_MODIFIED && headerOk()) || (io.readOpt() == IOobject::READ_IF_PRESENT_IF_MODIFIED && headerOkPar())
) )
{ {
readStream(typeName) >> *this; readStreamPar(typeName) >> *this;
close(); close();
} }
} }

View file

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

View file

@ -24,8 +24,32 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "IFstream.H" #include "IFstream.H"
#include "IOstream.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "debug.H"
#include "gzstream.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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * 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), ifPtr_(nullptr),
bufStr_(),
sliceStreamPtr_(nullptr),
compression_(IOstream::UNCOMPRESSED) compression_(IOstream::UNCOMPRESSED)
{ {
if (pathname.empty()) if (pathname.empty())
@ -48,7 +78,34 @@ Foam::IFstreamAllocator::IFstreamAllocator(const fileName& pathname)
} }
} }
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()); ifPtr_ = new ifstream(pathname.c_str());
}
// If the file is compressed, decompress it before reading. // If the file is compressed, decompress it before reading.
if (!ifPtr_->good() && isFile(pathname + ".gz", false)) if (!ifPtr_->good() && isFile(pathname + ".gz", false))
@ -68,6 +125,7 @@ Foam::IFstreamAllocator::IFstreamAllocator(const fileName& pathname)
compression_ = IOstream::COMPRESSED; compression_ = IOstream::COMPRESSED;
} }
} }
} }
@ -77,6 +135,12 @@ Foam::IFstreamAllocator::~IFstreamAllocator()
} }
void Foam::IFstreamAllocator::allocateAdios()
{
sliceStreamPtr_ = SliceReading{}.createStream();
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::IFstream::IFstream Foam::IFstream::IFstream
@ -86,7 +150,7 @@ Foam::IFstream::IFstream
versionNumber version versionNumber version
) )
: :
IFstreamAllocator(pathname), IFstreamAllocator(pathname, format),
ISstream ISstream
( (
*ifPtr_, *ifPtr_,
@ -95,7 +159,8 @@ Foam::IFstream::IFstream
version, version,
IFstreamAllocator::compression_ IFstreamAllocator::compression_
), ),
pathname_(pathname) pathname_(pathname),
tmpIssPtr_(nullptr)
{ {
setClosed(); setClosed();
@ -123,10 +188,15 @@ Foam::IFstream::IFstream
} }
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
Foam::IFstream::~IFstream() Foam::IFstream::~IFstream()
{} {
if (tmpIssPtr_)
{
delete tmpIssPtr_;
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * 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 const std::istream& Foam::IFstream::stdStream() const
{ {
if (!ifPtr_) 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 * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Operators * * * * * * * * * * * * * * //
Foam::IFstream& Foam::IFstream::operator()() const Foam::IFstream& Foam::IFstream::operator()() const

View file

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

View file

@ -25,7 +25,16 @@ License
#include "OFstream.H" #include "OFstream.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "OStringStream.H"
#include "UList.H"
#include "Pstream.H"
#include "gzstream.h" #include "gzstream.h"
#include "messageStream.H"
#include <iostream>
#include <memory>
#include "SliceStreamRepo.H"
#include "sliceWritePrimitives.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -38,6 +47,7 @@ Foam::OFstreamAllocator::OFstreamAllocator
( (
const fileName& pathname, const fileName& pathname,
ios_base::openmode mode, ios_base::openmode mode,
IOstream::streamFormat format,
IOstream::compressionType compression IOstream::compressionType compression
) )
: :
@ -52,6 +62,14 @@ Foam::OFstreamAllocator::OFstreamAllocator
} }
} }
if (format == IOstream::COHERENT)
{
// The file pointer is a buffer pointer in this case.
// The buffer is written to ADIOS in the destructor.
ofPtr_ = new std::ostringstream();
}
else
{
if (compression == IOstream::COMPRESSED) if (compression == IOstream::COMPRESSED)
{ {
// get identically named uncompressed version out of the way // get identically named uncompressed version out of the way
@ -73,6 +91,7 @@ Foam::OFstreamAllocator::OFstreamAllocator
ofPtr_ = new ofstream(pathname.c_str(), mode); ofPtr_ = new ofstream(pathname.c_str(), mode);
} }
} }
}
Foam::OFstreamAllocator::~OFstreamAllocator() Foam::OFstreamAllocator::~OFstreamAllocator()
@ -87,15 +106,27 @@ Foam::OFstream::OFstream
( (
const fileName& pathname, const fileName& pathname,
ios_base::openmode mode, ios_base::openmode mode,
streamFormat format, IOstreamOption streamOpt
versionNumber version,
compressionType compression
) )
: :
OFstreamAllocator(pathname, mode, compression), OFstreamAllocator
OSstream(*ofPtr_, "OFstream.sinkFile_", format, version, compression), (
pathname_(pathname) 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(); setClosed();
setState(ofPtr_->rdstate()); setState(ofPtr_->rdstate());
@ -122,13 +153,63 @@ Foam::OFstream::OFstream
// * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Destructors * * * * * * * * * * * * * * * //
Foam::OFstream::~OFstream() 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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * 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() std::ostream& Foam::OFstream::stdStream()
{ {
if (!ofPtr_) 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> #include <fstream>
using std::ofstream; using std::ofstream;
template<class T> class SLList;
#include "LIFOStack.H"
#include "uListProxyBase.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -67,8 +71,8 @@ class OFstreamAllocator
( (
const fileName& pathname, const fileName& pathname,
ios_base::openmode mode, ios_base::openmode mode,
IOstream::streamFormat format = IOstream::ASCII,
IOstream::compressionType compression = IOstream::UNCOMPRESSED IOstream::compressionType compression = IOstream::UNCOMPRESSED
); );
//- Destructor //- Destructor
@ -89,7 +93,12 @@ class OFstream
// Private data // Private data
fileName pathname_; fileName pathname_;
LIFOStack<word> blockNamesStack_;
//- String stream for temporary data written by ADIOS at destruction
OStringStream* tmpOssPtr_;
label boundaryCounter_{0};
public: public:
@ -99,20 +108,36 @@ public:
// Constructors // Constructors
//- Construct from pathname //- Default construct
OFstream OFstream
( (
const fileName& pathname, const fileName& pathname,
ios_base::openmode mode = ios_base::out|ios_base::trunc, 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, streamFormat format = ASCII,
versionNumber version = currentVersion, versionNumber version = currentVersion,
compressionType compression = UNCOMPRESSED compressionType compression = UNCOMPRESSED
); )
:
OFstream
(
pathname,
mode,
IOstreamOption(format, version, compression)
)
{}
// Destructor // Destructor
~OFstream(); virtual ~OFstream();
// Member functions // Member functions
@ -131,6 +156,19 @@ public:
return pathname_; 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 // STL stream
@ -145,6 +183,28 @@ public:
//- Print description of IOstream to Ostream //- Print description of IOstream to Ostream
void print(Ostream&) const; 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 // Define the default IOstream versions and precision
const IOstream::versionNumber IOstream::originalVersion(0.5); const IOstream::versionNumber IOstreamOption::originalVersion(0.5);
const IOstream::versionNumber IOstream::currentVersion(2.0); const IOstream::versionNumber IOstreamOption::currentVersion(2.0);
Foam::debug::infoSwitch Foam::debug::infoSwitch
IOstream::precision_ IOstream::precision_

View file

@ -207,6 +207,10 @@ inline Omanip<int> setprecision(const int i)
return Omanip<int>(&Ostream::precision, 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 "IOstream.H"
#include "error.H" #include "error.H"
#include "Switch.H"
#include <sstream> #include <sstream>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -35,57 +34,6 @@ Foam::fileName Foam::IOstream::name_("IOstream");
// * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * 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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -129,20 +77,8 @@ Foam::string Foam::IOstream::versionNumber::str() const
void Foam::IOstream::print(Ostream& os) const void Foam::IOstream::print(Ostream& os) const
{ {
os << "IOstream: " << "Version " << version_ << ", format "; os << "IOstream: " << "Version " << version() << ", format "
<< format() << ", line " << lineNumber();
switch (format_)
{
case ASCII:
os << "ASCII";
break;
case BINARY:
os << "BINARY";
break;
}
os << ", line " << lineNumber();
if (opened()) if (opened())
{ {
@ -205,29 +141,6 @@ void Foam::IOstream::print(Ostream& os, const int streamState) const
// * * * * * * * * * * * * * * * Friend Operators * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * 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 namespace Foam
{ {

View file

@ -42,14 +42,9 @@ SourceFiles
#ifndef IOstream_H #ifndef IOstream_H
#define IOstream_H #define IOstream_H
#include "char.H"
#include "bool.H"
#include "label.H"
#include "uLabel.H"
#include "scalar.H"
#include "fileName.H" #include "fileName.H"
#include "InfoProxy.H" #include "InfoProxy.H"
#include "infoSwitch.H" #include "IOstreamOption.H"
#include <iostream> #include <iostream>
@ -66,6 +61,8 @@ using std::cin;
using std::cout; using std::cout;
using std::cerr; using std::cerr;
typedef char parIOType;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam namespace Foam
@ -76,6 +73,8 @@ namespace Foam
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
class IOstream class IOstream
:
public IOstreamOption
{ {
public: public:
@ -83,138 +82,19 @@ public:
// Public data types // Public data types
//- Enumeration for whether the stream open or closed //- Enumeration for whether the stream open or closed
enum streamAccess enum streamAccess : char
{ {
OPENED, OPENED,
CLOSED 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 // Public static data
//- Original version number
static const versionNumber originalVersion;
//- Current version number
static const versionNumber currentVersion;
//- Default precision //- Default precision
static debug::infoSwitch precision_; static debug::infoSwitch precision_;
private: private:
// Private data // Private data
@ -222,10 +102,6 @@ private:
//- Name of the stream //- Name of the stream
static fileName name_; static fileName name_;
streamFormat format_;
versionNumber version_;
compressionType compression_;
streamAccess openClosed_; streamAccess openClosed_;
ios_base::iostate ioState_; ios_base::iostate ioState_;
@ -270,17 +146,10 @@ public:
// Constructors // Constructors
//- Construct setting format and version //- Default construct
IOstream IOstream(IOstreamOption streamOpt = IOstreamOption())
(
streamFormat format,
versionNumber version,
compressionType compression=UNCOMPRESSED
)
: :
format_(format), IOstreamOption(streamOpt),
version_(version),
compression_(compression),
openClosed_(CLOSED), openClosed_(CLOSED),
ioState_(ios_base::iostate(0)), ioState_(ios_base::iostate(0)),
lineNumber_(0) lineNumber_(0)
@ -288,6 +157,17 @@ public:
setBad(); setBad();
} }
//- Construct setting format and version
IOstream
(
IOstreamOption::streamFormat fmt,
IOstreamOption::versionNumber ver,
IOstreamOption::compressionType cmp = IOstreamOption::UNCOMPRESSED
)
:
IOstream(IOstreamOption(fmt, ver, cmp))
{}
// Destructor // Destructor
@ -377,70 +257,6 @@ public:
// Stream state functions // 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 //- Return current stream line number
label lineNumber() const 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) // ------ Manipulators (not taking arguments)
// -------------------------------------------------------------------- // --------------------------------------------------------------------

View file

@ -134,9 +134,14 @@ public:
//- Read binary block //- Read binary block
virtual Istream& read(char*, std::streamsize) = 0; 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 //- Rewind and return the stream so that it may be read again
virtual Istream& rewind() = 0; virtual Istream& rewind() = 0;
virtual Istream& readToStringStream(string&) = 0;
// Read List punctuation tokens // Read List punctuation tokens

View file

@ -28,6 +28,11 @@ License
#include "token.H" #include "token.H"
#include "keyType.H" #include "keyType.H"
#include "IOstreams.H" #include "IOstreams.H"
#include <iostream>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::Ostream, 0);
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
@ -58,6 +63,14 @@ Foam::Ostream& Foam::Ostream::write(const keyType& kw)
// Write the keyword followed by appropriate indentation // Write the keyword followed by appropriate indentation
Foam::Ostream& Foam::Ostream::writeKeyword(const keyType& kw) 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(); indent();
write(kw); write(kw);

View file

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

View file

@ -155,9 +155,17 @@ public:
//- Read binary block //- Read binary block
Istream& read(char*, std::streamsize); 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 //- Rewind and return the stream so that it may be read again
Istream& rewind(); Istream& rewind();
Istream& readToStringStream(string&)
{
return *this;
}
// Edit // 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 void Foam::OPstream::print(Ostream& os) const
{ {
os << "Writing from processor " << toProcNo_ os << "Writing from processor " << toProcNo_

View file

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

View file

@ -67,7 +67,7 @@ bool Foam::OPstream::write
const label comm const label comm
) )
{ {
if (debug) if (Pstream::debug)
{ {
Pout<< "OPstream::write : starting write to:" << toProcNo Pout<< "OPstream::write : starting write to:" << toProcNo
<< " tag:" << tag << " tag:" << tag
@ -104,7 +104,7 @@ bool Foam::OPstream::write
PstreamGlobals::MPICommunicators_[comm] // MPI_COMM_WORLD PstreamGlobals::MPICommunicators_[comm] // MPI_COMM_WORLD
); );
if (debug) if (Pstream::debug)
{ {
Pout<< "OPstream::write : finished write to:" << toProcNo Pout<< "OPstream::write : finished write to:" << toProcNo
<< " tag:" << tag << " size:" << label(bufSize) << " tag:" << tag << " size:" << label(bufSize)
@ -124,7 +124,7 @@ bool Foam::OPstream::write
PstreamGlobals::MPICommunicators_[comm] // MPI_COMM_WORLD PstreamGlobals::MPICommunicators_[comm] // MPI_COMM_WORLD
); );
if (debug) if (Pstream::debug)
{ {
Pout<< "OPstream::write : finished write to:" << toProcNo Pout<< "OPstream::write : finished write to:" << toProcNo
<< " tag:" << tag << " size:" << label(bufSize) << " tag:" << tag << " size:" << label(bufSize)
@ -147,7 +147,7 @@ bool Foam::OPstream::write
&request &request
); );
if (debug) if (Pstream::debug)
{ {
Pout<< "OPstream::write : started write to:" << toProcNo Pout<< "OPstream::write : started write to:" << toProcNo
<< " tag:" << tag << " size:" << label(bufSize) << " 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 void Foam::Pstream::allocatePstreamCommunicator
( (
const label parentIndex, const label parentIndex,
@ -445,9 +287,9 @@ Foam::label Foam::Pstream::allocateCommunicator
} }
parentCommunicator_[index] = parentIndex; parentCommunicator_[index] = parentIndex;
linearCommunication_[index] = calcLinearComm(procIDs_[index].size()); // Size but do not fill structure - this is done on-the-fly
treeCommunication_[index] = calcTreeComm(procIDs_[index].size()); linearCommunication_[index] = List<commsStruct>(procIDs_[index].size());
treeCommunication_[index] = List<commsStruct>(procIDs_[index].size());
if (doPstream && parRun()) 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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
// By default this is not a parallel run // By default this is not a parallel run

View file

@ -212,25 +212,6 @@ private:
//- Set data for parallel running //- Set data for parallel running
static void setParRun(const label nProcs); 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 //- Allocate a communicator with index
static void allocatePstreamCommunicator static void allocatePstreamCommunicator
( (
@ -775,6 +756,16 @@ inline void Pstream::enlargeBuffer(size_t count)
Ostream& operator<<(Ostream&, const Pstream::commsStruct&); 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<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(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 "token.H"
#include <cctype> #include <cctype>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::ISstream, 0);
// * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * * //
char Foam::ISstream::nextValid() char Foam::ISstream::nextValid()
@ -119,7 +123,18 @@ void Foam::ISstream::readWordToken(token& t)
} }
else if (token::compound::isCompound(*wPtr)) else if (token::compound::isCompound(*wPtr))
{ {
if (debug)
{
Pout<< "Start constructing compound token" << endl;
}
t = token::compound::New(*wPtr, *this).ptr(); t = token::compound::New(*wPtr, *this).ptr();
if (debug)
{
Pout<< "End constructing compound token" << endl;
}
delete wPtr; delete wPtr;
} }
else else
@ -137,6 +152,10 @@ Foam::Istream& Foam::ISstream::read(token& t)
// Return the put back token if it exists // Return the put back token if it exists
if (Istream::getBack(t)) if (Istream::getBack(t))
{ {
if (debug)
{
Pout<< "ISstream returns put back token: " << t << endl;
}
return *this; 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 // Set the line number of this token to the current stream line number
t.lineNumber() = lineNumber(); 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 // return on error
if (!c) if (!c)
{ {
@ -178,6 +203,14 @@ Foam::Istream& Foam::ISstream::read(token& t)
case token::MULTIPLY : case token::MULTIPLY :
case token::DIVIDE : 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); t = token::punctuationToken(c);
return *this; return *this;
} }
@ -199,6 +232,11 @@ Foam::Istream& Foam::ISstream::read(token& t)
t = sPtr; t = sPtr;
} }
if (debug)
{
Pout<< "ISstream returns string: " << t << endl;
}
return *this; return *this;
} }
// Possible verbatim string or dictionary functionEntry // 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; return *this;
} }
@ -394,6 +437,11 @@ Foam::Istream& Foam::ISstream::read(token& t)
putback(c); putback(c);
readWordToken(t); readWordToken(t);
if (debug)
{
Pout<< "ISstream returns word token: " << t << endl;
}
return *this; return *this;
} }
} }
@ -474,6 +522,12 @@ Foam::Istream& Foam::ISstream::read(word& str)
str = buf; str = buf;
putback(c); putback(c);
if (debug > 1)
{
Pout<< "ISstream::read(word& str) returns word = "
<< str << endl;
}
return *this; return *this;
} }

View file

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

View file

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

View file

@ -25,12 +25,36 @@ License
#include "error.H" #include "error.H"
#include "OSstream.H" #include "OSstream.H"
#include "messageStream.H"
#include "token.H" #include "token.H"
#include "Pstream.H"
#include <iostream>
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::OSstream, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
Foam::Ostream& Foam::OSstream::write(const token& t) 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) if (t.type() == token::VERBATIMSTRING)
{ {
write(char(token::HASH)); write(char(token::HASH));
@ -49,6 +73,15 @@ Foam::Ostream& Foam::OSstream::write(const token& t)
Foam::Ostream& Foam::OSstream::write(const char c) 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; os_ << c;
if (c == token::NL) if (c == token::NL)
{ {
@ -61,6 +94,16 @@ Foam::Ostream& Foam::OSstream::write(const char c)
Foam::Ostream& Foam::OSstream::write(const char* str) 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); lineNumber_ += string(str).count(token::NL);
os_ << str; os_ << str;
setState(os_.rdstate()); setState(os_.rdstate());
@ -70,6 +113,15 @@ Foam::Ostream& Foam::OSstream::write(const char* str)
Foam::Ostream& Foam::OSstream::write(const word& 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; os_ << str;
setState(os_.rdstate()); setState(os_.rdstate());
return *this; return *this;
@ -78,6 +130,15 @@ Foam::Ostream& Foam::OSstream::write(const word& str)
Foam::Ostream& Foam::OSstream::write(const string& 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; os_ << token::BEGIN_STRING;
int backslash = 0; int backslash = 0;
@ -127,6 +188,15 @@ Foam::Ostream& Foam::OSstream::writeQuoted
const bool quoted const bool quoted
) )
{ {
if (debug > 2)
{
std::cout
<< "From function " << __PRETTY_FUNCTION__ << nl
<< " in file " << __FILE__ << nl
<< " at line " << __LINE__
<< ": " << str << "\n";
}
if (quoted) if (quoted)
{ {
os_ << token::BEGIN_STRING; 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() void Foam::OSstream::indent()
{ {
for (unsigned short i = 0; i < indentLevel_*indentSize_; i++) 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() void Foam::OSstream::flush()
{ {
os_.flush(); os_.flush();

View file

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

View file

@ -31,12 +31,10 @@ inline Foam::OSstream::OSstream
( (
ostream& os, ostream& os,
const string& name, const string& name,
streamFormat format, IOstreamOption streamOpt
versionNumber version,
compressionType compression
) )
: :
Ostream(format, version, compression), Ostream(streamOpt),
name_(name), name_(name),
os_(os) 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() Foam::Istream& Foam::ITstream::rewind()
{ {
tokenIndex_ = 0; tokenIndex_ = 0;

View file

@ -191,9 +191,17 @@ public:
//- Read binary block //- Read binary block
virtual Istream& read(char*, std::streamsize); 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 //- Rewind and return the stream so that it may be read again
virtual Istream& rewind(); virtual Istream& rewind();
Istream& readToStringStream(string&)
{
return *this;
}
// Edit // Edit

View file

@ -32,6 +32,7 @@ Foam::token Foam::token::undefinedToken;
defineTypeNameAndDebug(Foam::token::compound, 0); defineTypeNameAndDebug(Foam::token::compound, 0);
defineRunTimeSelectionTable(Foam::token::compound, Istream); defineRunTimeSelectionTable(Foam::token::compound, Istream);
defineRunTimeSelectionTable(Foam::token::compound, label);
// * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * * // // * * * * * * * * * * * * 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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::token::compound::isCompound(const word& name) bool Foam::token::compound::isCompound(const word& name)

View file

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

View file

@ -29,9 +29,6 @@ Description
#include "error.H" #include "error.H"
#include "token.H" #include "token.H"
#include "IOstreams.H"
#include "scalar.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::token::token(Istream& is) 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) 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); return os << char(pt);
} }

View file

@ -29,8 +29,10 @@ Description
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "OSspecific.H"
#include "foamTime.H" #include "foamTime.H"
#include "IOobject.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 // Note: if name is empty, just check the directory itself
SliceStreamPaths paths;
if ( paths.meshPresent() )
{
return constant();
}
const fileName tPath(path()); const fileName tPath(path());
const fileName dirPath(tPath/timeName()/dir); const fileName dirPath(tPath/timeName()/dir);

View file

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

View file

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

View file

@ -122,7 +122,7 @@ public:
template<class T> template<class T>
primitiveEntry(const keyType&, const 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)); return autoPtr<entry>(new primitiveEntry(*this));
} }
@ -172,7 +172,7 @@ public:
virtual bool read(const dictionary&, Istream&); virtual bool read(const dictionary&, Istream&);
//- Write //- Write
void write(Ostream&) const; virtual void write(Ostream&) const;
//- Write, optionally with contents only (no keyword, etc) //- Write, optionally with contents only (no keyword, etc)
void write(Ostream&, const bool contentsOnly) const; 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 && 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); append(currToken, dict, is);
if if
@ -127,6 +136,15 @@ bool Foam::primitiveEntry::read(const dictionary& dict, Istream& is)
&& !(currToken == token::END_STATEMENT && blockCount == 0) && !(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 if
( (
currToken == token::BEGIN_BLOCK currToken == token::BEGIN_BLOCK
@ -146,6 +164,13 @@ bool Foam::primitiveEntry::read(const dictionary& dict, Istream& is)
append(currToken, dict, is); append(currToken, dict, is);
} }
if (dictionary::debug)
{
Pout<<
"End of primitiveEntry::readData(const dictionary&, Istream&)"
<< endl;
}
} }
is.fatalCheck is.fatalCheck

View file

@ -305,6 +305,21 @@ extern messageStream Info;
#define DebugInFunction \ #define DebugInFunction \
if (debug) InfoInFunction 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 //- Report a variable name and value
// using Foam::Pout in file __FILE__ at line __LINE__ // using Foam::Pout in file __FILE__ at line __LINE__
#define DebugVar(var) \ #define DebugVar(var) \

View file

@ -26,6 +26,8 @@ License
#include "objectRegistry.H" #include "objectRegistry.H"
#include "foamTime.H" #include "foamTime.H"
#include "SliceStreamRepo.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
defineTypeNameAndDebug(Foam::objectRegistry, 0); 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 bool Foam::objectRegistry::checkIn(regIOobject& io) const
{ {
if (objectRegistry::debug) 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) void Foam::objectRegistry::rename(const word& newName)
{ {
regIOobject::rename(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 bool Foam::objectRegistry::writeObject
( (
IOstream::streamFormat fmt, IOstream::streamFormat fmt,
IOstream::versionNumber ver, IOstream::versionNumber ver,
IOstream::compressionType cmp IOstream::compressionType cmp
) const ) const
{
return writeObject(IOstreamOption(fmt, ver, cmp));
}
bool Foam::objectRegistry::writeObject
(
IOstreamOption streamOpt
) const
{ {
bool ok = true; bool ok = true;
@ -395,13 +455,15 @@ bool Foam::objectRegistry::writeObject
<< iter.key() << iter.key()
<< " of type " << iter()->type() << " of type " << iter()->type()
<< " with writeOpt " << iter()->writeOpt() << " with writeOpt " << iter()->writeOpt()
<< ", streamFormat " << streamOpt.format()
<< " and streamMode " << streamOpt.mode()
<< " to file " << iter()->objectPath() << " to file " << iter()->objectPath()
<< endl; << endl;
} }
if (iter()->writeOpt() != NO_WRITE) 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 //- Current event
mutable label event_; mutable label event_;
//- I/O stream mode propagated to the objects
IOstreamOption::streamMode streamMode_ = IOstreamOption::DEFERRED;
// Private Member Functions // Private Member Functions
@ -201,6 +204,9 @@ public:
//- Return new event number. //- Return new event number.
label getEvent() const; label getEvent() const;
//- Return stream mode
IOstreamOption::streamMode streamMode() const;
// Edit // Edit
@ -213,6 +219,8 @@ public:
//- Remove an regIOobject from registry //- Remove an regIOobject from registry
virtual bool checkOut(regIOobject&) const; virtual bool checkOut(regIOobject&) const;
//- Alter stream mode
void streamMode(IOstreamOption::streamMode);
// Reading // Reading
@ -228,6 +236,9 @@ public:
// Writing // Writing
//- Write using setting from DB and current stream mode
virtual bool write() const;
//- writeData function required by regIOobject but not used //- writeData function required by regIOobject but not used
// for this class, write is used instead // for this class, write is used instead
virtual bool writeData(Ostream&) const virtual bool writeData(Ostream&) const
@ -244,6 +255,9 @@ public:
IOstream::versionNumber ver, IOstream::versionNumber ver,
IOstream::compressionType cmp IOstream::compressionType cmp
) const; ) 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 //- Return Istream and check object type against that given
Istream& readStream(const word&); Istream& readStream(const word&);
Istream& readStreamPar(const word&);
//- Close Istream //- Close Istream
void close(); void close();
@ -282,9 +284,30 @@ public:
IOstream::compressionType IOstream::compressionType
) const; ) const;
//- Write using stream option
virtual bool writeObject(IOstreamOption streamOpt) const;
//- Write using setting from DB //- Write using setting from DB
virtual bool write() const; 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 // Member operators

View file

@ -27,6 +27,7 @@ License
#include "IFstream.H" #include "IFstream.H"
#include "objectRegistry.H" #include "objectRegistry.H"
#include "PstreamReduceOps.H" #include "PstreamReduceOps.H"
#include <string>
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * 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() void Foam::regIOobject::close()
{ {
if (IFstream::debug) if (IFstream::debug)

View file

@ -30,6 +30,10 @@ Description
#include "objectRegistry.H" #include "objectRegistry.H"
#include "OSspecific.H" #include "OSspecific.H"
#include "OFstream.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::versionNumber ver,
IOstream::compressionType cmp IOstream::compressionType cmp
) const ) const
{
return writeObject(IOstreamOption(fmt, ver, cmp));
}
bool Foam::regIOobject::writeObject(IOstreamOption streamOpt) const
{ {
if (!good()) if (!good())
{ {
@ -70,17 +80,108 @@ bool Foam::regIOobject::writeObject
const_cast<regIOobject&>(*this).instance() = time().timeName(); const_cast<regIOobject&>(*this).instance() = time().timeName();
} }
if (time().writeFormat() == IOstream::COHERENT)
{
if (Pstream::master())
{
mkDir(path()); mkDir(path());
}
}
else
{
mkDir(path());
}
if (OFstream::debug) if (OFstream::debug)
{ {
Info<< "regIOobject::write() : " 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
);
if (OFstream::debug)
{
Info<< " .... written" << endl;
}
// Only update the lastModified_ time if this object is re-readable,
// i.e. lastModified_ is already set
if (watchIndex_ != -1)
{
time().setUnmodified(watchIndex_);
}
return osGood;
} }
bool osGood = false; bool Foam::regIOobject::write() const
{
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(),
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 // Try opening an OFstream for object
// Stream open for over-write. HJ, 17/Aug/2010 // Stream open for over-write. HJ, 17/Aug/2010
@ -88,9 +189,7 @@ bool Foam::regIOobject::writeObject
( (
objectPath(), objectPath(),
ios_base::out|ios_base::trunc, ios_base::out|ios_base::trunc,
fmt, streamOpt
ver,
cmp
); );
// If any of these fail, return (leave error handling to Ostream class) // If any of these fail, return (leave error handling to Ostream class)
@ -112,33 +211,7 @@ bool Foam::regIOobject::writeObject
writeEndDivider(os); writeEndDivider(os);
osGood = os.good(); return os.good();
}
if (OFstream::debug)
{
Info<< " .... written" << endl;
}
// Only update the lastModified_ time if this object is re-readable,
// i.e. lastModified_ is already set
if (watchIndex_ != -1)
{
time().setUnmodified(watchIndex_);
}
return osGood;
}
bool Foam::regIOobject::write() const
{
return writeObject
(
time().writeFormat(),
IOstream::currentVersion,
time().writeCompression()
);
} }
// ************************************************************************* // // ************************************************************************* //

View file

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

View file

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

View file

@ -212,6 +212,14 @@ Field<Type>::Field
const label s const label s
) )
{ {
if (debug)
{
Info<< "Field<Type>::Field"
<< "(const word& keyword, const dictionary& dict, const label s)"
<< " : keyword = " << keyword
<< endl;
}
if (s) if (s)
{ {
ITstream& is = dict.lookup(keyword); ITstream& is = dict.lookup(keyword);
@ -597,6 +605,14 @@ void Field<Type>::writeEntry(const word& keyword, Ostream& os) const
{ {
os.writeKeyword(keyword); 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; bool uniform = false;
if (this->size() && contiguous<Type>()) if (this->size() && contiguous<Type>())

View file

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

View file

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

View file

@ -27,6 +27,8 @@ License
#include "foamTime.H" #include "foamTime.H"
#include "demandDrivenData.H" #include "demandDrivenData.H"
#include "dictionary.H" #include "dictionary.H"
#include "OFCstream.H"
#include "IFCstream.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -56,6 +58,14 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::readField
const dictionary& fieldDict 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"); DimensionedField<Type, GeoMesh>::readField(fieldDict, "internalField");
tmp<GeometricBoundaryField> tboundaryField tmp<GeometricBoundaryField> tboundaryField
@ -94,6 +104,13 @@ Foam::tmp
> >
Foam::GeometricField<Type, PatchField, GeoMesh>::readField(Istream& is) 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) if (is.version() < 2.0)
{ {
FatalIOErrorIn FatalIOErrorIn
@ -104,8 +121,27 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::readField(Istream& is)
<< exit(FatalIOError); << exit(FatalIOError);
} }
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)); return readField(dictionary(is));
} }
}
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
@ -120,9 +156,9 @@ bool Foam::GeometricField<Type, PatchField, GeoMesh>::readIfPresent()
<< "suggests that a read constructor for field " << this->name() << "suggests that a read constructor for field " << this->name()
<< " would be more appropriate." << endl; << " 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(); this->close();
// Check compatibility between field and mesh // Check compatibility between field and mesh
@ -348,7 +384,7 @@ Foam::GeometricField<Type, PatchField, GeoMesh>::GeometricField
timeIndex_(this->time().timeIndex()), timeIndex_(this->time().timeIndex()),
field0Ptr_(nullptr), field0Ptr_(nullptr),
fieldPrevIterPtr_(nullptr), fieldPrevIterPtr_(nullptr),
boundaryField_(*this, readField(this->readStream(typeName))) boundaryField_(*this, readField(this->readStreamPar(typeName)))
{ {
this->close(); 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 // writeData member function required by regIOobject
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>
bool Foam::GeometricField<Type, PatchField, 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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type, template<class> class PatchField, class GeoMesh> template<class Type, template<class> class PatchField, class GeoMesh>

View file

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

View file

@ -492,6 +492,7 @@ Foam::argList::argList
) )
: :
parRunControl_(args.parRunControl_), parRunControl_(args.parRunControl_),
//adiosControl_(args.adiosControl_),
args_(args.args_), args_(args.args_),
options_(options), options_(options),
executable_(args.executable_), executable_(args.executable_),
@ -596,12 +597,31 @@ void Foam::argList::parse
// If this actually is a parallel run // If this actually is a parallel run
if (parRunControl_.parRun()) if (parRunControl_.parRun())
{ {
bool isCoherentFormat = false;
// For the master // For the master
if (Pstream::master()) if (Pstream::master())
{ {
// Establish rootPath_/globalCase_/case_ for master // Establish rootPath_/globalCase_/case_ for master
getRootCase(); 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) // See if running distributed (different roots for different procs)
label dictNProcs = -1; label dictNProcs = -1;
fileName source; fileName source;
@ -668,6 +688,21 @@ void Foam::argList::parse
// - decomposition to more processors : nProcs = dictNProcs // - decomposition to more processors : nProcs = dictNProcs
// - decomposition to fewer processors : nProcs = nProcDirs // - decomposition to fewer processors : nProcs = nProcDirs
if (dictNProcs > Pstream::nProcs()) if (dictNProcs > Pstream::nProcs())
{
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 FatalError
<< source << source
@ -676,6 +711,7 @@ void Foam::argList::parse
<< Pstream::nProcs() << " processors." << Pstream::nProcs() << " processors."
<< exit(FatalError); << exit(FatalError);
} }
}
// Distributed data // Distributed data
@ -708,7 +744,7 @@ void Foam::argList::parse
options_.set("case", roots[slave-1]/globalCase_); options_.set("case", roots[slave-1]/globalCase_);
OPstream toSlave(Pstream::scheduled, slave); OPstream toSlave(Pstream::scheduled, slave);
toSlave << args_ << options_; toSlave << args_ << options_ << isCoherentFormat;
} }
options_.erase("case"); options_.erase("case");
@ -722,7 +758,7 @@ void Foam::argList::parse
{ {
// Possibly going to fewer processors. // Possibly going to fewer processors.
// Check if all procDirs are there. // Check if all procDirs are there.
if (dictNProcs < Pstream::nProcs()) if (!isCoherentFormat && dictNProcs < Pstream::nProcs())
{ {
label nProcDirs = 0; label nProcDirs = 0;
while while
@ -755,7 +791,7 @@ void Foam::argList::parse
) )
{ {
OPstream toSlave(Pstream::scheduled, slave); OPstream toSlave(Pstream::scheduled, slave);
toSlave << args_ << options_; toSlave << args_ << options_ << isCoherentFormat;
} }
} }
} }
@ -763,15 +799,33 @@ void Foam::argList::parse
{ {
// Collect the master's argument list // Collect the master's argument list
IPstream fromMaster(Pstream::scheduled, Pstream::masterNo()); IPstream fromMaster(Pstream::scheduled, Pstream::masterNo());
fromMaster >> args_ >> options_; fromMaster >> args_ >> options_ >> isCoherentFormat;
// Establish rootPath_/globalCase_/case_ for slave // Establish rootPath_/globalCase_/case_ for slave
getRootCase(); getRootCase();
} }
nProcs = Pstream::nProcs(); nProcs = Pstream::nProcs();
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())); case_ = globalCase_/(word("processor") + name(Pstream::myProcNo()));
} }
}
else else
{ {
// Establish rootPath_/globalCase_/case_ // Establish rootPath_/globalCase_/case_
@ -1299,6 +1353,7 @@ bool Foam::argList::checkRootCase() const
return false; return false;
} }
/* Disabled this check to allow restarts from TARs
if (!isDir(path()) && Pstream::master()) if (!isDir(path()) && Pstream::master())
{ {
// Allow slaves on non-existing processor directories, created later // Allow slaves on non-existing processor directories, created later
@ -1309,6 +1364,7 @@ bool Foam::argList::checkRootCase() const
return false; return false;
} }
*/
return true; 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) RunPar(false)
{} {}
~ParRunControl() ~ParRunControl();
{
if (RunPar)
{
Info<< "Finalising parallel run" << endl;
Pstream::exit(0);
}
}
void runPar(int& argc, char**& argv) 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 // Read end of contents
is.readEndList("Matrix"); is.readEndList("Matrix");
} }
else else if (is.format() == IOstream::BINARY)
{ {
if (nm) 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 else
{ {
@ -243,13 +245,15 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const Matrix<Form, Type>& M)
os << token::BEGIN_LIST << token::END_LIST << nl; os << token::BEGIN_LIST << token::END_LIST << nl;
} }
} }
else else if (os.format() == IOstream::BINARY)
{ {
if (nm) if (nm)
{ {
os.write(reinterpret_cast<const char*>(M.v_[0]), nm*sizeof(Type)); 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 // Check state of IOstream
os.check("Ostream& operator<<(Ostream&, const Matrix&)"); 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_; os << bb.min_ << token::SPACE << bb.max_;
} }
else else if (os.format() == IOstream::BINARY)
{ {
os.write os.write
( (
@ -125,6 +125,8 @@ Foam::Ostream& Foam::operator<<(Ostream& os, const boundBox& bb)
sizeof(boundBox) sizeof(boundBox)
); );
} }
else if (os.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in boundBox.C\n"; }
// Check state of Ostream // Check state of Ostream
os.check("Ostream& operator<<(Ostream&, const boundBox&)"); 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_; return is >> bb.min_ >> bb.max_;
} }
else else if (is.format() == IOstream::BINARY)
{ {
is.read is.read
( (
@ -146,6 +148,8 @@ Foam::Istream& Foam::operator>>(Istream& is, boundBox& bb)
sizeof(boundBox) sizeof(boundBox)
); );
} }
else if (is.format() == IOstream::COHERENT)
{ cout << "Parallel IO not yet implemented in boundBox.C\n"; }
// Check state of Istream // Check state of Istream
is.check("Istream& operator>>(Istream&, boundBox&)"); is.check("Istream& operator>>(Istream&, boundBox&)");

View file

@ -27,7 +27,7 @@ License
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::globalIndex::globalIndex(const label localSize) Foam::globalIndex::globalIndex(const label localSize, const bool reduce)
: :
offsets_(Pstream::nProcs()) offsets_(Pstream::nProcs())
{ {
@ -36,6 +36,8 @@ Foam::globalIndex::globalIndex(const label localSize)
Pstream::gatherList(localSizes); Pstream::gatherList(localSizes);
Pstream::scatterList(localSizes); // just to balance out comms Pstream::scatterList(localSizes); // just to balance out comms
if (reduce)
{
label offset = 0; label offset = 0;
forAll(offsets_, procI) forAll(offsets_, procI)
{ {
@ -53,6 +55,11 @@ Foam::globalIndex::globalIndex(const label localSize)
offsets_[procI] = offset; offsets_[procI] = offset;
} }
} }
else
{
std::copy(localSizes.begin(), localSizes.end(), offsets_.begin());
}
}
Foam::globalIndex::globalIndex(Istream& is) Foam::globalIndex::globalIndex(Istream& is)

View file

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

View file

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

View file

@ -34,6 +34,18 @@ License
#include "treeDataCell.H" #include "treeDataCell.H"
#include "MeshObject.H" #include "MeshObject.H"
#include "pointMesh.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 * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -200,6 +212,7 @@ void Foam::polyMesh::calcDirections() const
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::polyMesh::polyMesh(const IOobject& io) Foam::polyMesh::polyMesh(const IOobject& io)
: :
objectRegistry(io), objectRegistry(io),
@ -212,9 +225,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
time().findInstance(meshDir(), "points"), time().findInstance(meshDir(), "points"),
meshSubDir, meshSubDir,
*this, *this,
IOobject::MUST_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::AUTO_WRITE
) ),
pointField(0)
), ),
// To be re-sliced later. HJ, 19/oct/2008 // To be re-sliced later. HJ, 19/oct/2008
points_(allPoints_, allPoints_.size()), points_(allPoints_, allPoints_.size()),
@ -226,9 +240,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
time().findInstance(meshDir(), "faces"), time().findInstance(meshDir(), "faces"),
meshSubDir, meshSubDir,
*this, *this,
IOobject::MUST_READ, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::AUTO_WRITE
) ),
faceList(0)
), ),
// To be re-sliced later. HJ, 19/oct/2008 // To be re-sliced later. HJ, 19/oct/2008
faces_(allFaces_, allFaces_.size()), faces_(allFaces_, allFaces_.size()),
@ -240,9 +255,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
time().findInstance(meshDir(), "faces"), time().findInstance(meshDir(), "faces"),
meshSubDir, meshSubDir,
*this, *this,
IOobject::READ_IF_PRESENT, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::AUTO_WRITE
) ),
labelList(0)
), ),
neighbour_ neighbour_
( (
@ -252,9 +268,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
time().findInstance(meshDir(), "faces"), time().findInstance(meshDir(), "faces"),
meshSubDir, meshSubDir,
*this, *this,
IOobject::READ_IF_PRESENT, IOobject::NO_READ,
IOobject::NO_WRITE IOobject::AUTO_WRITE
) ),
labelList(0)
), ),
syncPar_(true), // Reading mesh from IOobject: must be valid syncPar_(true), // Reading mesh from IOobject: must be valid
clearedPrimitives_(false), clearedPrimitives_(false),
@ -267,9 +284,10 @@ Foam::polyMesh::polyMesh(const IOobject& io)
meshSubDir, meshSubDir,
*this, *this,
IOobject::MUST_READ, IOobject::MUST_READ,
IOobject::NO_WRITE IOobject::AUTO_WRITE
), ),
*this *this,
0
), ),
bounds_(allPoints_), // Reading mesh from IOobject: syncPar bounds_(allPoints_), // Reading mesh from IOobject: syncPar
geometricD_(Vector<label>::zero), geometricD_(Vector<label>::zero),
@ -336,7 +354,118 @@ Foam::polyMesh::polyMesh(const IOobject& io)
oldAllPointsPtr_(nullptr), oldAllPointsPtr_(nullptr),
oldPointsPtr_(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(); initMesh();
} }
@ -382,6 +511,11 @@ Foam::polyMesh::polyMesh(const IOobject& io)
WarningIn("polyMesh(const IOobject&)") WarningIn("polyMesh(const IOobject&)")
<< "no cells in mesh" << endl; << "no cells in mesh" << endl;
} }
if (debug)
{
checkMesh( true );
}
} }
@ -522,6 +656,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr), oldAllPointsPtr_(nullptr),
oldPointsPtr_(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 // Check if the faces and cells are valid
forAll (allFaces_, faceI) forAll (allFaces_, faceI)
{ {
@ -684,6 +826,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr), oldAllPointsPtr_(nullptr),
oldPointsPtr_(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 // Check if the faces and cells are valid
forAll (allFaces_, faceI) 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 // IOstream Operators
friend Ostream& operator<<(Ostream&, const polyMesh&); 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), oldAllPointsPtr_(nullptr),
oldPointsPtr_(nullptr) oldPointsPtr_(nullptr)
{ {
if (time().writeFormat() == IOstream::COHERENT)
{
this->checkOut( allPoints_ );
this->checkOut( allFaces_ );
this->checkOut( owner_ );
this->checkOut( neighbour_ );
}
if (debug) if (debug)
{ {
Info<<"Constructing polyMesh from cell and boundary shapes." << endl; Info<<"Constructing polyMesh from cell and boundary shapes." << endl;
@ -843,6 +851,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr), oldAllPointsPtr_(nullptr),
oldPointsPtr_(nullptr) oldPointsPtr_(nullptr)
{ {
//if (time().writeFormat() == IOstream::COHERENT)
//{
//this->checkOut( allPoints_ );
//this->checkOut( allFaces_ );
//this->checkOut( owner_ );
//this->checkOut( neighbour_ );
//}
if (debug) if (debug)
{ {
Info<<"Constructing polyMesh from cell and boundary shapes." << endl; Info<<"Constructing polyMesh from cell and boundary shapes." << endl;

View file

@ -166,6 +166,14 @@ Foam::polyMesh::polyMesh
oldAllPointsPtr_(nullptr), oldAllPointsPtr_(nullptr),
oldPointsPtr_(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 // Check if the faces and cells are valid
forAll (allFaces_, faceI) 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); 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); 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); return subsetIndices(indices);
} }

View file

@ -119,7 +119,7 @@ public:
//- Construct from a list of labels //- Construct from a list of labels
// using the labels as indices to indicate which bits are set // 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 //- Construct from a list of labels
// using the labels as indices to indicate which bits are set // 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. //- Set the listed indices. Return number of elements changed.
// Does auto-vivify for non-existent entries. // 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. //- Set the listed indices. Return number of elements changed.
// Does auto-vivify for non-existent entries. // Does auto-vivify for non-existent entries.
@ -152,7 +152,7 @@ public:
//- Unset the listed indices. Return number of elements changed. //- Unset the listed indices. Return number of elements changed.
// Never auto-vivify entries. // 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. //- Unset the listed indices. Return number of elements changed.
// Never auto-vivify entries. // Never auto-vivify entries.
@ -163,7 +163,7 @@ public:
//- Subset with the listed indices. //- Subset with the listed indices.
// Return number of elements subsetted. // Return number of elements subsetted.
label subset(const UList<label>& indices); label subset(const Foam::UList<label>& indices);
//- Subset with the listed indices. //- Subset with the listed indices.
// Return number of elements subsetted. // Return number of elements subsetted.
@ -204,7 +204,7 @@ public:
//- Assignment operator, //- Assignment operator,
// using the labels as indices to indicate which bits are set // 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, //- Assignment operator,
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
@ -218,7 +218,7 @@ public:
//- And operator (lists may be dissimilar sizes) //- And operator (lists may be dissimilar sizes)
// using the labels as indices to indicate which bits are set // 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) //- And operator (lists may be dissimilar sizes)
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
@ -233,7 +233,7 @@ public:
//- Or operator (lists may be dissimilar sizes), //- Or operator (lists may be dissimilar sizes),
// using the labels as indices to indicate which bits are set // 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), //- Or operator (lists may be dissimilar sizes),
// using the labels as indices to indicate which bits are set // using the labels as indices to indicate which bits are set
@ -244,7 +244,7 @@ public:
inline PackedBoolList& operator+=(const PackedList<1>&); inline PackedBoolList& operator+=(const PackedList<1>&);
//- Add entries to this list, synonymous with the or operator //- 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 //- Add entries to this list, synonymous with the or operator
inline PackedBoolList& operator+=(const UIndirectList<label>&); inline PackedBoolList& operator+=(const UIndirectList<label>&);
@ -253,7 +253,7 @@ public:
inline PackedBoolList& operator-=(const PackedList<1>&); inline PackedBoolList& operator-=(const PackedList<1>&);
//- Remove entries from this list - unset the specified bits //- 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 //- Remove entries from this list - unset the specified bits
inline PackedBoolList& operator-=(const UIndirectList<label>&); 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) PackedList<1>(indices.size(), 0u)
{ {
@ -151,7 +151,7 @@ Foam::PackedBoolList::operator=(const PackedList<1>& lst)
inline Foam::PackedBoolList& inline Foam::PackedBoolList&
Foam::PackedBoolList::operator=(const UList<label>& indices) Foam::PackedBoolList::operator=(const Foam::UList<label>& indices)
{ {
clear(); clear();
set(indices); set(indices);
@ -189,7 +189,7 @@ Foam::PackedBoolList::operator&=(const PackedList<1>& lst)
inline Foam::PackedBoolList& inline Foam::PackedBoolList&
Foam::PackedBoolList::operator&=(const UList<label>& indices) Foam::PackedBoolList::operator&=(const Foam::UList<label>& indices)
{ {
subset(indices); subset(indices);
return *this; return *this;
@ -213,7 +213,7 @@ Foam::PackedBoolList::operator|=(const PackedList<1>& lst)
inline Foam::PackedBoolList& inline Foam::PackedBoolList&
Foam::PackedBoolList::operator|=(const UList<label>& indices) Foam::PackedBoolList::operator|=(const Foam::UList<label>& indices)
{ {
set(indices); set(indices);
return *this; return *this;
@ -236,7 +236,7 @@ Foam::PackedBoolList::operator+=(const PackedList<1>& lst)
inline Foam::PackedBoolList& inline Foam::PackedBoolList&
Foam::PackedBoolList::operator+=(const UList<label>& indices) Foam::PackedBoolList::operator+=(const Foam::UList<label>& indices)
{ {
return operator|=(indices); return operator|=(indices);
} }
@ -258,7 +258,7 @@ Foam::PackedBoolList::operator-=(const PackedList<1>& lst)
inline Foam::PackedBoolList& inline Foam::PackedBoolList&
Foam::PackedBoolList::operator-=(const UList<label>& indices) Foam::PackedBoolList::operator-=(const Foam::UList<label>& indices)
{ {
unset(indices); unset(indices);
return *this; 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; string cName = *this;
@ -214,7 +214,15 @@ Foam::string Foam::fileName::caseName() const
} }
else 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; word name() const;
//- Return file name (part beyond last /), subsitute for FOAM_CASE //- 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 //- Return file name, optionally without extension
word name(const bool noExt) const; word name(const bool noExt) const;

View file

@ -60,7 +60,7 @@ Foam::Particle<ParticleType>::Particle
is >> origProc_ >> origId_; is >> origProc_ >> origId_;
} }
} }
else else if (is.format() == IOstream::BINARY)
{ {
// In binary read all particle data - needed for parallel transfer // In binary read all particle data - needed for parallel transfer
if (readFields) 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) if (celli_ == -1)
{ {
@ -187,7 +189,7 @@ void Foam::Particle<ParticleType>::write(Ostream& os, bool writeFields) const
<< token::SPACE << celli_; << token::SPACE << celli_;
} }
} }
else else if (os.format() == IOstream::BINARY)
{ {
// In binary write both celli_ and facei_, needed for parallel transfer // In binary write both celli_ and facei_, needed for parallel transfer
if (writeFields) 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 // Check state of Ostream
os.check("Particle<ParticleType>::write(Ostream& os, bool) const"); os.check("Particle<ParticleType>::write(Ostream& os, bool) const");