예제 #1
0
def test_kh_uniform_solution(show=False, verbose=False):
    """Test eigenvalue solver using FourierGrid"""
    import numpy as np
    from psecas import Solver, FourierGrid
    from psecas.systems.kh_uniform import KelvinHelmholtzUniform

    grid = FourierGrid(N=64, zmin=0, zmax=2)

    system = KelvinHelmholtzUniform(grid, beta=1e4, nu=1e-2, kx=3.52615254237)
    system.u0 = 1.

    solver = Solver(grid, system)

    Ns = np.hstack((np.arange(2, 16) * 32, np.arange(2, 12) * 64))
    for useOPinv in [True, False]:
        omega, v, err = solver.iterate_solver(Ns,
                                              tol=1e-5,
                                              useOPinv=useOPinv,
                                              verbose=verbose)
    np.testing.assert_allclose(1.66548246011, omega, atol=1e-5)

    if show:
        from psecas import plot_solution

        plot_solution(system, smooth=True, num=2)

    # Check that information converged is set to False when solver does not converge
    solver.iterate_solver(np.arange(1, 3) * 16,
                          tol=1e-16,
                          useOPinv=useOPinv,
                          verbose=verbose)
    assert solver.system.result['converged'] is False

    return err
예제 #2
0
def test_channel(show=False, verbose=False):
    """Test eigenvalue solver using ChebyshevRationalGrid"""
    import numpy as np
    from psecas import Solver, ChebyshevRationalGrid, System

    grid = ChebyshevRationalGrid(N=199, z='z')

    class Channel(System):
        def make_background(self):
            import numpy as np

            zg = self.grid.zg
            self.h = np.exp(-zg**2 / 2)

    # Create the Channel system
    system = Channel(grid, variables='G', eigenvalue='K2')

    # Add the first (and only) equation
    system.add_equation("-h*K2*G = dz(dz(G)) +z*dz(G)", boundary=True)
    solver = Solver(grid, system, do_gen_evp=True)

    # Number of modes to test
    modes = 3
    results = np.zeros(modes, dtype=np.complex128)
    checks = np.array([85.08037778, 69.4741069099, 55.4410282999])

    def sorting_strategy(E):
        """Sorting strategy for channel modes"""
        E[E.real > 100.0] = 0
        E[E.real < -10.0] = 0
        index = np.argsort(np.real(E))[::-1]
        return (E, index)

    solver.sorting_strategy = sorting_strategy

    if show:
        import matplotlib.pyplot as plt

        plt.figure(3)
        plt.clf()
        fig, axes = plt.subplots(num=3, ncols=modes, sharey=True)
    for mode in range(modes):
        Ns = np.arange(1, 6) * 32
        omega, vec, err = solver.iterate_solver(Ns, mode=mode, verbose=True)
        results[mode] = omega
        if show:
            phi = np.arctan(vec[2].imag / vec[2].real)
            solver.keep_result(omega, vec * np.exp(-1j * phi), mode)
            axes[mode].set_title(r"$\sigma = ${:1.4f}".format(omega.real),
                                 fontsize=10)
            axes[mode].plot(grid.zg, system.result['G'].real)
            axes[mode].plot(grid.zg, system.result['G'].imag)
            axes[mode].set_xlim(-4, 4)

    if show:
        plt.show()

    np.testing.assert_allclose(results, checks, rtol=1e-6)
예제 #3
0
    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
예제 #4
0
    def f(kx):
        grid = FourierGrid(N=64, zmin=0.0, zmax=2.0)
        system = KelvinHelmholtzUniform(grid, beta=5, nu=0, kx=kx)
        solver = Solver(grid, system)

        Ns = np.hstack((np.arange(4, 5) * 16, np.arange(3, 16) * 32))
        omega, v, err = solver.iterate_solver(Ns, verbose=True, tol=1e-8)

        return -omega.real
예제 #5
0
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
예제 #6
0
def test_parser_findmatrices(verbose=False):
    """
    Here we add the value A
    to the equation without setting it in the system.
    This should return a NameError
    """
    
    # Create system
    system = System(grid, variables='f', eigenvalue='sigma')

    # Add the first (and only) equation
    system.add_equation("sigma*z*f = dz(dz(f)) + 2*A*f")

    with pytest.raises(NameError) as e_info:

        solver = Solver(grid, system)

    if verbose:
        print(str(e_info.value))
