def regenerate_weno_coarse_solution(self, solution_data): args = copy.deepcopy(solution_data['args']) if args.__dict__.get('eta') is None: args.__dict__['eta'] = 0 a, b, c, d, e = solution_data['a'], solution_data['b'], solution_data['c'], solution_data['d'], solution_data['e'] init_value = a + b * np.sin(c * np.pi * self.x_grid) + d * np.cos(e * np.pi * self.x_grid) args.Tscheme = 'rk4' beg = time.time() coarse_solver = weno3_fd(args, init_value=init_value, forcing=self.forcing, num_x=self.num_x, num_t=self.num_t, dt=self.dt, dx=self.dx) weno_coarse_grid_rk4 = coarse_solver.solve() self.weno_regenrate_time = time.time() - beg args.Tscheme = 'euler' coarse_solver = weno3_fd(args, init_value=init_value, forcing=self.forcing, num_x=self.num_x, num_t=self.num_t, dt=self.dt, dx=self.dx) weno_coarse_grid_euler = coarse_solver.solve() return weno_coarse_grid_rk4, weno_coarse_grid_euler
### compute and store precise solutions fine_num_x = int((args.x_high - args.x_low) / args.precise_dx + 1) fine_x_grid = np.linspace(args.x_low, args.x_high, fine_num_x, dtype=np.float64) ### precise_dx = 0.001 u0 = a + b * func(c * np.pi * fine_x_grid) fine_solver = weno3_fv(args.flux) fine_solution = fine_solver.solve(fine_x_grid, args.T, u0, args.cfl) ### compute and store weno solutions under coarse grids coarse_num_x = int((args.x_high - args.x_low) / args.dx + 1) coarse_x_grid = np.linspace(args.x_low, args.x_high, coarse_num_x, dtype=np.float64) ### precise_dx = 0.001 init_value = a + b * func(c * np.pi * coarse_x_grid) coarse_solver = weno3_fd(args, init_value=init_value) corase_solution = coarse_solver.solve() ### store the computed solutions func_name = 'sin' if func == np.sin else 'cos' init_name = '{0};{1};{2};{3}'.format(a, b, func_name, c) print('{0} + {1}{2}({3}\\pi * x)'.format(a, b, func_name, c)) np.save(file='../weno_solutions/{}-precise-{}-{}.npy'.format( init_name, args.flux, args.cfl), arr=fine_solution) np.save(file='../weno_solutions/{}-coarse-{}-{}-{}-{}'.format( init_name, args.Tscheme, args.dx, args.flux, args.cfl), arr=corase_solution)
def __init__(self, args, init_func=None, true_solution_grids=None, agent=None, coarse_solutions=None): ''' parameters: args: a dictionary storing all kinds of arguments init_func: a callable function giving the initial conditions. Interface should be f(x) true_solution_grids: the true solution grids agent: only required for RK4 time scheme. ''' self.T = args.T self.x_low, self.x_high = args.x_low, args.x_high self.dx = args.dx self.num_x = int((self.x_high - self.x_low) / self.dx + 1) self.num_t = int(args.T / args.dt + 1) # why + 1? self.x_grid = np.linspace(self.x_low, self.x_high, self.num_x, dtype=np.float64) # first dim: x; second dim: t self.RLgrid = np.zeros( (self.num_t, self.num_x)) # record the value at each (x,t) point # self.weno_grid = np.zeros((self.num_t, self.num_x)) # width: determine how many points in the previous time iteration will be used self.state_width = args.state_window_size ### mainly for filter-based methods self.action_width = args.action_window_size ### mainly for filter-based methods self.args = copy.copy(args) self.init_condition = init_func # agent for rk4 self.agent = agent if self.args.Tscheme == 'rk4': assert self.agent is not None # record actions at each time step for animation self.actions = np.zeros((self.num_t, self.num_x)) # currently trying fix dt self.dt = args.dt self.precise_dx = self.args.precise_dx #self.args.dx #0.001 self.precise_dt = self.precise_dx * args.cfl # initial and boundary conditions self.boundary_condition = args.boundary_condition # filters self.filters = np.array([[0, -0.5, 0, 0.5, 0], [0, 0, -1, 1, 0], [0, -1, 1, 0, 0], [0, 0, -1.5, 2, -0.5], [0.5, -2, 1.5, 0, 0]]) if self.args.mode == 'eno' or self.args.mode == 'weno': assert len(self.filters) == self.args.action_dim assert len(self.filters[0]) == 1 + 2 * self.action_width self.initial_value = self.init_condition(self.x_grid, self.args.initial_t) self.precise_weno_solutions = None self.weno_coarse_grid = None # if true_solution_grids is None: ### True solution use fine grid finite-volume weno # self.precise_weno_solutions = self.get_weno_grid(self.precise_dx, self.precise_dt, self.args.T + 0.1) # else: # self.precise_weno_solutions = true_solution_grids # if coarse_solutions is None: ### coarse solution use coarse grid finite-difference weno # corase_weno_solver = weno3_fd(args, init_value = self.initial_value) # self.weno_coarse_grid = corase_weno_solver.solve() # else: # self.weno_coarse_grid = coarse_solutions self.weno_error = None self.filter_inverse_matrix = np.linalg.inv( np.array([[1, 1, 1, 1, 1], [-2, -1, 0, 1, 2], [4, 1, 0, 1, 4], [-8, -1, 0, 1, 8], [16, 1, 0, 1, 16]])) self.weno_w = np.array([[1 / 3, 0, 0, 0], [-7 / 6, -1 / 6, 0, 0], [11 / 6, 5 / 6, 1 / 3, 0], [0, 1 / 3, 5 / 6, 11 / 6], [0, 0, -1 / 6, -7 / 6], [0, 0, 0, 1 / 3]]) if self.args.mode == 'nonlinear_weno_coef': self.corase_weno_solver = weno3_fd(self.args, init_value=self.initial_value)
def get_weno_corase(self): corase_weno_solver = weno3_fd(self.args, init_value=self.initial_value) self.weno_coarse_grid = corase_weno_solver.solve()
args.add_argument('--cfl', default=0.4, type=float) args.add_argument('--T', default=1.2, type=float) args.add_argument('--flux', default='u2', type=str) args.add_argument('--Tscheme', default='euler', type=str) args.add_argument('--x_low', default=-1, type=float) args.add_argument('--x_high', default=1, type=float) args = args.parse_args() precise_dx = 0.001 precise_dt = 0.0002 num_x = int((args.x_high - args.x_low) / args.dx + 1) reference_solution = get_weno_grid(args.x_low, args.x_high, precise_dx, precise_dt, args.T)[-1] reference_solution = subsample_precise_value(reference_solution, int(args.dx / precise_dx), num_x) init_x = np.linspace(args.x_low, args.x_high, num_x) init_u = init_condition(init_x) for dt in [0.01, 0.008, 0.006, 0.005, 0.004, 0.002, 0.001]: args.cfl = dt / args.dx solution = weno3_fd(args, init_u).solve()[-1] # solution1 = get_weno_grid(args.x_low, args.x_high, args.dx, dt, args.T)[-1] # plt.plot(solution1, 'ro', label = 'my weno') # plt.plot(solution2, 'b*', label = 'fe weno') # plt.plot(reference_solution, 'y+', label = 'reference') # plt.legend() # plt.show() error = np.linalg.norm(reference_solution - solution, 2) / np.linalg.norm( reference_solution, 2) print("dt: {}, error {}: ".format(dt, error))
print('dx: ', dx) args.dx = dx for tscheme in ['rk4', 'euler']: args.Tscheme = tscheme coarse_num_x = corase_num_x_list[dx_idx] corase_num_t = corase_num_t_list[dx_idx] coarse_x_grid = np.linspace( args.x_low, args.x_high, coarse_num_x, dtype=np.float64) ### precise_dx = 0.001 init_value = a + b * np.sin( c * np.pi * coarse_x_grid) + d * np.cos( e * np.pi * coarse_x_grid) coarse_solver = weno3_fd(args, init_value=init_value, forcing=forcing, num_x=coarse_num_x, num_t=corase_num_t) corase_solution = coarse_solver.solve() weno_coarse_solutions[tscheme][str(round(dx, 2))] = corase_solution # num_t = int(args.T / (dx * args.cfl)) - 10 # factor = int(dx / args.precise_dx) # for idx_t in range(num_t): # fig = plt.figure(figsize=(15, 7)) # plt.grid() # plt.plot(coarse_x_grid, weno_coarse_solutions[1][idx_t], 'bo-') # plt.plot(fine_x_grid, fine_solution[idx_t * int(dx / args.precise_dx)], 'r') # plt.show()