ENH: support format readOptions for surfaceReader types (#2609)

- similar to surface writing formats, also support optional
  dictionary of reading options. The main beneficiary of this is the
  ensight surface reader:

  readOptions
  {
      ensight
      {
          masterOnly true;
      }
  }

  This will restrict reading to the master rank. Surfaces and values
  read will be broadcast to the other ranks, with the intention of
  reducing load on the filesystem.

ENH: add writing of Dimensioned fields for areaWrite functionObject

- can be useful for examining finite-area source terms
This commit is contained in:
Mark Olesen
2022-12-07 16:53:58 +01:00
parent b69db76b67
commit 8afd6ff729
27 changed files with 813 additions and 401 deletions

View File

@ -65,7 +65,11 @@ Foam::fa::externalFileSource::externalFileSource
mesh_, mesh_,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false // Do not register (
dict.getOrDefault("store", false)
? IOobject::REGISTER
: IOobject::NO_REGISTER
)
), ),
regionMesh(), regionMesh(),
dimensionedScalar(dimPressure, Zero) dimensionedScalar(dimPressure, Zero)
@ -75,6 +79,10 @@ Foam::fa::externalFileSource::externalFileSource
{ {
fieldNames_.resize(1, fieldName_); fieldNames_.resize(1, fieldName_);
/// FUTURE?
/// // Optional entry (mandatory = false)
/// pExt_.dimensions().readEntry("dimensions", dict, false);
fa::option::resetApplied(); fa::option::resetApplied();
read(dict); read(dict);
@ -155,7 +163,7 @@ bool Foam::fa::externalFileSource::read(const dictionary& dict)
new PatchFunction1Types::MappedFile<scalar> new PatchFunction1Types::MappedFile<scalar>
( (
p, p,
"uniformValue", "uniformValue", // entryName
dict, dict,
tableName_, // field table name tableName_, // field table name
true // face values true // face values

View File

@ -54,6 +54,7 @@ Usage
type | Type name: externalFileSource | word | yes | - type | Type name: externalFileSource | word | yes | -
fieldName | Name of operand field | word | yes | - fieldName | Name of operand field | word | yes | -
tableName | Name of operand table file | word | yes | - tableName | Name of operand table file | word | yes | -
store | Register external field 'pExt' | bool | no | false
\endtable \endtable
The inherited entries are elaborated in: The inherited entries are elaborated in:

View File

@ -1,3 +1,4 @@
common/fileFormats.C
common/manifoldCellsMeshObject.C common/manifoldCellsMeshObject.C
colours/colourTable.C colours/colourTable.C

View File

@ -0,0 +1,122 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 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 "fileFormats.H"
#include "dictionary.H"
// * * * * * * * * * * * * * * * Local Functions * * * * * * * * * * * * * * //
namespace Foam
{
// Extract and merge 'default' + formatName from list of dictionaries
//
// \returns dictionary of merged options
static dictionary combineFormatOptions
(
const word& formatName,
std::initializer_list<const dictionary*> dicts
)
{
dictionary options;
// Default specification. Merge from all levels
// - literal search only
for (const dictionary* dict : dicts)
{
if
(
dict
&& (dict = dict->findDict("default", keyType::LITERAL)) != nullptr
)
{
options.merge(*dict);
}
}
// Format specification. Merge from all levels
// - allow REGEX search
if (!formatName.empty())
{
for (const dictionary* dict : dicts)
{
if
(
dict
&& (dict = dict->findDict(formatName)) != nullptr
)
{
options.merge(*dict);
}
}
}
return options;
}
} // End namespace Foam
// * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * //
Foam::dictionary Foam::fileFormats::getFormatOptions
(
const dictionary& dict,
const word& formatName,
const word& entryName
)
{
return combineFormatOptions
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL)
}
);
}
Foam::dictionary Foam::fileFormats::getFormatOptions
(
const dictionary& dict,
const dictionary& altDict,
const word& formatName,
const word& entryName
)
{
return combineFormatOptions
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL),
altDict.findDict(entryName, keyType::LITERAL)
}
);
}
// ************************************************************************* //

View File

@ -0,0 +1,102 @@
/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | www.openfoam.com
\\/ M anipulation |
-------------------------------------------------------------------------------
Copyright (C) 2022 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/>.
Namespace
Foam::fileFormats
Description
Namespace to isolate specifics for file formats,
and some common utilities.
SourceFiles
fileFormats.C
\*---------------------------------------------------------------------------*/
#ifndef Foam_fileFormats_H
#define Foam_fileFormats_H
#include "word.H"
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace Foam
{
// Forward Declarations
class dictionary;
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
namespace fileFormats
{
//- Find "formatOptions" in a top-level dictionary.
//- Extract and merge 'default' + formatName values.
//
// \returns dictionary of merged formatOptions
dictionary getFormatOptions
(
//! The top-level dictionary to search
const dictionary& dict,
//! The format name. Eg, \c ensight
const word& formatName,
//! Dictionary sub-entry to search for
const word& entryName = "formatOptions"
);
//- Find "formatOptions" in a top-level dictionary,
//- and optional override dictionary.
//- Extract and merge 'default' + formatName values.
//
// \returns dictionary of merged formatOptions
dictionary getFormatOptions
(
//! The top-level dictionary to search
const dictionary& dict,
//! Additional dictionary to search
const dictionary& altDict,
//! The format name. Eg, \c ensight
const word& formatName,
//! Dictionary sub-entry to search for
const word& entryName = "formatOptions"
);
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
} // End namespace fileFormats
} // End namespace Foam
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif
// ************************************************************************* //

View File

