def test_can_run_with_hex(): """Test that model can run with hex model grid.""" # Set up a 5x5 grid with open boundaries and low initial elevations. mg = HexModelGrid(7, 7) z = mg.add_zeros("node", "topographic__elevation") z[:] = 0.01 * mg.x_of_node # Create a D8 flow handler fa = FlowAccumulator(mg, flow_director="FlowDirectorSteepest") # Parameter values for test 1 U = 0.001 dt = 10.0 # Create the Space component... sp = Space( mg, K_sed=0.00001, K_br=0.00000000001, F_f=0.5, phi=0.1, H_star=1., v_s=0.001, m_sp=0.5, n_sp=1.0, sp_crit_sed=0, sp_crit_br=0, ) # ... and run it to steady state. for i in range(2000): fa.run_one_step() sp.run_one_step(dt=dt) z[mg.core_nodes] += U * dt
def test_non_raster(): """Test a hex model grid.""" grid = HexModelGrid(7, 3, dx=10) _ = grid.add_zeros('node', 'topographic__elevation') param_dict = {'faulted_surface': 'topographic__elevation', 'fault_dip_angle': 90.0, 'fault_throw_rate_through_time': {'time': [0, 9, 10], 'rate': [0, 0, 0.05]}, 'fault_trace': {'y1': 30.0, 'x1': 30.0, 'y2': 20.0, 'x2': 0.0}, 'include_boundaries': True} nf = NormalFault(grid, **param_dict) # plotting, to test this. it works! #import matplotlib.pyplot as plt #plt.figure() #imshow_grid(grid, nf.faulted_nodes, color_for_background='y') #plt.plot(grid.x_of_node, grid.y_of_node, 'c.') #plt.plot([param_dict['fault_trace']['x1'], param_dict['fault_trace']['x2']], # [param_dict['fault_trace']['y1'], param_dict['fault_trace']['y2']], 'r') #plt.show() out = np.array([ True, True, True, True, True, True, True, False, True, True, True, True, False, False, False, False, True, True, False, False, False, False, False, False, False, False, False, False, False, False], dtype=bool) assert_array_equal(nf.faulted_nodes, out)
def test_functions_with_Hex(): mg = HexModelGrid(10, 10) z = mg.add_zeros("node", "topographic__elevation") z += mg.x_of_node + mg.y_of_node fa = FlowAccumulator(mg) fa.run_one_step() ch = ChiFinder(mg, min_drainage_area=1.0, reference_concavity=1.0) ch.calculate_chi()
def test_flow__distance_irregular_grid_d4(): """Test to demonstrate that flow__distance utility works as expected with irregular grids""" # instantiate a model grid dx = 1.0 hmg = HexModelGrid(5, 3, dx) # instantiate and add the elevation field hmg.add_field( "topographic__elevation", hmg.node_x + np.round(hmg.node_y), at="node" ) # instantiate the expected flow__distance array flow__distance_expected = np.array( [ 0.0, 0.0, 0.0, 0.0, 0.0, dx, 0.0, 0.0, dx, dx, 2.0 * dx, 0.0, 0.0, 2.0 * dx, 2.0 * dx, 0.0, 0.0, 0.0, 0.0, ] ) # setting boundary conditions hmg.set_closed_nodes(hmg.boundary_nodes) # calculating flow directions with FlowAccumulator component: D4 algorithm fr = FlowAccumulator(hmg, flow_director="D4") fr.run_one_step() # calculating flow distance map flow__distance = calculate_flow__distance(hmg, add_to_grid=True, noclobber=False) # test that the flow__distance utility works as expected assert_almost_equal(flow__distance_expected, flow__distance, decimal=10)
def test_save_and_load_hex(): """Test saving and loading of a HexModelGrid.""" mg1 = HexModelGrid(3, 3, 1.0) mg1.add_zeros("node", "topographic__elevation") save_grid(mg1, "testsavedgrid.grid") mg2 = load_grid("testsavedgrid.grid") assert mg1.x_of_node[0] == mg2.x_of_node[0] assert_array_equal(mg1.status_at_node, mg2.status_at_node) for name in mg1.at_node: assert_array_equal(mg1.at_node[name], mg2.at_node[name])
def test_transitions_as_ids(): """Test passing from-state and to-state IDs instead of tuples """ mg = HexModelGrid(3, 2, 1.0, orientation="vertical", reorient_links=True) nsd = {0: "zero", 1: "one"} xnlist = [] xnlist.append(Transition(2, 3, 1.0, "transitioning")) nsg = mg.add_zeros("node", "node_state_grid") cts = HexCTS(mg, nsd, xnlist, nsg) assert cts.num_link_states == 4, "wrong number of transitions"
def test_oriented_hex_cts(): """Tests instantiation of an OrientedHexCTS() object""" mg = HexModelGrid(3, 2, 1.0, orientation="vertical", reorient_links=True) nsd = {0: "zero", 1: "one"} xnlist = [] xnlist.append(Transition((0, 1, 0), (1, 1, 0), 1.0, "transitioning")) nsg = mg.add_zeros("node", "node_state_grid") ohcts = OrientedHexCTS(mg, nsd, xnlist, nsg) assert_equal(ohcts.num_link_states, 12) assert_array_equal(ohcts.link_orientation, [2, 1, 0, 0, 0, 2, 1, 0, 2, 1, 0])
def test_hex_cts(): """Tests instantiation of a HexCTS() object""" mg = HexModelGrid(3, 2, 1.0, orientation='vertical', reorient_links=True) nsd = {0 : 'zero', 1 : 'one'} xnlist = [] xnlist.append(Transition((0,1,0), (1,1,0), 1.0, 'transitioning')) nsg = mg.add_zeros('node', 'node_state_grid') hcts = HexCTS(mg, nsd, xnlist, nsg) assert_equal(hcts.num_link_states, 4) assert_array_equal(hcts.link_orientation, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
def test_grid_type_testing(): """Test that only the right grids can be implemented.""" dx=(2./(3.**0.5))**0.5 hmg = HexModelGrid(9,5, dx) z = hmg.add_field('topographic__elevation', hmg.node_x + np.round(hmg.node_y), at = 'node') # D8 is ONLY RASTER with pytest.raises(NotImplementedError): FlowDirectorD8(hmg) # DINF IS ONLY RASTER RASTER with pytest.raises(NotImplementedError): FlowDirectorDINF(hmg)
def test_handle_grid_mismatch(): """Test error handling when user passes wrong grid type.""" mg = HexModelGrid(3, 2, 1.0, orientation="vertical", reorient_links=True) nsd = {0: "zero", 1: "one"} xnlist = [] xnlist.append(Transition(2, 3, 1.0, "transitioning")) nsg = mg.add_zeros("node", "node_state_grid") assert_raises(TypeError, RasterCTS, mg, nsd, xnlist, nsg) assert_raises(TypeError, OrientedRasterCTS, mg, nsd, xnlist, nsg) mg = RasterModelGrid((3, 3)) assert_raises(TypeError, HexCTS, mg, nsd, xnlist, nsg) assert_raises(TypeError, OrientedHexCTS, mg, nsd, xnlist, nsg)
def test_neighbor_shaping_hex(): hmg = HexModelGrid(6, 5, dx=1.) hmg.add_zeros("node", "topographic__elevation", dtype=float) hmg.add_zeros("node", "topographic__steepest_slope", dtype=float) hmg.add_zeros("node", "flow__receiver_node", dtype=int) hmg.add_zeros("node", "flow__link_to_receiver_node", dtype=int) lmb = LakeMapperBarnes(hmg, redirect_flow_steepest_descent=True) for arr in (lmb._neighbor_arrays, lmb._link_arrays): assert len(arr) == 1 assert arr[0].shape == (hmg.number_of_nodes, 6) assert len(lmb._neighbor_lengths) == hmg.number_of_links
def __init__(self, grid=None, node_state=None, propid=None, prop_data=None, prop_reset_value=None): # If needed, create grid if grid is None: num_rows = _DEFAULT_NUM_ROWS num_cols = _DEFAULT_NUM_COLS self.grid = HexModelGrid(num_rows, num_cols, dx=1.0, orientation='vertical', shape='rect', reorient_links=True) else: # Make sure caller passed the right type of grid assert (grid.orientation=='vertical'), \ 'Grid must have vertical orientation' # Keep a reference to the grid self.grid = grid # If needed, create node-state grid if node_state is None: self.node_state = self.grid.add_zeros('node', 'node_state_map') else: #print 'setting node state' self.node_state = node_state # Remember the # of rows and cols self.nr = self.grid.number_of_node_rows self.nc = self.grid.number_of_node_columns # propid should be either a reference to a CA model's "property id" # array, or None self.propid = propid self.prop_data = prop_data self.prop_reset_value = prop_reset_value
def create_grid_and_node_state_field(self, num_rows, num_cols, grid_orientation, grid_shape, cts_type): """Create the grid and the field containing node states.""" if cts_type == 'raster' or cts_type == 'oriented_raster': from landlab import RasterModelGrid self.grid = RasterModelGrid(shape=(num_rows, num_cols), spacing=1.0) else: from landlab import HexModelGrid self.grid = HexModelGrid(num_rows, num_cols, 1.0, orientation=grid_orientation, shape=grid_shape) self.grid.add_zeros('node', 'node_state', dtype=int)
class HexLatticeTectonicizer(object): """Base class from which classes to represent particular baselevel/fault geometries are derived. """ def __init__(self, grid=None, node_state=None): # If needed, create grid if grid is None: num_rows = _DEFAULT_NUM_ROWS num_cols = _DEFAULT_NUM_COLS self.grid = HexModelGrid(num_rows, num_cols, dx=1.0, orientation='vertical', shape='rect', reorient_links=True) else: # Make sure caller passed the right type of grid assert (grid.orientation == 'vertical'), \ 'Grid must have vertical orientation' # Keep a reference to the grid self.grid = grid # If needed, create node-state grid if node_state is None: self.node_state = self.grid.add_zeros('node', 'node_state_map') else: self.node_state = node_state # Remember the # of rows and cols self.nr = self.grid.number_of_node_rows self.nc = self.grid.number_of_node_columns
def __init__(self, grid=None, node_state=None): # If needed, create grid if grid is None: num_rows = _DEFAULT_NUM_ROWS num_cols = _DEFAULT_NUM_COLS self.grid = HexModelGrid(num_rows, num_cols, dx=1.0, orientation='vertical', shape='rect', reorient_links=True) else: # Make sure caller passed the right type of grid assert (grid.orientation == 'vertical'), \ 'Grid must have vertical orientation' # Keep a reference to the grid self.grid = grid # If needed, create node-state grid if node_state is None: self.node_state = self.grid.add_zeros('node', 'node_state_map') else: self.node_state = node_state # Remember the # of rows and cols self.nr = self.grid.number_of_node_rows self.nc = self.grid.number_of_node_columns
def test_move_reference_hex(random_xy, n_rows, n_cols, shape, orientation): mg = HexModelGrid( n_rows, n_cols, dx=2.0, xy_of_lower_left=random_xy, orientation=orientation, shape=shape, ) assert mg.xy_of_lower_left == random_xy assert mg.x_of_node.min() == random_xy[0] assert mg.y_of_node.min() == random_xy[1] mg.xy_of_lower_left = (30.0, 45.0) assert mg._xy_of_lower_left == (30.0, 45.0) assert mg.x_of_node.min() == approx(30.0) assert mg.y_of_node.min() == approx(45.0)
def test_nodes_at_link(): """Test nodes_at_link shares data with tail and head.""" grid = HexModelGrid((3, 2)) assert_array_equal(grid.nodes_at_link[:, 0], grid.node_at_link_tail) assert_array_equal(grid.nodes_at_link[:, 1], grid.node_at_link_head) assert np.may_share_memory(grid.nodes_at_link, grid.node_at_link_tail) assert np.may_share_memory(grid.nodes_at_link, grid.node_at_link_head)
def __init__( self, grid=None, node_state=None, propid=None, prop_data=None, prop_reset_value=None, ): """ Create and initialize a HexLatticeTectonicizer. Examples -------- >>> from landlab import HexModelGrid >>> hg = HexModelGrid(6, 6, shape='rect') >>> hlt = HexLatticeTectonicizer() >>> hlt.grid.number_of_nodes 25 >>> hlt.nr 5 >>> hlt.nc 5 """ # If needed, create grid if grid is None: num_rows = _DEFAULT_NUM_ROWS num_cols = _DEFAULT_NUM_COLS self.grid = HexModelGrid( num_rows, num_cols, dx=1.0, orientation="vertical", shape="rect", reorient_links=True, ) else: # Make sure caller passed the right type of grid assert grid.orientation == "vertical", "Grid must have vertical orientation" # Keep a reference to the grid self.grid = grid # If needed, create node-state grid if node_state is None: self.node_state = self.grid.add_zeros("node", "node_state_map", dtype=int) else: self.node_state = node_state # Remember the # of rows and cols self.nr = self.grid.number_of_node_rows self.nc = self.grid.number_of_node_columns # propid should be either a reference to a CA model's "property id" # array, or None self.propid = propid self.prop_data = prop_data self.prop_reset_value = prop_reset_value
def test_hex_cts(): """Tests instantiation of a HexCTS() object""" mg = HexModelGrid( (3, 2), spacing=1.0, orientation="vertical", node_layout="hex", # reorient_links=True, ) nsd = {0: "zero", 1: "one"} xnlist = [] xnlist.append(Transition((0, 1, 0), (1, 1, 0), 1.0, "transitioning")) nsg = mg.add_zeros("node_state_grid", at="node") hcts = HexCTS(mg, nsd, xnlist, nsg) assert hcts.num_link_states == 4 assert_array_equal(hcts.link_orientation, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
def test_shift_link_and_transition_data_upward(): """Test the LatticeUplifter method that uplifts link data and tr'ns.""" mg = HexModelGrid((4, 3), spacing=1.0, orientation="vertical", node_layout="rect") nsd = {0: "yes", 1: "no"} xnlist = [] xnlist.append(Transition((0, 0, 0), (1, 1, 0), 1.0, "frogging")) xnlist.append(Transition((0, 0, 1), (1, 1, 1), 1.0, "frogging")) xnlist.append(Transition((0, 0, 2), (1, 1, 2), 1.0, "frogging")) nsg = mg.add_zeros("node_state_grid", at="node") ohcts = OrientedHexCTS(mg, nsd, xnlist, nsg) assert_array_equal(ohcts.link_state[mg.active_links], [0, 4, 8, 8, 4, 0, 4, 8, 8, 4, 0]) assert_array_equal(ohcts.next_trn_id[mg.active_links], [0, 1, 2, 2, 1, 0, 1, 2, 2, 1, 0]) assert_array_equal( np.round(ohcts.next_update[mg.active_links], 2), [0.8, 1.26, 0.92, 0.79, 0.55, 1.04, 0.58, 2.22, 3.31, 0.48, 1.57], ) pq = ohcts.priority_queue assert_equal(pq._queue[0][2], 19) # link for first event = 19, not shifted assert_equal(round(pq._queue[0][0], 2), 0.48) # trn scheduled for t = 0.48 assert_equal(pq._queue[2][2], 14) # this event scheduled for link 15... assert_equal(round(pq._queue[2][0], 2), 0.58) # ...trn sched for t = 0.58 lu = LatticeUplifter(grid=mg) lu.shift_link_and_transition_data_upward(ohcts, 0.0) # note new events lowest 5 links assert_array_equal( np.round(ohcts.next_update[mg.active_links], 2), [0.75, 0.84, 2.6, 0.07, 0.09, 0.8, 0.02, 1.79, 1.51, 2.04, 3.85], ) assert_equal(pq._queue[0][2], 14) # new soonest event assert_equal(pq._queue[9][2], 13) # was previously 7, now shifted up... assert_equal(round(pq._queue[9][0], 2), 0.8) # ...still sched for t = 0.80
def test_outlet_lowering_object_with_scaling(): """Test using an outlet lowering object with scaling.""" mg = HexModelGrid(5, 5) z = mg.add_zeros("node", "topographic__elevation") node_id = 27 file = os.path.join(_TEST_DATA_DIR, "outlet_history.txt") bh = SingleNodeBaselevelHandler( mg, outlet_id=node_id, lowering_file_path=file, model_end_elevation=-318.0, ) for _ in range(241): bh.run_one_step(10) assert bh.z[node_id] == -95.0 assert z[1] == 0.0
def test_shift_link_and_transition_data_upward(): """Test the LatticeUplifter method that uplifts link data and tr'ns.""" mg = HexModelGrid(4, 3, 1.0, orientation="vertical", shape="rect") nsd = {0: "yes", 1: "no"} xnlist = [] xnlist.append(Transition((0, 0, 0), (1, 1, 0), 1.0, "frogging")) xnlist.append(Transition((0, 0, 1), (1, 1, 1), 1.0, "frogging")) xnlist.append(Transition((0, 0, 2), (1, 1, 2), 1.0, "frogging")) nsg = mg.add_zeros("node", "node_state_grid") ohcts = OrientedHexCTS(mg, nsd, xnlist, nsg) assert_array_equal( ohcts.link_state[mg.active_links], [0, 4, 8, 8, 4, 0, 4, 8, 8, 4, 0] ) assert_array_equal( ohcts.next_trn_id[mg.active_links], [0, 1, 2, 2, 1, 0, 1, 2, 2, 1, 0] ) assert_array_equal( np.round(ohcts.next_update[mg.active_links], 2), [0.8, 1.26, 0.92, 0.79, 0.55, 1.04, 0.58, 2.22, 3.31, 0.48, 1.57], ) pq = ohcts.priority_queue assert_equal(pq._queue[0][2], 20) # link for first event = 20, not shifted assert_equal(round(pq._queue[0][0], 2), 0.48) # trn scheduled for t = 0.48 assert_equal(pq._queue[2][2], 15) # this event scheduled for link 15... assert_equal(round(pq._queue[2][0], 2), 0.58) # ...trn sched for t = 0.58 lu = LatticeUplifter(grid=mg) lu.shift_link_and_transition_data_upward(ohcts, 0.0) # note new events lowest 5 links assert_array_equal( np.round(ohcts.next_update[mg.active_links], 2), [0.75, 0.84, 2.6, 0.07, 0.09, 0.8, 0.02, 1.79, 1.51, 2.04, 3.85], ) assert_equal(pq._queue[0][2], 15) # new soonest event assert_equal(pq._queue[9][2], 14) # was previously 7, now shifted up... assert_equal(round(pq._queue[9][0], 2), 0.8) # ...still sched for t = 0.80
def test_move_reference_hex(random_xy, n_rows, n_cols, node_layout, orientation): mg = HexModelGrid( n_rows, n_cols, dx=2.0, xy_of_lower_left=random_xy, orientation=orientation, node_layout=node_layout, ) assert mg.xy_of_lower_left == random_xy assert mg.x_of_node.min() == random_xy[0] assert mg.y_of_node.min() == random_xy[1] mg.xy_of_lower_left = (30.0, 45.0) assert mg._xy_of_lower_left == (30.0, 45.0) assert mg.x_of_node.min() == approx(30.0) assert mg.y_of_node.min() == approx(45.0)
def test_hex(): """Test using a hex grid.""" mg = HexModelGrid((5, 5)) z = mg.add_zeros("node", "topographic__elevation") bh = NotCoreNodeBaselevelHandler( mg, modify_core_nodes=False, lowering_rate=-0.1 ) bh.run_one_step(10.0) closed = mg.status_at_node != 0 not_closed = mg.status_at_node == 0 # closed should have been downdropped 10*0.1 assert_array_equal(z[closed], -1.0 * np.ones(np.sum(closed))) # not closed should have stayed the same assert_array_equal(z[not_closed], np.zeros(np.sum(not_closed)))
def test_can_run_with_hex(): """Test that model can run with hex model grid.""" # Set up a 5x5 grid with open boundaries and low initial elevations. mg = HexModelGrid(7, 7) z = mg.add_zeros('node', 'topographic__elevation') z[:] = 0.01 * mg.x_of_node # Create a D8 flow handler fa = FlowAccumulator(mg, flow_director='FlowDirectorSteepest') # Parameter values for test 1 K = 0.001 vs = 0.0001 U = 0.001 dt = 10.0 # Create the ErosionDeposition component... ed = ErosionDeposition(mg, K=K, phi=0.0, v_s=vs, m_sp=0.5, n_sp=1.0, solver='adaptive') # ... and run it to steady state. for i in range(2000): fa.run_one_step() ed.run_one_step(dt=dt) z[mg.core_nodes] += U * dt # Test the results s = mg.at_node['topographic__steepest_slope'] sa_factor = (1.0 + vs) * U / K a18 = mg.at_node['drainage_area'][18] a28 = mg.at_node['drainage_area'][28] s = mg.at_node['topographic__steepest_slope'] s18 = sa_factor * (a18**-0.5) s28 = sa_factor * (a28**-0.5) testing.assert_equal(np.round(s[18], 3), np.round(s18, 3)) testing.assert_equal(np.round(s[28], 3), np.round(s28, 3))
def test_shape_dep_warning(): """Test dep warning on use of shape keyword instead of node_layout.""" with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") # Trigger the deprecation warning. HexModelGrid(3, 2, shape="rect") # Verify some things assert len(w) == 1 assert issubclass(w[-1].category, DeprecationWarning) assert "node_layout" in str(w[-1].message)
def test_outlet_lowering_rate_on_not_outlet(): """Test using an rate lowering object with no scaling and bedrock.""" mg = HexModelGrid(5, 5) z = mg.add_ones("node", "topographic__elevation") b = mg.add_zeros("node", "bedrock__elevation") node_id = 27 bh = SingleNodeBaselevelHandler( mg, outlet_id=node_id, lowering_rate=-0.1, modify_outlet_id=False ) for _ in range(240): bh.run_one_step(10) assert z[node_id] == 1.0 assert b[node_id] == 0.0 not_outlet = mg.nodes != node_id assert np.all(z[not_outlet] == 241.0) assert np.all(b[not_outlet] == 240.0)
def test_outlet_lowering_object_no_scaling(): """Test using an outlet lowering object with no scaling.""" mg = HexModelGrid((5, 5)) z = mg.add_ones("node", "topographic__elevation") file = os.path.join(_TEST_DATA_DIR, "outlet_history.txt") bh = NotCoreNodeBaselevelHandler( mg, modify_core_nodes=False, lowering_file_path=file ) for _ in range(241): bh.run_one_step(10) closed = mg.status_at_node != 0 not_closed = mg.status_at_node == 0 # not closed should have stayed the same assert_array_equal(z[not_closed], np.ones(np.sum(not_closed))) # closed should lowered by 47.5 to -46.5 assert_array_equal(z[closed], -46.5 * np.ones(np.sum(closed)))
def test_not_passing_infiltration_capacity(): mg = HexModelGrid(5, 5) with pytest.raises(ValueError): PrecipChanger( mg, daily_rainfall__intermittency_factor=0.3, daily_rainfall__intermittency_factor_time_rate_of_change=0.001, rainfall__mean_rate=3.0, rainfall__mean_rate_time_rate_of_change=0.2, rainfall__shape_factor=0.65, )
def test_links_to_update(): """Test that update list includes lower 2 rows and fault-crossing links""" # Create a 6x6 test grid hg = HexModelGrid((6, 6), node_layout="rect", orientation="vertical") lnf = LatticeNormalFault(grid=hg, fault_x_intercept=-0.1) assert_array_equal( lnf.links_to_update, [ 6, 7, 9, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 22, 23, 24, 25, 26, 27, 28, 29, 30, 33, 34, 35, 36, 38, 39, 41, 44, 49, 52, 54, 58, 60, 66, 68, 71, 74, 75, 78, ], )
def test_links_to_update(): """Test that update list includes lower 2 rows and fault-crossing links""" # Create a 6x6 test grid hg = HexModelGrid(6, 6, shape="rect", orientation="vert") lnf = LatticeNormalFault(grid=hg, fault_x_intercept=-0.1) assert_array_equal( lnf.links_to_update, [ 8, 9, 11, 12, 13, 14, 15, 16, 18, 19, 20, 21, 22, 24, 25, 26, 27, 28, 29, 30, 31, 32, 35, 36, 37, 38, 40, 41, 43, 46, 51, 54, 56, 60, 62, 68, 70, 73, 76, 77, 80, ], )
def test_hex_lower_left_as_iterables(random_xy, to_iterable): expected = approx(tuple(random_xy)) grid = HexModelGrid( (9, 5), xy_of_lower_left=to_iterable(random_xy), orientation="horizontal", node_layout="rect", ) assert isinstance(grid.xy_of_lower_left, tuple) assert grid.xy_of_lower_left == expected
def test_outlet_lowering_object_no_scaling_bedrock(): """Test using an outlet lowering object with no scaling and bedrock.""" mg = HexModelGrid(5, 5) z = mg.add_ones("node", "topographic__elevation") b = mg.add_zeros("node", "bedrock__elevation") node_id = 27 file = os.path.join(_TEST_DATA_DIR, "outlet_history.txt") bh = SingleNodeBaselevelHandler( mg, outlet_id=node_id, lowering_file_path=file ) for _ in range(241): bh.run_one_step(10) assert z[1] == 1.0 assert b[1] == 0.0 assert z[node_id] == -46.5 assert b[node_id] == -47.5
def test_non_raster(): """Test a hex model grid.""" grid = HexModelGrid(7, 3, dx=10) _ = grid.add_zeros('node', 'topographic__elevation') param_dict = { 'faulted_surface': 'topographic__elevation', 'fault_dip_angle': 90.0, 'fault_throw_rate_through_time': { 'time': [0, 9, 10], 'rate': [0, 0, 0.05] }, 'fault_trace': { 'y1': 30.0, 'x1': 30.0, 'y2': 20.0, 'x2': 0.0 }, 'include_boundaries': True } nf = NormalFault(grid, **param_dict) # plotting, to test this. it works! #import matplotlib.pyplot as plt #plt.figure() #imshow_grid(grid, nf.faulted_nodes, color_for_background='y') #plt.plot(grid.x_of_node, grid.y_of_node, 'c.') #plt.plot([param_dict['fault_trace']['x1'], param_dict['fault_trace']['x2']], # [param_dict['fault_trace']['y1'], param_dict['fault_trace']['y2']], 'r') #plt.show() out = np.array([ True, True, True, True, True, True, True, False, True, True, True, True, False, False, False, False, True, True, False, False, False, False, False, False, False, False, False, False, False, False ], dtype=bool) assert_array_equal(nf.faulted_nodes, out)
def test_move_reference_hex(random_xy, n_rows, n_cols, node_layout, orientation): grid = HexModelGrid( (n_rows, n_cols), spacing=2.0, xy_of_lower_left=random_xy, orientation=orientation, node_layout=node_layout, ) assert grid.xy_of_lower_left == approx(random_xy) assert grid.x_of_node.min() == approx(random_xy[0]) assert grid.y_of_node.min() == approx(random_xy[1]) x, y = grid.x_of_node.copy(), grid.y_of_node.copy() grid.xy_of_lower_left = (30.0, 45.0) assert grid.xy_of_lower_left == (30.0, 45.0) assert grid.x_of_node - x == approx(30.0 - random_xy[0]) assert grid.y_of_node - y == approx(45.0 - random_xy[1])
def create_grid_and_node_state_field(self, num_rows, num_cols, grid_orientation, node_layout, cts_type): """Create the grid and the field containing node states.""" if cts_type == "raster" or cts_type == "oriented_raster": from landlab import RasterModelGrid self.grid = RasterModelGrid(shape=(num_rows, num_cols), xy_spacing=1.0) else: from landlab import HexModelGrid self.grid = HexModelGrid( (num_rows, num_cols), spacing=1.0, orientation=grid_orientation, node_layout=node_layout, ) self.grid.add_zeros("node_state", at="node", dtype=int)
def create_grid_and_node_state_field( self, num_rows, num_cols, grid_orientation, node_layout, cts_type ): """Create the grid and the field containing node states.""" if cts_type == "raster" or cts_type == "oriented_raster": from landlab import RasterModelGrid self.grid = RasterModelGrid(shape=(num_rows, num_cols), xy_spacing=1.0) else: from landlab import HexModelGrid self.grid = HexModelGrid( num_rows, num_cols, xy_spacing=1.0, orientation=grid_orientation, node_layout=node_layout, ) self.grid.add_zeros("node", "node_state", dtype=int)
def test_shape_dep_warning(): """Test dep warning on use of shape keyword instead of node_layout.""" with warnings.catch_warnings(record=True) as w: # Cause all warnings to always be triggered. warnings.simplefilter("always") # Trigger the deprecation warning. HexModelGrid(3, 2, shape="rect") # Verify some things catmsg = "" for warn in w: catmsg += str(warn.message) assert "node_layout" in catmsg
def create_grid_and_node_state_field(self, num_rows, num_cols, grid_orientation, grid_shape, cts_type): """Create the grid and the field containing node states.""" if cts_type == 'raster' or cts_type == 'oriented_raster': from landlab import RasterModelGrid self.grid = RasterModelGrid(shape=(num_rows, num_cols), spacing=1.0) else: from landlab import HexModelGrid self.grid = HexModelGrid(num_rows, num_cols, 1.0, orientation=grid_orientation, shape=grid_shape) self.grid.add_zeros('node', 'node_state', dtype=int) for edge in (self.grid.nodes_at_right_edge, self.grid.nodes_at_top_edge): self.grid.status_at_node[edge] = CLOSED_BOUNDARY
def test_can_run_with_hex(): """Test that model can run with hex model grid.""" # Set up a 5x5 grid with open boundaries and low initial elevations. mg = HexModelGrid(7, 7) z = mg.add_zeros('node', 'topographic__elevation') z[:] = 0.01 * mg.x_of_node # Create a D8 flow handler fa = FlowAccumulator(mg, flow_director='FlowDirectorSteepest') # Parameter values for test 1 K = 0.001 vs = 0.0001 U = 0.001 dt = 10.0 # Create the ErosionDeposition component... ed = ErosionDeposition(mg, K=K, phi=0.0, v_s=vs, m_sp=0.5, n_sp=1.0, method='simple_stream_power', discharge_method='drainage_area', area_field='drainage_area', solver='adaptive') # ... and run it to steady state. for i in range(2000): fa.run_one_step() ed.run_one_step(dt=dt) z[mg.core_nodes] += U * dt # Test the results s = mg.at_node['topographic__steepest_slope'] sa_factor = (1.0 + vs) * U / K a18 = mg.at_node['drainage_area'][18] a28 = mg.at_node['drainage_area'][28] s = mg.at_node['topographic__steepest_slope'] s18 = sa_factor * (a18 ** -0.5) s28 = sa_factor * (a28 ** -0.5) assert_equal(np.round(s[18], 3), np.round(s18, 3)) assert_equal(np.round(s[28], 3), np.round(s28, 3))
def test_can_run_with_hex(): """Test that model can run with hex model grid.""" # Set up a 5x5 grid with open boundaries and low initial elevations. mg = HexModelGrid(7, 7) z = mg.add_zeros('node', 'topographic__elevation') z[:] = 0.01 * mg.x_of_node # Create a D8 flow handler fa = FlowAccumulator(mg, flow_director='FlowDirectorSteepest') # Parameter values for test 1 K = 0.001 vs = 0.0001 U = 0.001 dt = 10.0 # Create the ErosionDeposition component... sp = Space(mg, K_sed=0.00001, K_br=0.00000000001, F_f=0.5, phi=0.1, H_star=1., v_s=0.001, m_sp=0.5, n_sp=1.0, sp_crit_sed=0, sp_crit_br=0, method='simple_stream_power', discharge_method=None, area_field=None, discharge_field=None) # ... and run it to steady state. for i in range(2000): fa.run_one_step() sp.run_one_step(dt=dt) z[mg.core_nodes] += U * dt
def create_grid_and_node_state_field(self, num_rows, num_cols, grid_orientation, grid_shape, cts_type, closed_bounds): """Create the grid and the field containing node states.""" if cts_type == 'raster' or cts_type == 'oriented_raster': from landlab import RasterModelGrid self.grid = RasterModelGrid(shape=(num_rows, num_cols), spacing=1.0) self.grid.set_closed_boundaries_at_grid_edges(closed_bounds[0], closed_bounds[1], closed_bounds[2], closed_bounds[3]) else: from landlab import HexModelGrid self.grid = HexModelGrid(num_rows, num_cols, 1.0, orientation=grid_orientation, shape=grid_shape) if True in closed_bounds: self._set_closed_boundaries_for_hex_grid(closed_bounds) self.grid.add_zeros('node', 'node_state', dtype=int)
def test_hex_grid_link_order(): """Test the order of links in a small hex grid.""" grid = HexModelGrid((3, 2)) assert_array_equal( grid.nodes_at_link, [ [0, 1], [0, 2], [0, 3], [1, 3], [1, 4], [2, 3], [3, 4], [2, 5], [3, 5], [3, 6], [4, 6], [5, 6], ], ) grid = HexModelGrid((2, 3), orientation="vertical") assert_array_equal( grid.nodes_at_link, [ [1, 0], [0, 2], [0, 3], [1, 3], [3, 2], [1, 4], [2, 5], [4, 3], [3, 5], [3, 6], [4, 6], [6, 5], ], )
def create_grid_and_node_state_field(self, num_rows, num_cols, grid_orientation, node_layout, cts_type, closed_bounds): """Create the grid and the field containing node states.""" if cts_type == 'raster' or cts_type == 'oriented_raster': from landlab import RasterModelGrid self.grid = RasterModelGrid(shape=(num_rows, num_cols), spacing=1.0) self.grid.set_closed_boundaries_at_grid_edges( closed_bounds[0], closed_bounds[1], closed_bounds[2], closed_bounds[3]) else: from landlab import HexModelGrid self.grid = HexModelGrid(shape=(num_rows, num_cols), spacing=1.0, orientation=grid_orientation, node_layout=node_layout) if True in closed_bounds: self._set_closed_boundaries_for_hex_grid(closed_bounds) self.grid.add_zeros('node', 'node_state', dtype=int)
def test_grid_from_dict_hex(orientation, node_layout, xy_of_lower_left): kwds = dict(shape=(3, 4)) if orientation is not None: kwds["orientation"] = orientation if node_layout is not None: kwds["node_layout"] = node_layout if xy_of_lower_left is not None: kwds["xy_of_lower_left"] = xy_of_lower_left expected = HexModelGrid(**kwds) actual = grid_from_dict("HexModelGrid", kwds) assert_array_almost_equal(expected.x_of_node, actual.x_of_node) assert_array_almost_equal(expected.y_of_node, actual.y_of_node)
def test_can_run_with_hex(): """Test that model can run with hex model grid.""" # %% # Set up a 5x5 grid with open boundaries and low initial elevations. mg = HexModelGrid((7, 7)) z = mg.add_zeros("topographic__elevation", at="node") _ = mg.add_zeros("soil__depth", at="node") z[:] = 0.01 * mg.x_of_node # Create a D8 flow handler fa = FlowAccumulator(mg, flow_director="FlowDirectorSteepest") # Parameter values for test 1 U = 0.001 dt = 10.0 # Create the SpaceLargeScaleEroder component... sp = SpaceLargeScaleEroder( mg, K_sed=0.00001, K_br=0.00000000001, F_f=0.5, phi=0.1, H_star=1.0, v_s=0.001, m_sp=0.5, n_sp=1.0, sp_crit_sed=0, sp_crit_br=0, ) # ... and run it to steady state. for _ in range(2000): fa.run_one_step() sp.run_one_step(dt=dt) z[mg.core_nodes] += U * dt
def test_error_handling(): radial_grid = RadialModelGrid( n_rings=1, nodes_in_first_ring=8) # , xy_of_center=(0., 0.)) assert_raises(TypeError, ListricKinematicExtender, radial_grid) hex_grid = HexModelGrid((3, 3)) assert_raises(TypeError, ListricKinematicExtender, hex_grid) grid = RasterModelGrid((3, 7)) grid.add_zeros("topographic__elevation", at="node") assert_raises(KeyError, ListricKinematicExtender, grid, track_crustal_thickness=True)
def test_flow__distance_irregular_grid_d4(): """Test to demonstrate that flow__distance utility works as expected with irregular grids""" # instantiate a model grid dx = 1.0 hmg = HexModelGrid(5, 3, dx) # instantiate and add the elevation field hmg.add_field("topographic__elevation", hmg.node_x + np.round(hmg.node_y), at="node") # instantiate the expected flow__distance array flow__distance_expected = np.array([ 0.0, 0.0, 0.0, 0.0, 0.0, dx, 0.0, 0.0, dx, dx, 2.0 * dx, 0.0, 0.0, 2.0 * dx, 2.0 * dx, 0.0, 0.0, 0.0, 0.0, ]) # setting boundary conditions hmg.set_closed_nodes(hmg.boundary_nodes) # calculating flow directions with FlowAccumulator component: D4 algorithm fr = FlowAccumulator(hmg, flow_director="D4") fr.run_one_step() # calculating flow distance map flow__distance = calculate_flow__distance(hmg, add_to_grid=True, noclobber=False) # test that the flow__distance utility works as expected assert_almost_equal(flow__distance_expected, flow__distance, decimal=10)
def test_create_lnf(nr, nc): pid = arange(nr * nc, dtype=int) ns = arange(nr * nc, dtype=int) pdata = arange(nr * nc) grid = HexModelGrid(nr, nc, 1.0, orientation='vertical', shape='rect', reorient_links=True) lnf = LatticeNormalFault(0.0, grid, ns, pid, pdata, 0.0) #for i in range(grid.number_of_nodes): # print i, grid.node_x[i], grid.node_y[i] return lnf
def test_hex_model_grid(tmpdir, format, orientation, node_layout): grid = HexModelGrid( shape=(4, 5), spacing=2.0, xy_of_lower_left=(-3, -5), orientation=orientation, node_layout=node_layout, ) with tmpdir.as_cwd(): to_netcdf(grid, "test.nc", format=format) actual = from_netcdf("test.nc") assert actual.spacing == grid.spacing assert actual.xy_of_lower_left == grid.xy_of_lower_left assert actual.orientation == grid.orientation assert actual.node_layout == grid.node_layout
def test_hex_from_dict(): params = { "base_num_rows": 5, "base_num_cols": 4, "dx": 2.0, "xy_of_lower_left": (35, 55), "axis_name": ("spam", "eggs"), "axis_units": ("smoot", "parsec"), "xy_of_reference": (12345, 678910), } mg = HexModelGrid.from_dict(params) # assert things. true_x_node = np.array( [ 37.0, 39.0, 41.0, 43.0, 36.0, 38.0, 40.0, 42.0, 44.0, 35.0, 37.0, 39.0, 41.0, 43.0, 45.0, 36.0, 38.0, 40.0, 42.0, 44.0, 37.0, 39.0, 41.0, 43.0, ] ) assert_array_equal(true_x_node, mg.x_of_node) assert (mg.x_of_node.min(), mg.y_of_node.min()) == (35, 55) assert mg.axis_units == ("smoot", "parsec") assert mg.axis_name == ("spam", "eggs") assert mg.xy_of_reference == (12345, 678910)
def testing_flux_divergence_with_hex(): """Test flux divergence function(s). Notes ----- Test grid looks like this: (7)-17-.(8)-18-.(9) . . . . . . 11 12 13 14 15 16 / \ / \ / \ (3)--8-.(4)--9-.(5)-10-.(6) . . . . . . 2 3 4 5 6 7 \ / \ / \ / (0)--0-.(1)--1-.(2) Node numbers in parentheses; others are link numbers; period indicates link head. """ hmg = HexModelGrid(3, 3, reorient_links=True) f = hmg.add_zeros('link', 'test_flux') f[:] = np.arange(hmg.number_of_links) make_links_at_node_array(hmg) assert_array_equal(hmg.gt_num_links_at_node, [3, 4, 3, 3, 6, 6, 3, 3, 4, 3]) assert_array_equal(hmg.gt_links_at_node, [[ 0, 0, 1, 2, 3, 5, 7, 11, 13, 15], [ 2, 1, 6, 8, 4, 6, 10, 12, 14, 16], [ 3, 4, 7, 11, 8, 9, 16, 17, 17, 18], [ -1, 5, -1, -1, 9, 10, -1, -1, 18, -1], [ -1, -1, -1, -1, 12, 14, -1, -1, -1, -1], [ -1, -1, -1, -1, 13, 15, -1, -1, -1, -1]]) assert_array_equal(hmg.gt_link_dirs_at_node, [[ -1, 1, 1, 1, 1, 1, 1, 1, 1, 1], [ -1, -1, -1, -1, 1, 1, 1, 1, 1, 1], [ -1, -1, -1, -1, 1, 1, -1, -1, 1, 1], [ 0, -1, 0, 0, -1, -1, 0, 0, -1, 0], [ 0, 0, 0, 0, -1, -1, 0, 0, 0, 0], [ 0, 0, 0, 0, -1, -1, 0, 0, 0, 0]]) raw_net_flux = np.zeros(hmg.number_of_nodes) for r in range(MAX_NUM_LINKS): raw_net_flux += f[hmg.gt_links_at_node[r,:]]*hmg.gt_link_dirs_at_node[r,:] assert_array_equal(raw_net_flux, [ -5., -10., -12., -17., -19., -19., 1., 6., 26., 49.]) nv = np.arange(hmg.number_of_nodes) #gt_calc_gradients_at_faces(hmg, nv) #gt_link_flux_divergence_at_cells_with_2darray(hmg, f) # Some time trials start = time.time() for i in range(1000): gt_grads_at_faces1(hmg, nv) endtime = time.time()
def test_bad_init_gridmethod(): hmg = HexModelGrid(30, 29, dx=3.) hmg.add_zeros("node", "topographic__elevation", dtype=float) with pytest.raises(ValueError): LakeMapperBarnes(hmg, method="D8")
def test_non_raster(): """Test a hex model grid.""" grid = HexModelGrid(7, 3, dx=10, xy_of_lower_left=(-15.0, 0.0)) grid.add_zeros("node", "topographic__elevation") param_dict = { "faulted_surface": "topographic__elevation", "fault_dip_angle": 90.0, "fault_throw_rate_through_time": {"time": [0, 9, 10], "rate": [0, 0, 0.05]}, "fault_trace": {"y1": 30.0, "x1": 30.0, "y2": 20.0, "x2": 0.0}, "include_boundaries": True, } nf = NormalFault(grid, **param_dict) # plotting, to test this. it works! # import matplotlib.pyplot as plt # plt.figure() # imshow_grid(grid, nf.faulted_nodes, color_for_background='y') # plt.plot(grid.x_of_node, grid.y_of_node, 'c.') # plt.plot([param_dict['fault_trace']['x1'], param_dict['fault_trace']['x2']], # [param_dict['fault_trace']['y1'], param_dict['fault_trace']['y2']], 'r') # plt.show() out = np.array( [ True, True, True, True, True, True, True, False, True, True, True, True, False, False, False, False, True, True, False, False, False, False, False, False, False, False, False, False, False, False, ], dtype=bool, ) assert_array_equal(nf.faulted_nodes, out)
def main(): """ In this simple tutorial example, the main function does all the work: it sets the parameter values, creates and initializes a grid, sets up the state variables, runs the main loop, and cleans up. """ # INITIALIZE # User-defined parameter values numrows = 7 # number of rows in the grid basenumcols = 6 # number of columns in the grid dx = 10.0 # grid cell spacing kd = 0.01 # diffusivity coefficient, in m2/yr uplift_rate = 0.001 # baselevel/uplift rate, in m/yr num_time_steps = 1000 # number of time steps in run # Derived parameters dt = 0.1*dx**2 / kd # time-step size set by CFL condition # Create and initialize a raster model grid mg = HexModelGrid(numrows, basenumcols, dx) # Set up scalar values: elevation and elevation time derivative z = mg.add_zeros('node', 'Land_surface__elevation') dzdt = mg.add_zeros('node', 'Land_surface__time_derivative_of_elevation') # Get a list of the core nodes core_nodes = mg.core_nodes # Display a message print( 'Running diffusion_with_model_hex_grid.py' ) print( 'Time-step size has been set to ' + str( dt ) + ' years.' ) start_time = time.time() # RUN # Main loop for i in range(0, num_time_steps): # Calculate the gradients and sediment fluxes g = mg.calculate_gradients_at_active_links(z) qs = -kd*g # Calculate the net deposition/erosion rate at each node dqsds = mg.calculate_flux_divergence_at_nodes(qs) # Calculate the total rate of elevation change dzdt = uplift_rate - dqsds # Update the elevations z[core_nodes] = z[core_nodes] + dzdt[core_nodes] * dt # FINALIZE import numpy # Test solution for a 1-cell hex grid if mg.number_of_nodes==7: # single cell with 6 boundaries perimeter = dx*6*(numpy.sqrt(3.)/3.) flux = kd*(numpy.amax(z)/dx) total_outflux = perimeter*flux total_influx = mg.cell_areas*uplift_rate # just one cell ... print 'total influx=',total_influx,'total outflux=',total_outflux print('Run time = '+str(time.time()-start_time)+' seconds') # Plot the points, colored by elevation pylab.figure() maxelev = numpy.amax(z) for i in range(mg.number_of_nodes): mycolor = str(z[i]/maxelev) pylab.plot(mg.node_x[i], mg.node_y[i], 'o', color=mycolor, ms=50) pylab.show() mg.display_grid()
def test_hex_mfd(): mg = HexModelGrid(5, 3) mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node") fa = LossyFlowAccumulator(mg, flow_director="MFD") fa.run_one_step()
def main(): # INITIALIZE # User-defined parameters nr = 80 # number of rows in grid nc = 50 # 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 = HexModelGrid(nr, nc, 1.0) # Make the boundaries be walls # mg.set_closed_boundaries_at_grid_edges(True, True, True, True)<--I am not sure what the equivalent is for hexgrid #Create a node-state dictionary ns_dict = { 0 : 'fluid', 1 : 'particle' } #Create the transition list 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 = OrientedHexCTS(mg, ns_dict, xn_list, node_state_grid) # Set up colors for plotting 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 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 simulation time '+str(current_time)+' \ ('+str(int(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() ca_plotter.finalize()
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 = OrientedHexLCA(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',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: node_state_grid[i]=0 # Create the CA model ca = OrientedHexLCA(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',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 = 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()