Exemple #1
0
    def __init__(self, nx, ny, nz, Lx, Ly, Lz, threeD=False, mesh=None):
        """
        Initializes the dedalus domain object. Many of the inputs match those in
        the class attribute docstring.

        Other attributes:
        -----------------
        mesh    : list of ints
            The CPU grid on which the domain is distributed.
        """
        self.nx, self.ny, self.nz = nx, ny, nz
        self.Lx, self.Ly, self.Lz = Lx, Ly, Lz
        self.threeD = threeD

        x_basis = de.Fourier('x',
                             nx,
                             interval=(-Lx / 2, Lx / 2),
                             dealias=3 / 2)
        self.bases = [
            x_basis,
        ]
        if threeD:
            y_basis = de.Fourier('y',
                                 ny,
                                 interval=(-Ly / 2, Ly / 2),
                                 dealias=3 / 2)
            self.bases += [y_basis]

        if isinstance(nz, list) and isinstance(Lz, list):
            Lz_int = 0
            z_basis_list = []
            for Lz_i, nz_i in zip(Lz, nz):
                Lz_top = Lz_i + Lz_int
                z_basis = de.Chebyshev('z',
                                       nz_i,
                                       interval=[Lz_int, Lz_top],
                                       dealias=3 / 2)
                z_basis_list.append(z_basis)
                Lz_int = Lz_top
            self.Lz = Lz_int
            self.nz = np.sum(nz)
            self.Lz_list = Lz
            self.nz_list = nz
            z_basis = de.Compound('z', tuple(z_basis_list), dealias=3 / 2)
        else:
            z_basis = de.Chebyshev('z', nz, interval=(0, Lz), dealias=3 / 2)
            self.Lz_list = None
            self.nz_list = None
        self.bases += [z_basis]
        self.domain = de.Domain(self.bases,
                                grid_dtype=np.float64,
                                mesh=mesh,
                                comm=MPI.COMM_WORLD)

        self.x = self.domain.grid(0)
        if threeD:
            self.y = self.domain.grid(1)
        else:
            self.y = None
        self.z = self.domain.grid(-1)