@ -180,7 +180,27 @@ Foam::Istream& Foam::ensightReadFile::read(label& value)
} }
Foam::Istream& Foam::ensightReadFile::read(scalar& value) Foam::Istream& Foam::ensightReadFile::read(float& value)
{
if (format() == IOstreamOption::BINARY)
{
read
(
reinterpret_cast<char*>(&value),
sizeof(value)
);
}
else
{
stdStream() >> value;
syncState();
}
return *this;
}
Foam::Istream& Foam::ensightReadFile::read(double& value)
{ {
float fvalue; float fvalue;
@ -191,15 +211,14 @@ Foam::Istream& Foam::ensightReadFile::read(scalar& value)
reinterpret_cast<char*>(&fvalue), reinterpret_cast<char*>(&fvalue),
sizeof(fvalue) sizeof(fvalue)
); );
value = fvalue;
} }
else else
{ {
stdStream() >> value; stdStream() >> fvalue;
syncState(); syncState();
} }
value = fvalue;
return *this; return *this;
} }

View File

@ -27,7 +27,8 @@ Class
Foam::ensightReadFile Foam::ensightReadFile
Description Description
Ensight output with specialized read() for strings, integers and floats. A variant of IFstream with specialised read() for
strings, integers and floats.
Correctly handles binary read as well. Correctly handles binary read as well.
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -98,13 +99,16 @@ public:
virtual Istream& read(char* buf, std::streamsize count); virtual Istream& read(char* buf, std::streamsize count);
//- Read string as "%80s" or as binary //- Read string as "%80s" or as binary
Istream& read(string& value); virtual Istream& read(string& value);
//- Read integer as "%10d" or as binary //- Read integer as "%10d" or as binary
Istream& read(label& value); virtual Istream& read(label& value);
//- Read float as "%12.5e" or as binary //- Read floating-point as "%12.5e" or as binary
Istream& read(scalar& value); virtual Istream& read(float& value);
//- Read floating-point as "%12.5e" or as a binary (narrowed) float
virtual Istream& read(double& value);
//- Read element keyword //- Read element keyword
virtual Istream& readKeyword(string& key); virtual Istream& readKeyword(string& key);

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2016-2017 Wikki Ltd Copyright (C) 2016-2017 Wikki Ltd
Copyright (C) 2018 OpenCFD Ltd. Copyright (C) 2018-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -92,5 +92,14 @@ const Foam::wordList Foam::fieldTypes::area
"areaTensorField" "areaTensorField"
}); });
const Foam::wordList Foam::fieldTypes::area_internal
({
"areaScalarField::Internal",
"areaVectorField::Internal",
"areaSphericalTensorField::Internal",
"areaSymmTensorField::Internal",
"areaTensorField::Internal"
});
// ************************************************************************* // // ************************************************************************* //

View File

@ -92,6 +92,9 @@ namespace fieldTypes
//- Standard area field types (scalar, vector, tensor, etc) //- Standard area field types (scalar, vector, tensor, etc)
extern const wordList area; extern const wordList area;
//- Standard dimensioned field types (scalar, vector, tensor, etc)
extern const wordList area_internal;
} // End namespace fieldTypes } // End namespace fieldTypes

View File

@ -53,6 +53,10 @@ namespace Foam
Foam::scalar Foam::areaWrite::mergeTol_ = 1e-10; Foam::scalar Foam::areaWrite::mergeTol_ = 1e-10;
// Implementation
#include "areaWriteImpl.C"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::areaWrite::areaWrite Foam::areaWrite::areaWrite
@ -110,7 +114,7 @@ Foam::areaWrite::areaWrite
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
bool Foam::areaWrite::verbose(const bool on) bool Foam::areaWrite::verbose(const bool on) noexcept
{ {
bool old(verbose_); bool old(verbose_);
verbose_ = on; verbose_ = on;
@ -137,7 +141,7 @@ bool Foam::areaWrite::read(const dictionary& dict)
obr_, obr_,
IOobject::NO_READ, IOobject::NO_READ,
IOobject::NO_WRITE, IOobject::NO_WRITE,
false IOobject::NO_REGISTER
) )
) )
); );
@ -299,7 +303,11 @@ bool Foam::areaWrite::write()
const word& clsName = iter.key(); const word& clsName = iter.key();
const label n = iter.val().size(); const label n = iter.val().size();
if (fieldTypes::area.found(clsName)) if
(
fieldTypes::area.found(clsName)
|| fieldTypes::area_internal.found(clsName)
)
{ {
nAreaFields += n; nAreaFields += n;
} }
@ -318,11 +326,43 @@ bool Foam::areaWrite::write()
// Write fields // Write fields
performAction<areaScalarField>(outWriter, areaMesh, objects); {
performAction<areaVectorField>(outWriter, areaMesh, objects); // Area fields
performAction<areaSphericalTensorField>(outWriter, areaMesh, objects); #undef doLocalCode
performAction<areaSymmTensorField>(outWriter, areaMesh, objects); #define doLocalCode(Type) \
performAction<areaTensorField>(outWriter, areaMesh, objects); performAction \
< \
GeometricField<Type, Foam::faPatchField, Foam::areaMesh> \
> \
( \
outWriter, areaMesh, objects \
); \
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
// Area internal fields
#undef doLocalCode
#define doLocalCode(Type) \
performAction \
< \
DimensionedField<Type, Foam::areaMesh> \
> \
( \
outWriter, areaMesh, objects \
);
doLocalCode(scalar);
doLocalCode(vector);
doLocalCode(sphericalTensor);
doLocalCode(symmTensor);
doLocalCode(tensor);
#undef doLocalCode
}
// Finish this time step // Finish this time step
@ -384,17 +424,17 @@ void Foam::areaWrite::readUpdate(const polyMesh::readUpdateState state)
} }
Foam::scalar Foam::areaWrite::mergeTol() Foam::scalar Foam::areaWrite::mergeTol() noexcept
{ {
return mergeTol_; return mergeTol_;
} }
Foam::scalar Foam::areaWrite::mergeTol(const scalar tol) Foam::scalar Foam::areaWrite::mergeTol(const scalar tol) noexcept
{ {
const scalar prev(mergeTol_); scalar old(mergeTol_);
mergeTol_ = tol; mergeTol_ = tol;
return prev; return old;
} }

View File

