Exemple #1
0
def test_simple_water_table_adaptive_dt():
    """Test a one-node steady simulation.

    Notes
    -----
    This test demonstrates the same simple water table as
    test_simple_water_table, but with the run_with_adaptive_time_step_solver
    method.


    """
    boundaries = {"top": "closed", "left": "closed", "bottom": "closed"}
    rg = RasterModelGrid((3, 3), bc=boundaries)
    rg.add_zeros("aquifer_base__elevation", at="node")
    rg.add_ones("topographic__elevation", at="node")
    rg.add_zeros("water_table__elevation", at="node")
    rg.at_node["water_table__elevation"][rg.core_nodes] += 1e-10
    gdp = GroundwaterDupuitPercolator(
        rg,
        recharge_rate=1.0e-8,
        hydraulic_conductivity=0.01,
    )
    for _ in range(10):
        gdp.run_with_adaptive_time_step_solver(1e4)

    assert_equal(np.round(gdp._thickness[4], 5), 0.001)
Exemple #2
0
def test_run_one_step():
    from landlab import RasterModelGrid
    grid = RasterModelGrid((10, 10), spacing=25)
    grid.add_ones('node', 'soil_water_infiltration__depth', dtype=float)
    grid.add_ones('node', 'surface_water__depth')
    hydraulic_conductivity = (2.5 * (10**-6))
    grid['node']['surface_water__depth'] *= 5.0
    grid['node']['soil_water_infiltration__depth'] *= (10**-5)
    SI = SoilInfiltrationGreenAmpt(
        grid,
        hydraulic_conductivity=hydraulic_conductivity,
        soil_bulk_density=1700.,
        rock_density=2650.,
        initial_soil_moisture_content=0.2,
        soil_type='silt loam',
        volume_fraction_coarse_fragments=0.6,
        coarse_sed_flag=False,
        surface_water_minimum_depth=1.e-7,
        soil_pore_size_distribution_index=None,
        soil_bubbling_pressure=None,
        wetting_front_capillary_pressure_head=None)

    SI.run_one_step(dt=5)
    np.testing.assert_almost_equal(grid['node']['surface_water__depth'][0],
                                   3.97677483519,
                                   decimal=6)
def test_exp_reg_prod():
    """
    Test RegolithExponentialProduction and ensure fields are updated
    based on an exact solution.
    """

    mg = RasterModelGrid((3, 3), xy_spacing=10.0)

    z = mg.add_ones("node", "topographic__elevation")
    zb = mg.add_zeros("node", "aquifer_base__elevation")
    zwt = mg.add_ones("node", "water_table__elevation")

    rm = RegolithExponentialProduction(mg)
    rm.run_step(1e9)

    assert_almost_equal(z[4], 1.001)
    assert_almost_equal(zb[4], 1.001 - np.log(np.exp(1) + 1e9 * 2e-12))
    assert_almost_equal(zwt[4], 1.001 - np.log(np.exp(1) + 1e9 * 2e-12) + 1.0)

    b0 = (z - zb)[4]
    rm.run_step(1e9)

    assert_almost_equal(z[4], 1.002)
    assert_almost_equal(zb[4], 1.002 - np.log(np.exp(b0) + 1e9 * 2e-12))
    assert_almost_equal(zwt[4], 1.002 - np.log(np.exp(b0) + 1e9 * 2e-12) + 1.0)
Exemple #4
0
def test_wt_above_surface_standard_run_step():
    """test that water tables above the topogrpahic elevation are
    set to the topographic elevation.

    Notes:
    ----
    Water tables above the land surface represent a non-physical condition.
    The GroundwaterDupuitPercolator will not produce this state when it
    is the only component operating on water table elevation or topogrpahic
    elevation, however, when combined with components that do, this may occur.
    If the water table is above the ground surface at a node, it is set to the ground
    surface elevation at that node.

    """

    grid = RasterModelGrid((3, 3))
    grid.set_closed_boundaries_at_grid_edges(True, True, True, False)
    wt = grid.add_ones("node", "water_table__elevation")
    _ = grid.add_ones("node", "topographic__elevation")
    _ = grid.add_zeros("node", "aquifer_base__elevation")

    # initialize the groundwater model
    gdp = GroundwaterDupuitPercolator(grid, recharge_rate=0.0)
    gdp.run_one_step(1)
    assert_equal(wt[4], 1)
Exemple #5
0
def test_simple_water_table():
    """Test a one-node steady simulation.

    Notes
    -----
    The analytical solution for one interior cell with one open boundary is as
    follows. The incoming recharge must equal the outgoing discharge. The
    incoming recharge is R, and the surface area is 1 m2, so the incoming
    volume per unit time is R m/s x 1 m x 1 m. The outgoing discharge is equal
    to the conductivity, K (m/s), times the thickness at the boundary, Hb,
    times the hydraulic gradient, which in this case is (H - 0) / dx = H.
    The model uses the upwind thickness, which in this case is H. Therefore:

        K H^2 = R, or

        H = sqrt( R / K ).

    With R = 10^-8 m/s and K = 10^-2 m/s, we should have

        H = 0.001 m.
    """
    boundaries = {"top": "closed", "left": "closed", "bottom": "closed"}
    rg = RasterModelGrid((3, 3), bc=boundaries)
    rg.add_zeros("aquifer_base__elevation", at="node")
    rg.add_ones("topographic__elevation", at="node")
    gdp = GroundwaterDupuitPercolator(rg,
                                      recharge_rate=1.0e-8,
                                      hydraulic_conductivity=0.01)
    for _ in range(100):
        gdp.run_one_step(1e3)

    assert_equal(np.round(gdp._thickness[4], 5), 0.001)
