Cantera  2.4.0
application.h
Go to the documentation of this file.
1 //! @file application.h
2 
3 // This file is part of Cantera. See License.txt in the top-level directory or
4 // at http://www.cantera.org/license.txt for license and copyright information.
5 
6 #ifndef CT_BASE_APPLICATION_H
7 #define CT_BASE_APPLICATION_H
8 
9 #include "cantera/base/config.h"
10 #include "cantera/base/logger.h"
11 
12 #include <boost/algorithm/string/join.hpp>
13 
14 #include <set>
15 #include <thread>
16 
17 namespace Cantera
18 {
19 
20 class XML_Node;
21 
22 /*!
23  * @defgroup globalData Global Data
24  *
25  * Global data are available anywhere. There are two kinds. Cantera has an
26  * assortment of constant values for physical parameters. Also, Cantera
27  * maintains a collection of global data which is specific to each process that
28  * invokes Cantera functions. This process-specific data is stored in the class
29  * Application.
30  */
31 
32 
33 //! Class to hold global data.
34 /*!
35  * Class Application is the top-level class that stores data that should persist
36  * for the duration of the process. The class should not be instantiated
37  * directly; instead, it is instantiated as needed by the functions declared
38  * here. At most one instance is created, and it is not destroyed until the
39  * process terminates.
40  *
41  * @ingroup textlogs
42  * @ingroup globalData
43  */
45 {
46 protected:
47  //! Class to carry out messages
48  class Messages
49  {
50  public:
51  Messages();
52 
53  Messages(const Messages& r) = delete;
54  Messages& operator=(const Messages& r) = delete;
55 
56  //! Set an error condition in the application class without
57  //! throwing an exception.
58  /*!
59  * This routine adds an error message to the end of the stack of errors
60  * that Cantera accumulates in the Application class.
61  * @param r Procedure name which is generating the error condition
62  * @param msg Descriptive message of the error condition.
63  *
64  * If only one argument is specified, that string is used as the
65  * entire message.
66  * @ingroup errorhandling
67  */
68  void addError(const std::string& r, const std::string& msg="");
69 
70  //! Return the number of errors that have been encountered so far.
71  /*!
72  * @ingroup errorhandling
73  */
74  int getErrorCount();
75 
76  //! Discard the last error message
77  /*!
78  * %Cantera saves a stack of exceptions that it has caught in the
79  * Application class. This routine eliminates the last exception to be
80  * added to that stack.
81  *
82  * @ingroup errorhandling
83  */
84  void popError();
85 
86  //! Retrieve the last error message in a string
87  /*!
88  * This routine will retrieve the last error message and return it in
89  * the return string.
90  *
91  * @ingroup errorhandling
92  */
93  std::string lastErrorMessage();
94 
95  //! Prints all of the error messages to an ostream
96  /*!
97  * Write out all of the saved error messages to the ostream f using
98  * the function Logger::writelog. Cantera saves a stack of exceptions
99  * that it has caught in the Application class. This routine writes
100  * out all of the error messages to the ostream and then clears them
101  * from internal storage.
102  *
103  * @param f ostream which will receive the error messages
104  *
105  * @ingroup errorhandling
106  */
107  void getErrors(std::ostream& f);
108 
109  //! Prints all of the error messages using writelog
110  /*!
111  * Print all of the error messages using function writelog. Cantera
112  * saves a stack of exceptions that it has caught in the Application
113  * class. This routine writes out all of the error messages and then
114  * clears them from internal storage.
115  *
116  * @ingroup errorhandling
117  */
118  void logErrors();
119 
120  //! Write a message to the screen.
121  /*!
122  * The string may be of any length, and may contain end-of-line
123  * characters. This method is used throughout Cantera to write log
124  * messages. It can also be called by user programs. The advantage of
125  * using writelog over writing directly to the standard output is that
126  * messages written with writelog will display correctly even when
127  * Cantera is used from MATLAB or other application that do not have a
128  * standard output stream.
129  *
130  * @param msg c++ string to be written to the screen
131  * @ingroup textlogs
132  */
133  void writelog(const std::string& msg);
134 
135  //! Write an end of line character to the screen and flush output
136  void writelogendl();
137 
138  //! Install a logger.
139  /*!
140  * Called by the language interfaces to install an appropriate logger.
141  * The logger is used for the writelog() function
142  *
143  * @param logwriter Pointer to a logger object
144  * @see Logger.
145  * @ingroup textlogs
146  */
147  void setLogger(Logger* logwriter);
148 
149  protected:
150  //! Current list of error messages
151  std::vector<std::string> errorMessage;
152 
153  //! Current pointer to the logwriter
154  std::unique_ptr<Logger> logwriter;
155  };
156 
157  //! Typedef for thread specific messages
158  typedef shared_ptr<Messages> pMessages_t;
159 
160  //! Class that stores thread messages for each thread, and retrieves them
161  //! based on the thread id.
163  {
164  public:
165  //! Constructor
167 
168  //! Provide a pointer dereferencing overloaded operator
169  /*!
170  * @returns a pointer to Messages
171  */
172  Messages* operator->();
173 
174  //! Remove a local thread message
175  void removeThreadMessages();
176 
177  //! Typedef for map between a thread and the message
178  typedef std::map<std::thread::id, pMessages_t> threadMsgMap_t;
179 
180  private:
181  //! Thread Msg Map
183  };
184 
185 protected:
186  //! Constructor for class sets up the initial conditions
187  //! Protected ctor access thru static member function Instance
188  Application();
189 
190 public:
191  //! Return a pointer to the one and only instance of class Application
192  /*!
193  * If the Application object has not yet been created, it is created
194  */
195  static Application* Instance();
196 
197  //! Destructor for class deletes global data
198  /*!
199  * Deletes any open XML trees.
200  */
201  virtual ~Application();
202 
203  //! Static function that destroys the application class's data
204  static void ApplicationDestroy();
205 
206  //! @copydoc Messages::addError
207  void addError(const std::string& r, const std::string& msg="") {
208  pMessenger->addError(r, msg);
209  }
210 
211  //! @copydoc Messages::getErrorCount
213  return pMessenger->getErrorCount();
214  }
215 
216  //! @copydoc Messages::popError
217  void popError() {
218  pMessenger->popError();
219  }
220 
221  //! @copydoc Messages::lastErrorMessage
222  std::string lastErrorMessage() {
223  return pMessenger->lastErrorMessage();
224  }
225 
226  //! @copydoc Messages::getErrors
227  void getErrors(std::ostream& f) {
228  pMessenger->getErrors(f);
229  }
230 
231  //! @copydoc Messages::logErrors
232  void logErrors() {
233  pMessenger->logErrors();
234  }
235 
236  //! Add a directory to the data file search path.
237  /*!
238  * @ingroup inputfiles
239  *
240  * @param dir String name for the directory to be added to the search path
241  */
242  void addDataDirectory(const std::string& dir);
243 
244  //! Find an input file.
245  /*!
246  * This routine will search for a file in the default locations specified
247  * for the application. See the routine setDefaultDirectories() listed
248  * above.
249  *
250  * The default set of directories specified for the application will be
251  * searched if a '/' or an '\\' is not found in the name. If either is found
252  * then a relative path name is presumed, and the default directories are
253  * not searched.
254  *
255  * The presence of the file is determined by whether the file can be
256  * opened for reading by the current user.
257  *
258  * @param name Name of the input file to be searched for
259  * @return The absolute path name of the first matching file is
260  * returned. If a relative path name is indicated, the relative path
261  * name is returned.
262  *
263  * If the file is not found, a message is written to stdout and a
264  * CanteraError exception is thrown.
265  *
266  * @ingroup inputfiles
267  */
268  std::string findInputFile(const std::string& name);
269 
270  //! Get the Cantera data directories
271  /*!
272  * This routine returns a string including the names of all the
273  * directories searched by Cantera for data files.
274  *
275  * @param sep Separator to use between directories in the string
276  * @return A string of directories separated by the input sep
277  *
278  * @ingroup inputfiles
279  */
280  std::string getDataDirectories(const std::string& sep) {
281  return boost::algorithm::join(inputDirs, sep);
282  }
283 
284  //! Return a pointer to the XML tree for a Cantera input file.
285  /*!
286  * This routine will find the file and read the XML file into an XML tree
287  * structure. Then, a pointer will be returned. If the file has already been
288  * processed, then just the pointer will be returned.
289  *
290  * @param file String containing the relative or absolute file name
291  * @param debug Debug flag
292  */
293  XML_Node* get_XML_File(const std::string& file, int debug=0);
294 
295  //! Read a CTI or CTML string and fill up an XML tree.
296  /*!
297  * Return a pointer to the XML tree corresponding to the specified CTI or
298  * XML string. If the given string has been processed before, the cached XML
299  * tree will be returned. Otherwise, the XML tree will be generated and
300  * stored in the cache.
301  * @param text CTI or CTML string
302  * @return Root of the corresponding XML tree
303  */
304  XML_Node* get_XML_from_string(const std::string& text);
305 
306  //! Close an XML File
307  /*!
308  * Close a file that is opened by this application object
309  *
310  * @param file String containing the relative or absolute file name
311  */
312  void close_XML_File(const std::string& file);
313 
314 #ifdef _WIN32
315  long int readStringRegistryKey(const std::string& keyName, const std::string& valueName,
316  std::string& value, const std::string& defaultValue);
317 #endif
318 
319  //! @copydoc Messages::writelog
320  void writelog(const std::string& msg) {
321  pMessenger->writelog(msg);
322  }
323 
324  //! Write an endl to the screen and flush output
325  void writelogendl() {
326  pMessenger->writelogendl();
327  }
328 
329  //! Print a warning indicating that *method* is deprecated. Additional
330  //! information (removal version, alternatives) can be specified in
331  //! *extra*. Deprecation warnings are printed once per method per
332  //! invocation of the application.
333  void warn_deprecated(const std::string& method, const std::string& extra="");
334 
335  //! Globally disable printing of deprecation warnings. Used primarily to
336  //! prevent certain tests from failing.
338  m_suppress_deprecation_warnings = true;
339  }
340 
341  //! Turns deprecation warnings into exceptions. Activated within the test
342  //! suite to make sure that no deprecated methods are being used.
344  m_fatal_deprecation_warnings = true;
345  }
346 
347  //! Globally disable printing of warnings about problematic thermo data,
348  //! e.g. NASA polynomials with discontinuities at the midpoint temperature.
349  void suppress_thermo_warnings(bool suppress=true) {
350  m_suppress_thermo_warnings = suppress;
351  }
352 
353  //! Returns `true` if thermo warnings should be suppressed.
355  return m_suppress_thermo_warnings;
356  }
357 
358  //! @copydoc Messages::setLogger
359  void setLogger(Logger* logwriter) {
360  pMessenger->setLogger(logwriter);
361  }
362 
363  //! Delete and free memory allocated per thread in multithreaded applications
364  /*!
365  * Delete the memory allocated per thread by Cantera. It should be called
366  * from within the thread just before the thread terminates. If your
367  * version of Cantera has not been specifically compiled for thread safety
368  * this function does nothing.
369  */
370  void thread_complete();
371 
372 protected:
373  //! Set the default directories for input files.
374  /*!
375  * %Cantera searches for input files along a path that includes platform-
376  * specific default locations, and possibly user-specified locations.
377  * This function installs the platform-specific directories on the search
378  * path. It is invoked at startup by appinit(), and never should need to
379  * be called by user programs.
380  *
381  * The current directory (".") is always searched first. Then, on Windows
382  * platforms, if environment variable COMMONPROGRAMFILES is set (which it
383  * should be on Win XP or Win 2000), then directories under this one will
384  * be added to the search path. The %Cantera Windows installer installs
385  * data files to this location.
386  *
387  * On the Mac, directory '/Applications/Cantera/data' is added to the
388  * search path.
389  *
390  * On any platform, if environment variable CANTERA_DATA is set to a
391  * directory name, then this directory is added to the search path.
392  *
393  * Finally, the location where the data files were installed when
394  * %Cantera was built is added to the search path.
395  *
396  * Additional directories may be added by calling function addDirectory.
397  * @ingroup inputfiles
398  */
399  void setDefaultDirectories();
400 
401  //! Current vector of input directories to search for input files
402  std::vector<std::string> inputDirs;
403 
404  //! Current vector of XML file trees that have been previously parsed
405  //! The second element of the value is used to store the last-modified time
406  //! for the file, to enable change detection.
407  std::map<std::string, std::pair<XML_Node*, int> > xmlfiles;
408  //! Vector of deprecation warnings that have been emitted (to suppress
409  //! duplicates)
410  std::set<std::string> warnings;
411 
412  bool m_suppress_deprecation_warnings;
413  bool m_fatal_deprecation_warnings;
414  bool m_suppress_thermo_warnings;
415 
416  ThreadMessages pMessenger;
417 
418 private:
419  //! Pointer to the single Application instance
421 };
422 
423 }
424 
425 #endif
void make_deprecation_warnings_fatal()
Turns deprecation warnings into exceptions.
Definition: application.h:343
void popError()
Discard the last error message.
void writelogendl()
Write an end of line character to the screen and flush output.
Definition: application.cpp:95
void writelogendl()
Write an endl to the screen and flush output.
Definition: application.h:325
Base class for &#39;loggers&#39; that write text messages to log files.
Definition: logger.h:40
Class to hold global data.
Definition: application.h:44
int getErrorCount()
Return the number of errors that have been encountered so far.
Definition: application.cpp:80
virtual ~Application()
Destructor for class deletes global data.
std::string lastErrorMessage()
Retrieve the last error message in a string.
Definition: application.h:222
std::string findInputFile(const std::string &name)
Find an input file.
static Application * s_app
Pointer to the single Application instance.
Definition: application.h:420
Class XML_Node is a tree-based representation of the contents of an XML file.
Definition: xml.h:97
void writelog(const std::string &msg)
Write a message to the screen.
Definition: application.h:320
XML_Node * get_XML_from_string(const std::string &text)
Read a CTI or CTML string and fill up an XML tree.
std::vector< std::string > inputDirs
Current vector of input directories to search for input files.
Definition: application.h:402
std::string lastErrorMessage()
Retrieve the last error message in a string.
shared_ptr< Messages > pMessages_t
Typedef for thread specific messages.
Definition: application.h:158
std::map< std::string, std::pair< XML_Node *, int > > xmlfiles
Current vector of XML file trees that have been previously parsed The second element of the value is ...
Definition: application.h:407
std::map< std::thread::id, pMessages_t > threadMsgMap_t
Typedef for map between a thread and the message.
Definition: application.h:178
void setDefaultDirectories()
Set the default directories for input files.
void setLogger(Logger *logwriter)
Install a logger.
Definition: application.cpp:85
void suppress_deprecation_warnings()
Globally disable printing of deprecation warnings.
Definition: application.h:337
std::unique_ptr< Logger > logwriter
Current pointer to the logwriter.
Definition: application.h:154
void warn_deprecated(const std::string &method, const std::string &extra="")
Print a warning indicating that method is deprecated.
Class that stores thread messages for each thread, and retrieves them based on the thread id...
Definition: application.h:162
std::set< std::string > warnings
Vector of deprecation warnings that have been emitted (to suppress duplicates)
Definition: application.h:410
void popError()
Discard the last error message.
Definition: application.h:217
XML_Node * get_XML_File(const std::string &file, int debug=0)
Return a pointer to the XML tree for a Cantera input file.
Application()
Constructor for class sets up the initial conditions Protected ctor access thru static member functio...
void thread_complete()
Delete and free memory allocated per thread in multithreaded applications.
void logErrors()
Prints all of the error messages using writelog.
Definition: application.h:232
void getErrors(std::ostream &f)
Prints all of the error messages to an ostream.
Definition: application.h:227
static Application * Instance()
Return a pointer to the one and only instance of class Application.
void addError(const std::string &r, const std::string &msg="")
Set an error condition in the application class without throwing an exception.
Definition: application.h:207
Header for Base class for &#39;loggers&#39; that write text messages to log files (see Writing messages to th...
void removeThreadMessages()
Remove a local thread message.
Class to carry out messages.
Definition: application.h:48
std::vector< std::string > errorMessage
Current list of error messages.
Definition: application.h:151
threadMsgMap_t m_threadMsgMap
Thread Msg Map.
Definition: application.h:182
bool thermo_warnings_suppressed()
Returns true if thermo warnings should be suppressed.
Definition: application.h:354
void addDataDirectory(const std::string &dir)
Add a directory to the data file search path.
static void ApplicationDestroy()
Static function that destroys the application class&#39;s data.
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:8
void writelog(const std::string &msg)
Write a message to the screen.
Definition: application.cpp:90
Messages * operator->()
Provide a pointer dereferencing overloaded operator.
void addError(const std::string &r, const std::string &msg="")
Set an error condition in the application class without throwing an exception.
Definition: application.cpp:66
void suppress_thermo_warnings(bool suppress=true)
Globally disable printing of warnings about problematic thermo data, e.g.
Definition: application.h:349
void logErrors()
Prints all of the error messages using writelog.
void getErrors(std::ostream &f)
Prints all of the error messages to an ostream.
int getErrorCount()
Return the number of errors that have been encountered so far.
Definition: application.h:212
void setLogger(Logger *logwriter)
Install a logger.
Definition: application.h:359
void close_XML_File(const std::string &file)
Close an XML File.
std::string getDataDirectories(const std::string &sep)
Get the Cantera data directories.
Definition: application.h:280