diff --git a/PLAN.md b/PLAN.md index 9d970bc..26be66c 100644 --- a/PLAN.md +++ b/PLAN.md @@ -12,7 +12,7 @@ - Phase directory: `phases/uel-3d-euler-beam` - Current planned entry point: `python scripts/execute.py uel-3d-euler-beam` -- First pending step: `step8` validation readiness +- First pending action: correct Abaqus-facing `UEL` wrapper/interface mismatch before `step8` validation readiness ## Planned Steps @@ -46,3 +46,4 @@ - Confirm exact first-scope beam assumptions in the requirements step. - Decide `PROPS`/`JPROPS` ordering and orientation-vector convention in the interface step. - Decide exact no-Abaqus Fortran source and test file layout in the reference model step. +- Add a top-level Abaqus-callable `SUBROUTINE UEL(...)` wrapper and correct the `VARIABLES`/`NSVARS` policy before external Abaqus validation readiness. diff --git a/PROGRESS.md b/PROGRESS.md index 6a443db..15ca58d 100644 --- a/PROGRESS.md +++ b/PROGRESS.md @@ -5,8 +5,8 @@ - Active objective: 3D Euler-Bernoulli beam Abaqus/Standard `UEL` - Active phase: `phases/uel-3d-euler-beam` - Active owner: unassigned -- Current status: completed `phases/uel-3d-euler-beam/step7.md` Fortran implementation step -- Next action: execute `phases/uel-3d-euler-beam/step8.md` validation-readiness step +- Current status: completed ad hoc UEL ABI research correction note after step 7 implementation review +- Next action: correct the Abaqus-facing UEL wrapper/interface mismatch before executing `phases/uel-3d-euler-beam/step8.md` validation-readiness step ## Completed @@ -49,6 +49,11 @@ - Fixed `scripts/fortran_toolchain.py` to use `ComSpec`/absolute `cmd.exe` and a minimal Windows PATH for oneAPI env setup. - Created `docs/build-test-reports/uel-3d-euler-beam-green.md`. - Updated `phases/uel-3d-euler-beam/index.json` step 7 to `completed`. +- Completed ad hoc UEL ABI format research after user review feedback. + - Created `docs/abaqus-uel-subroutines-research.md`. + - Confirmed current source has no top-level Abaqus-callable `SUBROUTINE UEL(...)` wrapper under `src/fortran`. + - Confirmed `uel3deb_abi_static` is a no-Abaqus adapter, not the manual Abaqus UEL ABI. + - Identified a likely Abaqus input contract issue: documented `*USER ELEMENT, VARIABLES` must be greater than zero, so the current `NSVARS=0` / `VARIABLES=0` contract should be corrected before external Abaqus validation. ## In Progress @@ -60,7 +65,21 @@ ## Last Verification -Latest verification after completing step 7 Fortran implementation: +Latest verification after creating the UEL ABI research document: + +```bash +python -m unittest discover -s scripts -p "test_*.py" +python scripts/validate_workspace.py +git diff --check +``` + +Result: all passed. +- `python -m unittest discover -s scripts -p "test_*.py"`: 57 tests passed. +- `python scripts/validate_workspace.py`: reference artifact validation succeeded; six Fortran manifest executables compiled and passed with Intel `ifx`; workspace validation succeeded. +- `git diff --check`: passed with line-ending warnings only. + +Previous verification after completing step 7 Fortran implementation: + ```bash python -m unittest discover -s scripts -p "test_*.py" @@ -79,5 +98,5 @@ Result: all passed. - Read `AGENTS.md`, `PLAN.md`, `PROGRESS.md`, and `WORKNOTE.md`. - Confirm no other owner is active in this file. -- Start `phases/uel-3d-euler-beam/step8.md`. +- Correct the Abaqus-facing `UEL` wrapper/interface mismatch before `phases/uel-3d-euler-beam/step8.md`. - Update this file when step status changes or before handing off. diff --git a/WORKNOTE.md b/WORKNOTE.md index 439a7ba..cbeb191 100644 --- a/WORKNOTE.md +++ b/WORKNOTE.md @@ -13,3 +13,7 @@ - `python scripts/validate_workspace.py`는 Fortran manifest가 없으면 `validate_fortran.py`에서 "No Fortran validation commands configured."를 출력하고 성공할 수 있다. 이것은 구현 전 scaffold 상태에서는 정상이다. - Step 6에서 `tests/fortran/manifest.json`을 추가한 뒤 기본 `python scripts/validate_fortran.py`가 nested `cmd` lookup에서 먼저 실패했다. PowerShell/Python은 `cmd.exe`를 찾지만 child `cmd.exe`가 `%PATH%`를 빈 값으로 보았다. RED compile evidence는 `$env:PATH='C:\Windows\System32;C:\Windows;C:\Users\user\miniforge3'; C:\Users\user\miniforge3\python.exe scripts/validate_fortran.py`로 확인했으며, 이때 `ifx`가 실행되고 missing `src/fortran/uel_3d_euler_beam_kernel.f90` compile failure가 발생했다. - Step 7에서 위 PATH 문제는 `scripts/fortran_toolchain.py`가 `ComSpec`/절대 `cmd.exe`와 최소 Windows PATH를 사용하도록 수정해 해결했다. 또한 `scripts/validate_fortran.py`가 per-test build directory를 만들지 않아 `LNK1104`가 발생했으므로 `build_dir.mkdir(parents=True, exist_ok=True)`를 추가했다. +- 2026-06-12 사용자 UEL 포맷 재조사에서 제공된 `default.htm?startat=ch01s01asb44.html`는 프레임 진입점이며 `ch01s01asb44.html` 자체는 2016 문서의 `UMAT` 섹션이다. UEL 직접 문서는 `https://ceae-server.colorado.edu/v2016/books/sub/ch01s01asb28.html`이다. +- 같은 조사에서 현재 `src/fortran`에는 Abaqus가 직접 호출할 top-level external `SUBROUTINE UEL(...)` wrapper가 없고, `uel3deb_abi_static`은 no-Abaqus adapter일 뿐임을 확인했다. 다음 구현 보정에서는 manual signature와 `ABA_PARAM.INC` include를 보존하는 wrapper가 필요하다. +- `docs/io-definitions/uel-3d-euler-beam.md`의 `VARIABLES=0`/`NSVARS=0` 정책은 Abaqus `*USER ELEMENT` 문서의 `VARIABLES` 값이 0보다 커야 한다는 규칙과 충돌할 가능성이 있다. 실제 Abaqus-facing 계약은 `VARIABLES=1` 이상 또는 target-version 근거가 있는 예외로 보정해야 한다. +- PowerShell에서 `git add ... && git status --short`를 실행하면 이 환경에서는 `&&`가 statement separator로 인식되지 않아 실패한다. 명령은 분리해서 실행한다. diff --git a/docs/abaqus-uel-subroutines-research.md b/docs/abaqus-uel-subroutines-research.md new file mode 100644 index 0000000..2252584 --- /dev/null +++ b/docs/abaqus-uel-subroutines-research.md @@ -0,0 +1,147 @@ +# Abaqus UEL Subroutines Research Brief + +## Metadata +- feature_id: abaqus-uel-subroutines +- related_feature: `uel-3d-euler-beam` +- status: ready-for-interface-correction +- owner_agent: research-agent +- date: 2026-06-12 + +## Research Questions +- Abaqus/Standard가 실제로 호출하는 `UEL` subroutine의 positional ABI는 무엇인가? +- `RHS`, `AMATRX`, `SVARS`, `ENERGY`, `PNEWDT`, `LFLAGS`의 update 책임은 무엇인가? +- `*USER ELEMENT`와 `*UEL PROPERTY`가 `NDOFEL`, `NNODE`, `MCRD`, `NPROPS`, `NJPROP`, `NSVARS`에 미치는 영향은 무엇인가? +- 공개 GitHub UEL 예제는 Abaqus-facing wrapper와 testable implementation logic을 어떻게 분리하는가? +- 현재 `uel-3d-euler-beam` Fortran 구현이 Abaqus UEL 포맷과 맞지 않는 지점은 무엇인가? + +## Source Inventory + +| id | source_type | title | author_or_org | URL | access_date | reliability_tier | notes | +| --- | --- | --- | --- | --- | --- | --- | --- | +| S1 | vendor manual mirror | Abaqus 2016 User Subroutines Reference Guide, user-provided entry URL | Dassault Systemes SIMULIA, mirrored by University of Colorado | https://ceae-server.colorado.edu/v2016/books/sub/default.htm?startat=ch01s01asb44.html | 2026-06-12 | Tier 1 version-specific mirror | The `default.htm?startat=...` frame URL returned a browser fallback in this environment. The `startat=ch01s01asb44.html` target is `UMAT`, not `UEL`. | +| S2 | vendor manual mirror | Abaqus 2016 User Subroutines Reference Guide, `UEL` section 1.1.28 | Dassault Systemes SIMULIA, mirrored by University of Colorado | https://ceae-server.colorado.edu/v2016/books/sub/ch01s01asb28.html | 2026-06-12 | Tier 1 version-specific mirror | Direct 2016 UEL page. Used as the user-requested manual family. | +| S3 | vendor manual mirror | Abaqus 2025 User Subroutines Reference Guide, `UEL` | Dassault Systemes SIMULIA | https://docs.software.vt.edu/abaqusv2025/English/SIMACAESUBRefMap/simasub-c-uel.htm | 2026-06-12 | Tier 1 accessible manual mirror | Used for accessible line-level confirmation of the UEL interface, variables, and `LFLAGS`. Recheck against the target licensed Abaqus installation before release. | +| S4 | vendor keyword manual mirror | Abaqus 2025 Keywords Reference, `*USER ELEMENT` | Dassault Systemes SIMULIA | https://docs.software.vt.edu/abaqusv2025/English/SIMACAEKEYRefMap/simakey-r-userelement.htm | 2026-06-12 | Tier 1 accessible manual mirror | Defines user element type declaration, active DOF data lines, properties, coordinates, `VARIABLES`, and `UNSYMM`. | +| S5 | vendor keyword manual mirror | Abaqus 2025 Keywords Reference, `*UEL PROPERTY` | Dassault Systemes SIMULIA | https://docs.software.vt.edu/abaqusv2025/English/SIMACAEKEYRefMap/simakey-r-uelproperty.htm | 2026-06-12 | Tier 1 accessible manual mirror | Defines UEL property assignment by `ELSET`, property data order, and optional `ORIENTATION`. | +| S6 | vendor analysis manual mirror | Abaqus 2025 Analysis User's Guide, User-Defined Elements | Dassault Systemes SIMULIA | https://docs.software.vt.edu/abaqusv2025/English/SIMACAEELMRefMap/simaelm-c-userelem.htm | 2026-06-12 | Tier 1 accessible manual mirror | Defines user element invocation, active DOF ordering, and the global-coordinate responsibility of user element matrices. | +| S7 | public example repository | `bibekanandadatta/Abaqus-UEL-Elasticity` | Bibekananda Datta | https://github.com/bibekanandadatta/Abaqus-UEL-Elasticity | 2026-06-12 | Tier 3 example repository | Useful implementation-pattern evidence only. The repository is not acceptance evidence for this project. | +| S8 | public example source | `src/uel_mech.for` | Bibekananda Datta | https://github.com/bibekanandadatta/Abaqus-UEL-Elasticity/blob/main/src/uel_mech.for | 2026-06-12 | Tier 3 example source | Shows a top-level Abaqus `UEL` wrapper outside modules, with calculation delegated to modular subroutines. | +| S9 | public example license | `LICENSE.md` | Bibekananda Datta | https://github.com/bibekanandadatta/Abaqus-UEL-Elasticity/blob/main/LICENSE.md | 2026-06-12 | Tier 3 license metadata | Source code is under BSD-3-Clause; documentation is CC BY-NC-SA 4.0. Do not copy code without preserving license obligations. | + +## Extracted Facts + +| fact_id | source | fact | relevance | +| --- | --- | --- | --- | +| F-UEL-001 | S2, S3 | Abaqus/Standard calls an external entry point named `UEL` for each general user-defined element when element calculations are needed. | A module-only helper subroutine is not enough; the linked user source must export the expected `UEL` entry point. | +| F-UEL-002 | S2, S3 | The manual UEL ABI is positional. The argument order is `RHS`, `AMATRX`, `SVARS`, `ENERGY`, element counts, real properties, coordinates, nodal solution arrays, element/procedure metadata, load arrays, predefined fields, `LFLAGS`, dimensions, `PNEWDT`, integer properties, and `PERIOD`. | The wrapper must not add extra arguments such as `status`, and it must not omit manual arguments such as `DU`, `V`, `A`, `JTYPE`, `TIME`, `PARAMS`, load arrays, `PREDEF`, `MDLOAD`, or `PERIOD`. | +| F-UEL-003 | S2, S3 | The wrapper convention includes `ABA_PARAM.INC` and manual dimensions such as `RHS(MLVARX,*)`, `AMATRX(NDOFEL,NDOFEL)`, `COORDS(MCRD,NNODE)`, `U(NDOFEL)`, `DU(MLVARX,*)`, and `PREDEF(2,NPREDF,NNODE)`. | The Abaqus-facing layer should use explicit Abaqus dimensions. Assumed-shape arrays are suitable for no-Abaqus module tests only when an explicit interface exists. | +| F-UEL-004 | S2, S3 | `RHS` is the element contribution to the right-hand-side vectors. In the common single-RHS nonlinear/static path it represents residual force, described as external minus internal force. | For a linear static element with no internally generated external load, the expected element residual contribution remains `-K_global * U` under the existing contract. | +| F-UEL-005 | S2, S3 | `AMATRX` is the element Jacobian, stiffness, damping, mass, or other matrix requested by `LFLAGS`. Nonzero terms should be defined even for symmetric matrices. | The beam UEL should fill the full requested 12-by-12 stiffness matrix. `UNSYMM` is unnecessary for the current symmetric linear scope. | +| F-UEL-006 | S2, S3 | `SVARS` are element solution-dependent state variables. `ENERGY` has eight element energy slots. `PNEWDT` can suggest automatic time increment changes. | A first-scope linear beam may ignore these physically, but the Abaqus ABI still passes them and the wrapper must handle their allocated sizes safely. | +| F-UEL-007 | S2, S3 | `LFLAGS` controls procedure and requested contribution. Relevant values include small vs large displacement in `LFLAGS(2)` and residual/Jacobian, stiffness-only, damping-only, mass-only, residual-only, initial-acceleration, and perturbation-output requests in `LFLAGS(3)`. | The wrapper must branch on `LFLAGS` rather than always assuming one static request. | +| F-UEL-008 | S3 | Static analysis requires `AMATRX`, `RHS`, and state variable update where applicable. The static procedure values are documented under `LFLAGS(1)=1,2`. | The first beam wrapper should at least verify static procedure scope, small displacement, and general-step behavior before filling outputs. | +| F-UEL-009 | S3, S6 | UEL solution variables are arranged node-major: all active DOFs for node 1, then all active DOFs for node 2, etc. | The current 12-DOF beam ordering is aligned if the input deck declares active DOFs `1,2,3,4,5,6` once for both nodes. | +| F-UEL-010 | S6 | Abaqus passes user element quantities in the global system; user element stiffness and related matrices should be provided with respect to global nodal directions. | Local beam stiffness must be transformed to global coordinates before assigning `AMATRX` or deriving `RHS`. | +| F-UEL-011 | S4 | A general user element declaration uses `*USER ELEMENT` with `TYPE=Un`, `NODES`, optional `COORDINATES`, `PROPERTIES`, `I PROPERTIES`, `UNSYMM`, and `VARIABLES`, followed by active DOF data lines. | The input deck is part of the ABI. The subroutine alone cannot define `NDOFEL`, `NNODE`, `NPROPS`, or active DOFs. | +| F-UEL-012 | S4 | For a general user element, `VARIABLES` declares the number of solution-dependent state variables and must be greater than zero; the default is one. | The existing contract `NSVARS=0` / `VARIABLES=0` is not consistent with this keyword rule. Use at least one state variable or verify a target-version exception before Abaqus-facing implementation. | +| F-UEL-013 | S5 | `*UEL PROPERTY` requires `ELSET`; when data lines are used, real property values precede integer property values. | A beam property list such as `E, G, A, Iy, Iz, J, a_ref_1, a_ref_2, a_ref_3` is a valid real-property strategy when `PROPERTIES=9` and `I PROPERTIES=0`. | +| F-UEL-014 | S5 | `*UEL PROPERTY` has an `ORIENTATION` parameter in Abaqus/Standard. The plain `UEL` argument list does not include an orientation matrix argument. | Do not rely on `ORIENTATION` being directly visible inside plain `UEL` unless an Abaqus run proves the intended behavior. Passing orientation through `PROPS` remains the safer first-scope contract. | +| F-UEL-015 | S7, S8 | The example repository describes `uel_mech.for` as the source implementing the UEL, while the main Abaqus `UEL` wrapper performs checks and delegates calculations to another subroutine. | This supports the project architecture: external `UEL` wrapper plus testable kernel/adapter logic. | +| F-UEL-016 | S8 | The example source keeps modules and helper subroutines in the same Fortran source path, then defines a top-level `SUBROUTINE UEL` outside those modules, includes `ABA_PARAM.INC`, dimensions all Abaqus arrays, initializes outputs, checks `LFLAGS`, and calls an internal element routine. | The pattern is compatible with Abaqus symbol lookup while preserving modular calculation logic. | +| F-UEL-017 | S9 | The example code license permits source redistribution under BSD-3-Clause conditions, while documentation is under CC BY-NC-SA 4.0. | The example can inform design, but this project should not copy source text without license handling. | + +## Minimum Abaqus-Facing UEL Contract + +The Abaqus-facing production source must expose a top-level external subroutine named `UEL` with the manual positional ABI. Local argument names can vary, but the order and shape cannot. For the current 3D beam scope the wrapper should preserve these groups: + +| group | required UEL arguments | +| --- | --- | +| element outputs | `RHS`, `AMATRX`, `SVARS`, `ENERGY`, `PNEWDT` | +| element sizes | `NDOFEL`, `NRHS`, `NSVARS`, `NPROPS`, `MCRD`, `NNODE`, `MLVARX`, `MDLOAD`, `NJPROP` | +| input arrays | `PROPS`, `COORDS`, `U`, `DU`, `V`, `A`, `TIME`, `PARAMS`, `JDLTYP`, `ADLMAG`, `DDLMAG`, `PREDEF`, `LFLAGS`, `JPROPS` | +| scalar metadata | `JTYPE`, `DTIME`, `KSTEP`, `KINC`, `JELEM`, `NDLOAD`, `NPREDF`, `PERIOD` | + +The wrapper should include `ABA_PARAM.INC` and use manual-style dimensions for all Abaqus arrays. A no-Abaqus adapter can keep assumed-shape arrays and a `status` output, but that adapter is not itself an Abaqus-callable UEL. + +## Minimum Input Deck Contract for the Current Beam + +For the first-scope two-node 3D Euler-Bernoulli beam, the research-supported `.inp` shape is: + +| keyword | required policy | +| --- | --- | +| `*USER ELEMENT` | use `TYPE=Un`, `NODES=2`, `COORDINATES=3`, `PROPERTIES=9`, and no `UNSYMM` for the symmetric linear scope | +| active DOF data line | declare `1,2,3,4,5,6` so `NDOFEL=12` for two nodes | +| `VARIABLES` | use at least `VARIABLES=1` or omit it and accept the default one state variable; do not assume Abaqus accepts zero without target-version evidence | +| `I PROPERTIES` | omit or set to zero for the first scope | +| `*ELEMENT` | use the same `TYPE=Un`; node order defines the positive beam axis from node 1 to node 2 | +| `*UEL PROPERTY` | provide `ELSET` and nine real properties in project-defined order | + +The current project interface document should be corrected before an external Abaqus run if it still says `VARIABLES=0` or requires `NSVARS=0`. + +## Pattern Observed in `uel_mech.for` + +The GitHub example is useful as a layout pattern, not as a source to copy. The relevant pattern is: + +- helper modules are available before the Abaqus entry point is compiled; +- the actual Abaqus entry is a top-level external `UEL`, not a module procedure; +- the wrapper includes `ABA_PARAM.INC` and manual array dimensions; +- wrapper code initializes Abaqus output arrays before calculation; +- wrapper code checks procedure flags and element type metadata; +- wrapper code delegates the element formulation to a lower-level routine with any extra internal arguments it wants. + +This is the missing layer in the current beam implementation. Our project already has a testable kernel and a no-Abaqus adapter, but it still needs the external `UEL` wrapper that Abaqus will actually call. + +## Findings Against Current `uel-3d-euler-beam` Implementation + +| finding_id | severity | evidence | impact | recommended follow-up | +| --- | --- | --- | --- | --- | +| C-UEL-001 | high | `rg` found no `SUBROUTINE UEL` in `src/fortran`; only `uel3deb_abi_static` is public in `src/fortran/uel_3d_euler_beam_abi_adapter.f90`. | Abaqus will not call the current implementation as a UEL unless another wrapper is provided at compile/link time. | Add `src/fortran/uel_3d_euler_beam_uel.for` or equivalent top-level `UEL` wrapper that calls the existing adapter/kernel. | +| C-UEL-002 | high | `uel3deb_abi_static` adds a `status` output and omits many manual UEL arguments. | The adapter is valid for no-Abaqus tests but is not the Abaqus ABI. | Keep it as test adapter; do not present it as production UEL wrapper. | +| C-UEL-003 | high | `uel3deb_abi_static` uses assumed-shape arrays such as `rhs(:, :)`, `amatrx(:, :)`, and `props(:)`. | Abaqus calls external user subroutines without an explicit Fortran module interface; assumed-shape dummy arguments are the wrong boundary for the top-level ABI. | The top-level wrapper should use manual explicit dimensions and pass slices to a module helper. | +| C-UEL-004 | high | Current interface and adapter require `NSVARS=0`; Abaqus `*USER ELEMENT` documentation says `VARIABLES` must be greater than zero and defaults to one. | An Abaqus input deck using `VARIABLES=0` may be rejected before the subroutine runs, or a valid deck may pass `NSVARS=1` and be rejected by the adapter. | Revise the Abaqus-facing contract to accept at least `NSVARS>=1` while ignoring `SVARS(1)` unless diagnostics are later approved. | +| C-UEL-005 | medium | Current adapter checks `LFLAGS(2)` and `LFLAGS(3)` but not `LFLAGS(1)` or `LFLAGS(4)`. | Non-static or linear perturbation calls could be mishandled by an Abaqus-facing wrapper if forwarded directly. | Wrapper should reject unsupported procedure/general-step states before kernel execution. | +| C-UEL-006 | medium | Current contract excludes `NDLOAD` and ignores load arrays, which is acceptable for first scope, but the top-level ABI must still receive `JDLTYP`, `ADLMAG`, `DDLMAG`, and `MDLOAD`. | Omitting these arguments breaks the manual ABI even if distributed loads are unsupported. | Preserve all manual load arguments and then enforce `NDLOAD=0` for first scope. | + +## Inferences and Design Guidance + +| inference_id | basis | inference | downstream owner | +| --- | --- | --- | --- | +| I-UEL-001 | F-UEL-001 through F-UEL-003, C-UEL-001 | The next implementation correction should add a real Abaqus wrapper, not replace the tested kernel. | Implementation Agent | +| I-UEL-002 | F-UEL-012, C-UEL-004 | `NSVARS=0` is a no-Abaqus convenience that conflicts with documented Abaqus keyword constraints. | I/O Definition Agent | +| I-UEL-003 | F-UEL-010 | The existing kernel's local-to-global matrix transformation remains directionally correct for Abaqus; the problem is the call boundary, not the beam matrix concept. | Formulation Agent | +| I-UEL-004 | F-UEL-014 | Passing the orientation reference through `PROPS(7:9)` remains an acceptable first-scope strategy. | I/O Definition Agent | +| I-UEL-005 | F-UEL-016 | A robust wrapper can be fixed-form `.for` for Abaqus compatibility, while calculation modules may remain `.f90` if the Abaqus compile path is made explicit. | Implementation Planning Agent | + +## Corrected Handoff for the 3D Beam UEL + +### I/O Definition Agent +- Replace `VARIABLES=0` / `NSVARS=0` with an Abaqus-compatible state-variable allocation policy, likely `VARIABLES=1` with unused `SVARS(1)` for first scope. +- Keep `PROPERTIES=9` and `I PROPERTIES=0` unless a later orientation or diagnostic mode requires integer properties. +- Define exact behavior for `LFLAGS(1)` static procedure values and `LFLAGS(4)` general-step requirement. + +### Implementation Agent +- Add a top-level external `SUBROUTINE UEL(...)` wrapper with the manual argument order and `ABA_PARAM.INC` include. +- Use manual explicit dimensions at the wrapper boundary. +- Call the existing no-Abaqus adapter or a small wrapper helper after mapping Abaqus arrays to the tested kernel inputs. +- Do not add Abaqus-specific logic into the matrix kernel unless tests require it. + +### Test Model Agent +- Add a source-smoke test that scans the production wrapper for `SUBROUTINE UEL`, `ABA_PARAM.INC`, the manual argument groups, and manual array dimensions. +- Update no-Abaqus ABI tests to cover the chosen `NSVARS` policy. +- Keep external Abaqus execution outside this repository; validation still depends on user-generated CSV and log-tail artifacts. + +### Numerical Review Agent +- Re-review residual sign only after the actual wrapper maps Abaqus `U` and `RHS` arrays. +- Confirm that accepting `NSVARS>=1` while leaving state values unchanged has no physical side effect for the linear static beam. + +## Applicability Limits +- This research did not run Abaqus and did not compile the public GitHub example. +- The accessible 2025 documentation mirror was used for line-level confirmation; final release should be checked against the user's installed Abaqus version and licensed documentation. +- The public GitHub example is Tier 3 evidence. It informs wrapper structure but does not validate this project's beam formulation. +- This document intentionally does not change production Fortran source. It identifies the next correction needed before Abaqus execution evidence can be meaningful. + +## Open Issues +- Target Abaqus version for external validation remains unspecified. +- Exact wrapper file extension and Abaqus compile path for mixed `.for` wrapper plus `.f90` modules must be decided before implementation. +- The current no-Abaqus tests assume `NSVARS=0`; they need revision if the production Abaqus wrapper requires `NSVARS>=1`. +- Whether `SVARS(1)` should be left unchanged, zeroed, or used as a diagnostic status slot requires an interface decision.