ENH: consolidate 'formatOptions' handling for coordSetWriter/surfaceWriter

- replaced ad hoc handling of formatOptions with coordSetWriter and
  surfaceWriter helpers.

  Accompanying this change, it is now possible to specify "default"
  settings to be inherited, format-specific settings and have a
  similar layering with surface-specific overrides.

- snappyHexMesh now conforms to setFormats

  Eg,

      formatOptions
      {
          default
          {
              verbose     true;
              format      binary;
          }
          vtk
          {
              precision   10;
          }
     }

     surfaces
     {
         surf1
         {
             ...

             formatOptions
             {
                 ensight
                 {
                     scale   1000;
                 }
             }
         }
     }
This commit is contained in:
Mark Olesen
2022-11-08 14:52:58 +01:00
committed by Andrew Heather
parent b7592c1ee8
commit 5b29ff0e42
20 changed files with 336 additions and 84 deletions

View File

@ -15,10 +15,5 @@ wordRes acceptFields(propsDict.get<wordRes>("fields"));
wordRes excludeFields; wordRes excludeFields;
propsDict.readIfPresent("exclude", excludeFields); propsDict.readIfPresent("exclude", excludeFields);
const dictionary formatOptions
(
propsDict.subOrEmptyDict("formatOptions", keyType::LITERAL)
);
// ************************************************************************* // // ************************************************************************* //

View File

@ -161,11 +161,12 @@ bool Foam::functionObjects::Curle::read(const dictionary& dict)
<< abort(FatalIOError); << abort(FatalIOError);
} }
const word surfaceType(dict.get<word>("surfaceType")); const word writerType = dict.get<word>("surfaceType");
surfaceWriterPtr_ = surfaceWriter::New surfaceWriterPtr_ = surfaceWriter::New
( (
surfaceType, writerType,
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(surfaceType) surfaceWriter::formatOptions(dict, writerType)
); );
// Use outputDir/TIME/surface-name // Use outputDir/TIME/surface-name

View File