@ -210,7 +210,7 @@ public:
//- Enable/disable verbose output //- Enable/disable verbose output
// \return old value // \return old value
bool verbose(const bool on); bool verbose(const bool on) noexcept;
//- Read the areaWrite dictionary //- Read the areaWrite dictionary
virtual bool read(const dictionary& dict); virtual bool read(const dictionary& dict);
@ -231,10 +231,10 @@ public:
virtual void readUpdate(const polyMesh::readUpdateState state); virtual void readUpdate(const polyMesh::readUpdateState state);
//- Get merge tolerance //- Get merge tolerance
static scalar mergeTol(); static scalar mergeTol() noexcept;
//- Set merge tolerance and return old value //- Set merge tolerance and return old value
static scalar mergeTol(const scalar tol); static scalar mergeTol(const scalar tol) noexcept;
}; };
@ -244,12 +244,6 @@ public:
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#ifdef NoRepository
#include "areaWriteTemplates.C"
#endif
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
#endif #endif
// ************************************************************************* // // ************************************************************************* //

View File

@ -27,93 +27,14 @@ License
#include "polyMesh.H" #include "polyMesh.H"
#include "rawIOField.H" #include "rawIOField.H"
#include "clockTime.H"
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
template<class Type> template<class Type>
Foam::PatchFunction1Types::MappedFile<Type>::MappedFile Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
( (
const polyPatch& pp, const bool dictConstructed,
const word& redirectType,
const word& entryName,
const dictionary& dict,
const bool faceValues
)
:
PatchFunction1<Type>(pp, entryName, dict, faceValues),
dictConstructed_(true),
setAverage_(dict.getOrDefault("setAverage", false)),
perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)),
fieldTableName_(dict.getOrDefault<word>("fieldTable", entryName)),
pointsName_(dict.getOrDefault<word>("points", "points")),
mapMethod_(),
filterRadius_(dict.getOrDefault<scalar>("filterRadius", 0)),
filterSweeps_(dict.getOrDefault<label>("filterSweeps", 0)),
filterFieldPtr_(nullptr),
readerFormat_(),
readerFile_(),
readerPtr_(nullptr),
mapperPtr_(nullptr),
sampleTimes_(),
sampleIndex_(-1, -1),
sampleAverage_(Zero, Zero),
sampleValues_(),
offset_(Function1<Type>::NewIfPresent("offset", dict))
{
// Simple sanity check
if ((filterSweeps_ < 1) || (filterRadius_ <= VSMALL))
{
filterRadius_ = 0;
filterSweeps_ = 0;
}
if (dict.readIfPresent("sampleFormat", readerFormat_))
{
dict.readEntry("sampleFile", readerFile_);
fileName fName(readerFile_);
fName.expand();
readerPtr_ = surfaceReader::New(readerFormat_, fName);
}
if (debug)
{
Info<< "mappedFile:" << nl;
if (readerFormat_.empty())
{
Info<< " boundary format" << nl;
}
else
{
Info<< " format:" << readerFormat_
<< " file:" << readerFile_ << nl;
}
Info<< " filter radius=" << filterRadius_
<< " sweeps=" << filterSweeps_ << endl;
}
if
(
dict.readIfPresent("mapMethod", mapMethod_)
&& !mapMethod_.empty()
&& mapMethod_ != "nearest"
&& !mapMethod_.starts_with("planar")
)
{
FatalIOErrorInFunction(dict)
<< "Unknown mapMethod type " << mapMethod_
<< "\n\nValid mapMethod types :\n"
<< "(nearest planar)" << nl
<< exit(FatalIOError);
}
}
template<class Type>
Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
(
const polyPatch& pp, const polyPatch& pp,
const word& entryName, const word& entryName,
const dictionary& dict, const dictionary& dict,
@ -122,7 +43,7 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
) )
: :
PatchFunction1<Type>(pp, entryName, dict, faceValues), PatchFunction1<Type>(pp, entryName, dict, faceValues),
dictConstructed_(false), dictConstructed_(dictConstructed),
setAverage_(dict.getOrDefault("setAverage", false)), setAverage_(dict.getOrDefault("setAverage", false)),
perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)), perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)),
fieldTableName_(fieldTableName), fieldTableName_(fieldTableName),
@ -141,6 +62,11 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
sampleValues_(), sampleValues_(),
offset_(Function1<Type>::NewIfPresent("offset", dict)) offset_(Function1<Type>::NewIfPresent("offset", dict))
{ {
if (fieldTableName_.empty())
{
fieldTableName_ = entryName;
}
// Simple sanity check // Simple sanity check
if ((filterSweeps_ < 1) || (filterRadius_ <= VSMALL)) if ((filterSweeps_ < 1) || (filterRadius_ <= VSMALL))
{ {
@ -155,7 +81,12 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
fileName fName(readerFile_); fileName fName(readerFile_);
fName.expand(); fName.expand();
readerPtr_ = surfaceReader::New(readerFormat_, fName); readerPtr_ = surfaceReader::New
(
readerFormat_,
fName,
surfaceReader::formatOptions(dict, readerFormat_, "readOptions")
);
} }
if (debug) if (debug)
@ -192,6 +123,50 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
} }
template<class Type>
Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
(
const polyPatch& pp,
const word& redirectType,
const word& entryName,
const dictionary& dict,
const bool faceValues
)
:
MappedFile<Type>
(
true, // dictConstructed = true
pp,
entryName,
dict,
dict.getOrDefault<word>("fieldTable", entryName),
faceValues
)
{}
template<class Type>
Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
(
const polyPatch& pp,
const word& entryName,
const dictionary& dict,
const word& fieldTableName,
const bool faceValues
)
:
MappedFile<Type>
(
false, // dictConstructed = false
pp,
entryName,
dict,
fieldTableName,
faceValues
)
{}
template<class Type> template<class Type>
Foam::PatchFunction1Types::MappedFile<Type>::MappedFile Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
( (
@ -313,9 +288,20 @@ void Foam::PatchFunction1Types::MappedFile<Type>::updateSampledValues
label fieldIndex = fieldNames.find(fieldTableName_); label fieldIndex = fieldNames.find(fieldTableName_);
DebugInfo if (fieldIndex < 0)
<< "checkTable : Update index=" << sampleIndex {
<< " field=" << fieldNames[fieldIndex] << endl; FatalErrorInFunction
<< "Sample field='" << fieldTableName_
<< "' not found. Known field names: "
<< flatOutput(fieldNames) << nl
<< exit(FatalError);
}
if (debug)
{
Pout<< "checkTable : Update index=" << sampleIndex
<< " field=" << fieldNames[fieldIndex] << endl;
}
tvalues = readerPtr_->field tvalues = readerPtr_->field
( (
@ -418,6 +404,8 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
// Initialise // Initialise
if (!mapperPtr_ && readerPtr_) if (!mapperPtr_ && readerPtr_)
{ {
clockTime timing;
auto& reader = readerPtr_(); auto& reader = readerPtr_();
const meshedSurface& geom = reader.geometry(0); const meshedSurface& geom = reader.geometry(0);
@ -436,7 +424,8 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
<< "Read " << samplePoints.size() << " sample points from " << "Read " << samplePoints.size() << " sample points from "
<< readerFile_ << endl << readerFile_ << endl
<< "Found times " << "Found times "
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl; << pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl
<< "... in " << timing.timeIncrement() << 's' << endl;
// tbd: run-time selection // tbd: run-time selection
const bool nearestOnly = const bool nearestOnly =
@ -444,7 +433,6 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
!mapMethod_.empty() && !mapMethod_.starts_with("planar") !mapMethod_.empty() && !mapMethod_.starts_with("planar")
); );
// Allocate the interpolator // Allocate the interpolator
if (this->faceValues()) if (this->faceValues())
{ {
@ -473,10 +461,19 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
); );
} }
DebugInfo
<< "Created point/point planar interpolation"
<< " - in " << timing.timeIncrement() << 's' << endl;
// Setup median filter (if any) // Setup median filter (if any)
if (filterSweeps_ > 0) if (filterSweeps_ > 0)
{ {
filterFieldPtr_.reset(new FilterField(geom, filterRadius_)); filterFieldPtr_.reset(new FilterField(geom, filterRadius_));
DebugInfo
<< "Calculated field-filter"
<< " - in " << timing.timeIncrement() << 's' << endl;
} }
else else
{ {
@ -485,6 +482,8 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
} }
else if (!mapperPtr_) else if (!mapperPtr_)
{ {
clockTime timing;
// Reread values and interpolate // Reread values and interpolate
const fileName samplePointsFile const fileName samplePointsFile
( (
@ -509,16 +508,23 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
// Read data (no average value!) // Read data (no average value!)
const rawIOField<point> samplePoints(io); const rawIOField<point> samplePoints(io);
// Read the times for which data is available
sampleTimes_ = Time::findTimes(samplePointsFile.path());
DebugInfo
<< "Read " << samplePoints.size() << " sample points from "
<< samplePointsFile << endl
<< "Found times "
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl
<< "... in " << timing.timeIncrement() << 's' << endl;
// tbd: run-time selection // tbd: run-time selection
const bool nearestOnly = const bool nearestOnly =
( (
!mapMethod_.empty() && !mapMethod_.starts_with("planar") !mapMethod_.empty() && !mapMethod_.starts_with("planar")
); );
DebugInfo
<< "Read " << samplePoints.size() << " sample points from "
<< samplePointsFile << endl;
// Allocate the interpolator // Allocate the interpolator
if (this->faceValues()) if (this->faceValues())
{ {
@ -547,19 +553,19 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
); );
} }
// Read the times for which data is available
const fileName samplePointsDir = samplePointsFile.path();
sampleTimes_ = Time::findTimes(samplePointsDir);
DebugInfo DebugInfo
<< "Found times " << "Created point/point planar interpolation"
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_) << " - in " << timing.timeIncrement() << 's' << endl;
<< endl;
// Setup median filter (if any) // Setup median filter (if any)
if (filterSweeps_ > 0) if (filterSweeps_ > 0)
{ {
filterFieldPtr_.reset(new FilterField(samplePoints, filterRadius_)); filterFieldPtr_.reset(new FilterField(samplePoints, filterRadius_));
DebugInfo
<< "Calculated field-filter"
<< " - in " << timing.timeIncrement() << 's' << endl;
} }
else else
{ {

View File

@ -62,6 +62,7 @@ Description
sampleFile | <case>/foo/bar/window.case sampleFile | <case>/foo/bar/window.case
filterRadius | Search radius [m] for median filter neighbours filterRadius | Search radius [m] for median filter neighbours
filterSweeps | Filter sweeps for median filter filterSweeps | Filter sweeps for median filter
readOptions | Format options for surfaceReader format (eg, ensight)
\endtable \endtable
Note Note
@ -173,6 +174,17 @@ class MappedFile
Type& avg Type& avg
) const; ) const;
//- Construct from entry name and dictionary
MappedFile
(
const bool dictConstructed,
const polyPatch& pp,
const word& entryName,
const dictionary& dict,
const word& fieldTableName,
const bool faceValues
);
public: public:
//- Runtime type information //- Runtime type information
@ -204,7 +216,7 @@ public:
const word& entryName, const word& entryName,
const dictionary& dict, const dictionary& dict,
const word& fieldTableName, const word& fieldTableName,
const bool faceValues const bool faceValues = true
); );
//- Copy construct //- Copy construct

View File

@ -227,7 +227,7 @@ void Foam::PatchFunction1Types::FilterField::buildWeightsImpl
total += n; total += n;
} }
Info<< "Weight neighbours: min=" << limits.min() Pout<< "Weight neighbours: min=" << limits.min()
<< " avg=" << (total / addressing_.size()) << " avg=" << (total / addressing_.size())
<< " max=" << limits.max() << endl; << " max=" << limits.max() << endl;
} }
@ -279,7 +279,7 @@ void Foam::PatchFunction1Types::FilterField::reset
if (debug) if (debug)
{ {
Info<< "Apply " << RBF_typeNames_[interp] << " filter," Pout<< "Apply " << RBF_typeNames_[interp] << " filter,"
<< " radius=" << radius << nl << " radius=" << radius << nl
<< "Create tree..." << endl; << "Create tree..." << endl;
} }
@ -325,15 +325,9 @@ void Foam::PatchFunction1Types::FilterField::reset
if (debug) if (debug)
{ {
Info<< "Apply " << RBF_typeNames_[interp] << " filter,"; Pout<< "Apply " << RBF_typeNames_[interp] << " filter,"
<< (relative ? " relative" : "") << " radius=" << radius << nl
if (relative) << "Create tree..." << endl;
{
Info<< " relative";
}
Info<< " radius=" << radius << endl;
Info<< "Create tree..." << endl;
} }
autoPtr<indexedOctree<treeDataPoint>> treePtr autoPtr<indexedOctree<treeDataPoint>> treePtr

