|
24 | 24 | # In part2, some diagnotic insight is explored. |
25 | 25 | # In part3, two identical runs ("adaptive variable steps" and "fixed small steps") are compared. |
26 | 26 | # |
27 | | -# LAST REVISED: May 5, 2024 |
| 27 | +# LAST REVISED: May 27, 2024 (using v. 1.0beta32) |
28 | 28 |
|
29 | 29 | # %% [markdown] |
30 | 30 | # ## Bathtub analogy: |
|
46 | 46 | # %% tags=[] |
47 | 47 | from experiments.get_notebook_info import get_notebook_basename |
48 | 48 |
|
| 49 | +from src.modules.chemicals.chem_data import ChemData |
49 | 50 | from src.modules.reactions.reaction_dynamics import ReactionDynamics |
50 | 51 | from src.modules.visualization.plotly_helper import PlotlyHelper |
51 | 52 |
|
|
66 | 67 |
|
67 | 68 | # %% tags=[] |
68 | 69 | # Instantiate the simulator and specify the chemicals |
69 | | -dynamics = ReactionDynamics(names=["A", "B", "C"]) |
| 70 | +chem = ChemData(names=["A", "B", "C"]) |
70 | 71 |
|
71 | 72 | # Reaction A <-> B (fast) |
72 | | -dynamics.add_reaction(reactants=["A"], products=["B"], |
| 73 | +chem.add_reaction(reactants=["A"], products=["B"], |
73 | 74 | forward_rate=64., reverse_rate=8.) |
74 | 75 |
|
75 | 76 | # Reaction B <-> C (slow) |
76 | | -dynamics.add_reaction(reactants=["B"], products=["C"], |
| 77 | +chem.add_reaction(reactants=["B"], products=["C"], |
77 | 78 | forward_rate=12., reverse_rate=2.) |
78 | 79 |
|
79 | | -print("Number of reactions: ", dynamics.number_of_reactions()) |
| 80 | +print("Number of reactions: ", chem.number_of_reactions()) |
80 | 81 |
|
81 | 82 | # %% |
82 | | -dynamics.describe_reactions() |
| 83 | +chem.describe_reactions() |
83 | 84 |
|
84 | 85 | # %% |
85 | 86 | # Send a plot of the network of reactions to the HTML log file |
86 | | -dynamics.plot_reaction_network("vue_cytoscape_2") |
| 87 | +chem.plot_reaction_network("vue_cytoscape_2") |
87 | 88 |
|
88 | 89 | # %% [markdown] |
89 | 90 | # ## Run the simulation |
90 | 91 |
|
91 | 92 | # %% |
| 93 | +dynamics = ReactionDynamics(chem_data=chem, preset="fast") |
| 94 | + |
92 | 95 | dynamics.set_conc([50., 0, 0.], snapshot=True) # Set the initial concentrations of all the chemicals, in their index order |
93 | 96 | dynamics.describe_state() |
94 | 97 |
|
|
101 | 104 | # %% |
102 | 105 | dynamics.set_diagnostics() # To save diagnostic information about the call to single_compartment_react() |
103 | 106 |
|
104 | | -# These settings can be tweaked to make the time resolution finer or coarser. |
105 | | -# Here we use a "fast" heuristic: less conservative about taking larger steps |
106 | | -dynamics.use_adaptive_preset(preset="fast") |
107 | | - |
108 | 107 | dynamics.single_compartment_react(initial_step=0.02, reaction_duration=0.4, |
109 | 108 | snapshots={"initial_caption": "1st reaction step", |
110 | 109 | "final_caption": "last reaction step"}, |
|
119 | 118 | colors=['blue', 'orange', 'green'], show_intervals=True) |
120 | 119 |
|
121 | 120 | # %% |
122 | | -dynamics.curve_intersection("A", "B", t_start=0, t_end=0.05) |
| 121 | +dynamics.curve_intersect("A", "B", t_start=0, t_end=0.05) |
123 | 122 |
|
124 | 123 | # %% |
125 | | -dynamics.curve_intersection("A", "C", t_start=0, t_end=0.05) |
| 124 | +dynamics.curve_intersect("A", "C", t_start=0, t_end=0.05) |
126 | 125 |
|
127 | 126 | # %% |
128 | | -dynamics.curve_intersection("B", "C", t_start=0.05, t_end=0.1) |
| 127 | +dynamics.curve_intersect("B", "C", t_start=0.05, t_end=0.1) |
129 | 128 |
|
130 | 129 | # %% |
131 | 130 | dynamics.get_history() |
|
195 | 194 | # We'll use **constant steps of size 0.0005** , which is 1/4 of the smallest steps (the "substep" size) previously used in the variable-step run |
196 | 195 |
|
197 | 196 | # %% |
198 | | -dynamics2 = ReactionDynamics(shared=dynamics) # Re-use the same chemicals and reactions of the previous simulation |
| 197 | +dynamics2 = ReactionDynamics(chem_data=chem) # Re-use the same chemicals and reactions of the previous simulation |
199 | 198 |
|
200 | 199 | # %% tags=[] |
201 | 200 | dynamics2.set_conc([50., 0, 0.], snapshot=True) |
202 | 201 |
|
203 | 202 | # %% |
| 203 | +# Notice that we're using FIXED steps this time |
204 | 204 | dynamics2.single_compartment_react(initial_step=0.0005, reaction_duration=0.4, |
205 | 205 | variable_steps=False, |
206 | 206 | snapshots={"initial_caption": "1st reaction step", |
|
215 | 215 | # _(Notice that the vertical steps are now equally spaced - and that there are so many of them that we're only showing some)_ |
216 | 216 |
|
217 | 217 | # %% |
218 | | -dynamics2.curve_intersection(t_start=0, t_end=0.05, chem1="A", chem2="B") |
| 218 | +dynamics2.curve_intersect(t_start=0, t_end=0.05, chem1="A", chem2="B") |
219 | 219 |
|
220 | 220 | # %% |
221 | | -dynamics2.curve_intersection(t_start=0, t_end=0.05, chem1="A", chem2="C") |
| 221 | +dynamics2.curve_intersect(t_start=0, t_end=0.05, chem1="A", chem2="C") |
222 | 222 |
|
223 | 223 | # %% |
224 | | -dynamics2.curve_intersection(t_start=0.05, t_end=0.1, chem1="B", chem2="C") |
| 224 | +dynamics2.curve_intersect(t_start=0.05, t_end=0.1, chem1="B", chem2="C") |
225 | 225 |
|
226 | 226 | # %% |
227 | 227 | df2 = dynamics2.get_history() |
|
251 | 251 | curve_labels=["B (adaptive variable steps)", "B (fixed small steps)"]) |
252 | 252 |
|
253 | 253 | # %% [markdown] |
254 | | -# #### They overlap fairly well! The 800 fixed-timestep points vs. the 48 adaptable variable-timestep ones |
| 254 | +# #### They overlap fairly well! The 800 fixed-timestep points vs. the 48 adaptable variable-timestep ones. |
| 255 | +# The adaptive algorithms avoided 752 extra steps of limited benefit... |
255 | 256 |
|
256 | 257 | # %% |
0 commit comments