diff --git a/applications/utilities/preProcessing/setExprBoundaryFields/Make/files b/applications/utilities/preProcessing/setExprBoundaryFields/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..c20222837bd1d4fb54a82ed4f4af6e6d5b3bd61e --- /dev/null +++ b/applications/utilities/preProcessing/setExprBoundaryFields/Make/files @@ -0,0 +1,3 @@ +setExprBoundaryFields.C + +EXE = $(FOAM_APPBIN)/setExprBoundaryFields diff --git a/applications/utilities/preProcessing/setExprBoundaryFields/Make/options b/applications/utilities/preProcessing/setExprBoundaryFields/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..969020c4afaf5d784299462b9e1af282040ba6b4 --- /dev/null +++ b/applications/utilities/preProcessing/setExprBoundaryFields/Make/options @@ -0,0 +1,8 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools \ + -lgenericPatchFields diff --git a/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C b/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C new file mode 100644 index 0000000000000000000000000000000000000000..179361cdc36a2b2b726ac778778bc47011b34b6d --- /dev/null +++ b/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFields.C @@ -0,0 +1,262 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 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 . + +Application + setExprFields + +Group + grpPreProcessingUtilities + +Description + Set boundary values using an expression + +Note + Based on funkySetBoundaryFields + Copyright 2006-2018 Bernhard Gschaider + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "Time.H" +#include "fvMesh.H" +#include "pointMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "surfaceFields.H" +#include "pointFields.H" +#include "patchExprDriver.H" +#include "timeSelector.H" + +using namespace Foam; + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // +// Main program: + +int main(int argc, char *argv[]) +{ + argList::noFunctionObjects(true); + + // No -constant, no special treatment for 0/ + timeSelector::addOptions(false); + + argList::addOption + ( + "dict", + "file", + "Alternative dictionary for setExprBoundaryFieldsDict" + ); + + argList::addBoolOption + ( + "cache-fields", + "Cache fields between calls", + true // Advanced + ); + argList::addBoolOption + ( + "backup", + "Preserve sub-entry as .backup", + true // Advanced + ); + + argList::addBoolOption + ( + "dry-run", + "Evaluate but do not write" + ); + + #include "addRegionOption.H" + #include "setRootCase.H" + + const bool dryrun = args.found("dry-run"); + const bool backup = args.found("backup"); + const bool cacheFields = args.found("cache-fields"); + + if (cacheFields) + { + Warning + << "The current cache-fields behaviour (caching disk reads) " + << "may lead to unexpected behaviour as previous modifications " + << "will not be visible." + << endl; + } + + const word dictName("setExprBoundaryFieldsDict"); + + #include "createTime.H" + + instantList times = timeSelector::select0(runTime, args); + + if (times.size() < 1) + { + FatalErrorInFunction + << "No times selected." << exit(FatalError); + } + + #include "createNamedMesh.H" + + #include "setSystemMeshDictionaryIO.H" + IOdictionary setExprDict(dictIO); + + forAll(times, timei) + { + runTime.setTime(times[timei], timei); + + Info<< "\nTime = " << runTime.timeName() << endl; + + mesh.readUpdate(); + + for (const entry& dEntry : setExprDict) + { + if (!dEntry.isDict()) + { + Info<< "Ignoring non-dictionary entry " + << dEntry.keyword() << nl; + continue; + } + + const dictionary& dict = dEntry.dict(); + + const word fieldName(dict.get("field")); + + List exprDicts; + dict.readEntry("expressions", exprDicts); + + if (exprDicts.empty()) + { + Info<< "No expressions for " << fieldName << nl; + continue; + } + + + // Read dictionary + // Note: disable class type checking so we can load field + const word oldTypeName = IOdictionary::typeName; + const_cast(IOdictionary::typeName) = word::null; + + IOobject fieldHeader + ( + fieldName, + mesh.thisDb().time().timeName(), + mesh.thisDb(), + IOobject::MUST_READ_IF_MODIFIED, + IOobject::NO_WRITE, + false + ); + + const bool headOk = fieldHeader.typeHeaderOk(false); + + if (!headOk) + { + // Restore type + const_cast(IOdictionary::typeName) = oldTypeName; + + WarningInFunction + << "Requested field to change " << fieldName + << " does not exist in " << fieldHeader.path() << endl; + continue; + } + + IOdictionary fieldDict(fieldHeader); + + // Restore type + const_cast(IOdictionary::typeName) = oldTypeName; + + // Fake type back to what was in field + const_cast(fieldDict.type()) = fieldDict.headerClassName(); + + Info<< "Processing field " << fieldName << nl; + + dictionary& boundaryFieldDict = fieldDict.subDict("boundaryField"); + + for (const dictionary& currDict : exprDicts) + { + const word targetName = currDict.get("target"); + const word patchName = currDict.get("patch"); + + dictionary& patchDict = boundaryFieldDict.subDict(patchName); + + expressions::exprString expr + ( + currDict.get("expression"), + currDict, + true // strip comments + ); + + Info<< "Set boundaryField/" << patchName << '/' + << targetName << nl + << "with expression" << nl + << "<<<<" << nl + << expr.c_str() << nl + << ">>>>" << nl; + + expressions::patchExprDriver driver(currDict, mesh); + + // Search on disc + driver.setSearchBehaviour(cacheFields, false, true); + + driver.clearVariables(); + driver.parse(expr); + + // Serializing via Field::writeEntry etc + OStringStream serialize; + driver.result().writeEntry("", serialize); + + if (backup && !dryrun) + { + patchDict.changeKeyword + ( + targetName, + word(targetName + ".backup"), + true // Overwrite + ); + } + + patchDict.set(targetName, serialize.str().c_str()); + + if (dryrun) + { + Info<< "Evaluated:" << nl + << "<<<<" << nl + << serialize.str().c_str() // (already includes nl) + << ">>>>" << nl; + } + } + + if (!dryrun) + { + Info<< "Write " << fieldDict.filePath() << nl; + fieldDict.regIOobject::write(); + } + } + } + + Info<< "\nEnd\n" << endl; + + return 0; +} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFieldsDict b/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFieldsDict new file mode 100644 index 0000000000000000000000000000000000000000..53724eb90e7baf9a543693485b41561050986dd1 --- /dev/null +++ b/applications/utilities/preProcessing/setExprBoundaryFields/setExprBoundaryFieldsDict @@ -0,0 +1,34 @@ +/*--------------------------------*- C++ -*----------------------------------*\ +| ========= | | +| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | +| \\ / O peration | Version: v1912 | +| \\ / A nd | Website: www.openfoam.com | +| \\/ M anipulation | | +\*---------------------------------------------------------------------------*/ +FoamFile +{ + version 2.0; + format ascii; + class dictionary; + object setExprBoundaryFieldsDict; +} +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +pattern +{ + field T; + + expressions + ( + { + patch bottom; + target theta0; + expression #{ (pos().x() < 1e-4 ? 60 : 120) #}; + } + ); + + keepPatches true; +} + + +// ************************************************************************* // diff --git a/applications/utilities/preProcessing/setExprFields/Make/files b/applications/utilities/preProcessing/setExprFields/Make/files new file mode 100644 index 0000000000000000000000000000000000000000..3212112fdc50ac8119e431b38483d06a64182064 --- /dev/null +++ b/applications/utilities/preProcessing/setExprFields/Make/files @@ -0,0 +1,3 @@ +setExprFields.C + +EXE = $(FOAM_APPBIN)/setExprFields diff --git a/applications/utilities/preProcessing/setExprFields/Make/options b/applications/utilities/preProcessing/setExprFields/Make/options new file mode 100644 index 0000000000000000000000000000000000000000..969020c4afaf5d784299462b9e1af282040ba6b4 --- /dev/null +++ b/applications/utilities/preProcessing/setExprFields/Make/options @@ -0,0 +1,8 @@ +EXE_INC = \ + -I$(LIB_SRC)/finiteVolume/lnInclude \ + -I$(LIB_SRC)/meshTools/lnInclude + +EXE_LIBS = \ + -lfiniteVolume \ + -lmeshTools \ + -lgenericPatchFields diff --git a/applications/utilities/preProcessing/setExprFields/setExprFields.C b/applications/utilities/preProcessing/setExprFields/setExprFields.C new file mode 100644 index 0000000000000000000000000000000000000000..21a609124c86503fcd00029462a02d1e27497e7e --- /dev/null +++ b/applications/utilities/preProcessing/setExprFields/setExprFields.C @@ -0,0 +1,915 @@ +/*---------------------------------------------------------------------------*\ + ========= | + \\ / F ield | OpenFOAM: The Open Source CFD Toolbox + \\ / O peration | + \\ / A nd | www.openfoam.com + \\/ M anipulation | +------------------------------------------------------------------------------- + Copyright (C) 2019 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 . + +Application + setExprFields + +Group + grpPreProcessingUtilities + +Description + Set values on a selected set of cells/patch-faces via a dictionary. + +Note + Based on funkySetFields + Copyright 2006-2018 Bernhard Gschaider + +\*---------------------------------------------------------------------------*/ + +#include "argList.H" +#include "Time.H" +#include "fvMesh.H" +#include "pointMesh.H" +#include "volFields.H" +#include "surfaceFields.H" +#include "surfaceFields.H" +#include "pointFields.H" +#include "exprOps.H" +#include "volumeExprDriver.H" +#include "timeSelector.H" +#include "dlLibraryTable.H" + + +using namespace Foam; + +using FieldAssociation = expressions::volumeExpr::FieldAssociation; + +word fieldGeoType(const FieldAssociation geoType) +{ + switch (geoType) + { + case FieldAssociation::VOLUME_DATA : return "cells"; break; + case FieldAssociation::SURFACE_DATA : return "faces"; break; + case FieldAssociation::POINT_DATA : return "points"; break; + default: break; + } + + return "unknown"; +} + + +//- Simple control structure to with collected switches to simplify passing +struct setExprFieldsControl +{ + bool dryRun; + bool debugParsing; + bool cacheVariables; + bool useDimension; + bool createNew; + bool keepPatches; + bool correctPatches; + bool correctBCs; +}; + + +template +void doCorrectBoundaryConditions +( + bool correctBCs, + GeometricField& field +) +{ + if (correctBCs) + { + Info<< "Correcting boundary conditions: " << field.name() << nl; + field.correctBoundaryConditions(); + } +} + + +template +void doCorrectBoundaryConditions +( + bool correctBCs, + GeometricField& field +) +{ + if (correctBCs) + { + Info<< "Correcting boundary conditions: " << field.name() << nl; + field.correctBoundaryConditions(); + } +} + + +template +void doCorrectBoundaryConditions +( + bool correctBCs, + GeometricField& field +) +{} + + +template +void setField +( + const word& fieldName, + const Mesh& mesh, + const GeoField& result, + const scalarField& cond, + const dimensionSet& dims, + const wordList& valuePatches, + + const setExprFieldsControl& ctrl +) +{ + Info<< "setField(" << fieldName << "): " + << pTraits::typeName << endl; + + tmp toutput; + + if (ctrl.createNew) + { + // Create with zero + toutput = GeoField::New + ( + fieldName, + mesh, + dimensioned(dims) + ); + } + else + { + // Read + toutput = tmp::New + ( + IOobject + ( + fieldName, + mesh.thisDb().time().timeName(), + mesh.thisDb(), + IOobject::MUST_READ, + IOobject::NO_WRITE, + false // No register + ), + mesh + ); + } + + auto& output = toutput.ref(); + + label setCells = 0; + + if (cond.empty()) + { + // No condition + output = result; + + setCells = output.size(); + } + else + { + forAll(output, celli) + { + if (expressions::boolOp()(cond[celli])) + { + output[celli] = result[celli]; + ++setCells; + } + } + } + + const label totalCells = returnReduce(output.size(), plusOp