|
1 | 1 | #!/usr/bin/env python3 |
2 | 2 | """ |
3 | | -Time-integration order verification for MFC's RK3 time stepper. |
| 3 | +Time-integration order verification for MFC's RK1, RK2, and RK3 time steppers. |
4 | 4 |
|
5 | 5 | Uses the 1D single-fluid Euler advection problem (rho = 1 + 0.2*sin(2*pi*x), |
6 | 6 | u=1, p=1, L=1, T=1) with a fine spatial grid (N=512, WENO5) so the spatial |
7 | | -error (~4e-12) is negligible compared to the RK3 temporal error at the CFLs |
8 | | -tested here. |
| 7 | +error (~4e-12) is negligible compared to the temporal error at the CFLs tested. |
9 | 8 |
|
10 | 9 | L2(rho(T) - rho(0)) measures total accumulated error. By fixing N and varying |
11 | 10 | CFL (and hence dt), the spatial contribution is constant and the measured rate |
12 | 11 | reflects the time integration order. |
13 | 12 |
|
14 | | -CFL values [0.5, 0.25] keep the temporal error well above the spatial floor: |
15 | | - CFL=0.50 → err ~8.3e-10 (>200x spatial floor) |
16 | | - CFL=0.25 → err ~1.1e-10 (>25x spatial floor) |
17 | | -Pairwise rate ≈ 2.95, threshold ≥ 2.7. |
| 13 | +CFL ranges are chosen to be within each stepper's stability region and keep |
| 14 | +temporal errors well above the ~4e-12 spatial floor: |
| 15 | + RK1 (Euler, 1st order): CFL=[0.10, 0.05] — stable limit ~0.1 with WENO5+LF |
| 16 | + (nearly-imaginary eigenvalues constrain Euler more than TVD RK); |
| 17 | + error ~2.5e-4 and ~1.2e-4 (rate ≈ 1.0) |
| 18 | + RK2 (TVD Heun, 2nd order): CFL=[0.50, 0.25]; |
| 19 | + error ~1.2e-6 and ~2.9e-7 (rate ≈ 2.0) |
| 20 | + RK3 (TVD Shu-Osher, 3rd order): CFL=[0.50, 0.25]; |
| 21 | + error ~8.3e-10 and ~1.1e-10 (rate ≈ 3.0) |
18 | 22 |
|
19 | 23 | Usage: |
20 | 24 | python toolchain/mfc/test/run_temporal_order.py |
21 | | - python toolchain/mfc/test/run_temporal_order.py --cfls 0.5 0.25 0.125 |
| 25 | + python toolchain/mfc/test/run_temporal_order.py --schemes RK3/WENO5 --cfls 0.5 0.25 0.125 |
22 | 26 | """ |
23 | 27 |
|
24 | 28 | import argparse |
|
37 | 41 | MFC = "./mfc.sh" |
38 | 42 |
|
39 | 43 | # (label, extra_args, expected_order, tolerance, cfls) |
40 | | -# All schemes here use RK3 (time_stepper=3 is default in MFC). |
41 | 44 | # N=512 is fixed; WENO5 keeps spatial error ~4e-12 (negligible at CFL>=0.25). |
| 45 | +# RK1/RK2 temporal errors at CFL=0.5 are ~2e-4 and ~2e-7, both >> spatial floor. |
42 | 46 | SCHEMES = [ |
43 | | - ("RK3/WENO5", ["--order", "5"], 3, 0.3, [0.5, 0.25]), |
| 47 | + # RK1 (Forward Euler): nearly-imaginary WENO5+LF eigenvalues constrain stability |
| 48 | + # to CFL < ~0.1; use [0.10, 0.05] which are provably stable and temporal-dominated |
| 49 | + ("RK1/WENO5", ["--order", "5", "--time-stepper", "1"], 1, 0.1, [0.10, 0.05]), |
| 50 | + # RK2/RK3 (TVD): stable to CFL~1; use [0.50, 0.25] for clean temporal dominance |
| 51 | + ("RK2/WENO5", ["--order", "5", "--time-stepper", "2"], 2, 0.2, [0.50, 0.25]), |
| 52 | + ("RK3/WENO5", ["--order", "5", "--time-stepper", "3"], 3, 0.3, [0.50, 0.25]), |
44 | 53 | ] |
45 | 54 |
|
46 | 55 | N_SPATIAL = 512 # fixed spatial resolution |
@@ -168,7 +177,7 @@ def main(): |
168 | 177 | parser.add_argument( |
169 | 178 | "--schemes", |
170 | 179 | nargs="+", |
171 | | - default=["RK3/WENO5"], |
| 180 | + default=["RK1/WENO5", "RK2/WENO5", "RK3/WENO5"], |
172 | 181 | help="Schemes to test (default: all)", |
173 | 182 | ) |
174 | 183 | parser.add_argument("--num-ranks", type=int, default=1, help="MPI ranks per simulation (default: 1)") |
|
0 commit comments