00001 /** 00002 * @file global.h 00003 * This file contains definitions for utility functions and text for modules, 00004 * inputfiles, logs, textlogs, HTML_logs (see \ref inputfiles, \ref logs, 00005 * \ref textlogs and \ref HTML_logs). 00006 * 00007 * @ingroup utils 00008 * 00009 * These functions store 00010 * some parameters in global storage that are accessible at all times 00011 * from the calling application. 00012 * Contains module definitions for 00013 * - inputfiles (see \ref inputfiles) 00014 * - logs (see \ref logs) 00015 * - textlogs (see \ref textlogs) 00016 * - HTML_logs (see \ref HTML_logs) 00017 */ 00018 00019 /* 00020 * $Revision: 368 $ 00021 * $Date: 2010-01-03 19:46:26 -0500 (Sun, 03 Jan 2010) $ 00022 */ 00023 00024 // Copyright 2001 California Institute of Technology 00025 00026 #ifndef CT_GLOBAL_H 00027 #define CT_GLOBAL_H 00028 00029 #include "ct_defs.h" 00030 00031 namespace Cantera { 00032 00033 class XML_Node; 00034 class Logger; 00035 00036 //! Return the number of errors that have been encountered so far 00037 /*! 00038 * @ingroup errorhandling 00039 */ 00040 int nErrors(); 00041 00042 //! Returns the last error message 00043 /*! 00044 * @return String containing the description of the last error 00045 * message. 00046 * 00047 * @ingroup errorhandling 00048 */ 00049 std::string lastErrorMessage(); 00050 00051 //! Set an error condition in the application class without throwing an exception. 00052 /*! 00053 * This routine adds an error message to the end of the stack 00054 * of errors that Cantera accumulates in the Application 00055 * class. 00056 * @param r Procedure name which is generating the error condition 00057 * @param msg Descriptive message of the error condition. 00058 * 00059 * @ingroup errorhandling 00060 */ 00061 void setError(std::string r, std::string msg); 00062 00063 //! Prints all of the error messages to an ostream 00064 /*! 00065 * Write out all of the saved error messages to the ostream f 00066 * using the member function writelog of class logger. 00067 * Cantera saves a stack of exceptions that it 00068 * has caught in the Application class. This routine writes 00069 * out all of the error messages to the ostream 00070 * and then clears them from internal storage. 00071 * 00072 * @param f ostream which will receive the error messages 00073 * 00074 * \ingroup errorhandling 00075 */ 00076 void showErrors(std::ostream& f); 00077 00078 //! Print all of the error messages using function writelog of class logger. 00079 /*! 00080 * Print all of the error messages 00081 * using the member function writelog of class logger. 00082 * Write out all of the saved error messages to the log device. 00083 * Cantera saves a stack of exceptions that it 00084 * has caught in the Application class. This routine writes 00085 * out all of the error messages to the log, usually stdout, 00086 * and then clears them from internal storage. 00087 * 00088 * \ingroup errorhandling 00089 */ 00090 void showErrors(); 00091 00092 //! Discard the last error message 00093 /*! 00094 * %Cantera saves a stack of exceptions that it 00095 * has caught in the Application class. This routine eliminates 00096 * the last exception to be added to that stack. 00097 * 00098 * \ingroup errorhandling 00099 */ 00100 void popError(); 00101 00102 /*! 00103 * @defgroup inputfiles Input File Handling 00104 * 00105 * The properties of phases and interfaces are specified in 00106 * text files. These procedures handle various aspects of reading 00107 * these files. 00108 * 00109 * For input files not specified by an absolute pathname, 00110 * %Cantera searches 00111 * for input files along a path that includes platform-specific 00112 * default locations, and possibly user-specified locations. 00113 * 00114 * The current directory (".") is always searched first. Then, on 00115 * Windows platforms, if environment variable COMMONPROGRAMFILES 00116 * is set (which it should be on Win XP or Win 2000), then 00117 * directories under this one will be added to the search 00118 * path. The %Cantera Windows installer installs data files to this 00119 * location. 00120 * 00121 * On the Mac, directory '/Applications/Cantera/data' is added to the 00122 * search path. 00123 * 00124 * On any platform, if environment variable CANTERA_DATA is set to a 00125 * directory name, then this directory is added to the search path. 00126 * 00127 * Finally, the location where the data files were installed when 00128 * %Cantera was built is added to the search path. 00129 * 00130 * Additional directories may be added by calling function addDirectory. 00131 * 00132 * There are two different types of input files within %Cantera: 00133 * ctml: This is an xml file layed out in such a way that %Cantera can 00134 * interpret the contents. 00135 * cti: A human-readable ascii format for information that %Cantera 00136 * will read. 00137 * 00138 * %Cantera can take its input from both types of files. However, given 00139 * a file in cti format, the initial operation that %Cantera will perform 00140 * is to translate the cti file into a ctml file. 00141 * The translation is carried out via a system call to a python interpretor 00142 * program that actually carries out the translation. In general, a new 00143 * ctml file is created by the translation that is written to the current 00144 * local directory. 00145 * The ctml file is then read back into %Cantera as the input. 00146 * 00147 * Other input routines in other modules: 00148 * @see importKinetics() 00149 * 00150 * @{ 00151 */ 00152 00153 //! Find an input file. 00154 /*! 00155 * This routine will search for a file in the default 00156 * locations specified for the application. 00157 * See the routine setDefaultDirectories() listed above. 00158 * 00159 * The default set of directories specified for the application 00160 * will be searched if a '/' or an '\\' is found in the 00161 * name. If either is found then a relative path name is 00162 * presumed, and the default directories are not searched. 00163 * 00164 * The presence of the file is determined by whether the file 00165 * can be opened for reading by the current user. 00166 * 00167 * @param name Name of the input file to be searched for 00168 * 00169 * @return 00170 * 00171 * The absolute path name of the first matching 00172 * file is returned. If a relative path name 00173 * is indicated, the relative path name is returned. 00174 * 00175 * If the file is not found, a message is written to 00176 * stdout and a CanteraError exception is thrown. 00177 * 00178 * @ingroup inputfiles 00179 */ 00180 std::string findInputFile(std::string name); 00181 00182 //! Add a directory to the input file search path. 00183 /*! 00184 * @ingroup inputfiles 00185 * 00186 * @param dir String name for the directory to be added to the search path 00187 */ 00188 void addDirectory(std::string dir); 00189 00190 //@} 00191 00192 //! Delete and free all memory associated with the application 00193 /*! 00194 * Delete all global data. It should be called at the end of the 00195 * application if leak checking is to be done. 00196 */ 00197 void appdelete(); 00198 00199 //! Delete and free memory allocated per thread in multithreaded applications 00200 /*! 00201 * Delete the memory allocated per thread by Cantera. It should be called from 00202 * within the thread just before the thread terminates. If your version of Cantera has not 00203 * been specifically compiled for thread safety this function does nothing. 00204 */ 00205 void thread_complete() ; 00206 00207 //! Returns root directory where %Cantera where installed 00208 /*! 00209 * @return 00210 * Returns a string containing the name of the base directory where %Cantera is installed. 00211 * If the environmental variable CANTERA_ROOT is defined, this function will 00212 * return its value, preferentially. 00213 * 00214 * @ingroup inputfiles 00215 */ 00216 std::string canteraRoot(); 00217 00218 //! Sets the temporary file directory. 00219 /*! 00220 * The default is to use the 00221 * directory specified by enviroment variable TMP or TEMP. If neither 00222 * of these are defined, then the current working directory will be 00223 * used for temporary files. Call this function to specify some other 00224 * place to put temporary files. 00225 * 00226 * @ingroup inputfiles 00227 * 00228 * @param tmp String name for the temporary directory 00229 */ 00230 void setTmpDir(std::string tmp); 00231 00232 //! Retrieves the directory name where temporary files are created 00233 /*! 00234 * @ingroup inputfiles 00235 * @return 00236 * Returns a string containing the directory name 00237 */ 00238 std::string tmpDir(); 00239 00240 //! Delay time in seconds. 00241 /*! 00242 * @return 00243 * Returns the length of time in seconds for calls to the 00244 * sleep function. 00245 * @ingroup inputfiles 00246 */ 00247 std::string sleep(); 00248 00249 /*! 00250 * @defgroup logs Diagnostic Output 00251 * 00252 * Writing diagnostic information to the screen or to a file. 00253 * It is often useful to be able to write diagnostic messages to 00254 * the screen or to a file. Cantera provides two sets of 00255 * procedures for this purpose. The first set is designed to 00256 * write text messages to the screen to document the progress of 00257 * a complex calculation, such as a flame simulation.The second 00258 * set writes nested lists in HTML format. This is useful to 00259 * print debugging output for a complex calculation that calls 00260 * many different procedures. 00261 */ 00262 00263 /*! 00264 * @defgroup textlogs Writing messages to the screen 00265 * @ingroup logs 00266 */ 00267 00268 00269 //! Write a message to the screen. 00270 /*! 00271 * The string may be of any 00272 * length, and may contain end-of-line characters. This method is 00273 * used throughout Cantera to write log messages. It can also be 00274 * called by user programs. The advantage of using writelog over 00275 * writing directly to the standard output is that messages 00276 * written with writelog will display correctly even when Cantera 00277 * is used from MATLAB or other application that do not have a 00278 * standard output stream. 00279 * 00280 * This routine is part of the interface suite whose behavior changes 00281 * with the interface. The interface suite has been moved to the 00282 * class logger and inherited classes of logger. 00283 * 00284 * @param msg String message to be written to the screen 00285 * @ingroup textlogs 00286 */ 00287 void writelog(const std::string& msg); 00288 00289 00290 //! Write a message to the screen. 00291 /*! 00292 * The string may be of any 00293 * length, and may contain end-of-line characters. This method is 00294 * used throughout %Cantera to write log messages. 00295 * 00296 * This routine is part of the interface suite whose behavior changes 00297 * with the interface. The interface suite has been moved to the 00298 * class logger and inherited classes of logger. 00299 * 00300 * @param msg c character string to be written to the screen 00301 * @ingroup textlogs 00302 */ 00303 void writelog(const char* msg); 00304 00305 //! Write a formatted message to the screen 00306 /*! 00307 * Using the printf formatting of C, write a message to the screen 00308 * with variable values. 00309 * 00310 * Here, we format an internal string with the correct values 00311 * and then feed it into writelog(). 00312 * 00313 * @param fmt c format string for the following arguments 00314 * @ingroup textlogs 00315 */ 00316 void writelogf(const char* fmt,...); 00317 00318 //! Write an end of line character to the screen and flush output 00319 /*! 00320 * Some implementations differentiate between \n and endl in 00321 * terms of when the output is flushed. 00322 */ 00323 void writelogendl(); 00324 00325 //! Write an error message and terminate execution. 00326 /*! 00327 * This routine is part of the interface suite whose behavior changes 00328 * with the interface. The interface suite has been moved to the 00329 * class logger and inherited classes of logger. 00330 * 00331 * @param msg Error message to be written to the screen. 00332 * @ingroup textlogs 00333 */ 00334 void error(const std::string& msg); 00335 00336 //! returns 1 for MATLAB, 2 for Python, and 0 for C++ or Fortran. 00337 /*! 00338 * This routine is part of the interface suite whose behavior changes 00339 * with the interface. The interface suite has been moved to the 00340 * class logger and inherited classes of logger. 00341 * 00342 * @ingroup textlogs 00343 */ 00344 int userInterface(); 00345 00346 //! Install a logger. 00347 /*! 00348 * Called by the language interfaces to install an appropriate logger. 00349 * The logger is used for the writelog() function 00350 * 00351 * @param logwriter Pointer to a logger object 00352 * @see Logger. 00353 * @ingroup textlogs 00354 */ 00355 void setLogger(Logger* logwriter); 00356 00357 //! Return the conversion factor to convert unit std::string 'unit' 00358 //! to SI units. 00359 /*! 00360 * @param unit String containing the units 00361 */ 00362 doublereal toSI(std::string unit); 00363 00364 /// Return the conversion factor to convert activation energy unit 00365 /// std::string 'unit' to Kelvin. 00366 /*! 00367 * @param unit String containing the activation energy units 00368 */ 00369 doublereal actEnergyToSI(std::string unit); 00370 00371 /// Return a pointer to the XML tree for a Cantera input file. 00372 /*! 00373 * This routine will find the file and read the XML file into an 00374 * XML tree structure. Then, a pointer will be returned. If the 00375 * file has already been processed, then just the pointer will 00376 * be returned. 00377 * 00378 * @param file String containing the relative or absolute file name 00379 * @param debug Debug flag 00380 */ 00381 XML_Node* get_XML_File(std::string file, int debug = 0); 00382 00383 /// Close a Cantera input file. 00384 /*! 00385 * @param file String containing the relative or absolute file name 00386 */ 00387 void close_XML_File(std::string file); 00388 00389 00390 #ifdef WITH_HTML_LOGS 00391 00392 /*! 00393 * @defgroup HTML_logs Writing HTML Logfiles 00394 * @ingroup logs 00395 * 00396 * These functions are designed to allow writing HTML diagnostic 00397 * messages in a manner that allows users to control how much 00398 * diagnostic output to print. It works like this: Suppose you 00399 * have function A that invokes function B that invokes function 00400 * C. You want to be able to print diagnostic messages just from 00401 * function A, or from A and B, or from A, B, and C, or to turn 00402 * off printing diagnostic messages altogether. All you need to 00403 * do is call 'beginLogGroup' within function A, and specify a 00404 * loglevel value. Then in B, call beginLogGroup again, but 00405 * without an explicit value for loglevel. By default, the 00406 * current level is decremented by one in beginLogGroup. If it 00407 * is <= 0, no log messages are written. Thus, if each function 00408 * begins with beginLogGroup and calls endLogGroup before 00409 * returning, then setting loglevel = 3 will cause messages from 00410 * A, B, and C to be written (in nested HTML lists), loglevel = 00411 * 2 results in messages only being written from A and B, etc. 00412 */ 00413 //@{ 00414 //@} 00415 00416 00417 //!Create a new group for log messages. 00418 /*! 00419 * Usually this is called 00420 * upon entering the function, with the title parameter equal to 00421 * the name of the function or method. Subsequent messages 00422 * written with addLogEntry will appear grouped under this 00423 * heading, until endLogGroup() is called. 00424 * 00425 * @param title String name of the LogGroup 00426 * @param loglevel loglevel of the group. 00427 * @ingroup HTML_logs 00428 */ 00429 void beginLogGroup(std::string title, int loglevel=-99); 00430 00431 //! Add an entry to an HTML log file. 00432 /*! 00433 * Entries appear in the form "tag:value". 00434 * 00435 * @param tag tag 00436 * @param value string value 00437 * 00438 * @ingroup HTML_logs 00439 */ 00440 void addLogEntry(std::string tag, std::string value); 00441 00442 //! Add an entry to an HTML log file. 00443 /*! 00444 * Entries appear in the form "tag:value". 00445 * 00446 * @param tag tag 00447 * @param value double value 00448 * 00449 * @ingroup HTML_logs 00450 */ 00451 void addLogEntry(std::string tag, doublereal value); 00452 00453 //! Add an entry to an HTML log file. 00454 /*! 00455 * Entries appear in the form "tag:value". 00456 * 00457 * @param tag tag 00458 * @param value int value 00459 * 00460 * @ingroup HTML_logs 00461 */ 00462 void addLogEntry(std::string tag, int value); 00463 00464 //! Add an entry msg string to an HTML log file. 00465 /*! 00466 * Add a message string to the HTML log file 00467 * 00468 * @param msg string mesg 00469 * 00470 * @ingroup HTML_logs 00471 */ 00472 void addLogEntry(std::string msg); 00473 00474 //! Close the current group of log messages. 00475 /*! 00476 * This is typically 00477 * called just before leaving a function or method, to close the 00478 * group of messages that were output from this 00479 * function. Subsequent messages written with addLogEntry() will 00480 * appear at the next-higher level in the outline, unless 00481 * beginLogGroup() is called first to create a new group. 00482 * 00483 * @param title Name of the log group. It defaults to the most recent 00484 * log group created. 00485 * @ingroup HTML_logs 00486 */ 00487 void endLogGroup(std::string title=""); 00488 00489 //! Write the HTML log file. 00490 /*! 00491 * Log entries are stored in memory in 00492 * an XML tree until this function is called, which writes the 00493 * tree to a file and clears the entries stored in memory. The 00494 * output file will have the name specified in the 'file' 00495 * argument. If this argument has no extension, the extension 00496 * '.html' will be appended. Also, if the file already exists, an 00497 * integer will be appended to the name so that no existing log 00498 * file will be overwritten. 00499 * WITH_HTML_LOGS must be defined. 00500 * 00501 * @param file Name of the file to be written 00502 * @ingroup HTML_logs 00503 */ 00504 void write_logfile(std::string file = "log.html"); 00505 00506 #else 00507 inline void beginLogGroup(std::string title, int loglevel=-99) {} 00508 inline void addLogEntry(std::string tag, std::string value) {} 00509 inline void addLogEntry(std::string tag, doublereal value) {} 00510 inline void addLogEntry(std::string tag, int value) {} 00511 inline void addLogEntry(std::string msg) {} 00512 inline void endLogGroup(std::string title="") {} 00513 inline void write_logfile(std::string file = "log.html") {} 00514 #endif 00515 00516 00517 //! This routine will locate an XML node in either the input 00518 //! XML tree or in another input file specified by the file 00519 //! part of the file_ID string. 00520 /*! 00521 * Searches are based on the 00522 * ID attribute of the XML element only. 00523 * 00524 * @param file_ID This is a concatenation of two strings seperated 00525 * by the "#" character. The string before the 00526 * pound character is the file name of an xml 00527 * file to carry out the search. The string after 00528 * the # character is the ID attribute 00529 * of the xml element to search for. 00530 * The string is interpreted as a file string if 00531 * no # character is in the string. 00532 * 00533 * @param root If the file string is empty, searches for the 00534 * xml element with matching ID attribute are 00535 * carried out from this XML node. 00536 * 00537 * @return 00538 * Returns the XML_Node, if found. Returns null if not found. 00539 */ 00540 XML_Node* get_XML_Node(const std::string& file_ID, XML_Node* root); 00541 00542 00543 //! This routine will locate an XML node in either the input 00544 //! XML tree or in another input file specified by the file 00545 //! part of the file_ID string. 00546 /*! 00547 * Searches are based on the 00548 * XML element name and the ID attribute of the XML element. 00549 * An exact match of both is usually required. However, the 00550 * ID attribute may be set to "", in which case the first 00551 * xml element with the correct element name will be returned. 00552 * 00553 * @param nameTarget This is the XML element name to look for. 00554 * 00555 * @param file_ID This is a concatenation of two strings seperated 00556 * by the "#" character. The string before the 00557 * pound character is the file name of an xml 00558 * file to carry out the search. The string after 00559 * the # character is the ID attribute 00560 * of the xml element to search for. 00561 * The string is interpreted as a file string if 00562 * no # character is in the string. 00563 * 00564 * @param root If the file string is empty, searches for the 00565 * xml element with matching ID attribute are 00566 * carried out from this XML node. 00567 * 00568 * @return 00569 * Returns the XML_Node, if found. Returns null if not found. 00570 */ 00571 XML_Node* get_XML_NameID(const std::string& nameTarget, 00572 const std::string& file_ID, 00573 XML_Node* root); 00574 } 00575 00576 #endif 00577