Coverage for pySDC / projects / RayleighBenard / analysis_scripts / RBC3D_order.py: 100%
58 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-12 11:13 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-02-12 11:13 +0000
1import os
2import pickle
3import numpy as np
4from pySDC.helpers.fieldsIO import FieldsIO
5from pySDC.projects.RayleighBenard.RBC3D_configs import get_config
6from pySDC.implementations.problem_classes.RayleighBenard3D import RayleighBenard3D
7from mpi4py import MPI
8import matplotlib.pyplot as plt
9from pySDC.helpers.plot_helper import figsize_by_journal
10from pySDC.projects.RayleighBenard.analysis_scripts.plotting_utils import get_plotting_style, savefig
12step_sizes = {
13 'RBC3DG4R4SDC22Ra1e5': [5e-3 * 2**i for i in range(8)],
14 'RBC3DG4R4SDC23Ra1e5': [5e-3 * 2**i for i in range(8)],
15 'RBC3DG4R4SDC34Ra1e5': [5e-3 * 2**i for i in range(8)],
16 'RBC3DG4R4SDC44Ra1e5': [5e-3 * 2**i for i in range(8)],
17 'RBC3DG4R4RKRa1e5': [5e-3 * 2**i for i in range(8)],
18 'RBC3DG4R4EulerRa1e5': [5e-3 * 2**i for i in range(8)],
19}
20n_freefall_times = {}
23def no_logging_hook(*args, **kwargs):
24 return None
27def get_path(args):
28 config = get_config(args)
29 fname = config.get_file_name()
30 return f'{fname[:fname.index('dt')]}order.pickle'
33def compute_errors(args, dts, Tend):
34 errors = {'u': [], 'v': [], 'w': [], 'T': [], 'p': [], 'dt': []}
35 prob = RayleighBenard3D(nx=4, ny=4, nz=4, comm=MPI.COMM_SELF)
37 dts = np.sort(dts)[::-1]
38 ref = run(args, dts[-1], Tend)
39 for dt in dts[:-1]:
40 u = run(args, dt, Tend)
41 e = u - ref
42 for comp in ['u', 'v', 'w', 'T', 'p']:
43 i = prob.index(comp)
44 e_comp = np.max(np.abs(e[i])) / np.max(np.abs(ref[i]))
45 e_comp = MPI.COMM_WORLD.allreduce(e_comp, op=MPI.MAX)
46 errors[comp].append(float(e_comp))
47 errors['dt'].append(dt)
49 path = get_path(args)
50 if MPI.COMM_WORLD.rank == 0:
51 with open(path, 'wb') as file:
52 pickle.dump(errors, file)
53 print(f'Saved errors to {path}', flush=True)
56def plot_error_all_components(args): # pragma: no cover
57 fig, ax = plt.subplots()
58 with open(get_path(args), 'rb') as file:
59 errors = pickle.load(file)
61 for comp in ['u', 'v', 'w', 'T', 'p']:
62 e = np.array(errors[comp])
63 dt = np.array(errors['dt'])
64 order = np.log(e[1:] / e[:-1]) / np.log(dt[1:] / dt[:-1])
65 ax.loglog(errors['dt'], errors[comp], label=f'{comp} order {np.mean(order):.1f}')
67 ax.loglog(errors['dt'], np.array(errors['dt']) ** 4, label='Order 4', ls='--')
68 ax.loglog(errors['dt'], np.array(errors['dt']) ** 2, label='Order 2', ls='--')
69 ax.legend()
70 ax.set_xlabel(r'$\Delta t$')
71 ax.set_ylabel(r'$e$')
74def compare_order(Ra): # pragma: no cover
75 fig, ax = plt.subplots(figsize=figsize_by_journal('Nature_CS', 1, 0.6))
76 if Ra == 1e5:
77 names = ['RK', 'Euler', 'SDC22', 'SDC23', 'SDC34', 'SDC44'][::-1]
78 configs = [f'RBC3DG4R4{me}Ra1e5' for me in names]
79 paths = [f'./data/RBC3DG4R4{me}Ra1e5-res-1-order.pickle' for me in names]
81 else:
82 raise NotImplementedError
84 for path, config in zip(paths, configs, strict=True):
85 with open(path, 'rb') as file:
86 errors = pickle.load(file)
88 e = np.array(errors['T'])
89 dt = np.array(errors['dt'])
90 order = np.log(e[1:] / e[:-1]) / np.log(dt[1:] / dt[:-1])
91 print(f'{config}: order: mean={np.mean(order):.1f} / median={np.median(order):.1f}')
92 ax.loglog(dt, e, **get_plotting_style(config))
94 for _dt in dt:
95 for i in [1, 2, 3, 4]:
96 ax.text(_dt, _dt**i, i, fontweight='bold', fontsize=14, ha='center', va='center')
97 ax.loglog(dt, dt**i, ls=':', color='black')
99 ax.legend(frameon=False)
100 ax.set_xlabel(r'$\Delta t$')
101 ax.set_ylabel(r'$e$')
102 savefig(fig, 'RBC3D_order_Ra1e5')
105def run(args, dt, Tend):
106 from pySDC.projects.RayleighBenard.run_experiment import run_experiment
107 from pySDC.core.errors import ConvergenceError
109 args['mode'] = 'run'
110 args['dt'] = dt
112 config = get_config(args)
113 config.Tend = n_freefall_times.get(type(config).__name__, 3)
115 desc = config.get_description(res=args['res'])
116 prob = desc['problem_class'](**desc['problem_params'])
118 ic_config_name = type(config).__name__
119 for name in ['RK', 'Euler', 'O3', 'O4', 'SDC23', 'SDC34', 'SDC44', 'SDC22']:
120 ic_config_name = ic_config_name.replace(name, 'SDC34')
122 ic_config = get_config({**args, 'config': ic_config_name})
123 config.ic_config['config'] = type(ic_config)
124 config.ic_config['res'] = ic_config.res
125 config.ic_config['dt'] = ic_config.dt
127 config.get_LogToFile = no_logging_hook
128 config.Tend = Tend
130 u_hat = run_experiment(args, config)
131 u = prob.itransform(u_hat)
133 return u
136if __name__ == '__main__':
137 from pySDC.projects.RayleighBenard.run_experiment import parse_args
139 args = parse_args()
141 if args['mode'] == 'run':
142 config = get_config(args)
143 dts = step_sizes[type(config).__name__]
144 compute_errors(args, dts, max(dts))
146 if args['config'] is not None:
147 plot_error_all_components(args)
149 compare_order(1e5)
150 if MPI.COMM_WORLD.rank == 0:
151 plt.show()