feat(nonlinear-static-newton-raphson): step 11 - equilibrium-projection-and-reference-gate

This commit is contained in:
KOKO\Mimi
2026-08-28 09:22:33 +09:00
parent 65b56b1755
commit 6dbf1b2bcf
30 changed files with 13122 additions and 728 deletions
+217 -105
View File
@@ -4,20 +4,22 @@
- feature_id: `nonlinear-static-newton-raphson`
- source_requirement: `docs/nonlinear-static-newton-raphson/requirements.md`
- source_requirement_sha256: `910E351F3F90FFA42F07D15206B55E62C05EAE821E250424430148337506EBF2`
- source_requirement_sha256: `89C1AB5F1BEDB7C5F6AD0726ED62F0982181EA8746EDE4661183FD3D18A2408E`
- source_research: `docs/nonlinear-static-newton-raphson/research.md`
- source_research_sha256: `C920A6B02381230D1DB419D73FE767D611B36720D27D6410507BA88C3CA28EEE`
- source_research_sha256: `4F63D23E03D1A68E5F8563B678FDD6F761F9558165778EF0433133EFAD303570`
- source_formulation: `docs/nonlinear-static-newton-raphson/formulation.md`
- source_formulation_sha256: `DFA629888041D5762FD0DF4271353464A692B325DC0C821A8D8689688C1EAFD0`
- source_formulation_sha256: `878028F7B8EC1B91DA9BF00AF78825F50EB0B71046E840A0EEA595AFFD5E14B9`
- source_numerical_review: `docs/nonlinear-static-newton-raphson/numerical-review.md`
- source_numerical_review_sha256: `9517E11804C45A6F3822D18821D52EA493AE20353C8FFAD61E960F4315977D01`
- source_numerical_review_sha256: `C00994EF4BB23A237547459E157EE5BDA96B28CAF08F712CD31A8E0ABBF62D2C`
- source_reference_model: `docs/nonlinear-static-newton-raphson/reference-model.md`
- source_reference_model_sha256: `52D10B1D0C0500B295C5E48BCB3618B309D9696371B8070D4E3DCEE8D3D74CD3`
- 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-23`
- date: `2026-08-28`
- authoritative_output: input sibling `<stem>_results.h5`
- diagnostic_log: input sibling `<stem>_log.txt`
- hdf5_schema_version: `1`
@@ -386,15 +388,15 @@ failure도 entered iteration이 없으면 iteration record가 없는 log file만
| 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` | `max(||f_int,f^u||_inf,||f_ext,f^u||_inf)` or `not-evaluated(reason)` |
| 11 | `residual_force_branch` | `relative`, `zero-scale`, 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` | `max(||f_int,f^phi||_inf,||f_ext,f^phi||_inf)` or `not-evaluated(reason)` |
| 18 | `residual_moment_branch` | `relative`, `zero-scale`, 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)` |
@@ -417,13 +419,29 @@ failure도 entered iteration이 없으면 iteration record가 없는 log file만
| 38 | `outcome` | `accepted`, `continue`, `nonconverged`, or `failed` |
| 39 | `diagnostic_code` | `none` or approved diagnostic code |
Completed gate record는 `failing_stage=none`이고 네 channel의 identity, numerator/norm,
denominator/scale, branch, typed threshold, pass를 모두 finite 또는 enum value로 노출한다.
Denominator가 exact zero이면 branch는 `zero-scale`이고 typed threshold는 residual force
`1e-3 force`, residual moment `1e-3 force*length`, correction translation `1e-3 length`,
correction rotation `1e-3 dimensionless`다. Denominator가 nonzero이면 branch는 `relative`이고
threshold는 dimensionless `1e-2`다. Empty free channel은 numerator와 denominator가 exact zero인
`zero-scale` branch로 평가한다.
`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)`을 기록한다.
@@ -523,19 +541,43 @@ row는 정확히 하나다. Factor zero는 이 dataset에 row를 갖지 않고 `
| generalized internal force | `/steps/Step-1/frames/<frame>/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/<frame>/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/<frame>/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 / physical residual projection | `/steps/Step-1/frames/<frame>/nodal/reaction` | `[node_count,6]` float64 | node row; `[RF1,RF2,RF3,RM1,RM2,RM3]` | `[force x3,force*length x3]`; global; constrained entry는 physical reaction, free entry는 same-state equilibrium evidence; rotational columns는 `J_l(phi)^(-T)` spatial moment conversion |
| reaction / spatial full-residual projection | `/steps/Step-1/frames/<frame>/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/<frame>/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/<frame>/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/<frame>/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/<frame>/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/<frame>/global/energy` | `[1]` float64 | `[PHYSICAL_STRAIN_ENERGY]` | `force*length`; deterministic element reduction; numerical drilling stabilization 제외 |
| global equilibrium | `/steps/Step-1/frames/<frame>/global/equilibrium` | `[6]` float64 | `[FORCE_1,FORCE_2,FORCE_3,MOMENT_1,MOMENT_2,MOMENT_3]` | `[force x3,force*length x3]`; global Cartesian; moment about global origin `[0,0,0]`, current force arms와 spatial physical nodal moments 사용 |
| global applied-plus-reaction balance error | `/steps/Step-1/frames/<frame>/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개일 수 있다.
@@ -568,9 +610,13 @@ CSV는 FESA output이 아니다. HDF5에서 추출한 deterministic CSV view는
| case id | role | exact path | comparison disposition |
| --- | --- | --- | --- |
| `shellnl-s4-final` | nonlinear input | `reference/shellNL/shellNL.inp` | required source input |
| `shellnl-s4-final` | displacement CSV | `reference/shellNL/shellNL displacements.csv` | required comparison |
| `shellnl-s4-final` | reaction CSV | `reference/shellNL/shellNL reactions.csv` | constrained nodes/components only required comparison |
| `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 |
@@ -578,21 +624,22 @@ CSV는 FESA output이 아니다. HDF5에서 추출한 deterministic CSV view는
| `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하지 않는다.
regenerate하지 않는다. Fine과 coarse nonlinear case는 각각 자기 input/CSV에 독립적으로
비교하며 cross-mesh row mapping이나 interpolation을 만들지 않는다.
### 8.2 Accepted-State and Frame Mapping
- `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/<frame>`를 선택한다.
- Required `shellNL` CSV row는 exact `Frame` value
`Increment 10: Step Time = 1.000`만 가져야 하며, 이는 accepted factor-one state로
논리 매핑한다. Required row에 다른 `Frame` 값이 있으면 schema mismatch다.
- `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/<frame>`를 선택한다.
- 두 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가
아니다.
- Trial Newton state, iteration log line, optional stress inventory row는 reference row가 아니다.
### 8.3 Nodal Displacement Projection
@@ -602,93 +649,141 @@ Required logical key는 다음과 같다.
(case_id, accepted_state, canonical_instance_name, source_node_label, component)
```
두 case 모두 instance `PART-1-1`에서 node label `1..49`가 정확히 한 번씩 필요하다.
Instance matching은 case-insensitive로 수행하되 report에는 raw spelling을 보존한다.
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` | `nodal/displacement` column `UX` | `nodal/displacement` column `UX` |
| `U-U2` | `U2` | `nodal/displacement` column `UY` | `nodal/displacement` column `UY` |
| `U-U3` | `U3` | `nodal/displacement` column `UZ` | `nodal/displacement` column `UZ` |
| `UR-UR1` | `UR1` | `nodal/displacement` column `URX` | `nodal/displacement` column `URX` |
| `UR-UR2` | `UR2` | `nodal/displacement` column `URY` | `nodal/displacement` column `URY` |
| `UR-UR3` | `UR3` | `nodal/displacement` column `URZ` | `nodal/displacement` column `URZ` |
| `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
`U1/U2/U3`는 blocking이다. `UR1/UR2/UR3`는 모든 case에서 warning-only다. UR warning
exceedance는 blocking verdict를 바꾸지 않는다.
### 8.4 Nonlinear Constrained Reaction Projection
### 8.4 Nonlinear Local Reaction Review Projection
Reaction comparison은 `shellnl-s4-final`에만 적용하며 input boundary mask의 constrained node
중 아래 24개 node에만 적용한다.
Reaction review row는 input boundary mask로 선택한다.
```text
1,3,4,5,6,7,8,9,14,15,16,17,22,23,24,25,26,27,28,29,30,31,32,33
```
- 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에서 이 24개 node는 여섯 global DOF가 모두 constrained다. Comparator는 required
HDF5 reaction row eligibility를 CSV zero value가 아니라 `/model/nodal_constraint_mask`와
source node identity에서 도출한다.
승인 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 | logical family | HDF5 source | disposition |
| CSV columns | coarse family | fine family | disposition |
| --- | --- | --- | --- |
| `RF-RF1`, `RF-RF2` | `nonlinear.reaction_inplane_force` | factor-one `/nodal/reaction` columns `RF1,RF2` | blocking |
| `RF-RF3` | `nonlinear.reaction_transverse_force` | factor-one `/nodal/reaction` column `RF3` | blocking |
| `RM-RM1`, `RM-RM2` | `nonlinear.reaction_physical_moment` | factor-one `/nodal/reaction` columns `RM1,RM2`; `J_l(phi)^(-T)` 변환 뒤 spatial physical moment | blocking |
| `RM-RM3` | excluded | comparison projection 없음 | blocking 및 warning-only family에서 제외 |
| `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 column은 Abaqus `RM` CSV column과 직접 비교하지
않는다.
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 Comparison Families
### 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는 허용하지
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 |
| `nonlinear.translation` | `shellnl-s4-final` | `U1,U2,U3` on nodes `1..49` | 147 | length / global | blocking |
| `nonlinear.rotation` | `shellnl-s4-final` | `UR1,UR2,UR3` on nodes `1..49` | 147 | dimensionless / fixed-initial global | warning-only |
| `nonlinear.reaction_inplane_force` | `shellnl-s4-final` | `RF1,RF2` on constrained nodes | 48 | force / fixed-initial global plane | blocking |
| `nonlinear.reaction_transverse_force` | `shellnl-s4-final` | `RF3` on constrained nodes | 24 | force / fixed-initial global transverse | blocking |
| `nonlinear.reaction_physical_moment` | `shellnl-s4-final` | `RM1,RM2` on constrained nodes | 48 | force*length / global spatial | blocking |
| `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는 다음과 같다.
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` |
| `nonlinear.translation` | `2.37408203e-5` | `2.37408203e-7` |
| `nonlinear.rotation` | `7.60725743e-6` | `7.60725743e-8` |
| `nonlinear.reaction_inplane_force` | `1.91663182` | `1.91663182e-2` |
| `nonlinear.reaction_transverse_force` | `1.17769805e4` | `1.17769805e2` |
| `nonlinear.reaction_physical_moment` | `1.95418418e4` | `1.95418418e2` |
| `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.6 Row Prechecks
### 8.7 Row Prechecks
아래 조건 중 하나라도 거짓이면 comparator는 tolerance 계산 전에 실패한다.
Tolerance 또는 internal metric 전에 다음을 검사한다.
1. Exact declared input path와 required CSV path가 존재하고 readable이다.
1. 각 case의 exact declared input과 해당 disposition에 필요한 CSV가 존재하고 readable이다.
2. Reference CSV header는 surrounding whitespace trim 뒤 필요한 column을 가진다.
3. `shellnl-s4-final` required row는 exact approved `Frame` value만 포함한다.
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, finite value를 가진다.
5. Wide CSV row는 이 문서의 component mapping으로 component row로 expand한다.
6. Required source wide key와 expanded component key는 unique하다. Duplicate reference 또는
HDF5 key는 실패다.
7. 각 declared family에서 FESA와 reference projected key set은 정확히 같아야 한다. Missing row와
extra row는 모두 실패다.
8. 모든 required numeric value는 finite다. Nonfinite HDF5 또는 CSV value는 tolerance 전 실패다.
9. `shellNL` reaction row는 constrained mask와 exact 24-node list에서 선택한다. Free-node CSV
row는 inventory only이며 zero reaction target으로 해석하지 않는다.
10. Required row를 omit, synthesize, average, substitute identity로 sort, normalize, zero-clamp,
repair하지 않는다.
문서화된 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.7 Stress CSV Disposition
### 8.8 Stress CSV Disposition
Optional stress CSV identity는 다음과 같다.
@@ -697,13 +792,16 @@ Optional stress CSV identity는 다음과 같다.
element_corner_node_label, section_surface, component)
```
현재 stress CSV는 element-corner node row와 `SPOS/SNEG` section surface에서 `S-S11`,
`S-S22`, `S-S33`, `S-S12`를 포함하며, 저장된 ascending element-label block `1..36` 순서를
갖는다. FESA HDF5는 `GP1..GP4`와 `BOTTOM/MIDDLE/TOP`에서 direct `[S11,S22,S12]`만 emit한다.
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를 수정하지 않는다.
따라서 두 case의 stress CSV는 optional read-only inspection 및 order evidence only다. HDF5
comparison projection, `S33` synthesis, nodal extrapolation, corner averaging, Gauss-to-corner
matching, element-label-order identity는 없다.
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
@@ -723,13 +821,14 @@ matching, element-label-order identity는 없다.
| 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 | residual force, residual moment, correction translation, correction rotation이 모두 inclusive `<=` rule 또는 typed zero-scale threshold 통과 | 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; final replace는 log close success 뒤에만 허용 | output, exit `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 | exact required artifacts, headers, row keys, component keys, finite values, factor-one frame mapping | reference precheck |
| tolerance | exact `docs/TOLERANCE.md` family-scale row/RMS policy; blocking/warning disposition 보존 | reference verification |
| 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는 다음을 포함한다.
@@ -785,21 +884,34 @@ Downstream handoff to Implementation Planning Agent through Coordinator:
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를 포함한다.
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` field order, finite round-trip numerics, escaping, completed-gate four-channel
metrics, early-failure `not-evaluated(reason)`, no-Newton zero-byte log, zero per-iteration
stderr duplication, flush-before-next/return을 포함한다.
- Exact CSV paths, trimmed headers, exact `shellNL` `Frame` value, source node/component
identity, constrained reaction mask, missing/extra/duplicate rows, nonfinite values를
tolerance 전에 precheck한다.
- Declared family에는 `docs/TOLERANCE.md`만 적용한다. `U`는 blocking, `UR`은 warning-only,
`RF1/RF2`, `RF3`, physical spatial `RM1/RM2`는 blocking으로 유지하고 `RM3`와 모든 stress
CSV value는 제외한다.
`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을 추가하지
않는다.