コード例 #1
0
    def n_min(self, n_min, apply_to_preconditioner=False):
        """Ensure n \geq n_min everywhere.

        If apply_to_preconditioner is True,then this is only done to the
        preconditioner."""

        if apply_to_preconditioner:
            self.set_n_pre(
                fd.conditional(fd.lt(fd.real(self._n_pre), n_min), n_min,
                               self._n_pre))

        else:
            self.set_n(
                fd.conditional(fd.lt(fd.real(self._n), n_min), n_min, self._n))
コード例 #2
0
def terminus(u, h, s):
    r"""Return the terminal stress part of the ice stream action functional

    The power exerted due to stress at the ice calving terminus :math:`\Gamma`
    is

    .. math::
       E(u) = \frac{1}{2}\int_\Gamma\left(\rho_Igh^2 - \rho_Wgd^2\right)
       u\cdot \nu\, ds

    where :math:`d` is the water depth at the terminus. We assume that sea
    level is at :math:`z = 0` for purposes of calculating the water depth.

    Parameters
    ----------
    u : firedrake.Function
        ice velocity
    h : firedrake.Function
        ice thickness
    s : firedrake.Function
        ice surface elevation
    ice_front_ids : list of int
        numeric IDs of the parts of the boundary corresponding to the
        calving front
    """
    from firedrake import conditional, lt
    d = conditional(lt(s - h, 0), s - h, 0)

    τ_I = ρ_I * g * h**2 / 2
    τ_W = ρ_W * g * d**2 / 2

    ν = firedrake.FacetNormal(u.ufl_domain())
    return (τ_I - τ_W) * inner(u, ν)
コード例 #3
0
def rate_factor(T):
    r"""Compute the rate factor in Glen's flow law for a given temperature

    The strain rate :math:`\dot\varepsilon` of ice resulting from a stress
    :math:`\tau` is

    .. math::
       \dot\varepsilon = A(T)\tau^3

    where :math:`A(T)` is the temperature-dependent rate factor:

    .. math::
       A(T) = A_0\exp(-Q/RT)

    where :math:`R` is the ideal gas constant, :math:`Q` has units of
    energy per mole, and :math:`A_0` is a prefactor with units of
    pressure :math:`\text{MPa}^{-3}\times\text{yr}^{-1}`.

    Parameters
    ----------
    T : float, np.ndarray, or UFL expression
        The ice temperature

    Returns
    -------
    A : same type as T
        The ice fluidity
    """
    import ufl

    if isinstance(T, ufl.core.expr.Expr):
        cold = firedrake.lt(T, transition_temperature)
        A0 = firedrake.conditional(cold, A0_cold, A0_warm)
        Q = firedrake.conditional(cold, Q_cold, Q_warm)
        A = A0 * firedrake.exp(-Q / (R * T))
        if isinstance(T, firedrake.Constant):
            return firedrake.Constant(A)

        return A

    cold = T < transition_temperature
    warm = ~cold if isinstance(T, np.ndarray) else (not cold)
    A0 = A0_cold * cold + A0_warm * warm
    Q = Q_cold * cold + Q_warm * warm

    return A0 * np.exp(-Q / (R * T))
コード例 #4
0
    # Use the static condensation PC for hybridized problems
    # and use a direct solve on the reduced system for lambda_h
    "pc_python_type": "firedrake.SCPC",
    "pc_sc_eliminate_fields": "0, 1",
    "condensed_field": {
        "ksp_type": "preonly",
        "pc_type": "lu",
        "pc_factor_mat_solver_type": "mumps"
    }
}

solver = fd.NonlinearVariationalSolver(problem,
                                       solver_parameters=hybrid_solver_params)

# -----------------
wave_speed = fd.conditional(fd.lt(np.abs(vnorm), tol), h / tol, h / vnorm)
# CFL
dt_ = fd.interpolate(wave_speed, DG1).dat.data.min() * cfl
outfile = fd.File(f"plots/adr-hdg-n-{refine}-p-{order}.pvd",
                  project_output=True)
dt = dt_  # dtime
dtc.assign(dt_)

# %%
# solve problem

# initialize timestep
t = 0.0
it = 0

p = 0
コード例 #5
0
    shock = fd.interpolate(vshock * np.abs(R), DG0)
    shock.rename('vshock')

F = F1

prob = fd.NonlinearVariationalProblem(F, c, bcs=t_bc)
transport = fd.NonlinearVariationalSolver(prob)

# %%
# 4) Solve problem
# -----------------
t = 0.0
it = 0
dt0 = dt
cfl_conditional = fd.conditional(fd.lt(np.abs(vnorm), tol), 1 / tol, h / vnorm)
outfile = fd.File("plots/sb_t_supg.pvd")

sol = fd.Function(W)
c0.assign(0.)
# initialize timestep
while t < sim_time:
    # move next time step
    print("* iteration= {:4d}, dtime= {:8.6f}, time={:8.6f}".format(it, dt, t))

    # SB
    idt.assign(1 / dt)
    fd.solve(a == L, sol, bcs=bcs)

    vel.assign(sol.sub(0))
    Pe = vnorm * h / (2.0 * fd.det(Diff))
コード例 #6
0
J = fd.derivative(F, w, dw)

problem = fd.NonlinearVariationalProblem(F, w, bcs, J)
param = {
    'snes_type': 'newtonls',
    'snes_max_it': 100,
    'ksp_type': 'gmres',
    'ksp_rtol': 1e-3
}
solver = fd.NonlinearVariationalSolver(problem, solver_parameters=param)


# %%
# 4) Solve problem
# -----------------
wave_speed = fd.conditional(fd.lt(abs(vnorm), tol), h_E/tol, h_E/vnorm)
outfile = fd.File("plots/sb_adr_fi.pvd")

w0.sub(2).assign(0.0)

# initialize timestep
t = 0.0
it = 0
dt = np.sqrt(tol)

while t < sim_time:
    # move next time step
    t += dt
    print("* iteration= {:4d}, dtime= {:8.6f}, time={:8.6f}".format(it, dt, t))

    # solver system: SB + tracer