Beispiel #1
0
def test_curl_implicit_FFC(basis, N, dealias, dtype):
    c, d, b, r = basis(N, dealias, dtype)
    Lz = b[2].bounds[1]
    lift_basis = b[2].clone_with(a=1 / 2, b=1 / 2)  # First derivative basis
    lift = lambda A, n: d3.Lift(A, lift_basis, n)
    integ = lambda A: d3.Integrate(
        d3.Integrate(d3.Integrate(A, c.coords[0]), c.coords[1]), c.coords[2])
    tau1 = d.VectorField(c, name='tau1', bases=b[0:2])
    tau2 = d.Field(name='tau2', bases=b[0:2])
    # ABC vector field
    k = 2 * np.pi * np.array([1 / Lx, 1 / Ly, 1 / Lz])
    f = d.VectorField(c, bases=b)
    f.preset_scales(dealias)
    f['g'][0] = np.sin(k[2] * r[2]) + np.cos(k[1] * r[1])
    f['g'][1] = np.sin(k[0] * r[0]) + np.cos(k[2] * r[2])
    f['g'][2] = np.sin(k[1] * r[1]) + np.cos(k[0] * r[0])
    g = d.VectorField(c, bases=b)
    g.preset_scales(dealias)
    g['g'][0] = k[2] * np.sin(k[2] * r[2]) + k[1] * np.cos(k[1] * r[1])
    g['g'][1] = k[0] * np.sin(k[0] * r[0]) + k[2] * np.cos(k[2] * r[2])
    g['g'][2] = k[1] * np.sin(k[1] * r[1]) + k[0] * np.cos(k[0] * r[0])
    # Skew LBVP
    u = d.VectorField(c, name='u', bases=b)
    phi = d.Field(name='phi', bases=b)
    problem = d3.LBVP([u, phi, tau1, tau2], namespace=locals())
    problem.add_equation("curl(u) + grad(phi) + lift(tau1,-1) = g")
    problem.add_equation("div(u) + lift(tau2,-1) = 0")
    problem.add_equation("u(z=0) = f(z=0)")
    problem.add_equation("phi(z=0) = 0")
    solver = problem.build_solver()
    solver.solve()
    assert np.allclose(u['c'], f['c'])
Beispiel #2
0
def test_poisson_1d_jacobi(Nx, a0, b0, da, db, dtype):
    # Bases
    coord = d3.Coordinate('x')
    dist = d3.Distributor(coord, dtype=dtype)
    basis = d3.Jacobi(coord,
                      size=Nx,
                      bounds=(0, 2 * np.pi),
                      a=a0 + da,
                      b=b0 + db,
                      a0=a0,
                      b0=b0)
    x = basis.local_grid(1)
    # Fields
    u = dist.Field(name='u', bases=basis)
    tau1 = dist.Field(name='tau1')
    tau2 = dist.Field(name='tau2')
    # Substitutions
    dx = lambda A: d3.Differentiate(A, coord)
    lift_basis = basis.clone_with(a=a0 + da + 2, b=b0 + db + 2)
    lift = lambda A, n: d3.Lift(A, lift_basis, n)
    F = dist.Field(bases=basis)
    F['g'] = -np.sin(x)
    # Problem
    problem = d3.LBVP([u, tau1, tau2], namespace=locals())
    problem.add_equation("dx(dx(u)) + lift(tau1,-1) + lift(tau2,-2) = F")
    problem.add_equation("u(x='left') = 0")
    problem.add_equation("u(x='right') = 0")
    # Solver
    solver = problem.build_solver()
    solver.solve()
    # Check solution
    u_true = np.sin(x)
    assert np.allclose(u['g'], u_true)
d = de.Distributor(c, dtype=np.float64)
zb = de.ChebyshevT(c.coords[-1], size=nz, bounds=(0, Lz), dealias=dealias)
b = zb
z = zb.local_grid(1)
zd = zb.local_grid(dealias)

# Fields
θ = d.Field(name='θ', bases=b)
Υ = d.Field(name='Υ', bases=b)
s = d.Field(name='s', bases=b)
u = d.VectorField(c, name='u', bases=b)

# Taus
zb1 = zb.clone_with(a=zb.a + 1, b=zb.b + 1)
zb2 = zb.clone_with(a=zb.a + 2, b=zb.b + 2)
lift1 = lambda A, n: de.Lift(A, zb1, n)
lift = lambda A, n: de.Lift(A, zb2, n)
τ_h1 = d.VectorField(c, name='τ_h1')
τ_s1 = d.Field(name='τ_s1')
τ_s2 = d.Field(name='τ_s2')
τ_u1 = d.VectorField(c, name='τ_u1')
τ_u2 = d.VectorField(c, name='τ_u2')

