3test_lapack_omp_small.py — Quick verification of LAPACK + OMP auto-pick.
5Small problem (I=V=1000, N_eq~2002), short time span (t_end=1e-2).
6Runs once with Jacobi, once with Woodbury, using the already-built
7solver.exe. Does NOT rebuild — uses whatever's in build/Release/.
10 1. Auto-thread picker fires (expect "auto-selected 4 threads ...")
11 2. Woodbury works (no "binary built without LAPACK" fallback)
12 3. Speedup of Woodbury over Jacobi
18os.environ.pop(
'OMP_NUM_THREADS',
None)
20import sys, io, time, importlib
21from pathlib
import Path
23MODULE_ROOT = Path(__file__).resolve().parent.parent.parent
24REPO_ROOT = MODULE_ROOT.parent
25for p
in [str(REPO_ROOT), str(MODULE_ROOT)]:
29import radcluster_code.py_utils.input_data
as _inp
30import radcluster_code.py_utils.reaction_rates
as _rr
31import radcluster_code.py_utils.rate_equations
as _re
32import radcluster_code.py_utils.cpp_bridge
as _cb
33import radcluster_code.py_utils.post_process
as _pp
34import radcluster_code.py_utils.simulation
as _sim
35for _m
in [_inp, _rr, _re, _cb, _pp, _sim]:
37from radcluster_code.py_utils.simulation
import RadClusterSimulation
43 'eta': 0.3,
'f_cl_i': 0.2,
'f_cl_v': 0.15,
44 'E_m_1D': 0.4,
'i_mobile': 1,
'L_hat': 5,
45 'c_C': 0.001,
'E_b_C_SIA': 0.65,
46 'rho_d': 1e15,
'Z_i': 1.08,
'Z_ii': 1.01,
47 'shape_function':
'linear',
48 'i_discrete': I,
'v_discrete': V,
49 'I_bin': 0,
'V_bin': 0,
54 saved = sys.stdout, sys.stderr
55 sys.stdout = sys.stderr = io.StringIO()
57 sim = RadClusterSimulation(
58 I=I, V=V, solver_mode=
'full_system',
59 physics_option=
'full_CD_fission',
60 C_floor=1e-25, he_kinetics=
'quasi_steady_state',
61 i_mobile=1, v_mobile=1,
64 for key, val
in OVERRIDES.items():
66 for d
in [inp.production_fission, inp.production_fusion,
67 inp.diffusion, inp.reactions,
68 inp.energetics, inp.dissociation]:
73 inp.reactions[key] = val
74 inp._calculate_derived()
77 sys.stdout, sys.stderr = saved
83 't_span': (1e-6, 1e-2),
91 'concentration_threshold': 1e-20,
'window_pad': 100,
92 'prec_type': prec_type,
95 name =
'Woodbury' if prec_type == 1
else 'Jacobi'
96 print(f
"\n{'='*60}\n {name} (prec_type={prec_type})\n{'='*60}", flush=
True)
98 t0 = time.perf_counter()
99 results = sim.run(solver_config=cfg, save_output=
False)
100 wall = time.perf_counter() - t0
102 print(f
" FAILED after {wall:.2f}s", flush=
True)
104 md = results.get(
'metadata', {})
105 n_thr = md.get(
'omp_threads_used',
'?')
106 print(f
" wall = {wall:.2f}s omp_threads_used = {n_thr}", flush=
True)
107 return {
'wall': wall,
'n_thr': n_thr,
'prec': name}
110print(f
"OMP_NUM_THREADS env at script start: "
111 f
"{os.environ.get('OMP_NUM_THREADS', '<unset>')}", flush=
True)
112print(f
"N_eq for I=V={I}: ~{2 * I + 2}", flush=
True)
118 print(f
"\n{'='*60}\n SUMMARY\n{'='*60}")
119 print(f
" Jacobi wall = {j['wall']:.2f}s ({j['n_thr']} threads)")
120 print(f
" Woodbury wall = {w['wall']:.2f}s ({w['n_thr']} threads)")
122 print(f
" Speedup (Jacobi / Woodbury) = {j['wall'] / w['wall']:.2f}x")