Exemple #6
0
def test_add_ones_at_corners():
    """Test add a field to corners."""
    grid = RasterModelGrid((4, 5))
    grid.add_ones('z', at='corner')

    assert_array_equal(grid.at_corner['z'],
                       [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])
Exemple #7
0
def grid_1():
    grid = RasterModelGrid((3, 21), xy_spacing=100.0)
    grid.set_closed_boundaries_at_grid_edges(False, True, False, True)
    grid.add_zeros("node", "topographic__elevation")
    grid.add_ones("node", "soil__depth")
    grid.add_zeros("node", "lithology_contact__elevation")
    return grid
def test_run_one_step():
    grid = RasterModelGrid((10, 10), xy_spacing=25)
    grid.add_ones("soil_water_infiltration__depth", at="node", dtype=float)
    grid.add_ones("surface_water__depth", at="node")
    hydraulic_conductivity = 2.5 * (10 ** -6)
    grid["node"]["surface_water__depth"] *= 5.0
    grid["node"]["soil_water_infiltration__depth"] *= 10 ** -5
    SI = SoilInfiltrationGreenAmpt(
        grid,
        hydraulic_conductivity=hydraulic_conductivity,
        soil_bulk_density=1700.0,
        rock_density=2650.0,
        initial_soil_moisture_content=0.2,
        soil_type="silt loam",
        volume_fraction_coarse_fragments=0.6,
        coarse_sed_flag=False,
        surface_water_minimum_depth=1.0e-7,
        soil_pore_size_distribution_index=None,
        soil_bubbling_pressure=None,
        wetting_front_capillary_pressure_head=None,
    )

    SI.run_one_step(dt=5)
    np.testing.assert_almost_equal(
        grid["node"]["surface_water__depth"][0], 3.97677483519, decimal=6
    )
def test_run_one_step():
    grid = RasterModelGrid((10, 10), xy_spacing=25)
    grid.add_ones("node", "soil_water_infiltration__depth", dtype=float)
    grid.add_ones("node", "surface_water__depth")
    hydraulic_conductivity = 2.5 * (10 ** -6)
    grid["node"]["surface_water__depth"] *= 5.0
    grid["node"]["soil_water_infiltration__depth"] *= 10 ** -5
    SI = SoilInfiltrationGreenAmpt(
        grid,
        hydraulic_conductivity=hydraulic_conductivity,
        soil_bulk_density=1700.,
        rock_density=2650.,
        initial_soil_moisture_content=0.2,
        soil_type="silt loam",
        volume_fraction_coarse_fragments=0.6,
        coarse_sed_flag=False,
        surface_water_minimum_depth=1.e-7,
        soil_pore_size_distribution_index=None,
        soil_bubbling_pressure=None,
        wetting_front_capillary_pressure_head=None,
    )

    SI.run_one_step(dt=5)
    np.testing.assert_almost_equal(
        grid["node"]["surface_water__depth"][0], 3.97677483519, decimal=6
    )
Exemple #10
0
def test_add_ones_at_corners():
    """Test add a field to corners."""
    grid = RasterModelGrid((4, 5))
    grid.add_ones("z", at="corner")

    assert_array_equal(
        grid.at_corner["z"], [1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]
    )
Exemple #11
0
def test_add_ones_zeros_empty_to_at_grid():
    """Test different add methods for keyword at='grid'"""
    grid = RasterModelGrid((4, 5))
    with pytest.raises(ValueError):
        grid.add_zeros("value", at="grid")
    with pytest.raises(ValueError):
        grid.add_empty("value", at="grid")
    with pytest.raises(ValueError):
        grid.add_ones("value", at="grid")
Exemple #12
0
def test_drainage_area():
    """Test that correct error is raised when no flow__upstream_node_order."""
    mg = RasterModelGrid(30, 70)
    mg.add_ones("node", "topographic__elevation")
    mg.add_ones("node", "flow__upstream_node_order")
    fd = FlowDirectorSteepest(mg)
    fd.run_one_step()
    with pytest.raises(FieldError):
        calculate_distance_to_divide(mg)
Exemple #13
0
def grid_5():
    grid = RasterModelGrid((6, 9), xy_spacing=10)
    grid.add_zeros("node", "topographic__elevation")
    grid.add_ones("node", "soil__depth")
    lith = grid.add_zeros("node", "lithology_contact__elevation")
    lith[:27] = -30
    lith[27:] = 10.0
    lith[grid.boundary_nodes] = -9999.0
    return grid
Exemple #14
0
def test_add_ones_at_corners():
    """Test add a field to corners."""
    grid = RasterModelGrid((4, 5))
    grid.add_ones("z", at="corner")

    assert_array_equal(
        grid.at_corner["z"],
        [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0],
    )
