Beispiel #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)
Beispiel #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)
Beispiel #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
Beispiel #4
0
def build_RF_RF(Nx, Ny, dealias_x, dealias_y):
    c = coords.CartesianCoordinates('x', 'y')
    d = distributor.Distributor((c, ))
    xb = basis.RealFourier(c.coords[0],
                           size=Nx,
                           bounds=(0, np.pi),
                           dealias=dealias_x)
    yb = basis.RealFourier(c.coords[1],
                           size=Ny,
                           bounds=(0, np.pi),
                           dealias=dealias_y)
    x = xb.local_grid(dealias_x)
    y = yb.local_grid(dealias_y)
    return c, d, xb, yb, x, y
Beispiel #5
0
def test_cartesian_output_virtual(dtype, dealias, output_scales):
    Nx = Ny = Nz = 16
    Lx = Ly = Lz = 2 * np.pi
    # Bases
    c = coords.CartesianCoordinates('x', 'y', 'z')
    d = distributor.Distributor((c,), mesh=(2,2))
    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 = Fourier(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)
    v = field.Field(name='v', dist=d, bases=(xb,yb,zb), tensorsig=(c,), dtype=dtype)
    u['g'] = np.sin(x) * np.sin(y) * np.sin(z)
    # Problem
    dt = operators.TimeDerivative
    problem = problems.IVP([u, v])
    problem.add_equation((dt(u) + u, 0))
    problem.add_equation((dt(v) + v, 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),
             v, v(x=0), v(y=0), v(z=0), v(x=0,y=0), v(x=0,z=0), v(y=0,z=0), v(x=0,y=0,z=0)]
    output = solver.evaluator.add_file_handler('test_output', iter=1, max_writes=1, virtual_file=True)
    for task in tasks:
        output.add_task(task, layout='g', name=str(task), scales=output_scales)
    solver.evaluator.evaluate_handlers([output])
    # Check solution
    errors = []
    d.comm.Barrier()
    with h5py.File('test_output/test_output_s1.h5', mode='r') as file:
        for task in tasks:
            task_name = str(task)
            task = task.evaluate()
            task.change_scales(output_scales)
            local_slices = (slice(None),) * len(task.tensorsig) + d.grid_layout.slices(task.domain, task.scales)
            task_saved = file['tasks'][task_name][-1]
            task_saved = task_saved[local_slices]
            local_error = task['g'] - task_saved
            if local_error.size:
                errors.append(np.max(np.abs(task['g'] - task_saved)))
    with Sync() as sync:
        if sync.comm.rank == 0:
            shutil.rmtree('test_output')
    assert np.allclose(errors, 0)
Beispiel #6
0
def build_CF_J(a, b, Nx, Ny, dealias_x, dealias_y):
    c = coords.CartesianCoordinates('x', 'y')
    d = distributor.Distributor((c, ))
    xb = basis.ComplexFourier(c.coords[0],
                              size=Nx,
                              bounds=(0, np.pi),
                              dealias=dealias_x)
    yb = basis.Jacobi(c.coords[1],
                      a=a,
                      b=b,
                      size=Ny,
                      bounds=(0, 1),
                      dealias=dealias_y)
    x = xb.local_grid(dealias_x)
    y = yb.local_grid(dealias_y)
    return c, d, xb, yb, x, y
Beispiel #7
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)
Beispiel #8
0
def test_fourier_AdvectiveCFL(x_basis_class, Nx, timestepper, dtype, dealias):
    Lx = 1
    # Bases
    c = coords.CartesianCoordinates('x')
    d = distributor.Distributor((c, ))
    xb = x_basis_class(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: np.sin(2 * np.pi * x / Lx)
    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)
Beispiel #9
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')
Beispiel #10
0
import numpy as np
from dedalus.core import coords, distributor, basis, field, operators, problems, solvers
from dedalus.tools import logging
from mpi4py import MPI
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()