pymrm is a Python package for modeling multiphase reactors, developed as part of the Multiphase Reactor Modeling course at Eindhoven University of Technology. Originally implemented in Matlab, pymrm is now a Python-based, open-access tool designed for accessibility and advanced modeling.
- Tools for modeling diffusion, convection, reaction, and mass transfer.
- User-friendly interface for students and professionals.
- Extensive documentation and example-based learning.
Install pymrm directly from PyPI:
pip install pymrmFor detailed instructions, see the Installation Guide.
Start with the tutorials in the tutorials folder to learn the basics of pymrm. Then, explore the examples folder for more advanced use cases, including modeling diffusion, convection, and reaction processes.
For extensive documentation, exercises, and additional resources, visit the PyMRM documentation site.
These are the conventions most often got wrong, by people and by coding agents.
The same list is in the package docstring (help(pymrm)).
- Boundary conditions are
(lower, upper)dictionaries{"a", "b", "d"}meaninga * dc/dn + b * c = dwithnthe outward normal, so at the lower enddc/dn = -dc/dx.describe_bc(bc, x_f)prints what a pair means.{"outflow": True}marks a pure-outflow boundary (a stirred volume's exit). - Shapes keep a trailing field axis: one field on
ncells is(n, 1).NumJaccouples the last axis in full, so a bare(n,)builds a dense Jacobian. - Recipe: assemble the constant operators once, return
(g, jac)from a residual function, useNumJaconly for local terms such as reactions, and solve withnewton. newtonstops on an absolute step: scale unknowns to order one or passtol=0, rtol=...; check the result withpymrm.checks.residual_check.- Boundary values come from
compute_boundary_values(its gradients are along the axis), never from the last cell centre. shapes_d: a dictionary'sdis a coefficient on the external vector of boundary values; used = 1.- Checks:
pymrm.checkshascheck_jacobian,observed_orders,find_rootsandresidual_check.
A minimal steady model, diffusion with a second-order reaction in a slab:
import numpy as np
from pymrm import NumJac, construct_div, construct_grad, newton
n = 100
x_f = np.linspace(0.0, 1.0, n + 1) # face positions
shape = (n, 1) # one field: keep a field axis
bc = ({"a": 1.0, "b": 0.0, "d": 0.0}, # x = 0: dc/dx = 0 (symmetry)
{"a": 0.0, "b": 1.0, "d": 1.0}) # x = 1: c = 1
grad, grad_bc = construct_grad(shape, x_f, bc=bc)
div = construct_div(shape, x_f, nu=0) # nu: 0 slab, 1 cylinder, 2 sphere
jac_const = (div @ -grad).tocsc() # diffusion, assembled once
g_const = (div @ -grad_bc).toarray().reshape(-1, 1)
numjac = NumJac(shape) # Jacobian of the local reaction
def residual(c):
g_rxn, jac_rxn = numjac(lambda u: 4.0 * u**2, c.reshape(shape))
return g_const + jac_const @ c.reshape(-1, 1) + g_rxn.reshape(-1, 1), jac_const + jac_rxn
result = newton(residual, np.ones(shape))
c = result.x.reshape(shape)Coding agents such as Claude Code already model well with pymrm: they read the installed package's source and docstrings. The pymrm agent plugin adds the house conventions (operator-sum Jacobians, monolithic coupling, model and notebook formats), known pitfalls and checkers, tested exemplar models, and, when you ask for it, a documented workflow with an independent verifier.
pymrm must be installed in the Python environment the agent runs in
(pip install pymrm). Then, inside Claude Code:
/plugin marketplace add computational-chemical-engineering/pymrm
/plugin install pymrm@pymrm
From a terminal, update later with claude plugin marketplace update pymrm and
remove with claude plugin uninstall pymrm@pymrm. To work from a local checkout of this repository
instead (for example while changing the skills), start Claude Code with
claude --plugin-dir plugins/pymrm, or register the checkout once with
claude plugin marketplace add /path/to/pymrm.
Describe what you want in plain words; the plugin picks the mode.
| You want | Ask for example |
|---|---|
| a checked model and its answer (default) | "Model steady diffusion with a second-order reaction in a 3 mm spherical pellet, D_eff = 1e-6 m2/s, and give the effectiveness factor." |
| a quick estimate: does it matter at all? | "Is external mass transfer limiting in my lab microreactor? Particles are 200 micrometre, ..." |
| advice on modelling choices | "Should I solve my membrane reactor monolithically or iterate between the channels?" |
| a documented, independently verified model | "I need a documented, independently verified model for a design review: ..." (specification for your approval, verification by a separate agent, model card) |
| teaching material | "For my course: a flat notebook that builds the operators step by step for ..." |
You can also call the skills directly: /pymrm:build-model,
/pymrm:conventions, /pymrm:model-patterns, /pymrm:verify-model. Optional
tools the checks use when present: nbformat and nbclient (to execute
notebooks), Node.js with KaTeX (to check that notebook equations render in
JupyterLab, VS Code, Colab and on GitHub). Details: plugins/pymrm/README.md.
The skills use the open Agent Skills format (SKILL.md) and work in other
tools too.
# Codex CLI: skills become $pymrm:build-model and so on
codex plugin marketplace add computational-chemical-engineering/pymrm
codex plugin add pymrm@pymrm
# Gemini CLI: skills become build-model, conventions, model-patterns, verify-model
gemini skills install https://github.com/computational-chemical-engineering/pymrm --path plugins/pymrm/skillsGemini overwrites existing skills of the same name without asking, so check
gemini skills list first (or add --scope workspace). The separate verifier
agent is Claude-only; the other tools run verification through the
verify-model skill. Details, updating and removal: plugins/pymrm/README.md.
Small building blocks used throughout the package are documented in
docs/helpers.md. These utilities assist with
handling boundary-condition coefficients and constructing sparse
coefficient matrices.
Contributions are welcome! For suggestions or enhancements, please contact us or submit a pull request.