Exemple #15
0
def test_add_ones_zeros_empty_to_at_grid():
    """Test different add methods for keyword at='grid'"""
    grid = RasterModelGrid((4, 5))
    with pytest.raises(ValueError):
        grid.add_zeros('value', at='grid')
    with pytest.raises(ValueError):
        grid.add_empty('value', at='grid')
    with pytest.raises(ValueError):
        grid.add_ones('value', at='grid')
def test_flow_director_steepest_flow__link_dir_field_creation():
    mg = RasterModelGrid((3, 3))
    mg.set_closed_boundaries_at_grid_edges(True, True, True, False)
    z = mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    mg.add_ones("flow__link_direction", at="link", dtype=int)
    fd = FlowDirectorSteepest(mg, z)
    assert_array_equal(
        fd.flow_link_direction, np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
    )
Exemple #17
0
def grid_3():
    grid = RasterModelGrid((21, 3), xy_spacing=100.0)
    grid.set_closed_boundaries_at_grid_edges(False, True, False, True)
    grid.add_zeros("node", "topographic__elevation")
    grid.add_ones("node", "soil__depth")
    lith = grid.add_zeros("node", "lithology_contact__elevation")
    lith[grid.core_nodes[:9]] = -100000.0
    lith[grid.core_nodes[9:]] = 100000.0
    return grid
Exemple #18
0
def grid_2():
    grid = RasterModelGrid((8, 20), xy_spacing=100.0)
    grid.set_closed_boundaries_at_grid_edges(False, True, False, True)
    grid.add_zeros("node", "topographic__elevation")
    grid.add_ones("node", "soil__depth")
    lith = grid.add_zeros("node", "lithology_contact__elevation")
    lith[:80] = 10
    lith[80:] = -10000.0
    return grid
Exemple #19
0
def test_flow_director_steepest_flow__link_dir_field_creation():
    mg = RasterModelGrid((3, 3))
    mg.set_closed_boundaries_at_grid_edges(True, True, True, False)
    z = mg.add_field("topographic__elevation", mg.node_x + mg.node_y, at="node")
    mg.add_ones("flow_link_direction", at="link", dtype=int)
    fd = FlowDirectorSteepest(mg, z)
    assert_array_equal(
        fd.flow_link_direction, np.array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
    )
Exemple #20
0
def test_stream_power_save_output(tmpdir):

    mg = RasterModelGrid((3, 3), xy_spacing=10.0)
    mg.set_status_at_node_on_edges(
        right=mg.BC_NODE_IS_CLOSED,
        top=mg.BC_NODE_IS_CLOSED,
        left=mg.BC_NODE_IS_CLOSED,
        bottom=mg.BC_NODE_IS_FIXED_VALUE,
    )
    mg.add_ones("node", "topographic__elevation")
    mg.add_zeros("node", "aquifer_base__elevation")
    mg.add_ones("node", "water_table__elevation")

    gdp = GroundwaterDupuitPercolator(mg, recharge_rate=1e-4)
    hm = HydrologySteadyStreamPower(mg, groundwater_model=gdp)
    sp = FastscapeEroder(
        mg,
        K_sp=1e-10,
        m_sp=1,
        n_sp=1,
        discharge_field="surface_water_area_norm__discharge",
    )
    ld = LinearDiffuser(mg, linear_diffusivity=1e-10)
    rm = RegolithConstantThickness(mg, uplift_rate=0.0)

    output = {}
    output["output_interval"] = 1000
    output["output_fields"] = [
        "at_node:topographic__elevation",
        "at_node:aquifer_base__elevation",
        "at_node:water_table__elevation",
    ]
    output["base_output_path"] = tmpdir.strpath + "/"
    output["run_id"] = 0  # make this task_id if multiple runs

    mdl = StreamPowerModel(
        mg,
        hydrology_model=hm,
        diffusion_model=ld,
        erosion_model=sp,
        regolith_model=rm,
        total_morphological_time=1e8,
        output_dict=output,
    )

    mdl.run_model()

    file = tmpdir.join("0_grid_0.nc")
    mg1 = from_netcdf(file.strpath)
    keys = [
        "topographic__elevation",
        "aquifer_base__elevation",
        "water_table__elevation",
    ]
    assert isinstance(mg1, RasterModelGrid)
    assert set(mg1.at_node.keys()) == set(keys)
    assert_equal(mg1.status_at_node, mg.status_at_node)
