#!/usr/bin/env python # coding: utf-8 # # Transient separation of 2 chemicals in 1D, due to their different diffusion rates # # ### Starting with identical concentrations in one of the bins, they initially separate... # ### until they eventually attain identical concentrations at equilibrium # # For a complete separation by means of membranes, see experiment `membranes_3` # ### TAGS : "diffusion 1D", "basic" # In[1]: LAST_REVISED = "Aug. 15, 2025" LIFE123_VERSION = "1.0.0rc6" # Library version this experiment is based on # In[2]: #import set_path # Using MyBinder? Uncomment this before running the next cell! # In[3]: #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 # In[4]: check_version(LIFE123_VERSION) # In[ ]: # ## Prepare the initial system # with identical bin concentrations of the chemicals `A` and `B`, in the center bin. # `B` diffuses much faster than `A` # In[5]: chem_data = ChemData(names=["A", "B"], diffusion_rates=[0.1, 2.], plot_colors=["turquoise", "green"]) bio = BioSim1D(n_bins=9, chem_data=chem_data) # In[6]: 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() # In[7]: bio.system_snapshot() # In[8]: bio.visualize_system(title_prefix="Diffusion. The 2 concentrations initially perfectly overlap") # Line curve view # In[9]: bio.system_heatmaps(title_prefix="Diffusion") # In[ ]: # ## Request history-keeping for some bins # In[10]: # 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) # In[ ]: # In[ ]: # ## Initial Diffusion Step # In[11]: # Advancing to time t=1, with moderate time steps bio.diffuse(total_duration=1.0, fraction_max_step=0.4) # In[13]: bio.describe_state() # In[ ]: # ## The 2 chemicals `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` # In[14]: bio.visualize_system(title_prefix="Diffusion") # Line curve view # In[15]: bio.system_heatmaps(title_prefix="Diffusion") # In[ ]: # In[ ]: # ## Let's advance the diffusion # In[16]: bio.diffuse(total_duration=2.0, fraction_max_step=0.4) # In[17]: bio.describe_state() # ## `B` is close to equilibrium, while `A` is nowhere near it! # In[18]: bio.visualize_system(title_prefix="Diffusion") # Line curve view # In[19]: bio.system_heatmaps(title_prefix="Diffusion") # In[ ]: # In[ ]: # ## Let's advance the diffusion some more # In[21]: bio.diffuse(total_duration=2.0, fraction_max_step=0.4) # In[22]: bio.describe_state() # ## Notice that the concentrations of `A` and `B` in the central bin 4 are again getting closer in value # In[23]: bio.visualize_system(title_prefix="Diffusion") # Line curve view # In[24]: bio.system_heatmaps(title_prefix="Diffusion") # In[ ]: # In[ ]: # ## Finally, let's advance the diffusion to equilibrium # In[25]: bio.diffuse(total_duration=95.0, fraction_max_step=0.4) # In[26]: bio.describe_state() # ## All bins now have essentially uniform concentration # ## Notice that the concentrations of `A` and `B` in the central bin 4 are again essentially identical; the separation of `A` and `B` is coming to an end # In[27]: bio.visualize_system(title_prefix="Diffusion") # Line curve view # In[28]: bio.system_heatmaps(title_prefix="Diffusion") # #### Verify that the total amount of each chemicals hasn't changed # In[29]: # Let's verify mass conservation bio.check_mass_conservation(chem_label="A", expected=10.) # In[30]: bio.check_mass_conservation(chem_label="B", expected=10.) # In[ ]: # In[ ]: # ## Visualization of time changes at particular bins # #### Instead of visualizing the entire system at a moment in time, like in the previous diagrams, let's now look at the time evolution of the concentrations of `A` and `B` at selected bins (bins whose history-keeping we requested prior to running the simulation) # In[31]: bin4_hist = bio.conc_history.bin_history(bin_address=4) # The bin where the initial concentration of `A` and `B` was applied bin4_hist # In[32]: bio.plot_history_single_bin(bin_address=4, title_prefix="`A` and `B` separate, until they finally rejoin") # ## The transient separation of `A` and `B` is best seen by plotting the difference of their concentrations, as a function of time # In[33]: bin4_hist["A"] - bin4_hist["B"] # In[34]: 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") # In[ ]: # ## The transient separation of `A` and `B` is also seen in other bins... # In[35]: bio.plot_history_single_bin(bin_address=0, title_prefix="The transient separation of `A` and `B` happens at other bins, too...") # In[36]: bio.plot_history_single_bin(bin_address=2, title_prefix="The transient separation of `A` and `B` happens at other bins, too...") # In[ ]: