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'>
../_images/compartments_7_1.png

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'>
../_images/compartments_9_1.png