Files
TRIMSP/tests
Zaher Salman 93f0b1c4d5 Fix parIRL=1 crash: zero recoil cutoff makes the cascade diverge
parIRL=1 crashed the engine with SIGSEGV (CGI exitCode 139) at both GUI
defaults, so the sputtering path has never actually worked.

The first diagnosis blamed KO(600,MAXNL5,2) being shallower than the
2000-wide recoil lists. That is wrong: enlarging KO to 2000 does not help,
because the cascade overruns all of them. The real cause is parERC=0, which
is the GUI default and what tests/Si_1layer/Si_1layer_E19000.inp carries. The
primary knock-on test is IF(DEN(IV).LE.ERC) GO TO 6, so with no cutoff every
atom receiving any energy is respawned as a recoil on each cascade
generation; the branching ratio exceeds one and NREC1/NREC2 grow
geometrically (81, 153, 269, 455, 773, 1317, ...) instead of draining, so the
list-2/list-1 loop at label 83 never terminates. Forcing a real cutoff
converges, with a peak depth of only 103, so KO was left at 600.

fortran/trimspNL.F:
- Refuse parIRL>=1 with parERC<=0 after readGuiInput, before any transport
  work, with a message naming the field to change.
- The IF(NREC2.GT.2000) guard now stops non-zero instead of falling through
  into the out-of-bounds write loop, so any future non-convergent cascade
  fails cleanly instead of corrupting memory.

TrimSPlib.js / TrimSP.html, so this is caught before the engine is invoked:
- handleRecoilModeChange, wired to the parIRL widget, fills parERC with
  TRIMSP_MIN_RECOIL_CUTOFF = 0.02 when recoils are switched on with a cutoff
  of 0, and says so.
- A pre-run check refuses the run if the user then insists on parIRL=1 with
  parERC=0, reporting via the status bar and a transient warning and focusing
  parERC. Deliberately not wired to parERC, so retyping the cutoff is what
  insisting means and is not silently overridden; this also covers shared
  config links, which assign widget values directly.
- The parIRL tooltip documents the requirement.

Tests: tests/recoil-cutoff-test.js (12 cases) lifts the shipped cutoff code
out of TrimSPlib.js and runs it against a document stub. Verified against a
fresh build: parERC=0/parIRL=1 now exits 1 with the new message instead of
139, parERC=0.02 completes with parIRL=0 or 1, and parERC=0/parIRL=0 output
is unchanged (.rge byte-identical). tests/cgi-tests.sh 18/18.
2026-09-26 18:55:38 +02:00
..
2026-06-25 09:42:41 +02:00
2026-06-25 09:42:41 +02:00
2026-06-25 09:42:41 +02:00
2026-06-25 09:42:41 +02:00
2026-08-27 15:07:36 +02:00

Regression test set

The tests/ tree contains the 13 target configurations used as the reference regression set for the TRIM.SP-NL modernization. Together they contain 143 energy-configuration points.

The committed .out files intentionally retain the banner TrimSPNL v1.3.2: they are the historical RANLUX reference outputs used to check behavior-preserving refactoring. They should therefore not be mechanically regenerated or replaced when preparing a new release.

For changes intended to preserve behavior, current RANLUX output should agree with these references apart from nondeterministic timing fields and quantities affected by explicitly documented corrections. PCG32 and xoshiro256** generate different Monte Carlo histories and are therefore compared statistically rather than by bitwise output identity.

The configurations are:

  • 6element_plus_multilayer
  • 7layer_stack
  • SiO2_Al2O3_TiN_Si_4layer
  • thin_Au_Cr_Si
  • Au_Cr_Si_3layer
  • AlCoCrFeNiTi_6elements
  • SiO2_Si_2layer
  • SiO2_1layer
  • Si_1layer
  • thin_C_foil
  • thin_C_Au_C
  • Li8-Si_1layer
  • Li8-thin_C_Au_C

When running an individual case manually, copy the relevant input deck to a scratch directory first so the committed reference files are not overwritten. The transport executable accepts an optional RNG backend as its second argument, for example:

trimspNL run_basename ranlux
trimspNL run_basename pcg32
trimspNL run_basename xoshiro

Omitting the second argument selects RANLUX.