mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
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:
@ -65,7 +65,11 @@ Foam::fa::externalFileSource::externalFileSource
|
||||
mesh_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false // Do not register
|
||||
(
|
||||
dict.getOrDefault("store", false)
|
||||
? IOobject::REGISTER
|
||||
: IOobject::NO_REGISTER
|
||||
)
|
||||
),
|
||||
regionMesh(),
|
||||
dimensionedScalar(dimPressure, Zero)
|
||||
@ -75,6 +79,10 @@ Foam::fa::externalFileSource::externalFileSource
|
||||
{
|
||||
fieldNames_.resize(1, fieldName_);
|
||||
|
||||
/// FUTURE?
|
||||
/// // Optional entry (mandatory = false)
|
||||
/// pExt_.dimensions().readEntry("dimensions", dict, false);
|
||||
|
||||
fa::option::resetApplied();
|
||||
|
||||
read(dict);
|
||||
@ -155,7 +163,7 @@ bool Foam::fa::externalFileSource::read(const dictionary& dict)
|
||||
new PatchFunction1Types::MappedFile<scalar>
|
||||
(
|
||||
p,
|
||||
"uniformValue",
|
||||
"uniformValue", // entryName
|
||||
dict,
|
||||
tableName_, // field table name
|
||||
true // face values
|
||||
|
||||
@ -54,6 +54,7 @@ Usage
|
||||
type | Type name: externalFileSource | word | yes | -
|
||||
fieldName | Name of operand field | word | yes | -
|
||||
tableName | Name of operand table file | word | yes | -
|
||||
store | Register external field 'pExt' | bool | no | false
|
||||
\endtable
|
||||
|
||||
The inherited entries are elaborated in:
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
common/fileFormats.C
|
||||
common/manifoldCellsMeshObject.C
|
||||
|
||||
colours/colourTable.C
|
||||
|
||||
122
src/fileFormats/common/fileFormats.C
Normal file
122
src/fileFormats/common/fileFormats.C
Normal 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)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
102
src/fileFormats/common/fileFormats.H
Normal file
102
src/fileFormats/common/fileFormats.H
Normal 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
|
||||
|
||||
// ************************************************************************* //
|
||||
@ -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;
|
||||
|
||||
@ -191,15 +211,14 @@ Foam::Istream& Foam::ensightReadFile::read(scalar& value)
|
||||
reinterpret_cast<char*>(&fvalue),
|
||||
sizeof(fvalue)
|
||||
);
|
||||
|
||||
value = fvalue;
|
||||
}
|
||||
else
|
||||
{
|
||||
stdStream() >> value;
|
||||
stdStream() >> fvalue;
|
||||
syncState();
|
||||
}
|
||||
|
||||
value = fvalue;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
@ -27,7 +27,8 @@ Class
|
||||
Foam::ensightReadFile
|
||||
|
||||
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.
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
@ -98,13 +99,16 @@ public:
|
||||
virtual Istream& read(char* buf, std::streamsize count);
|
||||
|
||||
//- Read string as "%80s" or as binary
|
||||
Istream& read(string& value);
|
||||
virtual Istream& read(string& value);
|
||||
|
||||
//- Read integer as "%10d" or as binary
|
||||
Istream& read(label& value);
|
||||
virtual Istream& read(label& value);
|
||||
|
||||
//- Read float as "%12.5e" or as binary
|
||||
Istream& read(scalar& value);
|
||||
//- Read floating-point as "%12.5e" or as binary
|
||||
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
|
||||
virtual Istream& readKeyword(string& key);
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2016-2017 Wikki Ltd
|
||||
Copyright (C) 2018 OpenCFD Ltd.
|
||||
Copyright (C) 2018-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -92,5 +92,14 @@ const Foam::wordList Foam::fieldTypes::area
|
||||
"areaTensorField"
|
||||
});
|
||||
|
||||
const Foam::wordList Foam::fieldTypes::area_internal
|
||||
({
|
||||
"areaScalarField::Internal",
|
||||
"areaVectorField::Internal",
|
||||
"areaSphericalTensorField::Internal",
|
||||
"areaSymmTensorField::Internal",
|
||||
"areaTensorField::Internal"
|
||||
});
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -92,6 +92,9 @@ namespace fieldTypes
|
||||
//- Standard area field types (scalar, vector, tensor, etc)
|
||||
extern const wordList area;
|
||||
|
||||
//- Standard dimensioned field types (scalar, vector, tensor, etc)
|
||||
extern const wordList area_internal;
|
||||
|
||||
} // End namespace fieldTypes
|
||||
|
||||
|
||||
|
||||
@ -53,6 +53,10 @@ namespace Foam
|
||||
|
||||
Foam::scalar Foam::areaWrite::mergeTol_ = 1e-10;
|
||||
|
||||
|
||||
// Implementation
|
||||
#include "areaWriteImpl.C"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::areaWrite::areaWrite
|
||||
@ -110,7 +114,7 @@ Foam::areaWrite::areaWrite
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::areaWrite::verbose(const bool on)
|
||||
bool Foam::areaWrite::verbose(const bool on) noexcept
|
||||
{
|
||||
bool old(verbose_);
|
||||
verbose_ = on;
|
||||
@ -137,7 +141,7 @@ bool Foam::areaWrite::read(const dictionary& dict)
|
||||
obr_,
|
||||
IOobject::NO_READ,
|
||||
IOobject::NO_WRITE,
|
||||
false
|
||||
IOobject::NO_REGISTER
|
||||
)
|
||||
)
|
||||
);
|
||||
@ -299,7 +303,11 @@ bool Foam::areaWrite::write()
|
||||
const word& clsName = iter.key();
|
||||
const label n = iter.val().size();
|
||||
|
||||
if (fieldTypes::area.found(clsName))
|
||||
if
|
||||
(
|
||||
fieldTypes::area.found(clsName)
|
||||
|| fieldTypes::area_internal.found(clsName)
|
||||
)
|
||||
{
|
||||
nAreaFields += n;
|
||||
}
|
||||
@ -318,11 +326,43 @@ bool Foam::areaWrite::write()
|
||||
|
||||
// Write fields
|
||||
|
||||
performAction<areaScalarField>(outWriter, areaMesh, objects);
|
||||
performAction<areaVectorField>(outWriter, areaMesh, objects);
|
||||
performAction<areaSphericalTensorField>(outWriter, areaMesh, objects);
|
||||
performAction<areaSymmTensorField>(outWriter, areaMesh, objects);
|
||||
performAction<areaTensorField>(outWriter, areaMesh, objects);
|
||||
{
|
||||
// Area fields
|
||||
#undef doLocalCode
|
||||
#define doLocalCode(Type) \
|
||||
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
|
||||
|
||||
@ -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_;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
return prev;
|
||||
return old;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -210,7 +210,7 @@ public:
|
||||
|
||||
//- Enable/disable verbose output
|
||||
// \return old value
|
||||
bool verbose(const bool on);
|
||||
bool verbose(const bool on) noexcept;
|
||||
|
||||
//- Read the areaWrite dictionary
|
||||
virtual bool read(const dictionary& dict);
|
||||
@ -231,10 +231,10 @@ public:
|
||||
virtual void readUpdate(const polyMesh::readUpdateState state);
|
||||
|
||||
//- Get merge tolerance
|
||||
static scalar mergeTol();
|
||||
static scalar mergeTol() noexcept;
|
||||
|
||||
//- 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
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -27,93 +27,14 @@ License
|
||||
|
||||
#include "polyMesh.H"
|
||||
#include "rawIOField.H"
|
||||
#include "clockTime.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||
|
||||
template<class Type>
|
||||
Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
|
||||
(
|
||||
const polyPatch& pp,
|
||||
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 bool dictConstructed,
|
||||
const polyPatch& pp,
|
||||
const word& entryName,
|
||||
const dictionary& dict,
|
||||
@ -122,7 +43,7 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
|
||||
)
|
||||
:
|
||||
PatchFunction1<Type>(pp, entryName, dict, faceValues),
|
||||
dictConstructed_(false),
|
||||
dictConstructed_(dictConstructed),
|
||||
setAverage_(dict.getOrDefault("setAverage", false)),
|
||||
perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)),
|
||||
fieldTableName_(fieldTableName),
|
||||
@ -141,6 +62,11 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
|
||||
sampleValues_(),
|
||||
offset_(Function1<Type>::NewIfPresent("offset", dict))
|
||||
{
|
||||
if (fieldTableName_.empty())
|
||||
{
|
||||
fieldTableName_ = entryName;
|
||||
}
|
||||
|
||||
// Simple sanity check
|
||||
if ((filterSweeps_ < 1) || (filterRadius_ <= VSMALL))
|
||||
{
|
||||
@ -155,7 +81,12 @@ Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
|
||||
fileName fName(readerFile_);
|
||||
fName.expand();
|
||||
|
||||
readerPtr_ = surfaceReader::New(readerFormat_, fName);
|
||||
readerPtr_ = surfaceReader::New
|
||||
(
|
||||
readerFormat_,
|
||||
fName,
|
||||
surfaceReader::formatOptions(dict, readerFormat_, "readOptions")
|
||||
);
|
||||
}
|
||||
|
||||
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>
|
||||
Foam::PatchFunction1Types::MappedFile<Type>::MappedFile
|
||||
(
|
||||
@ -313,9 +288,20 @@ void Foam::PatchFunction1Types::MappedFile<Type>::updateSampledValues
|
||||
|
||||
label fieldIndex = fieldNames.find(fieldTableName_);
|
||||
|
||||
DebugInfo
|
||||
<< "checkTable : Update index=" << sampleIndex
|
||||
if (fieldIndex < 0)
|
||||
{
|
||||
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
|
||||
(
|
||||
@ -418,6 +404,8 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
|
||||
// Initialise
|
||||
if (!mapperPtr_ && readerPtr_)
|
||||
{
|
||||
clockTime timing;
|
||||
|
||||
auto& reader = readerPtr_();
|
||||
|
||||
const meshedSurface& geom = reader.geometry(0);
|
||||
@ -436,7 +424,8 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
|
||||
<< "Read " << samplePoints.size() << " sample points from "
|
||||
<< readerFile_ << endl
|
||||
<< "Found times "
|
||||
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl;
|
||||
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_) << nl
|
||||
<< "... in " << timing.timeIncrement() << 's' << endl;
|
||||
|
||||
// tbd: run-time selection
|
||||
const bool nearestOnly =
|
||||
@ -444,7 +433,6 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
|
||||
!mapMethod_.empty() && !mapMethod_.starts_with("planar")
|
||||
);
|
||||
|
||||
|
||||
// Allocate the interpolator
|
||||
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)
|
||||
if (filterSweeps_ > 0)
|
||||
{
|
||||
filterFieldPtr_.reset(new FilterField(geom, filterRadius_));
|
||||
|
||||
DebugInfo
|
||||
<< "Calculated field-filter"
|
||||
<< " - in " << timing.timeIncrement() << 's' << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -485,6 +482,8 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
|
||||
}
|
||||
else if (!mapperPtr_)
|
||||
{
|
||||
clockTime timing;
|
||||
|
||||
// Reread values and interpolate
|
||||
const fileName samplePointsFile
|
||||
(
|
||||
@ -509,16 +508,23 @@ void Foam::PatchFunction1Types::MappedFile<Type>::checkTable
|
||||
// Read data (no average value!)
|
||||
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
|
||||
const bool nearestOnly =
|
||||
(
|
||||
!mapMethod_.empty() && !mapMethod_.starts_with("planar")
|
||||
);
|
||||
|
||||
DebugInfo
|
||||
<< "Read " << samplePoints.size() << " sample points from "
|
||||
<< samplePointsFile << endl;
|
||||
|
||||
// Allocate the interpolator
|
||||
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
|
||||
<< "Found times "
|
||||
<< pointToPointPlanarInterpolation::timeNames(sampleTimes_)
|
||||
<< endl;
|
||||
<< "Created point/point planar interpolation"
|
||||
<< " - in " << timing.timeIncrement() << 's' << endl;
|
||||
|
||||
|
||||
// Setup median filter (if any)
|
||||
if (filterSweeps_ > 0)
|
||||
{
|
||||
filterFieldPtr_.reset(new FilterField(samplePoints, filterRadius_));
|
||||
|
||||
DebugInfo
|
||||
<< "Calculated field-filter"
|
||||
<< " - in " << timing.timeIncrement() << 's' << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -62,6 +62,7 @@ Description
|
||||
sampleFile | <case>/foo/bar/window.case
|
||||
filterRadius | Search radius [m] for median filter neighbours
|
||||
filterSweeps | Filter sweeps for median filter
|
||||
readOptions | Format options for surfaceReader format (eg, ensight)
|
||||
\endtable
|
||||
|
||||
Note
|
||||
@ -173,6 +174,17 @@ class MappedFile
|
||||
Type& avg
|
||||
) 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:
|
||||
|
||||
//- Runtime type information
|
||||
@ -204,7 +216,7 @@ public:
|
||||
const word& entryName,
|
||||
const dictionary& dict,
|
||||
const word& fieldTableName,
|
||||
const bool faceValues
|
||||
const bool faceValues = true
|
||||
);
|
||||
|
||||
//- Copy construct
|
||||
|
||||
@ -227,7 +227,7 @@ void Foam::PatchFunction1Types::FilterField::buildWeightsImpl
|
||||
total += n;
|
||||
}
|
||||
|
||||
Info<< "Weight neighbours: min=" << limits.min()
|
||||
Pout<< "Weight neighbours: min=" << limits.min()
|
||||
<< " avg=" << (total / addressing_.size())
|
||||
<< " max=" << limits.max() << endl;
|
||||
}
|
||||
@ -279,7 +279,7 @@ void Foam::PatchFunction1Types::FilterField::reset
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Apply " << RBF_typeNames_[interp] << " filter,"
|
||||
Pout<< "Apply " << RBF_typeNames_[interp] << " filter,"
|
||||
<< " radius=" << radius << nl
|
||||
<< "Create tree..." << endl;
|
||||
}
|
||||
@ -325,15 +325,9 @@ void Foam::PatchFunction1Types::FilterField::reset
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Apply " << RBF_typeNames_[interp] << " filter,";
|
||||
|
||||
if (relative)
|
||||
{
|
||||
Info<< " relative";
|
||||
}
|
||||
|
||||
Info<< " radius=" << radius << endl;
|
||||
Info<< "Create tree..." << endl;
|
||||
Pout<< "Apply " << RBF_typeNames_[interp] << " filter,"
|
||||
<< (relative ? " relative" : "") << " radius=" << radius << nl
|
||||
<< "Create tree..." << endl;
|
||||
}
|
||||
|
||||
autoPtr<indexedOctree<treeDataPoint>> treePtr
|
||||
|
||||
@ -27,6 +27,7 @@ License
|
||||
|
||||
#include "coordSet.H"
|
||||
#include "coordSetWriter.H"
|
||||
#include "fileFormats.H"
|
||||
#include "Time.H"
|
||||
|
||||
// * * * * * * * * * * * * * * 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
|
||||
(
|
||||
const dictionary& dict,
|
||||
@ -125,13 +86,7 @@ Foam::dictionary Foam::coordSetWriter::formatOptions
|
||||
const word& entryName
|
||||
)
|
||||
{
|
||||
return formatOptions
|
||||
(
|
||||
formatName,
|
||||
{
|
||||
dict.findDict(entryName, keyType::LITERAL)
|
||||
}
|
||||
);
|
||||
return fileFormats::getFormatOptions(dict, formatName, entryName);
|
||||
}
|
||||
|
||||
|
||||
@ -143,14 +98,7 @@ Foam::dictionary Foam::coordSetWriter::formatOptions
|
||||
const word& entryName
|
||||
)
|
||||
{
|
||||
return formatOptions
|
||||
(
|
||||
formatName,
|
||||
{
|
||||
dict.findDict(entryName, keyType::LITERAL),
|
||||
setDict.findDict(entryName, keyType::LITERAL)
|
||||
}
|
||||
);
|
||||
return fileFormats::getFormatOptions(dict, setDict, formatName, entryName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -274,16 +274,6 @@ protected:
|
||||
//- No copy assignment
|
||||
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:
|
||||
|
||||
@ -314,10 +304,7 @@ public:
|
||||
|
||||
// Helpers
|
||||
|
||||
//- Find "formatOptions" in a top-level dictionary.
|
||||
//- Extract and merge 'default' + formatName values.
|
||||
//
|
||||
// \returns dictionary of merged formatOptions
|
||||
//- Same as fileFormats::getFormatOptions
|
||||
static dictionary formatOptions
|
||||
(
|
||||
const dictionary& dict,
|
||||
@ -325,11 +312,7 @@ public:
|
||||
const word& entryName = "formatOptions"
|
||||
);
|
||||
|
||||
//- Find "formatOptions" in a top-level dictionary,
|
||||
//- and in a set-specific dictionary.
|
||||
//- Extract and merge 'default' + formatName values.
|
||||
//
|
||||
// \returns dictionary of merged formatOptions
|
||||
//- Same as fileFormats::getFormatOptions
|
||||
static dictionary formatOptions
|
||||
(
|
||||
const dictionary& dict,
|
||||
|
||||
@ -178,6 +178,12 @@ public:
|
||||
return nPoints_;
|
||||
}
|
||||
|
||||
//- Number of target points
|
||||
label targetSize() const noexcept
|
||||
{
|
||||
return nearestVertex_.size();
|
||||
}
|
||||
|
||||
//- Interpolation addressing to face centres of underlying patch
|
||||
const List<FixedList<label, 3>>& nearestVertex() const noexcept
|
||||
{
|
||||
|
||||
@ -150,13 +150,26 @@ Foam::boundaryDataSurfaceReader::boundaryDataSurfaceReader
|
||||
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()),
|
||||
pointsName_(pointsName),
|
||||
timeValues_(),
|
||||
fieldNames_(),
|
||||
surfPtr_(nullptr)
|
||||
{
|
||||
options.readIfPresent("points", pointsName_);
|
||||
|
||||
baseDir_.toAbsolute();
|
||||
debug = 1;
|
||||
DebugInFunction << endl;
|
||||
|
||||
@ -37,8 +37,25 @@ Description
|
||||
// Values
|
||||
<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
|
||||
boundaryDataSurfaceReader.C
|
||||
boundaryDataSurfaceReaderTemplates.C
|
||||
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
@ -113,6 +130,14 @@ public:
|
||||
const word& pointsName = "points"
|
||||
);
|
||||
|
||||
//- Construct from fileName with reader options
|
||||
boundaryDataSurfaceReader
|
||||
(
|
||||
const fileName& fName,
|
||||
const dictionary& options,
|
||||
const word& pointsName = "points"
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~boundaryDataSurfaceReader() = default;
|
||||
|
||||
@ -26,6 +26,7 @@ License
|
||||
\*---------------------------------------------------------------------------*/
|
||||
|
||||
#include "surfaceReader.H"
|
||||
#include "fileFormats.H"
|
||||
|
||||
// * * * * * * * * * * * * * * 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 * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::surfaceReader::surfaceReader(const fileName& fName)
|
||||
Foam::surfaceReader::surfaceReader
|
||||
(
|
||||
const fileName& fName
|
||||
)
|
||||
:
|
||||
fileName_(fName)
|
||||
{}
|
||||
|
||||
|
||||
Foam::surfaceReader::surfaceReader
|
||||
(
|
||||
const fileName& fName,
|
||||
const dictionary& options
|
||||
)
|
||||
:
|
||||
surfaceReader(fName)
|
||||
{}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * Selectors * * * * * * * * * * * * * * * * //
|
||||
|
||||
Foam::autoPtr<Foam::surfaceReader>
|
||||
Foam::surfaceReader::New
|
||||
(
|
||||
const word& readerType,
|
||||
const fileName& fName
|
||||
const fileName& fName,
|
||||
const dictionary& options
|
||||
)
|
||||
{
|
||||
auto* ctorPtr = fileNameConstructorTable(readerType);
|
||||
@ -65,7 +93,7 @@ Foam::surfaceReader::New
|
||||
) << exit(FatalError);
|
||||
}
|
||||
|
||||
return autoPtr<surfaceReader>(ctorPtr(fName));
|
||||
return autoPtr<surfaceReader>(ctorPtr(fName, options));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
\\ / A nd | www.openfoam.com
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright (C) 2015 OpenCFD Ltd.
|
||||
Copyright (C) 2015-2022 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -29,6 +29,24 @@ Class
|
||||
Description
|
||||
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
|
||||
surfaceReader.C
|
||||
|
||||
@ -73,9 +91,21 @@ public:
|
||||
surfaceReader,
|
||||
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
|
||||
(
|
||||
const word& readType,
|
||||
const fileName& fName
|
||||
const fileName& fName,
|
||||
const dictionary& options = dictionary()
|
||||
);
|
||||
|
||||
|
||||
@ -94,6 +125,9 @@ public:
|
||||
//- Construct from fileName
|
||||
explicit surfaceReader(const fileName& fName);
|
||||
|
||||
//- Construct from fileName and specified options
|
||||
surfaceReader(const fileName& fName, const dictionary& options);
|
||||
|
||||
|
||||
//- Destructor
|
||||
virtual ~surfaceReader() = default;
|
||||
|
||||
@ -337,9 +337,18 @@ void Foam::ensightSurfaceReader::readCase(ISstream& is)
|
||||
|
||||
// * * * * * * * * * * * * * * * * 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
|
||||
baseDir_(fName.path()),
|
||||
meshFileName_(),
|
||||
@ -351,24 +360,46 @@ Foam::ensightSurfaceReader::ensightSurfaceReader(const fileName& fName)
|
||||
timeValues_(),
|
||||
surfPtr_(nullptr)
|
||||
{
|
||||
if (options.getOrDefault("debug", false))
|
||||
{
|
||||
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 * * * * * * * * * * * //
|
||||
|
||||
const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
|
||||
Foam::meshedSurface Foam::ensightSurfaceReader::readGeometry
|
||||
(
|
||||
const label timeIndex
|
||||
const fileName& geometryFile
|
||||
)
|
||||
{
|
||||
DebugInFunction << endl;
|
||||
|
||||
if (!surfPtr_)
|
||||
{
|
||||
// Auto-detect ascii/binary format
|
||||
ensightReadFile is(baseDir_/replaceMask(meshFileName_, timeIndex));
|
||||
ensightReadFile is(geometryFile);
|
||||
|
||||
// Format detected from the geometry
|
||||
readFormat_ = is.format();
|
||||
@ -573,15 +604,8 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry
|
||||
}
|
||||
}
|
||||
|
||||
faceTypeInfo_.transfer(faceTypeInfo);
|
||||
faceList faces(std::move(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)
|
||||
// From 1-based Ensight addressing to 0-based OF addressing
|
||||
for (face& f : dynFaces)
|
||||
{
|
||||
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_;
|
||||
|
||||
@ -29,6 +29,24 @@ Class
|
||||
Description
|
||||
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
|
||||
ensightSurfaceReader.C
|
||||
ensightSurfaceReaderTemplates.C
|
||||
@ -76,6 +94,9 @@ protected:
|
||||
|
||||
// Protected Data
|
||||
|
||||
//- Read on master and broadcast (in parallel)
|
||||
bool masterOnly_;
|
||||
|
||||
//- Format flag
|
||||
IOstreamOption::streamFormat readFormat_;
|
||||
|
||||
@ -135,6 +156,9 @@ protected:
|
||||
//- Read the case file
|
||||
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
|
||||
template<class Type>
|
||||
void readFromLine(const label nSkip, Istream& is, Type& value) const;
|
||||
@ -148,6 +172,14 @@ protected:
|
||||
Type& value
|
||||
) 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
|
||||
template<class Type>
|
||||
tmp<Field<Type>> readField
|
||||
@ -165,8 +197,12 @@ public:
|
||||
|
||||
// Constructors
|
||||
|
||||
//- Construct from fileName
|
||||
explicit ensightSurfaceReader(const fileName& fName);
|
||||
//- Construct from fileName, with reader options
|
||||
explicit ensightSurfaceReader
|
||||
(
|
||||
const fileName& fName,
|
||||
const dictionary& options = dictionary()
|
||||
);
|
||||
|
||||
|
||||
//- Destructor
|
||||
|
||||
@ -61,21 +61,17 @@ void Foam::ensightSurfaceReader::readFromLine
|
||||
template<class Type>
|
||||
Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
|
||||
(
|
||||
const label timeIndex,
|
||||
const label fieldIndex
|
||||
const fileName& dataFile,
|
||||
const word& fieldName
|
||||
) const
|
||||
{
|
||||
DebugInFunction << endl;
|
||||
|
||||
const word& fieldName = fieldNames_[fieldIndex];
|
||||
const label fileIndex = timeStartIndex_ + timeIndex*timeIncrement_;
|
||||
auto tfield = tmp<Field<Type>>::New(surfPtr_->nFaces(), Zero);
|
||||
auto& field = tfield.ref();
|
||||
|
||||
if (!masterOnly_ || UPstream::master(UPstream::worldComm))
|
||||
{
|
||||
// Use previously detected ascii/binary format
|
||||
ensightReadFile is
|
||||
(
|
||||
baseDir_/replaceMask(fieldFileNames_[fieldIndex], fileIndex),
|
||||
readFormat_
|
||||
);
|
||||
ensightReadFile is(dataFile, readFormat_);
|
||||
|
||||
if (!is.good())
|
||||
{
|
||||
@ -102,12 +98,10 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
|
||||
<< "Expected <" << ensightPTraits<Type>::typeName
|
||||
<< "> values for <" << pTraits<Type>::typeName
|
||||
<< "> but found " << primitiveType << nl
|
||||
<< " This may be okay, but could indicate an error" << nl << nl;
|
||||
<< " This may be okay, but could indicate an error"
|
||||
<< nl << nl;
|
||||
}
|
||||
|
||||
auto tfield = tmp<Field<Type>>::New(surfPtr_->nFaces(), Zero);
|
||||
auto& field = tfield.ref();
|
||||
|
||||
string strValue;
|
||||
label iValue;
|
||||
|
||||
@ -145,7 +139,8 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
|
||||
|
||||
for (direction d = 0; d < pTraits<Type>::nComponents; ++d)
|
||||
{
|
||||
const direction cmpt = ensightPTraits<Type>::componentOrder[d];
|
||||
const direction cmpt =
|
||||
ensightPTraits<Type>::componentOrder[d];
|
||||
|
||||
for (label facei = begFace; facei < endFace; ++facei)
|
||||
{
|
||||
@ -158,9 +153,50 @@ Foam::tmp<Foam::Field<Type>> Foam::ensightSurfaceReader::readField
|
||||
begFace = endFace;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (masterOnly_ && Pstream::parRun())
|
||||
{
|
||||
Pstream::broadcast(field, UPstream::worldComm);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -29,6 +29,7 @@ License
|
||||
#include "proxySurfaceWriter.H"
|
||||
#include "MeshedSurfaceProxy.H"
|
||||
|
||||
#include "fileFormats.H"
|
||||
#include "Time.H"
|
||||
#include "coordinateRotation.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
|
||||
(
|
||||
const dictionary& dict,
|
||||
@ -106,13 +67,7 @@ Foam::dictionary Foam::surfaceWriter::formatOptions
|
||||
const word& entryName
|
||||
)
|
||||
{
|
||||
return formatOptions
|
||||
(
|
||||
formatName,
|
||||
{
|
||||
dict.findDict(entryName, keyType::LITERAL)
|
||||
}
|
||||
);
|
||||
return fileFormats::getFormatOptions(dict, formatName, entryName);
|
||||
}
|
||||
|
||||
|
||||
@ -124,14 +79,7 @@ Foam::dictionary Foam::surfaceWriter::formatOptions
|
||||
const word& entryName
|
||||
)
|
||||
{
|
||||
return formatOptions
|
||||
(
|
||||
formatName,
|
||||
{
|
||||
dict.findDict(entryName, keyType::LITERAL),
|
||||
surfDict.findDict(entryName, keyType::LITERAL)
|
||||
}
|
||||
);
|
||||
return fileFormats::getFormatOptions(dict, surfDict, formatName, entryName);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -272,18 +272,6 @@ protected:
|
||||
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 Data
|
||||
@ -320,10 +308,7 @@ public:
|
||||
|
||||
// Helpers
|
||||
|
||||
//- Find "formatOptions" in a top-level dictionary.
|
||||
//- Extract and merge 'default' + formatName values.
|
||||
//
|
||||
// \returns dictionary of merged formatOptions
|
||||
//- Same as fileFormats::getFormatOptions
|
||||
static dictionary formatOptions
|
||||
(
|
||||
const dictionary& dict,
|
||||
@ -331,11 +316,7 @@ public:
|
||||
const word& entryName = "formatOptions"
|
||||
);
|
||||
|
||||
//- Find "formatOptions" in a top-level dictionary,
|
||||
//- and in a set-specific dictionary.
|
||||
//- Extract and merge 'default' + formatName values.
|
||||
//
|
||||
// \returns dictionary of merged formatOptions
|
||||
//- Same as fileFormats::getFormatOptions
|
||||
static dictionary formatOptions
|
||||
(
|
||||
const dictionary& dict,
|
||||
|
||||
Reference in New Issue
Block a user