View File

@ -27,6 +27,7 @@ License
#include "coordSet.H" #include "coordSet.H"
#include "coordSetWriter.H" #include "coordSetWriter.H"
#include "fileFormats.H"
#include "Time.H" #include "Time.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -78,46 +79,6 @@ Foam::word Foam::coordSetWriter::suffix
} }
Foam::dictionary Foam::coordSetWriter::formatOptions
(
const word& formatName,
std::initializer_list<const dictionary*> dicts
)
{
dictionary options;
// Default specification. Top-level and surface-specific
// - literal search only
for (const dictionary* dict : dicts)
{
if
(
dict
&& (dict = dict->findDict("default", keyType::LITERAL)) != nullptr
)
{
options.merge(*dict);
}
}
// Format specification. Top-level and surface-specific
// - allow REGEX search
for (const dictionary* dict : dicts)
{
if
(
dict && !formatName.empty()
&& (dict = dict->findDict(formatName)) != nullptr
)
{
options.merge(*dict);
}
}
return options;
}
Foam::dictionary Foam::coordSetWriter::formatOptions Foam::dictionary Foam::coordSetWriter::formatOptions
( (
const dictionary& dict, const dictionary& dict,
@ -125,13 +86,7 @@ Foam::dictionary Foam::coordSetWriter::formatOptions
const word& entryName const word& entryName
) )
{ {
return formatOptions return fileFormats::getFormatOptions(dict, formatName, entryName);
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL)
}
);
} }
@ -143,14 +98,7 @@ Foam::dictionary Foam::coordSetWriter::formatOptions
const word& entryName const word& entryName
) )
{ {
return formatOptions return fileFormats::getFormatOptions(dict, setDict, formatName, entryName);
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL),
setDict.findDict(entryName, keyType::LITERAL)
}
);
} }

