def test_golden_section(): """Test golden section method on a simple example""" import numpy as np from psecas import golden_section def f(x): return (x - 2)**2 tol = 1e-8 (c, d) = golden_section(f, 1, 5, tol) print(c, d) np.testing.assert_allclose(c, 2.0, tol) np.testing.assert_allclose(d, 2.0, tol)
if False: from psecas import golden_section def f(kx): grid = FourierGrid(N=64, zmin=0.0, zmax=2.0) system = KelvinHelmholtzHydroOnly(grid, u0=1.0, delta=1.0, kx=kx) solver = Solver(grid, system) Ns = np.hstack((np.arange(1, 5) * 16, np.arange(3, 12) * 32)) omega, v, err = solver.iterate_solver(Ns, verbose=False, tol=1e-8) return -omega.real a = 3.512831867406509 b = 3.512831875508205 (a, b) = golden_section(f, a, b, tol=1e-8) # Create initial conditions for Athena simulation if True: from psecas import save_system kxmax = 3.5128319 grid = FourierGrid(N=256, zmin=0.0, zmax=2.0) system = KelvinHelmholtzHydroOnly(grid, u0=1.0, delta=1.0, kx=kxmax) solver = Solver(grid, system) Ns = np.hstack((np.arange(1, 5) * 16, np.arange(3, 12) * 32)) omega, v, err = solver.iterate_solver(Ns, verbose=True, tol=1e-8) # Normalize eigenmodes y = np.vstack([
Using golden_section is much cheaper than calculating the growth rate for a fine mesh of wave vectors and taking the maximum. """ def f(kx, **kwargs): # Set up a grid grid = FourierGrid(N=64, zmin=0, zmax=2) system = KelvinHelmholtzUniform(grid, beta=1e3, nu=0, kx=kx) if 'nu' in kwargs.keys(): system.nu = kwargs['nu'] # Set up a solver solver = Solver(grid, system) # Iteratively solve Ns = np.hstack((np.arange(1, 5) * 16, np.arange(3, 12) * 32)) omega, v, err = solver.iterate_solver(Ns, verbose=False, tol=1e-4) return -omega.real (a, b) = golden_section(f, 3.0, 6, tol=1e-3, nu=0.0) print(a, b, (a + b) / 2, -f((a + b) / 2)) (a, b) = golden_section(f, 3.0, 6, tol=1e-3, nu=1e-2) print(a, b, (a + b) / 2, -f((a + b) / 2)) (a, b) = golden_section(f, 3.0, 6, tol=1e-3, nu=1e-1) print(a, b, (a + b) / 2, -f((a + b) / 2))
# Find the kx that gives maximum growth if False: from psecas import golden_section def f(kx): grid = FourierGrid(N=64, zmin=0.0, zmax=2.0) system = KelvinHelmholtzHydroOnly(grid, u0=1.0, delta=0.0, kx=kx) solver = Solver(grid, system) Ns = np.hstack((np.arange(1, 5) * 16, np.arange(3, 20) * 32)) omega, v, err = solver.iterate_solver(Ns, verbose=False, tol=1e-8) return -omega.real (a, b) = golden_section(f, 5.148550549911674, 5.158147443539172, tol=1e-8) a = 5.1540899488183065 b = 5.154089957164513 # Create initial conditions for Athena simulation if True: from psecas import save_system kxmax = 5.1540899 grid = FourierGrid(N=256, zmin=0.0, zmax=2.0) system = KelvinHelmholtzHydroOnly(grid, u0=1.0, delta=0.0, kx=kxmax) solver = Solver(grid, system) Ns = np.hstack((np.arange(1, 5) * 16, np.arange(3, 20) * 32)) omega, v, err = solver.iterate_solver(Ns, verbose=True, tol=1e-10)
# Find the kx that gives maximum growth if False: from psecas import golden_section def f(kx): grid = FourierGrid(N=64, zmin=0.0, zmax=2.0) system = KelvinHelmholtzHydroOnly(grid, u0=1.0, delta=1.0, kx=kx) solver = Solver(grid, system) Ns = np.hstack((np.arange(1, 5) * 16, np.arange(3, 12) * 32)) omega, v, err = solver.iterate_solver(Ns, verbose=False, tol=1e-6) return -omega.real (a, b) = golden_section(f, 3.512295, 3.513135, tol=1e-5) # Create initial conditions for Athena simulation if False: from psecas import write_athena, save_system kxmax = 3.5128286141291243 grid = FourierGrid(N=64, zmin=0.0, zmax=2.0) system = KelvinHelmholtzHydroOnly(grid, u0=1.0, delta=1.0, kx=kxmax) solver = Solver(grid, system) Ns = np.hstack((np.arange(1, 5) * 16, np.arange(3, 12) * 32)) omega, v, err = solver.iterate_solver(Ns, verbose=False, tol=1e-6) # Write files for loading into Athena # write_athena(system, Nz=256, Lz=2.0)