Exemple #21
0
def test_stoch_sp_raster_record_state():
    """
    Initialize HydrologyEventStreamPower on a raster grid.
    Use several storm-interstorm pairs and make sure state recorded
    as expected.
    """

    mg = RasterModelGrid((3, 3), xy_spacing=10.0)
    mg.set_status_at_node_on_edges(
        right=mg.BC_NODE_IS_CLOSED,
        top=mg.BC_NODE_IS_CLOSED,
        left=mg.BC_NODE_IS_CLOSED,
        bottom=mg.BC_NODE_IS_FIXED_VALUE,
    )
    mg.add_ones("node", "topographic__elevation")
    mg.add_zeros("node", "aquifer_base__elevation")
    wt = mg.add_ones("node", "water_table__elevation")

    gdp = GroundwaterDupuitPercolator(mg, recharge_rate=1e-6)
    pd = PrecipitationDistribution(
        mg,
        mean_storm_duration=10,
        mean_interstorm_duration=100,
        mean_storm_depth=1e-3,
        total_t=200,
    )
    pd.seed_generator(seedval=1)
    hm = HydrologyEventStreamPower(mg,
                                   precip_generator=pd,
                                   groundwater_model=gdp)

    wt0 = wt.copy()
    hm.run_step_record_state()

    times = np.array([
        0.0,
        hm.storm_dts[0],
        hm.storm_dts[0] + hm.interstorm_dts[0],
        hm.storm_dts[0] + hm.interstorm_dts[0] + hm.storm_dts[1],
        hm.storm_dts[0] + hm.interstorm_dts[0] + hm.storm_dts[1] +
        hm.interstorm_dts[1],
    ])
    intensities = np.zeros(5)
    intensities[0] = hm.intensities[0]
    intensities[2] = hm.intensities[1]

    assert_equal(hm.time, times)
    assert_equal(hm.intensity, intensities)

    assert_equal(hm.qs_all.shape, (5, 9))
    assert_equal(hm.Q_all.shape, (5, 9))
    assert_equal(hm.wt_all.shape, (5, 9))

    assert_equal(hm.qs_all[0, :], np.zeros(9))
    assert_equal(hm.Q_all[0, :], np.zeros(9))
    assert_equal(hm.wt_all[0, :], wt0)
Exemple #22
0
def test_wt_above_surface_adaptive_run_step():
    grid = RasterModelGrid((3, 3))
    grid.set_closed_boundaries_at_grid_edges(True, True, True, False)
    wt = grid.add_ones("node", "water_table__elevation")
    _ = grid.add_ones("node", "topographic__elevation")
    _ = grid.add_zeros("node", "aquifer_base__elevation")

    # initialize the groundwater model
    gdp = GroundwaterDupuitPercolator(grid, recharge_rate=0.0)
    gdp.run_with_adaptive_time_step_solver(1)
    assert_equal(wt[4], 1)
Exemple #23
0
def test_include_keyword_is_empty(tmpdir, format, include):
    grid = RasterModelGrid((4, 3),
                           xy_spacing=(2, 5),
                           xy_of_lower_left=(-2.0, 10.0))
    grid.add_ones("elev", at="node")
    grid.add_zeros("elev", at="link")
    grid.add_empty("temp", at="node")

    with tmpdir.as_cwd():
        to_netcdf(grid, "test.nc", format=format)
        actual = from_netcdf("test.nc", include=include)
        assert len(actual.at_node) == 0
        assert len(actual.at_link) == 0
Exemple #24
0
def test_sheetflow():
    flux = np.array(
        [1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+06,
         1.87867966e+06,   2.72182541e+06,   3.54415588e+06,
         4.35303038e+06,   5.15223689e+06,   5.94408409e+06,
         6.73016503e+06,   6.51166745e+06,   1.00000000e+00,
         1.00000000e+06,   2.12132034e+06,   3.24264069e+06,
         4.35965005e+06,   5.47056275e+06,   6.57568517e+06,
         7.67583899e+06,   8.77188984e+06,   8.86460677e+06,
         1.00000000e+00,   1.00000000e+06,   2.00000000e+06,
         3.03553391e+06,   4.08578644e+06,   5.14392129e+06,
         6.20695360e+06,   7.27341175e+06,   8.34244102e+06,
         8.41347211e+06,   1.00000000e+00,   1.00000000e+06,
         2.00000000e+06,   3.00000000e+06,   4.01040764e+06,
         5.03248558e+06,   6.06512434e+06,   7.10666517e+06,
         8.15550411e+06,   8.21025766e+06,   1.00000000e+00,
         1.00000000e+06,   2.00000000e+06,   3.00000000e+06,
         4.01040764e+06,   5.03248558e+06,   6.06512434e+06,
         7.10666517e+06,   8.15550411e+06,   8.21025766e+06,
         1.00000000e+00,   1.00000000e+06,   2.00000000e+06,
         3.03553391e+06,   4.08578644e+06,   5.14392129e+06,
         6.20695360e+06,   7.27341175e+06,   8.34244102e+06,
         8.41347211e+06,   1.00000000e+00,   1.00000000e+06,
         2.12132034e+06,   3.24264069e+06,   4.35965005e+06,
         5.47056275e+06,   6.57568517e+06,   7.67583899e+06,
         8.77188984e+06,   8.86460677e+06,   1.00000000e+00,
         1.00000000e+06,   1.87867966e+06,   2.72182541e+06,
         3.54415588e+06,   4.35303038e+06,   5.15223689e+06,
         5.94408409e+06,   6.73016503e+06,   6.51166745e+06,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00])

    mg = RasterModelGrid((NROWS, NCOLS), (DX, DX))
    z = (3000. - mg.node_x) * 0.5
    mg.at_node['topographic__elevation'] = z

    mg.set_closed_boundaries_at_grid_edges(False, True, True, True)
    mg.add_ones('node', 'water__unit_flux_in')

    pfr = PotentialityFlowRouter(mg)
    pfr.route_flow()

    assert_allclose(mg.at_node['surface_water__discharge'], flux)
