Skip to content

DKX 2.12.0

Latest

Choose a tag to compare

@rogeriojorge rogeriojorge released this 26 Oct 04:35
1458c01

Self-consistent bootstrap current at the ambipolar E_r for optimization
(KineticBootstrapMismatch(ambipolar=True), differentiated through the root),
spectral angles by default, the improved Sugama l = 1 correction (Spitzer-Harm
within 0.65%), Beidler et al. (2011)'s sign convention for D31*/D13*, and a
W7-X comparison against the digitized ICNTS curves.

  • Feature: KineticBootstrapMismatch(ambipolar=True) evaluates the traced bootstrap row at each surface's ambipolar E_r, with er_kV_per_m also accepting a callable of s, and spectral_angles=True. The root comes from a damped Newton iteration warm-started at the previous root (same branch), converged on the Newton gap |J_r / J_r'| and run as its own compiled program from the host, so the program VMEX differentiates holds one solve per surface and no loop: cold Jacobian 228 s to 57 s, warm residual 2.8 s (one surface, 9x9x32x4, loaded 8-core office host). The derivative through the root is j_p - j_E J_p / J_E (implicit function theorem). Against central differences of VMEX re-solves (QI example seed, s = 0.3 and 0.6, three boundary coefficients): at fixed E_r = -2 kV/m 3e-3 or better; at the ambipolar root 2e-2 or better. Default ambipolar grid 9 x 9 x 32 x 5 (DEFAULT_AMBIPOLAR_RESOLUTION): within 2.1% and 1.0% of 13 x 13 x 64 x 5 for <j.B> and 2% for the roots; Nx = 4 is 30% high at s = 0.3 whatever Nxi. unconverged counts rows whose root search failed; examples/advanced/ambipolar_bootstrap_dkx.py and tests/test_bootstrap_ambipolar.py.
  • Changed: D31* and D13* of the monoenergetic coefficients follow Beidler et al. (2011)'s sign convention: D31* is positive in the banana limit whatever the sign of iota (D13* = -D31* at EStar = 0). Up to 2.11.0 they carried sign(iota), so every stored D31*/D13* of an iota < 0 deck (W7-X, HSX, TJ-II, NCSX, DSHAPE) changes sign; D11* and D33* are unchanged. The sign is applied once, in monoenergetic_dstar_from_transport_matrix, and its docstring no longer claims the orientation was standardized. Sealed records re-sealed with the sign flipped: validation/independent_cross_code_v1.json (DKX and reference D31*/D13* of DSHAPE 0.015800 -> -0.015800, NCSX -0.137747 -> 0.137747, W7-X EIM 0.013317 -> -0.013317; reference cross_orientation -1 -> +1; relative errors unchanged), validation/cross_code_gaps_v1.json (all 13 D31* ladder values, e.g. DKX 0.013317 -> -0.013317), the five docs/_static/figures/paper_benchmarks JSONs (HSX, TJ-II, W7-X, low-collisionality, Shaing-Callen; Shaing-Callen limit at the tiny grid -0.059023 -> 0.059023), the compact-output and registry checksums (DKX output sha256: DSHAPE b195f55b -> 974801b8, NCSX 4be87097 -> e684c24f, W7-X afb539e0 -> dfcc52b8). dkes_to_beidler defaults to cross_orientation = +1. The #382 W7-X comparison no longer flips the sign by hand.
  • Default: [resolution] angles is now "spectral" (Fourier collocation); finite_difference stays an option and is written to the canonical case when chosen, while spectral is omitted. A case that omitted angles keeps its case ID but now names different numerics (a cached result of the old default has the same ID). Reason: at equal grid the spectral error is lower (see the table below) and the warm time is the same. A converted SFINCS namelist keeps angles = "finite_difference" explicitly, so deck parity is unchanged; the kernel-parity tests in tests/test_native_execution_result.py pin the stencil for the same reason.
  • [resolution] auto = true (opt-in) fills missing theta, zeta, pitch, speed from the measured ladder of docs/user_guide/convergence.md at the case's lowest ion collisionality (dkx.config.auto_resolution; tokamak rungs for file = "tokamak"). It stays opt-in because it is not calibrated: on an HSX deck (n = 2e19 m^-3, T_i = 0.1 keV) it chose 13 x 17 x 24 x 5, 33% from a 17 x 33 x 48 x 6 reference. Without auto, every size is required as before.
  • [run] check_grid = true is the input-file form of dkx run --check-grid (omitted from the canonical case when false). The refined solves of the certificate and of dkx converge do not re-certify.
  • Measurements (office, 8 pinned cores of a loaded host; error is the largest relative difference of the particle flux, heat flux and parallel current against a reference of the same case, warm time after one cold run, process peak RSS). Tolerance sweep, spectral angles, reference at 1e-12 (tokamak: 1e-10, since 1e-12 does not converge there): HSX deck 11 x 25 x 32 x 5 (Krylov) 1e-4 / 1e-6 / 1e-8 / 1e-10: error 6e-5 / 2e-7 / 2e-9 / 1e-10, time 21 / 25 / 30 / 56 s, 1.2 GB. Tokamak 21 x 1 x 20 x 6: error 6e-10 / 6e-10 / 2e-11 / 0 at 0.3 / 0.3 / 1.1 / 0.8 s, 0.3-0.5 GB; W7-X 11 x 13 x 32 x 5 uses the direct route, whose answer does not depend on the tolerance (error 0, 15 s, 1.5 GB). The solver error at 1e-8 is below the discretization error by 6 orders, so the default tolerance is unchanged. Defaults, tolerance 1e-10, against a finer spectral reference: tokamak finite differences / spectral / automatic grid 2.5e-3 / 1.5e-3 / 1.4e-3 (0.8 / 0.8 / 0.9 s); HSX 2.0 / 4.1e-2 / 3.3e-1 (32 / 28 / 13 s, 1.2 / 1.3 / 1.0 GB; reference 185 s, 4.4 GB). W7-X finite differences and spectral at 11 x 13 x 32 x 5 both take 11 s; its 15 x 33 x 64 x 8 reference and 21 x 49 x 96 x 8 automatic grid did not finish in 40 minutes.
  • The pitch-160 fallback to Krylov is a cost rule, not a tolerance miss: method = "auto" leaves the speed-coupled direct route above 150 GFlop per right-hand side (W7-X, 9 x 13, two species, full FP, pitch 80 and 160). Forced with structured_direct, the three fixed defect-correction sweeps reach a residual of 1e-17 at pitch 80 (108 s, 2.9 GB) and 160 (246 s, 5.5 GB), so the proposed longer refinement is not needed and is not included. The tokamak PAS truncated direct route does stall near 5e-10 and falls back to Krylov for tolerances below 1e-6; at 1e-12 the Krylov solve ends at 4e-12 and the run raises (open).
  • Test: W7-X Phi1 in the kinetic equation with spectral angles is accepted and within 1.5% of the stencil flux at 7 x 7 x 8 x 3 (tests/test_native_phi1.py).
  • Plan: section 19, literature round 2 (improved Sugama correction, unequal-temperature gaps, ICNTS and MONKES reference data). No code change.
  • Validation: validation/beidler2011_w7x_monoenergetic.csv holds D11*, D31* and D33* of the W7-X standard configuration at rho = 0.5, digitized from Figs 17, 21 and 26 of Beidler et al. (2011) with the method and errors in its header (3% on D11*, 0.003 on D31*, 0.002 on D33*). tests/test_beidler_w7x_reference.py runs DKX's monoenergetic route on w7x_standardConfig.bc against it: D11* within +1.6 to +3.0% (+5.4 and +7.7% at a finer grid, 1.1e-3 and 3.6e-4), D31* within 0.007, D33* within 1.5%, and D11* at v_E = 3e-3 inside the scatter of the DKES and Monte Carlo symbols. DKX's D31* takes the sign of iota, opposite to Beidler's convention for this file (iota < 0); the test applies the flip and the cause is not changed here.
  • Feature: improved Sugama (collisionOperator = 3) adds the l = 1 flow-moment correction of Sugama et al. (2019), Eqs. 40-43. The Landau l = 1 field block minus the model's rank-1 momentum term is projected onto the first K = 5 Laguerre flow moments (flow_order), keeping momentum exact and the shifted Maxwellian a null vector. The Spitzer-Harm conductivity moves from 11.1 / 9.8 / 7.8 / 3.1 % low to within 0.6 % at Z = 1, 2, 4, 16 (K = 2: within 2.1 %; Frei et al. 2022 compare K = 2 and 5). The same projection is valid at T_a != T_b: flow and heat-flow friction match the Landau operator to 2e-3 (T_e/T_i = 10, m_e/m_i = 1/1836), and the l = 0 energy exchange converges to 2019 Eq. A1. tests/test_physics_limits.py and tests/test_collisions_improved_sugama.py pin both.