@ -1138,14 +1138,14 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
if (writeFields_) if (writeFields_)
{ {
const word formatName(dict.get<word>("surfaceFormat")); const word writerType = dict.get<word>("surfaceFormat");
surfaceWriterPtr_.reset surfaceWriterPtr_.reset
( (
surfaceWriter::New surfaceWriter::New
( (
formatName, writerType,
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(formatName) surfaceWriter::formatOptions(dict, writerType)
) )
); );
@ -1159,7 +1159,7 @@ bool Foam::functionObjects::fieldValues::surfaceFieldValue::read
if (surfaceWriterPtr_->enabled()) if (surfaceWriterPtr_->enabled())
{ {
Info<< " surfaceFormat = " << formatName << nl; Info<< " surfaceFormat = " << writerType << nl;
} }
else else
{ {

View File

@ -355,16 +355,20 @@ void Foam::functionObjects::propellerInfo::setSampleDiskSurface
points_ points_
); );
// Surface writer // Surface writer (keywords: surfaceWriter, writeOptions)
word surfWriterType;
if (sampleDiskDict.readIfPresent("surfaceWriter", surfWriterType))
{
const auto writeOptions = sampleDiskDict.subOrEmptyDict("writeOptions");
word writerType;
if (sampleDiskDict.readIfPresent("surfaceWriter", writerType))
{
surfaceWriterPtr_ = surfaceWriter::New surfaceWriterPtr_ = surfaceWriter::New
( (
surfWriterType, writerType,
writeOptions.subOrEmptyDict(surfWriterType) surfaceWriter::formatOptions
(
sampleDiskDict,
writerType,
"writeOptions"
)
); );
// Use outputDir/TIME/surface-name // Use outputDir/TIME/surface-name

View File

@ -181,7 +181,7 @@ bool Foam::areaWrite::read(const dictionary& dict)
const dictionary writerOptions const dictionary writerOptions
( (
dict.subOrEmptyDict("formatOptions").subOrEmptyDict(writerType) surfaceWriter::formatOptions(dict, writerType)
); );
for (const word& areaName : meshes_.keys()) for (const word& areaName : meshes_.keys())

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2011-2017 OpenFOAM Foundation Copyright (C) 2011-2017 OpenFOAM Foundation
Copyright (C) 2016-2021 OpenCFD Ltd. Copyright (C) 2016-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -198,8 +198,11 @@ void Foam::FacePostProcessing<CloudType>::write()
auto writer = surfaceWriter::New auto writer = surfaceWriter::New
( (
surfaceFormat_, surfaceFormat_,
this->coeffDict().subOrEmptyDict("formatOptions") surfaceWriter::formatOptions
.subOrEmptyDict(surfaceFormat_) (
this->coeffDict(),
surfaceFormat_
)
); );
if (debug) if (debug)
@ -254,7 +257,7 @@ Foam::FacePostProcessing<CloudType>::FacePostProcessing
: :
CloudFunctionObject<CloudType>(dict, owner, modelName, typeName), CloudFunctionObject<CloudType>(dict, owner, modelName, typeName),
faceZoneIDs_(), faceZoneIDs_(),
surfaceFormat_(this->coeffDict().lookup("surfaceFormat")), surfaceFormat_(this->coeffDict().getWord("surfaceFormat")),
resetOnWrite_(this->coeffDict().getBool("resetOnWrite")), resetOnWrite_(this->coeffDict().getBool("resetOnWrite")),
log_(this->coeffDict().getBool("log")), log_(this->coeffDict().getBool("log")),
totalTime_(0.0), totalTime_(0.0),

View File

@ -6,7 +6,7 @@
\\/ M anipulation | \\/ M anipulation |
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
Copyright (C) 2012-2017 OpenFOAM Foundation Copyright (C) 2012-2017 OpenFOAM Foundation
Copyright (C) 2015-2021 OpenCFD Ltd. Copyright (C) 2015-2022 OpenCFD Ltd.
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
License License
This file is part of OpenFOAM. This file is part of OpenFOAM.
@ -457,13 +457,12 @@ void Foam::ParticleCollector<CloudType>::write()
<< endl; << endl;
if (surfaceFormat_ != "none" && Pstream::master()) if (Pstream::master() && surfaceFormat_ != "none")
{ {
auto writer = surfaceWriter::New auto writer = surfaceWriter::New
( (
surfaceFormat_, surfaceFormat_,
this->coeffDict().subOrEmptyDict("formatOptions") surfaceWriter::formatOptions(this->coeffDict(), surfaceFormat_)
.subOrEmptyDict(surfaceFormat_)
); );
if (debug) if (debug)
@ -536,7 +535,7 @@ Foam::ParticleCollector<CloudType>::ParticleCollector
( (
this->coeffDict().getBool("negateParcelsOppositeNormal") this->coeffDict().getBool("negateParcelsOppositeNormal")
), ),
surfaceFormat_(this->coeffDict().lookup("surfaceFormat")), surfaceFormat_(this->coeffDict().getWord("surfaceFormat")),
totalTime_(0.0), totalTime_(0.0),
mass_(), mass_(),
massTotal_(), massTotal_(),

View File

@ -196,17 +196,19 @@ Foam::ParticleZoneInfo<CloudType>::ParticleZoneInfo
data_(), data_(),
movedParticles_(), movedParticles_(),
maxIDs_(Pstream::nProcs(), Zero), maxIDs_(Pstream::nProcs(), Zero),
writerPtr_ writerPtr_(nullptr)
(
Pstream::master()
? coordSetWriter::New
(
this->coeffDict().getWord("writer"),
this->coeffDict().subOrEmptyDict("formatOptions")
)
: nullptr
)
{ {
if (Pstream::master())
{
const word writerType = this->coeffDict().getWord("writer");
writerPtr_ = coordSetWriter::New
(
writerType,
coordSetWriter::formatOptions(this->coeffDict(), writerType)
);
}
writeFile::read(this->coeffDict()); writeFile::read(this->coeffDict());
const auto& cellZones = owner.mesh().cellZones(); const auto& cellZones = owner.mesh().cellZones();

View File

@ -78,6 +78,82 @@ 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,
const word& formatName,
const word& entryName
)
{
return formatOptions
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL)
}
);
}
Foam::dictionary Foam::coordSetWriter::formatOptions
(
const dictionary& dict,
const dictionary& setDict,
const word& formatName,
const word& entryName
)
{
return formatOptions
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL),
setDict.findDict(entryName, keyType::LITERAL)
}
);
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::coordSetWriter::coordSetWriter() Foam::coordSetWriter::coordSetWriter()

View File

@ -274,6 +274,16 @@ 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:
@ -302,6 +312,33 @@ public:
); );
// Helpers
//- Find "formatOptions" in a top-level dictionary.
//- Extract and merge 'default' + formatName values.
//
// \returns dictionary of merged formatOptions
static dictionary formatOptions
(
const dictionary& dict,
const word& formatName,
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
static dictionary formatOptions
(
const dictionary& dict,
const dictionary& setDict,
const word& formatName,
const word& entryName = "formatOptions"
);
// Selectors // Selectors
//- True if New is likely to succeed for this writeType //- True if New is likely to succeed for this writeType

View File

@ -500,12 +500,14 @@ bool surfaceNoise::read(const dictionary& dict)
readerType_ = dict.get<word>("reader"); readerType_ = dict.get<word>("reader");
const word writerType(dict.get<word>("writer")); // Surface writer (keywords: writer, writeOptions)
const word writerType = dict.get<word>("writer");
writerPtr_ = surfaceWriter::New writerPtr_ = surfaceWriter::New
( (
writerType, writerType,
dict.subOrEmptyDict("writeOptions").subOrEmptyDict(writerType) surfaceWriter::formatOptions(dict, writerType, "writeOptions")
); );
// Use outputDir/TIME/surface-name // Use outputDir/TIME/surface-name

View File

@ -58,22 +58,20 @@ namespace Foam
Foam::autoPtr<Foam::coordSetWriter> Foam::sampledSets::newWriter Foam::autoPtr<Foam::coordSetWriter> Foam::sampledSets::newWriter
( (
word writeType, word writerType,
const dictionary& formatOptions, const dictionary& topDict,
const dictionary& setDict const dictionary& setDict
) )
{ {
// Per-set adjustment // Per-set adjustment
setDict.readIfPresent<word>("setFormat", writeType); setDict.readIfPresent<word>("setFormat", writerType);
dictionary options = formatOptions.subOrEmptyDict(writeType); return coordSetWriter::New
options.merge
( (
setDict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType) writerType,
// Top-level/set-specific "formatOptions"
coordSetWriter::formatOptions(topDict, setDict, writerType)
); );
return coordSetWriter::New(writeType, options);
} }
@ -338,7 +336,7 @@ void Foam::sampledSets::initDict(const dictionary& dict, const bool initial)
writers_.set writers_.set
( (
seti, seti,
newWriter(writeFormat_, writeFormatOptions_, subDict) newWriter(writeFormat_, dict_, subDict)
); );
// Use outputDir/TIME/set-name // Use outputDir/TIME/set-name
@ -396,7 +394,7 @@ void Foam::sampledSets::initDict(const dictionary& dict, const bool initial)
writers_.set writers_.set
( (
seti, seti,
newWriter(writeFormat_, writeFormatOptions_, subDict) newWriter(writeFormat_, dict_, subDict)
); );
// Use outputDir/TIME/set-name // Use outputDir/TIME/set-name
@ -446,7 +444,6 @@ Foam::sampledSets::sampledSets
searchEngine_(mesh_), searchEngine_(mesh_),
samplePointScheme_(), samplePointScheme_(),
writeFormat_(), writeFormat_(),
writeFormatOptions_(dict.subOrEmptyDict("formatOptions")),
selectedFieldNames_(), selectedFieldNames_(),
writers_(), writers_(),
probeFilePtrs_(), probeFilePtrs_(),
@ -484,7 +481,6 @@ Foam::sampledSets::sampledSets
searchEngine_(mesh_), searchEngine_(mesh_),
samplePointScheme_(), samplePointScheme_(),
writeFormat_(), writeFormat_(),
writeFormatOptions_(dict.subOrEmptyDict("formatOptions")),
selectedFieldNames_(), selectedFieldNames_(),
writers_(), writers_(),
probeFilePtrs_(), probeFilePtrs_(),
@ -548,12 +544,6 @@ bool Foam::sampledSets::read(const dictionary& dict)
probeFilePtrs_.clear(); probeFilePtrs_.clear();
} }
// const dictionary formatOptions(dict.subOrEmptyDict("formatOptions"));
// Writer type and format options
// const word writerType =
// (eptr ? dict.get<word>("setFormat") : word::null);
// writerType_ = (eptr ? dict.get<word>("setFormat") : word::null);
initDict(dict, true); initDict(dict, true);
// Have some sets, so sort out which fields are needed and report // Have some sets, so sort out which fields are needed and report