예제 #7
0
def test_parser_boundaries(verbose=False):
    """
    Here we add the value B
    to the boundary without setting it in the system.
    This should return a NameError
    """
    # Create system
    system = System(grid, variables='f', eigenvalue='sigma')

    # Add the first (and only) equation
    system.add_equation("sigma*z*f = dz(dz(f))")
    
    system.add_boundary('f', 'Dirichlet', 'B*f = 0')

    solver = Solver(grid, system)

    with pytest.raises(NameError) as e_info:
        # The error is found when the solve method is called
        solver.solve()

    if verbose:
        print(str(e_info.value))
예제 #8
0
def test_mti_solution(show=False, verbose=False):
    """Test eigenvalue solver using ChebyshevExtremaGrid"""
    import numpy as np
    from psecas import Solver, ChebyshevExtremaGrid
    from psecas.systems.mti import MagnetoThermalInstability

    grid = ChebyshevExtremaGrid(N=64, zmin=0, zmax=1)

    system = MagnetoThermalInstability(grid, beta=1e5, Kn0=200, kx=4 * np.pi)
    system.beta = 1e5
    system.Kn0 = 200

    assert system.Kn0 == 200
    assert system.beta == 1e5

    solver = Solver(grid, system)

    Ns = np.hstack(np.arange(1, 10) * 16)
    mode = 0
    omega, vec, err = solver.iterate_solver(Ns,
                                            mode=mode,
                                            tol=1e-8,
                                            verbose=verbose)

    system.get_bx_and_by()

    if show:
        from psecas import plot_solution

        phi = np.arctan(vec[2].imag / vec[2].real)
        solver.keep_result(omega, vec * np.exp(-1j * phi), mode=mode)

        plot_solution(system, smooth=True, num=1)

    np.testing.assert_allclose(1.7814514515967603, omega, atol=1e-8)

    return err
예제 #9
0
def test_solver_methods(verbose=False):
    """Show how the solver class methods can be called directly,
       using the MTI as an example.
       This can be useful when setting up a new problem.
    """
    import numpy as np
    from psecas import Solver, ChebyshevExtremaGrid
    from psecas.systems.mti import MagnetoThermalInstability
    from scipy.linalg import eig

    grid = ChebyshevExtremaGrid(N=64, zmin=0, zmax=1)

    system = MagnetoThermalInstability(grid, beta=1e5, Kn0=200, kx=4 * np.pi)

    solver = Solver(grid, system)

    solver.get_matrix1(verbose=verbose)

    solver.get_matrix2(verbose=verbose)

    E, V = eig(solver.mat1.toarray(), solver.mat2.toarray())

    # Sort the eigenvalues
    E, index = solver.sorting_strategy(E)

    mode = 0

    # Choose the eigenvalue mode value only
    sigma = E[index[mode]]
    v = V[:, index[mode]]

    np.testing.assert_allclose(1.7814514515967603, sigma, atol=1e-8)

    # Compare with solve without using OPinv
    solver.solve(useOPinv=False, saveall=True)
    np.testing.assert_allclose(solver.E[mode], sigma, atol=1e-8)
예제 #10
0
        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([
        system.result["dvx"].real,
        system.result["dvx"].imag,
        system.result["dvz"].real,
        system.result["dvz"].imag,
    ])

    val = np.max(np.abs(y))
    for key in system.variables:
        system.result[key] /= val
예제 #11
0
파일: channel.py 프로젝트: tberlok/psecas
and is solved  by employing a Neumann boundary condition on F.

One of the modes obtained here, with KH=3.1979, is not found
when solving 

    -h K² G = z G' + G'' 
    