def test_sheetflow():
    flux = np.array(
        [1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+06,
         1.87867966e+06,   2.72182541e+06,   3.54415588e+06,
         4.35303038e+06,   5.15223689e+06,   5.94408409e+06,
         6.73016503e+06,   6.51166745e+06,   1.00000000e+00,
         1.00000000e+06,   2.12132034e+06,   3.24264069e+06,
         4.35965005e+06,   5.47056275e+06,   6.57568517e+06,
         7.67583899e+06,   8.77188984e+06,   8.86460677e+06,
         1.00000000e+00,   1.00000000e+06,   2.00000000e+06,
         3.03553391e+06,   4.08578644e+06,   5.14392129e+06,
         6.20695360e+06,   7.27341175e+06,   8.34244102e+06,
         8.41347211e+06,   1.00000000e+00,   1.00000000e+06,
         2.00000000e+06,   3.00000000e+06,   4.01040764e+06,
         5.03248558e+06,   6.06512434e+06,   7.10666517e+06,
         8.15550411e+06,   8.21025766e+06,   1.00000000e+00,
         1.00000000e+06,   2.00000000e+06,   3.00000000e+06,
         4.01040764e+06,   5.03248558e+06,   6.06512434e+06,
         7.10666517e+06,   8.15550411e+06,   8.21025766e+06,
         1.00000000e+00,   1.00000000e+06,   2.00000000e+06,
         3.03553391e+06,   4.08578644e+06,   5.14392129e+06,
         6.20695360e+06,   7.27341175e+06,   8.34244102e+06,
         8.41347211e+06,   1.00000000e+00,   1.00000000e+06,
         2.12132034e+06,   3.24264069e+06,   4.35965005e+06,
         5.47056275e+06,   6.57568517e+06,   7.67583899e+06,
         8.77188984e+06,   8.86460677e+06,   1.00000000e+00,
         1.00000000e+06,   1.87867966e+06,   2.72182541e+06,
         3.54415588e+06,   4.35303038e+06,   5.15223689e+06,
         5.94408409e+06,   6.73016503e+06,   6.51166745e+06,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00,   1.00000000e+00,   1.00000000e+00,
         1.00000000e+00])

    mg = RasterModelGrid((NROWS, NCOLS), (DX, DX))
    z = (3000. - mg.node_x) * 0.5
    mg.at_node['topographic__elevation'] = z

    mg.set_closed_boundaries_at_grid_edges(False, True, True, True)
    mg.add_ones('node', 'water__unit_flux_in')

    pfr = PotentialityFlowRouter(mg)
    pfr.route_flow()

    assert_allclose(mg.at_node['water__discharge'], flux)
Exemple #26
0
def test_stoch_sp_threshold_above_threshold():
    """
    Test the stochastic event model with stream power threshold in which
    the one core node is set up to exceed erosion threshold for the value
    of Q that it attains. This can be checked by comparing the accumulated q
    to the threshold value needed for erosion Q0.
    """

    mg = RasterModelGrid((3, 3), xy_spacing=10.0)
    mg.set_status_at_node_on_edges(
        right=mg.BC_NODE_IS_CLOSED,
        top=mg.BC_NODE_IS_CLOSED,
        left=mg.BC_NODE_IS_CLOSED,
        bottom=mg.BC_NODE_IS_FIXED_VALUE,
    )
    elev = mg.add_ones("node", "topographic__elevation")
    mg.add_zeros("node", "aquifer_base__elevation")
    wt = mg.add_ones("node", "water_table__elevation")
    elev[4] += 0.01
    wt[:] = elev

    gdp = GroundwaterDupuitPercolator(mg, recharge_rate=1e-6)
    pd = PrecipitationDistribution(
        mg,
        mean_storm_duration=10,
        mean_interstorm_duration=100,
        mean_storm_depth=1e-3,
        total_t=100,
    )
    pd.seed_generator(seedval=1)
    hm = HydrologyEventThresholdStreamPower(
        mg,
        precip_generator=pd,
        groundwater_model=gdp,
        sp_coefficient=1e-5,
        sp_threshold=1e-12,
    )

    hm.run_step()

    storm_dt = 1.4429106411  # storm duration
    storm_q = 0.0244046740  # accumulated q before threshold effect subtracted
    interstorm_q = 0.0  # interstorm q is zero in this case
    assert_almost_equal(
        hm.q_eff[4],
        0.5 * (max(interstorm_q - hm.Q0[4], 0) + max(storm_q - hm.Q0[4], 0)) *
        storm_dt / hm.T_h,
    )
Exemple #27
0
 def _test():
     rmg = RasterModelGrid(4, 5)
     number_of_elements = rmg.number_of_elements(element)
     rtn_values = rmg.add_ones(element, 'name')
     assert_is(rtn_values, rmg.field_values(element, 'name'))
     assert_array_equal(rtn_values,
                        np.ones(number_of_elements, dtype=np.float))
 def _test():
     rmg = RasterModelGrid(4, 5)
     number_of_elements = rmg.number_of_elements(element)
     rtn_values = rmg.add_ones(element, 'name')
     assert_is(rtn_values, rmg.field_values(element, 'name'))
     assert_array_equal(
         rtn_values, np.ones(number_of_elements, dtype=np.float))
Exemple #29
0
def test_add_ones(graph_element):
    grid = RasterModelGrid((4, 5))
    number_of_elements = grid.number_of_elements(graph_element)
    rtn_values = grid.add_ones("name", at=graph_element, dtype=field_dtype)
    assert rtn_values is grid.field_values(graph_element, "name")
    assert np.all(
        rtn_values == approx(np.ones(number_of_elements, dtype=field_dtype)))