View File

@ -184,9 +184,6 @@ class sampledSets
//- Output format to use //- Output format to use
word writeFormat_; word writeFormat_;
//- Dictionary containing writer options
dictionary writeFormatOptions_;
// Output control // Output control
@ -221,9 +218,9 @@ class sampledSets
//- A new coordSet writer, with per-set formatOptions //- A new coordSet writer, with per-set formatOptions
static autoPtr<coordSetWriter> newWriter static autoPtr<coordSetWriter> newWriter
( (
word writeType, word writerType,
const dictionary& formatOptions, const dictionary& topDict,
const dictionary& surfDict const dictionary& setDict
); );
//- Perform sampling action with store/write //- Perform sampling action with store/write

View File

@ -190,22 +190,20 @@ Foam::IOobjectList Foam::sampledSurfaces::preCheckFields()
Foam::autoPtr<Foam::surfaceWriter> Foam::sampledSurfaces::newWriter Foam::autoPtr<Foam::surfaceWriter> Foam::sampledSurfaces::newWriter
( (
word writeType, word writerType,
const dictionary& formatOptions, const dictionary& topDict,
const dictionary& surfDict const dictionary& surfDict
) )
{ {
// Per-surface adjustment // Per-surface adjustment
surfDict.readIfPresent<word>("surfaceFormat", writeType); surfDict.readIfPresent<word>("surfaceFormat", writerType);
dictionary options = formatOptions.subOrEmptyDict(writeType); return surfaceWriter::New
options.merge
( (
surfDict.subOrEmptyDict("formatOptions").subOrEmptyDict(writeType) writerType,
// Top-level/surface-specific "formatOptions"
surfaceWriter::formatOptions(topDict, surfDict, writerType)
); );
return surfaceWriter::New(writeType, options);
} }
@ -305,8 +303,6 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
const word writerType = const word writerType =
(eptr ? dict.get<word>("surfaceFormat") : word::null); (eptr ? dict.get<word>("surfaceFormat") : word::null);
const dictionary formatOptions(dict.subOrEmptyDict("formatOptions"));
// Store on registry? // Store on registry?
const bool dfltStore = dict.getOrDefault("store", false); const bool dfltStore = dict.getOrDefault("store", false);
@ -355,7 +351,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
writers_.set writers_.set
( (
surfi, surfi,
newWriter(writerType, formatOptions, surfDict) newWriter(writerType, dict, surfDict)
); );
writers_[surfi].isPointData(surfs[surfi].isPointData()); writers_[surfi].isPointData(surfs[surfi].isPointData());
@ -417,7 +413,7 @@ bool Foam::sampledSurfaces::read(const dictionary& dict)
writers_.set writers_.set
( (
surfi, surfi,
newWriter(writerType, formatOptions, surfDict) newWriter(writerType, dict, surfDict)
); );
writers_[surfi].isPointData(surfs[surfi].isPointData()); writers_[surfi].isPointData(surfs[surfi].isPointData());

