def concentration_array_demo(det, dt=0.01, t_max=3, draw_iter_interval=50): """ Demonstration of setting up plume model and processing the outputted puff arrays with the ConcentrationArrayGenerator class, the resulting arrays being displayed with the matplotlib imshow function. """ # define simulation region wind_region = models.Rectangle(0., -2., 10., 2.) sim_region = models.Rectangle(0., -1., 2., 1.) # set up wind model wind_model = models.WindModel( wind_region, 21., 11., noise_gain=0, u_av=1, ) # set up plume model plume_model = models.PlumeModel(sim_region, (0.1, 0., 0.), wind_model, centre_rel_diff_scale=1.5, puff_release_rate=500, puff_init_rad=0.001, puff_spread_rate=0.0003) # set up concentration array generator array_gen = processors.ConcentrationArrayGenerator(sim_region, 0.01, 500, 500, 1.) # set up figure fig = _set_up_figure('Concentration field array demo') # display initial concentration field as image conc_array = array_gen.generate_single_array(plume_model.puff_array) im_extents = (sim_region.x_min, sim_region.x_max, sim_region.y_min, sim_region.y_max) conc_im = plt.imshow(conc_array.T, extent=im_extents, vmin=0, vmax=det, cmap=cm.binary_r) conc_im.axes.set_xlabel('x') conc_im.axes.set_ylabel('y') # define update and draw functions def update_func(dt, t): wind_model.update(dt) plume_model.update(dt) draw_func = lambda: conc_im.set_data( array_gen.generate_single_array(plume_model.puff_array).T) # start simulation loop _simulation_loop(dt, t_max, draw_iter_interval, update_func, draw_func, det) return fig
def plume_model_demo(dt=0.01, t_max=100, draw_iter_interval=200): """ Demonstration of setting up plume model and displaying with matplotlib plot and quiver functions. """ # define simulation region sim_region = models.Rectangle(0., -2., 8., 2.) # set up wind model wind_model = models.WindModel(sim_region, 21., 11., u_av=1., Kx=2., Ky=2.) # set up plume model plume_model = models.PlumeModel(sim_region, (0.5, 0., 0.), wind_model, puff_release_rate=10, centre_rel_diff_scale=1.5) # set up figure window fig, time_text = _set_up_figure('Plume model demo') # create quiver plot of initial velocity field # quiver expects first array dimension (rows) to correspond to y-axis # therefore need to transpose vf_plot = plt.quiver(wind_model.x_points, wind_model.y_points, wind_model.velocity_field[:, :, 0].T, wind_model.velocity_field[:, :, 1].T, width=0.001) # expand axis limits to make vectors at boundary of field visible vf_plot.axes.axis(vf_plot.axes.axis() + np.array([-0.5, 0.5, -0.5, 0.5])) # draw initial puff positions with scatter plot pp_plot = plt.scatter(plume_model.puff_array[:, 0], plume_model.puff_array[:, 1], 100 * plume_model.puff_array[:, 3]**0.5, c='r', edgecolors='none') # define update and draw functions def update_func(dt, t): wind_model.update(dt) plume_model.update(dt) def draw_func(): # update velocity field quiver plot data vf_plot.set_UVC(wind_model.velocity_field[:, :, 0].T, wind_model.velocity_field[:, :, 1].T) # update puff position scatter plot positions and sizes pp_plot.set_offsets(plume_model.puff_array[:, :2]) pp_plot._sizes = 100 * plume_model.puff_array[:, 3]**0.5 # begin simulation loop _simulation_loop(dt, t_max, time_text, draw_iter_interval, update_func, draw_func) return fig
def conc_point_val_demo(dt=0.01, t_max=5, draw_iter_interval=20, x=1., y=0.0): """ Demonstration of setting up plume model and processing the outputted puff arrays with the ConcentrationPointValueCalculator class, the resulting concentration time course at a point in the odour plume being displayed with the matplotlib plot function. """ # define simulation region wind_region = models.Rectangle(0., -2., 10., 2.) sim_region = models.Rectangle(0., -1., 2., 1.) # set up wind model wind_model = models.WindModel(wind_region, 21., 11., u_av=2.) # set up plume model plume_model = models.PlumeModel(sim_region, (0.1, 0., 0.), wind_model, centre_rel_diff_scale=1.5, puff_release_rate=25, puff_init_rad=0.01) # let simulation run for 10s to get plume established for t in np.arange(0, 10, dt): wind_model.update(dt) plume_model.update(dt) # set up concentration point value calculator val_calc = processors.ConcentrationValueCalculator(0.01**2) conc_vals = [] conc_vals.append(val_calc.calc_conc_point(plume_model.puff_array, x, y)) ts = [0.] # set up figure fig, time_text = _set_up_figure('Concentration point value trace demo') # display initial concentration field as image conc_line, = plt.plot(ts, conc_vals) conc_line.axes.set_xlim(0., t_max) conc_line.axes.set_ylim(0., .5) conc_line.axes.set_xlabel('t / s') conc_line.axes.set_ylabel('Normalised concentration') conc_line.axes.grid(True) # define update and draw functions def update_func(dt, t): wind_model.update(dt) plume_model.update(dt) ts.append(t) conc_vals.append(val_calc.calc_conc_point(plume_model.puff_array, x, y)) draw_func = lambda: conc_line.set_data(ts, conc_vals) # start simulation loop _simulation_loop(dt, t_max, time_text, draw_iter_interval, update_func, draw_func) return fig
# Define plume model parameters plume_model_params = { 'source_pos': (5., 0., 0.), 'centre_rel_diff_scale': 2., 'puff_release_rate': 10, 'puff_init_rad': 0.001**0.5, 'puff_spread_rate': 0.001, 'init_num_puffs': 10, 'max_num_puffs': 1000, 'model_z_disp': True, } # Create plume model object plume_model = models.PlumeModel(prng=rng, sim_region=sim_region, wind_model=wind_model, **plume_model_params) # Define concentration array (image) generator parameters array_gen_params = { 'array_z': 0., 'nx': 500, 'ny': 250, 'puff_mol_amount': 8.3e8 } # Create concentration array generator object array_gen = processors.ConcentrationArrayGenerator(array_xy_region=sim_region, **array_gen_params) # Set up figure
def wind_vel_and_conc_demo(dt=0.01, t_max=5, draw_iter_interval=50): """ Demonstration of setting up plume model and processing the outputted puff arrays with the ConcentrationArrayGenerator class, the resulting arrays being displayed with the matplotlib imshow function. """ # define simulation region wind_region = models.Rectangle(0., -1., 4., 1.) sim_region = models.Rectangle(0., -1., 4., 1.) # set up wind model wind_model = models.WindModel(wind_region, 11., 11., u_av=1., noise_gain=9., noise_bandwidth=0.3) # set up plume model plume_model = models.PlumeModel(sim_region, (0.1, 0., 0.), wind_model, centre_rel_diff_scale=1.5, puff_release_rate=200, puff_init_rad=0.001) for t in np.arange(0, 1, dt): wind_model.update(dt) plume_model.update(dt) # set up concentration array generator array_gen = processors.ConcentrationArrayGenerator(sim_region, 0.01, 1000, 500, 1.) # set up figure fig, time_text = _set_up_figure('Concentration array demo') ax_c = fig.add_subplot('111') # ax_w = fig.add_subplot('122') # display initial wind velocity field as quiver plot vf_plot = ax_c.quiver(wind_model.x_points, wind_model.y_points, wind_model.velocity_field[:, :, 0].T, wind_model.velocity_field[:, :, 1].T, width=0.002) ax_c.set_xlabel('x / m') ax_c.set_ylabel('y / m') ax_c.set_aspect(1) # display initial concentration field as image conc_array = (array_gen.generate_single_array( plume_model.puff_array).T[::-1]) im_extents = (sim_region.x_min, sim_region.x_max, sim_region.y_min, sim_region.y_max) conc_im = ax_c.imshow(conc_array, extent=im_extents, vmin=0, vmax=5e3, cmap=cm.Reds) ax_c.set_xlabel('x / m') ax_c.set_ylabel('y / m') # define update and draw functions def update_func(dt, t): wind_model.update(dt) plume_model.update(dt) def draw_func(): conc_im.set_data( array_gen.generate_single_array(plume_model.puff_array).T[::-1, :]) vf_plot.set_UVC(wind_model.velocity_field[:, :, 0].T, wind_model.velocity_field[:, :, 1].T) # start simulation loop _simulation_loop(dt, t_max, time_text, draw_iter_interval, update_func, draw_func) return fig