Exemple #1
0
        for i in range(1, len(field) - 1):
            newfield[i] = 0.5 * lastfield[i] + 0.25 * (lastfield[i + 1] +
                                                       lastfield[i - 1])
        j += 1
    return newfield


stop_time = 86400. * 2.  # simulation stop time  (seconds)
pulse_len = args.pulse_len  # seconds of forcing
N1 = 0.01  # buoyancy frequency in the troposphere (1/s)

Lx, Lz = (stop_time * 100, 15000)  # domain size in meters
nx, nz = (196 * 2, 124)  # number of points in each direction

# Create bases and domain
x_basis = de.Fourier('x', nx, interval=(-Lx / 2., Lx / 2.))
# compound z basis -- better to resolve jump condition?
#zb1 = de.Chebyshev('z1',int(nz/4), interval=(0, Lz+1000), dealias=3/2)
#zb2 = de.Chebyshev('z2', nz, interval=(Lz+1000,model_top), dealias = 3/2)
#z_basis = de.Compound('z',(zb1,zb2), dealias = 3/2)
#
m = args.m  # vertical mode number
k = args.k  # horizontal mode number
eps = args.eps  # ratio of N1/N2
N2 = N1 / eps  # buoyancy frequency in the stratosphere

if (args.rigid_lid):
    model_top = Lz
    nz = int(nz / 4)
else:
    model_top = 8. * Lz  # lid height
### 2. Simulation parameters
ra = float(args['--Rayleigh'])
pr = float(args['--Prandtl'])
aspect = float(args['--aspect'])
P = (ra*pr)**(-1./2)
R = (ra/pr)**(-1./2)

nx = int(args['--nx'])
ny = int(args['--ny'])
nz = int(args['--nz'])

logger.info("Ra = {:.3e}, Pr = {:2g}, resolution = {}x{}x{}".format(ra, pr, nx, ny, nz))

### 3. Setup Dedalus domain, problem, and substitutions/parameters
x_basis = de.Fourier( 'x', nx, interval = [-aspect/2, aspect/2], dealias=3/2)
if threeD : y_basis = de.Fourier( 'y', ny, interval = [-aspect/2, aspect/2], dealias=3/2)
z_basis = de.Chebyshev('z', nz, interval = [-1./2, 1./2], dealias=3/2)

if threeD:  bases = [x_basis, y_basis, z_basis]
else:       bases = [x_basis, z_basis]
domain = de.Domain(bases, grid_dtype=np.float64, mesh=mesh)

variables = ['T1', 'T1_z', 'p', 'u', 'v', 'w', 'Ox', 'Oy', 'Oz']
if not threeD:
    variables.remove('v')
    variables.remove('Ox')
    variables.remove('Oz')
problem = de.IVP(domain, variables=variables, ncc_cutoff=1e-10)

problem.parameters['P'] = P
config_file = pathlib.Path(sys.argv[-1])
runconfig.read(str(config_file))
logger.info("Using config file {}".format(config_file))

# parameters
params = runconfig['params']
nL = params.getint('nL')
nx = params.getint('nx')
ny = params.getint('ny')
Re = params.getfloat('Re')

logger.info("Re = {:e}".format(Re))

# always on square domain
L = nL * 2 * np.pi
x = de.Fourier('x',nx, interval=[0, L], dealias=3/2)
y = de.Fourier('y',ny, interval=[0, L], dealias=3/2)

domain = de.Domain([x,y], grid_dtype='float', mesh=mesh)

variables = ['u', 'v', 'p']

problem = de.IVP(domain, variables=variables)
problem.parameters['L'] = L
problem.parameters['Re'] = Re
problem.substitutions['Lap(A)'] = "dx(dx(A)) + dy(dy(A))"

# Navier-Stokes
problem.add_equation("dt(u) - Lap(u)/(Re) + dx(p) = - u*dx(u) - v*dy(u) + cos(y)/Re")
problem.add_equation("dt(v) - Lap(v)/(Re) + dy(p) = - u*dx(v) - v*dy(v)")
from dedalus.extras import flow_tools

import logging
logger = logging.getLogger(__name__)

MPI

# Parameters
Lx, Ly = (20., 20.)
Kappa = 1.0
Viscosity = 1e-3
Diffusivity = Viscosity
Adiabaticity = 1.0

# Create bases and domain
x_basis = de.Fourier('x', 256, interval=(-Lx / 2, Lx / 2), dealias=3 / 2)
y_basis = de.Fourier('y', 256, interval=(-Ly / 2, Ly / 2), dealias=3 / 2)
domain = de.Domain([x_basis, y_basis], grid_dtype=np.float64)

# Set up problem equations
problem = de.IVP(domain, variables=['n', 'psi', 'vx', 'vy', 'q'])
problem.parameters['Ka'] = Kappa
problem.parameters['Mu'] = Viscosity
problem.parameters['D'] = Diffusivity
problem.parameters['Ad'] = Adiabaticity
problem.parameters['Ly'] = Ly
problem.parameters['Lx'] = Lx
problem.substitutions['Lap(A)'] = "dx(dx(A)) + dy(dy(A))"

problem.add_equation(
    "dt(q) + D*Lap(Lap(q)) - Ka*dy(psi) = -(vx*dx(q) + vy*dy(q))")
Exemple #5
0
import logging
logger = logging.getLogger(__name__)

# Grid parameters
Lx = 40
Ly = 10

nx = 400
ny = 100

# Model parameters
A = 0.12
B = 0.394

x = de.Fourier('x', nx, interval=[-Lx / 2, Lx / 2])
y = de.Chebyshev('y', ny, interval=[-Ly / 2, Ly / 2])

