#!/usr/bin/env python # coding: utf-8 # # Membranes, with selective permeability, separate 2 previously fully-mixed chemicals # # #### The membranes are permeable to one of the chemicals, and impermeable to the other one. # # See also experiment `diffusion_3`, where a transient separation is achieved WITHOUT membranes # ### TAGS : "membranes 1D", "basic", "diffusion 1D" # In[1]: LAST_REVISED = "May 31, 2025" LIFE123_VERSION = "1.0.0rc3" # Library version this experiment is based on # In[2]: #import set_path # Using MyBinder? Uncomment this before running the next cell! # In[26]: #import sys, os #os.getcwd() #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 two chemicals `A` and `B` # In[5]: chem_data = ChemData(diffusion_rates=[2., 2.], plot_colors=["turquoise", "green"]) # Names "A", "B" automatically assigned 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.set_membranes(membranes=[ (4,5) ]) # By default impermeable bio.change_permeability("B", 1.) # Permeable to `B` (and only to `B`) bio.describe_state() # In[7]: bio.system_snapshot() # In[8]: bio.system_heatmaps() # In[ ]: # ## Request history-keeping for some bins # In[9]: # 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[ ]: # ## Now, let's start the diffusion # In[10]: bio.diffuse(time_step=0.02, n_steps=1) # In[11]: bio.system_snapshot() # In[12]: bio.system_heatmaps() # In[13]: bio.visualize_system() # Line curve view # ### The concentrations of `A` and `B` start to differ # The membranes are impermeable to `A` but permeable to `B` # # In[ ]: # ### Let's advance the diffusion # In[14]: bio.diffuse(time_step=0.02, n_steps=4) # In[15]: bio.system_heatmaps() # In[16]: bio.visualize_system() # Line curve view # In[ ]: # In[17]: bio.diffuse(time_step=0.02, n_steps=15) # In[18]: bio.system_heatmaps() # In[19]: bio.visualize_system() # Line curve view # In[ ]: # In[ ]: # ## Finally, let's advance the diffusion to equilibrium # In[20]: bio.diffuse(time_step=0.02, n_steps=600) # In[21]: bio.system_heatmaps() # In[22]: bio.visualize_system() # Line curve view # # The membranes, with their selective permeability, have managed to separate the previously fully-mixed `A` and `B`| # In[ ]: # #### Verify that the total amount of each chemicals hasn't changed; in the case of `B`, it has simply shifted across bins # In[23]: # Let's verify mass conservation bio.check_mass_conservation(chem_label="A", expected=10.) # In[24]: 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[25]: bio.plot_history_single_bin(bin_address=4, title_prefix="`A` and `B` get separated") # ## The transient separation of `A` and `B` is best seen by plotting the difference of their concentrations, as a function of time # In[28]: 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[29]: 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="The separation of `A` and `B`, as seen in central bin 4") # In[ ]: # ## The separation of `A` and `B` is also seen in other bins... # In[30]: bio.plot_history_single_bin(bin_address=0, title_prefix="The separation of `A` and `B` happens at other bins, too...") # In[31]: bio.plot_history_single_bin(bin_address=2, title_prefix="The separation of `A` and `B` happens at other bins, too...") # In[ ]: