ENH: timeVaryingMapped: abstract IFstream/regIOobject handling. See #1640.

This change abstracts out the reading of "boundaryData". It should
now support OpenFOAM headers and with that also binary input.
This commit is contained in:
mattijs 2020-06-11 12:00:51 +01:00
parent 30ea38a77e
commit 5bf440956a
16 changed files with 458 additions and 974 deletions

View File

@ -1,403 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "polyMesh.H"
#include "IFstream.H"
#include "AverageField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::PatchFunction1Types::MappedField<Type>::MappedField
(
const polyPatch& pp,
const word& entryName,
const dictionary& dict
)
:
PatchFunction1<Type>(pp, entryName, dict),
fieldTableName_(entryName),
setAverage_(dict.getOrDefault("setAverage", false)),
perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)),
pointsName_(dict.getOrDefault<word>("points", "points")),
mapMethod_
(
dict.getOrDefault<word>
(
"mapMethod",
"planarInterpolation"
)
),
mapperPtr_(nullptr),
sampleTimes_(0),
startSampleTime_(-1),
startSampledValues_(0),
startAverage_(Zero),
endSampleTime_(-1),
endSampledValues_(0),
endAverage_(Zero),
offset_()
{
if (dict.found("offset"))
{
offset_ = Function1<Type>::New("offset", dict);
}
if
(
mapMethod_ != "planarInterpolation"
&& mapMethod_ != "nearest"
)
{
FatalIOErrorInFunction(dict)
<< "mapMethod should be one of 'planarInterpolation'"
<< ", 'nearest'" << exit(FatalIOError);
}
dict.readIfPresent("fieldTable", fieldTableName_);
}
template<class Type>
Foam::PatchFunction1Types::MappedField<Type>::MappedField
(
const MappedField<Type>& ut
)
:
PatchFunction1<Type>(ut),
fieldTableName_(ut.fieldTableName_),
setAverage_(ut.setAverage_),
perturb_(ut.perturb_),
pointsName_(ut.pointsName_),
mapMethod_(ut.mapMethod_),
mapperPtr_(nullptr),
sampleTimes_(ut.sampleTimes_),
startSampleTime_(ut.startSampleTime_),
startSampledValues_(ut.startSampledValues_),
startAverage_(ut.startAverage_),
endSampleTime_(ut.endSampleTime_),
endSampledValues_(ut.endSampledValues_),
endAverage_(ut.endAverage_),
offset_(ut.offset_.clone())
{}
template<class Type>
Foam::PatchFunction1Types::MappedField<Type>::MappedField
(
const MappedField<Type>& ut,
const polyPatch& pp
)
:
PatchFunction1<Type>(ut, pp),
fieldTableName_(ut.fieldTableName_),
setAverage_(ut.setAverage_),
perturb_(ut.perturb_),
pointsName_(ut.pointsName_),
mapMethod_(ut.mapMethod_),
mapperPtr_(nullptr),
sampleTimes_(ut.sampleTimes_),
startSampleTime_(ut.startSampleTime_),
startSampledValues_(ut.startSampledValues_),
startAverage_(ut.startAverage_),
endSampleTime_(ut.endSampleTime_),
endSampledValues_(ut.endSampledValues_),
endAverage_(ut.endAverage_),
offset_(ut.offset_.clone())
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
void Foam::PatchFunction1Types::MappedField<Type>::autoMap
(
const FieldMapper& mapper
)
{
if (startSampledValues_.size())
{
startSampledValues_.autoMap(mapper);
endSampledValues_.autoMap(mapper);
}
// Clear interpolator
mapperPtr_.clear();
startSampleTime_ = -1;
endSampleTime_ = -1;
}
template<class Type>
void Foam::PatchFunction1Types::MappedField<Type>::rmap
(
const PatchFunction1<Type>& pf1,
const labelList& addr
)
{
const PatchFunction1Types::MappedField<Type>& tiptf =
refCast<const PatchFunction1Types::MappedField<Type>>(pf1);
startSampledValues_.rmap(tiptf.startSampledValues_, addr);
endSampledValues_.rmap(tiptf.endSampledValues_, addr);
// Clear interpolator
mapperPtr_.clear();
startSampleTime_ = -1;
endSampleTime_ = -1;
}
template<class Type>
void Foam::PatchFunction1Types::MappedField<Type>::checkTable() const
{
const polyMesh& mesh = this->patch_.boundaryMesh().mesh();
// Initialise
if (mapperPtr_.empty())
{
// Reread values and interpolate
fileName samplePointsFile
(
mesh.time().path()
/mesh.time().caseConstant()
/"boundaryData"
/this->patch_.name()
/pointsName_
);
pointField samplePoints((IFstream(samplePointsFile)()));
DebugInfo
<< " Read " << samplePoints.size() << " sample points from "
<< samplePointsFile << endl;
// tbd: run-time selection
bool nearestOnly =
(
!mapMethod_.empty()
&& mapMethod_ != "planarInterpolation"
);
// Allocate the interpolator
mapperPtr_.reset
(
new pointToPointPlanarInterpolation
(
samplePoints,
this->patch_.faceCentres(),
perturb_,
nearestOnly
)
);
// Read the times for which data is available
const fileName samplePointsDir = samplePointsFile.path();
sampleTimes_ = Time::findTimes(samplePointsDir);
DebugInfo
<< "In directory "
<< samplePointsDir << " found times "
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_)
<< endl;
}
// Find current time in sampleTimes
label lo = -1;
label hi = -1;
bool foundTime = mapperPtr_().findTime
(
sampleTimes_,
startSampleTime_,
mesh.time().value(),
lo,
hi
);
if (!foundTime)
{
FatalErrorInFunction
<< "Cannot find starting sampling values for current time "
<< mesh.time().value() << nl
<< "Have sampling values for times "
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl
<< "In directory "
<< mesh.time().constant()/"boundaryData"/this->patch_.name()
<< "\n on patch " << this->patch_.name()
<< " of field " << fieldTableName_
<< exit(FatalError);
}
// Update sampled data fields.
if (lo != startSampleTime_)
{
startSampleTime_ = lo;
if (startSampleTime_ == endSampleTime_)
{
// No need to reread since are end values
if (debug)
{
Pout<< "checkTable : Setting startValues to (already read) "
<< "boundaryData"
/this->patch_.name()
/sampleTimes_[startSampleTime_].name()
<< endl;
}
startSampledValues_ = endSampledValues_;
startAverage_ = endAverage_;
}
else
{
if (debug)
{
Pout<< "checkTable : Reading startValues from "
<< "boundaryData"
/this->patch_.name()
/sampleTimes_[lo].name()
<< endl;
}
// Reread values and interpolate
fileName valsFile
(
mesh.time().path()
/mesh.time().caseConstant()
/"boundaryData"
/this->patch_.name()
/sampleTimes_[startSampleTime_].name()
/fieldTableName_
);
Field<Type> vals;
if (setAverage_)
{
AverageField<Type> avals((IFstream(valsFile)()));
vals = avals;
startAverage_ = avals.average();
}
else
{
IFstream(valsFile)() >> vals;
}
if (vals.size() != mapperPtr_().sourceSize())
{
FatalErrorInFunction
<< "Number of values (" << vals.size()
<< ") differs from the number of points ("
<< mapperPtr_().sourceSize()
<< ") in file " << valsFile << exit(FatalError);
}
startSampledValues_ = mapperPtr_().interpolate(vals);
}
}
if (hi != endSampleTime_)
{
endSampleTime_ = hi;
if (endSampleTime_ == -1)
{
// endTime no longer valid. Might as well clear endValues.
if (debug)
{
Pout<< "checkTable : Clearing endValues" << endl;
}
endSampledValues_.clear();
}
else
{
if (debug)
{
Pout<< "checkTable : Reading endValues from "
<< "boundaryData"
/this->patch_.name()
/sampleTimes_[endSampleTime_].name()
<< endl;
}
// Reread values and interpolate
fileName valsFile
(
mesh.time().path()
/mesh.time().caseConstant()
/"boundaryData"
/this->patch_.name()
/sampleTimes_[endSampleTime_].name()
/fieldTableName_
);
Field<Type> vals;
if (setAverage_)
{
AverageField<Type> avals((IFstream(valsFile)()));
vals = avals;
endAverage_ = avals.average();
}
else
{
IFstream(valsFile)() >> vals;
}
if (vals.size() != mapperPtr_().sourceSize())
{
FatalErrorInFunction
<< "Number of values (" << vals.size()
<< ") differs from the number of points ("
<< mapperPtr_().sourceSize()
<< ") in file " << valsFile << exit(FatalError);
}
endSampledValues_ = mapperPtr_().interpolate(vals);
}
}
}
template<class Type>
void Foam::PatchFunction1Types::MappedField<Type>::writeData
(
Ostream& os
) const
{
PatchFunction1<Type>::writeData(os);
//os << token::END_STATEMENT << nl;
// uniformValuePtr_->writeData(os);
//os << endl;
}
// ************************************************************************* //

