コード例 #1
0
def test_symmetry_of_solution():
    """test that water table is symmetric under constant recharge

    Notes:
    ----
    Under constant recharge with radially symmetric aquifer base elevation,
    the model should produce a water table that is radially symmetric. This test
    demonstrates this is the case where topographic elevation and aquifer
    base elevation are radially symmetric parabolas on a hexagonal grid.

    """
    hmg = HexModelGrid(shape=(7, 4), spacing=10.0)
    x = hmg.x_of_node
    y = hmg.y_of_node
    elev = hmg.add_zeros("topographic__elevation", at="node")
    elev[:] = 1e-3 * (x * (max(x) - x) + y * (max(y) - y)) + 2
    base = hmg.add_zeros("aquifer_base__elevation", at="node")
    base[:] = elev - 2
    wt = hmg.add_zeros("water_table__elevation", at="node")
    wt[:] = elev
    wt[hmg.open_boundary_nodes] = 0.0

    gdp = GroundwaterDupuitPercolator(hmg,
                                      recharge_rate=1e-7,
                                      hydraulic_conductivity=1e-4)
    for _ in range(1000):
        gdp.run_one_step(1e3)

    tc = hmg.at_node["aquifer__thickness"]
    assert_almost_equal(tc[5], tc[31])  # SW-NE
    assert_almost_equal(tc[29], tc[7])  # NW-SE
    assert_almost_equal(tc[16], tc[20])  # W-E
コード例 #2
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)
コード例 #3
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)
コード例 #4
0
def test_inactive_interior_node():
    """
    Test that component returns correct values for recharge flux and
    storage when an interior node is INACTIVE

    Notes:
    ----
    When an interior node is inactive, the number of core nodes is not
    equal to the number of cells. This test confirms that the methods
    to calculate recharge flux and active storage acknowledge this difference.

    """

    mg = RasterModelGrid((4, 4), xy_spacing=1.0)
    mg.status_at_node[5] = mg.BC_NODE_IS_FIXED_VALUE
    elev = mg.add_zeros("node", "topographic__elevation")
    elev[:] = 1
    base = mg.add_zeros("node", "aquifer_base__elevation")
    base[:] = 0
    wt = mg.add_zeros("node", "water_table__elevation")
    wt[:] = 1

    gdp = GroundwaterDupuitPercolator(mg)
    assert_almost_equal(gdp.calc_recharge_flux_in(), 3e-8)
    assert_almost_equal(gdp.calc_total_storage(), 0.6)
コード例 #5
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)
コード例 #6
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)
コード例 #7
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)
コード例 #8
0
def test_conservation_of_mass_adaptive_dt():
    """test conservation of mass in a sloping aquifer.

    Notes
    ----
    This test demonstrates conservation of mass from a sloping aquifer
    with constant recharge using the flux and storage calculation methods.
    Note that there is a slight loss of mass as the adaptive timestep solver
    does not calculate fluxes in the intermediate substeps, so accuracy in
    this case is only to ~3 significant digits.
    """

    grid = RasterModelGrid((3, 10), xy_spacing=10.0)
    grid.set_closed_boundaries_at_grid_edges(True, True, False, True)
    elev = grid.add_zeros("topographic__elevation", at="node")
    grid.add_zeros("aquifer_base__elevation", at="node")

    elev[:] = grid.x_of_node / 100 + 1
    wt = grid.add_zeros("water_table__elevation", at="node")
    wt[:] = elev

    # initialize the groundwater model
    gdp = GroundwaterDupuitPercolator(
        grid,
        hydraulic_conductivity=0.0005,
        recharge_rate=1e-7,
        courant_coefficient=0.01,
    )
    fa = FlowAccumulator(grid, runoff_rate="surface_water__specific_discharge")

    # initialize fluxes we will record
    recharge_flux = 0
    gw_flux = 0
    sw_flux = 0
    storage_0 = gdp.calc_total_storage()

    dt = 1e4
    for _ in range(500):
        gdp.run_with_adaptive_time_step_solver(dt)
        fa.run_one_step()

        recharge_flux += gdp.calc_recharge_flux_in() * dt
        gw_flux += gdp.calc_gw_flux_out() * dt
        sw_flux += gdp.calc_sw_flux_out() * dt
    storage = gdp.calc_total_storage()

    assert_almost_equal(
        (gw_flux + sw_flux + storage - storage_0) / recharge_flux,
        1.0,
        decimal=3)
