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: June 23, 2024 (using v. 1.0 beta34.1)
import set_path # Importing this module will add the project's home directory to sys.path
Added 'D:\Docs\- MY CODE\BioSimulations\life123-Win7' to sys.path
from experiments.get_notebook_info import get_notebook_basename
from life123 import ChemData as chem
from life123 import BioSim1D
import plotly.express as px
from life123 import GraphicLog
# Initialize the HTML logging (for the graphics)
log_file = get_notebook_basename() + ".log.htm" # Use the notebook base filename for the log file
# Set up the use of some specified graphic (Vue) components
GraphicLog.config(filename=log_file,
components=["vue_cytoscape_2"],
extra_js="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.21.2/cytoscape.umd.js")
-> Output will be LOGGED into the file 'reaction_1.log.htm'
# Initialize the system
chem_data = chem(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.)
bio.set_uniform_concentration(species_name="B", conc=50.)
bio.describe_state()
SYSTEM STATE at Time t = 0: 3 bins and 2 species: Species 0 (A). Diff rate: None. Conc: [10. 10. 10.] Species 1 (B). Diff rate: None. Conc: [50. 50. 50.]
# Save the state of the concentrations of all species at bin 0
bio.add_snapshot(bio.bin_snapshot(bin_address = 0), caption="Initial state")
bio.get_history()
| SYSTEM TIME | A | B | caption | |
|---|---|---|---|---|
| 0 | 0 | 10.0 | 50.0 | Initial state |
# Specify the reaction
# Reaction A <-> B , with 1st-order kinetics in both directions
chem_data.add_reaction(reactants=["A"], products=["B"], forward_rate=3., reverse_rate=2.)
print("Number of reactions: ", chem_data.number_of_reactions())
Number of reactions: 1
chem_data.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'}
# Send a plot of the network of reactions to the HTML log file
chem_data.plot_reaction_network("vue_cytoscape_2")
[GRAPHIC ELEMENT SENT TO LOG FILE `reaction_1.log.htm`]
# First step of reaction
bio.react(time_step=0.1, n_steps=1)
bio.describe_state()
SYSTEM STATE at Time t = 0.1: 3 bins and 2 species: Species 0 (A). Diff rate: None. Conc: [17. 17. 17.] Species 1 (B). Diff rate: None. Conc: [43. 43. 43.]
NOTE: the concentration of species A is increasing, while that of species B is decreasing.
All bins have identical concentrations; so, there's no diffusion (and we're not attempting to compute it):
[[17. 17. 17.]
[43. 43. 43.]]
# Save the state of the concentrations of all species at bin 0
bio.add_snapshot(bio.bin_snapshot(bin_address = 0))
bio.get_history()
| SYSTEM TIME | A | B | caption | |
|---|---|---|---|---|
| 0 | 0.0 | 10.0 | 50.0 | Initial state |
| 1 | 0.1 | 17.0 | 43.0 |
# Numerous more steps
bio.react(time_step=0.1, n_steps=10, snapshots={"sample_bin": 0})
bio.describe_state()
SYSTEM STATE at Time t = 1.1: 3 bins and 2 species: Species 0 (A). Diff rate: None. Conc: [23.99316406 23.99316406 23.99316406] Species 1 (B). Diff rate: None. Conc: [36.00683594 36.00683594 36.00683594]
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
# Save the state of the concentrations of all species at bin 0
#bio.save_snapshot(bio.bin_snapshot(bin_address = 0))
bio.get_history()
| SYSTEM TIME | A | B | caption | |
|---|---|---|---|---|
| 0 | 0.0 | 10.000000 | 50.000000 | Initial state |
| 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 |
fig = px.line(data_frame=bio.get_history(), x="SYSTEM TIME", y=["A", "B"],
title="Changes in concentrations with time",
color_discrete_sequence = ['navy', 'darkorange'],
labels={"value":"concentration", "variable":"Chemical"})
fig.show()
# Same plot, but with a smoothed line
fig = px.line(data_frame=bio.get_history(), x="SYSTEM TIME", y=["A", "B"],
title="Changes in concentrations with time (smoothed)",
color_discrete_sequence = ['navy', 'darkorange'],
labels={"value":"concentration", "variable":"Chemical"},
line_shape="spline")
fig.show()