Beispiel #1
0
def test_poisson_1d_fourier(Nx, dtype, matrix_coupling):
    # Bases
    coord = d3.Coordinate('x')
    dist = d3.Distributor(coord, dtype=dtype)
    if dtype == np.complex128:
        basis = d3.ComplexFourier(coord, size=Nx, bounds=(0, 2 * np.pi))
    elif dtype == np.float64:
        basis = d3.RealFourier(coord, size=Nx, bounds=(0, 2 * np.pi))
    x = basis.local_grid(1)
    # Fields
    u = dist.Field(name='u', bases=basis)
    g = dist.Field(name='c')
    # Substitutions
    dx = lambda A: d3.Differentiate(A, coord)
    integ = lambda A: d3.Integrate(A, coord)
    F = dist.Field(bases=basis)
    F['g'] = -np.sin(x)
    # Problem
    problem = d3.LBVP([u, g], namespace=locals())
    problem.add_equation("dx(dx(u)) + g = F")
    problem.add_equation("integ(u) = 0")
    # Solver
    solver = problem.build_solver(matrix_coupling=[matrix_coupling])
    solver.solve()
    # Check solution
    u_true = np.sin(x)
    assert np.allclose(u['g'], u_true)
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)
Beispiel #3
0
def build_FFF(N, dealias, dtype):
    c = d3.CartesianCoordinates('x', 'y', 'z')
    d = d3.Distributor(c, dtype=dtype)
    if dtype == np.complex128:
        xb = d3.ComplexFourier(c.coords[0],
                               size=N,
                               bounds=(0, Lx),
                               dealias=dealias)
        yb = d3.ComplexFourier(c.coords[1],
                               size=N,
                               bounds=(0, Ly),
                               dealias=dealias)
        zb = d3.ComplexFourier(c.coords[2],
                               size=N,
                               bounds=(0, Lz),
                               dealias=dealias)
    elif dtype == np.float64:
        xb = d3.RealFourier(c.coords[0],
                            size=N,
                            bounds=(0, Lx),
                            dealias=dealias)
        yb = d3.RealFourier(c.coords[1],
                            size=N,
                            bounds=(0, Ly),
                            dealias=dealias)
        zb = d3.RealFourier(c.coords[2],
                            size=N,
                            bounds=(0, Lz),
                            dealias=dealias)
    b = (xb, yb, zb)
    x = xb.local_grid(dealias)
    y = yb.local_grid(dealias)
    z = zb.local_grid(dealias)
    r = (x, y, z)
    return c, d, b, r
Beispiel #4
0
def lane_emden(Nr, m=1.5, n_rho=3, radius=1,
               ncc_cutoff = 1e-10, tolerance = 1e-10, dtype=np.complex128, comm=None):
    # TO-DO: clean this up and make work for ncc ingestion in main script in np.float64 rather than np.complex128
    c = de.SphericalCoordinates('phi', 'theta', 'r')
    d = de.Distributor((c,), comm=comm, dtype=dtype)
    b = de.BallBasis(c, (1, 1, Nr), radius=radius, dtype=dtype)
    br = b.radial_basis
    phi, theta, r = b.local_grids()
    # Fields
    f = d.Field(name='f', bases=b)
    R = d.Field(name='R')
    τ = d.Field(name='τ', bases=b.S2_basis(radius=radius))
    # Parameters and operators
    lap = lambda A: de.Laplacian(A, c)
    lift_basis = b.clone_with(k=2) # match laplacian
    lift = lambda A: de.LiftTau(A, lift_basis, -1)
    problem = de.NLBVP([f, R, τ])
    problem.add_equation((lap(f) + lift(τ), - R**2 * f**m))
    problem.add_equation((f(r=0), 1))
    problem.add_equation((f(r=radius), np.exp(-n_rho/m, dtype=dtype))) # explicit typing to match domain

    # Solver
    solver = problem.build_solver(ncc_cutoff=ncc_cutoff)
    # Initial guess
    f['g'] = np.cos(np.pi/2 * r)**2
    R['g'] = 5

    # Iterations
    logger.debug('beginning Lane-Emden NLBVP iterations')
    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.debug(f'Perturbation norm: {pert_norm:.3e}')
    T = d.Field(name='T', bases=br)
    ρ = d.Field(name='ρ', bases=br)
    lnρ = d.Field(name='lnρ', bases=br)
    T['g'] = f['g']
    ρ['g'] = f['g']**m
    lnρ['g'] = np.log(ρ['g'])

    structure = {'T':T,'lnρ':lnρ}
    for key in structure:
        structure[key].require_scales(1)
    structure['r'] = r
    structure['problem'] = {'c':c, 'b':b, 'problem':problem}
    return structure
logger.info(args)
logger.info("saving data in: {}".format(data_dir))

# this assumes h_bot=1, grad_φ = (γ-1)/γ (or L=Hρ)
h_bot = 1
h_slope = -1 / (1 + m)
grad_φ = (γ - 1) / γ

