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 -------------------------------------------------------------------------------
10 License
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 
26 Application
27  setExprBoundaryFields
28 
29 Group
30  grpPreProcessingUtilities
31 
32 Description
33  Set boundary values using an expression
34 
35 Note
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 
52 using namespace Foam;
53 
54 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
55 // Main program:
56 
57 int main(int argc, char *argv[])
58 {
60 
61  // No -constant, no special treatment for 0/
63 
65  (
66  "ascii",
67  "Write in ASCII format instead of the controlDict setting"
68  );
70  (
71  "dict",
72  "file",
73  "Alternative dictionary for setExprBoundaryFieldsDict"
74  );
76  (
77  "cache-fields",
78  "Cache fields between calls",
79  true // Advanced
80  );
82  (
83  "load-fields",
84  "wordList",
85  "Specify field or fields to preload. Eg, 'T' or '(p T U)'",
86  true // Advanced
87  );
89  (
90  "backup",
91  "Preserve sub-entry as .backup",
92  true // Advanced
93  );
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 
120 
121  if (times.empty())
122  {
124  << "No times selected." << nl
125  << exit(FatalError);
126  }
127 
128  #include "createNamedMesh.H"
129 
130  #include "setSystemMeshDictionaryIO.H"
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(),
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  (
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  (
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::entry
A keyword and a list of tokens is an 'entry'.
Definition: entry.H:67
Foam::IOobject::NO_WRITE
Definition: IOobject.H:195
volFields.H
Foam::IOdictionary
IOdictionary is derived from dictionary and IOobject to give the dictionary automatic IO functionalit...
Definition: IOdictionary.H:54
runTime
engineTime & runTime
Definition: createEngineTime.H:13
Foam::IOobject
Defines the attributes of an object for which implicit objectRegistry management is supported,...
Definition: IOobject.H:169
Foam::expressions::exprString::getEntry
static exprString getEntry(const word &keyword, const dictionary &dict, const bool stripComments=true)
Definition: exprString.C:52
Foam::dictionary::changeKeyword
bool changeKeyword(const keyType &oldKeyword, const keyType &newKeyword, bool overwrite=false)
Change the keyword for an entry,.
Definition: dictionarySearch.C:611
Foam::word
A class for handling words, derived from Foam::string.
Definition: word.H:65
Foam::fvMesh::thisDb
virtual const objectRegistry & thisDb() const
Return the object registry - resolve conflict polyMesh/lduMesh.
Definition: fvMesh.H:292
Foam::IOobject::typeHeaderOk
bool typeHeaderOk(const bool checkType=true, const bool search=true, const bool verbose=true)
Read header (uses typeFilePath to find file) and check its info.
Definition: IOobjectTemplates.C:39
patchExprDriver.H
Foam::Time::writeFormat
IOstream::streamFormat writeFormat() const
The write stream format.
Definition: Time.H:387
Foam::Warning
messageStream Warning
dictName
const word dictName("faMeshDefinition")
Foam::Time::timeName
static word timeName(const scalar t, const int precision=precision_)
Definition: Time.C:780
Foam::IOstreamOption::format
streamFormat format() const noexcept
Get the current stream format.
Definition: IOstreamOption.H:286
Foam::argList::readListIfPresent
bool readListIfPresent(const word &optName, List< T > &list) const
Definition: argListI.H:394
Foam::endl
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:369
surfaceFields.H
Foam::surfaceFields.
Foam::dictionary::get
T get(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Definition: dictionaryTemplates.C:107
Foam::dictionary::set
entry * set(entry *entryPtr)
Assign a new entry, overwriting any existing entry.
Definition: dictionary.C:780
setSystemMeshDictionaryIO.H
forAll
#define forAll(list, i)
Loop across all elements in list.
Definition: stdFoam.H:296
Foam::fvMesh::readUpdate
virtual readUpdateState readUpdate()
Update the mesh based on the mesh files saved in time.
Definition: fvMesh.C:648
Foam::argList::noFunctionObjects
static void noFunctionObjects(bool addWithOption=false)
Remove '-noFunctionObjects' option and ignore any occurrences.
Definition: argList.C:473
Foam::argList::dryRun
int dryRun() const noexcept
Return the dry-run flag.
Definition: argListI.H:116
Foam::expressions::exprDriver::SEARCH_FILES
Search disk (eg, standalone app)
Definition: exprDriver.H:150
Foam::Info
messageStream Info
Information stream (stdout output on master, null elsewhere)
argList.H
Foam::dictionary::subDict
const dictionary & subDict(const word &keyword, enum keyType::option matchOpt=keyType::REGEX) const
Find and return a sub-dictionary.
Definition: dictionary.C:460
Foam::IOstreamOption
The IOstreamOption is a simple container for options an IOstream can normally have.
Definition: IOstreamOption.H:63
addRegionOption.H
Foam::dictionary::readEntry
bool readEntry(const word &keyword, T &val, enum keyType::option matchOpt=keyType::REGEX, bool mandatory=true) const
Definition: dictionaryTemplates.C:302
dict
dictionary dict
Definition: searchingEngine.H:14
Foam::FatalError
error FatalError
Foam::dictionary
A list of keyword definitions, which are a keyword followed by a number of values (eg,...
Definition: dictionary.H:123
createNamedMesh.H
Required Variables.
mesh
dynamicFvMesh & mesh
Definition: createDynamicFvMesh.H:6
dictIO
IOobject dictIO
Definition: setConstantMeshDictionaryIO.H:1
fvMesh.H
Foam
Namespace for OpenFOAM.
Definition: atmBoundaryLayer.C:33
Foam::expressions::patchExpr::parseDriver
Driver for patch expressions.
Definition: patchExprDriver.H:159
Foam::argList::addDryRunOption
static void addDryRunOption(const string &usage, bool advanced=false)
Enable a 'dry-run' bool option, with usage information.
Definition: argList.C:454
Foam::exit
errorManipArg< error, int > exit(error &err, const int errNo=1)
Definition: errorManip.H:130
Foam::Detail::StringStreamAllocator::str
Foam::string str() const
Get the string - as Foam::string rather than std::string.
Definition: StringStream.H:88
Foam::argList::addBoolOption
static void addBoolOption(const word &optName, const string &usage="", bool advanced=false)
Add a bool option to validOptions with usage information.
Definition: argList.C:324
Time.H
setRootCase.H
Foam::IOstreamOption::ASCII
"ascii" (normal default)
Definition: IOstreamOption.H:72
FatalErrorInFunction
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
Definition: error.H:453
Foam::nl
constexpr char nl
Definition: Ostream.H:404
Foam::readFieldsHandler::execute
bool execute(const UList< word > &fieldNames)
Definition: readFields.H:175
Foam::timeSelector::addOptions
static void addOptions(const bool constant=true, const bool withZero=false)
Add timeSelector options to argList::validOptions.
Definition: timeSelector.C:102
Foam::List< instant >
Foam::OStringStream
Output to string buffer, using a OSstream. Always UNCOMPRESSED.
Definition: StringStream.H:227
Foam::Time::setTime
virtual void setTime(const Time &t)
Reset the time and time-index to those of the given time.
Definition: Time.C:1003
Foam::word::null
static const word null
An empty word.
Definition: word.H:80
timeSelector.H
createTime.H
Foam::IOobject::MUST_READ_IF_MODIFIED
Definition: IOobject.H:186
Foam::Ostream::writeEntry
Ostream & writeEntry(const keyType &key, const T &value)
Write a keyword/value entry.
Definition: Ostream.H:236
Foam::readFieldsHandler
A simple field-loader, as per the readFields function object.
Definition: readFields.H:50
Foam::timeSelector::select0
static instantList select0(Time &runTime, const argList &args)
Definition: timeSelector.C:235
Foam::argList::addOption
static void addOption(const word &optName, const string &param="", const string &usage="", bool advanced=false)
Add an option to validOptions with usage information.
Definition: argList.C:335
args
Foam::argList args(argc, argv)
WarningInFunction
#define WarningInFunction
Report a warning using Foam::Warning.
Definition: messageStream.H:328
pointFields.H
Foam::objectRegistry::time
const Time & time() const noexcept
Return time registry.
Definition: objectRegistry.H:178
pointMesh.H
Foam::argList::found
bool found(const word &optName) const
Return true if the named option is found.
Definition: argListI.H:178