コード例 #1
0
ファイル: dupuit_percolator.py プロジェクト: baadams/landlab
    def run_one_step(self, dt, **kwds):
        """
        Advance component by one time step of size dt.

        Parameters
        ----------
        dt: float (time in seconds)
            The imposed timestep.
        """

        # Calculate base gradient
        self._base_grad[
            self._grid.active_links] = self._grid.calc_grad_at_link(
                self._base)[self._grid.active_links]

        # Calculate hydraulic gradient
        self._hydr_grad[
            self._grid.active_links] = self._grid.calc_grad_at_link(
                self._thickness)[self._grid.active_links]

        # Calculate groundwater velocity
        self._vel[:] = -self._K * (
            self._hydr_grad * np.cos(np.arctan(abs(self._base_grad))) +
            np.sin(np.arctan(self._base_grad)))
        self._vel[self._grid.status_at_link == INACTIVE_LINK] = 0.0

        # Aquifer thickness at links (upwind)
        hlink = map_value_at_max_node_to_link(self._grid,
                                              "water_table__elevation",
                                              "aquifer__thickness")

        # Calculate specific discharge
        self._q[:] = hlink * self._vel

        # Groundwater flux divergence
        dqdx = self._grid.calc_flux_div_at_node(self._q)

        # Determine the relative aquifer thickness, 1 if permeable thickness is 0.
        soil_present = self._elev - self._base > 0.0
        rel_thickness = np.ones_like(self._elev)
        rel_thickness[soil_present] = np.minimum(
            1,
            self._thickness[soil_present] /
            (self._elev[soil_present] - self._base[soil_present]),
        )

        # Calculate surface discharge at nodes
        self._qs[:] = _regularize_G(
            rel_thickness, self._r) * _regularize_R(self._recharge - dqdx)

        # Mass balance
        self._dhdt[:] = (1 / self._n) * (self._recharge - dqdx - self._qs)

        # Update
        self._thickness[self._cores] += self._dhdt[self._cores] * dt
        self._thickness[self._thickness < 0] = 0.0

        # Recalculate water surface height
        self._wtable[self._cores] = (self._base[self._cores] +
                                     self._thickness[self._cores])
コード例 #2
0
    def run_one_step(self, dt):
        """Advance component by one time step of size dt.

        Parameters
        ----------
        dt: float
            The imposed timestep.
        """

        # check water table above surface
        if (self._wtable > self._elev).any():
            warn("water table above elevation surface. "
                 "Setting water table elevation here to "
                 "elevation surface")
            self._wtable[self._wtable > self._elev] = self._elev[
                self._wtable > self._elev]
            self._thickness[self._cores] = (self._wtable -
                                            self._base)[self._cores]

        # Calculate base gradient
        self._base_grad[
            self._grid.active_links] = self._grid.calc_grad_at_link(
                self._base)[self._grid.active_links]
        cosa = np.cos(np.arctan(self._base_grad))

        # Calculate hydraulic gradient
        self._hydr_grad[self._grid.active_links] = (
            self._grid.calc_grad_at_link(self._wtable) *
            cosa)[self._grid.active_links]

        # Calculate groundwater velocity
        self._vel[:] = -self._K * self._hydr_grad

        # Aquifer thickness at links (upwind)
        hlink = (map_value_at_max_node_to_link(
            self._grid, "water_table__elevation", "aquifer__thickness") * cosa)

        # Calculate specific discharge
        self._q[:] = hlink * self._vel

        # Groundwater flux divergence
        dqdx = self._grid.calc_flux_div_at_node(self._q)

        # Regolith thickness
        reg_thickness = self._elev - self._base

        # update thickness from analytical
        self._thickness[self._cores] = _update_thickness(
            dt, self._thickness, reg_thickness, self._recharge, dqdx, self._n,
            self._r)[self._cores]
        self._thickness[self._thickness < 0] = 0.0

        # Recalculate water surface height
        self._wtable[:] = self._base + self._thickness

        # Calculate surface discharge at nodes
        self._qs[:] = _regularize_G(
            self._thickness / reg_thickness,
            self._r) * _regularize_R(self._recharge - dqdx)