n_h = float(args['--n_h'])
Lz = -1 / h_slope * (1 - np.exp(-n_h))
Lx = float(args['--aspect']) * Lz

dealias = 2
c = de.CartesianCoordinates('x', 'z')
d = de.Distributor(c, dtype=np.float64)
xb = de.RealFourier(c.coords[0], size=nx, bounds=(0, Lx), dealias=dealias)
zb = de.ChebyshevT(c.coords[1], size=nz, bounds=(0, Lz), dealias=dealias)
b = (xb, zb)
x = xb.local_grid(1)
z = zb.local_grid(1)

# Fields
T = d.Field(name='T', 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)
restart = (len(sys.argv) > 1 and sys.argv[1] == '--restart')

# Parameters
Nphi, Ntheta, Nr = 128, 64, 96
Rayleigh = 1e6
Prandtl = 1
dealias = 3 / 2
stop_sim_time = 20 + 20 * restart
timestepper = d3.SBDF2
max_timestep = 0.05
dtype = np.float64
mesh = None

# Bases
coords = d3.SphericalCoordinates('phi', 'theta', 'r')
dist = d3.Distributor(coords, dtype=dtype, mesh=mesh)
basis = d3.BallBasis(coords,
                     shape=(Nphi, Ntheta, Nr),
                     radius=1,
                     dealias=dealias,
                     dtype=dtype)
S2_basis = basis.S2_basis()

# 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)
Beispiel #7
0
logger = logging.getLogger(__name__)

# Parameters
Lx, Lz = 4, 1
Nx, Nz = 256, 64
Rayleigh = 2e6
Prandtl = 1
dealias = 3 / 2
stop_sim_time = 50
timestepper = d3.RK222
max_timestep = 0.125
dtype = np.float64

# Bases
coords = d3.CartesianCoordinates('x', 'z')
dist = d3.Distributor(coords, dtype=dtype)
xbasis = d3.RealFourier(coords['x'], size=Nx, bounds=(0, Lx), dealias=dealias)
zbasis = d3.ChebyshevT(coords['z'], size=Nz, bounds=(0, Lz), dealias=dealias)

# Fields
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)
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
Beispiel #9
0

# Parameters
Lx = 10
Nx = 1024
a = 1e-4
b = 2e-4
dealias = 3/2
stop_sim_time = 10
timestepper = d3.SBDF2
timestep = 2e-3
dtype = np.float64

# Bases
xcoord = d3.Coordinate('x')
dist = d3.Distributor(xcoord, dtype=dtype)
xbasis = d3.RealFourier(xcoord, size=Nx, bounds=(0, Lx), dealias=dealias)

# Fields
u = dist.Field(name='u', bases=xbasis)

# Substitutions
dx = lambda A: d3.Differentiate(A, xcoord)

# Problem
problem = d3.IVP([u], namespace=locals())
problem.add_equation("dt(u) - a*dx(dx(u)) - b*dx(dx(dx(u))) = - u*dx(u)")

# Initial conditions
x = dist.local_grid(xbasis)
n = 20
Beispiel #10
0
radius = 1

Ek = Ekman = float(args['--Ekman'])
Co2 = ConvectiveRossbySq = float(args['--ConvectiveRossbySq'])
Pr = Prandtl = float(args['--Prandtl'])
logger.info("Ek = {}, Co2 = {}, Pr = {}".format(Ek, Co2, Pr))

import dedalus.public as de
from dedalus.extras import flow_tools

from structure import lane_emden

dealias = float(args['--dealias'])

c = de.SphericalCoordinates('phi', 'theta', 'r')
d = de.Distributor(c, mesh=mesh, dtype=np.float64)
b = de.BallBasis(c,
                 shape=(Nφ, Nθ, Nr),
                 radius=radius,
                 dealias=dealias,
                 dtype=np.float64)
b_S2 = b.S2_basis()
phi, theta, r = b.local_grids()

p = d.Field(name='p', bases=b)
s = d.Field(name='s', bases=b)
u = d.VectorField(c, name='u', bases=b)
τ_p = d.Field(name='τ_p')
τ_s = d.Field(name='τ_s', bases=b_S2)
τ_u = d.VectorField(c, name='τ_u', bases=b_S2)
Beispiel #11
0
import dedalus.public as d3
import dedalus
from dedalus.tools.parallel import RotateProcesses

scales = 1

coords = d3.CartesianCoordinates('x', 'y')
dist = d3.Distributor(coords, dtype=float)
xb = d3.RealFourier(coords['x'], 32, (0, 1))
yb = d3.Chebyshev(coords['y'], 64, (0, 1))
domain = dedalus.core.domain.Domain(dist, (xb, yb))

for layout in dist.layouts:
    with RotateProcesses():
        print("Rank:", dist.comm.rank)
        print("Grid space:", layout.grid_space, " Local:", layout.local)
        print("Global shape:", layout.global_shape(domain, scales), " Chunk shape:", layout.chunk_shape(domain))
        print(layout.local_groups(domain, scales))
        print()