
Security News
Browserslist-rs Gets Major Refactor, Cutting Binary Size by Over 1MB
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
A Python implementation of the Benchmark Simulation Model 2 (BSM2) plant layout according to the IWA standard.
A Python implementation of Benchmark Simulation Model 1 (BSM1) and 2 (BSM2) plant layouts according to the IWA standard. A technical description of BSM2 can be found here. A description for BSM1 can be found here.
To run the project, install the latest release via PyPI:
pip install bsm2-python
If you want the bleeding edge version from the repo, build it yourself via hatch build
.
See the Contribution Guide for more details on how to install hatch
(or simply use the Docker image).
Then you can install it to arbitrary environments via pip install dist/bsm2_python<version-hash>.whl
You could then use the following convenience function:
from bsm2_python import BSM2OL
# initialise the BSM2 Open Loop model
bsm2_ol = BSM2OL()
# run the simulation
bsm2_ol.simulate()
This will run the BSM2 Open Loop model for the default 609 days of simulation time.
It will then plot IQI, EQI and OCI values for the effluent over the last few days of simulation.
Further, relevant data will be saved to data/output_evaluation.csv
for further analysis.
You can also run the BSM2 models with your own aeration control - this example selects a random kla value for each reactor every timestep.
The final performance is then saved in the oci
variable:
import numpy as np
from bsm2_python import BSM2OL
from tqdm import tqdm
bsm2_ol = BSM2OL()
# The kla values to choose from
select_klas = np.array([0, 60, 120, 180, 240])
for idx, _ in enumerate(tqdm(bsm2_ol.simtime)):
# select random klas for all five ASM1 reactors
klas = np.random.choice(select_klas, 5)
# make a step in the simulation with the specified kla values
bsm2_ol.step(idx, klas)
oci = bsm2_ol.get_final_performance()[-1]
You can also run the BSM2 Closed Loop model with your own dissolved oxygen (SO4) setpoints. Please note: The Closed Loop model runs with a resolution of 1 minute for the sake of sensor stability, so it might take a while to run the simulation.
from bsm2_python import BSM2CL
from tqdm import tqdm
bsm2_cl = BSM2CL()
# The custom DO setpoint for the BSM2 default aeration control
so4_ref = 1.5
for idx, _ in enumerate(tqdm(bsm2_cl.simtime)):
bsm2_cl.step(idx, so4_ref)
# get the final performance of the plant
oci = bsm2_cl.get_final_performance()[-1]
We introduced a simple energy management model (including CHPs, Boilers, Flares and a small techno-economic analysis) that can be used to simulate the energy consumption and production of the plant.
from bsm2_python import BSM2OLEM
bsm2_olem = BSM2OLEM()
bsm2_olem.simulate()
# get the cumulated cash flow of the plant
cash_flow = bsm2_olem.economics.cum_cash_flow
You can also implement your own plant layout. Lots of classes are available to choose from. See the Documentation for more information.
The tests
folder contains a lot of examples on how to use the plant layouts.
The project is structured as follows:
bsm2-python
├───docs
│ └────Documentation of the project
├───src
│ └────bsm2_python
│ | └─Root folder of the project code
│ │ Contains pre-defined plant layouts and controllers
│ ├───bsm2
│ │ │ └─All modules for the BSM2 plant layouts
│ │ └───init
│ │ └─Initialisation files for the BSM2 plant layouts
│ └───data
│ │ └─Standard datasets for influent data
│ │ and sensor noise
│ └───gas_management
│ │ └─Modules for the gas management side of the BSM2 plant
│ └───init
│ └─Initialisation files for the gas management side
└───tests
| └─Unit tests for the BSM2 components in both
│ steady state and dynamic mode
└───simulink_files
└─Reference files for validation purposes
At the moment, you can choose between different ready-to-use configurations of the plant:
You can as well create your own plant layout. Just use the classes in the bsm2
folder and mix them as you like.
The results of the pre-made configurations are saved inside the objects and can be accessed via calling the attribute names. For the plant effluent, just call bsm2.y_eff_all
.
With tempmodel
and activate
, differential equations for temperature dependency and additional components can be added.
If you want to create your own plant layout, use the bsm2_xx.py
files as template. Put your own parameters and values in separate init
files.
Your help is highly appreciated! Please read through the CONTRIBUTING.md file for details on our code of conduct, and the process for submitting pull requests to us. If you find any issues inside the repo, don't hesitate to raise an Issue.
There is also a fully functional Dev Container image available for development. Just open the repo in VSCode and install the Remote Containers extension. Then, open the repo in a container and you are ready to go.
In the future, this repo will be extended by the following features:
Thanks to Maike Böhm for first implementing the Activated Sludge Models in Python in her Masters Thesis. Thanks as well to Lukas Meier for implementing the Gas management side of the BSM2 plant and Nick Salomon for prettifying the documentation.
The development of this package was done in the context of the KLÄFFIZIENT and KLÄFFIZIENTER projects. Both are funded by the German Federal Ministry for Economic Affairs and Climate Action (BMWK) and are part of the 7th and 8th Energy Research Program of the Federal Government.
This project is licensed under BSD 3 Clause.
As we are maintaining this repo in our free time, don't expect rapid development. However, if any Issues are popping up, we will try to fix them in time.
If you use this code in your research, please cite the following paper:
@article{miederer2025,
title = {Energy Management Model for Wastewater Treatment Plants},
journal = {Energy Reports},
volume = {13},
pages = {6349-6361},
year = {2025},
issn = {2352-4847},
doi = {10.1016/j.egyr.2025.05.045},
author = {Jonas Miederer and Lukas Meier and Nora Elhaus and Simon Markthaler and Jürgen Karl}}
FAQs
A Python implementation of the Benchmark Simulation Model 2 (BSM2) plant layout according to the IWA standard.
We found that bsm2-python demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Browserslist-rs now uses static data to reduce binary size by over 1MB, improving memory use and performance for Rust-based frontend tools.
Research
Security News
Eight new malicious Firefox extensions impersonate games, steal OAuth tokens, hijack sessions, and exploit browser permissions to spy on users.
Security News
The official Go SDK for the Model Context Protocol is in development, with a stable, production-ready release expected by August 2025.