# Nonlinear Static Newton-Raphson I/O Definition ## 1. Metadata - feature_id: `nonlinear-static-newton-raphson` - source_requirement: `docs/nonlinear-static-newton-raphson/requirements.md` - source_requirement_sha256: `89C1AB5F1BEDB7C5F6AD0726ED62F0982181EA8746EDE4661183FD3D18A2408E` - source_research: `docs/nonlinear-static-newton-raphson/research.md` - source_research_sha256: `4F63D23E03D1A68E5F8563B678FDD6F761F9558165778EF0433133EFAD303570` - source_formulation: `docs/nonlinear-static-newton-raphson/formulation.md` - source_formulation_sha256: `878028F7B8EC1B91DA9BF00AF78825F50EB0B71046E840A0EEA595AFFD5E14B9` - source_numerical_review: `docs/nonlinear-static-newton-raphson/numerical-review.md` - source_numerical_review_sha256: `C00994EF4BB23A237547459E157EE5BDA96B28CAF08F712CD31A8E0ABBF62D2C` - source_reference_model: `docs/nonlinear-static-newton-raphson/reference-model.md` - source_reference_model_sha256: `B2E6845AB59A32F78261B7A47506C27F7BF4B61401B34BC5DE3DAD4F03D6ADDA` - decision_source: `USER-DECISION-004 option 1` - balance_gate_decision: user-approved factor-one global force/moment normalized gate `<=1e-8` - repository_policy: `AGENTS.md`, `docs/SOLVER_AGENT_DESIGN.md`, `docs/PRD.md`, `docs/ARCHITECTURE.md`, `docs/ADR.md`, `docs/TOLERANCE.md` - status: `ready-for-coordinator-review` - owner_agent: `io-definition-agent` - date: `2026-08-28` - authoritative_output: input sibling `_results.h5` - diagnostic_log: input sibling `_log.txt` - hdf5_schema_version: `1` 이 문서는 승인된 Stage 5 I/O 계약만 정의한다. Parser, writer, comparison tool의 C++ API나 파일 소유권은 정의하지 않는다. FESA는 Abaqus와 독립적인 solver이며, 아래 `.inp` subset과 reference CSV mapping은 Abaqus full compatibility, Abaqus `S4/S4R` 내부 알고리즘, 적분, stabilization, 상태 갱신 또는 output recovery 동등성을 주장하지 않는다. FEM wiki 근거는 `Abaqus Input File Syntax`, `Abaqus Output Database and Results Files`, `Abaqus General and Linear Perturbation Steps`, `Abaqus Initial and Boundary Conditions`, `Abaqus Loads and Predefined Fields`, `Abaqus Beam and Shell Section Definitions`를 사용했다. 이 근거는 keyword/data/comment line, model/history data, output request, step/load/boundary/section 용어를 정렬하기 위한 보조 근거이며, 승인된 FESA 요구조건과 정식화가 우선한다. ## 2. Abaqus Input Scope - input_format: Abaqus input file (`.inp`) - supported Abaqus documentation source/version: 프로젝트 연구 bundle 및 local FEM wiki에 보존된 Abaqus 2024 input syntax/output vocabulary. 저장된 nonlinear reference input은 Abaqus/CAE Learning Edition 2024 생성물이다. - supported_analysis: no-prior-history baseline에서 시작하는 정확히 하나의 source `*STEP, NLGEOM=YES`와 하나의 nonlinear `*STATIC` procedure. - internal_element_formulation: source `S4`와 `S4R` 모두 materially linear, geometrically nonlinear Total Lagrangian `FESA-MITC4`에 매핑한다. - ordinary_unit_system: 사용자가 일관되게 선택한 미지정 단위계. FESA는 단위 추론이나 변환을 수행하지 않는다. - compatibility_disclaimer: 이 문서가 명시한 keyword 위치, parameter, data-line arity, validation rule, output mapping만 지원 범위다. `supported`는 syntax가 parsing되고 feature semantic model에 매핑된다는 뜻이다. `unsupported`는 명확한 diagnostic으로 거부한다. `ignored-with-warning`은 syntax와 소속 data line을 소비하고 warning을 남기지만 Domain, AnalysisModel, nonlinear procedure, mandatory HDF5 output 또는 reference comparison 의미를 바꾸지 않는다. `requires-user-decision` 항목은 없다. | keyword | policy | allowed location | required parameters and data grammar | semantic mapping | unsupported behavior | | --- | --- | --- | --- | --- | --- | | `*HEADING` | supported | optional top-level first keyword | parameter 없음; 다음 keyword 전까지 text row 0개 이상 | raw heading을 source metadata로 보존 | parameter, nested location, 두 번째 heading은 input error | | `*INCLUDE` | unsupported | anywhere | 허용 data/parameter grammar 없음 | file traversal 또는 include expansion 없음 | `unsupported-keyword`; 참조 파일을 열지 않음 | | `*PART` / `*END PART` | supported | top-level model block | `NAME=` 필수; `*END PART` data 없음 | part-local node, element, set, shell section scope | unclosed, nested, duplicate, data-bearing close는 input error | | `*NODE` | supported | part scope | 각 row `node_label,x,y,z`; parameter 없음 | 양의 source node label과 finite global Cartesian coordinate | arity 오류, duplicate label, nonfinite value, dangling later reference는 input/model error | | `*NSET` | supported | part 또는 assembly scope | `NSET=` 필수; optional `GENERATE`; assembly scope는 `INSTANCE=` 필수; explicit labels 또는 `first,last,increment` | deterministic node-set membership | mixed-instance set, invalid generate row, duplicate set name, empty set, dangling member는 input error | | `*ELEMENT` | supported | part scope | `TYPE=S4` 또는 `TYPE=S4R`; 각 row `element_label,n1,n2,n3,n4` | four-node source shell connectivity; source type 보존; internal type `FESA-MITC4` | 다른 element type은 `unsupported-element-formulation`; repeated node, arity 오류, dangling node, mixed element model은 error | | `*ELSET` | supported | part 또는 assembly scope | `ELSET=` 필수; optional `GENERATE`; assembly scope는 `INSTANCE=` 필수; `*NSET`과 같은 row rule | deterministic element-set membership | mixed-instance set, invalid generate row, duplicate set name, empty set, dangling member는 input error | | `*MATERIAL` | supported | top-level model data | `NAME=` 필수; data 없음 | 정확히 하나의 supported isotropic `*ELASTIC` 소유 | duplicate material, missing/duplicate elasticity, 다른 material behavior는 input error | | `*ELASTIC` | supported | current `*MATERIAL` scope | 정확히 한 row `E,nu`; parameter 없음 | homogeneous isotropic linear elasticity; `G=E/(2(1+nu))` 파생 | extra field/row, dependency/temperature data, nonfinite value, `E<=0`, `nu<=-1`, `nu>=0.5`는 error | | `*SHELL SECTION` | supported | part scope | `ELSET=`와 `MATERIAL=` 필수; 정확히 한 row `thickness[,integration_points]` | centered homogeneous single-layer shell section | composite/layer data, offset, orientation, controls, variable thickness, missing reference, conflicting assignment, nonpositive thickness는 error | | `*ASSEMBLY` / `*END ASSEMBLY` | supported | 정확히 하나의 top-level assembly | `NAME=` 필수; `*END ASSEMBLY` data 없음 | identity-instance scope와 assembly-level set scope | nested/duplicate assembly, instance transform data, unmatched close는 input error | | `*INSTANCE` / `*END INSTANCE` | supported | assembly scope | `NAME=`, `PART=` 필수; transform data 없음 | named identity copy; 같은 part의 multiple identity instances 허용 | duplicate/dangling instance 또는 translation/rotation data는 unsupported input | | `*BOUNDARY` | supported | top-level model data 또는 sole step의 `*STATIC` 뒤 | parameter 없음; 각 row `target,first_dof,last_dof[,value]`; omitted value는 exact zero | common load-factor path의 factor-one absolute global DOF target; DOF `1..6` | amplitude, local coordinate system, invalid range/arity, unresolved target, nonfinite value, conflicting expanded value는 error | | `*CLOAD` | supported | sole step의 `*STATIC` 뒤 | parameter 없음; 각 row `target,dof,magnitude`; DOF `1..6` | load factor로만 scale되는 fixed-global dead nodal force/moment source | amplitude/follower/local load, invalid arity/DOF, unresolved target, nonfinite magnitude, drilling-direction aggregate moment는 error | | `*DLOAD` | unsupported | anywhere | 허용 data/parameter grammar 없음 | distributed/body/pressure/edge/follower load object를 만들지 않음 | load-like usage는 `unsupported-distributed-load`; 그 외는 `unsupported-keyword` | | `*STEP` / `*END STEP` | supported for nonlinear selector | 정확히 하나의 top-level history block | optional `NAME`; `NLGEOM=YES` 필수; `*END STEP` data 없음 | canonical nonlinear step identity `Step-1` | zero/multiple/mixed/unclosed/nested step 또는 non-`YES` nonlinear selector는 nonlinear increment 전 실패 | | `*STATIC` | supported nonlinear procedure | sole step의 첫 procedure keyword | 정확히 한 row `initial_increment,time_period,minimum_increment,maximum_increment`; 네 값 모두 finite positive; `time_period`는 endpoint `1.0` identity | 첫 값은 fixed increment `h`; 세 번째/네 번째 값은 unused compatibility source; factors는 one 미만 ordinal multiple 뒤 exact factor one | missing/extra rows/fields, nonpositive/nonfinite field, endpoint가 `1.0`이 아니면 `invalid-nonlinear-static-data` | | `*OUTPUT` | ignored-with-warning | sole step의 `*STATIC` 뒤 | 정확히 `FIELD, VARIABLE=PRESELECT` 또는 `HISTORY, VARIABLE=PRESELECT`; `FIELD`/`HISTORY`는 value 없는 flag이고 둘 중 하나만 필요; `VARIABLE`은 정확히 한 번 필요; duplicate, both flags, missing `VARIABLE`, 다른 value, extra parameter는 input error | stored reference의 `*Output, field, variable=PRESELECT`와 `*Output, history, variable=PRESELECT`를 warning no-op으로 수용; FESA mandatory output을 select/suppress할 수 없음 | output request는 FESA output을 바꾸지 않음; malformed parameter set은 `invalid-keyword-parameter` | | `*NODE OUTPUT` | ignored-with-warning | active allowlisted `*OUTPUT` scope | parameter와 다음 keyword 전 variable data를 소비 | legacy nodal request `U`, `RF` 등을 수용 | HDF5 selection, history output, empty synthetic dataset을 만들지 않음 | | `*ELEMENT OUTPUT` | ignored-with-warning | active allowlisted `*OUTPUT` scope | parameter와 다음 keyword 전 variable data를 소비 | legacy element request `S` 등을 수용 | extrapolated stress, averaging, comparison projection을 만들지 않음 | | `*PREPRINT` | ignored-with-warning | top-level | parameter를 보존 후 무시; data 불필요 | generator control syntax 수용 | semantic object 없음 | | `*RESTART` | ignored-with-warning | sole step | parameter를 보존 후 무시; restart state/data 없음 | legacy restart request syntax 수용 | restart write/read/continue 없음 | | `*CONTACT OUTPUT` | ignored-with-warning | active allowlisted `*OUTPUT` scope | parameter와 다음 keyword 전 data를 소비 | legacy contact-output request syntax만 수용 | contact model/output 없음 | `*ORIENTATION`, `*TRANSFORM`, amplitudes, follower loads, pressure, gravity, body force, edge load, `*DLOAD`, composite shell definitions, shell section offsets, material nonlinearity, density, temperature dependency, contact, MPC, penalty, multiple steps, restarts, submodels, transforms, nested assemblies와 위 표에 없는 모든 model-affecting keyword는 fail-closed unsupported input이다. 저장 또는 future linear shell input의 `NLGEOM=NO`는 `docs/linear-static-mitc4-shell/io.md`가 계속 관할한다. 이 feature bundle에서 해당 linear case는 `shell-s4-linear-limit` regression reference일 뿐 nonlinear response evidence가 아니다. ## 3. Syntax Policy - Keyword line은 optional leading whitespace 뒤 `*`로 시작한다. Comment line은 `**`로 시작하며 semantic effect가 없다. - Keyword name, parameter name, supported enumerated value, named-reference lookup은 ASCII case-insensitive다. Raw source spelling은 diagnostic/report display용으로 보존한다. - Data line과 keyword parameter field는 comma-separated다. 주변 whitespace는 parsing 전에 trim한다. 필수 field가 비어 있거나, 허용되지 않은 trailing field가 있거나, numeric token이 malformed이면 input error다. - 승인된 empty data-field 의미는 `*BOUNDARY` 네 번째 value 생략뿐이며 exact zero로 매핑한다. `*SHELL SECTION`의 optional second field는 생략 가능하고, 존재하면 positive base-10 integer여야 한다. - Continuation line, physical-line continuation, multiline name, quoted case-sensitive name, parameter substitution, include file은 unsupported다. 각 logical keyword/data row는 한 physical line에 완결되어야 한다. - 이 feature는 public numeric Abaqus line-length compatibility limit를 정의하지 않는다. 승인 input은 single-line ASCII record이며, 읽을 수 없는 physical line은 implicit continuation 없이 parsing 실패다. - Keyword, parameter, set/material/part/instance name, numeric label의 input text는 ASCII로 취급한다. HDF5 string output은 UTF-8이지만 non-ASCII source label/name은 이 feature 계약 밖이다. - Node label, element label, explicit set member는 positive base-10 integer다. Source label은 text와 numeric identity로 보존한다. Stable internal index는 diagnostic 또는 comparison row에서 source identity를 대체할 수 없다. - 모든 real-valued input은 finite `double`로 parse되어야 한다. `NaN`, `Inf`, overflow, nonfinite underflow, locale-dependent numeric format은 reject한다. - Model data와 history data는 개념적으로 분리한다. Mesh, set, material, section, coordinate, initial shell frame은 model data다. Step, procedure, boundary, load, output request는 history data다. - 어떤 keyword에도 속하지 않는 standalone data 또는 active keyword block 밖의 data는 input error다. Output-request variable data는 allowlisted output keyword에 종속될 때만 no-op으로 소비한다. - 모든 parsed keyword, parameter, data row, semantic entity는 normalized file path, 1-based line, raw keyword spelling, source identity까지 추적 가능해야 한다. ## 4. Model Data Mapping ### 4.1 Stable Source Identity and Ordering Identity-instance expansion 뒤 source node와 source element의 stable identity는 다음과 같다. ```text SourceEntityId { instance_name, source_label } ``` Name lookup은 case-insensitive지만 raw spelling은 보존한다. Stable internal ID는 input part declaration order, instance declaration order, part-local entity declaration order로 부여한다. Hash iteration, thread scheduling, set spelling, CSV row order는 source identity, internal row order, diagnostic order 또는 result row order를 바꾸면 안 된다. ### 4.2 Nodes, Elements and Sets - `*NODE`는 finite global Cartesian initial midsurface coordinate `[X,Y,Z]`로 매핑하며 unit dimension은 `length`다. - `*ELEMENT, TYPE=S4/S4R`는 ordered four-node shell connectivity `[1,2,3,4]`로 매핑한다. Natural corner 순서는 `(-1,-1)`, `(+1,-1)`, `(+1,+1)`, `(-1,+1)`이며 connectivity를 조용히 reverse하지 않는다. - Source type `S4` 또는 `S4R`는 metadata로 보존한다. 두 type 모두 같은 internal `FESA-MITC4` formulation, `2 x 2 x 2` integration, nonlinear state path를 선택한다. Source `S4R`는 reduced integration, hourglass control 또는 Abaqus `S4R` internal behavior를 활성화하지 않는다. - `*NSET`과 `*ELSET`은 explicit row order를 보존한다. `GENERATE`는 inclusive `first,last,increment` 순서로 expand한다. Assembly-scope set은 하나의 `INSTANCE`만 참조할 수 있고 mixed instance는 허용하지 않는다. - Set membership은 Domain commit 전에 source identity로 resolve한다. 같은 scope의 duplicate set definition, dangling member, invalid generate range는 analysis 전 실패한다. ### 4.3 Material, Section, Coordinates and Units - `*MATERIAL`과 `*ELASTIC`은 finite `E>0`, `-10`를 갖는 centered homogeneous shell layer로 매핑한다. Optional source integration-point 값은 syntax compatibility로만 보존하며 quadrature, recovery, output, reference comparison에 영향을 주지 않는다. - Initial nodal director와 right-handed triad는 instance expansion 뒤 승인된 linear MITC4 deterministic incident-element rule로 파생한다. 이 값들은 model data이며 모든 increment의 fixed initial reference를 정의한다. - 필수 geometry check는 finite coordinate, valid four-node topology, 모든 Gauss/tying/ center/recovery location의 positive reference Jacobian, non-opposed incident normals, valid reciprocal bases, valid initial frames를 포함한다. - `.inp` 단위는 user-consistent unspecified다. HDF5는 `length`, `force`, `force*length`, `force/length`, `force/length^2`, `1` 같은 unit dimension string만 기록하고 SI를 쓰거나 추론하지 않는다. ## 5. History Data Mapping ### 5.1 Step and Procedure Nonlinear procedure는 정확히 하나의 source step이 `*STEP, NLGEOM=YES`를 포함하고 그 안에 정확히 하나의 supported `*STATIC` data row가 있을 때만 선택한다. Semantic step name은 canonical `Step-1`이다. Raw source step name은 provenance로만 보존한다. Nonlinear `*STATIC` data row의 의미는 다음과 같다. - `initial_increment`는 fixed positive load-factor increment `h`다. - `time_period`는 endpoint `1.0`과 정확히 같은 identity여야 한다. - `minimum_increment`와 `maximum_increment`는 positive finite source value여야 하지만 cutback, growth, retry, stopping, convergence, output cadence에는 사용하지 않는다. - Intended factor identity는 `1.0`보다 작은 ordinal `j*h` 값들을 만든 뒤, 마지막에 exact assigned factor `1.0` 하나를 붙여 만든다. Cumulative `lambda += h`, tolerance-based duplicate endpoint detection, growth, cutback, retry는 금지한다. - `reference/shellNL/shellNL.inp`의 성공 run에서 expected intended/accepted factor sequence는 `0.1,0.2,...,1.0`이다. Factor zero는 no-prior-history step-start committed baseline이다. Accepted frame은 committed increment와 일대일 대응해야 하므로 factor zero는 accepted HDF5 frame이 아니다. Factor zero는 다음 metadata/model dataset으로만 projection한다. - `factor_zero_is_frame=0` - `factor_zero_load_factor=0.0` - `/model/prescribed_displacement_start`와 initial state의 step-start displacement 및 rotation-vector component - `/model/shell/nodal_frame`과 `/model/shell/nodal_director`의 step-start triad/director - zero scaled `*CLOAD` contribution과 step-start boundary value ### 5.2 Boundary Conditions `*BOUNDARY` target resolution은 direct node label 또는 node set을 허용한다. Expanded row는 stable source-node identity와 DOF order `1..6`를 사용한다. | DOF | component | unit dimension | nonlinear path meaning | | ---: | --- | --- | --- | | 1 | `UX` / CSV `U1` | length | factor-one absolute global displacement target | | 2 | `UY` / CSV `U2` | length | factor-one absolute global displacement target | | 3 | `UZ` / CSV `U3` | length | factor-one absolute global displacement target | | 4 | `URX` / CSV `UR1` | dimensionless rotation | factor-one absolute fixed-initial global rotation-vector target | | 5 | `URY` / CSV `UR2` | dimensionless rotation | factor-one absolute fixed-initial global rotation-vector target | | 6 | `URZ` / CSV `UR3` | dimensionless rotation | factor-one absolute fixed-initial global rotation-vector target | Step 앞 row와 sole step 내부 row는 모두 같은 semantic step의 factor-one target으로 매핑한다. Cross-step propagation은 없다. Load factor `lambda`에서 current constrained value는 `q_start + lambda * (q_target - q_start)`다. Current release에는 prior history가 없으므로 ordinary start value는 승인된 start-state dataset에 명시된 값을 제외하고 zero다. Constrained Newton correction component는 exact zero다. ### 5.3 Concentrated Loads `*CLOAD` target resolution은 boundary와 같다. 같은 node/DOF로 resolve되는 여러 row는 source order로 factor-one global load coefficient에 누적한다. Factor `lambda`에서 magnitude는 `lambda`만 곱한다. | DOF | source component | unit dimension | nonlinear meaning | | ---: | --- | --- | --- | | 1 | `F1` | force | fixed-global dead nodal force | | 2 | `F2` | force | fixed-global dead nodal force | | 3 | `F3` | force | fixed-global dead nodal force | | 4 | `M1` | force*length | fixed-global source nodal moment admitted only through physical director-tangent work | | 5 | `M2` | force*length | fixed-global source nodal moment admitted only through physical director-tangent work | | 6 | `M3` | force*length | fixed-global source nodal moment admitted only through physical director-tangent work | Nonzero aggregated nodal moment `M_src`마다 preprocessing과 모든 entered trial state에서 `abs(dot(d,M_src))/norm(M_src) <= 1e-12`를 denominator clamping 없이 만족해야 한다. 실패하면 `unsupported-drilling-load`다. Source moment vector는 fixed global coordinate에 남으며 FESA는 rejected moment component를 회전, 축소, 변형하거나 numerical drilling channel로 보내지 않는다. ### 5.4 Output Requests Abaqus output request keyword는 `ignored-with-warning` compatibility syntax로만 수용한다. 이 keyword들은 history output을 켜지 않고, frame cadence를 제어하지 않으며, mandatory FESA HDF5 dataset을 select, suppress, rename할 수 없다. Trial Newton state는 HDF5 field/history output이 아니다. Per-iteration evidence는 `_log.txt`에 diagnostic text로만 기록한다. ## 6. Internal Model Contract 이 section은 semantic field를 정의하며 C++ API를 정의하지 않는다. - Node record: stable internal node ID, `SourceEntityId`, finite global coordinate, initial director, initial right-handed triad, source location. - Element record: stable internal element ID, `SourceEntityId`, preserved source type `S4` 또는 `S4R`, internal formulation `FESA-MITC4`, ordered four-node connectivity, resolved section/material identity, source location. - Set record: case-insensitive set name, source scope, optional source instance, deterministic expanded source members, stable internal member IDs. - Material record: case-insensitive material name, finite `E`, finite `nu`, derived `G`, source location, homogeneous isotropic materially linear identity. - Section record: source `ELSET`, resolved material, positive thickness, optional ignored source integration-point field, centered single-layer identity. - Boundary record: source target, expanded node identities, DOF range, finite factor-one absolute target values, step-start values, source location, conflict status. - Load record: source target, expanded node identities, DOF, finite factor-one source magnitude, deterministic aggregate value, dead fixed-global load identity. - Step record: raw source name, canonical `Step-1`, `NLGEOM=YES` nonlinear procedure identity, fixed increment `h`, endpoint `1.0`, unused third/fourth `*STATIC` values, intended factor sequence, output-request no-op inventory. - State contract: committed state와 trial state는 alias될 수 없다. 완전하게 수렴한 candidate만 displacement, rotation vector, `Q`, director, load factor, frame identity, internal/external force, residual/reaction, physical recovery row를 commit한다. Failed trial, nonconvergence, nonfinite data, solve failure, recovery failure 또는 output failure는 prior committed state와 prior authoritative final result를 보존한다. - Output request record: keyword, parameter, variable row, source location은 warning diagnostic용으로만 보존한다. Solver 또는 HDF5 selection effect는 없다. Source identity와 internal index identity는 diagnostics, HDF5 row order, reference comparison 전체에서 구분해야 한다. CSV의 element-label order는 solver identity가 아니며 `(instance, source_label)` key를 대체하지 않는다. ## 7. Output HDF5 Schema ### 7.1 Public Output Names, Log and Lifecycle 승인된 public CLI shape는 다음 하나뿐이다. ```powershell fesa.exe ``` CLI는 input path 해석보다 먼저 argv token을 왼쪽에서 오른쪽으로 scan한다. 어떤 token이든 case-sensitive exact literal substring `--output`을 포함하면, `--output`, `--output=...`, `--output-path`, prefix/suffix form을 모두 포함해 usage failure다. 이 failure는 input path resolution, parsing, Analysis construction, derived-result path ownership, HDF5 candidate, log creation/truncation, output finalization 전 exit code `2`로 끝난다. Stderr에는 ordered diagnostic 하나만 쓴다. ```text severity=error code=cli-usage argument_index= argument= message=literal --output is not supported ``` 여러 token이 `--output`을 포함해도 첫 matching token만 보고 위 diagnostic 하나만 낸다. Literal `--output`에 대한 compatibility alias나 deprecation window는 없다. `--output`을 포함하지 않는 다른 unknown option은 별도 `unrecognized-option` usage diagnostic을 유지할 수 있다. Input/output lexical identity는 다음 순서로 정의한다. 1. 단일 input path token이 relative path이면 invocation CWD를 lexical base로 붙인다. 2. `.`와 `..` component만 lexically normalize한다. Symlink, junction, short-name, case-preserving target path는 resolve하지 않는다. 3. Normalized user-addressed final filename의 마지막 extension이 case-insensitive `.inp`가 아니면 input usage failure다. 4. ``은 마지막 extension 하나만 제거한 basename이다. 앞선 dot과 basename case는 보존한다. 예: `Beam.Model.INP` -> `Beam.Model_results.h5`, `Beam.Model_log.txt`. 5. Derived outputs는 normalized user-addressed input path의 sibling이다. - result final: `/_results.h5` - log final/live file: `/_log.txt` File-vs-directory collision과 same-derived-pair concurrency는 output ownership 문제다. `_log.txt`가 directory 또는 truncate 불가능한 non-regular path이면 log create/open/ truncate failure다. `_results.h5`가 directory이면 HDF5 output collision으로 fail-closed 한다. 같은 derived pair를 목표로 하는 concurrent invocation은 same-directory implementation-private lock을 nonblocking exclusive ownership으로 먼저 획득해야 한다. Lock 획득 실패 또는 lock path의 directory collision은 exit code `6`의 output-busy failure이며 best-effort fatal stderr diagnostic 하나를 시도하고 log/HDF5를 변경하지 않는다. Lock holder 하나만 log truncate, HDF5 candidate, final replace를 시도한다. Candidate filename은 public contract가 아니지만 반드시 same-directory, implementation-private, exclusive-create collision-safe여야 하며 실패한 candidate는 authoritative output이 아니다. HDF5 result lifecycle과 log lifecycle은 의도적으로 비대칭이다. - `_log.txt`는 CLI usage validation, lexical output derivation, single-writer lock 획득 뒤 replace/truncate된다. Create/open/truncate failure는 Analysis 전 exit code `6`으로 abort하며, best-effort fatal stderr diagnostic 하나를 시도한다. - Log write/flush failure는 즉시 abort한다. Solver는 retry, fallback, continue 또는 result commit을 하지 않는다. Prior authoritative HDF5는 보존하고, 이미 flush된 live-log prefix는 rollback하지 않는다. Failed write 뒤 남은 partial trailing line은 authoritative iteration record가 아니며 tooling은 LF-terminated complete record만 parsing한다. - Log close는 successful analysis/recovery 뒤, 그리고 HDF5 candidate open/write/final replace 전 수행한다. Close failure는 result commit을 block하고 exit code `6`으로 끝낸다. - `_results.h5`는 sibling candidate가 완전히 write, flush, close, reopen, schema-check된 뒤 atomic move/replace에 성공한 경우에만 authoritative다. - HDF5 failure는 exit code `6`을 반환하고 가능한 경우 prior valid final을 보존하며 current-run log를 rollback하지 않는다. HDF5 failure는 log close 성공 뒤 발생하므로 current log는 닫힌 current-run audit으로 남는다. Newton iteration log는 UTF-8 no BOM, LF-terminated text file이다. Header, trailer, BOM, CRLF는 없다. Entered Newton iteration마다 physical line 하나만 기록하고, 각 line은 fixed field order의 TAB-separated `label=value` record다. Per-iteration stderr duplication은 정확히 0개다. 각 iteration record는 다음 iteration 진입 전 또는 return 전 flush되어야 한다. Non-Newton procedure 또는 Newton iteration에 진입하기 전 끝난 controlled failure는 iteration record를 fabricate하지 않는다. 같은 open/truncate/failure lifecycle을 적용하되 successful non-Newton run의 `_log.txt` content는 zero-byte empty file이다. Pre-Newton controlled failure도 entered iteration이 없으면 iteration record가 없는 log file만 남긴다. 고정 field order는 다음과 같다. | order | label | value contract | | ---: | --- | --- | | 1 | `record` | literal `newton-iteration` | | 2 | `schema` | literal `nsnr-log-v1` | | 3 | `increment` | entered increment identity, `uint64` | | 4 | `target_factor` | finite round-trip numeric load factor | | 5 | `iteration` | entered Newton iteration identity `1..100` | | 6 | `last_completed_stage` | enum stage completed before outcome; `none` allowed | | 7 | `failing_stage` | `none` for completed gate records, otherwise failing stage enum | | 8 | `residual_force_channel` | literal `residual_force` or `not-evaluated(reason)` | | 9 | `residual_force_numerator_norm` | `||r_f^u||_inf` or `not-evaluated(reason)` | | 10 | `residual_force_denominator_scale` | matching `||f_ext,f^u||_inf`가 exact zero이면 exact `0`; nonzero이면 `max(||f_int,f^u||_inf,||f_ext,f^u||_inf)`; 또는 `not-evaluated(reason)` | | 11 | `residual_force_branch` | matching external scale이 nonzero이면 `relative`, exact zero이면 `zero-scale`, 또는 `not-evaluated(reason)` | | 12 | `residual_force_threshold` | `1e-2` for `relative`, `1e-3` for `zero-scale`, or `not-evaluated(reason)` | | 13 | `residual_force_threshold_unit` | `1`, `force`, or `not-evaluated(reason)` | | 14 | `residual_force_pass` | `0`, `1`, or `not-evaluated(reason)` | | 15 | `residual_moment_channel` | literal `residual_moment` or `not-evaluated(reason)` | | 16 | `residual_moment_numerator_norm` | `||r_f^phi||_inf` or `not-evaluated(reason)` | | 17 | `residual_moment_denominator_scale` | matching `||f_ext,f^phi||_inf`가 exact zero이면 exact `0`; nonzero이면 `max(||f_int,f^phi||_inf,||f_ext,f^phi||_inf)`; 또는 `not-evaluated(reason)` | | 18 | `residual_moment_branch` | matching external scale이 nonzero이면 `relative`, exact zero이면 `zero-scale`, 또는 `not-evaluated(reason)` | | 19 | `residual_moment_threshold` | `1e-2` for `relative`, `1e-3` for `zero-scale`, or `not-evaluated(reason)` | | 20 | `residual_moment_threshold_unit` | `1`, `force*length`, or `not-evaluated(reason)` | | 21 | `residual_moment_pass` | `0`, `1`, or `not-evaluated(reason)` | | 22 | `correction_translation_channel` | literal `correction_translation` or `not-evaluated(reason)` | | 23 | `correction_translation_numerator_norm` | `||Delta u_f||_inf` fresh correction or `not-evaluated(reason)` | | 24 | `correction_translation_denominator_scale` | `||Delta u_inc,f||_inf` from current trial relative to step start or `not-evaluated(reason)` | | 25 | `correction_translation_branch` | `relative`, `zero-scale`, or `not-evaluated(reason)` | | 26 | `correction_translation_threshold` | `1e-2` for `relative`, `1e-3` for `zero-scale`, or `not-evaluated(reason)` | | 27 | `correction_translation_threshold_unit` | `1`, `length`, or `not-evaluated(reason)` | | 28 | `correction_translation_pass` | `0`, `1`, or `not-evaluated(reason)` | | 29 | `correction_rotation_channel` | literal `correction_rotation` or `not-evaluated(reason)` | | 30 | `correction_rotation_numerator_norm` | `||Delta phi_f||_inf` fresh correction or `not-evaluated(reason)` | | 31 | `correction_rotation_denominator_scale` | `||Delta phi_inc,f||_inf` from current trial relative to step start or `not-evaluated(reason)` | | 32 | `correction_rotation_branch` | `relative`, `zero-scale`, or `not-evaluated(reason)` | | 33 | `correction_rotation_threshold` | `1e-2` for `relative`, `1e-3` for `zero-scale`, or `not-evaluated(reason)` | | 34 | `correction_rotation_threshold_unit` | `1`, `1`, or `not-evaluated(reason)` | | 35 | `correction_rotation_pass` | `0`, `1`, or `not-evaluated(reason)` | | 36 | `combined_pass` | logical AND of four pass fields, or `not-evaluated(reason)` | | 37 | `transition` | `accept`, `update`, `fail`, or `not-evaluated(reason)` | | 38 | `outcome` | `accepted`, `continue`, `nonconverged`, or `failed` | | 39 | `diagnostic_code` | `none` or approved diagnostic code | `nsnr-log-v1`의 39개 field label, order와 TAB-separated `label=value` serialization은 변경하지 않는다. Completed gate record는 `failing_stage=none`이고 네 channel의 identity, numerator/norm, denominator/scale, branch, typed threshold, pass를 모두 finite 또는 enum value로 노출한다. Residual channel은 required residual/internal/external vector와 그 infinity norm을 모두 finite로 확인한 뒤 matching external scale `S_ext^u=||f_ext,f^u||_inf` 또는 `S_ext^phi=||f_ext,f^phi||_inf` 자체로 branch를 선택한다. Matching external scale이 exact zero이면 `residual_*_denominator_scale=0`, `residual_*_branch=zero-scale`로 직렬화하고 numerator에 typed absolute `1e-3 force` 또는 `1e-3 force*length`를 inclusive `<=`로 직접 적용한다. 이 exact `0`은 matching external selector를 직렬화하며 divisor 또는 internal-inclusive max가 아니다. Selector predicate는 `S_ext==0`이고 tolerance band, zero clamp, `max(1,...)`를 쓰지 않는다. Internal scale 또는 residual numerator가 nonzero여도 이 branch를 `relative`로 바꾸지 않는다. Matching external scale이 nonzero이면 `residual_*_denominator_scale`은 retained `max(||f_int,f||_inf,||f_ext,f||_inf)`이고 `residual_*_branch=relative`이며, numerator/denominator ratio에 dimensionless `1e-2`를 inclusive `<=`로 적용한다. 이 branch에 typed absolute gate를 OR로 추가하지 않는다. Correction channel은 기존 계약 그대로 current-trial incremental-solution denominator가 exact zero이면 `zero-scale`과 typed `1e-3 length` 또는 `1e-3 dimensionless`를, nonzero이면 `relative`와 dimensionless `1e-2`를 사용한다. Empty free channel은 exact-zero numerator/scale의 typed `zero-scale` branch로 평가한다. 네 channel의 pass는 `combined_pass`에서 logical AND로만 결합한다. Early failure record는 entered iteration 하나에 대응한다. 이미 계산된 earlier fields는 실제 finite value를 기록하고, 실패 stage 뒤의 모든 later field는 `not-evaluated(reason)`을 기록한다. Not-evaluated field에 zero, pass `0`, pass `1`, fabricated denominator 또는 fabricated threshold를 쓰면 안 된다. `last_completed_stage`와 `failing_stage`는 stage enum을 사용하며 recommended enum은 `iteration-entered`, `trial-state`, `load-boundary`, `residual`, `tangent`, `factorization`, `correction`, `convergence-gates`, `update`, `recovery`, `commit`, `log-write`, `log-flush`, `none`이다. Numeric value는 locale-independent C-locale decimal point를 사용하고 finite IEEE-754 `double` round-trip이 가능해야 한다. `NaN`, `Inf`, localized comma, thousands separator, raw whitespace는 금지한다. String value는 raw TAB/LF/CR/control byte/backslash를 포함할 수 없으며 `\\`, `\t`, `\n`, `\r`, `\0`, `\xHH` escape를 사용한다. Record order는 increment, target factor, iteration 순서로 deterministic해야 한다. Schema version `1`의 모든 mandatory HDF5 dataset은 contiguous, uncompressed dataset이다. Chunking, compression filter, extendible dataset, trial-history group은 이 release 계약에 없다. ### 7.2 Metadata and Common Dataset Attribute Rules `results.h5` schema가 authoritative solver output이다. 실제 final filename은 Section 7.1의 `_results.h5`다. 모든 string은 UTF-8이다. 모든 physical real dataset은 IEEE-754 float64를 사용한다. Stable ID는 별도 명시가 없으면 unsigned 64-bit integer다. `/metadata` group의 required attributes는 다음과 같다. | attribute | required value or meaning | | --- | --- | | `schema_version` | `1` | | `feature_id` | `nonlinear-static-newton-raphson` | | `solver_version` | executing solver version string | | `source_input_identity` | lexical normalized user-addressed input path and content identity string; symlink/junction target resolution 없음 | | `unit_system_label` | `user-consistent-unspecified` | | `coordinate_convention` | `global-cartesian; shell-local=fixed-initial-reference; positive-thickness=+zeta` | | `analysis_procedure` | `nonlinear-static-full-newton` | | `internal_formulation` | `FESA-MITC4-total-lagrangian` | | `integration_rule` | `2x2x2-gauss; mitc4-edge-midpoint-shear` | | `step_name` | `Step-1` | | `frame_indexing` | `accepted-increment-order-zero-based` | | `factor_zero_is_frame` | `0` | | `factor_zero_load_factor` | `0.0` | 모든 numeric model/result dataset은 다음 required attributes를 가진다. - `schema_version=1` - `component_names` - `component_unit_dimensions` - `coordinate_system` - `location` Accepted-frame result dataset은 추가로 다음 attributes를 가진다. - `step_name=Step-1` - `frame_index=` - `increment_index=` - `load_factor=` - `is_factor_one=<0|1>` ### 7.3 Model Datasets | 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 ID ascending; `coordinate_system=global-cartesian`, `component_unit_dimensions=length,length,length`, `location=nodal-reference` | | `/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; `formulation=FESA-MITC4-total-lagrangian` | | `/model/shell/materials` | `[material_count]` compound | `internal_material_id:uint64`, `name:utf8`, `E:float64`, `nu:float64` | declaration order; `component_unit_dimensions=force/length^2,1`, `location=model-material` | | `/model/shell/sections` | `[section_count]` compound | `internal_section_id:uint64`, `source_file:utf8`, `source_line:uint64`, `source_elset:utf8`, `material_internal_id:uint64`, `thickness:float64` | declaration order; `component_unit_dimensions=length`, `location=model-shell-section`, `layering=centered-single-layer` | | `/model/shell/nodal_director` | `[node_count,3]` float64 | `/model/nodes` row; `[D1,D2,D3]` | initial director; `coordinate_system=global-cartesian`, `location=nodal-initial-director`, units `1,1,1` | | `/model/shell/nodal_frame` | `[node_count,3,3]` float64 | `/model/nodes` row; axis row `[A,B,D]`, global component column `[X,Y,Z]` | initial right-handed triad; `coordinate_system=global-cartesian`, `location=nodal-initial-frame`, units `1,1,1` | | `/model/nodal_constraint_mask` | `[node_count,6]` uint8 | `/model/nodes` row; DOF `[UX,UY,UZ,URX,URY,URZ]` | `0=free`, `1=constrained`; constrained reaction comparison identity의 authority | | `/model/prescribed_displacement_start` | `[node_count,6]` float64 | same row/DOF order | factor-zero start values; units `[length x3,1 x3]`, `load_factor=0.0` | | `/model/prescribed_displacement_target` | `[node_count,6]` float64 | same row/DOF order | factor-one absolute target values; units `[length x3,1 x3]`, `load_factor=1.0` | | `/model/shell/midsurface_locations` | `[4,2]` float64 | location rows `GP1..GP4`; columns `[XI,ETA]` | `coordinate_system=shell-natural`; `(-g,-g),(+g,-g),(+g,+g),(-g,+g)`, `g=1/sqrt(3)` | | `/model/shell/section_positions` | `[3]` float64 | rows `[BOTTOM,MIDDLE,TOP]`; values `[-1,0,+1]` | `coordinate_system=shell-natural`; physical `z=t*zeta/2`; Abaqus section-point identity가 아님 | ### 7.4 Accepted Frame Table Successful nonlinear run 뒤 `/steps/Step-1/accepted_frames`는 mandatory다. | path | shape and dtype | fields | required meaning | | --- | --- | --- | --- | | `/steps/Step-1/accepted_frames` | `[frame_count]` compound | `frame_index:uint64`, `increment_index:uint64`, `load_factor:float64`, `iteration_count:uint64`, `is_factor_one:uint8` | committed increment마다 한 row; `frame_index`는 `` group name과 같음; load factor는 strictly increasing; 마지막 row는 `load_factor=1.0`, `is_factor_one=1` | `frame_count`는 committed increment 수이며 successful run에서는 하나 이상이다. Factor-one row는 정확히 하나다. Factor zero는 이 dataset에 row를 갖지 않고 `/frames/0` 특별 의미도 갖지 않는다. ### 7.5 Accepted Frame Result Datasets `/steps/Step-1/accepted_frames.frame_index = `마다 아래 dataset들이 `/steps/Step-1/frames//` 아래 mandatory다. | quantity | exact dataset path | shape | row identity and component order | units / coordinates / location | | --- | --- | --- | --- | --- | | committed displacement and rotation vector | `/steps/Step-1/frames//nodal/displacement` | `[node_count,6]` float64 | `/model/nodes` row; `[UX,UY,UZ,URX,URY,URZ]` | `[length,length,length,1,1,1]`; global Cartesian translations and fixed-initial global rotation-vector components; nodal | | committed triad | `/steps/Step-1/frames//nodal/triad` | `[node_count,3,3]` float64 | node row; axis row `[A,B,D]`, global component column `[X,Y,Z]` | dimensionless; global Cartesian; committed `Q`; director는 row `D` | | committed director | `/steps/Step-1/frames//nodal/director` | `[node_count,3]` float64 | node row; `[D1,D2,D3]` | dimensionless; global Cartesian; triad axis `D`와 같아야 함 | | generalized internal force | `/steps/Step-1/frames//nodal/generalized_internal_force` | `[node_count,6]` float64 | node row; `[FI1,FI2,FI3,MI_PHI1,MI_PHI2,MI_PHI3]` | `[force x3,force*length x3]`; work-conjugate to `[u,phi]`; nodal | | generalized external force | `/steps/Step-1/frames//nodal/generalized_external_force` | `[node_count,6]` float64 | node row; `[FE1,FE2,FE3,ME_PHI1,ME_PHI2,ME_PHI3]` | `[force x3,force*length x3]`; work-conjugate to `[u,phi]`; approved physical moment projection 후 fixed-global dead loads; nodal | | generalized residual | `/steps/Step-1/frames//nodal/generalized_residual` | `[node_count,6]` float64 | node row; `[RU1,RU2,RU3,RPHI1,RPHI2,RPHI3]` | `[force x3,force*length x3]`; nonlinear solution coordinate의 full assembled `f_int-f_ext`; nodal | | reaction / spatial full-residual projection | `/steps/Step-1/frames//nodal/reaction` | `[node_count,6]` float64 | node row; `[RF1,RF2,RF3,RM1,RM2,RM3]` | `[force x3,force*length x3]`; global; translation은 full generalized residual과 같고 rotation은 `J_l(phi)^(-T)` spatial moment conversion. Constrained reaction은 mask를 generalized residual에 먼저 적용한 뒤 변환하며 accepted free residual의 authority는 이 dataset이 아니라 `nodal/generalized_residual`이다. | | shell local frame | `/steps/Step-1/frames//element/shell/local_frame` | `[element_count,4,3,3]` float64 | element row, midsurface location row `GP1..GP4`, axis row `[E1,E2,E3]`, global component column `[X,Y,Z]` | dimensionless; physical recovery용 fixed-initial shell local frame; rotating Abaqus output frame이 아님 | | generalized strain | `/steps/Step-1/frames//element/shell/generalized_strain` | `[element_count,4,8]` float64 | element row, `GP1..GP4`; `[E11,E22,G12,K11,K22,K12,G13,G23]` | `[1,1,1,1/length,1/length,1/length,1,1]`; fixed-reference shell local; midsurface | | section resultant | `/steps/Step-1/frames//element/shell/section_resultant` | `[element_count,4,8]` float64 | element row, `GP1..GP4`; `[N11,N22,N12,M11,M22,M12,Q13,Q23]` | `[force/length x3,force x3,force/length x2]`; fixed-reference shell local; midsurface | | in-plane stress | `/steps/Step-1/frames//element/shell/stress` | `[element_count,4,3,3]` float64 | element row, `GP1..GP4`, section position `[BOTTOM,MIDDLE,TOP]`, component `[S11,S22,S12]` | `force/length^2`; fixed-reference shell local; direct bottom/middle/top evaluation | | physical strain energy | `/steps/Step-1/frames//global/energy` | `[1]` float64 | `[PHYSICAL_STRAIN_ENERGY]` | `force*length`; deterministic element reduction; numerical drilling stabilization 제외 | | global applied-plus-reaction balance error | `/steps/Step-1/frames//global/equilibrium` | `[6]` float64 | `[FORCE_1,FORCE_2,FORCE_3,MOMENT_1,MOMENT_2,MOMENT_3]` | `[force x3,force*length x3]`; global Cartesian; formulation §13.4의 applied-plus-constrained-reaction balance error; moment about global origin `[0,0,0]`, current force arms와 spatial physical nodal moments 사용; `location=global-balance-error` | Trial Newton state, iteration history, line search, cutback attempt, damping, automatic stabilization, numerical drilling stress, drilling energy ratio, `S33`, `S13`, `S23`, nodal stress extrapolation, element-corner stress, averaged stress, Abaqus integration-point number에 대한 HDF5 dataset은 만들지 않는다. #### 7.5.1 Equilibrium Projection and Schema Compatibility Schema version `1`과 기존 `/global/equilibrium` path/shape는 유지한다. 기존 계약이 이미 global origin `[0,0,0]`, current force arm과 spatial physical nodal moment를 지정했으므로 이 dataset의 authoritative meaning은 처음부터 formulation §13.4의 **global applied-plus-reaction balance error**다. Raw full-residual sum, initial-coordinate arm 또는 raw rotation-coordinate covector를 이 path에 쓰는 것은 schema-compatible implementation이 아니다. 이 의미 명확화는 path, shape 또는 component를 바꾸지 않으므로 schema version을 올리지 않는다. 같은 accepted frame의 세 equilibrium quantity는 다음처럼 서로 다른 HDF5 projection으로 재구성된다. 별도 중복 summary dataset은 만들지 않는다. | logical quantity | authoritative HDF5 projection | coordinates / units | disposition | | --- | --- | --- | --- | | accepted free residual | `/model/nodal_constraint_mask==0`인 component를 `/nodal/generalized_residual`에서 선택한다. NSNR-069 scale은 같은 free component의 `/nodal/generalized_internal_force`와 `/nodal/generalized_external_force`에서 계산한다. | translation channel은 global force, rotation-coordinate channel은 generalized force-length | `blocking-internal` | | constrained reaction resultant | `/model/nodal_constraint_mask`를 `/nodal/generalized_residual`에 먼저 적용해 constrained generalized reaction을 만들고, rotation block만 accepted `phi`의 `J_l(phi)^(-T)`로 spatial moment로 변환한다. Current position은 `/model/nodes.coordinates + /nodal/displacement[UX,UY,UZ]`다. Stable node order로 `sum(F_react)`와 `sum(x cross F_react + M_react)`를 계산한다. | global force `[3]`, global spatial force-length moment `[3]` about `[0,0,0]` | `review-only-summary` | | applied-plus-reaction balance error | required dataset `/global/equilibrium`; applied contribution은 accepted `/nodal/generalized_external_force`의 translation block과 `J_l(phi)^(-T)`로 변환한 rotational block, reaction contribution은 바로 위 constrained projection을 사용한다. Stable node order로 formulation §13.4의 합을 계산한다. | global force `[3]`, global spatial force-length moment `[3]` about `[0,0,0]` | `blocking-internal` | Componentwise constraint selection은 spatial moment 변환보다 먼저 수행한다. 따라서 partial rotational constraint나 nonzero prescribed rotation에서도 constrained reaction resultant에 free generalized residual이 섞이지 않는다. Local `/nodal/reaction` display나 full residual sum을 위 세 quantity 중 다른 하나의 substitute로 사용하지 않는다. Nonzero prescribed translation에서는 initial position이 아니라 accepted current position을 force arm으로 사용한다. ### 7.6 Diagnostics Dataset `/diagnostics`는 mandatory이며 row가 0개일 수 있다. | path | shape and dtype | fields | required meaning | | --- | --- | --- | --- | | `/diagnostics` | `[diagnostic_count]` compound | `severity:utf8`, `code:utf8`, `file:utf8`, `line:uint64`, `keyword:utf8`, `entity_identity:utf8`, `message:utf8` | CLI/input/model/solver/output deterministic diagnostics; ignored keyword warning도 success file에 보존 | Diagnostic order는 source file declaration order, 1-based line, stable entity identity, diagnostic code, discovery order를 순서대로 사용한다. Source가 없는 CLI/solver/output diagnostic은 explicit empty source field를 사용한다. ### 7.7 Output Failure and Atomic Finalization Writer는 log close 성공 뒤에만 final file과 같은 directory에 implementation-private temporary HDF5 candidate를 만든다. Candidate는 metadata, model datasets, accepted-frame table, 모든 accepted-frame dataset, diagnostics를 모두 쓰고, shape, attribute, finite value, source identity, row order를 검증한다. Checked HDF5 close와 read-only reopen/self-check가 성공한 뒤에만 final `_results.h5`를 replace/create한다. 실패한 candidate는 제거하거나 non-authoritative implementation-private artifact로만 남긴다. Controlled failure는 incomplete final result를 노출하면 안 된다. HDF5 failure는 이미 닫힌 current-run log를 rollback하지 않는다. ## 8. FESA HDF5 to Reference CSV Comparison Mapping Comparison tooling은 FESA `results.h5` schema와 exact read-only Abaqus CSV artifact만 읽는다. CSV는 FESA output이 아니다. HDF5에서 추출한 deterministic CSV view는 debugging/reporting 보조물로만 둘 수 있다. ### 8.1 Declared Cases and Artifacts | case id | role | exact path | comparison disposition | | --- | --- | --- | --- | | `shellnl-meshfine-s4-final` | primary nonlinear input | `reference/shellNL-meshfine/shellNL-meshfine.inp` | required source input | | `shellnl-meshfine-s4-final` | displacement CSV | `reference/shellNL-meshfine/shellNL-meshfine displacements.csv` | required blocking/warning comparison | | `shellnl-meshfine-s4-final` | reaction CSV | `reference/shellNL-meshfine/shellNL-meshfine reactions.csv` | constrained nodes/components only required review | | `shellnl-meshfine-s4-final` | stress CSV | `reference/shellNL-meshfine/shellNL-meshfine stresses.csv` | optional read-only inspection/order evidence only | | `shellnl-s4-final` | companion nonlinear input | `reference/shellNL/shellNL.inp` | required source input | | `shellnl-s4-final` | displacement CSV | `reference/shellNL/shellNL displacements.csv` | required blocking/warning comparison | | `shellnl-s4-final` | reaction CSV | `reference/shellNL/shellNL reactions.csv` | constrained nodes/components only required review | | `shellnl-s4-final` | stress CSV | `reference/shellNL/shellNL stresses.csv` | optional read-only inspection/order evidence only | | `shell-s4-linear-limit` | linear control input | `reference/shell/shell.inp` | existing linear MITC4 contract의 required regression input | | `shell-s4-linear-limit` | displacement CSV | `reference/shell/shell displacements.csv` | required regression comparison | | `shell-s4-linear-limit` | reaction CSV | `reference/shell/shell reactions.csv` | optional read-only inspection only | | `shell-s4-linear-limit` | stress CSV | `reference/shell/shell stresses.csv` | optional read-only inspection/order evidence only | Reference artifact file은 workflow에서 rename, rewrite, normalize, zero-clamp, repair, regenerate하지 않는다. Fine과 coarse nonlinear case는 각각 자기 input/CSV에 독립적으로 비교하며 cross-mesh row mapping이나 interpolation을 만들지 않는다. ### 8.2 Accepted-State and Frame Mapping - `shellnl-meshfine-s4-final`과 `shellnl-s4-final`은 각각 accepted factor-one HDF5 frame만 비교한다. 해당 frame은 `/steps/Step-1/accepted_frames`에서 `is_factor_one=1`이고 `load_factor=1.0`인 unique row다. 그 `frame_index`가 `/steps/Step-1/frames/`를 선택한다. - 두 nonlinear case의 required CSV row는 exact `Frame` value `Increment 10: Step Time = 1.000`만 가져야 하며, 이는 각 case의 accepted factor-one state로 논리 매핑한다. Required row에 다른 `Frame` 값이 있으면 schema mismatch다. - `shell-s4-linear-limit` CSV에는 `Frame` column이 없으며 `docs/linear-static-mitc4-shell/io.md`의 existing linear MITC4 final frame `/steps/Step-1/frames/0`에 매핑한다. - Trial Newton state, iteration log line, optional stress inventory row는 reference row가 아니다. ### 8.3 Nodal Displacement Projection Required logical key는 다음과 같다. ```text (case_id, accepted_state, canonical_instance_name, source_node_label, component) ``` Instance `PART-1-1`에서 linear/coarse case는 node label `1..49`, fine case는 `1..729`를 각각 정확히 한 번 요구한다. Instance matching은 case-insensitive로 수행하되 report에는 raw spelling을 보존한다. Row order는 identity가 아니다. | CSV column | comparison component | nonlinear HDF5 source | linear regression HDF5 source | | --- | --- | --- | --- | | `U-U1` | `U1` | factor-one `nodal/displacement` column `UX` | final `nodal/displacement` column `UX` | | `U-U2` | `U2` | factor-one `nodal/displacement` column `UY` | final `nodal/displacement` column `UY` | | `U-U3` | `U3` | factor-one `nodal/displacement` column `UZ` | final `nodal/displacement` column `UZ` | | `UR-UR1` | `UR1` | factor-one `nodal/displacement` column `URX` | final `nodal/displacement` column `URX` | | `UR-UR2` | `UR2` | factor-one `nodal/displacement` column `URY` | final `nodal/displacement` column `URY` | | `UR-UR3` | `UR3` | factor-one `nodal/displacement` column `URZ` | final `nodal/displacement` column `URZ` | `U1/U2/U3`는 blocking이다. `UR1/UR2/UR3`는 모든 case에서 warning-only다. UR warning exceedance는 blocking verdict를 바꾸지 않는다. ### 8.4 Nonlinear Local Reaction Review Projection Reaction review row는 input boundary mask로 선택한다. - coarse `shellnl-s4-final`: `1,3..9,14..17,22..33` — 24 nodes; - fine `shellnl-meshfine-s4-final`: `1,3..9,34..57,82..153` — 104 nodes. 승인 input에서 위 node들은 여섯 global DOF가 모두 constrained다. Comparator는 row eligibility를 CSV zero value나 row position이 아니라 `/model/nodal_constraint_mask`와 source node identity에서 도출한다. Translation reaction은 factor-one `nodal/generalized_residual`의 constrained `RU1..RU3`이고, rotational reaction은 constrained `RPHI1..RPHI3`를 먼저 선택한 뒤 accepted `phi`의 `J_l(phi)^(-T)`로 변환한 spatial physical moment다. Stored all-six-constrained rows에서는 factor-one `/nodal/reaction`의 대응 column과 동일해야 한다. | CSV columns | coarse family | fine family | disposition | | --- | --- | --- | --- | | `RF-RF1`, `RF-RF2` | `coarse.local_reaction_inplane_force` | `fine.local_reaction_inplane_force` | `review-only` | | `RF-RF3` | `coarse.local_reaction_transverse_force` | `fine.local_reaction_transverse_force` | `review-only` | | `RM-RM1`, `RM-RM2` | `coarse.local_reaction_physical_moment` | `fine.local_reaction_physical_moment` | `review-only` | | `RM-RM3` | comparison projection 없음 | comparison projection 없음 | `excluded` | Raw generalized rotation-coordinate residual은 Abaqus `RM` CSV column과 직접 비교하지 않는다. Review-only family도 source key, schema, inventory, finite value와 모든 row/common-policy error를 보고한다. 그 precheck 또는 numerical finding은 blocking verdict를 바꾸지 않는다. ### 8.5 Internal Factor-One Equilibrium Projection Internal equilibrium은 Abaqus CSV comparison이 아니다. Fine primary와 coarse companion의 각 accepted factor-one HDF5 frame에서 Section 7.5.1의 projection을 사용한다. | family id | exact HDF5 rows/components | gate | | --- | --- | --- | | `coarse.accepted_free_force_residual` | 75 free `RU1/RU2/RU3` rows와 같은 rows의 internal/external force | NSNR-069 force channel | | `coarse.accepted_free_moment_residual` | 75 free `RPHI1/RPHI2/RPHI3` rows와 같은 rows의 internal/external generalized moment | NSNR-069 moment channel | | `coarse.global_force_balance` | factor-one `/global/equilibrium` `FORCE_1..3` | normalized `<=1e-8` | | `coarse.global_moment_balance` | factor-one `/global/equilibrium` `MOMENT_1..3` | normalized `<=1e-8` | | `fine.accepted_free_force_residual` | 1,875 free `RU1/RU2/RU3` rows와 같은 rows의 internal/external force | NSNR-069 force channel | | `fine.accepted_free_moment_residual` | 1,875 free `RPHI1/RPHI2/RPHI3` rows와 같은 rows의 internal/external generalized moment | NSNR-069 moment channel | | `fine.global_force_balance` | factor-one `/global/equilibrium` `FORCE_1..3` | normalized `<=1e-8` | | `fine.global_moment_balance` | factor-one `/global/equilibrium` `MOMENT_1..3` | normalized `<=1e-8` | Global balance의 force scale은 applied/reaction nodal force contribution의 2-norm 합 중 큰 값, moment scale은 current-arm force moment와 spatial physical nodal moment contribution의 2-norm 합 중 큰 값이다. Force와 moment를 분리해 `norm(balance_error)/scale<=1e-8`을 적용한다. Scale이 exact zero이면 balance error도 exact zero일 때만 pass한다. Absolute floor, `max(1,S)` 또는 zero clamp는 없다. Accepted free residual은 NSNR-069의 external-channel exact-zero/ nonzero branch를 그대로 재현한다. 이 internal gate에는 `docs/TOLERANCE.md`, Abaqus value 또는 local reaction error를 적용하지 않는다. Constrained reaction resultant force `[3]`와 moment `[3]`는 Section 7.5.1의 distinct `review-only-summary`로 함께 계산·보고한다. `/global/equilibrium`, constrained reaction resultant와 accepted free residual 중 어느 하나를 다른 quantity의 대체 dataset으로 쓰지 않는다. ### 8.6 External Comparison Families External tolerance source는 정확히 `docs/TOLERANCE.md`다. 별도 absolute floor, `max(1,S)` clamp, row averaging, source-order matching, component calibration 또는 zero clamp는 허용하지 않는다. | family id | case | components | required row count | units / coordinates | disposition | | --- | --- | --- | ---: | --- | --- | | `linear.translation` | `shell-s4-linear-limit` | `U1,U2,U3` on nodes `1..49` | 147 | length / global | blocking regression | | `linear.rotation` | `shell-s4-linear-limit` | `UR1,UR2,UR3` on nodes `1..49` | 147 | dimensionless / fixed-initial global | warning-only | | `coarse.translation` | `shellnl-s4-final` | `U1,U2,U3` on nodes `1..49` | 147 | length / global | blocking | | `coarse.rotation` | `shellnl-s4-final` | `UR1,UR2,UR3` on nodes `1..49` | 147 | dimensionless / fixed-initial global | warning-only | | `coarse.local_reaction_inplane_force` | `shellnl-s4-final` | `RF1,RF2` on constrained nodes | 48 | force / global shell plane | review-only | | `coarse.local_reaction_transverse_force` | `shellnl-s4-final` | `RF3` on constrained nodes | 24 | force / global transverse | review-only | | `coarse.local_reaction_physical_moment` | `shellnl-s4-final` | `RM1,RM2` on constrained nodes | 48 | force*length / global spatial | review-only | | `fine.translation` | `shellnl-meshfine-s4-final` | `U1,U2,U3` on nodes `1..729` | 2,187 | length / global | blocking | | `fine.rotation` | `shellnl-meshfine-s4-final` | `UR1,UR2,UR3` on nodes `1..729` | 2,187 | dimensionless / fixed-initial global | warning-only | | `fine.local_reaction_inplane_force` | `shellnl-meshfine-s4-final` | `RF1,RF2` on constrained nodes | 208 | force / global shell plane | review-only | | `fine.local_reaction_transverse_force` | `shellnl-meshfine-s4-final` | `RF3` on constrained nodes | 104 | force / global transverse | review-only | | `fine.local_reaction_physical_moment` | `shellnl-meshfine-s4-final` | `RM1,RM2` on constrained nodes | 208 | force*length / global spatial | review-only | Reference-model read-only scale audit value는 다음과 같다. 이 값은 calibration 상수가 아니다. | family id | `S=max(abs(reference))` | `0.01*S` | | --- | ---: | ---: | | `linear.translation` | `2.37408203e-5` | `2.37408203e-7` | | `linear.rotation` | `7.60725743e-6` | `7.60725743e-8` | | `coarse.translation` | `2.37408203e-5` | `2.37408203e-7` | | `coarse.rotation` | `7.60725743e-6` | `7.60725743e-8` | | `coarse.local_reaction_inplane_force` | `1.91663182` | `1.91663182e-2` | | `coarse.local_reaction_transverse_force` | `1.17769805e4` | `1.17769805e2` | | `coarse.local_reaction_physical_moment` | `1.95418418e4` | `1.95418418e2` | | `fine.translation` | `2.57957054e-5` | `2.57957054e-7` | | `fine.rotation` | `6.58704994e-6` | `6.58704994e-8` | | `fine.local_reaction_inplane_force` | `5.38827419e-1` | `5.38827419e-3` | | `fine.local_reaction_transverse_force` | `2.78506128e3` | `2.78506128e1` | | `fine.local_reaction_physical_moment` | `4.71557520e3` | `4.71557520e1` | ### 8.7 Row Prechecks Tolerance 또는 internal metric 전에 다음을 검사한다. 1. 각 case의 exact declared input과 해당 disposition에 필요한 CSV가 존재하고 readable이다. 2. Reference CSV header는 surrounding whitespace trim 뒤 필요한 column을 가진다. 3. 두 nonlinear case required row는 exact approved `Frame` value만 포함한다. 4. HDF5 metadata, model rows, accepted-frame table, factor-one frame, required result dataset이 문서화된 shape, component name, attributes와 finite value를 가진다. 5. Wide CSV row는 이 문서의 component mapping으로 component row로 deterministically expand한다. 6. Source wide key와 expanded component key는 unique하다. Duplicate reference 또는 HDF5 key는 affected family를 tolerance 전에 fail한다. 7. Input node inventory와 source constraint mask로 expected key set을 만든다. CSV zero value나 row position으로 reaction identity를 추론하지 않는다. 8. 각 declared external family에서 FESA와 reference projected key set은 exact equal해야 한다. Missing row와 extra row를 모두 fail한다. 9. Required HDF5/CSV value, derived scale, norm과 metric은 모두 finite여야 한다. 10. Internal free residual은 exact free mask와 force/moment channel을 보존한다. Global balance는 모든 applied source와 constrained reaction을 stable source order로 정확히 한 번 사용한다. 11. Local review row를 global resultant로 collapse하거나 대체하지 않는다. Review-only precheck/error는 deterministic review failure로 기록하지만 blocking verdict를 변경하지 않는다. 12. Warning-only precheck/tolerance failure는 deterministic warning을 만들고 blocking verdict를 변경하지 않는다. Blocking precheck failure만 전체 external comparison을 fail한다. 13. Row omission/synthesis, averaging, source-order matching, clamp, normalization 또는 artifact repair를 허용하지 않는다. ### 8.8 Stress CSV Disposition Optional stress CSV identity는 다음과 같다. ```text (case_id, accepted_state, instance, element_label, element_corner_node_label, section_surface, component) ``` Stored stress CSV는 element-corner node row와 `SPOS/SNEG` section surface에서 `S-S11`, `S-S22`, `S-S33`, `S-S12`를 포함한다. `reference/shell/shell stresses.csv`는 사용자가 변경한 ascending element-label block `1..36` 순서를 갖지만 row order는 identity가 아니다. Fine stress CSV의 element `1`, `SNEG`, `Node Label=ss` 한 행은 optional excluded artifact finding으로만 기록한다. Artifact를 수정하지 않는다. FESA HDF5는 `GP1..GP4`와 `BOTTOM/MIDDLE/TOP`에서 direct `[S11,S22,S12]`만 emit한다. 따라서 모든 stored stress CSV는 optional read-only inspection/order evidence only다. HDF5 numerical-comparison projection, `S33` synthesis, nodal extrapolation, corner averaging, Gauss-to-corner matching 또는 element-label-order matching은 없다. ## 9. Validation Rules | validation area | required pass condition | failure class | | --- | --- | --- | | CLI usage | input path 정확히 하나; 어떤 argv token에도 exact literal substring `--output` 없음; matching 시 path resolution/parsing/Analysis/log/HDF5 전 `cli-usage` stderr diagnostic 정확히 1개 | usage, exit `2` | | keyword inventory | keyword가 supported, explicit diagnostic의 unsupported, 또는 exact ignored-with-warning allowlist 중 하나 | input, exit `3` | | syntax | ASCII keyword/data grammar, comma fields, finite numeric tokens, continuation/include 없음 | input, exit `3` | | nesting/cardinality | part/assembly/instance/step이 닫힘; nonlinear procedure는 정확히 하나의 `NLGEOM=YES` step | input, exit `3` | | source identity | scope 내 duplicate name/label 없음; 모든 reference resolved; instance identity unique | input, exit `3` | | set expansion | explicit/generated set이 deterministic expand되고 하나의 supported scope/instance에 머묾 | input, exit `3` | | shell element | only `S4/S4R`; 네 개의 distinct resolved nodes; mixed element model 없음; source type metadata 보존 | input/model, exit `3` 또는 `4` | | material and section | single isotropic elastic material, centered homogeneous positive-thickness shell section, element마다 정확히 하나의 assignment | input/model, exit `3` 또는 `4` | | geometry and coordinates | finite global coordinates, positive reference/current validity checks, required location마다 valid directors/triads/branches | model 또는 solver trial failure, exit `4` 또는 `5` | | boundary | DOF `1..6`, resolved finite targets, factor-one absolute meaning, conflicting expanded value 없음 | input, exit `3` | | load | resolved finite `CLOAD`, stable aggregation, fixed-global dead path, unsupported `DLOAD`/follower/distributed load 없음 | input/model, exit `3` 또는 `4` | | aggregate moment | exact-zero case 또는 preprocessing 및 모든 entered trial에서 `rho_M<=1e-12` | model/solver, exit `4` 또는 `5` | | nonlinear static data | 네 positive finite values, endpoint `1.0`, fixed increment sequence with final exact factor one | input, exit `3` | | Newton iteration | iteration identity `1..100`; iteration `100` acceptance 가능; iteration `101` 없음; line search/cutback/retry/fallback 없음 | solver, exit `5` | | convergence channels | finite-first 평가 뒤 residual force/moment는 matching external scale exact-zero이면 typed absolute `1e-3`, nonzero이면 retained `max(internal,external)` relative `1e-2`; correction translation/rotation은 기존 denominator branch; 네 channel 모두 inclusive `<=`이고 logical AND | solver, exit `5` | | nonfinite data | required residual, tangent, correction, state, load, recovery, output value가 acceptance 전 finite | solver/output, exit `5` 또는 `6` | | commit/rollback | complete converged candidate만 commit; failure는 prior committed state와 prior authoritative final HDF5 보존 | solver/output, exit `5` 또는 `6` | | HDF5 schema | exact paths, shapes, attributes, schema version, row identities, finite values, accepted-frame table, diagnostics; `/global/equilibrium`은 applied-plus-reaction balance error이고 accepted free residual/constrained reaction resultant와 분리됨; final replace는 log close success 뒤에만 허용 | output, exit `6` | | equilibrium projection | accepted free rows는 generalized residual과 exact free mask, constrained reaction은 mask-before-spatial-conversion, global balance는 applied plus constrained reaction/current arm/origin `[0,0,0]`; factor-one global force와 moment는 각각 dimension-separated normalized `<=1e-8`; 세 quantity가 같은 accepted state를 공유하되 서로 대체되지 않음 | solver/output/reference internal gate | | log | UTF-8 no BOM, LF, TAB-separated fixed `label=value` schema; entered Newton iteration마다 record 하나; no per-iteration stderr duplication; no-Newton procedure는 zero-byte empty log; open/write/flush/close fail-closed | output, exit `6` | | reference rows | fine primary/coarse companion/linear-control exact artifacts, headers, row keys, component keys, finite values, factor-one frame mapping과 disposition별 precheck | reference precheck | | tolerance | external family에만 exact `docs/TOLERANCE.md` row/RMS policy 적용; U blocking, UR warning-only, local RF/RM review-only 보존; internal global balance/free residual gate와 혼합 금지 | reference/internal verification | Downstream test가 다뤄야 하는 approved diagnostic code는 다음을 포함한다. | code | class | meaning | | --- | --- | --- | | `cli-usage` | usage/2 | argv token이 exact literal substring `--output`을 포함하며 pre-input/pre-log/pre-output failure 하나를 stderr에 기록 | | `unrecognized-option` | usage/2 | `--output` substring을 포함하지 않는 다른 unsupported option | | `malformed-keyword` | input/3 | keyword 또는 parameter grammar invalid | | `invalid-keyword-location` | input/3 | keyword가 approved scope 밖에 위치 | | `invalid-keyword-parameter` | input/3 | parameter missing, duplicate, empty 또는 subset 밖 | | `unsupported-keyword` | input/3 | `*INCLUDE` 포함 approved subset 밖 keyword | | `unsupported-distributed-load` | input/3 | `*DLOAD`, pressure, gravity, body, edge, follower load 요청 | | `duplicate-entity` | input/3 | source identity가 scope 안에서 duplicate | | `unresolved-reference` | input/3 | connectivity, set, instance, section, material, load, boundary target dangling | | `unsupported-element-formulation` | input/3 | shell feature에서 source element type이 `S4` 또는 `S4R`가 아님 | | `unsupported-mixed-element-model` | input/3 | shell과 non-shell product semantics 혼합 | | `invalid-shell-connectivity` | input/3 | shell connectivity arity, duplicate node 또는 resolved node identity invalid | | `unsupported-shell-section-option` | input/3 | composite/layer/offset/orientation/variable-thickness section 의미 등장 | | `invalid-shell-material` | model/4 | material value가 finite `E,nu` bound 위반 | | `invalid-shell-thickness` | model/4 | shell thickness nonfinite 또는 nonpositive | | `invalid-shell-geometry` | model/4 | shell geometry, reference Jacobian 또는 topology invalid | | `opposed-incident-normal` | model/4 | averaging 전 incident normal pair가 nonpositive | | `invalid-shell-director` | model/4 | nodal/interpolated director, triad 또는 branch validity 실패 | | `invalid-shell-jacobian` | model/4 | required Gauss/tying/center/recovery point의 basis/Jacobian invalid | | `unsupported-drilling-load` | model/4 또는 solver/5 | aggregate nodal moment가 current-director admissibility 위반 | | `invalid-nonlinear-static-data` | input/3 | `*STATIC` row arity, finite/positive check 또는 endpoint-one identity 실패 | | `unsupported-analysis-procedure` | input/3 | supported nonlinear static source step으로 매핑되지 않음 | | `nonfinite-newton-data` | solver/5 | required residual, tangent, correction 또는 trial state nonfinite | | `tangent-factorization-failed` | solver/5 | entered iteration의 fresh tangent factorization 실패 | | `correction-solve-failed` | solver/5 | fresh Newton correction solve 실패 | | `nonlinear-nonconvergence` | solver/5 | iteration `100` 완료 후 네 convergence channel이 모두 통과하지 않음 | | `invalid-accepted-state` | solver/5 | converged candidate recovery/state identity가 commit 전 실패 | | `log-output-failure` | output/6 | required live log create/open/truncate, write, flush 또는 close 실패 | | `output-busy` | output/6 | same derived pair single-writer lock을 획득하지 못했거나 lock path collision 발생 | | `hdf5-output-failure` | output/6 | candidate HDF5 write, schema validation 또는 atomic finalization 실패 | ## 10. Open Issues and Downstream Handoff Open issues blocking Implementation Planning: 없음. Downstream handoff to Implementation Planning Agent through Coordinator: - Public CLI/output naming migration을 보존한다: `fesa.exe `, lexical sibling `_results.h5`, `_log.txt`, 그리고 exact literal substring `--output`을 포함하는 모든 argv token의 pre-input/pre-log/pre-output exit `2`와 정확히 하나의 `cli-usage` stderr diagnostic. - Supported/unsupported/ignored keyword row와 nonlinear `*STATIC` rule을 parser acceptance/rejection test로 변환한다. - Stored reference grammar인 `*Output, field, variable=PRESELECT`와 `*Output, history, variable=PRESELECT`를 duplicate/extra parameter 없이 `ignored-with-warning`으로 수용하고, output request가 FESA output을 바꾸지 못함을 test한다. - `NLGEOM=YES`가 nonlinear procedure를 선택하고 `shell` `NLGEOM=NO` case가 기존 linear MITC4 contract의 regression으로 남는지 test한다. - HDF5 schema version `1`을 위 accepted-frame schema 그대로 구현한다. Factor-zero non-frame handling, unique factor-one frame selection, triad/director projection, no compression/chunking, no trial-state HDF5 history를 포함한다. `/global/equilibrium` path/shape는 유지하되 authoritative meaning을 applied-plus-reaction balance error로 검증한다. - `AUDIT-001`을 별도 test로 닫는다. Accepted free residual은 generalized residual/internal/external force와 exact free mask, constrained reaction resultant는 mask-before-`J_l(phi)^(-T)`와 accepted current arm, global balance는 applied plus constrained reaction을 사용한다. Nonzero prescribed translation/rotation case에서도 initial arm, raw rotational covector 또는 raw full-residual sum을 세 quantity의 공통 substitute로 쓰지 않는다. - 비대칭 lifecycle을 보존한다. Log는 usage validation, lexical path derivation, single-writer lock 뒤 live current-run audit이고, log create/open/truncate는 Analysis 전 abort, write/flush는 즉시 abort, close failure는 HDF5 commit을 block한다. HDF5 final은 log close와 candidate self-check 성공 뒤에만 replace하며 failure는 prior valid final과 current log를 손상하지 않는다. - Newton log parser/schema test는 UTF-8 no BOM, LF, physical TAB-separated fixed `label=value` 39-field order, finite round-trip numerics, escaping, completed-gate four-channel metrics, residual matching-external-scale exact-zero/nonzero branch와 retained nonzero-scale denominator, typed thresholds, four-channel AND, early-failure `not-evaluated(reason)`, no-Newton zero-byte log, zero per-iteration stderr duplication, flush-before-next/return을 포함한다. - Fine primary, coarse companion과 linear control의 exact CSV path, trimmed header, 두 nonlinear case의 exact factor-one `Frame`, source node/component identity, constrained reaction mask, missing/extra/duplicate row와 nonfinite value를 tolerance 전에 precheck한다. Row order를 identity로 쓰지 않는다. - External declared family에는 `docs/TOLERANCE.md`만 적용한다. `U1/U2/U3`는 blocking, `UR1/UR2/UR3`는 warning-only, local `RF1/RF2/RF3`와 spatial physical `RM1/RM2`는 review-only다. Local `RM3`와 모든 stress CSV value는 제외한다. Review-only row의 schema/inventory/error report를 생략하거나 blocking으로 되돌리지 않는다. - Fine/coarse factor-one global force/moment balance는 dimension-separated normalized `<=1e-8`, accepted free force/moment residual은 NSNR-069으로 blocking 검증한다. 이 internal gate에 Abaqus CSV나 `docs/TOLERANCE.md` scale을 사용하지 않는다. Constrained reaction resultant는 distinct review-only summary로 보고한다. - Optional stress CSV는 read-only inventory/order evidence only로 유지한다. Nodal stress extrapolation, corner averaging, `S33` synthesis, element-label-order matching을 추가하지 않는다. - Final HDF5 projection, parser diagnostics, schema tests, reference comparison tests, log lifecycle tests는 Coordinator를 통해 전달한다. 이 문서만으로 parser, C++ API, reference artifact, comparison-result, physics, release 변경을 승인하지 않는다.