///////////////////////////////////////////////////////////// // // reaction path diagrams // // $Author$ // $Revision$ // $Date$ // // copyright California Institute of Technology 2002 // ///////////////////////////////////////////////////////////// // turn off warnings under Windows #ifdef WIN32 #pragma warning(disable:4786) #pragma warning(disable:4503) #endif #include #include #include #include "example_utils.h" #include #include // #include // using namespace std; void writeRxnPathDiagram(double time, ReactionPathBuilder& b, IdealGasMix& gas, ostream& logfile, ostream& outfile) { // create a new empty diagram ReactionPathDiagram d; // show the details of which reactions contribute to the flux d.show_details = false; // set the threshold for the minimum flux relative value that will // be plotted d.threshold = 0.001; // color for bold lines d.bold_color = "orange"; // color for normal-weight lines d.normal_color = "steelblue"; // color for dashed lines d.dashed_color = "gray"; // options for the 'dot' program d.dot_options = "center=1;size=\"6,9\";ratio=auto"; // minimum relative flux for bold lines d.bold_min = 0.0; // maximum relative flux for dashed lines d.dashed_max = 0.01; // minimum relative flux for labels d.label_min = 0.01; // autoscale d.scale = -1; // set to either NetFlow or OneWayFlow d.flow_type = NetFlow; //OneWayFlow; // arrow width. If < 0, then scale with flux value d.arrow_width = -2.0; // title d.title = "time = "+fp2str(time)+" (s)"; // build the diagram following elemental nitrogen b.build(gas, "N", logfile, d); // write an input file for 'dot' d.exportToDot(outfile); } int rxnpath_example1(int job) { try { cout << "Reaction path diagram movies with file gri30.cti." << endl; if (job >= 1) { cout << "Generate reaction path diagrams following nitrogen\n" << "as a function of time for constant-pressure ignition of a\n" << "hydrogen/oxygen/nitrogen" " mixture \nbeginning at T = 1001 K and P = 1 atm." << endl; } if (job < 2) return 0; // header writeCanteraHeader(cout); // create an ideal gas mixture that corresponds to GRI-Mech // 3.0 IdealGasMix gas("gri30.cti", "gri30"); gas.setState_TPX(1001.0, OneAtm, "H2:2.0, O2:1.0, N2:4.0"); int nsp = gas.nSpecies(); // create a reactor Reactor r; // create a reservoir to represent the environment Reservoir env; // specify the thermodynamic property and kinetics managers r.setThermoMgr(gas); r.setKineticsMgr(gas); env.setThermoMgr(gas); // create a flexible, insulating wall between the reactor and the // environment Wall w; w.install(r,env); // set the "Vdot coefficient" to a large value, in order to // approach the constant-pressure limit; see the documentation // for class Reactor w.setExpansionRateCoeff(1.e9); w.setArea(1.0); double tm; double dt = 1.e-5; // interval at which output is written int nsteps = 100; // number of intervals // create a container object to run the simulation // and add the reactor to it ReactorNet sim; sim.addReactor(&r); // create a reaction path diagram builder ReactionPathBuilder b; ofstream rplog("rp1.log"); // log file ofstream rplot("rp1.dot"); // output file b.init(rplog, gas); // initialize // main loop clock_t t0 = clock(); for (int i = 1; i <= nsteps; i++) { tm = i*dt; sim.advance(tm); writeRxnPathDiagram(tm, b, gas, rplog, rplot); } clock_t t1 = clock(); // print final temperature and timing data doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC; cout << " time = " << tmm << endl; cout << "Output files:" << endl << " rp1.log (log file)" << endl << " rp1.dot (input file for dot)" << endl; cout << "To generate the diagrams in Postscript, execute the command" << endl << endl << "dot -Tps rp1.dot > rp1.ps" << endl << endl << "Get dot for Windows here: http://blue.caltech.edu/dot.exe" << endl; return 0; } // handle exceptions thrown by Cantera catch (CanteraError) { showErrors(cout); cout << " terminating... " << endl; appdelete(); return -1; } }