domain = de.Domain([x, y], grid_dtype='float')

problem = de.IVP(domain, variables=['u', 'v', 'phi'])

problem.parameters['Lx'] = Lx
problem.parameters['Ly'] = Ly
problem.parameters['a'] = 0
problem.parameters['β'] = 1
problem.substitutions['f'] = "β*y"
problem.substitutions['vol_avg(A)'] = 'integ(A)/(Lx*Ly)'

problem.add_equation("dt(u) + a*u + dx(phi) - f*v = -u*dx(u) - v*dy(u)")
problem.add_equation("dt(v) + a*v + dy(phi) + f*u = -u*dx(v) - v*dy(v)")
Exemple #6
0
# Random Forcing
def forcing(solv, domain):
    global lastIt
    global lastF
    if (solv.iteration != lastIt or not correlated):
        global dt
        sh = domain.local_grid_shape()
        #logger.info('Iteration: %d' %solv.iteration)
        lastF = np.random.uniform(-1, 1, sh * 1.5) / np.sqrt(dt)
        #lastF = np.random.standard_normal(sh*1.5)/np.sqrt(dt)
        lastIt = solv.iteration
    return lastF


# Create bases and domain
x_basis = de.Fourier('x', nx, interval=(0, Lx), dealias=3 / 2)
y_basis = de.Fourier('y', ny, interval=(0, Ly), dealias=3 / 2)
domain = de.Domain([x_basis, y_basis], grid_dtype=np.float64)
forcing_func = de.operators.GeneralFunction(domain, 'g', forcing, args=[])

# Poisson equation
problem = de.IVP(domain, variables=['phi', 'u', 'v', 'w', 'wx', 'wy'])

# Create Parameters
problem.parameters['Lx'] = Lx
problem.parameters['Ly'] = Ly
problem.parameters['g'] = g
problem.parameters['mu'] = mu
problem.parameters['nu'] = nu
problem.parameters['fmag'] = fmag
problem.parameters['muZF'] = muZF
Exemple #7
0
Lz = params.getfloat('Lz')

ampl = params.getfloat('ampl')
Re = params.getfloat('Re')

run_params = runconfig['run']
restart = run_params.get('restart_file')
stop_wall_time = run_params.getfloat('stop_wall_time')
stop_sim_time = run_params.getfloat('stop_sim_time')
stop_iteration = run_params.getint('stop_iteration')
dt = run_params.getfloat('dt')

# Create bases and domain?
start_init_time = time.time()
dealias = 3 / 2
x_basis = de.Fourier('x', nx, interval=(0, Lx), dealias=dealias)
z_basis = de.Chebyshev('z', nz, interval=(0, Lz), dealias=dealias)

bases = [x_basis, z_basis]

domain = de.Domain(bases, grid_dtype=np.float64)
if domain.dist.comm.rank == 0:
    if not datadir.exists():
        datadir.mkdir()

problem = de.IVP(domain, variables=['p', 'u', 'w', 'uz', 'wz'], time='t')
problem.parameters['Re'] = Re
problem.substitutions['Lap(A, Az)'] = 'dx(dx(A)) + dz(Az)'
problem.substitutions['KE'] = '0.5 * (u**2 + w**2)'
problem.substitutions['U'] = 'z'
problem.substitutions['KE_pert'] = '0.5 * ((u-U)**2 + w**2)'
Exemple #8
0
from dedalus.tools import post

import logging
logger = logging.getLogger(__name__)

# Parameters
Lx, Lz = (2., 1.)
Nx, Nz = 512, 256
ln_K_std = 0.5
kmax = 100
tolerance = 1e-10
dt = 1
max_iter = 1000

# Create bases and domain
x_basis = de.Fourier('x', Nx, interval=(0, Lx), dealias=3 / 2)
z_basis = de.Fourier('z', Nz, interval=(0, Lz), dealias=3 / 2)
domain = de.Domain([x_basis, z_basis], grid_dtype=np.float64)


# Create permability field
def random_2d_fourier(kx, ky, kmax):
    k2 = kx * kx + ky * ky
    rand = np.random.randn(kx.size,
                           ky.size) + 1j * np.random.randn(kx.size, ky.size)
    mask = (k2 < kmax**2)
    N = np.pi * np.abs(kmax /
                       (kx[1, 0] - kx[0, 0])) * np.abs(kmax /
                                                       (ky[0, 1] - ky[0, 0]))
    return rand * mask / np.sqrt(N)
Exemple #9
0
from dedalus import public as de
from dedalus.extras import flow_tools

import logging

logger = logging.getLogger(__name__)

# Parameters done
Lx, Lz = (20., 1.)
q0val = 0.000
T1ovDTval = 5.5
betaval = 1.201

# Create bases and domain done
x_basis = de.Fourier('x', 768, interval=(0, Lx), dealias=2 / 3)
z_basis = de.Chebyshev('z', 129, interval=(0, Lz), dealias=2 / 3)
domain = de.Domain([x_basis, z_basis], grid_dtype=np.float64)

# 2D Boussinesq hydrodynamics
problem = de.IVP(
    domain,
    variables=['p', 'b', 'u', 'w', 'bz', 'uz', 'wz', 'temp', 'q', 'qz'])  #done
################################################################
problem.meta[
    'p', 'b', 'u',
    'w']['z']['dirichlet'] = True  #see if keeping this in changes anything
################################################################
problem.parameters['Eu'] = 1.0
problem.parameters['Prandtl'] = 1.0
problem.parameters['Ra'] = 1000000.0
Exemple #10
0
import pathlib

from dedalus import public as de
from dedalus.tools.array import reshape_vector
import parameters as param
import diagonal

