docs: define 3d euler beam uel interface

This commit is contained in:
김경종
2026-06-11 13:39:58 +09:00
parent 49bbd4d573
commit d23b08db8c
3 changed files with 387 additions and 5 deletions
+7 -4
View File
@@ -5,8 +5,8 @@
- Active objective: 3D Euler-Bernoulli beam Abaqus/Standard `UEL` - Active objective: 3D Euler-Bernoulli beam Abaqus/Standard `UEL`
- Active phase: `phases/uel-3d-euler-beam` - Active phase: `phases/uel-3d-euler-beam`
- Active owner: unassigned - Active owner: unassigned
- Current status: completed `phases/uel-3d-euler-beam/step3.md` numerical-review step - Current status: completed `phases/uel-3d-euler-beam/step4.md` interface-contract step
- Next action: execute `phases/uel-3d-euler-beam/step4.md` interface-contract step - Next action: execute `phases/uel-3d-euler-beam/step5.md` test/reference model planning step
## Completed ## Completed
@@ -25,6 +25,9 @@
- Completed step 3 numerical review for `uel-3d-euler-beam`. - Completed step 3 numerical review for `uel-3d-euler-beam`.
- Created `docs/numerical-reviews/uel-3d-euler-beam.md`. - Created `docs/numerical-reviews/uel-3d-euler-beam.md`.
- Updated `phases/uel-3d-euler-beam/index.json` step 3 to `completed`. - Updated `phases/uel-3d-euler-beam/index.json` step 3 to `completed`.
- Completed step 4 interface contract for `uel-3d-euler-beam`.
- Created `docs/io-definitions/uel-3d-euler-beam.md`.
- Updated `phases/uel-3d-euler-beam/index.json` step 4 to `completed`.
## In Progress ## In Progress
@@ -36,7 +39,7 @@
## Last Verification ## Last Verification
Latest verification after completing step 3 numerical review: Latest verification after completing step 4 interface contract:
```bash ```bash
python -m unittest discover -s scripts -p "test_*.py" python -m unittest discover -s scripts -p "test_*.py"
@@ -53,5 +56,5 @@ Result: all passed.
- Read `AGENTS.md`, `PLAN.md`, `PROGRESS.md`, and `WORKNOTE.md`. - Read `AGENTS.md`, `PLAN.md`, `PROGRESS.md`, and `WORKNOTE.md`.
- Confirm no other owner is active in this file. - Confirm no other owner is active in this file.
- Start `phases/uel-3d-euler-beam/step4.md`. - Start `phases/uel-3d-euler-beam/step5.md`.
- Update this file when step status changes or before handing off. - Update this file when step status changes or before handing off.
+378
View File
@@ -0,0 +1,378 @@
# 3D Euler-Bernoulli Beam UEL I/O Definition
## Metadata
- feature_id: uel-3d-euler-beam
- source_requirement: `docs/requirements/uel-3d-euler-beam.md`
- source_research: `docs/research/uel-3d-euler-beam-research.md`
- source_formulation: `docs/formulations/uel-3d-euler-beam.md`
- source_numerical_review: `docs/numerical-reviews/uel-3d-euler-beam.md`
- status: ready-for-reference-model-planning
- owner_agent: io-definition-agent
- date: 2026-06-11
## Scope and Compatibility Statement
- input_format: Abaqus input file (`.inp`) plus Abaqus/Standard `UEL` call data
- entry_point: Abaqus/Standard `UEL`
- compatibility: only the keyword, argument, and CSV subset defined here is supported
- solver_execution_policy: Abaqus jobs are run outside this repository by the user
- result_policy: this repository validates externally generated ODB-extracted CSV artifacts and does not parse ODB files
This interface contract deliberately avoids claiming full Abaqus input compatibility. It defines the first-scope two-node, small-displacement, linear elastic 3D Euler-Bernoulli beam `UEL` only.
## Abaqus/Standard UEL ABI Contract
The Abaqus/Standard production wrapper must preserve the manual `UEL` signature and include convention:
```fortran
SUBROUTINE UEL(RHS, AMATRX, SVARS, ENERGY, NDOFEL,
1 NRHS, NSVARS, PROPS, NPROPS, COORDS, MCRD, NNODE,
2 U, DU, V, A, JTYPE, TIME, DTIME, KSTEP, KINC, JELEM,
3 PARAMS, NDLOAD, JDLTYP, ADLMAG, PREDEF, NPREDF,
4 LFLAGS, MLVARX, DDLMAG, MDLOAD, PNEWDT, JPROPS,
5 NJPROP, PERIOD)
INCLUDE 'ABA_PARAM.INC'
DIMENSION RHS(MLVARX,*), AMATRX(NDOFEL,NDOFEL),
1 SVARS(*), ENERGY(8), PROPS(*), COORDS(MCRD,NNODE),
2 U(NDOFEL), DU(MLVARX,*), V(NDOFEL), A(NDOFEL),
3 TIME(2), PARAMS(*), JDLTYP(MDLOAD,*),
4 ADLMAG(MDLOAD,*), DDLMAG(MDLOAD,*),
5 PREDEF(2,NPREDF,NNODE), LFLAGS(*), JPROPS(*)
```
The wrapper must keep `aba_param.inc` / `ABA_PARAM.INC` as an Abaqus/Standard include, not a project-local replacement. The no-Abaqus kernel may use its own pure calculation interface, but that kernel interface is not defined in this document as source layout.
## Supported ABI Shape
| argument or count | supported value | validation rule |
| --- | --- | --- |
| `NNODE` | `2` | reject anything else |
| `NDOFEL` | `12` | reject anything else |
| active DOFs per node | `1,2,3,4,5,6` | input keyword and kernel vector order must match |
| `MCRD` | `>= 3` | read only `COORDS(1:3,1:2)` |
| `NPROPS` | `9` | reject anything else |
| `NJPROP` | `0` | first scope uses no integer properties |
| `NSVARS` | `0` | first scope stores no persistent state |
| `NRHS` | `1` | reject multi-RHS procedures |
| `MLVARX` | `>= 12` | required for `RHS(1:12,1)` and `DU(1:12,1)` addressing |
| `NDLOAD` | `0` | element-generated distributed loads are unsupported |
| `MDLOAD` | any Abaqus value | no `JDLTYP`, `ADLMAG`, or `DDLMAG` entries are used because `NDLOAD=0` is required |
| `NPREDF` | any Abaqus value | predefined fields are ignored; thermal and field coupling are unsupported |
Unsupported shape values are fatal input-contract violations. They must not silently produce zero stiffness or zero residual.
## DOF Ordering and Kernel Mapping
Abaqus element vector ordering is node-major:
```text
1 node 1 U1
2 node 1 U2
3 node 1 U3
4 node 1 UR1
5 node 1 UR2
6 node 1 UR3
7 node 2 U1
8 node 2 U2
9 node 2 U3
10 node 2 UR1
11 node 2 UR2
12 node 2 UR3
```
The wrapper passes this global vector order directly to the beam kernel as `q_global`. The kernel then applies the formulation transform:
```text
q_local = T*q_global
K_global = T^T*k_local*T
RHS = -K_global*q_global
```
No permutation is allowed between Abaqus `U(1:12)` and the kernel global vector. The local vector has the same node-major layout after projection to the local frame:
```text
[u1, v1, w1, th1_1, th2_1, th3_1, u2, v2, w2, th1_2, th2_2, th3_2]
```
## `PROPS` and `JPROPS` Schema
The first-scope interface uses `PROPS` only. `JPROPS` is not used.
| index | name | unit | required rule | semantic |
| --- | --- | --- | --- | --- |
| `PROPS(1)` | `E` | force / length^2 | finite and `> 0` | Young's modulus |
| `PROPS(2)` | `G` | force / length^2 | finite and `> 0` | shear modulus for Saint-Venant torsion |
| `PROPS(3)` | `A` | length^2 | finite and `> 0` | cross-sectional area |
| `PROPS(4)` | `Iy` | length^4 | finite and `> 0` | second moment about local 2; couples local `w/th2` |
| `PROPS(5)` | `Iz` | length^4 | finite and `> 0` | second moment about local 3; couples local `v/th3` |
| `PROPS(6)` | `J` | length^4 | finite and `> 0` | Saint-Venant torsion constant |
| `PROPS(7)` | `a_ref_1` | dimensionless direction component | finite | global approximate local 2 reference x-component |
| `PROPS(8)` | `a_ref_2` | dimensionless direction component | finite | global approximate local 2 reference y-component |
| `PROPS(9)` | `a_ref_3` | dimensionless direction component | finite | global approximate local 2 reference z-component |
Orientation vector rules:
- `a_ref = [PROPS(7), PROPS(8), PROPS(9)]` is a global direction vector, not a point coordinate.
- The vector magnitude is arbitrary because the kernel normalizes its projection.
- Reject `norm(a_ref) <= 1.0e-12`.
- Reject `norm(a_ref - dot(a_ref,e1)*e1) / norm(a_ref) <= 1.0e-8`, where `e1` is the node 1 to node 2 beam axis.
- The accepted local frame is `e1 = node1->node2`, `e2 = normalized projected a_ref`, and `e3 = cross(e1,e2)`.
`JPROPS` policy:
- `NJPROP` must be `0`.
- No integer flags, versions, orientation modes, or diagnostics are accepted in first scope.
- Any future `JPROPS` use requires a revised interface contract and new tests.
## Abaqus Input Keyword Subset
The reference model plan should use this `.inp` subset.
| keyword | support_status | required parameters | mapped concept | notes |
| --- | --- | --- | --- | --- |
| `*HEADING` | supported | none | model title | optional |
| `*NODE` | supported | none | node label and global coordinates | at least 3 coordinates per node for UEL geometry |
| `*ELEMENT` | supported | `TYPE=U1` or the approved user element type, optional `ELSET` | two-node UEL connectivity | connectivity order defines local axis 1 |
| `*ELSET` | supported | `ELSET` | element set | needed for `*UEL PROPERTY` |
| `*NSET` | supported | `NSET` | node set | recommended for BC/load/output selection |
| `*USER ELEMENT` | supported | `TYPE=U1`, `NODES=2`, `COORDINATES=3`, `PROPERTIES=9`, `VARIABLES=0` | UEL declaration | omit `UNSYMM`; omit `I PROPERTIES` |
| `*UEL PROPERTY` | supported | `ELSET` | real property assignment | data order is `PROPS(1:9)` |
| `*BOUNDARY` | supported | standard nodal DOF constraints | essential boundary conditions | DOFs 1-6 allowed |
| `*CLOAD` | supported | standard nodal concentrated load | external nodal loads/moments | loads are assembled by Abaqus outside UEL |
| `*STEP` | supported | optional `NAME` | analysis step | static only |
| `*STATIC` | supported | default or direct static data | small-displacement static procedure | no dynamics |
| `*OUTPUT` | supported | none | output request root | optional but required for external artifacts |
| `*NODE OUTPUT` | supported | `NSET` recommended | nodal CSV extraction source | request `U`, optional `UR`, `RF`/reaction moments as available |
| `*END STEP` | supported | none | step terminator | required |
Unsupported in first scope:
- `*DLOAD`, `*DSLOAD`, body forces, pressure loads, and distributed load generation
- `*MASS`, density, modal, transient, damping, and dynamic procedures
- `*BEAM SECTION`, `*BEAM GENERAL SECTION`, offsets, warping, and native beam section keywords for this UEL
- `*ORIENTATION` as the source of UEL orientation; use `PROPS(7:9)` instead
- material model keywords for UEL stiffness; use `*UEL PROPERTY` real values instead
- nonlinear geometry, follower loads, thermal expansion, predefined field coupling, plasticity, damage, creep, and viscoelastic behavior
### Required `*USER ELEMENT` Shape
The reference input deck should declare the user element with this logical content:
```text
*USER ELEMENT, TYPE=U1, NODES=2, COORDINATES=3, PROPERTIES=9, VARIABLES=0
1, 2, 3, 4, 5, 6
```
If the final reference model chooses a different `TYPE=Un` identifier to avoid conflicts, the same `NODES`, `COORDINATES`, `PROPERTIES`, `VARIABLES`, and active DOF contract still applies.
### Required `*UEL PROPERTY` Data Order
```text
*UEL PROPERTY, ELSET=<uel_element_set>
E, G, A, Iy, Iz, J, a_ref_1, a_ref_2
a_ref_3
```
Line breaks may follow Abaqus input formatting rules, but the logical property order is fixed.
## Subroutine Parameter Contract
| parameter | direction | first-scope responsibility |
| --- | --- | --- |
| `RHS(MLVARX,*)` | output | Initialize requested storage to zero every call; for supported residual requests, set `RHS(1:12,1) = -K_global*U(1:12)`. |
| `AMATRX(NDOFEL,NDOFEL)` | output | Initialize all `12x12` entries to zero every call; for supported stiffness requests, set all entries to `K_global`. |
| `SVARS(*)` | input/output | unused; require `NSVARS=0`; do not store diagnostics in first scope. |
| `ENERGY(8)` | input/output | set `ENERGY(1:8)=0.0` every supported call; do not use as validation evidence in first scope. |
| `NDOFEL` | input | must equal `12`. |
| `NRHS` | input | must equal `1`. |
| `NSVARS` | input | must equal `0`. |
| `PROPS(*)` | input | must contain the 9 real values defined above. |
| `NPROPS` | input | must equal `9`. |
| `COORDS(MCRD,NNODE)` | input | read `COORDS(1:3,1)` and `COORDS(1:3,2)` as original global node coordinates. |
| `MCRD` | input | must be at least `3`. |
| `NNODE` | input | must equal `2`. |
| `U(NDOFEL)` | input | total current nodal DOF estimate; used for static residual. |
| `DU(MLVARX,*)` | input | not used for first-scope static residual; may be used only by no-Abaqus tests to confirm it is ignored. |
| `V(NDOFEL)` | input | ignored; dynamics out of scope. |
| `A(NDOFEL)` | input | ignored; dynamics out of scope. |
| `JTYPE` | input | not used except optional diagnostics; element type compatibility is enforced by `.inp` contract. |
| `TIME(2)` | input | ignored for linear static stiffness/residual; may be copied to diagnostics only. |
| `DTIME` | input | ignored; no time-step-dependent behavior. |
| `KSTEP`, `KINC` | input | not used in calculations; may be used only for diagnostics. |
| `JELEM` | input | element label for diagnostics and traceability. |
| `PARAMS(*)` | input | ignored; no dynamic procedure parameters supported. |
| `NDLOAD` | input | must equal `0`; distributed loads unsupported. |
| `JDLTYP`, `ADLMAG`, `DDLMAG`, `MDLOAD` | input | ignored only after confirming `NDLOAD=0`. |
| `PREDEF`, `NPREDF` | input | ignored; predefined fields unsupported. |
| `LFLAGS(*)` | input | used to identify small-displacement static request and requested contribution. |
| `MLVARX` | input | must be at least `12`. |
| `PNEWDT` | input/output | do not modify for valid supported calls; invalid immutable inputs must fail explicitly rather than rely on cutback recovery. |
| `JPROPS(*)`, `NJPROP` | input | require `NJPROP=0`; `JPROPS` ignored. |
| `PERIOD` | input | ignored; not used in static analysis. |
## Supported `LFLAGS` Behavior
The first-scope wrapper supports only small-displacement static calls:
- require `LFLAGS(2)=0`
- support `LFLAGS(3)=1`, `2`, or `5`
- require `NRHS=1`
Contribution rules:
| condition | `AMATRX` | `RHS` | policy |
| --- | --- | --- | --- |
| `LFLAGS(3)=1` | `K_global` | `-K_global*U` | primary static call |
| `LFLAGS(3)=2` | `K_global` | zero | stiffness-only request |
| `LFLAGS(3)=5` | zero | `-K_global*U` | residual-only request |
| any other `LFLAGS(3)` | none | none | unsupported fatal diagnostic |
Unsupported request examples include mass, damping, dynamics, half-step residuals, perturbation-only behavior, and large-displacement kinematics.
## Validation Rules and Diagnostics
Invalid input must be caught before matrix assembly. The implementation may choose the exact Abaqus-compatible fatal-reporting mechanism later, but it must preserve these diagnostic identifiers and meanings in tests or logs where feasible.
| id | condition | expected behavior |
| --- | --- | --- |
| `UEL3DEB-E001` | `NDOFEL /= 12` | fatal unsupported element DOF count |
| `UEL3DEB-E002` | `NNODE /= 2` | fatal unsupported topology |
| `UEL3DEB-E003` | `MCRD < 3` | fatal missing 3D coordinates |
| `UEL3DEB-E004` | `NPROPS /= 9` | fatal wrong real property count |
| `UEL3DEB-E005` | `NJPROP /= 0` | fatal unsupported integer properties |
| `UEL3DEB-E006` | `NSVARS /= 0` | fatal unsupported state variables |
| `UEL3DEB-E007` | `NRHS /= 1` | fatal unsupported RHS count |
| `UEL3DEB-E008` | `MLVARX < 12` | fatal invalid RHS/DU leading dimension |
| `UEL3DEB-E009` | any required coordinate, `U`, or `PROPS` value is NaN or infinite | fatal nonfinite input |
| `UEL3DEB-E010` | `E`, `G`, `A`, `Iy`, `Iz`, or `J <= 0` | fatal nonpositive physical property |
| `UEL3DEB-E011` | element length `L <= 1.0e-12*max(1,norm(X1),norm(X2))` | fatal zero or near-zero element length |
| `UEL3DEB-E012` | `norm(a_ref) <= 1.0e-12` | fatal zero orientation reference |
| `UEL3DEB-E013` | `norm(a_perp)/norm(a_ref) <= 1.0e-8` | fatal near-parallel orientation reference |
| `UEL3DEB-E014` | `LFLAGS(2) /= 0` | fatal unsupported large-displacement or non-small-displacement request |
| `UEL3DEB-E015` | unsupported `LFLAGS(3)` | fatal unsupported contribution request |
| `UEL3DEB-E016` | `NDLOAD /= 0` | fatal unsupported element load input |
For valid supported calls, the wrapper should set deterministic outputs for the requested contribution and should not modify `PNEWDT`.
## Thin Wrapper Boundary
The Abaqus ABI wrapper owns:
- preserving the exact `UEL` signature and `ABA_PARAM.INC` include
- validating argument counts, dimensions, request flags, and property values
- extracting `X1`, `X2`, `U(1:12)`, and `PROPS(1:9)`
- mapping `LFLAGS` to requested stiffness/residual operations
- writing `AMATRX`, `RHS`, `SVARS`, `ENERGY`, and `PNEWDT` according to this contract
- reporting diagnostics with `JELEM`, `KSTEP`, and `KINC` when available
The no-Abaqus beam kernel conceptually owns:
- local frame construction from `X1`, `X2`, and `a_ref`
- local stiffness matrix assembly
- local-to-global transformation
- internal force and residual calculation
- numerical status reporting for invalid geometry or properties
This document does not prescribe Fortran module names, source files, helper APIs, or data structures.
## External CSV Extraction Schema
All CSV files are externally generated from Abaqus results by the user. They must be placed under `references/uel-3d-euler-beam/<model-id>/extracted/` and declared in that model's `metadata.json`.
### Required Common Columns
Every comparison CSV row must include:
| column | type | rule |
| --- | --- | --- |
| `step` | string | Abaqus step name or stable step index |
| `frame` | integer | frame or increment index |
| `time` | float | step time or total time used by extraction |
| `instance` | string | Abaqus instance name, or `ASSEMBLY` if not applicable |
| `node_label` | integer | Abaqus node label for nodal files |
| `quantity` | string | extracted output quantity, for example `U`, `UR`, `RF`, or `RM` |
| `component` | string | component label listed below |
| `coordinate_system` | string | must be `GLOBAL` for first-scope comparison |
| `unit` | string | declared user-consistent unit |
| `value` | float | numeric extracted value |
The CSV schema uses long format, one component per row, to avoid ambiguity between translational and rotational quantities.
### `nodal_displacements.csv`
Required for external solver-result comparison.
Allowed component rows:
| quantity | component | unit type | required |
| --- | --- | --- | --- |
| `U` | `U1`, `U2`, `U3` | length | yes |
| `UR` | `UR1`, `UR2`, `UR3` | radian | optional unless the reference model compares rotations |
Tolerance defaults:
- displacement absolute tolerance: `1.0e-8` in declared length units
- rotation absolute tolerance: `1.0e-8` radians unless the reference model narrows it
- relative tolerance: reference model may add scale-aware relative tolerance when needed
### `reactions.csv`
Required for external solver-result comparison at constrained nodes.
Allowed component rows:
| quantity | component | unit type | required |
| --- | --- | --- | --- |
| `RF` | `RF1`, `RF2`, `RF3` | force | yes for constrained translational DOFs |
| `RM` | `RM1`, `RM2`, `RM3` | force*length | required when constrained rotational DOFs are part of the benchmark comparison |
If the user's Abaqus extraction names rotational reactions differently, `metadata.json` must map the raw Abaqus variable/component name to the project component labels above.
Tolerance defaults:
- force and moment relative tolerance: `1.0e-6`
- absolute tolerance: Reference Model Agent must define a scale-aware floor for each benchmark if the expected reaction can be near zero
### Optional Element-Level CSVs
No element force, stress, strain, section force, or energy CSV is required or approved for first-scope external comparison. Such CSVs require a later `SVARS` or output-recovery contract.
## Reference Artifact Metadata Requirements
Each external reference model must include metadata fields sufficient for `scripts/validate_reference_artifacts.py` plus feature-level declarations:
- `feature_id`: `uel-3d-euler-beam`
- Abaqus version and precision
- compiler vendor/name/version used for the user subroutine build, when applicable
- user subroutine source file hashes after implementation exists
- `model.inp` path and hash
- declared extracted CSV files and their schema version
- ODB extraction provenance, including extraction script name/version if available
- unit declarations for length, force, stress, moment, and rotation
- coordinate system declaration: `GLOBAL` for nodal comparison CSVs
## Open Issues and Downstream Handoff
### Reference Model Agent
- Use the keyword subset and property order in this document for `model.inp` examples.
- Include no-Abaqus tests for exact `PROPS(1:9)` mapping, `NJPROP=0`, `NSVARS=0`, `NDOFEL=12`, `NNODE=2`, and active DOF order.
- Include negative tests for every `UEL3DEB-E###` validation rule that is practical in the no-Abaqus harness.
- Define benchmark-specific CSV filenames and near-zero absolute reaction tolerances.
- Keep external artifact generation outside this repository.
### Implementation Planning Agent
- Preserve the Abaqus `UEL` signature exactly in the wrapper.
- Keep the wrapper thin and route only validated arrays/scalars to a no-Abaqus beam kernel.
- Implement deterministic zeroing for non-requested `AMATRX`/`RHS` in no-Abaqus drivers so tests are stable.
- Do not implement `SVARS`, `ENERGY`, distributed loads, dynamics, `JPROPS`, or `*ORIENTATION` support in first scope.
### Reference Verification Agent
- Validate only externally generated CSVs declared in metadata.
- Match rows by `step`, `frame`, `instance`, `node_label`, `quantity`, `component`, `coordinate_system`, and `unit`.
- Reject CSVs with missing units, missing coordinate systems, unsupported component labels, or undeclared files.
- Compare first-scope external results using nodal displacement and reaction CSVs only.
+2 -1
View File
@@ -29,7 +29,8 @@
{ {
"step": 4, "step": 4,
"name": "interface", "name": "interface",
"status": "pending" "status": "completed",
"summary": "Created docs/io-definitions/uel-3d-euler-beam.md with the Abaqus/Standard UEL signature, supported ABI shape, DOF and kernel mapping, PROPS/JPROPS and orientation schema, input keyword subset, LFLAGS/RHS/AMATRX/SVARS/ENERGY/PNEWDT responsibilities, validation diagnostics, CSV extraction schemas, and thin-wrapper boundary."
}, },
{ {
"step": 5, "step": 5,