Example #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)
Example #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)
Example #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)
Example #4
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)
Example #5
0
def DoubleLaguerre(name, N, center=0.0, stretch=1.0, dealias=1):
    b0 = de.Laguerre('b0',
                     int(N // 2),
                     edge=center,
                     stretch=-stretch,
                     dealias=dealias)
    b1 = de.Laguerre('b1',
                     int(N // 2),
                     edge=center,
                     stretch=stretch,
                     dealias=dealias)
    return de.Compound(name, (b0, b1), dealias=dealias)
Example #6
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)
Example #7
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)
Example #8
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))
Example #9
0
def basis_from_basis(basis, factor):
    """duplicates input basis with number of modes multiplied by input factor.

    the new number of modes will be cast to an integer

    inputs
    ------
    basis : a dedalus basis
    factor : a float that will multiply the grid size by basis

    """
    basis_type = basis.__class__.__name__
    n_hi = int(basis.base_grid_size * factor)

    if type(basis) == de.Compound:
        sub_bases = []
        for sub_basis in basis.subbases:
            sub_basis_type = sub_basis.__class__.__name__
            try:
                nb = bases_register[sub_basis_type](
                    basis.name, n_hi, interval=sub_basis.interval)
            except KeyError:
                raise KeyError(
                    "Don't know how to make a basis of type {}".format(
                        basis_type))
            sub_bases.append(nb)
        new_basis = de.Compound(basis.name, tuple(sub_bases))
    else:
        try:
            new_basis = bases_register[basis_type](basis.name,
                                                   n_hi,
                                                   interval=basis.interval)
        except KeyError:
            raise KeyError(
                "Don't know how to make a basis of type {}".format(basis_type))

    return new_basis
Example #10
0
Rayleigh = 1e10 * 8
Prandtl = 1.
nu = 1 / np.sqrt(Rayleigh / Prandtl)
kappa = 1 / np.sqrt(Rayleigh * Prandtl)

S = 100
T_top = -200

N2 = np.abs(S * T_top * 2)
f = np.sqrt(N2) / (2 * np.pi)

N = int(256)
# Create bases and domain
z_basis_conv1 = de.Chebyshev('z', int(N / 2), interval=(0, z_match))
z_basis_rad1 = de.Chebyshev('z', int(N), interval=(z_match, Lz))
z_basis1 = de.Compound('z', [z_basis_conv1, z_basis_rad1])
domain1 = de.Domain([z_basis1], grid_dtype=np.complex128, comm=MPI.COMM_SELF)

int_field = domain1.new_field()
u_field = domain1.new_field()

ratio = []
for k in range(1, 21):
    data = pickle.load(open('eigenvalues/eigenvalue_data_k%i.pkl' % k, 'rb'))

    u = data['u']
    w = data['w']
    freq = data['values']

    ratio = []
    for i in range(u.shape[0]):
Example #11
0
    def __init__(self, atmosphere, resolution, aspect, mesh=None, 
                       dealias=3/2, comm=MPI.COMM_WORLD, dtype=np.float64):
        """
        Initializes a 2- or 3D domain. Horizontal directions (x, y) are Fourier decompositions,
        Vertical direction is either a Chebyshev (if nz, Lz are integers) or a compound
        Chebyshev (if nz, Lz are lists) domain.

        Parameters
        ----------
        All parameters match class attributes, as described in the class docstring.

        """
        self.atmosphere = atmosphere
        self.resolution = resolution
        self.aspect     = aspect
        self.dimensions  = len(self.resolution)
        self.mesh        = mesh
        self.dealias     = dealias
        self.dtype       = dtype
        self.comm        = comm

        #setup horizontal directions
        L_horiz = self.aspect*self.atmosphere.atmo_params['Lz']
        self.bases = []
        if self.dimensions >= 2:
            x_basis = de.Fourier('x', self.resolution[1], interval=(-L_horiz/2, L_horiz/2), dealias=dealias)
            self.bases += [x_basis]
        if self.dimensions == 3:
            y_basis = de.Fourier('y', self.resolution[2], interval=(-L_horiz/2, L_horiz/2), dealias=dealias)
            self.bases += [y_basis]

        #setup vertical direction
        if isinstance(self.resolution[0], list):
            Lz_int = 0
            z_basis_list = []
            for Lz_i, nz_i in zip(self.atmosphere.atmo_params['Lz_list'], self.resolution[0]):
                Lz_top = Lz_i + Lz_int
                z_basis = de.Chebyshev('z', nz_i, interval=[Lz_int, Lz_top], dealias=dealias)
                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=dealias)
        else:
            z_basis = de.Chebyshev('z', self.resolution[0], interval=(0, self.atmosphere.atmo_params['Lz']), dealias=dealias)
            self.Lz_list = None
            self.nz_list = None

        #create domain
        self.bases += [z_basis]
        self.domain = de.Domain(self.bases, grid_dtype=dtype, mesh=mesh, comm=comm)

        #store grid data
        if self.dimensions >= 2:
            self.x    = self.domain.grid(0)
            self.x_de = self.domain.grid(0, scales=dealias)
        else:
            self.x, self.x_de = None, None
        if self.dimensions == 3:
            self.y    = self.domain.grid(1)
            self.y_de = self.domain.grid(1, scales=dealias)
        else:
            self.y, self.y_de = None, None
        self.z    = self.domain.grid(-1)
        self.z_de = self.domain.grid(-1, scales=dealias)

        self.atmosphere.build_atmosphere(self)