de.operators.parseables['Diag'] = Diag = diagonal.FourierDiagonal

import logging

logger = logging.getLogger(__name__)

# Bases and domain
x_basis = de.Fourier('x',
                     param.Nx, [-param.Lx / 2, param.Lx / 2],
                     dealias=3 / 2)
y0_basis = de.Fourier('y0',
                      param.Ny, [-param.Ly / 2, param.Ly / 2],
                      dealias=3 / 2)
y1_basis = de.Fourier('y1',
                      param.Ny, [-param.Ly / 2, param.Ly / 2],
                      dealias=3 / 2)
domain = de.Domain([x_basis, y0_basis, y1_basis],
                   grid_dtype=np.float64,
                   mesh=param.mesh)

# Reference jet
cz_ref = domain.new_field()
cz_ref.meta['x']['constant'] = True
x, y0, y1 = domain.grids()
Exemple #11
0
    if log2 == int(log2):
        mesh = [int(2**np.ceil(log2 / 2)), int(2**np.floor(log2 / 2))]
    logger.info("running on processor mesh={}".format(mesh))

logger.info(sys.argv)
logger.info('-' * 40)
logger.info("Run parameters")
for key in args:
    logger.info("{} = {}".format(key, args[key]))
logger.info('-' * 40)

Lz = 1
Lx = Ly = aspect * Lz

# Bases and domain
x_basis = de.Fourier('x', nx, interval=(-Lx / 2, Lx / 2))
y_basis = de.Fourier('y', ny, interval=(-Ly / 2, Ly / 2))
z_basis = de.Chebyshev('z', nz, interval=(0, Lz))
domain = de.Domain([x_basis, y_basis, z_basis], grid_dtype='float', mesh=mesh)

problem = de.IVP(domain,
                 variables=['T', 'T_z', 'Ox', 'Oy', 'p', 'u', 'v', 'w'])
problem.meta['p', 'T', 'u', 'v', 'w']['z']['dirichlet'] = True

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['Kx'] = '(dy(Oz) - dz(Oy))'
problem.substitutions['Ky'] = '(dz(Ox) - dx(Oz))'
problem.substitutions['Kz'] = '(dx(Oy) - dy(Ox))'
problem.substitutions['vol_avg(A)'] = 'integ(A)/Lx/Ly/Lz'
Exemple #12
0
μ = 1e-2
M = .2
N = 0
L = 1
nx = 128
nz = 64
dt = 1e-3
timestepper = 'SBDF2'
simname = f'salty-boussinesq-melting-tangent-conserved-passive'
restart = False
if rank == 0: 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)
zbasis = de.Chebyshev('z', nz, interval=(0, 1), dealias=3 / 2)
domain = de.Domain([xbasis, zbasis], grid_dtype=np.float64)
if rank == 0: flt.save_domain(f'{savedir}/domain-{simname}.h5', domain)
x, z = domain.grids(scales=domain.dealias)
xx, zz = x + 0 * z, 0 * x + z
dims = range(1, 3)

problem = de.IVP(domain,
                 variables=[
                     'u21', 'u22', 'p2', 'q2', 'T1', 'T1_2', 'T2', 'T2_2',
                     'C2', 'C2_2', 'h', 'ht', 'E', 'S'
                 ])
