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)
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)
def DoubleLaguerre(name, N, interval=(-1,1), dealias=1): N0 = int(N // 2) N1 = N - N0 L = interval[1] - interval[0] C = (interval[0] + interval[1]) / 2 int0 = (C, C + L/2) int1 = (C, C - L/2) b0 = de.Chebyshev('b0', N0, interval=int0, dealias=dealias) b1 = de.Chebyshev('b1', N1, interval=int1, dealias=dealias) return de.Compound(name, (b0, b1), dealias=dealias)
def __init__(self, nr, nz, Lr, Lz, *args, r_cheby=False, twoD=False, **kwargs): """ Initialize the domain. Sets up a 2D (z, r) grid, with chebyshev decomposition in the z-direction and fourier decomposition in the r-direction. Inputs: ------- nr, nz : ints Number of coefficients in r- and z- direction Lr, Lz : floats The size of the domain in the r- and z- direction *args, **kwargs : tuple, dict Arguments and keyword arguments for the DedalusIntegrator._polytrope_initialize() function """ self.Lz, self.Lr = Lz, Lr if r_cheby: if twoD: bounds = (-5, Lz) else: bounds = (0, Lz) self.r_basis = de.Chebyshev('r', nr, interval=(0, Lr)) self.z_basis = de.Fourier('z', nz, interval=bounds) self.domain = de.Domain([self.z_basis, self.r_basis], grid_dtype=np.float64) self.r = self.domain.grid(1) self.z = self.domain.grid(0) else: self.r_basis = de.Fourier('r', nr, interval=(0, Lr)) self.z_basis = de.Chebyshev('z', nz, interval=(0, Lz)) self.domain = de.Domain([self.r_basis, self.z_basis], grid_dtype=np.float64) self.r = self.domain.grid(0) self.z = self.domain.grid(1) self.T0 = self.domain.new_field() self.rho0 = self.domain.new_field() self.rho0_z = self.domain.new_field() self.grad_ln_rho0 = self.domain.new_field() self.fields = [self.T0, self.rho0, self.rho0_z, self.grad_ln_rho0] self.fd1 = self.domain.new_field() self.fd2 = self.domain.new_field() self.fd3 = self.domain.new_field() self.sm_fields = [self.fd1, self.fd2, self.fd3] self._polytrope_initialize(*args, **kwargs)
def __init__(self, radius, L_max, N_max, R_max, L_dealias, N_dealias, m_max=None, mesh=None, comm=None): if m_max is None: m_max = L_max self.radius = radius self.L_max = L_max self.N_max = N_max self.R_max = R_max self.L_dealias = L_dealias self.N_dealias = N_dealias # Domain phi_basis = de.Fourier('phi', 2*(L_max+1), interval=(0, 2*np.pi), dealias=L_dealias) theta_basis = de.Chebyshev('theta', L_max+1, interval=(0, np.pi), dealias=L_dealias) r_basis = de.Chebyshev('r', N_max+1, interval=(0, 1), dealias=N_dealias) self.domain = domain = de.Domain([phi_basis, theta_basis, r_basis], grid_dtype=np.float64, mesh=mesh, comm=comm) # Local m mesh = self.domain.distributor.mesh if len(mesh) == 0: phi_layout = domain.distributor.layouts[3] th_m_layout = domain.distributor.layouts[2] ell_r_layout = domain.distributor.layouts[1] r_ell_layout = domain.distributor.layouts[1] elif len(mesh) == 1: phi_layout = domain.distributor.layouts[4] th_m_layout = domain.distributor.layouts[2] ell_r_layout = domain.distributor.layouts[1] r_ell_layout = domain.distributor.layouts[1] elif len(mesh) == 2: phi_layout = domain.distributor.layouts[5] th_m_layout = domain.distributor.layouts[3] ell_r_layout = domain.distributor.layouts[2] r_ell_layout = domain.distributor.layouts[1] self.m_start = th_m_layout.slices(scales=1)[0].start self.m_end = th_m_layout.slices(scales=1)[0].stop-1 self.m_size = self.m_end - self.m_start + 1 self.ell_start = r_ell_layout.slices(scales=1)[1].start self.ell_end = r_ell_layout.slices(scales=1)[1].stop-1 # Ball wrapper N_theta = int((L_max+1)*L_dealias) N_r = int((N_max+1)*N_dealias) self.B = B = ball_wrapper.Ball(N_max, L_max, N_theta=N_theta, N_r=N_r, R_max=R_max, ell_min=self.ell_start, ell_max=self.ell_end, m_min=self.m_start, m_max=self.m_end, a=0.) # Grids grid_slices = phi_layout.slices(domain.dealias) self.phi = domain.grid(0, scales=domain.dealias)[grid_slices[0], :, :] self.theta = B.grid(1, dimensions=3)[:, grid_slices[1], :] # local self.r = radius * B.grid(2, dimensions=3)[:, :, grid_slices[2]] # local self.weight_theta = B.weight(1, dimensions=3)[:, grid_slices[1], :] self.weight_r = radius**3 * B.weight(2, dimensions=3)[:, :, grid_slices[2]]
def domain_setup(self): # Parameters Lx, Ly, Lz = (1., 1., 1.) self.Nd = 3 self.Nx = 50 self.Ny = 10 self.Nz = 10 self.scale = 1 epsilon = 0.8 self.Pr = 1.0 Ra_crit = 1707.762 # No-slip top & bottom self.Ra = Ra_crit * (1 + epsilon) self.F = self.Ra * self.Pr # Create bases and self.domain self.x_basis = de.Fourier('x', self.Nx, interval=(0, Lx), dealias=self.scale) self.y_basis = de.Fourier('y', self.Ny, interval=(0, Ly), dealias=self.scale) self.z_basis = de.Chebyshev('z', self.Nz, interval=(-Lz / 2, Lz / 2), dealias=self.scale) self.domain = de.Domain([self.x_basis, self.y_basis, self.z_basis], grid_dtype=np.float64)
def test_rbc_growth(Nz, sparse): z = de.Chebyshev('z', Nz, interval=(0, 1)) d = de.Domain([z]) rayleigh_benard = de.EVP(d, ['p', 'b', 'u', 'w', 'bz', 'uz', 'wz'], eigenvalue='omega') rayleigh_benard.parameters['k'] = 3.117 #horizontal wavenumber rayleigh_benard.parameters['Ra'] = 1708. #Rayleigh number, rigid-rigid rayleigh_benard.parameters['Pr'] = 1 #Prandtl number rayleigh_benard.parameters['dzT0'] = 1 rayleigh_benard.substitutions['dt(A)'] = 'omega*A' rayleigh_benard.substitutions['dx(A)'] = '1j*k*A' rayleigh_benard.add_equation("dx(u) + wz = 0") rayleigh_benard.add_equation( "dt(u) - Pr*(dx(dx(u)) + dz(uz)) + dx(p) = -u*dx(u) - w*uz") rayleigh_benard.add_equation( "dt(w) - Pr*(dx(dx(w)) + dz(wz)) + dz(p) - Ra*Pr*b = -u*dx(w) - w*wz") rayleigh_benard.add_equation( "dt(b) - w*dzT0 - (dx(dx(b)) + dz(bz)) = -u*dx(b) - w*bz") rayleigh_benard.add_equation("dz(u) - uz = 0") rayleigh_benard.add_equation("dz(w) - wz = 0") rayleigh_benard.add_equation("dz(b) - bz = 0") rayleigh_benard.add_bc('left(b) = 0') rayleigh_benard.add_bc('right(b) = 0') rayleigh_benard.add_bc('left(w) = 0') rayleigh_benard.add_bc('right(w) = 0') rayleigh_benard.add_bc('left(u) = 0') rayleigh_benard.add_bc('right(u) = 0') EP = eig.Eigenproblem(rayleigh_benard, sparse=sparse) growth, index, freq = EP.growth_rate({}) assert np.allclose([growth, freq[0]], [0.0018125573647729994, 0.])
def get_solver(setup_problem, XMAX, ZMAX, N_X, N_Z, T_F, KX, KZ, H, RHO0, G, A): # Bases and domain x_basis = de.Fourier('x', N_X, interval=(0, XMAX), dealias=3 / 2) z_basis = de.Chebyshev('z', N_Z, interval=(0, ZMAX), dealias=3 / 2) domain = de.Domain([x_basis, z_basis], np.float64) z = domain.grid(1) problem = de.IVP(domain, variables=['P', 'rho', 'ux', 'uz']) problem.meta['uz']['z']['dirichlet'] = True problem.parameters['L'] = XMAX problem.parameters['g'] = G problem.parameters['H'] = H problem.parameters['A'] = A problem.parameters['KX'] = KX problem.parameters['KZ'] = KZ problem.parameters['omega'] = get_omega(G, H, KX, KZ) # rho0 stratification rho0 = domain.new_field() rho0.meta['x']['constant'] = True rho0['g'] = RHO0 * np.exp(-z / H) problem.parameters['rho0'] = rho0 setup_problem(problem, domain) # Build solver solver = problem.build_solver(de.timesteppers.RK443) solver.stop_sim_time = T_F solver.stop_wall_time = np.inf solver.stop_iteration = np.inf return solver, domain
def domain_from_file(filename, basis_types, dealias=3 / 2): with h5py.File(filename, 'r') as dfile: testkey = next(iter(dfile['tasks'])) testdata = dfile['tasks'][testkey] dims = testdata.shape[1:] # trim write dimension dim_names = [ i.decode('utf-8') for i in testdata.attrs['DIMENSION_LABELS'][1:] ] if not testdata.attrs['grid_space'][-1]: dims[-1] *= 2 bases = [] for n, b, d in zip(dim_names, basis_types, dims): if b == 'Fourier': limits = limits_from_grid('Fourier', dfile['/scales/' + n + '/1.0']) basis = de.Fourier(n, d, interval=limits, dealias=dealias) elif b == 'SinCos': limits = limits_from_grid('SinCos', dfile['/scales/' + n + '/1.0']) basis = de.SinCos(n, d, interval=limits, dealias=dealias) elif b == 'Chebyshev': limits = (-1, 1) # limits not implemented for Chebyshev basis = de.Chebyshev(n, d, limits=limits, dealias=dealias) else: raise ValueError("Unknown basis type:", basis_type) bases.append(basis) d = de.Domain(bases, grid_dtype=np.float64) # hardcoded domain dtype for now return d
def get_solver(params): ''' sets up solver ''' x_basis = de.Fourier('x', params['N_X'], interval=(0, params['XMAX']), dealias=3 / 2) z_basis = de.Chebyshev('z', params['N_Z'], interval=(0, params['ZMAX']), dealias=3 / 2) domain = de.Domain([x_basis, z_basis], np.float64) z = domain.grid(1) problem = de.IVP(domain, variables=[ 'P', 'rho', 'ux', 'uz', 'ux_z', 'uz_z', ]) problem.parameters.update(params) # rho0 stratification rho0 = domain.new_field() rho0.meta['x']['constant'] = True rho0['g'] = params['RHO0'] * np.exp(-z / params['H']) problem.parameters['rho0'] = rho0 problem.substitutions['sponge'] = 'SPONGE_STRENGTH * 0.5 * ' +\ '(2 + tanh((z - SPONGE_HIGH) / (0.6 * (ZMAX - SPONGE_HIGH))) - ' +\ 'tanh((z - SPONGE_LOW) / (0.6 * (SPONGE_LOW))))' problem.add_equation('dx(ux) + dz(uz) = 0') problem.add_equation('dt(rho) - rho0 * uz / H' + '= - sponge * rho - ux * dx(rho) - uz * dz(rho) +' + 'F * exp(-(z - Z0)**2 / (2 * S**2)) *' + 'cos(KX * x - OMEGA * t)') problem.add_equation('dt(ux) + dx(P) / rho0' + '- NU * (dx(dx(ux)) + dz(ux_z))' + '= - sponge * ux - ux * dx(ux) - uz * dz(ux)') problem.add_equation('dt(uz) + dz(P) / rho0 + rho * g / rho0' + '- NU * (dx(dx(uz)) + dz(uz_z))' + '= - sponge * uz - ux * dx(uz) - uz * dz(uz)') problem.add_equation('dz(ux) - ux_z = 0') problem.add_equation('dz(uz) - uz_z = 0') problem.add_bc('left(uz) = 0') problem.add_bc('left(ux) = 0') problem.add_bc('right(uz) = 0') problem.add_bc('right(ux) = 0') problem.add_bc('right(P) = 0') # Build solver solver = problem.build_solver(de.timesteppers.RK443) solver.stop_sim_time = params['T_F'] solver.stop_wall_time = np.inf solver.stop_iteration = np.inf return solver, domain
def create_domain(nx=32, nz=32, L=20, H=10): # Create bases and domain x_basis = de.Fourier('x', nx, interval=(-L/2, L/2)) y_basis = de.Fourier('y', nx, interval=(-L/2, L/2)) z_basis = de.Chebyshev('z', nz, interval=(-H, 0)) return de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64)
def simple_domain(nx, nz, Lx=2 * np.pi, Ly=2 * np.pi, Lz=1): x_basis = de.Fourier('x', nx, interval=(-Lx / 2, Lx / 2)) y_basis = de.Fourier('y', nx, interval=(-Ly / 2, Ly / 2)) z_basis = de.Chebyshev('z', nz, interval=(-Lz, 0)) domain = de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64) return domain
def read_files(self, keys): import h5py for i, dir in enumerate(self.dir_info): try: # if True: f = h5py.File(dir[0] + self.out_dir_name + self.out_file_name, 'r') Lz = np.exp(dir[self.parameters.index('nrhocz') + 1] / (1.5 - dir[self.parameters.index('eps') + 1])) - 1 z_basis = de.Chebyshev('z', len(f['z']), interval=[0, Lz], dealias=3 / 2) domain = de.Domain([z_basis], grid_dtype=np.float64, comm=MPI.COMM_SELF) current_field = domain.new_field() output_field = domain.new_field() storage = dict() for key_info in keys: key, type = key_info if type == 'val': if len(f[key].shape) == 1: if f[key].shape[0] == 1: storage[key] = (np.log(f[key][0]), 0, 0) else: storage[key + '_profile'] = f[key] else: storage[key + '_profile'] = f[key][0, 0, :] elif type == 'midplane': current_field['g'] = f[key] storage[key] = (current_field.interpolate(z=Lz / 2)['g'][0], 0, 0) elif type == 'minmax': storage[key] = (f[key + '_mean'][0], f[key + '_mean'][0] - np.min(f[key]), np.max(f[key]) - f[key + '_mean'][0]) elif type == 'logmaxovermin': storage[key] = (np.log( np.max(f[key]) / np.min(f[key])), 0, 0) if 'Ma_ad' in key: #This is a workaround for my current incorrect implementation of Ma_ad (off by sqrt(gamma)) storage[key] = list(storage[key]) for i in range(len(storage[key])): storage[key][i] = storage[key][i] * np.sqrt(5 / 3) for key in storage.keys(): if np.isnan(storage[key][0]): raise dir[-1] = storage except: print("PROBLEMS READING OUTPUT FILE IN {:s}".format(dir[0])) import sys sys.stdout.flush() return self.dir_info
def __init__(self, nz=256): # Bases and domain import dedalus.public as de z_basis = de.Chebyshev('z', nz, interval=(0, 1), dealias=1) domain = de.Domain([z_basis], np.float64, comm=MPI.COMM_SELF) self.T0 = domain.new_field() self.T0_z = domain.new_field() self.ln_rho0_z = domain.new_field() self.H_rho = domain.new_field() self.ln_rho0 = domain.new_field() self.z = domain.grid(0)
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)
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)
def build_domain(self): self.x_basis = de.Fourier('x', self.nx, interval=(0, self.Lx), dealias=3 / 2) self.y_basis = de.Fourier('y', self.ny, interval=(0, self.Ly), dealias=3 / 2) self.z_basis = de.Chebyshev('z', self.nz, interval=(-1, 1)) self.domain = de.Domain([self.x_basis, self.y_basis, self.z_basis], grid_dtype=np.float64)
def rotating_rbc_evp(Ek, Ra, k, Nz=24): z = de.Chebyshev('z', Nz, interval=(0, 1)) d = de.Domain([z], comm=MPI.COMM_SELF) variables = ['T', 'Tz', 'p', 'u', 'v', 'w', 'Ox', 'Oy'] problem = de.EVP(d, variables, eigenvalue='omega') #Parameters problem.parameters['kx'] = k / np.sqrt(2) #horizontal wavenumber (x) problem.parameters['ky'] = k / np.sqrt(2) #horizontal wavenumber (y) problem.parameters['Ra'] = Ra #Rayleigh number problem.parameters['Pr'] = 1 #Prandtl number problem.parameters['Pm'] = 1 #Magnetic Prandtl number problem.parameters['E'] = Ek problem.parameters['dzT0'] = -1 #Substitutions problem.substitutions["dt(A)"] = "omega*A" problem.substitutions["dx(A)"] = "1j*kx*A" problem.substitutions["dy(A)"] = "1j*ky*A" problem.substitutions['UdotGrad(A,A_z)'] = '(u*dx(A) + v*dy(A) + w*(A_z))' problem.substitutions['Lap(A,A_z)'] = '(dx(dx(A)) + dy(dy(A)) + dz(A_z))' problem.substitutions["Oz"] = "dx(v)-dy(u)" problem.substitutions["Kz"] = "dx(Oy)-dy(Ox)" problem.substitutions["Ky"] = "dz(Ox)-dx(Oz)" problem.substitutions["Kx"] = "dy(Oz)-dz(Oy)" #Dimensionless parameter substitutions problem.substitutions["inv_Re_ff"] = "(Pr/Ra)**(1./2.)" problem.substitutions["inv_Pe_ff"] = "(Ra*Pr)**(-1./2.)" #Equations problem.add_equation( "dt(T) + w*dzT0 - inv_Pe_ff*Lap(T, Tz) = -UdotGrad(T, Tz)") problem.add_equation( "dt(u) + dx(p) + inv_Re_ff*(Kx - v/E) = v*Oz - w*Oy") problem.add_equation( "dt(v) + dy(p) + inv_Re_ff*(Ky + u/E) = w*Ox - u*Oz") problem.add_equation( "dt(w) + dz(p) + inv_Re_ff*(Kz) - T = u*Oy - v*Ox") problem.add_equation("dx(u) + dy(v) + dz(w) = 0") problem.add_equation("Ox - (dy(w) - dz(v)) = 0") problem.add_equation("Oy - (dz(u) - dx(w)) = 0") problem.add_equation("Tz - dz(T) = 0") bcs = ['T', 'u', 'v', 'w'] for bc in bcs: problem.add_bc(" left({}) = 0".format(bc)) problem.add_bc("right({}) = 0".format(bc)) return problem
def _set_domain(self, nx=256, Lx=4, ny=256, Ly=4, nz=128, Lz=1, grid_dtype=np.float64, comm=MPI.COMM_WORLD, mesh=None): self.mesh = mesh z_basis = de.Chebyshev('z', nz, interval=[0., Lz], dealias=3 / 2) if self.dimensions > 1: x_basis = de.Fourier('x', nx, interval=[0., Lx], dealias=3 / 2) if self.dimensions > 2: y_basis = de.Fourier('y', ny, interval=[0., Ly], dealias=3 / 2) if self.dimensions == 1: bases = [z_basis] elif self.dimensions == 2: bases = [x_basis, z_basis] elif self.dimensions == 3: bases = [x_basis, y_basis, z_basis] else: logger.error('>3 dimensions not implemented') self.domain = de.Domain(bases, grid_dtype=grid_dtype, comm=comm, mesh=mesh) self.z = self.domain.grid(-1) # need to access globally-sized z-basis self.Lz = self.domain.bases[-1].interval[1] - self.domain.bases[ -1].interval[0] # global size of Lz self.nz = self.domain.bases[-1].coeff_size self.z_dealias = self.domain.grid(axis=-1, scales=self.domain.dealias) if self.dimensions == 1: self.x, self.Lx, self.nx, self.delta_x = None, 0, None, None self.y, self.Ly, self.ny, self.delta_y = None, 0, None, None if self.dimensions > 1: self.x = self.domain.grid(0) self.Lx = self.domain.bases[0].interval[1] - self.domain.bases[ 0].interval[0] # global size of Lx self.nx = self.domain.bases[0].coeff_size self.delta_x = self.Lx / self.nx if self.dimensions > 2: self.y = self.domain.grid(1) self.Ly = self.domain.bases[1].interval[1] - self.domain.bases[ 0].interval[0] # global size of Lx self.ny = self.domain.bases[1].coeff_size self.delta_y = self.Ly / self.ny
def build_LHS(Nz): # Parameters terms = 1 dt = 1e-3 kx = 50 * np.pi sigma = 1 Prandtl = 1. Reynolds = 1e2 ts = de.timesteppers.SBDF3 # Create bases and domain z_basis = de.Chebyshev('z', Nz, interval=(-1, 1), dealias=3 / 2) domain = de.Domain([z_basis], grid_dtype=np.complex128) # 2D Boussinesq hydrodynamics problem = de.IVP(domain, variables=['p', 'b', 'u', 'w', 'bz', 'uz', 'wz'], ncc_cutoff=1e-10, max_ncc_terms=terms) problem.meta[:]['z']['dirichlet'] = True problem.parameters['P'] = 1 / Reynolds / Prandtl problem.parameters['R'] = 1 / Reynolds problem.parameters['kx'] = kx problem.parameters['sigma'] = sigma problem.substitutions['Bz'] = "exp(-(z-1)**2 / 2 / sigma**2)" problem.substitutions['dx(A)'] = "1j*kx*A" problem.add_equation("dx(u) + wz = 0") problem.add_equation("dt(b) - P*(dx(dx(b)) + dz(bz)) + Bz*w = 0") problem.add_equation("dt(u) - R*(dx(dx(u)) + dz(uz)) + dx(p) = 0") problem.add_equation("dt(w) - R*(dx(dx(w)) + dz(wz)) + dz(p) - b = 0") problem.add_equation("bz - dz(b) = 0") problem.add_equation("uz - dz(u) = 0") problem.add_equation("wz - dz(w) = 0") problem.add_bc("left(b) = 0") problem.add_bc("left(u) = 0") problem.add_bc("left(w) = 0") problem.add_bc("right(b) = 0") problem.add_bc("right(u) = 0") if kx == 0: problem.add_bc("right(p) = 0") else: problem.add_bc("right(w) = 0", ) # Build solver solver = problem.build_solver(ts) # Step solver to form pencil LHS for i in range(10): solver.step(dt) return solver.pencils[0].LHS
def build_LHS(Nz, bw, format, entry_cutoff=0): # Parameters dt = 1e-3 kx = 50 * np.pi sigma = 1 ts = de.timesteppers.RK222 # Create bases and domain z1 = de.Chebyshev('z', Nz, interval=(-1, 1), dealias=3 / 2) z2 = de.Chebyshev('z', Nz, interval=(1, 2), dealias=3 / 2) z3 = de.Chebyshev('z', Nz, interval=(2, 3), dealias=3 / 2) z_basis = de.Compound('z', [z1, z2, z3]) domain = de.Domain([z_basis], grid_dtype=np.complex128) # 2D Boussinesq hydrodynamics problem = de.IVP(domain, variables=['T', 'Tz'], ncc_cutoff=0, max_ncc_terms=bw, entry_cutoff=entry_cutoff) problem.meta[:]['z']['dirichlet'] = True problem.parameters['kx'] = kx problem.parameters['sigma'] = sigma problem.substitutions['kappa'] = "exp(-(z-1)**2 / 2 / sigma**2)" problem.substitutions['dx(A)'] = "1j*kx*A" problem.add_equation("dt(T) - dx(kappa*dx(T)) - dz(kappa*Tz) = 0") problem.add_equation("Tz - dz(T) = 0") problem.add_bc("left(T) = 0") problem.add_bc("right(T) = 0") # Build solver solver = problem.build_solver(ts) # Step solver to form pencil LHS for i in range(1): solver.step(dt) return solver, solver.pencils[0].LHS.asformat(format)
def problem_setup(self, L=2., nx=192, nz=96, Prandtl_number=1., Rayleih_number=1e4, bc_type='no_slip'): self.L = float(L) self.nx = int(nx) self.nz = int(nz) x_basis = de.Fourier('x', int(nx), interval=(0, L), dealias=3 / 2) z_basis = de.Chebyshev('z', int(nz), interval=(0, 1), dealias=3 / 2) self.saving_shape = (int(nx * 3 / 2), int(nz * 3 / 2)) self.domain = de.Domain([x_basis, z_basis], grid_dtype=np.float64) self.problem = de.IVP( self.domain, variables=['T', 'Tz', 'psi', 'psiz', 'curl', 'curlz']) self.problem.parameters['L'] = L self.problem.parameters['nx'] = nx self.problem.parameters['nz'] = nz self.Pr = float(Prandtl_number) self.Ra = float(Rayleih_number) self.problem.parameters['Ra'] = self.Ra self.problem.parameters['Pr'] = self.Pr # Stream function relation to the speed self.problem.substitutions['u'] = "-dz(psi)" self.problem.substitutions['v'] = "dx(psi)" # Derivatives values relation to the main values self.problem.add_equation("psiz - dz(psi) = 0") self.problem.add_equation("curlz - dz(curl) = 0") self.problem.add_equation("Tz - dz(T) = 0") self.problem.add_equation("curl + dx(dx(psi)) + dz(psiz) = 0") self.problem.add_equation( "dt(curl)+Ra*Pr*dx(T)-Pr*(dx(dx(curl))+dz(curlz))=-(u*dx(curl)+v*curlz)" ) self.problem.add_equation("dt(T)-dx(dx(T))-dz(Tz)=-(u*dx(T)+v*Tz)") self.problem.add_bc("left(T) = 1") self.problem.add_bc("right(T) = 0") self.problem.add_bc("left(psi) = 0") self.problem.add_bc("right(psi) = 0") if bc_type not in ['no_slip', 'free_slip']: raise ValueError( "Boundary Conditions must be 'no_slip' or 'free_slip'") else: if bc_type == 'no_slip': self.problem.add_bc("left(psiz) = 0") self.problem.add_bc("right(psiz) = 0") if bc_type == 'free_slip': self.problem.add_bc("left(dz(psiz)) = 0") self.problem.add_bc("right(dz(psiz)) = 0")
def grid(Lx, Ly, Lz, nx, ny, nz): x_basis = de.Fourier("x", nx, interval=(0, Lx), dealias=3 / 2) y_basis = de.Fourier("y", ny, interval=(0, Ly), dealias=3 / 2) z_basis = de.Chebyshev("z", nz, interval=(-Lz, Lz), dealias=3 / 2) domain = de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64) # Unscaled grid (physical space) x = domain.grid(0) y = domain.grid(1) z = domain.grid(2) X, Y = np.meshgrid(x, y, indexing='ij') Y2, Z = np.meshgrid(y, z, indexing='ij') kx, ky = np.meshgrid(x_basis.wavenumbers, y_basis.wavenumbers, indexing='ij') x2, ky2 = np.meshgrid(x, y_basis.wavenumbers, indexing='ij') nkx, nky = kx.shape
def solve_mcwilliams_preconditioner_problem( buoyancy_bc="right(ψz) = 0", h=0.1, lx=1 / 2, ly=1 / 4, f=1, nx=32, nz=32, ): # Create bases and domain x_basis = de.Fourier('x', nx, interval=(-np.pi, np.pi)) y_basis = de.Fourier('y', nx, interval=(-np.pi, np.pi)) z_basis = de.Chebyshev('z', nz, interval=(-1, 0)) domain = de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64) # Poisson equation problem = de.LBVP(domain, variables=['ψ', 'ψz']) problem.parameters['h'] = h problem.parameters['lx'] = lx problem.parameters['ly'] = ly problem.parameters['f'] = f problem.parameters['N'] = h / (f * lx) problem.parameters['US'] = f * lx problem.substitutions[ 'uSy'] = "- y * US / ly**2 * exp(z/h - x**2 / (2 * lx**2) - y**2 / (2 * ly**2))" problem.substitutions[ 'uSz'] = "US / h * exp(z/h - x**2 / (2 * lx**2) - y**2 / (2 * ly**2))" problem.add_equation("dx(dx(ψ)) + dy(dy(ψ)) + f**2 / N**2 * dz(ψz) = -uSy", condition="(nx != 0) or (ny != 0)") problem.add_equation("ψ = 0", condition="(nx == 0) and (ny == 0)") problem.add_equation("ψz = 0", condition="(nx == 0) and (ny == 0)") problem.add_equation("dz(ψ) - ψz = 0", condition="(nx != 0) or (ny != 0)") problem.add_bc("left(ψz) = 0", condition="(nx != 0) or (ny != 0)") problem.add_bc(buoyancy_bc, condition="(nx != 0) or (ny != 0)") # Build solver solver = problem.build_solver() solver.solve() return solver
def solve_hydrostatic_pressure(param, dtype, comm=MPI.COMM_SELF): """Build domain and solve hydrostatic pressure from parameters.""" # NLBVP domain z_basis = de.Chebyshev('z', param.Nz, interval=(0, param.Lz), dealias=2) domain = de.Domain([z_basis], grid_dtype=dtype, comm=comm) # Solve NLBVP for background X0 = np.array([param.p_bottom, -param.ρ_bottom * param.g]) P = (param.N2_func, param.g, param.γ) p_full, pz_full = solve_dedalus(X0, P, domain, tolerance=param.nlbvp_tolerance, ncc_cutoff=param.nlbvp_cutoff, max_ncc_terms=param.nlbvp_max_terms) a_full = domain.new_field() a_full.set_scales(2) a_full['g'] = -param.g / pz_full['g'] return domain, p_full, a_full
def build_FC(N, dealias, dtype): c = d3.CartesianCoordinates('x', 'y') d = d3.Distributor(c, dtype=dtype) if dtype == np.complex128: xb = d3.ComplexFourier(c.coords[0], size=N, bounds=(0, Lx), dealias=dealias) elif dtype == np.float64: xb = d3.RealFourier(c.coords[0], size=N, bounds=(0, Lx), dealias=dealias) yb = d3.Chebyshev(c.coords[1], size=N, bounds=(0, Ly), dealias=dealias) b = (xb, yb) x = xb.local_grid(dealias) y = yb.local_grid(dealias) r = (x, y) return c, d, b, r
def _get_solver(setup_problem, params, variables): ''' get solver for given variables ''' x_basis = de.Fourier('x', params['N_X'], interval=(0, params['XMAX']), dealias=3/2) z_basis = de.Chebyshev('z', params['N_Z'], interval=(0, params['ZMAX']), dealias=3/2) domain = de.Domain([x_basis, z_basis], np.float64) z = domain.grid(1) problem = de.IVP(domain, variables=variables) problem.parameters['L'] = params['XMAX'] problem.parameters['g'] = params['G'] problem.parameters['H'] = params['H'] problem.parameters['A'] = params['A'] problem.parameters['F'] = params['F'] problem.parameters['KX'] = params['KX'] problem.parameters['KZ'] = params['KZ'] problem.parameters['NU'] = params['NU'] problem.parameters['RHO0'] = params['RHO0'] problem.parameters['omega'] = params['OMEGA'] problem.parameters['ZMAX'] = params['ZMAX'] problem.parameters['Z0'] = 0.2 * params['ZMAX'] problem.parameters['S'] = params['H'] # rho0 stratification rho0 = domain.new_field() rho0.meta['x']['constant'] = True rho0['g'] = params['RHO0'] * np.exp(-z / params['H']) problem.parameters['rho0'] = rho0 setup_problem(problem, domain, params) # Build solver solver = problem.build_solver(de.timesteppers.RK222) solver.stop_sim_time = params['T_F'] solver.stop_wall_time = np.inf solver.stop_iteration = np.inf return solver, domain
def __init__(self, param, dim, dtype=np.float64, comm=None): # Solve and truncate background bvp_domain, p0_full, a0_full = background.solve_hydrostatic_pressure( param, dtype) p0_full, p0_trunc, a0_full, a0_trunc, heq, N2 = background.truncate_background( param, p0_full, a0_full) # Save domain and backgrounds if dim == 1: # Use BVP results self.domain = bvp_domain self.a0 = a0_trunc self.p0 = p0_trunc elif dim == 2: # Construct new domain x_basis = de.Fourier('x', param.Nx, interval=(0, param.Lx), dealias=2) z_basis = de.Chebyshev('z', param.Nz, interval=(0, param.Lz), dealias=2) self.domain = de.Domain([x_basis, z_basis], grid_dtype=dtype, comm=comm) # Background state self.a0 = a0 = self.domain.new_field() self.p0 = p0 = self.domain.new_field() a0.meta['x']['constant'] = True p0.meta['x']['constant'] = True a0.set_scales(1) p0.set_scales(1) a0_trunc.set_scales(1) p0_trunc.set_scales(1) slices = self.domain.dist.grid_layout.slices(scales=1) a0['g'][:] = a0_trunc['g'][slices[1]] p0['g'][:] = p0_trunc['g'][slices[1]] else: raise ValueError("Dimension must be 1 or 2") # Store derivatives self.a0z = self.a0.differentiate('z') self.p0z = self.p0.differentiate('z')
def get_solver(setup_problem, params): ''' get solver ''' x_basis = de.Fourier('x', params['N_X'], interval=(0, params['XMAX']), dealias=3 / 2) z_basis = de.Chebyshev('z', params['N_Z'], interval=(0, params['ZMAX']), dealias=3 / 2) domain = de.Domain([x_basis, z_basis], np.float64) z = domain.grid(1) problem = de.IVP(domain, variables=['P', 'rho', 'ux', 'uz']) problem.parameters['L'] = params['XMAX'] problem.parameters['g'] = params['G'] problem.parameters['H'] = params['H'] problem.parameters['A'] = params['A'] problem.parameters['F'] = params['F'] problem.parameters['KX'] = params['KX'] problem.parameters['KZ'] = params['KZ'] problem.parameters['NU'] = params['NU'] problem.parameters['RHO0'] = params['RHO0'] problem.parameters['omega'] = params['OMEGA'] problem.parameters['ZMAX'] = params['ZMAX'] # rho0 stratification # rho0 = domain.new_field() # rho0.meta['x']['constant'] = True # rho0['g'] = params['RHO0'] * np.exp(-z / params['H']) # problem.parameters['rho0'] = rho0 problem.parameters['rho0'] = params['RHO0'] setup_problem(problem, domain, params) # Build solver solver = problem.build_solver(params['TIMESTEPPER']) solver.stop_sim_time = params['T_F'] solver.stop_wall_time = np.inf solver.stop_iteration = np.inf return solver, domain
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))