🚧 Note: This project is still in active development. Expect incomplete features and breaking changes. 🚧
The Biomechanical and Biochemical Simulator (BMBC-Sim) is a multi-physics simulation framework for simulating coupled mechanical and chemical processes in biological models using NGSolve. It is designed to easily prototype hypotheses, reproduce literature scenarios, or explore custom geometries with tightly coupled mechanical and chemical dynamics.
uv sync # create the development environment
uv run python scripts/demo.py # run a demo simulationBMBC-Sim relies on uv for reproducible environments. Once uv sync completes, the virtual environment is available in your IDE.
Setting up a simulation is straightforward as BMBC-Sim provides an easy-to-use API for defining geometries, species, diffusion, reactions, and more.
importastropy.unitsasuimportbmbcsimimportbmbcsim.simulation.transportastransport# Create a spherical mesh with a radius of 10 micrometers and a mesh size of 1 micrometermesh=bmbcsim.geometry.create_sphere_geometry(radius=10*u.um, mesh_size=1*u.um)
sim=bmbcsim.Simulation(
mesh, result_directory=bmbcsim.timestamped_directory("results", "demo")
)
# Access the compartment named "sphere" from the simulation geometry# and add species that can diffuse and react within itcell=sim.simulation_geometry.compartments["sphere"]
ca=sim.add_species("ca")
buffer=sim.add_species("buffer")
ca_buffer=sim.add_species("ca_buffer")
# Initialize the buffer with a concentration of 1 millimolarcell.initialize_species(buffer, value=1*u.mmol/u.l)
# Add diffusion constants on a per-species and per-compartment basiscell.add_diffusion(ca, diffusivity=0.2*u.um**2/u.ms)
cell.add_diffusion(buffer, diffusivity=0.1*u.um**2/u.ms)
cell.add_diffusion(ca_buffer, diffusivity=0.05*u.um**2/u.ms)
# Add reaction Ca + Buffer <-> CaBuffer with forward and reverse rate constantscell.add_reaction(
reactants=[ca, buffer], products=[ca_buffer],
k_f=0.1/ (u.ms*u.um**3), k_r=0.05/u.ms,
)
# Add influx of calcium at the boundary of the sphere with a rate of# 0.2 millimolar per millisecond for the first 5 millisecondsmembrane=sim.simulation_geometry.membranes["boundary"]
buffer_substance=1*u.mmol/u.l*cell.volumebase_flux=buffer_substance/ (5*u.ms)
spike=lambdat: 1ift<5*u.mselse0flux=transport.GeneralFlux(flux=base_flux, temporal=spike)
membrane.add_transport(ca, flux, source=None, target=cell)
# Run the simulation for 10 milliseconds with a time step of 0.1 milliseconds# recording a snapshot of all species every 1 millisecondsim.run(end_time=10.0*u.ms, time_step=0.1*u.ms, record_interval=1.0*u.ms)This runs a simple reaction-diffusion simulation in a spherical cell and stores the results in the results/demo_<timestamp> folder.
The ResultLoader API then lets you post-process outputs into pandas/xarray structures.
All results are saved as XDMF files for easy visualization in Paraview or similar tools.
Please use the 'Xdmf Reader' (no 'S' or 'T' version) in Paraview to load the files.
If the visualization is slow, consider only loading the point arrays you need under 'properties'.
This should give you an output like this:

src/bmbcsim/– core simulation engine, geometry builders, and utilities.scripts/– curated scenarios that are ready to run (literature replications) and ongoing work.scripts/prototypes/– bite-sized notebooks and scripts that explore specific techniques (point sampling, tortuosity, deformation, etc.).test/– pytest suite covering units, multi-compartment setups, electrostatics, and geometry validation.