Пример #1
0
def test_eet_attribute():
    grid = RasterModelGrid((20, 20), xy_spacing=10e3)
    grid.add_zeros("lithosphere__overlying_pressure_increment", at="node")
    for val in (10e3, 1e3):
        assert Flexure(grid, eet=val).eet == pytest.approx(val)
    with pytest.raises(ValueError):
        assert Flexure(grid, eet=-10e3)
Пример #2
0
    def initialize(self, param_filename):

        # Read parameters from input file
        params = load_params(param_filename)
        self.elastic_thickness = params['elastic_thickness']
        self.youngs_modulus = params['youngs_modulus']
        self.rho_m = params['mantle_density']
        self.grav_accel = params['gravitational_acceleration']
        self.water_surf_elev = params['water_surface_elevation']
        self.water_density = params['lake_water_density']
        self.tolerance = params['lake_elev_tolerance']

        # Read DEM
        print('Reading DEM file...')
        (self.grid, self.dem) = read_esri_ascii(params['dem_filename'])
        print('done.')

        # Store a copy that we'll modify
        self.flexed_dem = self.dem.copy()

        # Create and initialize Flexure component
        self.flexer = Flexure(self.grid,
                              eet=self.elastic_thickness,
                              youngs=self.youngs_modulus,
                              method="flexure",
                              rho_mantle=self.rho_m,
                              gravity=self.grav_accel)
        self.load = self.grid.at_node[
            'lithosphere__overlying_pressure_increment']
        self.deflection = self.grid.at_node[
            'lithosphere_surface__elevation_increment']

        self.initialized = True
Пример #3
0
def test_method_names():
    grid = RasterModelGrid((20, 20), xy_spacing=10e3)
    grid.add_zeros("lithosphere__overlying_pressure_increment", at="node")
    assert Flexure(grid, method="airy").method == "airy"
    assert Flexure(grid, method="flexure").method == "flexure"
    with pytest.raises(ValueError):
        Flexure(grid, method="bad-name")
Пример #4
0
def test_update():
    n = 11
    n_mid = (n - 1) // 2
    i_mid = np.ravel_multi_index((n_mid, n_mid), (n, n))
    load_0 = 1e9

    grid = RasterModelGrid((n, n), xy_spacing=1e3)
    flex = Flexure(grid, method="flexure")

    load = grid.at_node["lithosphere__overlying_pressure_increment"]
    load[i_mid] = load_0

    flex.update()
    dz = flex.grid.at_node["lithosphere_surface__elevation_increment"].reshape((n, n))

    assert np.argmax(dz) == i_mid
    assert dz[n_mid, n_mid] > 0.0
    assert np.all(dz[:, n_mid::-1] == dz[:, n_mid:])
    assert np.all(dz[n_mid::-1, :] == dz[n_mid:, :])
Пример #5
0
def test_subside_loads():
    n, load_0 = 11, 1e9

    grid = RasterModelGrid((n, n), xy_spacing=1e3)
    flex = Flexure(grid, method="flexure")

    grid.at_node["lithosphere__overlying_pressure_increment"][0] = load_0
    flex.update()
    dz_expected = flex.grid.at_node["lithosphere_surface__elevation_increment"]

    load = np.zeros((n, n))
    load[0, 0] = load_0

    dz = flex.subside_loads(load)
    assert np.all(dz.flatten() == pytest.approx(dz_expected))

    out = np.zeros((n, n))
    dz = flex.subside_loads(load, out=out)
    assert dz is out
Пример #6
0
def test_rho_mantle_attribute():
    grid = RasterModelGrid((20, 20), xy_spacing=10e3)
    grid.add_zeros("lithosphere__overlying_pressure_increment", at="node")
    for val in (10e3, 1e3):
        assert Flexure(grid, rho_mantle=val).rho_mantle == pytest.approx(val)