Visual inspection reveals that the extra mode is numerical garbage.
Automated detection of such modes would be a good feature to implement.
"""

grid = ChebyshevRationalGrid(N=199, z='z')
system = Channel(grid)

ch = Solver(grid, system)


def sorting_strategy(E):
    """Sorting strategy for channel modes"""
    E[E.real > 100.0] = 0
    E[E.real < -10.0] = 0
    index = np.argsort(np.real(E))[::-1]
    return (E, index)


# Overwrite the default sorting strategy in the Solver class
ch.sorting_strategy = sorting_strategy

plt.figure(1)
plt.clf()
예제 #12
0
def test_mri_solution(show=False, verbose=False):
    """Test eigenvalue solver using ChebyshevExtremaGrid"""
    import numpy as np
    from psecas import Solver, ChebyshevExtremaGrid, System

    class HallMRI(System):
        def __init__(self, grid, kz, variables, eigenvalue):
            # Set parameters
            self.q = 1.5
            self.eta = 0.003
            self.lh = 1
            self.h = 0.25
            self.va = 0.002
            self.kz = kz

            super().__init__(grid, variables, eigenvalue)

    # Create a grid
    grid = ChebyshevExtremaGrid(N=128, zmin=1, zmax=2, z='r')

    variables = ['rho', 'vr', 'vphi', 'vz', 'Aphi', 'bphi']

    kz = 2 * np.pi

    # Create the system
    system = HallMRI(grid, kz, variables=variables, eigenvalue='sigma')

    # The linearized equations
    system.add_equation("-r*sigma*rho = r*dr(vr) + vr + 1j*kz*r*vz")
    system.add_equation(
        "-r*r*sigma*vr = - 2*r**(2-q)*vphi + h**2*r*r*dr(rho) + va**2*(DrAphi)"
    )
    system.add_equation("-sigma*vphi = + (2-q)*r**(-q)*vr - va**2*1j*kz*bphi")
    system.add_equation("-sigma*vz = h**2*1j*kz*rho")
    system.add_equation(
        "-r*r*sigma*Aphi = + r*r*vr - eta*(DrAphi) + lh*va*1j*kz*r*r*bphi")
    system.add_equation(
        "-r*r*sigma*bphi = - 1j*kz*r*r*vphi - 1j*kz*q*r**(2-q)*Aphi - eta*(Drbphi) - lh*va*1j*kz*(DrAphi)"
    )

    # The boundary conditions
    Aphi_bound = 'r**2*dr(dr(Aphi)) + r*dr(Aphi) - Aphi = 0'
    system.add_boundary('vr', 'Dirichlet', 'Dirichlet')
    system.add_boundary('vphi', 'Dirichlet', 'Dirichlet')
    system.add_boundary('vz', 'Neumann', 'Neumann')
    system.add_boundary('Aphi', Aphi_bound, Aphi_bound)
    system.add_boundary('bphi', 'Dirichlet', 'Dirichlet')

    # Short hands for long expressions for derivatives
    system.add_substitution(
        'DrAphi = r*r*dr(dr(Aphi)) + r*dr(Aphi) - Aphi - kz**2*r*r*Aphi')
    system.add_substitution(
        'Drbphi = r*r*dr(dr(bphi)) + r*dr(bphi) - bphi - kz**2*r*r*bphi')

    solver = Solver(grid, system)

    mode = 0
    Ns = np.hstack(np.arange(1, 10) * 32)
    omega, vec, err = solver.iterate_solver(Ns,
                                            mode=mode,
                                            tol=1e-8,
                                            verbose=verbose)

    if show:
        from psecas import plot_solution

        phi = np.arctan(vec[2].imag / vec[2].real)
        solver.keep_result(omega, vec * np.exp(-1j * phi), mode=mode)

        plot_solution(system, smooth=True, num=1)

    np.testing.assert_allclose(0.09892641, omega, atol=1e-8)

    return err
예제 #13
0
        drhodz_sym = sym.diff(rho_sym, z)
        domgdz_sym = sym.diff(Omg_sym, z)

        zg = self.grid.zg
        self.rho = np.ones_like(zg) * lambdify(z, rho_sym)(zg)
        self.Omg = np.ones_like(zg) * lambdify(z, Omg_sym)(zg)
        self.shr = np.ones_like(zg) * lambdify(z, shr_sym)(zg)
        self.drhodz = np.ones_like(zg) * lambdify(z, drhodz_sym)(zg)
        self.domgdz = np.ones_like(zg) * lambdify(z, domgdz_sym)(zg)


# Create a grid
grid = ChebyshevRationalGrid(N=200, C=0.2)
# grid = ChebyshevExtremaGrid(N=199, zmin=-5, zmax=5)

# Create the system
system = VerticalShearInstability(grid,
                                  variables=['rh', 'wx', 'wy', 'wz'],
                                  eigenvalue='sigma')

# The linearized equations
system.add_equation("-sigma*rh = - 1j*kx*wx - 1/h*dz(wz) - 1/h*drhodz/rho*wz")
system.add_equation("-sigma*wx = + 2*Omg*wy - 1j*kx*(h/O0)**2*rh")
system.add_equation("-sigma*wy = - (2*Omg + shr)*wx - 1/h*domgdz*wz")
system.add_equation("-sigma*wz = - h/O0**2*dz(rh)", boundary=True)

solver = Solver(grid, system, do_gen_evp=True)

omega, vec = solver.solve(mode=0, verbose=True)
plot_solution(system)