Exemple #30
0
def test_callback_func():
    """
    Test the use of a callback function to return the storage and
    substep durations while using the run_with_adaptive_time_step_solver
    method.

    Notes:
    ----
    Two tests here: make sure that the substeps sum to the global timestep,
    and make sure that when recharge is 0.0, the total storage does not
    increase during any of the substeps. See component documentation for
    more detail on arguments for the callback_fun.
    """

    # make a function that writes storage and substep duration to
    # externally defined lists
    storage_subdt = []
    subdt = []
    all_n = []

    def test_fun(grid, recharge, dt, n=0.2):
        cores = grid.core_nodes
        h = grid.at_node["aquifer__thickness"]
        area = grid.cell_area_at_node
        storage = np.sum(n * h[cores] * area[cores])

        storage_subdt.append(storage)
        subdt.append(dt)
        all_n.append(n)

    # initialize grid
    grid = RasterModelGrid((3, 3))
    grid.set_closed_boundaries_at_grid_edges(True, True, False, True)
    elev = grid.add_ones("topographic__elevation", at="node")
    elev[3] = 0.1
    grid.add_zeros("aquifer_base__elevation", at="node")
    wt = grid.add_zeros("water_table__elevation", at="node")
    wt[:] = elev

    # initialize groundwater model
    gdp = GroundwaterDupuitPercolator(
        grid,
        recharge_rate=0.0,
        hydraulic_conductivity=0.0001,
        callback_fun=test_fun,
        n=0.1,
    )

    # run groundawter model
    gdp.run_with_adaptive_time_step_solver(1e5)

    # assert that the water table does not increase during substeps
    assert (np.diff(storage_subdt) <= 0.0).all()

    # assert that substeps sum to the global timestep
    assert_almost_equal(1e5, sum(subdt))

    assert all(x == 0.1 for x in all_n)
Exemple #31
0
def test_outlet_lowering_rate_no_scaling_bedrock():
    """Test using an outlet lowering rate with no scaling and bedrock."""

    mg = RasterModelGrid((5, 5))
    z = mg.add_ones("node", "topographic__elevation")
    b = mg.add_zeros("node", "bedrock__elevation")

    bh = NotCoreNodeBaselevelHandler(
        mg, modify_core_nodes=True, lowering_rate=-0.1
    )
    for _ in range(240):
        bh.run_one_step(10)

    closed = mg.status_at_node != 0
    not_closed = mg.status_at_node == 0

    # closed should have stayed the same
    assert_array_equal(z[closed], np.ones(np.sum(closed)))
    assert_array_equal(b[closed], np.zeros(np.sum(closed)))

    # not closed should have been uplifted 2410*0.1
    assert_array_equal(b[not_closed], 240.0 * np.ones(np.sum(not_closed)))
    assert_array_equal(z[not_closed], 241.0 * np.ones(np.sum(not_closed)))

    # % doing the oposite should also work
    mg = RasterModelGrid((5, 5))
    z = mg.add_ones("node", "topographic__elevation")
    b = mg.add_zeros("node", "bedrock__elevation")

    bh = NotCoreNodeBaselevelHandler(
        mg, modify_core_nodes=False, lowering_rate=-0.1
    )
    for _ in range(240):
        bh.run_one_step(10)

    closed = mg.status_at_node != 0
    not_closed = mg.status_at_node == 0

    # not closed should have staued the same
    assert_array_equal(z[not_closed], np.ones(np.sum(not_closed)))
    assert_array_equal(b[not_closed], np.zeros(np.sum(not_closed)))

    # closed should have lowered by 240
    assert_array_equal(b[closed], -240.0 * np.ones(np.sum(closed)))
    assert_array_equal(z[closed], -239.0 * np.ones(np.sum(closed)))
def test_const_thickness():
    """
    Test RegolithConstantThickness and ensure fields are updated
    based on an exact solution.
    """

    mg = RasterModelGrid((3, 3), xy_spacing=10.0)

    z = mg.add_ones("node", "topographic__elevation")
    zb = mg.add_zeros("node", "aquifer_base__elevation")
    zwt = mg.add_ones("node", "water_table__elevation")

    rm = RegolithConstantThickness(mg)
    rm.run_step(1e9)

    assert_almost_equal(z[4], 1.001)
    assert_almost_equal(zb[4], 0.001)
    assert_almost_equal(zwt[4], 1.001)
Exemple #33
0
def si():
    grid = RasterModelGrid((10, 10), spacing=25)
    grid.add_ones('soil_water_infiltration__depth', at='node', dtype=float)
    grid.add_ones('surface_water__depth', at='node')
    hydraulic_conductivity = (2.5 *  (10**-5))
    grid.at_node['surface_water__depth'] *= 0.5
    grid.at_node['soil_water_infiltration__depth'] *= (10**-5)
    return SoilInfiltrationGreenAmpt(
        grid,
        hydraulic_conductivity=hydraulic_conductivity,
        soil_bulk_density=1700., rock_density=2650.,
        initial_soil_moisture_content=0.2, soil_type='silt loam',
        volume_fraction_coarse_fragments=0.6,
        coarse_sed_flag=False,
        surface_water_minimum_depth=1.e-7,
        soil_pore_size_distribution_index=None,
        soil_bubbling_pressure=None,
        wetting_front_capillary_pressure_head=None)
