ENH: lazy reading of old volume, old surface area

- avoid explicit isFile() check in favour of a lazy-read.
  With redistributePar + fileHandler, for example, it is possible that
  the master processor finds file but not the subprocs

ENH: lazy reading of tetBasePtIs

- delay reading until needed

Co-authored-by: Mark Olesen <>
This commit is contained in:
mattijs 2023-05-11 08:53:50 +02:00 committed by Mark Olesen
parent 16064b60e2
commit 1abea53d1a
3 changed files with 111 additions and 76 deletions

View File

@ -153,8 +153,9 @@ Foam::autoPtr<Foam::labelIOList> Foam::polyMesh::readTetBasePtIs() const
instance(),
meshSubDir,
*this,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
IOobject::LAZY_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
if (io.typeHeaderOk<labelIOList>(true))
@ -244,7 +245,7 @@ Foam::polyMesh::polyMesh(const IOobject& io, const bool doInit)
comm_(UPstream::worldComm),
geometricD_(Zero),
solutionD_(Zero),
tetBasePtIsPtr_(readTetBasePtIs()),
tetBasePtIsPtr_(nullptr),
cellTreePtr_(nullptr),
pointZones_
(
@ -908,6 +909,11 @@ const Foam::labelIOList& Foam::polyMesh::tetBasePtIs() const
<< endl;
}
labelList basePts
(
polyMeshTetDecomposition::findFaceBasePts(*this)
);
tetBasePtIsPtr_.reset
(
new labelIOList
@ -918,10 +924,11 @@ const Foam::labelIOList& Foam::polyMesh::tetBasePtIs() const
instance(),
meshSubDir,
*this,
IOobject::READ_IF_PRESENT,
IOobject::NO_WRITE
IOobject::NO_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
polyMeshTetDecomposition::findFaceBasePts(*this)
std::move(basePts)
)
);
}

View File

@ -421,21 +421,33 @@ Foam::faMesh::faMesh
faMesh::init(false); // do not init lower levels
}
if (doInit && fileHandler().isFile(pMesh.time().timePath()/"S0"))
if (doInit)
{
S0Ptr_ = new DimensionedField<scalar, areaMesh>
// Read some optional fields
// - logic as per fvMesh
IOobject rio
(
IOobject
(
"S0",
time().timeName(),
faMesh::meshSubDir,
faMesh::thisDb(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
*this
"name",
time().timeName(),
faMesh::meshSubDir,
faMesh::thisDb(),
IOobject::LAZY_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
// Read old surface areas (if present)
rio.resetHeader("S0");
if (returnReduceOr(rio.typeHeaderOk<regIOobject>(false)))
{
S0Ptr_ = new DimensionedField<scalar, areaMesh>
(
rio,
*this,
dimensionedScalar(dimArea, Zero)
);
}
}
}
@ -680,21 +692,33 @@ Foam::faMesh::faMesh
faMesh::init(false); // do not init lower levels
}
if (doInit && fileHandler().isFile(pMesh.time().timePath()/"S0"))
if (doInit)
{
S0Ptr_ = new DimensionedField<scalar, areaMesh>
// Read old surface areas (if present)
// - logic as per fvMesh
IOobject rio
(
IOobject
(
"S0",
time().timeName(),
faMesh::meshSubDir,
faMesh::thisDb(),
IOobject::MUST_READ,
IOobject::AUTO_WRITE
),
*this
"name",
time().timeName(),
faMesh::meshSubDir,
faMesh::thisDb(),
IOobject::LAZY_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
// Read old surface areas (if present)
rio.resetHeader("S0");
if (returnReduceOr(rio.typeHeaderOk<regIOobject>(false)))
{
S0Ptr_ = new DimensionedField<scalar, areaMesh>
(
rio,
*this,
dimensionedScalar(dimArea, Zero)
);
}
}
}

View File

@ -176,20 +176,14 @@ void Foam::fvMesh::storeOldVol(const scalarField& V)
*V00Ptr_ = *V0Ptr_;
}
if (V0Ptr_)
if (!V0Ptr_)
{
// Copy V into V0 storage
V0Ptr_->scalarField::operator=(V);
}
else
{
// Allocate V0 storage, fill with V
V0Ptr_ = new DimensionedField<scalar, volMesh>
(
IOobject
(
"V0",
time().timeName(),
this->time().timeName(),
*this,
IOobject::NO_READ,
IOobject::NO_WRITE,
@ -198,13 +192,14 @@ void Foam::fvMesh::storeOldVol(const scalarField& V)
*this,
dimVolume
);
scalarField& V0 = *V0Ptr_;
// Note: V0 now sized with current mesh, not with (potentially
// different size) V.
V0.resize_nocopy(V.size());
V0 = V;
V0Ptr_->scalarField::resize_nocopy(V.size());
}
// Copy V into V0 storage
V0Ptr_->scalarField::operator=(V);
curTimeIndex_ = time().timeIndex();
if (debug)
@ -285,53 +280,62 @@ bool Foam::fvMesh::init(const bool doInit)
polyMesh::init(doInit);
}
// Check the existence of the cell volumes and read if present
// and set the storage of V00
if (fileHandler().isFile(time().timePath()/dbDir()/"V0"))
// Read some optional fields
// ~~~~~~~~~~~~~~~~~~~~~~~~~
// For redistributePar + fileHandler can have master processor
// find the file but not the subprocs.
IOobject rio
(
"none",
this->time().timeName(),
*this,
IOobject::LAZY_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
);
// Read old cell volumes (if present) and set the storage of V00
rio.resetHeader("V0");
if (returnReduceOr(rio.typeHeaderOk<regIOobject>(false)))
{
// Set the moving flag early in case the demand-driven geometry
// construction checks for it
moving(true);
DebugInFunction
<< "Detected V0: " << rio.objectRelPath() << nl;
V0Ptr_ = new DimensionedField<scalar, volMesh>
(
IOobject
(
"V0",
time().timeName(),
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
*this
rio,
*this,
dimensionedScalar(dimVol, Zero)
);
V00();
}
// Check the existence of the mesh fluxes, read if present and set the
// mesh to be moving
if (fileHandler().isFile(time().timePath()/dbDir()/"meshPhi"))
{
// Set the moving flag early in case the demand-driven geometry
// Set the moving flag early in case demand-driven geometry
// construction checks for it
moving(true);
(void)V00();
}
// Read mesh fluxes (if present) and set the mesh to be moving
rio.resetHeader("meshPhi");
if (returnReduceOr(rio.typeHeaderOk<regIOobject>(false)))
{
DebugInFunction
<< "Detected meshPhi: " << rio.objectRelPath() << nl;
phiPtr_ = new surfaceScalarField
(
IOobject
(
"meshPhi",
time().timeName(),
*this,
IOobject::MUST_READ,
IOobject::NO_WRITE,
IOobject::NO_REGISTER
),
*this
rio,
*this,
dimensionedScalar(dimVol/dimTime, Zero)
);
// Set the moving flag early in case demand-driven geometry
// construction checks for it
moving(true);
// The mesh is now considered moving so the old-time cell volumes
// will be required for the time derivatives so if they haven't been
// read initialise to the current cell volumes
@ -342,7 +346,7 @@ bool Foam::fvMesh::init(const bool doInit)
IOobject
(
"V0",
time().timeName(),
this->time().timeName(),
*this,
IOobject::NO_READ,
IOobject::NO_WRITE,