def run_mgrit(nt, space_procs, coarsening, freq=1, a=1.0, t_start=0, t_stop=1, cycle='V'): size = MPI.COMM_WORLD.Get_size() comm_x, comm_t = split_communicator(MPI.COMM_WORLD, space_procs) nx = ny = 65 dmda_coarse = PETSc.DMDA().create([nx, ny], stencil_width=1, comm=comm_x) dmda_fine = dmda_coarse.refine() t_interval = np.linspace(t_start, t_stop, nt) time_procs = int(size / space_procs) problem = [HeatPetsc(dmda=dmda_fine, comm_x=comm_x, freq=freq, a=a, t_interval=t_interval)] for i in range(0, len(coarsening)): problem.append(HeatPetsc(dmda=dmda_fine, comm_x=comm_x, freq=freq, a=a, t_interval=t_interval[::np.prod(coarsening[:i + 1], dtype=int)])) nested_iteration = True if len(coarsening) > 0 else False if cycle == 'V': mgrit = Mgrit(problem=problem, comm_time=comm_t, comm_space=comm_x, nested_iteration=nested_iteration) else: mgrit = Mgrit(problem=problem, comm_time=comm_t, comm_space=comm_x, nested_iteration=nested_iteration, cycle_type='F', cf_iter=0) info = mgrit.solve() return info['time_setup'], info['time_solve'], info['time_setup'] + info['time_solve']
def main(): # Split the communicator into space and time communicator comm_world = MPI.COMM_WORLD comm_x, comm_t = split_communicator(comm_world, 2) # Define spatial domain # The domain is a 10x10 square with periodic boundary conditions in each direction. n = 20 mesh = PeriodicSquareMesh(n, n, 10, comm=comm_x) # Set up the problem diffusion0 = Diffusion2D(mesh=mesh, kappa=0.1, comm_space=comm_x, t_start=0, t_stop=10, nt=17) diffusion1 = Diffusion2D(mesh=mesh, kappa=0.1, comm_space=comm_x, t_start=0, t_stop=10, nt=9) # Setup three-level MGRIT solver with the space and time communicators and # solve the problem mgrit = Mgrit(problem=[diffusion0, diffusion1], comm_time=comm_t, comm_space=comm_x) info = mgrit.solve()
def main(): # Create Dahlquist's test problem using implicit mid-point rule time integration dahlquist_lvl0 = Dahlquist(t_start=0, t_stop=5, nt=101, method='MR') # Create Dahlquist's test problem using backward Euler time integration dahlquist_lvl1 = Dahlquist(t_start=0, t_stop=5, nt=51, method='BE') # Setup an MGRIT solver and solve the problem mgrit = Mgrit(problem=[dahlquist_lvl0, dahlquist_lvl1]) info = mgrit.solve()
def main(): def output_fcn(self): # Set path to solution; here, we include the iteration number in the path name path = 'results/' + 'brusselator' + '/' + str(self.solve_iter) # Create path if not existing pathlib.Path(path).mkdir(parents=True, exist_ok=True) # Save solution to file. # Useful member variables of MGRIT solver: # - self.t[0] : local fine-grid (level 0) time interval # - self.index_local[0] : indices of local fine-grid (level 0) time interval # - self.u[0] : fine-grid (level 0) solution values # - self.comm_time_rank : Time communicator rank np.save(path + '/brusselator-rank' + str(self.comm_time_rank), [[[self.t[0][i], self.u[0][i]] for i in self.index_local[0]] ]) # Solution and time at local time points # Create two-level time-grid hierarchy for the Brusselator system brusselator_lvl_0 = Brusselator(t_start=0, t_stop=12, nt=641) brusselator_lvl_1 = Brusselator(t_interval=brusselator_lvl_0.t[::20]) # Set up the MGRIT solver using the two-level hierarchy and set the output function mgrit = Mgrit(problem=[brusselator_lvl_0, brusselator_lvl_1], output_fcn=output_fcn, output_lvl=2, cf_iter=0) # Solve Brusselator system info = mgrit.solve() # Plot the MGRIT approximation of the solution after each iteration if MPI.COMM_WORLD.Get_rank() == 0: # Dynamic images iterations_needed = len(info['conv']) + 1 cols = 2 rows = iterations_needed // cols + iterations_needed % cols position = range(1, iterations_needed + 1) fig = plt.figure(1, figsize=[10, 10]) for i in range(iterations_needed): # Load each file and add the loaded values to sol sol = [] path = 'results/brusselator/' + str(i) for filename in os.listdir(path): data = np.load(path + '/' + filename, allow_pickle=True).tolist()[0] sol += data # Sort the solution list by the time sol.sort(key=lambda tup: tup[0]) # Get the solution values values = np.array([i[1].get_values() for i in sol]) ax = fig.add_subplot(rows, cols, position[i]) # Plot the two solution values at each time point ax.scatter(values[:, 0], values[:, 1]) ax.set(xlabel='x', ylabel='y') fig.tight_layout(pad=2.0) plt.show()
def main(): t_interval = np.linspace(0, 5, 17) dahlquist_0 = Dahlquist(t_start=0, t_stop=5, nt=65) dahlquist_1 = Dahlquist(t_interval=dahlquist_0.t[[0,3,10,12,14,17,23,27,33,34,55,57,59,61,63,64]]) dahlquist_2 = Dahlquist(t_interval=dahlquist_1.t[::2]) dahlquist_3 = Dahlquist(t_interval=dahlquist_2.t[::2]) dahlquist_4 = Dahlquist(t_interval=dahlquist_3.t[::2]) mgrit = Mgrit(problem=[dahlquist_0, dahlquist_1, dahlquist_2, dahlquist_3,dahlquist_4], tol=1e-10, nested_iteration=False) #mgrit.plot_parallel_distribution(time_procs=6, save_name='test.png') info = mgrit.solve()
def main(): # Create two-level time-grid hierarchy for the Brusselator system brusselator_lvl_0 = Brusselator(t_start=0, t_stop=12, nt=641) brusselator_lvl_1 = Brusselator(t_interval=brusselator_lvl_0.t[::20]) # Set up the MGRIT solver using the two-level hierarchy and set the output function mgrit = Mgrit(problem=[brusselator_lvl_0, brusselator_lvl_1], cf_iter=1) # Solve Brusselator system info = mgrit.solve()
def main(): # Create Dahlquist's test problem with 101 time steps in the interval [0, 5] dahlquist = Dahlquist(t_start=0, t_stop=5, nt=101) # Construct a two-level multigrid hierarchy for the test problem using a coarsening factor of 2 dahlquist_multilevel_structure = simple_setup_problem(problem=dahlquist, level=2, coarsening=2) # Set up the MGRIT solver for the test problem and set the solver tolerance to 1e-10 mgrit = Mgrit(problem=dahlquist_multilevel_structure, tol=1e-10) # Solve the test problem info = mgrit.solve()
def main(): # Create Dahlquist's test problem with 101 time steps in the interval [0, 5] dahlquist = Dahlquist(t_start=0, t_stop=5, nt=101) # Construct a two-level multigrid hierarchy for the test problem using a coarsening factor of 2 dahlquist_multilevel_structure = simple_setup_problem(problem=dahlquist, level=2, coarsening=2) # Set up the MGRIT solver for the test problem mgrit = Mgrit( problem=dahlquist_multilevel_structure, # Problem structure transfer=None, # Spatial grid transfer. Automatically set if None. max_iter=10, # Maximum number of iterations (default: 100) tol=1e-10, # Stopping tolerance (default: 1e-7) nested_iteration= True, # Use (True) or do not use (False) nested iterations # (default: True) cf_iter=1, # Number of CF relaxations (default: 1) cycle_type='V', # multigrid cycling type (default: 'V'): # 'V' -> V-cycles # 'F' -> F-cycles comm_time=MPI. COMM_WORLD, # Time communicator (default: MPI.COMM_WORLD) comm_space=MPI. COMM_NULL, # Space communicator (default: MPI.COMM_NULL) weight_c=1, # C - relaxation weight (default: 1) logging_lvl=20, # Logging level (default: 20): # 10: Debug -> Runtime of all components # 20: Info -> Info per iteration + summary # 30: None -> No information output_fcn=None, # Function for saving solution values to file # (default: None) output_lvl=1, # Output level (default: 1): # 0 -> output_fcn is never called # 1 -> output_fcn is called at the end of the simulation # 2 -> output_fcn is called after each MGRIT iteration t_norm=2, # Temporal norm # 1 -> One-norm # 2 -> Two-norm # 3 -> Infinity-norm random_init_guess= False # Use (True) or do not use (False) random initial guess # for all unknowns (default: False) ) # Solve the test problem return mgrit.solve()
def main(): def output_fcn(self): # Set path to solution path = 'results/petsc' # Create path if not existing pathlib.Path(path).mkdir(parents=True, exist_ok=True) # Save solution with corresponding time point to file np.save(path + '/petsc' + str(self.comm_time_rank) + str(self.comm_space_rank), [[[self.t[0][i], self.comm_space_rank, self.u[0][i].get_values().getArray()] for i in self.index_local[0]]]) # Split the communicator into space and time communicator comm_world = MPI.COMM_WORLD comm_x, comm_t = split_communicator(comm_world, 4) # Create PETSc DMDA grids nx = 129 ny = 129 dmda_coarse = PETSc.DMDA().create([nx, ny], stencil_width=1, comm=comm_x) dmda_fine = dmda_coarse.refine() # Set up the problem heat_petsc_0 = HeatPetsc(dmda=dmda_fine, comm_x=comm_x, freq=1, a=1.0, t_start=0, t_stop=1, nt=33) heat_petsc_1 = HeatPetsc(dmda=dmda_coarse, comm_x=comm_x, freq=1, a=1.0, t_interval=heat_petsc_0.t[::2]) heat_petsc_2 = HeatPetsc(dmda=dmda_coarse, comm_x=comm_x, freq=1, a=1.0, t_interval=heat_petsc_1.t[::2]) # Setup three-level MGRIT solver with the space and time communicators and # solve the problem mgrit = Mgrit(problem=[heat_petsc_0, heat_petsc_1, heat_petsc_2], transfer=[GridTransferPetsc(fine_prob=dmda_fine, coarse_prob=dmda_coarse), GridTransferCopy()], comm_time=comm_t, comm_space=comm_x, output_fcn=output_fcn) info = mgrit.solve() import time if comm_t.Get_rank() == 0: time.sleep(1) sol = [] path = 'results/petsc/' for filename in os.listdir(path): data = np.load(path + filename, allow_pickle=True).tolist()[0] sol += data sol = [item for item in sol if item[1] == comm_x.Get_rank()] sol.sort(key=lambda tup: tup[0]) u_e = heat_petsc_0.u_exact(t=heat_petsc_0.t[-1]).get_values().getArray() diff = sol[-1][2] - u_e print('Difference at time point', heat_petsc_0.t[-1], ':', np.linalg.norm(diff, np.inf), '(space rank',comm_x.Get_rank() , ')')
def test_split_into(): """ Test the function split_into """ heat0 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=2**2 + 1) result = np.array([4, 3, 3]) mgrit = Mgrit(problem=[heat0], transfer=[], nested_iteration=False) np.testing.assert_equal(result, mgrit.split_into(10, 3))
def test_time_stepping(): heat0 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=65) mgrit = Mgrit(problem=[heat0], cf_iter=1, nested_iteration=True, max_iter=2, random_init_guess=False) res = mgrit.solve() result_conv = np.array([]) np.testing.assert_almost_equal(result_conv, res['conv'])
def test_split_points(): """ Test the function split points """ heat0 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=2**2 + 1) result_proc0 = (4, 0) result_proc1 = (3, 4) result_proc2 = (3, 7) mgrit = Mgrit(problem=[heat0], nested_iteration=False) np.testing.assert_equal(result_proc0, mgrit.split_points(10, 3, 0)) np.testing.assert_equal(result_proc1, mgrit.split_points(10, 3, 1)) np.testing.assert_equal(result_proc2, mgrit.split_points(10, 3, 2))
def test_heat_equation_run(): """ Test one run for the heat equation """ heat0 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=65) heat1 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=17) heat2 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=5) problem = [heat0, heat1, heat2] mgrit = Mgrit(problem=problem, cf_iter=1, nested_iteration=True, max_iter=2, random_init_guess=False) res = mgrit.solve() result_conv = np.array([0.00267692, 0.00018053]) np.testing.assert_almost_equal(result_conv, res['conv'])
def main(): # Define output function that writes the solution to a file def output_fcn(self): # Set path to solution path = 'results/' + 'dahlquist' # Create path if not existing pathlib.Path(path).mkdir(parents=True, exist_ok=True) # Save solution to file; here, we just have a single solution value at each time point. # Useful member variables of MGRIT solver: # - self.t[0] : local fine-grid (level 0) time interval # - self.index_local[0] : indices of local fine-grid (level 0) time interval # - self.u[0] : fine-grid (level 0) solution values np.save(path + '/dahlquist', [self.u[0][i].get_values() for i in self.index_local[0] ]) # Solution values at local time points # Create Dahlquist's test problem with 101 time steps in the interval [0, 5] dahlquist = Dahlquist(t_start=0, t_stop=5, nt=101) # Construct a two-level multigrid hierarchy for the test problem using a coarsening factor of 2 dahlquist_multilevel_structure = simple_setup_problem(problem=dahlquist, level=2, coarsening=2) # Set up the MGRIT solver for the test problem and set the output function mgrit = Mgrit(problem=dahlquist_multilevel_structure, output_fcn=output_fcn) # Solve the test problem info = mgrit.solve() # Plot the solution (Note: modifications necessary if more than one process is used for the simulation!) t = np.linspace(dahlquist.t_start, dahlquist.t_end, dahlquist.nt) sol = np.load('results/dahlquist/dahlquist.npy') plt.plot(t, sol) plt.xlabel('t') plt.ylabel('u(t)') plt.show()
def main(): def output_fcn(self): # Set path to solution path = 'results/' + 'arenstorf' # Create path if not existing pathlib.Path(path).mkdir(parents=True, exist_ok=True) # Save solution to file; here, we have four solution values at each time point. # Save solution values and time at local time points np.save(path + '/arenstorf-rank' + str(self.comm_time_rank), [[[self.t[0][i], self.u[0][i]] for i in self.index_local[0]]]) # Create two-level time-grid hierarchy for the ODE system describing Arenstorf orbits ahrenstorf_lvl_0 = ArenstorfOrbit(t_start=0, t_stop=17.06521656015796, nt=80001) ahrenstorf_lvl_1 = ArenstorfOrbit(t_interval=ahrenstorf_lvl_0.t[::320]) # Set up the MGRIT solver using the two-level hierarchy and set the output function mgrit = Mgrit(problem=[ahrenstorf_lvl_0, ahrenstorf_lvl_1], cf_iter=0, output_fcn=output_fcn) # Compute Arenstorf orbit info = mgrit.solve() if MPI.COMM_WORLD.Get_rank() == 0: time.sleep(1) # Wait for files sol = [] path = 'results/arenstorf/' for filename in os.listdir(path): data = np.load(path + filename, allow_pickle=True).tolist()[0] sol += data sol.sort(key=lambda tup: tup[0]) # Plot MGRIT approximation of Arenstorf orbit plt.plot(0, 0, marker='o', color='black') plt.plot(1, 0, marker='o', color='black') plt.text(0.1, 0.1, u'Earth') plt.text(1.0, 0.1, u'Moon') # Use member function of VectorArenstorf to plot orbit for i in range(0, len(sol), 1000): sol[i][1].plot() plt.show()
def main(): # Option 1: Use PyMGRIT's core function simple_setup_problem() dahlquist_multilevel_structure_1 = simple_setup_problem(problem=Dahlquist( t_start=0, t_stop=5, nt=101), level=3, coarsening=2) Mgrit(problem=dahlquist_multilevel_structure_1, tol=1e-10).solve() # Option 2: Build each level using t_start, t_end, and nt dahlquist_lvl_0 = Dahlquist(t_start=0, t_stop=5, nt=101) dahlquist_lvl_1 = Dahlquist(t_start=0, t_stop=5, nt=51) dahlquist_lvl_2 = Dahlquist(t_start=0, t_stop=5, nt=26) dahlquist_multilevel_structure_2 = [ dahlquist_lvl_0, dahlquist_lvl_1, dahlquist_lvl_2 ] Mgrit(problem=dahlquist_multilevel_structure_2, tol=1e-10).solve() # Option 3: Specify time intervals for each grid level t_interval = np.linspace(0, 5, 101) dahlquist_lvl_0 = Dahlquist(t_interval=t_interval) dahlquist_lvl_1 = Dahlquist( t_interval=t_interval[::2]) # Takes every second point from t_interval dahlquist_lvl_2 = Dahlquist( t_interval=t_interval[::4]) # Takes every fourth point from t_interval dahlquist_multilevel_structure_3 = [ dahlquist_lvl_0, dahlquist_lvl_1, dahlquist_lvl_2 ] Mgrit(problem=dahlquist_multilevel_structure_3, tol=1e-10).solve() # Option 4: Mix options 2 and 3 dahlquist_lvl_0 = Dahlquist(t_start=0, t_stop=5, nt=101) dahlquist_lvl_1 = Dahlquist( t_interval=dahlquist_lvl_0.t[::2]) # Using t from the upper level. dahlquist_lvl_2 = Dahlquist(t_start=0, t_stop=5, nt=26) dahlquist_multilevel_structure_4 = [ dahlquist_lvl_0, dahlquist_lvl_1, dahlquist_lvl_2 ] Mgrit(problem=dahlquist_multilevel_structure_4, tol=1e-10).solve()
def main(): def output_fcn(self): # Set path to solution path = 'results/' + 'advection' # Create path if not existing pathlib.Path(path).mkdir(parents=True, exist_ok=True) # Save solution to file; here, we have nx solution values at each time point. np.save(path + '/heat_equation_2d-rank' + str(self.comm_time_rank), [[[self.t[0][i], self.u[0][i]] for i in self.index_local[0]]]) # Create two-level time-grid hierarchy for the advection equation advection_lvl_0 = Advection1D(c=1, x_start=-1, x_end=1, nx=129, t_start=0, t_stop=2, nt=129) advection_lvl_1 = Advection1D(c=1, x_start=-1, x_end=1, nx=129, t_start=0, t_stop=2, nt=65) problem = [advection_lvl_0, advection_lvl_1] # Set up two-level MGRIT solver with FCF-relaxation without nested iterations mgrit = Mgrit(problem=problem, cf_iter=1, nested_iteration=False, output_fcn=output_fcn, output_lvl=2) # Solve the advection problem info = mgrit.solve() if MPI.COMM_WORLD.Get_rank() == 0: sol = [] path = 'results/advection/' for filename in os.listdir(path): data = np.load(path + filename, allow_pickle=True).tolist()[0] sol += data sol.sort(key=lambda tup: tup[0]) # Plot initial condition and MGRIT approximation of the solution at the final time t = 2 x = advection_lvl_0.x fig, ax = plt.subplots() ax.plot(x, sol[0][1].get_values(), 'b:', label='initial condition u(x, 0)') ax.plot(x, sol[-1][1].get_values(), 'r-', label='solution at final time u(x, 2)') ax.legend(loc='lower center', shadow=False, fontsize='x-large') plt.xlabel('x') plt.show()
def main(): def rhs(x, t): """ Right-hand side of 1D heat equation example problem at a given space-time point (x,t), -sin(pi*x)(sin(t) - a*pi^2*cos(t)), a = 1 Note: exact solution is np.sin(np.pi * x) * np.cos(t) :param x: spatial grid point :param t: time point :return: right-hand side of 1D heat equation example problem at point (x,t) """ return -np.sin(np.pi * x) * (np.sin(t) - 1 * np.pi**2 * np.cos(t)) def init_cond(x): """ Initial condition of 1D heat equation example, u(x,0) = sin(pi*x) :param x: spatial grid point :return: initial condition of 1D heat equation example problem """ return np.sin(np.pi * x) def exact_sol(x, t): return np.sin(np.pi * x) * np.cos(t) def plot_error(mgrit, ts): fonts = 18 lw = 2 ms = 10 plt.rcParams["font.weight"] = "bold" plt.rcParams["axes.labelweight"] = "bold" fig1 = plt.figure(figsize=(15, 8)) ax1 = fig1.add_subplot(1, 1, 1) labels = [ 'V-cycle, FCF', 'V-cycle, FCFCF', 'F-cycle, F', 'F-cycle, FCF', 'F-cycle, FCFCF', ] colors = ['green', 'black', 'orange', 'yellow', 'purple'] mfc = ['green', 'black', 'white', 'white', 'white'] marker = ['s', 'D', 'o', 's', 'D'] linetype = ['-', '-', '--', '--', '--'] count = 1 save_vecs = [] for j in range(len(mgrit)): sol = mgrit[j].u[0] diffs_vector = np.zeros(len(sol)) for i in range(len(sol)): u_e = exact_sol(x=mgrit[j].problem[0].x, t=mgrit[j].problem[0].t[i]) diffs_vector[i] = np.linalg.norm(sol[i].get_values() - u_e, np.inf) save_vecs.append(diffs_vector.copy()) ax1.plot( heat0.t, diffs_vector, linetype[j], label=labels[j], color=colors[j], lw=lw, markevery=[], markeredgewidth=3, markerfacecolor=mfc[j], marker=marker[j], markersize=ms, ) count += 1 diffs_vector = np.zeros(len(sol)) for i in range(len(sol)): u_e = exact_sol(x=heat0.x, t=heat0.t[i]) diffs_vector[i] += abs(ts[i].get_values() - u_e).max() ax1.plot(heat0.t, diffs_vector, label='time-stepping', color='blue', lw=lw, markevery=[], markeredgewidth=3, markerfacecolor='blue', marker='x', markersize=ms) val = len(heat0.t) / 7 for i in range(5): ax1.plot(heat0.t, save_vecs[i], color=[0, 0, 0, 0], lw=lw, markevery=[int((i + 1) * val)], markeredgewidth=3, markerfacecolor=mfc[i], marker=marker[i], markeredgecolor=colors[i], markersize=ms) ax1.plot(heat0.t, diffs_vector, color=[0, 0, 0, 0], lw=lw, markevery=[int(6 * val)], markeredgewidth=3, markerfacecolor='blue', marker='x', markeredgecolor='blue', markersize=ms) ax1.set_xlabel('time', fontsize=fonts, weight='bold') ax1.set_ylabel('L-infinity norm of error', fontsize=fonts, weight='bold') ax1.tick_params(axis='both', which='major', labelsize=fonts) # , weight='bold') ax1.legend(loc='upper right', prop={'size': fonts, 'weight': 'bold'}) plt.savefig("example_1_error.png", bbox_inches='tight') plt.show() # Parameters t_start = 0 t_stop = 2 x_start = 0 x_end = 1 nx0 = 2**10 + 1 a = 1 nt = 2**10 + 1 # number of time points iterations = 1 # Set up multigrid hierarchy heat0 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_start=t_start, t_stop=t_stop, nt=nt) heat1 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_interval=heat0.t[::4]) heat2 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_interval=heat1.t[::4]) heat3 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_interval=heat2.t[::4]) heat4 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_interval=heat3.t[::4]) problem = [heat0, heat1, heat2, heat3, heat4] # Plots mgrit_plots = MgritWithPlots(problem=problem, cf_iter=1, cycle_type='V', random_init_guess=True, nested_iteration=False) mgrit_plots.plot_parallel_distribution(time_procs=4, text_size=13) mgrit_plots.plot_cycle(iterations=2, text_size=13) mgrit_plots.solve() mgrit_plots.plot_convergence(text_size=14) # Start timings runtime = np.zeros(5) iters = np.zeros(5) # V-cycle, FCF-relaxation for i in range(iterations): mgrit_V_FCF = Mgrit(problem=problem, cf_iter=1, cycle_type='V', random_init_guess=True, nested_iteration=False) res = mgrit_V_FCF.solve() runtime[0] += res['time_setup'] + res['time_solve'] iters[0] += len(res['conv']) # # V-cycle, FCFCF-relaxation, BDF1 for i in range(iterations): mgrit_V_FCFCF = Mgrit(problem=problem, cf_iter=2, cycle_type='V', random_init_guess=True, nested_iteration=False) res = mgrit_V_FCFCF.solve() runtime[1] += res['time_setup'] + res['time_solve'] iters[1] += len(res['conv']) # F-cycle, F-relaxation for i in range(iterations): mgrit_F_F = Mgrit(problem=problem, cf_iter=0, cycle_type='F', random_init_guess=True, nested_iteration=False) res = mgrit_F_F.solve() runtime[2] += res['time_setup'] + res['time_solve'] iters[2] += len(res['conv']) # F-cycle, FCF-relaxation for i in range(iterations): mgrit_F_FCF = Mgrit(problem=problem, cf_iter=1, cycle_type='F', random_init_guess=True, nested_iteration=False) res = mgrit_F_FCF.solve() runtime[3] += res['time_setup'] + res['time_solve'] iters[3] += len(res['conv']) # F-cycle, FCFCF-relaxation for i in range(iterations): mgrit_F_FCFCF = Mgrit(problem=problem, cf_iter=2, cycle_type='F', random_init_guess=True, nested_iteration=False) res = mgrit_F_FCFCF.solve() runtime[4] += res['time_setup'] + res['time_solve'] iters[4] += len(res['conv']) # Save and print results if MPI.COMM_WORLD.Get_rank() == 0: save_runtime = runtime / iterations save_iters = iters / iterations print('V-cycle with FCF-relaxation:', save_iters[0], save_runtime[0]) print('V-cycle with FCFCF-relaxation:', save_iters[1], save_runtime[1]) print('F-cycle with F-relaxation:', save_iters[2], save_runtime[2]) print('F-cycle with FCF-relaxation:', save_iters[3], save_runtime[3]) print('F-cycle with FCFCF-relaxation:', save_iters[4], save_runtime[4]) print(save_iters) if MPI.COMM_WORLD.Get_size() == 1: ts = [heat0.vector_t_start.clone()] for i in range(1, len(heat0.t)): ts.append( heat0.step(u_start=ts[-1], t_start=heat0.t[i - 1], t_stop=heat0.t[i])) plot_error(mgrit=[ mgrit_V_FCF, mgrit_V_FCFCF, mgrit_F_F, mgrit_F_FCF, mgrit_F_FCFCF ], ts=ts)
def main(): def rhs(x, t): """ Right-hand side of 1D heat equation example problem at a given space-time point (x,t), -sin(pi*x)(sin(t) - a*pi^2*cos(t)), a = 1 Note: exact solution is np.sin(np.pi * x) * np.cos(t) :param x: spatial grid point :param t: time point :return: right-hand side of 1D heat equation example problem at point (x,t) """ return -np.sin(np.pi * x) * (np.sin(t) - 1 * np.pi**2 * np.cos(t)) def init_cond(x): """ Initial condition of 1D heat equation example, u(x,0) = sin(pi*x) :param x: spatial grid point :return: initial condition of 1D heat equation example problem """ return np.sin(np.pi * x) heat0 = Heat1D(x_start=0, x_end=1, nx=1001, a=1, init_cond=init_cond, rhs=rhs, t_start=0, t_stop=2, nt=65) heat1 = Heat1D(x_start=0, x_end=1, nx=1001, a=1, init_cond=init_cond, rhs=rhs, t_start=0, t_stop=2, nt=33) heat2 = Heat1D(x_start=0, x_end=1, nx=1001, a=1, init_cond=init_cond, rhs=rhs, t_start=0, t_stop=2, nt=17) heat3 = Heat1D(x_start=0, x_end=1, nx=1001, a=1, init_cond=init_cond, rhs=rhs, t_start=0, t_stop=2, nt=9) heat4 = Heat1D(x_start=0, x_end=1, nx=1001, a=1, init_cond=init_cond, rhs=rhs, t_start=0, t_stop=2, nt=5) # Setup five-level MGRIT solver and solve the problem problem = [heat0, heat1, heat2, heat3, heat4] # Unitary C-relaxation weight mgrit = Mgrit(problem=problem, tol=1e-8, cf_iter=1, cycle_type='F', nested_iteration=False, max_iter=10, logging_lvl=20, random_init_guess=False) info = mgrit.solve() # Non-unitary C-relaxation weight mgrit2 = Mgrit(problem=problem, weight_c=1.3, tol=1e-8, cf_iter=1, cycle_type='F', nested_iteration=False, max_iter=10, logging_lvl=20, random_init_guess=False) info = mgrit2.solve()
def main(): def rhs(x, t): """ Right-hand side of 1D heat equation example problem at a given space-time point (x,t), -sin(pi*x)(sin(t) - a*pi^2*cos(t)), a = 1 Note: exact solution is np.sin(np.pi * x) * np.cos(t) :param x: spatial grid point :param t: time point :return: right-hand side of 1D heat equation example problem at point (x,t) """ return -np.sin(np.pi * x) * (np.sin(t) - 1 * np.pi**2 * np.cos(t)) def init_cond(x): """ Initial condition of 1D heat equation example, u(x,0) = sin(pi*x) :param x: spatial grid point :return: initial condition of 1D heat equation example problem """ return np.sin(np.pi * x) # Construct a four-level multigrid hierarchy for the 1d heat example # * use a coarsening factor of 2 in time on all levels # * apply spatial coarsening by a factor of 2 on the first two levels heat0 = Heat1D(x_start=0, x_end=2, nx=2**4 + 1, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=2**7 + 1) heat1 = Heat1D(x_start=0, x_end=2, nx=2**3 + 1, a=1, rhs=rhs, init_cond=init_cond, t_interval=heat0.t[::2]) heat2 = Heat1D(x_start=0, x_end=2, nx=2**2 + 1, a=1, rhs=rhs, init_cond=init_cond, t_interval=heat1.t[::2]) heat3 = Heat1D(x_start=0, x_end=2, nx=2**2 + 1, a=1, rhs=rhs, init_cond=init_cond, t_interval=heat2.t[::2]) problem = [heat0, heat1, heat2, heat3] # Specify a list of grid transfer operators of length (#levels - 1) for the transfer between two consecutive levels # * Use the new class GridTransferHeat to apply spatial coarsening for transfers between the first three levels # * Use PyMGRIT's core class GridTransferCopy for the transfer between the last two levels (no spatial coarsening) transfer = [GridTransferHeat(), GridTransferHeat(), GridTransferCopy()] # Setup four-level MGRIT solver and solve the problem mgrit = Mgrit(problem=problem, transfer=transfer) info = mgrit.solve()
def main(): def output_fcn(self): # Set path to solution path = 'results/heat_equation_2d' # Create path if not existing pathlib.Path(path).mkdir(parents=True, exist_ok=True) # Save solution with corresponding time point to file np.save(path + '/heat_equation_2d-rank' + str(self.comm_time_rank), [[[self.t[0][i], self.u[0][i]] for i in self.index_local[0]]]) # example problem parameters x_end = 0.75 y_end = 1.5 a = 3.5 def rhs(x, y, t): """ Right-hand side of 2D heat equation example problem at a given space-time point (x,y,t), 5x(x_end - x)y(y_end - y) + 10at(y(y_end-y)) + x(x_end - x), a = 3.5 :param x: x-coordinate of spatial grid point :param y: y_coordinate of spatial grid point :param t: time point :return: right-hand side of 2D heat equation example problem at point (x,y,t) """ return 5 * x * (x_end - x) * y * (y_end - y) + 10 * a * t * (y * (y_end - y) + x * (x_end - x)) def exact_sol(x, y, t): """ Exact solution of 2D heat equation example problem at a given space-time point (x,y,t) Note: Can be used for computing the error of the MGRIT approximation :param x: x_coordinate of spatial grid point :param y: y_coordinate of spatial grid point :param t: time point :return: exact solution of 2D heat equation example problem at point (x,y,t) """ return 5 * t * x * (x_end - x) * y * (y_end - y) heat0 = Heat2D(x_start=0, x_end=x_end, y_start=0, y_end=y_end, nx=55, ny=125, a=a, rhs=rhs, t_start=0, t_stop=1, nt=33) heat1 = Heat2D(x_start=0, x_end=x_end, y_start=0, y_end=y_end, nx=55, ny=125, a=a, rhs=rhs, t_interval=heat0.t[::2]) # Setup two-level MGRIT solver and solve the problem mgrit = Mgrit(problem=[heat0, heat1], cycle_type='V', output_fcn=output_fcn) info = mgrit.solve() if MPI.COMM_WORLD.Get_rank() == 0: time.sleep(2) sol = [] path = 'results/heat_equation_2d/' for filename in os.listdir(path): data = np.load(path + filename, allow_pickle=True).tolist()[0] sol += data sol.sort(key=lambda tup: tup[0]) diff = 0 for i in range(len(sol)): u_e = exact_sol(x=heat0.x_2d, y=heat0.y_2d, t=heat0.t[i]) diff += abs(sol[i][1].get_values() - u_e).max() print("Difference between MGRIT solution and exact solution:", diff)
def main(): def rhs(x, t): """ Right-hand side of 1D heat equation example problem at a given space-time point (x,t), -sin(pi*x)(sin(t) - a*pi^2*cos(t)), a = 1 :param x: spatial grid point :param t: time point :return: right-hand side of 1D heat equation example problem at point (x,t) """ return -np.sin(np.pi * x) * (np.sin(t) - 1 * np.pi**2 * np.cos(t)) def init_cond(x): """ Initial condition of 1D heat equation example, u(x,0) = sin(pi*x) :param x: spatial grid point :return: initial condition of 1D heat equation example problem """ return np.sin(np.pi * x) def exact_sol(x, t): """ Exact solution of 1D heat equation example problem at a given space-time point (x,t) Note: Can be used for computing the error of the MGRIT approximation :param x: spatial grid point :param t: time point :return: exact solution of 1D heat equation example problem at point (x,t) """ return np.sin(np.pi * x) * np.cos(t) # Time interval t_start = 0 t_stop = 2 nt = 512 # number of time points excluding t_start dtau = t_stop / nt # time-step size # Time points are grouped in pairs of two consecutive time points # => (nt/2) + 1 pairs # Note: * Each pair is associated with the time value of its first point. # * The second value of the last pair (associated with t_stop) is not used. # * The spacing within each pair is the same (= dt) on all grid levels. t_interval = np.linspace(t_start, t_stop, int(nt / 2 + 1)) heat0 = Heat1DBDF2(x_start=0, x_end=1, nx=1001, a=1, dtau=dtau, rhs=rhs, init_cond=init_cond, t_interval=t_interval) heat1 = Heat1DBDF1(x_start=0, x_end=1, nx=1001, a=1, dtau=dtau, rhs=rhs, init_cond=init_cond, t_interval=heat0.t[::2]) heat2 = Heat1DBDF1(x_start=0, x_end=1, nx=1001, a=1, dtau=dtau, rhs=rhs, init_cond=init_cond, t_interval=heat1.t[::2]) # Setup three-level MGRIT solver and solve the problem problem = [heat0, heat1, heat2] mgrit = Mgrit(problem=problem) info = mgrit.solve()
def main(): def rhs(x, t): """ Right-hand side of 1D heat equation example problem at a given space-time point (x,t), -sin(pi*x)(sin(t) - a*pi^2*cos(t)), a = 1 Note: exact solution is np.sin(np.pi * x) * np.cos(t) :param x: spatial grid point :param t: time point :return: right-hand side of 1D heat equation example problem at point (x,t) """ return -np.sin(np.pi * x) * (np.sin(t) - 1 * np.pi**2 * np.cos(t)) def init_cond(x): """ Initial condition of 1D heat equation example, u(x,0) = sin(pi*x) :param x: spatial grid point :return: initial condition of 1D heat equation example problem """ return np.sin(np.pi * x) # Parameters t_start = 0 t_stop = 2 x_start = 0 x_end = 1 nx0 = 2**10 + 1 a = 1 nt = 2**10 + 1 # number of time points iterations = 1 # Set up multigrid hierarchy heat0 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_start=t_start, t_stop=t_stop, nt=nt) heat1 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_interval=heat0.t[::4]) heat2 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_interval=heat1.t[::4]) heat3 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_interval=heat2.t[::4]) heat4 = Heat1D(x_start=x_start, x_end=x_end, nx=nx0, a=a, init_cond=init_cond, rhs=rhs, t_interval=heat3.t[::4]) problem = [heat0, heat1, heat2, heat3, heat4] # Plots mgrit_plots = MgritWithPlots(problem=problem, cf_iter=1, cycle_type='V', random_init_guess=True, nested_iteration=False) mgrit_plots.plot_parallel_distribution(time_procs=4, text_size=13) mgrit_plots.plot_cycle(iterations=2, text_size=13) mgrit_plots.solve() mgrit_plots.plot_convergence(text_size=14) # Start timings problem = [heat0, heat1, heat2, heat3, heat4] runtime = np.zeros(6) iters = np.zeros(6) # V-cycle, FCF-relaxation for i in range(iterations): mgrit = Mgrit(problem=problem, cf_iter=1, cycle_type='V', random_init_guess=True, nested_iteration=False).solve() runtime[1] += mgrit['time_setup'] + mgrit['time_solve'] iters[1] += len(mgrit['conv']) # # V-cycle, FCFCF-relaxation, BDF1 for i in range(iterations): mgrit = Mgrit(problem=problem, cf_iter=2, cycle_type='V', random_init_guess=True, nested_iteration=False).solve() runtime[2] += mgrit['time_setup'] + mgrit['time_solve'] iters[2] += len(mgrit['conv']) # F-cycle, F-relaxation for i in range(iterations): mgrit = Mgrit(problem=problem, cf_iter=0, cycle_type='F', random_init_guess=True, nested_iteration=False).solve() runtime[3] += mgrit['time_setup'] + mgrit['time_solve'] iters[3] += len(mgrit['conv']) # F-cycle, FCF-relaxation for i in range(iterations): mgrit = Mgrit(problem=problem, cf_iter=1, cycle_type='F', random_init_guess=True, nested_iteration=False).solve() runtime[4] += mgrit['time_setup'] + mgrit['time_solve'] iters[4] += len(mgrit['conv']) # F-cycle, FCFCF-relaxation for i in range(iterations): mgrit = Mgrit(problem=problem, cf_iter=2, cycle_type='F', random_init_guess=True, nested_iteration=False).solve() runtime[5] += mgrit['time_setup'] + mgrit['time_solve'] iters[5] += len(mgrit['conv']) #Save and print results save_runtime = runtime / iterations save_iters = iters / iterations print('V-cycle with FCF-relaxation:', save_iters[1], save_runtime[1]) print('V-cycle with FCFCF-relaxation:', save_iters[2], save_runtime[2]) print('F-cycle with F-relaxation:', save_iters[3], save_runtime[3]) print('F-cycle with FCF-relaxation:', save_iters[4], save_runtime[4]) print('F-cycle with FCFCF-relaxation:', save_iters[5], save_runtime[5]) print(save_iters)
def test_setup_points_and_comm_info(): """ Test for the function setup_points_and_comm_info """ heat0 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=65) heat1 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=17) heat2 = Heat1D(x_start=0, x_end=2, nx=5, a=1, rhs=rhs, init_cond=init_cond, t_start=0, t_stop=2, nt=5) problem = [heat0, heat1, heat2] mgrit = Mgrit(problem=problem, cf_iter=1, nested_iteration=True, max_iter=2) size = 7 cpts = [] comm_front = [] comm_back = [] block_size_this_lvl = [] index_local = [] index_local_c = [] index_local_f = [] first_is_c_point = [] first_is_f_point = [] last_is_c_point = [] last_is_f_point = [] send_to = [] get_from = [] for i in range(size): mgrit.comm_time_size = size mgrit.comm_time_rank = i mgrit.int_start = 0 # First time points of process interval mgrit.int_stop = 0 # Last time points of process interval mgrit.cpts = [ ] # C-points per process and level corresponding to complete time interval mgrit.comm_front = [] # Communication inside F-relax per MGRIT level mgrit.comm_back = [] # Communication inside F-relax per MGRIT level mgrit.block_size_this_lvl = [ ] # Block size per process and level with ghost point mgrit.index_local_c = [] # Local indices of C-Points mgrit.index_local_f = [] # Local indices of F-Points mgrit.index_local = [] # Local indices of all points mgrit.first_is_f_point = [] # Communication after C-relax mgrit.first_is_c_point = [] # Communication after F-relax mgrit.last_is_f_point = [] # Communication after F-relax mgrit.last_is_c_point = [] # Communication after C-relax mgrit.send_to = [] mgrit.get_from = [] for lvl in range(mgrit.lvl_max): mgrit.t.append(np.copy(mgrit.problem[lvl].t)) mgrit.setup_points_and_comm_info(lvl=lvl) cpts.append(mgrit.cpts) comm_front.append(mgrit.comm_front) comm_back.append(mgrit.comm_back) block_size_this_lvl.append(mgrit.block_size_this_lvl) index_local.append(mgrit.index_local) index_local_c.append(mgrit.index_local_c) index_local_f.append(mgrit.index_local_f) first_is_c_point.append(mgrit.first_is_c_point) first_is_f_point.append(mgrit.first_is_f_point) last_is_c_point.append(mgrit.last_is_c_point) last_is_f_point.append(mgrit.last_is_f_point) send_to.append(mgrit.send_to) get_from.append(mgrit.get_from) test_cpts = [[np.array([0, 4, 8]), np.array([0]), np.array([0])], [np.array([12, 16]), np.array([4]), np.array([1])], [ np.array([20, 24, 28]), np.array([], dtype=int), np.array([], dtype=int) ], [np.array([32, 36]), np.array([8]), np.array([2])], [ np.array([40, 44]), np.array([], dtype=int), np.array([], dtype=int) ], [np.array([48, 52]), np.array([12]), np.array([3])], [np.array([56, 60, 64]), np.array([16]), np.array([4])]] test_comm_front = [[False, False, False], [True, True, False], [False, False, False], [False, False, False], [True, True, False], [True, False, False], [False, True, False]] test_comm_back = [[True, True, False], [False, False, False], [False, False, False], [True, True, False], [True, False, False], [False, True, False], [False, False, False]] test_block_size_this_lvl = [[10, 3, 1], [11, 3, 2], [10, 4, 0], [10, 3, 2], [10, 3, 0], [10, 3, 2], [10, 4, 2]] test_index_local = [[ np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]), np.array([0, 1, 2]), np.array([0]) ], [ np.array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]), np.array([1, 2]), np.array([1]) ], [ np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]), np.array([1, 2, 3]), np.array([], dtype=int) ], [ np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]), np.array([1, 2]), np.array([1]) ], [ np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]), np.array([1, 2]), np.array([], dtype=int) ], [ np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]), np.array([1, 2]), np.array([1]) ], [ np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]), np.array([1, 2, 3]), np.array([1]) ]] test_index_local_f = [[ np.array([9, 5, 6, 7, 1, 2, 3]), np.array([1, 2]), np.array([], dtype=float) ], [ np.array([8, 9, 10, 4, 5, 6, 1, 2]), np.array([1]), np.array([], dtype=float) ], [ np.array([6, 7, 8, 2, 3, 4]), np.array([1, 2, 3]), np.array([], dtype=float) ], [ np.array([1, 2, 3, 9, 5, 6, 7]), np.array([2]), np.array([], dtype=float) ], [ np.array([8, 9, 4, 5, 6, 1, 2]), np.array([1, 2]), np.array([], dtype=float) ], [ np.array([7, 8, 9, 3, 4, 5, 1]), np.array([2]), np.array([], dtype=float) ], [ np.array([6, 7, 8, 2, 3, 4]), np.array([1, 2]), np.array([], dtype=float) ]] test_index_local_c = [[np.array([0, 4, 8]), np.array([0]), np.array([0])], [np.array([3, 7]), np.array([2]), np.array([1])], [ np.array([1, 5, 9]), np.array([], dtype=int), np.array([], dtype=int) ], [np.array([4, 8]), np.array([1]), np.array([1])], [ np.array([3, 7]), np.array([], dtype=int), np.array([], dtype=int) ], [np.array([2, 6]), np.array([1]), np.array([1])], [np.array([1, 5, 9]), np.array([3]), np.array([1])]] test_first_is_c_point = [[False, False, False], [False, False, False], [True, False, False], [False, True, False], [False, False, False], [False, True, False], [True, False, False]] test_first_is_f_point = [[False, False, False], [False, False, False], [False, True, False], [True, False, False], [False, False, False], [False, False, False], [False, False, False]] test_last_is_f_point = [[False, False, False], [True, False, False], [False, True, False], [False, False, False], [False, True, False], [True, False, False], [False, False, False]] test_last_is_c_point = [[False, False, False], [False, True, False], [True, False, False], [False, False, False], [False, False, False], [False, False, False], [False, False, False]] test_send_to = [[1, 1, 1], [2, 2, 3], [3, 3, -99], [4, 4, 5], [5, 5, -99], [6, 6, 6], [-99, -99, -99]] test_get_from = [[-99, -99, -99], [0, 0, 0], [1, 1, -99], [2, 2, 1], [3, 3, -99], [4, 4, 3], [5, 5, 5]] for i in range(size): assert all([ a == b for a, b in zip(first_is_c_point[i], test_first_is_c_point[i]) ]) assert all([ a == b for a, b in zip(first_is_f_point[i], test_first_is_f_point[i]) ]) assert all([ a == b for a, b in zip(last_is_f_point[i], test_last_is_f_point[i]) ]) assert all([ a == b for a, b in zip(last_is_c_point[i], test_last_is_c_point[i]) ]) assert all([a == b for a, b in zip(comm_front[i], test_comm_front[i])]) assert all([a == b for a, b in zip(comm_back[i], test_comm_back[i])]) assert all([ a == b for a, b in zip(block_size_this_lvl[i], test_block_size_this_lvl[i]) ]) assert all([a == b for a, b in zip(send_to[i], test_send_to[i])]) assert all([a == b for a, b in zip(get_from[i], test_get_from[i])]) [np.testing.assert_equal(a, b) for a, b in zip(cpts[i], test_cpts[i])] [ np.testing.assert_equal(a, b) for a, b in zip(index_local[i], test_index_local[i]) ] [ np.testing.assert_equal(a, b) for a, b in zip(index_local_c[i], test_index_local_c[i]) ] [ np.testing.assert_equal(a, b) for a, b in zip(index_local_f[i], test_index_local_f[i]) ]