🌀 Conatus
Spectral PDEs and dynamical systems, from equations written as on paper.
Write the geometry, the unknowns and the equations as text. Conatus builds the spectral discretisation, then lets you simulate the model or take apart its dynamics.
Kelvin-Helmholtz billows rolling up in a shear layer, with a passive dye (examples/shear/kelvin_helmholtz.py).
What it does
You describe a problem the way you would on a blackboard. Conatus picks the bases, places the
boundary conditions, splits implicit and explicit terms, and then tells you what it did:
explain() prints every numerical choice, so nothing happens behind your back.
From one model you can:
- 🌊 Simulate it in time, on CPU or on an NVIDIA GPU (beta).
- 📈 Find its eigenvalues, each with its residual, adjoint modes, and a check that a finer resolution finds the same mode again.
- ⚡ Measure non-modal growth: optimal perturbations and transient amplification.
- 🔁 Study periodic problems with Floquet and Hill spectra.
- 🎯 Converge invariant solutions (equilibria, periodic orbits) with Newton-Krylov.
- 🧭 Follow branches with continuation and locate bifurcations.
- 🌪️ Quantify chaos with Lyapunov spectra and covariant vectors.
📐 Stability: where does convection start?
Rayleigh-Bénard onset between rigid plates. The normal-mode problem, written as on paper (from tutorial 0):
import conatus as cn
from conatus.expert import critical
onset = cn.Model(cn.Box(z=cn.walls(-0.5, 0.5)), name="convection onset", Ra=1700.0, k=3.1, Pr=1)
onset.scalar("w"), onset.scalar("theta") # w(z), theta(z) times exp(i k x + s t)
onset.eigenvalue("s", growth="real")
onset.define("L(f) = dz(dz(f)) - k**2*f")
onset.equations("""
momentum: s*L(w) = Pr*L(L(w)) - Pr*Ra*k**2*theta
heat: s*theta = w + L(theta)
""")
onset.at("walls", "w = 0", "dz(w) = 0", "theta = 0")
P = onset.parametric(N=32, over=("Ra", "k"), drift=48, drift_tol=1e-6) # modes confirmed at N=48
crit = critical(P, "Ra", bracket=(1500, 2000), over={"k": (2.8, 3.4)}, xtol=1e-9)
print(f"Ra_c = {crit.value:.4f} k_c = {crit.over['k']:.5f}")
Ra_c = 1707.7618 k_c = 3.11632
The classical value (Reid & Harris, 1958) is Ra_c = 1707.762 at k_c = 3.117.
🌡️ Simulation: the same convection, in time
import numpy as np
import conatus as cn
box = cn.Box(x=cn.periodic(2.0), z=cn.walls(-0.5, 0.5))
m = cn.Model(box, name="Rayleigh-Benard 2D", Ra=2500, Pr=1)
u, p, T = m.velocity("u"), m.pressure("p"), m.scalar("T")
m.equations("""
momentum: dt(u) + grad(p) - Pr*lap(u) = Pr*Ra*T*ez - u·grad(u)
continuity: div(u) = 0
heat: dt(T) - lap(T) = -u·grad(T)
""")
m.at("bottom", u=0, T=+0.5)
m.at("top", u=0, T=-0.5)
sim = m.simulate(N=(32, 24), scheme="RK443", dt=5e-4) # backend="cuda" on a GPU (beta)
sim.initial(T=lambda x, z: -z + 1e-6 * np.cos(np.pi * x) * np.cos(np.pi * z))
sim.run(until=0.8)
print(sim.explain())
The small perturbation grows at the rate of the leading eigenvalue of the linearised model (σ = 5.5425 at Ra = 2500), then saturates into rolls that carry the same heat flux through both plates.
📦 Install
pip install conatus # CPU wheel, compiled core included, no compiler needed
python -m conatus doctor # what this machine can run, and what is missing
GPU (beta). For an NVIDIA A100 or L40S class card with a driver that supports CUDA 12.9. The CUDA wheel is not on PyPI: grab the one matching your Python from the releases page and install it with CuPy:
pip install "$(echo ./conatus-0.1.0+cu12-cp312-*.whl)[gpu]" # the file you downloaded (CPython 3.12 here)
python -m conatus doctor # says whether the CUDA core sees a GPU
From source. pip install . with LAPACK and BLAS available. Details on the
install page.
📚 Learn more
- The website has the tutorials, the user guide, the API reference and the maths behind each method.
examples/holds ready-to-run cases: convection, shear flows, patterns, bifurcations.
⚠️ Good to know
- CPU speed. The CPU path is a NumPy reference implementation. It is great for eigenvalue problems, small grids and setting a run up, but slower than established CPU codes on large grids. The speed comes from the GPU path, which is still in beta.
- One GPU. 0.1.0 runs a simulation on one CPU process or one GPU. No multi-GPU or MPI yet.
- Young API. The 0.1 interface can still change. Any change comes with a deprecation warning and a line in the changelog.
📄 License
BSD-3-Clause, see LICENSE. Bundled third-party components and their licences are
listed in THIRD_PARTY_NOTICES.md, with the full texts in
licenses/. To cite Conatus, see CITATION.cff.
Made by Ruben Dahan.
Metadata
Release files for conatus 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| conatus-0.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl | CPython 3.13 | CPython 3.13 | Linux glibc 2.17+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| conatus-0.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl | CPython 3.12 | CPython 3.12 | Linux glibc 2.28+ x86-64, Linux glibc 2.17+ x86-64 | Details |
| conatus-0.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.17+ x86-64, Linux glibc 2.28+ x86-64 | Details |
Total release size: 55.2 MB
Release files / conatus-0.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | conatus-0.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 18.4 MB |
| Tags | CPython 3.13 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
fa128e04b4c11a659a1314ae36400ec3faab88c45530586588a64a9566a2c109
|
|
BLAKE2b-256 checksum How to use checksums |
0a12038843331a3b81fd1fee380a765d18b4ee2a9a4eb365344f21bddcaf0e78
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / conatus-0.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | conatus-0.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 18.4 MB |
| Tags | CPython 3.12 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
8cc1951dce758fc0bda37d6c2b227bc3938d31141e400bd54b618f41903f5964
|
|
BLAKE2b-256 checksum How to use checksums |
d6bd1edbdfcc751ab4e9c694e0f542d816edb517d9788f5055715e1e745f475b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Release files / conatus-0.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
| Download URL | conatus-0.1.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 18.4 MB |
| Tags | CPython 3.11 Linux glibc 2.17+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
5522265710b8bf54138a2e3f1b2eda7a66b32d4cec0cee76530b322ed9c621fb
|
|
BLAKE2b-256 checksum How to use checksums |
d72c176995214f5077be53ebfe005565e47a7aae22e38ee7f911619d36a748da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.14
|
Security for conatus 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.