12 #include "../../ext/libexecstream/exec-stream.h" 47 const char* py = getenv(
"PYTHON_CMD");
50 string sp = ba::trim_copy(
string(py));
58 void ct2ctml(
const char* file,
const int debug)
61 string out_name = file;
65 std::replace_if(out_name.begin(), out_name.end(),
66 std::bind2nd(std::equal_to<char>(),
'\\'),
'/');
68 size_t idir = out_name.rfind(
'/');
70 out_name = out_name.substr(idir+1, out_name.size());
72 size_t idot = out_name.rfind(
'.');
74 out_name = out_name.substr(0, idot) +
".xml";
78 std::ofstream out(out_name);
82 static std::string call_ctml_writer(
const std::string& text,
bool isfile)
84 std::string file, arg;
85 bool temp_file_created =
false;
86 std::string temp_cti_file_name = std::tmpnam(
nullptr);
88 if (temp_cti_file_name.find(
'\\') == 0) {
91 temp_cti_file_name =
"." + temp_cti_file_name;
96 arg =
"r'" + text +
"'";
99 arg =
"text=r'''" + text +
"'''";
115 long int max_argv_size = 32768;
117 long int max_argv_size = sysconf(_SC_ARG_MAX);
120 if (text.size() >
static_cast<size_t>(max_argv_size) - 500) {
126 ofstream temp_cti_file(temp_cti_file_name);
129 temp_cti_file << text;
130 file = temp_cti_file_name;
131 arg =
"r'" + file +
"'";
132 temp_file_created =
true;
135 throw CanteraError(
"call_ctml_writer",
"Very long source argument. " 136 "Error creating temporary file '{}'", temp_cti_file_name);
143 throw CanteraError(
"ct2ctml",
144 "python cti to ctml conversion requested for file, " + file +
145 ", but not available in this computational environment");
148 string python_output, error_output;
149 int python_exit_code;
151 exec_stream_t python;
152 python.set_wait_timeout(exec_stream_t::s_all, 1800000);
153 stringstream output_stream, error_stream;
154 std::vector<string> args;
155 args.push_back(
"-c");
158 "from __future__ import print_function\n" 161 " from cantera import ctml_writer\n" 162 "except ImportError:\n" 163 " print('sys.path: ' + repr(sys.path) + '\\n', file=sys.stderr)\n" 165 "ctml_writer.convert(" + arg +
", outName='STDOUT')\n" 168 python.start(
pypath(), args.begin(), args.end());
171 while (python.out().good()) {
172 std::getline(python.out(), line);
173 output_stream << line << std::endl;
181 while (python.err().good()) {
182 std::getline(python.err(), line);
183 error_stream << line << std::endl;
186 python_exit_code = python.exit_code();
187 error_output = ba::trim_copy(error_stream.str());
188 python_output = output_stream.str();
189 }
catch (std::exception& err) {
191 stringstream message;
192 message <<
"Error executing python while converting input file:\n";
193 message <<
"Python command was: '" <<
pypath() <<
"'\n";
194 message << err.what() << std::endl;
195 throw CanteraError(
"ct2ctml_string", message.str());
198 if (python_exit_code != 0) {
200 stringstream message;
201 message <<
"Error converting input file \"" << file <<
"\" to CTML.\n";
202 message <<
"Python command was: '" <<
pypath() <<
"'\n";
203 message <<
"The exit code was: " << python_exit_code <<
"\n";
204 if (error_output.size() > 0) {
205 message <<
"-------------- start of converter log --------------\n";
206 message << error_output << std::endl;
207 message <<
"--------------- end of converter log ---------------";
209 message <<
"The command did not produce any output." << endl;
211 throw CanteraError(
"ct2ctml_string", message.str());
214 if (error_output.size() > 0) {
216 stringstream message;
217 message <<
"Warning: Unexpected output from CTI converter\n";
218 message <<
"-------------- start of converter log --------------\n";
219 message << error_output << std::endl;
220 message <<
"--------------- end of converter log ---------------\n";
224 if (temp_file_created) {
226 bool status = std::remove(temp_cti_file_name.c_str());
228 writelog(
"WARNING: Error removing tmp file {}\n", temp_cti_file_name);
232 return python_output;
237 return call_ctml_writer(file,
true);
242 return call_ctml_writer(cti,
false);
245 void ck2cti(
const std::string& in_file,
const std::string& thermo_file,
246 const std::string& transport_file,
const std::string& id_tag)
251 string ppath = in_file;
253 "python ck to cti conversion requested for file, " + ppath +
254 ", but not available in this computational environment");
257 string python_output;
258 int python_exit_code;
260 exec_stream_t python;
261 python.set_wait_timeout(exec_stream_t::s_all, 1800000);
262 python.start(
pypath(),
"-i");
263 stringstream output_stream;
265 ostream& pyin = python.in();
266 pyin <<
"if True:\n" <<
268 " sys.stderr = sys.stdout\n" <<
270 " from cantera import ck2cti\n" <<
271 " except ImportError:\n" <<
272 " print('sys.path: ' + repr(sys.path))\n" <<
274 " ck2cti.Parser().convertMech(r'" << in_file <<
"',";
275 if (thermo_file !=
"" && thermo_file !=
"-") {
276 pyin <<
" thermoFile=r'" << thermo_file <<
"',";
278 if (transport_file !=
"" && transport_file !=
"-") {
279 pyin <<
" transportFile=r'" << transport_file <<
"',";
281 pyin <<
" phaseName='" << id_tag <<
"',";
282 pyin <<
" permissive=True,";
283 pyin <<
" quiet=True)\n";
284 pyin <<
" sys.exit(0)\n\n";
285 pyin <<
"sys.exit(7)\n";
289 while (python.out().good()) {
290 std::getline(python.out(), line);
291 output_stream << line << std::endl;;
294 python_exit_code = python.exit_code();
295 python_output = ba::trim_copy(output_stream.str());
296 }
catch (std::exception& err) {
298 stringstream message;
299 message <<
"Error executing python while converting input file:\n";
300 message <<
"Python command was: '" <<
pypath() <<
"'\n";
301 message << err.what() << std::endl;
305 if (python_exit_code != 0) {
307 stringstream message;
308 message <<
"Error converting input file \"" << in_file <<
"\" to CTI.\n";
309 message <<
"Python command was: '" <<
pypath() <<
"'\n";
310 message <<
"The exit code was: " << python_exit_code <<
"\n";
311 if (python_output.size() > 0) {
312 message <<
"-------------- start of converter log --------------\n";
313 message << python_output << std::endl;
314 message <<
"--------------- end of converter log ---------------";
316 message <<
"The command did not produce any output." << endl;
321 if (python_output.size() > 0) {
323 stringstream message;
324 message <<
"Warning: Unexpected output from CTI converter\n";
325 message <<
"-------------- start of converter log --------------\n";
326 message << python_output << std::endl;
327 message <<
"--------------- end of converter log ---------------\n";
CTML ("Cantera Markup Language") is the variant of XML that Cantera uses to store data...
const size_t npos
index returned by functions to indicate "no position"
void writelog(const std::string &fmt, const Args &... args)
Write a formatted message to the screen.
void ck2cti(const std::string &in_file, const std::string &thermo_file, const std::string &transport_file, const std::string &id_tag)
Convert a Chemkin-format mechanism into a CTI file.
Base class for exceptions thrown by Cantera classes.
static string pypath()
return the full path to the Python interpreter.
Contains declarations for string manipulation functions within Cantera.
Namespace for the Cantera kernel.