diff --git a/src/faOptions/sources/derived/externalFileSource/externalFileSource.C b/src/faOptions/sources/derived/externalFileSource/externalFileSource.C index 6f0a35080e3926456003315d1142a8f4537ea94d..a1d23336163763d78e1eb5b8b163181c1839db0f 100644 --- a/src/faOptions/sources/derived/externalFileSource/externalFileSource.C +++ b/src/faOptions/sources/derived/externalFileSource/externalFileSource.C @@ -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 diff --git a/src/faOptions/sources/derived/externalFileSource/externalFileSource.H b/src/faOptions/sources/derived/externalFileSource/externalFileSource.H index a2056e18b0a13236e2ed3740b19d95e48c51f9e0..74a0faa4d9b05d5bcf6b08dd26c204a6fc93b7f4 100644 --- a/src/faOptions/sources/derived/externalFileSource/externalFileSource.H +++ b/src/faOptions/sources/derived/externalFileSource/externalFileSource.H @@ -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: diff --git a/src/fileFormats/Make/files b/src/fileFormats/Make/files index 7b633c6b3f4d8e149e9a1a045b7e7c9ba21fd608..53d04f78524ce58c5e627838c9d9043880670765 100644 --- a/src/fileFormats/Make/files +++ b/src/fileFormats/Make/files @@ -1,3 +1,4 @@ +common/fileFormats.C common/manifoldCellsMeshObject.C colours/colourTable.C diff --git a/src/fileFormats/common/fileFormats.C b/src/fileFormats/common/fileFormats.C new file mode 100644 index 0000000000000000000000000000000000000000..d5a55e834f0e2cba2d6bf6130d80aa01ce64a28c --- /dev/null +++ b/src/fileFormats/common/fileFormats.C @@ -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) + } + ); +} + + +// ************************************************************************* // diff --git a/src/fileFormats/common/fileFormats.H b/src/fileFormats/common/fileFormats.H new file mode 100644 index 0000000000000000000000000000000000000000..ec1f4ed9f4bf53b3e5cbbd71ebb372be80c2125b --- /dev/null +++ b/src/fileFormats/common/fileFormats.H @@ -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 + +// ************************************************************************* // diff --git a/src/fileFormats/ensight/read/ensightReadFile.C b/src/fileFormats/ensight/read/ensightReadFile.C index 07064ce263371e50f5280535357c3c333bb922b2..3dcf09e4a1751b9abff8d858ab48520e33b547d8 100644 --- a/src/fileFormats/ensight/read/ensightReadFile.C +++ b/src/fileFormats/ensight/read/ensightReadFile.C @@ -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; } diff --git a/src/fileFormats/ensight/read/ensightReadFile.H b/src/fileFormats/ensight/read/ensightReadFile.H index 4f8ff48529a2928a94e798d9cc2a3c6585700ea0..6982ae907237799487ce1675f9ee633464554396 100644 --- a/src/fileFormats/ensight/read/ensightReadFile.H +++ b/src/fileFormats/ensight/read/ensightReadFile.H @@ -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); diff --git a/src/finiteArea/fields/areaFields/areaFields.C b/src/finiteArea/fields/areaFields/areaFields.C index 08412b1a69dc8e5b6019d5e03d06550f8141c04a..2120369959b8aba8b87e0509e576c7dc6e97a601 100644 --- a/src/finiteArea/fields/areaFields/areaFields.C +++ b/src/finiteArea/fields/areaFields/areaFields.C @@ -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" +}); + // ************************************************************************* // diff --git a/src/finiteArea/fields/areaFields/areaFieldsFwd.H b/src/finiteArea/fields/areaFields/areaFieldsFwd.H index 621222c69b40c9614f4587011cb86370fb14394e..202298c2d3bb866445e4680d73d7743bc06a6f39 100644 --- a/src/finiteArea/fields/areaFields/areaFieldsFwd.H +++ b/src/finiteArea/fields/areaFields/areaFieldsFwd.H @@ -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 diff --git a/src/functionObjects/utilities/areaWrite/areaWrite.C b/src/functionObjects/utilities/areaWrite/areaWrite.C index 6ef6ee820a37e2cf0b0ec71001a04b92a0673cff..8a6e7b898ef5326d9c1c4be7712bdfd486af74c4 100644 --- a/src/functionObjects/utilities/areaWrite/areaWrite.C +++ b/src/functionObjects/utilities/areaWrite/areaWrite.C @@ -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; } diff --git a/src/functionObjects/utilities/areaWrite/areaWrite.H b/src/functionObjects/utilities/areaWrite/areaWrite.H index fdcec555c3fd43cbb72c573560d84df21362d4fc..bca7c2a36de0f3f810f7982d757b6dc81d917093 100644 --- a/src/functionObjects/utilities/areaWrite/areaWrite.H +++ b/src/functionObjects/utilities/areaWrite/areaWrite.H @@ -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 // ************************************************************************* // diff --git a/src/functionObjects/utilities/areaWrite/areaWriteTemplates.C b/src/functionObjects/utilities/areaWrite/areaWriteImpl.C similarity index 100% rename from src/functionObjects/utilities/areaWrite/areaWriteTemplates.C rename to src/functionObjects/utilities/areaWrite/areaWriteImpl.C diff --git a/src/meshTools/PatchFunction1/MappedFile/MappedFile.C b/src/meshTools/PatchFunction1/MappedFile/MappedFile.C index 270ceaeaf1c8248388e84a813a4e0d67ca98006f..6d6138017aac29615a66739457e94d2bfbe6287f 100644 --- a/src/meshTools/PatchFunction1/MappedFile/MappedFile.C +++ b/src/meshTools/PatchFunction1/MappedFile/MappedFile.C @@ -27,24 +27,26 @@ License #include "polyMesh.H" #include "rawIOField.H" +#include "clockTime.H" // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // template<class Type> Foam::PatchFunction1Types::MappedFile<Type>::MappedFile ( + const bool dictConstructed, const polyPatch& pp, - const word& redirectType, const word& entryName, const dictionary& dict, + const word& fieldTableName, const bool faceValues ) : PatchFunction1<Type>(pp, entryName, dict, faceValues), - dictConstructed_(true), + dictConstructed_(dictConstructed), setAverage_(dict.getOrDefault("setAverage", false)), perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)), - fieldTableName_(dict.getOrDefault<word>("fieldTable", entryName)), + fieldTableName_(fieldTableName), pointsName_(dict.getOrDefault<word>("points", "points")), mapMethod_(), filterRadius_(dict.getOrDefault<scalar>("filterRadius", 0)), @@ -60,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)) { @@ -74,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) @@ -115,81 +127,44 @@ template<class Type> Foam::PatchFunction1Types::MappedFile<Type>::MappedFile ( const polyPatch& pp, + const word& redirectType, const word& entryName, const dictionary& dict, - const word& fieldTableName, const bool faceValues ) : - PatchFunction1<Type>(pp, entryName, dict, faceValues), - dictConstructed_(false), - setAverage_(dict.getOrDefault("setAverage", false)), - perturb_(dict.getOrDefault<scalar>("perturb", 1e-5)), - fieldTableName_(fieldTableName), - 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); - } + MappedFile<Type> + ( + true, // dictConstructed = true + pp, + entryName, + dict, + dict.getOrDefault<word>("fieldTable", entryName), + faceValues + ) +{} - 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 +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> ( - dict.readIfPresent("mapMethod", mapMethod_) - && !mapMethod_.empty() - && mapMethod_ != "nearest" - && !mapMethod_.starts_with("planar") + false, // dictConstructed = false + pp, + entryName, + dict, + fieldTableName, + faceValues ) - { - FatalIOErrorInFunction(dict) - << "Unknown mapMethod type " << mapMethod_ - << "\n\nValid mapMethod types :\n" - << "(nearest planar)" << nl - << exit(FatalIOError); - } -} +{} template<class Type> @@ -313,9 +288,20 @@ void Foam::PatchFunction1Types::MappedFile<Type>::updateSampledValues label fieldIndex = fieldNames.find(fieldTableName_); - DebugInfo - << "checkTable : Update index=" << sampleIndex - << " field=" << fieldNames[fieldIndex] << endl; + 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 { diff --git a/src/meshTools/PatchFunction1/MappedFile/MappedFile.H b/src/meshTools/PatchFunction1/MappedFile/MappedFile.H index b8ef66b9d8f20d8d37a5e7d10d0de6ef50797d00..7a87184340448b1fa7c9e7c9eb167526d1bbcefa 100644 --- a/src/meshTools/PatchFunction1/MappedFile/MappedFile.H +++ b/src/meshTools/PatchFunction1/MappedFile/MappedFile.H @@ -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 diff --git a/src/meshTools/PatchFunction1/MappedFile/MappedFileFilterField.C b/src/meshTools/PatchFunction1/MappedFile/MappedFileFilterField.C index fd738efbcbe85d006bf814232f6fba159eb4344f..8e7ce676cd6505fbeca14939a8fccc6b8ac36e0b 100644 --- a/src/meshTools/PatchFunction1/MappedFile/MappedFileFilterField.C +++ b/src/meshTools/PatchFunction1/MappedFile/MappedFileFilterField.C @@ -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 diff --git a/src/meshTools/coordSet/writers/common/coordSetWriter.C b/src/meshTools/coordSet/writers/common/coordSetWriter.C index 8f9e3789e6bbd2946f3bf2bd4862eef4246a02e0..35e53056b0dd423faf98d2a34acd19dc00560d29 100644 --- a/src/meshTools/coordSet/writers/common/coordSetWriter.C +++ b/src/meshTools/coordSet/writers/common/coordSetWriter.C @@ -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); } diff --git a/src/meshTools/coordSet/writers/common/coordSetWriter.H b/src/meshTools/coordSet/writers/common/coordSetWriter.H index 14befa5a1ac6fa6e039a4d3912679047056d6f80..05b2f43170c950ff4e089eaaac82d2d0ddf845af 100644 --- a/src/meshTools/coordSet/writers/common/coordSetWriter.H +++ b/src/meshTools/coordSet/writers/common/coordSetWriter.H @@ -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, diff --git a/src/meshTools/triSurface/triSurfaceTools/pointToPointPlanarInterpolation.H b/src/meshTools/triSurface/triSurfaceTools/pointToPointPlanarInterpolation.H index 93a297d0c6b4b1c8d3e42ea9de7f8aacfeac8a60..dd7da0d64e5411b35116bc1a5def546d9bda7950 100644 --- a/src/meshTools/triSurface/triSurfaceTools/pointToPointPlanarInterpolation.H +++ b/src/meshTools/triSurface/triSurfaceTools/pointToPointPlanarInterpolation.H @@ -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 { diff --git a/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.C b/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.C index 14030e120504f36c7aaf203750362535106e7a50..4e28be30f75fa566c5883760e6e405412d668fba 100644 --- a/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.C +++ b/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.C @@ -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; diff --git a/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.H b/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.H index 76821c298d8ecf7b8a9bd650770d3ba95c71cbdf..102f2ccc25a35ebd3227c3c7c46115c89825c1ff 100644 --- a/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.H +++ b/src/surfMesh/readers/boundary/boundaryDataSurfaceReader.H @@ -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; diff --git a/src/surfMesh/readers/common/surfaceReader.C b/src/surfMesh/readers/common/surfaceReader.C index e9251975b171e998888b163831e4e732e1eb572d..cd3dd74d6f65b61d0e457c2d076845d2c490f90a 100644 --- a/src/surfMesh/readers/common/surfaceReader.C +++ b/src/surfMesh/readers/common/surfaceReader.C @@ -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)); } diff --git a/src/surfMesh/readers/common/surfaceReader.H b/src/surfMesh/readers/common/surfaceReader.H index bd640289a49c096dc51b361a063e4671ca1939c7..99f79efddcbfe75d8555d8ef4bd6ef797d566f5d 100644 --- a/src/surfMesh/readers/common/surfaceReader.H +++ b/src/surfMesh/readers/common/surfaceReader.H @@ -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; diff --git a/src/surfMesh/readers/ensight/ensightSurfaceReader.C b/src/surfMesh/readers/ensight/ensightSurfaceReader.C index d4d7f1f2b86ababcec19ec2853f49bc8f3c36320..ab72a87efceaae0ccabad9ea3dbd8de7c6115cb2 100644 --- a/src/surfMesh/readers/ensight/ensightSurfaceReader.C +++ b/src/surfMesh/readers/ensight/ensightSurfaceReader.C @@ -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) { - IFstream is(fName); - readCase(is); + 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,6 +604,15 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry } } + // From 1-based Ensight addressing to 0-based OF addressing + for (face& f : dynFaces) + { + for (label& fp : f) + { + --fp; + } + } + faceTypeInfo_.transfer(faceTypeInfo); faceList faces(std::move(dynFaces)); @@ -580,16 +620,35 @@ const Foam::meshedSurface& Foam::ensightSurfaceReader::geometry << "read nFaces: " << faces.size() << nl << "file schema: " << faceTypeInfo_ << nl; - // Convert from 1-based Ensight addressing to 0-based OF addressing - for (face& f : faces) + 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)) { - for (label& fp : f) - { - --fp; - } + surf = readGeometry(geomFile); } - surfPtr_.reset(new meshedSurface(std::move(points), std::move(faces))); + if (masterOnly_ && Pstream::parRun()) + { + // Note: don't need faceTypeInfo_ on (non-reading) ranks + Pstream::broadcast(surf, UPstream::worldComm); + } } return *surfPtr_; diff --git a/src/surfMesh/readers/ensight/ensightSurfaceReader.H b/src/surfMesh/readers/ensight/ensightSurfaceReader.H index bf72aed3da5fedf8c75499916696797d7ba5d0ef..b364d4f15f02bdb04ab09e3322dfa8de031198c9 100644 --- a/src/surfMesh/readers/ensight/ensightSurfaceReader.H +++ b/src/surfMesh/readers/ensight/ensightSurfaceReader.H @@ -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 diff --git a/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C b/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C index ede7b84b6f0b23d5782376c45f5e268b645b849a..28cfbb1698c4f9a55c53a7740bea29b2e8c190d2 100644 --- a/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C +++ b/src/surfMesh/readers/ensight/ensightSurfaceReaderTemplates.C @@ -61,106 +61,142 @@ 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_; - - // Use previously detected ascii/binary format - ensightReadFile is - ( - baseDir_/replaceMask(fieldFileNames_[fieldIndex], fileIndex), - readFormat_ - ); + auto tfield = tmp<Field<Type>>::New(surfPtr_->nFaces(), Zero); + auto& field = tfield.ref(); - if (!is.good()) + if (!masterOnly_ || UPstream::master(UPstream::worldComm)) { - 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); + // Use previously detected ascii/binary format + ensightReadFile is(dataFile, readFormat_); - 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; - } + if (!is.good()) + { + FatalErrorInFunction + << "Cannot read file " << is.name() + << " for field " << fieldName + << exit(FatalError); + } - auto tfield = tmp<Field<Type>>::New(surfPtr_->nFaces(), Zero); - auto& field = tfield.ref(); + // Check that data type is as expected + // (assumes OpenFOAM generated the data set) + string primitiveType; + is.read(primitiveType); - string strValue; - label iValue; + DebugInfo << "primitiveType: " << primitiveType << endl; - // Read header info: part index, e.g. part 1 - is.read(strValue); - is.read(iValue); + 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; + } - label begFace = 0; + string strValue; + label iValue; - // Loop through different element types when reading the field values - for (const faceInfoTuple& facesInfo : faceTypeInfo_) - { - // [faceType, faceCount] - const label endFace = begFace + facesInfo.second(); + // Read header info: part index, e.g. part 1 + is.read(strValue); + is.read(iValue); - DebugInfo - << "Reading <" << pTraits<Type>::typeName << "> face type " - << ensightFaces::elemNames[facesInfo.first()] - << " data:" << facesInfo.second() << endl; + label begFace = 0; - if (begFace < endFace) + // Loop through different element types when reading the field values + for (const faceInfoTuple& facesInfo : faceTypeInfo_) { - // The element type, optionally with 'undef' - is.read(strValue); - - if (strValue.contains("undef")) - { - // Skip undef entry - scalar value; - is.read(value); - } + // [faceType, faceCount] + const label endFace = begFace + facesInfo.second(); - // Ensight fields are written component-wise - // (can be in different order than OpenFOAM uses) + DebugInfo + << "Reading <" << pTraits<Type>::typeName << "> face type " + << ensightFaces::elemNames[facesInfo.first()] + << " data:" << facesInfo.second() << endl; - for (direction d = 0; d < pTraits<Type>::nComponents; ++d) + if (begFace < endFace) { - const direction cmpt = ensightPTraits<Type>::componentOrder[d]; + // The element type, optionally with 'undef' + is.read(strValue); - for (label facei = begFace; facei < endFace; ++facei) + if (strValue.contains("undef")) { + // Skip undef entry scalar 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; } +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); +} + + // ************************************************************************* // diff --git a/src/surfMesh/writers/common/surfaceWriter.C b/src/surfMesh/writers/common/surfaceWriter.C index 83fce91cd0db2b839a7791373e77fb2d978ae394..eaf0ad1f4b9264adb4ad39516036e0606cfbfd92 100644 --- a/src/surfMesh/writers/common/surfaceWriter.C +++ b/src/surfMesh/writers/common/surfaceWriter.C @@ -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); } diff --git a/src/surfMesh/writers/common/surfaceWriter.H b/src/surfMesh/writers/common/surfaceWriter.H index aa2eadbe842daa3e291f7fdce4493b4656f3e152..ea3692cd41c384652dcfaa471d878e9917348d06 100644 --- a/src/surfMesh/writers/common/surfaceWriter.H +++ b/src/surfMesh/writers/common/surfaceWriter.H @@ -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,