def basal_beta(): # surface elevation s = alpha * H b = sp.Function("b", real=True)(x) nx_b, ny_b, nz_b = list(grad(b - z)) db = (s - H).subs(H, H_exact).factor(fraction=False).diff(x).subs(H_exact, H) # normalized x component of the downward-pointing normal vector norm = (db**2 + 1**2)**S("1/2") nx_n = db / norm nz_n = -1 / norm N_base = {nx: nx_n, ny: 0, nz: nz_n} I_base = 2 * eta(u_exact, v_exact, 3) * M(u_exact, v_exact).row(0) * N I_base = I_base[0].subs(N_base).doit() BC_basal = I_base.subs(H, H_exact).doit().subs(H_exact, H) sp.var("beta", positive=True) eq_beta = sp.Eq(BC_basal + beta * u, 0) return solve(eq_beta, beta)[0].subs(u, Q_0 / H)
def basal_bc(u0, v0): N_bed = {nx: 0, ny: 0, nz: -1} I = (2 * eta(u0, v0, n) * M(u0, v0).row(0) * N)[0].subs(N_bed) x_p = sp.symbols("x_p", positive=True) return I.subs(z, 0).subs(constants()).subs(x, x_p).subs(x_p, x).simplify()
def surface_bc(): u0, v0 = exact() return (2 * eta(u0, v0, n) * M(u0, v0).row(0) * N)[0].subs({ nx: 0, ny: 0, nz: 1 })
def lateral_bc(): u0, v0 = exact() return (2 * eta(u0, v0, n) * M(u0, v0).row(0) * N)[0].subs({ nx: 1, ny: 0, nz: 0, x: L })
def surface_bc(u0, v0, surface): ds = surface.diff(x) # normalized x component of the downward-pointing normal vector n_s_norm = (ds**2 + 1**2)**S("1/2") nx_s = -ds / n_s_norm ny_s = 0 nz_s = 1 / n_s_norm N_surface = {nx: nx_s, ny: ny_s, nz: nz_s} return (2 * eta(u0, v0, n) * M(u0, v0).row(0) * N)[0].subs(N_surface)
def source_lateral(): "Lateral BC" N_right = {nx: 1, ny: 0, nz: 0} I = 2 * eta(u_exact, v_exact, 3) * M(u_exact, v_exact).row(0) * N I = I[0].subs(N_right).subs(H, H_exact).doit() # tell SymPy that x is positive to make it simplify the expression I = I.subs(x, x_p) I = I.subs(x_p, x).subs(H_exact, H) return I, 0
def surface_bc(): # surface elevation s = alpha * H ds = s.diff(x) # normalized x component of the upward-pointing normal vector n_s_norm = (ds**2 + 1**2)**S("1/2") nx_s = -ds / n_s_norm ny_s = 0 nz_s = 1 / n_s_norm N_surface = {nx: nx_s, ny: ny_s, nz: nz_s} f_s = (2 * eta(u_exact, v_exact, 3) * M(u_exact, v_exact).row(0) * N) f_s = f_s[0].subs(N_surface).subs(H, H_exact).doit() f_s = f_s.subs(H_exact, H).factor() return f_s, 0
def lateral_bc(u0, v0): N_right = {nx: 1, ny: 0, nz: 0} return (2 * eta(u0, v0, n) * M(u0, v0).row(0) * N)[0].subs(N_right), 0.0