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