#!/usr/bin/env python # coding: utf-8 # # Exploring the change of delta_x (spatial resolution) in diffusion accuracy. # #### From the same initial setup, diffusion is carried out over a fixed time span, # #### at different spatial resolutions - and then the respective results are compared # # LAST REVISED: May 27, 2023 # In[1]: import set_path # Importing this module will add the project's home directory to sys.path # In[2]: from experiments.get_notebook_info import get_notebook_basename from src.life_1D.bio_sim_1d import BioSim1D from src.modules.reactions.reaction_data import ReactionData as chem from src.modules.numerical.numerical import Numerical as num import plotly.express as px import plotly.graph_objects as go from src.modules.html_log.html_log import HtmlLog as log from src.modules.visualization.graphic_log import GraphicLog # In[3]: # Initialize the HTML logging 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_heatmap_11", "vue_curves_3"]) # In[4]: # Set the heatmap parameters (for the log file) heatmap_pars = {"range": [0, 150], "outer_width": 850, "outer_height": 150, "margins": {"top": 30, "right": 30, "bottom": 30, "left": 55} } # Set the parameters of the line plots lineplot_pars = {"range": [0, 150], "outer_width": 850, "outer_height": 250, "margins": {"top": 30, "right": 30, "bottom": 30, "left": 55} } # ## Prepare the initial system # In[5]: chem_data = chem(names=["A"], diffusion_rates=[0.1]) conc_list=[10,13,17,21,25,28,30,38,42,55,65,47,35,32,27,23,20,17,14,8,3,10,16,18, 20,25,30,35,40,65,85,115,150,92,73,69,65,50,42,36,20,45,50,55,69,82,95, 77,60,43,37,31,25,22,20,18,15,11,9, 8] bio = BioSim1D(n_bins=len(conc_list), chem_data=chem_data) bio.set_species_conc(species_name="A", conc_list=conc_list) bio.describe_state() # In[6]: # Line plot fig = px.line(data_frame=bio.system_snapshot(), y=["A"], title= f"Diffusion. System snapshot at time t={bio.system_time}", color_discrete_sequence = ['red'], labels={"value":"concentration", "variable":"Chemical", "index":"Bin number"}) fig.show() # In[7]: # Show as a heatmap fig = px.imshow(bio.system_snapshot().T, title= f"Diffusion. System snapshot as a heatmap at time t={bio.system_time}", labels=dict(x="Bin number", y="Chem. species", color="Concentration"), text_auto=False, color_continuous_scale="gray_r") fig.data[0].xgap=2 fig.data[0].ygap=4 fig.show() # In[8]: log.write("1-D diffusion of a single species, with Diffusion rate 0.1", style=log.h2) log.write("Initial system state at time t=0:", blanks_before=2, style=log.bold) # Output a heatmap to the log file bio.single_species_heatmap(species_index=0, heatmap_pars=heatmap_pars, graphic_component="vue_heatmap_11") # Output a line plot the log file bio.single_species_line_plot(species_index=0, plot_pars=lineplot_pars, graphic_component="vue_curves_3") # In[9]: bio.describe_state(concise=True) # ### Populate the data set with more bins, using interpolated concentration values # ### IMPORTANT: we're **NOT** changing spacial resolution here; we're just creating a less ragged dataset, as *our initial system state* # In[10]: bio.smooth_spatial_resolution() bio.describe_state() # In[11]: bio.n_bins # # The STARTING POINT # ### This system setup will be our starting point in exploring diffusion using different spacial resolutions # In[12]: original_state = bio.save_system() # SAVE a copy of the system state, to do multiple runs starting from it # In[13]: # Line plot fig = px.line(data_frame=bio.system_snapshot(), y=["A"], title= f"Diffusion. System snapshot at time t={bio.system_time}", color_discrete_sequence = ['red'], labels={"value":"concentration", "variable":"Chemical", "index":"Bin number"}) fig.show() # In[14]: # Show as a heatmap fig = px.imshow(bio.system_snapshot().T, title= f"Diffusion. System snapshot as a heatmap at time t={bio.system_time}", labels=dict(x="Bin number", y="Chem. species", color="Concentration"), text_auto=False, color_continuous_scale="gray_r") fig.data[0].xgap=2 fig.data[0].ygap=4 fig.show() # # Initial Diffusions with delta_x = 1 # In[15]: bio.describe_state(concise=True) # Our initial state # In[16]: bio.diffuse(total_duration=7, time_step=0.0005) bio.describe_state(concise=True) # In[17]: # SAVE the above system data (a matrix of dimension n_species x n_bins): this is the result of diffusion with delta_x = 1 diffuse_dx_1 = bio.system # In[18]: # Line plot fig = px.line(data_frame=bio.system_snapshot(), y=["A"], title= f"Diffusion. System snapshot at time t={bio.system_time}", color_discrete_sequence = ['red'], labels={"value":"concentration", "variable":"Chemical", "index":"Bin number"}) fig.show() # ### Enough time has proceeded to result in some smoothing, and non-puny changes in most values - but still nowhere near equilibrium # # Now restore the system to its initial (pre-diffusion) state # ### and then perform a diffusion over the same time span, but with DOUBLE the spacial resolution # #### delta_x will be be 1/2 instead of the original default 1 # In[19]: bio.restore_system(original_state) # In[20]: bio.describe_state() # In[21]: # Double the spacial resolution bio.increase_spatial_resolution(2) bio.describe_state() # In[22]: # Now repeat the idential diffusion process as before, but with half the delta_x bio.diffuse(total_duration=7, time_step=0.0005, delta_x=0.5) # In[23]: # Finally, halve the resolution, to return to the original number of bins bio.decrease_spatial_resolution(2) # In[24]: bio.describe_state(concise=True) # In[25]: # SAVE the above system data: this is the result of diffusion with delta_x of 1/2 diffuse_dx_1_2 = bio.system # ### Compare the last 2 runs (with dx=1 and dx=1/2) # In[26]: num.compare_states(diffuse_dx_1 , diffuse_dx_1_2, verbose=True) # # Again, restore the system to its initial (pre-diffusion) state # ### and then perform a diffusion over the same time span, but with QUADRUPLE the spacial resolution # ### delta_x will be be 1/4 instead of the original default 1 # In[27]: bio.restore_system(original_state) # In[28]: bio.describe_state() # In[29]: # Quadruple the spacial resolution bio.increase_spatial_resolution(4) bio.describe_state() # In[30]: # Now repeat the idential diffusion process as before, but with 1/4 the delta_x bio.diffuse(total_duration=7, time_step=0.0005, delta_x=0.25) # In[31]: # Finally, reduce the resolution by a factor 4, to return to the original number of bins bio.decrease_spatial_resolution(4) bio.describe_state(concise=True) # In[32]: # SAVE the above system data: this is the result of diffusion with delta_x of 1/4 diffuse_dx_1_4 = bio.system # ### Compare the latest 2 runs (with dx=1/2 and dx=1/4) # In[33]: num.compare_states(diffuse_dx_1_2 , diffuse_dx_1_4) # ### Notice how the discrepancies have gone down # # One last time, restore the system to its initial (pre-diffusion) state # ### and then perform a diffusion over the same time span, but with 10x the spacial resolution # ### delta_x will be be 1/10 instead of the original default 1 # In[34]: bio.restore_system(original_state) # Increase by a factor 10 the spacial resolution bio.increase_spatial_resolution(10) bio.n_bins # In[35]: # Now repeat the idential diffusion process as before, but with 1/10 the delta_x bio.diffuse(total_duration=7, time_step=0.0005, delta_x=0.1) # In[36]: # Finally, reduce the resolution by a factor 10, to return to the original number of bins bio.decrease_spatial_resolution(10) bio.describe_state(concise=True) # In[37]: # SAVE the above system data: this is the result of diffusion with delta_x of 1/10 diffuse_dx_1_10 = bio.system # ### Again, compare the latest 2 runs (with dx=1/4 and dx=1/10) # In[38]: num.compare_states(diffuse_dx_1_4 , diffuse_dx_1_10) # ### Notice how the discrepancies have gone down even more # ### This matches expectations that we're getting closer and closer to a "true" (very high precision) value, as we keep increasing the spacial resolution # In[ ]: