Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"]
os: [ubuntu-latest]

steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v6
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
uses: actions/setup-python@v6
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
Expand Down
13 changes: 6 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,11 @@ conda install -c conda-forge chemcat

### Cite as:
```bibtex
@ARTICLE{CubillosBlecicEtal2024journalRadiativeChemicalEquilibrium,
author = {{Cubillos}, Patricio and {Blecic}, Jasmina and {Fossati}, Luca},
title = "{Radiative and Chemical Equilibrium Calculations with Application to Exoplanets}",
journal = {journal},
year = 2024,
adsurl = {https://ui.adsabs.harvard.edu/abs/2024journ.000....0C},
adsnote = {Provided by the SAO/NASA Astrophysics Data System}
@ARTICLE{CubillosBlecicEtal2026mnrasPyratbay2,
author = {{Cubillos}, Patricio and {Blecic}, Jasmina and {Shulyak}, Denis and {Fossati}, Luca},
title = "{Pyrat Bay 2.0: an Upgraded Framework for Exoplanet Atmosphere Modeling in the JWST Era}",
journal = {MNRAS},
year = 2026,
adsurl = {https://ui.adsabs.harvard.edu/abs/2026mnras.000....0C},
}
```
2 changes: 1 addition & 1 deletion chemcat/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

from .network import *
Expand Down
2 changes: 1 addition & 1 deletion chemcat/cea/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

from .cea import *
Expand Down
134 changes: 90 additions & 44 deletions chemcat/cea/cea.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

__all__ = [
'is_in',
'read_thermo_build',
#'write_thermo_build',
'heat_func',
'gibbs_func',
'Heat',
'Gibbs',
'setup_network',
'find_species',
]
Expand Down Expand Up @@ -170,53 +169,72 @@ def read_thermo_build(species, thermo_file=None):
return thermo_data


def heat_func(a_coeffs, t_coeffs):
class Heat():
"""
Generate a callable that evaluates the molar heat capacity
A class to evaluate the molar heat capacity
at a given temperature array.

Parameters
----------
a_coeffs: 2D float ndarray
species: string
Species name. If provided, ignore coefficient inputs.
a_coeffs: 1D float ndarray
Polynomial coefficients to reproduce the heat capacity data.
t_coeffs: 1D float ndarray
Temperature intervals of validity for each set of coefficients.

Returns
-------
heat: Callable
A function heat(temperature) that evaluates the molar heat
capacity at constant pressure (divided by the universal gas
constant), cp(T)/R, for a given temperature input
(which can be a single value or a 1D iterable).

Examples
--------
>>> import chemcat.cea as cea

>>> data = cea.read_thermo_build(['H2O'])[0]
>>> heat = cea.heat_func(
>>> data['a_coeffs'], data['t_coeffs'])

>>> heat = cea.Heat('H2O')
>>> print(heat(300.0))
[4.04063805]
>>> print(heat([300.0, 1000.0, 3000.0]))
[4.04063805 4.96614188 6.8342561 ]
"""
def heat(temperature):
def __init__(self, species=None, a_coeffs=None, t_coeffs=None):
if species is not None:
data = read_thermo_build([species])[0]
a_coeffs = data['a_coeffs']
t_coeffs = data['t_coeffs']
self.a_coeffs = a_coeffs
self.t_coeffs = t_coeffs

def __call__(self, temperature):
"""
Parameters
----------
temperature: scalar of 1D float
Polynomial coefficients to reproduce the heat capacity data.

Returns
-------
heat_capacity: 1D array
Evaluate the molar heat capacity at constant pressure
(divided by the universal gas constant), cp(T)/R

Examples
--------
>>> import chemcat.cea as cea

>>> heat = cea.Heat('H2O')
>>> print(heat(300.0))
[4.04063805]
>>> print(heat([300.0, 1000.0, 3000.0]))
[4.04063805 4.96614188 6.8342561 ]
"""
if not isinstance(temperature, Iterable):
temperature = [temperature]
temperature = np.array(temperature, np.double)

heat_capacity = u.heat(temperature, a_coeffs, t_coeffs)
heat_capacity = u.heat(temperature, self.a_coeffs, self.t_coeffs)
return heat_capacity
return heat


def gibbs_func(a_coeffs, b_coeffs, t_coeffs):
class Gibbs():
"""
Generate a callable that evaluates the Gibbs free energy
for a given temperature array.
A class to evaluate the Gibbs free energy for a given temperature array.

Parameters
----------
Expand All @@ -227,35 +245,59 @@ def gibbs_func(a_coeffs, b_coeffs, t_coeffs):
t_coeffs: 1D float ndarray
Temperature intervals of validity for each set of coefficients.

Returns
-------
gibbs: Callable
A function gibbs(temperature) that evaluates the Gibbs free
energy, G(T)/RT, for a given temperature input (which can be
a single value or a 1D iterable).

Examples
--------
>>> import chemcat.cea as cea

>>> data = cea.read_thermo_build(['H2O'])[0]
>>> gibbs = cea.gibbs_func(
>>> data['a_coeffs'], data['b_coeffs'], data['t_coeffs'])

>>> gibbs = cea.Gibbs('H2O')
>>> print(gibbs(300.0))
[-119.66025955]
>>> print(gibbs([300.0, 1000.0, 3000.0]))
[-119.66025955 -53.94898416 -39.09425268]
"""
def gibbs(temperature):
def __init__(self, species=None, a_coeffs=None, b_coeffs=None, t_coeffs=None):
if species is not None:
data = read_thermo_build([species])[0]
a_coeffs = data['a_coeffs']
b_coeffs = data['b_coeffs']
t_coeffs = data['t_coeffs']

