# FESA HDF5 Schema 2.0.0 ## 1. Scope and version compatibility Schema `2.0.0` is the self-contained Phase 1 result contract. One file contains the active normalized model, its single linear-static analysis definition and solver settings, and every nodal and Beam result needed without the source `.inp` file. FESA performs no unit conversion. Schema `1.0.0` was the earlier minimal vertical slice. Version `2.0.0` changes the required model and result objects, so it is a new major version rather than an in-place change to `1.0.0`. The current writer and reader accept exactly `2.0.0`; every other version fails with `hdf5.unsupported_schema`. A future reader may explicitly add support for compatible minor versions, but must not infer compatibility from a version prefix. ## 2. Common rules - Root attributes are variable-length UTF-8 strings: `schema_version="2.0.0"`, `fesa_version`, and `unit_policy="consistent_input_units_no_conversion"`, `input_source`, and `input_fingerprint`. `input_source` is the UTF-8 path supplied to the solve request. `input_fingerprint` is `fnv1a64:` followed by the 16 lowercase hexadecimal digits of FNV-1a 64 over the original input bytes; it is a reproducibility identifier, not a cryptographic integrity guarantee. - Integer datasets use the stated little-endian fixed-width type. Floating datasets use IEEE 754 little-endian `float64`. Strings are variable-length UTF-8. - `dense_index` is a contiguous 0-based row index. Semantic `internal_id` values are nonnegative and are not assumed to be dense or ordered. - Flat/orphan mesh `part_name` and `instance_name` values are empty strings. - Ragged arrays use an offset dataset of length `row_count + 1`. Offsets start at zero, are nondecreasing, and the final offset equals the flattened row count. Input order is preserved. - Numeric field datasets carry UTF-8 `coordinate_system` and `components` attributes where listed. `components` is a comma-separated ordered list. - Step and frame group names are contiguous decimal indices beginning at zero. Phase 1 requires exactly one analysis step and one result step with the same name, and exactly one result frame in that step. ## 3. Required objects ### 3.1 Model Let `N`, `E`, `M`, `S`, `NS`, and `ES` be the node, Beam element, material, section, node-set, and element-set counts. Let `P` be the total number of section recovery points, `NM` the total node-set membership count, and `EM` the total element-set membership count. | Path | Type | Rank and shape | Attributes / meaning | |---|---|---|---| | `/model/nodes/dense_index` | `uint64` | 1, `[N]` | contiguous row index | | `/model/nodes/internal_id` | `int64` | 1, `[N]` | `NodeId` | | `/model/nodes/part_name` | UTF-8 | 1, `[N]` | entity provenance | | `/model/nodes/instance_name` | UTF-8 | 1, `[N]` | entity provenance | | `/model/nodes/local_label` | `int64` | 1, `[N]` | external local label | | `/model/nodes/coordinates` | `float64` | 2, `[N,3]` | `coordinate_system="global"`, `components="X,Y,Z"` | | `/model/elements/dense_index` | `uint64` | 1, `[E]` | contiguous row index | | `/model/elements/internal_id` | `int64` | 1, `[E]` | `ElementId` | | `/model/elements/part_name` | UTF-8 | 1, `[E]` | entity provenance | | `/model/elements/instance_name` | UTF-8 | 1, `[E]` | entity provenance | | `/model/elements/local_label` | `int64` | 1, `[E]` | external local label | | `/model/elements/connectivity` | `uint64` | 2, `[E,2]` | node `dense_index`, ordered end `-1,+1` | | `/model/elements/material_id` | `int64` | 1, `[E]` | references material `internal_id` | | `/model/elements/section_id` | `int64` | 1, `[E]` | references section `internal_id` | | `/model/materials/internal_id` | `int64` | 1, `[M]` | `MaterialId` | | `/model/materials/name` | UTF-8 | 1, `[M]` | material name | | `/model/materials/young_modulus` | `float64` | 1, `[M]` | finite, positive | | `/model/materials/poisson_ratio` | `float64` | 1, `[M]` | finite, `-1 < nu < 0.5` | | `/model/sections/internal_id` | `int64` | 1, `[S]` | `SectionId` | | `/model/sections/name` | UTF-8 | 1, `[S]` | section name | | `/model/sections/area` | `float64` | 1, `[S]` | `A` | | `/model/sections/moment_y` | `float64` | 1, `[S]` | `Iy` | | `/model/sections/moment_z` | `float64` | 1, `[S]` | `Iz` | | `/model/sections/torsion_constant` | `float64` | 1, `[S]` | `J` | | `/model/sections/shear_area_y` | `float64` | 1, `[S]` | applied `Asy` | | `/model/sections/shear_area_z` | `float64` | 1, `[S]` | applied `Asz` | | `/model/sections/shear_source` | `uint8` | 1, `[S]` | `0=input`, `1=phase1_default` | | `/model/sections/orientation` | `float64` | 2, `[S,3]` | `coordinate_system="global"`, `components="X,Y,Z"` | | `/model/sections/recovery_point_offsets` | `uint64` | 1, `[S+1]` | offsets into `recovery_points` | | `/model/sections/recovery_points` | `float64` | 2, `[P,2]` | `coordinate_system="element_local"`, `components="y,z"` | | `/model/sets/node/names` | UTF-8 | 1, `[NS]` | exact node-set names | | `/model/sets/node/member_offsets` | `uint64` | 1, `[NS+1]` | offsets into `members` | | `/model/sets/node/members` | `int64` | 1, `[NM]` | `NodeId`, input set/member order | | `/model/sets/element/names` | UTF-8 | 1, `[ES]` | exact element-set names | | `/model/sets/element/member_offsets` | `uint64` | 1, `[ES+1]` | offsets into `members` | | `/model/sets/element/members` | `int64` | 1, `[EM]` | `ElementId`, input set/member order | ### 3.2 Analysis `/analysis/steps/0` has UTF-8 attribute `name`. Let `B` be the prescribed-DOF count and `L` the nodal-load count. | Path | Type | Rank and shape | Attributes / meaning | |---|---|---|---| | `/analysis/steps/0/boundary_conditions/node_ids` | `int64` | 1, `[B]` | target `NodeId` | | `/analysis/steps/0/boundary_conditions/dofs` | `uint8` | 1, `[B]` | Abaqus/FESA DOF number 1 through 6 | | `/analysis/steps/0/boundary_conditions/values` | `float64` | 1, `[B]` | prescribed value | | `/analysis/steps/0/nodal_loads/node_ids` | `int64` | 1, `[L]` | target `NodeId` | | `/analysis/steps/0/nodal_loads/values` | `float64` | 2, `[L,6]` | `coordinate_system="global"`, `components="Fx,Fy,Fz,Mx,My,Mz"` | `/analysis/solver_settings` has the exact UTF-8 attributes used by the Phase 1 pipeline: `backend="mkl_pardiso"`, `matrix_storage="symmetric_upper_csr"`, `matrix_type="symmetric_positive_definite"`, `constraint_method="essential_dof_elimination"`, and `assembly="deterministic_serial"`. No unused future settings are stored. ### 3.3 Results `/results/steps/0` has UTF-8 attribute `name`; frame group `0` has scalar `float64` attribute `step_time`. Let `RN`, `RE`, `RP`, and `D` be the nodal result, Beam result, flattened Beam recovery-point, and diagnostic counts. | Path below `/results/steps/0/frames/0` | Type | Rank and shape | Attributes / meaning | |---|---|---|---| | `nodal/node_ids` | `int64` | 1, `[RN]` | `NodeId`; provenance is joined from `/model/nodes` | | `nodal/displacement` | `float64` | 2, `[RN,6]` | `coordinate_system="global"`, `components="Ux,Uy,Uz,Rx,Ry,Rz"` | | `nodal/reaction` | `float64` | 2, `[RN,6]` | `coordinate_system="global"`, `components="RFx,RFy,RFz,RMx,RMy,RMz"` | | `element/beam/element_ids` | `int64` | 1, `[RE]` | `ElementId` | | `element/beam/part_name` | UTF-8 | 1, `[RE]` | result provenance | | `element/beam/instance_name` | UTF-8 | 1, `[RE]` | result provenance | | `element/beam/local_label` | `int64` | 1, `[RE]` | result provenance | | `element/beam/local_frame` | `float64` | 3, `[RE,3,3]` | `coordinate_system="global"`, `components="ex,ey,ez"`; last dimension is `X,Y,Z` | | `element/beam/end_node_ids` | `int64` | 2, `[RE,2]` | ordered ends `-1,+1` | | `element/beam/xi` | `float64` | 2, `[RE,2]` | `components="end_minus,end_plus"` | | `element/beam/section_strain` | `float64` | 3, `[RE,2,6]` | `coordinate_system="element_local"`, `components="epsilon,gamma_y,gamma_z,kappa_x,kappa_y,kappa_z"` | | `element/beam/section_force` | `float64` | 3, `[RE,2,6]` | `coordinate_system="element_local"`, `components="N,Vy,Vz,T,My,Mz"` | | `element/beam/centroid_sigma_xx` | `float64` | 2, `[RE,2]` | `coordinate_system="element_local"`, `components="end_minus,end_plus"`, `quantity="sigma_xx"` | | `element/beam/recovery_point_offsets` | `uint64` | 1, `[RE+1]` | offsets into recovery-point rows | | `element/beam/recovery_point_sigma_xx` | `float64` | 2, `[RP,2]` | `coordinate_system="element_local"`, `components="end_minus,end_plus"`, `quantity="sigma_xx"`; point order comes from the referenced section | | `diagnostics/stage` | `uint8` | 1, `[D]` | enum table below | | `diagnostics/severity` | `uint8` | 1, `[D]` | `0=warning`, `1=error` | | `diagnostics/code` | UTF-8 | 1, `[D]` | exact diagnostic code | | `diagnostics/message` | UTF-8 | 1, `[D]` | exact diagnostic message | | `diagnostics/has_source` | `uint8` | 1, `[D]` | `0=no source`, `1=source present` | | `diagnostics/source_file` | UTF-8 | 1, `[D]` | empty when source is absent | | `diagnostics/source_line` | `uint64` | 1, `[D]` | zero when source is absent | | `diagnostics/source_column` | `uint64` | 1, `[D]` | zero when source is absent | Diagnostic stage encoding follows the declaration order: | Value | Stage | |---:|---| | 0 | `io` | | 1 | `syntax` | | 2 | `semantic` | | 3 | `model` | | 4 | `equation` | | 5 | `solver` | | 6 | `results` | | 7 | `validation` | ## 4. Writer and reader contract - The writer validates `ResultDatabase`, exact schema version, model/result ID and provenance joins, Beam connectivity, recovery-point counts, and the single-step name before creating the file. - Required-object creation, write, flush, and close failures become `DiagnosticStage::results` errors. A failed write is never reported as success. - The reader validates the exact version, required datatypes, ranks, shapes, offsets, finite values, uniqueness, references, field metadata, and result contracts. It does not return a partial database or partial snapshots. - The public reader returns adapter-owned, read-only metadata, model, and analysis snapshots plus the semantic `ResultDatabase`. No HDF5 object or handle escapes the adapter, and the snapshots contain enough information to reconstruct the Phase 1 model and run definition without the source deck.