Пример #7
0
def test_with_flexure():
    """Test integrating with flexure."""
    crust_density = 2700.0  # density of crustal column, kg/m3
    dx = 2500.0  # grid spacing, m
    dt = 125000.0  # time step, y
    upper_crust_base_depth = 10000.0  # m

    grid = RasterModelGrid((3, 7), xy_spacing=dx)
    topo = grid.add_zeros("topographic__elevation", at="node")
    load = grid.add_zeros("lithosphere__overlying_pressure_increment",
                          at="node")
    thickness = grid.add_zeros("upper_crust_thickness", at="node")
    upper_crust_base = grid.add_zeros("upper_crust_base__elevation", at="node")

    extender = ListricKinematicExtender(
        grid,
        extension_rate=0.01,
        fault_location=2500.0,
        track_crustal_thickness=True,
    )
    flexer = Flexure(grid, eet=5000.0, method="flexure")
    deflection = grid.at_node["lithosphere_surface__elevation_increment"]

    topo[
        grid.x_of_node <=
        7500.0] = 1000.0  # this will force thickness to be 1 km greater at left
    upper_crust_base[:] = -upper_crust_base_depth
    thickness[:] = topo - upper_crust_base
    unit_wt = crust_density * flexer.gravity
    load[:] = unit_wt * thickness  # loading pressure

    # Get the initial deflection, which we'll need to calculate total current
    # deflection
    flexer.update()
    init_deflection = deflection.copy()

    # Run extension for half a grid cell. Elevations change, but thickness
    # doesn't, so deflection should not change. We should be able to recover
    # elevation from:
    #
    #   topo = thickness + crust base - (deflection + subsidence)
    #
    extender.run_one_step(dt=dt)
    flexer.update()
    net_deflection = deflection - init_deflection
    assert_array_almost_equal(
        net_deflection[7:14],
        [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
    )
    test_topo = thickness + upper_crust_base - (net_deflection +
                                                extender._cum_subs)
    assert_array_almost_equal(topo, test_topo)

    # Now extend for another half cell, which should force a shift. The
    # cumulative subsidence will be subtracted from the thickness field,
    # representing thinning as the hangingwall slides to the "right". This
    # will cause net upward isostatic deflection.
    extender.run_one_step(dt=dt)
    load[:] = unit_wt * thickness
    flexer.update()
    net_deflection = deflection - init_deflection
    assert_array_almost_equal(
        thickness[7:14],
        [
            11000.0,
            11000.0,
            8191.686362,  # greatest subsidence: lost nearly 3 km
            9178.66186,
            9818.767044,  # thicker because shifted (only lost <200 m)
            9233.908704,
            9503.149763,
        ],
    )
    assert_array_almost_equal(
        net_deflection[7:14],
        [
            -59.497362,
            -65.176276,
            -69.222531,
            -70.334462,
            -68.608952,
            -64.912352,
            -59.743080,
        ],
    )
Пример #8
0
class LakeFlexer():
    """Calculate elastic lithosphere flexure for a (paleo)lake.

    Landlab-built model that takes a digital elevation model and a target
    water-surface elevation, and calculates flexure resulting from the load of
    the water.
    """
    def __init__(self, param_filename=None):

        if param_filename is None:
            self.initialized = False
        else:
            self.initialize(param_filename)

    def initialize(self, param_filename):

        # Read parameters from input file
        params = load_params(param_filename)
        self.elastic_thickness = params['elastic_thickness']
        self.youngs_modulus = params['youngs_modulus']
        self.rho_m = params['mantle_density']
        self.grav_accel = params['gravitational_acceleration']
        self.water_surf_elev = params['water_surface_elevation']
        self.water_density = params['lake_water_density']
        self.tolerance = params['lake_elev_tolerance']

        # Read DEM
        print('Reading DEM file...')
        (self.grid, self.dem) = read_esri_ascii(params['dem_filename'])
        print('done.')

        # Store a copy that we'll modify
        self.flexed_dem = self.dem.copy()

        # Create and initialize Flexure component
        self.flexer = Flexure(self.grid,
                              eet=self.elastic_thickness,
                              youngs=self.youngs_modulus,
                              method="flexure",
                              rho_mantle=self.rho_m,
                              gravity=self.grav_accel)
        self.load = self.grid.at_node[
            'lithosphere__overlying_pressure_increment']
        self.deflection = self.grid.at_node[
            'lithosphere_surface__elevation_increment']

        self.initialized = True

    def update(self):

        # Make sure model has been initialized
        try:
            if self.initialized == False:
                raise RuntimeError('LakeFlexer must be initialized before' +
                                   'calling update()')
        except RuntimeError:
            raise

        i = 0
        done = False
        while not done:

            print('Iteration ' + str(i) + ':')

            # Calculate water depths
            print('  calculating water depth and loads...')
            self.water_depth = self.water_surf_elev - self.flexed_dem
            self.water_depth[self.water_depth < 0.0] = 0.0

            # Calculate loads
            self.load[:] = (self.water_density * self.grav_accel *
                            self.water_depth)

            # Calculate flexure and adjust elevations
            print('  calculating flexure...')
            self.flexer.update()
            self.flexed_dem = self.dem - self.deflection

            # Compare modeled and desired water-surface elevations
            flexed_wse = (self.flexed_dem[self.water_depth > 0.0] +
                          self.water_depth[self.water_depth > 0.0])
            residual = self.water_surf_elev - flexed_wse
            print('  max residual = ' + str(np.amax(np.abs(residual))))
            if np.amax(np.abs(residual)) < self.tolerance:
                done = True

            i += 1
            if i > MAX_ITERATIONS:
                print('Warning: maximum number of iterations exceeded')
                done = True

        print('Done. Maximum deflextion = ' + str(np.amax(self.deflection)) +
              ' meters.')

    def finalize(self):
        """Output data to file."""
        write_netcdf("lake_flex.nc", self.grid)
Пример #9
0
def test_rho_mantle_attribute():
    grid = RasterModelGrid((20, 20), xy_spacing=10e3)
    for val in (10e3, 1e3):
        assert Flexure(grid, rho_mantle=val).rho_mantle == pytest.approx(val)
Пример #10
0
def test_gravity_attribute():
    grid = RasterModelGrid((20, 20), xy_spacing=10e3)
    for val in (10e3, 1e3):
        assert Flexure(grid, gravity=val).gravity == pytest.approx(val)
Пример #11
0
def test_youngs_attribute():
    grid = RasterModelGrid((20, 20), xy_spacing=10e3)
    for val in (10e3, 1e3):
        assert Flexure(grid, youngs=val).youngs == pytest.approx(val)
Пример #12
0
def test_eet_attribute():
    grid = RasterModelGrid((20, 20), xy_spacing=10e3)
    for val in (10e3, 1e3):
        assert Flexure(grid, eet=val).eet == pytest.approx(val)
    with pytest.raises(ValueError):
        assert Flexure(grid, eet=-10e3)
Пример #13
0
def test_method_names():
    grid = RasterModelGrid((20, 20), xy_spacing=10e3)
    assert Flexure(grid, method="airy").method == "airy"
    assert Flexure(grid, method="flexure").method == "flexure"
    with pytest.raises(ValueError):
        Flexure(grid, method="bad-name")