problem.meta[:]['z']['dirichlet'] = True
problem.meta['h', 'ht']['z']['constant'] = True
problem.meta['E', 'S']['x', 'z']['constant'] = True
def run(subs, images):

    print ("\n\nBegin Taylor-Couette\n")
    print ("Using substitutions: ",subs)
    print ("Generating images  : ",images)
    print()

    # set lowest level of all loggers to INFO, i.e. dont follow DEBUG stuff
    root = logging.root
    for h in root.handlers:
        h.setLevel("INFO")

    # name logger using the module name
    logger = logging.getLogger(__name__)

    # Input params from Barenghi (1991) J. Comp. Phys.
    eta = 1./1.444  # R1/R2
    alpha = 3.13    # vertical wavenumber
    Re = 80.        # Reynolds number in units of R1.*Om1*delta/nu
    mu = 0.         # Om2/Om1

    # Computed quantities
    Omega_in = 1.
    Omega_out = mu*Omega_in
    R_in = eta/(1.-eta)
    R_out = 1./(1.-eta)
    height = 2.*numpy.pi/alpha
    V_l = 1.
    V_r = Omega_out*R_out

    # Problem Domain
    r_basis = de.Chebyshev('r', 32, interval=(R_in, R_out), dealias=3/2)
    z_basis = de.Fourier('z', 32, interval=(0., height), dealias=3/2)
    domain = de.Domain([z_basis, r_basis], grid_dtype=numpy.float64)

    # Equations
    #    incompressible, axisymmetric, Navier-Stokes in Cylindrical
    #    expand the non-constant-coefficients (NCC) to precision of 1.e-8
    TC = de.IVP(domain, variables=['p', 'u', 'v', 'w', 'ur', 'vr', 'wr'],
                ncc_cutoff=1.e-8)
    TC.parameters['nu'] = 1./Re
    TC.parameters['V_l'] = V_l
    TC.parameters['V_r'] = V_r
    mu = TC.parameters['V_r']/TC.parameters['V_l'] * eta

    # multiply r & theta equations through by r**2 to avoid 1/r**2 terms
    # multiply z equation through by r to avoid 1/r terms
    if (subs):

        # define AXISYMMETRIC substitutions, these can be used in 
        # equations & analysis tasks)

        # define ur, vr & wr
        #TC.substitutions['ur'] = 'dr(u)'
        #TC.substitutions['vr'] = 'dr(v)'
        #TC.substitutions['wr'] = 'dr(w)'

        # r*div(U)
        TC.substitutions['r_div(u,w)'] = 'u + r*ur + r*dz(w)'

        # r-component of gradient
        TC.substitutions['grad_1(p)'] = 'dr(p)'

        # z-component of gradient
        TC.substitutions['grad_3(p)'] = 'dz(p)'

        # r*Laplacian(scalar)
        TC.substitutions['r_Lap(f, fr)'] = 'r*dr(fr) + dr(f) + r*dz(dz(f))'

        # r-component of r*r*Laplacian(vector)
        TC.substitutions['r2_Lap_1(u,v,w)'] = 'r*r_Lap(u, ur) - u'

        # theta-component of r*r*Laplacian(vector)
        TC.substitutions['r2_Lap_2(u,v,w)'] = 'r*r_Lap(v, vr) - v'

        # z-component of r*Laplacian(vector)
        TC.substitutions['r_Lap_3(u,v,w)'] = 'r_Lap(w, wr)'

        # r-component of r*r*U dot grad(U)
        TC.substitutions['r2_u_grad_u_1(u,v,w,ur)'] = \
                                 'r*r*u*ur + r*r*w*dz(w) - r*v*v'
        # theta-component of r*r*U dot grad(U)
        TC.substitutions['r2_u_grad_u_2(u,v,w,vr)'] = \
                                 'r*r*u*vr + r*r*w*dz(v) + r*u*v'
        # z-component of r * U dot grad(U)
        TC.substitutions['r_u_grad_u_3(u,v,w,wr)'] = 'r*u*wr + r*w*dz(w)'

        # equations using substituions
        TC.add_equation("r_div(u,w) = 0")
        TC.add_equation("r*r*dt(u) - nu*r2_Lap_1(u,v,w) + r*r*grad_1(p)" + \
               "= -r2_u_grad_u_1(u,v,w,ur)")
        TC.add_equation("r*r*dt(v) - nu*r2_Lap_2(u,v,w)" + \
               "= -r2_u_grad_u_2(u,v,w,vr)")
        TC.add_equation("r*dt(w) - nu*r_Lap_3(u,v,w) + r*grad_3(p)" + \
               "= -r_u_grad_u_3(u,v,w,wr)")
        TC.add_equation("ur - dr(u) = 0")
        TC.add_equation("vr - dr(v) = 0")
        TC.add_equation("wr - dr(w) = 0")

    else:
        # equations with no substitutions
        TC.add_equation("r*ur + u + r*dz(w) = 0")
        TC.add_equation("r*r*dt(u) - r*r*nu*dr(ur) - r*nu*ur - " +
               "r*r*nu*dz(dz(u)) + nu*u + r*r*dr(p) = -r*r*u*ur - " +
               "r*r*w*dz(u) + r*v*v")
        TC.add_equation("r*r*dt(v) - r*r*nu*dr(vr) - r*nu*vr - " +
               "r*r*nu*dz(dz(v)) + nu*v  = -r*r*u*vr - r*r*w*dz(v) - r*u*v")
        TC.add_equation("r*dt(w) - r*nu*dr(wr) - nu*wr - r*nu*dz(dz(w)) + " +
               "r*dz(p) = -r*u*wr - r*w*dz(w)")
        TC.add_equation("ur - dr(u) = 0")
        TC.add_equation("vr - dr(v) = 0")
        TC.add_equation("wr - dr(w) = 0")

    # Boundary Conditions
    r = domain.grid(1, scales=domain.dealias)
    z = domain.grid(0, scales=domain.dealias)

    p_analytic = (eta/(1-eta**2))**2 * (-1./(2*r**2*(1-eta)**2) - \
                  2*numpy.log(r) +0.5*r**2 * (1.-eta)**2)
    v_analytic = eta/(1-eta**2) * ((1. - mu)/(r*(1-eta)) - \
                  r * (1.-eta) * (1 - mu/eta**2)) 

    TC.add_bc("left(u) = 0")
    TC.add_bc("left(v) = V_l")
    TC.add_bc("left(w) = 0")
    TC.add_bc("right(u) = 0", condition="nz != 0")
    TC.add_bc("right(v) = V_r")
    TC.add_bc("right(w) = 0")
    TC.add_bc("integ(p,'r') = 0", condition="nz == 0")

    # Timestepper
    dt = max_dt = 1.
    Omega_1 = TC.parameters['V_l']/R_in
    period = 2.*numpy.pi/Omega_1
    logger.info('Period: %f' %(period))

    ts = de.timesteppers.RK443
    IVP = TC.build_solver(ts)
    IVP.stop_sim_time = 15.*period
    IVP.stop_wall_time = numpy.inf
    IVP.stop_iteration = 10000000

    # alias the state variables
    p = IVP.state['p']
    u = IVP.state['u']
    v = IVP.state['v']
    w = IVP.state['w']
    ur = IVP.state['ur']
    vr = IVP.state['vr']
    wr = IVP.state['wr']

    # new field
    phi = Field(domain, name='phi')

    for f in [phi, p, u, v, w, ur, vr, wr]:
        f.set_scales(domain.dealias, keep_data=False)

    v['g'] = v_analytic
    #p['g'] = p_analytic

    v.differentiate(1,vr)

    # incompressible perturbation, arbitrary vorticity
    phi['g'] = 1.e-3*numpy.random.randn(*v['g'].shape)
    phi.differentiate(1,u)
    u['g'] *= -1.*numpy.sin(numpy.pi*(r - R_in))
    phi.differentiate(0,w)
    w['g'] *= numpy.sin(numpy.pi*(r - R_in))
    u.differentiate(1,ur)
    w.differentiate(1,wr)

    # Time step size
    CFL = flow_tools.CFL(IVP, initial_dt=1.e-3, cadence=5, safety=0.3,
                         max_change=1.5, min_change=0.5)
    CFL.add_velocities(('u', 'w'))

    # Analysis
    # integrated energy every 10 steps
    analysis1 = IVP.evaluator.add_file_handler("scalar_data", iter=10)
    analysis1.add_task("integ(0.5 * (u*u + v*v + w*w))", name="total KE")
    analysis1.add_task("integ(0.5 * (u*u + w*w))", name="meridional KE")
    analysis1.add_task("integ((u*u)**0.5)", name="u_rms")
    analysis1.add_task("integ((w*w)**0.5)", name="w_rms")

    # Snapshots every half inner rotation period
    analysis2 = IVP.evaluator.add_file_handler('snapshots', sim_dt=0.5*period,
                                               max_size=2**30)
    analysis2.add_system(IVP.state, layout='g')

    # Radial profiles every 100 steps
    analysis3 = IVP.evaluator.add_file_handler("radial_profiles", iter=100)
    analysis3.add_task("integ(r*v, 'z')", name="Angular Momentum")

    # MAIN LOOP
    dt = CFL.compute_dt()
    start_time = time.time()

    while IVP.ok:
        IVP.step(dt)
        if (images):
            # save a plot at every iteration for a movie
            mid_sim_plot(r, z, u, v, w, IVP.iteration)
        if (IVP.iteration % 10 == 0):
            logger.info('Iteration: %i, Time: %e, dt: %e' % \
                                          (IVP.iteration, IVP.sim_time, dt))
        dt = CFL.compute_dt()

    end_time = time.time()

    logger.info('Total time: %f' % (end_time-start_time))
    logger.info('Iterations: %i' % (IVP.iteration))
    logger.info('Average timestep: %f' %(IVP.sim_time/IVP.iteration))
    logger.info('Period: %f' %(period))
    logger.info('\n\tSimulation Complete\n')
    Ra *= ra_factor

    logger.info('updated Ra to {:.2e}'.format(Ra))
    ra_str_split = data_dir.split('Ra')
    data_dir = '{:s}Ra{:.2e}{:s}'.format(ra_str_split[0], Ra, data_dir.split(args['--Rayleigh'])[-1])
    if MPI.COMM_WORLD.rank == 0:
        if not os.path.exists('{:s}/'.format(data_dir)):
            os.makedirs('{:s}/'.format(data_dir))
        logdir = os.path.join(data_dir,'logs')
        if not os.path.exists(logdir):
            os.mkdir(logdir)
    logger.info("saving run in: {}".format(data_dir))