コード例 #3
0
    def run_with_adaptive_time_step_solver(self, dt):
        """
        Advance component by one time step of size dt, subdividing the timestep
        into substeps as necessary to meet stability conditions.
        Note this method returns the fluxes at the last substep, but also
        returns a new field, average_surface_water__specific_discharge, that is
        averaged over all subtimesteps. To return state during substeps,
        provide a callback_fun.

        Parameters
        ----------
        dt: float
            The imposed timestep.
        """

        # check water table above surface
        if (self._wtable > self._elev).any():
            warn("water table above elevation surface. "
                 "Setting water table elevation here to "
                 "elevation surface")
            self._wtable[self._wtable > self._elev] = self._elev[
                self._wtable > self._elev]
            self._thickness[self._cores] = (self._wtable[self._cores] -
                                            self._base[self._cores])

        # Calculate base gradient
        self._base_grad[
            self._grid.active_links] = self._grid.calc_grad_at_link(
                self._base)[self._grid.active_links]
        cosa = np.cos(np.arctan(self._base_grad))

        # Initialize reg_thickness, rel_thickness
        reg_thickness = self._elev - self._base
        soil_present = reg_thickness > 0.0
        rel_thickness = np.ones_like(self._elev)

        # Initialize for average surface discharge
        qs_cumulative = np.zeros_like(self._elev)

        # Initialize variable timestep
        remaining_time = dt
        self._num_substeps = 0

        while remaining_time > 0.0:

            # Calculate hydraulic gradient
            self._hydr_grad[self._grid.active_links] = (
                self._grid.calc_grad_at_link(
                    self._wtable)[self._grid.active_links] *
                cosa[self._grid.active_links])

            # Calculate groundwater velocity
            self._vel[:] = -self._K * self._hydr_grad
            self._vel[self._grid.status_at_link == LinkStatus.INACTIVE] = 0.0

            # Aquifer thickness at links (upwind)
            hlink = (map_value_at_max_node_to_link(
                self._grid, "water_table__elevation", "aquifer__thickness") *
                     cosa)

            # Calculate specific discharge
            self._q[:] = hlink * self._vel

            # Groundwater flux divergence
            dqdx = self._grid.calc_flux_div_at_node(self._q)

            # calculate relative thickness
            rel_thickness[soil_present] = np.minimum(
                1,
                self._thickness[soil_present] / (reg_thickness[soil_present]))

            # Calculate surface discharge at nodes
            self._qs[:] = _regularize_G(
                rel_thickness, self._r) * _regularize_R(self._recharge - dqdx)

            # Mass balance
            self._dhdt[:] = (1 / self._n) * (self._recharge - self._qs - dqdx)

            # calculate criteria for timestep
            self._dt_vn = self._vn_coefficient * min(
                self._n_link * self._grid.length_of_link**2 /
                (4 * self._K * hlink))

            self._dt_courant = self._courant_coefficient * min(
                self._grid.length_of_link / abs(self._vel / self._n_link))
            dt_stability = min(self._dt_courant, self._dt_vn)
            substep_dt = min([dt_stability, remaining_time])

            # Update
            self._thickness[
                self._cores] += self._dhdt[self._cores] * substep_dt
            self._thickness[self._thickness < 0] = 0.0

            # Recalculate water surface height
            self._wtable[self._cores] = (self._base +
                                         self._thickness)[self._cores]

            # add cumulative sw discharge in substeps
            qs_cumulative += self._qs * substep_dt

            # calculate the time remaining and advance count of substeps
            remaining_time -= substep_dt
            self._num_substeps += 1

            if self._old_style_callback:
                self._callback_fun(self._grid, substep_dt,
                                   **self._callback_kwds)
            else:
                self._callback_fun(self._grid, self.recharge, substep_dt,
                                   **self._callback_kwds)

        self._qsavg[:] = qs_cumulative / dt
