1515from pompy import models , processors
1616
1717
18- def set_up_figure (fig_size = (8 , 4 )):
18+ DEFAULT_SEED = 20181108
19+
20+
21+ def set_up_figure (fig_size = (10 , 5 )):
1922 """Set up Matplotlib figure with simulation time title text.
2023
2124 Parameters
@@ -44,7 +47,7 @@ def wrapped_update(i):
4447 return inner_decorator
4548
4649
47- def wind_model_demo (dt = 0.01 , t_max = 100 , steps_per_frame = 20 ):
50+ def wind_model_demo (dt = 0.01 , t_max = 100 , steps_per_frame = 20 , seed = DEFAULT_SEED ):
4851 """Set up wind model and animate velocity field with quiver plot.
4952
5053 Parameters
@@ -55,6 +58,8 @@ def wind_model_demo(dt=0.01, t_max=100, steps_per_frame=20):
5558 End time to simulate to.
5659 steps_per_frame: integer
5760 Number of simulation time steps to perform between animation frames.
61+ seed : integer
62+ Seed for random number generator.
5863
5964 Returns
6065 -------
@@ -65,10 +70,14 @@ def wind_model_demo(dt=0.01, t_max=100, steps_per_frame=20):
6570 anim : FuncAnimation
6671 Matplotlib animation object.
6772 """
73+ rng = np .random .RandomState (seed )
6874 # define simulation region
69- wind_region = models .Rectangle (x_min = 0. , x_max = 100 , y_min = - 25. , y_max = 25. )
75+ wind_region = models .Rectangle (x_min = 0. , x_max = 100. , y_min = - 25. , y_max = 25. )
7076 # set up wind model
71- wind_model = models .WindModel (wind_region , 21 , 11 , u_av = 1. , k_x = 2. , k_y = 2. )
77+ wind_model = models .WindModel (wind_region , 21 , 11 , rng = rng )
78+ # let simulation run for 10s to equilibrate wind model
79+ for t in np .arange (0 , 10 , dt ):
80+ wind_model .update (dt )
7281 # generate figure and attach close event
7382 fig , ax , title = set_up_figure ()
7483 # create quiver plot of initial velocity field
@@ -95,7 +104,8 @@ def update(i):
95104 return fig , ax , anim
96105
97106
98- def plume_model_demo (dt = 0.01 , t_max = 100 , steps_per_frame = 200 ):
107+ def plume_model_demo (dt = 0.01 , t_max = 100 , steps_per_frame = 200 ,
108+ seed = DEFAULT_SEED ):
99109 """Set up plume model and animate puffs overlayed over velocity field.
100110
101111 Puff positions displayed using Matplotlib `scatter` plot function and
@@ -110,6 +120,8 @@ def plume_model_demo(dt=0.01, t_max=100, steps_per_frame=200):
110120 End time to simulate to.
111121 steps_per_frame: integer
112122 Number of simulation time steps to perform between animation frames.
123+ seed : integer
124+ Seed for random number generator.
113125
114126 Returns
115127 -------
@@ -120,15 +132,17 @@ def plume_model_demo(dt=0.01, t_max=100, steps_per_frame=200):
120132 anim : FuncAnimation
121133 Matplotlib animation object.
122134 """
135+ rng = np .random .RandomState (seed )
123136 # define simulation region
124- wind_region = models .Rectangle (x_min = 0. , x_max = 100 , y_min = - 25. , y_max = 25. )
137+ sim_region = models .Rectangle (x_min = 0. , x_max = 100 , y_min = - 25. , y_max = 25. )
125138 # set up wind model
126- wind_model = models .WindModel (wind_region , 21 , 11 , u_av = 1. , k_x = 2. , k_y = 2. )
139+ wind_model = models .WindModel (sim_region , 21 , 11 , rng = rng )
140+ # let simulation run for 10s to equilibrate wind model
141+ for t in np .arange (0 , 10 , dt ):
142+ wind_model .update (dt )
127143 # set up plume model
128- sim_region = models .Rectangle (x_min = 0. , x_max = 50 , y_min = - 12.5 , y_max = 12.5 )
129144 plume_model = models .PlumeModel (
130- sim_region , (5. , 0. , 0. ), wind_model , puff_release_rate = 10 ,
131- centre_rel_diff_scale = 2 )
145+ sim_region , (5. , 0. , 0. ), wind_model , rng = rng )
132146 # set up figure window
133147 fig , ax , title = set_up_figure ()
134148 # create quiver plot of initial velocity field
@@ -168,12 +182,14 @@ def update(i):
168182 return fig , ax , anim
169183
170184
171- def concentration_array_demo (dt = 0.01 , t_max = 100 , steps_per_frame = 50 ):
172- """Set up plume model and animate concentration fields.
185+ def conc_point_val_demo (dt = 0.01 , t_max = 5 , steps_per_frame = 1 , x = 10. , y = 0.0 ,
186+ seed = DEFAULT_SEED ):
187+ """Set up plume model and animate concentration at a point as time series.
173188
174189 Demonstration of setting up plume model and processing the outputted
175- puff arrays with the `ConcentrationArrayGenerator` class, the resulting
176- arrays being displayed with the Matplotlib `imshow` function.
190+ puff arrays with the ConcentrationPointValueCalculator class, the
191+ resulting concentration time course at a point in the odour plume being
192+ displayed with the Matplotlib `plot` function.
177193
178194 Parameters
179195 ----------
@@ -183,6 +199,12 @@ def concentration_array_demo(dt=0.01, t_max=100, steps_per_frame=50):
183199 End time to simulate to.
184200 steps_per_frame: integer
185201 Number of simulation time steps to perform between animation frames.
202+ x : float
203+ x-coordinate of point to measure concentration at.
204+ y : float
205+ y-coordinate of point to measure concentration at.
206+ seed : integer
207+ Seed for random number generator.
186208
187209 Returns
188210 -------
@@ -193,49 +215,56 @@ def concentration_array_demo(dt=0.01, t_max=100, steps_per_frame=50):
193215 anim : FuncAnimation
194216 Matplotlib animation object.
195217 """
218+ rng = np .random .RandomState (seed )
196219 # define simulation region
197- wind_region = models .Rectangle (x_min = 0. , x_max = 10. , y_min = - 2. , y_max = 2. )
198- sim_region = models .Rectangle (x_min = 0. , x_max = 4 , y_min = - 1. , y_max = 1. )
220+ sim_region = models .Rectangle (x_min = 0. , x_max = 100 , y_min = - 25. , y_max = 25. )
199221 # set up wind model
200- wind_model = models .WindModel (wind_region , 21 , 11 , u_av = 1. , )
222+ wind_model = models .WindModel (sim_region , 21 , 11 , rng = rng )
201223 # set up plume model
202224 plume_model = models .PlumeModel (
203- sim_region , (0.1 , 0. , 0. ), wind_model , centre_rel_diff_scale = 1.5 ,
204- puff_release_rate = 500 , puff_init_rad = 0.001 )
205- # set up concentration array generator
206- array_gen = processors .ConcentrationArrayGenerator (
207- sim_region , 0.01 , 500 , 500 , 1. )
225+ sim_region , (5. , 0. , 0. ), wind_model , rng = rng )
226+ # let simulation run for 10s to initialise models
227+ for t in np .arange (0 , 10 , dt ):
228+ wind_model .update (dt )
229+ plume_model .update (dt )
230+ # set up concentration point value calculator
231+ val_calc = processors .ConcentrationValueCalculator (1. )
232+ conc_vals = []
233+ conc_vals .append (val_calc .calc_conc_point (plume_model .puff_array , x , y ))
234+ ts = [0. ]
208235 # set up figure
209236 fig , ax , title = set_up_figure ()
210237 # display initial concentration field as image
211- conc_array = array_gen . generate_single_array ( plume_model . puff_array )
212- conc_im = plt . imshow ( conc_array . T , extent = sim_region , vmin = 0 , vmax = 3e4 ,
213- cmap = 'Reds' )
214- ax .set_xlabel ('x-coordinate / m ' )
215- ax .set_ylabel ('y-coordinate / m ' )
216- ax .set_aspect ( 1 )
238+ conc_line , = plt . plot ( ts , conc_vals )
239+ ax . set_xlim ( 0. , t_max )
240+ ax . set_ylim ( 0. , 150. )
241+ ax .set_xlabel ('Time / s ' )
242+ ax .set_ylabel ('Normalised concentration ' )
243+ ax .grid ( True )
217244 fig .tight_layout ()
218245
219246 # define update function
220247 @update_decorator (dt , title , steps_per_frame , [wind_model , plume_model ])
221248 def update (i ):
222- conc_im .set_data (
223- array_gen .generate_single_array (plume_model .puff_array ).T )
224- return [conc_im ]
249+ ts .append (dt * i * steps_per_frame )
250+ conc_vals .append (
251+ val_calc .calc_conc_point (plume_model .puff_array , x , y ))
252+ conc_line .set_data (ts , conc_vals )
253+ return [conc_line ]
225254
226255 # create animation object
227256 n_frame = int (t_max / (dt * steps_per_frame ) + 0.5 )
228257 anim = FuncAnimation (fig , update , frames = n_frame , blit = True )
229258 return fig , ax , anim
230259
231260
232- def conc_point_val_demo (dt = 0.01 , t_max = 5 , steps_per_frame = 1 , x = 1. , y = 0.0 ):
233- """Set up plume model and animate concentration at a point as time series.
261+ def concentration_array_demo (dt = 0.01 , t_max = 100 , steps_per_frame = 50 ,
262+ seed = DEFAULT_SEED ):
263+ """Set up plume model and animate concentration fields.
234264
235265 Demonstration of setting up plume model and processing the outputted
236- puff arrays with the ConcentrationPointValueCalculator class, the
237- resulting concentration time course at a point in the odour plume being
238- displayed with the Matplotlib `plot` function.
266+ puff arrays with the `ConcentrationArrayGenerator` class, the resulting
267+ arrays being displayed with the Matplotlib `imshow` function.
239268
240269 Parameters
241270 ----------
@@ -245,10 +274,8 @@ def conc_point_val_demo(dt=0.01, t_max=5, steps_per_frame=1, x=1., y=0.0):
245274 End time to simulate to.
246275 steps_per_frame: integer
247276 Number of simulation time steps to perform between animation frames.
248- x : float
249- x-coordinate of point to measure concentration at.
250- y : float
251- y-coordinate of point to measure concentration at.
277+ seed : integer
278+ Seed for random number generator.
252279
253280 Returns
254281 -------
@@ -259,43 +286,38 @@ def conc_point_val_demo(dt=0.01, t_max=5, steps_per_frame=1, x=1., y=0.0):
259286 anim : FuncAnimation
260287 Matplotlib animation object.
261288 """
289+ rng = np .random .RandomState (seed )
262290 # define simulation region
263- wind_region = models .Rectangle (x_min = 0. , x_max = 10. , y_min = - 2. , y_max = 2. )
264- sim_region = models .Rectangle (x_min = 0. , x_max = 2 , y_min = - 1. , y_max = 1. )
291+ sim_region = models .Rectangle (x_min = 0. , x_max = 100 , y_min = - 25. , y_max = 25. )
265292 # set up wind model
266- wind_model = models .WindModel (wind_region , 21 , 11 , u_av = 2. )
293+ wind_model = models .WindModel (sim_region , 21 , 11 , rng = rng )
267294 # set up plume model
268295 plume_model = models .PlumeModel (
269- sim_region , (0.1 , 0. , 0. ), wind_model , centre_rel_diff_scale = 1.5 ,
270- puff_release_rate = 25 , puff_init_rad = 0.01 )
271- # let simulation run for 10s to get plume established
296+ sim_region , (5. , 0. , 0. ), wind_model , rng = rng )
297+ # let simulation run for 10s to initialise models
272298 for t in np .arange (0 , 10 , dt ):
273299 wind_model .update (dt )
274300 plume_model .update (dt )
275- # set up concentration point value calculator
276- val_calc = processors .ConcentrationValueCalculator (0.01 ** 2 )
277- conc_vals = []
278- conc_vals .append (val_calc .calc_conc_point (plume_model .puff_array , x , y ))
279- ts = [0. ]
301+ # set up concentration array generator
302+ array_gen = processors .ConcentrationArrayGenerator (
303+ sim_region , 0.01 , 500 , 250 , 1. )
280304 # set up figure
281305 fig , ax , title = set_up_figure ()
282306 # display initial concentration field as image
283- conc_line , = plt . plot ( ts , conc_vals )
284- ax . set_xlim ( 0. , t_max )
285- ax . set_ylim ( 0. , .5 )
286- ax .set_xlabel ('Time / s ' )
287- ax .set_ylabel ('Normalised concentration ' )
288- ax .grid ( True )
307+ conc_array = array_gen . generate_single_array ( plume_model . puff_array )
308+ conc_im = plt . imshow ( conc_array . T , extent = sim_region , cmap = 'Reds' ,
309+ vmin = 0. , vmax = 1. )
310+ ax .set_xlabel ('x-coordinate / m ' )
311+ ax .set_ylabel ('y-coordinate / m ' )
312+ ax .set_aspect ( 1 )
289313 fig .tight_layout ()
290314
291315 # define update function
292316 @update_decorator (dt , title , steps_per_frame , [wind_model , plume_model ])
293317 def update (i ):
294- ts .append (dt * i * steps_per_frame )
295- conc_vals .append (
296- val_calc .calc_conc_point (plume_model .puff_array , x , y ))
297- conc_line .set_data (ts , conc_vals )
298- return [conc_line ]
318+ conc_im .set_data (
319+ array_gen .generate_single_array (plume_model .puff_array ).T )
320+ return [conc_im ]
299321
300322 # create animation object
301323 n_frame = int (t_max / (dt * steps_per_frame ) + 0.5 )
0 commit comments