
: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/onedim/flamespeed_sensitivity.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_onedim_flamespeed_sensitivity.py>`
        to download the full example code.

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

.. _sphx_glr_examples_python_onedim_flamespeed_sensitivity.py:


Laminar flame speed sensitivity analysis
========================================

In this example we simulate a freely-propagating, adiabatic, premixed methane-air flame,
calculate its laminar burning velocity and perform a sensitivity analysis of its
kinetics with respect to each reaction rate constant.

Requires: cantera >= 3.0.0, pandas

.. tags:: Python, combustion, 1D flow, flame speed, premixed flame,
          sensitivity analysis, plotting

The figure below illustrates the setup, in a flame-fixed coordinate system. The
reactants enter with density :math:`\rho_u`, temperature :math:`T_u` and speed
:math:`S_u`. The products exit the flame at speed :math:`S_b`, density :math:`\rho_b`
and temperature :math:`T_b`.

.. image:: /_static/images/samples/flame-speed.svg
   :width: 50%
   :alt: Freely Propagating Flame
   :align: center

.. GENERATED FROM PYTHON SOURCE LINES 25-32

.. code-block:: Python


    import cantera as ct
    import pandas as pd
    import matplotlib.pyplot as plt

    plt.rcParams['figure.constrained_layout.use'] = True








.. GENERATED FROM PYTHON SOURCE LINES 33-35

Simulation parameters
---------------------

.. GENERATED FROM PYTHON SOURCE LINES 35-49

.. code-block:: Python


    # Define the gas mixture and kinetics used to compute mixture properties
    # In this case, we are using the GRI 3.0 model with methane as the fuel
    mech_file = "gri30.yaml"
    fuel_comp = {"CH4": 1.0}

    # Inlet temperature in kelvin and inlet pressure in pascals
    # In this case we are setting the inlet T and P to room temperature conditions
    To = 300
    Po = ct.one_atm

    # Domain width in metres
    width = 0.014








.. GENERATED FROM PYTHON SOURCE LINES 50-52

Simulation setup
----------------

.. GENERATED FROM PYTHON SOURCE LINES 52-61

.. code-block:: Python


    # Create the object representing the gas and set its state to match the inlet conditions
    gas = ct.Solution(mech_file)
    gas.TP = To, Po
    gas.set_equivalence_ratio(1.0, fuel_comp, {"O2": 1.0, "N2": 3.76})

    flame = ct.FreeFlame(gas, width=width)
    flame.set_refine_criteria(ratio=3, slope=0.07, curve=0.14)








.. GENERATED FROM PYTHON SOURCE LINES 62-64

Solve the flame
---------------

.. GENERATED FROM PYTHON SOURCE LINES 64-67

.. code-block:: Python


    flame.solve(loglevel=1, auto=True)





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

 .. code-block:: none


    ************ Solving on 8 point grid with energy equation enabled ************

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 2.136e-05  log(ss)= 5.493     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 0.0003649  log(ss)= 4.613     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 0.006235   log(ss)= 3.334     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [9] point grid(s).
    Expanding domain to accommodate flame thickness. New width: 0.028 m
    ##############################################################################
    Refining grid in flame.
        New points inserted after grid points 0 1 2 3 4 5 6 7 
        to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 N2O NCO NH3 NO NO2 O O2 OH T velocity 
    ##############################################################################

    *********** Solving on 17 point grid with energy equation enabled ************

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 2.136e-05  log(ss)= 5.75      

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 3.041e-05  log(ss)= 5.661     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 0.0001948  log(ss)= 5.54      

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 1.951e-05  log(ss)= 6.217     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 0.0003333  log(ss)= 5.466     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 1.977e-05  log(ss)= 6.035     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [17] point grid(s).
    grid refinement disabled.

    ******************** Solving with grid refinement enabled ********************

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [17] point grid(s).
    ##############################################################################
    Refining grid in flame.
        New points inserted after grid points 3 4 5 6 7 8 9 10 
        to resolve C C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 N2O NCO NH NH2 NO NO2 O O2 OH T velocity 
    ##############################################################################

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 0.0001709  log(ss)= 5.031     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [25] point grid(s).
    ##############################################################################
    Refining grid in flame.
        New points inserted after grid points 6 7 8 9 10 11 12 13 14 15 20 21 22 
        to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 N2O NCO NH NH2 NH3 NO NO2 O O2 OH T velocity 
    ##############################################################################

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve failed.

    Attempt 10 timesteps.
    Final timestep info: dt= 7.594e-05  log(ss)= 5.496     

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [38] point grid(s).
    ##############################################################################
    Refining grid in flame.
        New points inserted after grid points 8 9 10 11 12 13 14 15 16 17 18 19 20 21 
        to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 N2O NCO NH NH2 NH3 NO NO2 O O2 OH T velocity 
    ##############################################################################

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [52] point grid(s).
    ##############################################################################
    Refining grid in flame.
        New points inserted after grid points 11 12 13 14 15 16 17 18 19 20 21 22 
        to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 N2O NCO NO NO2 O O2 OH T velocity 
    ##############################################################################

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [64] point grid(s).
    ##############################################################################
    Refining grid in flame.
        New points inserted after grid points 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 
        to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO CO2 H H2 H2O H2O2 HCCO HCCOH HCN HCNO HCO HNCO HO2 N N2 NCO NO NO2 O O2 OH T velocity 
    ##############################################################################

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [83] point grid(s).
    ##############################################################################
    Refining grid in flame.
        New points inserted after grid points 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 
        to resolve C C2H C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2O CH2OH CH3 CH3CHO CH3O CH3OH CH4 CO H H2 H2O2 HCCO HCCOH HCN HCO HNCO HO2 NO2 O OH 
    ##############################################################################

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [112] point grid(s).
    ##############################################################################
    Refining grid in flame.
        New points inserted after grid points 26 27 28 29 30 31 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 
        to resolve C C2H2 C2H3 C2H4 C2H5 C2H6 C3H7 C3H8 CH CH2 CH2(S) CH2CHO CH2CO CH2OH CH3 CH3CHO CH3O CH3OH H2O2 HCCO HCCOH HCO HO2 
    ##############################################################################

    Attempt Newton solution of steady-state problem.
    Newton steady-state solve succeeded.

    Problem solved on [156] point grid(s).
    no new points needed in flame




.. GENERATED FROM PYTHON SOURCE LINES 68-71

.. code-block:: Python

    print(f"\nmixture-averaged flame speed = {flame.velocity[0]:7f} m/s\n")






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

 .. code-block:: none


    mixture-averaged flame speed = 0.381285 m/s





.. GENERATED FROM PYTHON SOURCE LINES 72-76

Plot temperature and major species profiles
-------------------------------------------

Check and see if all has gone well.

.. GENERATED FROM PYTHON SOURCE LINES 76-86

.. code-block:: Python


    # Extract the spatial profiles as a SolutionArray to simplify plotting specific species
    profile = flame.to_array()

    fig, ax = plt.subplots()

    ax.plot(profile.grid * 100, profile.T, ".-")
    ax.set_xlabel("Distance [cm]")
    ax.set_ylabel("Temperature [K]")




.. image-sg:: /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_001.png
   :alt: flamespeed sensitivity
   :srcset: /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_001.png, /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_001_2_00x.png 2.00x
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 87-100

.. code-block:: Python


    fig, ax = plt.subplots()

    ax.plot(profile.grid * 100, profile("CH4").X, "--", label="CH$_4$")
    ax.plot(profile.grid * 100, profile("O2").X, label="O$_2$")
    ax.plot(profile.grid * 100, profile("CO2").X, "--", label="CO$_2$")
    ax.plot(profile.grid * 100, profile("H2O").X, label="H$_2$O")

    ax.legend(loc="best")
    ax.set_xlabel("Distance [cm]")
    ax.set_ylabel("Mole fraction [-]")
    plt.show()




.. image-sg:: /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_002.png
   :alt: flamespeed sensitivity
   :srcset: /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_002.png, /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_002_2_00x.png 2.00x
   :class: sphx-glr-single-img





.. GENERATED FROM PYTHON SOURCE LINES 101-132

Sensitivity Analysis
--------------------

See which reactions affect the flame speed the most. The sensitivities can be
efficiently computed using the adjoint method. In the general case, we consider a
system :math:`f(x, p) = 0` where :math:`x` is the system's state vector and :math:`p`
is a vector of parameters. To compute the sensitivities of a scalar function
:math:`g(x, p)` to the parameters, we solve the system:

.. math::
   \left(\frac{\partial f}{\partial x}\right)^T \lambda =
       \left(\frac{\partial g}{\partial x}\right)^T

for the Lagrange multiplier vector :math:`\lambda`. The sensitivities are then
computed as

.. math::
   \left.\frac{dg}{dp}\right|_{f=0} =
       \frac{\partial g}{\partial p} - \lambda^T \frac{\partial f}{\partial p}

In the case of flame speed sensitivity to the reaction rate coefficients,
:math:`g = S_u` and :math:`\partial g/\partial p = 0`. Since
:math:`\partial f/\partial x` is already computed as part of the normal solution
process, computing the sensitivities for :math:`N` reactions only requires :math:`N`
additional evaluations of the residual function to obtain
:math:`\partial f/\partial p`, plus the solution of the linear system for
:math:`\lambda`.

Calculation of flame speed sensitivities with respect to rate coefficients is
implemented by the method `FreeFlame.get_flame_speed_reaction_sensitivities`. For
other sensitivities, the method `Sim1D.solve_adjoint` can be used.

.. GENERATED FROM PYTHON SOURCE LINES 132-142

.. code-block:: Python


    # Create a DataFrame to store sensitivity-analysis data
    sens = pd.DataFrame(index=gas.reaction_equations(), columns=["sensitivity"])

    # Use the adjoint method to calculate sensitivities
    sens.sensitivity = flame.get_flame_speed_reaction_sensitivities()

    # Show the first 10 sensitivities
    sens.head(10)






.. raw:: html

    <div class="output_subarea output_html rendered_html output_result">
    <div>
    <style scoped>
        .dataframe tbody tr th:only-of-type {
            vertical-align: middle;
        }

        .dataframe tbody tr th {
            vertical-align: top;
        }

        .dataframe thead th {
            text-align: right;
        }
    </style>
    <table border="1" class="dataframe">
      <thead>
        <tr style="text-align: right;">
          <th></th>
          <th>sensitivity</th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <th>2 O + M &lt;=&gt; O2 + M</th>
          <td>-0.000164</td>
        </tr>
        <tr>
          <th>H + O + M &lt;=&gt; OH + M</th>
          <td>-0.000739</td>
        </tr>
        <tr>
          <th>H2 + O &lt;=&gt; H + OH</th>
          <td>0.027949</td>
        </tr>
        <tr>
          <th>HO2 + O &lt;=&gt; O2 + OH</th>
          <td>-0.004699</td>
        </tr>
        <tr>
          <th>H2O2 + O &lt;=&gt; HO2 + OH</th>
          <td>-0.000019</td>
        </tr>
        <tr>
          <th>CH + O &lt;=&gt; CO + H</th>
          <td>-0.001092</td>
        </tr>
        <tr>
          <th>CH2 + O &lt;=&gt; H + HCO</th>
          <td>-0.003904</td>
        </tr>
        <tr>
          <th>CH2(S) + O &lt;=&gt; CO + H2</th>
          <td>-0.000310</td>
        </tr>
        <tr>
          <th>CH2(S) + O &lt;=&gt; H + HCO</th>
          <td>-0.000057</td>
        </tr>
        <tr>
          <th>CH3 + O &lt;=&gt; CH2O + H</th>
          <td>-0.012564</td>
        </tr>
      </tbody>
    </table>
    </div>
    </div>
    <br />
    <br />

.. GENERATED FROM PYTHON SOURCE LINES 143-159

.. code-block:: Python


    # Sort the sensitivities in order of descending magnitude
    sens = sens.iloc[(-sens['sensitivity'].abs()).argsort()]

    fig, ax = plt.subplots()

    # Reaction mechanisms can contains thousands of elementary steps. Limit the plot
    # to the top 15
    sens.head(15).plot.barh(ax=ax, legend=None)

    ax.invert_yaxis()  # put the largest sensitivity on top
    ax.set_title("Sensitivities for GRI 3.0")
    ax.set_xlabel(r"Sensitivity: $\frac{\partial\:\ln S_u}{\partial\:\ln k}$")
    ax.grid(axis='x')
    plt.show()




.. image-sg:: /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_003.png
   :alt: Sensitivities for GRI 3.0
   :srcset: /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_003.png, /examples/python/onedim/images/sphx_glr_flamespeed_sensitivity_003_2_00x.png 2.00x
   :class: sphx-glr-single-img






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

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


.. _sphx_glr_download_examples_python_onedim_flamespeed_sensitivity.py:

.. only:: html

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

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

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

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

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

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

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


.. only:: html

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

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