A <-> B reaction between 2 species with initial uniform concentrations across 3 bins,¶with 1st-order kinetics in both directions, taken to equilibrium
Diffusion NOT taken into account
See also the experiment reactions_single_compartment/react_1
LAST_REVISED = "Jan. 13, 2025"
LIFE123_VERSION = "1.0.0rc2" # Library version this experiment is based on
#import set_path # Using MyBinder? Uncomment this before running the next cell!
#import sys
#sys.path.append("C:/some_path/my_env_or_install") # CHANGE to the folder containing your venv or libraries installation!
# NOTE: If any of the imports below can't find a module, uncomment the lines above, or try: import set_path
from life123 import ChemData, BioSim1D
# Initialize the system
chem_data = ChemData(names=["A", "B"]) # Diffusion NOT taken into account
bio = BioSim1D(n_bins=3, chem_data=chem_data) # We'll specify the reactions later
bio.set_uniform_concentration(species_name="A", conc=10.) # Same across all bins
bio.set_uniform_concentration(species_name="B", conc=50.) # Same across all bins
bio.describe_state()
SYSTEM STATE at Time t = 0: 3 bins and 2 chemical species:
| Species | Diff rate | Bin 0 | Bin 1 | Bin 2 | |
|---|---|---|---|---|---|
| 0 | A | None | 10.0 | 10.0 | 10.0 |
| 1 | B | None | 50.0 | 50.0 | 50.0 |
# Let's enable history - by default for all chemicals and all bins
bio.enable_history(take_snapshot=True)
History enabled for bins None and chemicals None (None means 'all')
bio.get_bin_history(bin_address=0)
| SYSTEM TIME | A | B | |
|---|---|---|---|
| 0 | 0.0 | 10.0 | 50.0 |
bio.get_bin_history(bin_address=1)
| SYSTEM TIME | A | B | |
|---|---|---|---|
| 0 | 0.0 | 10.0 | 50.0 |
bio.get_bin_history(bin_address=2)
| SYSTEM TIME | A | B | |
|---|---|---|---|
| 0 | 0.0 | 10.0 | 50.0 |
# Specify the reaction
reactions = bio.get_reactions()
# Reaction A <-> B , with 1st-order kinetics in both directions
reactions.add_reaction(reactants="A", products="B", forward_rate=3., reverse_rate=2.)
reactions.describe_reactions()
Number of reactions: 1 (at temp. 25 C)
0: A <-> B (kF = 3 / kR = 2 / delta_G = -1,005.1 / K = 1.5) | 1st order in all reactants & products
Set of chemicals involved in the above reactions: {'B', 'A'}
# First step of reaction
bio.react(time_step=0.1, n_steps=1)
bio.describe_state()
System Time is now: 0.1 SYSTEM STATE at Time t = 0.1: 3 bins and 2 chemical species:
| Species | Diff rate | Bin 0 | Bin 1 | Bin 2 | |
|---|---|---|---|---|---|
| 0 | A | None | 17.0 | 17.0 | 17.0 |
| 1 | B | None | 43.0 | 43.0 | 43.0 |
NOTE: the concentration of the chemical species A is increasing, while that of B is decreasing.
All bins have identical concentrations; so, there's no diffusion (and we're not attempting to compute it; didn't specify diffusion rates)
bio.get_bin_history(bin_address=0)
| SYSTEM TIME | A | B | |
|---|---|---|---|
| 0 | 0.0 | 10.0 | 50.0 |
| 1 | 0.1 | 17.0 | 43.0 |
# Several more steps
bio.react(time_step=0.1, n_steps=10)
bio.describe_state()
System Time is now: 1.1 SYSTEM STATE at Time t = 1.1: 3 bins and 2 chemical species:
| Species | Diff rate | Bin 0 | Bin 1 | Bin 2 | |
|---|---|---|---|---|---|
| 0 | A | None | 23.993164 | 23.993164 | 23.993164 |
| 1 | B | None | 36.006836 | 36.006836 | 36.006836 |
bio.get_bin_history(bin_address=0)
| SYSTEM TIME | A | B | |
|---|---|---|---|
| 0 | 0.0 | 10.000000 | 50.000000 |
| 1 | 0.1 | 17.000000 | 43.000000 |
| 2 | 0.2 | 20.500000 | 39.500000 |
| 3 | 0.3 | 22.250000 | 37.750000 |
| 4 | 0.4 | 23.125000 | 36.875000 |
| 5 | 0.5 | 23.562500 | 36.437500 |
| 6 | 0.6 | 23.781250 | 36.218750 |
| 7 | 0.7 | 23.890625 | 36.109375 |
| 8 | 0.8 | 23.945312 | 36.054688 |
| 9 | 0.9 | 23.972656 | 36.027344 |
| 10 | 1.0 | 23.986328 | 36.013672 |
| 11 | 1.1 | 23.993164 | 36.006836 |
bio.get_bin_history(bin_address=2)
| SYSTEM TIME | A | B | |
|---|---|---|---|
| 0 | 0.0 | 10.000000 | 50.000000 |
| 1 | 0.1 | 17.000000 | 43.000000 |
| 2 | 0.2 | 20.500000 | 39.500000 |
| 3 | 0.3 | 22.250000 | 37.750000 |
| 4 | 0.4 | 23.125000 | 36.875000 |
| 5 | 0.5 | 23.562500 | 36.437500 |
| 6 | 0.6 | 23.781250 | 36.218750 |
| 7 | 0.7 | 23.890625 | 36.109375 |
| 8 | 0.8 | 23.945312 | 36.054688 |
| 9 | 0.9 | 23.972656 | 36.027344 |
| 10 | 1.0 | 23.986328 | 36.013672 |
| 11 | 1.1 | 23.993164 | 36.006836 |
NOTE: Consistent with the 3/2 ratio of forward/reverse rates (and the 1st order reactions), the systems settles in the following equilibrium:
[A] = 23.99316406
[B] = 36.00683594
bio.bin_snapshot(bin_address=0)
{'A': 23.9931640625, 'B': 36.0068359375}
# Verify that the reaction has reached equilibrium
bio.reaction_dynamics.is_in_equilibrium(conc=bio.bin_snapshot(bin_address=0))
0: A <-> B
Final concentrations: [A] = 23.99 ; [B] = 36.01
1. Ratio of reactant/product concentrations, adjusted for reaction orders: 1.50071
Formula used: [B] / [A]
2. Ratio of forward/reverse reaction rates: 1.5
Discrepancy between the two values: 0.04749 %
Reaction IS in equilibrium (within 1% tolerance)
True
bio.plot_history_single_bin(bin_address=0,
title="Reaction A <-> B . Concentrations at bin 0")
# Same plot, but with a smoothed line
bio.plot_history_single_bin(bin_address=0,
title="Reaction A <-> B . Concentrations at bin 0",
smoothed=True)
reactions_single_compartment/react_1¶