Lz = atmosphere.Lz
x_basis = de.Fourier(  'x', nx, interval = [0, Lz*aspect], dealias=3/2)
z_basis = de.Chebyshev('z', nz, interval = [0, Lz],        dealias=3/2)

bases = [x_basis, z_basis]
domain = de.Domain(bases, grid_dtype=np.float64, mesh=mesh)
z = domain.grid(-1)

equations = FCEquations2D()
problem = de.IVP(domain, variables=equations.variables, ncc_cutoff=1e-10)
atmosphere.build_atmosphere(domain, problem)

### 2. Simulation parameters
t_buoy, t_diff = atmosphere.set_parameters(Ra=Ra, Pr=Pr, aspect=aspect)


### 4.Setup equations and Boundary Conditions
    param.fix_DNS_2c = False

logger.info("Running with Nx = {:d}, Ny = {:d}".format(param.Nx, param.Ny))
logger.info("Ra = {:e}".format(param.Ra))
logger.info("beta = {:e}".format(param.beta))
logger.info("Pr = {:e}".format(param.Pr))
logger.info("C = {:e}".format(param.C))
logger.info("cu_lambda = {:e}".format(param.cu_lambda))
logger.info("cu_ampl = {:e}".format(param.cu_ampl))
if param.force_symmetry:
    logger.info("enforcing symmetry every {:d} timesteps".format(
        param.force_symmetry))

# Bases and domain
x_basis = de.Fourier('x',
                     param.Nx, [-param.Lx / 2, param.Lx / 2],
                     dealias=3 / 2)
y0_basis = de.SinCos('y0', param.Ny, [0, param.Ly], dealias=3 / 2)
y1_basis = de.SinCos('y1', param.Ny, [0, param.Ly], dealias=3 / 2)
domain = de.Domain([x_basis, y0_basis, y1_basis],
                   grid_dtype=np.float64,
                   mesh=param.mesh)

x, y0, y1 = domain.grids()

# Problem
problem = de.IVP(domain, variables=['cs', 'css', 'ct', 'cts', 'cst', 'ctt'])
problem.meta['cs']['x']['constant'] = True
problem.meta['ct']['x']['constant'] = True

problem.meta['cs']['y0']['parity'] = 1
import numpy as np
import matplotlib.pyplot as plt
from dedalus import public as de
from dedalus.extras.plot_tools import quad_mesh, pad_limits
import logging

from parareal_dedalus.parareal import Parareal_solver
from parareal_dedalus import parareal

#de.logging_setup.rootlogger.setLevel('ERROR')
logger = logging.getLogger(__name__)

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

domain = de.Domain([xbasis], np.float64)

problem = de.IVP(domain, variables=['u'])

problem.parameters['a'] = 1e-5

problem.add_equation("dt(u) = dx(dx(u))")
#problem.add_equation("dx(u) - ux = 0")

#problem.add_bc('left(u) = 0')
#problem.add_bc('right(u) = 0')

solver = problem.build_solver(de.timesteppers.SBDF2)

