def euler_explicit(initial, ival, D=1.0): alpha = ival.ALPHA_DIFFUSION * D matrix = make_bc( np.diag(np.ones(ival.N_X)*(1.0-2.0*alpha)) + \ np.diag(np.ones(ival.N_X-1)*alpha,k=1) + \ np.diag(np.ones(ival.N_X-1)*alpha,k=-1), ival.BoundaryType) return np.linalg.matrix_power(matrix, ival.N_T) @ initial
def lax_friedrichs(initial, ival, c=1.0): alpha = c * ival.ALPHA_HOPF t = ival.N_T matrix = make_bc( 0.5*(np.diag(np.ones(ival.N_X-1)*(1-alpha),k=1) + \ np.diag(np.ones(ival.N_X-1)*(1+alpha),-1)), ival.BoundaryType) return np.linalg.matrix_power(matrix, t) @ initial
def euler_implicit(initial, ival, D=1.0): alpha = ival.ALPHA_DIFFUSION * D matrix = make_bc( np.diag(np.ones(ival.N_X)*(1.0+2.0*alpha)) - \ np.diag(np.ones(ival.N_X-1)*alpha,k=1) - \ np.diag(np.ones(ival.N_X-1)*alpha,k=-1), ival.BoundaryType) result = np.linalg.matrix_power(np.linalg.inv(matrix), ival.N_T) @ initial return result
def lax_wendroff(initial, ival, c=1.0): alpha = c * ival.ALPHA_HOPF t = ival.N_T matrix = make_bc( (1.-alpha**2)*np.diag(np.ones(ival.N_X)) + \ np.diag(np.ones(ival.N_X-1)*0.5*(alpha**2-alpha),1) + \ np.diag(np.ones(ival.N_X-1)*0.5*(alpha**2+alpha),-1), ival.BoundaryType) return np.linalg.matrix_power(matrix, t) @ initial
def downwind(initial, ival, c=1.0): alpha = c * ival.ALPHA_HOPF t = ival.N_T matrix = make_bc( np.diag(np.ones(ival.N_X)*(1.0+alpha)) - \ np.diag(np.ones(ival.N_X-1),1)*alpha, ival.BoundaryType) result = np.linalg.matrix_power(matrix, t) @ initial return result
def implicit_centered(initial, ival, c=1.0): alpha = c * ival.ALPHA_HOPF / 2.0 t = ival.N_T matrix = make_bc( np.diag(np.ones(ival.N_X)) + \ np.diag(np.ones(ival.N_X-1)*alpha,1) - \ np.diag(np.ones(ival.N_X-1)*alpha,-1), ival.BoundaryType) result = np.linalg.matrix_power(np.linalg.inv(matrix), t) @ initial return result
def crank_nicolson(initial, ival, D=1.0): alpha = ival.ALPHA_DIFFUSION * D Bmat = make_bc( np.diag(np.ones(ival.N_X))*2 - \ np.diag(np.ones(ival.N_X-1),k=1) - \ np.diag(np.ones(ival.N_X-1),k=-1), ival.BoundaryType) left_mat = (2 * np.diag(np.ones(ival.N_X)) + alpha * Bmat) right_mat = (2 * np.diag(np.ones(ival.N_X)) - alpha * Bmat) #if CHECK_CRANK_COMMUTE: # closemat = np.isclose( # np.linalg.inv(left_mat) @ right_mat - \ # right_mat @ np.linalg.inv(left_mat), # np.zeros_like(right_mat)) # if not closemat.sum() == closemat.shape[0]**2: # # check if matrices commute to only solve the problem once, not # # recursively # warnings.warn('Matrices do not commute. Wrong result.',RuntimeWarning) #result = sc_la.solve(np.linalg.matrix_power(left_mat,ival.N_T), # np.dot(np.linalg.matrix_power(right_mat,ival.N_T),initial), # assume_a="sym") result = np.linalg.matrix_power( np.linalg.inv(left_mat) @ right_mat, ival.N_T) @ initial return result