Example #12
0
    def solve_hires(self, tol=1e-10):
        old_evp = self.EVP
        old_d = old_evp.domain
        old_x = old_d.bases[0]
        old_x_grid = old_d.grid(0, scales=old_d.dealias)
        if type(old_x) == de.Compound:
            bases = []
            for basis in old_x.subbases:
                old_x_type = basis.__class__.__name__
                n_hi = int(basis.base_grid_size * self.factor)
                if old_x_type == "Chebyshev":
                    x = de.Chebyshev(basis.name, n_hi, interval=basis.interval)
                elif old_x_type == "Fourier":
                    x = de.Fourier(basis.name, n_hi, interval=basis.interval)
                else:
                    raise ValueError(
                        "Don't know how to make a basis of type {}".format(
                            old_x_type))
                bases.append(x)
            x = de.Compound(old_x.name, tuple(bases))
        else:
            old_x_type = old_x.__class__.__name__
            n_hi = int(old_x.coeff_size * self.factor)
            if old_x_type == "Chebyshev":
                x = de.Chebyshev(old_x.name, n_hi, interval=old_x.interval)
            elif old_x_type == "Fourier":
                x = de.Fourier(old_x.name, n_hi, interval=old_x.interval)
            else:
                raise ValueError(
                    "Don't know how to make a basis of type {}".format(
                        old_x_type))
        d = de.Domain([x], comm=old_d.dist.comm)
        self.EVP_hires = de.EVP(d,
                                old_evp.variables,
                                old_evp.eigenvalue,
                                tolerance=tol)

        x_grid = d.grid(0, scales=d.dealias)

        for k, v in old_evp.substitutions.items():
            self.EVP_hires.substitutions[k] = v

        for k, v in old_evp.parameters.items():
            if type(v) == Field:  #NCCs
                new_field = d.new_field()
                v.set_scales(self.factor, keep_data=True)
                new_field['g'] = v['g']
                self.EVP_hires.parameters[k] = new_field
            else:  #scalars
                self.EVP_hires.parameters[k] = v

        for e in old_evp.equations:
            self.EVP_hires.add_equation(e['raw_equation'])

        try:
            for b in old_evp.boundary_conditions:
                self.EVP_hires.add_bc(b['raw_equation'])
        except AttributeError:
            # after version befc23584fea, Dedalus no longer
            # distingishes BCs from other equations
            pass

        solver = self.EVP_hires.build_solver()
        if self.sparse:
            solver.solve_sparse(solver.pencils[self.pencil],
                                N=10,
                                target=0,
                                rebuild_coeffs=True)
        else:
            solver.solve_dense(solver.pencils[self.pencil],
                               rebuild_coeffs=True)
        self.evalues_hires = solver.eigenvalues
logger.info(r_bot)
logger.info(r_top)

N = 256

r_int1 = 0.5
r_int2 = 0.8
r_int3 = r_top
#r_int3 = 0.95

# Create bases and domain
r_basis1 = de.Chebyshev('r', 2 * N, interval=(r_bot, r_int1))
r_basis2 = de.Chebyshev('r', N, interval=(r_int1, r_int2))
r_basis3 = de.Chebyshev('r', N, interval=(r_int2, r_int3))
r_basis = de.Compound('r', [r_basis1, r_basis2, r_basis3])
domain = de.Domain([r_basis], grid_dtype=np.float64, comm=MPI.COMM_SELF)

r_d = domain.grid(0)


def dedalus_interp(array):
    field = domain.new_field()
    interp = interpolate.interp1d(r / r[-1], array, kind='cubic')
    field['g'] = interp(r_d)
    return field


rho0 = dedalus_interp(rho)
g = dedalus_interp(g)
Gamma1 = dedalus_interp(Gamma_1)
Example #14
0
    if not os.path.isdir('k%i' %k):
        os.mkdir('k%i' %k)
MPI.COMM_WORLD.Barrier()

# want f_min(k) and f_max(k)
f_min = 0.5*k**(3/4)
f_max = 1*k**(3/4)

f_list = np.exp(np.linspace(np.log(f_min), np.log(f_max), num=100))
logger.info(f_list)

N = int(512)
# Create bases and domain
z_basis_conv = de.Chebyshev('z', int(N), interval=(0,z_match))
z_basis_rad  = de.Chebyshev('z', int(N/2),interval=(z_match,Lz))
z_basis = de.Compound('z',[z_basis_conv,z_basis_rad], dealias=3/2)
domain = de.Domain([z_basis], grid_dtype=np.complex128, comm=MPI.COMM_SELF)