Exemple #2
0
def DoubleChebyshev(name, N, interval=(-1, 1), dealias=1):
    N0 = int(N // 2)
    N1 = N - N0
    L = interval[1] - interval[0]
    int0 = (interval[0], interval[0] + L / 2)
    int1 = (interval[0] + L / 2, interval[1])
    b0 = de.Chebyshev('b0', N0, interval=int0, dealias=dealias)
    b1 = de.Chebyshev('b1', N1, interval=int1, dealias=dealias)
    return de.Compound(name, (b0, b1), dealias=dealias)
Exemple #3
0
def DoubleLaguerre(name, N, interval=(-1,1), dealias=1):
    N0 = int(N // 2)
    N1 = N - N0
    L = interval[1] - interval[0]
    C = (interval[0] + interval[1]) / 2
    int0 = (C, C + L/2)
    int1 = (C, C - L/2)
    b0 = de.Chebyshev('b0', N0, interval=int0, dealias=dealias)
    b1 = de.Chebyshev('b1', N1, interval=int1, dealias=dealias)
    return de.Compound(name, (b0, b1), dealias=dealias)
    def __init__(self,
                 nr,
                 nz,
                 Lr,
                 Lz,
                 *args,
                 r_cheby=False,
                 twoD=False,
                 **kwargs):
        """
        Initialize the domain. Sets up a 2D (z, r) grid, with chebyshev
        decomposition in the z-direction and fourier decomposition in the r-direction.

        Inputs:
        -------
        nr, nz  : ints
            Number of coefficients in r- and z- direction
        Lr, Lz  : floats
            The size of the domain in the r- and z- direction
        *args, **kwargs : tuple, dict
            Arguments and keyword arguments for the DedalusIntegrator._polytrope_initialize() function
        """
        self.Lz, self.Lr = Lz, Lr
        if r_cheby:
            if twoD:
                bounds = (-5, Lz)
            else:
                bounds = (0, Lz)
            self.r_basis = de.Chebyshev('r', nr, interval=(0, Lr))
            self.z_basis = de.Fourier('z', nz, interval=bounds)
            self.domain = de.Domain([self.z_basis, self.r_basis],
                                    grid_dtype=np.float64)
            self.r = self.domain.grid(1)
            self.z = self.domain.grid(0)
        else:
            self.r_basis = de.Fourier('r', nr, interval=(0, Lr))
            self.z_basis = de.Chebyshev('z', nz, interval=(0, Lz))
            self.domain = de.Domain([self.r_basis, self.z_basis],
                                    grid_dtype=np.float64)
            self.r = self.domain.grid(0)
            self.z = self.domain.grid(1)
        self.T0 = self.domain.new_field()
        self.rho0 = self.domain.new_field()
        self.rho0_z = self.domain.new_field()
        self.grad_ln_rho0 = self.domain.new_field()
        self.fields = [self.T0, self.rho0, self.rho0_z, self.grad_ln_rho0]
        self.fd1 = self.domain.new_field()
        self.fd2 = self.domain.new_field()
        self.fd3 = self.domain.new_field()
        self.sm_fields = [self.fd1, self.fd2, self.fd3]
        self._polytrope_initialize(*args, **kwargs)
Exemple #5
0
 def __init__(self, radius, L_max, N_max, R_max, L_dealias, N_dealias, m_max=None, mesh=None, comm=None):
     if m_max is None:
         m_max  = L_max
     self.radius = radius
     self.L_max = L_max
     self.N_max = N_max
     self.R_max = R_max
     self.L_dealias = L_dealias
     self.N_dealias = N_dealias
     # Domain
     phi_basis = de.Fourier('phi', 2*(L_max+1), interval=(0, 2*np.pi), dealias=L_dealias)
     theta_basis = de.Chebyshev('theta', L_max+1, interval=(0, np.pi), dealias=L_dealias)
     r_basis = de.Chebyshev('r', N_max+1, interval=(0, 1), dealias=N_dealias)
     self.domain = domain = de.Domain([phi_basis, theta_basis, r_basis], grid_dtype=np.float64, mesh=mesh, comm=comm)
     # Local m
     mesh = self.domain.distributor.mesh
     if len(mesh) == 0:
         phi_layout = domain.distributor.layouts[3]
         th_m_layout = domain.distributor.layouts[2]
         ell_r_layout = domain.distributor.layouts[1]
         r_ell_layout = domain.distributor.layouts[1]
     elif len(mesh) == 1:
         phi_layout = domain.distributor.layouts[4]
         th_m_layout = domain.distributor.layouts[2]
         ell_r_layout = domain.distributor.layouts[1]
         r_ell_layout = domain.distributor.layouts[1]
     elif len(mesh) == 2:
         phi_layout = domain.distributor.layouts[5]
         th_m_layout = domain.distributor.layouts[3]
         ell_r_layout = domain.distributor.layouts[2]
         r_ell_layout = domain.distributor.layouts[1]
     self.m_start = th_m_layout.slices(scales=1)[0].start
     self.m_end = th_m_layout.slices(scales=1)[0].stop-1
     self.m_size = self.m_end - self.m_start + 1
     self.ell_start = r_ell_layout.slices(scales=1)[1].start
     self.ell_end = r_ell_layout.slices(scales=1)[1].stop-1
     # Ball wrapper
     N_theta = int((L_max+1)*L_dealias)
     N_r = int((N_max+1)*N_dealias)
     self.B = B = ball_wrapper.Ball(N_max, L_max, N_theta=N_theta, N_r=N_r, R_max=R_max,
         ell_min=self.ell_start, ell_max=self.ell_end, m_min=self.m_start, m_max=self.m_end, a=0.)
     # Grids
     grid_slices = phi_layout.slices(domain.dealias)
     self.phi = domain.grid(0, scales=domain.dealias)[grid_slices[0], :, :]
     self.theta = B.grid(1, dimensions=3)[:, grid_slices[1], :] # local
     self.r = radius * B.grid(2, dimensions=3)[:, :, grid_slices[2]] # local
     self.weight_theta = B.weight(1, dimensions=3)[:, grid_slices[1], :]
     self.weight_r = radius**3 * B.weight(2, dimensions=3)[:, :, grid_slices[2]]
    def domain_setup(self):
        # Parameters
        Lx, Ly, Lz = (1., 1., 1.)
        self.Nd = 3
        self.Nx = 50
        self.Ny = 10
        self.Nz = 10
        self.scale = 1
        epsilon = 0.8
        self.Pr = 1.0

        Ra_crit = 1707.762  # No-slip top & bottom
        self.Ra = Ra_crit * (1 + epsilon)
        self.F = self.Ra * self.Pr
        # Create bases and self.domain
        self.x_basis = de.Fourier('x',
                                  self.Nx,
                                  interval=(0, Lx),
                                  dealias=self.scale)
        self.y_basis = de.Fourier('y',
                                  self.Ny,
                                  interval=(0, Ly),
                                  dealias=self.scale)
        self.z_basis = de.Chebyshev('z',
                                    self.Nz,
                                    interval=(-Lz / 2, Lz / 2),
                                    dealias=self.scale)
        self.domain = de.Domain([self.x_basis, self.y_basis, self.z_basis],
                                grid_dtype=np.float64)
Exemple #7
0
def test_rbc_growth(Nz, sparse):
    z = de.Chebyshev('z', Nz, interval=(0, 1))
    d = de.Domain([z])

    rayleigh_benard = de.EVP(d, ['p', 'b', 'u', 'w', 'bz', 'uz', 'wz'],
                             eigenvalue='omega')
    rayleigh_benard.parameters['k'] = 3.117  #horizontal wavenumber
    rayleigh_benard.parameters['Ra'] = 1708.  #Rayleigh number, rigid-rigid
    rayleigh_benard.parameters['Pr'] = 1  #Prandtl number
    rayleigh_benard.parameters['dzT0'] = 1
    rayleigh_benard.substitutions['dt(A)'] = 'omega*A'
    rayleigh_benard.substitutions['dx(A)'] = '1j*k*A'

    rayleigh_benard.add_equation("dx(u) + wz = 0")
    rayleigh_benard.add_equation(
        "dt(u) - Pr*(dx(dx(u)) + dz(uz)) + dx(p)           = -u*dx(u) - w*uz")
    rayleigh_benard.add_equation(
        "dt(w) - Pr*(dx(dx(w)) + dz(wz)) + dz(p) - Ra*Pr*b = -u*dx(w) - w*wz")
    rayleigh_benard.add_equation(
        "dt(b) - w*dzT0 - (dx(dx(b)) + dz(bz)) = -u*dx(b) - w*bz")
    rayleigh_benard.add_equation("dz(u) - uz = 0")
    rayleigh_benard.add_equation("dz(w) - wz = 0")
    rayleigh_benard.add_equation("dz(b) - bz = 0")
    rayleigh_benard.add_bc('left(b) = 0')
    rayleigh_benard.add_bc('right(b) = 0')
    rayleigh_benard.add_bc('left(w) = 0')
    rayleigh_benard.add_bc('right(w) = 0')
    rayleigh_benard.add_bc('left(u) = 0')
    rayleigh_benard.add_bc('right(u) = 0')

    EP = eig.Eigenproblem(rayleigh_benard, sparse=sparse)

    growth, index, freq = EP.growth_rate({})
    assert np.allclose([growth, freq[0]], [0.0018125573647729994, 0.])
def get_solver(setup_problem, XMAX, ZMAX, N_X, N_Z, T_F, KX, KZ, H, RHO0, G,
               A):
    # Bases and domain
    x_basis = de.Fourier('x', N_X, interval=(0, XMAX), dealias=3 / 2)
    z_basis = de.Chebyshev('z', N_Z, interval=(0, ZMAX), dealias=3 / 2)
    domain = de.Domain([x_basis, z_basis], np.float64)
    z = domain.grid(1)

    problem = de.IVP(domain, variables=['P', 'rho', 'ux', 'uz'])
    problem.meta['uz']['z']['dirichlet'] = True
    problem.parameters['L'] = XMAX
    problem.parameters['g'] = G
    problem.parameters['H'] = H
    problem.parameters['A'] = A
    problem.parameters['KX'] = KX
    problem.parameters['KZ'] = KZ
    problem.parameters['omega'] = get_omega(G, H, KX, KZ)

    # rho0 stratification
    rho0 = domain.new_field()
    rho0.meta['x']['constant'] = True
    rho0['g'] = RHO0 * np.exp(-z / H)
    problem.parameters['rho0'] = rho0

    setup_problem(problem, domain)

    # Build solver
    solver = problem.build_solver(de.timesteppers.RK443)
    solver.stop_sim_time = T_F
    solver.stop_wall_time = np.inf
    solver.stop_iteration = np.inf
    return solver, domain
Exemple #9
0
def domain_from_file(filename, basis_types, dealias=3 / 2):
    with h5py.File(filename, 'r') as dfile:
        testkey = next(iter(dfile['tasks']))
        testdata = dfile['tasks'][testkey]
        dims = testdata.shape[1:]  # trim write dimension
        dim_names = [
            i.decode('utf-8') for i in testdata.attrs['DIMENSION_LABELS'][1:]
        ]
        if not testdata.attrs['grid_space'][-1]:
            dims[-1] *= 2
        bases = []
        for n, b, d in zip(dim_names, basis_types, dims):
            if b == 'Fourier':
                limits = limits_from_grid('Fourier',
                                          dfile['/scales/' + n + '/1.0'])
                basis = de.Fourier(n, d, interval=limits, dealias=dealias)
            elif b == 'SinCos':
                limits = limits_from_grid('SinCos',
                                          dfile['/scales/' + n + '/1.0'])
                basis = de.SinCos(n, d, interval=limits, dealias=dealias)
            elif b == 'Chebyshev':
                limits = (-1, 1)  # limits not implemented for Chebyshev
                basis = de.Chebyshev(n, d, limits=limits, dealias=dealias)
            else:
                raise ValueError("Unknown basis type:", basis_type)

            bases.append(basis)
        d = de.Domain(bases,
                      grid_dtype=np.float64)  # hardcoded domain dtype for now
        return d
def get_solver(params):
    ''' sets up solver '''
    x_basis = de.Fourier('x',
                         params['N_X'],
                         interval=(0, params['XMAX']),
                         dealias=3 / 2)
    z_basis = de.Chebyshev('z',
                           params['N_Z'],
                           interval=(0, params['ZMAX']),
                           dealias=3 / 2)
    domain = de.Domain([x_basis, z_basis], np.float64)
    z = domain.grid(1)

    problem = de.IVP(domain,
                     variables=[
                         'P',
                         'rho',
                         'ux',
                         'uz',
                         'ux_z',
                         'uz_z',
                     ])
    problem.parameters.update(params)

    # rho0 stratification
    rho0 = domain.new_field()
    rho0.meta['x']['constant'] = True
    rho0['g'] = params['RHO0'] * np.exp(-z / params['H'])
    problem.parameters['rho0'] = rho0

    problem.substitutions['sponge'] = 'SPONGE_STRENGTH * 0.5 * ' +\
        '(2 + tanh((z - SPONGE_HIGH) / (0.6 * (ZMAX - SPONGE_HIGH))) - ' +\
        'tanh((z - SPONGE_LOW) / (0.6 * (SPONGE_LOW))))'
    problem.add_equation('dx(ux) + dz(uz) = 0')
    problem.add_equation('dt(rho) - rho0 * uz / H' +
                         '= - sponge * rho - ux * dx(rho) - uz * dz(rho) +' +
                         'F * exp(-(z - Z0)**2 / (2 * S**2)) *' +
                         'cos(KX * x - OMEGA * t)')
    problem.add_equation('dt(ux) + dx(P) / rho0' +
                         '- NU * (dx(dx(ux)) + dz(ux_z))' +
                         '= - sponge * ux - ux * dx(ux) - uz * dz(ux)')
    problem.add_equation('dt(uz) + dz(P) / rho0 + rho * g / rho0' +
                         '- NU * (dx(dx(uz)) + dz(uz_z))' +
                         '= - sponge * uz - ux * dx(uz) - uz * dz(uz)')
    problem.add_equation('dz(ux) - ux_z = 0')
    problem.add_equation('dz(uz) - uz_z = 0')

    problem.add_bc('left(uz) = 0')
    problem.add_bc('left(ux) = 0')
    problem.add_bc('right(uz) = 0')
    problem.add_bc('right(ux) = 0')
    problem.add_bc('right(P) = 0')

    # Build solver
    solver = problem.build_solver(de.timesteppers.RK443)
    solver.stop_sim_time = params['T_F']
    solver.stop_wall_time = np.inf
    solver.stop_iteration = np.inf
    return solver, domain
def create_domain(nx=32, nz=32, L=20, H=10):

    # Create bases and domain
    x_basis = de.Fourier('x',   nx, interval=(-L/2, L/2))
    y_basis = de.Fourier('y',   nx, interval=(-L/2, L/2))
    z_basis = de.Chebyshev('z', nz, interval=(-H, 0))
    
    return de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64)
Exemple #12
0
def simple_domain(nx, nz, Lx=2 * np.pi, Ly=2 * np.pi, Lz=1):

    x_basis = de.Fourier('x', nx, interval=(-Lx / 2, Lx / 2))
    y_basis = de.Fourier('y', nx, interval=(-Ly / 2, Ly / 2))
    z_basis = de.Chebyshev('z', nz, interval=(-Lz, 0))

    domain = de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64)

    return domain
    def read_files(self, keys):
        import h5py
        for i, dir in enumerate(self.dir_info):
            try:
                #            if True:
                f = h5py.File(dir[0] + self.out_dir_name + self.out_file_name,
                              'r')

                Lz = np.exp(dir[self.parameters.index('nrhocz') + 1] /
                            (1.5 - dir[self.parameters.index('eps') + 1])) - 1
                z_basis = de.Chebyshev('z',
                                       len(f['z']),
                                       interval=[0, Lz],
                                       dealias=3 / 2)
                domain = de.Domain([z_basis],
                                   grid_dtype=np.float64,
                                   comm=MPI.COMM_SELF)
                current_field = domain.new_field()
                output_field = domain.new_field()
                storage = dict()
                for key_info in keys:
                    key, type = key_info
                    if type == 'val':
                        if len(f[key].shape) == 1:
                            if f[key].shape[0] == 1:
                                storage[key] = (np.log(f[key][0]), 0, 0)
                            else:
                                storage[key + '_profile'] = f[key]
                        else:
                            storage[key + '_profile'] = f[key][0, 0, :]
                    elif type == 'midplane':
                        current_field['g'] = f[key]
                        storage[key] = (current_field.interpolate(z=Lz /
                                                                  2)['g'][0],
                                        0, 0)
                    elif type == 'minmax':
                        storage[key] = (f[key + '_mean'][0],
                                        f[key + '_mean'][0] - np.min(f[key]),
                                        np.max(f[key]) - f[key + '_mean'][0])
                    elif type == 'logmaxovermin':
                        storage[key] = (np.log(
                            np.max(f[key]) / np.min(f[key])), 0, 0)
                    if 'Ma_ad' in key:  #This is a workaround for my current incorrect implementation of Ma_ad (off by sqrt(gamma))
                        storage[key] = list(storage[key])
                        for i in range(len(storage[key])):
                            storage[key][i] = storage[key][i] * np.sqrt(5 / 3)
                for key in storage.keys():
                    if np.isnan(storage[key][0]):
                        raise
                dir[-1] = storage
            except:
                print("PROBLEMS READING OUTPUT FILE IN {:s}".format(dir[0]))
                import sys
                sys.stdout.flush()
        return self.dir_info
