Exemple #1
0
void runexample()
{
    // use reaction mechanism GRI-Mech 3.0
    IdealGasMix gas("gri30.cti", "gri30");

    // create a reservoir for the fuel inlet, and set to pure methane.
    Reservoir fuel_in;
    gas.setState_TPX(300.0, OneAtm, "CH4:1.0");
    fuel_in.insert(gas);
    double fuel_mw = gas.meanMolecularWeight();

    // create a reservoir for the air inlet
    Reservoir air_in;
    IdealGasMix air("air.cti");
    gas.setState_TPX(300.0, OneAtm, "N2:0.78, O2:0.21, AR:0.01");
    double air_mw = air.meanMolecularWeight();
    air_in.insert(gas);

    // to ignite the fuel/air mixture, we'll introduce a pulse of radicals.
    // The steady-state behavior is independent of how we do this, so we'll
    // just use a stream of pure atomic hydrogen.
    gas.setState_TPX(300.0, OneAtm, "H:1.0");
    Reservoir igniter;
    igniter.insert(gas);


    // create the combustor, and fill it in initially with N2
    gas.setState_TPX(300.0, OneAtm, "N2:1.0");
    Reactor combustor;
    combustor.insert(gas);
    combustor.setInitialVolume(1.0);


    // create a reservoir for the exhaust. The initial composition
    // doesn't matter.
    Reservoir exhaust;
    exhaust.insert(gas);


    // lean combustion, phi = 0.5
    double equiv_ratio = 0.5;

    // compute fuel and air mass flow rates
    double factor = 0.1;
    double air_mdot = factor*9.52*air_mw;
    double fuel_mdot = factor*equiv_ratio*fuel_mw;

    // create and install the mass flow controllers. Controllers
    // m1 and m2 provide constant mass flow rates, and m3 provides
    // a short Gaussian pulse only to ignite the mixture
    MassFlowController m1;
    m1.install(fuel_in, combustor);
    m1.setMassFlowRate(fuel_mdot);

    // Now create the air mass flow controller.  Note that this connects
    // two reactors with different reaction mechanisms and different
    // numbers of species. Downstream and upstream species are matched by
    // name.
    MassFlowController m2;
    m2.install(air_in, combustor);
    m2.setMassFlowRate(air_mdot);


    // The igniter will use a Gaussian 'functor' object to specify the
    // time-dependent igniter mass flow rate.
    double A = 0.1;
    double FWHM = 0.2;
    double t0 = 0.5;
    Gaussian igniter_mdot(A, t0, FWHM);

    MassFlowController m3;
    m3.install(igniter, combustor);
    m3.setFunction(&igniter_mdot);

    // put a valve on the exhaust line to regulate the pressure
    Valve v;
    v.install(combustor, exhaust);
    double Kv = 1.0;
    v.setParameters(1, &Kv);

    // the simulation only contains one reactor
    ReactorNet sim;
    sim.addReactor(combustor);

    // take single steps to 6 s, writing the results to a CSV file
    // for later plotting.
    double tfinal = 1.0;
    double tnow = 0.0;
    double tres;

    std::ofstream f("combustor_cxx.csv");
    std::vector<size_t> k_out {
        gas.speciesIndex("CH4"),
        gas.speciesIndex("O2"),
        gas.speciesIndex("CO2"),
        gas.speciesIndex("H2O"),
        gas.speciesIndex("CO"),
        gas.speciesIndex("OH"),
        gas.speciesIndex("H"),
        gas.speciesIndex("C2H6")
    };

    while (tnow < tfinal) {
        tnow += 0.005;
        sim.advance(tnow);
        tres = combustor.mass()/v.massFlowRate();
        f << tnow << ", "
          << combustor.temperature() << ", "
          << tres << ", ";
        ThermoPhase& c = combustor.contents();
        for (size_t i = 0; i < k_out.size(); i++) {
            f << c.moleFraction(k_out[i]) << ", ";
        }
        f << std::endl;
    }
    f.close();
}
Exemple #2
0
int kinetics1(int np, void* p)
{
    cout << "Constant-pressure ignition of a "
         << "hydrogen/oxygen/nitrogen"
         " mixture \nbeginning at T = 1001 K and P = 1 atm." << endl;

    // create an ideal gas mixture that corresponds to GRI-Mech 3.0
    IdealGasMix gas("gri30.cti", "gri30");

    // set the state
    gas.setState_TPX(1001.0, OneAtm, "H2:2.0, O2:1.0, N2:4.0");
    int nsp = gas.nSpecies();

    // create a reactor
    IdealGasConstPressureReactor r;

    // 'insert' the gas into the reactor and environment.  Note
    // that it is ok to insert the same gas object into multiple
    // reactors or reservoirs. All this means is that this object
    // will be used to evaluate thermodynamic or kinetic
    // quantities needed.
    r.insert(gas);

    double dt = 1.e-5; // interval at which output is written
    int nsteps = 100; // number of intervals

    // create a 2D array to hold the output variables,
    // and store the values for the initial state
    Array2D soln(nsp+4, 1);
    saveSoln(0, 0.0, gas, soln);

    // create a container object to run the simulation
    // and add the reactor to it
    ReactorNet sim;
    sim.addReactor(r);

    // main loop
    clock_t t0 = clock(); // save start time
    for (int i = 1; i <= nsteps; i++) {
        double tm = i*dt;
        sim.advance(tm);
        cout << "time = " << tm << " s" << endl;
        saveSoln(tm, gas, soln);
    }
    clock_t t1 = clock(); // save end time


    // make a Tecplot data file and an Excel spreadsheet
    std::string plotTitle = "kinetics example 1: constant-pressure ignition";
    plotSoln("kin1.dat", "TEC", plotTitle, gas, soln);
    plotSoln("kin1.csv", "XL", plotTitle, gas, soln);


    // print final temperature and timing data
    doublereal tmm = 1.0*(t1 - t0)/CLOCKS_PER_SEC;
    cout << " Tfinal = " << r.temperature() << endl;
    cout << " time = " << tmm << endl;
    cout << " number of residual function evaluations = "
         << sim.integrator().nEvals() << endl;
    cout << " time per evaluation = " << tmm/sim.integrator().nEvals()
         << endl << endl;
    cout << "Output files:" << endl
         << "  kin1.csv    (Excel CSV file)" << endl
         << "  kin1.dat    (Tecplot data file)" << endl;

    return 0;
}
int kinetics_example1(int job)
{
    try {

        cout << "Ignition simulation using class IdealGasMix "
             << "with file gri30.cti."
             << endl;

        if (job >= 1) {
            cout << "Constant-pressure ignition of a "
                 << "hydrogen/oxygen/nitrogen"
                 " mixture \nbeginning at T = 1001 K and P = 1 atm." << endl;
        }
        if (job < 2) {
            return 0;
        }

        // create an ideal gas mixture that corresponds to GRI-Mech
        // 3.0
        IdealGasMix gas("gri30.xml", "gri30");

        // set the state
        gas.setState_TPX(1001.0, OneAtm, "H2:2.0, O2:1.0, N2:4.0");
        size_t kk = 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);

        // create a container object to run the simulation
        // and add the reactor to it
        ReactorNet sim;
        sim.setVerbose(false);
        sim.addReactor(r);

        double tm;
        double dt = 1.e-5;    // interval at which output is written
        int nsteps = 100;     // number of intervals

        // create a 2D array to hold the output variables,
        // and store the values for the initial state
        Array2D soln(kk+4, 1);
        saveSoln(0, 0.0, gas, soln);

        // main loop
        for (int i = 1; i <= nsteps; i++) {
            tm = i*dt;
            sim.advance(tm);
            saveSoln(tm, gas, soln);
        }

        // make a Tecplot data file and an Excel spreadsheet
        string plotTitle = "kinetics example 1: constant-pressure ignition";
        plotSoln("kin1.dat", "TEC", plotTitle, gas, soln);
        plotSoln("kin1.csv", "XL", plotTitle, gas, soln);

        // print final temperature
        cout << " Tfinal = " << r.temperature() << endl;
        cout << "Output files:" << endl
             << "  kin1.csv    (Excel CSV file)" << endl
             << "  kin1.dat    (Tecplot data file)" << endl;
    } catch (CanteraError& err) {
        // handle exceptions thrown by Cantera
        std::cout << err.what() << std::endl;
        cout << " terminating... " << endl;
        appdelete();
        return -1;
    }
    return 0;
}