setExprBoundaryFields.C
Go to the documentation of this file.
1/*---------------------------------------------------------------------------*\
2 ========= |
3 \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
4 \\ / O peration |
5 \\ / A nd | www.openfoam.com
6 \\/ M anipulation |
7-------------------------------------------------------------------------------
8 Copyright (C) 2019-2021 OpenCFD Ltd.
9-------------------------------------------------------------------------------
10License
11 This file is part of OpenFOAM.
12
13 OpenFOAM is free software: you can redistribute it and/or modify it
14 under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17
18 OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
19 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
21 for more details.
22
23 You should have received a copy of the GNU General Public License
24 along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
25
26Application
27 setExprBoundaryFields
28
29Group
30 grpPreProcessingUtilities
31
32Description
33 Set boundary values using an expression
34
35Note
36 Based on funkySetBoundaryFields from
37 Bernhard Gschaider <bgschaid@hfd-research.com>
38
39\*---------------------------------------------------------------------------*/
40
41#include "argList.H"
42#include "Time.H"
43#include "fvMesh.H"
44#include "pointMesh.H"
45#include "volFields.H"
46#include "surfaceFields.H"
47#include "pointFields.H"
48#include "patchExprDriver.H"
49#include "timeSelector.H"
50#include "readFields.H"
51
52using namespace Foam;
53
54// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
55// Main program:
56
57int main(int argc, char *argv[])
58{
59 argList::noFunctionObjects(true);
60
61 // No -constant, no special treatment for 0/
62 timeSelector::addOptions(false);
63
64 argList::addBoolOption
65 (
66 "ascii",
67 "Write in ASCII format instead of the controlDict setting"
68 );
69 argList::addOption
70 (
71 "dict",
72 "file",
73 "Alternative dictionary for setExprBoundaryFieldsDict"
74 );
75 argList::addBoolOption
76 (
77 "cache-fields",
78 "Cache fields between calls",
79 true // Advanced
80 );
81 argList::addOption
82 (
83 "load-fields",
84 "wordList",
85 "Specify field or fields to preload. Eg, 'T' or '(p T U)'",
86 true // Advanced
87 );
88 argList::addBoolOption
89 (
90 "backup",
91 "Preserve sub-entry as .backup",
92 true // Advanced
93 );
94 argList::addDryRunOption
95 (
96 "Evaluate but do not write"
97 );
98
99 #include "addRegionOption.H"
100 #include "setRootCase.H"
101
102 const bool dryrun = args.dryRun();
103 const bool backup = args.found("backup");
104 const bool cacheFields = args.found("cache-fields");
105
106 if (cacheFields)
107 {
108 Warning
109 << "The current cache-fields behaviour (caching disk reads) "
110 << "may lead to unexpected behaviour as previous modifications "
111 << "will not be visible."
112 << endl;
113 }
114
115 const word dictName("setExprBoundaryFieldsDict");
116
117 #include "createTime.H"
118
119 instantList times = timeSelector::select0(runTime, args);
120
121 if (times.empty())
122 {
124 << "No times selected." << nl
125 << exit(FatalError);
126 }
127
128 #include "createNamedMesh.H"
129
131 IOdictionary setExprDict(dictIO);
132
133 IOstreamOption streamOpt(runTime.writeFormat());
134 if (args.found("ascii"))
135 {
136 streamOpt.format(IOstream::ASCII);
137 }
138
139 forAll(times, timei)
140 {
141 runTime.setTime(times[timei], timei);
142
143 Info<< "\nTime = " << runTime.timeName() << endl;
144
145 mesh.readUpdate();
146
147 // preload fields specified on command-line
148 if (timei == 0)
149 {
150 wordList preloadFields;
151 args.readListIfPresent("load-fields", preloadFields);
152 readFieldsHandler(mesh).execute(preloadFields);
153 }
154 // preload fields specified in dictionary
155 {
156 wordList preloadFields;
157 setExprDict.readIfPresent("readFields", preloadFields);
158 readFieldsHandler(mesh).execute(preloadFields);
159 }
160
161 for (const entry& dEntry : setExprDict)
162 {
163 if (!dEntry.isDict())
164 {
165 if (dEntry.keyword() != "readFields")
166 {
167 Info<< "Ignoring non-dictionary entry "
168 << dEntry.keyword() << nl;
169 }
170 continue;
171 }
172
173 const dictionary& dict = dEntry.dict();
174
175 const word fieldName(dict.get<word>("field"));
176
177 List<dictionary> exprDicts;
178 dict.readEntry("expressions", exprDicts);
179
180 if (exprDicts.empty())
181 {
182 Info<< "No expressions for " << fieldName << nl;
183 continue;
184 }
185
186
187 // Read dictionary
188 // Note: disable class type checking so we can load field
189 const word oldTypeName = IOdictionary::typeName;
190 const_cast<word&>(IOdictionary::typeName) = word::null;
191
192 IOobject fieldHeader
193 (
194 fieldName,
195 mesh.thisDb().time().timeName(),
196 mesh.thisDb(),
197 IOobject::MUST_READ_IF_MODIFIED,
198 IOobject::NO_WRITE,
199 false
200 );
201
202 const bool headOk = fieldHeader.typeHeaderOk<IOdictionary>(false);
203
204 if (!headOk)
205 {
206 // Restore type
207 const_cast<word&>(IOdictionary::typeName) = oldTypeName;
208
210 << "Requested field to change " << fieldName
211 << " does not exist in " << fieldHeader.path() << endl;
212 continue;
213 }
214
215 IOdictionary fieldDict(fieldHeader);
216
217 // Restore type
218 const_cast<word&>(IOdictionary::typeName) = oldTypeName;
219
220 // Fake type back to what was in field
221 const_cast<word&>(fieldDict.type()) = fieldDict.headerClassName();
222
223 Info<< "Processing field " << fieldName << nl;
224
225 dictionary& boundaryFieldDict = fieldDict.subDict("boundaryField");
226
227 for (const dictionary& currDict : exprDicts)
228 {
229 const word patchName(currDict.get<word>("patch"));
230 const word targetName(currDict.get<word>("target"));
231
232 dictionary& patchDict = boundaryFieldDict.subDict(patchName);
233
234 auto valueExpr_
235 (
236 expressions::exprString::getEntry
237 (
238 "expression",
239 currDict,
240 true // strip comments
241 )
242 );
243
244 Info<< "Set boundaryField/" << patchName << '/'
245 << targetName << nl
246 << "with expression" << nl
247 << "<<<<" << nl
248 << valueExpr_.c_str() << nl
249 << ">>>>" << nl;
250
251 expressions::patchExprDriver driver(currDict, mesh);
252
253 // Search files only
254 driver.setSearchBehaviour
255 (
256 expressions::exprDriver::SEARCH_FILES,
257 cacheFields
258 );
259
260 driver.clearVariables();
261 driver.parse(valueExpr_);
262
263 // Serializing via Field::writeEntry etc
264 OStringStream serialize;
265 driver.result().writeEntry("", serialize);
266
267 if (backup && !dryrun)
268 {
269 patchDict.changeKeyword
270 (
271 targetName,
272 word(targetName + ".backup"),
273 true // Overwrite
274 );
275 }
276
277 patchDict.set(targetName, serialize.str().c_str());
278
279 if (dryrun)
280 {
281 Info<< "Evaluated:" << nl
282 << "<<<<" << nl
283 << serialize.str().c_str() // (already includes nl)
284 << ">>>>" << nl;
285 }
286 }
287
288 if (!dryrun)
289 {
290 Info<< "Write " << fieldDict.filePath() << nl;
291 fieldDict.regIOobject::writeObject(streamOpt, true);
292 }
293 }
294 }
295
296 Info<< "\nEnd\n" << endl;
297
298 return 0;
299}
300
301
302// ************************************************************************* //
Foam::string str() const
Get the string - as Foam::string rather than std::string.
Definition: StringStream.H:88
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:57
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:170
The IOstreamOption is a simple container for options an IOstream can normally have.
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:231
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:239
bool empty() const noexcept
True if the UList is empty (ie, size() is zero)
Definition: UListI.H:427
int dryRun() const noexcept
Return the dry-run flag.
Definition: argListI.H:116
bool readListIfPresent(const word &optName, List< T > &list) const
Definition: argListI.H:394
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:178
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:126
bool changeKeyword(const keyType &oldKeyword, const keyType &newKeyword, bool overwrite=false)
Change the keyword for an entry,.
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:780
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:70
A simple field-loader, as per the readFields function object.
Definition: readFields.H:51
bool execute(const UList< word > &fieldNames)
Definition: readFields.H:175
A class for handling words, derived from Foam::string.
Definition: word.H:68
dynamicFvMesh & mesh
engineTime & runTime
Required Variables.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
const word dictName("faMeshDefinition")
#define WarningInFunction
Report a warning using Foam::Warning.
Namespace for OpenFOAM.
messageStream Info
Information stream (stdout output on master, null elsewhere)
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:372
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
messageStream Warning
constexpr char nl
The newline '\n' character (0x0a)
Definition: Ostream.H:53
dictionary dict
IOobject dictIO
Foam::argList args(argc, argv)
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:333
Foam::surfaceFields.