Пример #1
0
def test_box_AdvectiveCFL(x_basis_class, Nx, Nz, timestepper, dtype,
                          z_velocity_mag, dealias):
    # Bases
    Lx = 2
    Lz = 1
    c = coords.CartesianCoordinates('x', 'z')
    d = distributor.Distributor((c, ))
    xb = x_basis_class(c.coords[0], size=Nx, bounds=(0, Lx), dealias=dealias)
    x = xb.local_grid(1)
    zb = basis.ChebyshevT(c.coords[1],
                          size=Nz,
                          bounds=(0, Lz),
                          dealias=dealias)
    z = zb.local_grid(1)
    b = (xb, zb)
    # Fields
    u = field.Field(name='u', dist=d, tensorsig=(c, ), bases=b, dtype=dtype)
    print(u.domain.get_basis(c))
    # Test Fourier CFL
    fourier_velocity = lambda x: np.sin(4 * np.pi * x / Lx)
    chebyshev_velocity = lambda z: -z_velocity_mag * z
    u['g'][0] = fourier_velocity(x)
    u['g'][1] = chebyshev_velocity(z)
    # AdvectiveCFL initialization
    cfl = operators.AdvectiveCFL(u, c)
    cfl_freq = cfl.evaluate()['g']
    comparison_freq = np.abs(u['g'][0]) / cfl.cfl_spacing(u)[0]
    comparison_freq += np.abs(u['g'][1]) / cfl.cfl_spacing(u)[1]
    assert np.allclose(cfl_freq, comparison_freq)
Пример #2
0
def test_cartesian_output(dtype, dealias, output_scales, output_layout):
    Nx = Ny = Nz = 16
    Lx = Ly = Lz = 2 * np.pi
    # Bases
    c = coords.CartesianCoordinates('x', 'y', 'z')
    d = distributor.Distributor((c, ))
    Fourier = {
        np.float64: basis.RealFourier,
        np.complex128: basis.ComplexFourier
    }[dtype]
    xb = Fourier(c.coords[0], size=Nx, bounds=(0, Lx), dealias=dealias)
    yb = Fourier(c.coords[1], size=Ny, bounds=(0, Ly), dealias=dealias)
    zb = basis.ChebyshevT(c.coords[2],
                          size=Nz,
                          bounds=(0, Lz),
                          dealias=dealias)
    x = xb.local_grid(1)
    y = yb.local_grid(1)
    z = zb.local_grid(1)
    # Fields
    u = field.Field(name='u', dist=d, bases=(xb, yb, zb), dtype=dtype)
    u['g'] = np.sin(x) * np.sin(y) * np.sin(z)
    # Problem
    dt = operators.TimeDerivative
    problem = problems.IVP([u])
    problem.add_equation((dt(u) + u, 0))
    # Solver
    solver = solvers.InitialValueSolver(problem, timesteppers.RK222)
    # Output
    tasks = [
        u,
        u(x=0),
        u(y=0),
        u(z=0),
        u(x=0, y=0),
        u(x=0, z=0),
        u(y=0, z=0),
        u(x=0, y=0, z=0)
    ]
    with tempfile.TemporaryDirectory(dir='.') as tempdir:
        tempdir = pathlib.Path(tempdir).stem
        output = solver.evaluator.add_file_handler(tempdir, iter=1)
        for task in tasks:
            output.add_task(task,
                            layout=output_layout,
                            name=str(task),
                            scales=output_scales)
        solver.evaluator.evaluate_handlers([output])
        output.process_virtual_file()
        # Check solution
        #post.merge_process_files('test_output')
        errors = []
        with h5py.File(f'{tempdir}/{tempdir}_s1.h5', mode='r') as file:
            for task in tasks:
                task_saved = file['tasks'][str(task)][-1]
                task = task.evaluate()
                task.change_scales(output_scales)
                errors.append(np.max(np.abs(task[output_layout] - task_saved)))
    assert np.allclose(errors, 0)
