# Results Schema ## Purpose This document defines the FESA result data model and the proposed HDF5 layout. The schema must support Phase 1 linear static results while remaining compatible with future nonlinear increments, dynamic frames, thermal fields, and history outputs. ## Source Basis - HDF5 files organize named objects in a rooted graph with groups and datasets: https://docs.hdfgroup.org/documentation/hdf5/latest/_h5_d_m__u_g.html - HDF5 datasets store multidimensional arrays and metadata needed to interpret them: https://docs.hdfgroup.org/documentation/hdf5/latest/_h5_d__u_g.html - HDF5 attributes are small metadata objects attached to groups or datasets: https://portal.hdfgroup.org/documentation/hdf5/latest/_h5_a__u_g.html ## Data Model FESA stores results with this hierarchy: ```text ResultFile └── ResultStep └── ResultFrame ├── FieldOutput └── HistoryOutput ``` Definitions: - `ResultStep`: one analysis step from input. - `ResultFrame`: one output point inside a step. For Phase 1 linear static, use frame `0`. - `FieldOutput`: node, element, integration-point, or section-point field values. - `HistoryOutput`: scalar or vector time/load history values for selected entities or global quantities. ## HDF5 Root Layout Proposed file layout: ```text / metadata/ model/ results/ steps/ Step-1/ frames/ 0/ fieldOutputs/ U/ RF/ S/ E/ SF/ historyOutputs/ referenceComparison/ ``` ## Root Attributes Attach these attributes to `/`: | Attribute | Type | Required | Meaning | |---|---|---|---| | `schema_name` | string | yes | `FESA_RESULTS` | | `schema_version` | int64 | yes | Start at `1` | | `solver_name` | string | yes | `FESA` | | `solver_version` | string | no | Build or release version | | `created_utc` | string | no | ISO 8601 timestamp | | `input_file` | string | no | Original input path | | `input_sha256` | string | no | Input file hash | | `unit_system_note` | string | no | User-provided self-consistent unit note | | `dof_convention` | string | yes | `UX,UY,UZ,RX,RY,RZ` | | `sign_convention` | string | yes | `Abaqus-compatible` | ## `/metadata` Recommended datasets or attributes: ```text /metadata/sourceFiles /metadata/analysisType /metadata/precision /metadata/indexType /metadata/conventions ``` Rules: - Use attributes for small scalar metadata. - Use datasets for variable-length tables or arrays. - Store `precision = double`. - Store `index_type = int64`. ## `/model` The result file may contain enough model data to interpret outputs: ```text /model/nodes/ids /model/nodes/coordinates /model/elements/ids /model/elements/types /model/elements/connectivity /model/sets/nodeSets/ /model/sets/elementSets/ /model/dofs/components ``` Rules: - Store ids as int64. - Store coordinates as double. - Store connectivity as int64. - Phase 1 element type string should be `MITC4`. - If complete model mirroring is deferred, store at least node ids, element ids, and output entity labels required to interpret results. ## Field Output Layout Each field output group should follow this pattern: ```text /results/steps/Step-1/frames/0/fieldOutputs/U/ values entity_ids component_labels ``` Attributes: | Attribute | Type | Meaning | |---|---|---| | `position` | string | `NODAL`, `ELEMENT`, `INTEGRATION_POINT`, or `SECTION_POINT` | | `entity_type` | string | `node`, `element`, etc. | | `component_count` | int64 | Number of components | | `basis` | string | `GLOBAL`, `LOCAL_SHELL`, or another documented basis | | `description` | string | Human-readable field description | Datasets: - `entity_ids`: shape `[n_entities]`, int64. - `values`: shape `[n_entities, n_components]`, double. - `component_labels`: shape `[n_components]`, string. ## Phase 1 Field Outputs ### `U` Nodal displacement and rotation. ```text position = NODAL entity_type = node basis = GLOBAL component_labels = ["UX", "UY", "UZ", "RX", "RY", "RZ"] ``` ### `RF` Nodal reaction force and moment. ```text position = NODAL entity_type = node basis = GLOBAL component_labels = ["RFX", "RFY", "RFZ", "RMX", "RMY", "RMZ"] ``` `RF` is computed from the full system: ```text RF = K_full * U_full - F_full ``` ### `S` Shell stress output when implemented. ```text position = INTEGRATION_POINT or SECTION_POINT entity_type = element basis = LOCAL_SHELL component_labels = ["S11", "S22", "S33", "S12", "S13", "S23"] ``` ### `E` Shell strain output when implemented. ```text position = INTEGRATION_POINT or SECTION_POINT entity_type = element basis = LOCAL_SHELL component_labels = ["E11", "E22", "E33", "E12", "E13", "E23"] ``` ### `SF` Shell section force and moment resultants when implemented. ```text position = ELEMENT or INTEGRATION_POINT entity_type = element basis = LOCAL_SHELL component_labels = ["SF1", "SF2", "SF12", "SM1", "SM2", "SM12", "SS13", "SS23"] ``` The final component labels should be cross-checked with the accepted Abaqus reference output variables. ## Frame Attributes Attach these attributes to each frame group: | Attribute | Type | Meaning | |---|---|---| | `frame_id` | int64 | Zero-based frame id | | `step_time` | double | Time/load parameter within step | | `total_time` | double | Accumulated analysis time | | `increment` | int64 | Increment number | | `iteration` | int64 | Newton iteration or `0` for linear static | | `converged` | int | `1` true, `0` false | | `description` | string | Optional note | For Phase 1 linear static: - `frame_id = 0` - `step_time = 1.0` - `total_time = 1.0` - `increment = 1` - `iteration = 0` - `converged = 1` ## History Outputs History output layout: ```text /results/steps/Step-1/historyOutputs// x values component_labels ``` Attributes: - `x_label`: usually `step_time`, `total_time`, `load_factor`, or `frame_id`. - `entity_type`: `global`, `node`, `element`, `set`. - `entity_id` or `entity_name`. Phase 1 recommended history outputs: - total external load by component. - total reaction by component. - maximum displacement magnitude. - linear solver status. ## Reference Comparison Group Optional comparison output: ```text /referenceComparison/cases// expected actual abs_error rel_error pass ``` Attributes: - `reference_source` - `reference_solver` - `reference_solver_version` - `comparison_status` - `comparison_timestamp_utc` ## Naming Rules - Use stable ASCII group and dataset names. - Use original input labels as attributes when names contain spaces or nonportable characters. - Normalize step names to HDF5-safe names while preserving original names in attributes. - Never depend on HDF5 object iteration order for semantic ordering. Store explicit ids and labels. ## Compression and Chunking Phase 1 may write contiguous datasets for simplicity. For large models: - Use chunked datasets for large field outputs. - Consider compression only when it does not materially slow common read paths. - Keep metadata small enough for attributes. ## Open Decisions - Exact mandatory stress/strain/resultant output variables in Phase 1. - Whether result files always mirror the model or only store output entity ids. - Whether reference comparison results are stored in solver output files or separate reports.