Пример #1
0
def rk2_minmod(nx, t_end, system,
               cfl_factor=0.9, initial_data=initial_data_exp_sine,
               bc_form="outflow", rp_case="rusanov"):
    """
    Solve a conservation law on [0, 1] using N gridpoints to t=t_end.

    Parameters
    ----------
    nx : int
        Number of interior gridpoints.
    t_end : float
        Final time.
    system : class
        The system defining the conservation law
    cfl_factor : float
        The ratio of dt to dx
    initial_data : function
        The initial data as a function of x
    bc_form : string
        The form of the boundary condition

    Returns
    -------
    x : array of float
        Coordinates
    q : array of float
        Solution at the final time.
    """
    
    ngz = 2  # A second ghostzone is needed for slope limiting
    
    g = grids.Grid([0, 1], nx, ngz, cfl_factor)
    q = initial_data(g.x)
    
    t = 0
    while t < t_end:
        # Compute the maximum safe timestep
        g.dt = cfl_factor * g.dx / system.max_lambda(q)
        # Update current time
        if t + g.dt > t_end:
            g.dt = t_end - t
        t += g.dt
        # Take first step
        if rp_case == 'rusanov':
            q1 = q + g.dt * minmod_rusanov_step(q, g, flux=system.flux)
        elif rp_case == 'upwind':
            q1 = q + g.dt * minmod_upwind_step(q, g, flux=system.flux)
        else:
            raise NotImplementedError
        q1 = boundary_conditions.boundaries(q1, g, form=bc_form)
        # Take second step
        if rp_case == 'rusanov':
            q = 0.5 * (q + q1 + g.dt * minmod_rusanov_step(q1, g, flux=system.flux))
        elif rp_case == 'upwind':
            q = 0.5 * (q + q1 + g.dt * minmod_upwind_step(q1, g, flux=system.flux))
        else:
            raise NotImplementedError
        q = boundary_conditions.boundaries(q, g, form=bc_form)
    # Done
    return g.x, q
Пример #2
0
def weno_fvs(nx, t_end, system,
               cfl_factor=0.7, initial_data=initial_data_exp_sine,
               bc_form="outflow", weno_order=2):
    """
    Solve a conservation law on [0, 1] using N gridpoints to t=t_end.

    Parameters
    ----------
    nx : int
        Number of interior gridpoints.
    t_end : float
        Final time.
    system : class
        The system defining the conservation law
    cfl_factor : float
        The ratio of dt to dx
    initial_data : function
        The initial data as a function of x
    bc_form : string
        The form of the boundary condition
    weno_order : int
        Order of accuracy of the WENO reconstruction

    Returns
    -------
    x : array of float
        Coordinates
    q : array of float
        Solution at the final time.
    """
    
    ngz = weno_order  # WENO schemes of order 2k-1 need k ghostzones
    
    g = grids.Grid([0, 1], nx, ngz, cfl_factor)
    q = initial_data(g.x)
    
    t = 0
    while t < t_end:
        # Compute the maximum safe timestep
        g.dt = cfl_factor * g.dx / system.max_lambda(q)
        # Update current time
        if t + g.dt > t_end:
            g.dt = t_end - t
        t += g.dt
        # Take first step
        q1 = q + g.dt * weno_fvs_step(q, g, flux=system.flux, order=weno_order)
        q1 = boundary_conditions.boundaries(q1, g, form=bc_form)
        # Second RK2 step
        q2 = (3 * q + q1 + g.dt * weno_fvs_step(q1, g, flux=system.flux, order=weno_order)) / 4
        q2 = boundary_conditions.boundaries(q2, g, form=bc_form)
        # Second RK2 step
        q = (q + 2 * q2 + 2 * g.dt * weno_fvs_step(q2, g, flux=system.flux, order=weno_order)) / 3
        q = boundary_conditions.boundaries(q, g, form=bc_form)
    # Done
    return g.x, q
Пример #3
0
def godunov(nx,
            t_end,
            system,
            cfl_factor=0.9,
            initial_data=initial_data_sod,
            bc_form="outflow",
            rp_case="rusanov"):
    """
    Solve a conservation law on [0, 1] using N gridpoints to t=t_end.

    Parameters
    ----------
    nx : int
        Number of interior gridpoints.
    t_end : float
        Final time.
    system : class
        The system defining the conservation law
    cfl_factor : float
        The ratio of dt to dx
    initial_data : function
        The initial data as a function of x
    bc_form : string
        The form of the boundary condition
    rp_case : string
        The Riemann problem solver ('rusanov' or 'hlle')

    Returns
    -------
    x : array of float
        Coordinates
    q : array of float
        Solution at the final time.
    """

    ngz = 1  # This is all we need for upwind

    g = grids.Grid([0, 1], nx, ngz, cfl_factor)
    q = initial_data(system, g.x)

    t = 0
    while t < t_end:
        # Compute the maximum safe timestep
        g.dt = cfl_factor * g.dx / system.max_lambda(q)
        # Update current time
        if t + g.dt > t_end:
            g.dt = t_end - t
        t += g.dt
        # Take a single step
        if rp_case == 'rusanov':
            q += g.dt * godunov_rusanov_step(q, g, flux=system.flux)
        else:
            q += g.dt * godunov_hlle_step(
                q, g, flux=system.flux, c2p=system.c2p)
        q = boundary_conditions.boundaries(q, g, form=bc_form)
    # Done
    return g.x, q
Пример #4
0
def upwind(nx, t_end, system,
           cfl_factor=0.9, initial_data=initial_data_exp_sine,
           bc_form="outflow"):
    """
    Solve a conservation law on [0, 1] using N gridpoints to t=t_end.

    Parameters
    ----------
    nx : int
        Number of interior gridpoints.
    t_end : float
        Final time.
    system : class
        The system defining the conservation law
    cfl_factor : float
        The ratio of dt to dx
    initial_data : function
        The initial data as a function of x
    bc_form : string
        The form of the boundary condition

    Returns
    -------
    x : array of float
        Coordinates
    q : array of float
        Solution at the final time.
    """
    
    ngz = 1  # This is all we need for upwind
    
    g = grids.Grid([0, 1], nx, ngz, cfl_factor)
    q = initial_data(g.x)
    
    t = 0
    while t < t_end:
        # Compute the maximum safe timestep
        g.dt = cfl_factor * g.dx / system.max_lambda(q)
        # Update current time
        if t + g.dt > t_end:
            g.dt = t_end - t
        t += g.dt
        # Take a single step
        q += g.dt * upwind_step(q, g, flux=system.flux)
        q = boundary_conditions.boundaries(q, g, form=bc_form)
    # Done
    return g.x, q
Пример #5
0
def upwind(nx, t_end, cfl_factor=0.9, initial_data=initial_data_exp_sine):
    """
    Solve the advection equation on [0, 1] using N gridpoints to t=t_end.

    Parameters
    ----------
    nx : int
        Number of interior gridpoints.
    t_end : float
        Final time.
    cfl_factor : float
        The ratio of dt to dx
    initial_data : function
        The initial data as a function of x

    Returns
    -------
    x : array of float
        Coordinates
    q : array of float
        Solution at the final time.
    """
    
    ngz = 1  # This is all we need for upwind
    
    g = grids.Grid([0, 1], nx, ngz, cfl_factor)
    q = initial_data(g.x)
    
    t = 0
    while t < t_end:
        # Update current time
        if t + g.dt > t_end:
            g.dt = t_end - t
        t += g.dt
        # Take a single step
        q += g.dt * upwind_step(q, g)
        q = boundary_conditions.boundaries(q, g)
    # Done
    return g.x, q