mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-reporting' into 'develop'
Reporting tools See merge request Development/openfoam!716
This commit is contained in:
@ -9,6 +9,17 @@ areaWrite/areaWrite.C
|
|||||||
ensightWrite/ensightWrite.C
|
ensightWrite/ensightWrite.C
|
||||||
ensightWrite/ensightWriteUpdate.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
|
vtkWrite/vtkWrite.C
|
||||||
vtkWrite/vtkWriteUpdate.C
|
vtkWrite/vtkWriteUpdate.C
|
||||||
|
|
||||||
|
|||||||
350
src/functionObjects/utilities/foamReport/foamReport.C
Normal file
350
src/functionObjects/utilities/foamReport/foamReport.C
Normal file
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
273
src/functionObjects/utilities/foamReport/foamReport.H
Normal file
273
src/functionObjects/utilities/foamReport/foamReport.H
Normal file
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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)
|
||||||
|
{}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -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
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
238
src/functionObjects/utilities/graphFunctionObject/SVGTools.H
Normal file
238
src/functionObjects/utilities/graphFunctionObject/SVGTools.H
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\ / 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/>.
|
||||||
|
|
||||||
|
Namespace
|
||||||
|
Foam::SVG
|
||||||
|
|
||||||
|
Description
|
||||||
|
Collection of tools to generate SVG strings
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
SVGTools.H
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_SVGTools_H
|
||||||
|
#define Foam_SVGTools_H
|
||||||
|
|
||||||
|
#include "Ostream.H"
|
||||||
|
#include "OStringStream.H"
|
||||||
|
#include "List.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Namespace SVG Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
namespace SVG
|
||||||
|
{
|
||||||
|
typedef std::pair<const char*, string> entryType;
|
||||||
|
|
||||||
|
struct element;
|
||||||
|
Ostream& operator<<(Ostream& os, const element& e);
|
||||||
|
|
||||||
|
// Base SVG element
|
||||||
|
struct element
|
||||||
|
{
|
||||||
|
const word key_;
|
||||||
|
DynamicList<entryType> styles_;
|
||||||
|
DynamicList<entryType> elems_;
|
||||||
|
|
||||||
|
element
|
||||||
|
(
|
||||||
|
const word& key,
|
||||||
|
const std::initializer_list<entryType>& styles = {},
|
||||||
|
const std::initializer_list<entryType>& elems = {}
|
||||||
|
)
|
||||||
|
:
|
||||||
|
key_(key),
|
||||||
|
styles_(styles),
|
||||||
|
elems_(elems)
|
||||||
|
{}
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
void addAttr(const char* key, const Type& value)
|
||||||
|
{
|
||||||
|
OStringStream oss;
|
||||||
|
oss << value;
|
||||||
|
elems_.push_back(entryType(key, oss.str().c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void addAttrStr(const char* key, const string& str)
|
||||||
|
{
|
||||||
|
elems_.push_back(entryType(key, str.c_str()));
|
||||||
|
}
|
||||||
|
|
||||||
|
friend Ostream& operator<<(Ostream& os, const element& ele)
|
||||||
|
{
|
||||||
|
os << "<" << ele.key_;
|
||||||
|
|
||||||
|
for (const auto& e : ele.elems_)
|
||||||
|
{
|
||||||
|
os << " " << e.first << "=" << e.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
os << " style=\"";
|
||||||
|
for (const auto& s : ele.styles_)
|
||||||
|
{
|
||||||
|
os << s.first << ":" << s.second.c_str() << ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "\">";
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
const word end = "</" + key_ + ">";
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct text;
|
||||||
|
Ostream& operator<<(Ostream& os, const text& t);
|
||||||
|
|
||||||
|
// Text
|
||||||
|
struct text
|
||||||
|
:
|
||||||
|
element
|
||||||
|
{
|
||||||
|
const string text_;
|
||||||
|
|
||||||
|
text
|
||||||
|
(
|
||||||
|
const string text,
|
||||||
|
const label left,
|
||||||
|
const label top,
|
||||||
|
const std::initializer_list<entryType>& styles = {},
|
||||||
|
const word anchor = "middle",
|
||||||
|
const std::initializer_list<entryType>& elems = {}
|
||||||
|
)
|
||||||
|
:
|
||||||
|
element("text", styles, elems),
|
||||||
|
text_(text)
|
||||||
|
{
|
||||||
|
elems_.push_back(entryType("x", Foam::name(left)));
|
||||||
|
elems_.push_back(entryType("y", Foam::name(top)));
|
||||||
|
elems_.push_back(entryType("text-anchor", anchor));
|
||||||
|
elems_.push_back
|
||||||
|
(
|
||||||
|
entryType("font-family", "Arial, Helvetica, sans-serif")
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
friend Ostream& operator<<(Ostream& os, const text& t)
|
||||||
|
{
|
||||||
|
// element::operator<<(os, t);
|
||||||
|
os << static_cast<const element&>(t);
|
||||||
|
|
||||||
|
os << t.text_.c_str();
|
||||||
|
|
||||||
|
os << t.end;
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct line;
|
||||||
|
Ostream& operator<<(Ostream& os, const line& l);
|
||||||
|
|
||||||
|
// Line
|
||||||
|
struct line
|
||||||
|
:
|
||||||
|
element
|
||||||
|
{
|
||||||
|
line
|
||||||
|
(
|
||||||
|
const label x1,
|
||||||
|
const label y1,
|
||||||
|
const label x2,
|
||||||
|
const label y2,
|
||||||
|
const std::initializer_list<entryType>& styles = {},
|
||||||
|
const std::initializer_list<entryType>& elems = {}
|
||||||
|
)
|
||||||
|
:
|
||||||
|
element("line", styles, elems)
|
||||||
|
{
|
||||||
|
elems_.push_back(entryType("x1", Foam::name(x1)));
|
||||||
|
elems_.push_back(entryType("y1", Foam::name(y1)));
|
||||||
|
elems_.push_back(entryType("x2", Foam::name(x2)));
|
||||||
|
elems_.push_back(entryType("y2", Foam::name(y2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
friend Ostream& operator<<(Ostream& os, const line& l)
|
||||||
|
{
|
||||||
|
// element::operator<<(os, l);
|
||||||
|
os << static_cast<const element&>(l);
|
||||||
|
os << l.end;
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct header;
|
||||||
|
Ostream& operator<<(Ostream& os, const header& h);
|
||||||
|
|
||||||
|
// Header
|
||||||
|
struct header
|
||||||
|
{
|
||||||
|
label width_;
|
||||||
|
label height_;
|
||||||
|
|
||||||
|
header(const label width, const label height)
|
||||||
|
:
|
||||||
|
width_(width),
|
||||||
|
height_(height)
|
||||||
|
{}
|
||||||
|
|
||||||
|
friend Ostream& operator<<(Ostream& os, const header& h)
|
||||||
|
{
|
||||||
|
os << "<svg viewBox=\"0 0 " << h.width_ << ' ' << h.height_ << "\""
|
||||||
|
<< " xmlns=\"http://www.w3.org/2000/svg\""
|
||||||
|
<< " xmlns:xlink=\"http://www.w3.org/1999/xlink\""
|
||||||
|
<< " xmlns:bx=\"https://www.boxy-svg.com/bx\">";
|
||||||
|
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Close SVG element
|
||||||
|
const char* end = "</svg>";
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace SVG
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,654 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\ / 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 "graphFunctionObject.H"
|
||||||
|
#include "addToRunTimeSelectionTable.H"
|
||||||
|
#include "OFstream.H"
|
||||||
|
#include "labelVector.H"
|
||||||
|
#include "FlatOutput.H"
|
||||||
|
#include "SVGTools.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
namespace functionObjects
|
||||||
|
{
|
||||||
|
defineTypeNameAndDebug(graphFunctionObject, 0);
|
||||||
|
addToRunTimeSelectionTable
|
||||||
|
(
|
||||||
|
functionObject,
|
||||||
|
graphFunctionObject,
|
||||||
|
dictionary
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 'Muted' colour scheme from https://personal.sron.nl/~pault/ (12.07.24)
|
||||||
|
Foam::wordList Foam::functionObjects::graphFunctionObject::defaultColours
|
||||||
|
({
|
||||||
|
"#CC6677",
|
||||||
|
"#332288",
|
||||||
|
"#DDCC77",
|
||||||
|
"#117733",
|
||||||
|
"#88CCEE",
|
||||||
|
"#882255",
|
||||||
|
"#44AA99",
|
||||||
|
"#999933",
|
||||||
|
"#AA4499"
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
|
||||||
|
|
||||||
|
template<class Type>
|
||||||
|
bool Foam::functionObjects::graphFunctionObject::getValue
|
||||||
|
(
|
||||||
|
const label objecti,
|
||||||
|
label& valuei
|
||||||
|
)
|
||||||
|
{
|
||||||
|
const word& object = objects_[objecti];
|
||||||
|
const word& entry = entries_[objecti];
|
||||||
|
|
||||||
|
Type result;
|
||||||
|
if (!this->getObjectResult(object, entry, result))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& cols = objectToCol_[objecti];
|
||||||
|
if (cols.empty())
|
||||||
|
{
|
||||||
|
for (direction d = 0; d < pTraits<Type>::nComponents; ++d)
|
||||||
|
{
|
||||||
|
cols.push_back(valuei++);
|
||||||
|
values_.push_back(DynamicList<scalar>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (direction d = 0; d < pTraits<Type>::nComponents; ++d)
|
||||||
|
{
|
||||||
|
scalar v = component(result, d);
|
||||||
|
|
||||||
|
if (logScaleY_)
|
||||||
|
{
|
||||||
|
v = (v < SMALL) ? 1 : log10(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
values_[cols[d]].push_back(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Foam::label Foam::functionObjects::graphFunctionObject::setAxisProps
|
||||||
|
(
|
||||||
|
const bool logScale,
|
||||||
|
scalar& xmin,
|
||||||
|
scalar& xmax,
|
||||||
|
scalar& xtick
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
DebugInfo
|
||||||
|
<< "1 -- xmin:" << xmin << " xmax:" << xmax
|
||||||
|
<< " xtick:" << xtick << endl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Divisions Based on (12.07.24):
|
||||||
|
https://peltiertech.com/calculate-nice-axis-scales-in-your-excel-worksheet
|
||||||
|
*/
|
||||||
|
|
||||||
|
const scalar range = xmax - xmin;
|
||||||
|
const scalar eps = 0.01*range;
|
||||||
|
|
||||||
|
// Extend xmin and xmax by eps
|
||||||
|
if (mag(xmin) < SMALL)
|
||||||
|
{
|
||||||
|
xmin = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xmin = (xmin > 0) ? max(0, xmin - eps) : xmin - eps;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mag(xmax) < SMALL)
|
||||||
|
{
|
||||||
|
xmax = mag(xmin) < SMALL ? 1 : 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
xmax = (xmax < 0) ? min(0, xmax + eps) : xmax + eps;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugInfo
|
||||||
|
<< "2 -- xmin:" << xmin << " xmax:" << xmax
|
||||||
|
<< " xtick:" << xtick << endl;
|
||||||
|
|
||||||
|
auto lookup = [](const scalar x) -> scalar
|
||||||
|
{
|
||||||
|
if (x < 2.5) { return 0.2; }
|
||||||
|
if (x < 5.0) { return 0.5; }
|
||||||
|
if (x < 10.0) { return 2.0; }
|
||||||
|
return 10.0;
|
||||||
|
};
|
||||||
|
|
||||||
|
const scalar power = log10(range);
|
||||||
|
const scalar factor = pow(10, power - floor(power));
|
||||||
|
|
||||||
|
xtick = lookup(factor)*pow(10, floor(power));
|
||||||
|
xmin = xtick*floor(xmin/xtick);
|
||||||
|
xmax = xtick*(floor(xmax/xtick) + 1);
|
||||||
|
|
||||||
|
// Convert ticks to integer powers of 10 for log scales
|
||||||
|
if (logScale)
|
||||||
|
{
|
||||||
|
xmin = floor(xmin);
|
||||||
|
xmax = ceil(xmax);
|
||||||
|
xtick = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugInfo
|
||||||
|
<< "power:" << power << " factor:" << factor
|
||||||
|
<< " xmin:" << xmin << " xmax:" << xmax
|
||||||
|
<< " xtick:" << xtick << endl;
|
||||||
|
|
||||||
|
return round((xmax - xmin)/xtick);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
Foam::functionObjects::graphFunctionObject::graphFunctionObject
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const Time& runTime,
|
||||||
|
const dictionary& dict
|
||||||
|
)
|
||||||
|
:
|
||||||
|
stateFunctionObject(name, runTime),
|
||||||
|
writeFile(runTime, name, typeName, dict, true, ".svg"),
|
||||||
|
objects_(),
|
||||||
|
entries_(),
|
||||||
|
titles_(),
|
||||||
|
colours_(),
|
||||||
|
dashes_(),
|
||||||
|
times_(),
|
||||||
|
values_(),
|
||||||
|
objectToCol_(),
|
||||||
|
xMin_(dict.getOrDefault<scalar>("xMin", GREAT)),
|
||||||
|
xMax_(dict.getOrDefault<scalar>("xMax", GREAT)),
|
||||||
|
yMin_(dict.getOrDefault<scalar>("yMin", GREAT)),
|
||||||
|
yMax_(dict.getOrDefault<scalar>("yMax", GREAT)),
|
||||||
|
xlabel_(dict.getOrDefault<string>("xlabel", "Iteration/Time")),
|
||||||
|
ylabel_(dict.getOrDefault<string>("ylabel", "Property")),
|
||||||
|
width_(dict.getOrDefault<label>("width", 800)),
|
||||||
|
height_(dict.getOrDefault<label>("height", 600)),
|
||||||
|
strokeWidth_(dict.getOrDefault<label>("strokeWidth", 2)),
|
||||||
|
logScaleX_(dict.getOrDefault<bool>("logScaleX", false)),
|
||||||
|
logScaleY_(dict.getOrDefault<bool>("logScaleY", false)),
|
||||||
|
drawGrid_(dict.getOrDefault<bool>("drawGrid", true))
|
||||||
|
{
|
||||||
|
const dictionary& functions = dict.subDict("functions");
|
||||||
|
objects_.setSize(functions.size());
|
||||||
|
entries_.setSize(functions.size());
|
||||||
|
titles_.setSize(functions.size());
|
||||||
|
colours_.setSize(functions.size());
|
||||||
|
dashes_.setSize(functions.size());
|
||||||
|
objectToCol_.setSize(functions.size());
|
||||||
|
|
||||||
|
label defaultColouri = 0;
|
||||||
|
label entryi = 0;
|
||||||
|
|
||||||
|
for (const auto& e : functions)
|
||||||
|
{
|
||||||
|
if (!e.isDict())
|
||||||
|
{
|
||||||
|
FatalIOErrorInFunction(functions)
|
||||||
|
<< "Functions must be provided in dictionary format"
|
||||||
|
<< exit(FatalIOError);
|
||||||
|
}
|
||||||
|
|
||||||
|
const dictionary& d = e.dict();
|
||||||
|
objects_[entryi] = d.get<word>("object");
|
||||||
|
entries_[entryi] = d.get<word>("entry");
|
||||||
|
titles_[entryi] = d.getOrDefault<string>("title", e.keyword());
|
||||||
|
|
||||||
|
labelVector colour;
|
||||||
|
if (d.readIfPresent("colour", colour))
|
||||||
|
{
|
||||||
|
// Warn/error if outside 0-255 range?
|
||||||
|
colour[0] = min(255, max(0, colour[0]));
|
||||||
|
colour[1] = min(255, max(0, colour[1]));
|
||||||
|
colour[2] = min(255, max(0, colour[2]));
|
||||||
|
|
||||||
|
OStringStream oss;
|
||||||
|
oss << "rgb" << flatOutput(colour, FlatOutput::ParenComma{});
|
||||||
|
colours_[entryi] = oss.str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
colours_[entryi] = defaultColours[defaultColouri++];
|
||||||
|
if (defaultColouri == defaultColours.size())
|
||||||
|
{
|
||||||
|
// Lots of lines to plot - exhausted list of default colours.
|
||||||
|
// Restarting ...
|
||||||
|
defaultColouri = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
labelList dashes;
|
||||||
|
if (d.readIfPresent("dashes", dashes))
|
||||||
|
{
|
||||||
|
OStringStream oss;
|
||||||
|
oss << flatOutput(dashes, FlatOutput::BareSpace{});
|
||||||
|
dashes_[entryi] = oss.str();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Solid line
|
||||||
|
dashes_[entryi] = "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++entryi;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
bool Foam::functionObjects::graphFunctionObject::execute()
|
||||||
|
{
|
||||||
|
if (!Pstream::master()) return true;
|
||||||
|
|
||||||
|
scalar& graphTime = times_.emplace_back(time_.timeOutputValue());
|
||||||
|
|
||||||
|
if (logScaleX_)
|
||||||
|
{
|
||||||
|
graphTime = log10(max(graphTime, SMALL));
|
||||||
|
}
|
||||||
|
|
||||||
|
label valuei = 0;
|
||||||
|
forAll(objects_, objecti)
|
||||||
|
{
|
||||||
|
bool ok =
|
||||||
|
getValue<label>(objecti, valuei)
|
||||||
|
|| getValue<scalar>(objecti, valuei)
|
||||||
|
|| getValue<vector>(objecti, valuei)
|
||||||
|
|| getValue<sphericalTensor>(objecti, valuei)
|
||||||
|
|| getValue<symmTensor>(objecti, valuei)
|
||||||
|
|| getValue<tensor>(objecti, valuei);
|
||||||
|
|
||||||
|
if (!ok)
|
||||||
|
{
|
||||||
|
// Entry not found
|
||||||
|
Log << type() << " " << name() << " execute: "
|
||||||
|
<< "Unable to get value for object:" << objects_[objecti]
|
||||||
|
<< " entry:" << entries_[objecti] << endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Foam::functionObjects::graphFunctionObject::write()
|
||||||
|
{
|
||||||
|
if (!Pstream::master()) return true;
|
||||||
|
// DebugVar(values_);
|
||||||
|
|
||||||
|
auto filePtr = newFileAtTime(name(), time().value());
|
||||||
|
auto& os = filePtr();
|
||||||
|
|
||||||
|
scalar ymin = GREAT;
|
||||||
|
scalar ymax = -GREAT;
|
||||||
|
|
||||||
|
bool valid = false;
|
||||||
|
for (const auto& data : values_)
|
||||||
|
{
|
||||||
|
for (const auto& value : data)
|
||||||
|
{
|
||||||
|
ymin = min(ymin, value);
|
||||||
|
ymax = max(ymax, value);
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Early exit if there is no data
|
||||||
|
if (!valid)
|
||||||
|
{
|
||||||
|
Log << type() << " " << name() << " write:" << nl
|
||||||
|
<< " No data to plot - skipping" << nl;
|
||||||
|
|
||||||
|
// Empty graph
|
||||||
|
os << SVG::header(width_, height_) << nl << SVG::end << endl;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto applyLimits = [](const scalar val, const scalar lim, const bool lg)
|
||||||
|
{
|
||||||
|
if (lim < 0.99*GREAT)
|
||||||
|
{
|
||||||
|
return lg ? log10(lim) : lim;
|
||||||
|
}
|
||||||
|
|
||||||
|
return val;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Set y axis limits if user-supplied
|
||||||
|
ymin = applyLimits(ymin, yMin_, logScaleY_);
|
||||||
|
ymax = applyLimits(ymax, yMax_, logScaleY_);
|
||||||
|
|
||||||
|
|
||||||
|
scalar ytick = 0;
|
||||||
|
const label ny = setAxisProps(logScaleY_, ymin, ymax, ytick);
|
||||||
|
|
||||||
|
const scalar border = 0.1;
|
||||||
|
const scalar w = width_*(1.0 - 2*border);
|
||||||
|
const scalar h = height_*(1.0 - 2*border);
|
||||||
|
|
||||||
|
// Set x axis limits if user-supplied
|
||||||
|
scalar xmin = applyLimits(0, xMin_, logScaleX_);
|
||||||
|
scalar xmax = applyLimits(max(times_), xMax_, logScaleX_);
|
||||||
|
|
||||||
|
// Set x axis properties; return the number of tic divisions
|
||||||
|
scalar xtick = 0;
|
||||||
|
const label nx = setAxisProps(logScaleX_, xmin, xmax, xtick);
|
||||||
|
|
||||||
|
// Top pixel co-ordinate
|
||||||
|
auto top = [=](const scalar y)
|
||||||
|
{
|
||||||
|
const scalar ratio = (y - ymin)/(ymax - ymin + ROOTVSMALL);
|
||||||
|
return round(height_ - ratio*h - border*height_);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Left pixel co-ordinate
|
||||||
|
auto left = [=](const scalar x)
|
||||||
|
{
|
||||||
|
return round(x/(xmax - xmin + ROOTVSMALL)*w + border*width_);
|
||||||
|
};
|
||||||
|
|
||||||
|
const scalar fontpx = min(20, h/(2*values_.size()));
|
||||||
|
const scalar fontdy = 1.5*fontpx;
|
||||||
|
|
||||||
|
// Legend - top right: text (right aligned), coloured line (fixed positions)
|
||||||
|
const label legendLineRight = border*width_ + w - fontpx;
|
||||||
|
const label legendLineLeft = legendLineRight - 0.5*border*width_;
|
||||||
|
const label legendLabelRight = legendLineLeft - 0.5*fontpx;
|
||||||
|
|
||||||
|
// Graph box and tick colour
|
||||||
|
const word colour = "rgb(105,105,105)";
|
||||||
|
|
||||||
|
os << SVG::header(width_, height_) << nl;
|
||||||
|
|
||||||
|
// Graph bounding box
|
||||||
|
SVG::element bounds("rect", {{"fill", "none"}, {"stroke", colour}});
|
||||||
|
bounds.addAttr("x", round(border*width_));
|
||||||
|
bounds.addAttr("y", round(border*height_));
|
||||||
|
bounds.addAttr("width", round(w));
|
||||||
|
bounds.addAttr("height", round(h));
|
||||||
|
os << bounds << bounds.end << nl;
|
||||||
|
|
||||||
|
|
||||||
|
// X axis label
|
||||||
|
os << SVG::text
|
||||||
|
(
|
||||||
|
xlabel_,
|
||||||
|
0.5*width_,
|
||||||
|
height_ - 0.5*(border*height_) + fontpx,
|
||||||
|
{{"font-size", Foam::name(1.2*fontpx)}},
|
||||||
|
"middle"
|
||||||
|
)
|
||||||
|
<< nl;
|
||||||
|
|
||||||
|
// Y axis label - text rotated
|
||||||
|
SVG::text ytext
|
||||||
|
(
|
||||||
|
ylabel_,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
{{"font-size", Foam::name(1.2*fontpx)}},
|
||||||
|
"middle"
|
||||||
|
);
|
||||||
|
ytext.addAttr("alignment-baseline", "middle");
|
||||||
|
ytext.addAttrStr
|
||||||
|
(
|
||||||
|
"transform",
|
||||||
|
"translate(" + Foam::name(left(xmin) - 3*fontpx) + ","
|
||||||
|
+ Foam::name(0.5*height_) + ") rotate(270)"
|
||||||
|
);
|
||||||
|
os << ytext << nl;
|
||||||
|
|
||||||
|
const label dTick = 0.2*fontpx;
|
||||||
|
|
||||||
|
// Background grid
|
||||||
|
if (drawGrid_)
|
||||||
|
{
|
||||||
|
const word colourGrid = "rgb(200,200,200)";
|
||||||
|
|
||||||
|
for (label i = 1; i < nx; ++i)
|
||||||
|
{
|
||||||
|
const label x = left(xmin + i*xtick);
|
||||||
|
const label y1 = top(ymin);
|
||||||
|
const label y2 = top(ymax);
|
||||||
|
|
||||||
|
// Dashed grid lines
|
||||||
|
os << SVG::line
|
||||||
|
(
|
||||||
|
x,
|
||||||
|
y1,
|
||||||
|
x,
|
||||||
|
y2,
|
||||||
|
{
|
||||||
|
{"stroke", colourGrid},
|
||||||
|
{"stroke-width", "1"},
|
||||||
|
{"stroke-dasharray", "4"}
|
||||||
|
}
|
||||||
|
) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (label i = 1; i < ny; ++i)
|
||||||
|
{
|
||||||
|
const label y = top(ymin + i*ytick);
|
||||||
|
const label x1 = left(xmin);
|
||||||
|
const label x2 = left(xmax);
|
||||||
|
|
||||||
|
// Dashed grid lines
|
||||||
|
os << SVG::line
|
||||||
|
(
|
||||||
|
x1,
|
||||||
|
y,
|
||||||
|
x2,
|
||||||
|
y,
|
||||||
|
{
|
||||||
|
{"stroke", colourGrid},
|
||||||
|
{"stroke-width", "1"},
|
||||||
|
{"stroke-dasharray", "4"}
|
||||||
|
}
|
||||||
|
) << nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Axis labels
|
||||||
|
for (label i = 0; i <= nx; ++i)
|
||||||
|
{
|
||||||
|
const scalar v = xmin + i*xtick;
|
||||||
|
const label x = left(v);
|
||||||
|
const scalar y0 = ymin;
|
||||||
|
const label y1 = top(y0);
|
||||||
|
const label y2 = y1 + dTick;
|
||||||
|
const string tickLabel = logScaleX_
|
||||||
|
? "<tspan>10<tspan style=\"font-size:"
|
||||||
|
+ Foam::name(label(0.75*fontpx))
|
||||||
|
+ "px\" dy=\"" + Foam::name(-0.4*fontpx) + "\">"
|
||||||
|
+ Foam::name(v)
|
||||||
|
+ "</tspan></tspan>"
|
||||||
|
: Foam::name(v);
|
||||||
|
|
||||||
|
// Ticks
|
||||||
|
os << SVG::line
|
||||||
|
(
|
||||||
|
x,
|
||||||
|
y1,
|
||||||
|
x,
|
||||||
|
y2,
|
||||||
|
{
|
||||||
|
{"stroke", colour},
|
||||||
|
{"stroke-width", Foam::name(strokeWidth_)}
|
||||||
|
}
|
||||||
|
) << nl;
|
||||||
|
|
||||||
|
// Labels
|
||||||
|
os << SVG::text
|
||||||
|
(
|
||||||
|
tickLabel,
|
||||||
|
x,
|
||||||
|
y2 + 1.25*fontpx,
|
||||||
|
{{"font-size", Foam::name(fontpx)}},
|
||||||
|
"middle"
|
||||||
|
) << nl;
|
||||||
|
}
|
||||||
|
for (label i = 0; i <= ny; ++i)
|
||||||
|
{
|
||||||
|
const scalar v = ymin + i*ytick;
|
||||||
|
const label y = top(v);
|
||||||
|
const label y2 = y + 0.4*fontpx;
|
||||||
|
const scalar x0 = xmin;
|
||||||
|
const label x1 = left(x0);
|
||||||
|
const label x2 = x1 - dTick;
|
||||||
|
const string tickLabel = logScaleY_
|
||||||
|
? "<tspan>10<tspan style=\"font-size:"
|
||||||
|
+ Foam::name(label(0.6*fontpx))
|
||||||
|
+ "px\" dy=\"" + Foam::name(-0.4*fontpx) + "\">"
|
||||||
|
+ Foam::name(v)
|
||||||
|
+ "</tspan></tspan>"
|
||||||
|
: Foam::name(v);
|
||||||
|
|
||||||
|
// Ticks
|
||||||
|
os << SVG::line
|
||||||
|
(
|
||||||
|
x1,
|
||||||
|
y,
|
||||||
|
x2,
|
||||||
|
y,
|
||||||
|
{{"stroke", colour},{"stroke-width", "1"}}
|
||||||
|
) << nl;
|
||||||
|
|
||||||
|
// Labels
|
||||||
|
os << SVG::text
|
||||||
|
(
|
||||||
|
tickLabel,
|
||||||
|
x2 - 0.5*fontpx,
|
||||||
|
y2,
|
||||||
|
{{"font-size", Foam::name(fontpx)}},
|
||||||
|
"end"
|
||||||
|
) << nl;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
forAll(objects_, objecti)
|
||||||
|
{
|
||||||
|
const word& colour = colours_[objecti];
|
||||||
|
|
||||||
|
const auto& cols = objectToCol_[objecti];
|
||||||
|
for (const label c : cols)
|
||||||
|
{
|
||||||
|
const word cmpt = cols.size() > 1 ? Foam::name(c) : "";
|
||||||
|
|
||||||
|
label legendTop = border*height_ + fontdy*(c+1);
|
||||||
|
os << SVG::text
|
||||||
|
(
|
||||||
|
titles_[objecti] + cmpt,
|
||||||
|
legendLabelRight,
|
||||||
|
legendTop,
|
||||||
|
{{"font-size", Foam::name(fontpx)}},
|
||||||
|
"end"
|
||||||
|
) << nl;
|
||||||
|
|
||||||
|
os << SVG::line
|
||||||
|
(
|
||||||
|
legendLineLeft,
|
||||||
|
legendTop - 0.5*fontpx,
|
||||||
|
legendLineRight,
|
||||||
|
legendTop - 0.5*fontpx,
|
||||||
|
{{"stroke", colour},{"stroke-width", "2"}},
|
||||||
|
{{"stroke-dasharray", dashes_[objecti]}}
|
||||||
|
) << nl;
|
||||||
|
|
||||||
|
|
||||||
|
os << "<path d=\"";
|
||||||
|
const auto& data = values_[c];
|
||||||
|
bool firstPoint = true;
|
||||||
|
forAll(data, i)
|
||||||
|
{
|
||||||
|
const scalar t = times_[i];
|
||||||
|
const scalar v = data[i];
|
||||||
|
|
||||||
|
if ((v > ymin) && (v < ymax))
|
||||||
|
{
|
||||||
|
if (firstPoint)
|
||||||
|
{
|
||||||
|
os << " M ";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
os << " L ";
|
||||||
|
}
|
||||||
|
|
||||||
|
os << left(t) << ' ' << top(v);
|
||||||
|
|
||||||
|
firstPoint = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
firstPoint = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os << "\""
|
||||||
|
<< " style=\"stroke:" << colour << ";"
|
||||||
|
<< " fill:none; stroke-width:2;\""
|
||||||
|
<< " stroke-dasharray=\"" << dashes_[objecti].c_str() << "\" />"
|
||||||
|
<< nl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
os << SVG::end << endl;
|
||||||
|
|
||||||
|
Log << type() << " " << name() << " write:" << nl
|
||||||
|
<< " Written file " << os.name() << nl << endl;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,300 @@
|
|||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
========= |
|
||||||
|
\ / 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::graphFunctionObject
|
||||||
|
|
||||||
|
Description
|
||||||
|
Accumulates function object result values and renders into a graph in
|
||||||
|
SVG format.
|
||||||
|
|
||||||
|
Operands:
|
||||||
|
\table
|
||||||
|
Operand | Type | Location
|
||||||
|
input | Function object results | Memory; <!--
|
||||||
|
--> $FOAM_CASE/\<time\>/uniform/functionObjects/functionObjectProperties
|
||||||
|
output file | SVG | <!--
|
||||||
|
--> $FOAM_CASE/postProcessing/<functionObject>/<time>/<functionObject>.svg
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
Usage
|
||||||
|
Minimal example by using \c system/controlDict.functions to plot the
|
||||||
|
residuals from the \c solverInfo function object:
|
||||||
|
|
||||||
|
\verbatim
|
||||||
|
residualGraph
|
||||||
|
{
|
||||||
|
// Mandatory entries
|
||||||
|
type graphFunctionObject;
|
||||||
|
libs (utilityFunctionObjects);
|
||||||
|
|
||||||
|
functions
|
||||||
|
{
|
||||||
|
entry
|
||||||
|
{
|
||||||
|
// Mandatory entries
|
||||||
|
object <word>;
|
||||||
|
entry <word>;
|
||||||
|
|
||||||
|
// Optional entries
|
||||||
|
title <string>;
|
||||||
|
colour <labelVector>;
|
||||||
|
dashes <labelList>;
|
||||||
|
}
|
||||||
|
line1
|
||||||
|
{
|
||||||
|
object solverInfo1;
|
||||||
|
entry Ux_initial;
|
||||||
|
}
|
||||||
|
line2
|
||||||
|
{
|
||||||
|
object solverInfo1;
|
||||||
|
entry p_initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional entries
|
||||||
|
xMin <scalar>;
|
||||||
|
xMax <scalar>;
|
||||||
|
yMin <scalar>;
|
||||||
|
yMax <scalar>;
|
||||||
|
xlabel <string>; // "Iteration";
|
||||||
|
ylabel <string>; // "log10(Initial residual)";
|
||||||
|
width <label>;
|
||||||
|
height <label>;
|
||||||
|
strokeWidth <label>;
|
||||||
|
logScaleX <bool>;
|
||||||
|
logScaleY <bool>;
|
||||||
|
drawGrid <bool>;
|
||||||
|
|
||||||
|
// Inherited entries
|
||||||
|
...
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
where the entries mean:
|
||||||
|
\table
|
||||||
|
Property | Description | Type | Reqd | Deflt
|
||||||
|
type | Type name: graphFunctionObject | word | yes | -
|
||||||
|
libs | Library name: utilityFunctionObjects | word | yes | -
|
||||||
|
functions | Dictionary of lines to draw | dictionary | yes | -
|
||||||
|
width | Output SVG width in pixel | label| no | 800
|
||||||
|
height | Output SVG height in pixel | label| no | 600
|
||||||
|
xMin | User defined minimum x axis limit | scalar | no | calculated
|
||||||
|
xMax | User defined maximum x axis limit | scalar | no | calculated
|
||||||
|
yMin | User defined minimum y axis limit | scalar | no | calculated
|
||||||
|
yMax | User defined maximum y axis limit | scalar | no | calculated
|
||||||
|
xLabel | X axis label | string | no | Iteration/Time
|
||||||
|
yLabel | Y axis label | string | no | Property
|
||||||
|
strokeWidth | Line stroke width in pixel | label | no | 2
|
||||||
|
logScaleX | Use log scale for x axis | bool | no | false
|
||||||
|
logScaleY | Use log scale for y axis | bool | no | false
|
||||||
|
drawGrid | Draw background grid | bool | no | true
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
The inherited entries are elaborated in:
|
||||||
|
- \link stateFunctionObject.H \endlink
|
||||||
|
- \link writeFile.H \endlink
|
||||||
|
|
||||||
|
Each line corresponds to the history of function object result values, e.g.
|
||||||
|
|
||||||
|
\verbatim
|
||||||
|
line1
|
||||||
|
{
|
||||||
|
object solverInfo1;
|
||||||
|
entry Ux_initial;
|
||||||
|
colour (255 0 0);
|
||||||
|
dashes (4 1);
|
||||||
|
title Ux;
|
||||||
|
}
|
||||||
|
\endverbatim
|
||||||
|
|
||||||
|
where the entries mean:
|
||||||
|
\table
|
||||||
|
Property | Description | Type | Reqd | Deflt
|
||||||
|
object | Function object name | word | yes | -
|
||||||
|
entry | Function object result entry name | word | yes | -
|
||||||
|
colour | Line colour | label vector | no | auto
|
||||||
|
dashes | Line dash array | label vector | no | auto
|
||||||
|
title | Title | string | no | dict name
|
||||||
|
\endtable
|
||||||
|
|
||||||
|
See also
|
||||||
|
- Foam::functionObjects::solverInfo
|
||||||
|
|
||||||
|
SourceFiles
|
||||||
|
graphFunctionObject.C
|
||||||
|
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#ifndef Foam_functionObjects_graphFunctionObject_H
|
||||||
|
#define Foam_functionObjects_graphFunctionObject_H
|
||||||
|
|
||||||
|
#include "stateFunctionObject.H"
|
||||||
|
#include "writeFile.H"
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
namespace Foam
|
||||||
|
{
|
||||||
|
|
||||||
|
namespace functionObjects
|
||||||
|
{
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*\
|
||||||
|
Class graphFunctionObject Declaration
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class graphFunctionObject
|
||||||
|
:
|
||||||
|
public stateFunctionObject,
|
||||||
|
public writeFile
|
||||||
|
{
|
||||||
|
// Private Data
|
||||||
|
|
||||||
|
//- List of default curve colours
|
||||||
|
static wordList defaultColours;
|
||||||
|
|
||||||
|
//- Names of function objects
|
||||||
|
List<word> objects_;
|
||||||
|
|
||||||
|
//- Function object entries
|
||||||
|
List<word> entries_;
|
||||||
|
|
||||||
|
//- Line titles
|
||||||
|
List<string> titles_;
|
||||||
|
|
||||||
|
//- Line colours - hex string
|
||||||
|
List<word> colours_;
|
||||||
|
|
||||||
|
//- Line dash array
|
||||||
|
List<string> dashes_;
|
||||||
|
|
||||||
|
//- Times
|
||||||
|
DynamicList<scalar> times_;
|
||||||
|
|
||||||
|
//- Time vs. flattened values
|
||||||
|
DynamicList<DynamicList<scalar>> values_;
|
||||||
|
|
||||||
|
//- Mapping from object to column index in values_
|
||||||
|
List<DynamicList<label>> objectToCol_;
|
||||||
|
|
||||||
|
//- User-supplied minimum x value
|
||||||
|
scalar xMin_;
|
||||||
|
|
||||||
|
//- User-supplied maximum x value
|
||||||
|
scalar xMax_;
|
||||||
|
|
||||||
|
//- User-supplied minimum y value
|
||||||
|
scalar yMin_;
|
||||||
|
|
||||||
|
//- User-supplied maximum y value
|
||||||
|
scalar yMax_;
|
||||||
|
|
||||||
|
//- X axis label
|
||||||
|
const string xlabel_;
|
||||||
|
|
||||||
|
//- Y axis label
|
||||||
|
const string ylabel_;
|
||||||
|
|
||||||
|
//- Width in px
|
||||||
|
const label width_;
|
||||||
|
|
||||||
|
//- Height in px
|
||||||
|
const label height_;
|
||||||
|
|
||||||
|
//- Line width in px
|
||||||
|
const label strokeWidth_;
|
||||||
|
|
||||||
|
//- Flag to use log scale on x-axis
|
||||||
|
bool logScaleX_;
|
||||||
|
|
||||||
|
//- Flag to use log scale on y-axis
|
||||||
|
bool logScaleY_;
|
||||||
|
|
||||||
|
//- Draw background grid
|
||||||
|
const bool drawGrid_;
|
||||||
|
|
||||||
|
|
||||||
|
// Private Functions
|
||||||
|
|
||||||
|
//- Get the result value from the function object
|
||||||
|
// \returns true if the value was found
|
||||||
|
template<class Type>
|
||||||
|
bool getValue(const label objecti, label& valuei);
|
||||||
|
|
||||||
|
//- Set axis min, max, tick
|
||||||
|
// \returns number of ticks
|
||||||
|
label setAxisProps
|
||||||
|
(
|
||||||
|
const bool logScale,
|
||||||
|
scalar& xmin,
|
||||||
|
scalar& xmax,
|
||||||
|
scalar& xtick
|
||||||
|
) const;
|
||||||
|
|
||||||
|
//- No copy construct
|
||||||
|
graphFunctionObject(const graphFunctionObject&) = delete;
|
||||||
|
|
||||||
|
//- No copy assignment
|
||||||
|
void operator=(const graphFunctionObject&) = delete;
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
//- Runtime type information
|
||||||
|
TypeName("graphFunctionObject");
|
||||||
|
|
||||||
|
//- Construct from Time and dictionary
|
||||||
|
graphFunctionObject
|
||||||
|
(
|
||||||
|
const word& name,
|
||||||
|
const Time& runTime,
|
||||||
|
const dictionary& dict
|
||||||
|
);
|
||||||
|
|
||||||
|
//- Destructor
|
||||||
|
virtual ~graphFunctionObject() = default;
|
||||||
|
|
||||||
|
|
||||||
|
// Member Functions
|
||||||
|
|
||||||
|
//- Execute
|
||||||
|
virtual bool execute();
|
||||||
|
|
||||||
|
//- Write
|
||||||
|
virtual bool write();
|
||||||
|
};
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
} // End namespace functionObjects
|
||||||
|
} // End namespace Foam
|
||||||
|
|
||||||
|
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -51,6 +51,10 @@ functions
|
|||||||
#include "cuttingPlane"
|
#include "cuttingPlane"
|
||||||
#include "forceCoeffs"
|
#include "forceCoeffs"
|
||||||
#include "ensightWrite"
|
#include "ensightWrite"
|
||||||
|
|
||||||
|
#include "solverInfo"
|
||||||
|
#include "graphFunctionObject"
|
||||||
|
#include "foamReport"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,59 @@
|
|||||||
|
foamReport1
|
||||||
|
{
|
||||||
|
type foamReport;
|
||||||
|
libs (utilityFunctionObjects);
|
||||||
|
|
||||||
|
writeControl writeTime;
|
||||||
|
|
||||||
|
template "<system>/myReportTemplate.md";
|
||||||
|
|
||||||
|
substitutions
|
||||||
|
{
|
||||||
|
timing1
|
||||||
|
{
|
||||||
|
type fileRegEx;
|
||||||
|
path "log.simpleFoam";
|
||||||
|
|
||||||
|
entries
|
||||||
|
{
|
||||||
|
executionTime "ExecutionTime = (.*) s Clock.*";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
divSchemes1
|
||||||
|
{
|
||||||
|
type dictionaryValue;
|
||||||
|
path "<system>/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";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@ -0,0 +1,142 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v2406 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
residualGraph1
|
||||||
|
{
|
||||||
|
// Mandatory entries
|
||||||
|
type graphFunctionObject;
|
||||||
|
libs (utilityFunctionObjects);
|
||||||
|
|
||||||
|
functions
|
||||||
|
{
|
||||||
|
Ux
|
||||||
|
{
|
||||||
|
// Mandatory entries
|
||||||
|
object solverInfo1;
|
||||||
|
entry Ux_initial;
|
||||||
|
|
||||||
|
// Optional entries
|
||||||
|
// title <string>;
|
||||||
|
// colour <labelVector>;
|
||||||
|
// dashes <labelList>;
|
||||||
|
}
|
||||||
|
Uy
|
||||||
|
{
|
||||||
|
object solverInfo1;
|
||||||
|
entry Uy_initial;
|
||||||
|
}
|
||||||
|
Uz
|
||||||
|
{
|
||||||
|
object solverInfo1;
|
||||||
|
entry Uz_initial;
|
||||||
|
}
|
||||||
|
p
|
||||||
|
{
|
||||||
|
object solverInfo1;
|
||||||
|
entry p_initial;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Optional entries
|
||||||
|
logScaleX no;
|
||||||
|
logScaleY yes;
|
||||||
|
xlabel "Iteration";
|
||||||
|
ylabel "log10(Initial residual)";
|
||||||
|
// xMin <scalar>;
|
||||||
|
// xMax <scalar>;
|
||||||
|
// yMin <scalar>;
|
||||||
|
// yMax <scalar>;
|
||||||
|
// width <label>;
|
||||||
|
// height <label>;
|
||||||
|
// strokeWidth <label>;
|
||||||
|
// drawGrid <bool>;
|
||||||
|
|
||||||
|
// Inherited entries
|
||||||
|
writePrecision 6;
|
||||||
|
writeToFile true;
|
||||||
|
useUserTime true;
|
||||||
|
|
||||||
|
region region0;
|
||||||
|
enabled true;
|
||||||
|
log true;
|
||||||
|
timeStart 0;
|
||||||
|
timeEnd 1000;
|
||||||
|
executeControl timeStep;
|
||||||
|
executeInterval 1;
|
||||||
|
writeControl writeTime;
|
||||||
|
writeInterval -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
forceCoeffsGraph1
|
||||||
|
{
|
||||||
|
type graphFunctionObject;
|
||||||
|
libs (utilityFunctionObjects);
|
||||||
|
writeControl writeTime;
|
||||||
|
|
||||||
|
logScaleX no;
|
||||||
|
logScaleY no;
|
||||||
|
|
||||||
|
xlabel "Iteration";
|
||||||
|
ylabel "Coefficient";
|
||||||
|
|
||||||
|
yMin -1;
|
||||||
|
yMax 1;
|
||||||
|
|
||||||
|
functions
|
||||||
|
{
|
||||||
|
Cd
|
||||||
|
{
|
||||||
|
object forceCoeffs1;
|
||||||
|
entry Cd;
|
||||||
|
}
|
||||||
|
// CdMean
|
||||||
|
// {
|
||||||
|
// object valueAverage1;
|
||||||
|
// entry CdMean;
|
||||||
|
// }
|
||||||
|
Cd(f)
|
||||||
|
{
|
||||||
|
object forceCoeffs1;
|
||||||
|
entry Cd(f);
|
||||||
|
}
|
||||||
|
Cd(r)
|
||||||
|
{
|
||||||
|
object forceCoeffs1;
|
||||||
|
entry Cd(r);
|
||||||
|
}
|
||||||
|
Cl
|
||||||
|
{
|
||||||
|
object forceCoeffs1;
|
||||||
|
entry Cl;
|
||||||
|
//colour (0, 0, 0);
|
||||||
|
}
|
||||||
|
// ClMean
|
||||||
|
// {
|
||||||
|
// object valueAverage1;
|
||||||
|
// entry ClMean;
|
||||||
|
// }
|
||||||
|
Cl(f)
|
||||||
|
{
|
||||||
|
object forceCoeffs1;
|
||||||
|
entry Cl(f);
|
||||||
|
//colour (0, 0, 0);
|
||||||
|
title Cl(f);
|
||||||
|
}
|
||||||
|
Cl(r)
|
||||||
|
{
|
||||||
|
object forceCoeffs1;
|
||||||
|
entry Cl(r);
|
||||||
|
//colour (0, 0, 0);
|
||||||
|
title Cl(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
@ -0,0 +1,104 @@
|
|||||||
|
---
|
||||||
|
marp: true
|
||||||
|
paginate: true
|
||||||
|
---
|
||||||
|
|
||||||
|
<style>
|
||||||
|
:root {
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
td {
|
||||||
|
width: 1000px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
img {
|
||||||
|
display: block;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
# {{OF_EXECUTABLE}} : {{OF_CASE_NAME}} tutorial
|
||||||
|
|
||||||
|
- Case: {{OF_CASE_PATH}}
|
||||||
|
- Submission: {{OF_CLOCK_START}} on {{OF_DATE_START}}
|
||||||
|
- Report time: {{OF_CLOCK_NOW}} on {{OF_DATE_NOW}}
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Run information
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------------|--------------------|
|
||||||
|
| Host | {{OF_HOST}} |
|
||||||
|
| Processors | {{OF_NPROCS}} |
|
||||||
|
| Time steps | {{OF_TIME_INDEX}} |
|
||||||
|
| Initial deltaT | {{initial_deltaT}} |
|
||||||
|
| Current deltaT | {{OF_TIME_DELTAT}} |
|
||||||
|
| Execution time | {{executionTime}} |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## OpenFOAM information
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|----------------|--------------------|
|
||||||
|
| Version | {{OF_VERSION}} |
|
||||||
|
| API | {{OF_API}} |
|
||||||
|
| Patch | {{OF_PATCH}} |
|
||||||
|
| Build | {{OF_BUILD}} |
|
||||||
|
| Architecture | {{OF_BUILD_ARCH}} |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Mesh statistics
|
||||||
|
|
||||||
|
| Property | Value |
|
||||||
|
|-------------------|----------------------|
|
||||||
|
| Bounds | {{OF_MESH_BOUNDS_MIN}}{{OF_MESH_BOUNDS_MAX}} |
|
||||||
|
| Number of cells | {{OF_MESH_NCELLS}} |
|
||||||
|
| Number of faces | {{OF_MESH_NFACES}} |
|
||||||
|
| Number of points | {{OF_MESH_NPOINTS}} |
|
||||||
|
| Number of patches | {{OF_MESH_NPATCHES}} |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Linear solvers
|
||||||
|
|
||||||
|
| Property | Value | tolerance(rel) | Tolerance(abs) |
|
||||||
|
|----------|----------------|------------------|---------------------|
|
||||||
|
| p | `{{solver_p}}` | {{solver_p_tol}} | {{solver_p_reltol}} |
|
||||||
|
| U | `{{solver_U}}` | {{solver_u_tol}} | {{solver_u_reltol}} |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Numerical scehemes
|
||||||
|
|
||||||
|
The chosen divergence schemes comprised:
|
||||||
|
|
||||||
|
~~~
|
||||||
|
{{divSchemes}}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Graphs
|
||||||
|
|
||||||
|
Residuals
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Results
|
||||||
|
|
||||||
|
Forces
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Made using Open∇FOAM v2412 from https://openfoam.com
|
||||||
@ -0,0 +1,21 @@
|
|||||||
|
/*--------------------------------*- C++ -*----------------------------------*\
|
||||||
|
| ========= | |
|
||||||
|
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
|
||||||
|
| \\ / O peration | Version: v2406 |
|
||||||
|
| \\ / A nd | Website: www.openfoam.com |
|
||||||
|
| \\/ M anipulation | |
|
||||||
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
solverInfo1
|
||||||
|
{
|
||||||
|
// Mandatory entries
|
||||||
|
type solverInfo;
|
||||||
|
libs (utilityFunctionObjects);
|
||||||
|
fields (U p);
|
||||||
|
|
||||||
|
// Optional entries
|
||||||
|
writeResidualFields no;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ************************************************************************* //
|
||||||
Reference in New Issue
Block a user