Пример #1
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)
Пример #2
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)
Пример #3
0
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()
modes = 11
fig, axes = plt.subplots(num=1,
                         nrows=2,
                         ncols=modes,
                         sharex=True,
                         sharey='row')
for mode in range(modes):
    Ns = np.hstack((np.arange(3, 6) * 32, np.arange(4, 12) * 64))
    K2, vec, err = ch.iterate_solver(Ns,
                                     mode=mode,
                                     tol=1e-4,
                                     verbose=True,
Пример #4
0
    "Large" real and imaginary eigenvalues are removed and the eigenvalues
    are sorted from largest to smallest
    """
    import numpy as np

    # Set large values to zero, as they are presumably numerical artifact
    # and unphysical.
    E[np.abs(E.real) > 20.0] = 0
    E[np.abs(E.imag) > 20.0] = 0
    # Sort from largest to smallest eigenvalue
    index = np.argsort(np.real(E))[::-1]
    return (E, index)


# Overwrite the standard sorting strategy with the function defined above
solver.sorting_strategy = sorting_strategy

# Solve the full matrix problem keeping all eigenvalues and vectors
# results are stored in solver.E (a 1D array with the eigenvalues) and solver.v
# (a 2D array of the eigenvectors).
solver.solve(saveall=True)

"""
The approximation to the physical eigenvalue problem is a matrix eigenvalue
problem. The matrix has size d times N (where d is the number of linearized
equations and N is the number of grid points). There are thus d times N
eigenvalues. Obviously, the number of physical eigenvalues cannot depend on
the number of grid points. Some of the solutions found above are therefore not
physical (see e.g. the book by  Boyd).  The solutions were also calculated at
fixed number of grid  points, N. Convergent solutions are found by increasing
N and discarding the eigenvalues that are not present at higher N.