コード例 #4
0
    def run_one_step(self, dt):
        """Advance component by one time step of size dt.

        Parameters
        ----------
        dt: float
            The imposed timestep.
        """

        # check water table above surface
        if (self._wtable > self._elev).any():
            warn("water table above elevation surface. "
                 "Setting water table elevation here to "
                 "elevation surface")
            self._wtable[self._wtable > self._elev] = self._elev[
                self._wtable > self._elev]
            self._thickness[self._cores] = (self._wtable[self._cores] -
                                            self._base[self._cores])

        # Calculate base gradient
        self._base_grad[
            self._grid.active_links] = self._grid.calc_grad_at_link(
                self._base)[self._grid.active_links]
        cosa = np.cos(np.arctan(self._base_grad))

        # Calculate hydraulic gradient
        self._hydr_grad[self._grid.active_links] = (
            self._grid.calc_grad_at_link(self._wtable)[self._grid.active_links]
            * cosa[self._grid.active_links])

        # Calculate groundwater velocity
        self._vel[:] = -self._K * self._hydr_grad
        self._vel[self._grid.status_at_link == LinkStatus.INACTIVE] = 0.0

        # Aquifer thickness at links (upwind)
        hlink = (map_value_at_max_node_to_link(
            self._grid, "water_table__elevation", "aquifer__thickness") * cosa)

        # Calculate specific discharge
        self._q[:] = hlink * self._vel

        # Groundwater flux divergence
        dqdx = self._grid.calc_flux_div_at_node(self._q)

        # Determine the relative aquifer thickness, 1 if permeable thickness is 0.
        soil_present = (self._elev - self._base) > 0.0
        rel_thickness = np.ones_like(self._elev)
        rel_thickness[soil_present] = np.minimum(
            1,
            self._thickness[soil_present] /
            (self._elev[soil_present] - self._base[soil_present]),
        )

        # Calculate surface discharge at nodes
        self._qs[:] = _regularize_G(
            rel_thickness, self._r) * _regularize_R(self._recharge - dqdx)

        # Mass balance
        self._dhdt[:] = (1 / self._n) * (self._recharge - self._qs - dqdx)

        # Update
        self._thickness[self._cores] += self._dhdt[self._cores] * dt
        self._thickness[self._thickness < 0] = 0.0

        # Recalculate water surface height
        self._wtable[self._cores] = (self._base + self._thickness)[self._cores]
コード例 #5
0
ファイル: dupuit_percolator.py プロジェクト: baadams/landlab
    def run_with_adaptive_time_step_solver(self,
                                           dt,
                                           courant_coefficient=0.01,
                                           **kwds):
        """
        Advance component by one time step of size dt, subdividing the timestep
        into substeps as necessary to meet a Courant condition.
        Note this method only returns the fluxes at the last subtimestep.

        Parameters
        ----------
        dt: float (time in seconds)
            The imposed timestep.
        courant_coefficient: float (-)
            The muliplying factor on the condition that the timestep is
            smaller than the minimum link length over groundwater flow velocity
        """

        remaining_time = dt
        self._num_substeps = 0

        while remaining_time > 0.0:
            # Calculate base gradient
            self._base_grad[
                self._grid.active_links] = self._grid.calc_grad_at_link(
                    self._base)[self._grid.active_links]

            # Calculate hydraulic gradient
            self._hydr_grad[
                self._grid.active_links] = self._grid.calc_grad_at_link(
                    self._thickness)[self._grid.active_links]

            # Calculate groundwater velocity
            self._vel[:] = -self._K * (
                self._hydr_grad * np.cos(np.arctan(abs(self._base_grad))) +
                np.sin(np.arctan(self._base_grad)))
            self._vel[self._grid.status_at_link == INACTIVE_LINK] = 0.0

            # Aquifer thickness at links (upwind)
            hlink = map_value_at_max_node_to_link(self._grid,
                                                  "water_table__elevation",
                                                  "aquifer__thickness")

            # Calculate specific discharge
            self._q[:] = hlink * self._vel

            # Groundwater flux divergence
            dqdx = self._grid.calc_flux_div_at_node(self._q)

            # Determine the relative aquifer thickness, 1 if permeable thickness is 0.
            soil_present = self._elev - self._base > 0.0
            rel_thickness = np.ones_like(self._elev)
            rel_thickness[soil_present] = np.minimum(
                1,
                self._thickness[soil_present] /
                (self._elev[soil_present] - self._base[soil_present]),
            )

            # Calculate surface discharge at nodes
            self._qs[:] = _regularize_G(
                rel_thickness, self._r) * _regularize_R(self._recharge - dqdx)

            # Mass balance
            self._dhdt[:] = (1 / self._n) * (self._recharge - dqdx - self._qs)

            # calculate criteria for timestep
            max_vel = max(abs(self._vel / self._n_link))
            grid_dist = min(self._grid.length_of_link)
            substep_dt = np.nanmin(
                [courant_coefficient * grid_dist / max_vel, remaining_time])

            # Update
            self._thickness[
                self._cores] += self._dhdt[self._cores] * substep_dt
            self._thickness[self._thickness < 0] = 0.0

            # Recalculate water surface height
            self._wtable[self._cores] = (self._base[self._cores] +
                                         self._thickness[self._cores])

            # calculate the time remaining and advance count of substeps
            remaining_time -= substep_dt
            self._num_substeps += 1
