Multiple compartments
Multiple compartments#
Compartments can be nested within another Compartment, allowing some modularity in the definition of models. Inner compartments can be extracted, and simulated independently of the whole model.
import numpy as np
from simbio.components import EmptyCompartment, Species
from simbio.reactions.single import Conversion, Dissociation, Synthesis
from simbio.simulator import Simulator
Here, we define a model consisting of two inner compartments, both containing hydrogen, oxygen and water. Water is synthesized in one compartment, and transported to the other compartment, where it is dissociated, and the oxygen and hydrogen transported back to the first compartment.
class Outer(EmptyCompartment):
class Inner1(EmptyCompartment):
H2: Species = 1
O2: Species = 1
H2O: Species = 0
create_water = Synthesis(A=2 * H2, B=O2, AB=2 * H2O, rate=2)
class Inner2(EmptyCompartment):
H2: Species = 0
O2: Species = 0
H2O: Species = 0.1
electrolysis = Dissociation(AB=2 * H2O, A=2 * H2, B=O2, rate=0.5)
# Transport between compartments
water_transport = Conversion(A=Inner1.H2O, B=Inner2.H2O, rate=1)
H2_transport = Conversion(A=Inner2.H2, B=Inner1.H2, rate=1)
O2_transport = Conversion(A=Inner2.O2, B=Inner1.O2, rate=1)
We can simulate the whole model:
simulator = Simulator(Outer)
t = np.linspace(0, 10, 100)
df = simulator.run(t)
df.head()
| Inner1.H2 | Inner1.O2 | Inner1.H2O | Inner2.H2O | Inner2.H2 | Inner2.O2 | |
|---|---|---|---|---|---|---|
| time | ||||||
| 0.00000 | 1.000000 | 1.000000 | 0.000000 | 0.100000 | 0.000000 | 0.000000 |
| 0.10101 | 0.728348 | 0.864174 | 0.256748 | 0.113843 | 0.001060 | 0.000530 |
| 0.20202 | 0.586138 | 0.793069 | 0.366923 | 0.144387 | 0.002553 | 0.001276 |
| 0.30303 | 0.496147 | 0.748074 | 0.417331 | 0.181650 | 0.004872 | 0.002436 |
| 0.40404 | 0.433279 | 0.716640 | 0.437497 | 0.220904 | 0.008320 | 0.004160 |
and just visualize the time evolution of the H20 species in each compartment,
with the DataFrame.filter method followed by .plot:
df.filter(like="H2O").plot()
<AxesSubplot: xlabel='time'>
But, we can also simulate a single compartment:
simulator = Simulator(Outer.Inner1)
t = np.linspace(0, 10, 100)
df = simulator.run(t)
df.plot()
<AxesSubplot: xlabel='time'>