def initialize_plotting(self): """ Creates a CA plotter object, sets its colormap, and plots the initial model state. """ # Set up some plotting information grain = "#5F594D" bleached_grain = "#CC0000" fluid = "#D0E4F2" clist = [fluid, bleached_grain, grain] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display self.ca_plotter = CAPlotter(self, cmap=my_cmap) # Plot the initial grid self.ca_plotter.update_plot() # Make a colormap for use in showing the bleaching of each grain clist = [ (0.0, (1.0, 1.0, 1.0)), (0.49, (0.8, 0.8, 0.8)), (1.0, (0.0, 0.0, 0.0)), ] self.cmap_for_osl = matplotlib.colors.LinearSegmentedColormap.from_list( "osl_cmap", clist)
def initialize_plotting(self): """ Creates a CA plotter object, sets its colormap, and plots the initial model state. """ # Set up some plotting information grain = "#5F594D" bleached_grain = "#CC0000" fluid = "#D0E4F2" clist = [fluid, bleached_grain, grain] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display self.ca_plotter = CAPlotter(self, cmap=my_cmap) # Plot the initial grid self.ca_plotter.update_plot() # Make a colormap for use in showing the bleaching of each grain clist = [ (0.0, (1.0, 1.0, 1.0)), (0.49, (0.8, 0.8, 0.8)), (1.0, (0.0, 0.0, 0.0)), ] self.cmap_for_osl = matplotlib.colors.LinearSegmentedColormap.from_list( "osl_cmap", clist )
def initialize_plotting(self): """ Creates a CA plotter object, sets its colormap, and plots the initial model state. """ # Set up some plotting information grain = '#5F594D' bleached_grain = '#CC0000' fluid = '#D0E4F2' clist = [fluid,bleached_grain,grain] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display self.ca_plotter = CAPlotter(self, cmap=my_cmap) # Plot the initial grid self.ca_plotter.update_plot()
def main(): # INITIALIZE # User-defined parameters nr = 41 nc = 61 g = 0.8 f = 1.0 plot_interval = 1.0 run_duration = 200.0 report_interval = 5.0 # report interval, in real-time seconds p_init = 0.4 # probability that a cell is occupied at start plot_every_transition = False # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create a grid hmg = HexModelGrid(nr, nc, 1.0, orientation='vertical', reorient_links=True) # Close the grid boundaries #hmg.set_closed_nodes(hmg.open_boundary_nodes) # Set up the states and pair transitions. # Transition data here represent particles moving on a lattice: one state # per direction (for 6 directions), plus an empty state, a stationary # state, and a wall state. ns_dict = { 0: 'empty', 1: 'moving up', 2: 'moving right and up', 3: 'moving right and down', 4: 'moving down', 5: 'moving left and down', 6: 'moving left and up', 7: 'rest', 8: 'wall' } xn_list = setup_transition_list(g, f) # Create data and initialize values. node_state_grid = hmg.add_zeros('node', 'node_state_grid') # Make the grid boundary all wall particles node_state_grid[hmg.boundary_nodes] = 8 # Seed the grid interior with randomly oriented particles for i in hmg.core_nodes: if random.random() < p_init: node_state_grid[i] = random.randint(1, 7) # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time', current_time, '(', 100 * current_time / run_duration, '%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time + plot_interval, ca.node_state, plot_each_transition=plot_every_transition, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 41 nc = 61 plot_interval = 1.0 run_duration = 100.0 report_interval = 5.0 # report interval, in real-time seconds p_init = 0.1 # probability that a cell is occupied at start plot_every_transition = False # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create a grid hmg = HexModelGrid(nr, nc, 1.0, orientation='vertical', reorient_links=True) # Close the grid boundaries #hmg.set_closed_nodes(hmg.open_boundary_nodes) # Set up the states and pair transitions. # Transition data here represent particles moving on a lattice: one state # per direction (for 6 directions), plus an empty state, a stationary # state, and a wall state. ns_dict = { 0: 'empty', 1: 'moving up', 2: 'moving right and up', 3: 'moving right and down', 4: 'moving down', 5: 'moving left and down', 6: 'moving left and up', 7: 'rest', 8: 'wall' } xn_list = setup_transition_list() # Create data and initialize values. node_state_grid = hmg.add_zeros('node', 'node_state_grid', dtype=int) # Make the grid boundary all wall particles node_state_grid[hmg.boundary_nodes] = 8 # Seed the grid interior with randomly oriented particles for i in hmg.core_nodes: if random.random() < p_init: node_state_grid[i] = random.randint(1, 7) # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # Create an array to store the numbers of states at each plot interval nstates = zeros((9, int(run_duration / plot_interval))) k = 0 # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time', current_time, '(', 100 * current_time / run_duration, '%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time + plot_interval, ca.node_state, plot_each_transition=plot_every_transition, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # Record numbers in each state nstates[:, k] = bincount(node_state_grid) k += 1 # FINALIZE # Plot ca_plotter.finalize() # Display the numbers of each state fig, ax = subplots() for i in range(1, 8): plot(arange(plot_interval, run_duration + plot_interval, plot_interval), nstates[i, :], label=ns_dict[i]) ax.legend() xlabel('Time') ylabel('Number of particles in state') title('Particle distribution by state') axis([0, run_duration, 0, 2 * nstates[7, 0]]) show()
def main(): # INITIALIZE # User-defined parameters nr = 200 # number of rows in grid nc = 200 # number of columns in grid plot_interval = 0.05 # time interval for plotting (unscaled) run_duration = 5.0 # duration of run (unscaled) report_interval = 10.0 # report interval, in real-time seconds frac_spacing = 10 # average fracture spacing, nodes outfilename = 'wx' # name for netCDF files # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Counter for output files time_slice = 0 # Create grid mg = RasterModelGrid(nr, nc, 1.0) # Make the boundaries be walls mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. ns_dict = { 0 : 'rock', 1 : 'saprolite' } xn_list = setup_transition_list() # Create the node-state array and attach it to the grid. # (Note use of numpy's uint8 data type. This saves memory AND allows us # to write output to a netCDF3 file; netCDF3 does not handle the default # 64-bit integer type) node_state_grid = mg.add_zeros('node', 'node_state_map', dtype=np.uint8) node_state_grid[:] = make_frac_grid(frac_spacing, model_grid=mg) # Create the CA model ca = RasterCTS(mg, ns_dict, xn_list, node_state_grid) # Set up the color map rock_color = (0.8, 0.8, 0.8) sap_color = (0.4, 0.2, 0) clist = [rock_color, sap_color] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca, cmap=my_cmap) # Plot the initial grid ca_plotter.update_plot() # Output the initial grid to file write_netcdf((outfilename+str(time_slice)+'.nc'), mg, #format='NETCDF3_64BIT', names='node_state_map') # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time', current_time, '(', 100 * current_time/run_duration, '%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=False) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # Output the current grid to a netCDF file time_slice += 1 write_netcdf((outfilename+str(time_slice)+'.nc'), mg, #format='NETCDF3_64BIT', names='node_state_map') # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 41 nc = 61 g = 0.05 plot_interval = 1.0 run_duration = 100.0 report_interval = 5.0 # report interval, in real-time seconds p_init = 0.1 # probability that a cell is occupied at start plot_every_transition = False # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create a grid hmg = HexModelGrid(nr, nc, 1.0, orientation='vertical', reorient_links=True) # Close the grid boundaries #hmg.set_closed_nodes(hmg.open_boundary_nodes) # Set up the states and pair transitions. # Transition data here represent particles moving on a lattice: one state # per direction (for 6 directions), plus an empty state, a stationary # state, and a wall state. ns_dict = { 0 : 'empty', 1 : 'moving up', 2 : 'moving right and up', 3 : 'moving right and down', 4 : 'moving down', 5 : 'moving left and down', 6 : 'moving left and up', 7 : 'rest', 8 : 'wall'} xn_list = setup_transition_list(g) # Create data and initialize values. node_state_grid = hmg.add_zeros('node', 'node_state_grid') # Make the grid boundary all wall particles node_state_grid[hmg.boundary_nodes] = 8 # Seed the grid interior with randomly oriented particles for i in hmg.core_nodes: if random.random()<p_init: node_state_grid[i] = random.randint(1, 7) # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time',current_time,'(',100*current_time/run_duration,'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=plot_every_transition, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 80 nc = 80 plot_interval = 2 run_duration = 200 report_interval = 5.0 # report interval, in real-time seconds # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create grid mg = RasterModelGrid(nr, nc, 1.0) # Make the boundaries be walls mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. ns_dict = { 0 : 'fluid', 1 : 'particle' } xn_list = setup_transition_list() # Create the node-state array and attach it to the grid node_state_grid = mg.add_zeros('node', 'node_state_map', dtype=int) # Initialize the node-state array middle_rows = where(bitwise_and(mg.node_y>0.45*nr, mg.node_y<0.55*nr))[0] node_state_grid[middle_rows] = 1 # Create the CA model ca = OrientedRasterCTS(mg, ns_dict, xn_list, node_state_grid) # Debug output if needed if _DEBUG: n = ca.grid.number_of_nodes for r in range(ca.grid.number_of_node_rows): for c in range(ca.grid.number_of_node_columns): n -= 1 print('{0:.0f}'.format(ca.node_state[n]), end=' ') print() # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time',current_time,'(',100*current_time/run_duration,'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=False) #, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # for debugging if _DEBUG: n = ca.grid.number_of_nodes for r in range(ca.grid.number_of_node_rows): for c in range(ca.grid.number_of_node_columns): n -= 1 print('{0:.0f}'.format(ca.node_state[n]), end=' ') print() # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 80 nc = 41 plot_interval = 0.25 run_duration = 5.0 report_interval = 5.0 # report interval, in real-time seconds infection_rate = 3.0 outfilename = 'sirmodel'+str(int(infection_rate))+'ir' # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval time_slice = 0 # Create a grid hmg = HexModelGrid(nr, nc, 1.0) # Set up the states and pair transitions. # Transition data here represent the disease status of a population. ns_dict = { 0 : 'susceptible', 1 : 'infectious', 2: 'recovered' } xn_list = setup_transition_list(infection_rate) # Create data and initialize values node_state_grid = hmg.add_zeros('node', 'node_state_grid') wid = nc-1.0 ht = (nr-1.0)*0.866 is_middle_rows = logical_and(hmg.node_y>=0.4*ht, hmg.node_y<=0.5*ht) is_middle_cols = logical_and(hmg.node_x>=0.4*wid, hmg.node_x<=0.6*wid) middle_area = where(logical_and(is_middle_rows, is_middle_cols))[0] node_state_grid[middle_area] = 1 node_state_grid[0] = 2 # to force full color range, set lower left to 'recovered' # Create the CA model ca = HexCTS(hmg, ns_dict, xn_list, node_state_grid) # Set up the color map import matplotlib susceptible_color = (0.5, 0.5, 0.5) # gray infectious_color = (0.05, 0.0, 0.0) # dark red recovered_color = (0.95, 0.95, 1.0) # white w/ faint blue clist = [susceptible_color, infectious_color, recovered_color] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca, cmap=my_cmap) # Plot the initial grid ca_plotter.update_plot() pylab.axis('off') savename = outfilename+'0' pylab.savefig(savename+'.pdf', format='pdf') # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time',current_time,'(',100*current_time/run_duration,'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=False) #True, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() pylab.axis('off') time_slice += 1 savename = outfilename+str(time_slice) pylab.savefig(savename+'.pdf', format='pdf') # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 100 # number of rows in grid nc = 64 # number of columns in grid plot_interval = 0.5 # time interval for plotting, sec run_duration = 20.0 # duration of run, sec report_interval = 10.0 # report interval, in real-time seconds # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create grid mg = RasterModelGrid(nr, nc, 1.0) # Make the boundaries be walls mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. ns_dict = {0: "fluid", 1: "particle"} xn_list = setup_transition_list() # Create the node-state array and attach it to the grid node_state_grid = mg.add_zeros("node", "node_state_map", dtype=int) # Initialize the node-state array: here, the initial condition is a pile of # resting grains at the bottom of a container. bottom_rows = where(mg.node_y < 0.1 * nr)[0] node_state_grid[bottom_rows] = 1 # For visual display purposes, set all boundary nodes to fluid node_state_grid[mg.closed_boundary_nodes] = 0 # Create the CA model ca = OrientedRasterCTS(mg, ns_dict, xn_list, node_state_grid) grain = "#5F594D" fluid = "#D0E4F2" clist = [fluid, grain] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca, cmap=my_cmap) # Plot the initial grid ca_plotter.update_plot() # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print( "Current sim time", current_time, "(", 100 * current_time / run_duration, "%)", ) next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time + plot_interval, ca.node_state, plot_each_transition=False) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # FINALIZE # Plot ca_plotter.finalize() # Calculate concentration profile c = zeros(nr) for r in range(nr): c[r] = mean(node_state_grid[r * nc : (r + 1) * nc]) figure(2) plot(c, range(nr), "o") show()
def main(): # INITIALIZE # User-defined parameters nr = 41 nc = 61 g = 0.8 f = 1.0 silo_y0 = 30.0 silo_opening_half_width = 6 plot_interval = 1.0 run_duration = 80.0 report_interval = 5.0 # report interval, in real-time seconds p_init = 0.4 # probability that a cell is occupied at start plot_every_transition = False # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create a grid hmg = HexModelGrid(nr, nc, 1.0, orientation='vertical', reorient_links=True) # Set up the states and pair transitions. # Transition data here represent particles moving on a lattice: one state # per direction (for 6 directions), plus an empty state, a stationary # state, and a wall state. ns_dict = { 0 : 'empty', 1 : 'moving up', 2 : 'moving right and up', 3 : 'moving right and down', 4 : 'moving down', 5 : 'moving left and down', 6 : 'moving left and up', 7 : 'rest', 8 : 'wall'} xn_list = setup_transition_list(g, f) # Create data and initialize values. node_state_grid = hmg.add_zeros('node', 'node_state_grid') # Make the grid boundary all wall particles node_state_grid[hmg.boundary_nodes] = 8 # Place wall particles to form the base of the silo, initially closed tan30deg = numpy.tan(numpy.pi/6.) rampy1 = silo_y0-hmg.node_x*tan30deg rampy2 = silo_y0-((nc*0.866-1.)-hmg.node_x)*tan30deg rampy = numpy.maximum(rampy1, rampy2) (ramp_nodes, ) = numpy.where(numpy.logical_and(hmg.node_y>rampy-0.5, \ hmg.node_y<rampy+0.5)) node_state_grid[ramp_nodes] = 8 # Seed the grid interior with randomly oriented particles for i in hmg.core_nodes: if hmg.node_y[i]>rampy[i] and random.random()<p_init: node_state_grid[i] = random.randint(1, 7) # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # RUN # Run with closed silo current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time '+str(current_time)+' ('+str(100*current_time/run_duration)+'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=plot_every_transition, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # Open the silo xmid = nc*0.866*0.5 for i in range(hmg.number_of_nodes): if node_state_grid[i]==8 and hmg.node_x[i]>(xmid-silo_opening_half_width) \ and hmg.node_x[i]<(xmid+silo_opening_half_width) \ and hmg.node_y[i]>0: node_state_grid[i]=0 # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # Re-run with open silo current_time = 0.0 while current_time < 5*run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time '+str(current_time)+' ('+str(100*current_time/run_duration)+'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=plot_every_transition, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 80 nc = 41 plot_interval = 0.25 run_duration = 5.0 report_interval = 5.0 # report interval, in real-time seconds infection_rate = 8.0 outfilename = 'sirmodel'+str(int(infection_rate))+'ir' # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval time_slice = 0 # Create a grid hmg = HexModelGrid(nr, nc, 1.0) # Set up the states and pair transitions. # Transition data here represent the disease status of a population. ns_dict = { 0 : 'susceptible', 1 : 'infectious', 2: 'recovered' } xn_list = setup_transition_list(infection_rate) # Create data and initialize values node_state_grid = hmg.add_zeros('node', 'node_state_grid') wid = nc-1.0 ht = (nr-1.0)*0.866 is_middle_rows = logical_and(hmg.node_y>=0.4*ht, hmg.node_y<=0.5*ht) is_middle_cols = logical_and(hmg.node_x>=0.4*wid, hmg.node_x<=0.6*wid) middle_area = where(logical_and(is_middle_rows, is_middle_cols))[0] node_state_grid[middle_area] = 1 node_state_grid[0] = 2 # to force full color range, set lower left to 'recovered' # Create the CA model ca = HexCTS(hmg, ns_dict, xn_list, node_state_grid) # Set up the color map import matplotlib susceptible_color = (0.5, 0.5, 0.5) # gray infectious_color = (0.5, 0.0, 0.0) # dark red recovered_color = (0.0, 0.0, 1.0) # blue clist = [susceptible_color, infectious_color, recovered_color] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca, cmap=my_cmap) # Plot the initial grid ca_plotter.update_plot() pylab.axis('off') savename = outfilename+'0' pylab.savefig(savename+'.pdf', format='pdf') # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time',current_time,'(',100*current_time/run_duration,'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=False) #True, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() pylab.axis('off') time_slice += 1 savename = outfilename+str(time_slice) pylab.savefig(savename+'.pdf', format='pdf') # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 52 nc = 120 plot_interval = 1.0 run_duration = 100.0 report_interval = 5.0 # report interval, in real-time seconds p_init = 0.1 # probability that a cell is occupied at start plot_every_transition = False # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create a grid hmg = HexModelGrid(nr, nc, 1.0, orientation='vertical', reorient_links=True) # Close the grid boundaries #hmg.set_closed_nodes(hmg.open_boundary_nodes) # Set up the states and pair transitions. # Transition data here represent particles moving on a lattice: one state # per direction (for 6 directions), plus an empty state, a stationary # state, and a wall state. ns_dict = { 0 : 'empty', 1 : 'moving up', 2 : 'moving right and up', 3 : 'moving right and down', 4 : 'moving down', 5 : 'moving left and down', 6 : 'moving left and up', 7 : 'rest', 8 : 'wall'} xn_list = setup_transition_list() # Create data and initialize values. node_state_grid = hmg.add_zeros('node', 'node_state_grid', dtype=int) # Make the grid boundary all wall particles node_state_grid[hmg.boundary_nodes] = 8 # Seed the grid interior with randomly oriented particles for i in hmg.core_nodes: if random.random()<p_init: node_state_grid[i] = random.randint(1, 7) # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) # Set up a color map for plotting import matplotlib clist = [ (1.0, 1.0, 1.0), # empty = white (1.0, 0.0, 0.0), # up = red (1.0, 1.0, 0.0), # right-up = yellow (0.0, 1.0, 0.0), # down-up = green (0.0, 1.0, 1.0), # down = cyan (0.0, 0.0, 1.0), # left-down = blue (1.0, 0.0, 1.0), # left-up = magenta (0.5, 0.5, 0.5), # resting = gray (0.0, 0.0, 0.0) ] # wall = black my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca, cmap=my_cmap) # Plot the initial grid ca_plotter.update_plot() # Create an array to store the numbers of states at each plot interval nstates = zeros((9, int(run_duration/plot_interval))) k = 0 # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time',current_time,'(',100*current_time/run_duration,'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=plot_every_transition, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() axis('off') # Record numbers in each state nstates[:,k] = bincount(node_state_grid) k += 1 # FINALIZE # Plot ca_plotter.finalize() # Display the numbers of each state fig, ax = subplots() for i in range(1, 8): plot(arange(plot_interval, run_duration+plot_interval, plot_interval), nstates[i,:], label=ns_dict[i], color=clist[i]) ax.legend() xlabel('Time') ylabel('Number of particles in state') title('Particle distribution by state') axis([0, run_duration, 0, 2*nstates[7,0]]) show()
def main(): # INITIALIZE # User-defined parameters nr = 41 nc = 61 g = 1.0 f = 0.7 silo_y0 = 30.0 silo_opening_half_width = 6 plot_interval = 10.0 run_duration = 240.0 report_interval = 300.0 # report interval, in real-time seconds p_init = 0.4 # probability that a cell is occupied at start plot_every_transition = False # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create a grid hmg = HexModelGrid(nr, nc, 1.0, orientation='vertical', shape='rect', reorient_links=True) # Set up the states and pair transitions. # Transition data here represent particles moving on a lattice: one state # per direction (for 6 directions), plus an empty state, a stationary # state, and a wall state. ns_dict = { 0: 'empty', 1: 'moving up', 2: 'moving right and up', 3: 'moving right and down', 4: 'moving down', 5: 'moving left and down', 6: 'moving left and up', 7: 'rest', 8: 'wall' } xn_list = setup_transition_list(g, f) # Create data and initialize values. node_state_grid = hmg.add_zeros('node', 'node_state_grid') # Make the grid boundary all wall particles node_state_grid[hmg.boundary_nodes] = 8 # Place wall particles to form the base of the silo, initially closed tan30deg = numpy.tan(numpy.pi / 6.) rampy1 = silo_y0 - hmg.node_x * tan30deg rampy2 = silo_y0 - ((nc * 0.866 - 1.) - hmg.node_x) * tan30deg rampy = numpy.maximum(rampy1, rampy2) (ramp_nodes, ) = numpy.where(numpy.logical_and(hmg.node_y>rampy-0.5, \ hmg.node_y<rampy+0.5)) node_state_grid[ramp_nodes] = 8 # Seed the grid interior with randomly oriented particles for i in hmg.core_nodes: if hmg.node_y[i] > rampy[i] and random.random() < p_init: node_state_grid[i] = random.randint(1, 7) # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) import matplotlib rock = (0.0, 0.0, 0.0) #'#5F594D' sed = (0.6, 0.6, 0.6) #'#A4874B' #sky = '#CBD5E1' #sky = '#85A5CC' sky = (1.0, 1.0, 1.0) #'#D0E4F2' mob = (0.3, 0.3, 0.3) #'#D98859' #mob = '#DB764F' #mob = '#FFFF00' #sed = '#CAAE98' #clist = [(0.5, 0.9, 0.9),mob, mob, mob, mob, mob, mob,'#CD6839',(0.3,0.3,0.3)] clist = [sky, mob, mob, mob, mob, mob, mob, sed, rock] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca, cmap=my_cmap) k = 0 # Plot the initial grid ca_plotter.update_plot() # RUN # Run with closed silo current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print 'Current sim time', current_time, '(', 100 * current_time / run_duration, '%)' next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time + plot_interval, ca.node_state, plot_each_transition=plot_every_transition, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # Open the silo xmid = nc * 0.866 * 0.5 for i in range(hmg.number_of_nodes): if node_state_grid[i]==8 and hmg.node_x[i]>(xmid-silo_opening_half_width) \ and hmg.node_x[i]<(xmid+silo_opening_half_width) \ and hmg.node_y[i]>0 and hmg.node_y[i]<38.0: node_state_grid[i] = 0 # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # Re-run with open silo savefig('silo' + str(k) + '.png') k += 1 current_time = 0.0 while current_time < 5 * run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print 'Current sim time', current_time, '(', 100 * current_time / run_duration, '%)' next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time + plot_interval, ca.node_state, plot_each_transition=plot_every_transition, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() savefig('silo' + str(k) + '.png') k += 1 # FINALIZE # Plot ca_plotter.finalize()
class TurbulentSuspensionAndBleachingModel(OrientedRasterCTS): """ Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 4 ... model_grid_column__count: number of columns in grid ... 4 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 2.0 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.node_state array([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]) >>> tsbm.grid.at_node['osl'] array([ 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0.]) >>> tsbm.n_xn array([0, 1, 1, 0, 0, 1, 1, 0]) >>> tsbm.fluid_surface_height 3.5 """ def __init__(self, input_stream): """ Reads in parameters and initializes the model. Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 4 ... model_grid_column__count: number of columns in grid ... 4 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 2.0 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.node_state array([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]) >>> tsbm.grid.at_node['osl'] array([ 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0.]) >>> tsbm.n_xn array([0, 1, 1, 0, 0, 1, 1, 0]) >>> tsbm.fluid_surface_height 3.5 """ # Get a source for input parameters. params = ModelParameterDictionary(input_stream) # Read user-defined parameters nr = params.read_int('model_grid_row__count') # number of rows (CSDMS Standard Name [CSN]) nc = params.read_int('model_grid_column__count') # number of cols (CSN) self.plot_interval = params.read_float('plot_interval') # interval for plotting output, s self.run_duration = params.read_float('model__run_time') # duration of run, sec (CSN) self.report_interval = params.read_float('model__report_interval') # report interval, in real-time seconds self.bleach_T0 = params.read_float('surface_bleaching_time_scale') # time scale for bleaching at fluid surface, s self.zstar = params.read_float('light_attenuation_length') # length scale for light attenuation in fluid, CELLS # Derived parameters self.fluid_surface_height = nr-0.5 # Calculate when we next want to report progress. self.next_report = time.time() + self.report_interval # Create grid mg = RasterModelGrid(nr, nc, 1.0) # Make the boundaries be walls mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. ns_dict = { 0 : 'fluid', 1 : 'particle' } xn_list = self.setup_transition_list() # Create the node-state array and attach it to the grid node_state_grid = mg.add_zeros('node', 'node_state_map', dtype=int) # For visual display purposes, set all boundary nodes to fluid node_state_grid[mg.closed_boundary_nodes] = 0 # Initialize the node-state array: here, the initial condition is a pile of # resting grains at the bottom of a container. bottom_rows = where(mg.node_y<0.4*nr)[0] node_state_grid[bottom_rows] = 1 # Create a data array for bleaching. # Here, osl=optically stimulated luminescence, normalized to the original # signal (hence, initially all unity). Over time this signal may get # bleached out due to exposure to light. self.osl = mg.add_zeros('node', 'osl') self.osl[bottom_rows] = 1.0 self.osl_display = mg.add_zeros('node', 'osl_display') self.osl_display[bottom_rows] = 1.0 # We'll need an array to track the last time any given node was # updated, so we can figure out the duration of light exposure between # update events self.last_update_time = mg.add_zeros('node','last_update_time') # Call the base class (RasterCTS) init method super(TurbulentSuspensionAndBleachingModel, \ self).__init__(mg, ns_dict, xn_list, node_state_grid, prop_data=self.osl) # Set up plotting (if plotting desired) if self.plot_interval <= self.run_duration: self.initialize_plotting() def initialize_plotting(self): """ Creates a CA plotter object, sets its colormap, and plots the initial model state. """ # Set up some plotting information grain = '#5F594D' bleached_grain = '#CC0000' fluid = '#D0E4F2' clist = [fluid,bleached_grain,grain] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display self.ca_plotter = CAPlotter(self, cmap=my_cmap) # Plot the initial grid self.ca_plotter.update_plot() # Make a colormap for use in showing the bleaching of each grain clist = [(0.0, (1.0, 1.0, 1.0)), (0.49, (0.8, 0.8, 0.8)), (1.0, (0.0, 0.0, 0.0))] self.cmap_for_osl = matplotlib.colors.LinearSegmentedColormap.from_list('osl_cmap', clist) def setup_transition_list(self): """ Creates and returns a list of Transition() objects to represent state transitions for a biased random walk, in which the rate of downward motion is greater than the rate in the other three directions. Parameters ---------- (none) Returns ------- xn_list : list of Transition objects List of objects that encode information about the link-state transitions. Notes ----- State 0 represents fluid and state 1 represents a particle (such as a sediment grain, tea leaf, or dissolved heavy particle). The states and transitions are as follows: Pair state Transition to Process Rate (cells/s) ========== ============= ======= ============== 0 (0-0) (none) - - 1 (0-1) 2 (1-0) left motion 10.0 2 (1-0) 1 (0-1) right motion 10.0 3 (1-1) (none) - - 4 (0-0) (none) - - 5 (0-1) 2 (1-0) down motion 10.55 6 (1-0) 1 (0-1) up motion 9.45 7 (1-1) (none) - - """ # Create an empty transition list xn_list = [] # Append four transitions to the list. # Note that the arguments to the Transition() object constructor are: # - Tuple representing starting pair state # (left cell, right cell, orientation [0=horizontal]) # - Tuple representing new pair state # (bottom cell, top cell, orientation [1=vertical]) # - Transition rate (cells per time step, in this case 1 sec) # - Name for transition # - Flag indicating that the transition involves an exchange of properties # - Function to be called after each transition, to update a property # (in this case, to simulate bleaching of the luminescence signal) xn_list.append( Transition((0,1,0), (1,0,0), 10., 'left motion', True, self.update_bleaching) ) xn_list.append( Transition((1,0,0), (0,1,0), 10., 'right motion', True, self.update_bleaching) ) xn_list.append( Transition((0,1,1), (1,0,1), 10.55, 'down motion', True, self.update_bleaching) ) xn_list.append( Transition((1,0,1), (0,1,1), 9.45, 'up motion', True, self.update_bleaching) ) return xn_list def bleach_grain(self, node, dt): """ Updates the luminescence signal at node. Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 10 ... model_grid_column__count: number of columns in grid ... 3 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 6.5 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.bleach_grain(10, 1.0) >>> int(tsbm.prop_data[tsbm.propid[10]]*1000) 858 """ depth = self.fluid_surface_height - self.grid.node_y[node] T_bleach = self.bleach_T0*exp( depth/self.zstar) self.prop_data[self.propid[node]] *= exp( -dt/T_bleach ) def update_bleaching(self, ca_unused, node1, node2, time_now): """ Updates the luminescence signal at a pair of nodes that have just undergone a transition, if either or both nodes is a grain. Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 10 ... model_grid_column__count: number of columns in grid ... 3 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 6.5 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.update_bleaching(tsbm, 10, 13, 1.0) >>> int(tsbm.prop_data[tsbm.propid[10]]*1000) 858 >>> tsbm.prop_data[tsbm.propid[13]] 0.0 """ if self.node_state[node1]==1: dt = time_now - self.last_update_time[self.propid[node1]] self.bleach_grain(node1, dt) self.last_update_time[self.propid[node1]] = time_now if self.node_state[node2]==1: dt = time_now - self.last_update_time[self.propid[node2]] self.bleach_grain(node2, dt) self.last_update_time[self.propid[node2]] = time_now def synchronize_bleaching(self, sync_time): """ Brings all nodes up to the same time, sync_time, by applying bleaching up to this time, and updating last_update_time. Notes ----- In a CellLab-CTS model, the "time" is usually different for each node: some will have only just recently undergone a transition and had their properties (in this case, OSL bleaching) updated, while others will have last been updated a long time ago, and some may never have had a transition. If we want to plot the properties at a consistent time, we need to bring all node properties (again, in this case, OSL) up to date. This method does so. We multiply elapsed time (between last update and "sync time") by the node state, because we only want to update the solid particles--- because the state of a particle is 1 and fluid 0, this multiplication masks out the fluid nodes. We don't call bleach_grain(), because we want to take advantage of numpy array operations rather than calling a method for each node. Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 10 ... model_grid_column__count: number of columns in grid ... 3 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 6.5 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.synchronize_bleaching(1.0) >>> int(tsbm.osl[10]*100000) 85897 """ dt = (sync_time - self.last_update_time[self.propid])*self.node_state assert (amin(dt)>=0.0), 'sync_time must be >= 0 everywhere' depth = self.fluid_surface_height - self.grid.node_y T_bleach = self.bleach_T0*exp( depth/self.zstar) self.prop_data[self.propid] *= exp( -dt/T_bleach ) self.last_update_time[self.propid] = sync_time*self.node_state def go(self): """ Runs the model. """ # RUN while self.current_time < self.run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= self.next_report: print('Current sim time',self.current_time,'(',100*self.current_time/self.run_duration,'%)') self.next_report = current_real_time + self.report_interval # Run the model forward in time until the next output step self.run(self.current_time+self.plot_interval, self.node_state, plot_each_transition=False) self.current_time += self.plot_interval self.synchronize_bleaching(self.current_time) if self.plot_interval <= self.run_duration: # Plot the current grid self.ca_plotter.update_plot() # Display the OSL content of grains figure(3) clf() self.osl_display[:] = self.osl[self.propid]+self.node_state imshow_node_grid(self.grid, 'osl_display', limits=(0.0, 2.0), cmap=self.cmap_for_osl) show() figure(1) def finalize(self): # FINALIZE # Plot self.ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 21 nc = 21 plot_interval = 0.5 run_duration = 25.0 report_interval = 5.0 # report interval, in real-time seconds # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create a grid hmg = HexModelGrid(nr, nc, 1.0, orientation='vertical', reorient_links=True) # Close the grid boundaries hmg.set_closed_nodes(hmg.open_boundary_nodes) # Set up the states and pair transitions. # Transition data here represent the disease status of a population. ns_dict = { 0 : 'fluid', 1 : 'grain' } xn_list = setup_transition_list() # Create data and initialize values. We start with the 3 middle columns full # of grains, and the others empty. node_state_grid = hmg.add_zeros('node', 'node_state_grid') middle = 0.25*(nc-1)*sqrt(3) is_middle_cols = logical_and(hmg.node_x<middle+1., hmg.node_x>middle-1.) node_state_grid[where(is_middle_cols)[0]] = 1 # Create the CA model ca = OrientedHexCTS(hmg, ns_dict, xn_list, node_state_grid) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time',current_time,'(',100*current_time/run_duration,'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=False) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 200 # number of rows in grid nc = 200 # number of columns in grid plot_interval = 0.05 # time interval for plotting (unscaled) run_duration = 5.0 # duration of run (unscaled) report_interval = 10.0 # report interval, in real-time seconds frac_spacing = 10 # average fracture spacing, nodes outfilename = 'wx' # name for netCDF files # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Counter for output files time_slice = 0 # Create grid mg = RasterModelGrid(nr, nc, 1.0) # Make the boundaries be walls mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. ns_dict = {0: 'rock', 1: 'saprolite'} xn_list = setup_transition_list() # Create the node-state array and attach it to the grid. # (Note use of numpy's uint8 data type. This saves memory AND allows us # to write output to a netCDF3 file; netCDF3 does not handle the default # 64-bit integer type) node_state_grid = mg.add_zeros('node', 'node_state_map', dtype=np.uint8) node_state_grid[:] = make_frac_grid(frac_spacing, model_grid=mg) # Create the CA model ca = RasterCTS(mg, ns_dict, xn_list, node_state_grid) # Set up the color map rock_color = (0.8, 0.8, 0.8) sap_color = (0.4, 0.2, 0) clist = [rock_color, sap_color] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca, cmap=my_cmap) # Plot the initial grid ca_plotter.update_plot() # Output the initial grid to file write_netcdf( (outfilename + str(time_slice) + '.nc'), mg, #format='NETCDF3_64BIT', names='node_state_map') # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time', current_time, '(', 100 * current_time / run_duration, '%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time + plot_interval, ca.node_state, plot_each_transition=False) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # Output the current grid to a netCDF file time_slice += 1 write_netcdf( (outfilename + str(time_slice) + '.nc'), mg, #format='NETCDF3_64BIT', names='node_state_map') # FINALIZE # Plot ca_plotter.finalize()
class TurbulentSuspensionAndBleachingModel(OrientedRasterCTS): """ Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 4 ... model_grid_column__count: number of columns in grid ... 4 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 2.0 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.node_state array([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]) >>> tsbm.grid.at_node['osl'] array([ 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0.]) >>> tsbm.n_xn array([0, 1, 1, 0, 0, 1, 1, 0]) >>> tsbm.fluid_surface_height 3.5 """ def __init__(self, input_stream): """ Reads in parameters and initializes the model. Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 4 ... model_grid_column__count: number of columns in grid ... 4 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 2.0 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.node_state array([1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0]) >>> tsbm.grid.at_node['osl'] array([ 1., 1., 1., 1., 1., 1., 1., 1., 0., 0., 0., 0., 0., 0., 0., 0.]) >>> tsbm.n_xn array([0, 1, 1, 0, 0, 1, 1, 0]) >>> tsbm.fluid_surface_height 3.5 """ # Get a source for input parameters. params = ModelParameterDictionary(input_stream) # Read user-defined parameters nr = params.read_int('model_grid_row__count' ) # number of rows (CSDMS Standard Name [CSN]) nc = params.read_int( 'model_grid_column__count') # number of cols (CSN) self.plot_interval = params.read_float( 'plot_interval') # interval for plotting output, s self.run_duration = params.read_float( 'model__run_time') # duration of run, sec (CSN) self.report_interval = params.read_float( 'model__report_interval') # report interval, in real-time seconds self.bleach_T0 = params.read_float( 'surface_bleaching_time_scale' ) # time scale for bleaching at fluid surface, s self.zstar = params.read_float( 'light_attenuation_length' ) # length scale for light attenuation in fluid, CELLS # Derived parameters self.fluid_surface_height = nr - 0.5 # Calculate when we next want to report progress. self.next_report = time.time() + self.report_interval # Create grid mg = RasterModelGrid(nr, nc, 1.0) # Make the boundaries be walls mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. ns_dict = {0: 'fluid', 1: 'particle'} xn_list = self.setup_transition_list() # Create the node-state array and attach it to the grid node_state_grid = mg.add_zeros('node', 'node_state_map', dtype=int) # For visual display purposes, set all boundary nodes to fluid node_state_grid[mg.closed_boundary_nodes] = 0 # Initialize the node-state array: here, the initial condition is a pile of # resting grains at the bottom of a container. bottom_rows = where(mg.node_y < 0.4 * nr)[0] node_state_grid[bottom_rows] = 1 # Create a data array for bleaching. # Here, osl=optically stimulated luminescence, normalized to the original # signal (hence, initially all unity). Over time this signal may get # bleached out due to exposure to light. self.osl = mg.add_zeros('node', 'osl') self.osl[bottom_rows] = 1.0 self.osl_display = mg.add_zeros('node', 'osl_display') self.osl_display[bottom_rows] = 1.0 # We'll need an array to track the last time any given node was # updated, so we can figure out the duration of light exposure between # update events self.last_update_time = mg.add_zeros('node', 'last_update_time') # Call the base class (RasterCTS) init method super(TurbulentSuspensionAndBleachingModel, \ self).__init__(mg, ns_dict, xn_list, node_state_grid, prop_data=self.osl) # Set up plotting (if plotting desired) if self.plot_interval <= self.run_duration: self.initialize_plotting() def initialize_plotting(self): """ Creates a CA plotter object, sets its colormap, and plots the initial model state. """ # Set up some plotting information grain = '#5F594D' bleached_grain = '#CC0000' fluid = '#D0E4F2' clist = [fluid, bleached_grain, grain] my_cmap = matplotlib.colors.ListedColormap(clist) # Create a CAPlotter object for handling screen display self.ca_plotter = CAPlotter(self, cmap=my_cmap) # Plot the initial grid self.ca_plotter.update_plot() # Make a colormap for use in showing the bleaching of each grain clist = [(0.0, (1.0, 1.0, 1.0)), (0.49, (0.8, 0.8, 0.8)), (1.0, (0.0, 0.0, 0.0))] self.cmap_for_osl = matplotlib.colors.LinearSegmentedColormap.from_list( 'osl_cmap', clist) def setup_transition_list(self): """ Creates and returns a list of Transition() objects to represent state transitions for a biased random walk, in which the rate of downward motion is greater than the rate in the other three directions. Parameters ---------- (none) Returns ------- xn_list : list of Transition objects List of objects that encode information about the link-state transitions. Notes ----- State 0 represents fluid and state 1 represents a particle (such as a sediment grain, tea leaf, or dissolved heavy particle). The states and transitions are as follows: Pair state Transition to Process Rate (cells/s) ========== ============= ======= ============== 0 (0-0) (none) - - 1 (0-1) 2 (1-0) left motion 10.0 2 (1-0) 1 (0-1) right motion 10.0 3 (1-1) (none) - - 4 (0-0) (none) - - 5 (0-1) 2 (1-0) down motion 10.55 6 (1-0) 1 (0-1) up motion 9.45 7 (1-1) (none) - - """ # Create an empty transition list xn_list = [] # Append four transitions to the list. # Note that the arguments to the Transition() object constructor are: # - Tuple representing starting pair state # (left cell, right cell, orientation [0=horizontal]) # - Tuple representing new pair state # (bottom cell, top cell, orientation [1=vertical]) # - Transition rate (cells per time step, in this case 1 sec) # - Name for transition # - Flag indicating that the transition involves an exchange of properties # - Function to be called after each transition, to update a property # (in this case, to simulate bleaching of the luminescence signal) xn_list.append( Transition((0, 1, 0), (1, 0, 0), 10., 'left motion', True, self.update_bleaching)) xn_list.append( Transition((1, 0, 0), (0, 1, 0), 10., 'right motion', True, self.update_bleaching)) xn_list.append( Transition((0, 1, 1), (1, 0, 1), 10.55, 'down motion', True, self.update_bleaching)) xn_list.append( Transition((1, 0, 1), (0, 1, 1), 9.45, 'up motion', True, self.update_bleaching)) return xn_list def bleach_grain(self, node, dt): """ Updates the luminescence signal at node. Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 10 ... model_grid_column__count: number of columns in grid ... 3 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 6.5 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.bleach_grain(10, 1.0) >>> int(tsbm.prop_data[tsbm.propid[10]]*1000) 858 """ depth = self.fluid_surface_height - self.grid.node_y[node] T_bleach = self.bleach_T0 * exp(depth / self.zstar) self.prop_data[self.propid[node]] *= exp(-dt / T_bleach) def update_bleaching(self, ca_unused, node1, node2, time_now): """ Updates the luminescence signal at a pair of nodes that have just undergone a transition, if either or both nodes is a grain. Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 10 ... model_grid_column__count: number of columns in grid ... 3 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 6.5 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.update_bleaching(tsbm, 10, 13, 1.0) >>> int(tsbm.prop_data[tsbm.propid[10]]*1000) 858 >>> tsbm.prop_data[tsbm.propid[13]] 0.0 """ if self.node_state[node1] == 1: dt = time_now - self.last_update_time[self.propid[node1]] self.bleach_grain(node1, dt) self.last_update_time[self.propid[node1]] = time_now if self.node_state[node2] == 1: dt = time_now - self.last_update_time[self.propid[node2]] self.bleach_grain(node2, dt) self.last_update_time[self.propid[node2]] = time_now def synchronize_bleaching(self, sync_time): """ Brings all nodes up to the same time, sync_time, by applying bleaching up to this time, and updating last_update_time. Notes ----- In a CellLab-CTS model, the "time" is usually different for each node: some will have only just recently undergone a transition and had their properties (in this case, OSL bleaching) updated, while others will have last been updated a long time ago, and some may never have had a transition. If we want to plot the properties at a consistent time, we need to bring all node properties (again, in this case, OSL) up to date. This method does so. We multiply elapsed time (between last update and "sync time") by the node state, because we only want to update the solid particles--- because the state of a particle is 1 and fluid 0, this multiplication masks out the fluid nodes. We don't call bleach_grain(), because we want to take advantage of numpy array operations rather than calling a method for each node. Example ------- >>> from six import StringIO >>> p = StringIO(''' ... model_grid_row__count: number of rows in grid ... 10 ... model_grid_column__count: number of columns in grid ... 3 ... plot_interval: interval for plotting to display, s ... 2.0 ... model__run_time: duration of model run, s ... 1.0 ... model__report_interval: time interval for reporting progress, real-time seconds ... 1.0e6 ... surface_bleaching_time_scale: time scale for OSL bleaching, s ... 2.42 ... light_attenuation_length: length scale for light attenuation, cells (1 cell = 1 mm) ... 6.5 ... ''') >>> tsbm = TurbulentSuspensionAndBleachingModel(p) >>> tsbm.synchronize_bleaching(1.0) >>> int(tsbm.osl[10]*100000) 85897 """ dt = (sync_time - self.last_update_time[self.propid]) * self.node_state assert (amin(dt) >= 0.0), 'sync_time must be >= 0 everywhere' depth = self.fluid_surface_height - self.grid.node_y T_bleach = self.bleach_T0 * exp(depth / self.zstar) self.prop_data[self.propid] *= exp(-dt / T_bleach) self.last_update_time[self.propid] = sync_time * self.node_state def go(self): """ Runs the model. """ # RUN while self.current_time < self.run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= self.next_report: print('Current sim time', self.current_time, '(', 100 * self.current_time / self.run_duration, '%)') self.next_report = current_real_time + self.report_interval # Run the model forward in time until the next output step self.run(self.current_time + self.plot_interval, self.node_state, plot_each_transition=False) self.current_time += self.plot_interval self.synchronize_bleaching(self.current_time) if self.plot_interval <= self.run_duration: # Plot the current grid self.ca_plotter.update_plot() # Display the OSL content of grains figure(3) clf() self.osl_display[:] = self.osl[self.propid] + self.node_state imshow_node_grid(self.grid, 'osl_display', limits=(0.0, 2.0), cmap=self.cmap_for_osl) show() figure(1) def finalize(self): # FINALIZE # Plot self.ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 10 nc = 10 plot_interval = 0.25 run_duration = 40.0 report_interval = 5.0 # report interval, in real-time seconds # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create grid mg = RasterModelGrid(nr, nc, 1.0) mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. # Transition data here represent a body of fractured rock, with rock # represented by nodes with state 0, and saprolite (weathered rock) # represented by nodes with state 1. Node pairs (links) with 0-1 or 1-0 # can undergo a transition to 1-1, representing chemical weathering of the # rock. ns_dict = { 0 : 'air', 1 : 'particle' } xn_list = setup_transition_list() # Create the node-state array and attach it to the grid node_state_grid = mg.add_zeros('node', 'node_state_map', dtype=int) node_state_grid[where(mg.node_y>nr-3)[0]] = 1 # Create the CA model ca = OrientedRasterCTS(mg, ns_dict, xn_list, node_state_grid) #ca = RasterCTS(mg, ns_dict, xn_list, node_state_grid) # Debug output if needed if _DEBUG: n = ca.grid.number_of_nodes for r in range(ca.grid.number_of_node_rows): for c in range(ca.grid.number_of_node_columns): n -= 1 print('{0:.0f}'.format(ca.node_state[n]), end=' ') print() # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # RUN current_time = 0.0 updated = False while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time',current_time,'(',100*current_time/run_duration,'%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time+plot_interval, ca.node_state, plot_each_transition=False) #, plotter=ca_plotter) current_time += plot_interval # Add a bunch of particles if current_time > run_duration/2. and not updated: print('updating...') node_state_grid[where(ca.grid.node_y>(nc/2.0))[0]] = 1 ca.update_link_states_and_transitions(current_time) updated = True # Plot the current grid ca_plotter.update_plot() # for debugging if _DEBUG: n = ca.grid.number_of_nodes for r in range(ca.grid.number_of_node_rows): for c in range(ca.grid.number_of_node_columns): n -= 1 print('{0:.0f}'.format(ca.node_state[n]), end=' ') print() # FINALIZE # Plot ca_plotter.finalize()
def main(): # INITIALIZE # User-defined parameters nr = 5 # number of rows in grid nc = 5 # number of columns in grid plot_interval = 10.0 # time interval for plotting, sec run_duration = 10.0 # duration of run, sec report_interval = 10.0 # report interval, in real-time seconds # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create grid mg = RasterModelGrid(nr, nc, 1.0) # Make the boundaries be walls mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. ns_dict = {0: "black", 1: "white"} xn_list = setup_transition_list() # Create the node-state array and attach it to the grid node_state_grid = mg.add_zeros("node", "node_state_map", dtype=int) # For visual display purposes, set all boundary nodes to fluid node_state_grid[mg.closed_boundary_nodes] = 0 # Create the CA model ca = RasterCTS(mg, ns_dict, xn_list, node_state_grid) # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print("Current sim time", current_time, "(", 100 * current_time / run_duration, "%)") next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time + plot_interval, ca.node_state, plot_each_transition=True, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # FINALIZE # Plot ca_plotter.finalize() print("ok, here are the keys") print(ca.__dict__.keys())
def main(): # INITIALIZE # User-defined parameters nr = 80 nc = 80 plot_interval = 2 run_duration = 200 report_interval = 5.0 # report interval, in real-time seconds # Remember the clock time, and calculate when we next want to report # progress. current_real_time = time.time() next_report = current_real_time + report_interval # Create grid mg = RasterModelGrid(nr, nc, 1.0) # Make the boundaries be walls mg.set_closed_boundaries_at_grid_edges(True, True, True, True) # Set up the states and pair transitions. ns_dict = {0: 'fluid', 1: 'particle'} xn_list = setup_transition_list() # Create the node-state array and attach it to the grid node_state_grid = mg.add_zeros('node', 'node_state_map', dtype=int) # Initialize the node-state array middle_rows = where( bitwise_and(mg.node_y > 0.45 * nr, mg.node_y < 0.55 * nr))[0] node_state_grid[middle_rows] = 1 # Create the CA model ca = OrientedRasterCTS(mg, ns_dict, xn_list, node_state_grid) # Debug output if needed if _DEBUG: n = ca.grid.number_of_nodes for r in range(ca.grid.number_of_node_rows): for c in range(ca.grid.number_of_node_columns): n -= 1 print('{0:.0f}'.format(ca.node_state[n]), end=' ') print() # Create a CAPlotter object for handling screen display ca_plotter = CAPlotter(ca) # Plot the initial grid ca_plotter.update_plot() # RUN current_time = 0.0 while current_time < run_duration: # Once in a while, print out simulation and real time to let the user # know that the sim is running ok current_real_time = time.time() if current_real_time >= next_report: print('Current sim time', current_time, '(', 100 * current_time / run_duration, '%)') next_report = current_real_time + report_interval # Run the model forward in time until the next output step ca.run(current_time + plot_interval, ca.node_state, plot_each_transition=False) #, plotter=ca_plotter) current_time += plot_interval # Plot the current grid ca_plotter.update_plot() # for debugging if _DEBUG: n = ca.grid.number_of_nodes for r in range(ca.grid.number_of_node_rows): for c in range(ca.grid.number_of_node_columns): n -= 1 print('{0:.0f}'.format(ca.node_state[n]), end=' ') print() # FINALIZE # Plot ca_plotter.finalize()