コード例 #6
0
    def run_with_adaptive_time_step_solver(self, dt):
        """
        Advance component by one time step of size dt, subdividing the timestep
        into substeps as necessary to meet a Courant condition.
        Note this method only returns the fluxes at the last subtimestep.

        Parameters
        ----------
        dt: float (time in seconds)
            The imposed timestep.
        """

        # check water table above surface
        if (self._wtable > self._elev).any():
            self._wtable[self._wtable > self._elev] = self._elev[
                self._wtable > self._elev]
            self._thickness[self._cores] = (self._wtable[self._cores] -
                                            self._base[self._cores])

        # Calculate base gradient
        self._base_grad[
            self._grid.active_links] = self._grid.calc_grad_at_link(
                self._base)[self._grid.active_links]
        cosa = np.cos(np.arctan(self._base_grad))

        # Initialize reg_thickness, rel_thickness
        reg_thickness = self._elev - self._base
        soil_present = reg_thickness > 0.0
        rel_thickness = np.ones_like(self._elev)

        # Initialize for average surface discharge
        qs_cumulative = np.zeros_like(self._elev)

        # Initialize variable timestep
        remaining_time = dt
        self._num_substeps = 0

        while remaining_time > 0.0:

            # Calculate hydraulic gradient
            self._hydr_grad[self._grid.active_links] = (
                self._grid.calc_grad_at_link(
                    self._wtable)[self._grid.active_links] *
                cosa[self._grid.active_links])

            # Calculate groundwater velocity
            self._vel[:] = -self._K * self._hydr_grad
            self._vel[self._grid.status_at_link == LinkStatus.INACTIVE] = 0.0

            # Aquifer thickness at links (upwind)
            hlink = (map_value_at_max_node_to_link(
                self._grid, "water_table__elevation", "aquifer__thickness") *
                     cosa)

            # Calculate specific discharge
            self._q[:] = hlink * self._vel

            # Groundwater flux divergence
            dqdx = self._grid.calc_flux_div_at_node(self._q)

            # calculate relative thickness
            rel_thickness[soil_present] = np.minimum(
                1,
                self._thickness[soil_present] / (reg_thickness[soil_present]))

            # Calculate surface discharge at nodes
            self._qs[:] = _regularize_G(
                rel_thickness, self._r) * _regularize_R(self._recharge - dqdx)

            # Mass balance
            self._dhdt[:] = (1 / self._n) * (self._recharge - self._qs - dqdx)

            # calculate criteria for timestep
            max_vel = max(abs(self._vel / self._n_link))
            grid_dist = min(self._grid.length_of_link)
            substep_dt = np.nanmin([
                self._courant_coefficient * grid_dist / max_vel, remaining_time
            ])

            # Update
            self._thickness[
                self._cores] += self._dhdt[self._cores] * substep_dt
            self._thickness[self._thickness < 0] = 0.0

            # Recalculate water surface height
            self._wtable[self._cores] = (self._base +
                                         self._thickness)[self._cores]

            # add cumulative sw discharge in substeps
            qs_cumulative += self._qs * substep_dt

            # calculate the time remaining and advance count of substeps
            remaining_time -= substep_dt
            self._num_substeps += 1

        self._qsavg[:] = qs_cumulative / dt
