We would appreciate maintainer review of a small source correction for a reproducible face-to-face contact failure in CalculiX 2.23.
AI disclosure: ChatGPT Astra Ultra identified the defect, implemented the candidate fix, and carried out the controlled build/solver investigation in my local environment under my direction. It also prepared this report and reproducibility package, and is posting with my authorization. The evidence consists of saved compiler diagnostics and actual solver runs; AI involvement is not independent validation, and we are asking for expert review.
Defect and proposed correction
In the pinned 2.23 source, resultsmech.f:59 declares fnl(3,10), while springforc_f2f.f declares the corresponding argument as fnl(3,19). The exercised face-contact path exceeds the caller’s ten columns. With the unchanged official load1 test, caller bounds instrumentation reports:
At line 453 of file resultsmech.f
Fortran runtime error: Index '11' of dimension 2 of array 'fnl' above upper bound of 10
The candidate correction changes only the caller’s buffer extent:
- & fnl(3,10),skl(3,3),beta(6),q(0:mi(2),20),xl2(3,8),
+ & fnl(3,19),skl(3,3),beta(6),q(0:mi(2),20),xl2(3,8),
Controlled results
Private macOS arm64 builds used Clang 19.1.7, gfortran 14.3.0, static SPOOLES 2.2.0, ARPACK 3.9.1 and netlib BLAS/LAPACK 3.9. Exact recipes and runtime receipts are in the package.
| Case | Recorded result |
|---|---|
| Uncorrected O2 | load1 completes and passes the official reference check |
| Uncorrected O3 | Exit 201; zero accepted increments |
| Caller O3 with bounds checks over O2 baseline | Index-11 bounds failure |
| O3 with only the caller-buffer correction | Completes and passes the official reference check |
| Corrected bounds-instrumented variant | Completes and passes |
Independent O2/O3 rebuilds repeated the original pass/fail contrast. Corrected O2/O3 builds also passed the tested contact15 and contact17 regressions at requested thread settings 1 and 2; those additional regression builds include a separately identified energy-output correction. They are distinguished from the minimal buffer-only candidate.
We interpret this as a source-level memory-safety defect with build-dependent symptoms, not an established macOS-only compiler bug or a legitimate numerical-tolerance difference. The uncorrected O3 failure has no accepted equilibrium state; its best-iterate FRD must not be treated as a valid stress/displacement comparison.
Reproduction and limits
A prepared 604 KB reproducibility ZIP contains the isolated patch generated against pristine 2.23 release source, unchanged official load1.inp, official reference/checker, failed and corrected DAT/FRD/STA files, bounds diagnostics, build recipes, dependency records, hashes, and reproduction instructions. The official test files were retained from the 2.22 test suite and exercised with 2.23 binaries. Start with README.md; python3 verify_package.py rechecks saved evidence without running ccx. The new relocatable build helper has not itself been exercised through a fresh full rebuild.
Release archive SHA-256:
9c88385c10fb04f5dc6c4e98027a51bebdd8aee3920e05190d6c1dd08357d6e7
Our earlier Linux baseline was CalculiX, not OpenFOAM, and still contained the undersized buffer. Its agreement is comparative evidence only; corrected-source second-platform validation remains outstanding. We have not audited every contact path or demonstrated general solver correctness.
Before posting, we searched forum/upstream reports for resultsmech, fnl, and load1 without finding this specific correction. Current upstream commit 3593817a4a7658eb8af9e9827fbe98f9552fbd44 still declares fnl(3,10); we have not run that current revision or ruled out work in other branches.
The forum rejected the ZIP because uploads here currently allow only images. I have therefore included the small reproducer and key output below. The complete package is ready; please advise a maintainer-preferred way to provide it. Its SHA-256 is 71f9e338e2f5ea0ea1a0eea0c66f66f8f5fde274090f8b86cc3bc373074c092b.
Could maintainers confirm the required caller-array extent and advise whether this should become an issue or pull request on the official GitHub repository? Thank you for reviewing the evidence.
Run the reproducer
Save the deck below as load1.inp. Use separate directories for each binary. With the recorded one-thread requests:
OMP_NUM_THREADS=1 CCX_NPROC_RESULTS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 BLIS_NUM_THREADS=1 LC_ALL=C /path/to/ccx -i load1 > load1.log 2>&1
Keep the source, libraries and other flags fixed when comparing O2/O3. To reproduce the bounds diagnostic, compile resultsmech.f with -O3 -fcheck=bounds -fbacktrace -g over the otherwise O2 baseline; replace that object and relink. Then enlarge only the caller array and repeat the O3 control. Neither binary completion nor a match to a failed output is acceptance. The saved corrected run passes the official block-normalized 0.1% reference check; this is a regression tolerance, not an application force/energy criterion.
Official load1.inp (92 lines)
**
** Structure: cube with distributed loading.
** Test objective: facial loading not coincident with
** faces of the cube: loading area
** modeled as thin shell
**
*NODE, NSET=Nall
1,1.000000000000e+00,1.000000000000e+00,0.000000000000e+00
2,1.000000000000e+00,0.000000000000e+00,0.000000000000e+00
3,1.000000000000e+00,0.000000000000e+00,1.000000000000e+00
4,1.000000000000e+00,1.000000000000e+00,1.000000000000e+00
5,0.000000000000e+00,1.000000000000e+00,0.000000000000e+00
6,0.000000000000e+00,0.000000000000e+00,0.000000000000e+00
7,0.000000000000e+00,0.000000000000e+00,1.000000000000e+00
8,0.000000000000e+00,1.000000000000e+00,1.000000000000e+00
9,1.000000000000e+00,5.000000000000e-01,0.000000000000e+00
10,1.000000000000e+00,0.000000000000e+00,5.000000000000e-01
11,1.000000000000e+00,5.000000000000e-01,1.000000000000e+00
12,1.000000000000e+00,1.000000000000e+00,5.000000000000e-01
13,5.000000000000e-01,1.000000000000e+00,0.000000000000e+00
14,5.000000000000e-01,0.000000000000e+00,0.000000000000e+00
15,5.000000000000e-01,0.000000000000e+00,1.000000000000e+00
16,5.000000000000e-01,1.000000000000e+00,1.000000000000e+00
17,0.000000000000e+00,5.000000000000e-01,0.000000000000e+00
18,0.000000000000e+00,0.000000000000e+00,5.000000000000e-01
19,0.000000000000e+00,5.000000000000e-01,1.000000000000e+00
20,0.000000000000e+00,1.000000000000e+00,5.000000000000e-01
21,7.500000000000e-01,7.500000000000e-01,1.000000000000e+00
22,7.500000000000e-01,2.500000000000e-01,1.000000000000e+00
23,7.500000000000e-01,2.500000000000e-01,1.500000000000e+00
24,7.500000000000e-01,7.500000000000e-01,1.500000000000e+00
25,2.500000000000e-01,7.500000000000e-01,1.000000000000e+00
26,2.500000000000e-01,2.500000000000e-01,1.000000000000e+00
27,2.500000000000e-01,2.500000000000e-01,1.500000000000e+00
28,2.500000000000e-01,7.500000000000e-01,1.500000000000e+00
29,7.500000000000e-01,5.000000000000e-01,1.000000000000e+00
30,7.500000000000e-01,2.500000000000e-01,1.250000000000e+00
31,7.500000000000e-01,5.000000000000e-01,1.500000000000e+00
32,7.500000000000e-01,7.500000000000e-01,1.250000000000e+00
33,5.000000000000e-01,7.500000000000e-01,1.000000000000e+00
34,5.000000000000e-01,2.500000000000e-01,1.000000000000e+00
35,5.000000000000e-01,2.500000000000e-01,1.500000000000e+00
36,5.000000000000e-01,7.500000000000e-01,1.500000000000e+00
37,2.500000000000e-01,5.000000000000e-01,1.000000000000e+00
38,2.500000000000e-01,2.500000000000e-01,1.250000000000e+00
39,2.500000000000e-01,5.000000000000e-01,1.500000000000e+00
40,2.500000000000e-01,7.500000000000e-01,1.250000000000e+00
*ELEMENT,TYPE=C3D20R,ELSET=Esolid
1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 17, 18, 19, 20, 13, 14, 15, 16
*ELEMENT,TYPE=S8,ELSET=Eshell
2,25,21,22,26,33,29,34,37
*NSET,NSET=Nfix
1,
2,
5,
6,
9,
13,
14,
17,
*BOUNDARY
Nfix,1,3
*SURFACE,NAME=Sslav
2, S2
*SURFACE,NAME=Smast
1, S5
*CONTACT PAIR,INTERACTION=SI1,TYPE=SURFACE TO SURFACE
Sslav,Smast
*SURFACE INTERACTION,NAME=SI1
*SURFACE BEHAVIOR,PRESSURE-OVERCLOSURE=TIED
1.E10
*FRICTION
.2,1.E10
*MATERIAL,NAME=EL
*ELASTIC
210000.,.0
*SOLID SECTION,ELSET=Esolid,MATERIAL=EL
*SHELL SECTION,ELSET=Eshell,MATERIAL=EL
1.e-10
*STEP,NLGEOM
*STATIC
1.,1.
*DLOAD
2, P, 100.000000
*NODE PRINT,NSET=Nfix,TOTALS=ONLY
RF
*EL PRINT,ELSET=Esolid
E
*EL PRINT,ELSET=Eshell,GLOBAL=YES
S
*END STEP
Original deck SHA-256: 4d7aa118adf4dc0df22424b31a52727b59218977be488d5da99f88d7b0284cd1. If copying through the forum changes whitespace or line endings, use the original official test deck for byte-identical comparisons.
Corrected K31 DAT excerpt
total force (fx,fy,fz) for set NFIX and time 0.1000000E+01
-6.107604E-10 1.759753E-10 2.499554E+01
strains (elem, integ.pnt.,exx,eyy,ezz,exy,exz,eyz) for set ESOLID and time 0.1000000E+01
1 1 2.578082E-05 2.578082E-05 -1.190422E-04 -1.256678E-09 2.577865E-05 2.577865E-05