Пример #3
0
def build_2d_box(Nx, Nz, dealias, dtype, k=0):
    c = coords.CartesianCoordinates('x', 'z')
    d = distributor.Distributor((c,))
    if dtype == np.complex128:
        xb = basis.ComplexFourier(c.coords[0], size=Nx, bounds=(0, Lx))
    elif dtype == np.float64:
        xb = basis.RealFourier(c.coords[0], size=Nx, bounds=(0, Lx))
    zb = basis.ChebyshevT(c.coords[1], size=Nz, bounds=(0, Lz))
    b = (xb, zb)
    x = xb.local_grid(1)
    z = zb.local_grid(1)
    return c, d, b, x, z
Пример #4
0
def test_flow_tools_cfl(x_basis_class, Nx, Nz, timestepper, dtype, safety,
                        z_velocity_mag, dealias):
    # Bases
    Lx = 2
    Lz = 1
    c = coords.CartesianCoordinates('x', 'z')
    d = distributor.Distributor((c, ))
    xb = x_basis_class(c.coords[0], size=Nx, bounds=(0, Lx), dealias=dealias)
    x = xb.local_grid(1)
    zb = basis.ChebyshevT(c.coords[1],
                          size=Nz,
                          bounds=(0, Lz),
                          dealias=dealias)
    z = zb.local_grid(1)
    b = (xb, zb)
    # Fields
    u = field.Field(name='u', dist=d, tensorsig=(c, ), bases=b, dtype=dtype)
    # Problem
    ddt = operators.TimeDerivative
    problem = problems.IVP([u])
    problem.add_equation((ddt(u), 0))
    # Solver
    solver = solvers.InitialValueSolver(problem, timestepper)
    # cfl initialization
    dt = 1
    cfl = flow_tools.CFL(solver, dt, safety=safety, cadence=1)
    cfl.add_velocity(u)

    # Test Fourier CFL
    fourier_velocity = lambda x: np.sin(4 * np.pi * x / Lx)
    chebyshev_velocity = lambda z: -z_velocity_mag * z
    u['g'][0] = fourier_velocity(x)
    u['g'][1] = chebyshev_velocity(z)
    solver.step(dt)
    solver.step(
        dt
    )  #need two timesteps to get past stored_dt per compute_timestep logic
    dt = cfl.compute_timestep()
    op = operators.AdvectiveCFL(u, c)
    cfl_freq = np.abs(u['g'][0] / op.cfl_spacing(u)[0])
    cfl_freq += np.abs(u['g'][1] / op.cfl_spacing(u)[1])
    cfl_freq = np.max(cfl_freq)
    dt_comparison = safety * (cfl_freq)**(-1)
    assert np.allclose(dt, dt_comparison)
Пример #5
0
def test_chebyshev_AdvectiveCFL(Nx, timestepper, dtype, dealias):
    # Bases
    Lx = 1
    c = coords.CartesianCoordinates('x')
    d = distributor.Distributor((c, ))
    xb = basis.ChebyshevT(c.coords[0],
                          size=Nx,
                          bounds=(0, Lx),
                          dealias=dealias)
    x = xb.local_grid(1)
    # Fields
    u = field.Field(name='u',
                    dist=d,
                    tensorsig=(c, ),
                    bases=(xb, ),
                    dtype=dtype)
    velocity = lambda x: x
    u['g'][0] = velocity(x)
    # AdvectiveCFL initialization
    cfl = operators.AdvectiveCFL(u, c)
    cfl_freq = cfl.evaluate()['g']
    comparison_freq = np.abs(u['g']) / cfl.cfl_spacing(u)[0]
    assert np.allclose(cfl_freq, comparison_freq)