View File

@ -274,16 +274,6 @@ protected:
//- No copy assignment //- No copy assignment
void operator=(const coordSetWriter&) = delete; void operator=(const coordSetWriter&) = delete;
//- Extract and merge 'default' + formatName from
//- top-level and set-specific formatOptions dictionaries
//
// \returns dictionary of merged formatOptions
static dictionary formatOptions
(
const word& formatName,
std::initializer_list<const dictionary*> dicts
);
public: public:
@ -314,10 +304,7 @@ public:
// Helpers // Helpers
//- Find "formatOptions" in a top-level dictionary. //- Same as fileFormats::getFormatOptions
//- Extract and merge 'default' + formatName values.
//
// \returns dictionary of merged formatOptions
static dictionary formatOptions static dictionary formatOptions
( (
const dictionary& dict, const dictionary& dict,
@ -325,11 +312,7 @@ public:
const word& entryName = "formatOptions" const word& entryName = "formatOptions"
); );
//- Find "formatOptions" in a top-level dictionary, //- Same as fileFormats::getFormatOptions
//- and in a set-specific dictionary.
//- Extract and merge 'default' + formatName values.
//
// \returns dictionary of merged formatOptions
static dictionary formatOptions static dictionary formatOptions
( (
const dictionary& dict, const dictionary& dict,

View File

@ -178,6 +178,12 @@ public:
return nPoints_; return nPoints_;
} }
//- Number of target points
label targetSize() const noexcept
{
return nearestVertex_.size();
}
//- Interpolation addressing to face centres of underlying patch //- Interpolation addressing to face centres of underlying patch
const List<FixedList<label, 3>>& nearestVertex() const noexcept const List<FixedList<label, 3>>& nearestVertex() const noexcept
{ {

View File

@ -150,13 +150,26 @@ Foam::boundaryDataSurfaceReader::boundaryDataSurfaceReader
const word& pointsName const word& pointsName
) )
: :
surfaceReader(fName), boundaryDataSurfaceReader(fName, dictionary(), pointsName)
{}
Foam::boundaryDataSurfaceReader::boundaryDataSurfaceReader
(
const fileName& fName,
const dictionary& options,
const word& pointsName
)
:
surfaceReader(fName, options),
baseDir_(fName.path()), baseDir_(fName.path()),
pointsName_(pointsName), pointsName_(pointsName),
timeValues_(), timeValues_(),
fieldNames_(), fieldNames_(),
surfPtr_(nullptr) surfPtr_(nullptr)
{ {
options.readIfPresent("points", pointsName_);
baseDir_.toAbsolute(); baseDir_.toAbsolute();
debug = 1; debug = 1;
DebugInFunction << endl; DebugInFunction << endl;

View File

@ -37,8 +37,25 @@ Description
// Values // Values
<case>/constant/region0/"boundaryData"/patchName/TIME/field <case>/constant/region0/"boundaryData"/patchName/TIME/field
\verbatim
readOptions
{
boundaryData
{
points points;
}
}
\endverbatim
Format options for boundaryData:
\table
Property | Description | Required | Default
points | Name of the "points" file | no | points
\endtable
SourceFiles SourceFiles
boundaryDataSurfaceReader.C boundaryDataSurfaceReader.C
boundaryDataSurfaceReaderTemplates.C
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
@ -113,6 +130,14 @@ public:
const word& pointsName = "points" const word& pointsName = "points"
); );
//- Construct from fileName with reader options
boundaryDataSurfaceReader
(
const fileName& fName,
const dictionary& options,
const word& pointsName = "points"
);
//- Destructor //- Destructor
virtual ~boundaryDataSurfaceReader() = default; virtual ~boundaryDataSurfaceReader() = default;

