Welcome to pyEQL’s documentation!

Release

0.5.2

Date

Nov 27, 2022

Contents:

Installation

Dependencies

pyEQL requires Python 3.0 or greater. We highly recommend the Anaconda distribution of Python, which bundles many other scientific computing packages and is easier to install (especially on Windows). You can download it at https://www.continuum.io/downloads.

pyEQL also requires the following packages:

If you use pip to install pyEQL (recommended), they should be installed automatically.

Automatically install via pip and PyPI

Once Python is installed, The Python Package Index repository will allow installation to be done easily from the command line as follows:

pip install pyEQL

This should automatically pull in the required dependencies as well.

Note

You may have to run ‘pip3’ rather than ‘pip’ if you intend to use your system’s default Python installation rather than Anaconda. For example, on many Linux and Mac systems Python 2.x and Python 3.x are installed side-by-side. You can tell if this is the case on your system by going to a command line and typing ‘python’ like so:

$ python
Python 2.7.12 (default, Jul  1 2016, 15:12:24)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>>

This means Python 2.x is installed. If you run ‘pip install’ it will point to the Python 2.7 installation, but pyEQL only works on Python 3. So, try this:

$ python3
Python 3.5.1+ (default, Mar 30 2016, 22:46:26)
[GCC 5.3.1 20160330] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>

To get to Python 3.x, you have to type ‘python3’. In this case, you would run ‘pip3 install’

Manually install via Git

Simply navigate to a directory of your choice on your computer and clone the repository by executing the following terminal command:

git clone https://github.com/rkingsbury/pyEQL

Then install by executing:

pip install -e pyEQL

Note

You may have to run ‘pip3’ rather than ‘pip’. See the note in the Automatic installation section.

Tutorial

pyEQL creates a new type (Solution class) to represent a chemical solution. It also comes pre-loaded with a database of diffusion coefficients, activity correction parameters, and other data on a variety of common electrolytes. Virtually all of the user-facing functions in pyEQL are accessed through the Solution class.

Creating a Solution Object

Create a Solution object by invoking the Solution class:

>>> import pyEQL
>>> s1 = pyEQL.Solution()
>>> s1
<pyEQL.pyEQL.Solution at 0x7f9d188309b0>

If no arguments are specified, pyEQL creates a 1-L solution of water at pH 7 and 25 degC.

More usefully, you can specify solutes and bulk properties:

>>> s2 = pyEQL.Solution([['Na+','0.5 mol/kg'],['Cl-','0.5 mol/kg']],pH=8,temperature = '20 degC', volume='8 L')

Retrieving Solution Properties

Bulk Solution Properties

pyEQL provides a variety of methods to calculate or look up bulk properties like temperature, ionic strength, conductivity, and density.

>>> s2.get_volume()
8.071524653929277 liter
>>> s2.get_density()
1.0182802742389558 kilogram/liter
>>> s2.get_conductivity()
4.083570230022633 siemens/meter
>>> s2.get_ionic_strength()
0.500000505903012 mole/kilogram

Individual Solute Properties

You can also retrieve properties for individual solutes (or the solvent, water)

