docs: finalize eigen2 io contract and review evidence

This commit is contained in:
KOKO\Mimi
2026-09-08 21:30:15 +09:00
parent 5b77ecd26a
commit ad89661e71
10 changed files with 567 additions and 7 deletions
+128
View File
@@ -0,0 +1,128 @@
# MITC4 eigen 내부 mapping·reference projection
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `io-definition-agent`; Contract revision: `r1`.
- 기본 보고서: [io.md](io.md). 수학 원본: [formulation-eigen](formulation-eigen.md).
## 내부 소유권과 identity
| Owner | 필수 의미와 mapping |
| --- | --- |
| ParsedInput | 실제 input bytes의 기존 content identity, lexical path, keyword/parameter presence·raw 값·빈 data slot·source line |
| Domain | 전체 geometry/source topology, section→material→constant rho, 원형상 director, homogeneous BC, sole Frequency definition; 파싱 후 가능한 불변 |
| Frequency definition | source step raw/canonical name, step/Frequency/data 위치, requested N, 각 option의 explicit presence/effective value, no-op warning inventory; storage Step-1과 구별 |
| AnalysisModel | Domain보다 짧은 수명의 활성 shell/material/section/BC/procedure const non-owning view |
| DofManager | Source node×고정 6 DOF, full/free/constrained injection, stable equation IDs/scatter/sparse pattern; Node/Element에 equation ID를 저장하지 않음 |
| Assembly/procedure | 실제 consistent moment→derived lumped→개선 K, 같은 source scatter/reduction; E1~E7의 constraint-first split·whitening·FEAST·복구·all-c validation |
| Private backend | Vendor CSR/index/workspace/FEAST control·runtime·call evidence; MKL type/header를 public core에 노출하지 않음 |
| Eigen state | Candidate/accepted 분리, N개의 paired raw scalar/global vectors, source mapping, c개 validation evidence; static/Newton state를 mode count로 재사용하지 않음 |
| ResultsWriter | Validated state serialization→closed candidate self-check→final replacement; 물리값·identity 재계산/보정으로 실패를 숨기지 않음 |
Source `(instance_name,numeric source label)`과 raw spelling, internal model row, free equation
index, FEAST column, sorted rank, public mode ID는 별개다. Instance expansion/declaration의 기존
model 순서와 DOF `UX,UY,UZ,URX,URY,URZ` 순서를 유지한다. Source renumbering 비교는
geometry/connectivity/BC 대응을 함께 사용하며 숫자가 우연히 같은 internal ID를 source key로
대체하지 않는다. Repeated eigenvalues는 별개 rank이며 특정 vector 방향의 유일성을 요구하지 않는다.
Raw consistent 계산을 lumped로 덮어쓰지 않는다. Global dense mass dump는 필수 결과가 아니다.
실제 constrained free space에서만 analytic null을 제거하며 tiny positive mass를 rank cutoff로
삭제하지 않는다. `requested N`, finite dimension n, count의 overwritten m0, allocated m0,
solve returned m, validated c, public N을 각기 보존한다. 모든 c를 검증한 뒤 첫 N을 공개한다.
## 실패와 공개 lifecycle
Public CLI·path·lock·log는 [현재 공통 계약 §7.1](../nonlinear-static-newton-raphson/io.md#71-public-output-names-log-and-lifecycle)을
유지한다. `fesa.exe <model.inp>`이며 output override를 추가하지 않는다. Input lexical sibling은
`<stem>_results.h5`와 `<stem>_log.txt`다. 마지막 `.inp` extension만 제거하고 basename case·
앞선 dot은 보존한다. Symlink/junction을 resolve해 결과 위치를 바꾸지 않는다.
1. Usage 검증→derived pair의 exclusive nonblocking ownership→live log open/truncate.
2. Parse/model/solve/all-c validation을 candidate에서 수행한다. 기존 accepted state/final은 유지한다.
3. Candidate state를 완성하고 log close 성공을 확인한다. 같은 directory의 exclusive-create private
HDF5 candidate를 write/flush/close/reopen/self-check하고 모든 handle을 닫는다.
4. Final replace가 성공한 뒤 준비된 state를 no-fail swap한다. 이후 allocation/validation/callback
failure를 남기지 않는다. 실패 candidate는 authoritative 결과가 아니다.
제어된 solve/validation/write/flush/close/reopen/self-check/replace 실패에서 이전 valid final과
state를 보존한다. 이전 final이 없으면 만들지 않는다. Log는 별도 live lifecycle이며 rollback하지
않는다. Eigen log에는 Newton iteration/FEAST trace를 새로 쓰지 않고 정상 log는 zero-byte다.
Backend evidence는 아래 result/Status에 둔다. Lock 실패는 기존 log/final도 건드리지 않는다.
Candidate 정리는 best effort이며 다른 run 파일을 삭제하지 않는다. Crash/power-loss 전체 원자성은
약속하지 않는다. Reference `.inp`/TXT/CSV는 read-only이며 output으로 덮어쓰지 않는다.
| Solver 실패 / exit5 | Stable code·필수 context |
| --- | --- |
| Analytic mass space·null identity 오류 | invalid-eigen-mass-space: node/DOF/n/nz·실패 identity |
| Positive block conditioning 실패 | eigen-mass-conditioning: node·metric·관측값·NR limit |
| Checked index/capacity 또는 CSR | eigen-index-overflow / invalid-eigen-csr: n,nnz,N,m0와 실패 bound |
| Workspace allocation | eigen-allocation-failed: 역할·checked byte request; N 축소 없음 |
| Fatal FEAST status | eigen-feast-failed: raw info, call kind/ordinal, interval, allocated m0 |
| Count/solve 수·monotonicity 불일치 | eigen-count-inconsistent: 실제 count history·certified interval |
| Endpoint separation | eigen-endpoint-separation: raw endpoints·nearest returned value·NR limit |
| Mandatory search budget 소진 | eigen-search-budget-exhausted: attempts·마지막 safe bracket·fallback 가능 여부 |
| Significant negative spectrum | negative-eigenvalue-spectrum: raw lambda/mu/s·rank·NR limit |
| Nonfinite/invalid conversion/frequency | invalid-eigenvalue-result: raw quantity·stage·source step |
| Pair/Gram/original-free residual/energy 실패 | eigenpair-validation-failed: metric·value·limit·solver column/rank |
선택적 upper-prefix 최적화에서 인증되지 않은 empty/count status는 count0으로 바꾸지 않는다.
Formulation E4와 NR가 허용한 safe bracket fallback은 실패를 은폐한 성공 count가 아니며
actual attempted call·종료 이유를 evidence에 남긴다. Mandatory final count/solve/validation 실패는
부분 결과로 성공하지 않는다. Count workspace의 작은/null scratch를 문헌 보장으로 가정하지 않는다.
Failure Status는 Frequency 위치와 지금까지의 chronological call context를 포함한다.
Undefined vendor outputs는 읽지 않고 unavailable로 표시한다. Allocation 실패의 부속 message
생성은 기존 best-effort diagnostic 한계를 따른다.
## 원본 TXT grammar와 prechecks
Input은 `reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp`, reference는 같은 폴더의
`shellNL-eigen-meshfine eigenvalues.txt`다. 이름 변경, TXT rewrite, CSV 변환, companion
README/metadata/version/provenance 추가를 요구하지 않는다. TXT에 step이 없으므로 지정 input의
**유일한 frequency source step Step-2**에 대응한다. 이름에서 ODB frame index를 추정하지 않는다.
LF/CRLF logical line에서 space/tab-only 행은 건너뛴다. 나머지는 아래 case-sensitive full-match다.
`ws=[ \t]*`, `ws1=[ \t]+`; id는 checked positive int64 decimal이다.
```text
number := [+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[Ee][+-]?[0-9]+)?
id := [0-9]+
row := ws 'Frame:' ws1 'Mode' ws1 id ':' ws1 'Value' ws '=' ws number
ws1 'Freq' ws '=' ws number ws1 '(cycles/time)' ws
```
Header/footer/comment/BOM/extra token/malformed row는 schema 실패다. Value는 finite binary64
full conversion이며 range error를 거부한다. Freq는 숫자 token 구조만 검사하며 수치 변환·
물리 일치·오차 판정에 사용하지 않는다. Freq에서 Value를 재구성하지 않는다. 같은 numeric mode
ID의 재등장은 duplicate이며 같은 Value의 다른 mode는 정상이다.
Tolerance 전에 다음을 순서대로 완료한다.
1. 지정 input/TXT와 HDF5 존재, eigen discriminator, source_input_identity를 현재 입력의
lexical path와 기존 byte-content identity에 대조한다. Static output·unknown eigen schema를 거부한다.
2. Input sole source step/N을 직접 읽어 HDF5 source step·requested/public count와 대응한다.
N을 TXT row 수나 검증 c에서 추론하지 않는다. 현재 양쪽 required mode inventory는 1..10이다.
3. TXT 모든 nonblank row를 parse하고 duplicate/missing/extra/nonfinite를 거부한다. Malformed-row
skip/dictionary overwrite/값 sorting으로 source mode identity를 바꾸지 않는다.
4. HDF5 mandatory dataset/type/shape, units·quantity·실제 backend·mass variant·normalization,
source/model identities, modes ID 1..N, paired vector shape, raw eigenvalue finite를 검사한다.
HDF5 순서 오류는 reader 재정렬로 숨기지 않는다. 값이 같아도 ID가 다르면 multiplicity다.
5. `(case,source_step_name,mode_id,component=Value)`로 one-to-one join하고 mode ID 순서로 출력한다.
TXT row reorder는 허용한다. `modes.eigenvalue`만 FESA scalar authority다. c개 검증 table,
frequencies, vectors 또는 static fields에서 fallback하지 않는다.
## Family와 보고
[NR reference-model](reference-model.md)이 정의하는 family는 `(case,source step,modal-frame=mode_id,quantity=eigenvalue,
dimension=time^-2,coordinates=scalar,impact=blocking)`다. Mode별 frame은 10개 singleton
family이며 하나의 storage table이라고 서로 합치지 않는다. [공통 TOLERANCE](../TOLERANCE.md)의
reference-only S, inclusive near-zero/relative row branch, relative RMS, zero-scale 처리를
그대로 적용한다. 현재 양수 singleton의 실효 기준은 mode별 RMS 1%이며 5% row만으로 통과하지
않는다. S=0은 exact-zero FESA만 성공한다. I/O는 새 tolerance를 선택하지 않는다.
Report는 input/reference/result identity, freshness evidence, 전체 prechecks, source key/
component/family/count/S, raw reference/FESA/error·branch·row verdict, RMS·family verdict,
blocking failure와 overall verdict를 mode 순서로 남긴다. Zero-scale 미정 metric은 named state로
표시하고 NaN/Inf/floor를 넣지 않는다. 필요 시 HDF5 projection CSV는 보조 debug view일 뿐이다.
외부 eigen gate는 Value뿐이다. N개의 global vectors는 내부 constraint/residual/normalization
재검증용이며 외부 shape reference는 요구하지 않는다. 기존 static 회귀는 [requirements](requirements.md)의
retained shell/shellNL/linear-limit portfolio와 기존 source step/frame·U blocking·UR warning-only,
nonlinear reaction review-only 의미를 유지한다. 제외 네 예제는 원본·복사·cache로도 사용하지 않는다.