Пример #6
0
 def __init__(self, Nx, Ny, Lx, Ly, dtype, **kw):
     self.Nx = Nx
     self.Ny = Ny
     self.Lx = Lx
     self.Ly = Ly
     self.dtype = dtype
     self.N = Nx * Ny
     self.R = 2 * Nx + 2 * Ny
     self.M = self.N + self.R
     # Bases
     self.c = c = coords.CartesianCoordinates('x', 'y')
     self.d = d = distributor.Distributor((c, ))
     self.xb = xb = basis.ChebyshevT(c.coords[0], Nx, bounds=(0, Lx))
     self.yb = yb = basis.ChebyshevT(c.coords[1], Ny, bounds=(0, Ly))
     self.x = x = xb.local_grid(1)
     self.y = y = yb.local_grid(1)
     xb2 = xb._new_a_b(1.5, 1.5)
     yb2 = yb._new_a_b(1.5, 1.5)
     # Forcing
     self.f = f = field.Field(name='f',
                              dist=d,
                              bases=(xb2, yb2),
                              dtype=dtype)
     # Boundary conditions
     self.uL = uL = field.Field(name='f', dist=d, bases=(yb, ), dtype=dtype)
     self.uR = uR = field.Field(name='f', dist=d, bases=(yb, ), dtype=dtype)
     self.uT = uT = field.Field(name='f', dist=d, bases=(xb, ), dtype=dtype)
     self.uB = uB = field.Field(name='f', dist=d, bases=(xb, ), dtype=dtype)
     # Fields
     self.u = u = field.Field(name='u', dist=d, bases=(xb, yb), dtype=dtype)
     self.tx1 = tx1 = field.Field(name='tx1',
                                  dist=d,
                                  bases=(xb2, ),
                                  dtype=dtype)
     self.tx2 = tx2 = field.Field(name='tx2',
                                  dist=d,
                                  bases=(xb2, ),
                                  dtype=dtype)
     self.ty1 = ty1 = field.Field(name='ty1',
                                  dist=d,
                                  bases=(yb2, ),
                                  dtype=dtype)
     self.ty2 = ty2 = field.Field(name='ty2',
                                  dist=d,
                                  bases=(yb2, ),
                                  dtype=dtype)
     # Problem
     Lap = lambda A: operators.Laplacian(A, c)
     self.problem = problem = problems.LBVP([u, tx1, tx2, ty1, ty2])
     problem.add_equation((Lap(u), f))
     problem.add_equation((u(y=Ly), uT))
     problem.add_equation((u(x=Lx), uR))
     problem.add_equation((u(y=0), uB))
     problem.add_equation((u(x=0), uL))
     # Solver
     self.solver = solver = solvers.LinearBoundaryValueSolver(
         problem,
         bc_top=False,
         tau_left=False,
         store_expanded_matrices=False,
         **kw)
     # Tau entries
     L = solver.subproblems[0].L_min.tolil()
     # Taus
     for nx in range(Nx):
         L[Ny - 1 + nx * Ny, Nx * Ny + 0 * Nx + nx] = 1  # tx1 * Py1
         L[Ny - 2 + nx * Ny, Nx * Ny + 1 * Nx + nx] = 1  # tx2 * Py2
     for ny in range(Ny - 2):
         L[(Nx - 1) * Ny + ny,
           Nx * Ny + 2 * Nx + 0 * Ny + ny] = 1  # ty1 * Px1
         L[(Nx - 2) * Ny + ny,
           Nx * Ny + 2 * Nx + 1 * Ny + ny] = 1  # ty2 * Px2
     # BC taus not resolution safe
     if Nx != Ny:
         raise ValueError("Current implementation requires Nx == Ny.")
     else:
         # Remember L is left preconditoined but not right preconditioned
         L[-7, Nx * Ny + 2 * Nx + 0 * Ny + Ny - 2] = 1  # Right -2
         L[-5, Nx * Ny + 2 * Nx + 0 * Ny + Ny - 1] = 1  # Right -1
         L[-3, Nx * Ny + 2 * Nx + 1 * Ny + Ny - 2] = 1  # Left -2
         L[-1, Nx * Ny + 2 * Nx + 1 * Ny + Ny - 1] = 1  # Left -1
     solver.subproblems[0].L_min = L.tocsr()
     # Neumann operators
     ux = operators.Differentiate(u, c.coords[0])
     uy = operators.Differentiate(u, c.coords[1])
     self.duL = -ux(x='left')
     self.duR = ux(x='right')
     self.duT = uy(y='right')
     self.duB = -uy(y='left')
     # Neumann matrix
     duT_mat = self.duT.expression_matrices(solver.subproblems[0],
                                            vars=[u])[u]
     duR_mat = self.duR.expression_matrices(solver.subproblems[0],
                                            vars=[u])[u]
     duB_mat = self.duB.expression_matrices(solver.subproblems[0],
                                            vars=[u])[u]
     duL_mat = self.duL.expression_matrices(solver.subproblems[0],
                                            vars=[u])[u]
     self.interior_to_neumann_matrix = sp.vstack(
         [duT_mat, duR_mat, duB_mat, duL_mat], format='csr')