View File

@ -26,6 +26,7 @@ License
\*---------------------------------------------------------------------------*/ \*---------------------------------------------------------------------------*/
#include "surfaceReader.H" #include "surfaceReader.H"
#include "fileFormats.H"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
@ -36,21 +37,48 @@ namespace Foam
} }
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
Foam::dictionary Foam::surfaceReader::formatOptions
(
const dictionary& dict,
const word& formatName,
const word& entryName
)
{
return fileFormats::getFormatOptions(dict, formatName, entryName);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::surfaceReader::surfaceReader(const fileName& fName) Foam::surfaceReader::surfaceReader
(
const fileName& fName
)
: :
fileName_(fName) fileName_(fName)
{} {}
Foam::surfaceReader::surfaceReader
(
const fileName& fName,
const dictionary& options
)
:
surfaceReader(fName)
{}
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
Foam::autoPtr<Foam::surfaceReader> Foam::autoPtr<Foam::surfaceReader>
Foam::surfaceReader::New Foam::surfaceReader::New
( (
const word& readerType, const word& readerType,
const fileName& fName const fileName& fName,
const dictionary& options
) )
{ {
auto* ctorPtr = fileNameConstructorTable(readerType); auto* ctorPtr = fileNameConstructorTable(readerType);
@ -65,7 +93,7 @@ Foam::surfaceReader::New
) << exit(FatalError); ) << exit(FatalError);
} }
return autoPtr<surfaceReader>(ctorPtr(fName)); return autoPtr<surfaceReader>(ctorPtr(fName, options));
} }

View File

@ -5,7 +5,7 @@
\\ / A nd | www.openfoam.com \\ / A nd | www.openfoam.com
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2015 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -29,6 +29,24 @@ Class
Description Description
Abstract base class for surface readers with fields. Abstract base class for surface readers with fields.
Some readers support different input options, these are typically
specified as 'readOptions' in the containing dictionary.
\verbatim
readOptions
{
default
{
verbose false;
}
ensight
{
masterOnly false;
}
}
\endverbatim
SourceFiles SourceFiles
surfaceReader.C surfaceReader.C
@ -73,9 +91,21 @@ public:
surfaceReader, surfaceReader,
fileName, fileName,
( (
const fileName& fName const fileName& fName,
const dictionary& options
), ),
(fName) (fName, options)
);
// Helpers
//- Same as fileFormats::getFormatOptions
static dictionary formatOptions
(
const dictionary& dict,
const word& formatName,
const word& entryName = "formatOptions"
); );
@ -85,7 +115,8 @@ public:
static autoPtr<surfaceReader> New static autoPtr<surfaceReader> New
( (
const word& readType, const word& readType,
const fileName& fName const fileName& fName,
const dictionary& options = dictionary()
); );
@ -94,6 +125,9 @@ public:
//- Construct from fileName //- Construct from fileName
explicit surfaceReader(const fileName& fName); explicit surfaceReader(const fileName& fName);
//- Construct from fileName and specified options
surfaceReader(const fileName& fName, const dictionary& options);
//- Destructor //- Destructor
virtual ~surfaceReader() = default; virtual ~surfaceReader() = default;

View File

@ -337,9 +337,18 @@ void Foam::ensightSurfaceReader::readCase(ISstream& is)
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName) Foam::ensightSurfaceReader::ensightSurfaceReader
(
const fileName& fName,
const dictionary& options
)
: :
surfaceReader(fName), surfaceReader(fName, options),
masterOnly_
(
Pstream::parRun()
&& options.getOrDefault("masterOnly", false)
),
readFormat_(IOstreamOption::ASCII), // Placeholder value readFormat_(IOstreamOption::ASCII), // Placeholder value
baseDir_(fName.path()), baseDir_(fName.path()),
meshFileName_(), meshFileName_(),
@ -351,24 +360,46 @@ Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName)
timeValues_(), timeValues_(),
surfPtr_(nullptr) surfPtr_(nullptr)
{ {
IFstream is(fName); if (options.getOrDefault("debug", false))
readCase(is); {
debug |= 1;
}
if (!masterOnly_ || UPstream::master(UPstream::worldComm))
{
IFstream is(fName);
readCase(is);
}
if (masterOnly_ && Pstream::parRun())
{
Pstream::broadcasts
(
UPstream::worldComm,
meshFileName_,
fieldNames_,
fieldFileNames_,
nTimeSteps_,
timeStartIndex_,
timeIncrement_,
timeValues_
);
}
} }
// * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * // // * * * * * * * * * * * * * Public Member Functions * * * * * * * * * * * //
const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry Foam::meshedSurface Foam::ensightSurfaceReader::readGeometry
( (
const label timeIndex const fileName& geometryFile
) )
{ {
DebugInFunction << endl; DebugInFunction << endl;
if (!surfPtr_)
{ {
// Auto-detect ascii/binary format // Auto-detect ascii/binary format
ensightReadFile is(baseDir_/replaceMask(meshFileName_, timeIndex)); ensightReadFile is(geometryFile);
// Format detected from the geometry // Format detected from the geometry
readFormat_ = is.format(); readFormat_ = is.format();
@ -573,15 +604,8 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
} }
} }
faceTypeInfo_.transfer(faceTypeInfo); // From 1-based Ensight addressing to 0-based OF addressing
faceList faces(std::move(dynFaces)); for (face& f : dynFaces)
DebugInfo
<< "read nFaces: " << faces.size() << nl
<< "file schema: " << faceTypeInfo_ << nl;
// Convert from 1-based Ensight addressing to 0-based OF addressing
for (face& f : faces)
{ {
for (label& fp : f) for (label& fp : f)
{ {
@ -589,7 +613,42 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
} }
} }
surfPtr_.reset(new meshedSurface(std::move(points), std::move(faces))); faceTypeInfo_.transfer(faceTypeInfo);
faceList faces(std::move(dynFaces));
DebugInfo
<< "read nFaces: " << faces.size() << nl
<< "file schema: " << faceTypeInfo_ << nl;
return meshedSurface(std::move(points), std::move(faces));
}
}
const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
(
const label timeIndex
)
{
DebugInFunction << endl;
if (!surfPtr_)
{
surfPtr_.reset(new meshedSurface);
auto& surf = *surfPtr_;
fileName geomFile(baseDir_/replaceMask(meshFileName_, timeIndex));
if (!masterOnly_ || UPstream::master(UPstream::worldComm))
{
surf = readGeometry(geomFile);
}
if (masterOnly_ && Pstream::parRun())
{
// Note: don't need faceTypeInfo_ on (non-reading) ranks
Pstream::broadcast(surf, UPstream::worldComm);
}
} }
return *surfPtr_; return *surfPtr_;

