def minmod_fvs_step(q, g, flux): """ Update the solution one timestep using the slope limited minmod method Parameters ---------- q : array of float The solution at t^n g : Grid Information about the grid flux : function The flux function to use Returns ------- q_rhs : array of float The update to take the solution to q at t^{n+1} Notes ----- Compare the update formula carefully with the upwind scheme. The f_rusanov is now an intercell flux, so f_rusanov[i] is the flux through x[i-1/2]. This means the indics are off-by-one compared to the upwind scheme. """ q_rhs = numpy.zeros_like(q) f = flux(q) alpha = abs(system.max_lambda(q)) f_p = (f + alpha * q) / 2 f_m = (f - alpha * q) / 2 f_p_L = numpy.zeros_like(q) f_m_R = numpy.zeros_like(q) f_fvs = numpy.zeros_like(q) for i in range(g.ngz - 1, g.nx + g.ngz + 1): # Reconstruct f plus to the right to get the state to the Left of the interface sigma_up = f_p[i + 1] - f_p[i] sigma_do = f_p[i] - f_p[i - 1] sigma_bar = minmod(sigma_up, sigma_do) f_p_L[i + 1] = f_p[i] + 0.5 * sigma_bar # Reconstruct f minus to the left to get the state to the Right of the interface sigma_up = f_m[i + 1] - f_m[i] sigma_do = f_m[i] - f_m[i - 1] sigma_bar = minmod(sigma_up, sigma_do) f_m_R[i] = f_m[i] - 0.5 * sigma_bar for i in range(g.ngz, g.nx + g.ngz + 1): f_fvs[i] = f_p_L[i] + f_m_R[i] for i in range(g.ngz, g.nx + g.ngz): q_rhs[i] = 1.0 / g.dx * (f_fvs[i] - f_fvs[i + 1]) return q_rhs
def minmod_rusanov_step(q, g, flux): """ Update the solution one timestep using the slope limited minmod method Parameters ---------- q : array of float The solution at t^n g : Grid Information about the grid flux : function The flux function to use Returns ------- q_rhs : array of float The update to take the solution to q at t^{n+1} Notes ----- Compare the update formula carefully with the upwind scheme. The f_rusanov is now an intercell flux, so f_rusanov[i] is the flux through x[i-1/2]. This means the indics are off-by-one compared to the upwind scheme. """ q_rhs = numpy.zeros_like(q) f_rusanov = numpy.zeros_like(q) q_L = numpy.zeros_like(q) q_R = numpy.zeros_like(q) for i in range(g.ngz - 1, g.nx + g.ngz + 1): for k in range(q.shape[1]): sigma_up = q[i + 1, k] - q[i, k] sigma_do = q[i, k] - q[i - 1, k] sigma_bar = minmod(sigma_up, sigma_do) q_R[i, k] = q[i, k] - 0.5 * sigma_bar q_L[i + 1, k] = q[i, k] + 0.5 * sigma_bar f_L = flux(q_L) f_R = flux(q_R) for i in range(g.ngz, g.nx + g.ngz + 1): f_rusanov[i, :] = (f_L[i, :] + f_R[i, :] + g.dx / g.dt * (q_L[i, :] - q_R[i, :])) / 2 for i in range(g.ngz, g.nx + g.ngz): q_rhs[i, :] = 1.0 / g.dx * (f_rusanov[i, :] - f_rusanov[i + 1, :]) return q_rhs
def minmod_upwind_step(q, g, flux): """ Update the solution one timestep using the slope limited minmod method Parameters ---------- q : array of float The solution at t^n g : Grid Information about the grid flux : function The flux function to use Returns ------- q_rhs : array of float The update to take the solution to q at t^{n+1} Notes ----- Compare the update formula carefully with the upwind scheme. The f_rusanov is now an intercell flux, so f_rusanov[i] is the flux through x[i-1/2]. This means the indics are off-by-one compared to the upwind scheme. """ q_rhs = numpy.zeros_like(q) f_upwind = numpy.zeros_like(q) q_L = numpy.zeros_like(q) q_R = numpy.zeros_like(q) for i in range(g.ngz - 1, g.nx + g.ngz + 1): sigma_up = q[i+1] - q[i] sigma_do = q[i] - q[i-1] sigma_bar = minmod(sigma_up, sigma_do) q_R[i] = q[i] - 0.5 * sigma_bar q_L[i+1] = q[i] + 0.5 * sigma_bar for i in range(g.ngz, g.nx + g.ngz + 1): f_upwind[i] = #! To be completed for i in range(g.ngz, g.nx + g.ngz): q_rhs[i] = #! To be completed return q_rhs