Пример #7
0
rank = MPI.COMM_WORLD.rank
import logging
logger = logging.getLogger(__name__)
dtype = np.complex128 #np.float64

Nx = 64
Nz = 32
Lz = 2*np.pi
# Bases
c = coords.CartesianCoordinates('x', 'z')
d = distributor.Distributor((c,))
if dtype == np.complex128:
    xb = basis.ComplexFourier(c.coords[0], size=Nx, bounds=(0, 2*np.pi), dealias=3/2)
elif dtype == np.float64:
    xb = basis.RealFourier(c.coords[0], size=Nx, bounds=(0, 2*np.pi), dealias=3/2)
zb = basis.ChebyshevT(c.coords[1], size=Nz, bounds=(0, Lz),dealias=3/2)
x = xb.local_grid(1)
z = zb.local_grid(1)
zb1 = basis.ChebyshevU(c.coords[1], size=Nz, bounds=(0, Lz), alpha0=0)
t1 = field.Field(name='t1', dist=d, bases=(xb,), dtype=dtype)
t2 = field.Field(name='t2', dist=d, bases=(xb,), dtype=dtype)
P1 = field.Field(name='P1', dist=d, bases=(zb1,), dtype=dtype)
if rank == 0:
    P1['c'][0,-1] = 1
dz = lambda A: operators.Differentiate(A, c.coords[1])
P2 = dz(P1).evaluate()

# Fields
u = field.Field(name='u', dist=d, bases=(xb,zb), dtype=dtype)
F = field.Field(name='F', dist=d, bases=(xb,zb), dtype=dtype)
u_true = 0
Пример #8
0
logger = logging.getLogger(__name__)

# Parameters
Lx, Ly, Lz = (4, 4, 1)
Nx, Ny, Nz = 8, 8, 16
Prandtl = 1
Rayleigh = 3000
timestep = 0.01
stop_iteration = 10

# Bases
c = coords.CartesianCoordinates('x', 'y', 'z')
d = distributor.Distributor((c, ))
xb = basis.ComplexFourier(c.coords[0], size=Nx, bounds=(0, Lx))
yb = basis.ComplexFourier(c.coords[1], size=Ny, bounds=(0, Ly))
zb = basis.ChebyshevT(c.coords[2], size=Nz, bounds=(0, Lz))

# Fields
p = field.Field(name='p', dist=d, bases=(xb, yb, zb), dtype=np.complex128)
b = field.Field(name='b', dist=d, bases=(xb, yb, zb), dtype=np.complex128)
u = field.Field(name='u',
                dist=d,
                bases=(xb, yb, zb),
                dtype=np.complex128,
                tensorsig=(c, ))

