Cantera  3.1.0a1
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 <thread>
15 
16 namespace Cantera
17 {
18 
19 /**
20  * @defgroup globalData Global Data
21  *
22  * Global data are available anywhere. There are two kinds. %Cantera has an
23  * assortment of constant values for physical parameters. Also, Cantera
24  * maintains a collection of global data which is specific to each process that
25  * invokes %Cantera functions. This process-specific data is stored in the class
26  * Application.
27  */
28 
29 
30 //! Class to hold global data.
31 /*!
32  * Class Application is the top-level class that stores data that should persist
33  * for the duration of the process. The class should not be instantiated
34  * directly; instead, it is instantiated as needed by the functions declared
35  * here. At most one instance is created, and it is not destroyed until the
36  * process terminates.
37  *
38  * @ingroup globalData
39  * @ingroup debugGroup
40  */
42 {
43 protected:
44  //! Class to carry out messages
45  class Messages
46  {
47  public:
48  Messages();
49 
50  Messages(const Messages& r) = delete;
51  Messages& operator=(const Messages& r) = delete;
52 
53  //! Set an error condition in the application class without
54  //! throwing an exception.
55  /*!
56  * This routine adds an error message to the end of the stack of errors
57  * that %Cantera accumulates in the Application class.
58  * @param r Procedure name which is generating the error condition
59  * @param msg Descriptive message of the error condition.
60  *
61  * If only one argument is specified, that string is used as the
62  * entire message.
63  * @ingroup errGroup
64  */
65  void addError(const string& r, const string& msg="");
66 
67  //! Return the number of errors that have been encountered so far.
68  /*!
69  * @ingroup errGroup
70  */
71  int getErrorCount();
72 
73  //! Discard the last error message
74  /*!
75  * %Cantera saves a stack of exceptions that it has caught in the
76  * Application class. This routine eliminates the last exception to be
77  * added to that stack.
78  *
79  * @ingroup errGroup
80  */
81  void popError();
82 
83  //! Retrieve the last error message in a string
84  /*!
85  * This routine will retrieve the last error message and return it in
86  * the return string.
87  *
88  * @ingroup errGroup
89  */
90  string lastErrorMessage();
91 
92  //! Prints all of the error messages to an ostream
93  /*!
94  * Write out all of the saved error messages to the ostream f using
95  * the function Logger::writelog. %Cantera saves a stack of exceptions
96  * that it has caught in the Application class. This routine writes
97  * out all of the error messages to the ostream and then clears them
98  * from internal storage.
99  *
100  * @param f ostream which will receive the error messages
101  *
102  * @ingroup errGroup
103  */
104  void getErrors(std::ostream& f);
105 
106  //! Prints all of the error messages using writelog
107  /*!
108  * Print all of the error messages using function writelog. Cantera
109  * saves a stack of exceptions that it has caught in the Application
110  * class. This routine writes out all of the error messages and then
111  * clears them from internal storage.
112  *
113  * @ingroup errGroup
114  */
115  void logErrors();
116 
117  //! Write a message to the screen.
118  /*!
119  * The string may be of any length, and may contain end-of-line
120  * characters. This method is used throughout %Cantera to write log
121  * messages. It can also be called by user programs. The advantage of
122  * using writelog over writing directly to the standard output is that
123  * messages written with writelog will display correctly even when
124  * %Cantera is used from MATLAB or other application that do not have a
125  * standard output stream.
126  *
127  * @param msg c++ string to be written to the screen
128  * @ingroup logGroup
129  */
130  void writelog(const string& msg);
131 
132  //! Write an end of line character to the screen and flush output
133  void writelogendl();
134 
135  //! Write a warning message to the screen.
136  /*!
137  * @param warning String specifying type of warning; see Logger::warn()
138  * @param msg String to be written to the screen
139  * @ingroup logGroup
140  */
141  void warnlog(const string& warning, const string& msg);
142 
143  //! Install a logger.
144  /*!
145  * Called by the language interfaces to install an appropriate logger.
146  * The logger is used for the writelog() function
147  *
148  * @param logwriter Pointer to a logger object
149  * @see Logger.
150  * @ingroup logGroup
151  */
152  void setLogger(Logger* logwriter);
153 
154  protected:
155  //! Current list of error messages
156  vector<string> errorMessage;
157 
158  //! Current pointer to the logwriter
159  unique_ptr<Logger> logwriter;
160  };
161 
162  //! Typedef for thread specific messages
163  typedef shared_ptr<Messages> pMessages_t;
164 
165  //! Class that stores thread messages for each thread, and retrieves them
166  //! based on the thread id.
168  {
169  public:
170  //! Constructor
172 
173  //! Provide a pointer dereferencing overloaded operator
174  /*!
175  * @returns a pointer to Messages
176  */
177  Messages* operator->();
178 
179  //! Remove a local thread message
180  void removeThreadMessages();
181 
182  //! Typedef for map between a thread and the message
183  typedef map<std::thread::id, pMessages_t> threadMsgMap_t;
184 
185  private:
186  //! Thread Msg Map
188  };
189 
190 protected:
191  //! Constructor for class sets up the initial conditions
192  //! Protected ctor access thru static member function Instance
193  Application();
194 
195 public:
196  //! Return a pointer to the one and only instance of class Application
197  /*!
198  * If the Application object has not yet been created, it is created
199  */
200  static Application* Instance();
201 
202  //! Destructor for class deletes global data
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 string& r, const 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  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 inputGroup
241  *
242  * @param dir String name for the directory to be added to the search path
243  */
244  void addDataDirectory(const 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 inputGroup
266  */
267  string findInputFile(const 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 inputGroup
278  */
279  string getDataDirectories(const string& sep) {
280  return boost::algorithm::join(inputDirs, sep);
281  }
282 
283  //! Load an extension implementing user-defined models
284  //! @param extType Specifies the interface / language of the extension, for example
285  //! "python"
286  //! @param name Specifies the name of the extension. The meaning of this
287  //! parameter depends on the specific extension interface. For example, for
288  //! Python extensions, this is the name of the Python module containing the
289  //! models.
290  //! @since New in %Cantera 3.0
291  void loadExtension(const string& extType, const string& name);
292 
293  //! Set the versions of Python to try when loading user-defined extensions,
294  //! in order of preference. Separate multiple versions with commas, for example
295  //! `"3.11,3.10"`.
296  //! @since New in %Cantera 3.0
297  void searchPythonVersions(const string& versions);
298 
299 #ifdef _WIN32
300  long int readStringRegistryKey(const string& keyName, const string& valueName,
301  string& value, const string& defaultValue);
302 #endif
303 
304  //! @copydoc Messages::writelog
305  void writelog(const string& msg) {
306  pMessenger->writelog(msg);
307  }
308 
309  //! Write an endl to the screen and flush output
310  void writelogendl() {
311  pMessenger->writelogendl();
312  }
313 
314  //! @copydoc Messages::warnlog
315  void warnlog(const string& warning, const string& msg) {
316  pMessenger->warnlog(warning, msg);
317  }
318 
319  //! Print a warning indicating that *method* is deprecated. Additional
320  //! information (removal version, alternatives) can be specified in
321  //! *extra*. Deprecation warnings are printed once per method per
322  //! invocation of the application.
323  void warn_deprecated(const string& method, const string& extra="");
324 
325  //! Globally disable printing of deprecation warnings. Used primarily to
326  //! prevent certain tests from failing.
328  m_suppress_deprecation_warnings = true;
329  m_fatal_deprecation_warnings = false;
330  }
331 
332  //! Turns deprecation warnings into exceptions. Activated within the test
333  //! suite to make sure that no deprecated methods are being used.
335  m_fatal_deprecation_warnings = true;
336  }
337 
338  //! Generate a general purpose warning; repeated warnings are not suppressed
339  //! @param warning Warning type; see Logger::warn()
340  //! @param method Name of method triggering the warning
341  //! @param extra Additional information printed for the warning
342  void warn(const string& warning, const string& method, const string& extra="");
343 
344  //! Globally disable printing of (user) warnings. Used primarily to
345  //! prevent certain tests from failing.
347  m_suppress_warnings = true;
348  m_fatal_warnings = false;
349  }
350 
351  //! Returns `true` if warnings should be suppressed.
353  return m_suppress_warnings;
354  }
355 
356  //! Turns %Cantera warnings into exceptions. Activated within the test
357  //! suite to make sure that your warning message are being raised.
359  m_fatal_warnings = true;
360  }
361 
362  //! Globally disable printing of warnings about problematic thermo data,
363  //! such as NASA polynomials with discontinuities at the midpoint temperature.
364  void suppress_thermo_warnings(bool suppress=true) {
365  m_suppress_thermo_warnings = suppress;
366  }
367 
368  //! Returns `true` if thermo warnings should be suppressed.
370  return m_suppress_thermo_warnings;
371  }
372 
373  //! Set definition used for rate constant calculation.
374  //! @see Kinetics::getFwdRateConstants()
375  /*!
376  * If set to `false` (default value), rate constants of three-body reactions are
377  * consistent with conventional definitions (for example Eq. 9.75 in Kee, et al.
378  * @cite kee2003).
379  * If set to `true`, output for rate constants of three-body reactions is
380  * multiplied by third-body concentrations, consistent with %Cantera's behavior
381  * prior to version 3.0.
382  */
383  void use_legacy_rate_constants(bool legacy=true) {
384  m_use_legacy_rate_constants = legacy;
385  }
386 
387  //! Returns `true` if legacy rate constant definition is used
389  return m_use_legacy_rate_constants;
390  }
391 
392  //! @copydoc Messages::setLogger
393  void setLogger(Logger* logwriter) {
394  pMessenger->setLogger(logwriter);
395  }
396 
397  //! Delete and free memory allocated per thread in multithreaded applications
398  /*!
399  * Delete the memory allocated per thread by Cantera. It should be called
400  * from within the thread just before the thread terminates. If your
401  * version of %Cantera has not been specifically compiled for thread safety
402  * this function does nothing.
403  */
404  void thread_complete();
405 
406 protected:
407  //! Set the default directories for input files.
408  /*!
409  * %Cantera searches for input files along a path that includes platform-
410  * specific default locations, and possibly user-specified locations.
411  * This function installs the platform-specific directories on the search
412  * path. It is invoked at startup by appinit(), and never should need to
413  * be called by user programs.
414  *
415  * The current directory (".") is always searched first. Then, on Windows, the
416  * registry is checked to find the %Cantera installation directory, and the
417  * 'data' subdirectory of the installation directory will be added to the search
418  * path.
419  *
420  * On any platform, if environment variable CANTERA_DATA is set to a directory
421  * name or a list of directory names separated with the OS-dependent path
422  * separator (that is, ";" on Windows, ":" elsewhere), then these directories will
423  * be added to the search path.
424  *
425  * Finally, the location where the data files were installed when
426  * %Cantera was built is added to the search path.
427  *
428  * Additional directories may be added by calling function addDirectory.
429  * @ingroup inputGroup
430  */
431  void setDefaultDirectories();
432 
433  //! Current vector of input directories to search for input files
434  vector<string> inputDirs;
435 
436  //! Versions of Python to consider when attempting to load user extensions
437  vector<string> m_pythonSearchVersions = {"3.12", "3.11", "3.10", "3.9", "3.8"};
438 
439  //! Set of deprecation warnings that have been emitted (to suppress duplicates)
440  set<string> warnings;
441 
442  bool m_suppress_deprecation_warnings = false;
443  bool m_fatal_deprecation_warnings = false;
444  bool m_suppress_thermo_warnings = false;
445  bool m_suppress_warnings = false;
446  bool m_fatal_warnings = false;
447  bool m_use_legacy_rate_constants = false;
448 
449  set<pair<string, string>> m_loaded_extensions;
450 
451  ThreadMessages pMessenger;
452 
453 private:
454  //! Pointer to the single Application instance
456 };
457 
458 }
459 
460 #endif
Class to carry out messages.
Definition: application.h:46
unique_ptr< Logger > logwriter
Current pointer to the logwriter.
Definition: application.h:159
vector< string > errorMessage
Current list of error messages.
Definition: application.h:156
void writelogendl()
Write an end of line character to the screen and flush output.
Definition: application.cpp:74
Class that stores thread messages for each thread, and retrieves them based on the thread id.
Definition: application.h:168
Messages * operator->()
Provide a pointer dereferencing overloaded operator.
Definition: application.cpp:87
threadMsgMap_t m_threadMsgMap
Thread Msg Map.
Definition: application.h:187
map< std::thread::id, pMessages_t > threadMsgMap_t
Typedef for map between a thread and the message.
Definition: application.h:183
void removeThreadMessages()
Remove a local thread message.
Class to hold global data.
Definition: application.h:42
bool warnings_suppressed()
Returns true if warnings should be suppressed.
Definition: application.h:352
void use_legacy_rate_constants(bool legacy=true)
Set definition used for rate constant calculation.
Definition: application.h:383
static Application * s_app
Pointer to the single Application instance.
Definition: application.h:455
void suppress_deprecation_warnings()
Globally disable printing of deprecation warnings.
Definition: application.h:327
vector< string > m_pythonSearchVersions
Versions of Python to consider when attempting to load user extensions.
Definition: application.h:437
bool thermo_warnings_suppressed()
Returns true if thermo warnings should be suppressed.
Definition: application.h:369
void warnlog(const string &warning, const string &msg)
Write a warning message to the screen.
Definition: application.h:315
void make_warnings_fatal()
Turns Cantera warnings into exceptions.
Definition: application.h:358
void setLogger(Logger *logwriter)
Install a logger.
Definition: application.h:393
void make_deprecation_warnings_fatal()
Turns deprecation warnings into exceptions.
Definition: application.h:334
static Application * Instance()
Return a pointer to the one and only instance of class Application.
void addError(const string &r, const string &msg="")
Set an error condition in the application class without throwing an exception.
Definition: application.h:209
void logErrors()
Prints all of the error messages using writelog.
Definition: application.h:234
void loadExtension(const string &extType, const string &name)
Load an extension implementing user-defined models.
void warn_deprecated(const string &method, const string &extra="")
Print a warning indicating that method is deprecated.
void searchPythonVersions(const string &versions)
Set the versions of Python to try when loading user-defined extensions, in order of preference.
bool legacy_rate_constants_used()
Returns true if legacy rate constant definition is used.
Definition: application.h:388
void suppress_warnings()
Globally disable printing of (user) warnings.
Definition: application.h:346
vector< string > inputDirs
Current vector of input directories to search for input files.
Definition: application.h:434
void thread_complete()
Delete and free memory allocated per thread in multithreaded applications.
void writelog(const string &msg)
Write a message to the screen.
Definition: application.h:305
set< string > warnings
Set of deprecation warnings that have been emitted (to suppress duplicates)
Definition: application.h:440
void suppress_thermo_warnings(bool suppress=true)
Globally disable printing of warnings about problematic thermo data, such as NASA polynomials with di...
Definition: application.h:364
shared_ptr< Messages > pMessages_t
Typedef for thread specific messages.
Definition: application.h:163
void getErrors(std::ostream &f)
Prints all of the error messages to an ostream.
Definition: application.h:229
string lastErrorMessage()
Retrieve the last error message in a string.
Definition: application.h:224
int getErrorCount()
Return the number of errors that have been encountered so far.
Definition: application.h:214
virtual ~Application()
Destructor for class deletes global data.
Definition: application.h:203
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:310
static void ApplicationDestroy()
Static function that destroys the application class's data.
void warn(const string &warning, const string &method, const string &extra="")
Generate a general purpose warning; repeated warnings are not suppressed.
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
void addError(const string &r, const string &msg="")
Set an error condition in the application class without throwing an exception.
Definition: application.cpp:45
void logErrors()
Prints all of the error messages using writelog.
void getErrors(std::ostream &f)
Prints all of the error messages to an ostream.
string lastErrorMessage()
Retrieve the last error message in a string.
int getErrorCount()
Return the number of errors that have been encountered so far.
Definition: application.cpp:59
void popError()
Discard the last error message.
string getDataDirectories(const string &sep)
Get the Cantera data directories.
Definition: application.h:279
string findInputFile(const string &name)
Find an input file.
void addDataDirectory(const string &dir)
Add a directory to the data file search path.
void setDefaultDirectories()
Set the default directories for input files.
void warnlog(const string &warning, const string &msg)
Write a warning message to the screen.
Definition: application.cpp:79
void setLogger(Logger *logwriter)
Install a logger.
Definition: application.cpp:64
void writelog(const string &msg)
Write a message to the screen.
Definition: application.cpp:69
Header for Base class for 'loggers' that write text messages to log files (see Logging and class Logg...
Namespace for the Cantera kernel.
Definition: AnyMap.cpp:564