1 /**
2 * @file global.h
3 * This file contains definitions for utility functions and text for modules,
4 * inputfiles, logs, textlogs, (see \ref inputfiles, \ref logs, and
5 * \ref textlogs).
6 *
7 * @ingroup utils
8 *
9 * These functions store some parameters in global storage that are accessible
10 * at all times from the calling application. Contains module definitions for
11 * - inputfiles (see \ref inputfiles)
12 * - logs (see \ref logs)
13 * - textlogs (see \ref textlogs)
14 */
15
16 // This file is part of Cantera. See License.txt in the top-level directory or
17 // at https://cantera.org/license.txt for license and copyright information.
18
19 #ifndef CT_GLOBAL_H
20 #define CT_GLOBAL_H
21
22 #include "ct_defs.h"
23 #include "cantera/base/fmt.h"
24
25 namespace Cantera
26 {
27
28 class XML_Node;
29 class Logger;
30
31 /*!
32 * @defgroup inputfiles Input File Handling
33 *
34 * The properties of phases and interfaces are specified in text files. These
35 * procedures handle various aspects of reading these files.
36 *
37 * For input files not specified by an absolute pathname, %Cantera searches
38 * for input files along a path that includes platform-specific default
39 * locations, and possibly user-specified locations.
40 *
41 * The current directory (".") is always searched first. Then, on Windows, the
42 * registry is checked to find the Cantera installation directory, and the
43 * 'data' subdirectory of the installation directory will be added to the search
44 * path.
45 *
46 * On the Mac, directory '/Applications/Cantera/data' is added to the
47 * search path.
48 *
49 * On any platform, if environment variable CANTERA_DATA is set to a directory
50 * name or a list of directory names separated with the OS-dependent path
51 * separator (i.e. ";" on Windows, ":" elsewhere), then these directories will
52 * be added to the search path.
53 *
54 * Finally, the location where the data files were installed when
55 * %Cantera was built is added to the search path.
56 *
57 * Additional directories may be added by calling function addDirectory.
58 *
59 * There are currently three different types of input files within %Cantera. The
60 * YAML format is new in Cantera 2.5, and replaces both the CTI and CTML (XML)
61 * formats, which are deprecated and will be removed in Cantera 3.0. The scripts
62 * `cti2yaml.py` and `ctml2yaml.py` can be used to convert legacy input files to
63 * the YAML format.
64 *
65 * - YAML: A human-readable input file written using YAML syntax which
66 * defines species, phases, and reactions, and contains thermodynamic,
67 * chemical kinetic, and transport data needed by %Cantera.
68 *
69 * - CTI: A human-readable input file written using Python syntax. Some options
70 * for non-ideal equations of state available in the CTML format have not
71 * been implemented for the CTI format.
72 *
73 * - CTML: This is an XML file laid out in such a way that %Cantera can
74 * interpret the contents directly. Given a file in CTI format, %Cantera will
75 * convert the CTI file into the CTML format on-the-fly using a Python script
76 * (ctml_writer). This process is done in-memory without writing any new
77 * files to disk. Explicit use of the CTML format is not recommended.
78 *
79 * %Cantera provides converters (`ck2yaml` and `ckcti`) for converting
80 * Chemkin-format mechanisms to the YAML and CTI formats, respectively.
81 *
82 * Other input routines in other modules:
83 * @see importKinetics()
84 *
85 * @{
86 */
87
88 //! @copydoc Application::findInputFile
89 std::string findInputFile(const std::string& name);
90
91 //! @copydoc Application::addDataDirectory
92 void addDirectory(const std::string& dir);
93
94 //! @copydoc Application::getDataDirectories
95 std::string getDataDirectories(const std::string& sep);
96 //@}
97
98 //! Delete and free all memory associated with the application
99 /*!
100 * Delete all global data. It should be called at the end of the
101 * application if leak checking is to be done.
102 */
103 void appdelete();
104
105 //! @copydoc Application::thread_complete
106 void thread_complete();
107
108 //! Returns the hash of the git commit from which Cantera was compiled, if known
109 std::string gitCommit();
110
111 //! Returns root directory where %Cantera is installed
112 /*!
113 * @returns a string containing the name of the base directory where %Cantera is
114 * installed. If the environmental variable CANTERA_ROOT is defined, this
115 * function will return its value, preferentially.
116 *
117 * @ingroup inputfiles
118 */
119 std::string canteraRoot();
120
121 /*!
122 * @defgroup logs Diagnostic Output
123 *
124 * Writing diagnostic information to the screen or to a file. It is often
125 * useful to be able to write diagnostic messages to the screen or to a file.
126 * Cantera a set of procedures for this purpose designed to write text messages
127 * to the screen to document the progress of a complex calculation, such as a
128 * flame simulation.
129 */
130
131 /*!
132 * @defgroup textlogs Writing messages to the screen
133 * @ingroup logs
134 */
135
136 //! @copydoc Application::Messages::writelog(const std::string&)
137 void writelog_direct(const std::string& msg);
138
139 //! Write a message to the log only if loglevel > 0
debuglog(const std::string & msg,int loglevel)140 inline void debuglog(const std::string& msg, int loglevel)
141 {
142 if (loglevel > 0) {
143 writelog_direct(msg);
144 }
145 }
146
147 //! Write a formatted message to the screen.
148 //!
149 //! This function passes its arguments to the fmt library 'format' function to
150 //! generate a formatted string from a Python-style (curly braces) format
151 //! string. This method is used throughout Cantera to write log messages. It can
152 //! also be called by user programs. The advantage of using writelog over
153 //! writing directly to the standard output is that messages written with
154 //! writelog will display correctly even when Cantera is used from MATLAB or
155 //! other application that do not have a standard output stream.
156 //! @ingroup textlogs
157 template <typename... Args>
writelog(const std::string & fmt,const Args &...args)158 void writelog(const std::string& fmt, const Args&... args) {
159 if (sizeof...(args) == 0) {
160 writelog_direct(fmt);
161 } else {
162 writelog_direct(fmt::format(fmt, args...));
163 }
164 }
165
166 //! Write a formatted message to the screen
167 /*!
168 * Using the printf formatting of C, write a message to the screen
169 * with variable values.
170 *
171 * Here, we format an internal string with the correct values
172 * and then feed it into writelog().
173 *
174 * @param fmt c format string for the following arguments
175 * @param args arguments used to interpolate the format string
176 * @ingroup textlogs
177 */
178 template <typename... Args>
writelogf(const char * fmt,const Args &...args)179 void writelogf(const char* fmt, const Args& ... args) {
180 writelog_direct(fmt::sprintf(fmt, args...));
181 }
182
183 //! Write an end of line character to the screen and flush output
184 void writelogendl();
185
186 void writeline(char repeat, size_t count,
187 bool endl_after=true, bool endl_before=false);
188
189 //! @copydoc Application::warn_deprecated
190 void warn_deprecated(const std::string& method, const std::string& extra="");
191
192 //! @copydoc Application::suppress_deprecation_warnings
193 void suppress_deprecation_warnings();
194
195 //! helper function passing user warning to global handler
196 void _warn_user(const std::string& method, const std::string& extra);
197
198 /*!
199 * Print a user warning raised from *method*.
200 *
201 * @param method method name
202 * @param msg Python-style format string with the following arguments
203 * @param args arguments for the format string
204 */
205 template <typename... Args>
warn_user(const std::string & method,const std::string & msg,const Args &...args)206 void warn_user(const std::string& method, const std::string& msg,
207 const Args&... args) {
208 if (sizeof...(args) == 0) {
209 _warn_user(method, msg);
210 } else {
211 _warn_user(method, fmt::format(msg, args...));
212 }
213 }
214
215 //! @copydoc Application::make_deprecation_warnings_fatal
216 void make_deprecation_warnings_fatal();
217
218 //! @copydoc Application::suppress_thermo_warnings
219 void suppress_thermo_warnings(bool suppress=true);
220
221 //! @copydoc Application::thermo_warnings_suppressed
222 bool thermo_warnings_suppressed();
223
224 //! @copydoc Application::use_legacy_rate_constants
225 void use_legacy_rate_constants(bool legacy=true);
226
227 //! @copydoc Application::legacy_rate_constants_used
228 bool legacy_rate_constants_used();
229
230 //! @copydoc Application::Messages::setLogger
231 void setLogger(Logger* logwriter);
232
233 //! Return the conversion factor to convert unit std::string 'unit'
234 //! to SI units.
235 /*!
236 * @param unit String containing the units
237 */
238 doublereal toSI(const std::string& unit);
239
240 /// Return the conversion factor to convert activation energy unit
241 /// std::string 'unit' to Kelvin.
242 /*!
243 * @param unit String containing the activation energy units
244 */
245 doublereal actEnergyToSI(const std::string& unit);
246
247 //! @copydoc Application::get_XML_File
248 XML_Node* get_XML_File(const std::string& file, int debug = 0);
249
250 //! @copydoc Application::get_XML_from_string
251 XML_Node* get_XML_from_string(const std::string& text);
252
253 //! @copydoc Application::close_XML_File
254 void close_XML_File(const std::string& file);
255
256 //! This routine will locate an XML node in either the input
257 //! XML tree or in another input file specified by the file
258 //! part of the file_ID string.
259 /*!
260 * Searches are based on the ID attribute of the XML element only.
261 *
262 * @param file_ID This is a concatenation of two strings separated by the "#"
263 * character. The string before the pound character is the file
264 * name of an XML file to carry out the search. The string after
265 * the # character is the ID attribute of the XML element to
266 * search for. The string is interpreted as a file string if no #
267 * character is in the string.
268 * @param root If the file string is empty, searches for the XML element with
269 * matching ID attribute are carried out from this XML node.
270 * @returns the XML_Node, if found. Returns null if not found.
271 *
272 * @deprecated The XML input format is deprecated and will be removed in
273 * Cantera 3.0.
274 */
275 XML_Node* get_XML_Node(const std::string& file_ID, XML_Node* root);
276
277
278 //! This routine will locate an XML node in either the input XML tree or in
279 //! another input file specified by the file part of the file_ID string.
280 /*!
281 * Searches are based on the XML element name and the ID attribute of the XML
282 * element. An exact match of both is usually required. However, the ID
283 * attribute may be set to "", in which case the first XML element with the
284 * correct element name will be returned.
285 *
286 * @param nameTarget This is the XML element name to look for.
287 * @param file_ID This is a concatenation of two strings separated by the "#"
288 * character. The string before the pound character is the file
289 * name of an XML file to carry out the search. The string after
290 * the # character is the ID attribute of the XML element to
291 * search for. The string is interpreted as a file string if no #
292 * character is in the string.
293 * @param root If the file string is empty, searches for the XML element with
294 * matching ID attribute are carried out from this XML node.
295 * @returns the XML_Node, if found. Returns null if not found.
296 *
297 * @deprecated The XML input format is deprecated and will be removed in
298 * Cantera 3.0.
299 */
300 XML_Node* get_XML_NameID(const std::string& nameTarget,
301 const std::string& file_ID,
302 XML_Node* root);
303
304 //! Clip *value* such that lower <= value <= upper
305 template <class T>
clip(const T & value,const T & lower,const T & upper)306 inline T clip(const T& value, const T& lower, const T& upper)
307 {
308 return std::max(lower, std::min(upper, value));
309 }
310
311 //! Sign of a number. Returns -1 if x < 0, 1 if x > 0 and 0 if x == 0.
sign(T x)312 template <typename T> int sign(T x) {
313 return (T(0) < x) - (x < T(0));
314 }
315
316 }
317
318 #endif
319