# Parameters and operators
div = lambda A: de.Divergence(A, index=0)
lap = lambda A: de.Laplacian(A, c)
grad = lambda A: de.Gradient(A, c)
#curl = lambda A: de.operators.Curl(A)
cross = lambda A, B: de.CrossProduct(A, B)
trace = lambda A: de.Trace(A)
trans = lambda A: de.TransposeComponents(A)
# Fields
u = dist.VectorField(coords, name='u', bases=basis)
p = dist.Field(name='p', bases=basis)
T = dist.Field(name='T', bases=basis)
tau_p = dist.Field(name='tau_p')
tau_u = dist.VectorField(coords, name='tau u', bases=S2_basis)
tau_T = dist.Field(name='tau T', bases=S2_basis)

# Substitutions
phi, theta, r = dist.local_grids(basis)
r_vec = dist.VectorField(coords, bases=basis.radial_basis)
r_vec['g'][2] = r
T_source = 6
kappa = (Rayleigh * Prandtl)**(-1 / 2)
nu = (Rayleigh / Prandtl)**(-1 / 2)
lift = lambda A: d3.Lift(A, basis, -1)
strain_rate = d3.grad(u) + d3.trans(d3.grad(u))
shear_stress = d3.angular(d3.radial(strain_rate(r=1), index=1))

# Problem
problem = d3.IVP([p, u, T, tau_p, tau_u, tau_T], namespace=locals())
problem.add_equation("div(u) + tau_p = 0")
problem.add_equation(
    "dt(u) - nu*lap(u) + grad(p) - r_vec*T + lift(tau_u) = - cross(curl(u),u)")
problem.add_equation(
    "dt(T) - kappa*lap(T) + lift(tau_T) = - u@grad(T) + kappa*T_source")
problem.add_equation("shear_stress = 0")  # Stress free
problem.add_equation("radial(u(r=1)) = 0")  # No penetration
problem.add_equation("radial(grad(T)(r=1)) = -2")
problem.add_equation("integ(p) = 0")  # Pressure gauge
Beispiel #5
0
p = dist.Field(name='p', bases=(xbasis, zbasis))
b = dist.Field(name='b', bases=(xbasis, zbasis))
u = dist.VectorField(coords, name='u', bases=(xbasis, zbasis))
tau_p = dist.Field(name='tau_p')
tau_b1 = dist.Field(name='tau_b1', bases=xbasis)
tau_b2 = dist.Field(name='tau_b2', bases=xbasis)
tau_u1 = dist.VectorField(coords, name='tau_u1', bases=xbasis)
tau_u2 = dist.VectorField(coords, name='tau_u2', bases=xbasis)

# Substitutions
kappa = (Rayleigh * Prandtl)**(-1 / 2)
nu = (Rayleigh / Prandtl)**(-1 / 2)
x, z = dist.local_grids(xbasis, zbasis)
ex, ez = coords.unit_vector_fields(dist)
lift_basis = zbasis.derivative_basis(1)
lift = lambda A: d3.Lift(A, lift_basis, -1)
grad_u = d3.grad(u) + ez * lift(tau_u1)  # First-order reduction
grad_b = d3.grad(b) + ez * lift(tau_b1)  # First-order reduction

# Problem
# First-order form: "div(f)" becomes "trace(grad_f)"
# First-order form: "lap(f)" becomes "div(grad_f)"
problem = d3.IVP([p, b, u, tau_p, tau_b1, tau_b2, tau_u1, tau_u2],
                 namespace=locals())
problem.add_equation("trace(grad_u) + tau_p = 0")
problem.add_equation("dt(b) - kappa*div(grad_b) + lift(tau_b2) = - u@grad(b)")
problem.add_equation(
    "dt(u) - nu*div(grad_u) + grad(p) - b*ez + lift(tau_u2) = - u@grad(u)")
problem.add_equation("b(z=0) = Lz")
problem.add_equation("u(z=0) = 0")
problem.add_equation("b(z=Lz) = 0")
Beispiel #6
0
tau_2 = dist.Field(name='tau_2', bases=xbasis)

# Forcing
x, y = dist.local_grids(xbasis, ybasis)
f = dist.Field(bases=(xbasis, ybasis))
g = dist.Field(bases=xbasis)
h = dist.Field(bases=xbasis)
f.fill_random('g', seed=40)
f.low_pass_filter(shape=(64, 32))
g['g'] = np.sin(8 * x) * 0.025
h['g'] = 0

# Substitutions
dy = lambda A: d3.Differentiate(A, coords['y'])
lift_basis = ybasis.derivative_basis(2)
lift = lambda A, n: d3.Lift(A, lift_basis, n)

# Problem
problem = d3.LBVP([u, tau_1, tau_2], namespace=locals())
problem.add_equation("lap(u) + lift(tau_1,-1) + lift(tau_2,-2) = f")
problem.add_equation("u(y=0) = g")
problem.add_equation("dy(u)(y=Ly) = h")

