From 73dc761282fc88e0c5fa0dec064f25e4c9525720 Mon Sep 17 00:00:00 2001 From: "KOKO\\Mimi" Date: Wed, 12 Aug 2026 01:23:56 +0900 Subject: [PATCH] docs: define MITC4 shell I/O contract --- .../linear-static-mitc4-shell-io.md | 759 ++++++++++++++++++ 1 file changed, 759 insertions(+) create mode 100644 docs/io-definitions/linear-static-mitc4-shell-io.md diff --git a/docs/io-definitions/linear-static-mitc4-shell-io.md b/docs/io-definitions/linear-static-mitc4-shell-io.md new file mode 100644 index 0000000..ae5fdf3 --- /dev/null +++ b/docs/io-definitions/linear-static-mitc4-shell-io.md @@ -0,0 +1,759 @@ +# Linear Static MITC4 Shell I/O Definition + +## Metadata + +- feature_id: `linear-static-mitc4-shell` +- source_requirement: `docs/requirements/linear-static-mitc4-shell.md` +- source_research: `docs/research/linear-static-mitc4-shell-research.md` +- source_formulation: `docs/formulations/mitc4-shell-formulation.md` +- source_numerical_review: `docs/numerical-reviews/linear-static-mitc4-shell-review.md` +- source_commits: requirements `5c3025a`, research `02680dc`, formulation + `6cb0302`, numerical review `ebb2657`, S4 legacy artifacts `57122b0` +- status: `ready-for-reference-model-not-implementation-planning` +- owner_agent: `io-definition-agent` +- date: `2026-08-12` +- authoritative_output: `results.h5` +- hdf5_schema_version: `0` +- current_reference_alias: `reference/shell/` as read-only S4 legacy alias +- missing_reference_family: separate canonical S4R bundle +- implementation_planning_authorized: `false` + +This document defines the approved semantic input and output contract for the +linear-static MITC4 shell feature. It does not define parser, model, HDF5-writer, or +comparison-tool C++ APIs and does not claim full Abaqus compatibility or Abaqus +`S4`/`S4R` formulation equivalence. + +The user approved the following I/O-specific decisions on `2026-08-12`: + +1. `S4` and `S4R` reference artifacts remain separate even though both source types + map to one internal `FESA-MITC4` formulation. +2. The optional positive integer on a `*SHELL SECTION` thickness row is accepted + without a warning and has no semantic effect on FESA quadrature. FESA always uses + the formulation's `2 x 2 x 2` rule. +3. The existing `reference/shell/` files are retained without mutation as an exact + S4 legacy alias. Missing provenance is supplied only by a separately approved + Reference Model contract; it is not inferred here. +4. HDF5 schema version `0` is extended additively with MITC4-specific datasets while + retaining the existing common metadata, nodal-result, diagnostic, CLI, and + failure-atomicity conventions. + +Numerical Review has accepted the current linear formulation but has not approved +the drilling default, geometry/director thresholds, U mixed tolerance, or UR warning +threshold. This I/O contract names where those approved values must appear but does +not invent implementation defaults. + +## 1. Abaqus Input Scope + +- input_format: Abaqus input file (`.inp`) +- supported_analysis: exactly one small-displacement, small-rotation linear-static + step containing four-node `S4` and/or `S4R` shell elements +- ordinary_unit_system: user-consistent; FESA does not infer SI or another unit + system from an `.inp` file +- internal_element_formulation: `FESA-MITC4` +- compatibility_disclaimer: only the keyword locations, parameters, and data grammar + in this document are supported + +`supported` means only the documented subset is semantically interpreted. `warning +no-op` means the syntax is consumed and a structured warning is recorded, but no +Domain, AnalysisModel, numerical, or mandatory-output meaning changes. The optional +`*SHELL SECTION` integration-point field is a separately approved silent provenance +field, not a warning no-op keyword. + +| keyword | status and allowed location | required parameters and data grammar | semantic mapping | unsupported behavior | +| --- | --- | --- | --- | --- | +| `*HEADING` | supported; optional top-level first keyword | no parameters; zero or more text rows until next keyword | original heading retained as source metadata | nested location or parameters are input errors | +| `*PART` / `*END PART` | supported; top-level model block | `NAME=` required; no `*END PART` data | scope for part-local nodes, elements, sets, and shell sections | unclosed/nested part or duplicate name is an input error | +| `*NODE` | supported; part scope | no parameters; each row `node_label,x,y,z` | positive source node label and finite global Cartesian coordinates | wrong arity, duplicate label, or nonfinite value is an input error | +| `*ELEMENT` | supported; part scope | `TYPE=S4` or `TYPE=S4R`; each row `element_label,node_1,node_2,node_3,node_4` | ordered four-node shell connectivity; source type retained separately; internal type is `FESA-MITC4` | another type is `unsupported-element-formulation`; wrong arity, repeated connected node, or dangling node is an error | +| `*NSET` | supported; part or assembly scope | `NSET=`; optional `GENERATE`; assembly scope requires `INSTANCE=`; explicit labels or `first,last,increment` | deterministic node-set membership | mixed-instance set, invalid generate range, duplicate name, or dangling member is an error | +| `*ELSET` | supported; part or assembly scope | `ELSET=`; optional `GENERATE`; assembly scope requires `INSTANCE=`; same row rules as `*NSET` | deterministic element-set membership | mixed-instance set, invalid range, duplicate name, or dangling member is an error | +| `*MATERIAL` | supported; top-level model data | `NAME=` required; no data | owns exactly one approved isotropic `*ELASTIC` definition | duplicate name, missing/duplicate elasticity, or another material model is an error | +| `*ELASTIC` | supported; current material scope | no parameters; exactly one row `E,nu` | homogeneous isotropic elasticity; `G=E/(2(1+nu))` | extra row/field, dependency/temperature data, nonfinite value, `E<=0`, or `nu<=-1`/`nu>=0.5` is an error | +| `*SHELL SECTION` | supported; part scope | `ELSET=` and `MATERIAL=` required; exactly one row `thickness[,integration_points]` | one centered homogeneous layer with constant thickness | composite/layer data, offset, orientation, distributed/nodal thickness, missing reference, or conflicting assignment is an error | +| `*ASSEMBLY` / `*END ASSEMBLY` | supported; exactly one top-level assembly | `NAME=` required; no end data | scope for identity instances and assembly sets | nested/duplicate assembly is `unsupported-nested-assembly` | +| `*INSTANCE` / `*END INSTANCE` | supported; assembly scope | `NAME=`, `PART=` required; no intervening data | named identity copy; multiple instances of a part are allowed | translation/rotation data is `unsupported-instance-transform`; duplicate or dangling instance is an error | +| `*BOUNDARY` | supported; top-level model data or sole step | no parameters; each row `target,first_dof,last_dof[,value]`; omitted value is exact zero | prescribed global shell DOFs 1 through 6 | invalid arity/range, unresolved target, or conflicting expanded value is an error | +| `*CLOAD` | supported; sole step | no parameters; each row `target,dof,magnitude` | concentrated global nodal force/moment on DOFs 1 through 6 | invalid arity/DOF, nonfinite magnitude, unresolved target, or drilling-direction aggregate moment is an error | +| `*STEP` / `*END STEP` | supported; exactly one top-level history block | optional `NAME`; optional `NLGEOM=NO`; no end data | one canonical result identity `(Step-1,frame 0)` | second step is `unsupported-multiple-step`; `NLGEOM=YES` is `unsupported-nonlinear-geometry` | +| `*STATIC` | supported; exactly once in sole step | no parameters; exactly one row `initial_increment,time_period,minimum_increment,maximum_increment` | source values retained; exactly one linear solve and frame 0 | another procedure or missing/extra/nonfinite/nonpositive field is an error | +| `*PREPRINT` | warning no-op; top-level | all parameters retained then ignored; no data | accepts generator control | no semantic object is created | +| `*RESTART` | warning no-op; sole step | all parameters retained then ignored; no data | accepts a legacy restart request | no restart state is created | +| `*OUTPUT, FIELD` | warning no-op; sole step | parameters and subordinate variable data retained then ignored | accepts field-output request root | cannot select, suppress, or expand mandatory FESA output | +| `*OUTPUT, HISTORY` | warning no-op; sole step | parameters and subordinate variable data retained then ignored | accepts history-output request root | no history dataset is created | +| `*NODE OUTPUT` | warning no-op; active output request | all parameters and following variable rows ignored | accepts legacy nodal request | cannot change the HDF5 schema | +| `*ELEMENT OUTPUT` | warning no-op; active output request | all parameters and following variable rows ignored | accepts legacy element request | cannot change the HDF5 schema | +| `*CONTACT OUTPUT` | warning no-op; active output request | all parameters and following variable rows ignored | accepts legacy contact-output syntax only | no contact model or output is created | + +`*DLOAD`, pressure, gravity, body force, edge traction, follower load, explicit +normal/director input, `*ORIENTATION`, composite/layer controls, `*INCLUDE`, and +model-affecting keywords not listed above are `unsupported-keyword` errors. A mixed +B33/shell model and a shell-beam joint are `unsupported-mixed-element-model`; the +presence of an existing B33 implementation does not expand this feature contract. + +Multiple `*ELEMENT` blocks containing `S4`, `S4R`, or both are allowed. Every element +retains its own source element type, and source type never changes FESA quadrature, +tying, drilling, recovery, or numerical path. + +### 1.1 Shell-section data rule + +The exact accepted data row is + +```text +thickness[,integration_points] +``` + +- `thickness` is a finite `double` strictly greater than zero. +- If present, `integration_points` is a positive base-10 integer. +- The optional field is syntactically accepted without a warning and has no Domain, + quadrature, recovery, or output effect. +- The raw input remains recoverable through the source file/content identity, but + no `source_integration_points` physical property is created. +- FESA stiffness remains four midsurface Gauss locations times two thickness Gauss + locations, including when the source value is `5` as in the S4 legacy deck. + +Silently accepting this field is an explicit feature contract, not a general rule +that Abaqus section parameters may be ignored. + +### 1.2 Nesting grammar + +```text +input-file + := heading? part+ assembly material+ model-boundary* step EOF + +part + := *PART + node-block+ element-block+ (nset | elset)* shell-section+ + *END PART + +assembly + := *ASSEMBLY + instance+ assembly-set* + *END ASSEMBLY + +instance + := *INSTANCE *END INSTANCE + +step + := *STEP *STATIC step-boundary* cload* allowed-no-op* *END STEP +``` + +All parts close before assembly. Assembly contains only identity instances and +assembly-level sets. Instance-local node/element redefinition, nested assembly, +instance transforms, and dependent/independent mesh semantics are excluded. + +## 2. Syntax Policy + +- The first non-whitespace character of a keyword line is `*`; `**` begins a comment. +- Comments have no semantic effect but retain normalized file and 1-based line + provenance for neighboring parsed records. +- Keyword names, parameter names, enumerated values, and named-reference lookup are + ASCII case-insensitive. Raw source spelling remains available for identity and + diagnostics. +- Keyword and data fields are comma-separated with surrounding whitespace removed. + A required empty field, an unexpected trailing field, or a malformed numeric token + is an input error. +- Keyword continuation, physical-line continuation, quoted/multiline names, and + include files are unsupported. Each logical keyword or data row is complete on one + physical line. +- Node/element labels and explicit set members are positive base-10 integers. + Internal numeric IDs do not replace preserved source label text. +- All real-valued input is finite. `NaN` and positive/negative infinity are rejected. +- Every parsed keyword, parameter, data row, and semantic entity remains traceable to + normalized file path, 1-based line, raw keyword, and source identity. +- Output-request variable data is a warning no-op only while subordinate to an + allowlisted output keyword. An unexpected standalone data line is an input error. + +### 2.1 Duplicate and dangling-reference policy + +- Part, assembly, instance, material, set, and section identities are unique in + their documented case-insensitive scope. +- Node and element source labels are unique within a part. +- Multiple identity instances of the same part are distinct through instance name. +- Connectivity, set membership, instance `PART`, section `ELSET`/`MATERIAL`, assembly + set `INSTANCE`, boundary target, and load target all resolve before Domain commit. +- Duplicate definitions use `duplicate-entity`; unresolved references use + `unresolved-reference`. A partial Domain is never passed to analysis. + +## 3. Model Data Mapping + +### 3.1 Stable source identity and ordering + +After identity-instance expansion, each node and element has + +```text +SourceEntityId { instance_name, source_label } +``` + +Raw spelling and the case-insensitive lookup key are separate. Stable internal IDs +follow input part declaration order, instance declaration order, and part-local +entity declaration order. Hash iteration and thread scheduling cannot affect IDs, +director accumulation, result rows, or diagnostics. + +Assembly sets name one identity instance and resolve their numeric members to that +instance's part-local source identities. A set cannot mix members from multiple +instances in the approved grammar. + +### 3.2 Nodes, elements, sets, material, and section + +- A node has global Cartesian coordinates, stable internal ID, source identity, + geometry-derived initial director, and deterministic tangent frame. +- A shell element has ordered connectivity `[node_1,node_2,node_3,node_4]`, stable + internal ID, source identity, preserved source type `S4` or `S4R`, internal type + `FESA-MITC4`, and exactly one resolved section/material. +- Connectivity order fixes natural corners `1=(-1,-1)`, `2=(+1,-1)`, + `3=(+1,+1)`, `4=(-1,+1)` and positive thickness through + `A_xi x A_eta`. Connectivity is not silently reversed. +- Explicit set order follows data rows. Generated sets use inclusive + `first,last,increment` order. Set members remain round-trippable to source identity. +- Material preserves `E` and `nu`; `G=E/(2(1+nu))` is derived. +- Section preserves positive constant thickness and resolved material. It represents + one centered homogeneous isotropic layer. +- Multiple materials, sections, element sets, `S4` blocks, and `S4R` blocks are + allowed when each element resolves to exactly one valid assignment. + +### 3.3 Director and geometry preprocessing + +Initial directors are semantic model data derived after instance expansion, not +parser-provided rotations. + +1. Process accepted shell elements in stable source-element order. +2. Compute each source-order-positive center normal candidate and its `2 x 2` + surface-area weight. +3. At each node, sort incident elements by stable source identity and reject any + nonpositive pairwise normal dot product before averaging. +4. Form and normalize the deterministic area-weighted director. +5. Apply the approved smooth-patch angle criterion. +6. Select the least-aligned global basis axis with fixed `x,y,z` tie order and form + right-handed nodal frame `[a,b,d]`. + +The complete center, volume-Gauss, tying, and committed-recovery inventory uses the +formulation's `J`, `j_s`, `a_g`, `c_d`, `r_J`, and `theta_w` measures. Exact numerical +thresholds are required inputs from a future approved Numerical Review decision; +this document supplies no fallback, clamp, point omission, normal flip, or default +axis. + +Geometry and director failures are model-validation errors. Duplicate connectivity, +self-intersection, degenerate/reversed geometry, invalid Jacobians, opposed incident +normals, and unapproved sharp folds fail closed. + +## 4. History Data Mapping + +### 4.1 Step and procedure + +Exactly one history object is created. The source step name remains provenance, but +the result identity is literal `Step-1`, frame index `0`. The four `*STATIC` values +are finite positive source data and `minimum_increment <= maximum_increment`; they do +not create increments, iteration history, or additional frames. + +`NLGEOM=NO` or omission is accepted. `NLGEOM=YES`, another procedure, or another step +is unsupported. The future nonlinear formulation does not expand this history +contract. + +### 4.2 Boundary conditions + +Boundary target is a direct source node label or node set and expands to stable +source node identities. `first_dof <= last_dof`, with both in `1..6`. Omitted value +is exact zero; a finite nonzero value is supported. Model-level and step-level +boundaries activate in the sole step. Different prescribed values on one expanded +node/DOF are an error. + +| DOF | kinematic component | unit dimension | +| ---: | --- | --- | +| 1 | `U1` | length | +| 2 | `U2` | length | +| 3 | `U3` | length | +| 4 | `UR1` | radian/dimensionless angle | +| 5 | `UR2` | radian/dimensionless angle | +| 6 | `UR3` | radian/dimensionless angle | + +### 4.3 Concentrated loads and drilling projection + +`*CLOAD` target expansion matches boundary expansion. Rows resolving to the same +node/DOF are accumulated in stable source order before physical admissibility is +tested. + +| DOF | load component | unit dimension | +| ---: | --- | --- | +| 1 | `F1` | force | +| 2 | `F2` | force | +| 3 | `F3` | force | +| 4 | `M1` | force*length | +| 5 | `M2` | force*length | +| 6 | `M3` | force*length | + +For aggregate nodal moment `M_I` and approved unit director `d_I`, exact-zero moment +is accepted as a separate case. Otherwise compute, without denominator clamping, + +```text +rho_M = abs(dot(d_I,M_I)) / norm(M_I) +``` + +and require `rho_M <= 1e-12`. Failure is `unsupported-drilling-load`. No part of a +rejected physical moment is transferred to numerical drilling stabilization. + +### 4.4 Output requests + +Allowlisted Abaqus output requests do not activate history output and cannot change +the mandatory HDF5 inventory. FESA writes all datasets in Section 6 on a successful +run even when the input contains no output request. Requested Abaqus variables that +have no FESA dataset do not create empty synthetic physical results. + +## 5. Internal Model Contract + +- Domain owns the complete immutable-after-mapping definition of nodes, shell + elements, sets, materials, sections, boundary/load data, sole static step, stable + source identities, initial directors, and source formulation labels. +- `S4`/`S4R` remains source metadata. Numerical selection uses one explicit internal + identity, `FESA-MITC4`. +- AnalysisModel is a non-owning view of active Domain objects and does not copy them. +- Nodes/elements do not own equation IDs. Six-DOF numbering, constrained/free maps, + scatter maps, and sparse pattern are DofManager responsibilities. +- Boundary and load records retain both the source target and their deterministic + expanded source-node identities. +- Section/material assignment is resolved before element processing. An element with + zero or multiple assignments is invalid. +- AnalysisState contains only the current linear-static displacement, external and + internal force, full residual/reaction, shell recovery, equilibrium, and energy + rows. No nonlinear director history, iteration state, velocity, or acceleration is + allocated. +- Midsurface generalized rows, section-position stress rows, nodal rows, global + equilibrium rows, and drilling evidence have distinct quantity/location identity. + Values from different locations are never averaged to satisfy a schema. + +## 6. Output HDF5 Schema + +The sole authoritative output is `results.h5`, schema version `0`. MITC4 extends +that schema additively; it does not migrate or reinterpret B33 datasets. Every +string is UTF-8, every physical real is IEEE-754 float64, stable internal IDs are +uint64, and constraint masks are uint8. + +The literal result path identity is `(Step-1,frame 0)`. No history or nonlinear +frame group is created. + +### 6.1 Metadata + +`/metadata` is a group with these required scalar attributes: + +| attribute | required value or meaning | +| --- | --- | +| `schema_version` | integer `0` | +| `feature_id` | `linear-static-mitc4-shell` | +| `solver_version` | executing solver version | +| `source_input_identity` | normalized input path plus auditable content identity | +| `unit_system_label` | ordinary run: `user-consistent-unspecified`; a reference run uses the externally approved label from its Reference Model metadata | +| `coordinate_convention` | `global-cartesian; shell-local=(e1,e2,e3); positive-thickness=+zeta` | +| `internal_formulation` | `FESA-MITC4` | +| `integration_rule` | `2x2x2-gauss; mitc4-edge-midpoint-shear` | +| `step_name` | `Step-1` | +| `frame_index` | integer `0` | +| `drilling_reference_family` | exact approved family identifier used in this run | +| `drilling_nominal_coordinate` | approved dimensionless nominal `rho_d` policy identifier/value | +| `theta_smooth` | approved smooth-patch bound used in validation | +| `tau_ang` | approved `j_s` bound | +| `tau_area` | approved `a_g` bound | +| `tau_dir` | approved `c_d` bound | +| `tau_var` | approved `r_J` bound | +| `theta_warp` | approved `theta_w` bound | +| `drilling_energy_warning_threshold` | approved warning rule identifier/value | + +No unapproved stand-in number is legal in these numerical-policy attributes. The writer can +be implementation-ready only after Numerical Review approves their values and +definition identifiers. + +### 6.2 Model identity datasets + +| exact dataset path | shape/dtype | row identity and fields | attributes/order | +| --- | --- | --- | --- | +| `/model/nodes` | `[node_count]` compound | `internal_node_id:uint64`, `instance_name:utf8`, `source_label:utf8`, `coordinates:float64[3]` | internal node ID ascending; global Cartesian; coordinate unit `length` | +| `/model/elements` | `[element_count]` compound | `internal_element_id:uint64`, `instance_name:utf8`, `source_label:utf8`, `source_element_type:utf8`, `internal_formulation:utf8`, `node_internal_ids:uint64[4]`, `shell_section_internal_id:uint64`, `material_internal_id:uint64` | internal element ID ascending; connectivity in exact source order; source type `S4|S4R`; formulation `FESA-MITC4` | +| `/model/shell/nodal_director` | `[node_count,3]` float64 | `/model/nodes` row | dimensionless global components; unit norm within `1e-12` frame check | +| `/model/shell/nodal_frame` | `[node_count,3,3]` float64 | `/model/nodes` row, axis row `[a,b,d]`, global component column | dimensionless; right-handed and orthonormal | +| `/model/shell/materials` | `[material_count]` compound | `internal_material_id`, raw `name`, `E`, `nu` | stable declaration order; units `[force/length^2,1]` | +| `/model/shell/sections` | `[section_count]` compound | `internal_section_id`, source keyword file/line identity, source ELSET, `material_internal_id`, `thickness` | stable declaration order; centered single layer; thickness unit `length` | +| `/model/nodal_constraint_mask` | `[node_count,6]` uint8 | node row and global DOF order | `0=free`, `1=constrained`; existing HDF5 component names `[UX,UY,UZ,URX,URY,URZ]` | +| `/model/prescribed_displacement` | `[node_count,6]` float64 | same row/component order | constrained entry is prescribed value; free entry is exact zero with mask as authority | +| `/model/shell/midsurface_locations` | `[4,2]` float64 | `location_index` implicit row 1..4; columns `[xi,eta]` | exact order in Section 6.3; dimensionless | +| `/model/shell/section_positions` | `[3]` float64 | rows `BOTTOM,MIDDLE,TOP`; value is `zeta` | exact values `[-1,0,+1]`; physical `z=t*zeta/2` | + +The optional source shell-section integration-point field is not written as a +physical model property. Exact source bytes remain auditable through +`source_input_identity`. + +### 6.3 Fixed shell location ordering + +Let `g=1/sqrt(3)`. Every shell result with a four-location axis uses: + +| location index | name | `(xi,eta)` | +| ---: | --- | --- | +| 1 | `GP1` | `(-g,-g)` | +| 2 | `GP2` | `(+g,-g)` | +| 3 | `GP3` | `(+g,+g)` | +| 4 | `GP4` | `(-g,+g)` | + +Every three-section-position axis uses `BOTTOM(zeta=-1)`, `MIDDLE(zeta=0)`, then +`TOP(zeta=+1)`. Location indices are not Abaqus integration-point numbers and must +not be relabeled as such in a reference comparison. + +### 6.4 Step/frame result datasets + +All datasets are mandatory after a successful run, independent of Abaqus output +requests. + +| quantity | exact dataset path | shape | row identity and component order | units/coordinates/location | +| --- | --- | --- | --- | --- | +| displacement | `/steps/Step-1/frames/0/nodal/displacement` | `[node_count,6]` float64 | `/model/nodes` row; existing HDF5 component names `[UX,UY,UZ,URX,URY,URZ]` | `[length x3,radian x3]`; global; nodal | +| reaction/full residual | `/steps/Step-1/frames/0/nodal/reaction` | `[node_count,6]` float64 | `/model/nodes` row; `[RF1,RF2,RF3,RM1,RM2,RM3]` | `[force x3,force*length x3]`; global; nodal; constrained entry is physical reaction, free entry is residual evidence | +| local frame | `/steps/Step-1/frames/0/element/shell/local_frame` | `[element_count,4,3,3]` float64 | element row, location row, axis row `[e1,e2,e3]`, global component column | dimensionless; location-specific shell local frame | +| generalized strain | `/steps/Step-1/frames/0/element/shell/generalized_strain` | `[element_count,4,8]` float64 | element row, location row; `[E11,E22,G12,K11,K22,K12,G13,G23]` | `[1,1,1,1/length,1/length,1/length,1,1]`; shell local; midsurface location | +| section resultant | `/steps/Step-1/frames/0/element/shell/section_resultant` | `[element_count,4,8]` float64 | element row, location row; `[N11,N22,N12,M11,M22,M12,Q13,Q23]` | `[force/length x3,force x3,force/length x2]`; shell local; midsurface location | +| in-plane stress | `/steps/Step-1/frames/0/element/shell/stress` | `[element_count,4,3,3]` float64 | element row, location row, section-position row, component `[S11,S22,S12]` | `force/length^2`; shell local; direct bottom/middle/top evaluation | +| drilling stiffness | `/steps/Step-1/frames/0/element/shell/drilling_stiffness` | `[element_count,4]` float64 | element row and source-local node position 1..4 | `force*length`; actual positive `k_d,I` used | +| drilling ratio | `/steps/Step-1/frames/0/element/shell/drilling_ratio` | `[element_count,4]` float64 | same row and source-local node position | dimensionless actual `rho_d,I=k_d,I/D_iso` | +| energy | `/steps/Step-1/frames/0/global/energy` | `[2]` float64 | `[PHYSICAL_STRAIN_ENERGY,DRILLING_STABILIZATION_ENERGY]` | `force*length`; deterministic element reduction | +| force/moment balance | `/steps/Step-1/frames/0/global/equilibrium` | `[6]` float64 | `[FORCE_1,FORCE_2,FORCE_3,MOMENT_1,MOMENT_2,MOMENT_3]` | `[force x3,force*length x3]`; global; moment reference point is global origin `[0,0,0]` | +| verification metrics | `/steps/Step-1/frames/0/global/verification_metrics` | `[3]` float64 | `[FREE_RESIDUAL_NORMALIZED,FORCE_BALANCE_NORMALIZED,MOMENT_BALANCE_NORMALIZED]` | dimensionless; metric-definition IDs and thresholds required as attributes | +| diagnostics | `/diagnostics` | `[diagnostic_count]` compound | `severity`, `code`, `file`, `line`, `keyword`, `entity_identity`, `message` | deterministic order; required empty dataset when count is zero | + +`S33=0` is a plane-stress assumption and is not emitted. `S13`, `S23`, physical +drilling stress/resultant, and nodally extrapolated/averaged shell stress are not +created. Transverse shear is externally represented through `Q13/Q23`. + +Each numeric result dataset has required attributes `component_names`, +`component_unit_dimensions`, `coordinate_system`, `location`, `step_name=Step-1`, +and `frame_index=0`. Shell element results additionally identify their source +element type, internal formulation, midsurface-location dataset, section-position +dataset when applicable, and local-frame dataset. + +The verification-metric definitions and approved thresholds remain Numerical Review +dependencies. Until their formula IDs are approved, this path is a fixed schema +reservation and not an implementation default. + +### 6.5 Reaction, residual, equilibrium, and energy meaning + +`nodal/reaction` stores the assembled full residual `K*d-F`; a duplicate nodal +residual dataset is not written. `/model/nodal_constraint_mask` controls meaning: + +- constrained entry: physical reaction; +- free entry: equation-equilibrium residual evidence. + +Global force/moment balance uses applied `CLOAD` plus constrained reaction about +the global origin. Free residual entries remain separate evidence and are not added +as physical reactions. Energy is split exactly into physical strain energy and +numerical drilling energy. A near-zero physical-energy denominator is never clamped +to form a misleading ratio; the later approved warning policy must classify that +case explicitly. + +### 6.6 Atomic finalization + +The writer creates a temporary candidate in the final output directory, writes every +mandatory group/dataset/attribute, validates finite values, shape, identity, and +ordering, flushes, closes, reopens read-only, and self-checks the schema. Only then +may it atomically replace/create the requested final path. A failure preserves any +previous valid final output when possible, removes or quarantines the non-authority +candidate, emits an output diagnostic, and returns exit code `6`. + +## 7. FESA HDF5 to Reference CSV Comparison Schema + +Authoritative comparison reads `results.h5` and read-only Abaqus CSV artifacts. +A deterministic FESA CSV projection is a debugging/review view only; it is neither +solver output nor a reference artifact. + +### 7.1 S4/S4R portfolio separation + +- S4 and S4R use distinct `model_id`, input, metadata, and CSV bundles. +- FESA maps both source types to `FESA-MITC4`, but Abaqus S4 and S4R values are not + expected to equal each other on a finite mesh. +- Reference comparison always compares one FESA run with Abaqus rows generated from + the same source model/type. +- Equality of FESA internal numerical rows after changing only source type is a + separate implementation test, not an Abaqus S4-versus-S4R comparison. + +### 7.2 Approved S4 legacy alias inventory + +The current exact alias is model ID `shell-s4-legacy`: + +| role | exact path | SHA-256 | observed inventory | +| --- | --- | --- | --- | +| input | `reference/shell/shell.inp` | `4005851E1AB22FD3A16AC17A8D5DA3E051233F69F37419079F3553AD134ECFCF` | 164 lines; `TYPE=S4`; one `*STEP,*STATIC`; `NLGEOM=NO`; generator comment `Abaqus/CAE Learning Edition 2024` | +| displacement | `reference/shell/shell displacements.csv` | `C81D94E0B4A849F87AA0F79C83A79B94D5661AC79E44ED826919AB432C87746B` | 49 finite data rows; U and UR columns | +| reaction | `reference/shell/shell reactions.csv` | `0E34EEC27E700C3C0C744C1DAFD8A3B95EFEF34B8616FE96665876586FE82D41` | 49 finite data rows; RF and RM columns; review-only | +| stress | `reference/shell/shell stresses.csv` | `CBAA6E90400FE561535C4793B126F5A47020FF3FA60026C6F100253F276EFBBE` | nodal-associated S columns including S33; review-only and not location-compatible with mandatory FESA stress rows | + +The files were introduced by source commit +`57122b0a1bdcb1a8d0eed55599742751edd534be`. They must not be renamed, rewritten, +zero-clamped, normalized, or repaired. A hash mismatch is +`needs-reference-artifacts`, not permission to restore or change the bundle. + +The alias is `recognized-legacy-alias-needs-reference-metadata`. Before numerical +comparison, the Reference Model contract must supply or approve externally: + +- generation owner/date and exact provenance; +- user unit system and component unit labels; +- canonical model ID, source input identity, step and final-frame identity; +- global coordinate convention; +- material/section/thickness summary; +- CSV schema version and tolerance policy. + +CSV lacks explicit step/frame/unit/coordinate columns. They map to +`(Step-1,frame 0)`, global Cartesian, and documented units if and only if approved +metadata confirms that exact interpretation. Absence or conflict is a +schema/provenance failure; I/O Definition does not infer values. + +### 7.3 Separate canonical S4R bundle + +At least one S4R reference bundle is still required: + +```text +reference// + model.inp + metadata.json + _displacements.csv +``` + +`model.inp` must contain the approved subset and `TYPE=S4R`. Metadata records +generator/version/provenance, unit system, coordinate system, model/step/frame, +material/section/thickness, source element type, schema version, and tolerance +policy. Optional reaction/stress artifacts remain nonblocking evidence. + +`` is a Reference Model-owned schema variable, not an unresolved +filename placeholder in this I/O contract. + +The canonical wide displacement CSV columns are: + +```text +step_name,frame_index,instance_name,source_node_label, +coordinate_system,translation_unit,rotation_unit, +U1,U2,U3,UR1,UR2,UR3 +``` + +Rows are unique by `(step_name,frame_index,instance_name,source_node_label)`, all +numeric values are finite, and the component coordinate system is global Cartesian. + +### 7.4 Legacy header normalization + +After trimming header whitespace, the exact S4 displacement header mapping is: + +| legacy column | canonical field/component | FESA HDF5 source | +| --- | --- | --- | +| `Part Instance Name` | `instance_name` | `/model/nodes.instance_name` | +| `Node Label` | `source_node_label` | `/model/nodes.source_label` | +| `U-U1` | displacement `U1` | `nodal/displacement` column 0, HDF5 component `UX` | +| `U-U2` | displacement `U2` | `nodal/displacement` column 1, HDF5 component `UY` | +| `U-U3` | displacement `U3` | `nodal/displacement` column 2, HDF5 component `UZ` | +| `UR-UR1` | displacement `UR1` | `nodal/displacement` column 3, HDF5 component `URX` | +| `UR-UR2` | displacement `UR2` | `nodal/displacement` column 4, HDF5 component `URY` | +| `UR-UR3` | displacement `UR3` | `nodal/displacement` column 5, HDF5 component `URZ` | + +Reaction columns are inventoried as `[RF1,RF2,RF3,RM1,RM2,RM3]` when the optional +file passes its schema precheck, but they do not +enter MITC4 Abaqus pass/fail. The legacy stress CSV is not projected onto FESA +integration/section-position rows because it contains a different nodal-associated +location identity and an `S33` column that FESA does not emit. Missing comparison +meaning is recorded as N/A, never repaired by averaging or synthesized rows. + +### 7.5 Canonical normalized row + +Wide CSV and HDF5 rows normalize in memory to: + +```text +model_id, step_name, frame_index, instance_name, source_node_label, +quantity, component, value, unit_dimension, coordinate_system, +hdf5_dataset_path +``` + +The unique key is all fields except `value`, `unit_dimension`, +`coordinate_system`, and `hdf5_dataset_path`; those remaining fields must agree for +the matched key. Stable ordering is model, step, frame, instance declaration order, +stable source node order, then component order +`[U1,U2,U3,UR1,UR2,UR3]`. + +### 7.6 Row-set precheck and comparison policy + +Before tolerance evaluation: + +1. Verify exact artifact inventory/hash or canonical bundle metadata. +2. Verify input source type matches model contract. +3. Verify one approved static step and final frame identity. +4. Verify expected trimmed headers, finite values, unique row keys, units, coordinate + system, and exact source node/instance identities. +5. Project HDF5 and reference to the same six-component displacement inventory. +6. Fail on any missing, extra, duplicate, nonfinite, schema-mismatched, or + identity-mismatched projected row. + +Only `U1/U2/U3` affect pass/fail. `UR1/UR2/UR3` are always compared and reported but +can emit only an approved deterministic nonblocking warning. + +For each model, step/frame, quantity, and component group: + +```text +reference_scale_c = max(abs(reference_value_i)) +row_tolerance_c = absolute_floor_c + + relative_coefficient_c * reference_scale_c +row_pass = abs(fesa_value-reference_value) <= row_tolerance_c +``` + +Reference scale uses finite Abaqus values only. A zero scale makes the relative term +zero. No reference or result value is zero-clamped, no row-specific relative +denominator replaces the component scale, and B33 floors/coefficient are not +inherited. + +The exact `absolute_floor_c`, `relative_coefficient_c`, and UR warning threshold are +`needs-reference-model-and-numerical-review`. Comparison implementation cannot begin +until those values and their unit context are approved. + +The report records every U/UR row, blocking/nonblocking decision, absolute error, +component-scale normalized error, RMS error, displacement/rotation vector-norm +error, worst source row/component, and every UR warning. + +## 8. CLI and Diagnostics Contract + +```powershell +fesa.exe --output +``` + +Omitting `--output` uses `results.h5` in the current directory. Unknown option, +missing input, missing output argument, or repeated `--output` is usage failure. + +| exit code | meaning | +| ---: | --- | +| `0` | successful analysis and authoritative HDF5 finalization | +| `2` | CLI usage error | +| `3` | input syntax or semantic mapping error, including unsupported keyword, formulation, wrapper, step, or distributed load | +| `4` | model validation error, including section/material property, geometry, director, Jacobian, or drilling-direction aggregate moment | +| `5` | factorization or substitution error | +| `6` | HDF5 write, schema validation, or atomic finalization error | + +Each stderr and HDF5 diagnostic has exact field order `severity`, `code`, `file`, +`line`, `keyword`, `entity_identity`, `message`. Source-backed records carry +normalized file and 1-based line; source-less solver/output records use explicit +empty source fields. Order is source declaration order, file line, stable entity ID, +diagnostic code, then discovery order for an otherwise equal key. + +The approved shell-specific diagnostic inventory includes: + +| code | class/exit | meaning | +| --- | --- | --- | +| `unsupported-element-formulation` | input/3 | element type is not S4/S4R in this feature | +| `unsupported-mixed-element-model` | input/3 | shell and non-shell element/joint semantics are mixed | +| `invalid-shell-connectivity` | input/3 | connectivity arity is not four, a node repeats, or a connected source node is unresolved | +| `unresolved-shell-section` | input/3 | section/material/ELSET reference is unresolved | +| `invalid-shell-section-assignment` | input/3 | an element resolves to zero or multiple shell sections | +| `unsupported-shell-section-option` | input/3 | composite, offset, orientation, variable thickness, or other excluded meaning appears | +| `invalid-shell-thickness` | model/4 | thickness is nonfinite or nonpositive | +| `invalid-shell-material` | model/4 | isotropic material violates finite `E,nu` bounds | +| `invalid-shell-geometry` | model/4 | duplicate, self-intersecting, collapsed, reversed, or threshold-invalid surface geometry | +| `opposed-incident-normal` | model/4 | an incident normal pair has nonpositive dot product before averaging | +| `sharp-shell-fold` | model/4 | incident deviation exceeds approved `theta_smooth` | +| `invalid-shell-director` | model/4 | candidate, average, interpolation, or tangent-frame construction is invalid | +| `invalid-shell-jacobian` | model/4 | required point violates `J/j_s/a_g/c_d/r_J/theta_w` contract | +| `unsupported-drilling-load` | model/4 | nonzero aggregate moment violates `rho_M<=1e-12` | +| `unsupported-distributed-load` | input/3 | DLOAD, pressure, gravity, body/edge/follower load is requested | + +The accepted optional `*SHELL SECTION` integration-point field emits no diagnostic. +Allowlisted `*PREPRINT`, `*RESTART`, and output-request no-ops retain their existing +warning behavior. + +## 9. Validation Rules + +| validation area | required pass condition | failure class | +| --- | --- | --- | +| keyword inventory | supported or exact allowlisted no-op | input, exit 3 | +| nesting/cardinality | closed part/assembly/instance/step; one assembly and one static step | input, exit 3 | +| source identity | duplicates absent; all references resolved; multi-instance identity unique | input, exit 3 | +| element syntax/semantics | only four-node S4/S4R, distinct resolved connectivity, internal FESA-MITC4, no mixed element model | input, exit 3 | +| resolved element geometry | source order satisfies orientation and every approved geometry measure | model, exit 4 | +| material/section syntax | exact row grammar, resolvable references, exactly one centered homogeneous assignment per element | input, exit 3 | +| material/section values | finite approved `E,nu,t` bounds | model, exit 4 | +| director/geometry | deterministic pairwise/average/frame construction and every approved measure threshold passes | model, exit 4 | +| boundary/load syntax | global DOF 1..6, resolved finite values, no conflicting prescribed values | input, exit 3 | +| aggregate nodal moment | exact-zero case or nonzero `rho_M<=1e-12` | model, exit 4 | +| history | sole static Step-1/frame 0, NLGEOM disabled | input, exit 3 | +| HDF5 model | exact paths, dtypes, shapes, IDs, source types, directors, sections, and finite values | output, exit 6 | +| HDF5 results | every mandatory row/location/component exists in stable order and is finite | output, exit 6 | +| S4 legacy alias | exact paths/hashes/headers plus approved external metadata | reference precheck | +| S4R canonical bundle | canonical files, metadata, S4R input, unique finite U/UR rows | reference precheck | +| comparison | exact normalized row-set; U blocking; UR warning-only; approved tolerance | reference verification | + +No successful parser/HDF5 implementation, numerical solution, reference comparison, +physics review, or release status follows from approval of this document alone. + +## 10. Requirement Traceability + +| requirement group | I/O contract coverage | remaining owner | +| --- | --- | --- | +| `001-004`, `021-023`, `030`, `037` | exact step, S4/S4R mapping, source/internal identity, wrapper and no-op policies | Implementation Planning tests | +| `005-010` | six global DOFs, isotropic ELASTIC, single-row SHELL SECTION, exact assignment | Implementation Planning tests | +| `011-016` | auto-director semantic mapping, geometry inventory, fail-closed diagnostics | Numerical Review for thresholds | +| `017-020` | BOUNDARY/CLOAD grammar, deterministic aggregation, `rho_M<=1e-12`, distributed-load rejection | Implementation Planning tests | +| `024-029` | Domain/AnalysisModel/DofManager/AnalysisState semantic ownership and residual meaning | Implementation Planning | +| `031-038` | source-independent MITC4 identity, drilling output evidence, full-integration policy | Numerical Review for coefficient/energy rule | +| `039-048` | additive HDF5 v0 paths, mandatory quantities, location identity, atomic output | Reference Model and Implementation Planning | +| `049-057` | diagnostic/schema hooks and mandatory verification-metric/energy evidence | Numerical Review and planning | +| `058-064` | normalized U/UR rows, row-set precheck, blocking/warning behavior, report inventory | Reference Model and Numerical Review for values | +| `065-072` | exact S4 legacy alias, separate S4R canonical bundle, immutability, displacement-only gate | Reference Model | + +## 11. Open Issues and Downstream Handoff + +### 11.1 Upstream metadata corrections + +The requirements metadata says the previously unobserved `reference/shell/` candidate +was declared as S4R. The observed immutable input is `TYPE=S4`, and the user has now +approved separate S4 and S4R artifacts. A later Requirement/Numerical Review metadata +refresh should correct that observation without changing the core requirement that +both source types map to one FESA formulation. + +The current Numerical Review also records `reference/shell/` as unobserved because it +predates the dev-branch merge. Its next rerun should consume this exact alias +inventory and the Reference Model contract. + +### 11.2 Numerical Review dependencies + +The following values remain explicitly unapproved and have no I/O default: + +1. drilling reference family, nodewise `rho_d` range, stable plateau, and nominal; +2. scaled rank/conditioning and U/N/M/Q contamination bounds; +3. drilling-to-physical energy warning classification and threshold; +4. `theta_smooth`; +5. `tau_ang`, `tau_area`, `tau_dir`, `tau_var`, and `theta_warp`; +6. verification-metric formula IDs and acceptance thresholds where not already fixed; +7. component-specific U absolute floors/relative coefficients and UR warning threshold. + +Until these are approved, this document is ready for Reference Model design but not +Implementation Planning. + +### 11.3 Reference Model Agent + +- Write `docs/reference-models/linear-static-mitc4-shell-reference-models.md` using + this exact keyword/HDF5/reference-row contract. +- Register `shell-s4-legacy` without modifying its four files and supply verified + provenance, units, coordinate system, and final-frame identity. +- Provide a separate canonical S4R bundle and additional flat/thin/thick/distorted/ + curved models needed for tolerance and director/geometry calibration. +- Propose U mixed-tolerance values and the UR nonblocking warning threshold for + Numerical Review approval. +- Treat reaction/stress artifacts as nonblocking review evidence and do not create + location-equivalence claims absent from this contract. + +### 11.4 Numerical Review Agent + +- Review Reference Model evidence and close every dependency in Section 11.2. +- Confirm that actual HDF5 drilling and geometry policy attributes reproduce the + approved calibration decision. +- Rerun the numerical gate before authorizing Implementation Planning. + +### 11.5 Implementation Planning Agent + +- Do not start while `implementation_planning_authorized=false`. +- After approval, convert every supported/unsupported keyword row, source identity, + geometry/director error, drilling-load projection, exact HDF5 path/shape/order, + atomic failure, legacy/canonical row normalization, and U-versus-UR decision into + `RED -> GREEN -> VERIFY` tests. +- Keep distributed loads, mixed beam-shell models, Abaqus reduced integration, + nonlinear state/tangent, and reference artifact mutation outside the plan. + +### 11.6 Reference Verification Agent + +- Enforce artifact/schema precheck before numeric tolerance. +- Match HDF5 and Abaqus rows only by the canonical identity in Section 7.5. +- Never ignore missing/extra/nonfinite rows, synthesize S33/S13/S23, average location + mismatches, or let UR warnings change U pass/fail.