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
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
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
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
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