def test_half_qho_dense_evp(benchmark, x_basis_class, Nx, dtype): n_comp = 5 # Domain x_basis = x_basis_class('x', Nx, interval=(0, 1)) domain = de.Domain([x_basis], np.float64) # Problem problem = de.EVP(domain, variables=['ψ', 'ψx'], eigenvalue='E') problem.substitutions["V"] = "x**2 / 2" problem.substitutions["H(ψ,ψx)"] = "-dx(ψx)/2 + V*ψ" problem.add_equation("ψx - dx(ψ) = 0", tau=True) problem.add_equation("H(ψ,ψx) - E*ψ = 0", tau=False) problem.add_bc("left(ψ) = 0") # Solver solver = problem.build_solver() solver.solve_dense(solver.pencils[0]) # Filter infinite/nan eigenmodes finite = np.isfinite(solver.eigenvalues) solver.eigenvalues = solver.eigenvalues[finite] solver.eigenvectors = solver.eigenvectors[:, finite] # Sort eigenmodes by eigenvalue order = np.argsort(solver.eigenvalues) solver.eigenvalues = solver.eigenvalues[order] solver.eigenvectors = solver.eigenvectors[:, order] # Check solution n = np.arange(n_comp) exact_eigenvalues = 2 * n + 3 / 2 assert np.allclose(solver.eigenvalues[:n_comp], exact_eigenvalues)
def test_heat_1d_nonperiodic(benchmark, x_basis_class, Nx, timestepper, dtype): # Bases and domain x_basis = x_basis_class('x', Nx, interval=(0, 2 * np.pi)) domain = de.Domain([x_basis], grid_dtype=dtype) # Forcing F = domain.new_field(name='F') x = domain.grid(0) F['g'] = -np.sin(x) # Problem problem = de.IVP(domain, variables=['u', 'ux']) problem.parameters['F'] = F problem.add_equation("ux - dx(u) = 0") problem.add_equation("-dt(u) + dx(ux) = F") problem.add_bc("left(u) - right(u) = 0") problem.add_bc("left(ux) - right(ux) = 0") # Solver solver = problem.build_solver(timestepper) dt = 1e-5 iter = 10 for i in range(iter): solver.step(dt) # Check solution amp = 1 - np.exp(-solver.sim_time) u_true = amp * np.sin(x) u = solver.state['u'] assert np.allclose(u['g'], u_true)
def test_wave_sparse_evp(benchmark, x_basis_class, Nx, dtype): n_comp = 8 # Domain x_basis = x_basis_class('x', Nx, interval=(-1, 1)) domain = de.Domain([x_basis], np.float64) # Problem problem = de.EVP(domain, variables=['u', 'ux'], eigenvalue='k2') problem.add_equation("ux - dx(u) = 0") problem.add_equation("dx(ux) + k2*u = 0") problem.add_bc("left(u) = 0") problem.add_bc("right(u) = 0") # Solver solver = problem.build_solver() solver.solve_sparse(solver.pencils[0], n_comp, target=0) # Filter infinite/nan eigenmodes finite = np.isfinite(solver.eigenvalues) solver.eigenvalues = solver.eigenvalues[finite] solver.eigenvectors = solver.eigenvectors[:, finite] # Sort eigenmodes by eigenvalue order = np.argsort(solver.eigenvalues) solver.eigenvalues = solver.eigenvalues[order] solver.eigenvectors = solver.eigenvectors[:, order] # Check solution n = np.arange(n_comp) exact_eigenvalues = ((1 + n) * np.pi / 2)**2 assert np.allclose(solver.eigenvalues[:n_comp], exact_eigenvalues)
def general_test(test_func): # Parameters Cx = 4 Cy = 7 Lx = 2 * np.pi Ly = np.pi Nx = 32 Ny = 32 # Bases and domain x_basis = de.Fourier('x', Nx, [Cx - Lx / 2, Cx + Lx / 2], dealias=3 / 2) y0_basis = de.Fourier('y0', Ny, [Cy - Ly / 2, Cy + Ly / 2], dealias=3 / 2) y1_basis = de.Fourier('y1', Ny, [Cy - Ly / 2, Cy + Ly / 2], dealias=3 / 2) domain = de.Domain([x_basis, y0_basis, y1_basis], grid_dtype=np.float64) # Test fields x, y0, y1 = domain.grids() a = Cy - Ly / 2 interp = de.operators.parseables['interp'] f = domain.new_field() h = domain.new_field() f['g'] = test_func(x, y0, y1) h['g'] = test_func(x, y0 + y1 - a, y0 + y1 - a) g = Diag(f, 'y0', 'y1').evaluate() return np.allclose(g['c'], h['c'])
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 __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 test_sin_nlbvp(benchmark, x_basis_class, Nx, dtype): # Parameters ncc_cutoff = 1e-10 tolerance = 1e-10 # Build domain x_basis = x_basis_class('x', Nx, interval=(0, 1), dealias=2) domain = de.Domain([x_basis], np.float64) # Setup problem problem = de.NLBVP(domain, variables=['u'], ncc_cutoff=ncc_cutoff) problem.add_equation("dx(u) = sqrt(1 - u**2)") problem.add_bc("left(u) = 0") # Setup initial guess solver = problem.build_solver() x = domain.grid(0) u = solver.state['u'] u['g'] = x # Iterations pert = solver.perturbations.data pert.fill(1 + tolerance) while np.sum(np.abs(pert)) > tolerance: solver.newton_iteration() logger.info('Perturbation norm: {}'.format(np.sum(np.abs(pert)))) # Check solution u_true = np.sin(x) u.set_scales(1) assert np.allclose(u['g'], u_true)
def test_poisson_2d_nonperiodic(benchmark, x_basis_class, y_basis_class, Nx, Ny, dtype): # Bases and domain x_basis = x_basis_class('x', Nx, interval=(0, 2*np.pi)) y_basis = y_basis_class('y', Ny, interval=(0, 2*np.pi)) domain = de.Domain([x_basis, y_basis], grid_dtype=dtype) # Forcing F = domain.new_field(name='F') F.meta['x']['parity'] = -1 x, y = domain.grids() F['g'] = -2 * np.sin(x) * np.sin(y) # Problem problem = de.LBVP(domain, variables=['u','uy']) problem.meta['u']['x']['parity'] = -1 problem.meta['uy']['x']['parity'] = -1 problem.parameters['F'] = F problem.add_equation("uy - dy(u) = 0") problem.add_equation("dx(dx(u)) + dy(uy) = F") problem.add_bc("left(u) - right(u) = 0") problem.add_bc("left(uy) - right(uy) = 0", condition="nx != 0") problem.add_bc("left(u) = 0", condition="nx == 0") # Solver solver = problem.build_solver() solver.solve() # Check solution u_true = np.sin(x) * np.sin(y) u = solver.state['u'] assert np.allclose(u['g'], u_true)
def fast_field_test(oloops, iloops, N): xbasis = de.Fourier('x', N[0], interval=(-1, 1), dealias=1) ybasis = de.Fourier('y', N[1], interval=(-1, 1), dealias=1) domain = de.Domain([xbasis, ybasis], grid_dtype=np.float64, comm=None) maxtime = 0.0 mintime = 1E99 meantime = 0.0 maxb = 0.0 for i in range(oloops): t0 = time.time() a = dedalus_field_fast(init=domain) a['g'][:] = 1.0 * i b = dedalus_field_fast(a) maxb = inner_loop(iloops, dedalus_field_fast, maxb, a, b) t1 = time.time() maxtime = max(maxtime, t1 - t0) mintime = min(mintime, t1 - t0) meantime += t1 - t0 meantime /= oloops print(maxb) print(maxtime, mintime, meantime)
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(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 make_dedalus_movie(Nt, nsave, Lx, Nx, yr=[-1, 1], varname="u", name="movie", show=1): x_basis = de.Fourier('x', Nx, interval=(-Lx / 2, Lx / 2), dealias=3 / 2) domain = de.Domain([x_basis], np.float64) x = domain.grid(0) framerate = 20 intvl = 20 list = os.listdir("data/") file_count = len(list) fig = plt.figure() ax = plt.axes(xlim=(-Lx / 2, Lx / 2), ylim=(yr[0], yr[1])) ax.set_xlabel(r'$x$') # Set x label ax.set_ylabel(r'$c$') # Set y label plt.title(name) line, = ax.plot([], [], lw=2) def init(): line.set_data([], []) return line, def animate(j): n = int(j * nsave) n_str = str(n) filename = str(varname) + n_str hf = h5py.File('data/' + filename + '.h5', 'r') ut = hf.get(str(varname)) u = np.array(ut) line.set_data(x, u) return line, anim = animation.FuncAnimation(fig, animate, init_func=init, frames=file_count, interval=intvl, blit=True) anim.save(str(name) + ".mp4", fps=framerate, extra_args=['-vcodec', 'libx264']) if show == 1: plt.show() plt.close()
def test_rbc_growth(z, sparse): d = de.Domain([z]) rayleigh_benard = rbc_problem('EVP', d) EP = eig.Eigenproblem(rayleigh_benard) growth, index, freq = EP.growth_rate(sparse=sparse) assert np.allclose((growth, freq), (0.0018125573647729994, 0.))
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) z_basis = de.Fourier('z', params.Nz, interval=params.Bz, dealias=3 / 2) domain = de.Domain([x_basis, y_basis, z_basis], grid_dtype=np.float64, comm=comm) return domain
def test_rbc_output(z): d = de.Domain([z]) rb_evp = rbc_problem('EVP', d) EP = eig.Eigenproblem(rb_evp) growth, index, freq = EP.growth_rate(sparse=False) x = de.Fourier('x', 32) ivp_domain = de.Domain([x, z], grid_dtype=np.float64) fields = EP.project_mode(index, ivp_domain, [ 1, ]) EP.write_global_domain(fields) rb_IVP = rbc_problem('IVP', ivp_domain) solver = rb_IVP.build_solver(de.timesteppers.RK222) solver.load_state("IVP_output/IVP_output_s1.h5", -1)
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, 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', 'nu', 'freq', 'comm'] 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) # we assert that nvars looks very particular here.. this will be necessary for coarsening in space later on if problem_params['freq'] % 2 != 0: raise ProblemError('setup requires freq to be an equal number') xbasis = de.Fourier('x', problem_params['nvars'][0], interval=(0, 1), dealias=1) ybasis = de.Fourier('y', problem_params['nvars'][1], interval=(0, 1), dealias=1) domain = de.Domain([xbasis, ybasis], grid_dtype=np.float64, comm=problem_params['comm']) # invoke super init, passing number of dofs, dtype_u and dtype_f super(heat2d_dedalus_forced, self).__init__(init=domain, dtype_u=dtype_u, dtype_f=dtype_f, params=problem_params) self.x = self.init.grid(0, scales=1) self.y = self.init.grid(1, scales=1) self.rhs = self.dtype_u(self.init, val=0.0) self.problem = de.IVP(domain=self.init, variables=['u']) self.problem.parameters['nu'] = self.params.nu self.problem.add_equation( "dt(u) - nu * dx(dx(u)) - nu * dy(dy(u)) = 0") self.solver = self.problem.build_solver(de.timesteppers.SBDF1) self.u = self.solver.state['u']
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 __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 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 _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 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 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_solver(nx, ny, Lx, Ly, RA, BE, PR, CC): comm = MPI.COMM_WORLD rank = comm.Get_rank() Nx = nx Ny = ny #for equilibrium: # C = 0, beta = 0, Pr = 1, Ra = 5000 Ra = RA Pr = PR beta = BE C = CC #for travelling wave #Ra = 7.542e5 Pr = 1. beta = 3E4 C = 0 if rank == 0: print("dedalus: solver is built for: Nx "+str(nx)+" Ny: "+str(ny)+" Lx: "+str(Lx)+ " Ly: "+str(Ly)+" and Ra: "+str(Ra)) print("dedalus: Pr "+str(Pr)+" beta: "+str(beta)+" C: "+str(C)) x_basis = de.Fourier('x', Nx, interval=(0, Lx), dealias=3/2) y_basis = de.SinCos ('y', Ny, interval=(0, Ly), dealias=3/2) domain = de.Domain([x_basis, y_basis], grid_dtype=np.float64) # 2D Boussinesq hydrodynamics problem = de.IVP(domain, variables=['psi','theta','zeta'], time='t') problem.meta['psi','zeta','theta']['y']['parity'] = -1 # sin basis problem.parameters['Pr'] = Pr problem.parameters['Ra'] = Ra problem.parameters['beta'] = beta problem.parameters['sbeta'] = np.sqrt(np.abs(beta)) problem.parameters['C'] = C # construct the 2D Jacobian problem.substitutions['J(A,B)'] = "dx(A) * dy(B) - dy(A) * dx(B)" problem.add_equation("dt(zeta) - beta*dx(psi) + Ra/Pr * dx(theta) + C * sbeta * zeta - dx(dx(zeta)) - dy(dy(zeta)) = -J(psi,zeta)", condition="ny != 0") problem.add_equation("dt(theta) + dx(psi) - (dx(dx(theta)) + dy(dy(theta)))/Pr = -J(psi,theta)", condition="ny != 0") problem.add_equation("dx(dx(psi)) + dy(dy(psi)) - zeta = 0", condition="ny != 0") problem.add_equation("zeta = 0", condition="ny ==0") problem.add_equation("theta = 0", condition="ny ==0") problem.add_equation("psi = 0", condition="ny ==0") # Build solver solver = problem.build_solver(de.timesteppers.MCNAB2) #solver = problem.build_solver(de.timesteppers.SBDF1) logger.info('Solver built') return solver
def domain_setup(self): # Bases and domain self.Nx = 100 self.Lc = 2 * np.pi / 0.5 # (2*pi/qc) self.Lx = 20 * self.Lc self.Ny = 4 self.Nz = 4 self.Nd = 3 self.scale = 3 / 2 self.x_basis = de.Fourier('x', self.Nx, interval=(0, self.Lx), dealias=self.scale) self.domain = de.Domain([self.x_basis], grid_dtype=np.float64)
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 __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 test_exponential_free(benchmark, x_basis_class, Nx, dtype): # Bases and domain x_basis = x_basis_class('x', Nx, edge=0) domain = de.Domain([x_basis], grid_dtype=dtype) # Problem problem = de.LBVP(domain, variables=['u']) problem.add_equation("dx(u) + u = 0") problem.add_bc("left(u) = 1") # Solver solver = problem.build_solver() solver.solve() # Check solution x = domain.grid(0) u_true = np.exp(-x) u = solver.state['u'] assert np.allclose(u['g'], u_true)