Exemplo n.º 1
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))
Exemplo n.º 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)
Exemplo n.º 3
0
    Berlok, T. & Pfrommer, C. (2019). *On the Kelvin-Helmholtz instability 
    with smooth initial conditions – Linear theory and simulations*, MNRAS,
    485, 908

    Another reference for the KHI with anisotropic viscosity is

    Suzuki, K., Ogawa, T., Matsumoto, Y., & Matsumoto, R. (2013).
    Magnetohydrodynamic simulations of the formation of cold fronts in
    clusters of galaxies: Effects of anisotropic viscosity. Astrophysical
    Journal, 768(2). https://doi.org/10.1088/0004-637X/768/2/175
"""

directory = './data/'
kx_global = np.linspace(3, 4, 5)
kx_local = kx_global[comm.rank :: comm.size]

grid = FourierGrid(N=64, zmin=0, zmax=2)
system = KelvinHelmholtzUniform(grid, beta=1e4, nu=1e-2, kx=0)
io = IO(system, directory, __file__, len(kx_global))

solver = Solver(grid, system)

for i in range(len(kx_local)):
    t1 = time.time()
    system.kx = kx_local[i]
    omega, v = solver.solve()
    io.save_system(i)
    io.log(i, time.time() - t1, 'kx = {:1.4e}'.format(system.kx))

io.finished()
Exemplo n.º 4
0
    # 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.
This would normally be done by manually increasing N, calling solve, looking
at the eigenvalues, increasing N, calling solve,
comparing with previous iteration and so on. This procedure is tedious.

The solver class in Psecas contains a different method, iterate_solver,
Exemplo n.º 5
0
    hydrodynamics, MNRAS, 455(4), 4274–4288.
    https://doi.org/10.1093/mnras/stv2564
"""

# Plot omega vs kx
if True:
    grid = FourierGrid(N=64, zmin=0.0, zmax=2.0)
    system = KelvinHelmholtzHydroOnly(grid, u0=1.0, delta=1.0, kx=0)
    solver = Solver(grid, system)

    omega_vec = []
    kx_vec = np.linspace(0.1, 8, 15)
    for kx in kx_vec:
        t1 = time.time()
        system.kx = kx
        (omega, v) = solver.solve()
        omega_vec.append(omega)
        print(kx, omega)
        t2 = time.time()
        print("Solver took {} seconds".format(t2 - t1))
    omega_vec = np.array(omega_vec)

    plt.figure(1)
    # plt.clf()
    plt.plot(kx_vec, omega_vec.real)
    plt.xlabel(r"$k_x$")
    plt.ylabel(r"$\omega$")
    plt.show()

# Find the kx that gives maximum growth
if False:
Exemplo n.º 6
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)