def test_create_weatherer_and_change_rate(): grid = RasterModelGrid((3, 3), 1.0) grid.add_zeros("soil__depth", at="node") ew = ExponentialWeatherer(grid, soil_production__maximum_rate=0.0001) ew.maximum_weathering_rate = 0.0004 assert ew.maximum_weathering_rate == 0.0004
def __init__(self, input_file=None, params=None, BaselevelHandlerClass=None): """Initialize the BasicChSa model.""" # Call ErosionModel's init super(BasicChSa, self).__init__(input_file=input_file, params=params, BaselevelHandlerClass=BaselevelHandlerClass) 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 # 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) # Instantiate a FastscapeEroder component self.eroder = FastscapeEroder(self.grid, K_sp=self.K_sp, m_sp=self.params['m_sp'], n_sp=self.params['n_sp']) # Instantiate a weathering component self.weatherer = ExponentialWeatherer(self.grid, max_soil_production_rate=max_soil_production_rate, soil_production_decay_depth=soil_production_decay_depth) # Instantiate a soil-transport component self.diffuser = DepthDependentTaylorDiffuser(self.grid, linear_diffusivity=linear_diffusivity, slope_crit=self.params['slope_crit'], soil_transport_decay_depth=soil_transport_decay_depth, nterms=11)
def test_raise_kwargs_error(): mg = RasterModelGrid((5, 5)) soilTh = mg.add_zeros('node', 'soil__depth') z = mg.add_zeros('node', 'topographic__elevation') BRz = mg.add_zeros('node', 'bedrock__elevation') z += mg.node_x.copy()**2 BRz = z.copy() - 1.0 soilTh[:] = z - BRz expweath = ExponentialWeatherer(mg) assert_raises(TypeError, DepthDependentCubicDiffuser, mg, diffusivity=1)
def test_raise_error(): mg = RasterModelGrid((5, 5)) soilTh = mg.add_zeros('node', 'soil__depth') z = mg.add_zeros('node', 'topographic__elevation') BRz = mg.add_zeros('node', 'bedrock__elevation') z += mg.node_x.copy()**2 BRz = z.copy() - 1.0 soilTh[:] = z - BRz expweath = ExponentialWeatherer(mg) DDdiff = DepthDependentCubicDiffuser(mg) expweath.calc_soil_prod_rate() assert_raises(RuntimeError, DDdiff.soilflux, 10, if_unstable='raise')
def test_4x7_grid_vs_analytical_solution(): """Test against known analytical solution.""" # Create a 4-row by 7-column grid with 10 m spacing mg = RasterModelGrid((4, 7), xy_spacing=10.0) # Close off top and bottom (N and S) boundaries so it becomes a 1D problem mg.set_closed_boundaries_at_grid_edges(False, True, False, True) # Create an elevation field, initially zero z = mg.add_zeros("topographic__elevation", at="node") mg.add_zeros("soil__depth", at="node") # Instantiate components, and set their parameters. Note that traditional # diffusivity, D, is D = SCE x H*, where SCE is soil-creep efficiency. # Here we want D = 0.01 m2/yr and H* = 0,.5 m, so cwe set SCE = 0.02. weatherer = ExponentialWeatherer(mg, soil_production__maximum_rate=0.0002, soil_production__decay_depth=0.5) diffuser = DepthDependentTaylorDiffuser(mg, linear_diffusivity=0.01, slope_crit=0.8, soil_transport_decay_depth=0.5) # Get a reference to bedrock elevation field z_bedrock = mg.at_node["bedrock__elevation"] # Estimate a reasonable time step. Here we take advantage of the fact that # we know the final slope at the outer links will be about 1.33. Stability # for the cubic term involves an "effective D" parameter, Deff, that should # be Deff = D (S / Sc)^2. (see notebook calcs) baselevel_rate = 0.0001 dt = 250.0 # Run for 750 ky for i in range(3000): z[mg.core_nodes] += baselevel_rate * dt z_bedrock[mg.core_nodes] += baselevel_rate * dt weatherer.calc_soil_prod_rate() diffuser.run_one_step(dt) # Test: these numbers represent equilibrium. See Jupyter notebook for # calculations. my_nodes = mg.nodes[2, :] assert_array_equal(np.round(z[my_nodes], 1), np.array([0.0, 6.2, 10.7, 12.6, 10.7, 6.2, 0.0])) assert_array_equal( np.round(mg.at_node["soil__depth"][8:13], 2), np.array([0.35, 0.35, 0.35, 0.35, 0.35]), )
def test_infinite_taylor_error(): mg = RasterModelGrid((5, 5)) soilTh = mg.add_zeros('node', 'soil__depth') z = mg.add_zeros('node', 'topographic__elevation') BRz = mg.add_zeros('node', 'bedrock__elevation') z += mg.node_x.copy()**4 BRz = z.copy() - 1.0 soilTh[:] = z - BRz expweath = ExponentialWeatherer(mg) DDdiff = DepthDependentTaylorDiffuser(mg, nterms=400) expweath.calc_soil_prod_rate() assert_raises(RuntimeError, DDdiff.soilflux, 10)
def test_raise_stability_error(): mg = RasterModelGrid((5, 5)) soilTh = mg.add_zeros("node", "soil__depth") z = mg.add_zeros("node", "topographic__elevation") BRz = mg.add_zeros("node", "bedrock__elevation") z += mg.node_x.copy() ** 2 BRz = z.copy() - 1.0 soilTh[:] = z - BRz expweath = ExponentialWeatherer(mg) DDdiff = DepthDependentTaylorDiffuser(mg) expweath.calc_soil_prod_rate() with pytest.raises(RuntimeError): DDdiff.soilflux(10, if_unstable="raise")
def test_infinite_taylor_error(): mg = RasterModelGrid((5, 5)) soilTh = mg.add_zeros("soil__depth", at="node") z = mg.add_zeros("topographic__elevation", at="node") BRz = mg.add_zeros("bedrock__elevation", at="node") z += mg.node_x.copy()**4 BRz = z.copy() - 1.0 soilTh[:] = z - BRz expweath = ExponentialWeatherer(mg) DDdiff = DepthDependentTaylorDiffuser(mg, nterms=400) expweath.calc_soil_prod_rate() with pytest.raises(RuntimeError): DDdiff.soilflux(10)
def test_raise_kwargs_error(): mg = RasterModelGrid((5, 5)) soilTh = mg.add_zeros('node', 'soil__depth') z = mg.add_zeros('node', 'topographic__elevation') BRz = mg.add_zeros('node', 'bedrock__elevation') z += mg.node_x.copy() BRz += mg.node_x / 2. soilTh[:] = z - BRz expweath = ExponentialWeatherer(mg) with pytest.raises(TypeError): DepthDependentDiffuser(mg, diffusivity=1) DDdiff = DepthDependentDiffuser(mg) with pytest.raises(TypeError): DDdiff.soilflux(2., bad_var=1)
#route flow fr = FlowDirectorD8(mg, 'topographic__elevation') #instantiate BRaKE, the collection of functions governing river evolution blocks = bl.BrakeLandlab() #instantiate hillslope diffusion model component, from Landlab hillslopeflux = DepthDependentDiffuser( mg, linear_diffusivity=linear_diffusivity, soil_transport_decay_depth=soil_transport_decay_depth) #instantiate exponential weathering component, from Landlab weatheringrate = ExponentialWeatherer( mg, soil_production__maximum_rate=max_soil_production_rate, soil_production__decay_depth=soil_production_decay_depth) #set boundary elevations to enable easier data visualization in Paraview mg.at_node['topographic__elevation'][mg.boundary_nodes] -= (bl_drop * time_to_run) mg.at_node['bedrock__elevation'][mg.boundary_nodes] -= (bl_drop * time_to_run) mg.at_node['bedrock__elevation'][baselevel_node] = min( mg.at_node['bedrock__elevation'][channel_nodes]) - 0.0001 mg.at_node['topographic__elevation'][baselevel_node] = mg.at_node[ 'bedrock__elevation'][baselevel_node] #instantiate fluvial block tracking matrix blocks.instantiate_tracking_matrix() #instantiate channel elev and cover frac arrays for saving
def __init__( self, clock, grid, m_sp=0.5, n_sp=1.0, water_erodibility=0.0001, regolith_transport_parameter=0.1, critical_slope=0.3, number_of_taylor_terms=11, soil_production__maximum_rate=0.001, soil_production__decay_depth=0.5, soil_transport_decay_depth=0.5, **kwargs ): """ Parameters ---------- clock : terrainbento Clock instance grid : landlab model grid instance The grid must have all required fields. m_sp : float, optional Drainage area exponent (:math:`m`). Default is 0.5. n_sp : float, optional Slope exponent (:math:`n`). Default is 1.0. water_erodibility : float, optional Water erodibility (:math:`K`). Default is 0.0001. regolith_transport_parameter : float, optional Regolith transport efficiency (:math:`D`). Default is 0.1. critical_slope : float, optional Critical slope (:math:`S_c`, unitless). Default is 0.3. number_of_taylor_terms : int, optional Number of terms in the Taylor Series Expansion (:math:`N`). Default is 11. soil_production__maximum_rate : float, optional Maximum rate of soil production (:math:`P_{0}`). Default is 0.001. soil_production__decay_depth : float, optional Decay depth for soil production (:math:`H_{s}`). Default is 0.5. soil_transport_decay_depth : float, optional Decay depth for soil transport (:math:`H_{0}`). Default is 0.5. **kwargs : Keyword arguments to pass to :py:class:`ErosionModel`. Importantly these arguments specify the precipitator and the runoff generator that control the generation of surface water discharge (:math:`Q`). Returns ------- BasicChSa : model object Examples -------- This is a minimal example to demonstrate how to construct an instance of model **BasicChSa**. For more detailed examples, including steady-state test examples, see the terrainbento tutorials. To begin, import the model class. >>> from landlab import RasterModelGrid >>> from landlab.values import constant >>> from terrainbento import Clock, BasicChSa >>> clock = Clock(start=0, stop=100, step=1) >>> grid = RasterModelGrid((5,5)) >>> _ = constant(grid, "topographic__elevation", value=1.0) >>> _ = constant(grid, "soil__depth", value=1.0) Construct the model. >>> model = BasicChSa(clock, grid) Running the model with ``model.run()`` would create output, so here we will just run it one step. >>> model.run_one_step(10) >>> model.model_time 10.0 """ # Call ErosionModel"s init super(BasicChSa, self).__init__(clock, grid, **kwargs) # verify correct fields are present. self._verify_fields(self._required_fields) self.m = m_sp self.n = n_sp self.K = water_erodibility # Create bedrock elevation field soil_thickness = self.grid.at_node["soil__depth"] bedrock_elev = self.grid.add_zeros("node", "bedrock__elevation") bedrock_elev[:] = self.z - soil_thickness # Instantiate a FastscapeEroder component self.eroder = FastscapeEroder( self.grid, K_sp=self.K, m_sp=self.m, n_sp=self.n, discharge_name="surface_water__discharge", ) # Instantiate a weathering component self.weatherer = ExponentialWeatherer( self.grid, soil_production__maximum_rate=soil_production__maximum_rate, soil_production__decay_depth=soil_production__decay_depth, ) # Instantiate a soil-transport component self.diffuser = DepthDependentTaylorDiffuser( self.grid, linear_diffusivity=regolith_transport_parameter, slope_crit=critical_slope, soil_transport_decay_depth=soil_transport_decay_depth, nterms=number_of_taylor_terms, )
print("---------------------") ##---------------------------------Rain implementation--------------------------# ##Set up a Timeseries of rainfall values rainTimeseries = np.zeros(int(totalT / dt)) + baseRainfall mg.add_zeros('node', 'rainvalue') mg.at_node['rainvalue'][:] = int(baseRainfall) ##---------------------------------Component initialization---------------------# fr = FlowRouter(mg, method='d8', runoff_rate=baseRainfall) lm = DepressionFinderAndRouter(mg) expWeath = ExponentialWeatherer( mg, soil_production__maximum_rate=soilProductionRate, soil_production__decay_depth=soilProductionDecayDepth) sf = SteepnessFinder(mg, min_drainage_area=1e6) sp = Space(mg, K_sed=Kvs, K_br=Kvb, F_f=Ff, phi=phi, H_star=Hstar, v_s=vs, m_sp=m, n_sp=n, sp_crit_sed=sp_crit_sedi, sp_crit_br=sp_crit_bedrock,
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)
# n_sp = nsp, # threshold_sp=thresholdSP) fc = FastscapeEroder(mg, K_sp=Kv, m_sp=msp, n_sp=nsp, threshold_sp=0, rainfall_intensity=1) fr = FlowRouter(mg) lm = DepressionFinderAndRouter(mg) expw = ExponentialWeatherer(mg, max_soil_production_rate=maxSoilProductionRate, soil_production_decay_depth=soilProductionDepth) dld = DepthDependentDiffuser(mg, linear_diffusivity=linDiff, soil_transport_decay_depth=soilTransportDepth) ld = LinearDiffuser(mg, linear_diffusivity=linDiff) print("finished with the initialization of the erosion components") print("---------------------") ##---------------------------------Main Loop------------------------------------# t0 = time.time() elapsed_time = 0 print("starting with main loop.")
def __init__(self, clock, grid, m_sp=0.5, n_sp=1.0, water_erodibility=0.0001, regolith_transport_parameter=0.1, soil_production__maximum_rate=0.001, soil_production__decay_depth=0.5, soil_transport_decay_depth=0.5, hydraulic_conductivity=0.1, **kwargs): """ Parameters ---------- clock : terrainbento Clock instance grid : landlab model grid instance The grid must have all required fields. m_sp : float, optional Drainage area exponent (:math:`m`). Default is 0.5. n_sp : float, optional Slope exponent (:math:`n`). Default is 1.0. water_erodibility : float, optional Water erodibility (:math:`K`). Default is 0.0001. regolith_transport_parameter : float, optional Regolith transport efficiency (:math:`D`). Default is 0.1. soil_production__maximum_rate : float, optional Maximum rate of soil production (:math:`P_{0}`). Default is 0.001. soil_production__decay_depth : float, optional Decay depth for soil production (:math:`H_{s}`). Default is 0.5. soil_transport_decay_depth : float, optional Decay depth for soil transport (:math:`H_{0}`). Default is 0.5. hydraulic_conductivity : float, optional Hydraulic conductivity (:math:`K_{sat}`). Default is 0.1. **kwargs : Keyword arguments to pass to :py:class:`ErosionModel`. Importantly these arguments specify the precipitator and the runoff generator that control the generation of surface water discharge (:math:`Q`). Returns ------- BasicSaVs : model object Examples -------- This is a minimal example to demonstrate how to construct an instance of model **BasicSaVs**. For more detailed examples, including steady-state test examples, see the terrainbento tutorials. To begin, import the model class. >>> from landlab import RasterModelGrid >>> from landlab.values import random >>> from terrainbento import Clock, BasicSaVs >>> clock = Clock(start=0, stop=100, step=1) >>> grid = RasterModelGrid((5,5)) >>> _ = random(grid, "topographic__elevation") >>> _ = random(grid, "soil__depth") Construct the model. >>> model = BasicSaVs(clock, grid) Running the model with ``model.run()`` would create output, so here we will just run it one step. >>> model.run_one_step(1.) >>> model.model_time 1.0 """ # Call ErosionModel"s init super(BasicSaVs, self).__init__(clock, grid, **kwargs) # ensure Precipitator and RunoffGenerator are vanilla self._ensure_precip_runoff_are_vanilla(vsa_precip=True) # verify correct fields are present. self._verify_fields(self._required_fields) # Get Parameters and convert units if necessary: self.m = m_sp self.n = n_sp self.K = water_erodibility soil_thickness = self.grid.at_node["soil__depth"] bedrock_elev = self.grid.add_zeros("node", "bedrock__elevation") bedrock_elev[:] = self.z - soil_thickness # Get the effective-area parameter self._Kdx = hydraulic_conductivity * self.grid.dx # Instantiate a FastscapeEroder component self.eroder = FastscapeEroder( self.grid, discharge_name="surface_water__discharge", K_sp=self.K, m_sp=self.m, n_sp=self.n, ) # Instantiate a DepthDependentDiffuser component self.diffuser = DepthDependentDiffuser( self.grid, linear_diffusivity=regolith_transport_parameter, soil_transport_decay_depth=soil_transport_decay_depth, ) self.weatherer = ExponentialWeatherer( self.grid, soil_production__maximum_rate=soil_production__maximum_rate, soil_production__decay_depth=soil_production__decay_depth, )
def __init__( self, clock, grid, soil_production__maximum_rate=0.001, soil_production__decay_depth=0.5, soil_transport_decay_depth=0.5, **kwargs ): """ Parameters ---------- clock : terrainbento Clock instance grid : landlab model grid instance The grid must have all required fields. m_sp : float, optional Drainage area exponent (:math:`m`). Default is 0.5. n_sp : float, optional Slope exponent (:math:`n`). Default is 1.0. water_erodibility_upper : float, optional Water erodibility of the upper layer (:math:`K_{1}`). Default is 0.001. water_erodibility_lower : float, optional Water erodibility of the upper layer (:math:`K_{2}`). Default is 0.0001. contact_zone__width : float, optional Thickness of the contact zone (:math:`W_c`). Default is 1. regolith_transport_parameter : float, optional Regolith transport efficiency (:math:`D`). Default is 0.1. soil_production__maximum_rate : float, optional Maximum rate of soil production (:math:`P_{0}`). Default is 0.001. soil_production__decay_depth : float, optional Decay depth for soil production (:math:`H_{s}`). Default is 0.5. soil_transport_decay_depth : float, optional Decay depth for soil transport (:math:`H_{0}`). Default is 0.5. **kwargs : Keyword arguments to pass to :py:class:`TwoLithologyErosionModel`. Importantly these arguments specify the precipitator and the runoff generator that control the generation of surface water discharge (:math:`Q`). Returns ------- BasicRtSa : model object Examples -------- This is a minimal example to demonstrate how to construct an instance of model **BasicRtSa**. For more detailed examples, including steady-state test examples, see the terrainbento tutorials. To begin, import the model class. >>> from landlab import RasterModelGrid >>> from landlab.values import random, constant >>> from terrainbento import Clock, BasicRtSa >>> clock = Clock(start=0, stop=100, step=1) >>> grid = RasterModelGrid((5,5)) >>> _ = random(grid, "topographic__elevation") >>> _ = random(grid, "soil__depth") >>> _ = constant(grid, "lithology_contact__elevation", value=-10.) Construct the model. >>> model = BasicRtSa(clock, grid) Running the model with ``model.run()`` would create output, so here we will just run it one step. >>> model.run_one_step(1.) >>> model.model_time 1.0 """ # Call ErosionModel"s init super(BasicRtSa, self).__init__(clock, grid, **kwargs) # verify correct fields are present. self._verify_fields(self._required_fields) # Set up rock-till boundary and associated grid fields. self._setup_rock_and_till() # Instantiate a FastscapeEroder component self.eroder = FastscapeEroder( self.grid, K_sp=self.erody, m_sp=self.m, n_sp=self.n, discharge_name="surface_water__discharge", ) soil_thickness = self.grid.at_node["soil__depth"] bedrock_elev = self.grid.add_zeros("node", "bedrock__elevation") bedrock_elev[:] = self.z - soil_thickness # Instantiate diffusion and weathering components self.diffuser = DepthDependentDiffuser( self.grid, linear_diffusivity=self.regolith_transport_parameter, soil_transport_decay_depth=soil_transport_decay_depth, ) self.weatherer = ExponentialWeatherer( self.grid, soil_production__maximum_rate=soil_production__maximum_rate, soil_production__decay_depth=soil_production__decay_depth, )
def __init__(self, input_file=None, params=None, BaselevelHandlerClass=None): """Initialize the BasicSa.""" # Call ErosionModel's init super(BasicHySa, self).__init__(input_file=input_file, params=params, BaselevelHandlerClass=BaselevelHandlerClass) self.K_br = self.get_parameter_from_exponent('K_rock_sp') self.K_sed = self.get_parameter_from_exponent('K_sed_sp') linear_diffusivity = ( self._length_factor**2.) * self.get_parameter_from_exponent( 'linear_diffusivity') # has units length^2/time v_sc = self.get_parameter_from_exponent( 'v_sc') # normalized settling velocity. Unitless. 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 # Instantiate a FlowAccumulator with DepressionFinderAndRouter using D8 method self.flow_router = FlowAccumulator( self.grid, flow_director='D8', depression_finder=DepressionFinderAndRouter) #set methods and fields. K's and sp_crits need to be field names method = 'simple_stream_power' discharge_method = 'discharge_field' area_field = None discharge_field = 'surface_water__discharge' # Instantiate a SPACE component self.eroder = Space(self.grid, K_sed=self.K_sed, K_br=self.K_br, F_f=self.params['F_f'], phi=self.params['phi'], H_star=self.params['H_star'], v_s=v_sc, m_sp=self.params['m_sp'], n_sp=self.params['n_sp'], method=method, discharge_method=discharge_method, area_field=area_field, discharge_field=discharge_field, solver=self.params['solver']) # 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') # Set soil thickness and bedrock elevation try: initial_soil_thickness = self.params['initial_soil_thickness'] except KeyError: initial_soil_thickness = 1.0 # default value soil_thickness[:] = initial_soil_thickness bedrock_elev[:] = self.z - initial_soil_thickness # Instantiate diffusion and weathering components 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) self.grid.at_node['soil__depth'][:] = \ self.grid.at_node['topographic__elevation'] - \ self.grid.at_node['bedrock__elevation']
def __init__( self, clock, grid, m_sp=0.5, n_sp=1.0, water_erodibility_sediment=0.001, water_erodibility_rock=0.0001, regolith_transport_parameter=0.1, settling_velocity=0.001, sediment_porosity=0.3, fraction_fines=0.5, roughness__length_scale=0.5, solver="basic", soil_production__maximum_rate=0.001, soil_production__decay_depth=0.5, soil_transport_decay_depth=0.5, sp_crit_br=0, sp_crit_sed=0, **kwargs ): """ Parameters ---------- clock : terrainbento Clock instance grid : landlab model grid instance The grid must have all required fields. m_sp : float, optional Drainage area exponent (:math:`m`). Default is 0.5. n_sp : float, optional Slope exponent (:math:`n`). Default is 1.0. water_erodibility : float, optional Water erodibility (:math:`K`). Default is 0.0001. regolith_transport_parameter : float, optional Regolith transport efficiency (:math:`D`). Default is 0.1. settling_velocity : float, optional Normalized settling velocity of entrained sediment (:math:`V_s`). Default is 0.001. sediment_porosity : float, optional Sediment porosity (:math:`\phi`). Default is 0.3. fraction_fines : float, optional Fraction of fine sediment that is permanently detached (:math:`F_f`). Default is 0.5. roughness__length_scale : float, optional Bedrock roughness length scale. Default is 0.5. solver : str, optional Solver option to pass to the Landlab `Space <https://landlab.readthedocs.io/en/master/reference/components/space.html>`_ component. Default is "basic". soil_production__maximum_rate : float, optional Maximum rate of soil production (:math:`P_{0}`). Default is 0.001. soil_production__decay_depth : float, optional Decay depth for soil production (:math:`H_{s}`). Default is 0.5. soil_transport_decay_depth : float, optional Decay depth for soil transport (:math:`H_{0}`). Default is 0.5. **kwargs : Keyword arguments to pass to :py:class:`ErosionModel`. Importantly these arguments specify the precipitator and the runoff generator that control the generation of surface water discharge (:math:`Q`). Returns ------- BasicHySa : model object Examples -------- This is a minimal example to demonstrate how to construct an instance of model **BasicHySa**. For more detailed examples, including steady-state test examples, see the terrainbento tutorials. To begin, import the model class. >>> from landlab import RasterModelGrid >>> from landlab.values import random >>> from terrainbento import Clock, BasicHySa >>> clock = Clock(start=0, stop=100, step=1) >>> grid = RasterModelGrid((5,5)) >>> _ = random(grid, "topographic__elevation") >>> _ = random(grid, "soil__depth") Construct the model. >>> model = BasicHySa(clock, grid) Running the model with ``model.run()`` would create output, so here we will just run it one step. >>> model.run_one_step(1.) >>> model.model_time 1.0 """ # Call ErosionModel"s init super().__init__(clock, grid, **kwargs) # verify correct fields are present. self._verify_fields(self._required_fields) soil_thickness = self.grid.at_node["soil__depth"] bedrock_elev = self.grid.add_zeros("node", "bedrock__elevation") bedrock_elev[:] = self.z - soil_thickness self.m = m_sp self.n = n_sp self.K_br = water_erodibility_rock self.K_sed = water_erodibility_sediment # Instantiate a SPACE component self.eroder = Space( self.grid, K_sed=self.K_sed, K_br=self.K_br, sp_crit_br=sp_crit_br, sp_crit_sed=sp_crit_sed, F_f=fraction_fines, phi=sediment_porosity, H_star=roughness__length_scale, v_s=settling_velocity, m_sp=self.m, n_sp=self.n, discharge_field="surface_water__discharge", solver=solver, ) # Instantiate diffusion and weathering components self.weatherer = ExponentialWeatherer( self.grid, soil_production__maximum_rate=soil_production__maximum_rate, soil_production__decay_depth=soil_production__decay_depth, ) self.diffuser = DepthDependentDiffuser( self.grid, linear_diffusivity=regolith_transport_parameter, soil_transport_decay_depth=soil_transport_decay_depth, ) self.grid.at_node["soil__depth"][:] = ( self.grid.at_node["topographic__elevation"] - self.grid.at_node["bedrock__elevation"] )