def set_eigenvalue_problem_type_2(self, Rayleigh, Prandtl, **kwargs): self.problem = de.EVP(self.domain, variables=self.variables, eigenvalue='nu', tolerance=1e-6) self.problem.substitutions['dt(f)'] = "(0*f)" self.set_equations(Rayleigh, Prandtl, EVP_2=True, **kwargs)
def test_wave_sparse_evp(benchmark, x_basis_class, Nx, dtype): n_comp = 5 # 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 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 build_solver(domain, domain_old, N, N_old, k): # We have N >= N_old # but N/2 < N_old T_old = domain_old.new_field() T_old.set_scales(512/N_old) data = np.loadtxt(dir + '/T.dat') T_old['g'] = data[1,:] T0 = domain.new_field() T0['c'][:int(N/2)] = T_old['c'][:int(N/2)] T0['c'][int(N/2):int(N/2) + int(N_old/2)] = T_old['c'][N_old:] # T0['c'][:N_old] = T_old['c'][:N_old] # T0['c'][N:N+int(N_old/2)] = T_old['c'][N_old:] rho = domain.new_field() T0.set_scales(1) rho.require_grid_space() np.place(rho['g'], T0['g']>0, -1) np.place(rho['g'], T0['g']<=0, S) rho['g'] *= T0['g'] N2 = rho.differentiate(0) z = domain.grid(0) T0z = T0.differentiate(0) T0z['g'][z<0.45] *= 0 T0z.require_coeff_space() logger.info(k) problem = de.EVP(domain, variables=['p','T','u','w','Tz','uz'], eigenvalue='om') problem.parameters['nu'] = nu problem.parameters['kappa'] = kappa problem.parameters['T0z'] = T0z problem.parameters['S'] = S problem.substitutions['dt(A)'] = "-1j*om*A" problem.parameters['kx'] = 2*np.pi*k problem.substitutions['dx(A)'] = "1j*kx*A" problem.add_equation("dx(u) + dz(w) = 0") problem.add_equation("dt(T) - kappa*(dx(dx(T)) + dz(Tz)) + w*T0z = 0") problem.add_equation("dt(u) - nu*(dx(dx(u)) + dz(uz)) + dx(p) = 0") problem.add_equation("dt(w) - nu*(dx(dx(w)) - dz(dx(u))) + dz(p) + S*T = 0") problem.add_equation("Tz - dz(T) = 0") problem.add_equation("uz - dz(u) = 0") problem.add_bc("left(uz) = 0") problem.add_bc("left(w) = 0") problem.add_bc("left(T) = 0") problem.add_bc("right(uz) = 0") problem.add_bc("right(w) = 0") problem.add_bc("right(T) = 0") solver = problem.build_solver() return solver
def test_half_qho_dense_evp(benchmark, x_basis_class, Nx, dtype): n_comp = 10 stretch = 0.1 # Domain x_basis = x_basis_class('x', Nx, edge=0, stretch=stretch) 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_qho_stretch_dense_evp(benchmark, x_basis_class, Nx, dtype): n_comp = 10 # Domain x_basis = x_basis_class('x', Nx, center=0, stretch=1.0) domain = de.Domain([x_basis], np.float64) # Problem sign_x = domain.new_field() sign_x.meta['x']['envelope'] = False sign_x['g'] = np.sign(domain.grid(0)) problem = de.EVP(domain, variables=['ψ', 'ψx'], eigenvalue='E') problem.parameters['sign_x'] = sign_x problem.substitutions["V"] = "abs(x) / 2" problem.substitutions[ "H(ψ,ψx)"] = "-(4*sign_x*x*dx(ψx) + 2*sign_x*ψx)/2 + V*ψ" problem.add_equation("ψx - dx(ψ) = 0", tau=False) problem.add_equation("H(ψ,ψx) - E*ψ = 0", tau=False) # 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(np.abs(solver.eigenvalues)) solver.eigenvalues = solver.eigenvalues[order] solver.eigenvectors = solver.eigenvectors[:, order] # Check solution n = np.arange(n_comp) exact_eigenvalues = n + 1 / 2 assert np.allclose(solver.eigenvalues[:n_comp], exact_eigenvalues)
def eigenmodes_inviscid_1d(param, kx, comm=MPI.COMM_SELF): """Solve normal modes for any kx in 1D.""" # Background BVP domain, p_full, a_full = background.solve_hydrostatic_pressure( param, np.complex128, comm=comm) p_full, p_trunc, a_full, a_trunc, heq, N2 = background.truncate_background( param, p_full, a_full) # Adiabatic viscous fully-compressible hydrodynamics problem = de.EVP(domain, variables=['a1', 'p1', 'u', 'w', 'uz', 'wz'], eigenvalue='σ', ncc_cutoff=param.ivp_cutoff, entry_cutoff=param.matrix_cutoff) problem.meta[:]['z']['dirichlet'] = True problem.parameters['a0'] = a_trunc problem.parameters['p0'] = p_trunc problem.parameters['a0z'] = a_trunc.differentiate('z') problem.parameters['p0z'] = p_trunc.differentiate('z') problem.substitutions['a0x'] = '0' problem.substitutions['p0x'] = '0' problem.parameters['U'] = 0 # Look at modes in local frame problem.substitutions['μ'] = '0' # Solve for inviscid modes problem.parameters['γ'] = param.γ problem.parameters['kx'] = kx # Instead of k_tide problem.parameters['Lx'] = param.Lx problem.parameters['Lz'] = param.Lz problem.substitutions['dt(A)'] = "σ*A" problem.substitutions['dx(A)'] = "1j*kx*A" problem.substitutions['ux'] = "dx(u)" problem.substitutions['wx'] = "dx(w)" problem.substitutions['div_u'] = "ux + wz" problem.substitutions['txx'] = "μ*(2*ux - 2/3*div_u)" problem.substitutions['txz'] = "μ*(wx + uz)" problem.substitutions['tzz'] = "μ*(2*wz - 2/3*div_u)" problem.substitutions['φ'] = "0" problem.substitutions['cs20'] = "γ*p0*a0" problem.add_equation( "dt(u) + U*ux + a0*dx(p1) + a1*p0x - a0*(dx(txx) + dz(txz)) = - (u*ux + w*uz) - a1*dx(p1) + a1*(dx(txx) + dz(txz)) - dx(φ)" ) problem.add_equation( "dt(w) + U*wx + a0*dz(p1) + a1*p0z - a0*(dx(txz) + dz(tzz)) = - (u*wx + w*wz) - a1*dz(p1) + a1*(dx(txz) + dz(tzz)) - dz(φ)" ) problem.add_equation( "dt(a1) + U*dx(a1) + u*a0x + w*a0z - a0*div_u = - (U*a0x + u*dx(a1) + w*dz(a1)) + a1*div_u" ) problem.add_equation( "dt(p1) + U*dx(p1) + u*p0x + w*p0z + γ*p0*div_u = - (U*p0x + u*dx(p1) + w*dz(p1)) - γ*p1*div_u" ) problem.add_equation("uz - dz(u) = 0") problem.add_equation("wz - dz(w) = 0") #problem.add_bc("left(txz) = 0") #problem.add_bc("right(txz) = 0") problem.add_bc("left(uz - dz(u)) = 0") problem.add_bc("left(w) = 0") problem.add_bc("right(w) = 0") return domain, problem
def set_EVP(self, *args, ncc_cutoff=1e-10, tolerance=1e-10, **kwargs): """ Constructs an eigenvalue problem of the current objeect's equation set. Note that dt(f) = omega * f, not i * omega * f, so real parts of omega are growth / shrinking nodes, imaginary parts are oscillating. """ self.problem_type = 'EVP' self.problem = de.EVP(self.domain, variables=self.variables, eigenvalue='omega', ncc_cutoff=ncc_cutoff, tolerance=tolerance) self.problem.substitutions['dt(f)'] = "omega*f" self.set_equations(*args, **kwargs)
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_eigenvalue_problem(self, *args, ncc_cutoff=1e-10, tol=1e-6, **kwargs): self.problem_type = 'EVP' self.problem = de.EVP(self.domain, variables=self.variables, eigenvalue='omega', ncc_cutoff=ncc_cutoff, tolerance=tol) self.problem.substitutions['dt(f)'] = "omega*f" self.set_equations(*args, **kwargs)
def _build_hires(self): """builds a high-resolution EVP from the EVP passed in at construction """ old_evp = self.EVP old_x = old_evp.domain.bases[0] x = tools.basis_from_basis(old_x, self.factor) d = de.Domain([x], comm=old_evp.domain.dist.comm) self.EVP_hires = de.EVP(d, old_evp.variables, old_evp.eigenvalue, ncc_cutoff=old_evp.ncc_kw['cutoff'], max_ncc_terms=old_evp.ncc_kw['max_terms'], tolerance=self.EVP.tol) for k, v in old_evp.substitutions.items(): self.EVP_hires.substitutions[k] = v for k, v in old_evp.parameters.items(): if type(v) == Field: #NCCs new_field = d.new_field() v.set_scales(self.factor, keep_data=True) new_field['g'] = v['g'] self.EVP_hires.parameters[k] = new_field else: #scalars self.EVP_hires.parameters[k] = v for e in old_evp.equations: self.EVP_hires.add_equation(e['raw_equation']) try: for b in old_evp.boundary_conditions: self.EVP_hires.add_bc(b['raw_equation']) except AttributeError: # after version befc23584fea, Dedalus no longer # distingishes BCs from other equations pass self.hires_solver = self.EVP_hires.build_solver()
def max_growth_rate(Nz, Prandtl, Rayleigh, kx): """Calculate maximum linear growth-rate for no-slip RBC.""" # Create bases and domain # Use COMM_SELF so keep calculations independent between processes z_basis = de.Chebyshev('z', Nz, interval=(-1/2, 1/2)) domain = de.Domain([z_basis], grid_dtype=np.complex128, comm=MPI.COMM_SELF) # 2D Boussinesq hydrodynamics, with no-slip boundary conditions # Use substitutions for x and t derivatives problem = de.EVP(domain, variables=['p','b','u','w','bz','uz','wz'], eigenvalue='omega') problem.parameters['P'] = (Rayleigh * Prandtl)**(-1/2) problem.parameters['R'] = (Rayleigh / Prandtl)**(-1/2) problem.parameters['F'] = F = 1 problem.parameters['kx'] = kx problem.substitutions['dx(A)'] = "1j*kx*A" problem.substitutions['dt(A)'] = "-1j*omega*A" problem.add_equation("dx(u) + wz = 0") problem.add_equation("dt(b) - P*(dx(dx(b)) + dz(bz)) - F*w = -(u*dx(b) + w*bz)") problem.add_equation("dt(u) - R*(dx(dx(u)) + dz(uz)) + dx(p) = -(u*dx(u) + w*uz)") problem.add_equation("dt(w) - R*(dx(dx(w)) + dz(wz)) + dz(p) - b = -(u*dx(w) + w*wz)") 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") problem.add_bc("integ(p, 'z') = 0") # Solve for eigenvalues solver = problem.build_solver() solver.solve(solver.pencils[0]) # Return largest finite imaginary part ev = solver.eigenvalues ev = ev[np.isfinite(ev)] return np.max(ev.imag)
def test_non_constant(Nx, sparse, ordinal): x = de.Chebyshev('x', Nx, interval=(0, 5)) d = de.Domain([ x, ]) prob = de.EVP(d, ['y', 'yx', 'yxx', 'yxxx'], 'sigma') prob.add_equation( "dx(yxxx) -0.02*x*x*yxx -0.04*x*yx + (0.0001*x*x*x*x - 0.02)*y - sigma*y = 0" ) prob.add_equation("dx(yxx) - yxxx = 0") prob.add_equation("dx(yx) - yxx = 0") prob.add_equation("dx(y) - yx = 0") prob.add_bc("left(y) = 0") prob.add_bc("right(y) = 0") prob.add_bc("left(yx) = 0") prob.add_bc("right(yx) = 0") EP = Eigenproblem(prob, use_ordinal=ordinal) EP.solve(sparse=sparse) indx = EP.evalues_good.argsort() five_evals = EP.evalues_good[indx][0:5] print("First five good eigenvalues are: ") print(five_evals) print(five_evals[-1]) reference = np.array([ 0.86690250239956 + 0j, 6.35768644786998 + 0j, 23.99274694653769 + 0j, 64.97869559403952 + 0j, 144.2841396045761 + 0j ]) assert np.allclose(reference, five_evals, rtol=1e-4)
nu['g'] = Nus[tind, :] U = domain.new_field(name='U') U['g'] = Us[tind, :] Uz = domain.new_field(name='Uz') Uz = U.differentiate(z_basis) V = domain.new_field(name='V') V['g'] = Vs[tind, :] Vz = domain.new_field(name='Vz') Vz['g'] = Vzs[tind, :] Bz = domain.new_field(name='Bz') B = domain.new_field(name='B') B['g'] = Bs[tind, :] Bz = B.differentiate(z_basis) problem = de.EVP(domain, variables=['u', 'v', 'w', 'b', 'p', 'uz', 'vz', 'wz', 'bz'], eigenvalue='omg', tolerance=1e-10) problem.parameters['tht'] = tht problem.parameters['U'] = U problem.parameters['V'] = V problem.parameters['B'] = B problem.parameters['Uz'] = Uz problem.parameters['Vz'] = Vz problem.parameters['Bz'] = Bz problem.parameters['N'] = 3.5e-3 problem.parameters['f'] = 1e-4 problem.parameters['kap'] = kap problem.parameters['nu'] = nu problem.parameters['k'] = 0. problem.parameters['l'] = l
import dedalus.public as de import numpy as np import matplotlib.pyplot as plt import logging import time logger = logging.getLogger(__name__) # Domain Nx = 128 x_basis = de.Chebyshev('x', Nx, interval=(-1, 1)) domain = de.Domain([x_basis], np.float64) # Problem problem = de.EVP(domain, variables=['u', 'u_x'],eigenvalue='l') problem.meta[:]['x']['dirichlet'] = True problem.add_equation("l*u + dx(u_x) = 0") problem.add_equation("u_x - dx(u) = 0") problem.add_bc("left(u) = 0") problem.add_bc("right(u) = 0") # Solver solver = problem.build_solver() t1 = time.time() solver.solve_dense(solver.pencils[0]) t2 = time.time() logger.info('Elapsed solve time: %f' %(t2-t1)) # Filter infinite/nan eigenmodes finite = np.isfinite(solver.eigenvalues)
y(0) = y(5) = y'(0) = y'(5) = 0 NB: I corrected a typo """ import dedalus.public as de from eigentools import Eigenproblem, CriticalFinder x = de.Chebyshev('x', 50, interval=(0, 5)) d = de.Domain([ x, ]) prob = de.EVP(d, ['y', 'yx', 'yxx', 'yxxx'], 'sigma') c3 = d.new_field(name='c3') c1 = d.new_field(name='c1') c01 = d.new_field(name='c01') xx = x.grid() # this is not a reasonable way to do this; it's just to test non-constant coefficients c3['g'] = -0.02 * xx**2 c1['g'] = -0.04 * xx c01['g'] = 0.0001 * xx**4 prob.parameters['c3'] = c3 prob.parameters['c1'] = c1 prob.parameters['c01'] = c01 prob.parameters['c02'] = -0.02
matplotlib.use('Agg') from mpi4py import MPI from eigentools import Eigenproblem, CriticalFinder import time import dedalus.public as de import numpy as np import matplotlib.pylab as plt comm = MPI.COMM_WORLD # Define the Orr-Somerfeld problem in Dedalus: z = de.Chebyshev('z', 50) d = de.Domain([z], comm=MPI.COMM_SELF) orr_somerfeld = de.EVP(d, ['w', 'wz', 'wzz', 'wzzz'], 'sigma') orr_somerfeld.parameters['alpha'] = 1. orr_somerfeld.parameters['Re'] = 10000. orr_somerfeld.add_equation( 'dz(wzzz) - 2*alpha**2*wzz + alpha**4*w - sigma*(wzz-alpha**2*w)-1j*alpha*(Re*(1-z**2)*(wzz-alpha**2*w) + 2*Re*w) = 0 ' ) orr_somerfeld.add_equation('dz(w)-wz = 0') orr_somerfeld.add_equation('dz(wz)-wzz = 0') orr_somerfeld.add_equation('dz(wzz)-wzzz = 0') orr_somerfeld.add_bc('left(w) = 0') orr_somerfeld.add_bc('right(w) = 0') orr_somerfeld.add_bc('left(wz) = 0') orr_somerfeld.add_bc('right(wz) = 0')
def set_eigenvalue_problem(self, *args, **kwargs): self._set_domain() self.problem = de.EVP(self.domain, variables=self.variables, eigenvalue='omega') self.problem.substitutions['dt(f)'] = "omega*f" self.set_equations(*args, **kwargs)
structure = heated_polytrope(nz, γ, ε, n_h) h0 = d.Field(name='h0', bases=zb) θ0 = d.Field(name='θ0', bases=zb) Υ0 = d.Field(name='Υ0', bases=zb) s0 = d.Field(name='s0', bases=zb) h0['g'] = structure['h']['g'] θ0['g'] = structure['θ']['g'] Υ0['g'] = structure['Υ']['g'] s0['g'] = structure['s']['g'] logger.info(structure) c = de.CartesianCoordinates('z') R_inv = d.Field(name='R_inv') ρ0 = np.exp(Υ0).evaluate() # Υ = ln(ρ), θ = ln(h) problem = de.EVP([u, Υ, θ, s, τ_u1, τ_u2, τ_s1, τ_s2], eigenvalue=R_inv) problem.add_equation( (ρ0 * (1 / Ma2 * (h0 * grad(θ) + grad(h0) * θ) - 1 / Ma2 * s_c_over_c_P * h0 * (grad(s) + θ * grad(s0))) - R_inv * viscous_terms + lift(τ_u1, -1) + lift(τ_u2, -2), 0)) problem.add_equation( (h0 * (div(u) + u @ grad(Υ0)) + R_inv * lift(τ_u2, -1) @ ez, 0)) problem.add_equation( (θ - (γ - 1) * Υ - s_c_over_c_P * γ * s, 0)) #EOS, s_c/cP = scrS #TO-DO: #consider adding back in diffusive & source nonlinearities problem.add_equation( (ρ0 * u @ grad(s0) - R_inv / Pr * (lap(θ) + 2 * grad(θ0) @ grad(θ)) + lift(τ_s1, -1) + lift(τ_s2, -2), 0)) if no_slip:
from mpi4py import MPI from eigentools import Eigenproblem, CriticalFinder import time import dedalus.public as de import numpy as np import matplotlib.pylab as plt comm = MPI.COMM_WORLD # Define the MRI problem in Dedalus: x = de.Chebyshev('x', 64) d = de.Domain([x], comm=MPI.COMM_SELF) mri = de.EVP( d, ['psi', 'u', 'A', 'B', 'psix', 'psixx', 'psixxx', 'ux', 'Ax', 'Bx'], 'sigma') Rm = 4.879 Pm = 0.001 mri.parameters['q'] = 1.5 mri.parameters['beta'] = 25.0 mri.parameters['iR'] = Pm / Rm mri.parameters['iRm'] = 1. / Rm mri.parameters['Q'] = 0.745 mri.add_equation( "sigma*psixx - Q**2*sigma*psi - iR*dx(psixxx) + 2*iR*Q**2*psixx - iR*Q**4*psi - 2*1j*Q*u - (2/beta)*1j*Q*dx(Ax) + (2/beta)*Q**3*1j*A = 0" ) mri.add_equation( "sigma*u - iR*dx(ux) + iR*Q**2*u - (q - 2)*1j*Q*psi - (2/beta)*1j*Q*B = 0")
def linearStabilityAnalysisPar(f, tht, kappa, Pr, U, Uz, V, Vz, B, Bz, nz, H, l, k, domain): # Need to decide whether input variables are in rotated frame or not. import sys import numpy as np import pdb from mpi4py import MPI from eigentools import Eigenproblem, CriticalFinder # import matplotlib.pyplot as plt # from pylab import * # import scipy.integrate as integrate from dedalus import public as de # import logging # logger = logging.getLogger(__name__) # LOAD IN PARAMETERS #f = parameters, tht, kappa, Pr, U, Uz, V, Vz, B, Bz, nz, H, ll, domain) # f, tht, kappa, Pr, U, Uz, V, Vz, B, Bz, nz, H, ll, domain): # pdb.set_trace() # f = args[0] # tht = args[1] # kappa = args[2] # Pr = args[3] # U = args[4] # Uz = args[5] # V = args[6] # Vz = args[7] # B = args[8] # Bz = args[9] # nz = args[10] # H = args[11] # ll = args[12] ## domain = args[13] # z_basis = de.Chebyshev('z', nz, interval=(0, H)) # domain = de.Domain([z_basis], np.complex128) # non-constant coefficients # kap = domain.new_field(name='kap') # z = domain.grid(0) # kap['g'] = kapi # SETUP LINEAR STABILITY ANALYSIS problem = de.EVP( domain, variables=['u', 'v', 'w', 'b', 'p', 'uz', 'vz', 'wz', 'bz'], eigenvalue='omg', tolerance=1e-3) problem.parameters['U'] = U problem.parameters['V'] = V problem.parameters['B'] = B problem.parameters['Uz'] = Uz problem.parameters['Vz'] = Vz problem.parameters['Bz'] = Bz problem.parameters['f'] = f problem.parameters['tht'] = tht problem.parameters['kap'] = kappa problem.parameters['Pr'] = Pr problem.parameters['k'] = 0. # will be set in loop problem.parameters['l'] = 0. # will be set in loop problem.substitutions['dx(A)'] = "1j*k*A" problem.substitutions['dy(A)'] = "1j*l*A" problem.substitutions['dt(A)'] = "-1j*omg*A" problem.add_equation( ('dt(u) + U*dx(u) + V*dy(u) + w*Uz - f*v*cos(tht) + dx(p)' '- b*sin(tht) - Pr*(kap*dx(dx(u)) + kap*dy(dy(u)) + dz(kap)*uz' '+ kap*dz(uz)) = 0')) problem.add_equation( ('dt(v) + U*dx(v) + V*dy(v) + w*Vz + f*u*cos(tht)' '- f*w*sin(tht) + dy(p) - Pr*(kap*dx(dx(v)) + kap*dy(dy(v))' '+ dz(kap)*vz + kap*dz(vz)) = 0')) # problem.add_equation(('dt(w) + U*dx(w) + V*dy(w) + f*v*sin(tht) + dz(p)' # '- b*cos(tht) - Pr*(kap*dx(dx(w)) + kap*dy(dy(w)) + dz(kap)*wz' # '+ kap*dz(wz)) = 0')) problem.add_equation( '0*(dt(w) + U*dx(w) + V*dy(w)) + f*v*sin(tht) + dz(p)' '- b*cos(tht) - Pr*(kap*dx(dx(w)) + kap*dy(dy(w)) + dz(kap)*wz' '+ kap*dz(wz)) = 0') # problem.add_equation(('dt(b) + U*dx(b) + V*dy(b) + u*N**2*sin(tht)' # '+ w*(N**2*cos(tht) + Bz) - kap*dx(dx(b)) - kap*dy(dy(b)) - dz(kap)*bz' # '- kap*dz(bz) = 0')) problem.add_equation( ('dt(b) + U*dx(b) + V*dy(b) + u*Vz*f' '+ w*(Bz) - kap*dx(dx(b)) - kap*dy(dy(b)) - dz(kap)*bz' '- kap*dz(bz) = 0')) problem.add_equation('dx(u) + dy(v) + wz = 0') problem.add_equation('uz - dz(u) = 0') problem.add_equation('vz - dz(v) = 0') problem.add_equation('wz - dz(w) = 0') problem.add_equation('bz - dz(b) = 0') problem.add_bc('left(u) = 0') problem.add_bc('left(v) = 0') problem.add_bc('left(w) = 0') problem.add_bc('left(bz) = 0') problem.add_bc('right(uz) = 0') problem.add_bc('right(vz) = 0') problem.add_bc('right(w) = 0') problem.add_bc('right(bz) = 0') problem.namespace['k'].value = k problem.namespace['l'].value = l # solve problem EP = Eigenproblem(problem) (gr, idx, freq) = EP.growth_rate({}) # print(str(np.max(idx))) # print(str(idx[-1])) # if idx[-1]>nz: # grt = 0 gr = np.array([gr]) # #get full eigenvectors and eigenvalues for l with largest growth ## idx = sorted_eigen(0., ll[np.argmax(gr)]) # solver.set_state(idx[-1]) # # # collect eigenvector # u = solver.state['u'] # v = solver.state['v'] # w = solver.state['w'] # b = solver.state['b'] # shear production # SP = -2*np.real(np.conj(w['g'])*(u['g']*Uz['g']+v['g']*Vz['g'])) # # # buoyancy production # BP = 2*np.real((u['g']*np.sin(tht)+w['g']*np.cos(tht))*np.conj(b['g'])) return (gr, 0, 0, 0, 0)
def mhd_rbc_evp(Q, Ra, k, Nz=24, variables_form=True): z = de.Chebyshev('z', Nz, interval=(0, 1)) d = de.Domain([z], comm=MPI.COMM_SELF) if variables_form: variables = [ 'T', 'Tz', 'u', 'w', 'phi', 'Ax', 'Ay', 'Az', 'Bx', 'By', 'Bz', 'Jx', 'Jy', 'Oy', 'p' ] else: variables = [ 'T', 'Tz', 'u', 'w', 'Ax', 'Ay', 'Az', 'Bx', 'By', 'Oy', 'p', 'phi' ] problem = de.EVP(d, variables, eigenvalue='omega') #Parameters problem.parameters['kx'] = k #horizontal wavenumber (x) problem.parameters['ky'] = 0 #horizontal wavenumber (y) problem.parameters['Ra'] = Ra #Rayleigh number problem.parameters['Pr'] = 1 #Prandtl number problem.parameters['Pm'] = 1 #Magnetic Prandtl number problem.parameters['Q'] = Q problem.parameters['dzT0'] = -1 #Substitutions problem.substitutions['v'] = '0' problem.substitutions['Ox'] = '0' 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))' if not variables_form: problem.substitutions["Bz"] = "dx(Ay)-dy(Ax)" problem.substitutions["Jx"] = "dy(Bz)-dz(By)" problem.substitutions["Jy"] = "dz(Bx)-dx(Bz)" problem.substitutions["Jz"] = "dx(By)-dy(Bx)" problem.substitutions["Kz"] = "dx(Oy)-dy(Ox)" problem.substitutions["Oz"] = "dx(v)-dy(u)" 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_Rem_ff"] = "(inv_Re_ff / Pm)" problem.substitutions["JxB_pre"] = "((Q*Pr)/(Ra*Pm))" problem.substitutions["inv_Pe_ff"] = "(Ra*Pr)**(-1./2.)" #Equations problem.add_equation("Tz - dz(T) = 0") 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 - JxB_pre*Jy = v*Oz - w*Oy + JxB_pre*(Jy*Bz - Jz*By)" ) problem.add_equation( "dt(w) + dz(p) + inv_Re_ff*Kz - T = u*Oy - v*Ox + JxB_pre*(Jx*By - Jy*Bx) " ) problem.add_equation( "dt(Ax) + dx(phi) + inv_Rem_ff*Jx - v = v*Bz - w*By") problem.add_equation( "dt(Ay) + dy(phi) + inv_Rem_ff*Jy + u = w*Bx - u*Bz") problem.add_equation( "dt(Az) + dz(phi) + inv_Rem_ff*Jz = u*By - v*Bx") problem.add_equation("dx(u) + dy(v) + dz(w) = 0") problem.add_equation("dx(Ax) + dy(Ay) + dz(Az) = 0") #do I need dy here?? problem.add_equation("Bx - (dy(Az) - dz(Ay)) = 0") problem.add_equation("By - (dz(Ax) - dx(Az)) = 0") if variables_form: problem.add_equation("Bz - (dx(Ay) - dy(Ax)) = 0") problem.add_equation("Jx - (dy(Bz) - dz(By)) = 0") problem.add_equation("Jy - (dz(Bx) - dx(Bz)) = 0") problem.add_equation("Oy - (dz(u) - dx(w)) = 0") bcs = ['T', 'u', 'w', 'Jx', 'Jy', 'Bz'] for bc in bcs: problem.add_bc(" left({}) = 0".format(bc)) problem.add_bc("right({}) = 0".format(bc)) return problem
def Rayleigh_Benard_onset(Prandtl=1, nz=32, nx=128, aspect=64, data_dir='./', multiplier=1.5, no_slip=False, stress_free=False, no_lid=False): if not no_slip and not stress_free and not no_lid: no_slip = True # input parameters logger.info(" Pr = {}".format(Prandtl)) # Parameters Lz = 1. Lx = aspect * Lz logger.info("resolution: [{}x{}]".format(nx, nz)) # Create bases and domain x_basis = de.Fourier('x', nx, interval=(0, Lx), dealias=3 / 2) z_basis_set = [] nz_set = [nz, int(nz * multiplier)] for nz_solve in nz_set: z_basis_set.append( de.Chebyshev('z', nz_solve, interval=(0, Lz), dealias=3 / 2)) domain_set = [] for z_basis in z_basis_set: domain_set.append(de.Domain([x_basis, z_basis], grid_dtype=np.float64)) solver_set = [] # 2D Boussinesq hydrodynamics for domain in domain_set: problem = de.EVP(domain, variables=['p', 'b', 'u', 'w', 'bz', 'uz', 'wz'], eigenvalue='Ra') problem.meta['p', 'b', 'u', 'w']['z']['dirichlet'] = True problem.parameters['F'] = F = 1 problem.parameters['Pr'] = np.sqrt(Prandtl) problem.parameters['Lx'] = Lx problem.parameters['Lz'] = Lz problem.substitutions['plane_avg(A)'] = 'integ(A, "x")/Lx' problem.substitutions['vol_avg(A)'] = 'integ(A)/Lx/Lz' # for eq_type_1 = False; not working problem.substitutions['dt(f)'] = '(0*f)' problem.substitutions['P'] = '(1/sqrt(Ra)*1/sqrt(Pr))' problem.substitutions['R'] = '(1/sqrt(Ra)*sqrt(Pr))' #problem.substitutions['scale'] = 'sqrt(Ra)' eq_type_1 = True problem.add_equation("dx(u) + wz = 0") if eq_type_1: problem.add_equation(" - (dx(dx(b)) + dz(bz)) - F*w = 0") problem.add_equation(" - (dx(dx(u)) + dz(uz)) + dx(p) = 0") problem.add_equation(" - (dx(dx(w)) + dz(wz)) + dz(p) - Ra*b = 0") else: # not working problem.add_equation( "(dt(b) - P*(dx(dx(b)) + dz(bz)) - F*w ) = -(u*dx(b) + w*bz)" ) problem.add_equation( "(dt(u) - R*(dx(dx(u)) + dz(uz)) + dx(p) ) = -(u*dx(u) + w*uz)" ) problem.add_equation( "(dt(w) - R*(dx(dx(w)) + dz(wz)) + dz(p) - b ) = -(u*dx(w) + w*wz)" ) 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") if no_slip: problem.add_bc("left(u) = 0") problem.add_bc("right(u) = 0") logger.info("using no_slip BCs") elif stress_free: problem.add_bc("left(uz) = 0") problem.add_bc("right(uz) = 0") logger.info("using stress_free BCs") elif no_lid: problem.add_bc("left(u) = 0") problem.add_bc("right(uz) = 0") logger.info("using stress_free BCs") problem.add_bc("left(w) = 0") problem.add_bc("right(b) = 0") problem.add_bc("right(w) = 0", condition="(nx != 0)") problem.add_bc("integ(p, 'z') = 0", condition="(nx == 0)") solver_set.append(problem.build_solver()) logger.info('Solver built') # Main loop try: logger.info('Starting loop') start_time = time.time() crit_Ra_set = [] min_wavenumber = 1 max_wavenumber = int(nx / 2) first_output = True for wave in np.arange(min_wavenumber, max_wavenumber): low_e_val_set = [] for solver in solver_set: solver.solve(solver.pencils[wave]) eigenvalue_indices = np.argsort(np.abs(solver.eigenvalues)) eigenvalues = np.copy(solver.eigenvalues[eigenvalue_indices]) low_e_val_set.append(eigenvalues[0]) x_grid = solver.domain.grid(0) if np.isfinite(low_e_val_set[0]): if first_output: print( "k_h Ra_1 Ra_2 relative error" ) print( " (nz={:4d}) (nz={:4d}) |Ra_1 - Ra_2|/|Ra_1|" .format(nz_set[0], nz_set[1])) first_output = False print( "{:4d}:{:12.4g} {:>12.4g} {:>12.4g} {:8.3g}".format( wave, wave / Lx, low_e_val_set[0], low_e_val_set[1], np.abs( np.abs(low_e_val_set[0] - low_e_val_set[1]) / low_e_val_set[0]))) crit_Ra_set.append(low_e_val_set[1]) else: print(wave, "no finite values") except: logger.error('Exception raised, triggering end of main loop.') raise finally: i_min_Ra = np.argmin(crit_Ra_set) logger.info("Minimum Ra = {:g} at wavenumber={:g} (# {:d})".format( crit_Ra_set[i_min_Ra], (i_min_Ra + min_wavenumber) / Lx, i_min_Ra + min_wavenumber)) end_time = time.time() logger.info('Run time: %.2f sec' % (end_time - start_time))
def solve_hires(self, tol=1e-10): old_evp = self.EVP old_d = old_evp.domain old_x = old_d.bases[0] old_x_grid = old_d.grid(0, scales=old_d.dealias) if type(old_x) == de.Compound: bases = [] for basis in old_x.subbases: old_x_type = basis.__class__.__name__ n_hi = int(basis.base_grid_size * self.factor) if old_x_type == "Chebyshev": x = de.Chebyshev(basis.name, n_hi, interval=basis.interval) elif old_x_type == "Fourier": x = de.Fourier(basis.name, n_hi, interval=basis.interval) else: raise ValueError( "Don't know how to make a basis of type {}".format( old_x_type)) bases.append(x) x = de.Compound(old_x.name, tuple(bases)) else: old_x_type = old_x.__class__.__name__ n_hi = int(old_x.coeff_size * self.factor) if old_x_type == "Chebyshev": x = de.Chebyshev(old_x.name, n_hi, interval=old_x.interval) elif old_x_type == "Fourier": x = de.Fourier(old_x.name, n_hi, interval=old_x.interval) else: raise ValueError( "Don't know how to make a basis of type {}".format( old_x_type)) d = de.Domain([x], comm=old_d.dist.comm) self.EVP_hires = de.EVP(d, old_evp.variables, old_evp.eigenvalue, tolerance=tol) x_grid = d.grid(0, scales=d.dealias) for k, v in old_evp.substitutions.items(): self.EVP_hires.substitutions[k] = v for k, v in old_evp.parameters.items(): if type(v) == Field: #NCCs new_field = d.new_field() v.set_scales(self.factor, keep_data=True) new_field['g'] = v['g'] self.EVP_hires.parameters[k] = new_field else: #scalars self.EVP_hires.parameters[k] = v for e in old_evp.equations: self.EVP_hires.add_equation(e['raw_equation']) try: for b in old_evp.boundary_conditions: self.EVP_hires.add_bc(b['raw_equation']) except AttributeError: # after version befc23584fea, Dedalus no longer # distingishes BCs from other equations pass solver = self.EVP_hires.build_solver() if self.sparse: solver.solve_sparse(solver.pencils[self.pencil], N=10, target=0, rebuild_coeffs=True) else: solver.solve_dense(solver.pencils[self.pencil], rebuild_coeffs=True) self.evalues_hires = solver.eigenvalues
def run(subs): print("\n\nBegin Linearized Pure Hydro, Const/Static Background\n") print("Using substitutions: ", subs) 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 parameters gamma = 1.4 kappa = 1.e-4 c_v = 1. k_z = 3.13 # vertical wavenumber R_in = 1. R_out = 3. # background is const rho0 = 5. T0 = 10. p0 = (gamma - 1) * c_v * rho0 * T0 height = 2. * numpy.pi / k_z # 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) th_basis = de.Fourier('th', 32, interval=(0., 2. * numpy.pi), dealias=3 / 2) domain = de.Domain([r_basis, th_basis, z_basis], grid_dtype=numpy.float64) # alias the grids z = domain.grid(2, scales=domain.dealias) th = domain.grid(1, scales=domain.dealias) r = domain.grid(0, scales=domain.dealias) # Equations # incompressible, axisymmetric, Navier-Stokes in Cylindrical # expand the non-constant-coefficients (NCC) to precision of 1.e-8 TC = de.EVP(domain, variables=['rho', 'p', 'T', 'u', 'v', 'w', 'Tr'], ncc_cutoff=1.e-8, eigenvalue='omega') TC.parameters['gamma'] = gamma TC.parameters['kappa'] = kappa TC.parameters['p0'] = p0 TC.parameters['T0'] = T0 TC.parameters['rho0'] = rho0 # multiply equations through by r**2 or r to avoid 1/r**2 & 1/r terms if (subs): # substitute for dt() TC.substitutions['dt(A)'] = '-1.j*omega*A' # r*div(U) TC.substitutions['r_div(A,B,C)'] = 'A + r*dr(A) + dth(B) + r*dz(C)' # r-component of gradient TC.substitutions['grad_1(A)'] = 'dr(A)' # th-component of gradient TC.substitutions['r_grad_2(A)'] = 'r*dth(A)' # z-component of gradient TC.substitutions['grad_3(A)'] = 'dz(A)' # r*r*Laplacian(scalar) TC.substitutions['r2_Lap(f, fr)'] = \ 'r*r*dr(fr) + r*dr(f) + dth(f) + r*r*dz(dz(f))' # equations using substituions TC.add_equation("p/p0 - rho/rho0 - T/T0 = 0") TC.add_equation("r*r*dt(p) + gamma*p0*r*r_div(u,v,w) - " + \ "(gamma-1)*kappa*r2_Lap(T, Tr) = 0") TC.add_equation("r*dt(rho) + rho0*r_div(u,v,w) = 0") TC.add_equation("rho0*dt(u) + grad_1(p) = 0") TC.add_equation("r*rho0*dt(v) + r_grad_2(p) = 0") TC.add_equation("rho0*dt(w) + grad_3(p) = 0") TC.add_equation("Tr - dr(T) = 0") else: print("\nNon-Substitutions Version is not coded up\n") sys.exit(2) # Boundary Conditions TC.add_bc("left(u) = 0") TC.add_bc("left(v) = 0") TC.add_bc("left(w) = 0") TC.add_bc("right(u) = 0", condition="nz != 0") TC.add_bc("right(v) = 0") TC.add_bc("right(w) = 0") TC.add_bc("integ(p,'r') = 0", condition="nz == 0") ############################################################### # Force break since the following has not been edited yet... ############################################################### print("\nThe rest of the script needs to be changed still\n") sys.exit(2) # 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 (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') return
#k = np.pi/10 #Rm = 4.052 R = Rm/Pm iR = 1.0/R c1 = (Omega2*R2**2 - Omega1*R1**2)/(R2**2 - R1**2) c2 = (R1**2*R2**2*(Omega1 - Omega2))/(R2**2 - R1**2) zeta_mean = 2*(R2**2*Omega2 - R1**2*Omega1)/((R2**2 - R1**2)*np.sqrt(Omega1*Omega2)) print("mean zeta is {}, meaning q = 2 - zeta = {}".format(zeta_mean, 2 - zeta_mean)) r = de.Chebyshev('r', nr, interval = (R1, R2)) d = de.Domain([r],comm=MPI.COMM_SELF) widegap = de.EVP(d,['psi','u', 'A', 'B', 'psir', 'psirr', 'psirrr', 'ur', 'Ar', 'Br'],'sigma') widegap.parameters['k'] = k widegap.parameters['iR'] = iR widegap.parameters['Rm'] = Rm # Rm rather than iRm so search options are more intuitive widegap.parameters['c1'] = c1 widegap.parameters['c2'] = c2 widegap.parameters['beta'] = beta widegap.parameters['B0'] = 1 widegap.parameters['xi'] = 0 widegap.substitutions['ru0'] = '(r*r*c1 + c2)' # u0 = r Omega(r) = Ar + B/r widegap.substitutions['rrdu0'] = '(c1*r*r-c2)' # du0/dr = A - B/r^2 widegap.substitutions['twooverbeta'] = '(2.0/beta)' widegap.substitutions['psivisc'] = '(2*r**2*k**2*psir - 2*r**3*k**2*psirr + r**3*k**4*psi + r**3*dr(psirrr) - 3*psir + 3*r*psirr - 2*r**2*psirrr)' widegap.substitutions['uvisc'] = '(-r**3*k**2*u + r**3*dr(ur) + r**2*ur - r*u)'
Re = 0. Pr = 1 Ra = 25 use_Laguerre = False find_crit = True if use_Laguerre: logger.info("Running with Laguerre z-basis") z_basis = de.Laguerre('z', nz, dealias=3 / 2) else: z_basis = de.Chebyshev('z', nz, interval=(0, Lz), dealias=3 / 2) domain = de.Domain([z_basis], comm=MPI.COMM_SELF) problem = de.EVP(domain, variables=['p', 'θ', 'u', 'v', 'w', 'θz', 'uz', 'vz', 'wz'], eigenvalue='sigma') problem.parameters['Ra'] = Ra problem.parameters['Re'] = Re problem.parameters['Pr'] = Pr problem.parameters['kx'] = kx problem.parameters['ky'] = ky problem.substitutions['Uz'] = '-Pr' problem.substitutions['dt(A)'] = 'sigma*A' problem.substitutions['dx(A)'] = '-1j*kx*A' problem.substitutions['dy(A)'] = '-1j*ky*A' if use_Laguerre: problem.substitutions['Ux'] = 'Pr*Re*(1-exp(-z))' problem.substitutions['Uxz'] = 'Pr*Re*exp(-z)' #problem.substitutions['Ux'] = '-Pr*Re*exp(-z)' #problem.substitutions['Uxz'] = 'Pr*Re*exp(-z)'
if case == 3: velocity_bc = "no-slip" temperature_bc = "FT" kc = 2.55 kx_global = np.linspace(kc * (1 - zoom), kc * (1 + zoom), Nk) # Create bases and domain # Use COMM_SELF so keep calculations independent between processes z_basis = de.Chebyshev('z', Nz, interval=(-1 / 2, 1 / 2)) domain = de.Domain([z_basis], grid_dtype=np.complex128, comm=MPI.COMM_SELF) # 2D Boussinesq hydrodynamics, with various boundary conditions # Use substitutions for x derivatives problem = de.EVP(domain, variables=['p', 'T', 'u', 'w', 'F', 'ω'], eigenvalue='Ra') problem.parameters['kx'] = 1 problem.substitutions['dx(A)'] = "1j*kx*A" problem.add_equation(" dx(u) + dz(w) = 0") problem.add_equation(" dx(dx(T)) - dz(F) + w = 0") problem.add_equation(" dz(ω) + dx(p) = 0") problem.add_equation(" - dx(ω) + dz(p) - Ra*T = 0") problem.add_equation("F + dz(T) = 0") problem.add_equation("ω - dx(w) + dz(u) = 0") problem.add_bc("left(w) = 0") problem.add_bc("right(w) = 0") if velocity_bc == "no-slip":
if __name__ == '__main__': ''' setup domain and calculate derivatives of vertical profiles as needed ''' z_basis = de.Chebyshev('z', nz_waves, interval=(zmin * Hgas, zmax * Hgas)) domain_EVP = de.Domain([z_basis], comm=MPI.COMM_SELF) ''' notation: W = delta_P/P = delta_ln_rhog, Q=delta_eps/eps = delta_ln_eps, U = velocities W_p = W_primed (dW/dz)...etc ''' if (diffusion == True) and (tstop == True): #full problem waves = de.EVP(domain_EVP, ['W', 'W_p', 'Q', 'Q_p', 'Ux', 'Uy', 'Uz'], eigenvalue='sigma', tolerance=tol) if (diffusion == False) and (tstop == True): waves = de.EVP(domain_EVP, ['W', 'W_p', 'Q', 'Ux', 'Uy', 'Uz'], eigenvalue='sigma', tolerance=tol) if (diffusion == False) and (tstop == False): waves = de.EVP(domain_EVP, ['W', 'Q', 'Ux', 'Uy', 'Uz'], eigenvalue='sigma', tolerance=tol) ''' set up required vertical profiles as non-constant coefficients ''' z = domain_EVP.grid(0)
def weakfield_hydro(Ra, k, Nz=24, noHorizB_BCs=True, kx=True): z = de.Chebyshev('z', Nz, interval=(0, 1)) d = de.Domain([z], comm=MPI.COMM_SELF) variables = ['p', 'u', 'v', 'w', 'Ox', 'Oy', 'Bx', 'By', 'Bz', 'Jz_z'] problem = de.EVP(d, variables, eigenvalue='omega') #Parameters if kx: problem.parameters['kx'] = k problem.parameters['ky'] = 0 else: problem.parameters['kx'] = 0 problem.parameters['ky'] = k problem.parameters['Ra'] = Ra #Rayleigh number problem.parameters['Pm'] = 1 #Magnetic Prandtl number 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["Jx"] = "dy(Bz)-dz(By)" problem.substitutions["Jy"] = "dz(Bx)-dx(Bz)" problem.substitutions["Jz"] = "dx(By)-dy(Bx)" 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_Rem_ff"] = "(inv_Re_ff / Pm)" problem.substitutions['B0'] = '0' problem.substitutions['T'] = '0' #Equations problem.add_equation("dx(u) + dy(v) + dz(w) = 0") problem.add_equation("dt(u) + dx(p) + inv_Re_ff*(dy(Oz)-dz(Oy)) = 0 ") problem.add_equation("dt(v) + dy(p) + inv_Re_ff*(dz(Ox)-dx(Oz)) = 0 ") problem.add_equation("dt(w) + dz(p) + inv_Re_ff*(dx(Oy)-dy(Ox)) = 0 ") problem.add_equation("Ox - (dy(w) - dz(v)) = 0") problem.add_equation("Oy - (dz(u) - dx(w)) = 0") problem.add_equation("dx(Bx) + dy(By) + dz(Bz) = 0") problem.add_equation( "dt(Bz) + inv_Rem_ff*(dx(Jy) - dy(Jx)) = 0" ) #need to figure out nonliner terms problem.add_equation( "dt(Jz) - inv_Rem_ff*(dx(dx(Jz)) + dy(dy(Jz)) + dz(Jz_z)) = 0") problem.add_equation("Jz_z - dz(Jz) = 0") if noHorizB_BCs: bcs = ['Oy', 'Ox', 'w', 'Bx', 'By'] else: bcs = ['Oy', 'Ox', 'w', 'Bz', 'Jz_z'] for bc in bcs: problem.add_bc(" left({}) = 0".format(bc)) problem.add_bc("right({}) = 0".format(bc)) return problem