x = domain.grid(0)
u = solver.state['u']
Exemple #17
0
import dedalus.public as de
from spheromak import spheromak
import matplotlib.pyplot as plt

nx = 100
ny = 100
nz = 100

r = 0.08
length = 2

x = de.Fourier('x', nx, interval=(-r, r))
y = de.Fourier('y', ny, interval=(-r, r))
z = de.Chebyshev('z', nz, interval=(0,length))

domain = de.Domain([x,y,z],grid_dtype='float')

SSX = de.IVP(domain, variables=['lnrho','T', 'vx', 'vy', 'vz', 'Ax', 'Ay', 'Az'])

SSX.parameters['mu'] = mu
SSX.parameters['chi'] kappa/rho0

SSX.substituions['divv'] = "dx(vx) + dy(vy) + dz(vz)"
SSX.substitutions['udotgrad(A)'] = "vx*dx(A) + vy*dy(A) + vz*dz(A)"
SSX.substitutions['Bdotgrad(A)'] = "Bx*dx(A) + By*dy(A) + Bz*dz(A)"
SSX.substitutions['Bx'] = "dy(Az) - dz(Ay)"
SSX.substitutions['By'] = "dz(Ax) - dx(Az)"
SSX.substitutions['Bz'] = "dx(Ay) - dy(Ax)"
SSX.substitutions['jx'] = "dy(bz) - dz(by)"
SSX.substitutions['jy'] = "dz(bx) - dx(bz)"
SSX.substitutions['jz'] = "dx(by) - dy(bx)"
from dedalus import public as de
from dedalus.extras import plot_tools
from dedalus.extras.plot_tools import plot_bot_2d

# Wavenumber
g = 1.0 # non-dimensional for now
k = 5

h = 1
L = 40
ϵ = 0.001

σ = np.sqrt(g * k * np.tanh(k * h))

a_basis = de.Fourier('a',   128, interval = (-L/4, L))
b_basis = de.Chebyshev('b',  32, interval = (  -h, 0))

domain = de.Domain([a_basis, b_basis], grid_dtype=np.complex128)

problem = de.IVP(domain, variables=['xw', 'yw', 'uw', 'vw', 'pw']) #,
                                    #'xm', 'ym', 'um', 'vm', 'pm'])

problem.parameters["k"] = k
problem.parameters["g"] = g
problem.parameters["σ"] = σ
problem.parameters["ep"] = ϵ