View File

@ -62,9 +62,13 @@ Description
formatOptions formatOptions
{ {
default
{
verbose true;
}
vtk vtk
{ {
precision 10; precision 10;
} }
} }
@ -222,8 +226,8 @@ class sampledSurfaces
//- A new surfaceWriter, with per-surface formatOptions //- A new surfaceWriter, with per-surface formatOptions
static autoPtr<surfaceWriter> newWriter static autoPtr<surfaceWriter> newWriter
( (
word writeType, word writerType,
const dictionary& formatOptions, const dictionary& topDict,
const dictionary& surfDict const dictionary& surfDict
); );

View File

@ -59,6 +59,82 @@ 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,
const word& formatName,
const word& entryName
)
{
return formatOptions
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL)
}
);
}
Foam::dictionary Foam::surfaceWriter::formatOptions
(
const dictionary& dict,
const dictionary& surfDict,
const word& formatName,
const word& entryName
)
{
return formatOptions
(
formatName,
{
dict.findDict(entryName, keyType::LITERAL),
surfDict.findDict(entryName, keyType::LITERAL)
}
);
}
Foam::autoPtr<Foam::surfaceWriter> Foam::autoPtr<Foam::surfaceWriter>
Foam::surfaceWriter::New(const word& writeType) Foam::surfaceWriter::New(const word& writeType)
{ {

View File

@ -44,15 +44,21 @@ Description
\verbatim \verbatim
formatOptions formatOptions
{ {
someFormat // Eg, ensight, vtk, etc default
{ {
verbose true; verbose true;
commsType scheduled;
fieldLevel fieldLevel
{ {
"p.*" 1e5; // Absolute -> gauge [Pa] "p.*" 1e5; // Absolute -> gauge [Pa]
T 273.15; // [K] -> [C] T 273.15; // [K] -> [C]
U #eval{ 10/sqrt(3) }; // Uniform magU=10 U #eval{ 10/sqrt(3) }; // Uniform magU=10
} }
}
someFormat // Eg, ensight, vtk, etc
{
fieldScale fieldScale
{ {
"p.*" 0.01; // [Pa] -> [mbar] "p.*" 0.01; // [Pa] -> [mbar]
@ -267,6 +273,17 @@ protected:
} }
//- 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
@ -301,6 +318,33 @@ public:
); );
// Helpers
//- Find "formatOptions" in a top-level dictionary.
//- Extract and merge 'default' + formatName values.
//
// \returns dictionary of merged formatOptions
static dictionary formatOptions
(
const dictionary& dict,
const word& formatName,
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
static dictionary formatOptions
(
const dictionary& dict,
const dictionary& surfDict,
const word& formatName,
const word& entryName = "formatOptions"
);
// Selectors // Selectors
//- True if New is likely to succeed for this writeType //- True if New is likely to succeed for this writeType

View File

@ -96,6 +96,14 @@ plane
surfaceFormat vtk; surfaceFormat vtk;
formatOptions
{
default
{
verbose true;
}
}
surfaces surfaces
{ {
zNormal zNormal

View File

@ -44,6 +44,15 @@ __surfaceFieldValue
writeFields false; writeFields false;
surfaceFormat vtk; surfaceFormat vtk;
formatOptions
{
default
{
verbose true;
}
}
// writeArea true; // writeArea true;
// resetOnStartUp true; // resetOnStartUp true;

View File

@ -44,6 +44,15 @@ __surfaceFieldValue
writeFields false; writeFields false;
surfaceFormat vtk; surfaceFormat vtk;
formatOptions
{
default
{
verbose true;
}
}
// writeArea true; // writeArea true;
// resetOnStartUp true; // resetOnStartUp true;