T0 = domain.new_field()
T0.set_scales(1024*3/2/N)

data = np.loadtxt('T.dat')
T0['g'] = data[1,:]

T0.set_scales(1)

z = domain.grid(0)

T0z = T0.differentiate(0)
T0z.set_scales(1)
T0z['g'] *= 0.5*(1 + np.tanh( (z - 0.4)/0.01 ))
def run_salty_boussinesq_vpf(simname, ϵ, dt, comm, logger):
    ν = 1e-2
    κ = 1e-2
    γ = 1e-2
    μ = 1e-2
    M = .2
    N = 0
    L = 1
    β = 4 / 2.6482282
    #ϵ = #np.sqrt(1e-4)
    η = (β * ϵ)**2 / ν
    α = (5 / 6) * (L / κ) * ϵ

    nx = 128
    nz = 256
    #dt = float(sys.argv[2])#2e-4
    timestepper = 'SBDF2'
    #simname = f'salty-boussinesq-melting-vpf-tangent-{timestepper}-{ϵ:.0e}-conserved-passive'
    flt.makedir(f'{savedir}/frames/{simname}')
    tend = 10
    save_step = 1
    save_freq = round(save_step / dt)

    xbasis = de.Fourier('x', nx, interval=(0, 4), dealias=3 / 2)
    zb0 = de.Chebyshev('z0', 32, interval=(0, 10 * ϵ), dealias=3 / 2)
    zb1 = de.Chebyshev('z1', 64, interval=(10 * ϵ, 1 - 10 * ϵ), dealias=3 / 2)
    zb2 = de.Chebyshev('z2', 32, interval=(1 - 10 * ϵ, 1), dealias=3 / 2)
    zbasis = de.Compound('z', [zb0, zb1, zb2])
    domain = de.Domain([xbasis, zbasis], grid_dtype=np.float64, comm=comm)
    flt.save_domain(f'{savedir}/domain-{simname}.h5', domain)
    x, z = domain.grids(scales=domain.dealias)
    xx, zz = x + 0 * z, 0 * x + z
    xc = xx
    dims = range(1, 3)

    # Define GeneralFunction subclass to handle parities
    GeneralFunction = de.operators.GeneralFunction

    class HorizontalFunction(GeneralFunction):
        def __init__(
            self,
            domain,
            layout,
            func=None,
            args=[],
            kw={},
            out=None,
        ):
            super().__init__(
                domain,
                layout,
                func=func,
                args=args,
                kw=kw,
                out=out,
            )

        def meta_constant(self, axis):
            if axis == 1 or axis == 'z': return True
            else: return False

    refname = 'salty-boussinesq-melting-tangent-conserved-passive'
    reffile = glob.glob(f'{savedir}/interface-{refname}/*.h5')[0]
    t0s, x0s = flt.load_data(reffile, 'sim_time', 'x/1.0', group='scales')
    h0s, ht0s = flt.load_data(reffile, 'h', 'ht', group='tasks')
    from scipy.interpolate import RectBivariateSpline
    h0s, ht0s = np.squeeze(h0s), np.squeeze(ht0s)
    hspline = RectBivariateSpline(t0s, x0s, h0s)
    htspline = RectBivariateSpline(t0s, x0s, ht0s)

    def h_func(*args):
        return hspline(args[0].value, args[1].data[:, 0]).T

    def ht_func(*args):
        return htspline(args[0].value, args[1].data[:, 0]).T

    def h_op(*args, domain=domain, h_func=h_func):
        return HorizontalFunction(domain, layout='g', func=h_func, args=args)

    def ht_op(*args, domain=domain, ht_func=ht_func):
        return HorizontalFunction(domain, layout='g', func=ht_func, args=args)

    de.operators.parseables['h_op'] = h_op
    de.operators.parseables['ht_op'] = ht_op
    problem = de.IVP(domain,
                     variables=[
                         'u11', 'u12', 'u21', 'u22', 'p1', 'q1', 'p2', 'q2',
                         'T1', 'T1_2', 'T2', 'T2_2', 'C1', 'C1_2', 'C2',
                         'C2_2', 'f1', 'f1_2', 'f2', 'f2_2', 'E', 'S'
                     ])

    problem.meta[:]['z']['dirichlet'] = True
    problem.meta['E', 'S']['x', 'z']['constant'] = True
    problem.parameters['ν'] = ν
    problem.parameters['κ'] = κ
    problem.parameters['γ'] = γ
    problem.parameters['μ'] = μ
    problem.parameters['M'] = M
    problem.parameters['N'] = N
    problem.parameters['δ'] = 1e-4
    problem.parameters['ε'] = ϵ
    problem.parameters['L'] = L
    problem.parameters['η'] = η
    problem.parameters['α'] = α
    As = [4] * 5
    for i in range(len(As)):
        problem.parameters[f'A{i+1}'] = As[i]

    problem.substitutions['h'] = 'h_op(t,x)'
    problem.substitutions['ht'] = 'ht_op(t,x)'
    problem.substitutions['d_1(A)'] = 'dx(A)'
    problem.substitutions['d_2(A)'] = 'dz(A)'
    problem.substitutions['T1_1'] = 'd_1(T1)'
    problem.substitutions['T2_1'] = 'd_1(T2)'
    problem.substitutions['C1_1'] = 'd_1(C1)'
    problem.substitutions['C2_1'] = 'd_1(C2)'
    problem.substitutions['f1_1'] = 'd_1(f1)'
    problem.substitutions['f2_1'] = 'd_1(f2)'
    problem.substitutions['hx'] = 'd_1(h)'
    problem.substitutions['angle'] = 'sqrt(1 + hx**2)'
    problem.substitutions['omz1'] = 'sqrt(1 + (hx)**2)/(2-h)'
    problem.substitutions['omz2'] = 'sqrt(1 + (hx)**2)/h'
    problem.substitutions['curvature'] = 'dx(hx)/angle**3'
    problem.substitutions['xc'] = 'x'
    problem.substitutions['zc1'] = 'h + (2-h)*z'
    problem.substitutions['zc2'] = 'h*z'
    problem.substitutions['d_0(A)'] = '0'
    for l in [1, 2]:
        problem.substitutions[f'Kdet{l}'] = Kdet[l]
        for i in range(3):
            for j in range(3):
                problem.substitutions[f'J{l}{i}{j}'] = J.get((l, i, j), '0')
                problem.substitutions[f'K{l}{i}{j}'] = K.get((l, i, j), '0')
                problem.substitutions[f'g{l}{i}{j}'] = g.get((l, i, j), '0')
                for k in range(3):
                    problem.substitutions[f'G{l}{i}_{j}{k}'] = G.get(
                        (l, i, j, k), '0')

        for i in dims:
            for j in dims:
                problem.substitutions[
                    f'cd_{i}_u{l}{j}'] = f'd_{i}(u{l}{j})' + ' + '.join(
                        [''] + [
                            f'G{l}{j}_{k}{i}*u{l}{k}'
                            for k in dims if G.get((l, j, k, i), 0)
                        ])
        problem.substitutions[f'div{l}'] = f'cd_1_u{l}1 + cd_2_u{l}2'
        problem.substitutions[f'vorticity{l}'] = f'Kdet{l}*' + '({})'.format(
            ' + '.join([
                f'{eps[i,j]}*g{l}{i}{k}*cd_{k}_u{l}{j}' for k in dims
                for j in dims for i in dims if eps.get((i, j), 0)
            ]))
        for j in dims:
            problem.substitutions[
                f'curl_vorticity{l}{j}'] = f'(1/Kdet{l})*' + '({})'.format(
                    ' + '.join(f'{eps[i,j]}*d_{i}(q{l})'
                               for i in dims if eps.get((i, j), 0)))
        for k in dims:
            problem.substitutions[
                f'q_cross_u{l}{k}'] = f'Kdet{l}*q{l}*' + '({})'.format(
                    ' + '.join(f'{eps[i,j]}*g{l}{i}{k}*u{l}{j}' for i in dims
                               for j in dims if eps.get((i, j), 0)))
        for j in dims:
            problem.substitutions[f'grad_p{l}{j}'] = ' + '.join(
                [f'g{l}{i}{j}*d_{i}(p{l})' for i in dims])
        for j in dims:
            problem.substitutions[f'f{l}{j}'] = f'(T{l}+N*C{l})*J{l}2{j}'
        for j in dims:
            problem.substitutions[f'adv_u{l}{j}'] = ' + '.join([
                f'J{l}0{i}*d_{i}(u{l}{j})' for i in dims if J.get((l, 0, i), 0)
            ] + [
                f'J{l}0{i}*u{l}{k}*G{l}{j}_{k}{i}' for i in range(3)
                for k in dims if J.get((l, 0, i), 0) and G.get((l, j, k, i))
            ])
        for i in dims:
            problem.substitutions[
                f'dτu{l}{i}'] = f'- adv_u{l}{i} + ν*curl_vorticity{l}{i} - grad_p{l}{i} + q_cross_u{l}{i} - (f{l}/η)*u{l}{i} + f{l}{i}'
        for i in dims:
            problem.substitutions[f'dtu{l}{i}'] = f'dτu{l}{i} + adv_u{l}{i}'
        problem.substitutions[f'lapT{l}'] = '{} - ({})'.format(
            ' + '.join(
                [f'g{l}{i}{j}*d_{i}(T{l}_{j})' for i in dims for j in dims]),
            ' + '.join([
                f'g{l}{i}{j}*T{l}_{k}*G{l}{k}_{i}{j}' for i in dims
                for j in dims for k in dims if G.get((l, k, i, j))
            ]))
        problem.substitutions[f'lapC{l}'] = '{} - ({})'.format(
            ' + '.join(
                [f'g{l}{i}{j}*d_{i}(C{l}_{j})' for i in dims for j in dims]),
            ' + '.join([
                f'g{l}{i}{j}*C{l}_{k}*G{l}{k}_{i}{j}' for i in dims
                for j in dims for k in dims if G.get((l, k, i, j))
            ]))
        problem.substitutions[f'lapf{l}'] = '{} - ({})'.format(
            ' + '.join(
                [f'g{l}{i}{j}*d_{i}(f{l}_{j})' for i in dims for j in dims]),
            ' + '.join([
                f'g{l}{i}{j}*f{l}_{k}*G{l}{k}_{i}{j}' for i in dims
                for j in dims for k in dims if G.get((l, k, i, j))
            ]))
        problem.substitutions[f'udotT{l}'] = f'u{l}1*T{l}_1 + u{l}2*T{l}_2'
        problem.substitutions[f'udotC{l}'] = f'u{l}1*C{l}_1 + u{l}2*C{l}_2'
        problem.substitutions[
            f'ndotT{l}'] = f'left(( g{l}21*T{l}_1 + g{l}22*T{l}_2)/omz{l})'
        problem.substitutions[
            f'ndotf{l}'] = f'left(( g{l}21*f{l}_1 + g{l}22*f{l}_2)/omz{l})'
        problem.substitutions[
            f'f_flux{l}'] = f'-ε**(-2)*f{l}*(1-f{l})*(γ*(1-2*f{l}) + ε*(T{l}+M*C{l}))'
        problem.substitutions[f'dtf{l}'] = f'(1/α)*(γ*lapf{l} + f_flux{l})'
        problem.substitutions[f'dτf{l}'] = f'dtf{l} - ' + '({})'.format(
            ' + '.join(
                [f'J{l}0{i}*f{l}_{i}' for i in dims if J.get((l, 0, i))]))
        problem.substitutions[f'gradfdotgradC{l}'] = ' + '.join(
            [f'g{l}{i}{j}*f{l}_{i}*C{l}_{j}' for i in dims for j in dims])
        problem.substitutions[
            f'dτT{l}'] = 'κ*({}) - ({}) + ({}) - ({})'.format(
                f'lapT{l}', f'udotT{l}', f'L*dtf{l}', ' + '.join(
                    [f'J{l}0{i}*T{l}_{i}' for i in dims if J.get((l, 0, i))]))
        problem.substitutions[
            f'dτC{l}'] = 'μ*({}) - ({}) + ({}) - ({})'.format(
                f'lapC{l}', f'udotC{l}',
                f'(dtf{l}*C{l} - μ*gradfdotgradC{l})/(1-f{l}+δ)', ' + '.join(
                    [f'J{l}0{i}*C{l}_{i}' for i in dims if J.get((l, 0, i))]))
    # problem.substitutions['dτh'] = ' - (1/2)*(left(dtf1/(J122*f1_2)) + right(dtf2/(J222*f2_2)))'
    # # Cartesian quantities
    # problem.substitutions[f'ux{l}'] = ' + '.join(f'u{l}{j}*K{l}{j}1' for j in dims if K.get((l,j,1)))
    # problem.substitutions[f'uz{l}'] = ' + '.join(f'u{l}{j}*K{l}{j}2' for j in dims if K.get((l,j,2)))
    # problem.substitutions[f'kenergy{l}'] = f'0.5*(ux{l}**2 + uz{l}**2)'
    # problem.substitutions[f'pr{l}'] = f'p{l} - kenergy{l}'
    # problem.substitutions[f'dxc{l}(A)'] = ' + '.join(f'J{l}1{j}*d_{j}(A)' for j in dims if J.get((l,1,j)))
    # problem.substitutions[f'dzc{l}(A)'] = ' + '.join(f'J{l}2{j}*d_{j}(A)' for j in dims if J.get((l,2,j)))
    # problem.substitutions[f'dtux{l}'] = f'- dxc{l}(p{l}) - ν*dzc{l}(q{l}) + q{l}*uz{l}'
    # problem.substitutions[f'dtuz{l}'] = f'- dzc{l}(p{l}) + ν*dxc{l}(q{l}) - q{l}*ux{l}'
    # problem.substitutions[f'dtT1'] = f'- dzc{l}(p{l}) + ν*dxc{l}(q{l}) - q{l}*ux{l}'
    for l in [1, 2]:
        problem.add_equation(
            f'       A1*(d_1(u{l}1) + d_2(u{l}2)) = A1*(d_1(u{l}1) + d_2(u{l}2)) - div{l}'
        )
        problem.add_equation(
            f'q{l} + A2*(d_2(u{l}1) - d_1(u{l}2)) = A2*(d_2(u{l}1) - d_1(u{l}2)) + vorticity{l}'
        )
        problem.add_equation(
            f'dt(u{l}1) + A3*d_1(p{l}) + A4*ν*d_2(q{l}) =             A3*d_1(p{l}) + A4*ν*d_2(q{l}) + dτu{l}1'
        )
        problem.add_equation(
            f'dt(u{l}2) + A3*d_2(p{l}) - A4*ν*d_1(q{l}) - T2 = - T2 + A3*d_2(p{l}) - A4*ν*d_1(q{l}) + dτu{l}2'
        )
        problem.add_equation(f'T{l}_2 - d_2(T{l}) = 0')
        problem.add_equation(
            f'dt(T{l}) - κ*A5*(d_1(T{l}_1) + d_2(T{l}_2)) = - κ*A5*(d_1(T{l}_1) + d_2(T{l}_2)) + dτT{l}'
        )
        problem.add_equation(f'C{l}_2 - d_2(C{l}) = 0')
        problem.add_equation(
            f'dt(C{l}) - μ*A5*(d_1(C{l}_1) + d_2(C{l}_2)) = - μ*A5*(d_1(C{l}_1) + d_2(C{l}_2)) + dτC{l}'
        )
        problem.add_equation(f'f{l}_2 - d_2(f{l}) = 0')
        problem.add_equation(
            f'α*dt(f{l})-γ*A5*(d_1(f{l}_1) + d_2(f{l}_2)) = - γ*A5*(d_1(f{l}_1) + d_2(f{l}_2)) + α*dτf{l}'
        )
    # problem.add_equation('ht - (κ/L)*(right(T2_2) - right(T1_2)) = - (κ/L)*(right(T2_2) - right(T1_2)) + dτh')
    # problem.add_equation('ht = -100*(left(f1) - .5)')
    # problem.add_equation('dt(h) - ht = 0')
    problem.add_equation(
        'E = integ(Kdet1*(T1 + L*(1-f1)) + Kdet2*(T2 + L*(1-f2)))')
    problem.add_equation('S = integ(Kdet1*(1-f1)*C1 + Kdet2*(1-f2)*C2)')

    problem.add_bc('right(u11) = 0')
    problem.add_bc('right(u12) = 0', condition='nx != 0')
    # problem.add_bc('right(T1) = -1')
    problem.add_bc('right(T1_2) = 0')
    problem.add_bc('right(C1_2) = 0')
    problem.add_bc('right(f1_2) = 0')
    problem.add_bc('left(u11) - right(u21) = 0')
    problem.add_bc(
        'left(u12) - right(u22) = left((h-1)*u12) + right((h-1)*u22)')
    problem.add_bc('left(p1) - right(p2) = 0')
    problem.add_bc('left(q1) - right(q2) = 0')
    problem.add_bc('right(T2) - left(T1) = 0')
    problem.add_bc('right(C2) - left(C1) = 0')
    problem.add_bc('right(f2) - left(f1) = 0')
    # problem.add_bc('right(f2) = 0.5')
    problem.add_bc(
        'left(T1_2) - right(T2_2) = left((1-h)*T1_2) + right((1-h)*T2_2)')
    problem.add_bc(
        'left(C1_2) - right(C2_2) = left((1-h)*C1_2) + right((1-h)*C2_2)')
    problem.add_bc(
        'left(f1_2) - right(f2_2) = left((1-h)*f1_2) + right((1-h)*f2_2)')
    problem.add_bc('left(p2) = 0', condition='nx == 0')
    problem.add_bc('left(u21) = 0')
    problem.add_bc('left(u22) = 0')
    problem.add_bc('left(T2_2) = 0')
    # problem.add_bc('left(T2) = 1')
    problem.add_bc('left(C2_2) = 0')
    problem.add_bc('left(f2_2) = 0')

    solver = problem.build_solver(eval(f'de.timesteppers.{timestepper}'))

    solver.stop_sim_time = tend

    fields = {fname: solver.state[fname] for fname in problem.variables}
    for fname, field in fields.items():
        field.set_scales(domain.dealias)
    hop, htop = solver.evaluator.vars['h'], solver.evaluator.vars['ht']
    h, ht = hop.evaluate(), htop.evaluate()
    T1, T2, C1, C2, f1, f2, E, S = [
        fields[name]
        for name in ['T1', 'T2', 'C1', 'C2', 'f1', 'f2', 'E', 'S']
    ]
    xc = xx
    zc1 = h['g'] + (2 - h['g']) * zz
    zc2 = h['g'] * zz
    h['g'] = 1
    T1['g'] = 1 - zc1
    T2['g'] = 1 - zc2 + np.exp(-((xc - 2)**2 + (zc2 - .5)**2) * 5**2)
    T1.differentiate('z', out=fields['T1_2'])
    T2.differentiate('z', out=fields['T2_2'])
    C1['g'] = 0.05 + (1 - 0.05) * .5 * (1 - np.tanh(10 * (zc1 - .5)))
    C2['g'] = 0.05 + (1 - 0.05) * .5 * (1 - np.tanh(10 * (zc2 - .5)))
    C1.differentiate('z', out=fields['C1_2'])
    C2.differentiate('z', out=fields['C2_2'])
    zc1 = h['g'] + (2 - h['g']) * zz
    zc2 = h['g'] * zz
    f1['g'] = .5 * (1 + np.tanh(
        (1 / (2 * ϵ)) * (zc1 - h['g']) / np.sqrt(1 + d(h, 'x')**2)['g']))
    f2['g'] = .5 * (1 + np.tanh(
        (1 / (2 * ϵ)) * (zc2 - h['g']) / np.sqrt(1 + d(h, 'x')**2)['g']))
    f1.differentiate('z', out=fields['f1_2'])
    f2.differentiate('z', out=fields['f2_2'])
    E['g'] = (h * (T2 + L * (1 - f2)) + (2 - h) *
              (T1 + L * (1 - f1))).evaluate().integrate()['g']
    S['g'] = (h * (1 - f2) * C2 + (2 - h) *
              (1 - f1) * C1).evaluate().integrate()['g']

    analysis = solver.evaluator.add_file_handler(
        f'{savedir}/analysis-{simname}',
        iter=save_freq,
        max_writes=100,
        mode='overwrite')
    for task in problem.variables + ['h', 'ht', 'zc1', 'zc2']:
        analysis.add_task(task)

    while solver.ok:
        if solver.iteration % 100 == 0:
            logger.info(solver.iteration)
            if np.any(np.isnan(T2['g'])): break
        solver.step(dt)
    solver.step(dt)
    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):
        """
        Here the dedalus domain is created for the equation set

        Inputs:
            nx, ny, nz      - Number of grid points in the x, y, z directions
            Lx, Ly, Lz      - Physical size of the x, y, z direction
            grid_dtype      - Datatype to use for grid points in the problem
            comm            - Comm group over which to solve.  Use COMM_SELF for EVP
            mesh            - The processor mesh over which the problem is solved.
        """
        # the naming conventions here force cartesian, generalize to spheres etc. make sense?
        self.mesh = mesh

        if not isinstance(nz, list):
            nz = [nz]
        if not isinstance(Lz, list):
            Lz = [Lz]

        if len(nz) > 1:
            logger.info("Setting compound basis in vertical (z) direction")
            z_basis_list = []
            Lz_interface = 0.
            for iz, nz_i in enumerate(nz):
                Lz_top = Lz[iz] + Lz_interface
                z_basis = de.Chebyshev('z',
                                       nz_i,
                                       interval=[Lz_interface, Lz_top],
                                       dealias=3 / 2)
                z_basis_list.append(z_basis)
                Lz_interface = Lz_top
            self.compound = True
            z_basis = de.Compound('z', tuple(z_basis_list), dealias=3 / 2)
        elif len(nz) == 1:
            logger.info(
                "Setting single chebyshev basis in vertical (z) direction")
            z_basis = de.Chebyshev('z',
                                   nz[0],
                                   interval=[0, Lz[0]],
                                   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.Lx, self.Ly = 0, 0
        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
Example #17
0
from dedalus import public as de
import numpy as np
import matplotlib.pyplot as plt

de.logging_setup.rootlogger.setLevel('ERROR')

xbasis = de.Chebyshev('x', 32, interval=(0, 5), dealias=3 / 2)

grid_normal = xbasis.grid(scale=1)
grid_dealias = xbasis.grid(scale=3 / 2)

plt.figure(figsize=(10, 1))
plt.plot(grid_normal, np.zeros_like(grid_normal) + 1, 'o', markersize=5)
plt.plot(grid_dealias, np.zeros_like(grid_dealias) - 1, 'o', markersize=5)
plt.ylim([-2, 2])
plt.gca().yaxis.set_ticks([])

xb1 = de.Chebyshev('x1', 16, interval=(0, 2))
xb2 = de.Chebyshev('x2', 32, interval=(2, 8))
xb3 = de.Chebyshev('x3', 16, interval=(8, 10))
xbasis = de.Compound('x', (xb1, xb2, xb3))

compound_grid = xbasis.grid(scale=1)

plt.figure(figsize=(10, 1))
plt.plot(compound_grid, np.zeros_like(compound_grid), 'o', markersize=5)
plt.gca().yaxis.set_ticks([])
Example #18
0
Rayleigh = 2e8*8
Prandtl = 1.
nu = 1/np.sqrt(Rayleigh/Prandtl)
kappa = 1/np.sqrt(Rayleigh*Prandtl)

S = 100
T_top = -60

N2 = np.abs(S*T_top*2)
f = np.sqrt(N2)/(2*np.pi)

N = int(256)
# Create bases and domain
z_basis_conv1 = de.Chebyshev('z', int(N/2), interval=(0,z_match))
z_basis_rad1  = de.Chebyshev('z', int(N),interval=(z_match,Lz))
z_basis1 = de.Compound('z',[z_basis_conv1,z_basis_rad1])
domain1 = de.Domain([z_basis1], grid_dtype=np.complex128, comm=MPI.COMM_SELF)

z_basis_conv2 = de.Chebyshev('z', int(3*N/4), interval=(0,z_match))
z_basis_rad2  = de.Chebyshev('z', int(3*N/2),interval=(z_match,Lz))
z_basis2 = de.Compound('z',[z_basis_conv2,z_basis_rad2])
domain2 = de.Domain([z_basis2], grid_dtype=np.complex128, comm=MPI.COMM_SELF)

z_basis_conv_old = de.Chebyshev('z', int(N), interval=(0,z_match))
z_basis_rad_old  = de.Chebyshev('z', int(N/2),interval=(z_match,Lz))
z_basis_old = de.Compound('z',[z_basis_conv_old,z_basis_rad_old])
domain_old = de.Domain([z_basis_old], grid_dtype=np.complex128, comm=MPI.COMM_SELF)

def build_solver(domain, domain_old, N, N_old, k):
    # We have N >= N_old
    # but N/2 < N_old
Example #19
0
    rayleigh_benard.add_bc('right(b) = 0')
    rayleigh_benard.add_bc('left(w) = 0')
    rayleigh_benard.add_bc('right(w) = 0')
    if stress_free:
        rayleigh_benard.add_bc('left(uz) = 0')
        rayleigh_benard.add_bc('right(uz) = 0')
    else:
        rayleigh_benard.add_bc('left(u) = 0')
        rayleigh_benard.add_bc('right(u) = 0')

    return rayleigh_benard


@pytest.mark.parametrize('z', [
    de.Chebyshev('z', 16, interval=(0, 1)),
    de.Compound('z', (de.Chebyshev(
        'z', 10, interval=(0, 0.5)), de.Chebyshev('z', 10, interval=(0.5, 1))))
])
@pytest.mark.parametrize('sparse', [True, False])
def test_rbc_growth(z, sparse):
    d = de.Domain([z])

    rayleigh_benard = rbc_problem('EVP', d)

    EP = eig.Eigenproblem(rayleigh_benard)

    growth, index, freq = EP.growth_rate(sparse=sparse)
    assert np.allclose((growth, freq), (0.0018125573647729994, 0.))


@pytest.mark.parametrize('z', [de.Chebyshev('z', 16, interval=(0, 1))])
def test_rbc_output(z):
Example #20
0
    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):
        # the naming conventions here force cartesian, generalize to spheres etc. make sense?
        self.mesh=mesh
        
        if not isinstance(nz, list):
            nz = [nz]
        if not isinstance(Lz, list):
            Lz = [Lz]   

        if len(nz)>1:
            logger.info("Setting compound basis in vertical (z) direction")
            z_basis_list = []
            Lz_interface = 0.
            for iz, nz_i in enumerate(nz):
                Lz_top = Lz[iz]+Lz_interface
                z_basis = de.Chebyshev('z', nz_i, interval=[Lz_interface, Lz_top], dealias=3/2)
                z_basis_list.append(z_basis)
                Lz_interface = Lz_top
            self.compound = True
            z_basis = de.Compound('z', tuple(z_basis_list),  dealias=3/2)
        elif len(nz)==1:
            logger.info("Setting single chebyshev basis in vertical (z) direction")
            self.compound = False
            z_basis = de.Chebyshev('z', nz[0], interval=[0, Lz[0]], 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
plt.close()
plt.figure(figsize=(6, 1.5), dpi=100)
plt.plot(grid_normal, 0 * grid_normal + 1, 'o', markersize=5)
plt.plot(grid_dealias, 0 * grid_dealias - 1, 'o', markersize=5)
plt.xlabel('x')
plt.title('Chebyshev grid with scales 1 and 3/2')
plt.ylim([-2, 2])
plt.gca().yaxis.set_ticks([])
plt.tight_layout()
plt.savefig("fig/Chebyshev_grid_with_scales_1_and_1.5.png")

# Compound bases
xb1 = de.Chebyshev('x1', 16, interval=(0, 2))
xb2 = de.Chebyshev('x2', 32, interval=(2, 8))
xb3 = de.Chebyshev('x3', 16, interval=(8, 10))
xbasis = de.Compound(
    'x', (xb1, xb2, xb3))  # Define compound bases by three individual bases

compound_grid = xbasis.grid(scale=1)

plt.close()
plt.figure(figsize=(6, 1.5), dpi=100)
plt.plot(compound_grid, 0 * compound_grid, 'o', markersize=5)
plt.xlabel('x')
plt.title('Compound Chebyshev grid')
plt.gca().yaxis.set_ticks([])
plt.tight_layout()
plt.savefig("fig/Compound_Chebyshev_grid.png")

# Creating a domain
xbasis = de.Fourier('x', 32, interval=(0, 2), dealias=3 / 2)  # Periodic
ybasis = de.Fourier('y', 32, interval=(0, 2), dealias=3 / 2)