View File

@ -29,6 +29,24 @@ Class
Description Description
Ensight format surface reader Ensight format surface reader
\verbatim
readOptions
{
ensight
{
debug false;
masterOnly false;
}
}
\endverbatim
Format options for ensight:
\table
Property | Description | Required | Default
debug | Add debug flag | no | false
masterOnly | Read files on master and broadcast values | no | true
\endtable
SourceFiles SourceFiles
ensightSurfaceReader.C ensightSurfaceReader.C
ensightSurfaceReaderTemplates.C ensightSurfaceReaderTemplates.C
@ -76,6 +94,9 @@ protected:
// Protected Data // Protected Data
//- Read on master and broadcast (in parallel)
bool masterOnly_;
//- Format flag //- Format flag
IOstreamOption::streamFormat readFormat_; IOstreamOption::streamFormat readFormat_;
@ -135,6 +156,9 @@ protected:
//- Read the case file //- Read the case file
void readCase(ISstream& is); void readCase(ISstream& is);
//- Read and return surface geometry. Updates faceTypeInfo_
meshedSurface readGeometry(const fileName& geometryFile);
//- Helper function to return Type after skipping n tokens //- Helper function to return Type after skipping n tokens
template<class Type> template<class Type>
void readFromLine(const label nSkip, Istream& is, Type& value) const; void readFromLine(const label nSkip, Istream& is, Type& value) const;
@ -148,6 +172,14 @@ protected:
Type& value Type& value
) const; ) const;
//- Helper function to return a field
template<class Type>
tmp<Field<Type>> readField
(
const fileName& dataFile,
const word& fieldName
) const;
//- Helper function to return a field //- Helper function to return a field
template<class Type> template<class Type>
tmp<Field<Type>> readField tmp<Field<Type>> readField
@ -165,8 +197,12 @@ public:
// Constructors // Constructors
//- Construct from fileName //- Construct from fileName, with reader options
explicit ensightSurfaceReader(const fileName& fName); explicit ensightSurfaceReader
(
const fileName& fName,
const dictionary& options = dictionary()
);
//- Destructor //- Destructor

View File

@ -61,106 +61,142 @@ void Foam::ensightSurfaceReader::readFromLine
template<class Type> template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
( (
const label timeIndex, const fileName& dataFile,
const label fieldIndex const word& fieldName
) const ) const
{ {
DebugInFunction << endl;
const word& fieldName = fieldNames_[fieldIndex];
const label fileIndex = timeStartIndex_ + timeIndex*timeIncrement_;
// Use previously detected ascii/binary format
ensightReadFile is
(
baseDir_/replaceMask(fieldFileNames_[fieldIndex], fileIndex),
readFormat_
);
if (!is.good())
{
FatalErrorInFunction
<< "Cannot read file " << is.name()
<< " for field " << fieldName
<< exit(FatalError);
}
// Check that data type is as expected
// (assumes OpenFOAM generated the data set)
string primitiveType;
is.read(primitiveType);
DebugInfo << "primitiveType: " << primitiveType << endl;
if
(
primitiveType != ensightPTraits<Type>::typeName
&& primitiveType != pTraits<Type>::typeName
)
{
IOWarningInFunction(is)
<< "Expected <" << ensightPTraits<Type>::typeName
<< "> values for <" << pTraits<Type>::typeName
<< "> but found " << primitiveType << nl
<< " This may be okay, but could indicate an error" << nl << nl;
}
auto tfield = tmp<Field<Type>>::New(surfPtr_->nFaces(), Zero); auto tfield = tmp<Field<Type>>::New(surfPtr_->nFaces(), Zero);
auto& field = tfield.ref(); auto& field = tfield.ref();
string strValue; if (!masterOnly_ || UPstream::master(UPstream::worldComm))
label iValue;
// Read header info: part index, e.g. part 1
is.read(strValue);
is.read(iValue);
label begFace = 0;
// Loop through different element types when reading the field values
for (const faceInfoTuple& facesInfo : faceTypeInfo_)
{ {
// [faceType, faceCount] // Use previously detected ascii/binary format
const label endFace = begFace + facesInfo.second(); ensightReadFile is(dataFile, readFormat_);
DebugInfo if (!is.good())
<< "Reading <" << pTraits<Type>::typeName << "> face type "
<< ensightFaces::elemNames[facesInfo.first()]
<< " data:" << facesInfo.second() << endl;
if (begFace < endFace)
{ {
// The element type, optionally with 'undef' FatalErrorInFunction
is.read(strValue); << "Cannot read file " << is.name()
<< " for field " << fieldName
<< exit(FatalError);
}
if (strValue.contains("undef")) // Check that data type is as expected
// (assumes OpenFOAM generated the data set)
string primitiveType;
is.read(primitiveType);
DebugInfo << "primitiveType: " << primitiveType << endl;
if
(
primitiveType != ensightPTraits<Type>::typeName
&& primitiveType != pTraits<Type>::typeName
)
{
IOWarningInFunction(is)
<< "Expected <" << ensightPTraits<Type>::typeName
<< "> values for <" << pTraits<Type>::typeName
<< "> but found " << primitiveType << nl
<< " This may be okay, but could indicate an error"
<< nl << nl;
}
string strValue;
label iValue;
// Read header info: part index, e.g. part 1
is.read(strValue);
is.read(iValue);
label begFace = 0;
// Loop through different element types when reading the field values
for (const faceInfoTuple& facesInfo : faceTypeInfo_)
{
// [faceType, faceCount]
const label endFace = begFace + facesInfo.second();
DebugInfo
<< "Reading <" << pTraits<Type>::typeName << "> face type "
<< ensightFaces::elemNames[facesInfo.first()]
<< " data:" << facesInfo.second() << endl;
if (begFace < endFace)
{ {
// Skip undef entry // The element type, optionally with 'undef'
scalar value; is.read(strValue);
is.read(value);
}
// Ensight fields are written component-wise if (strValue.contains("undef"))
// (can be in different order than OpenFOAM uses)
for (direction d = 0; d < pTraits<Type>::nComponents; ++d)
{
const direction cmpt = ensightPTraits<Type>::componentOrder[d];
for (label facei = begFace; facei < endFace; ++facei)
{ {
// Skip undef entry
scalar value; scalar value;
is.read(value); is.read(value);
setComponent(field[facei], cmpt) = value;
} }
}
begFace = endFace; // Ensight fields are written component-wise
// (can be in different order than OpenFOAM uses)
for (direction d = 0; d < pTraits<Type>::nComponents; ++d)
{
const direction cmpt =
ensightPTraits<Type>::componentOrder[d];
for (label facei = begFace; facei < endFace; ++facei)
{
scalar value;
is.read(value);
setComponent(field[facei], cmpt) = value;
}
}
begFace = endFace;
}
} }
} }
if (masterOnly_ && Pstream::parRun())
{
Pstream::broadcast(field, UPstream::worldComm);
}
return tfield; return tfield;
} }
template<class Type>
Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
(
const label timeIndex,
const label fieldIndex
) const
{
if (fieldIndex < 0 || fieldIndex >= fieldNames_.size())
{
FatalErrorInFunction
<< "Invalid timeIndex:" << timeIndex
<< " should be in range [0.." << fieldNames_.size() << ')' << nl
<< "Possibly used incorrect field lookup name. Known field names: "
<< flatOutput(fieldNames_) << nl
<< exit(FatalError);
}
const word& fieldName = fieldNames_[fieldIndex];
const label fileIndex = timeStartIndex_ + timeIndex*timeIncrement_;
const fileName dataFile
(
baseDir_/replaceMask(fieldFileNames_[fieldIndex], fileIndex)
);
if (debug)
{
Pout<< "Read <" << pTraits<Type>::typeName << "> field, file="
<< dataFile << endl;
}
return readField<Type>(dataFile, fieldName);
}
// ************************************************************************* // // ************************************************************************* //

