SkillAgentSearch skills...

Chempy

⚗ A package useful for chemistry written in Python

Install / Use

/learn @bjodah/Chempy

README

ChemPy

.. image:: https://github.com/bjodah/chempy/actions/workflows/lint_python.yml/badge.svg :target: https://github.com/bjodah/chempy/actions/workflows/lint_python.yml :alt: Github Actions CI status .. image:: https://hackspett.bjodah.se/api/badges/1/status.svg :target: https://hackspett.bjodah.se/repos/1 :alt: Woodpecker CI status .. image:: https://img.shields.io/pypi/v/chempy.svg :target: https://pypi.python.org/pypi/chempy :alt: PyPI version .. image:: https://img.shields.io/pypi/l/chempy.svg :target: https://github.com/bjodah/chempy/blob/master/LICENSE :alt: License .. image:: http://joss.theoj.org/papers/10.21105/joss.00565/status.svg :target: https://doi.org/10.21105/joss.00565 :alt: Journal of Open Source Software DOI

.. contents::

About ChemPy

ChemPy is a Python <https://www.python.org>_ package useful for chemistry (mainly physical/inorganic/analytical chemistry). Currently it includes:

  • Numerical integration routines for chemical kinetics (ODE solver front-end)

  • Integrated rate expressions (and convenience fitting routines)

  • Solver for equilibria (including multiphase systems)

  • Relations in physical chemistry:

    • Debye-Hückel expressions
    • Arrhenius & Eyring equation
    • Einstein-Smoluchowski equation
  • Properties (pure python implementations from the literature)

    • water density <https://github.com/bjodah/chempy/blob/master/chempy/properties/water_density_tanaka_2001.py>_ as function of temperature
    • water permittivity <https://github.com/bjodah/chempy/blob/master/chempy/properties/water_permittivity_bradley_pitzer_1979.py>_ as function of temperature and pressure
    • water diffusivity <https://github.com/bjodah/chempy/blob/master/chempy/properties/water_diffusivity_holz_2000.py>_ as function of temperature
    • water viscosity <https://github.com/bjodah/chempy/blob/master/chempy/properties/water_viscosity_korson_1969.py>_ as function of temperature
    • sulfuric acid density <https://github.com/bjodah/chempy/blob/master/chempy/properties/sulfuric_acid_density_myhre_1998.py>_ as function of temperature & weight fraction H₂SO₄
    • More <https://github.com/bjodah/chempy/tree/master/chempy/properties>_ to come... (and contributions are most welcome!)

Documentation

The easiest way to get started is to have a look at the examples in this README, and also the jupyter notebooks_. In addition there is auto-generated API documentation for the latest stable release here <https://bjodah.github.io/chempy/latest>_.

.. _notebooks: https://github.com/bjodah/chempy/tree/master/examples

Installation

Simplest way to install ChemPy and its (optional) dependencies is to use the conda package manager <https://conda.pydata.org/docs/>_::

$ conda install -c conda-forge chempy pytest $ pytest -rs -W ignore::chempy.ChemPyDeprecationWarning --pyargs chempy

currently conda packages are only provided for Linux. On Windows and OS X you will need to use pip instead::

$ python3 -m pip install chempy pytest $ python3 -m pytest -rs -W ignore::chempy.ChemPyDeprecationWarning --pyargs chempy

there will a few tests which will be skipped due to some missing optional backends in addition to those in SciPy (used for solving systems of non-linear equations and ordinary differential equations).

Optional dependencies

If you used ``conda`` to install ChemPy you can skip this section.
But if you use ``pip`` the default installation is achieved by writing::

   $ python3 -m pip install --user --upgrade chempy pytest
   $ python3 -m pytest -rs --pyargs chempy

you can skip the ``--user`` flag if you have got root permissions.
You may be interested in using additional backends (in addition to those provided by SciPy)
for solving ODE-systems and non-linear optimization problems::

   $ python3 -m pip install chempy[all]

Note that this option will install the following libraries
(some of which require additional libraries to be present on your system):

- `pygslodeiv2 <https://github.com/bjodah/pygslodeiv2>`_: solving initial value problems, requires GSL_. (>=1.16).
- `pyodeint <https://github.com/bjodah/pyodeint>`_: solving initial value problems, requires boost_ (>=1.65.0).
- `pycvodes <https://github.com/bjodah/pycvodes>`_: solving initial value problems, requires SUNDIALS_ (>=5.3.0).
- `pykinsol <https://github.com/bjodah/pykinsol>`_: solving non-linear root-finding, requires SUNDIALS_ (>=5.3.0).
- `pycompilation <https://github.com/bjodah/pycompilation>`_: python front-end for calling compilers, requires gcc/clang/icpc.
- `pycodeexport <https://github.com/bjodah/pycodeexport>`_: package for code-generation, used when generating C++ code.

.. _GSL: https://www.gnu.org/software/gsl/
.. _boost: http://www.boost.org/
.. _SUNDIALS: https://computation.llnl.gov/projects/sundials

if you want to see what packages need to be installed on a Debian based system you may look at this
`Dockerfile <scripts/environment/Dockerfile>`_.

Using Docker
~~~~~~~~~~~~
If you have `Docker <https://www.docker.com>`_ installed, you may use it to host a jupyter
notebook server::

  $ ./scripts/host-env.sh host-notebook --port 8888

the first time you run the command, some dependencies will be downloaded. When the installation
is complete there will be a link visible which you can open in your browser. You can also run
the test suite using the same docker-image::

  $ ./scripts/host-env.sh run-tests

