
:html_theme.sidebar_secondary.remove:

.. py:currentmodule:: cantera


.. DO NOT EDIT.
.. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY.
.. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE:
.. "examples/cxx/combustor.cpp"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

    .. note::
        :class: sphx-glr-download-link-note

        :ref:`Go to the end <sphx_glr_download_examples_cxx_combustor.cpp>`
        to download the full example code.

.. rst-class:: sphx-glr-example-title

.. _sphx_glr_examples_cxx_combustor.cpp:

Adiabatic combustor
===================

Two separate streams - one pure methane and the other air, both at 300 K
and 1 atm flow into an adiabatic combustor where they mix. We are interested
in the steady-state burning solution. Since at 300 K no reaction will occur
between methane and air, we need to use an 'igniter' to initiate the
chemistry. A simple igniter is a pulsed flow of atomic hydrogen. After the
igniter is turned off, the system approaches the steady burning solution.

.. tags:: C++, combustion, reactor network, well-stirred reactor

.. GENERATED FROM PYTHON SOURCE LINES 13-133

.. code-block:: C++

    // This file is part of Cantera. See License.txt in the top-level directory or
    // at https://cantera.org/license.txt for license and copyright information.

    #include "cantera/zerodim.h"
    #include <fstream>

    using namespace Cantera;

    void runexample()
    {
        // use reaction mechanism GRI-Mech 3.0
        auto sol = newSolution("gri30.yaml", "gri30", "none");
        auto gas = sol->thermo();

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

        // create a reservoir for the air inlet
        auto air = newSolution("air.yaml", "air", "none");
        double air_mw = air->thermo()->meanMolecularWeight();
        auto air_in = newReservoir(air);

        // 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");
        auto igniter = newReservoir(sol);

        // create the combustor, and fill it in initially with N2
        gas->setState_TPX(300.0, OneAtm, "N2:1.0");
        auto combustor = newReactor4("Reactor", sol);
        combustor->setInitialVolume(1.0);

        // create a reservoir for the exhaust. The initial composition doesn't matter.
        auto exhaust = newReservoir(sol);

        // 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(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(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;
        shared_ptr<Func1> igniter_mdot = newFunc1("Gaussian", {A, t0, FWHM});

        MassFlowController m3(igniter, combustor);
        m3.setTimeFunction(igniter_mdot);

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

        // the simulation only contains one reactor
        ReactorNet sim(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");
        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 << ", ";
            const auto& c = combustor->phase()->thermo();
            for (size_t i = 0; i < k_out.size(); i++) {
                f << c->moleFraction(k_out[i]) << ", ";
            }
            f << std::endl;
        }
    }

    int main()
    {
        try {
            runexample();
            return 0;
        } catch (CanteraError& err) {
            // handle exceptions thrown by Cantera
            std::cout << err.what() << std::endl;
            std::cout << " terminating... " << std::endl;
            appdelete();
            return 1;
        }
    }

.. _sphx_glr_download_examples_cxx_combustor.cpp:

.. only:: html

  .. container:: sphx-glr-footer sphx-glr-footer-example

    .. container:: sphx-glr-download sphx-glr-download-python

      :download:`Download C++ source code: combustor.cpp <combustor.cpp>`

    .. container:: sphx-glr-download sphx-glr-download-zip

      :download:`Download zipped: combustor.zip <combustor.zip>`


.. only:: html

 .. rst-class:: sphx-glr-signature

    `Gallery generated by Sphinx-Gallery <https://sphinx-gallery.github.io>`_
