Coverage for pySDC/projects/Resilience/advection.py: 69%

59 statements  

« prev     ^ index     » next       coverage.py v7.6.9, created at 2024-12-20 14:51 +0000

1# script to run a simple advection problem 

2 

3from pySDC.implementations.problem_classes.AdvectionEquation_ND_FD import advectionNd 

4from pySDC.implementations.sweeper_classes.generic_implicit import generic_implicit 

5from pySDC.helpers.stats_helper import get_sorted 

6from pySDC.projects.Resilience.hook import LogData, hook_collection 

7from pySDC.projects.Resilience.fault_injection import prepare_controller_for_faults 

8from pySDC.projects.Resilience.strategies import merge_descriptions 

9 

10 

11def plot_embedded(stats, ax): 

12 u = get_sorted(stats, type='u', recomputed=False) 

13 uold = get_sorted(stats, type='uold', recomputed=False) 

14 t = [me[0] for me in u] 

15 e_em = get_sorted(stats, type='error_embedded_estimate', recomputed=False) 

16 e_em_semi_glob = [abs(u[i][1] - uold[i][1]) for i in range(len(u))] 

17 ax.plot(t, e_em_semi_glob, label=r'$\|u^{\left(k-1\right)}-u^{\left(k\right)}\|$') 

18 ax.plot([me[0] for me in e_em], [me[1] for me in e_em], linestyle='--', label=r'$\epsilon$') 

19 ax.set_xlabel(r'$t$') 

20 ax.legend(frameon=False) 

21 

22 

23def run_advection( 

24 custom_description=None, 

25 num_procs=1, 

26 Tend=2e-1, 

27 hook_class=LogData, 

28 fault_stuff=None, 

29 custom_controller_params=None, 

30 use_MPI=False, 

31 **kwargs, 

32): 

33 """ 

34 Run an advection problem with default parameters. 

35 

36 Args: 

37 custom_description (dict): Overwrite presets 

38 num_procs (int): Number of steps for MSSDC 

39 Tend (float): Time to integrate to 

40 hook_class (pySDC.Hook): A hook to store data 

41 fault_stuff (dict): A dictionary with information on how to add faults 

42 custom_controller_params (dict): Overwrite presets 

43 use_MPI (bool): Whether or not to use MPI 

44 

45 Returns: 

46 dict: The stats object 

47 controller: The controller 

48 Tend: The time that was supposed to be integrated to 

49 """ 

50 # initialize level parameters 

51 level_params = {} 

52 level_params['dt'] = 0.05 

53 

54 # initialize sweeper parameters 

55 sweeper_params = {} 

56 sweeper_params['quad_type'] = 'RADAU-RIGHT' 

57 sweeper_params['num_nodes'] = 3 

58 sweeper_params['QI'] = 'IE' 

59 

60 problem_params = {'freq': 2, 'nvars': 2**9, 'c': 1.0, 'stencil_type': 'center', 'order': 4, 'bc': 'periodic'} 

61 

62 # initialize step parameters 

63 step_params = {} 

64 step_params['maxiter'] = 5 

65 

66 # initialize controller parameters 

67 controller_params = {} 

68 controller_params['logger_level'] = 30 

69 controller_params['hook_class'] = hook_collection + (hook_class if type(hook_class) == list else [hook_class]) 

70 controller_params['mssdc_jac'] = False 

71 

72 if custom_controller_params is not None: 

73 controller_params = {**controller_params, **custom_controller_params} 

74 

75 # fill description dictionary for easy step instantiation 

76 description = {} 

77 description['problem_class'] = advectionNd 

78 description['problem_params'] = problem_params 

79 description['sweeper_class'] = generic_implicit 

80 description['sweeper_params'] = sweeper_params 

81 description['level_params'] = level_params 

82 description['step_params'] = step_params 

83 

84 if custom_description is not None: 

85 description = merge_descriptions(description, custom_description) 

86 

87 # set time parameters 

88 t0 = 0.0 

89 

90 # instantiate controller 

91 if use_MPI: 

92 from mpi4py import MPI 

93 from pySDC.implementations.controller_classes.controller_MPI import controller_MPI 

94 

95 comm = kwargs.get('comm', MPI.COMM_WORLD) 

96 controller = controller_MPI(controller_params=controller_params, description=description, comm=comm) 

97 

98 # get initial values on finest level 

99 P = controller.S.levels[0].prob 

100 uinit = P.u_exact(t0) 

101 else: 

102 from pySDC.implementations.controller_classes.controller_nonMPI import controller_nonMPI 

103 

104 controller = controller_nonMPI( 

105 num_procs=num_procs, controller_params=controller_params, description=description 

106 ) 

107 

108 # get initial values on finest level 

109 P = controller.MS[0].levels[0].prob 

110 uinit = P.u_exact(t0) 

111 

112 # insert faults 

113 if fault_stuff is not None: 

114 rnd_args = { 

115 'iteration': 5, 

116 } 

117 args = { 

118 'time': 1e-1, 

119 'target': 0, 

120 } 

121 prepare_controller_for_faults(controller, fault_stuff, rnd_args, args) 

122 

123 # call main function to get things done... 

124 uend, stats = controller.run(u0=uinit, t0=t0, Tend=Tend) 

125 return stats, controller, Tend 

126 

127 

128if __name__ == '__main__': 

129 import matplotlib.pyplot as plt 

130 from pySDC.implementations.convergence_controller_classes.adaptivity import Adaptivity 

131 from pySDC.projects.Resilience.hook import LogUold 

132 

133 adaptivity_params = {} 

134 adaptivity_params['e_tol'] = 1e-8 

135 

136 convergence_controllers = {} 

137 convergence_controllers[Adaptivity] = adaptivity_params 

138 

139 description = {} 

140 description['convergence_controllers'] = convergence_controllers 

141 

142 fig, axs = plt.subplots(1, 2, figsize=(12, 4), sharex=True, sharey=True) 

143 plot_embedded(run_advection(description, 1, hook_class=LogUold)[0], axs[0]) 

144 plot_embedded(run_advection(description, 4, hook_class=LogUold)[0], axs[1]) 

145 axs[0].set_title('1 process') 

146 axs[1].set_title('4 processes') 

147 fig.tight_layout() 

148 plt.show()