Coverage for pySDC/projects/Resilience/paper_plots.py: 0%
29 statements
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
« prev ^ index » next coverage.py v7.6.9, created at 2024-12-20 14:51 +0000
1# script to make pretty plots for papers or talks
2import numpy as np
3import matplotlib as mpl
4import matplotlib.pyplot as plt
5from pySDC.projects.Resilience.fault_stats import (
6 FaultStats,
7 run_Lorenz,
8 run_Schroedinger,
9 run_vdp,
10 run_quench,
11 run_AC,
12 run_RBC,
13 RECOVERY_THRESH_ABS,
14)
15from pySDC.projects.Resilience.strategies import (
16 BaseStrategy,
17 AdaptivityStrategy,
18 IterateStrategy,
19 HotRodStrategy,
20 DIRKStrategy,
21 ERKStrategy,
22 AdaptivityPolynomialError,
23 cmap,
24)
25from pySDC.helpers.plot_helper import setup_mpl, figsize_by_journal
26from pySDC.helpers.stats_helper import get_sorted
29cm = 1 / 2.5
30TEXTWIDTH = 11.9446244611 * cm
31JOURNAL = 'Springer_Numerical_Algorithms'
32BASE_PATH = 'data/paper'
35def get_stats(problem, path='data/stats-jusuf', num_procs=1, strategy_type='SDC'):
36 """
37 Create a FaultStats object for a given problem to use for the plots.
38 Note that the statistics need to be already generated somewhere else, this function will only load them.
40 Args:
41 problem (function): A problem to run
42 path (str): Path to the associated stats for the problem
44 Returns:
45 FaultStats: Object to analyse resilience statistics from
46 """
47 if strategy_type == 'SDC':
48 strategies = [BaseStrategy(), AdaptivityStrategy(), IterateStrategy()]
49 if JOURNAL not in ['JSC_beamer']:
50 strategies += [HotRodStrategy(), AdaptivityPolynomialError()]
51 elif strategy_type == 'RK':
52 strategies = [DIRKStrategy()]
53 if problem.__name__ in ['run_Lorenz', 'run_vdp']:
54 strategies += [ERKStrategy()]
56 stats_analyser = FaultStats(
57 prob=problem,
58 strategies=strategies,
59 faults=[False, True],
60 reload=True,
61 recovery_thresh=1.1,
62 recovery_thresh_abs=RECOVERY_THRESH_ABS.get(problem, 0),
63 mode='default',
64 stats_path=path,
65 num_procs=num_procs,
66 )
67 stats_analyser.get_recovered()
68 return stats_analyser
71def my_setup_mpl(**kwargs):
72 setup_mpl(reset=True, font_size=8)
73 mpl.rcParams.update({'lines.markersize': 6})
76def savefig(fig, name, format='pdf', tight_layout=True): # pragma: no cover
77 """
78 Save a figure to some predefined location.
80 Args:
81 fig (Matplotlib.Figure): The figure of the plot
82 name (str): The name of the plot
83 tight_layout (bool): Apply tight layout or leave as is
84 Returns:
85 None
86 """
87 if tight_layout:
88 fig.tight_layout()
89 path = f'{BASE_PATH}/{name}.{format}'
90 fig.savefig(path, bbox_inches='tight', transparent=True, dpi=200)
91 print(f'saved "{path}"')
94def analyse_resilience(problem, path='data/stats', **kwargs): # pragma: no cover
95 """
96 Generate some stats for resilience / load them if already available and make some plots.
98 Args:
99 problem (function): A problem to run
100 path (str): Path to the associated stats for the problem
102 Returns:
103 None
104 """
106 stats_analyser = get_stats(problem, path)
107 stats_analyser.get_recovered()
109 strategy = IterateStrategy()
110 not_fixed = stats_analyser.get_mask(strategy=strategy, key='recovered', val=False)
111 not_overflow = stats_analyser.get_mask(strategy=strategy, key='bit', val=1, op='uneq', old_mask=not_fixed)
112 stats_analyser.print_faults(not_overflow)
114 compare_strategies(stats_analyser, **kwargs)
115 plot_recovery_rate(stats_analyser, **kwargs)
118def compare_strategies(stats_analyser, **kwargs): # pragma: no cover
119 """
120 Make a plot showing local error and iteration number of time for all strategies
122 Args:
123 stats_analyser (FaultStats): Fault stats object, which contains some stats
125 Returns:
126 None
127 """
128 my_setup_mpl()
129 fig, ax = plt.subplots(figsize=(TEXTWIDTH, 5 * cm))
130 stats_analyser.compare_strategies(ax=ax)
131 savefig(fig, 'compare_strategies', **kwargs)
134def plot_recovery_rate(stats_analyser, **kwargs): # pragma: no cover
135 """
136 Make a plot showing recovery rate for all faults and only for those that can be recovered.
138 Args:
139 stats_analyser (FaultStats): Fault stats object, which contains some stats
141 Returns:
142 None
143 """
144 my_setup_mpl()
145 fig, axs = plt.subplots(1, 2, figsize=(TEXTWIDTH, 5 * cm), sharex=True, sharey=True)
146 stats_analyser.plot_things_per_things(
147 'recovered',
148 'bit',
149 False,
150 op=stats_analyser.rec_rate,
151 args={'ylabel': 'recovery rate'},
152 plotting_args={'markevery': 5},
153 ax=axs[0],
154 )
155 plot_recovery_rate_recoverable_only(stats_analyser, fig, axs[1], ylabel='')
156 axs[0].get_legend().remove()
157 axs[0].set_title('All faults')
158 axs[1].set_title('Only recoverable faults')
159 axs[0].set_ylim((-0.05, 1.05))
160 savefig(fig, 'recovery_rate_compared', **kwargs)
163def plot_recovery_rate_recoverable_only(stats_analyser, fig, ax, **kwargs): # pragma: no cover
164 """
165 Plot the recovery rate considering only faults that can be recovered theoretically.
167 Args:
168 stats_analyser (FaultStats): Fault stats object, which contains some stats
169 fig (matplotlib.pyplot.figure): Figure in which to plot
170 ax (matplotlib.pyplot.axes): Somewhere to plot
172 Returns:
173 None
174 """
175 for i in range(len(stats_analyser.strategies)):
176 fixable = stats_analyser.get_fixable_faults_only(strategy=stats_analyser.strategies[i])
178 stats_analyser.plot_things_per_things(
179 'recovered',
180 'bit',
181 False,
182 op=stats_analyser.rec_rate,
183 mask=fixable,
184 args={**kwargs},
185 ax=ax,
186 fig=fig,
187 strategies=[stats_analyser.strategies[i]],
188 plotting_args={'markevery': 5},
189 )
192def compare_recovery_rate_problems(target='resilience', **kwargs): # pragma: no cover
193 """
194 Compare the recovery rate for various problems.
195 Only faults that can be recovered are shown.
197 Returns:
198 None
199 """
200 if target == 'resilience':
201 problems = [run_Lorenz, run_Schroedinger, run_AC, run_RBC]
202 titles = ['Lorenz', r'Schr\"odinger', 'Allen-Cahn', 'Rayleigh-Benard']
203 elif target == 'thesis':
204 problems = [run_vdp, run_Lorenz, run_AC, run_RBC] # TODO: swap in Gray-Scott
205 titles = ['Van der Pol', 'Lorenz', 'Allen-Cahn', 'Rayleigh-Benard']
206 else:
207 raise NotImplementedError()
209 stats = [get_stats(problem, **kwargs) for problem in problems]
211 my_setup_mpl()
212 fig, axs = plt.subplots(2, 2, figsize=figsize_by_journal(JOURNAL, 1, 0.8), sharey=True)
213 [
214 plot_recovery_rate_recoverable_only(stats[i], fig, axs.flatten()[i], ylabel='', title=titles[i])
215 for i in range(len(stats))
216 ]
218 for ax in axs.flatten():
219 ax.get_legend().remove()
221 if kwargs.get('strategy_type', 'SDC') == 'SDC':
222 axs[1, 1].legend(frameon=False, loc="lower right")
223 else:
224 axs[0, 1].legend(frameon=False, loc="lower right")
225 axs[0, 0].set_ylim((-0.05, 1.05))
226 axs[1, 0].set_ylabel('recovery rate')
227 axs[0, 0].set_ylabel('recovery rate')
229 name = ''
230 for key, val in kwargs.items():
231 name = f'{name}_{key}-{val}'
233 savefig(fig, f'compare_equations{name}.pdf')
236def plot_adaptivity_stuff(): # pragma: no cover
237 """
238 Plot the solution for a van der Pol problem as well as the local error and cost associated with the base scheme and
239 adaptivity in k and dt in order to demonstrate that adaptivity is useful.
241 Returns:
242 None
243 """
244 from pySDC.implementations.hooks.log_errors import LogLocalErrorPostStep
245 from pySDC.implementations.hooks.log_work import LogWork
246 from pySDC.projects.Resilience.hook import LogData
247 import pickle
249 my_setup_mpl()
250 scale = 0.5 if JOURNAL == 'JSC_beamer' else 1.0
251 fig, axs = plt.subplots(3, 1, figsize=figsize_by_journal(JOURNAL, scale, 1), sharex=True, sharey=False)
253 def plot_error(stats, ax, iter_ax, strategy, **kwargs):
254 """
255 Plot global error and cumulative sum of iterations
257 Args:
258 stats (dict): Stats from pySDC run
259 ax (Matplotlib.pyplot.axes): Somewhere to plot the error
260 iter_ax (Matplotlib.pyplot.axes): Somewhere to plot the iterations
261 strategy (pySDC.projects.Resilience.fault_stats.Strategy): The resilience strategy
263 Returns:
264 None
265 """
266 markevery = 1 if type(strategy) in [AdaptivityStrategy, AdaptivityPolynomialError] else 10000
267 e = stats['e_local_post_step']
268 ax.plot([me[0] for me in e], [me[1] for me in e], markevery=markevery, **strategy.style, **kwargs)
269 k = stats['work_newton']
270 iter_ax.plot(
271 [me[0] for me in k], np.cumsum([me[1] for me in k]), **strategy.style, markevery=markevery, **kwargs
272 )
273 ax.set_yscale('log')
274 ax.set_ylabel('local error')
275 iter_ax.set_ylabel(r'Newton iterations')
277 run = False
278 for strategy in [BaseStrategy, IterateStrategy, AdaptivityStrategy, AdaptivityPolynomialError]:
279 S = strategy(newton_inexactness=False)
280 desc = S.get_custom_description(problem=run_vdp, num_procs=1)
281 desc['problem_params']['mu'] = 1000
282 desc['problem_params']['u0'] = (1.1, 0)
283 if strategy in [AdaptivityStrategy, BaseStrategy]:
284 desc['step_params']['maxiter'] = 5
285 if strategy in [BaseStrategy, IterateStrategy]:
286 desc['level_params']['dt'] = 1e-4
287 desc['sweeper_params']['QI'] = 'LU'
288 if strategy in [IterateStrategy]:
289 desc['step_params']['maxiter'] = 99
290 desc['level_params']['restol'] = 1e-10
292 path = f'./data/adaptivity_paper_plot_data_{strategy.__name__}.pickle'
293 if run:
294 stats, _, _ = run_vdp(
295 custom_description=desc,
296 Tend=20,
297 hook_class=[LogLocalErrorPostStep, LogWork, LogData],
298 custom_controller_params={'logger_level': 15},
299 )
301 data = {
302 'u': get_sorted(stats, type='u', recomputed=False),
303 'e_local_post_step': get_sorted(stats, type='e_local_post_step', recomputed=False),
304 'work_newton': get_sorted(stats, type='work_newton', recomputed=None),
305 }
306 with open(path, 'wb') as file:
307 pickle.dump(data, file)
308 else:
309 with open(path, 'rb') as file:
310 data = pickle.load(file)
312 plot_error(data, axs[1], axs[2], strategy())
314 if strategy == BaseStrategy or True:
315 u = data['u']
316 axs[0].plot([me[0] for me in u], [me[1][0] for me in u], color='black', label=r'$u$')
318 axs[2].set_xlabel(r'$t$')
319 axs[0].set_ylabel('solution')
320 axs[2].legend(frameon=JOURNAL == 'JSC_beamer')
321 axs[1].legend(frameon=True)
322 axs[2].set_yscale('log')
323 savefig(fig, 'adaptivity')
326def plot_fault_vdp(bit=0): # pragma: no cover
327 """
328 Make a plot showing the impact of a fault on van der Pol without any resilience.
329 The faults are inserted in the last iteration in the last node in u_t such that you can best see the impact.
331 Args:
332 bit (int): The bit that you want to flip
334 Returns:
335 None
336 """
337 from pySDC.projects.Resilience.fault_stats import (
338 FaultStats,
339 BaseStrategy,
340 )
341 from pySDC.projects.Resilience.hook import LogData
343 stats_analyser = FaultStats(
344 prob=run_vdp,
345 strategies=[BaseStrategy()],
346 faults=[False, True],
347 reload=True,
348 recovery_thresh=1.1,
349 num_procs=1,
350 mode='combination',
351 )
353 my_setup_mpl()
354 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 0.8, 0.5))
355 colors = ['blue', 'red', 'magenta']
356 ls = ['--', '-']
357 markers = ['*', '^']
358 do_faults = [False, True]
359 superscripts = ['*', '']
360 subscripts = ['', 't', '']
362 run = 779 + 12 * bit # for faults in u_t
363 # run = 11 + 12 * bit # for faults in u
365 for i in range(len(do_faults)):
366 stats, controller, Tend = stats_analyser.single_run(
367 strategy=BaseStrategy(),
368 run=run,
369 faults=do_faults[i],
370 hook_class=[LogData],
371 )
372 u = get_sorted(stats, type='u')
373 faults = get_sorted(stats, type='bitflip')
374 for j in [0, 1]:
375 ax.plot(
376 [me[0] for me in u],
377 [me[1][j] for me in u],
378 ls=ls[i],
379 color=colors[j],
380 label=rf'$u^{ {superscripts[i]}} _{ {subscripts[j]}} $',
381 marker=markers[j],
382 markevery=60,
383 )
384 for idx in range(len(faults)):
385 ax.axvline(faults[idx][0], color='black', label='Fault', ls=':')
386 print(
387 f'Fault at t={faults[idx][0]:.2e}, iter={faults[idx][1][1]}, node={faults[idx][1][2]}, space={faults[idx][1][3]}, bit={faults[idx][1][4]}'
388 )
389 ax.set_title(f'Fault in bit {faults[idx][1][4]}')
391 ax.legend(frameon=True, loc='lower left')
392 ax.set_xlabel(r'$t$')
393 savefig(fig, f'fault_bit_{bit}')
396def plot_fault_Lorenz(bit=0): # pragma: no cover
397 """
398 Make a plot showing the impact of a fault on the Lorenz attractor without any resilience.
399 The faults are inserted in the last iteration in the last node in x such that you can best see the impact.
401 Args:
402 bit (int): The bit that you want to flip
404 Returns:
405 None
406 """
407 from pySDC.projects.Resilience.fault_stats import (
408 FaultStats,
409 BaseStrategy,
410 )
411 from pySDC.projects.Resilience.hook import LogData
413 stats_analyser = FaultStats(
414 prob=run_Lorenz,
415 strategies=[BaseStrategy()],
416 faults=[False, True],
417 reload=True,
418 recovery_thresh=1.1,
419 num_procs=1,
420 mode='combination',
421 )
423 strategy = BaseStrategy()
425 my_setup_mpl()
426 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 0.8, 0.5))
427 colors = ['grey', strategy.color, 'magenta']
428 ls = ['--', '-']
429 markers = [None, strategy.marker]
430 do_faults = [False, True]
431 superscripts = ['*', '']
432 labels = ['x', 'x']
434 run = 19 + 20 * bit
436 for i in range(len(do_faults)):
437 stats, controller, Tend = stats_analyser.single_run(
438 strategy=BaseStrategy(),
439 run=run,
440 faults=do_faults[i],
441 hook_class=[LogData],
442 )
443 u = get_sorted(stats, type='u')
444 faults = get_sorted(stats, type='bitflip')
445 ax.plot(
446 [me[0] for me in u],
447 [me[1][0] for me in u],
448 ls=ls[i],
449 color=colors[i],
450 label=rf'${ {labels[i]}} ^{ {superscripts[i]}} $',
451 marker=markers[i],
452 markevery=500,
453 )
454 for idx in range(len(faults)):
455 ax.axvline(faults[idx][0], color='black', label='Fault', ls=':')
456 print(
457 f'Fault at t={faults[idx][0]:.2e}, iter={faults[idx][1][1]}, node={faults[idx][1][2]}, space={faults[idx][1][3]}, bit={faults[idx][1][4]}'
458 )
459 ax.set_title(f'Fault in bit {faults[idx][1][4]}')
461 ax.legend(frameon=True, loc='lower left')
462 ax.set_xlabel(r'$t$')
463 savefig(fig, f'fault_bit_{bit}')
466def plot_Lorenz_solution(): # pragma: no cover
467 my_setup_mpl()
469 fig, axs = plt.subplots(1, 2, figsize=figsize_by_journal(JOURNAL, 1, 0.4), sharex=True)
471 strategy = BaseStrategy()
472 desc = strategy.get_custom_description(run_Lorenz, num_procs=1)
473 stats, controller, _ = run_Lorenz(custom_description=desc, Tend=strategy.get_Tend(run_Lorenz))
475 u = get_sorted(stats, recomputed=False, type='u')
477 axs[0].plot([me[1][0] for me in u], [me[1][2] for me in u])
478 axs[0].set_ylabel('$z$')
479 axs[0].set_xlabel('$x$')
481 axs[1].plot([me[1][0] for me in u], [me[1][1] for me in u])
482 axs[1].set_ylabel('$y$')
483 axs[1].set_xlabel('$x$')
485 for ax in axs:
486 ax.set_box_aspect(1.0)
488 path = 'data/paper/Lorenz_sol.pdf'
489 fig.savefig(path, bbox_inches='tight', transparent=True, dpi=200)
492def plot_quench_solution(): # pragma: no cover
493 """
494 Plot the solution of Quench problem over time
496 Returns:
497 None
498 """
499 my_setup_mpl()
500 if JOURNAL == 'JSC_beamer':
501 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 0.5, 0.9))
502 else:
503 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 1.0, 0.45))
505 strategy = BaseStrategy()
507 custom_description = strategy.get_custom_description(run_quench, num_procs=1)
509 stats, controller, _ = run_quench(custom_description=custom_description, Tend=strategy.get_Tend(run_quench))
511 prob = controller.MS[0].levels[0].prob
513 u = get_sorted(stats, type='u', recomputed=False)
515 ax.plot([me[0] for me in u], [max(me[1]) for me in u], color='black', label='$T$')
516 ax.axhline(prob.u_thresh, label=r'$T_\mathrm{thresh}$', ls='--', color='grey', zorder=-1)
517 ax.axhline(prob.u_max, label=r'$T_\mathrm{max}$', ls=':', color='grey', zorder=-1)
519 ax.set_xlabel(r'$t$')
520 ax.legend(frameon=False)
521 savefig(fig, 'quench_sol')
524def plot_RBC_solution(): # pragma: no cover
525 """
526 Plot solution of Rayleigh-Benard convection
527 """
528 my_setup_mpl()
530 from mpl_toolkits.axes_grid1 import make_axes_locatable
532 plt.rcParams['figure.constrained_layout.use'] = True
533 fig, axs = plt.subplots(2, 1, sharex=True, sharey=True, figsize=figsize_by_journal(JOURNAL, 1.0, 0.45))
534 caxs = []
535 divider = make_axes_locatable(axs[0])
536 caxs += [divider.append_axes('right', size='3%', pad=0.03)]
537 divider2 = make_axes_locatable(axs[1])
538 caxs += [divider2.append_axes('right', size='3%', pad=0.03)]
540 from pySDC.projects.Resilience.RBC import RayleighBenard, PROBLEM_PARAMS
542 prob = RayleighBenard(**PROBLEM_PARAMS)
544 def _plot(t, ax, cax):
545 u_hat = prob.u_exact(t)
546 u = prob.itransform(u_hat)
547 im = ax.pcolormesh(prob.X, prob.Z, u[prob.index('T')], rasterized=True, cmap='plasma')
548 fig.colorbar(im, cax, label=f'$T(t={ {t}} )$')
550 _plot(0, axs[0], caxs[0])
551 _plot(21, axs[1], caxs[1])
553 axs[1].set_xlabel('$x$')
554 axs[0].set_ylabel('$z$')
555 axs[1].set_ylabel('$z$')
557 savefig(fig, 'RBC_sol', tight_layout=False)
560def plot_Schroedinger_solution(): # pragma: no cover
561 from pySDC.implementations.problem_classes.NonlinearSchroedinger_MPIFFT import nonlinearschroedinger_imex
563 my_setup_mpl()
564 if JOURNAL == 'JSC_beamer':
565 raise NotImplementedError
566 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 0.5, 0.9))
567 else:
568 fig, axs = plt.subplots(1, 2, figsize=figsize_by_journal(JOURNAL, 1.0, 0.45), sharex=True, sharey=True)
570 from mpl_toolkits.axes_grid1 import make_axes_locatable
572 plt.rcParams['figure.constrained_layout.use'] = True
573 cax = []
574 divider = make_axes_locatable(axs[0])
575 cax += [divider.append_axes('right', size='5%', pad=0.05)]
576 divider2 = make_axes_locatable(axs[1])
577 cax += [divider2.append_axes('right', size='5%', pad=0.05)]
579 problem_params = dict()
580 problem_params['nvars'] = (256, 256)
581 problem_params['spectral'] = False
582 problem_params['c'] = 1.0
583 description = {'problem_params': problem_params}
584 stats, _, _ = run_Schroedinger(Tend=1.0e0, custom_description=description)
586 P = nonlinearschroedinger_imex(**problem_params)
587 u = get_sorted(stats, type='u')
589 im = axs[0].pcolormesh(*P.X, np.abs(u[0][1]), rasterized=True)
590 im1 = axs[1].pcolormesh(*P.X, np.abs(u[-1][1]), rasterized=True)
592 fig.colorbar(im, cax=cax[0])
593 fig.colorbar(im1, cax=cax[1])
594 axs[0].set_title(r'$\|u(t=0)\|$')
595 axs[1].set_title(r'$\|u(t=1)\|$')
596 for ax in axs:
597 ax.set_aspect(1)
598 ax.set_xlabel('$x$')
599 ax.set_ylabel('$y$')
600 savefig(fig, 'Schroedinger_sol')
603def plot_AC_solution(): # pragma: no cover
604 from pySDC.projects.Resilience.AC import monitor
606 my_setup_mpl()
607 if JOURNAL == 'JSC_beamer':
608 raise NotImplementedError
609 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 0.5, 0.9))
610 else:
611 fig, axs = plt.subplots(1, 2, figsize=figsize_by_journal(JOURNAL, 1.0, 0.45))
613 description = {'problem_params': {'nvars': (256, 256)}}
614 stats, _, _ = run_AC(Tend=0.032, hook_class=monitor, custom_description=description)
616 u = get_sorted(stats, type='u')
618 computed_radius = get_sorted(stats, type='computed_radius')
619 axs[1].plot([me[0] for me in computed_radius], [me[1] for me in computed_radius], ls='-')
620 axs[1].axvline(0.025, ls=':', label=r'$t=0.025$', color='grey')
621 axs[1].set_title('Radius over time')
622 axs[1].set_xlabel('$t$')
623 axs[1].legend(frameon=False)
625 im = axs[0].imshow(u[0][1], extent=(-0.5, 0.5, -0.5, 0.5))
626 fig.colorbar(im)
627 axs[0].set_title(r'$u_0$')
628 axs[0].set_xlabel('$x$')
629 axs[0].set_ylabel('$y$')
630 savefig(fig, 'AC_sol')
633def plot_vdp_solution(): # pragma: no cover
634 """
635 Plot the solution of van der Pol problem over time to illustrate the varying time scales.
637 Returns:
638 None
639 """
640 from pySDC.implementations.convergence_controller_classes.adaptivity import Adaptivity
642 my_setup_mpl()
643 if JOURNAL == 'JSC_beamer':
644 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 0.5, 0.9))
645 else:
646 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 1.0, 0.33))
648 custom_description = {
649 'convergence_controllers': {Adaptivity: {'e_tol': 1e-7, 'dt_max': 1e0}},
650 'problem_params': {'mu': 1000, 'crash_at_maxiter': False},
651 'level_params': {'dt': 1e-3},
652 }
654 stats, _, _ = run_vdp(custom_description=custom_description, Tend=2000)
656 u = get_sorted(stats, type='u', recomputed=False)
657 _u = np.array([me[1][0] for me in u])
658 _x = np.array([me[0] for me in u])
660 x1 = _x[abs(_u - 1.1) < 1e-2][0]
661 ax.plot(_x, _u, color='black')
662 ax.axvspan(x1, x1 + 20, alpha=0.4)
663 ax.set_ylabel(r'$u$')
664 ax.set_xlabel(r'$t$')
665 savefig(fig, 'vdp_sol')
668def work_precision(): # pragma: no cover
669 from pySDC.projects.Resilience.work_precision import (
670 all_problems,
671 )
673 all_params = {
674 'record': False,
675 'work_key': 't',
676 'precision_key': 'e_global_rel',
677 'plotting': True,
678 'base_path': 'data/paper',
679 }
681 for mode in ['compare_strategies', 'parallel_efficiency', 'RK_comp']:
682 all_problems(**all_params, mode=mode)
683 all_problems(**{**all_params, 'work_key': 'param'}, mode='compare_strategies')
686def plot_recovery_rate_per_acceptance_threshold(problem): # pragma no cover
687 stats_analyser = get_stats(problem)
689 stats_analyser.plot_recovery_thresholds(thresh_range=np.linspace(0.5, 1.5, 1000), recoverable_only=True)
692def make_plots_for_TIME_X_website(): # pragma: no cover
693 global JOURNAL, BASE_PATH
694 JOURNAL = 'JSC_beamer'
695 BASE_PATH = 'data/paper/time-x_website'
697 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 0.5, 2.0 / 3.0))
698 plot_recovery_rate_recoverable_only(get_stats(run_vdp), fig, ax)
699 savefig(fig, 'recovery_rate', format='png')
701 from pySDC.projects.Resilience.work_precision import vdp_stiffness_plot
703 vdp_stiffness_plot(base_path=BASE_PATH, format='png')
706def make_plots_for_SIAM_CSE23(): # pragma: no cover
707 """
708 Make plots for the SIAM talk
709 """
710 global JOURNAL, BASE_PATH
711 JOURNAL = 'JSC_beamer'
712 BASE_PATH = 'data/paper/SIAMCSE23'
714 fig, ax = plt.subplots(figsize=figsize_by_journal(JOURNAL, 0.5, 3.0 / 4.0))
715 plot_recovery_rate_recoverable_only(get_stats(run_vdp), fig, ax)
716 savefig(fig, 'recovery_rate')
718 plot_adaptivity_stuff()
719 compare_recovery_rate_problems()
720 plot_vdp_solution()
723def make_plots_for_adaptivity_paper(): # pragma: no cover
724 """
725 Make plots that are supposed to go in the paper.
726 """
727 global JOURNAL, BASE_PATH
728 JOURNAL = 'Springer_Numerical_Algorithms'
729 BASE_PATH = 'data/paper'
731 plot_adaptivity_stuff()
733 work_precision()
735 plot_vdp_solution()
736 plot_AC_solution()
737 plot_Schroedinger_solution()
738 plot_quench_solution()
741def make_plots_for_resilience_paper(): # pragma: no cover
742 plot_Lorenz_solution()
743 plot_fault_Lorenz(0)
744 plot_fault_Lorenz(20)
745 plot_RBC_solution()
746 compare_recovery_rate_problems(target='resilience', num_procs=1, strategy_type='SDC')
747 # plot_recovery_rate(get_stats(run_Lorenz))
748 # plot_recovery_rate_per_acceptance_threshold(run_Lorenz)
749 plt.show()
752def make_plots_for_notes(): # pragma: no cover
753 """
754 Make plots for the notes for the website / GitHub
755 """
756 global JOURNAL, BASE_PATH
757 JOURNAL = 'Springer_Numerical_Algorithms'
758 BASE_PATH = 'notes/Lorenz'
760 analyse_resilience(run_Lorenz, format='png')
761 analyse_resilience(run_quench, format='png')
764def make_plots_for_thesis(): # pragma: no cover
765 global JOURNAL
766 JOURNAL = 'TUHH_thesis'
768 plot_RBC_solution()
769 # plot_vdp_solution()
771 # plot_adaptivity_stuff()
772 compare_recovery_rate_problems(target='thesis', num_procs=1, strategy_type='SDC')
775if __name__ == "__main__":
776 import argparse
778 parser = argparse.ArgumentParser()
779 parser.add_argument(
780 '--target', choices=['adaptivity', 'resilience', 'thesis', 'notes', 'SIAM_CSE23', 'TIME_X_website'], type=str
781 )
782 args = parser.parse_args()
784 if args.target == 'adaptivity':
785 make_plots_for_adaptivity_paper()
786 elif args.target == 'resilience':
787 make_plots_for_resilience_paper()
788 elif args.target == 'thesis':
789 make_plots_for_thesis()
790 elif args.target == 'notes':
791 make_plots_for_notes()
792 elif args.target == 'SIAM_CSE23':
793 make_plots_for_SIAM_CSE23()
794 elif args.target == 'TIME_X_website':
795 make_plots_for_TIME_X_website()
796 else:
797 raise NotImplementedError(f'Don\'t know how to make plots for target {args.target}')