Exemple #14
0
 def __init__(self, nz=256):
     # Bases and domain
     import dedalus.public as de
     z_basis = de.Chebyshev('z', nz, interval=(0, 1), dealias=1)
     domain = de.Domain([z_basis], np.float64, comm=MPI.COMM_SELF)
     self.T0 = domain.new_field()
     self.T0_z = domain.new_field()
     self.ln_rho0_z = domain.new_field()
     self.H_rho = domain.new_field()
     self.ln_rho0 = domain.new_field()
     self.z = domain.grid(0)
Exemple #15
0
def LCCL(name, N, center=0.0, stretch=1.0, cwidth=1.0, dealias=1):
    b1 = de.Laguerre('b1',
                     int(N // 4),
                     edge=center - cwidth,
                     stretch=-stretch,
                     dealias=dealias)
    b2 = de.Chebyshev('b2',
                      int(N // 4),
                      interval=(center - cwidth, center),
                      dealias=dealias)
    b3 = de.Chebyshev('b3',
                      int(N // 4),
                      interval=(center, center + cwidth),
                      dealias=dealias)
    b4 = de.Laguerre('b4',
                     int(N // 4),
                     edge=center + cwidth,
                     stretch=stretch,
                     dealias=dealias)
    return de.Compound(name, (b1, b2, b3, b4), dealias=dealias)
Exemple #16
0
def ChebLag(name, N, edge=0.0, stretch=1.0, cwidth=1.0, dealias=1):
    b1 = de.Chebyshev('b1',
                      int(N // 2),
                      interval=(edge, edge + cwidth),
                      dealias=dealias)
    b2 = de.Laguerre('b2',
                     int(N // 2),
                     edge=edge + cwidth,
                     stretch=stretch,
                     dealias=dealias)
    return de.Compound(name, (b1, b2), dealias=dealias)
Exemple #17
0
 def build_domain(self):
     self.x_basis = de.Fourier('x',
                               self.nx,
                               interval=(0, self.Lx),
                               dealias=3 / 2)
     self.y_basis = de.Fourier('y',
                               self.ny,
                               interval=(0, self.Ly),
                               dealias=3 / 2)
     self.z_basis = de.Chebyshev('z', self.nz, interval=(-1, 1))
     self.domain = de.Domain([self.x_basis, self.y_basis, self.z_basis],
                             grid_dtype=np.float64)
Exemple #18
0
def rotating_rbc_evp(Ek, Ra, k, Nz=24):
    z = de.Chebyshev('z', Nz, interval=(0, 1))
    d = de.Domain([z], comm=MPI.COMM_SELF)

    variables = ['T', 'Tz', 'p', 'u', 'v', 'w', 'Ox', 'Oy']
    problem = de.EVP(d, variables, eigenvalue='omega')

    #Parameters
    problem.parameters['kx'] = k / np.sqrt(2)  #horizontal wavenumber (x)
    problem.parameters['ky'] = k / np.sqrt(2)  #horizontal wavenumber (y)
    problem.parameters['Ra'] = Ra  #Rayleigh number
    problem.parameters['Pr'] = 1  #Prandtl number
    problem.parameters['Pm'] = 1  #Magnetic Prandtl number
    problem.parameters['E'] = Ek
    problem.parameters['dzT0'] = -1

    #Substitutions
    problem.substitutions["dt(A)"] = "omega*A"
    problem.substitutions["dx(A)"] = "1j*kx*A"
    problem.substitutions["dy(A)"] = "1j*ky*A"
    problem.substitutions['UdotGrad(A,A_z)'] = '(u*dx(A) + v*dy(A) + w*(A_z))'
    problem.substitutions['Lap(A,A_z)'] = '(dx(dx(A)) + dy(dy(A)) + dz(A_z))'
    problem.substitutions["Oz"] = "dx(v)-dy(u)"
    problem.substitutions["Kz"] = "dx(Oy)-dy(Ox)"
    problem.substitutions["Ky"] = "dz(Ox)-dx(Oz)"
    problem.substitutions["Kx"] = "dy(Oz)-dz(Oy)"

    #Dimensionless parameter substitutions
    problem.substitutions["inv_Re_ff"] = "(Pr/Ra)**(1./2.)"
    problem.substitutions["inv_Pe_ff"] = "(Ra*Pr)**(-1./2.)"

    #Equations
    problem.add_equation(
        "dt(T) + w*dzT0   - inv_Pe_ff*Lap(T, Tz)          = -UdotGrad(T, Tz)")

    problem.add_equation(
        "dt(u)  + dx(p)   + inv_Re_ff*(Kx - v/E)     = v*Oz - w*Oy")
    problem.add_equation(
        "dt(v)  + dy(p)   + inv_Re_ff*(Ky + u/E)     = w*Ox - u*Oz")
    problem.add_equation(
        "dt(w)  + dz(p)   + inv_Re_ff*(Kz)       - T = u*Oy - v*Ox")

    problem.add_equation("dx(u)  + dy(v)  + dz(w)  = 0")

    problem.add_equation("Ox - (dy(w) - dz(v)) = 0")
    problem.add_equation("Oy - (dz(u) - dx(w)) = 0")
    problem.add_equation("Tz - dz(T) = 0")

    bcs = ['T', 'u', 'v', 'w']
    for bc in bcs:
        problem.add_bc(" left({}) = 0".format(bc))
        problem.add_bc("right({}) = 0".format(bc))
    return problem
    def _set_domain(self,
                    nx=256,
                    Lx=4,
                    ny=256,
                    Ly=4,
                    nz=128,
                    Lz=1,
                    grid_dtype=np.float64,
                    comm=MPI.COMM_WORLD,
                    mesh=None):
        self.mesh = mesh

        z_basis = de.Chebyshev('z', nz, interval=[0., Lz], dealias=3 / 2)
        if self.dimensions > 1:
            x_basis = de.Fourier('x', nx, interval=[0., Lx], dealias=3 / 2)
        if self.dimensions > 2:
            y_basis = de.Fourier('y', ny, interval=[0., Ly], dealias=3 / 2)
        if self.dimensions == 1:
            bases = [z_basis]
        elif self.dimensions == 2:
            bases = [x_basis, z_basis]
        elif self.dimensions == 3:
            bases = [x_basis, y_basis, z_basis]
        else:
            logger.error('>3 dimensions not implemented')

        self.domain = de.Domain(bases,
                                grid_dtype=grid_dtype,
                                comm=comm,
                                mesh=mesh)

        self.z = self.domain.grid(-1)  # need to access globally-sized z-basis
        self.Lz = self.domain.bases[-1].interval[1] - self.domain.bases[
            -1].interval[0]  # global size of Lz
        self.nz = self.domain.bases[-1].coeff_size

        self.z_dealias = self.domain.grid(axis=-1, scales=self.domain.dealias)

        if self.dimensions == 1:
            self.x, self.Lx, self.nx, self.delta_x = None, 0, None, None
            self.y, self.Ly, self.ny, self.delta_y = None, 0, None, None
        if self.dimensions > 1:
            self.x = self.domain.grid(0)
            self.Lx = self.domain.bases[0].interval[1] - self.domain.bases[
                0].interval[0]  # global size of Lx
            self.nx = self.domain.bases[0].coeff_size
            self.delta_x = self.Lx / self.nx
        if self.dimensions > 2:
            self.y = self.domain.grid(1)
            self.Ly = self.domain.bases[1].interval[1] - self.domain.bases[
                0].interval[0]  # global size of Lx
            self.ny = self.domain.bases[1].coeff_size
            self.delta_y = self.Ly / self.ny
Exemple #20
0
def build_LHS(Nz):

    # Parameters
    terms = 1
    dt = 1e-3
    kx = 50 * np.pi
    sigma = 1
    Prandtl = 1.
    Reynolds = 1e2
    ts = de.timesteppers.SBDF3

    # Create bases and domain
    z_basis = de.Chebyshev('z', Nz, interval=(-1, 1), dealias=3 / 2)
    domain = de.Domain([z_basis], grid_dtype=np.complex128)

    # 2D Boussinesq hydrodynamics
    problem = de.IVP(domain,
                     variables=['p', 'b', 'u', 'w', 'bz', 'uz', 'wz'],
                     ncc_cutoff=1e-10,
                     max_ncc_terms=terms)
    problem.meta[:]['z']['dirichlet'] = True
    problem.parameters['P'] = 1 / Reynolds / Prandtl
    problem.parameters['R'] = 1 / Reynolds
    problem.parameters['kx'] = kx
    problem.parameters['sigma'] = sigma
    problem.substitutions['Bz'] = "exp(-(z-1)**2 / 2 / sigma**2)"
    problem.substitutions['dx(A)'] = "1j*kx*A"
    problem.add_equation("dx(u) + wz = 0")
    problem.add_equation("dt(b) - P*(dx(dx(b)) + dz(bz)) + Bz*w      = 0")
    problem.add_equation("dt(u) - R*(dx(dx(u)) + dz(uz)) + dx(p)     = 0")
    problem.add_equation("dt(w) - R*(dx(dx(w)) + dz(wz)) + dz(p) - b = 0")
    problem.add_equation("bz - dz(b) = 0")
    problem.add_equation("uz - dz(u) = 0")
    problem.add_equation("wz - dz(w) = 0")
    problem.add_bc("left(b) = 0")
    problem.add_bc("left(u) = 0")
    problem.add_bc("left(w) = 0")
    problem.add_bc("right(b) = 0")
    problem.add_bc("right(u) = 0")
    if kx == 0:
        problem.add_bc("right(p) = 0")
    else:
        problem.add_bc("right(w) = 0", )

    # Build solver
    solver = problem.build_solver(ts)

    # Step solver to form pencil LHS
    for i in range(10):
        solver.step(dt)

    return solver.pencils[0].LHS
Exemple #21
0
def build_LHS(Nz, bw, format, entry_cutoff=0):

    # Parameters
    dt = 1e-3
    kx = 50 * np.pi
    sigma = 1
    ts = de.timesteppers.RK222

    # Create bases and domain
    z1 = de.Chebyshev('z', Nz, interval=(-1, 1), dealias=3 / 2)
    z2 = de.Chebyshev('z', Nz, interval=(1, 2), dealias=3 / 2)
    z3 = de.Chebyshev('z', Nz, interval=(2, 3), dealias=3 / 2)
    z_basis = de.Compound('z', [z1, z2, z3])
    domain = de.Domain([z_basis], grid_dtype=np.complex128)

    # 2D Boussinesq hydrodynamics
    problem = de.IVP(domain,
                     variables=['T', 'Tz'],
                     ncc_cutoff=0,
                     max_ncc_terms=bw,
                     entry_cutoff=entry_cutoff)
    problem.meta[:]['z']['dirichlet'] = True
    problem.parameters['kx'] = kx
    problem.parameters['sigma'] = sigma
    problem.substitutions['kappa'] = "exp(-(z-1)**2 / 2 / sigma**2)"
    problem.substitutions['dx(A)'] = "1j*kx*A"
    problem.add_equation("dt(T) - dx(kappa*dx(T)) - dz(kappa*Tz) = 0")
    problem.add_equation("Tz - dz(T) = 0")
    problem.add_bc("left(T) = 0")
    problem.add_bc("right(T) = 0")

    # Build solver
    solver = problem.build_solver(ts)

    # Step solver to form pencil LHS
    for i in range(1):
        solver.step(dt)

    return solver, solver.pencils[0].LHS.asformat(format)
 def problem_setup(self,
                   L=2.,
                   nx=192,
                   nz=96,
                   Prandtl_number=1.,
                   Rayleih_number=1e4,
                   bc_type='no_slip'):
     self.L = float(L)
     self.nx = int(nx)
     self.nz = int(nz)
     x_basis = de.Fourier('x', int(nx), interval=(0, L), dealias=3 / 2)
     z_basis = de.Chebyshev('z', int(nz), interval=(0, 1), dealias=3 / 2)
     self.saving_shape = (int(nx * 3 / 2), int(nz * 3 / 2))
     self.domain = de.Domain([x_basis, z_basis], grid_dtype=np.float64)
     self.problem = de.IVP(
         self.domain, variables=['T', 'Tz', 'psi', 'psiz', 'curl', 'curlz'])
     self.problem.parameters['L'] = L
     self.problem.parameters['nx'] = nx
     self.problem.parameters['nz'] = nz
     self.Pr = float(Prandtl_number)
     self.Ra = float(Rayleih_number)
     self.problem.parameters['Ra'] = self.Ra
     self.problem.parameters['Pr'] = self.Pr
     # Stream function relation to the speed
     self.problem.substitutions['u'] = "-dz(psi)"
     self.problem.substitutions['v'] = "dx(psi)"
     # Derivatives values relation to the main values
     self.problem.add_equation("psiz - dz(psi) = 0")
     self.problem.add_equation("curlz - dz(curl) = 0")
     self.problem.add_equation("Tz - dz(T) = 0")
     self.problem.add_equation("curl + dx(dx(psi)) + dz(psiz) = 0")
     self.problem.add_equation(
         "dt(curl)+Ra*Pr*dx(T)-Pr*(dx(dx(curl))+dz(curlz))=-(u*dx(curl)+v*curlz)"
     )
     self.problem.add_equation("dt(T)-dx(dx(T))-dz(Tz)=-(u*dx(T)+v*Tz)")
     self.problem.add_bc("left(T) = 1")
     self.problem.add_bc("right(T) = 0")
     self.problem.add_bc("left(psi) = 0")
     self.problem.add_bc("right(psi) = 0")
     if bc_type not in ['no_slip', 'free_slip']:
         raise ValueError(
             "Boundary Conditions must be 'no_slip' or 'free_slip'")
     else:
         if bc_type == 'no_slip':
             self.problem.add_bc("left(psiz) = 0")
             self.problem.add_bc("right(psiz) = 0")
         if bc_type == 'free_slip':
             self.problem.add_bc("left(dz(psiz)) = 0")
             self.problem.add_bc("right(dz(psiz)) = 0")
Exemple #23
0
def grid(Lx, Ly, Lz, nx, ny, nz):
    x_basis = de.Fourier("x", nx, interval=(0, Lx), dealias=3 / 2)
    y_basis = de.Fourier("y", ny, interval=(0, Ly), dealias=3 / 2)
    z_basis = de.Chebyshev("z", nz, interval=(-Lz, Lz), dealias=3 / 2)
    domain = de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64)

    # Unscaled grid (physical space)
    x = domain.grid(0)
    y = domain.grid(1)
    z = domain.grid(2)

    X, Y = np.meshgrid(x, y, indexing='ij')
    Y2, Z = np.meshgrid(y, z, indexing='ij')
    kx, ky = np.meshgrid(x_basis.wavenumbers, y_basis.wavenumbers, indexing='ij')
    x2, ky2 = np.meshgrid(x, y_basis.wavenumbers, indexing='ij')
    nkx, nky = kx.shape
def solve_mcwilliams_preconditioner_problem(
    buoyancy_bc="right(ψz) = 0",
    h=0.1,
    lx=1 / 2,
    ly=1 / 4,
    f=1,
    nx=32,
    nz=32,
):

    # Create bases and domain
    x_basis = de.Fourier('x', nx, interval=(-np.pi, np.pi))
    y_basis = de.Fourier('y', nx, interval=(-np.pi, np.pi))
    z_basis = de.Chebyshev('z', nz, interval=(-1, 0))
    domain = de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64)

    # Poisson equation
    problem = de.LBVP(domain, variables=['ψ', 'ψz'])

    problem.parameters['h'] = h
    problem.parameters['lx'] = lx
    problem.parameters['ly'] = ly
    problem.parameters['f'] = f
    problem.parameters['N'] = h / (f * lx)
    problem.parameters['US'] = f * lx

    problem.substitutions[
        'uSy'] = "- y * US / ly**2 * exp(z/h - x**2 / (2 * lx**2) - y**2 / (2 * ly**2))"
    problem.substitutions[
        'uSz'] = "US / h * exp(z/h - x**2 / (2 * lx**2) - y**2 / (2 * ly**2))"

    problem.add_equation("dx(dx(ψ)) + dy(dy(ψ)) + f**2 / N**2 * dz(ψz) = -uSy",
                         condition="(nx != 0) or (ny != 0)")

    problem.add_equation("ψ = 0", condition="(nx == 0) and (ny == 0)")
    problem.add_equation("ψz = 0", condition="(nx == 0) and (ny == 0)")
    problem.add_equation("dz(ψ) - ψz = 0", condition="(nx != 0) or (ny != 0)")

    problem.add_bc("left(ψz) = 0", condition="(nx != 0) or (ny != 0)")
    problem.add_bc(buoyancy_bc, condition="(nx != 0) or (ny != 0)")

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

    return solver
Exemple #25
0
def solve_hydrostatic_pressure(param, dtype, comm=MPI.COMM_SELF):
    """Build domain and solve hydrostatic pressure from parameters."""
    # NLBVP domain
    z_basis = de.Chebyshev('z', param.Nz, interval=(0, param.Lz), dealias=2)
    domain = de.Domain([z_basis], grid_dtype=dtype, comm=comm)
    # Solve NLBVP for background
    X0 = np.array([param.p_bottom, -param.ρ_bottom * param.g])
    P = (param.N2_func, param.g, param.γ)
    p_full, pz_full = solve_dedalus(X0,
                                    P,
                                    domain,
                                    tolerance=param.nlbvp_tolerance,
                                    ncc_cutoff=param.nlbvp_cutoff,
                                    max_ncc_terms=param.nlbvp_max_terms)
    a_full = domain.new_field()
    a_full.set_scales(2)
    a_full['g'] = -param.g / pz_full['g']
    return domain, p_full, a_full
Exemple #26
0
def build_FC(N, dealias, dtype):
    c = d3.CartesianCoordinates('x', 'y')
    d = d3.Distributor(c, dtype=dtype)
    if dtype == np.complex128:
        xb = d3.ComplexFourier(c.coords[0],
                               size=N,
                               bounds=(0, Lx),
                               dealias=dealias)
    elif dtype == np.float64:
        xb = d3.RealFourier(c.coords[0],
                            size=N,
                            bounds=(0, Lx),
                            dealias=dealias)
    yb = d3.Chebyshev(c.coords[1], size=N, bounds=(0, Ly), dealias=dealias)
    b = (xb, yb)
    x = xb.local_grid(dealias)
    y = yb.local_grid(dealias)
    r = (x, y)
    return c, d, b, r
Exemple #27
0
def _get_solver(setup_problem, params, variables):
    ''' get solver for given variables '''
    x_basis = de.Fourier('x',
                         params['N_X'],
                         interval=(0, params['XMAX']),
                         dealias=3/2)
    z_basis = de.Chebyshev('z',
                           params['N_Z'],
                           interval=(0, params['ZMAX']),
                           dealias=3/2)
    domain = de.Domain([x_basis, z_basis], np.float64)
    z = domain.grid(1)

    problem = de.IVP(domain, variables=variables)
    problem.parameters['L'] = params['XMAX']
    problem.parameters['g'] = params['G']
    problem.parameters['H'] = params['H']
    problem.parameters['A'] = params['A']
    problem.parameters['F'] = params['F']
    problem.parameters['KX'] = params['KX']
    problem.parameters['KZ'] = params['KZ']
    problem.parameters['NU'] = params['NU']
    problem.parameters['RHO0'] = params['RHO0']
    problem.parameters['omega'] = params['OMEGA']
    problem.parameters['ZMAX'] = params['ZMAX']

    problem.parameters['Z0'] = 0.2 * params['ZMAX']
    problem.parameters['S'] = params['H']

    # rho0 stratification
    rho0 = domain.new_field()
    rho0.meta['x']['constant'] = True
    rho0['g'] = params['RHO0'] * np.exp(-z / params['H'])
    problem.parameters['rho0'] = rho0

    setup_problem(problem, domain, params)

    # Build solver
    solver = problem.build_solver(de.timesteppers.RK222)
    solver.stop_sim_time = params['T_F']
    solver.stop_wall_time = np.inf
    solver.stop_iteration = np.inf
    return solver, domain
Exemple #28
0
 def __init__(self, param, dim, dtype=np.float64, comm=None):
     # Solve and truncate background
     bvp_domain, p0_full, a0_full = background.solve_hydrostatic_pressure(
         param, dtype)
     p0_full, p0_trunc, a0_full, a0_trunc, heq, N2 = background.truncate_background(
         param, p0_full, a0_full)
     # Save domain and backgrounds
     if dim == 1:
         # Use BVP results
         self.domain = bvp_domain
         self.a0 = a0_trunc
         self.p0 = p0_trunc
     elif dim == 2:
         # Construct new domain
         x_basis = de.Fourier('x',
                              param.Nx,
                              interval=(0, param.Lx),
                              dealias=2)
         z_basis = de.Chebyshev('z',
                                param.Nz,
                                interval=(0, param.Lz),
                                dealias=2)
         self.domain = de.Domain([x_basis, z_basis],
                                 grid_dtype=dtype,
                                 comm=comm)
         # Background state
         self.a0 = a0 = self.domain.new_field()
         self.p0 = p0 = self.domain.new_field()
         a0.meta['x']['constant'] = True
         p0.meta['x']['constant'] = True
         a0.set_scales(1)
         p0.set_scales(1)
         a0_trunc.set_scales(1)
         p0_trunc.set_scales(1)
         slices = self.domain.dist.grid_layout.slices(scales=1)
         a0['g'][:] = a0_trunc['g'][slices[1]]
         p0['g'][:] = p0_trunc['g'][slices[1]]
     else:
         raise ValueError("Dimension must be 1 or 2")
     # Store derivatives
     self.a0z = self.a0.differentiate('z')
     self.p0z = self.p0.differentiate('z')
def get_solver(setup_problem, params):
    ''' get solver '''
    x_basis = de.Fourier('x',
                         params['N_X'],
                         interval=(0, params['XMAX']),
                         dealias=3 / 2)
    z_basis = de.Chebyshev('z',
                           params['N_Z'],
                           interval=(0, params['ZMAX']),
                           dealias=3 / 2)
    domain = de.Domain([x_basis, z_basis], np.float64)
    z = domain.grid(1)

    problem = de.IVP(domain, variables=['P', 'rho', 'ux', 'uz'])
    problem.parameters['L'] = params['XMAX']
    problem.parameters['g'] = params['G']
    problem.parameters['H'] = params['H']
    problem.parameters['A'] = params['A']
    problem.parameters['F'] = params['F']
    problem.parameters['KX'] = params['KX']
    problem.parameters['KZ'] = params['KZ']
    problem.parameters['NU'] = params['NU']
    problem.parameters['RHO0'] = params['RHO0']
    problem.parameters['omega'] = params['OMEGA']
    problem.parameters['ZMAX'] = params['ZMAX']

    # rho0 stratification
    # rho0 = domain.new_field()
    # rho0.meta['x']['constant'] = True
    # rho0['g'] = params['RHO0'] * np.exp(-z / params['H'])
    # problem.parameters['rho0'] = rho0
    problem.parameters['rho0'] = params['RHO0']

    setup_problem(problem, domain, params)

    # Build solver
    solver = problem.build_solver(params['TIMESTEPPER'])
    solver.stop_sim_time = params['T_F']
    solver.stop_wall_time = np.inf
    solver.stop_iteration = np.inf
    return solver, domain
Exemple #30
0
def erf_tanh_compound(nx,
                      intervals,
                      center,
                      width,
                      fig_name='erf_tanh_compound.png'):

    x_basis_list = []
    for i in range(len(nx)):
        print('sub interval {} : {} (nx={})'.format(i, intervals[i], nx[i]))
        x_basis = de.Chebyshev('x',
                               nx[i],
                               interval=intervals[i],
                               dealias=3 / 2)
        x_basis_list.append(x_basis)

    x_basis = de.Compound('x', tuple(x_basis_list), dealias=3 / 2)
    domain = de.Domain([x_basis])

    make_plots(domain,
               fig_name=fig_name,
               intervals=intervals,
               nx_intervals=np.cumsum(nx))