Exemple #34
0
def test_simple_surface_leakage():
    """test a one-node steady simulation for surface leakage.

    Notes
    ----
    This test demonstrates that at steady state when no flow is
    allowed to leave the domain through the subsurface, the surface
    water flux is equal to the recharge flux.

    """
    grid = RasterModelGrid((3, 3), xy_spacing=1.0)
    grid.set_closed_boundaries_at_grid_edges(True, True, True, True)
    grid.add_zeros("aquifer_base__elevation", at="node")
    grid.add_ones("topographic__elevation", at="node")
    gdp = GroundwaterDupuitPercolator(grid, recharge_rate=1.0e-6)

    for _ in range(1000):
        gdp.run_one_step(1e3)

    assert_almost_equal(gdp._qs[4], 1e-6)
Exemple #35
0
def test_steady_sp_raster():
    """
    Initialize HydrologySteadyStreamPower on a raster grid.
    After one timestep it returns all recharge as discharge.
    """

    mg = RasterModelGrid((3, 3), xy_spacing=10.0)
    mg.status_at_node[mg.status_at_node == 1] = 4
    mg.status_at_node[0] = 1
    mg.add_ones("node", "topographic__elevation")
    mg.add_zeros("node", "aquifer_base__elevation")
    mg.add_ones("node", "water_table__elevation")

    gdp = GroundwaterDupuitPercolator(mg, recharge_rate=1e-6)
    hm = HydrologySteadyStreamPower(mg, groundwater_model=gdp)

    hm.run_step()

    assert_almost_equal(hm.q[4], 1e-4)
    assert_almost_equal(hm.q_an[4], 1e-5)
def test_no_upstream_array():
    """Test that correct error is raised when no flow__upstream_node_order."""

    # instantiate a model grid, do not run flow accumulation on it

    mg = RasterModelGrid((30, 70))

    # Add a field called topographic__elevation to mg

    mg.add_ones("node", "topographic__elevation")

    # Run the FlowDirectorSteepest component

    fd = FlowDirectorSteepest(mg)
    fd.run_one_step()

    # test that the flow distance utility will fail because of a ValueError

    with pytest.raises(FieldError):
        calculate_flow__distance(mg)
Exemple #37
0
def si():
    grid = RasterModelGrid((10, 10), spacing=25)
    grid.add_ones('soil_water_infiltration__depth', at='node', dtype=float)
    grid.add_ones('surface_water__depth', at='node')
    hydraulic_conductivity = (2.5 * (10**-5))
    grid.at_node['surface_water__depth'] *= 0.5
    grid.at_node['soil_water_infiltration__depth'] *= (10**-5)
    return SoilInfiltrationGreenAmpt(
        grid,
        hydraulic_conductivity=hydraulic_conductivity,
        soil_bulk_density=1700.,
        rock_density=2650.,
        initial_soil_moisture_content=0.2,
        soil_type='silt loam',
        volume_fraction_coarse_fragments=0.6,
        coarse_sed_flag=False,
        surface_water_minimum_depth=1.e-7,
        soil_pore_size_distribution_index=None,
        soil_bubbling_pressure=None,
        wetting_front_capillary_pressure_head=None)
Exemple #38
0
def test_no_upstream_array():
    """Test that correct error is raised when no flow__upstream_node_order."""

    # instantiate a model grid, do not run flow accumulation on it

    mg = RasterModelGrid((30, 70))

    # Add a field called topographic__elevation to mg

    mg.add_ones("topographic__elevation", at="node")

    # Run the FlowDirectorSteepest component

    fd = FlowDirectorSteepest(mg)
    fd.run_one_step()

    # test that the flow distance utility will fail because of a ValueError

    with pytest.raises(FieldError):
        calculate_flow__distance(mg)
#Create data fields
zb=mg.add_empty('node','land_surface_elevation')
h=mg.add_zeros('node','water_thickness')
zw=mg.add_empty('node','water_elevation')
w_slope=mg.add_zeros('link','water_slope') #make all links have zero slope
q=mg.add_zeros('link','flux')

#Initialize elevation
zb[:]=zmax-valley_s*mg.node_x
zb+=side_s * np.abs(mg.node_y - mg.dx * ((num_rows - 1) / 2.0))
zw[:]=zb+h

#Define constants 
n=0.045 #roughness of bed surface 
r=mg.add_ones('node','rain_rate')
inf=mg.add_ones('node','infiltration_rate')

#Boundary conditions (ENWS)
mg.set_closed_boundaries_at_grid_edges(False, True, True, True) #water can flow out of right side

#Plot setup
nplots=10 #number of plots
tplot=int(t_max/nplots)

#Number of runs
imax=len(timearray)