View File

@ -29,6 +29,7 @@ License
#include "proxySurfaceWriter.H" #include "proxySurfaceWriter.H"
#include "MeshedSurfaceProxy.H" #include "MeshedSurfaceProxy.H"
#include "fileFormats.H"
#include "Time.H" #include "Time.H"
#include "coordinateRotation.H" #include "coordinateRotation.H"
#include "transformField.H" #include "transformField.H"
@ -59,46 +60,6 @@ bool Foam::surfaceWriter::supportedType(const word& writeType)
} }
Foam::dictionary Foam::surfaceWriter::formatOptions
(
const word& formatName,
std::initializer_list<const dictionary*> dicts
)
{
dictionary options;
// Default specification. Top-level and surface-specific
// - literal search only
for (const dictionary* dict : dicts)
{
if
(
dict
&& (dict = dict->findDict("default", keyType::LITERAL)) != nullptr
)
{
options.merge(*dict);
}
}
// Format specification. Top-level and surface-specific
// - allow REGEX search
for (const dictionary* dict : dicts)
{
if
(
dict && !formatName.empty()
&& (dict = dict->findDict(formatName)) != nullptr
)
{
options.merge(*dict);
}
}
return options;
}
Foam::dictionary Foam::surfaceWriter::formatOptions Foam::dictionary Foam::surfaceWriter::formatOptions
( (
const dictionary& dict, const dictionary& dict,
@ -106,13 +67,7 @@ Foam::dictionary Foam::surfaceWriter::formatOptions
const word& entryName const word& entryName
) )
{ {
return formatOptions return fileFormats::getFormatOptions(dict, formatName, entryName);
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL)
}
);
} }
@ -124,14 +79,7 @@ Foam::dictionary Foam::surfaceWriter::formatOptions
const word& entryName const word& entryName
) )
{ {
return formatOptions return fileFormats::getFormatOptions(dict, surfDict, formatName, entryName);
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL),
surfDict.findDict(entryName, keyType::LITERAL)
}
);
} }

View File

@ -272,18 +272,6 @@ protected:
return fileName::null; return fileName::null;
} }
//- Extract and merge 'default' + formatName from
//- top-level and surface-specific formatOptions dictionaries
//
// \returns dictionary of merged formatOptions
static dictionary formatOptions
(
const word& formatName,
std::initializer_list<const dictionary*> dicts
);
public: public:
// Public Data // Public Data
@ -320,10 +308,7 @@ public:
// Helpers // Helpers
//- Find "formatOptions" in a top-level dictionary. //- Same as fileFormats::getFormatOptions
//- Extract and merge 'default' + formatName values.
//
// \returns dictionary of merged formatOptions
static dictionary formatOptions static dictionary formatOptions
( (
const dictionary& dict, const dictionary& dict,
@ -331,11 +316,7 @@ public:
const word& entryName = "formatOptions" const word& entryName = "formatOptions"
); );
//- Find "formatOptions" in a top-level dictionary, //- Same as fileFormats::getFormatOptions
//- and in a set-specific dictionary.
//- Extract and merge 'default' + formatName values.
//
// \returns dictionary of merged formatOptions
static dictionary formatOptions static dictionary formatOptions
( (
const dictionary& dict, const dictionary& dict,