For a complete separation by means of membranes, see experiment membranes_3
LAST_REVISED = "May 30, 2025"
LIFE123_VERSION = "1.0.0rc3" # 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 BioSim1D, ChemData, PlotlyHelper, check_version
check_version(LIFE123_VERSION)
OK
with identical bin concentrations of the chemicals A and B, in the center bin.
B diffuses much faster than A
chem_data = ChemData(names=["A", "B"], diffusion_rates=[0.1, 2.], plot_colors=["turquoise", "green"])
bio = BioSim1D(n_bins=9, chem_data=chem_data)
bio.set_bin_conc(bin_address=4, chem_label="A", conc=10.)
bio.set_bin_conc(bin_address=4, chem_label="B", conc=10.)
bio.describe_state()
SYSTEM STATE at Time t = 0: 9 bins and 2 chemical species
| Species | Diff rate | Bin 0 | Bin 1 | Bin 2 | Bin 3 | Bin 4 | Bin 5 | Bin 6 | Bin 7 | Bin 8 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | A | 0.1 | 0.0 | 0.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 1 | B | 2.0 | 0.0 | 0.0 | 0.0 | 0.0 | 10.0 | 0.0 | 0.0 | 0.0 | 0.0 |
bio.system_snapshot()
| A | B | |
|---|---|---|
| 0 | 0.0 | 0.0 |
| 1 | 0.0 | 0.0 |
| 2 | 0.0 | 0.0 |
| 3 | 0.0 | 0.0 |
| 4 | 10.0 | 10.0 |
| 5 | 0.0 | 0.0 |
| 6 | 0.0 | 0.0 |
| 7 | 0.0 | 0.0 |
| 8 | 0.0 | 0.0 |
bio.visualize_system(title_prefix="Diffusion. The 2 concentrations initially perfectly overlap") # Line curve view
bio.system_heatmaps(title_prefix="Diffusion")
# Request to save the concentration history at the bin with the initial concentration injection,
# and at a couple of other bins
bio.enable_history(bins=[0, 2, 4], frequency=3, take_snapshot=True)
History enabled for bins [0, 2, 4] and chemicals None (None means 'all')
# Advancing to time t=1, with time steps of 0.05
bio.diffuse(total_duration=1.0, time_step=0.05)
{'steps': 20, 'system time': '1'}
bio.describe_state()
SYSTEM STATE at Time t = 1: 9 bins and 2 chemical species
| Species | Diff rate | Bin 0 | Bin 1 | Bin 2 | Bin 3 | Bin 4 | Bin 5 | Bin 6 | Bin 7 | Bin 8 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | A | 0.1 | 0.000026 | 0.001203 | 0.039743 | 0.829776 | 8.258503 | 0.829776 | 0.039743 | 0.001203 | 0.000026 |
| 1 | B | 2.0 | 0.355341 | 0.656747 | 1.201979 | 1.773354 | 2.025158 | 1.773354 | 1.201979 | 0.656747 | 0.355341 |
A and B, previously identical in concentrations, have separated due to their different diffusion rates¶Notice how B has spread out far more than A
bio.visualize_system(title_prefix="Diffusion") # Line curve view
bio.system_heatmaps(title_prefix="Diffusion")
bio.diffuse(total_duration=2.0, time_step=0.05)
{'steps': 40, 'system time': '3'}
bio.describe_state()
SYSTEM STATE at Time t = 3: 9 bins and 2 chemical species
| Species | Diff rate | Bin 0 | Bin 1 | Bin 2 | Bin 3 | Bin 4 | Bin 5 | Bin 6 | Bin 7 | Bin 8 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | A | 0.1 | 0.001863 | 0.024620 | 0.254045 | 1.731402 | 5.976139 | 1.731402 | 0.254045 | 0.024620 | 0.001863 |
| 1 | B | 2.0 | 0.993368 | 1.048422 | 1.132834 | 1.207131 | 1.236490 | 1.207131 | 1.132834 | 1.048422 | 0.993368 |
B is close to equilibrium, while A is nowhere near it!¶bio.visualize_system(title_prefix="Diffusion") # Line curve view
bio.system_heatmaps(title_prefix="Diffusion")
bio.diffuse(total_duration=2.0, time_step=0.05)
{'steps': 40, 'system time': '5'}
bio.describe_state()
SYSTEM STATE at Time t = 5: 9 bins and 2 chemical species
| Species | Diff rate | Bin 0 | Bin 1 | Bin 2 | Bin 3 | Bin 4 | Bin 5 | Bin 6 | Bin 7 | Bin 8 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | A | 0.1 | 0.010722 | 0.080956 | 0.500624 | 2.086625 | 4.642148 | 2.086625 | 0.500624 | 0.080956 | 0.010722 |
| 1 | B | 2.0 | 1.093790 | 1.101895 | 1.114312 | 1.125232 | 1.129544 | 1.125232 | 1.114312 | 1.101895 | 1.093790 |
A and B in the central bin 4 are again getting closer in value¶bio.visualize_system(title_prefix="Diffusion") # Line curve view
bio.system_heatmaps(title_prefix="Diffusion")
bio.diffuse(total_duration=95.0, time_step=0.05)
{'steps': 1900, 'system time': '100'}
bio.describe_state()
SYSTEM STATE at Time t = 100: 9 bins and 2 chemical species
| Species | Diff rate | Bin 0 | Bin 1 | Bin 2 | Bin 3 | Bin 4 | Bin 5 | Bin 6 | Bin 7 | Bin 8 | |
|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | A | 0.1 | 1.091824 | 1.100848 | 1.114675 | 1.126835 | 1.131637 | 1.126835 | 1.114675 | 1.100848 | 1.091824 |
| 1 | B | 2.0 | 1.111111 | 1.111111 | 1.111111 | 1.111111 | 1.111111 | 1.111111 | 1.111111 | 1.111111 | 1.111111 |
bio.visualize_system(title_prefix="Diffusion") # Line curve view
bio.system_heatmaps(title_prefix="Diffusion")
# Let's verify mass conservation
bio.check_mass_conservation(chem_label="A", expected=10.)
True
bio.check_mass_conservation(chem_label="B", expected=10.)
True
A and B at selected bins (bins whose history-keeping we requested prior to running the simulation)¶bin4_hist = bio.conc_history.bin_history(bin_address=4) # The bin where the initial concentration of `A` and `B` was applied
bin4_hist
| SYSTEM TIME | A | B | |
|---|---|---|---|
| 0 | 0.00 | 10.000000 | 10.000000 |
| 1 | 0.15 | 9.704475 | 5.600000 |
| 2 | 0.30 | 9.422007 | 3.908040 |
| 3 | 0.45 | 9.151954 | 3.108505 |
| 4 | 0.60 | 8.893710 | 2.652694 |
| ... | ... | ... | ... |
| 661 | 99.35 | 1.132271 | 1.111111 |
| 662 | 99.50 | 1.132123 | 1.111111 |
| 663 | 99.65 | 1.131976 | 1.111111 |
| 664 | 99.80 | 1.131830 | 1.111111 |
| 665 | 99.95 | 1.131685 | 1.111111 |
666 rows × 3 columns
bio.plot_history_single_bin(bin_address=4, title_prefix="`A` and `B` separate, until they finally rejoin")
A and B is best seen by plotting the difference of their concentrations, as a function of time¶bin4_hist["A"] - bin4_hist["B"]
0 0.000000
1 4.104475
2 5.513967
3 6.043449
4 6.241017
...
661 0.021160
662 0.021012
663 0.020865
664 0.020719
665 0.020574
Length: 666, dtype: float64
PlotlyHelper.plot_curves(x=bin4_hist['SYSTEM TIME'], y = bin4_hist['A'] - bin4_hist['B'],
x_label="SYSTEM TIME", y_label="[A] - [B]",
colors="purple", title="Transient separation of `A` and `B`, as seen in central bin 4")
A and B is also seen in other bins...¶bio.plot_history_single_bin(bin_address=0, title_prefix="The transient separation of `A` and `B` happens at other bins, too...")
bio.plot_history_single_bin(bin_address=2, title_prefix="The transient separation of `A` and `B` happens at other bins, too...")