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))")
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)")
# 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
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)'
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)
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
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()
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'
μ = 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']
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)) "
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'])
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
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]
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)
# 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
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
""" 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