475 lines
31 KiB
Markdown
475 lines
31 KiB
Markdown
# Linear Static 3D Euler Beam I/O Definition
|
||
|
||
## Metadata
|
||
|
||
- feature_id: `linear-static-3d-euler-beam`
|
||
- source_requirement: `docs/linear-static-3d-euler-beam/requirements.md`
|
||
- source_formulation: `docs/linear-static-3d-euler-beam/formulation.md`
|
||
- source_numerical_review: `docs/linear-static-3d-euler-beam/numerical-review.md`
|
||
- source_research: `docs/linear-static-3d-euler-beam/research.md`
|
||
- approved_design: `docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
|
||
- status: `ready-for-implementation-planning`
|
||
- owner_agent: `io-definition-agent`
|
||
- date: `2026-08-09`
|
||
- authoritative_output: `results.h5`
|
||
- reference_baseline: exact read-only artifacts under `reference/cantilever beam/`
|
||
|
||
이 문서는 승인된 V0의 semantic I/O contract만 정의한다. Parser, HDF5 writer,
|
||
comparison tooling의 C++ API나 구현 구조는 정의하지 않으며 Abaqus full compatibility를
|
||
주장하지 않는다.
|
||
|
||
## Abaqus Input Scope
|
||
|
||
- input_format: Abaqus input file (`.inp`)
|
||
- supported_analysis: 입력 파일당 하나의 linear-static step과 `TYPE=B33` 2절점 3D
|
||
Euler–Bernoulli beam
|
||
- ordinary_unit_system: user-consistent; `.inp`만 보고 SI를 추론하지 않음
|
||
- compatibility_disclaimer: 아래 표의 위치, parameter, data grammar만 지원함
|
||
|
||
`supported`는 해당 행의 정확한 subset만 의미한다. `warning no-op`은 syntax를 소비하고
|
||
구조화된 warning을 기록하지만 Domain, AnalysisModel 또는 mandatory HDF5 output을
|
||
변경하지 않는다는 뜻이다.
|
||
|
||
| keyword | status and allowed location | required parameters and data grammar | purpose and semantic mapping | unsupported behavior |
|
||
| --- | --- | --- | --- | --- |
|
||
| `*HEADING` | supported; optional top-level first keyword | parameters 없음; 다음 keyword 전까지 0개 이상의 text data line | 원문 heading을 source metadata로 보존 | 중첩 위치 또는 parameter는 input error |
|
||
| `*PART` / `*END PART` | supported; top-level model block | `NAME=<part-name>` 필수; `*END PART` data 없음 | part-local node, element, set, section 정의 범위 | 닫히지 않음, 중첩 part, duplicate part name은 error |
|
||
| `*NODE` | supported; part 내부 | parameter 없음; 각 row `node_label, x, y, z` | positive integer source label과 finite global Cartesian 좌표 | 다른 arity, duplicate label, nonfinite 좌표는 error |
|
||
| `*ELEMENT` | supported; part 내부 | `TYPE=B33` 필수; 각 row `element_label, node_1, node_2` | 2절점 straight Euler beam definition | `TYPE=B31`은 `unsupported-element-formulation`; 다른 type/arity와 dangling connectivity는 error |
|
||
| `*NSET` | supported; part 또는 assembly 내부 | `NSET=<name>` 필수; optional `GENERATE`; assembly에서는 `INSTANCE=<instance-name>` 필수; explicit row는 하나 이상의 node label, generate row는 `first,last,increment` | part-local 또는 single-instance assembly node set | mixed-instance set, zero/negative increment, duplicate name, dangling member는 error |
|
||
| `*ELSET` | supported; part 또는 assembly 내부 | `ELSET=<name>` 필수; optional `GENERATE`; assembly에서는 `INSTANCE=<instance-name>` 필수; explicit/generate grammar는 `*NSET`과 동일 | part-local 또는 single-instance assembly element set | mixed-instance set, invalid range, duplicate name, dangling member는 error |
|
||
| `*MATERIAL` | supported; top-level model data | `NAME=<material-name>` 필수; data 없음 | 뒤따르는 단일 isotropic `*ELASTIC`을 소유 | duplicate name, missing/duplicate elasticity, 다른 material model은 error |
|
||
| `*ELASTIC` | supported; 현재 material 내부 | parameter 없음; 정확히 한 row `E, nu` | homogeneous isotropic elasticity; `G=E/(2(1+nu))` | extra field/row, nonfinite value 또는 `E<=0`/`G<=0`은 model error |
|
||
| `*BEAM GENERAL SECTION` | supported; part 내부 | `ELSET=<name>`, `MATERIAL=<name>`, `SECTION=GENERAL` 필수; 첫 row `A,I11,I12,I22,J`, 둘째 row `n1x,n1y,n1z` | section assignment, properties와 first section axis | 다른 `SECTION`, missing/dangling reference, `I12!=0`, invalid property/guide vector는 error |
|
||
| `*SECTION POINTS` | supported; 바로 앞 general beam section에 종속 | parameter 없음; 하나 이상의 row `x1,x2` | 입력 순서의 stress recovery point; `x1=y`, `x2=z` | 선행 section 없음, 다른 arity, nonfinite 또는 duplicate point는 error |
|
||
| `*ASSEMBLY` / `*END ASSEMBLY` | supported; 정확히 하나의 top-level assembly block | `NAME=<assembly-name>` 필수; `*END ASSEMBLY` data 없음 | identity instance와 assembly set 범위 | nested/duplicate assembly는 `unsupported-nested-assembly` |
|
||
| `*INSTANCE` / `*END INSTANCE` | supported; assembly 내부 | `NAME=<instance-name>`, `PART=<part-name>` 필수; 두 keyword 사이 data 없음 | named identity copy; 같은 part의 여러 identity instance 허용 | translation/rotation data는 `unsupported-instance-transform`; duplicate/dangling instance는 error |
|
||
| `*BOUNDARY` | supported; top-level model data 또는 sole step 내부 | parameter 없음; 각 row `target, first_dof, last_dof[, value]`; omitted value는 `0` | sole step의 prescribed displacement | invalid arity/range, unresolved target, conflicting expanded node/DOF value는 error |
|
||
| `*CLOAD` | supported; sole step 내부 | parameter 없음; 각 row `target, dof, magnitude` | sole step의 global nodal concentrated load | invalid arity/DOF, nonfinite magnitude 또는 unresolved target은 error |
|
||
| `*STEP` / `*END STEP` | supported; exactly one top-level history block | optional `NAME`; optional `NLGEOM=NO`; `*END STEP` data 없음 | canonical result identity `(Step-1, frame 0)` | second step은 `unsupported-multiple-step`; `NLGEOM=YES`는 `unsupported-nonlinear-geometry` |
|
||
| `*STATIC` | supported; sole step 내부, exactly once | parameter 없음; exactly one row `initial_increment, time_period, minimum_increment, maximum_increment` | 승인 legacy row를 읽되 V0는 하나의 linear solve와 frame 0만 생성 | missing/extra/nonfinite/nonpositive field 또는 다른 procedure는 error |
|
||
| `*PREPRINT` | warning no-op; top-level | 모든 parameter를 보존 후 무시; data 없음 | legacy generator control 수용 | semantic object를 만들지 않음 |
|
||
| `*RESTART` | warning no-op; sole step | 모든 parameter를 보존 후 무시; data 없음 | legacy restart request 수용 | restart state를 만들지 않음 |
|
||
| `*TRANSVERSE SHEAR STIFFNESS` | warning no-op; beam section context | keyword와 소속 data line을 보존 후 무시 | B33 legacy deck 수용 | Euler formulation/property를 변경하지 않음 |
|
||
| `*OUTPUT, FIELD` | warning no-op; sole step | output parameter와 subordinate data를 보존 후 무시 | legacy field request root 수용 | mandatory FESA output을 선택·억제하지 않음 |
|
||
| `*OUTPUT, HISTORY` | warning no-op; sole step | output parameter와 subordinate data를 보존 후 무시 | legacy history request root 수용 | history result를 생성하지 않음 |
|
||
| `*NODE OUTPUT` | warning no-op; active output request 내부 | 모든 parameter와 다음 keyword 전 variable data를 무시 | legacy nodal variable request 수용 | requested variables로 HDF5 schema를 변경하지 않음 |
|
||
| `*ELEMENT OUTPUT` | warning no-op; active output request 내부 | 모든 parameter와 다음 keyword 전 variable data를 무시 | legacy element variable request 수용 | requested variables로 HDF5 schema를 변경하지 않음 |
|
||
| `*CONTACT OUTPUT` | warning no-op; active output request 내부 | 모든 parameter와 다음 keyword 전 variable data를 무시 | legacy contact variable request 수용 | contact model/result를 만들지 않음 |
|
||
|
||
`*DLOAD`, `*INCLUDE` 및 표에 없는 model-affecting keyword는 no-op 대상이 아니며
|
||
`unsupported-keyword` input error다. 특히 formulation-only constant local line-load
|
||
kernel은 parser나 Domain의 distributed-load 지원을 뜻하지 않는다.
|
||
|
||
### Nesting grammar
|
||
|
||
```text
|
||
input-file
|
||
:= heading? part+ assembly material+ model-boundary* step EOF
|
||
|
||
part
|
||
:= *PART
|
||
node-block+ element-block+ (nset | elset)*
|
||
general-section+ section-points*
|
||
*END PART
|
||
|
||
assembly
|
||
:= *ASSEMBLY
|
||
instance+ assembly-set*
|
||
*END ASSEMBLY
|
||
|
||
instance
|
||
:= *INSTANCE *END INSTANCE
|
||
|
||
step
|
||
:= *STEP *STATIC step-boundary* cload* allowed-no-op* *END STEP
|
||
```
|
||
|
||
Top-level material과 model boundary는 step 전에만 나타난다. Part는 assembly 전에 모두
|
||
닫혀야 하고 assembly 안에는 instance와 assembly-level set만 허용한다. Instance 안의
|
||
node/element 재정의, nested assembly, dependent/independent mesh option은 지원하지 않는다.
|
||
Sole step의 source `NAME` spelling은 metadata에 보존하지만 V0 HDF5와 comparison의
|
||
canonical identity는 항상 `Step-1`, `frame 0`이다.
|
||
|
||
## Syntax Policy
|
||
|
||
- keyword line은 첫 non-whitespace character가 `*`이고 `**`가 아니어야 한다.
|
||
- comment line은 `**`로 시작하며 의미 모델에서는 제외하되 file과 1-based line 위치를
|
||
유지한다.
|
||
- keyword, parameter name, enumerated parameter value와 named-reference lookup은 ASCII
|
||
case-insensitive다. Part, instance, material, set의 원래 spelling과 numeric label lexeme는
|
||
외부 identity를 위해 그대로 보존한다.
|
||
- keyword line은 comma-separated `KEY[=VALUE]` fields다. Data line도 comma-separated이며
|
||
field 양끝 whitespace를 제거한다. Required empty field, trailing empty optional value,
|
||
잘못된 numeric token은 input error다.
|
||
- Keyword/data continuation, quoted/multiline name, include file 및 line continuation은 V0에서
|
||
지원하지 않는다. 한 logical keyword/data row는 한 physical line에 완결되어야 한다.
|
||
- Node/element labels와 explicit set members는 positive base-10 integer다. Internal index로
|
||
바꾸어도 raw source label text를 잃지 않는다.
|
||
- 모든 numeric value는 finite `double`이어야 한다. `NaN`, positive/negative infinity는
|
||
syntax/semantic validation에서 거부한다.
|
||
- 각 parsed keyword, parameter, data row와 semantic entity는 `file`, 1-based `line`, raw
|
||
`keyword`, raw source label을 추적할 수 있어야 한다.
|
||
- Output-request subordinate variable data는 직전의 allowlisted output keyword부터 다음
|
||
keyword까지에만 warning no-op이다. 그 밖의 예상되지 않은 data line은 input error다.
|
||
|
||
### Duplicate and dangling-reference policy
|
||
|
||
- Part, assembly, instance, material, set 이름은 각 semantic scope의 case-insensitive key로
|
||
unique해야 한다. Node/element numeric source label은 part scope에서 unique해야 한다.
|
||
- 같은 part의 여러 identity instance는 duplicate가 아니다. 각 copy는 instance name으로
|
||
구분되는 별도 source identity를 가진다.
|
||
- Element connectivity, set membership, instance `PART`, section `ELSET`/`MATERIAL`, assembly
|
||
set `INSTANCE`, boundary/load target은 Domain finalization 전에 모두 resolve되어야 한다.
|
||
- Duplicate definition은 `duplicate-entity`; unresolved reference는 `unresolved-reference`로
|
||
진단하고 partial Domain을 해석에 넘기지 않는다.
|
||
|
||
## Model Data Mapping
|
||
|
||
### Stable source identity and instances
|
||
|
||
Part-local node, element, set은 instance expansion 뒤 다음 identity를 갖는다.
|
||
|
||
```text
|
||
SourceEntityId { instance_name, source_label }
|
||
```
|
||
|
||
`instance_name`과 `source_label`은 원래 spelling을 보존한다. Case-insensitive lookup key와
|
||
표시용 raw text는 별개다. Stable Domain internal index는 input declaration order,
|
||
instance declaration order, part-local entity declaration order의 결정적 순서로 부여하며
|
||
thread count나 hash iteration order에 의존하지 않는다. 같은 part의 두 identity instance는
|
||
source label이 같아도 instance name이 다르므로 서로 merge하지 않는다.
|
||
|
||
Assembly-level `*NSET`/`*ELSET`의 `INSTANCE`는 정확히 하나의 identity instance를
|
||
지정하고 data의 label을 그 instance가 참조하는 part-local source label로 resolve한다.
|
||
따라서 assembly set member도 `(instance_name, source_label)`로 결정된다. V0는 한 set에
|
||
여러 instance의 member를 섞는 grammar를 제공하지 않는다.
|
||
|
||
### Nodes, elements, sets, material, and section
|
||
|
||
- Node는 global Cartesian coordinate `[X,Y,Z]`, stable internal node ID와 source identity를
|
||
가진다.
|
||
- B33 element는 ordered connectivity `[node_1,node_2]`, stable internal element ID,
|
||
source identity, general-section assignment를 가진다. Connectivity order가 local tangent
|
||
`t=(X2-X1)/L`의 방향을 정한다.
|
||
- Explicit set은 data order, generated set은 inclusive `first,last,increment` expansion
|
||
order를 보존한다. Membership은 internal ID에 연결되지만 source identity로 round-trip
|
||
가능해야 한다.
|
||
- Material은 정확한 입력 `E,nu`를 보존하고 `G=E/(2(1+nu))`를 유도한다.
|
||
- General section 첫 row는 정확히 `[A,I11,I12,I22,J]`다. V0는 `I12`의 exact numeric
|
||
zero만 허용하고 `Iy=I11`, `Iz=I22`로 매핑한다.
|
||
- Guide vector `a=n1`을 tangent에 직교 투영·정규화하여 local `y`로, `t x n1`을 local
|
||
`z`로 둔다. `(x,y,z)`는 right-handed다.
|
||
|
||
### Model validation
|
||
|
||
모든 값은 finite여야 하고 다음 조건을 element calculation 전에 검사한다.
|
||
|
||
```text
|
||
E > 0
|
||
G = E / (2 * (1 + nu)) > 0
|
||
A > 0, Iy > 0, Iz > 0, J > 0
|
||
L > 1e-12 * max(1, norm(X1), norm(X2))
|
||
norm(a_perp) > 1e-12 * max(1, norm(a))
|
||
```
|
||
|
||
`a_perp = a - dot(a,t)*t`다. 길이 조건 실패는 `invalid-beam-length`, zero guide vector나
|
||
projection 조건 실패는 `invalid-beam-guide-vector`, nonpositive property는
|
||
`invalid-beam-property`, `I12!=0`은 `unsupported-coupled-section` model diagnostic이다.
|
||
Fallback axis, absolute-value 보정 또는 B31 재해석은 허용하지 않는다.
|
||
|
||
## History Data Mapping
|
||
|
||
V0는 하나의 history object, canonical `Step-1`만 만든다. `*STATIC`의 네 legacy field는
|
||
각각 `initial_increment`, `time_period`, `minimum_increment`, `maximum_increment`로
|
||
보존한다. 모두 finite positive여야 하고 `minimum_increment <= maximum_increment`여야
|
||
한다. 이 값들은 입력 호환성과 provenance를 위한 값이며 V0가 increment loop나 여러
|
||
frame을 생성하게 하지 않는다. 결과는 항상 `(Step-1, frame 0)`이다.
|
||
|
||
`*BOUNDARY`의 target은 node source label 또는 node set이다. Assembly set은 그
|
||
`INSTANCE`를 포함해 source node identity로 확장한다. `first_dof <= last_dof`이고 두 값은
|
||
1..6이어야 한다. 생략된 value는 exact zero다. Model-level boundary와 step-level boundary는
|
||
sole step에 활성화되며 같은 expanded node/DOF에 서로 다른 value가 생기면 input error다.
|
||
|
||
`*CLOAD` target resolution은 boundary와 같고 각 row는 해당 target의 모든 node에 global
|
||
component load를 적용한다. 같은 node/DOF로 resolve되는 여러 load row는 input order로
|
||
결정적으로 합산한다.
|
||
|
||
| DOF | nodal kinematic component | boundary unit dimension | CLOAD component | load unit dimension |
|
||
| ---: | --- | --- | --- | --- |
|
||
| 1 | `UX` | length | `FX` | force |
|
||
| 2 | `UY` | length | `FY` | force |
|
||
| 3 | `UZ` | length | `FZ` | force |
|
||
| 4 | `URX` | radian | `MX` | force x length |
|
||
| 5 | `URY` | radian | `MY` | force x length |
|
||
| 6 | `URZ` | radian | `MZ` | force x length |
|
||
|
||
Abaqus output request는 history activation이나 output selection으로 매핑하지 않는다.
|
||
Allowlisted request의 존재 여부와 무관하게 mandatory HDF5 dataset은 모두 생성된다.
|
||
|
||
## Internal Model Contract
|
||
|
||
- Domain은 nodes, B33 elements, sets, material, section, boundary, load와 sole static step의
|
||
완전한 semantic definition을 소유하고 mapping 이후 effectively immutable하다.
|
||
- AnalysisModel은 sole step에 활성인 Domain IDs/references만 제공하며 Domain object를
|
||
복사하지 않는다.
|
||
- Node/element는 equation ID를 소유하지 않는다. DOF numbering과 constrained/free mapping은
|
||
이 I/O 계약 밖의 DofManager 책임이다.
|
||
- Boundary와 load는 expansion 전 target identity와 expansion 후 stable node identity를 모두
|
||
추적할 수 있어야 한다.
|
||
- Result identity는 source identity와 stable internal identity를 모두 보유해야 하며
|
||
parser의 raw keyword string을 solver physics object로 사용하지 않는다.
|
||
- Endpoint equilibrium action, endpoint section resultant, Gauss generalized result,
|
||
assembled residual reaction은 서로 다른 quantity/location identity다.
|
||
|
||
## Output HDF5 Schema
|
||
|
||
Authoritative output은 하나의 HDF5 file `results.h5`, schema version `0`이다. 아래의
|
||
`<step-name>`은 V0에서 literal `Step-1`이다. 모든 string은 UTF-8, 모든 물리 실수는
|
||
IEEE-754 float64, stable internal ID는 uint64다.
|
||
|
||
### Metadata and model identity
|
||
|
||
`/metadata`는 group이며 다음 scalar attributes를 반드시 가진다.
|
||
|
||
| attribute | required value or meaning |
|
||
| --- | --- |
|
||
| `schema_version` | `0` |
|
||
| `feature_id` | `linear-static-3d-euler-beam` |
|
||
| `solver_version` | 실행 solver version string |
|
||
| `source_input_identity` | normalized input path와 content identity를 추적 가능한 string |
|
||
| `unit_system_label` | ordinary run은 `user-consistent-unspecified` |
|
||
| `coordinate_convention` | `global-cartesian; beam-local=(t,n1,t-cross-n1)` |
|
||
| `element_formulation` | `B33-3D-Euler-Bernoulli` |
|
||
| `step_name` | `Step-1` |
|
||
| `frame_index` | integer `0` |
|
||
|
||
승인 legacy comparison은 `.inp`에서 SI를 추론하지 않는다. Reference Model Contract와
|
||
verification report가 model `cantilever-beam-b33`에 외부 `SI` provenance를 적용한다.
|
||
|
||
| dataset path | shape and dtype | row identity / fields | required attributes and ordering |
|
||
| --- | --- | --- | --- |
|
||
| `/model/nodes` | `[node_count]` compound | `internal_node_id:uint64`, `instance_name:utf8`, `source_label:utf8`, `coordinates:float64[3]` | internal node ID ascending; `coordinate_system=global-cartesian`, `units_label=length` |
|
||
| `/model/elements` | `[element_count]` compound | `internal_element_id:uint64`, `instance_name:utf8`, `source_label:utf8`, `node_internal_ids:uint64[2]`, `local_axes:float64[3,3]` | internal element ID ascending; axes row order `[x,y,z]`, `formulation=B33-3D-Euler-Bernoulli` |
|
||
|
||
### Step/frame result datasets
|
||
|
||
| quantity | exact dataset path | shape | row identity and component order | units/coordinates/location |
|
||
| --- | --- | --- | --- | --- |
|
||
| displacement | `/steps/<step-name>/frames/0/nodal/displacement` | `[node_count,6]` float64 | `/model/nodes` row; `[UX,UY,UZ,URX,URY,URZ]` | `[length,length,length,radian,radian,radian]`; global; nodal |
|
||
| reaction | `/steps/<step-name>/frames/0/nodal/reaction` | `[node_count,6]` float64 | `/model/nodes` row; `[RF1,RF2,RF3,RM1,RM2,RM3]` | `[force,force,force,force*length,force*length,force*length]`; global; nodal |
|
||
| equilibrium end action | `/steps/<step-name>/frames/0/element/end_force_local` | `[element_count,2,6]` float64 | element row, endpoint `[-1,+1]`; `[FX,FY,FZ,MX,MY,MZ]` | `[force x3, force*length x3]`; beam local; endpoint outward action |
|
||
| endpoint section resultant | `/steps/<step-name>/frames/0/element/section_resultant` | `[element_count,2,4]` float64 | element row, endpoint `[-1,+1]`; `[N,T,My,Mz]` | `[force,force*length,force*length,force*length]`; beam local; positive-local-x section cut |
|
||
| generalized strain | `/steps/<step-name>/frames/0/element/generalized_strain` | `[element_count,2,4]` float64 | element row, Gauss point `[-1/sqrt(3),+1/sqrt(3)]`; `[epsilon0,kappa_x,kappa_y,kappa_z]` | `[1,1/length,1/length,1/length]`; beam local; integration point |
|
||
| generalized resultant | `/steps/<step-name>/frames/0/element/generalized_resultant` | `[element_count,2,4]` float64 | element row, same Gauss points; `[N,T,My,Mz]` | `[force,force*length,force*length,force*length]`; beam local; integration point |
|
||
| axial stress | `/steps/<step-name>/frames/0/element/stress_s11` | `[stress_row_count]` compound | `internal_element_id`, `gauss_point_index`, `section_point_index`, `x1`, `x2`, `source`, `S11` | element/Gauss/section order; `units_label=force/length^2`, beam local section point |
|
||
| diagnostics | `/diagnostics` | `[diagnostic_count]` compound | `severity`, `code`, `file`, `line`, `keyword`, `entity_identity`, `message` | deterministic diagnostic order; empty dataset is required when count is zero |
|
||
|
||
각 numeric result dataset은 `component_names`, `component_unit_dimensions`,
|
||
`coordinate_system`, `location`, `step_name=Step-1`, `frame_index=0` attributes를 가진다.
|
||
Endpoint axis order는 `xi=-1` then `xi=+1`, Gauss axis order는 negative then positive다.
|
||
Stress row는 internal element ID, Gauss index 1..2, input section-point index 순으로 정렬한다.
|
||
입력 section point가 없으면 `(x1,x2)=(0,0)`, index `0`, `source=fesa-default`인 centroid
|
||
row 하나를 각 Gauss point에 쓴다. 입력 point는 index 1부터 원래 data order를 따른다.
|
||
|
||
Reaction은 모든 node와 여섯 component에 존재하며 free DOF의 residual도 포함한다.
|
||
Transverse/torsional shear stress dataset이나 averaged nodal stress는 만들지 않는다.
|
||
`S11`은 mandatory HDF5 output이지만 Abaqus reference comparison은 명시적 N/A다.
|
||
|
||
### Atomic finalization
|
||
|
||
Writer는 requested final path와 같은 directory에 temporary HDF5를 만들고 모든 mandatory
|
||
group/dataset/attribute 작성, flush, close, schema self-check가 성공한 뒤에만 final path를
|
||
원자적으로 교체한다. 실패하면 temporary artifact는 비권위적이며 기존 final file이
|
||
있다면 그대로 보존한다. 실패한 새 run은 불완전한 `results.h5`를 남기지 않고 exit code
|
||
`6`과 HDF5 diagnostic을 반환한다.
|
||
|
||
## FESA HDF5 to Reference CSV Comparison Schema
|
||
|
||
Authoritative 비교는 위 HDF5 rows와 read-only Abaqus CSV rows 사이에서만 수행한다.
|
||
HDF5에서 추출한 deterministic CSV view는 debugging/review 보조물이며 solver output이나
|
||
reference artifact가 아니다.
|
||
|
||
### Approved legacy artifact precheck
|
||
|
||
Comparison 전에 다음 exact files가 존재하고 변경되지 않았음을 확인한다.
|
||
|
||
- `reference/cantilever beam/cantilever beam.inp`
|
||
- `reference/cantilever beam/cantilever beam displacements.csv`
|
||
- `reference/cantilever beam/cantilever beam reactions.csv`
|
||
- `reference/cantilever beam/cantilever beam elemental forces.csv`
|
||
|
||
Input은 `TYPE=B33`이어야 하고 trim한 CSV header는 아래 mapping 표와 정확히 일치해야
|
||
한다. 각 projected row key는 unique하고 모든 numeric value는 finite여야 한다. 파일
|
||
missing/type mismatch는 `needs-reference-artifacts`, header/value/identity mismatch는
|
||
`schema-mismatch`이며 comparison은 시작하지 않는다. `metadata.json` 부재는 프로젝트
|
||
전역 정책에 따라 허용되고, `README.md`는 이 legacy bundle에서 N/A다. 파일을 rename,
|
||
rewrite, zero-clamp 또는 보정하지 않는다.
|
||
|
||
### Header and component normalization
|
||
|
||
| legacy file/header | canonical quantity/component | FESA HDF5 source |
|
||
| --- | --- | --- |
|
||
| `U-U1`, `U-U2`, `U-U3` | displacement `UX`, `UY`, `UZ` | `nodal/displacement` columns 0..2 |
|
||
| `UR-UR1`, `UR-UR2`, `UR-UR3` | displacement `URX`, `URY`, `URZ` | `nodal/displacement` columns 3..5 |
|
||
| `RF-RF1`, `RF-RF2`, `RF-RF3` | reaction `RF1`, `RF2`, `RF3` | `nodal/reaction` columns 0..2 |
|
||
| `RM-RM1`, `RM-RM2`, `RM-RM3` | reaction `RM1`, `RM2`, `RM3` | `nodal/reaction` columns 3..5 |
|
||
| `SF-SF1` | section resultant `N` | `element/section_resultant` component `N` |
|
||
| `SM-SM1` | section resultant `My` | `element/section_resultant` component `My` |
|
||
| `SM-SM2` | section resultant `Mz` | `element/section_resultant` component `Mz` |
|
||
| `SM-SM3` | section resultant `T` | `element/section_resultant` component `T` |
|
||
|
||
General Abaqus beam component meaning and FESA local mapping은 다음과 같다.
|
||
|
||
| Abaqus component | equilibrium end-action component | section-resultant component |
|
||
| --- | --- | --- |
|
||
| `SF1` | `FX` | `N` |
|
||
| `SF3` | `FY` | N/A in `[N,T,My,Mz]` |
|
||
| `SF2` | `FZ` | N/A in `[N,T,My,Mz]` |
|
||
| `SM3` | `MX` | `T` |
|
||
| `SM1` | `MY` | `My` |
|
||
| `SM2` | `MZ` | `Mz` |
|
||
|
||
이 general mapping은 component axis의 의미다. Outward equilibrium end action과
|
||
positive-local-x-face section resultant의 sign identity를 합치지 않는다. 승인 legacy
|
||
CSV는 `SF1/SM1/SM2/SM3`만 제공하고 section-cut result와 비교하므로 `SF2`/`SF3` row를
|
||
0으로 만들거나 reference row로 합성하지 않는다. HDF5의 transverse end action은
|
||
unit/analytical test와 physics sanity 대상이다.
|
||
|
||
### Frame, instance, and element-endpoint normalization
|
||
|
||
- Legacy `Frame` value `Increment 1: Step Time = 1.000`은 canonical `(Step-1, frame 0)`으로
|
||
변환한다. 승인 bundle의 다른 increment/time string은 `schema-mismatch`다.
|
||
- `Part Instance Name`은 HDF5 `/model/nodes` 또는 `/model/elements`의 exact preserved
|
||
`instance_name`과 case-insensitive lookup 후 raw identity 일치 여부를 확인한다.
|
||
- `Node Label`은 instance 안의 preserved source node label로 resolve한다. Displacement와
|
||
reaction key는 `(model_id,Step-1,0,instance_name,source_node_label,quantity,component)`다.
|
||
- Elemental-force CSV의 `Element Label`은 instance 안의 preserved source element label로,
|
||
`Node Label`은 해당 B33 connectivity의 정확한 endpoint source node로 resolve한다.
|
||
- Section-resultant key는
|
||
`(model_id,Step-1,0,instance_name,source_element_label,source_node_label,quantity,component)`다.
|
||
한 element에는 connectivity와 일치하는 두 endpoint 행이 정확히 존재해야 한다.
|
||
- Missing, extra, duplicate 또는 element-connectivity-mismatched endpoint row는
|
||
`schema-mismatch`로 tolerance 전에 실패한다. Source node station collapse,
|
||
deterministic representative 선택 또는 endpoint 평균은 사용하지 않는다.
|
||
|
||
Projected canonical comparison row는 다음 fields를 가진다.
|
||
|
||
```text
|
||
model_id, step_name, frame_index, instance_name,
|
||
[source_element_label], source_node_label, quantity, component, value,
|
||
unit_dimension, coordinate_system, hdf5_dataset_path
|
||
```
|
||
|
||
`source_element_label`은 section-resultant row에 필수이고 nodal row에는 적용하지 않는다.
|
||
Stable ordering은 quantity inventory order, instance declaration order, stable source
|
||
node/element-endpoint order, component order다. Approved model ID는 `cantilever-beam-b33`;
|
||
nodal quantities는 global Cartesian, section resultants는 beam local이다.
|
||
|
||
### Row-set precheck and tolerance
|
||
|
||
먼저 양쪽을 legacy contract가 실제 제공하는 quantity/component projection으로 제한한다.
|
||
그 projection 안에서는 missing, extra, duplicate, nonfinite, schema-mismatched 또는
|
||
identity-mismatched row가 하나라도 있으면 tolerance 계산 전에 실패한다. HDF5에만
|
||
mandatory인 `SF2/SF3` 대응 end action, generalized results와 `S11`은 계약상 비교 대상이
|
||
아니므로 extra reference row가 아니다.
|
||
|
||
Matched rows는 같은 model/case, step/frame, logical quantity, unit dimension, coordinate
|
||
system과 blocking behavior의 component family로 group한다. B33 family는 translation
|
||
`UX/UY/UZ`, rotation `URX/URY/URZ`, reaction force `RF1/RF2/RF3`, reaction moment
|
||
`RM1/RM2/RM3`, section force `N`, section moment `T/My/Mz`다.
|
||
|
||
```text
|
||
S = max(abs(reference_value_i))
|
||
error_i = abs(fesa_value_i-reference_value_i)
|
||
near_zero_band = 0.01*S
|
||
|
||
if abs(reference_value_i) <= near_zero_band:
|
||
row_pass = error_i <= near_zero_band
|
||
else:
|
||
row_pass = error_i/abs(reference_value_i) <= 0.05
|
||
|
||
relative_rms = sqrt(mean(error_i^2))/S
|
||
family_pass = all(row_pass) and relative_rms <= 0.01
|
||
```
|
||
|
||
`S`는 read-only Abaqus values만 사용하고 FESA 값으로 조정하지 않는다. 독립적인
|
||
absolute-error gate와 zero clamp는 사용하지 않는다. `S=0`이면 모든 FESA 값도 exact
|
||
zero일 때 relative RMS를 0으로 기록하고 통과하며, 하나라도 nonzero이면 NaN/Inf 대신
|
||
`zero-reference-scale-nonzero-error`로 실패한다. Verification report는 모든 row의 적용
|
||
branch와 pass/fail, family identity/components, scale, near-zero band/count, max absolute
|
||
error, scale-relative RMS와 worst row/component를 기록한다. 이 reference tolerance는
|
||
analytical/formulation tolerance를 대체하지 않는다.
|
||
|
||
## CLI and Diagnostics Contract
|
||
|
||
```powershell
|
||
fesa.exe <model.inp> --output <results.h5>
|
||
```
|
||
|
||
`--output`을 생략하면 현재 작업 directory의 `results.h5`가 final path다. Input path는
|
||
정확히 하나이며 unknown option, missing argument, repeated `--output`은 usage error다.
|
||
|
||
| exit code | meaning |
|
||
| ---: | --- |
|
||
| `0` | success; authoritative HDF5 finalization complete |
|
||
| `2` | CLI usage error |
|
||
| `3` | input syntax or semantic mapping error, including unsupported keyword/formulation/wrapper |
|
||
| `4` | model validation error, including geometry, section or property invalidity |
|
||
| `5` | factorization or substitution error |
|
||
| `6` | HDF5 write, validation or atomic finalization error |
|
||
|
||
각 stderr diagnostic record는 exact field order `severity`, `code`, `file`, `line`,
|
||
`keyword`, `entity_identity`, `message`를 사용한다. Source-backed diagnostics는 normalized
|
||
file path와 1-based line을 가지며, source가 없는 solver/output error는 빈 source field를
|
||
명시한다. 출력 순서는 source file declaration order, line, entity stable internal ID,
|
||
diagnostic code의 tuple로 결정하고 같은 tuple에서는 discovery order를 보존한다. Warning은
|
||
성공 run에서도 `/diagnostics`에 기록되며 error가 있으면 해당 exit class를 반환한다.
|
||
|
||
## Validation Rules
|
||
|
||
| validation area | required pass condition | failure class |
|
||
| --- | --- | --- |
|
||
| keyword inventory | supported 또는 exact warning no-op allowlist에 속함 | input, exit 3 |
|
||
| nesting/cardinality | closed part/assembly/instance/step; one assembly and one static step | input, exit 3 |
|
||
| source identity | duplicate 없음; all references resolve; multi-instance identity unique | input, exit 3 |
|
||
| B33 semantics | only `TYPE=B33`; two distinct connected nodes | input/model, exit 3 or 4 |
|
||
| section/material | exact data arity/mapping, `I12=0`, all required positive properties | model, exit 4 |
|
||
| geometry/local axes | approved length/projection thresholds and right-handed axes | model, exit 4 |
|
||
| history | DOF 1..6, resolved targets, finite values, sole canonical frame | input, exit 3 |
|
||
| HDF5 | all exact paths, shapes, attributes, identities and finite result values | output, exit 6 |
|
||
| legacy artifacts | exact four files, B33, exact headers, unique finite rows | reference precheck |
|
||
| comparison | exact projected row-set, endpoint eligibility/consistency, approved tolerance | reference verification |
|
||
|
||
No parser/HDF5 implementation, reference artifact mutation, Abaqus execution, physics pass 또는
|
||
release approval을 이 status가 의미하지 않는다.
|
||
|
||
## Open Issues and Downstream Handoff
|
||
|
||
### Resolved numerical-review handoff
|
||
|
||
`NR-O03-STATION-NORMALIZATION`은 2026-08-18 regenerated elemental-force CSV의
|
||
`Element Label`로 해소됐다. Comparator는 `(instance, element label, endpoint node label,
|
||
component)`를 직접 대응하며 station collapse, 대표 endpoint 선택 또는 평균을 하지 않는다.
|
||
|
||
### Reference Model Agent
|
||
|
||
- Exact legacy inventory, current row schema와 stress comparison N/A를 계약에 고정한다.
|
||
- 추가 reference case의 exact paths와 수치 비교 계약은 해당 feature requirement가 정하며,
|
||
canonical naming이나 optional metadata를 readiness 조건으로 추가하지 않는다.
|
||
|
||
### Implementation Planning Agent
|
||
|
||
- Keyword별 positive/negative grammar, source location, duplicates/dangling references,
|
||
B31/transform/nested/multiple-step/NLGEOM diagnostics를 TDD cases로 만든다.
|
||
- Exact HDF5 path/shape/component/identity, mandatory-output independence와 atomic failure를
|
||
검증한다.
|
||
- C++ API는 이 semantic contract에서 파생하되 여기에 소급해 API 설계를 추가하지 않는다.
|
||
|
||
### Reference Verification Agent
|
||
|
||
- Artifact precheck 뒤 HDF5-to-CSV source identity projection, direct element-endpoint row-set
|
||
equality, common family-scale comparison 순서를 유지한다.
|
||
- Missing/extra/nonfinite row를 무시하거나 `SF2/SF3`/stress reference row를 합성하지 않는다.
|
||
|