# Taus
zb2 = basis.ChebyshevV(c.coords[2], size=Nz, bounds=(0, Lz), alpha0=0)
t1 = field.Field(name='t4', dist=d, bases=(xb, yb), dtype=np.complex128)
t2 = field.Field(name='t4', dist=d, bases=(xb, yb), dtype=np.complex128)
t3 = field.Field(name='t4',
Пример #9
0
import numpy as np
from dedalus.core import coords, distributor, basis, field, operators
from mpi4py import MPI

comm = MPI.COMM_WORLD

results = []

## 2D Fourier * Chebyshev
c = coords.CartesianCoordinates('x', 'y')
d = distributor.Distributor((c, ))
xb = basis.ComplexFourier(c.coords[0], size=16, bounds=(0, 2 * np.pi))
yb = basis.ChebyshevT(c.coords[1], size=16, bounds=(0, 1))
x = xb.local_grid(1)
y = yb.local_grid(1)

# Gradient of a scalar
f = field.Field(dist=d, bases=(xb, yb), dtype=np.complex128)
f.name = 'f'
f['g'] = np.sin(x) * y**5
u = operators.Gradient(f, c)
u = u.evaluate()
u.name = 'u'
ug = np.array([np.cos(x) * y**5, np.sin(x) * 5 * y**4])
result = np.allclose(u['g'], ug)
results.append(result)
print(len(results), ':', result, '(gradient of a scalar)')

# Gradient of a vector
T = operators.Gradient(u, c)
T = T.evaluate()
Пример #10
0
def main(N, alpha, method, tau):
    # Bases
    c = coords.Coordinate('x')
    d = distributor.Distributor((c,))
    xb = basis.ChebyshevT(c, size=N, bounds=(-1, 1))
    x = xb.local_grid(1)
    # Fields
    u = field.Field(name='u', dist=d, bases=(xb,), dtype=np.float64)
    ux = field.Field(name='ux', dist=d, bases=(xb,), dtype=np.float64)
    f = field.Field(name='f', dist=d, bases=(xb,), dtype=np.float64)
    t1 = field.Field(name='t1', dist=d, dtype=np.float64)
    t2 = field.Field(name='t2', dist=d, dtype=np.float64)
    pi, sin, cos = np.pi, np.sin, np.cos
    f['g'] = 64*pi**3*(4*pi*sin(4*pi*x)**2*sin(4*pi*cos(4*pi*x)) + cos(4*pi*x)*cos(4*pi*cos(4*pi*x))) + alpha*sin(4*pi*cos(4*pi*x))
    # Tau polynomials
    xb1 = xb._new_a_b(xb.a+1, xb.b+1)
    xb2 = xb._new_a_b(xb.a+2, xb.b+2)
    if tau == 0:
        # First-order classical Chebyshev tau: T[-1], dx(T[-1])
        p1 = field.Field(name='p1', dist=d, bases=(xb,), dtype=np.float64)
        p2 = field.Field(name='p2', dist=d, bases=(xb,), dtype=np.float64)
        p1['c'][-1] = 1
        p2['c'][-1] = 1
    elif tau == 1:
        # First-order ultraspherical tau: U[-1], dx(U[-1])
        p1 = field.Field(name='p1', dist=d, bases=(xb1,), dtype=np.float64)
        p2 = field.Field(name='p2', dist=d, bases=(xb1,), dtype=np.float64)
        p1['c'][-1] = 1
        p2['c'][-1] = 1
    # Problem
    dx = lambda A: operators.Differentiate(A, c)
    problem = problems.LBVP([u, ux, t1, t2])
    problem.add_equation((alpha*u - dx(ux) + t1*p1, f))
    problem.add_equation((ux - dx(u) + t2*p2, 0))
    problem.add_equation((u(x=-1), 0))
    problem.add_equation((u(x=+1), 0))
    solver = solvers.LinearBoundaryValueSolver(problem)
    # Methods
    if method == 0:
        # Condition number
        L_exp = solver.subproblems[0].L_exp
        result = np.linalg.cond(L_exp.A)
    elif method == 1:
        # Roundtrip roundoff with uniform u
        A = solver.subproblems[0].L_exp
        v = np.random.rand(A.shape[1])
        f = A * v
        u = solver.subproblem_matsolvers[solver.subproblems[0]].solve(f)
        result = np.max(np.abs(u-v))
    elif method == 2:
        # Manufactured solution
        from mpi4py_fft import fftw as mpi4py_fftw
        solver.solve()
        ue = np.sin(4*np.pi*np.cos(4*np.pi*x))
        d = mpi4py_fftw.aligned(N, fill=0)
        k = 2*(1 + np.arange((N-1)//2))
        d[::2] = (2./N)/np.hstack((1., 1.-k*k))
        w = mpi4py_fftw.aligned_like(d)
        dct = mpi4py_fftw.dctn(w, axes=(0,), type=3)
        weights = dct(d, w)
        result = np.sqrt(np.sum(weights*(u['g']-ue)**2))
    elif method == 3:
        # Roundtrip roundoff with uniform f
        A = solver.subproblems[0].L_exp
        g = np.random.rand(A.shape[0])
        v = solver.subproblem_matsolvers[solver.subproblems[0]].solve(g)
        f = A * v
        u = solver.subproblem_matsolvers[solver.subproblems[0]].solve(f)
        result = np.max(np.abs(u-v))
    return result