#__________RUN___________#
for t in range(imax):
Exemple #40
0
def test_raster_cts():
    """
    Tests instantiation of a RasterCTS and implementation of one transition,
    with a callback function.
    """

    # Set up a small grid with no events scheduled
    mg = RasterModelGrid((4, 4))
    mg.set_closed_boundaries_at_grid_edges(True, True, True, True)
    node_state_grid = mg.add_ones("node", "node_state_map", dtype=int)
    node_state_grid[6] = 0
    ns_dict = {0: "black", 1: "white"}
    xn_list = []
    xn_list.append(Transition((1, 0, 0), (0, 1, 0), 0.1, "", True, callback_function))
    pd = mg.add_zeros("node", "property_data", dtype=int)
    pd[5] = 50
    ca = RasterCTS(
        mg, ns_dict, xn_list, node_state_grid, prop_data=pd, prop_reset_value=0
    )

    # Test the data structures
    assert ca.num_link_states == 4, "wrong number of link states"
    assert ca.prop_data[5] == 50, "error in property data"
    assert ca.num_node_states == 2, "error in num_node_states"
    assert ca.link_orientation[-1] == 0, "error in link orientation array"
    assert ca.link_state_dict[(1, 0, 0)] == 2, "error in link state dict"
    assert ca.n_trn[2] == 1, "error in n_trn"
    assert ca.node_pair[1] == (0, 1, 0), "error in cell_pair list"

    assert len(ca.priority_queue._queue) == 1, "event queue has wrong size"
    assert ca.next_trn_id.size == 24, "wrong size next_trn_id"
    assert ca.trn_id.shape == (4, 1), "wrong size for trn_to"
    assert ca.trn_id[2][0] == 0, "wrong value in trn_to"
    assert ca.trn_to[0] == 1, "wrong trn_to state"
    assert ca.trn_rate[0] == 0.1, "wrong trn rate"
    assert ca.trn_propswap[0] == 1, "wrong trn propswap"
    assert ca.trn_prop_update_fn == callback_function, "wrong prop upd"

    # Manipulate the data in the event queue for testing:

    # pop the scheduled event off the queue
    (event_time, index, event_link) = ca.priority_queue.pop()
    assert ca.priority_queue._queue == [], "event queue should now be empty but is not"

    # engineer an event
    ca.priority_queue.push(8, 1.0)
    ca.next_update[8] = 1.0
    ca.next_trn_id[8] = 0

    # run the CA
    ca.run(2.0)

    # some more tests.
    # Is current time advancing correctly? (should only go to 1.0, not 2.0)
    # Did the two nodes (5 and 6) correctly exchange states?
    # Did the property ID and data arrays get updated? Note that the "propswap"
    # should switch propids between nodes 5 and 6, and the callback function
    # should increase the value of prop_data in the "swap" node from 50 to 150.
    assert ca.current_time == 1.0, "current time incorrect"
    assert ca.node_state[5] == 0, "error in node state 5"
    assert ca.node_state[6] == 1, "error in node state 6"
def test_raster_cts():
    """
    Tests instantiation of a RasterCTS and implementation of one transition,
    with a callback function.
    """

    # Set up a small grid with no events scheduled
    mg = RasterModelGrid(4, 4, 1.0)
    mg.set_closed_boundaries_at_grid_edges(True, True, True, True)
    node_state_grid = mg.add_ones('node', 'node_state_map', dtype=int)
    node_state_grid[6] = 0
    ns_dict = { 0 : 'black', 1 : 'white' }
    xn_list = []
    xn_list.append( Transition((1,0,0), (0,1,0), 0.1, '', True, callback_function))
    pd = mg.add_zeros('node', 'property_data', dtype=int)
    pd[5] = 50
    ca = RasterCTS(mg, ns_dict, xn_list, node_state_grid, prop_data=pd,
                   prop_reset_value=0)

    # Test the data structures
    assert (ca.xn_to.size==4), 'wrong size for xn_to'
    assert (ca.xn_to.shape==(4, 1)), 'wrong size for xn_to'
    assert (ca.xn_to[2][0]==1), 'wrong value in xn_to'
    assert (len(ca.event_queue)==1), 'event queue has wrong size'
    assert (ca.num_link_states==4), 'wrong number of link states'
    assert (ca.prop_data[5]==50), 'error in property data'
    assert (ca.xn_rate[2][0]==0.1), 'error in transition rate array'
    assert (ca._active_links_at_node[1][6]==8), 'error in active link array'
    assert (ca.num_node_states==2), 'error in num_node_states'
    assert (ca.link_orientation[-1]==0), 'error in link orientation array'
    assert (ca.link_state_dict[(1, 0, 0)]==2), 'error in link state dict'
    assert (ca.n_xn[2]==1), 'error in n_xn'
    assert (ca.node_pair[1]==(0, 1, 0)), 'error in cell_pair list'

    # Manipulate the data in the event queue for testing:

    # pop the scheduled event off the queue
    ev = heappop(ca.event_queue)
    assert (ca.event_queue==[]), 'event queue should now be empty but is not'

    # engineer an event
    ev.time = 1.0
    ev.link = 8
    ev.xn_to = 1
    ev.propswap = True
    ev.prop_update_fn = callback_function
    ca.next_update[8] = 1.0

    # push it onto the event queue
    heappush(ca.event_queue, ev)

    # run the CA
    ca.run(2.0)

    # some more tests.
    # Is current time advancing correctly? (should only go to 1.0, not 2.0)
    # Did the two nodes (5 and 6) correctly exchange states?
    # Did the property ID and data arrays get updated? Note that the "propswap"
    # should switch propids between nodes 5 and 6, and the callback function
    # should increase the value of prop_data in the "swap" node from 50 to 150.
    assert (ca.current_time==1.0), 'current time incorrect'
    assert (ca.node_state[5]==0), 'error in node state 5'
    assert (ca.node_state[6]==1), 'error in node state 6'