# Solver
solver = problem.build_solver()
solver.solve()

# Gather global data
x = xbasis.global_grid()
y = ybasis.global_grid()
ug = u.allgather_data('g')
def heated_polytrope(nz, γ, ε, n_h,
                     tolerance = 1e-8,
                     ncc_cutoff = 1e-10,
                     dealias = 2,
                     verbose=False):

    import dedalus.public as de

    cP = γ/(γ-1)
    m_ad = 1/(γ-1)

    s_c_over_c_P = scrS = 1 # s_c/c_P = 1

    logger.info("γ = {:.3g}, ε={:.3g}".format(γ, ε))

    # this assumes h_bot=1, grad_φ = (γ-1)/γ (or L=Hρ)
    h_bot = 1
    # generally, h_slope = -1/(1+m)
    # start in an adibatic state, heat from there
    h_slope = -1/(1+m_ad)
    grad_φ = (γ-1)/γ

    Lz = -1/h_slope*(1-np.exp(-n_h))

    print(n_h, Lz, h_slope)

    c = de.CartesianCoordinates('z')
    d = de.Distributor(c, dtype=np.float64)
    zb = de.ChebyshevT(c.coords[-1], size=nz, bounds=(0, Lz), dealias=dealias)
    b = zb
    z = zb.local_grid(1)
    zd = zb.local_grid(dealias)

    # Fields
    θ = d.Field(name='θ', bases=b)
    Υ = d.Field(name='Υ', bases=b)
    s = d.Field(name='s', bases=b)
    u = d.VectorField(c, name='u', bases=b)

    # Taus
    lift_basis = zb.clone_with(a=zb.a+2, b=zb.b+2)
    lift = lambda A, n: de.Lift(A, lift_basis, n)
    lift_basis1 = zb.clone_with(a=zb.a+1, b=zb.b+1)
    lift1 = lambda A, n: de.Lift(A, lift_basis1, n)
    τ_h1 = d.VectorField(c,name='τ_h1')
    τ_s1 = d.Field(name='τ_s1')
    τ_s2 = d.Field(name='τ_s2')

    # Parameters and operators
    lap = lambda A: de.Laplacian(A, c)
    grad = lambda A: de.Gradient(A, c)

    ez, = c.unit_vector_fields(d)

    # NLBVP goes here
    # intial guess
    h0 = d.Field(name='h0', bases=zb)
    θ0 = d.Field(name='θ0', bases=zb)
    Υ0 = d.Field(name='Υ0', bases=zb)
    s0 = d.Field(name='s0', bases=zb)
    structure = {'h':h0,'s':s0,'θ':θ0,'Υ':Υ0}
    for key in structure:
        structure[key].change_scales(dealias)
    h0['g'] = h_bot + zd*h_slope #(Lz+1)-z
    θ0['g'] = np.log(h0).evaluate()['g']
    Υ0['g'] = (m_ad*θ0).evaluate()['g']
    s0['g'] = 0

    problem = de.NLBVP([h0, s0, Υ0, τ_s1, τ_s2, τ_h1])
    problem.add_equation((grad(h0) + lift1(τ_h1,-1),
                         -grad_φ*ez + h0*grad(s0)))
    problem.add_equation((-lap(h0)
    + lift(τ_s1,-1) + lift(τ_s2,-2), ε))
    problem.add_equation(((γ-1)*Υ0 + s_c_over_c_P*γ*s0, np.log(h0)))
    problem.add_equation((Υ0(z=0), 0))
    problem.add_equation((h0(z=0), 1))
    problem.add_equation((h0(z=Lz), np.exp(-n_h)))

    # Solver
    solver = problem.build_solver(ncc_cutoff=ncc_cutoff)
    pert_norm = np.inf
    while pert_norm > tolerance:
        solver.newton_iteration()
        pert_norm = sum(pert.allreduce_data_norm('c', 2) for pert in solver.perturbations)
        logger.info('current perturbation norm = {:.3g}'.format(pert_norm))

    if verbose:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots()
        ax2 = ax.twinx()

        ax.plot(zd, h0['g'], linestyle='dashed', color='xkcd:dark grey', label='h')
        ax2.plot(zd, np.log(h0).evaluate()['g'], label=r'$\ln h$')
        ax2.plot(zd, Υ0['g'], label=r'$\ln \rho$')
        ax2.plot(zd, s0['g'], color='xkcd:brick red', label=r'$s$')
        ax.legend()
        ax2.legend()
        fig.savefig('heated_polytrope_nh{}_eps{}_gamma{:.3g}.pdf'.format(n_h,ε,γ))

    for key in structure:
        structure[key].change_scales(1)

    return structure