def test_sp_discharges_new(): input_str = os.path.join(_THIS_DIR, 'test_sp_params_discharge_new.txt') inputs = ModelParameterDictionary(input_str, auto_type=True) nrows = 5 ncols = 5 dx = inputs.read_float('dx') dt = inputs.read_float('dt') mg = RasterModelGrid(nrows, ncols, dx) mg.add_zeros('topographic__elevation', at='node') z = np.array([5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4., 4., 5., 5., 5., 5., 5., 5.]) mg['node']['topographic__elevation'] = z fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, **inputs) # perform the loop (once!) for i in range(1): fr.run_one_step() sp.run_one_step(dt) z_tg = np.array([5. , 5. , 0. , 5. , 5. , 5. , 1.47759225, 0.43050087, 1.47759225, 5. , 5. , 2.32883687, 1.21525044, 2.32883687, 5. , 5. , 3.27261262, 3.07175015, 3.27261262, 5. , 5. , 5. , 5. , 5. , 5. ]) assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
def test_sp_discharges_new(): input_str = os.path.join(_THIS_DIR, 'test_sp_params_discharge_new.txt') inputs = ModelParameterDictionary(input_str, auto_type=True) nrows = 5 ncols = 5 dx = inputs.read_float('dx') dt = inputs.read_float('dt') mg = RasterModelGrid(nrows, ncols, dx) mg.add_zeros('topographic__elevation', at='node') z = np.array([ 5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4., 4., 5., 5., 5., 5., 5., 5. ]) mg['node']['topographic__elevation'] = z fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, **inputs) # perform the loop (once!) for i in range(1): fr.run_one_step() sp.run_one_step(dt) z_tg = np.array([ 5., 5., 0., 5., 5., 5., 1.47759225, 0.43050087, 1.47759225, 5., 5., 2.32883687, 1.21525044, 2.32883687, 5., 5., 3.27261262, 3.07175015, 3.27261262, 5., 5., 5., 5., 5., 5. ]) assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
def __init__(self, input_file=None, params=None, BaselevelHandlerClass=None): """Initialize the BasicVsRt.""" # Call ErosionModel's init super(BasicVsRt, self).__init__(input_file=input_file, params=params, BaselevelHandlerClass=BaselevelHandlerClass) contact_zone__width = (self._length_factor) * self.params[ 'contact_zone__width'] # has units length self.K_rock_sp = self.get_parameter_from_exponent('K_rock_sp') self.K_till_sp = self.get_parameter_from_exponent('K_till_sp') linear_diffusivity = ( self._length_factor** 2.) * self.get_parameter_from_exponent('linear_diffusivity') recharge_rate = (self._length_factor) * self.params[ 'recharge_rate'] # has units length per time soil_thickness = (self._length_factor) * self.params[ 'initial_soil_thickness'] # has units length K_hydraulic_conductivity = (self._length_factor) * self.params[ 'K_hydraulic_conductivity'] # has units length per time # Set up rock-till self.setup_rock_and_till(self.params['rock_till_file__name'], self.K_rock_sp, self.K_till_sp, contact_zone__width) # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method self.flow_router = FlowAccumulator( self.grid, flow_director='D8', depression_finder=DepressionFinderAndRouter) # Add a field for effective drainage area if 'effective_drainage_area' in self.grid.at_node: self.eff_area = self.grid.at_node['effective_drainage_area'] else: self.eff_area = self.grid.add_zeros('node', 'effective_drainage_area') # Get the effective-area parameter self.sat_param = (K_hydraulic_conductivity * soil_thickness * self.grid.dx) / (recharge_rate) # Instantiate a FastscapeEroder component self.eroder = StreamPowerEroder(self.grid, K_sp=self.erody, m_sp=self.params['m_sp'], n_sp=self.params['n_sp'], use_Q=self.eff_area) # Instantiate a LinearDiffuser component self.diffuser = LinearDiffuser(self.grid, linear_diffusivity=linear_diffusivity)
def __init__(self, input_file=None, params=None, BaselevelHandlerClass=None): """Initialize the BasicVs.""" # Call ErosionModel's init super(BasicVs, self).__init__(input_file=input_file, params=params, BaselevelHandlerClass=BaselevelHandlerClass) # Get Parameters: K_sp = self.get_parameter_from_exponent('K_sp', raise_error=False) K_ss = self.get_parameter_from_exponent('K_ss', raise_error=False) linear_diffusivity = (self._length_factor**2.)*self.get_parameter_from_exponent('linear_diffusivity') # has units length^2/time recharge_rate = (self._length_factor)*self.params['recharge_rate'] # has units length per time soil_thickness = (self._length_factor)*self.params['initial_soil_thickness'] # has units length K_hydraulic_conductivity = (self._length_factor)*self.params['K_hydraulic_conductivity'] # has units length per time # check that a stream power and a shear stress parameter have not both been given if K_sp != None and K_ss != None: raise ValueError('A parameter for both K_sp and K_ss has been' 'provided. Only one of these may be provided') elif K_sp != None or K_ss != None: if K_sp != None: self.K = K_sp else: self.K = (self._length_factor**(1./3.))*K_ss # K_ss has units Lengtg^(1/3) per Time else: raise ValueError('A value for K_sp or K_ss must be provided.') # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method self.flow_router = FlowAccumulator(self.grid, flow_director='D8', depression_finder = DepressionFinderAndRouter) # Add a field for effective drainage area if 'effective_drainage_area' in self.grid.at_node: self.eff_area = self.grid.at_node['effective_drainage_area'] else: self.eff_area = self.grid.add_zeros('node', 'effective_drainage_area') # Get the effective-area parameter self.sat_param = (K_hydraulic_conductivity*soil_thickness*self.grid.dx)/(recharge_rate) # Instantiate a FastscapeEroder component self.eroder = StreamPowerEroder(self.grid, use_Q=self.eff_area, K_sp=self.K, m_sp=self.params['m_sp'], n_sp=self.params['n_sp']) # Instantiate a LinearDiffuser component self.diffuser = LinearDiffuser(self.grid, linear_diffusivity = linear_diffusivity)
def test_route_to_multiple_error_raised_run_StreamPowerEroder(): mg = RasterModelGrid((10, 10)) z = mg.add_zeros("node", "topographic__elevation") z += mg.x_of_node + mg.y_of_node sp = StreamPowerEroder(mg) fa = FlowAccumulator(mg, flow_director="MFD") fa.run_one_step() with pytest.raises(NotImplementedError): sp.run_one_step(10)
def test_route_to_multiple_error_raised_run_StreamPowerEroder(): mg = RasterModelGrid((10, 10)) z = mg.add_zeros('node', 'topographic__elevation') z += mg.x_of_node + mg.y_of_node sp = StreamPowerEroder(mg) fa = FlowAccumulator(mg, flow_director='MFD') fa.run_one_step() with pytest.raises(NotImplementedError): sp.run_one_step(10)
def test_sp_voronoi(): nnodes = 100 np.random.seed(0) x = np.random.rand(nnodes) np.random.seed(1) y = np.random.rand(nnodes) mg = VoronoiDelaunayGrid(x, y) np.random.seed(2) z = mg.add_field('node', 'topographic__elevation', np.random.rand(nnodes) / 10000., copy=False) fr = FlowAccumulator(mg) spe = StreamPowerEroder( mg, os.path.join(_THIS_DIR, 'drive_sp_params_voronoi.txt')) for i in range(10): z[mg.core_nodes] += 0.01 fr.run_one_step() spe.erode(mg, 1.) z_tg = np.array([ 4.35994902e-05, 2.59262318e-06, 5.49662478e-05, 6.56738615e-03, 4.20367802e-05, 1.21371424e-02, 2.16596169e-02, 4.73320898e-02, 6.00389761e-02, 5.22007356e-02, 5.37507115e-02, 5.95794752e-02, 5.29862904e-02, 6.76465914e-02, 7.31720024e-02, 6.18730861e-02, 8.53975293e-05, 5.32189275e-02, 7.34302556e-02, 8.07385044e-02, 5.05246090e-05, 4.08940657e-02, 7.39971005e-02, 3.31915602e-02, 6.72650419e-02, 5.96745309e-05, 4.72752445e-02, 3.60359567e-02, 7.59432065e-02, 7.24461985e-02, 7.80305760e-02, 4.93866869e-02, 8.69642467e-02, 7.21627626e-02, 8.96368291e-02, 4.65142080e-02, 6.07720217e-02, 8.83372939e-02, 2.35887558e-02, 7.97616193e-02, 8.35615355e-02, 4.61809032e-02, 6.34634214e-02, 9.25711770e-02, 4.11717225e-03, 7.24493623e-02, 7.97908053e-02, 9.10375623e-02, 9.13155023e-02, 7.10567915e-02, 7.35271752e-02, 6.13091341e-02, 9.45498463e-02, 8.48532386e-02, 8.82702021e-02, 7.14969941e-02, 2.22640943e-02, 8.53311932e-02, 7.49161159e-02, 3.48837223e-02, 9.30132692e-02, 6.01817121e-05, 3.87455443e-02, 8.44673586e-02, 9.35213577e-02, 6.76075824e-02, 1.58614508e-02, 8.51346837e-02, 8.83645680e-02, 8.69944117e-02, 5.04000439e-05, 5.02319084e-02, 8.63882765e-02, 5.00991880e-02, 7.65156630e-02, 5.07591983e-02, 6.54909962e-02, 6.91505342e-02, 7.33358371e-02, 5.30109890e-02, 2.99074601e-02, 2.55509418e-06, 8.21523907e-02, 8.09368483e-02, 4.35073025e-02, 3.04096109e-02, 3.26298627e-02, 4.92259177e-02, 5.48690358e-02, 6.44732130e-02, 6.28133567e-02, 4.17977098e-06, 5.37149677e-02, 4.32828136e-02, 1.30559903e-02, 2.62405261e-02, 2.86079272e-02, 6.61481327e-05, 1.70477133e-05, 8.81652236e-05 ]) assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
def test_sp_new(): """ Tests new style component instantiation and run. """ input_str = os.path.join(_THIS_DIR, 'drive_sp_params.txt') inputs = ModelParameterDictionary(input_str, auto_type=True) nrows = inputs.read_int('nrows') ncols = inputs.read_int('ncols') dx = inputs.read_float('dx') dt = inputs.read_float('dt') time_to_run = inputs.read_float('run_time') uplift = inputs.read_float('uplift_rate') init_elev = inputs.read_float('init_elev') mg = RasterModelGrid((nrows, ncols), spacing=(dx, dx)) mg.set_closed_boundaries_at_grid_edges(False, False, True, True) mg.add_zeros('topographic__elevation', at='node') z = mg.zeros(at='node') + init_elev numpy.random.seed(0) mg['node']['topographic__elevation'] = z + \ numpy.random.rand(len(z)) / 1000. fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, **inputs) elapsed_time = 0. while elapsed_time < time_to_run: if elapsed_time + dt > time_to_run: dt = time_to_run - elapsed_time fr.run_one_step() sp.run_one_step(dt) mg.at_node['topographic__elevation'][mg.core_nodes] += uplift * dt elapsed_time += dt z_trg = numpy.array([ 5.48813504e-04, 7.15189366e-04, 6.02763376e-04, 5.44883183e-04, 4.23654799e-04, 6.45894113e-04, 1.01830760e-02, 9.58036770e-03, 6.55865452e-03, 3.83441519e-04, 7.91725038e-04, 1.00142749e-02, 8.80798884e-03, 5.78387585e-03, 7.10360582e-05, 8.71292997e-05, 9.81911417e-03, 9.52243406e-03, 7.55093226e-03, 8.70012148e-04, 9.78618342e-04, 1.00629755e-02, 8.49253798e-03, 5.33216680e-03, 1.18274426e-04, 6.39921021e-04, 9.88956320e-03, 9.47119567e-03, 6.43790696e-03, 4.14661940e-04, 2.64555612e-04, 1.00450743e-02, 8.37262908e-03, 5.21540904e-03, 1.87898004e-05, 6.17635497e-04, 9.21286940e-03, 9.34022513e-03, 7.51114450e-03, 6.81820299e-04, 3.59507901e-04, 6.19166921e-03, 7.10456176e-03, 6.62585507e-03, 6.66766715e-04, 6.70637870e-04, 2.10382561e-04, 1.28926298e-04, 3.15428351e-04, 3.63710771e-04 ]) assert_array_almost_equal(mg.at_node['topographic__elevation'], z_trg)
def test_storms(): dt = 500.0 uplift = 0.0001 mean_duration = 100.0 mean_interstorm = 400.0 mean_depth = 5.0 storm_run_time = 3000000.0 delta_t = 500.0 mg = RasterModelGrid((10, 10), xy_spacing=1000.0) mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") mg["node"]["topographic__elevation"] = z + np.random.rand(len(z)) / 1000.0 mg.add_zeros("water__unit_flux_in", at="node") precip = PrecipitationDistribution( mean_storm_duration=mean_duration, mean_interstorm_duration=mean_interstorm, mean_storm_depth=mean_depth, total_t=storm_run_time, delta_t=delta_t, ) fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder( mg, K_sp=0.0001, m_sp=0.5, n_sp=1.0, threshold_sp=1.0, discharge_field="surface_water__discharge", ) for ( interval_duration, rainfall_rate, ) in precip.yield_storm_interstorm_duration_intensity(): if rainfall_rate != 0.0: mg.at_node["water__unit_flux_in"].fill(rainfall_rate) fr.run_one_step() sp.run_one_step(dt) mg.at_node["topographic__elevation"][mg.core_nodes] += ( uplift * interval_duration)
def test_route_to_multiple_error_raised_init_StreamPowerEroder(): mg = RasterModelGrid((10, 10)) z = mg.add_zeros("node", "topographic__elevation") z += mg.x_of_node + mg.y_of_node fa = FlowAccumulator(mg, flow_director="MFD") fa.run_one_step() with pytest.raises(NotImplementedError): StreamPowerEroder(mg)
def test_storms(): input_file_string = os.path.join(_THIS_DIR, "drive_sp_params_storms.txt") inputs = ModelParameterDictionary(input_file_string, auto_type=True) nrows = inputs.read_int("nrows") ncols = inputs.read_int("ncols") dx = inputs.read_float("dx") dt = inputs.read_float("dt") uplift = inputs.read_float("uplift_rate") mean_duration = inputs.read_float("mean_storm") mean_interstorm = inputs.read_float("mean_interstorm") mean_depth = inputs.read_float("mean_depth") storm_run_time = inputs.read_float("storm_run_time") delta_t = inputs.read_float("delta_t") mg = RasterModelGrid(nrows, ncols, xy_spacing=dx) mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") mg["node"]["topographic__elevation"] = z + np.random.rand(len(z)) / 1000. mg.add_zeros("water__unit_flux_in", at="node") precip = PrecipitationDistribution( mean_storm_duration=mean_duration, mean_interstorm_duration=mean_interstorm, mean_storm_depth=mean_depth, total_t=storm_run_time, delta_t=delta_t, ) fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, **inputs) for ( interval_duration, rainfall_rate, ) in precip.yield_storm_interstorm_duration_intensity(): if rainfall_rate != 0.: mg.at_node["water__unit_flux_in"].fill(rainfall_rate) fr.run_one_step() sp.run_one_step(dt) mg.at_node["topographic__elevation"][mg.core_nodes] += ( uplift * interval_duration )
def test_storms(): input_file_string = os.path.join(_THIS_DIR, "drive_sp_params_storms.txt") inputs = ModelParameterDictionary(input_file_string, auto_type=True) nrows = inputs.read_int("nrows") ncols = inputs.read_int("ncols") dx = inputs.read_float("dx") dt = inputs.read_float("dt") uplift = inputs.read_float("uplift_rate") mean_duration = inputs.read_float("mean_storm") mean_interstorm = inputs.read_float("mean_interstorm") mean_depth = inputs.read_float("mean_depth") storm_run_time = inputs.read_float("storm_run_time") delta_t = inputs.read_float("delta_t") mg = RasterModelGrid((nrows, ncols), xy_spacing=dx) mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") mg["node"]["topographic__elevation"] = z + np.random.rand(len(z)) / 1000.0 mg.add_zeros("water__unit_flux_in", at="node") precip = PrecipitationDistribution( mean_storm_duration=mean_duration, mean_interstorm_duration=mean_interstorm, mean_storm_depth=mean_depth, total_t=storm_run_time, delta_t=delta_t, ) fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, **inputs) for ( interval_duration, rainfall_rate, ) in precip.yield_storm_interstorm_duration_intensity(): if rainfall_rate != 0.0: mg.at_node["water__unit_flux_in"].fill(rainfall_rate) fr.run_one_step() sp.run_one_step(dt) mg.at_node["topographic__elevation"][mg.core_nodes] += ( uplift * interval_duration)
def test_sp_widths(): input_str = os.path.join(_THIS_DIR, 'test_sp_params_widths.txt') inputs = ModelParameterDictionary(input_str, auto_type=True) nrows = 5 ncols = 5 dx = inputs.read_float('dx') dt = inputs.read_float('dt') mg = RasterModelGrid(nrows, ncols, dx) widths = np.ones(mg.number_of_nodes, dtype=float) mg.add_zeros('topographic__elevation', at='node') z = np.array([5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4., 4., 5., 5., 5., 5., 5., 5.]) mg['node']['topographic__elevation'] = z fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, use_W=widths, **inputs) # perform the loop (once!) for i in range(1): fr.run_one_step() sqrt_A = mg.at_node['drainage_area']**0.5 widths[mg.core_nodes] = sqrt_A[mg.core_nodes]/sqrt_A[ mg.core_nodes].mean() # so widths has mean=1. # note the issue with drainage_area not defined at perimeter => nans # if not careful... sp.run_one_step(dt) z_tg = np.array([ 5. , 5. , 0. , 5. , 5. , 5. , 1.37222369, 0.36876358, 1.37222369, 5. , 5. , 2.17408606, 1.07986038, 2.17408606, 5. , 5. , 3.08340277, 2.85288049, 3.08340277, 5. , 5. , 5. , 5. , 5. , 5. ]) assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
def test_storms(): input_file_string = os.path.join(_THIS_DIR, 'drive_sp_params_storms.txt') inputs = ModelParameterDictionary(input_file_string, auto_type=True) nrows = inputs.read_int('nrows') ncols = inputs.read_int('ncols') dx = inputs.read_float('dx') dt = inputs.read_float('dt') time_to_run = inputs.read_float('run_time') uplift = inputs.read_float('uplift_rate') mean_duration = inputs.read_float('mean_storm') mean_interstorm = inputs.read_float('mean_interstorm') mean_depth = inputs.read_float('mean_depth') storm_run_time = inputs.read_float('storm_run_time') delta_t = inputs.read_float('delta_t') mg = RasterModelGrid(nrows, ncols, dx) mg.add_zeros('topographic__elevation', at='node') z = mg.zeros(at='node') mg['node']['topographic__elevation'] = z + np.random.rand(len(z)) / 1000. mg.add_zeros('water__unit_flux_in', at='node') precip = PrecipitationDistribution( mean_storm_duration=mean_duration, mean_interstorm_duration=mean_interstorm, mean_storm_depth=mean_depth, total_t=storm_run_time, delta_t=delta_t) fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, **inputs) for (interval_duration, rainfall_rate) in \ precip.yield_storm_interstorm_duration_intensity(): if rainfall_rate != 0.: mg.at_node['water__unit_flux_in'].fill(rainfall_rate) fr.run_one_step() sp.run_one_step(dt) mg.at_node['topographic__elevation'][ mg.core_nodes] += uplift * interval_duration
def test_sp_widths(): input_str = os.path.join(_THIS_DIR, 'test_sp_params_widths.txt') inputs = ModelParameterDictionary(input_str, auto_type=True) nrows = 5 ncols = 5 dx = inputs.read_float('dx') dt = inputs.read_float('dt') mg = RasterModelGrid(nrows, ncols, dx) widths = np.ones(mg.number_of_nodes, dtype=float) mg.add_zeros('topographic__elevation', at='node') z = np.array([ 5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4., 4., 5., 5., 5., 5., 5., 5. ]) mg['node']['topographic__elevation'] = z fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, use_W=widths, **inputs) # perform the loop (once!) for i in range(1): fr.run_one_step() sqrt_A = mg.at_node['drainage_area']**0.5 widths[mg.core_nodes] = sqrt_A[mg.core_nodes] / sqrt_A[ mg.core_nodes].mean() # so widths has mean=1. # note the issue with drainage_area not defined at perimeter => nans # if not careful... sp.run_one_step(dt) z_tg = np.array([ 5., 5., 0., 5., 5., 5., 1.37222369, 0.36876358, 1.37222369, 5., 5., 2.17408606, 1.07986038, 2.17408606, 5., 5., 3.08340277, 2.85288049, 3.08340277, 5., 5., 5., 5., 5., 5. ]) assert_array_almost_equal(mg.at_node['topographic__elevation'], z_tg)
def test_storms(): input_file_string = os.path.join(_THIS_DIR, 'drive_sp_params_storms.txt') inputs = ModelParameterDictionary(input_file_string, auto_type=True) nrows = inputs.read_int('nrows') ncols = inputs.read_int('ncols') dx = inputs.read_float('dx') dt = inputs.read_float('dt') time_to_run = inputs.read_float('run_time') uplift = inputs.read_float('uplift_rate') mean_duration = inputs.read_float('mean_storm') mean_interstorm = inputs.read_float('mean_interstorm') mean_depth = inputs.read_float('mean_depth') storm_run_time = inputs.read_float('storm_run_time') delta_t = inputs.read_float('delta_t') mg = RasterModelGrid(nrows, ncols, dx) mg.add_zeros('topographic__elevation', at='node') z = mg.zeros(at='node') mg['node']['topographic__elevation'] = z + np.random.rand(len(z)) / 1000. mg.add_zeros('water__unit_flux_in', at='node') precip = PrecipitationDistribution(mean_storm_duration = mean_duration, mean_interstorm_duration = mean_interstorm, mean_storm_depth = mean_depth, total_t = storm_run_time, delta_t = delta_t) fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, **inputs) for (interval_duration, rainfall_rate) in \ precip.yield_storm_interstorm_duration_intensity(): if rainfall_rate != 0.: mg.at_node['water__unit_flux_in'].fill(rainfall_rate) fr.run_one_step() sp.run_one_step(dt) mg.at_node['topographic__elevation'][ mg.core_nodes] += uplift * interval_duration
#create the fields in the grid mg.add_zeros('topographic__elevation', at='node') z = mg.zeros(at='node') + init_elev mg['node']['topographic__elevation'] = z + numpy.random.rand(len(z)) / 1000. #make some K values in a field to test mg.at_node['K_values'] = 1.e-6 + numpy.random.rand(nrows * ncols) * 1.e-8 mg.set_closed_boundaries_at_grid_edges(False, True, True, True) print('Running ...') #instantiate the components: fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, './drive_sp_params.txt') fsp = Fsc(mg, './drive_sp_params.txt') #load the Fastscape module too, to allow direct comparison fsp = Fsc(mg, './drive_sp_params.txt') #vid = VideoPlotter(mg, data_centering='node', step=2.5) try: mg = copy.deepcopy(mg_mature) except NameError: #run to a steady state: #We're going to cheat by running Fastscape SP for the first part of the solution elapsed_time = 0. #total time in simulation while elapsed_time < time_to_run: print(elapsed_time) if elapsed_time + dt > time_to_run:
def test_sp_old(): input_str = os.path.join(_THIS_DIR, "drive_sp_params.txt") inputs = ModelParameterDictionary(input_str) nrows = inputs.read_int("nrows") ncols = inputs.read_int("ncols") dx = inputs.read_float("dx") dt = inputs.read_float("dt") time_to_run = inputs.read_float("run_time") uplift = inputs.read_float("uplift_rate") init_elev = inputs.read_float("init_elev") mg = RasterModelGrid((nrows, ncols), xy_spacing=(dx, dx)) mg.set_closed_boundaries_at_grid_edges(False, False, True, True) mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") + init_elev numpy.random.seed(0) mg["node"]["topographic__elevation"] = z + numpy.random.rand( len(z)) / 1000.0 fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, input_str) elapsed_time = 0.0 while elapsed_time < time_to_run: if elapsed_time + dt > time_to_run: dt = time_to_run - elapsed_time fr.run_one_step() sp.erode(mg, dt) mg.at_node["topographic__elevation"][mg.core_nodes] += uplift * dt elapsed_time += dt z_trg = numpy.array([ 5.48813504e-04, 7.15189366e-04, 6.02763376e-04, 5.44883183e-04, 4.23654799e-04, 6.45894113e-04, 1.01830760e-02, 9.58036770e-03, 6.55865452e-03, 3.83441519e-04, 7.91725038e-04, 1.00142749e-02, 8.80798884e-03, 5.78387585e-03, 7.10360582e-05, 8.71292997e-05, 9.81911417e-03, 9.52243406e-03, 7.55093226e-03, 8.70012148e-04, 9.78618342e-04, 1.00629755e-02, 8.49253798e-03, 5.33216680e-03, 1.18274426e-04, 6.39921021e-04, 9.88956320e-03, 9.47119567e-03, 6.43790696e-03, 4.14661940e-04, 2.64555612e-04, 1.00450743e-02, 8.37262908e-03, 5.21540904e-03, 1.87898004e-05, 6.17635497e-04, 9.21286940e-03, 9.34022513e-03, 7.51114450e-03, 6.81820299e-04, 3.59507901e-04, 6.19166921e-03, 7.10456176e-03, 6.62585507e-03, 6.66766715e-04, 6.70637870e-04, 2.10382561e-04, 1.28926298e-04, 3.15428351e-04, 3.63710771e-04, ]) assert_array_almost_equal(mg.at_node["topographic__elevation"], z_trg)
def __init__(self, input_file=None, params=None, BaselevelHandlerClass=None): """Initialize the StochasticDischargeHortonianModel.""" # Call ErosionModel's init super(BasicStVs, self).__init__(input_file=input_file, params=params, BaselevelHandlerClass=BaselevelHandlerClass) # Get Parameters: K_sp = self.get_parameter_from_exponent('K_stochastic_sp') linear_diffusivity = ( self._length_factor**2.) * self.get_parameter_from_exponent( 'linear_diffusivity') # has units length^2/time soil_thickness = (self._length_factor) * self.params[ 'initial_soil_thickness'] # has units length K_hydraulic_conductivity = (self._length_factor) * self.params[ 'K_hydraulic_conductivity'] # has units length per time # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method self.flow_router = FlowAccumulator( self.grid, flow_director='D8', depression_finder=DepressionFinderAndRouter) # instantiate rain generator self.instantiate_rain_generator() # Add a field for discharge if 'surface_water__discharge' not in self.grid.at_node: self.grid.add_zeros('node', 'surface_water__discharge') self.discharge = self.grid.at_node['surface_water__discharge'] # Add a field for subsurface discharge if 'subsurface_water__discharge' not in self.grid.at_node: self.grid.add_zeros('node', 'subsurface_water__discharge') self.qss = self.grid.at_node['subsurface_water__discharge'] # Get the transmissivity parameter # transmissivity is hydraulic condiuctivity times soil thickness self.trans = (K_hydraulic_conductivity * soil_thickness) assert (self.trans > 0.0), 'Transmissivity must be > 0' self.tlam = self.trans * self.grid._dx # assumes raster # Run flow routing and lake filler self.flow_router.run_one_step() # Keep a reference to drainage area and steepest-descent slope self.area = self.grid.at_node['drainage_area'] self.slope = self.grid.at_node['topographic__steepest_slope'] # Instantiate a FastscapeEroder component self.eroder = StreamPowerEroder(self.grid, use_Q=self.discharge, K_sp=K_sp, m_sp=self.params['m_sp'], n_sp=self.params['n_sp']) # Instantiate a LinearDiffuser component self.diffuser = LinearDiffuser(self.grid, linear_diffusivity=linear_diffusivity)
class BasicRtVs(ErosionModel): """ A BasicVsRt computes erosion using linear diffusion, basic stream power with 2 lithologies, and Q ~ A exp( -b S / A). """ def __init__(self, input_file=None, params=None, BaselevelHandlerClass=None): """Initialize the BasicVsRt.""" # Call ErosionModel's init super(BasicVsRt, self).__init__(input_file=input_file, params=params, BaselevelHandlerClass=BaselevelHandlerClass) contact_zone__width = (self._length_factor) * self.params[ 'contact_zone__width'] # has units length self.K_rock_sp = self.get_parameter_from_exponent('K_rock_sp') self.K_till_sp = self.get_parameter_from_exponent('K_till_sp') linear_diffusivity = ( self._length_factor** 2.) * self.get_parameter_from_exponent('linear_diffusivity') recharge_rate = (self._length_factor) * self.params[ 'recharge_rate'] # has units length per time soil_thickness = (self._length_factor) * self.params[ 'initial_soil_thickness'] # has units length K_hydraulic_conductivity = (self._length_factor) * self.params[ 'K_hydraulic_conductivity'] # has units length per time # Set up rock-till self.setup_rock_and_till(self.params['rock_till_file__name'], self.K_rock_sp, self.K_till_sp, contact_zone__width) # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method self.flow_router = FlowAccumulator( self.grid, flow_director='D8', depression_finder=DepressionFinderAndRouter) # Add a field for effective drainage area if 'effective_drainage_area' in self.grid.at_node: self.eff_area = self.grid.at_node['effective_drainage_area'] else: self.eff_area = self.grid.add_zeros('node', 'effective_drainage_area') # Get the effective-area parameter self.sat_param = (K_hydraulic_conductivity * soil_thickness * self.grid.dx) / (recharge_rate) # Instantiate a FastscapeEroder component self.eroder = StreamPowerEroder(self.grid, K_sp=self.erody, m_sp=self.params['m_sp'], n_sp=self.params['n_sp'], use_Q=self.eff_area) # Instantiate a LinearDiffuser component self.diffuser = LinearDiffuser(self.grid, linear_diffusivity=linear_diffusivity) def calc_effective_drainage_area(self): """Calculate and store effective drainage area. Effective drainage area is defined as: $A_{eff} = A \exp ( \alpha S / A) = A R_r$ where $S$ is downslope-positive steepest gradient, $A$ is drainage area, $R_r$ is the runoff ratio, and $\alpha$ is the saturation parameter. """ area = self.grid.at_node['drainage_area'] slope = self.grid.at_node['topographic__steepest_slope'] cores = self.grid.core_nodes self.eff_area[cores] = ( area[cores] * (np.exp(-self.sat_param * slope[cores] / area[cores]))) def setup_rock_and_till(self, file_name, rock_erody, till_erody, contact_width): """Set up lithology handling for two layers with different erodibility. Parameters ---------- file_name : string Name of arc-ascii format file containing elevation of contact position at each grid node (or NODATA) Read elevation of rock-till contact from an esri-ascii format file containing the basal elevation value at each node, create a field for erodibility. Some considerations here: 1. We could represent the contact between two layers either as a depth below present land surface, or as an altitude. Using a depth would allow for vertical motion, because for a fixed surface, the depth remains constant while the altitude changes. But the depth must be updated every time the surface is eroded or aggrades. Using an altitude avoids having to update the contact position every time the surface erodes or aggrades, but any tectonic motion would need to be applied to the contact position as well. Here we'll use the altitude approach because this model was originally written for an application with lots of erosion expected but no tectonics. """ from landlab.io import read_esri_ascii # Read input data on rock-till contact elevation read_esri_ascii(file_name, grid=self.grid, name='rock_till_contact__elevation', halo=1) # Get a reference to the rock-till field self.rock_till_contact = self.grid.at_node[ 'rock_till_contact__elevation'] # Create field for erodibility if 'substrate__erodibility' in self.grid.at_node: self.erody = self.grid.at_node['substrate__erodibility'] else: self.erody = self.grid.add_zeros('node', 'substrate__erodibility') # Create array for erodibility weighting function self.erody_wt = np.zeros(self.grid.number_of_nodes) # Read the erodibility value of rock and till self.rock_erody = rock_erody self.till_erody = till_erody # Read and remember the contact zone characteristic width self.contact_width = contact_width def update_erodibility_field(self): """Update erodibility at each node based on elevation relative to contact elevation. To promote smoothness in the solution, the erodibility at a given point (x,y) is set as follows: 1. Take the difference between elevation, z(x,y), and contact elevation, b(x,y): D(x,y) = z(x,y) - b(x,y). This number could be positive (if land surface is above the contact), negative (if we're well within the rock), or zero (meaning the rock-till contact is right at the surface). 2. Define a smoothing function as: $F(D) = 1 / (1 + exp(-D/D*))$ This sigmoidal function has the property that F(0) = 0.5, F(D >> D*) = 1, and F(-D << -D*) = 0. Here, D* describes the characteristic width of the "contact zone", where the effective erodibility is a mixture of the two. If the surface is well above this contact zone, then F = 1. If it's well below the contact zone, then F = 0. 3. Set the erodibility using F: $K = F K_till + (1-F) K_rock$ So, as F => 1, K => K_till, and as F => 0, K => K_rock. In between, we have a weighted average. Translating these symbols into variable names: z = self.elev b = self.rock_till_contact D* = self.contact_width F = self.erody_wt K_till = self.till_erody K_rock = self.rock_erody """ # Update the erodibility weighting function (this is "F") core = self.grid.core_nodes if self.contact_width > 0.0: self.erody_wt[core] = ( 1.0 / (1.0 + np.exp(-(self.z[core] - self.rock_till_contact[core]) / self.contact_width))) else: self.erody_wt[core] = 0.0 self.erody_wt[np.where(self.z > self.rock_till_contact)[0]] = 1.0 # (if we're varying K through time, update that first) if self.opt_var_precip: erode_factor = self.pc.get_erodibility_adjustment_factor( self.model_time) self.till_erody = self.K_till_sp * erode_factor self.rock_erody = self.K_rock_sp * erode_factor # Calculate the effective erodibilities using weighted averaging self.erody[:] = (self.erody_wt * self.till_erody + (1.0 - self.erody_wt) * self.rock_erody) def run_one_step(self, dt): """ Advance model for one time-step of duration dt. """ # Route flow self.flow_router.run_one_step() # Update effective runoff ratio self.calc_effective_drainage_area() # Zero out effective area in flooded nodes self.eff_area[self.flow_router.depression_finder.flood_status == 3] = 0.0 # Update the erodibility field self.update_erodibility_field() # Do some erosion (but not on the flooded nodes) self.eroder.run_one_step(dt) # Do some soil creep self.diffuser.run_one_step(dt) # calculate model time self.model_time += dt # Lower outlet self.update_outlet(dt) # Check walltime self.check_walltime()
def test_sp_discharges_new(): dt = 1.0 mg = RasterModelGrid((5, 5)) mg.add_zeros("topographic__elevation", at="node") z = np.array([ 5.0, 5.0, 0.0, 5.0, 5.0, 5.0, 2.0, 1.0, 2.0, 5.0, 5.0, 3.0, 2.0, 3.0, 5.0, 5.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, ]) mg["node"]["topographic__elevation"] = z fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, K_sp=0.5, m_sp=0.5, n_sp=1.0, threshold_sp=0.0) # perform the loop (once!) for i in range(1): fr.run_one_step() sp.run_one_step(dt) z_tg = np.array([ 5.0, 5.0, 0.0, 5.0, 5.0, 5.0, 1.47759225, 0.43050087, 1.47759225, 5.0, 5.0, 2.32883687, 1.21525044, 2.32883687, 5.0, 5.0, 3.27261262, 3.07175015, 3.27261262, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, ]) assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
# create the fields in the grid mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") + init_elev mg["node"]["topographic__elevation"] = z + numpy.random.rand(len(z)) / 1000. # make some K values in a field to test mg.at_node["K_values"] = 1.e-6 + numpy.random.rand(nrows * ncols) * 1.e-8 mg.set_closed_boundaries_at_grid_edges(False, True, True, True) print("Running ...") # instantiate the components: fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, "./drive_sp_params.txt") fsp = Fsc(mg, "./drive_sp_params.txt") # load the Fastscape module too, to allow direct comparison fsp = Fsc(mg, "./drive_sp_params.txt") # vid = VideoPlotter(mg, data_centering='node', step=2.5) try: mg = copy.deepcopy(mg_mature) except NameError: # run to a steady state: # We're going to cheat by running Fastscape SP for the first part of the solution elapsed_time = 0. # total time in simulation while elapsed_time < time_to_run: print(elapsed_time) if elapsed_time + dt > time_to_run:
import numpy as np from matplotlib.pyplot import show from six.moves import range from landlab import VoronoiDelaunayGrid from landlab.components import FlowAccumulator, StreamPowerEroder from landlab.plot.imshow import imshow_node_grid nnodes = 10000 x, y = np.random.rand(nnodes), np.random.rand(nnodes) mg = VoronoiDelaunayGrid(x, y) z = mg.add_field("node", "topographic__elevation", np.random.rand(nnodes) / 10000., copy=False) fr = FlowAccumulator(mg) spe = StreamPowerEroder(mg, "drive_sp_params_voronoi.txt") for i in range(100): z[mg.core_nodes] += 0.01 fr.run_one_step() spe.erode(mg, 1.) imshow_node_grid(mg, "topographic__elevation") show()
mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") + init_elev mg["node"]["topographic__elevation"] = z + numpy.random.rand(len(z)) / 1000. mg.add_zeros("node", "water__unit_flux_in") # make some K values in a field to test # mg.at_node['K_values'] = 0.1+numpy.random.rand(nrows*ncols)/10. mg.at_node["K_values"] = numpy.empty(nrows * ncols, dtype=float) # mg.at_node['K_values'].fill(0.1+numpy.random.rand()/10.) mg.at_node["K_values"].fill(0.001) print("Running ...") # instantiate the components: fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, input_file_string) # fsp = FastscapeEroder(mg, input_file_string) precip = PrecipitationDistribution(input_file=input_file_string) # load the Fastscape module too, to allow direct comparison fsp = FastscapeEroder(mg, input_file_string) try: # raise NameError mg = copy.deepcopy(mg_mature) except NameError: print("building a new grid...") out_interval = 50000. last_trunc = time_to_run # we use this to trigger taking an output plot # run to a steady state: # We're going to cheat by running Fastscape SP for the first part of the solution
def test_sp_discharges_old(): input_str = os.path.join(_THIS_DIR, "test_sp_params_discharge.txt") inputs = ModelParameterDictionary(input_str) nrows = 5 ncols = 5 dx = inputs.read_float("dx") dt = inputs.read_float("dt") mg = RasterModelGrid(nrows, ncols, xy_spacing=dx) mg.add_zeros("topographic__elevation", at="node") z = np.array( [ 5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4., 4., 5., 5., 5., 5., 5., 5., ] ) mg["node"]["topographic__elevation"] = z fr = FlowAccumulator(mg, flow_director="D8") my_Q = mg.at_node["surface_water__discharge"] sp = StreamPowerEroder(mg, input_str, use_Q=my_Q) # perform the loop (once!) for i in range(1): fr.run_one_step() my_Q[:] = mg.at_node["surface_water__discharge"] * 1. sp.run_one_step(dt) z_tg = np.array( [ 5., 5., 0., 5., 5., 5., 1.47759225, 0.43050087, 1.47759225, 5., 5., 2.32883687, 1.21525044, 2.32883687, 5., 5., 3.27261262, 3.07175015, 3.27261262, 5., 5., 5., 5., 5., 5., ] ) assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
# create the field z = mg.add_zeros("topographic__elevation", at="node") z += leftmost_elev z += initial_slope * np.amax(mg.node_y) - initial_slope * mg.node_y # put these values plus roughness into that field z += np.random.rand(len(z)) / 100000. mg.status_at_node[mg.nodes_at_left_edge] = CLOSED_BOUNDARY mg.status_at_node[mg.nodes_at_right_edge] = CLOSED_BOUNDARY fr = FlowAccumulator(mg, flow_director="D8") if DL_or_TL == "TL": tle = TransportLimitedEroder(mg, input_file) else: spe = StreamPowerEroder(mg, input_file) for i in range(nt): # print 'loop ', i mg.at_node["topographic__elevation"][mg.core_nodes] += uplift_per_step mg = fr.route_flow(grid=mg) if DL_or_TL == "TL": mg, _ = tle.erode(mg, dt) else: mg, _, _ = spe.erode(mg, dt=dt) if i % init_interval == 0: print("loop {0}".format(i)) print( "max_slope", np.amax(mg.at_node["topographic__steepest_slope"][mg.core_nodes]), )
def test_sp_voronoi(): nnodes = 100 np.random.seed(0) x = np.random.rand(nnodes) np.random.seed(1) y = np.random.rand(nnodes) mg = VoronoiDelaunayGrid(x, y) np.random.seed(2) z = mg.add_field( "node", "topographic__elevation", np.random.rand(nnodes) / 10000.0, copy=False ) fr = FlowAccumulator(mg) spe = StreamPowerEroder(mg, os.path.join(_THIS_DIR, "drive_sp_params_voronoi.txt")) for i in range(10): z[mg.core_nodes] += 0.01 fr.run_one_step() spe.erode(mg, 1.0) z_tg = np.array( [ 4.35994902e-05, 2.59262318e-06, 5.49662478e-05, 6.56738615e-03, 4.20367802e-05, 1.21371424e-02, 2.16596169e-02, 4.73320898e-02, 6.00389761e-02, 5.22007356e-02, 5.37507115e-02, 5.95794752e-02, 5.29862904e-02, 6.76465914e-02, 7.31720024e-02, 6.18730861e-02, 8.53975293e-05, 5.32189275e-02, 7.34302556e-02, 8.07385044e-02, 5.05246090e-05, 4.08940657e-02, 7.39971005e-02, 3.31915602e-02, 6.72650419e-02, 5.96745309e-05, 4.72752445e-02, 3.60359567e-02, 7.59432065e-02, 7.24461985e-02, 7.80305760e-02, 4.93866869e-02, 8.69642467e-02, 7.21627626e-02, 8.96368291e-02, 4.65142080e-02, 6.07720217e-02, 8.83372939e-02, 2.35887558e-02, 7.97616193e-02, 8.35615355e-02, 4.61809032e-02, 6.34634214e-02, 9.25711770e-02, 4.11717225e-03, 7.24493623e-02, 7.97908053e-02, 9.10375623e-02, 9.13155023e-02, 7.10567915e-02, 7.35271752e-02, 6.13091341e-02, 9.45498463e-02, 8.48532386e-02, 8.82702021e-02, 7.14969941e-02, 2.22640943e-02, 8.53311932e-02, 7.49161159e-02, 3.48837223e-02, 9.30132692e-02, 6.01817121e-05, 3.87455443e-02, 8.44673586e-02, 9.35213577e-02, 6.76075824e-02, 1.58614508e-02, 8.51346837e-02, 8.83645680e-02, 8.69944117e-02, 5.04000439e-05, 5.02319084e-02, 8.63882765e-02, 5.00991880e-02, 7.65156630e-02, 5.07591983e-02, 6.54909962e-02, 6.91505342e-02, 7.33358371e-02, 5.30109890e-02, 2.99074601e-02, 2.55509418e-06, 8.21523907e-02, 8.09368483e-02, 4.35073025e-02, 3.04096109e-02, 3.26298627e-02, 4.92259177e-02, 5.48690358e-02, 6.44732130e-02, 6.28133567e-02, 4.17977098e-06, 5.37149677e-02, 4.32828136e-02, 1.30559903e-02, 2.62405261e-02, 2.86079272e-02, 6.61481327e-05, 1.70477133e-05, 8.81652236e-05, ] ) assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
#create the fields in the grid mg.add_zeros('topographic__elevation', at='node') z = mg.zeros(at='node') + init_elev mg['node'][ 'topographic__elevation'] = z + numpy.random.rand(len(z))/1000. #make some K values in a field to test mg.at_node['K_values'] = 0.1+numpy.random.rand(nrows*ncols)/10. mg.set_closed_boundaries_at_grid_edges(False, True, True, True) print( 'Running ...' ) time_on = time.time() #instantiate the components: fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, './drive_sp_params.txt') #load the Fastscape module too, to allow direct comparison fsp = FastscapeEroder(mg, './drive_sp_params.txt') #perform the loop: elapsed_time = 0. #total time in simulation counter = 0. while elapsed_time < time_to_run: print(elapsed_time) if elapsed_time+dt>time_to_run: print("Short step!") dt = time_to_run - elapsed_time mg = fr.route_flow(method='D8') #print 'Area: ', numpy.max(mg.at_node['drainage_area']) #mg = fsp.erode(mg) mg,_,_ = sp.erode(mg, dt, node_drainage_areas='drainage_area', slopes_at_nodes='topographic__steepest_slope', K_if_used='K_values')
mg = RasterModelGrid(nrows, ncols, dx) # create the fields in the grid mg.add_zeros('topographic__elevation', at='node') z = np.array([ 5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4., 4., 5., 5., 5., 5., 5., 5. ]) mg['node']['topographic__elevation'] = z print('Running ...') # instantiate the components: fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, './drive_sp_params_discharge.txt') # load the Fastscape module too, to allow direct comparison fsp = Fsc(mg, './drive_sp_params_discharge.txt') # perform the loop (once!) for i in range(1): fr.route_flow(method='D8') my_Q = mg.at_node['surface_water__discharge'] * 1. sp.erode(mg, dt, node_drainage_areas='drainage_area', slopes_at_nodes='topographic__steepest_slope', Q_if_used=my_Q) # no uplift # print the stream power that was calculated:
m = 0.3 n = 0.7 k_tau = 8.357150818380437e-15 tc0 = (k_tau * (0.)**a) tc1 = (k_tau * (10.)**a) tc5 = (k_tau * (25.)**a) tc10 = (k_tau * (50.)**a) fr = FlowRouter(rmg, method='D4') fr1 = FlowRouter(rmg1, method='D4') fr5 = FlowRouter(rmg5, method='D4') fr10 = FlowRouter(rmg10, method='D4') dle = StreamPowerEroder(rmg, K_sp=(1e-10), threshold_sp=float(tc0), use_Q='water__discharge', m_sp=m, n_sp=n) #(3.4e-11) dle1 = StreamPowerEroder(rmg1, K_sp=(1e-10), threshold_sp=float(tc1), use_Q='water__discharge', m_sp=m, n_sp=n) #(3.4e-11) dle5 = StreamPowerEroder(rmg5, K_sp=(1e-10), threshold_sp=float(tc5), use_Q='water__discharge', m_sp=m, n_sp=n) #(3.4e-11) dle10 = StreamPowerEroder(rmg10,
import numpy as np from matplotlib.pyplot import show from six.moves import range from landlab import VoronoiDelaunayGrid from landlab.components import FlowAccumulator, StreamPowerEroder from landlab.plot.imshow import imshow_grid nnodes = 10000 x, y = np.random.rand(nnodes), np.random.rand(nnodes) mg = VoronoiDelaunayGrid(x, y) z = mg.add_field( "node", "topographic__elevation", np.random.rand(nnodes) / 10000., copy=False ) fr = FlowAccumulator(mg) spe = StreamPowerEroder(mg, "drive_sp_params_voronoi.txt") for i in range(100): z[mg.core_nodes] += 0.01 fr.run_one_step() spe.erode(mg, 1.) imshow_grid(mg, "topographic__elevation") show()
mg = RasterModelGrid(nrows, ncols, dx) # create the fields in the grid mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") + init_elev mg["node"]["topographic__elevation"] = z + numpy.random.rand(len(z)) / 1000. # make some K values in a field to test mg.at_node["K_values"] = 0.1 + numpy.random.rand(nrows * ncols) / 10. print("Running ...") # instantiate the components: fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, "./drive_sp_params.txt") # load the Fastscape module too, to allow direct comparison fsp = FastscapeEroder(mg, "./drive_sp_params.txt") # perform the loop: elapsed_time = 0. # total time in simulation while elapsed_time < time_to_run: print(elapsed_time) if elapsed_time + dt > time_to_run: print("Short step!") dt = time_to_run - elapsed_time mg = fr.run_one_step() # print 'Area: ', numpy.max(mg.at_node['drainage_area']) # mg = fsp.erode(mg) mg = fsp.erode(mg, K_if_used="K_values") # mg,_,_ = sp.erode(mg, dt, node_drainage_areas='drainage_area', slopes_at_nodes='topographic__steepest_slope')
mg.add_zeros('topographic__elevation', at='node') z = mg.zeros(at='node') + init_elev mg['node'][ 'topographic__elevation'] = z + numpy.random.rand(len(z))/1000. mg.add_zeros('node', 'water__unit_flux_in') #make some K values in a field to test #mg.at_node['K_values'] = 0.1+numpy.random.rand(nrows*ncols)/10. mg.at_node['K_values'] = numpy.empty(nrows*ncols, dtype=float) #mg.at_node['K_values'].fill(0.1+numpy.random.rand()/10.) mg.at_node['K_values'].fill(0.001) print( 'Running ...' ) #instantiate the components: fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, input_file_string) #fsp = FastscapeEroder(mg, input_file_string) precip = PrecipitationDistribution(input_file=input_file_string) #load the Fastscape module too, to allow direct comparison fsp = FastscapeEroder(mg, input_file_string) try: #raise NameError mg = copy.deepcopy(mg_mature) except NameError: print('building a new grid...') out_interval = 50000. last_trunc = time_to_run #we use this to trigger taking an output plot #run to a steady state: #We're going to cheat by running Fastscape SP for the first part of the solution
# create the fields in the grid mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") + init_elev mg["node"]["topographic__elevation"] = z + numpy.random.rand(len(z)) / 1000. # make some K values in a field to test mg.at_node["K_values"] = 0.1 + numpy.random.rand(nrows * ncols) / 10. mg.set_closed_boundaries_at_grid_edges(False, True, True, True) print("Running ...") time_on = time.time() # instantiate the components: fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, "./drive_sp_params.txt") # load the Fastscape module too, to allow direct comparison fsp = FastscapeEroder(mg, "./drive_sp_params.txt") # perform the loop: elapsed_time = 0. # total time in simulation counter = 0. while elapsed_time < time_to_run: print(elapsed_time) if elapsed_time + dt > time_to_run: print("Short step!") dt = time_to_run - elapsed_time mg = fr.route_flow(method="D8") # print 'Area: ', numpy.max(mg.at_node['drainage_area']) # mg = fsp.erode(mg) mg, _, _ = sp.erode(
4., 5., 5., 5., 5., 5., 5., ] ) mg["node"]["topographic__elevation"] = z print("Running ...") # instantiate the components: fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, "./drive_sp_params_discharge.txt") # load the Fastscape module too, to allow direct comparison fsp = Fsc(mg, "./drive_sp_params_discharge.txt") # perform the loop (once!) for i in range(1): fr.route_flow(method="D8") my_Q = mg.at_node["surface_water__discharge"] * 1. sp.erode( mg, dt, node_drainage_areas="drainage_area", slopes_at_nodes="topographic__steepest_slope", Q_if_used=my_Q, ) # no uplift
def test_sp_discharges_old(): input_str = os.path.join(_THIS_DIR, "test_sp_params_discharge.txt") inputs = ModelParameterDictionary(input_str) nrows = 5 ncols = 5 dx = inputs.read_float("dx") dt = inputs.read_float("dt") mg = RasterModelGrid(nrows, ncols, dx) mg.add_zeros("topographic__elevation", at="node") z = np.array([ 5., 5., 0., 5., 5., 5., 2., 1., 2., 5., 5., 3., 2., 3., 5., 5., 4., 4., 4., 5., 5., 5., 5., 5., 5., ]) mg["node"]["topographic__elevation"] = z fr = FlowAccumulator(mg, flow_director="D8") my_Q = mg.at_node["surface_water__discharge"] sp = StreamPowerEroder(mg, input_str, use_Q=my_Q) # perform the loop (once!) for i in range(1): fr.run_one_step() my_Q[:] = mg.at_node["surface_water__discharge"] * 1. sp.run_one_step(dt) z_tg = np.array([ 5., 5., 0., 5., 5., 5., 1.47759225, 0.43050087, 1.47759225, 5., 5., 2.32883687, 1.21525044, 2.32883687, 5., 5., 3.27261262, 3.07175015, 3.27261262, 5., 5., 5., 5., 5., 5., ]) assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
def __init__(self, input_file=None, params=None, BaselevelHandlerClass=None): """Initialize the BasicVsSa.""" # Call ErosionModel's init super(BasicVsSa, self).__init__(input_file=input_file, params=params, BaselevelHandlerClass=BaselevelHandlerClass) # Get Parameters and convert units if necessary: self.K_sp = self.get_parameter_from_exponent('K_sp') linear_diffusivity = (self._length_factor**2.)*self.get_parameter_from_exponent('linear_diffusivity') # has units length^2/time try: initial_soil_thickness = (self._length_factor)*self.params['initial_soil_thickness'] # has units length except KeyError: initial_soil_thickness = 1.0 # default value soil_transport_decay_depth = (self._length_factor)*self.params['soil_transport_decay_depth'] # has units length max_soil_production_rate = (self._length_factor)*self.params['max_soil_production_rate'] # has units length per time soil_production_decay_depth = (self._length_factor)*self.params['soil_production_decay_depth'] # has units length recharge_rate = (self._length_factor)*self.params['recharge_rate'] # has units length per time K_hydraulic_conductivity = (self._length_factor)*self.params['K_hydraulic_conductivity'] # has units length per time # Create soil thickness (a.k.a. depth) field if 'soil__depth' in self.grid.at_node: soil_thickness = self.grid.at_node['soil__depth'] else: soil_thickness = self.grid.add_zeros('node', 'soil__depth') # Create bedrock elevation field if 'bedrock__elevation' in self.grid.at_node: bedrock_elev = self.grid.at_node['bedrock__elevation'] else: bedrock_elev = self.grid.add_zeros('node', 'bedrock__elevation') soil_thickness[:] = initial_soil_thickness bedrock_elev[:] = self.z - initial_soil_thickness # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method self.flow_router = FlowAccumulator(self.grid, flow_director='D8', depression_finder = DepressionFinderAndRouter) # Add a field for effective drainage area if 'effective_drainage_area' in self.grid.at_node: self.eff_area = self.grid.at_node['effective_drainage_area'] else: self.eff_area = self.grid.add_zeros('node', 'effective_drainage_area') # Get the effective-length parameter self.sat_len = (K_hydraulic_conductivity*self.grid.dx)/(recharge_rate) # Instantiate a FastscapeEroder component self.eroder = StreamPowerEroder(self.grid, use_Q=self.eff_area, K_sp=self.K_sp, m_sp=self.params['m_sp'], n_sp=self.params['n_sp']) # Instantiate a DepthDependentDiffuser component self.diffuser = DepthDependentDiffuser(self.grid, linear_diffusivity=linear_diffusivity, soil_transport_decay_depth=soil_transport_decay_depth) self.weatherer = ExponentialWeatherer(self.grid, max_soil_production_rate=max_soil_production_rate, soil_production_decay_depth=soil_production_decay_depth)
def test_sp_discharges_new(): input_str = os.path.join(_THIS_DIR, "test_sp_params_discharge_new.txt") inputs = ModelParameterDictionary(input_str, auto_type=True) nrows = 5 ncols = 5 dx = inputs.read_float("dx") dt = inputs.read_float("dt") mg = RasterModelGrid((nrows, ncols), xy_spacing=dx) mg.add_zeros("topographic__elevation", at="node") z = np.array( [ 5.0, 5.0, 0.0, 5.0, 5.0, 5.0, 2.0, 1.0, 2.0, 5.0, 5.0, 3.0, 2.0, 3.0, 5.0, 5.0, 4.0, 4.0, 4.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, ] ) mg["node"]["topographic__elevation"] = z fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, **inputs) # perform the loop (once!) for i in range(1): fr.run_one_step() sp.run_one_step(dt) z_tg = np.array( [ 5.0, 5.0, 0.0, 5.0, 5.0, 5.0, 1.47759225, 0.43050087, 1.47759225, 5.0, 5.0, 2.32883687, 1.21525044, 2.32883687, 5.0, 5.0, 3.27261262, 3.07175015, 3.27261262, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, ] ) assert_array_almost_equal(mg.at_node["topographic__elevation"], z_tg)
#create the fields in the grid mg.add_zeros('topographic__elevation', at='node') z = mg.zeros(at='node') + init_elev mg['node']['topographic__elevation'] = z + numpy.random.rand(len(z)) / 1000. #make some K values in a field to test mg.at_node['K_values'] = 0.1 + numpy.random.rand(nrows * ncols) / 10. mg.set_closed_boundaries_at_grid_edges(False, True, True, True) print('Running ...') time_on = time.time() #instantiate the components: fr = FlowAccumulator(mg, flow_director='D8') sp = StreamPowerEroder(mg, './drive_sp_params.txt') #load the Fastscape module too, to allow direct comparison fsp = FastscapeEroder(mg, './drive_sp_params.txt') #perform the loop: elapsed_time = 0. #total time in simulation counter = 0. while elapsed_time < time_to_run: print(elapsed_time) if elapsed_time + dt > time_to_run: print("Short step!") dt = time_to_run - elapsed_time mg = fr.route_flow(method='D8') #print 'Area: ', numpy.max(mg.at_node['drainage_area']) #mg = fsp.erode(mg) mg, _, _ = sp.erode(mg,
gridlist = [] # add initial noise to produce convergent flow from the initial conditions np.random.seed(91) # so our figures are reproducible mg_noise = np.random.rand(mg.number_of_nodes)/1000. # set up the input fields zr = mg.add_zeros('node', 'topographic__elevation') zr += mg_noise # Landlab sets fixed elevation boundary conditions by default. This is # what we want, so we will not modify these here. # instantiate the components: frr = FlowRouter(mg) # water__unit_flux_in gets automatically ingested spr = StreamPowerEroder(mg, K_sp=K_sp, m_sp=m_sp, n_sp=n_sp, threshold_sp=0, use_Q=None) lake = DepressionFinderAndRouter(mg) # Hillslopes dfn = LinearDiffuser(mg, linear_diffusivity=K_hs) zr_last = -9999 keep_running = np.mean(np.abs(zr - zr_last)) >= end_thresh ti = 0 while keep_running: zr_last = zr.copy() zr[mg.core_nodes] += uplift_rate*dt dfn.run_one_step(dt) # hillslopes always diffusive, even when dry frr.run_one_step() lake.map_depressions() spr.run_one_step(dt, flooded_nodes=lake.lake_at_node)
class BasicVsSa(_ErosionModel): """ A BasicVsSa computes erosion using depth-dependent linear diffusion, basic stream power, and Q ~ A exp( -c H S / A); H = soil thickness. This "c" parameter has dimensions of length, and is defined as c = K dx / R, where K is saturated hydraulic conductivity, dx is grid spacing, and R is recharge. """ def __init__(self, input_file=None, params=None, BaselevelHandlerClass=None): """Initialize the BasicVsSa.""" # Call ErosionModel's init super(BasicVsSa, self).__init__(input_file=input_file, params=params, BaselevelHandlerClass=BaselevelHandlerClass) # Get Parameters and convert units if necessary: self.K_sp = self.get_parameter_from_exponent('K_sp') linear_diffusivity = (self._length_factor**2.)*self.get_parameter_from_exponent('linear_diffusivity') # has units length^2/time try: initial_soil_thickness = (self._length_factor)*self.params['initial_soil_thickness'] # has units length except KeyError: initial_soil_thickness = 1.0 # default value soil_transport_decay_depth = (self._length_factor)*self.params['soil_transport_decay_depth'] # has units length max_soil_production_rate = (self._length_factor)*self.params['max_soil_production_rate'] # has units length per time soil_production_decay_depth = (self._length_factor)*self.params['soil_production_decay_depth'] # has units length recharge_rate = (self._length_factor)*self.params['recharge_rate'] # has units length per time K_hydraulic_conductivity = (self._length_factor)*self.params['K_hydraulic_conductivity'] # has units length per time # Create soil thickness (a.k.a. depth) field if 'soil__depth' in self.grid.at_node: soil_thickness = self.grid.at_node['soil__depth'] else: soil_thickness = self.grid.add_zeros('node', 'soil__depth') # Create bedrock elevation field if 'bedrock__elevation' in self.grid.at_node: bedrock_elev = self.grid.at_node['bedrock__elevation'] else: bedrock_elev = self.grid.add_zeros('node', 'bedrock__elevation') soil_thickness[:] = initial_soil_thickness bedrock_elev[:] = self.z - initial_soil_thickness # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method self.flow_router = FlowAccumulator(self.grid, flow_director='D8', depression_finder = DepressionFinderAndRouter) # Add a field for effective drainage area if 'effective_drainage_area' in self.grid.at_node: self.eff_area = self.grid.at_node['effective_drainage_area'] else: self.eff_area = self.grid.add_zeros('node', 'effective_drainage_area') # Get the effective-length parameter self.sat_len = (K_hydraulic_conductivity*self.grid.dx)/(recharge_rate) # Instantiate a FastscapeEroder component self.eroder = StreamPowerEroder(self.grid, use_Q=self.eff_area, K_sp=self.K_sp, m_sp=self.params['m_sp'], n_sp=self.params['n_sp']) # Instantiate a DepthDependentDiffuser component self.diffuser = DepthDependentDiffuser(self.grid, linear_diffusivity=linear_diffusivity, soil_transport_decay_depth=soil_transport_decay_depth) self.weatherer = ExponentialWeatherer(self.grid, max_soil_production_rate=max_soil_production_rate, soil_production_decay_depth=soil_production_decay_depth) def calc_effective_drainage_area(self): """Calculate and store effective drainage area. Effective drainage area is defined as: $A_{eff} = A \exp ( c H S / A) = A R_r$ where $H$ is soil thickness, $S$ is downslope-positive steepest gradient, $A$ is drainage area, $R_r$ is the runoff ratio, and $c$ is the saturation length parameter. """ area = self.grid.at_node['drainage_area'] slope = self.grid.at_node['topographic__steepest_slope'] soil = self.grid.at_node['soil__depth'] cores = self.grid.core_nodes self.eff_area[cores] = (area[cores] * (np.exp(-self.sat_len * soil[cores] * slope[cores] / area[cores]))) def run_one_step(self, dt): """ Advance model for one time-step of duration dt. """ # Route flow self.flow_router.run_one_step() # Update effective runoff ratio self.calc_effective_drainage_area() # Zero out effective area in flooded nodes self.eff_area[self.flow_router.depression_finder.flood_status==3] = 0.0 # Do some erosion (but not on the flooded nodes) # (if we're varying K through time, update that first) if self.opt_var_precip: self.eroder.K = (self.K_sp * self.pc.get_erodibility_adjustment_factor(self.model_time)) self.eroder.run_one_step(dt) # We must also now erode the bedrock where relevant. If water erosion # into bedrock has occurred, the bedrock elevation will be higher than # the actual elevation, so we simply re-set bedrock elevation to the # lower of itself or the current elevation. b = self.grid.at_node['bedrock__elevation'] b[:] = np.minimum(b, self.grid.at_node['topographic__elevation']) # Calculate regolith-production rate self.weatherer.calc_soil_prod_rate() # Do some soil creep self.diffuser.run_one_step(dt) # calculate model time self.model_time += dt # Lower outlet self.update_outlet(dt) # Check walltime self.check_walltime()
n_sp = 1. ### Initialize components # Set initial surface_water__discharge rmg['node']['surface_water__discharge'] = np.zeros(rmg.number_of_nodes) Q = rmg.at_node['surface_water__discharge'] ### Initialize components # Flow router using D8 Flow Director (default FD) fr = FlowRouter(rmg) # Stream Power Eroder (erosion by water) sp = StreamPowerEroder(rmg, K_sp=Ksp, m_sp=m_sp, n_sp=n_sp, threshold_sp=0, use_Q=Q) # Set up LEM def run_LEM(years): # Create list for saving rainfall rainOutput = [] for i in range(years): ### Random rainfall # Pull random number for yearly rain total based on mean and sd of RAINFALL # in study area yearRain = np.random.normal(0.878982, 0.2744, 1) # Add rainfall to rainfall list
def test_sp_old(): input_str = os.path.join(_THIS_DIR, "drive_sp_params.txt") inputs = ModelParameterDictionary(input_str) nrows = inputs.read_int("nrows") ncols = inputs.read_int("ncols") dx = inputs.read_float("dx") dt = inputs.read_float("dt") time_to_run = inputs.read_float("run_time") uplift = inputs.read_float("uplift_rate") init_elev = inputs.read_float("init_elev") mg = RasterModelGrid((nrows, ncols), xy_spacing=(dx, dx)) mg.set_closed_boundaries_at_grid_edges(False, False, True, True) mg.add_zeros("topographic__elevation", at="node") z = mg.zeros(at="node") + init_elev numpy.random.seed(0) mg["node"]["topographic__elevation"] = z + numpy.random.rand(len(z)) / 1000.0 fr = FlowAccumulator(mg, flow_director="D8") sp = StreamPowerEroder(mg, input_str) elapsed_time = 0.0 while elapsed_time < time_to_run: if elapsed_time + dt > time_to_run: dt = time_to_run - elapsed_time fr.run_one_step() sp.erode(mg, dt) mg.at_node["topographic__elevation"][mg.core_nodes] += uplift * dt elapsed_time += dt z_trg = numpy.array( [ 5.48813504e-04, 7.15189366e-04, 6.02763376e-04, 5.44883183e-04, 4.23654799e-04, 6.45894113e-04, 1.01830760e-02, 9.58036770e-03, 6.55865452e-03, 3.83441519e-04, 7.91725038e-04, 1.00142749e-02, 8.80798884e-03, 5.78387585e-03, 7.10360582e-05, 8.71292997e-05, 9.81911417e-03, 9.52243406e-03, 7.55093226e-03, 8.70012148e-04, 9.78618342e-04, 1.00629755e-02, 8.49253798e-03, 5.33216680e-03, 1.18274426e-04, 6.39921021e-04, 9.88956320e-03, 9.47119567e-03, 6.43790696e-03, 4.14661940e-04, 2.64555612e-04, 1.00450743e-02, 8.37262908e-03, 5.21540904e-03, 1.87898004e-05, 6.17635497e-04, 9.21286940e-03, 9.34022513e-03, 7.51114450e-03, 6.81820299e-04, 3.59507901e-04, 6.19166921e-03, 7.10456176e-03, 6.62585507e-03, 6.66766715e-04, 6.70637870e-04, 2.10382561e-04, 1.28926298e-04, 3.15428351e-04, 3.63710771e-04, ] ) assert_array_almost_equal(mg.at_node["topographic__elevation"], z_trg)