
: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/python/reactors/surf_pfr_chain.py"
.. LINE NUMBERS ARE GIVEN BELOW.

.. only:: html

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

        :ref:`Go to the end <sphx_glr_download_examples_python_reactors_surf_pfr_chain.py>`
        to download the full example code.

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

.. _sphx_glr_examples_python_reactors_surf_pfr_chain.py:


Plug flow reactor modeled as a chain of well stirred reactors
=============================================================

This example solves a plug flow reactor problem, where the chemistry is surface
chemistry. The specific problem simulated is the partial oxidation of methane over a
platinum catalyst in a packed bed reactor. To avoid needing to solve a DAE system, the
PFR is approximated as a chain of successive WSRs. See :doc:`surf_pfr.py <surf_pfr>` for
a more advanced implementation that solves the DAE system directly.

Requires: cantera >= 3.2

.. tags:: Python, catalysis, reactor network, surface chemistry, plug flow reactor,
          packed bed reactor

.. GENERATED FROM PYTHON SOURCE LINES 16-25

.. code-block:: Python


    import csv

    import cantera as ct

    # unit conversion factors to SI
    cm = 0.01
    minute = 60.0








.. GENERATED FROM PYTHON SOURCE LINES 26-28

Input Parameters
######################################################################

.. GENERATED FROM PYTHON SOURCE LINES 28-45

.. code-block:: Python


    tc = 800.0  # Temperature in Celsius
    length = 0.3 * cm  # Catalyst bed length
    area = 1.0 * cm**2  # Catalyst bed area
    cat_area_per_vol = 1000.0 / cm  # Catalyst particle surface area per unit volume
    velocity = 40.0 * cm / minute  # gas velocity
    porosity = 0.3  # Catalyst bed porosity

    # input file containing the surface reaction mechanism
    yaml_file = 'methane_pox_on_pt.yaml'

    output_filename = 'surf_pfr_output.csv'

    # The PFR will be simulated by a chain of 'NReactors' stirred reactors.
    NReactors = 201
    dt = 1.0








.. GENERATED FROM PYTHON SOURCE LINES 46-132

.. code-block:: Python


    t = tc + 273.15  # convert to Kelvin

    # import the phase models and set the initial conditions
    surf = ct.Interface(yaml_file, 'Pt_surf')
    surf.TP = t, ct.one_atm
    gas = surf.adjacent['gas']
    gas.TPX = t, ct.one_atm, 'CH4:1, O2:1.5, AR:0.1'

    rlen = length/(NReactors-1)
    rvol = area * rlen * porosity

    # catalyst area in one reactor
    cat_area = cat_area_per_vol * rvol

    mass_flow_rate = velocity * gas.density * area * porosity

    # The plug flow reactor is represented by a linear chain of zero-dimensional
    # reactors. The gas at the inlet to the first one has the specified inlet
    # composition, and for all others the inlet composition is fixed at the
    # composition of the reactor immediately upstream. Since in a PFR model there
    # is no diffusion, the upstream reactors are not affected by any downstream
    # reactors, and therefore the problem may be solved by simply marching from
    # the first to last reactor, integrating each one to steady state.

    TDY = gas.TDY
    cov = surf.coverages

    print('    distance       X_CH4        X_H2        X_CO')

    # create a new reactor
    gas.TDY = TDY
    r = ct.IdealGasReactor(gas, energy='off', clone=True)
    r.volume = rvol

    # create a reservoir to represent the reactor immediately upstream. Note
    # that the gas object is set already to the state of the upstream reactor
    upstream = ct.Reservoir(gas, name='upstream', clone=True)

    # create a reservoir for the reactor to exhaust into. The composition of
    # this reservoir is irrelevant.
    downstream = ct.Reservoir(gas, name='downstream', clone=True)

    # Add the reacting surface to the reactor. The area is set to the desired
    # catalyst area in the reactor.
    rsurf = ct.ReactorSurface(surf, r, A=cat_area, clone=True)

    # The mass flow rate into the reactor will be fixed by using a
    # MassFlowController object.
    m = ct.MassFlowController(upstream, r, mdot=mass_flow_rate)

    # We need an outlet to the downstream reservoir. This will determine the
    # pressure in the reactor. The value of K will only affect the transient
    # pressure difference.
    v = ct.PressureController(r, downstream, primary=m, K=1e-5)

    sim = ct.ReactorNet([r])

    output_data = []

    for n in range(NReactors):
        # Set the state of the reservoir to match that of the previous reactor
        gas.TDY = r.phase.TDY
        upstream.syncState()
        sim.reinitialize()
        sim.advance_to_steady_state()
        dist = n * rlen * 1.0e3  # distance in mm

        if n % 10 == 0:
            print('  {0:10f}  {1:10f}  {2:10f}  {3:10f}'.format(
                dist, *r.phase['CH4', 'H2', 'CO'].X))

        # write the gas mole fractions and surface coverages vs. distance
        output_data.append(
            [dist, r.T - 273.15, r.phase.P / ct.one_atm]
            + list(r.phase.X)  # use r.phase.X not gas.X
            + list(rsurf.phase.coverages)  # use rsurf.phase.coverages not surf.coverages
        )

    with open(output_filename, 'w', newline="") as outfile:
        writer = csv.writer(outfile)
        writer.writerow(['Distance (mm)', 'T (C)', 'P (atm)'] +
                        gas.species_names + surf.species_names)
        writer.writerows(output_data)

    print("Results saved to '{0}'".format(output_filename))




.. rst-class:: sphx-glr-script-out

 .. code-block:: none

        distance       X_CH4        X_H2        X_CO
        0.000000    0.093002    0.001365    0.010247
        0.150000    0.093002    0.001365    0.010247
        0.300000    0.093002    0.001365    0.010247
        0.450000    0.093002    0.001365    0.010247
        0.600000    0.093002    0.001365    0.010247
        0.750000    0.093002    0.001365    0.010247
        0.900000    0.093002    0.001365    0.010247
        1.050000    0.093002    0.001365    0.010247
        1.200000    0.093002    0.001365    0.010247
        1.350000    0.093002    0.001365    0.010247
        1.500000    0.093002    0.001365    0.010247
        1.650000    0.093002    0.001365    0.010247
        1.800000    0.093002    0.001365    0.010247
        1.950000    0.093002    0.001365    0.010247
        2.100000    0.093002    0.001365    0.010247
        2.250000    0.093002    0.001365    0.010247
        2.400000    0.093002    0.001365    0.010247
        2.550000    0.093002    0.001365    0.010247
        2.700000    0.093002    0.001365    0.010247
        2.850000    0.093002    0.001365    0.010247
        3.000000    0.093002    0.001365    0.010247
    Results saved to 'surf_pfr_output.csv'





.. rst-class:: sphx-glr-timing

   **Total running time of the script:** (0 minutes 0.251 seconds)


.. _sphx_glr_download_examples_python_reactors_surf_pfr_chain.py:

.. only:: html

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

    .. container:: sphx-glr-download sphx-glr-download-jupyter

      :download:`Download Jupyter notebook: surf_pfr_chain.ipynb <surf_pfr_chain.ipynb>`

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

      :download:`Download Python source code: surf_pfr_chain.py <surf_pfr_chain.py>`

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

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


.. only:: html

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

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