>>> s2.get_amount('Na+','mol/L')
0.4946847550064916 mole/liter
>>> s2.get_activity_coefficient('Na+)
0.6838526233869155
>>> s2.get_activity('Na+')
0.3419263116934578
>>> s2.get_property('Na+','diffusion_coefficient')
1.1206048116287536e-05 centimeter2/second

Units-Aware Calculations using pint

pyEQL uses pint to perform units-aware calculations. The pint library creates Quantity objects that contain both a magnitude and a unit.

>>> from pyEQL import unit
>>> test_qty = pyEQL.unit('1 kg/m**3')
1.0 kilogram/meter3

Many pyEQL methods require physical quantities to be input as strings, then these methods return pint Quantity objects. A string quantity must contain both a magnitude and a unit (e.g. ‘0.5 mol/L’). In general, pint recognizes common abbreviations and SI prefixes. Compound units must follow Python math syntax (e.g. cm**2 not cm2).

Pint Quantity objects have several useful attributes. They can be converted to strings:

>>> str(test_qty)
'1.0 kg/m**3'

the magnitude, units, or dimensionality can be retrieved via attributes:

>>> test_qty.magnitude
1.0
>>> test_qty.units
<UnitsContainer({'kilogram': 1.0, 'meter': -3.0})>
>>> test_qty.dimensionality
<UnitsContainer({'[length]': -3.0, '[mass]': 1.0})>

See the pint documentation for more details on creating and manipulating Quantity objects.

Using pyEQL in your projects

To access pyEQL’s main features in your project all that is needed is an import statement:

>>> import pyEQL

In order to directly create Quantity objects, you need to explicitly import the unit module:

>>> from pyEQL import unit
>>> test_qty = pyEQL.unit('1 kg/m**3')
1.0 kilogram/meter3

Warning

if you use pyEQL in conjunction with another module that also uses pint for units-aware calculations, you must convert all Quantity objects to strings before passing them to the other module, as pint cannot perform mathematical operations on units that belong to different “registries.” See the pint documentation for more details.

Contributing to pyEQL

Reporting Issues

You can report any bugs, packaging issues, feature requests, comments, or questions using the issue tracker on github.

Contributing Code

To contribute bug fixes, documentation enhancements, or new code, please fork pyEQL and send us a pull request. It’s not as hard as it sounds!

It is strongly recommended that you read the following short articles before starting your work, especially if you are new to the open source community.

Hacking pyEQL in Six Easy Steps:

  1. Fork the pyEQL repository on Github

  2. Clone your repository to a directory of your choice:

    git clone https://github.com/<username>/pyEQL
    
  3. Create a branch for your work. We loosely follow the branching guidelines outlined at http://nvie.com/posts/a-successful-git-branching-model.

    If you are adding documentation or bug fixes, start with the master branch and prefix your branch with “fix-” or “doc-” as appropriate:

    git checkout -b fix-myfix master
    
    git checkout -b doc-mydoc master
    

    If you are adding a new feature, start with the develop branch and prefix your branch with “feature-“:

    git checkout -b feature-myfeature develop
    
  4. Hack away until you’re satisfied.

  5. Push your work back to Github:

    git push origin feature-myfeature
    
  6. Create a pull request with your changes. See this tutorial for instructions.

Generating Test Cases

pyEQL has many capabilities that have not been tested thoroughly. You can help the project simply by using pyEQL and comparing the output to experimental data and/or more established models. Report back your results on the issue tracker.

Even better, write up an automated test case (see the tests/ directory for examples).

Making a Donation

If you’d like to leave a ‘tip’ for the project maintainer to support the time and effort required to develop pyEQL, simply send it via Paypal to RyanSKingsbury@alumni.unc.edu

Chemical Formulas

Representing Chemical Substances in pyEQL

pyEQL interprets the chemical formula of a substance to calculate its molecular weight and formal charge. The formula is also used as a key to search the database for parameters (e.g. diffusion coefficient) that are used in subsequent calculations.

How to Enter Valid Chemical Formulas

Generally speaking, type the chemical formula of your solute the “normal” way and pyEQL should be able to inerpret it. Here are some examples:

  • Sodium Chloride - NaCl

  • Sodium Sulfate - Na(SO4)2

  • Methanol - CH4OH or CH5O

  • Magnesium Ion - Mg+2

  • Chloride Ion - Cl-

Formula Rules:

  1. Are composed of valid atomic symbols that start with capital letters

  2. Contain no non-alphanumeric characters other than ‘(’, ‘)’, ‘+’, or ‘-’

  3. If a ‘+’ or ‘-’ is present, the formula must contain ONLY ‘+’ or ‘-’ (e.g. ‘Na+-’ is invalid) and the formula must end with either a series of charges (e.g. ‘Fe+++’) or a numeric charge (e.g. ‘Fe+3’)

  4. Formula must contain matching numbers of ‘(’ and ‘)’

  5. Open parentheses must precede closed parentheses

Alternate Formulas and Isomers

Many complex molecules can be written in multiple ways. pyEQL cares only about the number and identity of the elements and the formal charge on the molecule, so you can use any form you choose. The hill_order() method takes a formula and reduces it to its simplest form, like so:

>>> pyEQL.chemical_formula.hill_order('CH2(CH3)4COOH')
'C6H15O2'

When searching the parameters database, pyEQL uses this method to reduce both user-entered formulas AND keys in the database. So even if you created a solution containing ‘ClNa’, pyEQL would still match it with parameters for ‘NaCl’.

Currently pyEQL does not distinguish between isomers.

API Documentation (chemical_formula.py)

Database System

pyEQL creates a database to collect various parameters needed to perform it’s calculations. pyEQL’s default database includes a collection of the following parameters for some common electrolytes:

  • Diffusion coefficients for 104 ions

  • Pitzer model activity correction coefficients for 157 salts

  • Pitzer model partial molar volume coefficients for 120 salts

  • Jones-Dole “B” coefficients for 83 ions

  • Hydrated and ionic radii for 23 ions

  • Dielectric constant model parameters for 18 ions

  • Partial molar volumes for 10 ions

Basics

The Paramsdb class creates a container for parameters. Each paramter is an object which contains not only the value, but also information about the units, the reference, and the conditions of measurement. paramsdb() also defines several methods that are helpful for retrieving parameters.

pyEQL automatically initializes an instance of Paramsdb under the name ‘db’. You can access database methods like this:

>>> import pyEQL
>>> pyEQL.db
<pyEQL.database.Paramsdb at 0x7fead183f240>
>>> pyEQL.db.has_species('H+')
True

Anytime a new solute is added to a solution, the search_parameters() method is called. This method searches every database file within the search path (by default, only pyEQL’s built-in databases) for any parameters associated with that solute, and adds them to the database.

Adding your own Database Files

Custom Search Paths

The database system is meant to be easily extensible. To include your own parameters, first you need to add a directory of your choosing to the search path.

>>> pyEQL.db.add_path('/home/user')

You can always check to see which paths pyEQL is searching by using list_path():

>>> pyEQL.db.list_path()
<default installation directory>/database
/home/user

Then, place your custom database file inside that directory. NOTE: custom database files are searched IN ADDITION TO the default databases. You don’t need to re-create the information from the built-in files. Custom databases only need to contain extra parameters that are not included already.

File Format

Databases are formatted as TAB-SEPARATED text files and carry the .tsv extension. The intent of this format is to make database files easy to edit with common spreadsheet software.

Warning

If you open an existing or template database file for editing, some spreadsheet software will try to replace the tabs with commas when you save it again. pyEQL does NOT read comma-separated files.

Since pyEQL compiles the database from multiple files, the intent is for each file to contain values for one type of parameter (such as a diffusion coefficient) from one source. The file can then list values of that parameter for a number of different solutes.

The upper section of each file contains information about the source of the data, the units, the name of the parameter, and the conditions of measurement. The top of each database file must, at a minimum, contain rows for ‘Name’ and ‘Units’. Preferably, other information such as conditions, notes and a reference are also supplied. See template.tsv in the database subdirectory for an example.

The remainder of the file contains solute formulas in the first column (see Chemical Formulas) and corresponding values of the parameter in the following columns. Sets of parameters (such as activity correction coefficients) can be specified by using more than one column.

Warning

Currently there is no way to handle duplicated parameters. So if you supply a parameter with the same name as a built-in one, unexpected behavior may result.

Special Names

The name of a parameter is used as a kind of index within pyEQL. Certain methods expect certain parameter names. The following are the currently-used internal names:

  • ‘diffusion_coefficient’ - diffusion coefficient

  • ‘pitzer_parameters_activity’ - coefficients for the Pitzer model for activity correction

  • ‘pitzer_parameters_volume’- coefficients for the Pitzer model for partial molar volume

  • ‘erying_viscosity_coefficients’ - coefficients for an Erying-type viscosity correction model

  • ‘partial_molar_volume’- the partial molar volume (used if Pitzer parameters are not available)

  • ‘hydrated_radius’ - hydrated radius

  • ‘ionic_radius’ - ionic radius

  • ‘jones_dole_B’ - Jones-Dole “B” coefficient

If you wish to supply these parameters for a custom solute not included in the built-in database, make sure to format the name exactly the same way.

You can also specify a custom parameter name, and retrieve it using the get_parameter() method. If the solute is ‘Na+’

>>> pyEQL.db.get_parameter('Na+','my_parameter_name')

Viewing the Database

You can view the entire contents of the database using the print_database() method. Since pyEQL searches for parameters as they are added, the database will only contain parameters for solutes that have actually been used during the execution of your script. The output is organized by solute.

>>> pyEQL.db.print_database()

>>> s1 = pyEQL.Solution([['Na+','0.5 mol/kg'],['Cl-','0.5 mol/kg']])
>>> pyEQL.db.print_database()
Parameters for species Cl-:
--------------------------
Parameter diffusion_coefficient
Diffusion Coefficient
-------------------------------------------
Value: 2.032e-05 cm²/s
Conditions (T,P,Ionic Strength): 25 celsius, 1 atm, 0
Notes: For most ions, increases 2-3% per degree above 25C
Reference: CRC Handbook of Chemistry and Physics, 92nd Ed., pp. 5-77 to 5-79

Parameter partial_molar_volume
Partial molar volume
-------------------------------------------
Value: 21.6 cm³/mol
Conditions (T,P,Ionic Strength): 25 celsius, 1 atm, 0
Notes: correction factor 5e-4 cm3/g-K
Reference: Durchschlag, H., Zipper, P., 1994. "Calculation of the Partial Molal Volume of Organic Compounds and Polymers." Progress in Colloid & Polymer Science (94), 20-39.
...

API Documentation (database.py)

API Documentation (parameter.py)

The Solution Class

The Solute Class

Internal Reference Documentation

Activity Correction API

Water Properties API

Functions Module