コード例 #9
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)
コード例 #10
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)
コード例 #11
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)

    gdp = GroundwaterDupuitPercolator(grid, recharge_rate=1.0e-6)

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

    assert_almost_equal(gdp._qs[4], 1e-6)
コード例 #12
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 thickness at the boundary in this test is H/2. Therefore:

        K H^2 / 2 = R, or

        H = sqrt( 2 R / K ).

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

        H ~ 0.00141 m.
    """
    boundaries = {"top": "closed", "left": "closed", "bottom": "closed"}
    rg = RasterModelGrid((3, 3), bc=boundaries)
    gdp = GroundwaterDupuitPercolator(rg,
                                      recharge_rate=1.0e-8,
                                      hydraulic_conductivity=0.01)
    for i in range(12):
        gdp.run_one_step(5.0e4)

    assert_equal(np.round(gdp._thickness[4], 5), 0.00141)

    # Re-instantiate to test the case when the necessary fields already exist
    gdp = GroundwaterDupuitPercolator(rg)
コード例 #13
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,
    )
コード例 #14
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)
コード例 #15
0
def test_stream_power_run_model_subdivide():

    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,
    )
    z = mg.add_ones("node", "topographic__elevation")
    z[1] = 1e-15
    zb = 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)

    mdl = StreamPowerModel(
        mg,
        hydrology_model=hm,
        diffusion_model=ld,
        erosion_model=sp,
        regolith_model=rm,
        total_morphological_time=1e8,
        maximum_morphological_dt=2e7,
    )

    mdl.run_step(1e5, dt_m_max=2e4)

    assert z[4] < 1.0
    assert_equal(z[4] - zb[4], 1.0)
    assert_equal(mdl.num_substeps, 5)
コード例 #16
0
def test_stoch_sp_threshold_hex():
    """
    Initialize HydrologyEventStreamPower on a hex grid.
    Use single storm-interstorm pair and make sure it returns the
    quantity calculated. This is not an analytical solution, just
    the value that is returned when using gdp and adaptive
    timestep solver. Confirms that hex grid returns the same value
    as raster grid, adjusted for cell area. Confirms that when streampower
    threshold is zero (Default), returns the same values as
    HydrologyEventStreamPower.
    """

    mg = HexModelGrid((3, 3), node_layout="rect", 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)
    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,
                                            routing_method="Steepest")

    hm.run_step()

    assert_almost_equal(hm.q_eff[4], 0.00017614 * np.sqrt(3) / 2)
    assert_almost_equal(
        hm.q_an[4],
        0.00017614 * np.sqrt(3) / 2 / np.sqrt(np.sqrt(3) / 2 * 100))
コード例 #17
0
def test_stoch_sp_threshold_raster_null():
    """
    Initialize HydrologyEventThresholdStreamPower on a raster grid.
    Use single storm-interstorm pair and make sure it returns the
    quantity calculated. This is not an analytical solution, just
    the value that is returned when using gdp and adaptive
    timestep solver. Confirms that when streampower threshold is
    zero (Default), returns the same values as HydrologyEventStreamPower.
    """

    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-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)

    hm.run_step()

    assert_almost_equal(hm.q_eff[4], 0.00017614)
    assert_almost_equal(hm.q_an[4], 0.00017614 / 10.0)
コード例 #18
0
def test_steady_sp_hex():
    """
    Initialize HydrologySteadyStreamPower on a hex grid.
    After one timestep it returns all recharge as discharge.
    """

    mg = HexModelGrid((3, 3), node_layout="rect", 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,
                                    routing_method="Steepest")

    hm.run_step()

    assert_almost_equal(hm.q[4], (np.sqrt(3) / 2) * 10**(-4))
    assert_almost_equal(hm.q_an[4], np.sqrt((np.sqrt(3) / 2)) * 10**(-5))
コード例 #19
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)
    gdp = GroundwaterDupuitPercolator(rg,
                                      recharge_rate=1.0e-8,
                                      hydraulic_conductivity=0.01)
    for i in range(10):
        gdp.run_with_adaptive_time_step_solver(1e4, courant_coefficient=0.01)

    assert_equal(np.round(gdp._thickness[4], 5), 0.001)

    # Re-instantiate to test the case when the necessary fields already exist
    gdp = GroundwaterDupuitPercolator(rg)
コード例 #20
0
                     index=True)

Ks = df_params['ksat']  # hydraulic conductivity [m/s]
p = df_params['p']  # recharge rate [m/s]
n = df_params['n']  # drainable porosity [-]
b = df_params['b']  # characteristic depth  [m]
Th = df_params['Th']  # hydrological timestep
tg = df_params['tg']
dtg = df_params['dtg']
hg = df_params['hg']

gdp = GroundwaterDupuitPercolator(
    mg,
    porosity=n,
    hydraulic_conductivity=Ks,
    regularization_f=0.01,
    recharge_rate=p,
    courant_coefficient=0.01,  #*Ks/1e-5,
    vn_coefficient=0.01,  #*Ks/1e-5,
)

hm = HydrologySteadyStreamPower(
    mg,
    groundwater_model=gdp,
    hydrological_timestep=Th,
    routing_method='D8' if isinstance(mg, RasterModelGrid) else 'Steepest',
)

#run model
for i in tqdm(range(500), desc="Completion"):
    hm.run_step()
コード例 #21
0
def test_k_func():
    """
    Test the use of a function to specify how hydraulic conductivity changes
    with water table position.

    Note:
    ----
    Test that component keeps hydraulic conductivity at default value when
    k_func is None. Then test that a simple function correctly sets the
    hydraulic conductivity value after run_one_step and run_with_adaptive_time_step_solver.

    """

    # initialize model grid
    mg = RasterModelGrid((4, 4), xy_spacing=1.0)
    elev = mg.add_zeros("node", "topographic__elevation")
    elev[:] = 1
    base = mg.add_zeros("node", "aquifer_base__elevation")
    base[:] = 0
    wt = mg.add_zeros("node", "water_table__elevation")
    wt[:] = 0.5

    # initialize model without giving k_func
    gdp = GroundwaterDupuitPercolator(mg)

    # run model and assert that K hasn't changed from the default value
    gdp.run_one_step(0)
    assert np.equal(0.001, gdp.K).all()

    gdp.run_with_adaptive_time_step_solver(0)
    assert np.equal(0.001, gdp.K).all()

    # create a simple k_func, where hydraulic conductivity varies linearly
    # with depth, from Ks at surface to 0 at aquifer base
    def k_func_test(grid, Ks=0.01):
        h = grid.at_node["aquifer__thickness"]
        b = (grid.at_node["topographic__elevation"] -
             grid.at_node["aquifer_base__elevation"])
        blink = map_mean_of_link_nodes_to_link(grid, b)
        hlink = map_mean_of_link_nodes_to_link(grid, h)

        return (hlink / blink) * Ks

    # initialize model with given k_func
    gdp1 = GroundwaterDupuitPercolator(mg, hydraulic_conductivity=k_func_test)

    # run model and assert that K has been updated correctly
    gdp1.run_one_step(0)
    assert np.equal(0.005, gdp1.K).all()

    gdp1.run_with_adaptive_time_step_solver(0)
    assert np.equal(0.005, gdp1.K).all()
コード例 #22
0
output["run_id"] = ID  #make this task_id if multiple runs

#initialize grid
np.random.seed(12345)
grid = RasterModelGrid((125, 125), xy_spacing=v0)
grid.set_status_at_node_on_edges(right=grid.BC_NODE_IS_CLOSED, top=grid.BC_NODE_IS_CLOSED, \
                              left=grid.BC_NODE_IS_FIXED_VALUE, bottom=grid.BC_NODE_IS_CLOSED)
elev = grid.add_zeros('node', 'topographic__elevation')
elev[:] = b + 0.1 * hg * np.random.rand(len(elev))
base = grid.add_zeros('node', 'aquifer_base__elevation')
wt = grid.add_zeros('node', 'water_table__elevation')
wt[:] = elev.copy()

#initialize landlab components
gdp = GroundwaterDupuitPercolator(grid, porosity=n, hydraulic_conductivity=ksat, \
                                  regularization_f=0.01, recharge_rate=0.0, \
                                  courant_coefficient=0.9, vn_coefficient = 0.9)
pd = PrecipitationDistribution(grid,
                               mean_storm_duration=tr,
                               mean_interstorm_duration=tb,
                               mean_storm_depth=ds,
                               total_t=Th)
pd.seed_generator(seedval=1235)
ld = LinearDiffuser(grid, linear_diffusivity=D)

#initialize other models
hm = HydrologyEventStreamPower(
    grid,
    precip_generator=pd,
    groundwater_model=gdp,
)
コード例 #23
0
    file.write('%f, %f, %f, %f, %f\n' % (dt, r_tot, qs_tot, storage, qs_nodes))


#initialize components
if isinstance(mg, RasterModelGrid):
    method = 'D8'
elif isinstance(mg, HexModelGrid):
    method = 'Steepest'
else:
    raise TypeError("grid should be Raster or Hex")

gdp = GroundwaterDupuitPercolator(
    mg,
    porosity=n,
    hydraulic_conductivity=Ks,
    regularization_f=0.01,
    recharge_rate=0.0,
    courant_coefficient=0.05,
    vn_coefficient=0.05,
    callback_fun=write_SQ,
)
pdr = PrecipitationDistribution(mg,
                                mean_storm_duration=tr,
                                mean_interstorm_duration=tb,
                                mean_storm_depth=ds,
                                total_t=T_h)
pdr.seed_generator(seedval=2)

hm = HydrologyEventStreamPower(
    mg,
    routing_method=method,
    precip_generator=pdr,
コード例 #24
0
                              left=grid.BC_NODE_IS_FIXED_VALUE, bottom=grid.BC_NODE_IS_CLOSED)
elev = grid.add_zeros('node', 'topographic__elevation')
x = grid.x_of_node
z =  calc_z(x, sc, U, D) - calc_z(x[-1], sc, U, D)
z = np.fliplr(z.reshape(grid.shape))
elev[:] = z.flatten()
base = grid.add_zeros('node', 'aquifer_base__elevation')
base[:] = elev - b
wt = grid.add_zeros('node', 'water_table__elevation')
wt[:] = elev

# initialize landlab and DupuitLEM components
gdp = GroundwaterDupuitPercolator(grid,
                                  porosity=n,
                                  hydraulic_conductivity=ks,
                                  recharge_rate=0.0,
                                  vn_coefficient=0.5,
                                  courant_coefficient=0.5,
                                  )
pdr = PrecipitationDistribution(grid,
                               mean_storm_duration=tr,
                               mean_interstorm_duration=tb,
                               mean_storm_depth=ds,
                               total_t=Nt*(tr+tb))
pdr.seed_generator(seedval=1235)
svm = SchenkVadoseModel(
                potential_evapotranspiration_rate=pet,
                 available_relative_saturation=Srange,
                 profile_depth=b,
                 porosity=n,
                 num_bins=Nz,