there will be a few skipped test (due to some dependencies not being installed by default) and
quite a few warnings.


Examples
--------
See demonstration scripts in `examples/ <https://github.com/bjodah/chempy/tree/master/examples>`_,
and some rendered jupyter notebooks_.
You may also browse the documentation for more examples. Below you will find a few code snippets:

Parsing formulae
~~~~~~~~~~~~~~~~
.. code:: python

   >>> from chempy import Substance
   >>> ferricyanide = Substance.from_formula('Fe(CN)6-3')
   >>> ferricyanide.composition == {0: -3, 26: 1, 6: 6, 7: 6}  # 0 for charge
   True
   >>> print(ferricyanide.unicode_name)
   Fe(CN)₆³⁻
   >>> print(ferricyanide.latex_name + ", " + ferricyanide.html_name)
   Fe(CN)_{6}^{3-}, Fe(CN)<sub>6</sub><sup>3-</sup>
   >>> print('%.3f' % ferricyanide.mass)
   211.955


as you see, in composition, the atomic numbers (and 0 for charge) is used as
keys and the count of each kind became respective value.

Balancing stoichiometry of a chemical reaction

.. code:: python

from chempy import balance_stoichiometry # Main reaction in NASA's booster rockets: reac, prod = balance_stoichiometry({'NH4ClO4', 'Al'}, {'Al2O3', 'HCl', 'H2O', 'N2'}) from pprint import pprint pprint(dict(reac)) {'Al': 10, 'NH4ClO4': 6} pprint(dict(prod)) {'Al2O3': 5, 'H2O': 9, 'HCl': 6, 'N2': 3} from chempy import mass_fractions for fractions in map(mass_fractions, [reac, prod]): ... pprint({k: '{0:.3g} wt%'.format(v*100) for k, v in fractions.items()}) ... {'Al': '27.7 wt%', 'NH4ClO4': '72.3 wt%'} {'Al2O3': '52.3 wt%', 'H2O': '16.6 wt%', 'HCl': '22.4 wt%', 'N2': '8.62 wt%'}

ChemPy can also balance reactions where the reacting species are more complex and are better described in other terms than their molecular formula. A silly, yet illustrative example would be how to make pancakes without any partially used packages:

.. code:: python

substances = {s.name: s for s in [ ... Substance('pancake', composition=dict(eggs=1, spoons_of_flour=2, cups_of_milk=1)), ... Substance('eggs_6pack', composition=dict(eggs=6)), ... Substance('milk_carton', composition=dict(cups_of_milk=4)), ... Substance('flour_bag', composition=dict(spoons_of_flour=60)) ... ]} pprint([dict(_) for _ in balance_stoichiometry({'eggs_6pack', 'milk_carton', 'flour_bag'}, ... {'pancake'}, substances=substances)]) [{'eggs_6pack': 10, 'flour_bag': 2, 'milk_carton': 15}, {'pancake': 60}]

ChemPy can even handle reactions with linear dependencies (underdetermined systems), e.g.:

.. code:: python

pprint([dict(_) for _ in balance_stoichiometry({'C', 'O2'}, {'CO2', 'CO'})]) # doctest: +SKIP [{'C': x1 + 2, 'O2': x1 + 1}, {'CO': 2, 'CO2': x1}]

the x1 object above is an instance of SymPy's Symbol_. If we prefer to get a solution with minimal (non-zero) integer coefficients we can pass underdetermined=None:

.. code:: python

pprint([dict(_) for _ in balance_stoichiometry({'C', 'O2'}, {'CO2', 'CO'}, underdetermined=None)]) [{'C': 3, 'O2': 2}, {'CO': 2, 'CO2': 1}]

note however that even though this solution is in some sense "canonical", it is merely one of an infinite number of solutions (x1 from earlier may be any integer).

.. _Symbol: http://docs.sympy.org/latest/modules/core.html#sympy.core.symbol.Symbol

Balancing reactions

.. code:: python

   >>> from chempy import Equilibrium
   >>> from sympy import symbols
   >>> K1, K2, Kw = symbols('K1 K2 Kw')
   >>> e1 = Equilibrium({'MnO4-': 1, 'H+': 8, 'e-': 5}, {'Mn+2': 1, 'H2O': 4}, K1)
   >>> e2 = Equilibrium({'O2': 1, 'H2O': 2, 'e-': 4}, {'OH-': 4}, K2)
   >>> coeff = Equilibrium.eliminate([e1, e2], 'e-')
   >>> coeff
   [4, -5]
   >>> redox = e1*coeff[0] + e2*coeff[1]
   >>> print(redox)
   32 H+ + 4 MnO4- + 20 OH- = 26 H2O + 4 Mn+2 + 5 O2; K1**4/K2**5
   >>> autoprot = Equilibrium({'H2O': 1}, {'H+': 1, 'OH-': 1}, Kw)
   >>> n = redox.cancel(autoprot)
   >>> n
   20
   >>> redox2 = redox + n*autoprot
   >>> print(redox2)
   12 H+ + 4 MnO4- = 6 H2O + 4 Mn+2 + 5 O2; K1**4*Kw**20/K2**5

Working with units
~~~~~~~~~~~~~~~~~~
Functions and objects useful
for working with units are available from the ``chempy.units`` module. Here is an
example of how ChemPy can check consistency of units:

.. code:: python

   >>> from chem

Related Skills

View on GitHub
GitHub Stars638
CategoryProduct
Updated4d ago
Forks83

Languages

Python

Security Score

100/100

Audited on Mar 28, 2026

No findings