View File

@ -1,221 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::PatchFunction1Types::MappedField
Description
SourceFiles
MappedField.C
\*---------------------------------------------------------------------------*/
#ifndef PatchFunction1Types_MappedField_H
#define PatchFunction1Types_MappedField_H
#include "PatchFunction1.H"
#include "pointToPointPlanarInterpolation.H"
#include "Function1.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
namespace PatchFunction1Types
{
/*---------------------------------------------------------------------------*\
Class MappedField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class MappedField
:
public PatchFunction1<Type>
{
// Private data
//- Name of the field data table, defaults to the name of the field
word fieldTableName_;
//- If true adjust the mapped field to maintain average value
Switch setAverage_;
//- Fraction of perturbation (fraction of bounding box) to add
scalar perturb_;
//- Name of points file; default = "points"
word pointsName_;
//- Interpolation scheme to use
word mapMethod_;
//- 2D interpolation (for 'planarInterpolation' mapMethod)
mutable autoPtr<pointToPointPlanarInterpolation> mapperPtr_;
//- List of boundaryData time directories
mutable instantList sampleTimes_;
//- Current starting index in sampleTimes
mutable label startSampleTime_;
//- Interpolated values from startSampleTime
mutable Field<Type> startSampledValues_;
//- If setAverage: starting average value
mutable Type startAverage_;
//- Current end index in sampleTimes
mutable label endSampleTime_;
//- Interpolated values from endSampleTime
mutable Field<Type> endSampledValues_;
//- If setAverage: end average value
mutable Type endAverage_;
//- Time varying offset values to interpolated data
autoPtr<Function1<Type>> offset_;
// Private Member Functions
void checkTable() const;
//- No copy assignment
void operator=(const MappedField<Type>&) = delete;
public:
// Runtime type information
TypeName("mapped");
// Constructors
//- Construct from components
MappedField
(
const polyPatch& pp,
const word& entryName,
const Field<Type>& value
);
//- Construct from entry name and dictionary
MappedField
(
const polyPatch& pp,
const word& entryName,
const dictionary& dict
);
//- Copy constructor
explicit MappedField(const MappedField<Type>& ut);
//- Copy constructor setting patch
explicit MappedField
(
const MappedField<Type>& ut,
const polyPatch& pp
);
//- Construct and return a clone
virtual tmp<PatchFunction1<Type>> clone() const
{
return tmp<PatchFunction1<Type>>
(
new MappedField<Type>(*this)
);
}
//- Construct and return a clone setting patch
virtual tmp<PatchFunction1<Type>> clone(const polyPatch& pp) const
{
return tmp<PatchFunction1<Type>>
(
new MappedField<Type>(*this, pp)
);
}
//- Destructor
virtual ~MappedField() = default;
// Member Functions
// Evaluation
//- Return MappedField value
virtual inline tmp<Field<Type>> value(const scalar) const;
//- Integrate between two values
virtual inline tmp<Field<Type>> integrate
(
const scalar x1,
const scalar x2
) const;
// Mapping
//- Map (and resize as needed) from self given a mapping object
virtual void autoMap(const FieldMapper& mapper);
//- Reverse map the given PatchFunction1 onto this PatchFunction1
virtual void rmap
(
const PatchFunction1<Type>& pf1,
const labelList& addr
);
// I-O
//- Write in dictionary format
virtual void writeData(Ostream& os) const;
};
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace PatchFunction1Types
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#include "MappedFieldI.H"
#ifdef NoRepository
#include "MappedField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -1,150 +0,0 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2018 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "MappedField.H"
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
inline Foam::tmp<Foam::Field<Type>>
Foam::PatchFunction1Types::MappedField<Type>::value
(
const scalar x
) const
{
const polyMesh& mesh = this->patch_.boundaryMesh().mesh();
checkTable();
tmp<Field<Type>> tfld(new Field<Type>(this->patch_.size()));
Field<Type>& fld = tfld.ref();
Type wantedAverage;
if (endSampleTime_ == -1)
{
// Only start value
if (debug)
{
Pout<< "updateCoeffs : Sampled, non-interpolated values"
<< " from start time:"
<< sampleTimes_[startSampleTime_].name() << nl;
}
fld = startSampledValues_;
wantedAverage = startAverage_;
}
else
{
scalar start = sampleTimes_[startSampleTime_].value();
scalar end = sampleTimes_[endSampleTime_].value();
scalar s = (mesh.time().value() - start)/(end - start);
if (debug)
{
Pout<< "updateCoeffs : Sampled, interpolated values"
<< " between start time:"
<< sampleTimes_[startSampleTime_].name()
<< " and end time:" << sampleTimes_[endSampleTime_].name()
<< " with weight:" << s << endl;
}
fld = ((1 - s)*startSampledValues_ + s*endSampledValues_);
wantedAverage = (1 - s)*startAverage_ + s*endAverage_;
}
// Enforce average. Either by scaling (if scaling factor > 0.5) or by
// offsetting.
if (setAverage_)
{
const scalarField magSf(mag(this->patch_.faceAreas()));
Type averagePsi = gSum(magSf*fld)/gSum(magSf);
if (debug)
{
Pout<< "updateCoeffs :"
<< " actual average:" << averagePsi
<< " wanted average:" << wantedAverage
<< endl;
}
if (mag(averagePsi) < VSMALL)
{
// Field too small to scale. Offset instead.
const Type offset = wantedAverage - averagePsi;
if (debug)
{
Pout<< "updateCoeffs :"
<< " offsetting with:" << offset << endl;
}
fld += offset;
}
else
{
const scalar scale = mag(wantedAverage)/mag(averagePsi);
if (debug)
{
Pout<< "updateCoeffs :"
<< " scaling with:" << scale << endl;
}
fld *= scale;
}
}
// Apply offset to mapped values
if (offset_.valid())
{
const scalar t = mesh.time().timeOutputValue();
fld += offset_->value(t);
}
if (debug)
{
Pout<< "updateCoeffs : set fixedValue to min:" << gMin(fld)
<< " max:" << gMax(fld)
<< " avg:" << gAverage(fld) << endl;
}
return this->transform(tfld);
}
template<class Type>
inline Foam::tmp<Foam::Field<Type>>
Foam::PatchFunction1Types::MappedField<Type>::integrate
(
const scalar x1,
const scalar x2
) const
{
NotImplemented;
return tmp<Field<Type>>(nullptr);
}
// ************************************************************************* //

View File

@ -837,7 +837,6 @@ DebugSwitches
sampledSet 0;
sampledSurface 0;
saturateEvaporationModel 0;
scalarAverageField 0;
scalarField 0;
scaleSimilarity 0;
scatterModel 0;
@ -864,7 +863,6 @@ DebugSwitches
spectEddyVisc 0;
sphereToCell 0;
spherical 0;
sphericalTensorAverageField 0;
sphericalTensorField 0;
standardDragModel 0;
standardEvaporationModel 0;
@ -895,12 +893,10 @@ DebugSwitches
surfaceWriter 0;
surfaces 0;
swirlInjector 0;
symmTensorAverageField 0;
symmTensorField 0;
symmetryPlane 0;
symmetry 0;
syringePressure 0;
tensorAverageField 0;
tensorField 0;
tetDecomposedPolyMesh 0;
thermoCloud 0;
@ -950,7 +946,6 @@ DebugSwitches
vanLeer01 0;
vanLeerV 0;
vector2DField 0;
vectorAverageField 0;
vectorField 0;
velocityComponentLaplacian 0;
velocityLaplacian 0;

View File

@ -28,8 +28,6 @@ License
#include "timeVaryingMappedFixedValueFvPatchField.H"
#include "Time.H"
#include "AverageField.H"
#include "IFstream.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //

View File

@ -31,8 +31,9 @@ License
#include "addToRunTimeSelectionTable.H"
#include "fvPatchFieldMapper.H"
#include "momentOfInertia.H"
#include "Fstream.H"
#include "OFstream.H"
#include "globalIndex.H"
#include "rawIOField.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -108,31 +109,30 @@ void Foam::turbulentDFSEMInletFvPatchVectorField::writeLumleyCoeffs() const
// Before interpolation/raw data
if (interpolateR_)
{
fileName valsFile
const fileName valsFile
(
fileHandler().filePath
fileName
(
fileName
(
db().time().path()
/db().time().caseConstant()
/"boundaryData"
/this->patch().name()
/"0"
/"R"
)
this->db().time().globalPath()
/this->db().time().constant()
/"boundaryData"
/this->patch().name()
/"0"
/"R"
)
);
autoPtr<ISstream> isPtr
IOobject io
(
fileHandler().NewIFstream
(
valsFile
)
valsFile, // absolute path
this->db().time(),
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
Field<symmTensor> Rexp(isPtr());
const rawIOField<symmTensor> Rexp(io, false);
OFstream os(db().time().path()/"lumley_input.out");
@ -192,17 +192,40 @@ Foam::turbulentDFSEMInletFvPatchVectorField::patchMapper() const
// Initialise interpolation (2D planar interpolation by triangulation)
if (mapperPtr_.empty())
{
// Reread values and interpolate
fileName samplePointsFile
//// Reread values and interpolate
//fileName samplePointsFile
//(
// this->db().time().path()
// /this->db().time().caseConstant()
// /"boundaryData"
// /this->patch().name()
// /"points"
//);
//
//pointField samplePoints((IFstream(samplePointsFile)()));
const fileName samplePointsFile
(
this->db().time().path()
/this->db().time().caseConstant()
this->db().time().globalPath()
/this->db().time().constant()
/"boundaryData"
/this->patch().name()
/"points"
);
pointField samplePoints((IFstream(samplePointsFile)()));
IOobject io
(
samplePointsFile, // absolute path
this->db().time(),
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
// Read data
const rawIOField<point> samplePoints(io, false);
DebugInFunction
<< " Read " << samplePoints.size() << " sample points from "

View File

@ -28,7 +28,7 @@ License
#include "pointToPointPlanarInterpolation.H"
#include "Time.H"
#include "IFstream.H"
#include "rawIOField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -73,31 +73,56 @@ Foam::turbulentDFSEMInletFvPatchVectorField::interpolateBoundaryData
{
const word& patchName = this->patch().name();
fileName valsFile
//fileName valsFile
//(
// fileHandler().filePath
// (
// fileName
// (
// this->db().time().path()
// /this->db().time().caseConstant()
// /"boundaryData"
// /patchName
// /"0"
// /fieldName
// )
// )
//);
//
//autoPtr<ISstream> isPtr
//(
// fileHandler().NewIFstream
// (
// valsFile
// )
//);
//
//Field<Type> vals(isPtr());
const fileName valsFile
(
fileHandler().filePath
fileName
(
fileName
(
this->db().time().path()
/this->db().time().caseConstant()
/"boundaryData"
/patchName
/"0"
/fieldName
)
this->db().time().globalPath()
/this->db().time().constant()
/"boundaryData"
/patchName
/"0"
/fieldName
)
);
autoPtr<ISstream> isPtr
IOobject io
(
fileHandler().NewIFstream
(
valsFile
)
valsFile, // absolute path
this->db().time(),
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
Field<Type> vals(isPtr());
const rawIOField<Type> vals(io, false);
Info<< "Turbulent DFSEM patch " << patchName
<< ": interpolating field " << fieldName

View File

@ -53,17 +53,41 @@ Foam::turbulentDigitalFilterInletFvPatchVectorField::patchMapper() const
// Initialise interpolation (2D planar interpolation by triangulation)
if (mapperPtr_.empty())
{
//// Reread values and interpolate
//fileName samplePointsFile
//(
// this->db().time().path()
// /this->db().time().caseConstant()
// /"boundaryData"
// /this->patch().name()
// /"points"
//);
//
//pointField samplePoints((IFstream(samplePointsFile)()));
// Reread values and interpolate
fileName samplePointsFile
const fileName samplePointsFile
(
this->db().time().path()
/this->db().time().caseConstant()
this->db().time().globalPath()
/this->db().time().constant()
/"boundaryData"
/this->patch().name()
/"points"
);
pointField samplePoints((IFstream(samplePointsFile)()));
IOobject io
(
samplePointsFile, // absolute path
this->db().time(),
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
// Read data
const rawIOField<point> samplePoints(io, false);
// tbd: run-time selection
bool nearestOnly =

View File

@ -28,7 +28,7 @@ License
#include "pointToPointPlanarInterpolation.H"
#include "Time.H"
#include "IFstream.H"
#include "rawIOField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -73,31 +73,55 @@ Foam::turbulentDigitalFilterInletFvPatchVectorField::interpolateBoundaryData
{
const word& patchName = this->patch().name();
fileName valsFile
//fileName valsFile
//(
// fileHandler().filePath
// (
// fileName
// (
// this->db().time().path()
// /this->db().time().caseConstant()
// /"boundaryData"
// /patchName
// /"0"
// /fieldName
// )
// )
//);
//
//autoPtr<ISstream> isPtr
//(
// fileHandler().NewIFstream
// (
// valsFile
// )
//);
//
//Field<Type> vals(isPtr());
// Reread values and interpolate
const fileName valsFile
(
fileHandler().filePath
(
fileName
(
this->db().time().path()
/this->db().time().caseConstant()
/"boundaryData"
/patchName
/"0"
/fieldName
)
)
this->db().time().globalPath()
/this->db().time().constant()
/"boundaryData"
/patchName
/"0"
/fieldName
);
autoPtr<ISstream> isPtr
IOobject io
(
fileHandler().NewIFstream
(
valsFile
)
valsFile, // absolute path
this->db().time(),
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
Field<Type> vals(isPtr());
const rawIOField<Type> vals(io, false);
Info<< "Turbulent DFM/FSM patch " << patchName
<< ": Interpolating field " << fieldName

View File

@ -28,8 +28,7 @@ License
#include "timeVaryingMappedFixedValuePointPatchField.H"
#include "Time.H"
#include "AverageField.H"
#include "IFstream.H"
#include "rawIOField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -246,6 +245,8 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::rmap
template<class Type>
void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
{
const Time& time = this->db().time();
// Initialise
if (startSampleTime_ == -1 && endSampleTime_ == -1)
{
@ -284,15 +285,26 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
}
// Reread values and interpolate
fileName samplePointsFile
const fileName samplePointsFile
(
this->db().time().caseConstant()
time.caseConstant()
/"boundaryData"
/this->patch().name()
/"points"
);
pointField samplePoints((IFstream(samplePointsFile)()));
IOobject io
(
samplePointsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
// Read data
const rawIOField<point> samplePoints(io, false);
// tbd: run-time selection
bool nearestOnly =
@ -335,7 +347,7 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
(
sampleTimes_,
startSampleTime_,
this->db().time().value(),
time.value(),
lo,
hi
);
@ -344,11 +356,11 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
{
FatalErrorInFunction
<< "Cannot find starting sampling values for current time "
<< this->db().time().value() << nl
<< time.value() << nl
<< "Have sampling values for times "
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl
<< "In directory "
<< this->db().time().constant()/"boundaryData"/this->patch().name()
<< time.constant()/"boundaryData"/this->patch().name()
<< "\n on patch " << this->patch().name()
<< " of field " << fieldTableName_
<< exit(FatalError);
@ -387,26 +399,29 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
}
// Reread values and interpolate
fileName valsFile
const fileName valsFile
(
this->db().time().caseConstant()
time.caseConstant()
/"boundaryData"
/this->patch().name()
/sampleTimes_[startSampleTime_].name()
/fieldTableName_
);
Field<Type> vals;
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (setAverage_)
{
AverageField<Type> avals((IFstream(valsFile)()));
vals = avals;
startAverage_ = avals.average();
}
else
{
IFstream(valsFile)() >> vals;
startAverage_ = vals.average();
}
if (vals.size() != mapperPtr_().sourceSize())
@ -447,26 +462,30 @@ void Foam::timeVaryingMappedFixedValuePointPatchField<Type>::checkTable()
}
// Reread values and interpolate
fileName valsFile
const fileName valsFile
(
this->db().time().caseConstant()
time.caseConstant()
/"boundaryData"
/this->patch().name()
/sampleTimes_[endSampleTime_].name()
/fieldTableName_
);
Field<Type> vals;
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (setAverage_)
{
AverageField<Type> avals((IFstream(valsFile)()));
vals = avals;
endAverage_ = avals.average();
}
else
{
IFstream(valsFile)() >> vals;
endAverage_ = vals.average();
}
if (vals.size() != mapperPtr_().sourceSize())

View File

@ -298,6 +298,7 @@ polyTopoChange/polyTopoChange.C
PatchFunction1/makePatchFunction1s.C
PatchFunction1/coordinateLabelScaling.C
PatchFunction1/CodedField/makeCodedFields.C
PatchFunction1/MappedFile/rawIOFields.C
meshStructure/meshStructure.C

View File

@ -26,8 +26,7 @@ License
\*---------------------------------------------------------------------------*/
#include "polyMesh.H"
#include "IFstream.H"
#include "AverageField.H"
#include "rawIOField.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
@ -239,21 +238,33 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
) const
{
const polyMesh& mesh = this->patch_.boundaryMesh().mesh();
const Time& time = mesh.time();
// Initialise
if (!mapperPtr_)
{
// Reread values and interpolate
fileName samplePointsFile
const fileName samplePointsFile
(
mesh.time().globalPath()
/mesh.time().constant()
time.globalPath()
/time.constant()
/"boundaryData"
/this->patch_.name()
/pointsName_
);
pointField samplePoints((IFstream(samplePointsFile)()));
IOobject io
(
samplePointsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
// Read data
const rawIOField<point> samplePoints(io, false);
DebugInfo
<< "Read " << samplePoints.size() << " sample points from "
@ -329,7 +340,7 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
<< "Have sampling values for "
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl
<< "In directory "
<< mesh.time().constant()/"boundaryData"/this->patch_.name()
<< time.constant()/"boundaryData"/this->patch_.name()
<< "\n on patch " << this->patch_.name()
<< " of field " << fieldTableName_
<< exit(FatalError);
@ -369,27 +380,30 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
// Reread values and interpolate
fileName valsFile
const fileName valsFile
(
mesh.time().globalPath()
/mesh.time().constant()
time.globalPath()
/time.constant()
/"boundaryData"
/this->patch_.name()
/sampleTimes_[startSampleTime_].name()
/fieldTableName_
);
Field<Type> vals;
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (setAverage_)
{
AverageField<Type> avals((IFstream(valsFile)()));
vals = avals;
startAverage_ = avals.average();
}
else
{
IFstream(valsFile)() >> vals;
startAverage_ = vals.average();
}
if (vals.size() != mapperPtr_().sourceSize())
@ -432,25 +446,28 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
// Reread values and interpolate
fileName valsFile
(
mesh.time().globalPath()
/mesh.time().constant()
time.globalPath()
/time.constant()
/"boundaryData"
/this->patch_.name()
/sampleTimes_[endSampleTime_].name()
/fieldTableName_
);
Field<Type> vals;
IOobject io
(
valsFile, // absolute path
time,
IOobject::MUST_READ,
IOobject::NO_WRITE,
false, // no need to register
true // is global object (currently not used)
);
const rawIOField<Type> vals(io, setAverage_);
if (setAverage_)
{
AverageField<Type> avals((IFstream(valsFile)()));
vals = avals;
endAverage_ = avals.average();
}
else
{
IFstream(valsFile)() >> vals;
endAverage_ = vals.average();
}
if (vals.size() != mapperPtr_().sourceSize())

View File

@ -0,0 +1,149 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2016-2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
\*---------------------------------------------------------------------------*/
#include "rawIOField.H"
#include "IFstream.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type>
Foam::rawIOField<Type>::rawIOField(const IOobject& io, const bool readAverage)
:
regIOobject(io),
average_(Zero)
{
// Check for MUST_READ_IF_MODIFIED
warnNoRereading<rawIOField<Type>>();
if
(
io.readOpt() == IOobject::MUST_READ
|| io.readOpt() == IOobject::MUST_READ_IF_MODIFIED
|| io.readOpt() == IOobject::READ_IF_PRESENT
)
{
bool haveFile = false;
bool headerOk = false;
// Replacement of regIOobject::headerok() since that one complains
// if there is no header. TBD - Move up to headerOk()/fileHandler.
{
const fileName fName(filePath());
// Try to open raw first
autoPtr<ISstream> isPtr(fileHandler().NewIFstream(fName));
if (isPtr && isPtr->good())
{
haveFile = true;
ISstream& is = isPtr();
const token firstToken(is);
headerOk =
is.good()
&& firstToken.isWord()
&& firstToken.wordToken() == "FoamFile";
}
isPtr.clear();
if (debug)
{
Pout<< "rawIOField : object:" << io.name()
<< " haveFile:" << haveFile
<< " headerOk:" << headerOk << endl;
}
}
if (headerOk)
{
// Read but don't fail upon wrong class. Could extend by providing
// wanted typeName. Tbd.
Istream& is = readStream(word::null);
if (is.good())
{
is >> static_cast<Field<Type>&>(*this);
if (readAverage)
{
average_ = pTraits<Type>(is);
}
close();
}
}
else if (haveFile)
{
// Failed reading - fall back to IFstream
autoPtr<ISstream> isPtr(fileHandler().NewIFstream(io.objectPath()));
if (!isPtr || !isPtr->good())
{
if (io.readOpt() != IOobject::READ_IF_PRESENT)
{
FatalIOErrorInFunction(isPtr)
<< "Trying to read raw field" << exit(FatalIOError);
}
}
else
{
ISstream& is = isPtr();
is >> static_cast<Field<Type>&>(*this);
if (readAverage)
{
average_ = pTraits<Type>(is);
}
}
}
if (debug)
{
Pout<< "rawIOField : object:" << io.name()
<< " size:" << this->size() << endl;
}
}
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
bool Foam::rawIOField<Type>::writeData(Ostream& os) const
{
os << static_cast<const Field<Type>&>(*this);
if (average_ != pTraits<Type>::zero)
{
os << token::NL << average_;
}
return os.good();
}
// ************************************************************************* //

View File

@ -5,7 +5,6 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -25,20 +24,21 @@ License
along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
Class
Foam::AverageField
Foam::rawIOField
Description
A primitive field with a separate average value.
Like IOField but falls back to raw IFstream if no header found.
Optionally reads average value. For use in MappedFile container.
SourceFiles
AverageField.C
rawIOField.C
\*---------------------------------------------------------------------------*/
#ifndef AverageField_H
#define AverageField_H
#ifndef rawIOField_H
#define rawIOField_H
#include "Field.H"
#include "IOField.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
@ -46,41 +46,53 @@ namespace Foam
{
/*---------------------------------------------------------------------------*\
Class AverageField Declaration
Class rawIOField Declaration
\*---------------------------------------------------------------------------*/
template<class Type>
class AverageField
class rawIOField
:
public regIOobject,
public Field<Type>
{
// Private Data
//- The average of the field
//- The average of the field (Zero if not used)
Type average_;
public:
TypeName("rawField");
// Constructors
//- Construct from size (does not set values)
explicit AverageField(const label size);
//- Default copy construct
rawIOField(const rawIOField&) = default;
//- Construct from components
AverageField(const Field<Type>& fld, const Type& average);
//- Construct from IOobject
explicit rawIOField(const IOobject& io, const bool readAverage);
//- Construct from Istream
explicit AverageField(Istream& is);
//- Destructor
virtual ~rawIOField() = default;
// Member Functions
const Type& average() const;
Type& average();
const Type& average() const
{
return average_;
}
bool writeData(Ostream& os) const;
// Member Operators
//- Copy or move assignment of entries
using Field<Type>::operator=;
};
@ -91,7 +103,7 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "AverageField.C"
#include "rawIOField.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

View File

@ -5,7 +5,6 @@
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2011-2016 OpenFOAM Foundation
Copyright (C) 2020 OpenCFD Ltd.
-------------------------------------------------------------------------------
License
@ -26,63 +25,25 @@ License
\*---------------------------------------------------------------------------*/
#include "AverageField.H"
#include "rawIOField.H"
#include "fieldTypes.H"
#include "addToRunTimeSelectionTable.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
Foam::AverageField<Type>::AverageField(const label size)
:
Field<Type>(size),
average_(Zero)
{}
template<class Type>
Foam::AverageField<Type>::AverageField
(
const Field<Type>& fld,
const Type& average
)
:
Field<Type>(fld),
average_(average)
{}
template<class Type>
Foam::AverageField<Type>::AverageField(Istream& is)
:
Field<Type>(is),
average_(pTraits<Type>(is))
{}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
template<class Type>
const Type& Foam::AverageField<Type>::average() const
namespace Foam
{
return average_;
}
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
template<class Type>
Type&Foam::AverageField<Type>::average()
{
return average_;
}
defineNamedTemplateTypeNameAndDebug(rawIOField<scalar>, 0);
defineNamedTemplateTypeNameAndDebug(rawIOField<vector>, 0);
defineNamedTemplateTypeNameAndDebug(rawIOField<sphericalTensor>, 0);
defineNamedTemplateTypeNameAndDebug(rawIOField<symmTensor>, 0);
defineNamedTemplateTypeNameAndDebug(rawIOField<tensor>, 0);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
template<class Type>
bool Foam::AverageField<Type>::writeData(Ostream& os) const
{
os << static_cast<const Field<Type>&>(*this)
<< token::NL
<< average_;
return os.good();
}
} // End namespace Foam
// ************************************************************************* //

View File

@ -61,6 +61,16 @@ functions
{
type surfaces;
surfaceFormat boundaryData;
formatOptions
{
//// Optionally specify write options
//boundaryData
//{
// header true; // write as OpenFOAM object
// format binary; // write binary or ascii
// compression false; // compress after writing
//}
}
writeControl writeTime;
interpolationScheme cell;
fields