self.a_coeffs = a_coeffs
self.b_coeffs = b_coeffs
self.t_coeffs = t_coeffs

def __call__(self, temperature):
"""
Parameters
----------
temperature: scalar of 1D float
Polynomial coefficients to reproduce the heat capacity data.

Returns
-------
gibbs_free_energy: 1D array
The Gibbs free energy, G(T)/RT, at temperature input

Examples
--------
>>> import chemcat.cea as cea

>>> data = cea.read_thermo_build(['H2O'])[0]
>>> gibbs = cea.gibbs_func(
>>> data['a_coeffs'], data['b_coeffs'], data['t_coeffs'])

>>> print(gibbs(300.0))
[-119.66025955]
>>> print(gibbs([300.0, 1000.0, 3000.0]))
[-119.66025955 -53.94898416 -39.09425268]
"""
if not isinstance(temperature, Iterable):
temperature = [temperature]
temperature = np.array(temperature, np.double)

free_energy = u.gibbs(
temperature, a_coeffs, b_coeffs, t_coeffs)
free_energy = u.gibbs(temperature, self.a_coeffs, self.b_coeffs, self.t_coeffs)
return free_energy
return gibbs



def setup_network(input_species):
Expand Down Expand Up @@ -325,10 +367,14 @@ def setup_network(input_species):
gibbs_free_energy = []
stoich_data = []
for data in thermo_data:
heat_capacity.append(
heat_func(data['a_coeffs'], data['t_coeffs']))
gibbs_free_energy.append(
gibbs_func(data['a_coeffs'], data['b_coeffs'], data['t_coeffs']))
a_coeffs = data['a_coeffs']
b_coeffs = data['b_coeffs']
t_coeffs = data['t_coeffs']
heat = Heat(a_coeffs=a_coeffs, t_coeffs=t_coeffs)
gibbs = Gibbs(a_coeffs=a_coeffs, b_coeffs=b_coeffs, t_coeffs=t_coeffs)

heat_capacity.append(heat)
gibbs_free_energy.append(gibbs)
stoich_data.append(data['stoich'])

return (
Expand Down
8 changes: 8 additions & 0 deletions chemcat/data/thermo_build_cea.dat
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,14 @@ C- Hotop,1985. Gordon,1999.
6000.000 20000.0007 -2.0 -1.0 0.0 1.0 2.0 3.0 4.0 0.0 6218.836
1.223289007D+01-5.196185830D-03 2.500001344D+00-1.743497251D-10 1.206609009D-14
-4.252419790D-19 5.992333270D-24 7.001221630D+04 4.879608421D+00
CaH Gurvich,1996a pt1 p447 pt2 p353.
2 tpis96 CA 1.00H 1.00 0.00 0.00 0.00 0 41.0859400 229409.105
200.000 1000.0007 -2.0 -1.0 0.0 1.0 2.0 3.0 4.0 0.0 8705.105
-4.513782230D+04 7.629429210D+02-1.280874223D+00 1.318774659D-02-1.481595334D-05
8.536573220D-09-1.989958945D-12 0.000000000D+00 2.300378814D+04 3.053421525D+01
1000.000 6000.0007 -2.0 -1.0 0.0 1.0 2.0 3.0 4.0 0.0 8705.105
-2.696952529D+06 8.607059750D+03-7.027454820D+00 7.467916310D-03-2.318610699D-06
3.423072420D-10-1.892679792D-14 0.000000000D+00-2.773819107D+04 7.845822010D+01
CH Gurvich,1979 pt1 p37 pt2 p39.
3 tpis79 C 1.00H 1.00 0.00 0.00 0.00 0 13.0186400 597370.604
200.000 1000.0007 -2.0 -1.0 0.0 1.0 2.0 3.0 4.0 0.0 8625.104
Expand Down
1 change: 1 addition & 0 deletions chemcat/data/white_pages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ OAlH HAlO
OAlOH HAlO2
ONO- NO2-
SSO S2O
COS COS OCS
None C4H2,butadiyne C4H2
2 changes: 1 addition & 1 deletion chemcat/janaf/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

from .janaf import *
Expand Down
3 changes: 1 addition & 2 deletions chemcat/janaf/janaf.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

__all__ = [
Expand Down Expand Up @@ -417,4 +417,3 @@ def find_species(elements, charge='neutral', num_atoms=None, state='gas'):

return np.array(species)


2 changes: 1 addition & 1 deletion chemcat/network.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

__all__ = [
Expand Down
2 changes: 1 addition & 1 deletion chemcat/utils/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

from .utils import *
Expand Down
2 changes: 1 addition & 1 deletion chemcat/utils/utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

__all__ = [
Expand Down
4 changes: 2 additions & 2 deletions chemcat/version.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Copyright (c) 2022-2025 Blecic and Cubillos
# Copyright (c) 2022-2026 Blecic and Cubillos
# chemcat is open-source software under the GPL-2.0 license (see LICENSE)

# chemcat version:
__version__ = '0.3.12'
__version__ = '1.0.0'

Loading