problem.substitutions["J1(r, s)"] = (
    "   ( da(conj(r)) - 1j * k * conj(r) ) * db(s)       " +
    " - ( da(s)       + 1j * k * s       ) * db(conj(r)) "
Exemple #19
0
    def __init__(self, problem_params, dtype_u=dedalus_field, dtype_f=rhs_imex_dedalus_field):
        """
        Initialization routine

        Args:
            problem_params (dict): custom parameters for the example
            dtype_u: mesh data type (will be passed parent class)
            dtype_f: mesh data type (will be passed parent class)
        """

        if 'comm' not in problem_params:
            problem_params['comm'] = None

        # these parameters will be used later, so assert their existence
        essential_keys = ['nvars', 'Ra', 'Pr', 'comm', 'initial']
        for key in essential_keys:
            if key not in problem_params:
                msg = 'need %s to instantiate problem, only got %s' % (key, str(problem_params.keys()))
                raise ParameterError(msg)

        xbasis = de.Fourier('x', problem_params['nvars'][0], interval=(0, 2), dealias=3 / 2)
        zbasis = de.Chebyshev('z', problem_params['nvars'][1], interval=(-1 / 2, +1 / 2), dealias=3 / 2)
        domain = de.Domain([xbasis, zbasis], grid_dtype=np.complex128, comm=problem_params['comm'])

        # invoke super init, passing number of dofs, dtype_u and dtype_f
        super(rayleighbenard_2d_dedalus, self).__init__(init=(domain, 3), dtype_u=dtype_u, dtype_f=dtype_f,
                                                        params=problem_params)

        self.x = self.init[0].grid(0, scales=1)
        self.z = self.init[0].grid(1, scales=1)

        imp_var = ['T', 'u', 'w', 'Tz', 'uz', 'wz', 'p']
        self.problem_imp = de.IVP(domain=self.init[0], variables=imp_var)
        self.problem_imp.parameters['Ra'] = self.params.Ra
        self.problem_imp.parameters['Pr'] = self.params.Pr
        self.problem_imp.add_equation(" dx(u) + wz = 0 ")
        self.problem_imp.add_equation(" dt(T) - ( dx(dx(T)) + dz(Tz) )        = 0")
        self.problem_imp.add_equation(" dt(u) - ( dx(dx(u)) + dz(uz) ) +dx(p) = 0")  # need to look at Pr
        self.problem_imp.add_equation(" dt(w) - ( dx(dx(w)) + dz(wz) ) +dz(p) - Ra*T  = 0")  # Need to look at Pr
        self.problem_imp.add_equation(" Tz - dz(T) = 0")
        self.problem_imp.add_equation(" uz - dz(u) = 0")
        self.problem_imp.add_equation(" wz - dz(w) = 0")

        # Boundary conditions.
        self.problem_imp.add_bc("left(T) = 1")
        self.problem_imp.add_bc("left(u) = 0")
        self.problem_imp.add_bc("left(w) = 0")
        self.problem_imp.add_bc("right(T) = 0")
        self.problem_imp.add_bc("right(u) = 0")
        self.problem_imp.add_bc("right(w) = 0", condition="(nx != 0)")
        self.problem_imp.add_bc("left(p) = 0", condition="(nx == 0)")
        self.solver_imp = self.problem_imp.build_solver(de.timesteppers.SBDF1)
        self.imp_var = []
        for l in range(self.init[1]):
            self.imp_var.append(self.solver_imp.state[imp_var[l]])

        exp_var = ['T', 'u', 'w']
        self.problem_exp = de.IVP(domain=self.init[0], variables=exp_var)
        self.problem_exp.parameters['Ra'] = self.params.Ra
        self.problem_exp.parameters['Pr'] = self.params.Pr
        self.problem_exp.add_equation("dt(T) = - (u * dx(T) + w * dz(T) )")
        self.problem_exp.add_equation("dt(u) = - (u * dx(u) + w * dz(u) )")  # Need to look at pr
        self.problem_exp.add_equation("dt(w) = - (u * dx(w) + w * dz(w) ) ")  # need to look at pr
        self.solver_exp = self.problem_exp.build_solver(de.timesteppers.SBDF1)
        self.exp_var = []
        for l in range(self.init[1]):
            self.exp_var.append(self.solver_exp.state[exp_var[l]])

# ## Dominio del problema

Lx, Ly = (0.2, 0.35)
nx, ny = (256, 256)

ν = 1.8e-6
T0 = 4.5
ρ0 = 999.9699
α = 8.1e-6
Prandtl = 1. #ν/α #0.22
Rayleigh = 5.8e7


x_basis = de.Fourier('x', nx, interval=(0, Lx))
y_basis = de.Chebyshev('y', ny, interval=(0, Ly))
domain = de.Domain([x_basis, y_basis], grid_dtype=np.float64)


# ## Ecuaciones
problem = de.IVP(domain, variables=['p', 'u', 'v', 'ρ', 'T', 'uy', 'vy', 'Ty'])

problem.meta['p', 'T', 'u', 'v', 'ρ']['y']['dirichlet'] = True

problem.parameters['P'] = (Rayleigh * Prandtl)**(-1/2)
problem.parameters['R'] = (Rayleigh / Prandtl)**(-1/2)
#problem.parameters['F'] = F = 1
problem.parameters['ρ0'] = ρ0
problem.parameters['T_0'] = T0 #10ºC
problem.parameters['K'] = 1.3e-7
    run_time_diff = float(run_time_diff)

mesh = args['--mesh']
if mesh is not None:
    mesh = mesh.split(',')
    mesh = [int(mesh[0]), int(mesh[1])]

### 2. Setup Dedalus domain, problem, and substitutions/parameters
nx = int(args['--nx'])
ny = int(args['--ny'])
nz = int(args['--nz'])
aspect = float(args['--aspect'])

logger.info("Simulation resolution = {}x{}x{}".format(nx, ny, nz))

x_basis = de.Fourier(  'x', nx, interval = [0, aspect], dealias=3/2)
y_basis = de.Fourier(  'y', ny, interval = [0, aspect], dealias=3/2)
z_basis = de.Chebyshev('z', nz, interval = [0, 1],      dealias=3/2)

bases = [x_basis, y_basis, z_basis]
domain = de.Domain(bases, grid_dtype=np.float64, mesh=mesh)
z = domain.grid(-1)

equations = FCEquations3D()
problem = de.IVP(domain, variables=equations.variables, ncc_cutoff=1e-10)
atmosphere = LinearAtmosphere(domain, problem)

### 2. Simulation parameters
Ra = float(args['--Rayleigh'])
Ta = float(args['--Taylor'])
Pr = float(args['--Prandtl'])
Exemple #22
0
T_F = abs(ZMAX / VG_Z)
DT = 0.1
N_X = 64
N_Z = 256
Z0 = 0.15 * ZMAX
A = 0.005
F = 0.005
S = abs(1 / KZ)
NU = 0.01 * (ZMAX / N_Z)**2 / np.pi**2  # smallest wavenumber

if __name__ == '__main__':
    snapshots_dir = 'snapshots_lin'
    logger = logging.getLogger('lin')

    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=['W', 'U', 'ux', 'uz', 'uz_z', 'ux_z', 'U_z'])
    params = {
        'OMEGA': OMEGA,
        'KX': KX,
        'KZ': KZ,
        'H': H,
        'RHO0': RHO0,
        'g': g,
        'A': A,
        'F': F,
amp = 1*H

# Integration parameters
dt = period/6000.  # timestep
n_iterations = 200  # total iterations
n_output = 2  # data output cadence
output_folder = 'output_files/pole_norot/'  # data output folder

# Find MPI rank
comm = MPI.COMM_WORLD
rank = comm.rank

L_dealias=3/2

# Make domain
phi_basis   = de.Fourier('phi'  , 2*(L_max+1), interval=(0,2*np.pi), dealias=L_dealias)
theta_basis = de.Fourier('theta', L_max+1, interval=(0,np.pi), dealias=L_dealias)
domain = de.Domain([phi_basis,theta_basis], grid_dtype=np.float64)

# set up sphere

m_start = domain.distributor.coeff_layout.start(1)[0]
m_len = domain.distributor.coeff_layout.local_shape(1)[0]
m_end = m_start + m_len - 1
N_theta = int((L_max+1)*L_dealias)
S = sph.Sphere(L_max,S_max,N_theta=N_theta,m_min=m_start,m_max=m_end)

phi = domain.grids(L_dealias)[0]
theta_slice = domain.distributor.grid_layout.slices(domain.dealias)[1]
theta_len = domain.local_grid_shape(domain.dealias)[1]
theta_global = S.grid
Exemple #24
0
inset_axes = fig.add_axes([left, bottom, width, height])

left = l_mar / w_total
bottom = 1 - (t_mar + h_eig + h_pad + h_error) / h_total
width = w_error / w_total
height = h_error / h_total
error_axes = fig.add_axes([left, bottom, width, height])

N_max = 511
ell = 50
vals, r, vec = bessel.eigensystem(N_max, ell, cutoff=np.inf)
r = r.astype(np.float64)

L_max, N_max, R_max = 63, 2047, 1

theta_basis = de.Fourier('theta', 2 * L_max + 1, interval=(0, np.pi))
r_basis = de.Fourier('r', N_max + 1, interval=(0, 1))
domain = de.Domain([theta_basis, r_basis], grid_dtype=np.float64)

mesh = domain.distributor.mesh
if len(mesh) == 0:  #serial
    ell_r_layout = domain.distributor.layouts[1]
    r_ell_layout = domain.distributor.layouts[1]
else:
    ell_r_layout = domain.distributor.layouts[2]
    r_ell_layout = domain.distributor.layouts[1]

ell_min = r_ell_layout.slices(scales=1)[0].start
ell_max = r_ell_layout.slices(scales=1)[0].stop - 1
B = ball.Ball(N_max, L_max, R_max=R_max, ell_min=ell_min, ell_max=ell_max)
r = B.grid(1)[0]
Exemple #25
0
T = 2*np.pi/omega
A = 1e-4
PolRel = {'u': -A*g*omega*np.tan(theta)/N0**2,  # dictionary of forcing coeffs
          'w': A*g*omega/N0**2,
          'b': -A*g}

for fld in PolRel:
    if fld == 'b':
        units = 'm/s2'
    else:
        units = 'm/s'
    logger.info('amplitude of {0} = {1:.2e} {2}'.format(
        fld, PolRel[fld], units))
logger.info('frequency is {0:.2e} 1/s'.format(omega))
'-----------create basis and domain---------'
x_basis = de.Fourier('x', mx, interval=(0., L), dealias=3/2)

# n1= 2**10#layers' resolution
# n2= 2**7
# n3= 2**6

# zb1 = de.Chebyshev('z1', n1, interval=(-H,-H/3))
# zb2 = de.Chebyshev('z2', n2, interval=(-H/3,-2*H/3))
# zb3 = de.Chebyshev('z3', n3, interval=(-2*H/3,0))
# z_basis = de.Compound('z', (zb1, zb2, zb3))


z_basis = de.Chebyshev('z', mz, interval=(-H, 0.), dealias=3/2)
domain = de.Domain([x_basis, z_basis], grid_dtype=np.float64)
x = domain.grid(0)
z = domain.grid(1)
Exemple #26
0
# start with the same resolution as the DNS; during output, scale to the size required.
Nx = theta.domain.bases[0].grid_size(scale=1)
Ny = theta.domain.bases[1].grid_size(scale=1)

print(args['--xres'])
if args['--xres'] == 'None':
    output_Nx = Nx
else:
    output_Nx = int(args['--xres'])
if args['--yres'] == 'None':
    output_Ny = Ny
else:
    output_Ny = int(args['--yres'])


x_basis = de.Fourier('x', Nx, [-Lx/2, Lx/2])
y0_basis = de.SinCos('y0', Ny, [0, Ly])
y1_basis = de.SinCos('y1', Ny, [0, Ly])
domain = de.Domain([x_basis, y0_basis, y1_basis], grid_dtype=np.float64)
xi, y0, y1 = domain.grids()

out_fields = ['cs','ct', 'css', 'ctt', 'cts', 'cst']
y0_parity = [1, 1, -1, -1, -1, -1]

output_vars = {}

for name, parity in zip(out_fields, y0_parity):
    output_vars[name] =domain.new_field(name=name)
    output_vars[name].meta['y0']['parity'] = parity
    output_vars[name].meta['y1']['parity'] = -1
Exemple #27
0
    def solve_hires(self, tol=tol):
        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'])

#        for b in old_evp.boundary_conditions:
#            self.EVP_hires.add_bc(b['raw_equation'])

        solver = self.EVP_hires.build_solver()
        if self.sparse:
            #    solver.solve_sparse(solver.pencils[self.pencil], N=10, target=0, rebuild_coeffs=True)
            solver.solve_sparse(solver.pencils[self.pencil],
                                N=self.N,
                                target=self.target,
                                rebuild_coeffs=True)
        else:
            solver.solve_dense(solver.pencils[self.pencil],
                               rebuild_coeffs=True)
        self.evalues_hires = solver.eigenvalues
Exemple #28
0
"""

import h5py
import numpy as np
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
plt.ioff()
from dedalus.extras import plot_tools
from mpi4py import MPI

# Bases and domain
import dedalus.public as de
import parameters as param

x_basis = de.Fourier('x', param.N, interval=(0, param.L), dealias=3 / 2)
y_basis = de.Fourier('y', param.N, interval=(0, param.L), dealias=3 / 2)
domain = de.Domain([x_basis, y_basis],
                   grid_dtype=np.float64,
                   comm=MPI.COMM_SELF)

ux = domain.new_field()
uy = domain.new_field()

kx = domain.elements(0)
ky = domain.elements(1)
dkx = dky = 2 * np.pi / param.L
k = (kx**2 + ky**2)**0.5

kmax = int(np.ceil(np.max(k)))
bins = np.arange(1, kmax + 1, 2)
def build_domain(params, comm=None):
    """Build domain object."""
    x_basis = de.Fourier('x', params.Nx, interval=params.Bx, dealias=3 / 2)
    y_basis = de.Fourier('y', params.Ny, interval=params.By, dealias=3 / 2)
    domain = de.Domain([x_basis, y_basis], grid_dtype=np.float64, comm=comm)
    return domain
    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