diff --git a/src/functionObjects/utilities/Make/files b/src/functionObjects/utilities/Make/files index bf81b19565e4315902ba61e9409822a97d181842..9da1341dfa4c24e926fd98462203b5aec976a3d3 100644 --- a/src/functionObjects/utilities/Make/files +++ b/src/functionObjects/utilities/Make/files @@ -9,6 +9,15 @@ areaWrite/areaWrite.C ensightWrite/ensightWrite.C ensightWrite/ensightWriteUpdate.C +foamReport/foamReport.C +foamReport/substitutionModels/substitutionModel/substitutionModel.C +foamReport/substitutionModels/substitutionModel/substitutionModelNew.C +foamReport/substitutionModels/dictionaryValue/dictionaryValue.C +foamReport/substitutionModels/functionObjectValue/functionObjectValue.C +foamReport/substitutionModels/fileRegEx/fileRegEx.C +foamReport/substitutionModels/environmentVariable/environmentVariable.C +foamReport/substitutionModels/userValue/userValue.C + graphFunctionObject/graphFunctionObject.C vtkWrite/vtkWrite.C diff --git a/src/functionObjects/utilities/foamReport/foamReport.C b/src/functionObjects/utilities/foamReport/foamReport.C new file mode 100644 index 0000000000000000000000000000000000000000..349fbf777bed5ea7d048a43d5f2a8019d01bf07d --- /dev/null +++ b/src/functionObjects/utilities/foamReport/foamReport.C @@ -0,0 +1,350 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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 "foamReport.H" +#include "addToRunTimeSelectionTable.H" +#include "argList.H" +#include "clock.H" +#include "cloud.H" +#include "foamVersion.H" +#include "fvMesh.H" +#include "IFstream.H" +#include "stringOps.H" +#include "substitutionModel.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace functionObjects +{ + defineTypeNameAndDebug(foamReport, 0); + addToRunTimeSelectionTable(functionObject, foamReport, dictionary); +} +} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +void Foam::functionObjects::foamReport::setStaticBuiltins() +{ + substitutionModel::addBuiltinStr("OF_HOST", Foam::hostName()); + substitutionModel::addBuiltinStr + ( + "OF_PROC_ZERO_DIR", + Pstream::parRun() ? "processor0" : "" + ); + + substitutionModel::addBuiltin("OF_API", foamVersion::api); + substitutionModel::addBuiltinStr("OF_PATCH", foamVersion::patch); + substitutionModel::addBuiltinStr("OF_BUILD", foamVersion::build); + substitutionModel::addBuiltinStr("OF_BUILD_ARCH", foamVersion::buildArch); + substitutionModel::addBuiltinStr("OF_VERSION", foamVersion::version); + + substitutionModel::addBuiltinStr("OF_DATE_START", clock::date()); + substitutionModel::addBuiltinStr("OF_CLOCK_START", clock::clockTime()); + + substitutionModel::addBuiltinStr("OF_EXECUTABLE", argList::envExecutable()); + substitutionModel::addBuiltinStr("OF_CASE_PATH", argList::envGlobalPath()); + substitutionModel::addBuiltinStr("OF_CASE_NAME", time().globalCaseName()); + + substitutionModel::addBuiltin("OF_NPROCS", Pstream::nProcs()); + + // Set mesh builtins when there is only 1 mesh + const auto meshes = time_.lookupClass<fvMesh>(); + if (meshes.size() == 1) + { + const auto& mesh = *(meshes.begin().val()); + substitutionModel::addBuiltin("OF_MESH_NCELLS", mesh.nCells()); + substitutionModel::addBuiltin("OF_MESH_NFACES", mesh.nFaces()); + substitutionModel::addBuiltin("OF_MESH_NEDGES", mesh.nEdges()); + substitutionModel::addBuiltin("OF_MESH_NPOINTS", mesh.nPoints()); + substitutionModel::addBuiltin + ( + "OF_MESH_NINTERNALFACES", + mesh.nInternalFaces() + ); + substitutionModel::addBuiltin + ( + "OF_MESH_NBOUNDARYFACES", + mesh.nBoundaryFaces() + ); + substitutionModel::addBuiltin + ( + "OF_MESH_NPATCHES", + mesh.boundaryMesh().nNonProcessor() + ); + substitutionModel::addBuiltin + ( + "OF_MESH_BOUNDS_MIN", + mesh.bounds().min() + ); + substitutionModel::addBuiltin + ( + "OF_MESH_BOUNDS_MAX", + mesh.bounds().max() + ); + } +} + + +void Foam::functionObjects::foamReport::setDynamicBuiltins() +{ + // Overwrite existing entries + substitutionModel::setBuiltinStr("OF_TIME", time().timeName()); + substitutionModel::setBuiltin("OF_NTIMES", time().times().size()); + substitutionModel::setBuiltin("OF_TIME_INDEX", time().timeIndex()); + substitutionModel::setBuiltin("OF_TIME_DELTAT", time().deltaTValue()); + + substitutionModel::setBuiltinStr("OF_DATE_NOW", clock::date()); + substitutionModel::setBuiltinStr("OF_CLOCK_NOW", clock::clockTime()); + + substitutionModel::setBuiltin("OF_NREGIONS", time().names<fvMesh>().size()); + substitutionModel::setBuiltin("OF_NCLOUDS", time().names<cloud>().size()); +} + + +bool Foam::functionObjects::foamReport::parseTemplate(const fileName& fName) +{ + Info<< " Reading template from " << fName << endl; + + IFstream is(fName); + + if (!is.good()) + { + FatalErrorInFunction + << "Unable to open file " << fName << endl; + } + + DynamicList<string> contents; + string buffer; + + label lineNo = 0; + while (is.good()) + { + is.getLine(buffer); + + // Collect keys for this line and clean the buffer + const wordList keys(substitutionModel::getKeys(buffer)); + + Tuple2<label, DynamicList<label>> nullValue(-1, DynamicList<label>()); + + // Assemble table of keyword and lines where the keyword appears + for (const word& key : keys) + { + if (modelKeys_.insert(key, nullValue)) + { + // Set substitution model responsible for this keyword + label modeli = -1; + forAll(substitutions_, i) + { + if (substitutions_[i].valid(key)) + { + modeli = i; + break; + } + } + + // Note: cannot check that key/model is set here + // - dynamic builtins not ready yet... + + modelKeys_[key].first() = modeli; + } + + DynamicList<label>& lineNos = modelKeys_[key].second(); + lineNos.push_back(lineNo); + } + + contents.push_back(buffer); + + ++lineNo; + } + + templateContents_.transfer(contents); + + return templateContents_.size() > 0; +} + + +bool Foam::functionObjects::foamReport::apply(Ostream& os) const +{ + List<string> out(templateContents_); + + forAllConstIters(modelKeys_, iter) + { + const word& key = iter.key(); + const label modeli = iter.val().first(); + const DynamicList<label>& lineNos = iter.val().second(); + + DebugInfo<< "key:" << key << endl; + + for (const label linei : lineNos) + { + if (modeli == -1) + { + if (!substitutionModel::replaceBuiltin(key, out[linei])) + { + WarningInFunction + << "Unable to find substitution for " << key + << " on line " << linei << endl; + } + } + else + { + substitutions_[modeli].apply(key, out[linei]); + } + } + } + + for (const auto& line : out) + { + os << line.c_str() << nl; + } + + return true; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::functionObjects::foamReport::foamReport +( + const word& name, + const Time& runTime, + const dictionary& dict +) +: + stateFunctionObject(name, runTime), + writeFile(runTime, name, typeName, dict), + templateFile_(), + modelKeys_(), + substitutions_(), + debugKeys_(dict.getOrDefault<bool>("debugKeys", false)) +{ + read(dict); + + setStaticBuiltins(); +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::functionObjects::foamReport::read(const dictionary& dict) +{ + if (stateFunctionObject::read(dict)) + { + Info<< type() << " " << name() << ":" << nl; + + dict.readEntry("template", templateFile_); + + Info<< " Template: " << templateFile_ << endl; + + const word ext = templateFile_.ext(); + + if (ext.size()) + { + setExt("." + ext); + } + else + { + setExt(ext); + } + + Info<< " Reading substitutions" << endl; + + const dictionary& subsDict = dict.subDict("substitutions"); + + substitutions_.resize(subsDict.size()); + + label i = 0; + for (const entry& e : subsDict) + { + if (!e.isDict()) + { + FatalIOErrorInFunction(subsDict) + << "Substitution models must be provided in dictionary " + << "format" + << exit(FatalIOError); + } + + substitutions_.set(i++, substitutionModel::New(e.dict(), time())); + } + + parseTemplate(templateFile_.expand()); + + Info<< endl; + + return true; + } + + return false; +} + + +bool Foam::functionObjects::foamReport::execute() +{ + for (auto& sub : substitutions_) + { + sub.update(); + } + + return true; +} + + +bool Foam::functionObjects::foamReport::write() +{ + if (!Pstream::master()) return true; + + setDynamicBuiltins(); + + auto filePtr = newFileAtTime(name(), time().value()); + auto& os = filePtr(); + + // Reset stream width (by default assumes fixed width tabular output) + os.width(0); + + // Perform the substitutions + apply(os); + + if (debugKeys_) + { + os << "Model keys:" << nl; + for (const auto& model : substitutions_) + { + os << model.type() << ":" << model.keys() << nl; + } + + os << "Builtins:" << nl; + substitutionModel::writeBuiltins(os); + } + + return true; +} + + +// ************************************************************************* // diff --git a/src/functionObjects/utilities/foamReport/foamReport.H b/src/functionObjects/utilities/foamReport/foamReport.H new file mode 100644 index 0000000000000000000000000000000000000000..52651560cf3de5493d33138cad390c990a3c62c3 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/foamReport.H @@ -0,0 +1,273 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::functionObjects::foamReport + +Group + grpUtilitiesFunctionObjects + +Description + Replaces user-supplied keywords by run-time computed values in a text file. + + Operands: + \table + Operand | Type | Location + input | - | - + output file | TBA <!-- + --> | postProcessing/\<FO\>/\<time\>/\<file\>(s) + \endtable + +Usage + Example using \c system/controlDict.functions: + + \verbatim + foamReport1 + { + // Mandatory entries + type foamReport; + libs (utilityFunctionObjects); + + template "<system>/myTemplate.md"; + + substitutions + { + divSchemes1 + { + type dictionaryValue; + object fvSchemes; + + entries + { + divSchemes "divSchemes"; + } + } + fvSolution1 + { + type dictionaryValue; + path "<system>/fvSolution"; + + entries + { + solver_p "solvers/p/solver"; + solver_p_tol "solvers/p/tolerance"; + solver_p_reltol "solvers/p/relTol"; + solver_U "solvers/U/solver"; + solver_U_tol "solvers/U/tolerance"; + solver_U_reltol "solvers/U/relTol"; + } + } + controlDict1 + { + type dictionaryValue; + path "<system>/controlDict"; + + entries + { + initial_deltaT "deltaT"; + } + } + continuityErrors + { + type functionObjectValue; + functionObject continuityError1; + + entries + { + cont_error_local local; + cont_error_global global; + cont_error_cumulative cumulative; + } + } + } + + // Optional entries + debugKeys <bool>; + + // Inherited entries + ... + } + \endverbatim + + where the entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: foamReport | word | yes | - + libs | Library name: utilityFunctionObjects | word | yes | - + template | Path to user-supplied text template | string | yes | - + substitutions | Dictionary of substitution models | dictionary | yes | - + debugKeys | Flag to write all known keys | bool | no | false + \endtable + + The \c entries sections typically define a dictionary of keys (to use in + your template) and method to set the key value, e.g. for a dictionaryValue + model used to set values from the \c fvSolution file: + + \verbatim + type dictionaryValue; + path "<system>/fvSolution"; + + entries + { + solver_p "solvers/p/solver"; + solver_p_tol "solvers/p/tolerance"; + } + \endverbatim + + The inherited entries are elaborated in: + - \link substitutionModel.H \endlink + - \link stateFunctionObject.H \endlink + - \link writeFile.H \endlink + +See also + - Foam::functionObject + - Foam::functionObjects::stateFunctionObject + - Foam::functionObjects::writeFile + - Foam::substitutionModel + +SourceFiles + foamReport.C + foamReportTemplates.C + +\*---------------------------------------------------------------------------*/ + +#ifndef functionObjects_foamReport_H +#define functionObjects_foamReport_H + +#include "stateFunctionObject.H" +#include "writeFile.H" +#include "Tuple2.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +class substitutionModel; + +namespace functionObjects +{ + +/*---------------------------------------------------------------------------*\ + Class foamReport Declaration +\*---------------------------------------------------------------------------*/ + +class foamReport +: + public stateFunctionObject, + public writeFile +{ + +protected: + + // Protected Data + + //- Path to user-supplied template + fileName templateFile_; + + //- Mapping from keyword to substitution model index and line + //- numbers of template file where keyword is used + HashTable<Tuple2<label, DynamicList<label>>> modelKeys_; + + //- Template file contents split into lines + List<string> templateContents_; + + //- List of substitution models + PtrList<substitutionModel> substitutions_; + + //- Debug flag to write all known keys + // Helps when assembling template file... + bool debugKeys_; + + + // Protected Member Functions + + //- Parse the template and collect keyword information + bool parseTemplate(const fileName& fName); + + //- Set static builtin entries + void setStaticBuiltins(); + + //- Set dynamic (potentially changing per execution step) builtin + //- entries + void setDynamicBuiltins(); + + //- Apply the substitution models to the template + bool apply(Ostream& os) const; + + + // Generated Methods + + //- No copy construct + foamReport(const foamReport&) = delete; + + //- No copy assignment + void operator=(const foamReport&) = delete; + + +public: + + //- Runtime type information + TypeName("foamReport"); + + + // Constructors + + //- Construct from Time and dictionary + foamReport + ( + const word& name, + const Time& runTime, + const dictionary& dict + ); + + + //- Destructor + virtual ~foamReport() = default; + + + // Member Functions + + //- Read foamReport settings + virtual bool read(const dictionary&); + + //- Execute foamReport + virtual bool execute(); + + //- Write foamReport results + virtual bool write(); +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace functionObjects +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/dictionaryValue/dictionaryValue.C b/src/functionObjects/utilities/foamReport/substitutionModels/dictionaryValue/dictionaryValue.C new file mode 100644 index 0000000000000000000000000000000000000000..d754ff598c4574d5d6606bbc0332411326389328 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/dictionaryValue/dictionaryValue.C @@ -0,0 +1,219 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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 "dictionaryValue.H" +#include "addToRunTimeSelectionTable.H" +#include "IFstream.H" +#include "polyMesh.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace substitutionModels +{ + defineTypeNameAndDebug(dictionaryValue, 0); + addToRunTimeSelectionTable(substitutionModel, dictionaryValue, dictionary); +} +} + + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +bool Foam::substitutionModels::dictionaryValue::processDict +( + const dictionary& dict, + const word& key, + string& buffer +) const +{ + const string& lookup = entries_[key]; + + OStringStream oss; + if (lookup.empty()) + { + // Add complete dictionary + oss << dict; + } + else + { + const entry* ePtr = dict.findScoped(lookup); + + if (!ePtr) + { + WarningInFunction + << "Unable to find entry " << lookup + << endl; + return false; + } + + if (ePtr->isDict()) + { + const dictionary& de = ePtr->dict(); + + // Write dictionary contents + oss << de.dictName() << de; + } + else + { + for (const auto& t : ePtr->stream()) + { + if (oss.count()) oss << separator_; + oss << t; + } + } + } + + buffer.replaceAll(keyify(key), oss.str()); + + return true; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::substitutionModels::dictionaryValue::dictionaryValue +( + const dictionary& dict, + const Time& time +) +: + substitutionModel(dict, time), + object_(), + region_(polyMesh::defaultRegion), + path_(), + separator_(dict.getOrDefault<word>("separator", " ")), + entries_() +{ + const auto* oPtr = dict.findEntry("object"); + const auto* pPtr = dict.findEntry("path"); + + if (oPtr && pPtr) + { + FatalIOErrorInFunction(dict) + << "Specify either 'object' or 'path' but not both" + << exit(FatalIOError); + } + + if (oPtr) + { + // Optionally read the region + dict.readIfPresent<word>("region", region_); + + // Must read the object name to look up + object_ = dict.get<word>("object"); + } + + if (pPtr) + { + path_ = dict.get<fileName>("path").expand(); + } + + // Populate entries + const dictionary& entriesDict = dict.subDict("entries"); + for (const auto& e : entriesDict) + { + entries_.insert(cleanKey(e.keyword()), string(e.stream())); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::substitutionModels::dictionaryValue::valid(const word& keyName) const +{ + return entries_.found(keyName); +} + + +bool Foam::substitutionModels::dictionaryValue::apply +( + const word& key, + string& buffer +) const +{ + if (!valid(key)) return false; + + if (path_.size()) + { + fileName path(path_); + if (replaceBuiltin(path)) + { + path.clean(); + } + + IFstream is(path); + + if (!is.good()) + { + WarningInFunction + << "Unable to find dictionary at " << path + << ". Deactivating." << endl; + + return false; + } + + return processDict(dictionary(is), key, buffer); + } + else + { + const auto* obrPtr = time_.cfindObject<objectRegistry>(region_); + + if (!obrPtr) + { + WarningInFunction + << "Unable to find region " << region_ + << ". Deactivating." << endl; + + return false; + } + + // Find object; recursive lookup into parent + const auto* dictPtr = obrPtr->cfindObject<IOdictionary>(object_, true); + + if (!dictPtr) + { + WarningInFunction + << "Unable find dictionary " << object_ + << " on region " << region_ + << ". Deactivating." << endl; + + return false; + } + + return processDict(*dictPtr, key, buffer); + } +} + + +Foam::wordList Foam::substitutionModels::dictionaryValue::keys() const +{ + return entries_.sortedToc(); +} + + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/dictionaryValue/dictionaryValue.H b/src/functionObjects/utilities/foamReport/substitutionModels/dictionaryValue/dictionaryValue.H new file mode 100644 index 0000000000000000000000000000000000000000..e1cd47506a623f857311cf8c6050ef5d38724ccf --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/dictionaryValue/dictionaryValue.H @@ -0,0 +1,182 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::substitutionModels::dictionaryValue + +Description + The \c dictionaryValue substitution model. Dictionaries can be retrieved + from an object registry, e.g. time, mesh, or from file. + + The example below shows how the keywords \c p_solver and \c u_solver are set + by retrieving values from the \c fvSolution dictionary. + + \verbatim + dictionaryValues1 + { + // Mandatory entries + type dictionaryValue; + + entries + { + p_solver "solvers/p/solver"; + u_solver "solvers/u/solver"; + } + + // Conditional entries + + // Option-1 + object "fvSolution"; // registry-based retrieval + // region "fluidMesh"; + + // Option-2 + // path "<system>/fvSolution"; // file-based retrieval + + + // Optional entries + separator <word>; + + // Inherited entries + ... + } + \endverbatim + + The entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: dictionaryValue | word | yes | - + entries | keyword lookup pairs | dictionary | yes | - + object | Name of registered dictionary | string | no | - + region | Name of mesh region | word | no | region0 + path | Path to dictionary file | string | no | - + separator | Sep. when lookup value has multiple tokens | word | no | - + \endtable + + The inherited entries are elaborated in: + - \link substitutionModel.H \endlink + +SourceFiles + dictionaryValue.C + +---------------------------------------------------------------------------*/ + +#ifndef Foam_substitutionModels_dictionaryValue_H +#define Foam_substitutionModels_dictionaryValue_H + +#include "substitutionModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +namespace substitutionModels +{ + +/*---------------------------------------------------------------------------*\ + Class dictionaryValue Declaration +\*---------------------------------------------------------------------------*/ + +class dictionaryValue +: + public substitutionModel +{ + // Private Data + + //- Dictionary name for registry-based lookup + word object_; + + //- Region name for registry-based lookup + word region_; + + //- Path to dictionary for file-based lookup + fileName path_; + + //- Separator when lookup value has multiple tokens + const word separator_; + + //- Hash table for key and entry-lookup pairs + HashTable<string> entries_; + + + // Private Functions + + //- No copy construct + dictionaryValue(const dictionaryValue&) = delete; + + //- No copy assignment + void operator=(const dictionaryValue&) = delete; + + +protected: + + // Protected Member Functions + + //- Main function to process the dictionary + bool processDict + ( + const dictionary& dict, + const word& key, + string& buffer + ) const; + + +public: + + //- Runtime type information + TypeName("dictionaryValue"); + + + //- Constructor + dictionaryValue(const dictionary& dict, const Time& time); + + + //- Destructor + virtual ~dictionaryValue() = default; + + + // Member Functions + + //- Return true of model applies to this keyName + virtual bool valid(const word& keyName) const; + + //- Apply substitutions to this string buffer + virtual bool apply(const word& key, string& buffer) const; + + //- Return a word list of the keys + virtual wordList keys() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace substitutionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/environmentVariable/environmentVariable.C b/src/functionObjects/utilities/foamReport/substitutionModels/environmentVariable/environmentVariable.C new file mode 100644 index 0000000000000000000000000000000000000000..49e1951e02ae586b20e856b542f434baf753185d --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/environmentVariable/environmentVariable.C @@ -0,0 +1,101 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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 "environmentVariable.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace substitutionModels +{ + defineTypeNameAndDebug(environmentVariable, 0); + addToRunTimeSelectionTable + ( + substitutionModel, + environmentVariable, + dictionary + ); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::substitutionModels::environmentVariable::environmentVariable +( + const dictionary& dict, + const Time& time +) +: + substitutionModel(dict, time), + entries_() +{ + // Populate entries + const dictionary& entriesDict = dict.subDict("entries"); + for (const auto& e : entriesDict) + { + entries_.insert(cleanKey(e.keyword()), string(e.stream())); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::substitutionModels::environmentVariable::valid +( + const word& keyName +) const +{ + return entries_.found(keyName); +} + + +bool Foam::substitutionModels::environmentVariable::apply +( + const word& key, + string& buffer +) const +{ + if (!valid(key)) return false; + + const string env(Foam::getEnv(entries_[key])); + + buffer.replaceAll(keyify(key), env); + + return true; +} + + +Foam::wordList Foam::substitutionModels::environmentVariable::keys() const +{ + return entries_.sortedToc(); +} + + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/environmentVariable/environmentVariable.H b/src/functionObjects/utilities/foamReport/substitutionModels/environmentVariable/environmentVariable.H new file mode 100644 index 0000000000000000000000000000000000000000..d72088e823b4219b27e19741fe0e3a1f6a8672bf --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/environmentVariable/environmentVariable.H @@ -0,0 +1,136 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::substitutionModels::environmentVariable + +Description + The \c environmentVariable substitution model. + + \verbatim + environmentVariables1 + { + // Mandatory entries + type environmentVariable; + + entries + { + home "HOME"; + ldpath "LD_LIBRARY_PATH"; + } + + // Inherited entries + ... + } + \endverbatim + + The entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: environmentVariable | word | yes | - + entries | Keyword lookup pairs | dictionary | yes | - + \endtable + + The inherited entries are elaborated in: + - \link substitutionModel.H \endlink + +SourceFiles + environmentVariable.C + +---------------------------------------------------------------------------*/ + +#ifndef Foam_substitutionModels_environmentVariable_H +#define Foam_substitutionModels_environmentVariable_H + +#include "substitutionModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +namespace substitutionModels +{ + +/*---------------------------------------------------------------------------*\ + Class environmentVariable Declaration +\*---------------------------------------------------------------------------*/ + +class environmentVariable +: + public substitutionModel +{ + // Private Data + + //- Hash table for key and environment variable pairs + HashTable<string> entries_; + + + // Private Functions + + //- No copy construct + environmentVariable(const environmentVariable&) = delete; + + //- No copy assignment + void operator=(const environmentVariable&) = delete; + + +public: + + //- Runtime type information + TypeName("environmentVariable"); + + + //- Constructor + environmentVariable(const dictionary& dict, const Time& time); + + + //- Destructor + virtual ~environmentVariable() = default; + + + // Member Functions + + //- Return true of model applies to this keyName + virtual bool valid(const word& keyName) const; + + //- Apply substitutions to this string buffer + virtual bool apply(const word& key, string& buffer) const; + + //- Return a word list of the keys + virtual wordList keys() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace substitutionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/fileRegEx/fileRegEx.C b/src/functionObjects/utilities/foamReport/substitutionModels/fileRegEx/fileRegEx.C new file mode 100644 index 0000000000000000000000000000000000000000..37fc3f0d68c9dbc76f873adec166d5d1b8251ce2 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/fileRegEx/fileRegEx.C @@ -0,0 +1,163 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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 "fileRegEx.H" +#include "addToRunTimeSelectionTable.H" +#include "IFstream.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace substitutionModels +{ + defineTypeNameAndDebug(fileRegEx, 0); + addToRunTimeSelectionTable(substitutionModel, fileRegEx, dictionary); +} +} + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::substitutionModels::fileRegEx::fileRegEx +( + const dictionary& dict, + const Time& time +) +: + substitutionModel(dict, time), + path_(dict.get<fileName>("path")), + entries_(), + sectionSeparator_ + ( + dict.getOrDefault<string> + ( + "sectionSeparator", + "Time =" + ) + ), + matchSeparator_(dict.getOrDefault<string>("matchSeparator", " ")), + lastMatch_(dict.getOrDefault<bool>("lastMatch", true)) +{ + // Populate entries + const dictionary& entriesDict = dict.subDict("entries"); + for (const auto& e : entriesDict) + { + entries_.insert(cleanKey(e.keyword()), string(e.stream())); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::substitutionModels::fileRegEx::valid(const word& keyName) const +{ + return entries_.found(keyName); +} + + +bool Foam::substitutionModels::fileRegEx::apply +( + const word& key, + string& buffer +) const +{ + if (!valid(key)) return false; + + fileName path(path_); + replaceBuiltin(path); + IFstream is(path); + + if (!is.good()) + { + WarningInFunction + << "Unable to find file at " << path_ + << ". Deactivating." << endl; + + return false; + } + + Info<< "Scanning for sections beginning with " + << sectionSeparator_ << endl; + + // For log files containing multiple time steps + // - put strings for last time step into a string list + DynamicList<string> lines(96); + string line; + bool started = sectionSeparator_.empty() ? true : false; + while (is.good()) + { + is.getLine(line); + if (line.starts_with(sectionSeparator_)) + { + started = true; + lines.clear(); + } + if (started) + { + lines.append(line); + } + } + + Info<< "Cached " << lines.size() << " lines" << endl; + + OStringStream oss; + regExp re(entries_[key].c_str()); + + for (const string& data : lines) + { + regExp::results_type match; + if (re.match(data, match)) + { + oss.reset(); + + for (size_t i = 1; i < match.size(); ++i) + { + if (i > 1) oss << matchSeparator_; + oss << match[i].str().c_str(); + } + + if (!lastMatch_) break; + } + } + + if (oss.count()) + { + buffer.replaceAll(keyify(key), oss.str()); + return true; + } + + return false; +} + + +Foam::wordList Foam::substitutionModels::fileRegEx::keys() const +{ + return entries_.sortedToc(); +} + + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/fileRegEx/fileRegEx.H b/src/functionObjects/utilities/foamReport/substitutionModels/fileRegEx/fileRegEx.H new file mode 100644 index 0000000000000000000000000000000000000000..891a1d6858f27fd5551322afb3b4997e0246ef37 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/fileRegEx/fileRegEx.H @@ -0,0 +1,162 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::substitutionModels::fileRegEx + +Description + The \c fileRegEx substitution model. + + The example below shows how the keyword \c executionTime is set by + applying a regular expression (string) to a log file. + + \verbatim + fileRegEx1 + { + // Mandatory entries + type fileRegEx; + path "log.simpleFoam"; + + entries + { + executionTime "ExecutionTime = (.*) s Clock.*"; + } + + // Optional entries + sectionSeparator <string>; + matchSeparator <string>; + lastMatch <bool>; + + // Inherited entries + ... + } + \endverbatim + + The entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: functionObjectValue | word | yes | - + path | Path to file | string | yes | - + entries | Keyword regular-expression pairs | dictionary | yes | - + sectionSeparator | Marker used to separate files into sections <!-- + --!> | string | no | "Time =" + matchSeparator | Separator used to join multiple values <!-- + --!> | string | no | " " + lastMatch | Flag to use last file section | bool | no | yes + \endtable + + The inherited entries are elaborated in: + - \link substitutionModel.H \endlink + +SourceFiles + fileRegEx.C + +---------------------------------------------------------------------------*/ + +#ifndef Foam_substitutionModels_fileRegEx_H +#define Foam_substitutionModels_fileRegEx_H + +#include "substitutionModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +namespace substitutionModels +{ + +/*---------------------------------------------------------------------------*\ + Class fileRegEx Declaration +\*---------------------------------------------------------------------------*/ + +class fileRegEx +: + public substitutionModel +{ + // Private Data + + //- Path to dictionary + const fileName path_; + + //- Hash table for key and regular expression pairs + HashTable<string> entries_; + + //- Section separator to dive log files, e.g. into time step info + const string sectionSeparator_; + + //- Separator to apply between (multiple) matches + const string matchSeparator_; + + //- Last match wins flag + bool lastMatch_; + + + // Private Functions + + //- No copy construct + fileRegEx(const fileRegEx&) = delete; + + //- No copy assignment + void operator=(const fileRegEx&) = delete; + + +public: + + //- Runtime type information + TypeName("fileRegEx"); + + + //- Constructor + fileRegEx(const dictionary& dict, const Time& time); + + + //- Destructor + virtual ~fileRegEx() = default; + + + // Member Functions + + //- Return true of model applies to this keyName + virtual bool valid(const word& keyName) const; + + //- Apply substitutions to this string buffer + virtual bool apply(const word& key, string& buffer) const; + + //- Return a word list of the keys + virtual wordList keys() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace substitutionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/functionObjectValue/functionObjectValue.C b/src/functionObjects/utilities/foamReport/substitutionModels/functionObjectValue/functionObjectValue.C new file mode 100644 index 0000000000000000000000000000000000000000..34f5188331581d43a6d755bc923f424c9a829aa3 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/functionObjectValue/functionObjectValue.C @@ -0,0 +1,149 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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 "functionObjectValue.H" +#include "addToRunTimeSelectionTable.H" +#include "IFstream.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace substitutionModels +{ + defineTypeNameAndDebug(functionObjectValue, 0); + addToRunTimeSelectionTable + ( + substitutionModel, + functionObjectValue, + dictionary + ); +} +} + +// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * // + +template<class Type> +bool Foam::substitutionModels::functionObjectValue::getValue +( + OStringStream& oss, + const word& lookup +) const +{ + const auto& foProps = time_.functionObjects().propsDict(); + + Type result; + if (foProps.getObjectResult(functionObject_, lookup, result)) + { + oss << result; + return true; + } + + return false; +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::substitutionModels::functionObjectValue::functionObjectValue +( + const dictionary& dict, + const Time& time +) +: + substitutionModel(dict, time), + functionObject_(dict.get<word>("functionObject")), + entries_(), + debugValues_(dict.getOrDefault<bool>("debugValues", false)) +{ + // Populate entries + const dictionary& entriesDict = dict.subDict("entries"); + for (const auto& e : entriesDict) + { + entries_.insert(cleanKey(e.keyword()), word(e.stream())); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::substitutionModels::functionObjectValue::update() +{ + if (debugValues_) + { + Info<< nl << "Function object results:" << nl; + time_.functionObjects().propsDict().writeAllResultEntries(Info); + } + + return true; +} + + +bool Foam::substitutionModels::functionObjectValue::valid +( + const word& keyName +) const +{ + return entries_.found(keyName); +} + + +bool Foam::substitutionModels::functionObjectValue::apply +( + const word& key, + string& buffer +) const +{ + if (!valid(key)) return false; + + OStringStream oss; + + const word& lookup = entries_[key]; + + bool ok = + getValue<label>(oss, lookup) + || getValue<scalar>(oss, lookup) + || getValue<vector>(oss, lookup) + || getValue<sphericalTensor>(oss, lookup) + || getValue<symmTensor>(oss, lookup) + || getValue<tensor>(oss, lookup); + + if (!ok) return false; + + buffer.replaceAll(keyify(key), oss.str()); + + return true; +} + + +Foam::wordList Foam::substitutionModels::functionObjectValue::keys() const +{ + return entries_.sortedToc(); +} + + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/functionObjectValue/functionObjectValue.H b/src/functionObjects/utilities/foamReport/substitutionModels/functionObjectValue/functionObjectValue.H new file mode 100644 index 0000000000000000000000000000000000000000..024ef6774c50e7234bcad368ab41432d8472f13e --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/functionObjectValue/functionObjectValue.H @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::substitutionModels::functionObjectValue + +Description + functionObjectValue substitution model. + +Usage + The \c functionObjectValue substitution model. + + The example below shows how the keywords \c cont_error_* are set by + retrieving the values \c local, \c global, \c cumulative from the function + object \c functionObjectValue. + + \verbatim + functionObjectValue1 + { + // Mandatory entries + type functionObjectValue; + functionObject continuityError1; + + entries + { + cont_error_local local; + cont_error_global global; + cont_error_cumulative cumulative; + } + + // Optional entries + debugValues <bool>; + + // Inherited entries + ... + } + \endverbatim + + The entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: functionObjectValue | word | yes | - + functionObject | Name of function object to query | word | yes | - + entries | Keyword-lookup pairs | dictionary | yes | - + debugValues | Flag to show available function values | bool | no | false + \endtable + + The inherited entries are elaborated in: + - \link substitutionModel.H \endlink + +SourceFiles + functionObjectValue.C + +---------------------------------------------------------------------------*/ + +#ifndef Foam_substitutionModels_functionObjectValue_H +#define Foam_substitutionModels_functionObjectValue_H + +#include "substitutionModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +namespace substitutionModels +{ + +/*---------------------------------------------------------------------------*\ + Class functionObjectValue Declaration +\*---------------------------------------------------------------------------*/ + +class functionObjectValue +: + public substitutionModel +{ + // Private Data + + //- Name of function object + const word functionObject_; + + //- Hash table for key and entry-lookup pairs + HashTable<word> entries_; + + //- Debug - shows available function values + bool debugValues_; + + + // Private Functions + + //- Get the result value from the function object + template<class Type> + bool getValue(OStringStream& oss, const word& lookup) const; + + //- No copy construct + functionObjectValue(const functionObjectValue&) = delete; + + //- No copy assignment + void operator=(const functionObjectValue&) = delete; + + +public: + + //- Runtime type information + TypeName("functionObjectValue"); + + + //- Constructor + functionObjectValue + ( + const dictionary& dict, + const Time& time + ); + + + //- Destructor + virtual ~functionObjectValue() = default; + + + // Member Functions + + //- Update model local data + virtual bool update(); + + //- Return true of model applies to this keyName + virtual bool valid(const word& keyName) const; + + //- Apply substitutions to this string buffer + virtual bool apply(const word& key, string& buffer) const; + + //- Return a word list of the keys + virtual wordList keys() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace substitutionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModel.C b/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModel.C new file mode 100644 index 0000000000000000000000000000000000000000..bac232c9516473341f34ff89750da8498f07bd43 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModel.C @@ -0,0 +1,167 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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 "substitutionModel.H" +#include "stringOps.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ + defineTypeNameAndDebug(substitutionModel, 0); + defineRunTimeSelectionTable(substitutionModel, dictionary); +} + +const Foam::word Foam::substitutionModel::KEY_BEGIN = "{{"; +const Foam::word Foam::substitutionModel::KEY_END = "}}"; +Foam::HashTable<Foam::string> Foam::substitutionModel::builtin_; + +// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * // + +Foam::string Foam::substitutionModel::keyify(const word& w) +{ + return KEY_BEGIN + w + KEY_END; +} + + +Foam::word Foam::substitutionModel::cleanKey(const string& str) +{ + return stringOps::upper(stringOps::trim(str)); +}; + + +Foam::wordList Foam::substitutionModel::getKeys(string& buffer) +{ + const label lBegin = KEY_BEGIN.length(); + const label lEnd = KEY_END.length(); + + wordHashSet keys; + + size_t pos0 = 0; + size_t pos = 0; + string cleanedBuffer = ""; + while (((pos = buffer.find(KEY_BEGIN, pos)) != string::npos)) + { + cleanedBuffer += buffer.substr(pos0, pos-pos0); + + size_t posEnd = buffer.find(KEY_END, pos); + + if (posEnd != string::npos) + { + const word k(cleanKey(buffer.substr(pos+lBegin, posEnd-pos-lEnd))); + keys.insert(k); + cleanedBuffer += keyify(k); + } + + pos = posEnd + lEnd; + pos0 = pos; + } + + cleanedBuffer += buffer.substr(pos0, buffer.length() - pos0); + buffer = cleanedBuffer; + + return keys.toc(); +} + + +void Foam::substitutionModel::addBuiltinStr +( + const word& key, + const string& value +) +{ + builtin_.insert(cleanKey(key), value.c_str()); +} + + +bool Foam::substitutionModel::containsBuiltin(const word& key) +{ + return builtin_.contains(key); +} + + +void Foam::substitutionModel::setBuiltinStr +( + const word& key, + const string& value +) +{ + builtin_.set(cleanKey(key), value.c_str()); +} + + +bool Foam::substitutionModel::replaceBuiltin(const word& key, string& str) +{ + if (builtin_.found(key)) + { + str.replaceAll(keyify(key), builtin_[key].c_str()); + return true; + } + + return false; +} + + +bool Foam::substitutionModel::replaceBuiltin(string& str) +{ + const string str0 = str; + + // Quick exit if there are no keys in the string + if (str.find(KEY_BEGIN) == string::npos) return false; + + forAllConstIters(builtin_, iter) + { + str.replaceAll(keyify(iter.key()), iter.val().c_str()); + } + + return str != str0; +} + + +void Foam::substitutionModel::writeBuiltins(Ostream& os) +{ + for (const auto& iter : builtin_.csorted()) + { + os << keyify(iter.key()).c_str() << " : " << iter.val() << nl; + } +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::substitutionModel::substitutionModel +( + const dictionary& dict, + const Time& time +) +: + dict_(dict), + time_(time) +{} + + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModel.H b/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModel.H new file mode 100644 index 0000000000000000000000000000000000000000..d4c474416bba3df2798ac03fecad09a5aae11e87 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModel.H @@ -0,0 +1,206 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::substitutionModel + +Description + Base class for substitution models. + + Provides a static hash table for builtin keyword-value pairs and functions + to manipulate/interact. + +SourceFiles + substitutionModel.C + substitutionModelNew.C + +---------------------------------------------------------------------------*/ + +#ifndef Foam_substitutionModel_H +#define Foam_substitutionModel_H + +#include "runTimeSelectionTables.H" +#include "dictionary.H" +#include "Time.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +/*---------------------------------------------------------------------------*\ + Class substitutionModel Declaration +\*---------------------------------------------------------------------------*/ + +class substitutionModel +{ +public: + + // Static Data Members + + //- Keyword starting characters + static const word KEY_BEGIN; + + //- Keyword ending characters + static const word KEY_END; + + //- Built-in substitutions + static HashTable<string> builtin_; + + + // Static Member Functions + + //- Return a key representation from a word + static string keyify(const word& w); + + //- Clean the key text + static word cleanKey(const string& str); + + //- Return all keys from a string buffer + // Also cleans the key strings in the buffer + static wordList getKeys(string& buffer); + + //- Add a builtin to the hash table - does not overwrite + static void addBuiltinStr(const word& key, const string& value); + + //- Add a builtin to the hash table - does not overwrite + template<class Type> + static void addBuiltin(const word& key, const Type& value); + + //- Return true if key is builtin + static bool containsBuiltin(const word& key); + + //- Set a builtin to the hash table + static void setBuiltinStr(const word& key, const string& value); + + //- Set a builtin to the hash table + template<class Type> + static void setBuiltin(const word& key, const Type& value); + + //- Replace key in string + static bool replaceBuiltin(const word& key, string& str); + + //- Replace all occurrences of key in string + static bool replaceBuiltin(string& str); + + //- Write all builtins to stream + static void writeBuiltins(Ostream& os); + + +private: + + // Private Functions + + //- No copy construct + substitutionModel(const substitutionModel&) = delete; + + //- No copy assignment + void operator=(const substitutionModel&) = delete; + + +protected: + + // Protected Data + + //- Construction dictionary + const dictionary dict_; + + //- Reference to the time database + const Time& time_; + + +public: + + //- Runtime type information + TypeName("substitutionModel"); + + // Declare run-time constructor selection table + + declareRunTimeSelectionTable + ( + autoPtr, + substitutionModel, + dictionary, + ( + const dictionary& dict, + const Time& time + ), + (dict, time) + ); + + + // Selectors + + //- Return a reference to the selected substitution model + static autoPtr<substitutionModel> New + ( + const dictionary& dict, + const Time& time + ); + + + //- Constructor + substitutionModel + ( + const dictionary& dict, + const Time& time + ); + + + //- Destructor + virtual ~substitutionModel() = default; + + + // Member Functions + + //- Update model local data + virtual bool update() { return true; } + + //- Return true of model applies to this keyName + virtual bool valid(const word& keyName) const = 0; + + //- Apply substitutions to this string buffer + virtual bool apply(const word& key, string& buffer) const = 0; + + //- Return a word list of the keys + virtual wordList keys() const = 0; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#ifdef NoRepository + #include "substitutionModelTemplates.C" +#endif + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModelNew.C b/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModelNew.C new file mode 100644 index 0000000000000000000000000000000000000000..c284136c373d29e39bd032209b7696deaabb0798 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModelNew.C @@ -0,0 +1,60 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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 "substitutionModel.H" +#include "error.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +Foam::autoPtr<Foam::substitutionModel> Foam::substitutionModel::New +( + const dictionary& dict, + const Time& time +) +{ + const word modelType(dict.get<word>("type")); + + Info<< " Selecting substitution model " << modelType << endl; + + auto* ctorPtr = dictionaryConstructorTable(modelType); + + if (!ctorPtr) + { + FatalIOErrorInLookup + ( + dict, + "substitutionModel", + modelType, + *dictionaryConstructorTablePtr_ + ) << exit(FatalIOError); + } + + return autoPtr<substitutionModel>(ctorPtr(dict, time)); +} + + +// ************************************************************************* // diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModelTemplates.C b/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModelTemplates.C new file mode 100644 index 0000000000000000000000000000000000000000..71a4a90b83a73e8e021e45cdd5cc1cfaaa963d38 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/substitutionModel/substitutionModelTemplates.C @@ -0,0 +1,47 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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/>. + +\*---------------------------------------------------------------------------*/ + +template<class Type> +void Foam::substitutionModel::addBuiltin(const word& key, const Type& value) +{ + OStringStream oss; + oss << value; + addBuiltinStr(key, oss.str()); +} + + +template<class Type> +void Foam::substitutionModel::setBuiltin(const word& key, const Type& value) +{ + OStringStream oss; + oss << value; + + setBuiltinStr(key, oss.str()); +} + + +// ************************************************************************* // diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/userValue/userValue.C b/src/functionObjects/utilities/foamReport/substitutionModels/userValue/userValue.C new file mode 100644 index 0000000000000000000000000000000000000000..4c05164c32f3692b880c810bb5bfdece26bfb96c --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/userValue/userValue.C @@ -0,0 +1,99 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 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 "userValue.H" +#include "addToRunTimeSelectionTable.H" + +// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * // + +namespace Foam +{ +namespace substitutionModels +{ + defineTypeNameAndDebug(userValue, 0); + addToRunTimeSelectionTable + ( + substitutionModel, + userValue, + dictionary + ); +} +} + + +// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * // + +Foam::substitutionModels::userValue::userValue +( + const dictionary& dict, + const Time& time +) +: + substitutionModel(dict, time), + entries_() +{ + // Populate entries + const dictionary& entriesDict = dict.subDict("entries"); + for (const auto& e : entriesDict) + { + entries_.insert(cleanKey(e.keyword()), string(e.stream())); + } +} + + +// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // + +bool Foam::substitutionModels::userValue::valid +( + const word& keyName +) const +{ + return entries_.found(keyName); +} + + +bool Foam::substitutionModels::userValue::apply +( + const word& key, + string& buffer +) const +{ + if (!valid(key)) return false; + + buffer.replaceAll(keyify(key), entries_[key]); + + return true; +} + + +Foam::wordList Foam::substitutionModels::userValue::keys() const +{ + return entries_.sortedToc(); +} + + +// ************************************************************************* // \ No newline at end of file diff --git a/src/functionObjects/utilities/foamReport/substitutionModels/userValue/userValue.H b/src/functionObjects/utilities/foamReport/substitutionModels/userValue/userValue.H new file mode 100644 index 0000000000000000000000000000000000000000..78ec3a48183d533cbafed4d645c2bf40448f4d40 --- /dev/null +++ b/src/functionObjects/utilities/foamReport/substitutionModels/userValue/userValue.H @@ -0,0 +1,137 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \ / F ield | OpenFOAM: The Open Source CFD Toolbox + \ / O peration | + \ / A nd | www.openfoam.com + \/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2024 OpenCFD Ltd. +------------------------------------------------------------------------------- +License + This file is part of OpenFOAM. + + OpenFOAM is free software: you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + OpenFOAM is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License + along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. + +Class + Foam::substitutionModels::userValue + +Description + The \c userValue substitution model. Dictionaries can be retrieved from + an object registry, e.g. time, mesh, or from a file. + + \verbatim + userValues1 + { + // Mandatory entries + type userValue; + + entries + { + my_keyword1 "My local string value"; + my_keyword2 "My local string value"; + } + + // Inherited entries + ... + } + \endverbatim + + The entries mean: + \table + Property | Description | Type | Reqd | Deflt + type | Type name: userValue | word | yes | - + entries | Keyword lookup pairs | dictionary | yes | - + \endtable + + The inherited entries are elaborated in: + - \link substitutionModel.H \endlink + +SourceFiles + userValue.C + +---------------------------------------------------------------------------*/ + +#ifndef Foam_substitutionModels_userValue_H +#define Foam_substitutionModels_userValue_H + +#include "substitutionModel.H" + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +namespace Foam +{ + +namespace substitutionModels +{ + +/*---------------------------------------------------------------------------*\ + Class userValue Declaration +\*---------------------------------------------------------------------------*/ + +class userValue +: + public substitutionModel +{ + // Private Data + + //- Hash table for key and environment variable pairs + HashTable<string> entries_; + + + // Private Functions + + //- No copy construct + userValue(const userValue&) = delete; + + //- No copy assignment + void operator=(const userValue&) = delete; + + +public: + + //- Runtime type information + TypeName("userValue"); + + + //- Constructor + userValue(const dictionary& dict, const Time& time); + + + //- Destructor + virtual ~userValue() = default; + + + // Member Functions + + //- Return true of model applies to this keyName + virtual bool valid(const word& keyName) const; + + //- Apply substitutions to this string buffer + virtual bool apply(const word& key, string& buffer) const; + + //- Return a word list of the keys + virtual wordList keys() const; +}; + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +} // End namespace substitutionModels +} // End namespace Foam + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +#endif + +// ************************************************************************* // \ No newline at end of file