codedFunctionObject.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 | Copyright (C) 2011-2017 OpenFOAM Foundation
6  \\/ M anipulation |
7 -------------------------------------------------------------------------------
8 License
9  This file is part of OpenFOAM.
10 
11  OpenFOAM is free software: you can redistribute it and/or modify it
12  under the terms of the GNU General Public License as published by
13  the Free Software Foundation, either version 3 of the License, or
14  (at your option) any later version.
15 
16  OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
17  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
19  for more details.
20 
21  You should have received a copy of the GNU General Public License
22  along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>.
23 
24 \*---------------------------------------------------------------------------*/
25 
26 #include "codedFunctionObject.H"
27 #include "volFields.H"
28 #include "dictionary.H"
29 #include "Time.H"
30 #include "SHA1Digest.H"
31 #include "dynamicCode.H"
32 #include "dynamicCodeContext.H"
33 #include "stringOps.H"
35 
36 // * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
37 
38 namespace Foam
39 {
40  defineTypeNameAndDebug(codedFunctionObject, 0);
41 
43  (
44  functionObject,
45  codedFunctionObject,
46  dictionary
47  );
48 }
49 
50 // * * * * * * * * * * * * Protected Member Functions * * * * * * * * * * * //
51 
53 (
54  dynamicCode& dynCode,
55  const dynamicCodeContext& context
56 ) const
57 {
58  // Set additional rewrite rules
59  dynCode.setFilterVariable("typeName", name_);
60  dynCode.setFilterVariable("codeData", codeData_);
61  dynCode.setFilterVariable("codeRead", codeRead_);
62  dynCode.setFilterVariable("codeExecute", codeExecute_);
63  dynCode.setFilterVariable("codeWrite", codeWrite_);
64  dynCode.setFilterVariable("codeEnd", codeEnd_);
65 
66  // Compile filtered C template
67  dynCode.addCompileFile("functionObjectTemplate.C");
68 
69  // Copy filtered H template
70  dynCode.addCopyFile("functionObjectTemplate.H");
71 
72  // Debugging: make BC verbose
73  // dynCode.setFilterVariable("verbose", "true");
74  // Info<<"compile " << name_ << " sha1: "
75  // << context.sha1() << endl;
76 
77  // Define Make/options
78  dynCode.setMakeOptions
79  (
80  "EXE_INC = -g \\\n"
81  "-I$(LIB_SRC)/finiteVolume/lnInclude \\\n"
82  "-I$(LIB_SRC)/meshTools/lnInclude \\\n"
83  + context.options()
84  + "\n\nLIB_LIBS = \\\n"
85  + " -lOpenFOAM \\\n"
86  + " -lfiniteVolume \\\n"
87  + " -lmeshTools \\\n"
88  + context.libs()
89  );
90 }
91 
92 
94 {
95  return const_cast<Time&>(time_).libs();
96 }
97 
98 
100 {
101  return "functionObject " + name();
102 }
103 
104 
106 {
107  redirectFunctionObjectPtr_.clear();
108 }
109 
110 
112 {
113  return dict_;
114 }
115 
116 
117 // * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
118 
119 Foam::codedFunctionObject::codedFunctionObject
120 (
121  const word& name,
122  const Time& time,
123  const dictionary& dict
124 )
125 :
126  functionObject(name),
127  codedBase(),
128  time_(time),
129  dict_(dict)
130 {
131  read(dict_);
132 
133  updateLibrary(name_);
134  redirectFunctionObject();
135 }
136 
137 
138 // * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
139 
141 {}
142 
143 
144 // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
145 
147 {
148  if (!redirectFunctionObjectPtr_.valid())
149  {
150  dictionary constructDict(dict_);
151  constructDict.set("type", name_);
152 
153  redirectFunctionObjectPtr_ = functionObject::New
154  (
155  name_,
156  time_,
157  constructDict
158  );
159  }
160  return redirectFunctionObjectPtr_();
161 }
162 
163 
165 {
166  updateLibrary(name_);
167  return redirectFunctionObject().execute();
168 }
169 
170 
172 {
173  updateLibrary(name_);
174  return redirectFunctionObject().write();
175 }
176 
177 
179 {
180  updateLibrary(name_);
181  return redirectFunctionObject().end();
182 }
183 
184 
186 {
187  // Backward compatibility
188  if (dict.found("redirectType"))
189  {
190  dict.lookup("redirectType") >> name_;
191  }
192  else
193  {
194  dict.lookup("name") >> name_;
195  }
196 
197  const entry* dataPtr = dict.lookupEntryPtr
198  (
199  "codeData",
200  false,
201  false
202  );
203  if (dataPtr)
204  {
205  codeData_ = stringOps::trim(dataPtr->stream());
206  stringOps::inplaceExpand(codeData_, dict);
208  (
209  codeData_,
210  dataPtr->startLineNumber(),
211  dict.name()
212  );
213  }
214 
215  const entry* readPtr = dict.lookupEntryPtr
216  (
217  "codeRead",
218  false,
219  false
220  );
221  if (readPtr)
222  {
223  codeRead_ = stringOps::trim(readPtr->stream());
224  stringOps::inplaceExpand(codeRead_, dict);
226  (
227  codeRead_,
228  readPtr->startLineNumber(),
229  dict.name()
230  );
231  }
232 
233  const entry* execPtr = dict.lookupEntryPtr
234  (
235  "codeExecute",
236  false,
237  false
238  );
239  if (execPtr)
240  {
241  codeExecute_ = stringOps::trim(execPtr->stream());
242  stringOps::inplaceExpand(codeExecute_, dict);
244  (
245  codeExecute_,
246  execPtr->startLineNumber(),
247  dict.name()
248  );
249  }
250 
251  const entry* writePtr = dict.lookupEntryPtr
252  (
253  "codeWrite",
254  false,
255  false
256  );
257  if (writePtr)
258  {
259  codeWrite_ = stringOps::trim(writePtr->stream());
260  stringOps::inplaceExpand(codeWrite_, dict);
262  (
263  codeWrite_,
264  writePtr->startLineNumber(),
265  dict.name()
266  );
267  }
268 
269  const entry* endPtr = dict.lookupEntryPtr
270  (
271  "codeEnd",
272  false,
273  false
274  );
275  if (endPtr)
276  {
277  codeEnd_ = stringOps::trim(endPtr->stream());
278  stringOps::inplaceExpand(codeEnd_, dict);
280  (
281  codeEnd_,
282  endPtr->startLineNumber(),
283  dict.name()
284  );
285  }
286 
287  if(!dataPtr && !readPtr && !execPtr && !writePtr && !endPtr)
288  {
290  (
291  dict
292  ) << "No critical \"code\" prefixed keywords were found."
293  << " Please check the code documentation for more details."
294  << nl << endl;
295  }
296 
297  updateLibrary(name_);
298  return redirectFunctionObject().read(dict);
299 }
300 
301 
302 // ************************************************************************* //
functionObject & redirectFunctionObject() const
Dynamically compiled functionObject.
bool found(const word &, bool recursive=false, bool patternMatch=true) const
Search dictionary for given keyword.
Definition: dictionary.C:431
virtual bool read(const dictionary &)
Read and set the function object if its data have changed.
const entry * lookupEntryPtr(const word &, bool recursive, bool patternMatch) const
Find and return an entry data stream pointer if present.
Definition: dictionary.C:470
A list of keyword definitions, which are a keyword followed by any number of values (e...
Definition: dictionary.H:137
void setMakeOptions(const std::string &content)
Define contents for Make/options.
Definition: dynamicCode.C:394
static void addLineDirective(string &, const label lineNum, const fileName &name)
Helper: add #line directive.
virtual label startLineNumber() const =0
Return line number of first token in dictionary.
Ostream & endl(Ostream &os)
Add newline and flush stream.
Definition: Ostream.H:253
virtual void clearRedirect() const
void addCompileFile(const fileName &name)
Add a file template name, which will be found and filtered.
Definition: dynamicCode.C:350
Abstract base-class for Time/database function objects.
Class to control time during OpenFOAM simulations that is also the top-level objectRegistry.
Definition: Time.H:68
virtual const dictionary & codeDict() const
Macros for easy insertion into run-time selection tables.
virtual dlLibraryTable & libs() const
Get the loaded dynamic libraries.
virtual void prepare(dynamicCode &, const dynamicCodeContext &) const
Adapt the context for the current object.
string trim(const string &)
Return string trimmed of leading and trailing whitespace.
Definition: stringOps.C:923
bool read(const char *, int32_t &)
Definition: int32IO.C:85
const fileName & name() const
Return the dictionary name.
Definition: dictionary.H:103
A class for handling words, derived from string.
Definition: word.H:59
virtual bool end()
Called when Time::run() determines that the time-loop exits.
Base class for function objects and boundary conditions using dynamic code.
Definition: codedBase.H:53
A table of dynamically loaded libraries.
addToRunTimeSelectionTable(ensightPart, ensightPartCells, istream)
static const char nl
Definition: Ostream.H:262
defineTypeNameAndDebug(combustionModel, 0)
word name(const complex &)
Return a string representation of a complex.
Definition: complex.C:47
virtual ~codedFunctionObject()
Destructor.
const string & libs() const
Return the code-libs.
Tools for handling dynamic code compilation.
Definition: dynamicCode.H:56
Encapsulation of dynamic code dictionaries.
void setFilterVariable(const word &key, const std::string &value)
Define a filter variable.
Definition: dynamicCode.C:385
string & inplaceExpand(string &, const HashTable< string, word, string::hash > &mapping, const char sigil='$')
Inplace expand occurences of variables according to the mapping.
Definition: stringOps.C:87
const string & options() const
Return the code-options.
static autoPtr< functionObject > New(const word &name, const Time &, const dictionary &)
Select from dictionary, based on its "type" entry.
void addCopyFile(const fileName &name)
Add a file template name, which will be found and filtered.
Definition: dynamicCode.C:356
virtual bool execute()
Called at each ++ or += of the time-loop.
void set(entry *)
Assign a new entry, overwrite any existing entry.
Definition: dictionary.C:941
virtual bool write()
Called at each ++ or += of the time-loop.
#define IOWarningInFunction(ios)
Report an IO warning using Foam::Warning.
virtual string description() const
virtual ITstream & stream() const =0
Return token stream if this entry is a primitive entry.
A class for handling character strings derived from std::string.
Definition: string.H:74
Namespace for OpenFOAM.
A keyword and a list of tokens is an &#39;entry&#39;.
Definition: entry.H:65
ITstream & lookup(const word &, bool recursive=false, bool patternMatch=true) const
Find and return an entry data stream.
Definition: dictionary.C:576