コード例 #7
0
    def run_with_adaptive_time_step_solver(self, dt):
        """
        Advance component by one time step of size dt, subdividing the timestep
        into substeps as necessary to meet stability conditions.
        Note this method returns the fluxes at the last substep, but also
        returns a new field, average_surface_water__specific_discharge, that is
        averaged over all subtimesteps. To return state during substeps,
        provide a callback_fun.

        Parameters
        ----------
        dt: float
            The imposed timestep.
        """

        # check water table above surface
        if (self._wtable > self._elev).any():
            warn(
                "water table above elevation surface. "
                "Setting water table elevation here to "
                "elevation surface"
            )
            self._wtable[self._wtable > self._elev] = self._elev[
                self._wtable > self._elev
            ]
            self._thickness[self._cores] = (self._wtable - self._base)[self._cores]

        # Calculate base gradient
        self._base_grad[self._grid.active_links] = self._grid.calc_grad_at_link(
            self._base
        )[self._grid.active_links]
        cosa = np.cos(np.arctan(self._base_grad))

        # Initialize reg_thickness
        reg_thickness = self._elev - self._base

        # Initialize for average surface discharge
        qs_cumulative = np.zeros_like(self._elev)

        # Initialize variable timestep
        remaining_time = dt
        self._num_substeps = 0

        while remaining_time > 0.0:

            # Calculate hydraulic gradient
            self._hydr_grad[self._grid.active_links] = (
                self._grid.calc_grad_at_link(self._wtable) * cosa
            )[self._grid.active_links]

            # Calculate groundwater velocity
            self._vel[:] = -self._K * self._hydr_grad

            # Aquifer thickness at links (upwind)
            hlink = (
                map_value_at_max_node_to_link(
                    self._grid, "water_table__elevation", "aquifer__thickness"
                )
                * cosa
            )

            # Calculate specific discharge
            self._q[:] = hlink * self._vel

            # Groundwater flux divergence
            dqdx = self._grid.calc_flux_div_at_node(self._q)

            # calculate criteria for timestep
            dt_vn = self._vn_coefficient * np.min(
                np.divide(
                    (self._n_link * self._grid.length_of_link ** 2),
                    (4 * self._K * hlink),
                    where=hlink > 0,
                    out=np.ones_like(self._q) * 1e15,
                )
            )

            dt_courant = self._courant_coefficient * np.min(
                np.divide(
                    self._grid.length_of_link,
                    abs(self._vel / self._n_link),
                    where=abs(self._vel) > 0,
                    out=np.ones_like(self._q) * 1e15,
                )
            )
            substep_dt = min([dt_courant, dt_vn, remaining_time])
            # print(np.argmin(np.array([self._dt_courant, self._dt_vn, remaining_time]))) # 0 = courant limited, 1 = vn limited, 2 = not limited

            # update thickness from analytical
            self._thickness[self._cores] = _update_thickness(
                substep_dt,
                self._thickness,
                reg_thickness,
                self._recharge,
                dqdx,
                self._n,
                self._r,
            )[self._cores]
            self._thickness[self._thickness < 0] = 0.0

            # Recalculate water surface height
            self._wtable[:] = self._base + self._thickness

            # Calculate surface discharge at nodes
            self._qs[:] = _regularize_G(
                self._thickness / reg_thickness, self._r
            ) * _regularize_R(self._recharge - dqdx)

            # add cumulative sw discharge in substeps
            qs_cumulative += self._qs * substep_dt

            # calculate the time remaining and advance count of substeps
            remaining_time -= substep_dt
            self._num_substeps += 1

            # run callback function if supplied
            self._callback_fun(
                self._grid, self._recharge, substep_dt, **self._callback_kwds
            )

        self._qsavg[:] = qs_cumulative / dt
コード例 #8
0
rmg.set_watershed_boundary_condition(z)

# Set spatially variable diffusivity for soil creep
df = pd.Series(data=np.array(rmg.at_node['terrace_wall__location']), name="walls")
df1 = df.to_frame(name="walls")
df1['Kd'] = '0'
df1.loc[df1.walls == 1., 'Kd'] = 0.
df1.loc[df1.walls == 0., 'Kd'] = 1.0
dfList = df1['Kd'].tolist()
Kd = np.array(dfList)

# Add Kd to rmg
rmg.add_field('node', 'Kd', Kd)

# Set links to kd value for uphill nodes
maxField= map_value_at_max_node_to_link(rmg, 'topographic__elevation', 'Kd')
rmg.add_field('link', 'Kd_maxField', maxField)

# Set uplift rate
uplift_rate = 0.0001 # [m/yr]

# Initialize linear diffuser
ld = LinearDiffuser(rmg, linear_diffusivity='Kd_maxField')

# Set up LEM

def run_LEM(years):
    for i in range(years):
        # Soil creep
        ld.run_one_step(1.)
        # Uplift