chore: remove retired workflow and historical material

This commit is contained in:
KOKO\Mimi
2026-10-17 22:39:47 +09:00
parent 4bd19f5bf0
commit 774b80099c
768 changed files with 0 additions and 54164 deletions
-109
View File
@@ -1,109 +0,0 @@
# MITC4 Shell Mass·FEAST Eigen 2 결정 기록
- Feature ID: `mitc4-shell-feast-eigen2`
- Owner: 메인 assistant
- Requirement baseline revision: `r1`
기준: [프로젝트 지침](../../AGENTS.md), [프로젝트 PRD](../PRD.md),
[공통 ADR](../ADR.md#adr-028). 사용자 요청·현재 checklist는 [PRD](PRD.md),
지역 지침·소유권은 [FEATURED_AGENTS](FEATURED_AGENTS.md)를 따른다.
## MFE2-ADR-001 — 새로운 requirement baseline과 작업 범위
- 상태: 사용자 명시 요청, 2026-09-08.
- 결정: `mitc4-shell-feast-eigen2`를 새 Feature ID로 사용하고 requirement 단계만 수행한다. 변경 문서는 이 폴더에 작성하며 완성된 변경을 경로별로 커밋한다.
- 근거: “mitc4-shell-feast-eigen2 라는 이름으로 처음 requirement 작업부터 시작”, “requirement 단계만 진행”, “변경사항들을 깃에 커밋”.
- 영향: 새 요구 ID·r1을 작성한다. 기존 Feature·phase의 미커밋 변경과 실패 이력은 보존하고 research 이후 작업·push는 이번 범위에 포함하지 않는다.
- 이유: 요구사항을 현재 운영 기준에서 다시 검토하면서 기존 작업과 결과를 혼동하지 않기 위함이다.
## MFE2-ADR-002 — 기존 명시 사용자 요구의 적용
- 상태: 기존 명시 사용자 결정의 재시작 기준으로서 기록. 새로운 수학·schema 승인 아님.
- 결정: consistent→lumped→FEAST, 입력의 mode count, 고유치 Value-only 외부 비교, 좌표 공변적 stabilization 개선 및 영향받는 static/eigen 재검증, reference/temp 제외의 의미를 새 요구사항에 반영한다.
- 근거: 기존 [ADR](../mitc4-shell-feast-eigen/ADR.md)의 MFE-ADR-001·002·004·005·007·013 및 [requirements](../mitc4-shell-feast-eigen/requirements.md#requirements) r3. 기존 ADR에는 질량 사용·개선 범위·제외에 관한 사용자 답변이 명시되어 있다.
- 영향: 알려진 사용자 결정을 다시 양자택일 질문으로 만들지 않는다. 기존 formulation/NR/I/O의 상세 수식·control·영속 식별자를 자동 채택하거나 통과로 표시하지 않는다.
- 한계: 이 결정 당시 일부 기존 r3 문서는 당시 worktree의 미커밋 자료였다. 필요한 요구의 실제 의미와 제외 목록은 새 requirements에 독립적으로 명시하고 이전 HEAD에 동일 내용이 있다고 주장하지 않는다.
## MFE2-ADR-003 — 참고 자료와 새 evidence의 경계
- 상태: 현행 프로젝트 기준을 적용한 문서 작성 결정.
- 결정: 기존 요구사항·근거는 요구 정의의 입력, research/formulation/NR/I/O 문서는 후속 검토 후보로 구분한다. 기존 implementation/environment/recovery/coordination/phase는 역사적 진단 자료다.
- 이유: 유용한 연구·반례를 재사용하되 과거 gate와 환경 통과를 새 Feature의 검증으로 오인하지 않게 한다.
- 영향: 새 정식화의 채택·수치 기준·source/result mapping은 후속 전문 작업이 필요할 때 정의한다. 이 요구사항 단계는 solver 구현·FEAST 실행·reference 비교·환경 준비 통과를 선언하지 않는다.
- 보존: reference artifact와 `docs/TOLERANCE.md`는 읽기 전용이다. 제외 예제의 재사용이나 comparison tolerance 완화로 알려진 문제를 숨기지 않는다.
## MFE2-ADR-004 — 현행 운영 방식과 요구사항 완료
- 상태: [ADR-028](../ADR.md#adr-028) 적용.
- 결정: 메인이 관리 문서·검토·커밋을 맡고 Requirement specialist는 할당된 요구사항 문서만 작성한다. 상태는 PRD checklist에만 둔다.
- 영향: 고정 9단계 dispatch, 별도 planning/correction/release profile, 자동 Git·hook, phase payload·retry budget을 새 요구사항으로 복원하지 않는다.
- 검증: 문서·ID·출처·링크·scope의 정적 확인을 수행한다. 실제 동작 검증 의무와 기존 명시 감사 요구의 보존은 문서 작성과 별개이며 이번에는 실행하지 않는다.
## MFE2-ADR-005 — Research부터 I/O 계약까지의 후속 작업
- 상태: 사용자 명시 요청, 2026-09-08. Owner: 메인 assistant.
- 결정: requirement r1을 기준으로 research, formulation, 독립 numerical review, io-definition을 진행하고 변경을 커밋한다. ADR-001의 requirement-only 작업 범위는 이 후속 요청으로 확장된다.
- 승인 근거: “research 단계부터 io-definition 단계까지 작업을 진행”, “작업시간이 30분 이상 걸리면 작업을 중지하고 진행사항과 오래걸리는 이유를 보고”.
- 영향: 기존 수식·control·schema는 새 전문 검토를 거쳐 채택 여부를 명시한다. 문서 승인과 실제 solver 검증을 구분하며 구현·reference 실행·push는 수행하지 않는다.
- 제한: 2026-09-08 12:07:56 UTC부터 12:37:56 UTC까지. 제한 내 미완료 작업은 통과로 바꾸지 않고 상태·원인을 보고한다.
## MFE2-ADR-006 — 정식화 r1의 선택과 연구 gap 처리
- 상태: 승인된 요구 범위 안의 formulation 선택. 독립 numerical 판정은 별도 기록한다. Owner: formulation-agent; 기록: 메인 assistant.
- 결정: [정식화](formulation.md)의 27점 consistent moments→nodal block lumping, 실제 BC 우선 analytic null 제거·nodal whitening 및 초기 physical rotary trace 평균 stabilization을 이번 수학 계약으로 선택한다. Nonlinear objective potential과 초기 scale 고정 lifecycle을 유지한다.
- 이유: 질량 유도 관계·drilling null·부분 회전 제약을 보존하고 기존 최소 대각 scale의 기저 의존성을 해결한다. 기존 유도의 채택 범위를 새 문서에 명시하며 과거 pass를 승계하지 않는다.
- FEAST: 독립 outer enclosure와 성공 total count를 기준으로 lower endpoint를 고정하고 upper-prefix 축소만 선택적으로 사용한다. 미확인 empty-count 성공에 의존하지 않으며 최적화 실패 시 마지막 확인된 구간을 사용한다.
- 근거·한계: [연구 G01/G02](research.md#research-evidence)에서 count-only 빈 구간 및 작은 workspace 보장이 확인되지 않았다. 보수적 workspace와 실제 runtime·memory 검증 의무를 남기며 backend 통과를 선언하지 않는다.
- 승인 경계: 기존 사용자 요구의 수학적 구체화이며 새로운 물리 범위·외부 tolerance·공개 호환성 변경은 없다. 수치 controls·검토는 NR, 영속 schema는 I/O가 소유한다.
## MFE2-ADR-007 — 독립 수치 검토와 comparison family
- 상태: numerical-review-agent의 독립 `pass-for-io-definition`, 2026-09-08. Owner: numerical-review-agent; 기록: 메인 assistant.
- 근거: [검토](numerical-review.md#numerical-review), [새 계산](numerical-review.md#numerical-review-evidence). Geometry부터 complete K·질량·부분 제약 정적 응답을 재계산하여 `lambda=10369/450` 및 좌표 공변성을 확인했다. 별도 rational mass oracle도 새로 실행했다.
- 결정: [내부 controls](numerical-review-controls.md)와 [27개 사례](numerical-review-cases.md)를 적용한다. 초기 enclosing count 재시도는 최초 포함 3회, 이후 lower endpoint 고정·upper search·전체 count/solve 유한 한계를 명시했다. B=0의 시작 구간은 (-1,1)로 고정했다.
- 외부 비교: 원본 TXT의 literal modal frame과 유일한 source Step-2를 [reference-model](reference-model.md)에 대응한다. 같은 frame 규칙에 따라 10개 singleton Value blocking family를 정의하고 공통 행 5%·RMS 1% 정책을 그대로 적용한다. 이번 양수 singleton의 실효 각 Value 한계는 RMS 1%다.
- 영향·한계: 확인된 수학 차단 이슈 없이 I/O 정의를 진행할 수 있다. 이 판정은 구현·실제 FEAST·정적 회귀·외부 비교·Physics·release 통과가 아니다. Runtime count/cluster/ABI/workspace와 메모리 검증은 후속 필수 evidence다.
## MFE2-ADR-008 — Eigen I/O의 additive 계약과 이번 작업 종료
- 상태: 요청 범위의 I/O 정의 완료 및 메인 계약 대조 완료, 2026-09-08. Owner: io-definition-agent; 기록: 메인 assistant.
- 결정: [I/O](io.md#io)의 source density/Frequency/동차 BC·정확한 no-op allowlist를 사용한다. 기존 static schema0/1을 보존하고 eigen discriminator `(schema_version=0, feature_id=mitc4-shell-feast-eigen2, analysis_procedure=linear-frequency, eigen_schema_version=1)`를 추가한다.
- Identity: storage Step-1과 source Step-2를 구분한다. 공개 N개 scalar/global normalized vectors와 전체 c개 validation evidence를 분리한다. 원본 TXT Value만 source modal frame에 직접 대응하며 외부 mode-shape gate를 추가하지 않는다.
- 이유: 실제 parser·model·writer의 현재 경계를 보존하면서 새 procedure의 input/result 의미를 명확히 하기 위함이다. Candidate self-check·final 교체와 별도 live log lifecycle을 유지한다.
- 승인 경계: 이미 승인된 새 eigen procedure의 상세 schema 정의이며 기존 static 호환성·물리·외부 tolerance 변경은 없다. 일반 routine 정의에 반복 사용자 승인 gate를 추가하지 않는다.
- 종료: 요청한 네 문서 작업을 시간 제한 안에 마친다. 링크·ID·coverage·소스 대조·diff 정적 확인과 독립 수학 oracle를 evidence로 남기고, 구현·실제 solver/reference/physics 실행은 미실행으로 기록한다. 새 Feature 변경만 커밋하고 기존 사용자 변경은 보존한다.
## MFE2-ADR-009 — Implementation 실행과 시간 제한 해제
- 상태: 사용자 명시 요청, 2026-09-09 KST. Owner: 메인 assistant.
- 근거: “implementation 단계를 진행해주세요”, “implementation 단계에서 30분 제한은 없습니다”.
- 결정: 확정된 r1 계약을 구현하고 동작별 테스트·실제 FEAST·남는 필수 회귀/reference와 독립 검토를 진행한다. 30분 시간 제한을 적용하지 않는다.
- 영향: [구현 계획](README.md#재사용-handoff)의 파일 소유권으로 병행 작업하고 메인이 CMake 등록·빌드·통합·커밋을 조정한다. 수치/공개 schema/지원 범위를 구현 결과에 맞춰 변경하지 않는다. 공통 문서·기존 사용자 변경·reference를 보존한다.
## MFE2-ADR-010 — 실제 실행에서 드러난 계약 충돌
- 상태: 문제 기록·후속 제안, **수치 계약 변경 미승인**. Owner: 메인 assistant.
- 근거: [실행 결과](implementation-verification.md), [독립 수치 검토](implementation-review.md#implementation-numerical-review), [S3 검토](implementation-review.md#implementation-numerical-review-s3-static).
- 관찰: 원본 모델은 고정 FEAST trace stopping의 실제 반환값에서 전체 c residual 기준을 넘는다. S3 public static은 rotation-only drilling의 미평형 모멘트 때문에 실패한다.
- 현재 처리: r1 controls·tolerance·물리 식을 유지하고 실패를 명시한다. 요청 N 밖의 모드를 버리거나 reaction에서 torque를 제거하지 않는다. 구현 진행분은 커밋하되 기능 완료로 표시하지 않는다.
- 당시 후속 제안: residual stopping 후보의 FEAST 제어와 S3 정식화/회복/평형 계약을 사용자 결정 후 formulation·NR에서 재검토한다. 이 기록 시점에는 채택·승인된 변경이 없었다. 이후 FEAST 제어만 ADR-011로 변경한다.
## MFE2-ADR-011 — FEAST residual stopping과 S3 후속 분리
- 상태: 사용자 명시 승인, 2026-09-10. Owner: 메인 assistant; 수치 검토: numerical-review-agent.
- 승인 근거: “FEAST 잔차 초과 문제를 Trace 기반 종료 → residual 기반 종료로 변경”, “S3 문제는 추후에 고려”.
- 결정: C-index `fpm[5]`를 `1`에서 `0`으로 변경한다. `fpm[2]=12`, `fpm[3]=20`, count/solve 구간·capacity·seed·thread·실패 정책 및 전체 c개 독립 `1e-10` 검증은 유지한다.
- 이유: trace 변화의 수렴만으로는 원본 모델 전체 고유쌍의 독립 잔차를 충족하지 못했다. 개별 잔차를 사용하는 backend 종료를 선택하되 backend 성공을 독립 검증으로 대체하지 않는다.
- 영향: [정식화 E5](formulation-eigen.md), [수치 controls C5](numerical-review-controls.md), backend와 HDF5 writer의 control 검증을 함께 갱신한다. 기존 schema의 실제 `base_fpm[5]` 기록값이 바뀌며 field·shape·단위와 reference mapping은 유지한다.
- 검증: [실행 결과](implementation-verification.md) 및 [독립 수치 검토](implementation-review.md#implementation-feast-residual-review)에 새 실행을 기록한다. 기존 trace 실패 evidence는 당시 결과로 보존한다.
- 범위: S3 정식화·부분 회전 BC·reaction·평형 기준은 변경하지 않고 알려진 충돌을 후속 과제로 유지한다. S3를 해결하거나 unsupported로 재분류한 결정이 아니다. 외부 reference와 공통 tolerance도 유지한다.
## MFE2-ADR-012 — 첫 구현의 외부 고유치 5% 수용
- 상태: 사용자 명시 승인, 2026-09-10. Owner: 메인 assistant.
- 승인 근거: “5% 이내면 첫 구현이므로 Abaqus와의 고유치 정확도 향상은 추후에 진행”, “구현을 마무리”.
- 결정: [공통 ADR-029](../ADR.md#adr-029)와 [TOLERANCE 예외](../TOLERANCE.md#승인된-mitc4-eigen-첫-구현-예외)의 `mitc4-eigen-first-implementation` 정책을 적용한다. Mode별 Value relative/RMS limit은 inclusive5%다.
- 영향: Requirement022, reference model, I/O mapping과 comparator/report를 갱신한다. 같은 모드 identity·singleton family·원본 artifact와 내부 all-c1e-10 기준을 유지한다. 다른 기능의 공통 RMS1%는 변경하지 않는다.
- 범위: 첫 구현의 외부 고유치 정확도 향상 및 ADR-011의 S3는 후속 과제로 유지한다. 나머지 필수 구현/실패 보존 검사는 실제 evidence로 마무리하며 미실행을 통과로 표시하지 않는다.
- 결과: [구현 결과](implementation-verification.md)와 [첫 구현 독립 검토](implementation-review.md#implementation-first-version-review)에 새 정책의 fresh 검증 및 제한을 기록한다. 과거1% 비교 실패는 당시 계약의 이력으로 보존한다.
- 통합 승인: 사용자는 구현·검증 완료 후 `dev` 병합과 push를 명시 요청했다. 메인은 통과한 변경을 커밋하고 `dev`에 반영하며 관련 없는 사용자 worktree 변경은 보존한다. 외부 release/tag 승인으로 확대하지 않는다.
@@ -1,22 +0,0 @@
# mitc4-shell-feast-eigen2 문서·작업 지침
- Feature ID: `mitc4-shell-feast-eigen2`
- 문서 진입점·목적·사용법·Handoff: [README](README.md).
- 현재 범위·checklist: [PRD](PRD.md); 결정·승인·대체 이력: [ADR](ADR.md).
- 적용 범위: 해당 기능의 문서. 자동 로드되는 코드 영역 `AGENTS.md`가 아니다.
기준: [프로젝트 지침](../../AGENTS.md), [ARCHITECTURE](../ARCHITECTURE.md),
[Feature 문서 관리](../FEATURE_DOCUMENTATION.md), [공통 tolerance](../TOLERANCE.md).
## 보존할 계약과 인계
수식·I/O·수치 기준의 원본은 README에서 연결한 전문 문서를 따른다. 기능을 재개할 때
관련 계약과 실제 실행 revision·미해결 항목을 함께 읽는다. 과거 stage pass나 현재 문서
정리를 solver 검증 통과로 계산하지 않는다. 요구사항·ADR ID와 승인 이력을 유지한다.
메인은 PRD·ADR·진입점·문서 참조를 관리하고 전문 작업자는 할당한 본문과 관련 범위만 수정한다.
기존 개인 설정·reference·다른 작업자의 변경을 보존하며 실패를 tolerance 완화로 숨기지 않는다.
문서만 수정하면 정적 검토를 수행하고, 동작 변경에는 관련 검사와 필요한 독립 검토를 수행한다.
현재 첫 구현은 FEAST residual stopping·모드별5% 정책의 승인 범위다. 다른 기능의 RMS1%를
바꾸지 않는다. `reference/temp` 제외 portfolio를 cache·복사본으로 재사용하지 않는다.
S3 public static 충돌과 외부 정확도 개선은 보류이며, HHT consistent kinetic mass와 구분한다.
-65
View File
@@ -1,65 +0,0 @@
# MITC4 Shell Mass·FEAST Eigen 2 PRD
- Feature ID: `mitc4-shell-feast-eigen2`
- Owner: 메인 assistant
- Requirement baseline revision: `r2` (022의 외부 accuracy 기준 변경)
- 상태: **사용자 승인 첫 구현 완료**. 전체 417개 검사와 모드별 외부5% 비교, 독립 수치 검토를 통과했다. S3와 후속 정확도 개선은 보류한다.
기준: [프로젝트 지침](../../AGENTS.md), [프로젝트 PRD](../PRD.md),
[공통 ADR](../ADR.md#adr-028). 지역 지침은 [FEATURED_AGENTS](FEATURED_AGENTS.md),
결정 근거는 [Feature ADR](ADR.md)을 따른다.
## 사용자 결정과 현재 적용 범위
새 MFE2 baseline은 이전 유용한 수학 근거를 명시적으로 채택하되 실행·검증 결과는 승계하지
않는다. 사용자 승인 첫 구현은 residual stopping과 모드별 외부5% 정책이다.
[ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)·
[ADR-012](ADR.md#mfe2-adr-012--첫-구현의-외부-고유치-5-수용)에 채택 이유와 승인 이력을 남긴다.
옛30분 문서 작업 제한·당시 Git 운영 요청은 현재 기능 개발의 제약·권한이 아니다.
## 솔버 기능의 요구 범위 요약
기존 사용자 결정에 기록된 다음 의미를 새 요구사항의 출발점으로 사용한다.
승계 근거와 후속 전문 판단 경계는 [ADR](ADR.md)에 기록한다.
1. MITC4 shell consistent mass를 계산하고 그 결과로부터 lumped mass를 유도한다.
2. 실제 무감쇠 선형 고유진동 해석은 derived lumped mass와 Intel MKL FEAST를 사용한다.
3. 원형상·무응력 상태와 승인된 shell/constraint 범위를 대상으로 하며, requested mode count는 `.inp`의 `*FREQUENCY`에서 얻는다.
4. 지정 `reference/shellNL-eigen-meshfine`의 기존 입력·고유치 TXT를 보존하고 외부 eigen 비교는 `Value`만 사용한다. Mode shape는 내부 검증 대상이며 외부 acceptance를 추가하지 않는다.
5. 좌표 공변적인 numerical drilling stabilization 개선과 영향받는 기존 선형·비선형 정적 및 새 eigen 검증을 포함한다. 기존 물리 kernel·source identity·output 의미·공통 tolerance는 보존한다.
6. `reference/temp`로 제외된 예제는 검증에 사용하지 않는다. 남는 정적 회귀와 내부 물리 검증 의무를 명시한다.
지속할 상세 계약이 필요하므로 요구사항과 verification matrix 원본은
[requirements.md](requirements.md#requirements)에 둔다. 이 PRD에는 수식·threshold·schema를 중복 정의하지 않는다.
## Acceptance 요약과 원본
아래 ID는 `FEM-REQ-MITC4-EIGEN2-` prefix를 생략하며 링크는 상세 matrix의 원본을 가리킨다.
| 영역 | Requirement IDs | 요구되는 결과와 검증 의도 |
| --- | --- | --- |
| 입력·물리 범위 | [001~004, 015~016](requirements.md#requirements--requirement-verification-matrix) | 밀도·section·geometry·boundary·mode 요청의 의미를 보존하고 미지원 조합을 명확히 진단 |
| 질량·stabilization | [005~008, 014, 026~027](requirements.md#requirements--requirement-verification-matrix) | 두 질량의 유도 관계, 물리 관성·drilling null, 대칭성·에너지·좌표 공변성 검증 |
| FEAST·modal evidence | [009~013](requirements.md#requirements--requirement-verification-matrix) | 실제 backend, 낮은 N개·multiplicity, 동일 사용 질량의 residual·normalization·orthogonality 및 실패 보존 |
| 결과·reference | [017~022](requirements.md#requirements--requirement-verification-matrix) | HDF5 source/mode identity, Value-only 대응, completeness·finite 사전검사와 공통 tolerance |
| 회귀·완료 | [023~025](requirements.md#requirements--requirement-verification-matrix) | 제외 예제를 사용하지 않는 남은 static·내부 물리 검증, 필요한 실제 실행 evidence와 미실행의 구분 |
각 영역의 원자적 ID·검증 방법·출처는 requirements 및 [근거 문서](requirements.md#requirements-evidence)를 따른다.
과거 문서의 `pass`, 362/352 test count나 stage 완료를 이 baseline의 실행 결과로 사용하지 않는다.
## 현재 checklist
- [x] MFE2 요구사항·정식화·수치 기준·I/O·기존 MFE 대응과 독립 검산 확정.
- [x] Density/Frequency, mass·공변 stabilization, constraint-first modal reduction·실제 FEAST 구현.
- [x] State/procedure·HDF5 candidate 보존·Value 비교 및 failure/normalization·mass oracle 보강.
- [x] 2026-09-10 첫 구현 전체417/417 PASS·원본10개 Value 최대 상대차 약4.261331%·독립 수치/물리 검토 기록.
- [x] FEAST residual stopping으로 원본 전체 c의 독립 잔차 실패 해소·저장 controls 검증.
- [ ] Abaqus Value 정확도 개선. 이전 RMS1% 불일치는 이력으로 보존.
- [ ] S3 public static 평형 계약 충돌의 후속 검토.
## 실행과 미검증 범위
[실행 보고서](implementation-verification.md)와 [구현 독립 검토](implementation-review.md)는
당시 명령·수치·수정 전 실패·실제 주입 범위를 기록한다. 실제512회 vendor 호출과 HDF5
close-error 전체 주입은 하지 않았다. 이후 통합 회귀는 [전체 현황](../tracking/status.md)이
연결하며 첫 구현 범위를 release 또는 임의 모델 정확도 보증으로 확대하지 않는다.
@@ -1,519 +0,0 @@
# MITC4 eigen 구현 독립 검토와 수정 이력
수정 전 finding·수정 확인·S3 보류·물리 한계·종료 제어·첫 구현 acceptance를 구분한다. 아래 각 문서의 날짜·검토 source와 미실행 범위를 유지하며 새로운 검토를 수행한 것은 아니다.
<a id="implementation-numerical-review-history"></a>
<a id="implementation-numerical-review-history--수정-전-구현-수치-검토-기록"></a>
## 수정 전 구현 수치 검토 기록
아래는 최초 검토 당시 관찰이다. 현재 판정·수정 상태는 [현재 보고서](implementation-review.md#implementation-numerical-review)를 따른다.
<a id="implementation-numerical-review-history--구현-독립-수치-검토"></a>
## 구현 독립 수치 검토
- Feature: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`.
- 검토일: `2026-09-09`; 대상: 질량·선형 stabilization·constraint-first reduction의 현재 작업본.
- 판정: **correction-required / verification-incomplete**. 최초 질량/축소 검토에 이어 메인의 추가 할당으로 FEAST backend를 검토했다. Procedure는 메인이 수정 중이므로 검토하지 않았다.
- 기준: [formulation](formulation.md), [mass/stabilization](formulation-mass-stabilization.md), [eigen](formulation-eigen.md), [controls](numerical-review-controls.md), [cases](numerical-review-cases.md), [requirements](requirements.md#requirements), [공통 tolerance](../TOLERANCE.md).
<a id="implementation-numerical-review-history--수정-사항"></a>
### 수정 사항
<a id="implementation-numerical-review-history--nr-imp-01--p2-질량-양성-검사가-불필요한-곱의-범위에-의존한다"></a>
#### NR-IMP-01 — P2: 질량 양성 검사가 불필요한 곱의 범위에 의존한다
[mitc4_shell.cpp](../../src/fesa/elements/mitc4_shell.cpp) 819–824행은
`m*j-h*h`의 finite/positive 여부를 검사한다. 채택 C2-09의 검사는
`j-h²/m>0`이며, 전자는 유한하고 잘 조건화된 질량도 density 배율만으로 거부한다.
평판 `A=4,t=2,h=0`에서 `m=2*rho,j=(2/3)*rho`다.
| rho | m*j의 binary64 결과 | j-(h/m)*h | 현재 guard |
| ---: | ---: | ---: | --- |
| 1 | 1.3333333333333333 | 0.6666666666666666 | true |
| 1e-180 | 0 | 6.666666666666667e-181 | false |
| 1e180 | inf | 6.666666666666666e179 | false |
이는 Python 표준 `float`/`math.isfinite`로 실제 계산한 scalar 반례이며 C++ solver 재현은 미실행이다.
모든 사례의 `m,j`와 nodal block 성분은 finite positive이고 density 배율은 condition number를 바꾸지 않는다.
**수정:** 승인된 Schur variance를 불필요한 `m*j`, `h*h` 중간 곱 없이 평가하고 strict finite/positive 판정은 유지한다.
두 배율의 element mass 회귀로 실패를 재현하고, 정상 mass의 density 비례 및 잘못된 variance의 거부를 확인한다.
근거: M4/M5, C1 및 C2-09, 요구 003/014/026. 허용오차·rank·density 계약 변경은 필요하지 않다.
<a id="implementation-numerical-review-history--nr-imp-02--p2-새-oraclecovariance-검사가-승인된-metric을-사용하지-않는다"></a>
#### NR-IMP-02 — P2: 새 oracle/covariance 검사가 승인된 metric을 사용하지 않는다
[mitc4_shell_test.cpp](../../tests/unit/elements/mitc4_shell_test.cpp) 837–845, 901, 922–937행은
차원이 다른 `C0/C1/C2` 및 translation/rotation matrix entries에 동일한 absolute `1e-12`를 적용한다.
특히 `ExpectGlobalZCovariance`는 `D^T M D`, `D^T K D`와 상대 Frobenius 지표를 계산하지 않는다.
이 검사는 현재 fixture의 entry 오차를 확인하지만 C1/C2-02/03의 통과 evidence를 대신할 수 없다.
**수정:** scalar Ck 오차는 `m_e(t/2)^k`, matrix congruence는 같은 `ell`의 D congruence 후
`norm(R-S)/(norm(R)+norm(S))`로 검사한다. Finite-first와 승인된 zero branch를 유지한다.
단위변환 E2-C20을 함께 연결하여 고정 절대 단위에 의존하지 않음을 확인한다.
<a id="implementation-numerical-review-history--feast-추가-검토-수정-사항"></a>
### FEAST 추가 검토: 수정 사항
대상은 [mkl_feast_eigen_solver.cpp](../../src/fesa/solvers/eigen/mkl_feast_eigen_solver.cpp)의
2026-09-09 추가 할당 시점 작업본이다. 아래 행 번호는 후속 수정 전이며 기준은 C1/C3/C5/C6다.
| Finding | 위치·영향 | 필요한 수정·검증 |
| --- | --- | --- |
| NR-IMP-03 **P1** | 420–425행은 optional count의 **모든** 오류를 fallback으로 처리한다. Invalid/SPD/inner-solver 오류도 이후 solve 성공으로 우회될 수 있다. | `info=1,2,3,-5`만 optional search 종료로 분류하고 나머지는 즉시 실패. E2-C21 status 주입으로 각각 확인 |
| NR-IMP-04 **P1** | 429–433행은 세 guard의 서로 다른 successful count를 모두 fatal로 처리한다. Spectrum이 guard 사이에 있으면 정상적인 nondecreasing count 차이이며 endpoint collision이다. 반대로 서로 다른 interval들의 global monotonicity는 검사하지 않는다. | C5의 후보 `0,+1,-1,+2,-2,+4,-4` times delta 최대7개와 certified fallback을 구현. Successful count가 interval 포함관계에 모순될 때만 count-inconsistent. 정상 collision과 실제 역전 mock을 구분 |
| NR-IMP-05 **P1** | 451–457행의 final interior endpoint 검사는 central count 한 번뿐이다. 500–505행의 retry는 같은 b에서 capacity만 늘리며 재count하지 않는다. 542–546행의 endpoint separation 실패는 retry 경로에 들어가지 않는다. | Final interior b의 세 guard 재확인, 저장된 더 큰 certified b 선택→재count→capacity 갱신을 solve retry와 endpoint 실패에 연결. 최종 b0 및 변경 없는 입력 재호출 금지·3회/budget 한계 확인 |
| NR-IMP-06 **P2** | 360–365행은 초기 retry 때 Gershgorin padding 대신 전체 bracket 폭을 2^j배 한다. 불필요하게 넓어진 contour는 승인된 controls와 다른 수렴 동작을 만든다. | 원 gL/gU를 보존하고 **16delta padding만** 2^j배로 outward 재계산. Zero B의 ±2^j branch는 현재 정의와 일치 |
| NR-IMP-07 **P2** | 175–219행의 QR은 reflector norm의 absolute 1e-12만 검사하고 relative pivot, positive R diagonal, post-QR Gram 검사를 수행하지 않는다. | C6의 원 column scale 대비 pivot·positive R sign·Gram<=1e-12를 실제 계산. Fixed seed/n,m0별 재현성과 부적합 QR 실패 검증 |
| NR-IMP-08 **P1** | 236–238/312/459–473행은 일부 size_t product만 검사한다. n²/nm0의 byte·PTRDIFF_MAX·container max_size와 count padding arithmetic 사전검사가 없고 allocation exception 변환도 이 함수에 없다. | 모든 integer/byte operation 전에 C6 범위 검사, allocation/length 오류의 structured failure 경로를 연결. 불가능한 count m0도 cast 전 `0<=m0<=n` 검증(338–344행). E2-C22의 boundary/실패 주입 |
| NR-IMP-09 **P2** | 513–535행은 finite 검사 전에 eigenvalues를 sort한다. 565행은 physical lambda 환산의 finite/비영 underflow 검사를 하지 않는다. 492–495행은 epsout을 무조건 available로 기록하고 finite 검사하지 않는다. 571–579행은 Gram 최대 entry만 계산한다. | Raw eigenpairs finite-first 후 sort, `mu*s` overflow/비영→0 실패, epsout finite 검증, 전체 c의 `norm(G-I)F/sqrt(c)`와 pairwise 기준을 별도 적용. Public 결과의 gram_error 의미를 승인된 schema에 맞춤 |
추가 관찰: `ValidateSymmetry` 118–143행의 max-entry 기준도 C2-01의 Frobenius 지표와 다르다.
Failure 반환은 local `calls`를 버리므로 실패/fallback 이력을 상위 diagnostic/log에 남기는 연결을 확인해야 한다.
현재 [backend tests](../../tests/unit/solvers/eigen/mkl_feast_eigen_solver_test.cpp)는 actual n1/zero/repeated/prefix/negative/thread/request를 다루지만,
위 C5 status·collision·monotonicity·final guard·retry·512 call budget·overflow failure injection은 확인되지 않았다.
Backend를 이 검토에서 실행하지 않았으며 actual FEAST의 성공 또는 실패를 새로 주장하지 않는다.
<a id="implementation-numerical-review-history--정적-대조에서-일치한-구현"></a>
### 정적 대조에서 일치한 구현
| 경로·행 | 확인 내용 |
| --- | --- |
| [mitc4_shell.cpp](../../src/fesa/elements/mitc4_shell.cpp) 292–299, 725–805 | `S=-[d]cross`, 27점 xi→eta→zeta 적분, 각 점 geometry/J 검사, 대칭 Ck와 MC의 네 block 부호·DOF 순서가 M1/M3와 일치 |
| 같은 파일 808–850 | 보존된 Ck의 실제 row sum에서 m/h/j를 만들고 nodal tensor를 재구성한다. Full24 row sum 또는 인공 drilling mass를 사용하지 않음 |
| 같은 파일 649–716 | 초기 physical rotary 8개 전부의 trace mean, zero 포함 분모8, negative/nonfinite/allzero 거부 및 complete K 재조립이 S1과 일치 |
| [eigen_reduction.cpp](../../src/fesa/analysis/eigen_reduction.cpp) 65–112 | 실제 component BC를 먼저 적용하고 constrained director의 **정확한 비영** 성분으로 analytic null을 판정. Partial URZ의 양의 mass를 보존 |
| 같은 파일 116–200, 311–332, 359–370 | `Mp/scale`의 block Cholesky, small triangular inverse action으로 rcond_inf, `P L^-T` lift, nodal stiffness congruence 및 constrained-zero scaled mode 복원 방향이 E1–E4와 일치. Global dense inverse 없음 |
| 같은 파일 238–280, 289–349 | 원 scaled constrained MZ/KZ/PZ를 검사하고 null stiffness kappa의 strict positivity를 유지. `nz=0`의 storage0는 상위 I/O에서 N/A flag와 연결해야 함 |
<a id="implementation-numerical-review-history--아직-연결해야-하는-검증"></a>
### 아직 연결해야 하는 검증
다음은 할당된 [element tests](../../tests/unit/elements/mitc4_shell_test.cpp)와
[reduction tests](../../tests/unit/analysis/eigen_reduction_test.cpp)의 정적 coverage 확인이다.
다른 파일의 미확인 coverage를 전체 저장소의 부재로 단정하지 않는다.
- E2-C02/03/04/11: warped oracle는 현재 Ck(0,0) 및 전체 scalar sums만 확인한다.
모든 Ck/row, `sum(m_i X_i+h_i d_i)`의 독립 first spatial moment, MC/ML 각각의 직접 kinetic energy,
Jensen pairwise integral·mesh 차이, consistent rank20·nodal rank5·drill null·여섯 physical rigid mass Gram이 필요하다.
- E2-C08/09/10: 원 S3 exact scalar target은 구현되어 있다. **회전한 같은 S3 fixture**의 실제 partial BC spectrum과
admissible tangent moment `(5/3)b`의 정적 응답·full residual covariance는 아직 이 두 파일에서 확인되지 않았다.
Zero 포함 rotary inventory와 독립 tangent basis, invalid inventory 경계도 별도 evidence가 필요하다.
- E2-C13/14/15/16: 현 reduction 3개 테스트는 URZ positive, full-free aligned null/Kpz 실패, p=1e-8 conditioning 실패를 다룬다.
p=1/2000 positive 성공과 p=0 exact null, 2개 free rotations, drill-only free/all-fixed node/global n0,
nonpositive kappa·MZ 위반, **비대각 Mp** `[[2,1],[1,2]]`의 lambda `2,10/3` 및 original-mass 복원 검증이 필요하다.
- E2-C06/12/20/26: 공유 node의 section별 stable assembly·재현성, frozen nonlinear scale/미분/rollback,
density와 단위변환, retained static·pressure synthetic evidence는 이번 할당 파일 범위 밖의 후속 연결 사항이다.
<a id="implementation-numerical-review-history--실행-경계와-잔여-위험"></a>
### 실행 경계와 잔여 위험
이번에는 문서·source·test를 읽고 scalar binary64 반례만 실행했다. Build/CTest·FEAST·external reference·physics 검증은 실행하지 않았다.
메인의 focused build/test 성공 전달은 별도 실행 evidence이며 본 검토가 전체 기능 완료를 승인하지 않는다.
Reference artifact와 제외 예제는 읽거나 수정하지 않았다. 상위 계약·source·test·Git도 수정하지 않았다.
남는 위험은 거의 정렬된 partial BC의 forward accuracy, geometry 평가점 밖 injectivity,
원 free residual·전체 c개 Gram을 포함한 procedure 복원 검증과 actual FEAST의 count/cluster/runtime다.
<a id="implementation-numerical-review"></a>
<a id="implementation-numerical-review--구현-독립-수치-검토"></a>
## 구현 독립 수치 검토
- Feature: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; 검토일: `2026-09-09`.
- 판정: **correction-required / verification-incomplete**.
- 대상: 질량·stabilization·reduction, 수정된 FEAST backend와 `linear_frequency_procedure.cpp`. Writer는 검토하지 않았다.
- 기준: [formulation](formulation.md), [mass/stabilization](formulation-mass-stabilization.md), [eigen](formulation-eigen.md), [controls](numerical-review-controls.md), [cases](numerical-review-cases.md), [requirements](requirements.md#requirements), [공통 tolerance](../TOLERANCE.md).
- 최초 finding·scalar 반례는 [이전 검토 상세](implementation-review.md#implementation-numerical-review-history)에 보존한다. 아래는 후속 수정본에 대한 현재 판정이다.
<a id="implementation-numerical-review--이전-finding의-수정-확인"></a>
### 이전 finding의 수정 확인
Central Count·안정적 QR까지 수정한 최신 저장본 `mkl_feast_eigen_solver.cpp`를 직접 대조했다.
아래 source 판정과 메인이 전달한 실제 재실행 결과를 구분한다.
| Finding | 현재 상태 | 최신 정적 evidence |
| --- | --- | --- |
| NR-IMP-01 | **addressed** | [mass source](../../src/fesa/elements/mitc4_shell.cpp)의 `j-h*(h/m)` strict finite/positive와 [density 회귀](../../tests/unit/elements/mitc4_shell_test.cpp) 확인. 메인이 실제 통과를 전달 |
| NR-IMP-02 | **open** | Mass Ck oracle/`ExpectGlobalZCovariance`의 승인된 차원별 scale·D congruence 적용 및 단위변환 coverage 미완료 |
| NR-IMP-03 | **addressed in source** | [backend](../../src/fesa/solvers/eigen/mkl_feast_eigen_solver.cpp) optional info1/2/3/-5만 fallback, 나머지는 실패 |
| NR-IMP-04 | **addressed in source** | Offsets `0,±1,±2,±4`, 21-call 예약으로 optimization384 유지, 각 Count/solve의 total512 guard 확인. Central Count 473–484행에서 동일 lower의 모든 성공 이력에 대해 upper/count 단조성과 동일 endpoint count 일치를 검사 |
| NR-IMP-05 | **addressed in source** | 최초·retry interior 3-count guard, previous/new capacity 비교와 실제 interval 변경 조건을 확인. Retry Count도 위 central history 검사를 거침 |
| NR-IMP-06 | **addressed in source** | 초기 재시도는 16delta padding만 2^j배 |
| NR-IMP-07 | **addressed in source** | 229–245행의 relative pivot·`alpha=-copysign(norm,x0)` reflector, 276–290행의 Q column sign으로 positive R diagonal 및 `norm(Q^T Q-I)_F/sqrt(m0)<=1e-12` 확인 |
| NR-IMP-08 | **production guards added; failure coverage incomplete** | n²/nm0 storage·PTRDIFF/container·padding·count[0,n] 검사, 주요 allocation 변환 및 [procedure](../../src/fesa/analysis/linear_frequency_procedure.cpp)의 bad_alloc/length_error 변환 확인. 경계/실패 주입 검증 미확인 |
| NR-IMP-09 | **addressed in source** | Successful epsout/loop 및 유효한 반환 범위의 모든 eigenvalue/vector finite 검사를 endpoint/retry 앞에 수행. Finite-first sort, physical lambda 환산, exact-zero nonfinite backend res의 unavailable 처리, all-c pairwise/Frobenius Gram acceptance 확인 |
<a id="implementation-numerical-review--최신-backend-correction과-검증-경계"></a>
### 최신 backend correction과 검증 경계
[Backend source](../../src/fesa/solvers/eigen/mkl_feast_eigen_solver.cpp)의 이전 count/QR/nonfinite-vector finding은
현재 저장본에서 수정됐다. Optional guard가 중간 실패해도 이전 성공 Count는 공통 이력에 남아 이후 대조에 사용된다.
Signed Householder는 cancellation을 피하며 Q column sign 변경은 R row sign 변경과 대응하므로 positive diagonal 규칙에 맞는다.
`ValidateSymmetry` 134–166행도 scale로 정규화한 Frobenius 비율이며, max-entry acceptance라는 이전 finding은 해소됐다.
C5 실패/status/동일 endpoint/역전/retry/budget/allocation 주입은 **실행 evidence 미완료**다.
`CallHistory`는 residual 실패에 연결됐지만 다른 early failure의 전체 이력 보존도 미확인이다.
Source correction 확인을 해당 실패 경로의 실행 통과로 확대하지 않는다. NR-IMP-02의 mass oracle 차원별 scale은 별도로 남는다.
<a id="implementation-numerical-review--frequency-procedure와-reduction의-대조-결과"></a>
### Frequency procedure와 reduction의 대조 결과
[Procedure source](../../src/fesa/analysis/linear_frequency_procedure.cpp)에서 다음 수학 계약과의 불일치는 발견하지 못했다.
- 161–185행: active shell 길이 scale과 analytic reduction 뒤 actual FEAST를 사용하고, exact-zero A의 scale 후보는 `min(E/rho/ell²)`로 만든다.
- 201–223행: K/M Frobenius norm은 실제 free/free 부분에 D congruence를 적용해 같은 단위로 계산한다.
- 235–270행: `q=D y`, scaled source maximum-component sign, actual ML mass 정규화, 최종 phi에서 g/y 재계산, 원 조립 K/ML의 모든 free DOF residual·Rayleigh·energy를 평가한다. Constrained components는 exact0이며 modal reaction을 생성하지 않는다.
- 271–305행: whitened/operator residual 및 raw lambda를 보존한 near-zero/positive·connected cluster·frequency validity를 검사한다. 전체 c를 검증하고 첫 N개만 mode/vector로 공개한다.
- 306–319행: 정규화된 physical phi와 actual mass action으로 전체 c의 Gram/각 pairwise orthogonality를 다시 계산한다. `nz=0`의 null metric은 applicable flag0와 연결된다.
- [Reduction tests](../../tests/unit/analysis/eigen_reduction_test.cpp)에 비대각 Mp의 lambda2,10/3·original mass 복원, p1/2000 positive, 2 free rotations, MZ 위반, drill-only/all-fixed empty 실패가 추가됐다.
<a id="implementation-numerical-review--원본-eigen-column20-residual-실패의-한정-재검토"></a>
### 원본 eigen column20 residual 실패의 한정 재검토
메인이 전달한 correction 후 실제 값은 `n=3125,c=22,m0=33`, backend 26 calls,
`rho_B=1.48674481038207483e-10`이다. **현재 근거로 procedure/reduction의 구현 결함이 원인이라고 판정할 수 없으며,
보고된 값에 대한 실패 처리는 승인 C3-02/C5와 일치한다.** 기준1e-10을 48.6745% 초과하고,
requested10 밖의 column20도 검증 대상인 전체 c개에 속하므로 삭제하거나 검사에서 제외할 수 없다.
FEAST 성공 status·trace stopping은 이 독립 operator residual 기준을 대신하지 않는다.
- [Procedure](../../src/fesa/analysis/linear_frequency_procedure.cpp) 184–186행은 backend 실패를 즉시 반환한다.
따라서 201행 이후의 scaled original-free norm, `q=D y`, 최종 physical normalization·Gram/energy는
이번 실패 때 실행되지 않았다. 그 계산에서 이번 backend column20 오류가 생겼다는 설명은 실행 순서와 맞지 않는다.
- 최신 [reduction](../../src/fesa/analysis/eigen_reduction.cpp) 116–206, 301–356행을 다시 대조했다.
`Mp/scale=L0 L0^T`, lift=`P L0^-T/sqrt(scale)`, `A=lift^T Khat_f lift`의 전치·양쪽 D·질량·단위는 일치한다.
실제 global BC의 exact null 처리와 원 MZ/KZ/PZ 검증에도 이 residual 실패를 설명하는 수식 오류를 발견하지 못했다.
이는 실제 큰 모델의 forward accuracy 보장이거나 모든 입력 inventory의 독립 검증 완료를 뜻하지 않는다.
- Backend가 계산하는 `norm((A/s)x-mu*x)/norm(x)`는 해당 승인 metric이다.
모드 진폭을 바꿔도 비율은 같고 물리 mass 정규화로 이 값을 낮추려는 변경은 근거가 없다.
메인이 전달한 column20의 correction 전·후 actual rerun 진단값은 다음과 같다.
| 관찰 | 이전 실행 | 최신 correction 후 실행 |
| --- | ---: | ---: |
| FEAST info / loop | 0 / 4 | 0 / 4 |
| trace epsout | 2.82730672643927457e-14 | 2.82488401287762986e-14 |
| full CSR rho_B | 1.42356735413003805e-10 | 1.48674481038207483e-10 |
| mirrored upper CSR rho_B | 1.42356735389686902e-10 | 1.48674481542089335e-10 |
| full/upper difference action norm | 1.24572423402534915e-17 | 1.38724134018909290e-17 |
**해당 실행 판정: mandatory all-c residual failure confirmed.** FEAST가 실제 받은 symmetric upper operator에서도
같은 기준을 넘으므로 full/upper symmetry roundoff는 이 실패의 원인이 아니다.
고정 `fpm[5]=1` trace stopping이 4회에서 충족된 결과이며 **최대20회 반복을 소진한 실패가 아니다**.
따라서 단순히 maximum loop를 늘리는 것을 확인된 원인 수정으로 제시할 수 없다.
작은 trace 변화나 `info=0`을 모든 eigenpair residual의 통과로 해석하지 않는다.
최신 진단은 위 central Count·안정적 QR correction **이후 실행**이다. 확인된 구현 결함을 수정한 뒤에도
승인 fixed controls로 얻은 이 모델의 결과가 mandatory all-c 기준을 충족하지 못한다.
이는 모든 잠재적 구현 결함을 배제한 증명은 아니지만, 현재 reference 성공 또는 기능 완료 판정을 막는 실제 evidence다.
전체 runner 통과가 있더라도 이 필수 residual/reference 실패를 대신 해소하지 않는다.
FEAST stopping/control·후검증 기준·실패 retry 정책을 바꾸려는 경우에는 고정 C3/C5 계약의
**사용자 결정과 관련 수치 재검토가 먼저 필요하다**. 구현 correction은 기존 계약 안에서 진행할 수 있으며,
mass·seed·N 변경, column20 제외 또는 실패 후 미승인 재시도의 근거가 되지 않는다.
이번 검토자는 actual rerun을 직접 실행하지 않았고 전달받은 진단값과 read-only 실행 경로를 대조했다.
<a id="implementation-numerical-review--남은-검증과-실행-경계"></a>
### 남은 검증과 실행 경계
- **NR-IMP-10 / upstream-contract-conflict:** S3의 public static global moment failure는 exact numerical drilling torque에서 발생한다. `norm(e_M)=95/41476`, 현재 normalized metric≈7.328771e-4다. [독립 유도와 판단](implementation-review.md#implementation-numerical-review-s3-static)을 참조한다. 메인은 수정된 E2-C09 direct pencil/full Kq-F covariance 테스트 통과와 별도 public rejection 재현을 전달했다. 수학 case의 검증은 연결됐지만 public 지원 범위의 평형 충돌은 미해결이다.
- [Procedure integration tests](../../tests/integration/analysis/linear_frequency_procedure_test.cpp)는 S3 direct pencil/full residual covariance와 free panel의 여섯 near-zero mode/all-c evidence를 다룬다. Density4 및 length1024의 물리 단위변환에서 lambda·rotation amplitude·residual/energy를 검증하는 테스트도 추가됐고 메인은 최신 focused 통과를 전달했다. Wrong-mass/vector/constraint mutation 검증은 미완료다.
- Mass의 모든 warped Ck/rows·first spatial moment·두 mass의 독립 energy/Jensen·mesh 오차·rank20/rank5·physical rigid Gram, 독립 tangent inventory 및 frozen nonlinear/retained static 검증은 최초 상세의 coverage gap이 남아 있다.
- [Actual FEAST tests](../../tests/unit/solvers/eigen/mkl_feast_eigen_solver_test.cpp)에 zero/positive known spectra의 lowest prefix와 Givens congruence로 회전한 close distinct spectrum/Gram 검증이 추가됐고 메인은 최신 focused 통과를 전달했다. C5 status·guard collision/역전·retry·budget·allocation 주입, repeated eigenspace projector 및 세 반복 재현성 evidence는 미확인이다.
- 메인이 전달한 최신 source checkpoint는 `22c9d44`이며 configured full runner는 **395개 중394 통과, 원본 eigen 1개 실패, 155.31초**다. Input/FEAST/procedure/writer focused41은 새 density·unit scaling을 포함해 모두 통과했다. 본 검토자는 실행 로그를 직접 재검증하거나 build/test를 실행하지 않았다. 필수 reference/physics 완료는 승인하지 않는다.
- 최초 원본 eigen 실행의 10669ms 뒤 column20 `eigenpair-validation-failed`는 위 actual rerun의 full/upper residual·loop/epsout evidence로 구체화됐다. 필수 reference/전체 기능의 성공 판정은 할 수 없다.
- 이번 후속 수정은 본 보고서뿐이며 과거 검토 상세는 보존했다. 상위 계약·source·tests·writer·Git·reference는 수정하지 않았고 reference·제외 예제는 열람하지 않았다. 잔여 위험은 mandatory residual와 public static 계약 충돌, near-aligned forward accuracy, geometry 평가점 밖 injectivity 및 필수 coverage다.
<a id="implementation-numerical-review-s3-static"></a>
<a id="implementation-numerical-review-s3-static--s3-partial-bc-정적-평형-불일치"></a>
## S3 partial-BC 정적 평형 불일치
- Feature: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; 검토일: `2026-09-09`.
- Finding: **NR-IMP-10 / upstream-contract-conflict**. [현재 보고서](implementation-review.md#implementation-numerical-review)의 추가 검토다.
- 입력: [S3 정식화](formulation-mass-stabilization.md), [E2-C09](numerical-review-cases.md), 채택 [C7](../mitc4-shell-feast-eigen/numerical-review.md#numerical-review-controls), 기존 [linear formulation §14.1](../linear-static-mitc4-shell/formulation.md), [linear I/O §6.5](../linear-static-mitc4-shell/io.md).
<a id="implementation-numerical-review-s3-static--독립-수치-결론"></a>
### 독립 수치 결론
`d=(3/5,0,4/5)`, node1 URZ만 free, applied moment `(-4/3,0,1)=(5/3)b`,
`M0=1`인 승인 S3에서 다음은 정확하다. Moment의 단위는 `[force·length]`다.
\[
\theta_{1Z}=7500/10369,\qquad
\gamma_1=d^T\theta_1=6000/10369,\qquad k_d=19/4800.
\]
Physical stiffness의 spatial total moment는 0이지만,
`Kdrill`은 node1에 `tau_d=kd gamma1 d`를 더한다. `r=Kq-F`의 free 성분은 0이므로
applied load와 **constrained full residual**을 더한 기존 global moment evidence는
\[
e_M=\tau_d=(57/41476,\ 0,\ 19/10369),\qquad
\|e_M\|=95/41476\approx0.002290481242164143\ne0.
\]
Global Z45° 회전에서는 `e_M'=Q e_M`이며 norm은 같다. Applied moment가 tangent라는 사실은
partial global BC가 만든 `gamma1!=0`을 없애지 않는다. Load의 constrained X 성분을 추가해도
`Ff=1`과 위 nonzero torque는 그대로다. Physical rigid representative의 회전은 `P_i Omega`이고,
full spatial `Omega`와 numerical drilling energy를 혼동하면 이 불일치를 놓친다.
[기존 독립 oracle](numerical-review.md#numerical-review-evidence)의 첫 Python block을 그대로 실행한 뒤
원 `K,q,F`에서 constrained `Kq-F`, 각 node의 `X cross R+RM`을 따로 합산했다.
현재 [global recovery](../../src/fesa/results/global_equilibrium_recovery.cpp) 193–249행과 같은
정규화에서 `reaction moment scale=3.1253278233567374`,
`applied moment scale=5/3`, `eta_M=0.0007328771161369957`을 얻었다.
Fraction 산술의 위 exact torque와 일치한다. 따라서 기존 `1e-10` 검사가 실패하는 것은 예상된 결과다.
이것은 독립 수학 실행이며 C++/reference/solver 재실행이 아니다.
<a id="implementation-numerical-review-s3-static--e2-c09-검증-계층과-계약-경계"></a>
### E2-C09 검증 계층과 계약 경계
**E2-C09 자체는 public `LinearStaticProcedureExecutor::Execute`의 성공을 명시하지 않는다.**
S3, E2-C09 및 채택 C7의 해당 문장은 `thetaZ`, complete full `Kq-F`, same-BC/load 회전 공변성을 요구한다.
기존 독립 evidence도 direct1DOF partition solve로 이를 검증했고 zero global moment를 확인한 적은 없다.
따라서 production kernel의 complete K를 geometry/frame부터 재계산하여 `Kff theta=Ff`를 풀고,
전체 `r=Kq-F`와 원/회전 결과를 비교하는 **직접 pencil 테스트는 E2-C09에 맞는 검증**이다.
Constrained residual이 0이어야 한다는 의미로 complete residual 기준을 적용하지 않는다.
이는 case의 test layer를 바로잡는 것이며 threshold·물리·reaction 계약을 바꾸지 않는다.
동시에 **public static 실패는 별개의 실제 계약 충돌로 남는다.** 기존
[linear requirements](../linear-static-mitc4-shell/requirements.md)의 017–019는 이 global component BC와
tangent CLOAD를 지원하고, 029/046/057 및 기존 I/O는 full residual reaction과 spatial global balance를 유지한다.
새 요구 024/027은 그 의미를 보존한다. 승인된 M2의 rotation-only drill penalty와 이 조합은
S3에서 exact algebra상 동시에 public 성공 조건을 만족할 수 없다.
직접 테스트 통과만으로 public static 회귀가 해소되었다거나 이 입력이 새로 unsupported라고 선언하면 안 된다.
**처리:** E2-C09의 algebraic 검증과 현재 public failure 재현은 따로 보존한다.
Global balance를 완화하거나 drill torque를 빼거나 reaction을 projection하거나 fixture BC/load를 바꾸어 실패를 감추지 않는다.
Public static의 해당 supported 범위까지 성공해야 하는 완료 판정을 내려면 메인이 formulation/requirements owner에게
이 exact 반례를 전달하고, physics·지원 범위·recovery/acceptance 중 어떤 계약을 바꿀지 사용자 결정을 받아야 한다.
현재 numerical reviewer에게 그 변경을 자체 승인할 권한은 없다. Eigen S3의 finite-pencil target은 이 static 충돌로 바뀌지 않는다.
후속 실행 전달: 메인은 E2-C09를 direct pencil/full `Kq-F` covariance 테스트로 수정하여 통과했고,
별도 public static 테스트는 현재 global-equilibrium rejection을 재현한다고 보고했다.
이는 수학 case와 public 실패를 분리해 검증한 evidence이며, 지원 범위의 상위 계약 충돌을 해결하거나
public failure를 승인된 unsupported-input 진단으로 바꾼 결정은 아니다.
<a id="implementation-physics-review"></a>
> 이 절은 2026-09-10 residual stopping·후속 recovery 수정 이전의 발견 기록이다.
> Eigen all-c 잔차는 후속 수정으로 해소했고, 굽힘 단면력은 HHT 후속 작업에서 수정했다.
> 원래 실패 수치와 coverage 한계는 그대로 보존하며 S3는 보류다.
<a id="implementation-physics-review--구현-결과-물리-검토"></a>
## 구현 결과 물리 검토
- Feature: `mitc4-shell-feast-eigen2`; Owner: `physics-evaluation-agent`; 검토일: `2026-09-09`.
- 결론: **유지 대상 변위·평형 evidence는 타당하나 feature 완료 판정 불가**. 원본 eigen 필수 residual 실패, S3 public static 계약 충돌이 남는다. 별도로 기존 nonlinear 굽힘 단면력 복구 결함을 확인했다.
- 기준: [cases E2-C08/09/11/12/26](numerical-review-cases.md), [mass/stabilization S1–S3](formulation-mass-stabilization.md), [controls C3/C7](numerical-review-controls.md), [공통 tolerance](../TOLERANCE.md), [nonlinear I/O §7.5/8.5](../nonlinear-static-newton-raphson/io.md). 새 acceptance나 release 승인을 만들지 않는다.
<a id="implementation-physics-review--직접-확인한-evidence"></a>
### 직접 확인한 evidence
아래 `A/B/C`는 이번 검토 시 허용된 각 경로에서 `LastWriteTime`으로 선택한 최신 결과다. HDF5를 `h5py.File(path, 'r')`로 읽어 계산했으며 solver/build/test는 재실행하지 않았다. 이후 구현 수정·재실행 결과로 자동 승계하지 않는다.
| ID | Artifact |
| --- | --- |
| A | [.harness/build-ninja-msvc-debug/reference/mitc4-shell-s4-comparison/shell_results.h5](../../.harness/build-ninja-msvc-debug/reference/mitc4-shell-s4-comparison/shell_results.h5), 같은 폴더 [comparison.json](../../.harness/build-ninja-msvc-debug/reference/mitc4-shell-s4-comparison/comparison.json) |
| B | .harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shellNL/shellnl-s4-final-798076888102900-0/shellNL_results.h5(당시 경로: `../../.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shellNL/shellnl-s4-final-798076888102900-0/shellNL_results.h5`, 현재 checkout에 없음), 같은 폴더 `shellNL_log.txt` |
| C | .harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shell/shell-s4-linear-limit-798054727288300-1/shell_results.h5(당시 경로: `../../.harness/build-ninja-msvc-debug/reference/nonlinear-static-reference/shell/shell-s4-linear-limit-798054727288300-1/shell_results.h5`, 현재 checkout에 없음) |
| Model/reference | [shell.inp](../../reference/shell/shell.inp), [shell displacements.csv](<../../reference/shell/shell displacements.csv>), [shellNL.inp](../../reference/shellNL/shellNL.inp), [shellNL displacements.csv](<../../reference/shellNL/shellNL displacements.csv>), [shellNL reactions.csv](<../../reference/shellNL/shellNL reactions.csv>) |
두 모델은 `36 S4 / 49 nodes`, `[-5,5]×[-5,5]` 평판, `t=0.5`, `E=2.1e11`, `nu=0.3`, 외곽 24 node의 6 DOF 고정, 중앙 `(Part-1-1, node 2)`의 `FZ=-100000`이다. A/C는 linear, B는 `nlgeom=YES`, factor `0.1..1.0`의 10 accepted frames다. 단위계는 입력의 일관된 미지정 단위: 변위 `length`, 힘 `force`, 모멘트·에너지 `force*length`, 응력 `force/length²`, 굽힘 단면력 `force`다. SI로 추정하지 않는다. 제외된 원본·복사·cache 모델과 stress reference CSV는 열거나 사용하지 않았다.
<a id="implementation-physics-review--변위-대칭-평형과-에너지"></a>
### 변위, 대칭, 평형과 에너지
| 관찰 | 직접 계산/저장 결과 | 해석 |
| --- | --- | --- |
| A/C 하중 방향·크기 | 중앙 `UZ=-2.3550441765084857e-5`; `UX=UY=URZ=0`; `max|URX/Y|=7.55060026636933e-6` | 음의 Z 하중에 음의 처짐. `|UZ|/t=4.71009e-5`로 작은 변형 영역 |
| A 대칭 | X/Y 반사 node 대응의 `max|ΔUZ|=3.21873e-20 length` | 중앙하중·고정 외곽의 대칭과 일치. 이 수치는 별도 새 판정 기준이 아닌 관찰 |
| A 평형 | HDF5 `global/verification_metrics`: free residual `1.07747756e-14`, force `1.12049747e-14`, moment `2.35981342e-15` | 각각 기존 `1e-10` 이내 |
| A 에너지 | physical energy `1.1775220882542212`; `Fᵀu/2=1.1775220882542428`; 상대차 `1.82912e-14` | 양의 선형 변형에너지와 일치, 기존 energy `1e-12` 이내 |
| B 최종 변위 | 중앙 `UZ=-2.355044174560645e-5`; `max|UX/UY|≈8.79961e-12`; 반사 `max|ΔUZ|=7.41128e-17` | 작은 면내 응답과 대칭 유지. 큰 변형의 외부 검증으로 확대할 수 없음 |
| B 선형극한 | C 대비 중앙 UZ 상대차 `8.27093e-10`; 전체 translation 최대차/최대 linear translation `3.73649e-7` | 작은 하중의 nonlinear displacement가 linear에 접근. 단면력 일치까지 뜻하지 않음 |
| B 에너지·증분 | factor0.1 energy `0.011775220886841211`, factor1 energy `1.1775220868030056`; 모든 10 frame 양수·증가, 각 2 Newton iterations | 거의 factor² 에너지와 factor 비례 처짐. Nonlinear에서 `Fᵀu/2`를 일반 항등식으로 요구하지 않음 |
B frame9의 `generalized_residual`에 **먼저 constraint mask**를 적용한 뒤 회전만 `J_l(phi)^(-T)`로 spatial 변환하고 current arm `X+u`를 사용했다. `|phi|<1.1e-5`에서 inverse-Jacobian의 안정적 소각 전개를 사용했다. 독립 합산은 저장된 `/global/equilibrium`과 roundoff 범위에서 일치한다.
- Constrained resultant force: `(-5.88263e-12, 6.25300e-12, 100000.00000082512) force`. Applied force `(0,0,-100000)`을 상쇄한다. Reference CSV 전체 RF 합의 Z는 `99999.99959279996 force`; 이는 review-only 관찰이다.
- Constrained resultant moment about origin: `(-5.63887e-11, 3.63798e-11, -4.17886618386e-5) force*length`. 중앙 applied force arm은 사실상 0이다.
- I/O §8.5의 nodal norm-sum scale은 force `100000.00439300563`, moment `780242.2734309232`. 독립 normalized force `8.25134e-12`, moment `5.35586e-11`로 각각 기존 factor-one `1e-8` 이내다. 저장 balance Z-force `8.25122697279e-7`, Z-moment `-4.17886618392e-5`를 zero-clamp하지 않았다.
- Accepted free residual: force infinity norm `0.031462885121074535 force`, matching external scale `100000`, internal-inclusive scale `100000.00000106206` → relative `3.14629e-7 <= 1e-2`. Moment infinity norm `3.3292018315478344e-6 force*length`, matching external scale exact0 → 기존 typed absolute `1e-3` 이내. 이 accepted residual과 global balance는 서로 다른 관찰이다.
<a id="implementation-physics-review--외부-변위-비교와-복구-결함"></a>
### 외부 변위 비교와 복구 결함
A comparison JSON은 49 nodes × 6 components의 294행, blocking U와 warning-only UR 각각 147행, 실패행·warning 0이다. U relative RMS `0.0010332756650397166`, UR `0.0029771372973060382`로 기존 `0.01` 이내다.
B는 실제 CSV/HDF5의 `(case-insensitive instance, source node label, component)`를 직접 대응했다. 49개의 유일 node identity가 일치하고 값이 모두 유한하다. 같은 공통 tolerance로 U relative RMS `0.0010332757195474177`, UR `0.0029771373238648216`, 각 family 실패행 0이다. Reaction CSV를 blocking 비교로 승격하지 않는다. 변위 수치 일치는 아래 복구 결함을 검출하지 않는다.
**PE-IMP-01 — 기존 nonlinear 굽힘 단면력 복구 결함, 구현 owner 인계.** B frame9 `(Part-1-1, element 3, midsurface GP2)`의 `S11` bottom/middle/top은 `[313254.63790344447, 3.694293034163272, -313246.91989287396] force/length²`이다. [nonlinear formulation §13.3](../nonlinear-static-newton-raphson/formulation.md)의 `M11=∫z S11 dz`, `z∈[-t/2,t/2]`와 평판의 두께 stress polynomial에서:
`M11 = t²/12 * (S11_top-S11_bottom) = -13052.1157874233 force`.
그러나 HDF5 `section_resultant[...,3]`는 `-26104.23157284045 force`, 비율 `1.999999999846297`이다. A의 같은 적분은 저장 M과 최대차 `9.09495e-12 force`로 일치한다. B의 모든 row/component 중 최대 굽힘 오차는 `13052.11578541715 force`다.
메인의 추가 읽기 허가로 [nonlinear recovery source](../../src/fesa/elements/nonlinear_mitc4_shell.cpp#L1243)를 확인했다. 두께 Gauss moment 가중치가 `0.25*t*zeta*stress`이므로 `z dz`가 요구하는 `0.25*t²*zeta*stress`의 thickness 한 개가 빠져 있다. `t=0.5`의 2배 차이와 직접 연결되며 차원도 맞지 않는다. 해당 파일의 `git diff HEAD -- <path>`는 비어 있다. 따라서 **현재 eigen 변경이 도입한 결함이라는 근거는 없고 HEAD에도 존재하는 복구 결함**이다. 코드 수정이나 새 gate를 수행하지 않았다. Finite stress/strain, 양의 에너지, U/UR 통과만으로 nonlinear section-resultant 물리 타당성을 주장할 수 없다.
<a id="implementation-physics-review--eigens3와-남은-범위"></a>
### Eigen/S3와 남은 범위
- **원본 eigen 미해결:** 메인의 최신 actual FEAST 전달값은 `676 shells / 729 nodes`, `nf=3750,nz=625,n=3125,N=10`, `c=22,m0=33,loop=4`, column20 `rho_B=1.48674481038207483e-10 > 1e-10`이다. Symmetric upper operator에서도 `1.48674481542089335e-10`이다. 요청 10개 밖이어도 all-c 검증 대상이므로 버릴 수 없다. Accepted modal HDF5와 Value reference comparison이 없으므로 원본 modal energy·mass normalization·mode shape 물리 검증은 **미실시**다. 최신 실패값은 메인 실행 전달이며 이 검토자가 eigen artifact를 직접 읽은 값이 아니다.
- **S3 public static 충돌:** [독립 수치 검토](implementation-review.md#implementation-numerical-review-s3-static)의 `thetaZ=7500/10369`, `lambda=10369/450`과 complete `Kq-F` 회전 공변성은 direct pencil 검증이다. `gamma1=6000/10369`에서 미상쇄 drilling torque `(57/41476,0,19/10369) force*length`, norm `95/41476≈0.002290481242164143`, normalized spatial moment `0.0007328771161369957 > 1e-10`가 남는다. 메인은 direct 검증 통과와 별도 public rejection 재현을 전달했다. 지원되는 static 성공을 의미하지 않으며 기존 reaction/global-balance 의미와의 계약 충돌 해결은 formulation/requirements owner와 사용자 결정 사항이다.
- **전달받은 synthetic 통과의 한계:** 작은 S3 eigen, free panel 여섯 rigid near-zero modes 및 all-c Gram, nonlinear tangent/objectivity/force/moment/free residual/energy/rollback 통과는 메인 실행 전달이다. 이번 검토자는 해당 test output을 직접 열지 않았다. Massless drill null과 양의 질량을 가진 physical rigid modes를 구분하는 근거이지만 큰 원본 모델 성공을 대신하지 않는다.
- Retained 외부 모델은 같은 평판의 매우 작은 변형이다. Arbitrary curved/director, 큰 회전·큰 변형의 외부 정확도, pressure external fresh comparison, modal stress/reaction, 일반 mesh 수렴은 여기서 검증하지 않았다. Synthetic pressure 통과가 외부 pressure coverage를 채우지 않는다.
검토 변경은 이 보고서뿐이다. 계약·허용오차·source·test·output·reference는 수정하지 않았다. 후속 action은 원본 eigen 실패와 S3 계약 충돌의 owner 처리, PE-IMP-01의 기존 recovery 결함 분리 추적이다.
<a id="implementation-feast-residual-review"></a>
<a id="implementation-feast-residual-review--feast-residual-stopping-독립-검토"></a>
## FEAST residual stopping 독립 검토
- Feature: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; 2026-09-10.
- 범위: 사용자 승인 `fpm[5]:1→0`, `[2]=12`, `[3]=20` 유지. S3는 보류 상태를 유지한다.
- 판정: **`PASS` — 승인된 종료 제어 변경**, **`FAIL` — 원본 외부 Value acceptance**.
전체 기능 완료 판정이 아니다.
- 기준: [PRD](PRD.md), [ADR](ADR.md), [E4–E7](formulation-eigen.md),
[C3/C5](numerical-review-controls.md), [I/O](io.md#io-schema), [TOLERANCE](../TOLERANCE.md).
<a id="implementation-feast-residual-review--판단과-필요한-확인"></a>
### 판단과 필요한 확인
| 항목 | 독립 판단 |
| --- | --- |
| 종료 기준 | [Intel C parameter 표](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html)는 `[5]=0` residual, `1` trace이며 double epsilon은 `10^-fpm[2]`임을 명시한다. `1e-12` vendor stopping과 독립 all-c `1e-10`은 서로 다른 metric이다 |
| 불변 수식 | `B=A/s`, `mu=lambda/s`는 무차원이고 `rho_B=norm2(Bx-mu x)/norm2(x)`도 무차원이다. 종료 시점만 바뀌며 K/M, 부호·단위·DOF 순서, 적분, whitening, raw sort, 복구·state commit 식은 그대로다 |
| 전체 c | 요청 N 밖을 포함한 c개 residual과 pairwise/Frobenius Gram 검증 후 첫 N개를 공개해야 한다. FEAST 성공이나 작은 epsout으로 생략할 수 없다 |
| Zero·반복군 | 정확한 zero의 backend residual이 비유한이면 기존 available=false 표현을 유지한다. 독립 zero identity와 nonzero vector·Gram은 검증한다. Residual stopping에서 zero/mixed-zero의 실제 성공 여부는 실행으로 확인해야 하며 trace fallback을 추가하지 않는다. 반복군은 multiplicity·공간·Gram으로 판단하고 개별 벡터 방향의 유일성을 요구하지 않는다 |
| 상태·metadata | `SetControls`를 count/solve마다 재초기화하며 count의 `[49]=1` reset을 다음 solve에 전파하지 않는다. `base_fpm[5]=0,[2]=12,[3]=20`은 실제 새 HDF5에서 확인한다. `epsout`은 기존 trace 변화 진단량이며 residual stopping 지표로 이름·의미를 바꾸지 않는다 |
| 실패·안정성 | Refinement 최대20, bounded interval/capacity retry와 독립 검증 실패 즉시 종료를 유지한다. 새 종료 조건에서도 모든 conditioning의 수렴을 보장하지 않는다. Source의 미수렴/status/budget/allocation 전체 실패 주입 coverage는 기존 미완료 위험으로 남는다 |
검토 source: [backend](../../src/fesa/solvers/eigen/mkl_feast_eigen_solver.cpp),
[기존 backend tests](../../tests/unit/solvers/eigen/mkl_feast_eigen_solver_test.cpp).
추가로 [writer 검증](../../src/fesa/io/hdf5/eigen_hdf5_results_writer.cpp)의 `[5]=0` 제한과
[실제 HDF5 readback·변조 거부 검사](../../tests/unit/io/hdf5/eigen_hdf5_results_writer_test.cpp)를
대조했다. Schema의 field/type/layout 변경 없이 승인된 control 값만 일치시킨다.
본 검토자는 source/tests를 변경하거나 build/test를 중복 실행하지 않고 메인의 실행 로그를 대조했다.
<a id="implementation-feast-residual-review--새-실행-evidence"></a>
### 새 실행 evidence
개인 `.harness/config.json`과 preset의 MSVC x64 Debug·oneMKL 2026.1 설정을 확인했다.
| Evidence 경로 | 확인 결과 |
| --- | --- |
| `.harness/feast-residual-red.log` | 변경 전 backend와 실제 HDF5에서 `[5]=1`을 읽어 새 `[5]=0` 검사 두 개가 실패함 |
| `.harness/feast-residual-focused.log` | 12개 중 11 통과. Backend 10개는 n1/all-zero/mixed-zero/repeated40 prefix/close distinct·Givens/negative/invalid/thread 복원 포함. Writer 한 개는 실제 control readback·trace로 변조한 candidate 거부 포함 |
| 같은 focused log의 원본 reference | Application 성공 후 Value 비교까지 진행했으나 10 singleton 중 9개 실패. 기존 독립 residual 차단과 다른 외부 acceptance 실패이며 전체 검사가 통과한 것은 아님 |
| `.harness/feast-residual-full-run.log` | 구성된 전체 build/test에서 CTest 395개 중 394 통과, 원본 Value reference 한 개 실패, CTest exit8, 실행178.42초. 전체 통과 아님 |
| `.harness/build-ninja-msvc-debug/feast-residual-metrics.json` | `.harness/build-ninja-msvc-debug/extract_feast_residual.py`가 공식 원본 sibling HDF5를 read-only 추출한 값. 스크립트의 실제 dataset·mode_id 대응과 JSON을 대조함 |
원본 새 HDF5에서 `c=22,m0=33,info=0,loop=6`, controls `[2]=12,[3]=20,[5]=0`,
`epsout=2.4227135616446226e-17`을 확인했다. 전체 c개의 최대값은 다음과 같다.
| Metric | 실제 최대값 | 판정 기준 |
| --- | ---: | ---: |
| 독립 rho_B | `1.605467212112365e-13` | `<=1e-10`, PASS |
| Original-free eta_r / whitened eta_w | `9.981033437726324e-15` / `7.315529163435965e-15` | 각각 `<=1e-10`, PASS |
| Gram eta_gram / max_eta_orth | `1.3777964580680282e-15` / `1.6958335496991244e-15` | 각각 `<=1e-10`, PASS |
| Backend res | `8.280018892001454e-13` | vendor 진단량, 독립 rho_B 대체 아님 |
Value 행별 상대오차는 전부 5% 이내지만 Mode2–10의 singleton RMS는 1%를 초과한다.
Mode1은 `0.5648341627%`로 PASS, Mode2–10은 `1.3496440956%`–`4.2613310845%`로 FAIL이다.
양의 singleton은 RMS가 relative error와 같다는 [승인된 family 계약](reference-model.md)을
그대로 적용했다. 행 5%만으로 전체 PASS를 선언하거나 frame을 합쳐 RMS를 완화할 수 없다.
**필요한 후속 correction:** 메인이 이 외부 불일치의 원인·모델 가정을 별도 조사해야 한다.
현재 evidence만으로 질량·stabilization 등 특정 물리 식이 원인이라고 단정할 수 없다.
반복군 검사 통과를 모든 projector·3회 결정론·vendor 실패 주입 coverage 완료로 확장하지 않는다.
<a id="implementation-feast-residual-review--trace-stopping-이력과-잔여-위험"></a>
### Trace stopping 이력과 잔여 위험
[기존 실행 기록](implementation-verification.md)의 trace stopping 실패는
`n=3125,N=10,c=22,m0=33,info=0,loop=4`, raw solver column20의
`rho_B=1.48674481038207483e-10>1e-10`, `epsout=2.82488401287762986e-14`다.
Full/upper action 차이 `1.38724134018909290e-17`은 해당 실패 크기를 설명하지 못한다.
이 관찰은 trace 수렴이 각 vector residual 통과를 보장하지 않는 실제 반례이며,
새 제어의 개선 정도·통과 여부를 선취하지 않는다.
공통 외부 정책은 필요한 row의 누락·추가·중복·비유한을 tolerance 전에 거부하고 승인된
Value family에 적용한다. 독립 modal 허용오차를 외부 reference tolerance로 대체하지 않는다.
S3 정적 계약 충돌과 기존 nonlinear recovery 문제, 27개 case 전체 세부 coverage 미완료는
[기존 독립 검토](implementation-review.md#implementation-numerical-review)의 별도 제한으로 남는다.
<a id="implementation-first-version-review"></a>
<a id="implementation-first-version-review--첫-구현-acceptance-독립-검토"></a>
## 첫 구현 acceptance 독립 검토
- Feature: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; 2026-09-10.
- 판정: **`PASS` — 사용자 승인 첫 구현 범위**. S3와 후속 정확도 개선은 보류 상태다.
- 적용: 사용자 승인 외부 Value 5%, [PRD](PRD.md), [ADR](ADR.md),
[TOLERANCE](../TOLERANCE.md), [reference-model](reference-model.md),
[필수 cases](numerical-review-cases.md), [내부 controls](numerical-review-controls.md).
<a id="implementation-first-version-review--승인-경계와-수치-판단"></a>
### 승인 경계와 수치 판단
원본 Mode1–10은 source `Step-2`의 독립 modal-frame singleton이다. 첫 구현 profile
`mitc4-eigen-first-implementation`은 각 `Value`의 reference-only relative error와 RMS를
각각 .05로 검사한다. 경계 포함이며 family를 합치거나 mode를 평균하지 않는다.
다른 공통 comparison의 RMS .01, missing/extra/duplicate/nonfinite 거부, zero-scale exact-zero,
내부 전체 c개의 residual/Gram `1e-10`은 유지한다.
[종료 제어 검토](implementation-review.md#implementation-feast-residual-review)의 원본 최대 Value 오차
`4.2613310845%`는 승인된 새 5% 범위 안이다. 새 comparator의 실제 focused 실행에서
원본 10개 family가 통과했다. 기존 1% FAIL 기록은 당시 판정으로 보존한다. 수식·DOF·단위·적분·
mass·whitening·복구·state update는 이번 외부 정책으로 바뀌지 않는다.
<a id="implementation-first-version-review--필수-보강과-추가-검증-한계"></a>
### 필수 보강과 추가 검증 한계
| 분류 | 요구·현재 evidence·필요한 보강 |
| --- | --- |
| 확인 — backend 실패 | REQ012/019, C21/C22. Fatal count·optional info1 fallback, final count 불일치·변경 없는 solve 반복 금지, info2의 더 큰 구간 retry, 요청 N 밖 고유벡터의 실제 residual 초과 및 nonfinite/Gram 거부 통과. Production이 사용하는 동일 budget helper의 511/512·363/364, size product·PTRDIFF/container 경계, 실제 count/solve workspace bad_alloc·thread 복원 및 초기 count3회 한계를 검사 |
| 확인 — raw·순위·반복군 | C18/C19/C21. 증가 upper의 감소 count 거부, raw -1e-12와 -1e-9 보존 및 -1e-9 바로 아래 실패 통과. 작은 isolated repeated군을 세 번 실제 FEAST로 풀어 순서·history와 승인된 Frobenius projector/sqrt(2r) metric을 비교 |
| 확인 — mass oracle·단위 | REQ005/014/026, C02/C03/C05. 48개 rational Ck/각 row·first spatial moment, theta×d 부호의 C1 cross-block·C2 rotary block과 두24×24 질량, pairwise Jensen의1/2 및2*C1 항을 대조. Scalar는 m_e(t/2)^k, matrix는 D Frobenius norm합, Jensen 차이는 qMLq+qMCq로 정규화. Proper Q+shift를 geometry/director부터 재계산하여 두 mass의 공변성 통과 |
| 확인 — 공유 node assembly | REQ003/004/007, C06. rho2/t.5와 rho5/t1의 공유 node URX만 free인 patch에서 mass7/64, local K합/m와 modal amplitude²*mass1, element source order 변화의 결과를 확인. Model-level BC로 fixture를 바로잡은 뒤 통과; parser 지원 범위를 넓히지 않음 |
| 확인 — final 보존 | REQ019, C24. Eigen candidate 변조·empty pencil 보존 및 실제 valid HDF5에 Win32 delete-sharing lock을 걸어 close/self-check 뒤 replace 실패·원본 bytes 보존 통과. 공통 AtomicFinalizeValidatedCandidate의 실패 경로와 연결 |
| 확인 — 5% 한정 정책 | C25. ±5% 경계와 바로 밖, zero/nonfinite·identity 거부, common RMS1% 보존, actual profile metadata와 원본 10 family fresh 비교 통과. 아래 focused evidence와 source 대조 |
| 사용자 명시 보류 | S3의 public static moment 충돌. Direct pencil/covariance 검사의 성공과 구별하고 지원 정적 사례의 성공으로 표시하지 않는다 |
| 추가 검증의 한계 | 모든 조건수·geometry injectivity·mesh spectrum 수렴차수·vendor/OS 오류 조합·임의 반복군 방향은 보장하지 않는다. H5Fclose 오류 자체와512회 actual vendor 호출은 미실행이다. CloseChecked 실패는 RequireHdf5→catch/cleanup→replace전 종료를 정적으로 대조했고 budget은 실제 사용 helper의 경계 검사다. 대표 분기 검증을 모든 오류 조합 전수 검사로 확대하지 않는다 |
검토 대상 tests: [mass contract](../../tests/unit/elements/mitc4_shell_mass_contract_test.cpp),
[mass/kernel](../../tests/unit/elements/mitc4_shell_test.cpp),
[공유 node assembly](../../tests/unit/analysis/eigen_mass_assembly_test.cpp),
[reduction](../../tests/unit/analysis/eigen_reduction_test.cpp),
[backend](../../tests/unit/solvers/eigen/mkl_feast_eigen_solver_test.cpp),
[procedure](../../tests/integration/analysis/linear_frequency_procedure_test.cpp),
[writer](../../tests/unit/io/hdf5/eigen_hdf5_results_writer_test.cpp),
[common finalize](../../tests/unit/io/hdf5/hdf5_writer_components_test.cpp).
Source의 guard 존재와 실제 실패 주입 통과를 구분한다. 검토자는 source/tests·상위 계약·reference를
수정하지 않고 메인의 fresh 결과를 대조한다.
<a id="implementation-first-version-review--실행-evidence"></a>
### 실행 evidence
- `.harness/eigen-first-implementation-focused.log`: comparator/policy 10/10 PASS,
원본 실제 해석→HDF5→10개 family 비교 포함. 정책 코드의 공통 Evaluate는 RMS .01을
유지하고 named entry는 blocking singleton `Value`만 허용한다.
- 독립 재계산: [기존 rational coefficient 적분](numerical-review.md#numerical-review-evidence)의 Python을
표준 라이브러리로 새 실행하고 mass test의 48개 rational 상수를 Fraction으로 대조하여
전부 exact 일치를 확인했다. 이종 두 요소 공유 node의 rotary mass도
`2*(1/2)^3/48+5/48=7/64 [M L²]`로 독립 확인했다. 이는 C++ 실행 대체가 아니다.
- `.harness/eigen-first-implementation-coverage.log`: 31개 중30 PASS. Backend24개·writer
통과, C06 fixture의 BC 위치만 실패했다. `.harness/eigen-first-implementation-mass.log`에서
fixture와 정규화 보강 뒤 mass6/6 PASS를 직접 확인했다.
- `.harness/eigen-first-implementation-boundaries.log`: raw negative와 count monotonicity 경계2/2 PASS.
- `.harness/eigen-first-implementation-full-run.log`: MSVC x64 Debug의 configure/build/
discovery/CTest 모두 exit0, **417/417 PASS**, 166.86초. Unit339/integration42/reference36.
같은 build의 `Testing/Temporary/LastTest.log`에서도 Passed417/Failed0와 원본 reference
실행을 직접 확인했다. 과거 C06 실패를 담은 `LastTestsFailed.log`는 최신 판정 근거로 사용하지 않는다.
이번 검토에서 추가 numerical correction은 필요하지 않다. 독립 내부 기준과 새 외부
정책의 실행 연결을 확인했으며, 모든 vendor·OS 실패 조합이나 S3 해결·Abaqus 내부 절차
동등성을 승인한 판정은 아니다. [이전 물리 검토](implementation-review.md#implementation-physics-review)의 기존
nonlinear recovery 제한도 이 변경으로 해소됐다고 주장하지 않는다.
@@ -1,237 +0,0 @@
# MITC4 eigen 구현 및 실행 결과
- Feature: `mitc4-shell-feast-eigen2`; Owner: 메인 assistant; 갱신 2026-09-10 KST.
- 현재 판정: **사용자 승인 첫 구현 범위 PASS**. FEAST 잔차 초과를 해소했고 외부10개 Value가 모드별5% 기준을 충족한다. S3와 후속 정확도 개선은 보류한다.
아래 2026-09-10 결과가 최신이며 2026-09-09 trace 실행은 당시 evidence로 보존한다.
- 기준: [프로젝트 지침](../../AGENTS.md), [PRD](PRD.md), [ADR](ADR.md),
[정식화](formulation.md), [수치 controls](numerical-review-controls.md), [I/O](io.md#io).
- 독립 검토: [수치](implementation-review.md#implementation-numerical-review),
[S3 정적 계약](implementation-review.md#implementation-numerical-review-s3-static),
[물리](implementation-review.md#implementation-physics-review), [FEAST 종료 변경](implementation-review.md#implementation-feast-residual-review), [첫 구현 최종 검토](implementation-review.md#implementation-first-version-review).
## 2026-09-10 첫 구현의 5% 수용과 검증 보강
사용자는 첫 구현의 Abaqus Value 차이를 모드별5%까지 수용하고 정확도 향상과 S3는 후속으로
진행하도록 명시했다. [공통 ADR-029](../ADR.md#adr-029), [Feature ADR-012](ADR.md#mfe2-adr-012--첫-구현의-외부-고유치-5-수용)에 따라
`mitc4-eigen-first-implementation`의 상대오차/RMS를 각각5%로 적용한다. 기존 singleton
identity·공통 사전검사와 내부 all-c1e-10은 유지하며 다른 기능은 기존 RMS1%다.
비교 보고서에는 policy_id와 relative_rms_tolerance를 기록한다. 아래 과거1% 판정은 소급 수정하지 않는다.
| 보강 | 실제 관찰 |
| --- | --- |
| C25 외부 policy | 합성 output의 ±5% 경계와 바로 밖, zero/nonfinite·nonmodal family 거부, 다른 공통 policy RMS1% 보존. 변경 전3%/5% 비교 실패를 확인한 뒤 새 정책으로 통과 |
| C02/03 mass | Warped C0/C1/C2 48개 rational 성분·row·first spatial moment, 24×24 consistent/lumped cross block 및 독립 pairwise Jensen energy. 차원별 scale과 D-congruence Frobenius 사용 |
| C05/06 covariance·assembly | Proper Q+shift 재계산, 서로 다른 rho/t/material 두 요소의 공유 절점 mass7/64·modal normalization·source order 변경 |
| C19/21 backend | Raw tiny-negative/정확한 -tau_zero 보존과 경계 바로 밖 거부, fatal/count 모순·monotonicity·returned mismatch·nonfinite·요청 N 밖의 residual/Gram 실패, certified fallback·변경된 구간 retry |
| C22 budget·storage | Production-used private helper의 511/512·363/364·SIZE_MAX 및 곱/저장 한계, 실제 allocation try 안의 bad_alloc 주입, initial info1의 정확히3회 종료·MKL thread 복원 |
| C24 final 보존 | Eigen writer의 valid final을 Win32 delete-sharing lock으로 보호하여 실제 replacement 실패를 만들고 byte 보존·self-check 확인. 공통 finalizer의 기존 실패 테스트도 유지 |
오류 주입은 `src/fesa/solvers/eigen/`의 private thread-local seam으로만 수행한다.
일반 실행에서는 hook이 없으며 vendor 호출·수치식·control·공개 API를 유지한다. Bounds/storage
helper는 기존 검사를 옮겨 production과 테스트가 같은 조건을 사용한다. 모든 vendor/OS 오류
조합을 실행한 것은 아니며 actual512회 vendor 호출이나 실제 HDF5 close-error 주입은 하지 않았다.
Close 실패는 기존 checked-close→exception→candidate 정리/기존 final 보존 제어 흐름을 정적으로 대조했다.
| 실행 | 결과 |
| --- | --- |
| policy 변경 전 focused | 기존 RMS1% 때문에3% 및 ±5% 사례 실패. `.harness/eigen-first-implementation-red.log` |
| policy/원본 focused | 10/10 PASS, 원본10개 Value 포함. `.harness/eigen-first-implementation-focused.log` |
| coverage 최초 focused | 30/31 PASS. C06 합성 BC 위치만 input 계약 위반으로 실패했고 model-level로 수정 |
| 수정 mass focused | 6/6 PASS. `.harness/eigen-first-implementation-mass.log` |
| 최종 monotonicity/raw 경계 focused | 2/2 PASS. `.harness/eigen-first-implementation-boundaries.log` |
| 구성된 전체 build/test | `python scripts/execute.py` exit0, configure/build/discovery/test 모두 exit0. **417/417 PASS**: unit339·integration42·reference36, 166.86초. `.harness/eigen-first-implementation-full-run.log`, 상세 `.harness/eigen-first-implementation-full-ctest.log` |
최종 전체 실행 후 공식 HDF5를 read-only로 다시 추출했다
(`.harness/eigen-first-implementation-metrics.log`). 원본10개 Value의 최대 상대오차는
`4.261331%`, 전체 c=22 최대 독립 잔차는 `1.605467212112365e-13`으로 아래 residual
실행과 같다. 새 profile의 외부 비교와 내부 `1e-10` 기준을 모두 통과했다. Compiler warning을
추가하지 않았으며 Python Harness suite는 변경 범위가 아니므로 실행하지 않았다.
추가 테스트 작성 중 nested initializer와 lambda capture의 컴파일 오류를 수정한 뒤 MSVC x64
Debug build가 성공했다. 실패한 빌드 뒤 등록되지 않은 테스트의 `No tests were found`를 PASS로
계산하지 않았다. [첫 구현 독립 검토](implementation-review.md#implementation-first-version-review)는 새 oracle와
failure/acceptance evidence·전체 실행을 대조하고 **사용자 승인 첫 구현 범위 PASS**로 판정했다.
임의 모델 정확도나 외부 release를 보장하는 판정은 아니다.
## 2026-09-10 FEAST residual stopping 변경 결과
[ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)의 사용자 승인에 따라 backend의 C-index
`fpm[5]`만 `1→0`으로 변경하고 HDF5 writer의 실제 control 검증도 `0`으로 맞췄다.
`fpm[2]=12`, `[3]=20`, seed/thread/구간/capacity/실패 정책과 모든 독립 tolerance는 유지했다.
S3, K/M·질량 축소·회복 수식, reference artifact는 변경하지 않았다.
새 테스트는 실제 backend snapshot과 저장한 HDF5의 `[5]=0`을 확인하고 trace 값으로
변조한 candidate를 거부하면서 기존 최종 파일을 보존하는지 검사한다. 변경 전 `[5]=1`
때문에 두 검사가 실패한 뒤 최소 source 수정으로 통과했다.
| 실행 | 결과 |
| --- | --- |
| 변경 전 backend/HDF5 focused CTest | 2/2 실패, `[5]=1` 확인. `.harness/feast-residual-red.log` |
| MSVC x64 Debug 3개 test target build | exit0, 새 compiler warning 없음 |
| 변경 후 backend/writer/원본 reference focused CTest | 12개 중 11 통과, exit1. 영·혼합 영·반복·근접 고유값, thread 복원, control readback/변조 거부 통과. 원본은 해석 성공 후 외부 Value 비교에서 실패 |
| `python scripts/execute.py` | build 성공, runner exit1 / CTest exit8. **395개 중 394 통과**, 원본 Value reference 1개 실패. 178.42초; unit320, integration42, reference33 |
| 공식 HDF5 read-only 추출 | 전체 c개 metric과 실제 controls·backend call·10개 Value를 확인. Focused와 full 실행의 modes/vectors/eigenpair_checks/base_fpm dataset bytes 동일 |
전체 실행은 `.harness/feast-residual-full-run.log`, 상세 CTest는
`.harness/feast-residual-full-ctest.log`, focused는 `.harness/feast-residual-focused.log`다.
Read-only 추출 스크립트와 JSON은 최종적으로 ignored build directory에 보관했다.
재현 명령은 `uv run --with h5py python .harness/build-ninja-msvc-debug/extract_feast_residual.py`이며,
그 directory의 `feast-residual-metrics.json`과 `feast-residual-full-metrics.json`이 각 실행의 기록이다.
개인 환경·추출 스크립트·기계 생성 로그/결과는 커밋하지 않는다. 이 작업에서 Python Harness suite는 실행하지 않았다.
원본 결과 HDF5(당시 경로: `../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine_results.h5`, 현재 checkout에 없음)는
이번 실제 해석이 새로 생성한 공식 sibling output이다. 생성과 closed-file self-check는 성공했고,
기존 외부 INP/TXT의 실행 전후 bytes는 reference test에서 보존을 확인했다.
| Metric | 새 결과 |
| --- | ---: |
| 요청 N / 계산 c / m0 | 10 / 22 / 33 |
| Count / solve calls | 25 / 1 |
| FEAST info / loop | 0 / 6 (기존 trace는 4회) |
| 전체 c 최대 rho_B | `1.605467212112365e-13` |
| 최대 original-free eta_r / whitened eta_w | `9.981033437726324e-15` / `7.315529163435965e-15` |
| eta_gram / max_eta_orth | `1.3777964580680282e-15` / `1.6958335496991244e-15` |
| 최대 backend_res | `8.280018892001454e-13` |
| epsout (trace 변화 진단량) | `2.4227135616446226e-17` |
전체 22개는 각각 독립 `1e-10` 기준을 통과한다. 기존 실패 column20의
`rho_B=1.48674481038207483e-10` 대비 같은 column의 잔차가 약926배 감소했다.
기존 trace 진단에서 추출한 첫10개 Value 대비 새 Value의 최대 상대 변화는 약`2.74e-14`다.
따라서 이 개선은 고유쌍의 대수적 잔차 개선이며 외부 reference와의 일치를 보장하지 않는다.
| Mode | FESA Value (표시 반올림) | Abaqus Value | 상대오차 / singleton RMS (%) |
| --- | ---: | ---: | ---: |
| 1 | 218267.149475 | 219507 | 0.564834 |
| 2 | 873571.591115 | 885523 | 1.349644 |
| 3 | 873571.591115 | 885523 | 1.349644 |
| 4 | 1816890.360227 | 1855340 | 2.072377 |
| 5 | 2669030.373076 | 2740230 | 2.598308 |
| 6 | 2703557.194039 | 2775150 | 2.579781 |
| 7 | 4013818.213002 | 4149410 | 3.267737 |
| 8 | 4013818.213002 | 4149410 | 3.267737 |
| 9 | 6446840.913563 | 6733790 | 4.261331 |
| 10 | 6446840.913563 | 6733790 | 4.261331 |
모드별 singleton family와 [공통 tolerance](../TOLERANCE.md)를 그대로 적용했다.
모든 행은 상대오차5% 이내지만 Mode2–10은 RMS1%를 초과하여 blocking FAIL이다.
이는 이전에는 residual 실패 때문에 도달하지 못했던 비교 결과다. 원인은 이번 변경에서
확정하지 않았으며 질량·drilling 정식화나 tolerance를 결과에 맞춰 수정하지 않았다.
독립 수치 검토는 이번 종료 제어 변경을 PASS로 판단했으나 외부 acceptance는 FAIL로 구분했다.
S3의 알려진 실패와 아래 기존 세부 coverage 제한도 남는다.
## 2026-09-09 trace stopping 구현 이력
## 구현된 경로
`DENSITY/FREQUENCY` 입력과 source Step-2/N → 별도 Frequency Domain/step →
27점 consistent moments와 derived nodal lumped mass → 실제 global BC 우선 null/positive
분해 → nodal Cholesky whitening과 sparse congruence → 실제 MKL FEAST → 전체 c개 검증 →
N개 mass-normalized global vectors와 scalar → additive eigen HDF5와 closed-file self-check를 연결했다.
Prepared analysis와 application은 frequency를 독립 procedure/state/writer로 dispatch한다.
초기 drilling scale은 physical rotary 8개 diagonal의 zero를 포함한 평균으로 바꿨다.
기존 nonlinear trial/commit 상태 코드는 변경하지 않았다. 성공·실패 때 source identity를 보존하고,
실패한 solve/validation/candidate로 기존 최종 HDF5를 교체하지 않는다.
TXT comparator는 `Value`만 비교하며 같은 값의 별도 mode ID를 유지한다.
## 실행 evidence
개인 설정의 `mfe-workspace-msvc-ninja-debug` preset, CMake/MSVC x64 Debug,
MKL 2026.1 ILP64를 사용했다. 설치 경로·개인 preset은 커밋하지 않는다.
| 실행 | 결과와 의미 |
| --- | --- |
| `cmake --build --preset mfe-workspace-msvc-ninja-debug --target fesa_unit_tests fesa_integration_tests fesa_reference_tests` | exit 0, `/W4 /WX` 빌드 |
| 초기 `python scripts/execute.py` | exit 1, 392개 중 387 통과·5 실패. 입력 회귀 4개와 원본 eigen 1개 |
| 입력·FEAST·procedure·writer focused CTest | 수정 후 41/41 통과, exit 0. 기존 입력 4개 회귀 포함 |
| 수정된 Householder/count 이후 원본 eigen + FEAST focused CTest | 8/9 통과, 원본 eigen 실패, exit 1 |
| 최종 `python scripts/execute.py` | build exit 0, runner exit 1 / CTest exit 8. **395개 중 394 통과·원본 eigen 1개 실패**, 155.31초. Unit 320개, integration 42개, reference 33개 |
최종 전체 실행 로그는 `.harness/eigen2-full-run.log`, CTest 상세는
`.harness/eigen2-full-ctest.log`에 남긴다. 생성 로그·결과는 source와 함께 커밋하지 않는다.
Test discovery의 CMake 4.4 POST_BUILD 임시 JSON 충돌을 확인해 세 target을 `PRE_TEST`로
변경했다. 초기 392개 CTest name/실행 binary 대응을 실제 `--gtest_list_tests`와 대조했고
누락·중복·다른 binary로의 등록이 없었다. 이후 추가한 3개를 포함한 최종 395개도 같은 방법으로 확인했다.
HDF5의 duplicate model node ID가 self-check를 통과하는 실패를 재현한 뒤 source/model
compound member의 정확한 type/value readback을 추가했다. 수정된 검사에서 같은 변조는 거부됐다.
NaN vector, 불일치 scalar/cluster/constraint, 악화된 residual/rcond/Gram의 candidate 거부와
이전 최종 파일의 byte 보존도 확인했다. 이 검사는 실제 물리 residual 계산을 대신하지 않는다.
## 원본 eigen의 차단 결과
실행한 파일은 [원본 INP](../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp)다.
원본 INP/TXT의 실행 전후 bytes를 비교해 보존했다. 제외된 예제의 원본·복사본·cache는 사용하지 않았다.
| 관찰 | 실제 값 |
| --- | ---: |
| node / element | 729 / 676 |
| full / free / null / finite DOF | 4374 / 3750 / 625 / 3125 |
| 요청 N / 계산 c / m0 | 10 / 22 / 33 |
| 총 backend 호출 / 마지막 solve ordinal | 26 / 25 |
| FEAST info / loop | 0 / 4 |
| 실패 solver column | 20, 즉 계산된 21번째 모드 |
| mu | 4.81673637615627741e-03 |
| full CSR rho_B | 1.48674481038207483e-10 |
| FEAST가 받은 upper 대칭 행렬의 rho_B | 1.48674481542089335e-10 |
| full/upper action 차이 norm | 1.38724134018909290e-17 |
| backend res / epsout | 7.75636151025973760e-10 / 2.82488401287762986e-14 |
`rho_B<=1e-10`은 전체 c개에 적용된다. 요청한 10개 밖의 모드라는 이유로 생략하지 않았다.
초기 Householder의 cancellation을 수정하고 positive R·relative pivot·Gram를 확인한 뒤에도
실패가 재현됐다. 물리 모드 복원 전에 실패하며 upper/full 차이로 설명되지 않는다.
FEAST의 `info=0`이나 trace stopping은 별도 residual 기준 통과가 아니다.
[Intel parameter 설명](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html)에
따르면 현재 고정 `fpm[5]=1`은 trace stopping이며, 이번 4회 종료는 maximum20 소진이 아니다.
따라서 원본 모델의 **성공 HDF5 및 10개 Value의 외부 tolerance 비교는 미완료**다.
기존/복사 결과를 가져와 fresh 통과로 바꾸지 않았고 tolerance·seed·FEAST controls를 바꾸지 않았다.
## 유지 회귀와 남은 검증 범위
Retained shell/shellNL/linear-limit의 fresh 변위 reference, force/moment/free residual,
Newton tangent/objectivity/energy/rollback와 pressure synthetic 검사는 초기 전체 실행에서 통과했다.
수치 비교 통과는 아래 물리 문제를 덮지 않는다.
- **S3 상위 계약 충돌:** direct pencil의 `lambda=10369/450`,
`thetaZ=7500/10369`와 full `Kq-F`의 회전 공변성은 통과했다. 그러나 public static 실행은
drilling에 의한 정확한 미평형 모멘트 때문에 실패한다. 별도 재현 테스트의 성공은 이 실패를
올바르게 검출했다는 뜻이며, 지원 범위의 정적 해석 성공이 아니다.
- **기존 PE-IMP-01:** nonlinear 굽힘 단면력 복구가 stress 적분과 불일치한다.
`t=0.5`에서 약 2배이며 해당 nonlinear source는 HEAD 대비 변경되지 않았다.
물리 보고서에 근거와 기존 구현 owner를 남겼다. 현재 작업에서 별도 수식 수정은 하지 않았다.
- Mass flat/warped scalar oracle, row moments, Jensen energy, m1/2/4 mesh work,
partial-BC complete K/ML, rigid modes, off-diagonal whitening, near-aligned conditioning,
rho×4 및 length×1024 단위 변환, actual FEAST known/zero/repeated/close-Givens spectra는 검사했다.
**27개 case의 모든 세부 관찰을 완료했다고 주장하지 않는다.**
- 특히 E2-C02의 모든 warped Ck 독립 적분, C03 perturbation 전파, C05 rational Q+shift와
full-row-sum mutation, C06 이종 section 공유 node mass assembly, C21/22의 vendor-status/
budget/allocation 실패 주입 전체, C24의 close/replace 실패 주입 전체는 추가 evidence가 필요하다.
## 2026-09-09 당시 후속 제안
현재 요구·정식화·NR·I/O의 수치를 구현 결과에 맞춰 조용히 바꾸지 않는다.
[프로젝트 지침](../../AGENTS.md)의 Physics/지원 범위/acceptance 변경 및 미해결 필수 계약 충돌
경계에 따라 다음 재검토를 제안했다. 당시에는 **미승인 제안**이었으며,
이후 1번의 residual stopping만 ADR-011로 승인·실행했다. 2번 S3는 사용자 요청으로 후속 검토한다.
1. `rho_B<=1e-10`과 전체 c 검증을 유지하면서 FEAST 종료 제어를 재검토한다.
`fpm[5]=0` residual stopping은 검토 후보이며, actual runtime·zero/repeated/endpoint/
실패 controls 검증과 독립 NR 이후 채택 여부를 결정한다. Maximum loop 증가만으로
이번 원인이 해결된다고 가정하지 않는다.
2. S3에서 승인된 drilling 정식화·full residual reaction·공간 평형·부분 global rotation BC를
함께 만족시키는 계약을 formulation/NR로 다시 정리한다. 임의 torque 제거·평균·tolerance
완화 또는 새 unsupported 분류로 성공처럼 처리하지 않는다.
3. 수정 계약이 확정되면 영향받는 mass-null reduction/정적·비선형/eigen 검증과 위 미완료
case들을 완성하고 원본 HDF5→Value 비교 및 전체 검증을 다시 수행한다.
기존 Feature/phase의 사용자 변경 16개는 시작 시 raw Git object hash와 동일했다.
공통 AGENTS/PRD/ADR, reference INP/TXT/CSV와 개인 build 설정은 커밋 범위에서 제외한다.
## Git 기록
- `e74ac24 docs: record eigen2 implementation scope and verification plan`
- `22c9d44 feat: add eigen2 frequency pipeline and fail-closed validation`
구현 commit은 source·test·CMake 39개 파일의 진행분이며 acceptance 완료 commit이 아니다.
이 결과 및 독립 검토 문서는 별도 `docs:` commit으로 보존한다. Push는 수행하지 않았다.
-585
View File
@@ -1,585 +0,0 @@
# MITC4 eigen 입력·결과·mapping 계약
Density/Frequency 입력, authoritative additive HDF5 schema와 identity·실패 lifecycle의 현재 계약이다.
<a id="io"></a>
<a id="io--mitc4-eigen-io-계약"></a>
## MITC4 eigen I/O 계약
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `io-definition-agent`; Contract revision: `r2` (외부 Value acceptance만 변경).
- 입력 baseline: [requirements r1](requirements.md#requirements), [formulation r1](formulation.md).
- 기준: [프로젝트 지침](../../AGENTS.md), [PRD](../PRD.md), [ADR-028](../ADR.md#adr-028),
[ARCHITECTURE](../ARCHITECTURE.md), [Feature ADR](ADR.md).
- 상태: formulation r1과 독립 NR의 `pass-for-io-definition` 및 최종 controls/reference-model을 반영한 I/O 계약 작성 완료. 구현·실행 검증 기록이 아니다.
<a id="io--결정"></a>
### 결정
원본 frequency input의 N과 source step을 보존하며 consistent에서 유도한 lumped mass와
실제 MKL FEAST의 N개 고유쌍을 공식 HDF5로 식별한다. 기존 static schema0/1과 CLI/output
lifecycle는 유지한다. Eigen discriminator·density·modal datasets는 additive다.
N개의 global mass-normalized vectors는 내부 검증을 위해 필수이며 외부 shape gate는 없다.
전체 c개의 내부 validation evidence는 공개 mode N개와 분리한다.
2026-09-10 사용자 명시 5% 승인에 따라 첫 구현 외부 Value 비교에는
`mitc4-eigen-first-implementation` 정책을 적용한다. 같은 identity의 mode별 singleton에서
상대오차와 relative RMS를 모두 5% 이하(inclusive)로 판정한다. 근거는
[공통 TOLERANCE](../TOLERANCE.md)와 [MFE2-ADR-012](ADR.md)이며 I/O가 새 기준을 선택한 것이 아니다.
다른 공통 comparison family의 RMS 1%, 전체 c개 내부 독립 검증 `1e-10`, HDF5 schema는 유지한다.
정확도 개선과 이미 분리한 S3는 후속 과제이며 이 acceptance 변경으로 해결을 주장하지 않는다.
| 상세 문서 | 권위와 내용 |
| --- | --- |
| [io-input](io.md#io-input) | Supported syntax/defaults, source scope, rho/BC mapping, no-op allowlist, fail-closed diagnostics |
| [io-schema](io.md#io-schema) | Authoritative HDF5 types/shapes/units, source step·mode identity, all-c evidence, self-check |
| [io-mapping](io.md#io-mapping) | Domain/AnalysisModel/DOF/state ownership, candidate/failure lifecycle, TXT grammar·prechecks·Value projection |
| [NR controls](numerical-review-controls.md), [reference-model](reference-model.md) | 내부 수치 controls와 외부 modal-frame family; I/O가 tolerance를 선택하지 않음 |
공개 Abaqus convention은 [입력 문서의 공식 출처](io.md#io-input--step와-frequency)를 직접 대조했다.
Lanczos/SIM은 source compatibility 정보이며 실제 algorithm 동등성을 주장하지 않는다.
ACOUSTIC COUPLING=ON은 acoustic-free 모델에서만 적용 대상 없음으로 처리한다.
물리량은 사용자 일관 units이며 SI로 추론하지 않는다. Meaningful unsupported input은 실패한다.
<a id="io--현재-source와의-차이"></a>
### 설계 당시 source와의 차이
2026-09-08 설계 당시 지정 source를 읽기 전용으로 확인한 기록이다. 아래 표는 당시의
미구현 연결을 설명하며 현재 구현 상태를 뜻하지 않는다. 연결 후 실행 결과와 남은 한계는
[구현 검증](implementation-verification.md)을 따른다. 기존 Feature의 pass를 승계하지 않았다.
| 실제 확인 파일 | 확인 결과와 필요한 연결 |
| --- | --- |
| [input_reader](../../src/fesa/io/abaqus/input_reader.cpp) | ASCII/256-byte/continuation/raw fields와 FNV byte identity 재사용; 새 lexical framework 불필요 |
| [domain_mapping_context](../../src/fesa/io/abaqus/domain_mapping_context.cpp) | RawMaterial에 density 없음, RawStep은 static 전용, DENSITY/FREQUENCY 없음. PERTURBATION/ENERGY OUTPUT도 새 eigen subset 필요. FinalizeStep의 hardcoded Step-1 외에 raw source name·N을 보존해야 함 |
| [material mapper](../../src/fesa/io/abaqus/material_property_mapper.cpp), [step mapper](../../src/fesa/io/abaqus/step_definition_mapper.cpp) | Context 위임 경계다. Density/property와 Frequency semantic 확정은 같은 candidate 흐름에 연결 |
| [model writer](../../src/fesa/io/hdf5/hdf5_model_writer.cpp), [primitives](../../src/fesa/io/hdf5/hdf5_primitives.cpp) | 기존 compounds, UTF-8/fixed-width, user-consistent-unspecified, path+content identity 재사용; material compound 수정 대신 별도 densities |
| [linear writer](../../src/fesa/io/hdf5/hdf5_results_writer.cpp), [nonlinear writer](../../src/fesa/io/hdf5/nonlinear_hdf5_results_writer.cpp), [self_check](../../src/fesa/io/hdf5/hdf5_self_check.cpp) | Static0/1 전용 경로를 eigen에 재사용해 modal 값을 static frame0으로 내면 오류. Dedicated eigen serialization/self-check dispatch 필요 |
<a id="io--후속-검증-의무"></a>
### 후속 검증 의무
Requirement prefix는 `FEM-REQ-MITC4-EIGEN2-`다. 아래 검증을 문서 작업 중 실행한 것으로
집계하지 않는다. 수치 기준·oracle는 [NR](numerical-review.md#numerical-review)와 연결된 상세가 권위다.
| ID | 필수 관찰 | Requirement suffix |
| --- | --- | --- |
| IO-T01 | 원본 변경 없이 Step-2/N10/rho2700/t0.5, keyword defaults/no-op warnings·실제 FEAST; S4R source-only 변형 같은 physical path | 001–004,015–016 |
| IO-T02 | 다중 material/section 연결; missing/duplicate/unresolved/0/negative/nonfinite/dependent rho, extra row/field, 잘못된 geometry/section 거부 | 003–004,016 |
| IO-T03 | N blank/0/fraction/overflow, nonblank frequency slots2~7(0 포함), eighth empty slot, duplicate/unknown option, multiple/preload/acoustic/load/nonzero BC 거부 | 001,009,015–016 |
| IO-T04 | Source label/instance/set renumbering·모호함, partial BC·fully constrained·drill-only, 실제 free injection/global 복구; rank cutoff로 tiny positive mass 삭제 금지 | 006–008,014,018 |
| IO-T05 | Additive schema round-trip·source step·units·N/c·mass/backend identity; normalized final phi로 original residual/Gram/energy 재검증; raw negative/zero/positive와 frequency subset | 010–013,017–018 |
| IO-T06 | 실제 FEAST known zero/repeated/cluster/n1/N=n·full capacity, optional abandoned count와 safe fallback, count/reset/budget/index/allocation/Gram/residual 실패; 최종 N과 c 구별 | 008–013,019 |
| IO-T07 | 기존 accepted state/final 준비 후 solve/validation/log/lock/write/flush/close/reopen/self-check/replace failure injection; 기존 final 보존과 최초 실패 final 미생성 | 012,019 |
| IO-T08 | TXT reorder·같은 Value의 다른 mode 허용; missing/extra/duplicate/nonfinite/malformed/step/quantity/unit/mass/backend/schema 오류를 tolerance 전에 거부; Freq 변화는 Value 판정 불변 | 020–021 |
| IO-T09 | Named first-implementation 정책의 singleton row/RMS 5% inclusive 경계·양옆, near-zero와 exact zero-scale; report policy_id/relative_rms_tolerance와 다른 공통 family RMS1% 유지 확인 | 022 |
| IO-T10 | Density 없는 static 입력과 schema0/1 유지, retained shell/shellNL/linear-limit source identity·U/UR/reaction 분류와 fresh 회귀, 제외 예제0건 | 023–025,027 |
| IO-T11 | Consistent→lumped 원본 연결과 같은 mass의 실제 FEAST/검증; mass oracle·inertia/null·coordinate/NR-MFE-001 및 deterministic assembly/row/diagnostic | 005–008,011,013–014,023,026–027 |
<a id="io--최종-대조와-미실행"></a>
### 최종 대조와 미실행
최종 NR의 B=0 enclosure, 초기 count 최대3회·전체 count512/solve3, fixed a0와
optional upper search 종료·certified fallback, normalized final phi metrics를 대조했다.
별도 per-call control 변경 없이 base_fpm 한 개와 count index49 override로 현재 controls를 표현한다.
입력 계약과 additive schema 선택은 이번 요청 안의 정의 작업이다. 기존 static public 호환성
변경은 없다. 새 mode shape 외부 acceptance, CSV mandate, reference 보조 metadata, full matrix
mandatory dump, lower/empty-prefix 검색 schema를 추가하지 않았다.
이 I/O 정의를 작성할 당시 density/Frequency/state/writer 연결은 미구현이었다. Research G01/G02의 installed
FEAST 동작·workspace와 실제 peak memory, retained regression/새 eigen reference 및 physics
검증은 당시 후속 실행 의무였다. 현재 실행·미실행 범위는 [구현 검증](implementation-verification.md)에
기록했다. Safe enclosure fallback이 runtime 확인을 대신하지 않는다.
문서만 수정하므로 build/test/Harness/FEAST/외부 solver를 실행하지 않았다. Source/test/reference와
제외 네 예제의 원본·복사·cache는 수정·검증에 사용하지 않았다.
정적 검사: owned 문서 4개의 UTF-8·Markdown fence·trailing whitespace·상대 파일 링크
41개와 원본 TXT full grammar/finite Value/unique Mode1..10을 Python read-only 검사로 확인했다.
경로 한정 `git diff --check`도 exit0이었다. Untracked 문서는 별도 내용 검사로 확인했으며
diff 검사만으로 검증했다고 하지 않는다. Build/test와 수치 comparison은 미실행이다.
<a id="io-input"></a>
<a id="io-input--mitc4-eigen-입력진단-계약"></a>
## MITC4 eigen 입력·진단 계약
- Feature ID: `mitc4-shell-feast-eigen2`
- Contract revision: `r1`
- 기본 보고서: [io.md](io.md#io)
<a id="io-input--문법과-기존-지원-범위"></a>
### 문법과 기존 지원 범위
기존 [shell 입력](../linear-static-mitc4-shell/io.md#1-abaqus-input-scope)과
[후속 lexical 계약](../shell-surface-pressure-load/io.md)을 유지한다. 현재
[input_reader.cpp](../../src/fesa/io/abaqus/input_reader.cpp)와
[domain_mapping_context.cpp](../../src/fesa/io/abaqus/domain_mapping_context.cpp)를 대조했다.
LF/CRLF, 종결자 제외 physical line 256 ASCII bytes, printable ASCII/tab, blank와 `**`
comment, keyword parameter continuation은 기존 규칙을 따른다. Inline comment, data
continuation, include/substitution/quoted name을 추가하지 않는다. Keyword·parameter·enum·
name lookup은 ASCII case-insensitive이며 raw spelling/physical source line은 보존한다.
Duplicate parameter는 같은 값이어도 실패한다. Comma split은 빈 field를 보존한다.
Eigen model의 순서는 `HEADING? PREPRINT? PART+ ASSEMBLY MATERIAL+ BOUNDARY* STEP EOF`다.
Part 내부 NODE→ELEMENT→sets→SHELL SECTION, assembly의 identity INSTANCE와 explicit-instance
sets, forward section→material lookup은 기존 shell 범위다. `S4`와 `S4R`는 source type만
구별하고 같은 FESA MITC4 kernel에 대응한다. Node/element positive int64 source label,
instance/name scope, element 네 distinct nodes, section 유일 할당, geometry-derived director,
centered finite thickness>0, homogeneous isotropic `E>0,-1<nu<0.5` 검증은 기존 계약 그대로다.
`*SHELL SECTION`의 optional positive integration-point integer는 기존 명시 예외로
warning 없이 읽고 물리 integration을 바꾸지 않는다. 새 mass integration은 formulation 권위다.
Model/history의 허용 keyword는 기존 topology/material의 `HEADING,PART,END PART,NODE,
ELEMENT,NSET,ELSET,SHELL SECTION,ASSEMBLY,END ASSEMBLY,INSTANCE,END INSTANCE,MATERIAL,
ELASTIC,BOUNDARY`와 아래 DENSITY/STEP/FREQUENCY/no-op 목록뿐이다. Assembly ELSET의 기존
`INTERNAL` flag도 보존한다. 기존 static의 load·output 범위를 이 eigen allowlist로 축소하지 않는다.
<a id="io-input--density"></a>
### Density
`*DENSITY`는 current MATERIAL 안에서 parameter 없이 최대 한 번, 정확히 한 data row를
갖는다. `rho` 또는 `rho,`만 허용한다. 뒤의 빈 temperature slot은 constant 값이며 원본
`2700.,`를 그대로 수용한다. Nonempty temperature, 추가 field/comma/row, `DEPENDENCIES=0`을
포함한 모든 parameter와 distribution은 거부한다. ELASTIC과 DENSITY의 상대 순서는 자유다.
새 rho의 C-locale token은 아래 full-match이고 binary64 full conversion을 요구한다.
```text
number := [+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[Ee][+-]?[0-9]+)?
```
Hex/D exponent/locale comma/잘못된 token은 input 오류다. NaN/Inf spelling은 아래 model
nonfinite 진단으로 분류하며 허용 token이 아니다. Overflow/underflow conversion error,
nonfinite, `rho<=0`는 invalid material이다. 모든 활성 `element→section→material→rho`가
정확히 하나로 결정되어야 한다. 누락값·다른 material·global 평균으로 대체하지 않는다.
사용하지 않은 material에 선언된 density도 문법·양성 검증한다. 필수 존재 조건은 활성 material에
적용한다. 단위는 `mass/length^3`, 사용자 일관 단위계이며 자동 SI 추론·변환은 없다.
Density 허용은 새 eigen procedure에 한정한다. 기존 static 입력 지원을 확장하거나 density를
필수화하지 않는다. Procedure 확인 전 raw material을 보존한 뒤 해당 procedure로 검증한다.
<a id="io-input--step와-frequency"></a>
### Step와 Frequency
`*STEP`은 정확히 하나이며 optional `NAME`, `NLGEOM=NO`, value 없는 `PERTURBATION`만
허용한다. Data는 없다. 생략 NLGEOM은 NO, 생략 NAME은 source `Step-1`이다. FREQUENCY가
원형상 무응력 linear perturbation procedure를 결정하므로 PERTURBATION 생략도 같은 의미다.
Raw/canonical name과 flag presence를 보존한다. Storage `Step-1`과 source `Step-2`는 별개다.
`NLGEOM=YES`, INC, 선행/다중 step, 다른 procedure와 step description은 거부한다.
| FREQUENCY parameter | 허용/생략 default | FESA 의미 |
| --- | --- | --- |
| `EIGENSOLVER` | `LANCZOS` / LANCZOS | 실제 MKL FEAST 사용; 항상 `source-eigensolver-mapped-to-feast` warning |
| `SIM` | flag 또는 `YES` / YES | Source option만 보존; 명시되면 `source-sim-option-not-applied` warning |
| `ACOUSTIC COUPLING` | `ON` / ON | Structural-only 모델에서 적용 대상 없음; 명시되면 `acoustic-option-inapplicable-structural-only` warning |
| `NORMALIZATION` | `MASS` / MASS | 실제 derived lumped mass로 normalization |
SIM=NO, DISPLACEMENT normalization, AMS/SUBSPACE/FEAST enum, coupling OFF/PROJECTION,
RESIDUAL MODES, DAMPING PROJECTION, PROPERTY EVALUATION, NSET와 모든 미열거 parameter는
실패한다. Acoustic 요소/ASI/TIE/coupling 정의가 존재하면 ON no-op을 적용하지 않고 실패한다.
FREQUENCY data는 한 physical row, 1~7 comma fields다. 첫 field N은 `[0-9]+`, checked
positive int64이며 나머지 존재하는 fields는 전부 empty여야 한다. Fields 2~7은 source의
minimum/maximum frequency, shift, block size, Lanczos step count, acoustic range factor 자리다.
빈칸은 unspecified이며 숫자0이 아니다. Nonempty0도 실패하고 eighth empty field도 실패한다.
원본 `10, , , , ,`는 6 fields, N=10이다. Bounds/shift/FEAST controls는 사용자 입력 기능으로
추가하지 않는다. `N>finite_dimension`과 빈 finite system은 equation 구성 뒤 model 실패다.
공개 Abaqus convention의 근거는 [FREQUENCY](https://docs.software.vt.edu/abaqusv2025/English/SIMACAEKEYRefMap/simakey-r-frequency.htm),
[DENSITY](https://docs.software.vt.edu/abaqusv2025/English/SIMACAEKEYRefMap/simakey-r-density.htm),
[STEP](https://docs.software.vt.edu/abaqusv2025/English/SIMACAEKEYRefMap/simakey-r-step.htm)이다.
2026-09-08 직접 확인했다. 위 allowlist와 warning은 FESA의 지원 차이이며 Abaqus algorithm·
SIM·parser 내부 구현의 동등성을 주장하지 않는다.
<a id="io-input--homogeneous-bc와-result-neutral-allowlist"></a>
### Homogeneous BC와 result-neutral allowlist
BOUNDARY는 model 또는 FREQUENCY 뒤/output 앞에 parameter 없이
`target,first,last[,value]`로 둔다. `1<=first<=last<=6`; value 생략은 exact0, 명시 value는
finite exact0만 허용한다. 빈 fourth field는 생략으로 보지 않는다. 기존 bare source label 또는
unambiguous node-set resolver와 assembly INSTANCE binding을 사용한다. 새로운 dotted target,
local/tangent BC, MPC를 추가하지 않는다. Model BC→step BC 순서의 zero constraint union이며
같은 zero 재선언은 같은 constraint다. Nonzero를 상쇄·override해서 통과시키지 않는다.
Global DOF는 `UX,UY,UZ,URX,URY,URZ`; partial rotation BC를 그대로 유지한다.
| Keyword | 정확한 조합·위치; 모두 data 없음 |
| --- | --- |
| PREPRINT | Optional top-level, ECHO=NO,MODEL=NO,HISTORY=NO,CONTACT=NO 네 개 |
| RESTART | FREQUENCY/BC 뒤, WRITE flag와 FREQUENCY=0 |
| OUTPUT | FREQUENCY/BC 뒤, FIELD 또는 HISTORY flag 하나, optional VARIABLE=PRESELECT |
| NODE OUTPUT | 활성 OUTPUT FIELD 아래, VARIABLE=PRESELECT |
| ENERGY OUTPUT | 활성 OUTPUT HISTORY 아래, VARIABLE=ALL |
Parameter 순서는 자유이며 duplicate/extra parameter는 실패한다. OUTPUT root/RESTART/END STEP은
이전 output scope를 닫는다. 모든 허용 no-op keyword마다 `ignored-input-keyword` warning과
`mandatory-eigen-output-unchanged` 이유를 기록한다. 선택·억제·restart state를 생성하지 않는다.
Unknown output variable row/child, restart READ/nonzero frequency는 실패한다.
어떤 위치의 CLOAD/DLOAD/DSLOAD(값0 포함), initial state/stress/temperature, damping,
amplitude, acoustic/beam/solid/mixed model, concentrated/nonstructural mass, composite/offset/
variable thickness, contact/MPC/TIE, transform/orientation/explicit director, surface 등 의미 있는
미지원 입력은 fail-closed다. 이름 `shellNL` 또는 `Step-2`에서 preload를 추정하지 않는다.
<a id="io-input--진단"></a>
### 진단
기존 record `severity,code,file,line,keyword,entity_identity,message`와 CLI category를 유지한다.
File은 absolute lexical normalized path, line은 1-based; entity에 source instance/material/
element/node/step와 DOF 또는 field ordinal을 연결한다. Backend 오류도 Frequency 위치를 붙인다.
Warnings는 기존 SortDiagnostics와 same-key discovery order다. Fatal은 첫 원인을 유지하고
후속 solve/commit을 중단한다. 수치값은 round-trip decimal로 보고하며 임의 tolerance를 붙이지 않는다.
| 실패 | Code | Exit |
| --- | --- | --- |
| Lexical/arity/duplicate parameter/unresolved | 해당 기존 code: invalid-input-character, input-line-too-long, invalid-data-arity, duplicate-entity, unresolved-reference 등 | 3 |
| Density scope/malformed data/options/duplicate | invalid-density-data / unsupported-density-option / duplicate-density | 3 |
| Active rho missing / nonfinite·nonpositive·conversion range | missing-material-density / invalid-material-density | 4 |
| Frequency options/count/data | unsupported-frequency-option / invalid-frequency-data | 3 |
| Multiple/preload/other procedure | unsupported-analysis-procedure | 3 |
| Nonzero prescribed BC | unsupported-eigen-boundary | 3 |
| Other unsupported model semantics | unsupported-keyword / unsupported-element-formulation / unsupported-mixed-element-model | 3 |
| Existing geometry/material/section invalid | 기존 model code; 새 mass point 오류 invalid-shell-mass-geometry | 4 |
| Empty finite system / N>n | empty-eigenproblem / insufficient-finite-modes | 4 |
| Mass-space/conditioning/backend/numerical failure | [mapping의 solver diagnostics](io.md#io-mapping--실패와-공개-lifecycle) | 5 |
| Log/candidate/self-check/finalization | 기존 output category | 6 |
Usage2/success0와 stderr escaping은 기존 공통 CLI 계약이다. 지원되는 입력의 conditioning
실패를 input subset 축소나 인공 mass/zero clamp로 우회하지 않는다.
<a id="io-schema"></a>
<a id="io-schema--mitc4-eigen-authoritative-hdf5-schema"></a>
## MITC4 eigen authoritative HDF5 schema
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `io-definition-agent`; Contract revision: `r1`.
- 기본 보고서: [io.md](io.md#io). 수치 원본: [formulation-eigen](formulation-eigen.md),
[NR controls](numerical-review-controls.md).
<a id="io-schema--container와-compatibility"></a>
### Container와 compatibility
공식 결과는 input lexical sibling `<stem>_results.h5`다. Linear schema0와 nonlinear schema1의
기존 dataset/type/필수성/reader 의미를 바꾸지 않는다. 새 eigen discriminator는
`(schema_version=0,feature_id=mitc4-shell-feast-eigen2,analysis_procedure=linear-frequency,
eigen_schema_version=1)`이다. 이는 공통 shell model container에 대한 additive procedure다.
Reader는 schema_version만 보고 static으로 해석하지 않는다. Unknown procedure/version 또는
eigen 필수 field 누락은 명시적 unsupported/invalid schema다. Static 파일에 새 eigen fields를
요구하거나 migration하지 않는다. Unknown optional additive fields만 무시할 수 있다.
File scalar는 f64=`H5T_IEEE_F64LE`, u64/u8/i64는 해당 fixed-width little-endian integer,
string은 variable-length UTF-8다. Compound byte padding/offset은 private이며 field name/type/
array extent가 계약이다. 차원 product는 allocation 전에 checked integer다. 아래 nn/ne/nmat는
model node/element/material 수, N은 input 요청, n은 finite dimension, c는 최종 전체 검증 수다.
<a id="io-schema--metadata와-model"></a>
### Metadata와 model
`/metadata` 필수 attributes:
| 이름 | Type / 값 |
| --- | --- |
| schema_version, eigen_schema_version | u64 0,1 |
| feature_id, analysis_procedure | utf8 mitc4-shell-feast-eigen2, linear-frequency |
| solver_version | utf8 실제 binary version |
| source_input_identity | utf8 기존 `path=<absolute lexical generic path>;content_identity=fnv1a64:<16 lower hex>`; 실제 읽은 원본 bytes |
| unit_system_label | utf8 user-consistent-unspecified |
| coordinate_convention | utf8 global-cartesian; shell-local=initial-reference; positive-thickness=+zeta |
| internal_formulation | utf8 FESA-MITC4 |
| integration_rule, mass_integration_rule | utf8 2x2x2-gauss; mitc4-edge-midpoint-shear / 3x3x3-gauss |
| stabilization_rule | utf8 initial-physical-rotary-trace-mean |
| mass_variant, mass_origin, normalization | utf8 derived-lumped, consistent-moment-row-sum, mass |
| eigensolver_backend, eigensolver_routine | utf8 MKL FEAST, dfeast_scsrgv |
| backend_problem | utf8 scaled-whitened-lumped-with-identity-mass |
| numerical_contract | utf8 mitc4-shell-feast-eigen2:r1 |
Model compounds의 기존 physical field는 수정하지 않고 아래처럼 재사용한다.
| Dataset | Shape / fields | 의미 |
| --- | --- | --- |
| /model/nodes | [nn] internal_node_id:u64,instance_name:utf8,source_label:utf8,coordinates:f64[3] | ID 0..nn-1, 기존 expansion/declaration order, global length |
| /model/elements | [ne] internal_element_id:u64,instance_name:utf8,source_label:utf8,source_element_type:utf8,internal_formulation:utf8,node_internal_ids:u64[4],shell_section_internal_id:u64,material_internal_id:u64 | ID order; S4/S4R 원형 유지; 모두 FESA-MITC4 |
| /model/shell/materials | [nmat] internal_material_id:u64,name:utf8,E:f64,nu:f64 | 기존 declaration order; E force/length^2, nu1; rho를 compound에 삽입하지 않음 |
| /model/shell/sections | [section_count] internal_section_id:u64,source_file:utf8,source_line:u64,source_elset:utf8,material_internal_id:u64,thickness:f64 | 기존 centered-single-layer와 thickness length |
| /model/shell/nodal_director | [nn,3] f64 | 기존 global unit director D1,D2,D3 |
| /model/shell/nodal_frame | [nn,3,3] f64 | 기존 A,B,D axes×global X,Y,Z, dimension1 |
| /model/nodal_constraint_mask | [nn,6] u8 | UX,UY,UZ,URX,URY,URZ; free0/constrained1 |
| /model/prescribed_displacement | [nn,6] f64 | 같은 component order; 전부 exact0, 기존 length/radian dimensions |
| /model/shell/densities | [density_count] 새 compound material_internal_id:u64,rho:f64,source_file:utf8,source_line:u64 | Material ID ascending, 선언 density마다 한 row; 활성 material 전부 존재, rho>0 mass/length^3 |
| /diagnostics | [diagnostic_count] 기존 severity:utf8,code:utf8,file:utf8,line:u64,keyword:utf8,entity_identity:utf8,message:utf8 | 기존 deterministic order, 성공 파일은 warning만 |
기존 model dataset attrs는 [현재 model writer](../../src/fesa/io/hdf5/hdf5_model_writer.cpp)의
동일 field 의미를 따른다. `/model/shell/densities` attrs는 component_names=rho,
component_unit_dimensions=mass/length^3,coordinate_system=scalar,location=model-material다.
공유 writer의 midsurface_locations/section_positions 추가 저장은 허용하지만 eigen 필수량이 아니다.
`/steps/Step-1`은 storage group이며 아래 attributes가 source/procedure authority다.
Raw name을 HDF5 path에 넣거나 Step-1에서 source name을 역추정하지 않는다.
| Attribute | Type / 의미 |
| --- | --- |
| source_step_name, source_step_name_canonical | utf8 원문/ASCII uppercase; 지정 입력 Step-2/STEP-2 |
| step_source_line, frequency_source_line, frequency_data_line | u64 source 1-based 위치 |
| source_nlgeom, source_perturbation_present | u8 effective0 / flag presence0 또는1 |
| source_eigensolver, source_sim, source_acoustic_coupling, source_normalization | utf8 effective LANCZOS,YES,ON,MASS |
| source_option_presence | u8[4] 위 네 option의 explicit presence 순서 |
| requested_mode_count, returned_mode_count | u64 N,N |
| full_dof_count, free_dof_count, mass_null_dimension, finite_dimension | u64 6nn,nf,nz,n; nf=n+nz |
| validated_eigenpair_count | u64 c; N<=c<=n |
| frame_indexing | utf8 mode-rank-one-based |
별도 raw source-record table이나 duplicate reference provenance 파일은 필수로 만들지 않는다.
Raw keyword/data/blank fields는 Domain의 ParsedInput provenance와 source byte identity로 추적한다.
<a id="io-schema--공개-modal-결과"></a>
### 공개 modal 결과
Prefix `/steps/Step-1/eigen`. 새 result dataset의 공통 attrs는
`eigen_schema_version:u64=1,source_step_name:utf8=<raw>,domain:utf8=mode`와 아래 quantity/
component/dimension/coordinate/location이다. Numeric/physical values는 전부 finite다.
| Dataset | Shape/type | Quantity·identity |
| --- | --- | --- |
| modes | [N] compound mode_id:u64,eigenvalue:f64,classification:u8,cluster_id:u64 | 유일 Value authority; mode_id1..N 순서, quantity=eigenvalue, component_names=Value, component_unit_dimensions=time^-2, coordinate_system=scalar, location=modal-frame |
| frequencies | [Nv] compound mode_id:u64,frequency:f64 | modes 중 raw lambda>=0의 정확한 ID subset, mode order; quantity=cycle-frequency, component_names=Freq, component_unit_dimensions=time^-1, coordinate_system=scalar, location=modal-frame |
| vectors | [N,nn,6] f64 | Modes와 같은 mode axis, model/nodes와 같은 node axis; component_names=UX,UY,UZ,URX,URY,URZ, global-cartesian, nodal-modal-vector |
Vectors는 **mandatory 내부 검증 projection**이다. 병진 dimension `mass^-1/2` 세 개와
회전 `mass^-1/2*length^-1` 세 개를 component_unit_dimensions에 기록한다.
`normalization=mass,mass_variant=derived-lumped,interpretation=normalized-mode-not-response-displacement`
attrs를 둔다. 회전은 initial global infinitesimal rotation이다. Constrained component는 exact0.
Static displacement/reaction/stress/accepted_frames를 modal 결과로 생성하지 않는다.
[NR raw 분류](numerical-review-controls.md)대로 mu=lambda/s의 절댓값<=1e-9는
classification0=near-zero, 나머지 허용 양수는1=positive다. mu<-1e-9는 성공 파일을 만들 수 없다.
Raw lambda는 작은 음수도 보존하며 절댓값/zero clamp하지 않는다. Frequency는 raw lambda>0이면
sqrt(lambda)/(2pi), exact0이면0, 음수에는 row가 없다. Mandatory frequencies dataset은 Nv=0도
허용하며 unavailable_rule=negative-raw-eigenvalue를 기록한다. Finite/range 검사는 NR 기준이며
양수의 frequency underflow-to-zero도 invalid-eigenvalue-result다.
Sort는 paired raw lambda ascending, exact tie는 원 FEAST column order다. Sign은 최대 절댓값
scaled global component(translation/ell,rotation)를 양수로, tie는 model row×DOF 순서다.
Cluster는 전체 c sorted pairs의 NR connected rule로 1부터 부여한 후 N개에 투영한다.
Cluster label은 진단 identity이며 mode average/deduplicate/외부 shape 비교를 유발하지 않는다.
<a id="io-schema--전체-c-검증과-실제-backend-evidence"></a>
### 전체 c 검증과 실제 backend evidence
Prefix `/steps/Step-1/eigen/verification`. Attributes `characteristic_length:f64=ell [length]`,
`operator_scale:f64=s [time^-2]`는 positive finite다. `validation_scope=all-computed-c-columns`,
`eta_gram:f64,max_eta_orth:f64`는 dimension1, c=1이면 latter0이다. Null 검사는
`null_checks_applicable:u8`와 `eta_mz,eta_kz,eta_pz:f64`로 저장한다. nz=0이면 flag0/storage0이며
N/A이지 검증 통과 metric0이 아니다. 모든 metric 식과 limit는 NR controls와 채택 V식이다. 정규화 후 최종 phi에서
modal_mass와 yf를 다시 계산하고 모든 저장 residual/Gram/Rayleigh/energy에 이 값을 사용한다.
| Dataset | Shape / fields |
| --- | --- |
| nodal_reduction | [nn] compound free_count:u8,null_count:u8,positive_count:u8,rcond_available:u8,rcond_inf:f64 |
| eigenpair_checks | [c] compound sorted_rank:u64,solver_column:u64,eigenvalue:f64,modal_mass:f64,rayleigh_quotient:f64,eta_r:f64,eta_w:f64,rho_b:f64,eta_norm:f64,eta_energy:f64,backend_res_available:u8,backend_res:f64 |
두 검증 dataset attrs는 coordinate_system=scalar이며 location은 각각 nodal-mass-reduction,
eigenpair-verification이다. component_names는 표의 f64 fields 순서, component_unit_dimensions는
아래 해당 field 차원 순서다. Nodal counts는 nn source row에 대응하고 합이 nf/nz/n과 일치한다. Positive block 없는 node는
rcond_available0/storage0이다. Sorted_rank1..c, solver_column0-based unique, modes의 첫 N scalar와
exact pairing한다. Eigenvalue/Rayleigh는 time^-2, 나머지는 dimension1이다. Backend relative res가
zero-mode에서 정의되지 않는 경우에만 unavailable0/storage0으로 두고 의미를 명시한다.
Nonzero mode의 nonfinite res 및 모든 mandatory independent metric nonfinite는 실패다.
C개 vectors는 solve/validation 동안 유지한다. Accepted state/HDF5에는 N vectors와 전체 c의
metrics를 남긴다. N vectors로 같은 input의 K/ML를 재조립해 N개의 original-free residual/
normalization을 재현할 수 있다. 전체 c Gram의 실제 검증 evidence는 runtime/test 결과로 남기며
N vectors만으로 c Gram를 재계산했다고 주장하지 않는다. Full matrices의 영속 dump는 요구하지 않는다.
Prefix `/steps/Step-1/eigen/backend` attributes:
`runtime_version:utf8,integer_abi:utf8=LP64|ILP64,thread_count:u64=1,seed:u64`,
`enclosure_lower:f64,enclosure_upper:f64,solve_lower:f64,solve_upper:f64`,
`count_calls:u64,solve_calls:u64,final_solve_ordinal:u64,final_count:u64=c`,
`upper_search_termination:utf8`를 둔다. 마지막 값은 count-target/width-limit/no-midpoint/
optimization-budget/collision-exhausted/optional-status 중 실제 종료 이유다.
Bounds는 dimensionless B-space이며 사용자 frequency interval이 아니다. Seed는 NR 값이다.
| Dataset | Shape / fields | 의미 |
| --- | --- | --- |
| base_fpm | [128] i64 | feastinit 뒤 NR override한 실제 solve control snapshot; defaults 포함. Count는 동일 snapshot에서 C-index49만1, 매 call 재초기화 |
| calls | [Lcalls] compound ordinal:u64,kind:utf8,purpose:utf8,lower:f64,upper:f64,allocated_m0:u64,info:i64,count_available:u8,count:u64,loop_available:u8,loop:u64,epsout_available:u8,epsout:f64,outcome:utf8,decision_reason:utf8 | 실제 chronological 호출, ordinal0-based; kind=count/solve, purpose=total-enclosure/upper-guard/final-count/solve |
Count의 overwritten m0 또는 solve의 returned m을 count에 담고 allocated_m0와 구분한다.
Outcome은 accepted/optional-abandoned/retry이며 NR의 실제 결정에 대응한다. Decision_reason은
accepted 또는 status/count-mismatch/endpoint-separation 등의 결정 원인과 필요한 관측값을
round-trip decimal로 남긴다. 호출 없이 budget/width로 종료한 이유는 upper_search_termination에 둔다.
초기 enclosing 재시도에서만 a0가 확정 전 변경될 수 있고, 성공한 total enclosure 이후 하한은 고정이다. Guard 세 구간은
각각 call row다. 실패·fallback을 삭제하지 않는다. Undefined vendor output은 flag0/storage0으로
두고 읽지 않는다. 성공 count는 count_available1; 성공 solve는 loop/epsout available1이고 finite다.
Calls와 final interval/rank/c를 통해 fixed a0, certified upper/full enclosure fallback, budget,
capacity, returned count의 경로를 재구성할 수 있어야 한다. CLI live log로 이 trace를 옮기지 않는다.
Calls의 f64 component_names는 lower,upper,epsout이고 component_unit_dimensions=1,1,1,
coordinate_system=scalar,location=backend-call이다. Base_fpm은 component_names=fpm,
component_unit_dimensions=1,coordinate_system=none,location=backend-parameter다.
128개 per-call dump 대신 공통 snapshot 한 개와 kind로 실제 controls를 재현한다. 향후 call별
control 차이를 추가하려면 이 표현과 NR 계약을 함께 재검토해야 한다.
<a id="io-schema--closed-candidate-self-check"></a>
### Closed candidate self-check
현재 [self_check](../../src/fesa/io/hdf5/hdf5_self_check.cpp)는 static schema0/1 전용이므로
별도 eigen dispatch/check가 필요하다. Candidate를 닫고 read-only reopen하여 다음을 검증한다.
- Discriminator/metadata/source input bytes·step·요청수, known type/rank/shape/dimension attrs와
model source identity uniqueness/각 reference ID range, density coverage/positivity를 candidate와 대조한다.
- Model mask는0/1, prescribed values exact0, modes inventory 정확히1..N, 오름차순·cluster/classification,
frequencies 정확한 subset, vectors paired axis/finite/constraint zero와 validated candidate 값을 대조한다.
- nf=n+nz 및 nodal count 합, N<=c<=n, c rank/solver-column uniqueness, first-N scalar pairing,
independent metrics finite/NR limits, applicable/available flags를 검사한다. N/A를 pass로 계산하지 않는다.
- Backend routine/ABI/runtime/base controls, actual call ordering/count/bounds/capacity/status/budget와 final
certified interval·c 및 successful all-c validation 연결을 확인한다. Static result paths가 없어야 한다.
- Mandatory row 누락/추가/중복/nonfinite/잘못된 quantity·units·mass는 실패한다. Writer가 sorting,
averaging, 값 수정으로 candidate mismatch를 수리하지 않는다. 모든 handle close 후에만 replace한다.
Self-check는 serialization과 검증된 state의 동일성을 확인한다. 독립 physics/NR 테스트를 대신하거나
저장 metric만으로 실행되지 않은 residual/Gram 계산을 통과로 인정하지 않는다.
<a id="io-mapping"></a>
<a id="io-mapping--mitc4-eigen-내부-mappingreference-projection"></a>
## MITC4 eigen 내부 mapping·reference projection
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `io-definition-agent`; Contract revision: `r2` (외부 Value acceptance만 변경).
- 기본 보고서: [io.md](io.md#io). 수학 원본: [formulation-eigen](formulation-eigen.md).
<a id="io-mapping--내부-소유권과-identity"></a>
### 내부 소유권과 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을 공개한다.
<a id="io-mapping--실패와-공개-lifecycle"></a>
### 실패와 공개 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 한계를 따른다.
<a id="io-mapping--원본-txt-grammar와-prechecks"></a>
### 원본 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하지 않는다.
<a id="io-mapping--family와-보고"></a>
### 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이라고 서로 합치지 않는다. 2026-09-10 사용자 명시 5% 승인과
[MFE2-ADR-012](ADR.md)에 따라 [공통 TOLERANCE](../TOLERANCE.md)의 승인된 한정 정책
`mitc4-eigen-first-implementation`을 이 Feature의 외부 Value 비교에 적용한다.
Reference-only S와 near-zero 분류·row branch는 유지하고 상대오차와 relative RMS의 한계를
각각 `0.05`로 적용한다. 같은 identity의 양수 singleton에서는 두 metric이 모두
`abs(FESA - reference) / abs(reference)`이므로 mode별 5% 이하(inclusive)가 통과 조건이다.
Mode 사이 평균·collapse·재정렬로 실패를 숨기지 않는다. S=0은 exact-zero FESA만 성공하며,
missing/extra/duplicate/nonfinite/schema/identity 오류는 위 prechecks에서 먼저 거부한다.
다른 공통 family의 RMS `0.01`과 전체 c개 내부 독립 검증 `1e-10`은 유지한다.
이는 승인된 첫 구현 acceptance이며 후속 정확도 개선이나 S3 해결의 evidence가 아니다.
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 순서로 남긴다. Comparator report는
`policy_id=mitc4-eigen-first-implementation`과 `relative_rms_tolerance=0.05`를 명시해
공통 RMS 1% 정책과 구별한다. 임의 tolerance를 지정하는 generic policy argument는 노출하지 않는다.
이 report 계약 변경은 HDF5 field·shape·단위·schema version을 변경하지 않는다.
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#requirements)의
retained shell/shellNL/linear-limit portfolio와 기존 source step/frame·U blocking·UR warning-only,
nonlinear reaction review-only 의미를 유지한다. 제외 네 예제는 원본·복사·cache로도 사용하지 않는다.
@@ -1,88 +0,0 @@
# 필수 검증 사례와 요구사항 연결
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; revision `r2` (2026-09-10, E2-C25의 승인된 첫 구현 profile 반영).
- 기본 보고서: [numerical-review](numerical-review.md#numerical-review); 판정 수치: [controls](numerical-review-controls.md).
- 아래는 구현의 필수 관찰이다. 문서 r1 시점의 실제 수학 oracle는 [evidence](numerical-review.md#numerical-review-evidence)이며,
최신 실행·미실행 분류는 [첫 구현 검토](implementation-review.md#implementation-first-version-review)를 따른다.
[이전 case C01–C24](../mitc4-shell-feast-eigen/numerical-review.md#numerical-review-cases)의 synthetic fixture와
독립 oracle를 읽고 새 formulation에 대조해 아래에 채택한다. 숫자·fixture 상세는 그 문서를
참조하되 **이 문서의 새 controls와 아래 예외가 우선**한다. 기존 requirement prefix,
RED 고정 순서·phase/release 절차·test 이름/개수·이전 pass는 채택하지 않는다.
Old C25–C27의 실행·portfolio 지시는 아래 새 정의로 대체한다.
| 새 Case ID | 필수 입력·관찰과 반증 기준 |
| --- | --- |
| E2-C01 | Affine rectangle 4×2, rho3,t1/2: independent C0 matrix, C1=0,C2=t²C0/12, nodal m3,j1/16; full24/physical20, energy·rank·drill null |
| E2-C02 | 이번 rational warped director fixture의 모든 Ck/rows/first moment를 독립 적분. C1 강제0, 2-point mass, flat C2 비례식 mutation 검출. Custom director는 kernel-level이며 새 input 기능 아님 |
| E2-C03 | Consistent 원본 snapshot→row sum→block 연결, C1/C2 perturbation 전파; 직접 nodal energy 및 Jensen pairwise integral. 각 mass의 energy를 따로 검증 |
| E2-C04 | Square [-1,1]², rho=t1, m=1,2,4 mesh, velocity(x,0,0): consistent work4/3, lumping 차8/(3m²), uniform translation work4. 일반 spectrum 수렴차수 약속 아님 |
| E2-C05 | Proper rational Q 및 shift(7,-3,5), geometry/director/frame부터 두 mass 재계산; d=(1,1,1)/sqrt3의 full row-sum 실패 mutation |
| E2-C06 | 공유 node·상이 rho/t/material sections, source labels/order 변화, sequential/parallel의 stable contribution/reduction 및 정확한 scatter |
| E2-C07 | Density missing/duplicate/unresolved/nonpositive/nonfinite/dependent, invalid thickness/material/geometry/27점 평가 실패. Density 없는 static 허용 |
| E2-C08 | NR-MFE-001의 원/회전 geometry부터 complete K/ML 새 계산: kd19/4800,Mff3/50,Kff10369/7500,lambda10369/450. Node1 URZ만 free; min-diagonal mutation은 실패 |
| E2-C09 | 같은 partial BC와 admissible moment(5/3)b, thetaZ7500/10369; 회전 load와 full Kq-F reaction covariance. Pure eZ moment로 대체 금지 |
| E2-C10 | Rotary inventory[0,0,2,4,0,6,0,4]→kd.002; independent tangent changes. Allzero/negative/nonfinite/overflow/underflow 실패; zero 포함 분모8 |
| E2-C11 | Free affine element physical K20 rank14, complete K24 rank18/nullity6, consistent physical mass rank20와 lumped rank5/node. 여섯 rigid fields·positive mass Gram·drill null 분리 |
| E2-C12 | 기존 nonlinear fixture의 frozen initial kd, exact unchanged trial/commit/rollback; objective gamma potential의 1·2차 variation, finite rigid motion, physical 선형극한·recovery 제외 |
| E2-C13 | d축정렬/기울임, full/partial/all-fixed rotations와 drill-only free를 지원 global component BC로 구성. Expected null은 constrained director exact-zero 교집합, tiny nonzero 보존. Global n0/N>n 실패 |
| E2-C14 | d=(2p/(1+p²),0,(1-p²)/(1+p²)), m=j1,h0, URX fixed. p=1/2000와1e-8 모두 analytic rank5; 두 번째 conditioning failure, p0만 exact null1. Rank cutoff mutation 검출 |
| E2-C15 | K[[6,2],[2,4]],Mdiag(2,0)의 lambda5/2,z=-p/2; 단순 삭제3을 거부. Production shell에 Kpz/nonpositiveKzz 위반 주입 후 실패, general dense fallback 추가 안 함 |
| E2-C16 | M[[2,1],[1,2]],K[[6,4],[4,6]]→lambda2,10/3. Whitening/복원/original M normalization; wrong lambda/mass/vector/constraint mutation 검출 |
| E2-C17 | 실제 FEAST: n1 lambda2; [0,0,0,2,5,9] N1/4/6; [1,2,4,8] N1/2/4; n4 allzero N1/4. Production bound search로 lowest N·zero·N=n 확인 |
| E2-C18 | 실제 FEAST n64의 첫40개 lambda1, 나머지2..25, N1/41; [1,1+2^-28,1+2^-27,8] N2와 고정 Givens dense congruence. Repeated group>N, c 전체 Gram, distinct cluster merge 금지 |
| E2-C19 | [-2,0,3],[-1e-12,0,1] raw negative 및 정확한 ±tau_zero 경계. Significant negative 실패, nearzero 분류/raw 보존, 양수화/삭제 금지 |
| E2-C20 | rho×4→M×4,lambda/4,normalized amplitude1/2; 길이×1024,rho/1024³,E/1024,t×1024의 단위변환 lambda 불변. Same physical BC와 baseline s 사용 |
| E2-C21 | Count info1은 certified empty 아님. Optional failed/unknown prefix는 certified enclosure로 fallback, successful nonmonotone count는 실패. Final count/solve mismatch와 invalid/SPD/inner-solver/nonfinite/Gram/residual 등 status 주입은 C5의 retry/즉시실패 분류대로 검사 |
| E2-C22 | 실제 endpoint/cluster probes 및 mock count512/solve3/초기count3 한계, budget 직전 fallback·예약 불충분 실패. n²/nm0/nnz+1/index/byte overflow·allocation 실패. a0 below spectrum은 독립 bound로 검증; empty count 성공을 필수로 기대하지 않음 |
| E2-C23 | 원본 single Step-2/N10/density/blank bounds/normalization, source Lanczos/SIM/acoustic-free 의미; unsupported preload/acoustic/mixed/damping/비영 BC 등의 silent no-op 금지. I/O allowlist로 구체화 |
| E2-C24 | Source renumbering, HDF5 self-check와 final normalized modes/used mass/backend/count evidence; solve/validation/write/close/replace failure의 기존 state/final 보존. 정확한 layout은 I/O |
| E2-C25 | [Reference model](reference-model.md)의 원본 Value 10개, per-modal-frame singleton families·identity/finite 전검사. 승인된 `mitc4-eigen-first-implementation`에서 inclusive row/RMS 각각5%, 바로 밖은 실패; nearzero/zero scale 유지. 다른 공통 family RMS1% 보존; reordered rows/동일값 distinct IDs 허용, missing/extra/duplicate 거부 |
| E2-C26 | Retained shell/shellNL/linear-limit fresh solve·기존 U blocking/UR warning·reaction review-only, density-free static, partial-BC response, Newton tangent/objectivity/force/moment/free residual/energy/rollback·pressure synthetic·기타 기존 회귀 |
| E2-C27 | 향후 구현 시 구성 MSVC x64 Debug 전체 CMake/CTest와 actual FEAST/필수 reference를 한 번 연결. Source identity로 등록/선택/실행/제외를 구분하고 관련 없는 회귀 보존. 고정 과거 test 수 또는 중복 manual/automatic 실행 요구 없음 |
E2-C17/18/22는 mock만으로 충족하지 않는다. E2-C21의 실패 주입은 actual FEAST를
바꾸는 행위가 아니라 adapter 경계 테스트다. Expected eigenvalues로 production bounds를
설정하거나 동일 production 함수를 oracle로 호출하지 않는다. Actual FEAST의 G01/G02
installed probes에는 occupied/empty/endpoint count 반환·flag reset·full m0=n/zero matrix·
workspace/ABI/thread 복원이 포함된다. r1 문서 시점에는 **NOT RUN**이었으며,
이후 실행 여부는 [첫 구현 검토](implementation-review.md#implementation-first-version-review)의 evidence와 구분한다.
E2-C26은 excluded original/copied/cached examples를 절대로 사용하지 않는다.
제외된 혼합 시험에 있던 retained shellNL force/moment balance·free force/moment residual
네 관찰, nonzero constrained resultant 및 shell/linear-limit 원본 보존 관찰은 retained fixture에
따로 연결한다. Pressure external fresh coverage 부재를 내부 synthetic 통과로 대체하지 않는다.
## 27개 requirement coverage
접두사는 `FEM-REQ-MITC4-EIGEN2-`, Case 접두사는 `E2-C`를 생략한다.
| Requirement suffix | Cases |
| --- | --- |
| 001 | 23,25 |
| 002 | 01,08,12,23,26 |
| 003 | 06,07,23 |
| 004 | 01,02,07 |
| 005 | 01,02,03 |
| 006 | 01,03,11,13 |
| 007 | 06,13,27 |
| 008 | 08,13,14,15,16 |
| 009 | 13,17,18,19,22,23 |
| 010 | 17,18,25,27 |
| 011 | 03,16,17,23,25 |
| 012 | 14,19,21,22,24 |
| 013 | 11,16,17,18,21 |
| 014 | 01,02,03,04,05,08,11,20 |
| 015 | 23,25 |
| 016 | 07,21,23 |
| 017 | 24,25 |
| 018 | 06,13,16,24,25 |
| 019 | 21,22,24 |
| 020 | 25,26 |
| 021 | 25 |
| 022 | 25 |
| 023 | 27 |
| 024 | 09,12,26,27 |
| 025 | 27 |
| 026 | 01,02,03,04,05 |
| 027 | 08,09,10,11,12,26 |
@@ -1,124 +0,0 @@
# 내부 수치 기준과 FEAST controls
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; revision `r2` (2026-09-10, C5 종료 제어만 변경).
- 기본 보고서: [numerical-review](numerical-review.md#numerical-review); 수식: [새 formulation](formulation.md).
- IEEE binary64의 내부 검증 계약이며 [외부 TOLERANCE](../TOLERANCE.md)를 변경하지 않는다.
- 아래 `NOT RUN`은 r1 문서 검토 당시의 기록이다. 변경된 C5의 실제 실행 판정은
[종료 제어 구현 검토](implementation-review.md#implementation-feast-residual-review)를 따른다.
## C1–C4, C6, C7의 독립 검토 후 명시 채택
[이전 controls](../mitc4-shell-feast-eigen/numerical-review.md#numerical-review-controls)의 C1, C2-01~14와
nodal rcond 절, C3-01~08와 raw classification, C4, C6의 seed/QR/thread/storage,
C7의 retained static 기준을 전부 읽고 새 M/S/E 식에 대조하여 **수치 정의만 채택**한다.
이것은 과거 판정·runtime·reference pass의 승계가 아니다. 다음 적용 경계가 우선한다.
- E/V/S 식 번호는 [새 formulation](formulation.md)과 그 문서가 명시 채택한
[V1–V5 측정식](../mitc4-shell-feast-eigen/formulation.md#formulation-verification)에 대응한다.
- 이전 C5 전체와 lower/empty-prefix search는 채택하지 않는다. 아래 C5가 완전히 대체한다.
- C6 count `n×n`은 이번의 보수적 allocation 선택이며 Intel의 최소 workspace 의무가 아니다.
Count input capacity `n`, 반환 count, solve capacity `m0`, 요청 `N`은 서로 다른 값이다.
- C7는 `shell`, `shellNL`, linear-limit 및 내부 synthetic 의무에만 적용한다.
이전 문서의 제외 예제·고정 검사 수·고정 workflow는 채택하지 않는다.
- Runtime/ABI/thread의 설치 확인은 **NOT RUN**이며 후속 implementation 의무다.
| 분류 | 채택한 기준과 근거 |
| --- | --- |
| 단위·zero branch | `ell=max active edge length`, `D=diag(ell I3,I3)` congruence 뒤 norm. Finite-first; 분자=분모=0이면 항등식 metric0, 분모0·분자비영이면 failure. Zero vector/nonpositive mass는 실패. Floor/clamp 없음 |
| 대수 C1/C2 | Symmetry·oracle·moment·covariance·null/PZ·Cholesky reconstruction `<=1e-12`; `u=2^-53`, `gamma4096≈4.55e-13`와 기존 linear algebra 기준. 어려운 geometry의 forward accuracy 보장 아님 |
| 질량 C2 | Scalar Ck entry error를 `m_e(t/2)^k`로 나눔; first moment는 `m_e ell`. Strict `mi,ji,ji-hi²/mi>0`; analytic rank와 director constraint exact-zero intersection. Nodal scaled positive block `rcond_inf>=2^-32`; 작으면 failure이며 rank 변경 금지 |
| Modal C3 | Original free residual·whitened residual·`norm(Bx-mu x)/norm(x)`·normalization·pairwise orthogonality·Gram·energy·rigid/scaling `<=1e-10`; FEAST stopping `1e-12`와 별도 독립 후검증 |
| Known spectrum | Error/s `<=1e-10`, known distinct gap 존재 시 error `<=gap/8`; exact repeated subspace projector `<=1e-6`는 isolated known gap `>=1e-3 s`인 검증군에만 적용 |
| Raw 분류 | `mu=lambda/s`, `tau_zero=1e-9`, `tau_cluster=1e-8`; `mu<-tau_zero`는 실패, 양끝 포함 near-zero는 분류만. Raw 부호·값 보존, 작은 양수 mode 삭제 금지, 음수 frequency 생성 금지 |
| 결정론 C4/C6 | Stable raw sort, equal tie는 solver column; connected cluster 평균/merge 금지. Source 최대 scaled component sign·첫 tie. 같은 runtime/thread/input 세 반복의 structure/order exact; repeated vector는 projector 비교 |
| 정적 C7 | Linear symmetry/frame/energy `1e-12`, full residual/equilibrium `1e-10`. Nonlinear directional tangent `1e-6`, zero direction `1e-10`, objectivity `1e-10`, factor-one force/moment balance 각각 `1e-8`; 기존 typed Newton zero/100-iteration/no-cutback 계약 유지 |
C6의 seed `0x4D495443344D4645`, uint64 recurrence
`z=6364136223846793005*z+1442695040888963407 mod 2^64`, column-major
`x=2*(double(z>>11)*2^-53)-1`, nonpivoted Householder QR 및 positive R diagonal을 채택한다.
`m0=n`은 identity. QR relative pivot `<=1e-12`는 실패, post-QR Gram `<=1e-12`다.
Seed 변경으로 통과를 찾지 않는다. oneMKL thread-local 1을 설정하고 모든 exit에서 반환된
이전 설정을 복원한다. 이 반환 의미는 이번 [Intel 원문](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/mkl-set-num-threads-local.html)에서 재확인했다.
## C5. Fixed lower enclosure와 bounded upper search
실제 backend는 `dfeast_scsrgv(B,I)`, `uplo='U'`, sorted duplicate-free 1-based CSR이다.
각 call에 `feastinit` 후 C-index fpm을 다음과 같이 다시 설정한다.
| Index | 값 |
| --- | --- |
| `[0],[1],[2],[3]` | `0,16,12,20` |
| `[4],[5],[13]` | `1,0,0` |
| `[26],[27]` | `1,1` |
| `[49]` | Count `1`, solve `0` |
| `[63]` | `0` |
나머지는 해당 설치의 초기값을 유지·기록한다. 이번 [Intel parameter table](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html)의 허용 contour16,
residual stopping, CSR/SPD checks와 count flag reset을 확인했다. 위 값은 FESA의 고정
제어 선택이며 어떤 matrix에서도 수렴한다는 vendor 보장이 아니다.
2026-09-10 사용자 승인으로 C-index `fpm[5]=1` trace stopping을 `0` residual stopping으로
대체한다. Double precision의 vendor stopping epsilon은 `10^-fpm[2]=1e-12`이며
`fpm[3]=20`을 유지한다. Count/solve 모두 같은 초기 controls를 적용하고 `[49]`만 구분한다.
전체 c개의 독립 `rho_B=||Bx-mu x||2/||x||2<=1e-10`, Gram 및 original-free 복구 검증은
그대로다. Vendor residual의 정규화와 독립 rho_B를 동일시하지 않으며 `info=0`도 독립 검증을
대체하지 않는다. `epsout`은 trace 변화 진단량으로 보존하고 새 residual 오차로 재해석하지 않는다.
기존 trace 실행의 pass/fail·loop·epsout은 당시 controls의 이력이다. Zero/mixed-zero/repeated
및 원본 모델의 새 실행과 미해결 위험은 [종료 제어 구현 검토](implementation-review.md#implementation-feast-residual-review)에
구분한다. S3·물리 정식화·공통 외부 tolerance는 이 결정으로 변경하지 않는다.
Gershgorin off-diagonal absolute row sum은 매 합산 뒤 `nextafter(+infinity)`로 outward
누적하고 diagonal±sum도 바깥 한 ULP를 적용한다. `beta=norm(B,inf)`도 outward로 구한다.
`B=0`의 algorithmic enclosure에서만 beta=1이며 physical mass/λ floor가 아니다.
`ulp(v)`는 양쪽 finite adjacent spacing의 큰 값,
`delta(v)=1e-8 beta+64 ulp(v)`로 고정한다. Finite overflow/underflow로 strict bound를
구성할 수 없으면 failure다. `a0=nextafter(gL-16delta(gL),-inf)`,
`b0=nextafter(gU+16delta(gU),+inf)`로 spectrum을 엄밀히 포함한다.
정확한 B=0은 별도 결정론 branch로 **초기 (a0,b0)=(-1,1)**를 사용하며 위 gL/gU padding
식을 적용하지 않는다. 초기 endpoint 재시도 j=0,1,2에서는 `(-2^j,2^j)`를 사용한다.
이 branch에서도 beta=1의 동일 delta·count/solve·분리·raw 검증을 적용한다.
**하한은 a0로 고정한다.** 바깥 spectral bound가 lower completeness를 증명하므로
empty-prefix count를 의무로 호출하지 않는다. 최초 `(a0,b0)` count는 `info=0,c=n`이어야
한다. 초기 endpoint 재시도는 최초 포함 최대3회이며 `info=1,-5` 또는 성공 count!=n에만
허용한다. Attempt j=0,1,2에서 최초 16delta padding을 `2^j`배로 넓히고 outward 처리한다.
최종 성공 enclosure를 a0,b0로 고정한다. 그 외 status·3회 소진은 failure다.
이 성공 bracket은 항상 fallback 후보로 보존한다.
Upper candidate v의 세 intervals `(a0,v-delta(v))`, `(a0,v)`, `(a0,v+delta(v))`가
strict하고 enclosing 범위 안에 있으며 모두 `info=0`이고 같은 count c이면 guarded endpoint다.
`c>=N`이면 certified upper로 저장하고 더 낮은 v를 탐색한다. `c<N`은 탐색 왼쪽만
갱신하며 최종 a0를 움직이지 않는다. 서로 다른 successful count의 monotonicity 모순은
즉시 failure다. `info=1`은 empty 증명이 아니고 optional search를 종료한다.
Optional 후보의 `info=2,3,-5`도 search를 종료하고 이미 certified bracket을 유지한다.
그 외 invalid/inner-solver/SPD/index/allocation 오류는 즉시 failure다.
| 제어 | 고정 한계·처리 |
| --- | --- |
| Count 전체 | 초기·실패·guard·최종·retry를 모두 포함 최대512 calls |
| Optional upper search | 최대32 midpoint, optimization 최대384 calls; 나머지128은 최종·retry 예약 |
| Collision 후보 | midpoint에서 `0,+1,-1,+2,-2,+4,-4` times delta 순서 최대7; bracket 내부만 |
| Search 종료 | `N<=c<=min(n,2N+8)`, 폭 `<=8delta(mid)`, representable midpoint 없음 또는 optimization budget; 저장한 가장 작은 certified b 사용, 없으면 b0 |
| 최종 count | `(a0,b)` 성공 count=c>=N 재확인; interior b는 세 guard 재확인. b0는 outward bound가 margin 증거이며 outside empty count를 요구하지 않음 |
| Solve capacity | `m0=min(n,max(c+8,ceil(3c/2)))`; c=n이면 n. Overflow 전 exact integer 검사 |
| Solve 횟수 | 최초 포함 최대3, 각 refinement 최대20 |
| Solve retry | `info=1,2,3`, count/returned-m mismatch, endpoint separation failure에만 저장한 더 큰 certified b 선택 후 재count; 최종 b0. `m0=min(n,max(new formula,2*previous m0))` |
| Retry 종료 | 더 큰 certified bracket/증가 capacity 등 바뀐 입력이 없으면 동일 실패 call 반복 금지; 최종 검증·budget 부족이면 failure |
| 즉시 실패 | Nonfinite eigenpair, Gram/residual 실패, 유의한 negative spectrum, invalid/SPD/inner-solver/index/allocation 오류. Mass/seed/backend/threshold 변경 금지 |
Returned `m=c`, 전체 c개 독립 Gram/residual 및 `mu-a0>=delta(a0)`,
`b-mu>=delta(b)`를 검사하고 첫 N개만 공개한다. N번째가 반복군 안이면 전체 c를
검사하되 외부 requested rows는 N개다. Bounds/status/count/m0/m/loops/epsout/최종 ranks와
모든 실패·fallback을 기록한다. 초기 total count=n만으로 floating API의 무오류를 주장하지
않으며 known spectra/runtime probes로 구현을 반증 가능하게 검증한다.
## Storage와 미실행 위험
Count `x[n*n]`, `e[n]`, `res[n]` 보수 storage와 identity initial subspace를 사용한다.
`1<=N<=n<=MKL_INT_MAX`, `nnz+1`, `n+1`, `6*nodes`, `n*m0`, `n*n`, byte product,
container max_size 및 `min(SIZE_MAX,PTRDIFF_MAX)`를 overflow **전** 검사한다.
Global inverse를 만들지 않으며 allocation/shifted factorization 실패는 명시적으로 종료한다.
Count n² scratch는 최소 memory 보장이나 전체 peak memory 추정이 아니다.
[Research G01/G02](research.md#research-evidence)의 installed empty/occupied/endpoint/count reset,
workspace·header/runtime probes는 **NOT RUN**이다. Safe enclosing fallback으로 빈 count 성공이
수학적 전제에서는 제거됐지만 실제 FEAST 실행·메모리·cluster 동작 검증 의무는 남는다.
@@ -1,271 +0,0 @@
# MITC4 eigen 독립 검산과 판정
<a id="numerical-review"></a>
<a id="numerical-review--독립-numerical-review"></a>
## 독립 Numerical Review
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; revision `r1`.
- 입력: [requirements r1](requirements.md#requirements), [evidence](requirements.md#requirements-evidence),
[새 research](research.md#research), [새 formulation r1](formulation.md), [TOLERANCE](../TOLERANCE.md).
- Verdict: **`pass-for-io-definition`**. 새 수학 계약의 확인된 blocking defect 없음.
- 범위: 문서·독립 수학 검산. 구현, FEAST runtime, build/test, reference comparison, Physics/release 통과 판정이 아니다.
<a id="numerical-review--판단과-독립-근거"></a>
### 판단과 독립 근거
새 질량·stabilization·constraint/FEAST 문서를 실제 작성 후 모두 읽었다.
기존 pass를 전제로 삼지 않고 새 요구 27개와 식·실패 경계를 대조했다.
기준 문서는 [프로젝트 지침](../../AGENTS.md), [PRD](../PRD.md),
[ARCHITECTURE](../ARCHITECTURE.md), [ADR-028](../ADR.md#adr-028)이다.
| 검토 | 판단 |
| --- | --- |
| 운동학·부호·DOF·단위 | `[uX,uY,uZ,thetaX,thetaY,thetaZ]`, `S=-[d]cross`, `S theta=theta cross d`의 signs와 mass cross-block transpose 일치. C0/C1/C2 차원 M/ML/ML²; 길이 congruence 후 eigen/residual norm 일관 |
| 적분·consistent mass | `NiNj z^k J` 최대 성분별 차수4로 27점의 degree5 정확성 충분. Positive weights/J에서 Hq=0인 다항식은 모든 nodal u=0, Si theta=0이므로 physical20 positive, drill null4. 독립 rational 적분으로 C1 비영·행합·first moment 재현 |
| Derived lumped | Partition of unity로 scalar moment row-sum과 `integral rho Ni Gi^TGi` 일치. Strict Cauchy–Schwarz로 rank5/node·central tangent inertia 양수. Jensen 차1/2와 kinetic energy 추가1/2 구분. Orbital inertia/모든 spectrum 동일성을 주장하지 않음 |
| 공변 stabilization | Rotary block trace는 independent tangent orthogonal change에 불변. 여덟 항을 모두 평균하며 양의 초기 scale. Geometry/frame부터 재적분한 complete K/ML와 partial-BC static reaction이 공변; NR-MFE-001 새 식에서 해소 |
| 실제 BC·finite spectrum | Free injection을 먼저 적용. Constrained director exact-zero 교집합만 mass null이고 tiny positive는 유지. Shared director와 positive kd로 KZ=Zdiag(kappa), Kpz=0,Kzz>0; partial BC에 남은 stabilization 보존. 일반 Schur 반례5/2 대 삭제3도 정합 |
| Whitening·안정성 | Mp nodal SPD Cholesky와 `A=L^-1KpL^-T`·`phi=DCPL^-T x`는 exact congruence. Null rank와 numerical conditioning 분리, inverse/floor/pseudoinverse 우회 없음 |
| Lowest N·multiplicity | Fixed a0의 outward enclosure가 낮은 spectrum 부재 근거. 성공 total count=n과 guarded upper search·bounded enclosing fallback, final c=count=m와 c 전체 Gram/residual을 조합. Count empty 성공의 비보장성은 필수 수학 전제에서 제거 |
| Recovery·state | 최종 normalized phi에서 gi/yf를 다시 계산한 full original-free residual·Gram·Rayleigh/energy를 검사. Constrained components exact zero; modal reaction/stress를 새 output으로 만들지 않음. 검증 candidate·writer finalize 후 state commit 경계 유지 |
| 비선형 영향 | Initial kd의 Dkd=D²kd=0으로 기존 objective potential의 residual/Hessian 미분을 유지. Nonlinear Hessian SPD나 초기 Dgamma=linear Td를 주장하지 않음. 선형극한·objectivity·회귀·rollback은 후속 실행 의무 |
Fresh 독립 oracle의 재현 코드와 실제 값은 [numerical-review-evidence](numerical-review.md#numerical-review-evidence)에 있다.
NR-MFE-001은 `kd=19/4800`, `Mff=3/50`, `Kff=10369/7500`,
`lambda=10369/450`, 단위 moment `thetaZ=7500/10369`을 확인했다.
Complete K/ML/response/full reaction 공변성 ratio는 모두 `1.8e-16` 미만이다.
곡면 mass rational oracle와 27점 적분 최대 entry 차는 `2.221e-16` 미만이었다.
<a id="numerical-review--고정한-기준과-후속-인계"></a>
### 고정한 기준과 후속 인계
- [내부 controls](numerical-review-controls.md): 검토 후 채택한 기존 C1–C4/C6/C7 수치 정의,
새 fixed-lower C5·finite budgets·seed·conditioning·raw classification. 기존 workflow/제외 portfolio/과거 pass는 미채택.
- [27개 verification cases](numerical-review-cases.md): requirement 27개별 analytical/invariant,
actual FEAST·실패 주입·남는 static coverage. Expected value는 production 재호출로 생성하지 않는다.
- [reference-model](reference-model.md): 원본 TXT의 literal `Frame: Mode i`와 유일한 source
`Step-2`에서 per-modal-frame 10 singleton Value families를 새로 판정했다. 공통 정책 그대로
행5%·RMS1%, 이번 singleton의 실효 각 Value1%; 모두 blocking. 외부 mode shape gate 없음.
I/O는 정확한 입력 allowlist·diagnostic·영속 HDF5 경로 및 source/modal identity를 정의한다.
최소한 used lumped mass/backend, N개 public pair와 전체 c개 검증의 재현 evidence,
raw negative/nearzero와 frequency validity, 실패한 optional optimization·fallback까지의
count/solve history를 의미 손실 없이 연결해야 한다. 데이터 layout은 NR가 선점하지 않는다.
<a id="numerical-review--잔여-위험미실행"></a>
### 잔여 위험·미실행
Research G01/G02의 installed count-empty/endpoint/workspace·ABI probes, n1/N=n/allzero/
repeated/clustered actual FEAST와 shifted sparse factorization memory는 **NOT RUN**이다.
현재 수학 blocker는 아니지만 구현 완료 시 필수다. 넓은 enclosing fallback도 runtime 실패나
O(n²) 메모리 비용을 없애지 않으며 bounded failure와 기존 결과 보존이 필요하다.
얇은 shell·거의 정렬된 partial BC의 positive mass conditioning, 왜곡/곡면 MITC4의
locking·accuracy, 27점 밖 geometry injectivity 및 floating count의 정확성 한계가 남는다.
이 한계를 arbitrary rank cutoff·reference fitting·tolerance 완화로 숨기지 않는다.
남는 shell/shellNL/linear-limit fresh solves와 nonlinear tangent/objectivity·balance는 미실행이다.
제외된 네 예제의 원본·복사·cache를 읽거나 사용하지 않았다. Pressure fresh 외부 coverage 부재를 명시한다.
확인된 수학 correction request는 없다. 구현 owner는 명시 controls/cases를 실제 runtime과
연결하고 I/O owner는 reference/validation projection을 보존해야 한다. Source/tests,
upstream 계약·공통 tolerance·reference artifacts·Git은 수정하지 않았다.
<a id="numerical-review-evidence"></a>
<a id="numerical-review-evidence--독립-수학-검산-evidence"></a>
## 독립 수학 검산 evidence
- Feature ID: `mitc4-shell-feast-eigen2`
- 검토일: `2026-09-08`; 기본 보고서: [numerical-review](numerical-review.md#numerical-review).
- 대상: 새 requirement r1. 아래는 Python 표준 라이브러리만 사용하는 수학 검산이며 C++/FEAST 실행이 아니다.
<a id="numerical-review-evidence--nr-mfe-001의-geometry부터-재계산"></a>
### NR-MFE-001의 geometry부터 재계산
`a=(0,1,0)`, `b=(-4/5,0,3/5)`, `d=(3/5,0,4/5)`이고
`X=[-2a-b,2a-b,2a+b,-2a+b]`, `E=12`, `nu=0`, `rho=t=1`이다.
Node 1 URZ만 free이고 나머지 23 DOF는 fixed다. Z45° 회전은 같은 physical
free subspace를 유지한다. 아래는 [이전 독립 적분](../mitc4-shell-feast-eigen/numerical-review.md#numerical-review-evidence)의
평판 membrane/curvature/MITC edge-work를 검토한 뒤 geometry edge에서 길이·axes·director를
다시 얻도록 구성한 새 실행이다. 기존 수치 출력이나 저장 K를 입력으로 쓰지 않는다.
전역 24×24 physical K를 직접 적분하고 새 director의 least-aligned tangent를 재생성해
여덟 rotary diagonal의 trace mean을 계산한다. 비교 대상 congruence에만 원 K를 회전한다.
Norm에는 ell=4, D=diag(ell I3,I3)를 사용하여 matrix는 D^T A D,
response는 D^-1 q, force/moment residual은 D^T r로 같은 단위를 만든다.
```python
from math import sqrt, fsum
from fractions import Fraction as F
def dot(a,b): return fsum(x*y for x,y in zip(a,b))
def cross(a,b): return (a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0])
def norm(a): return sqrt(dot(a,a))
def unit(a): return tuple(x/norm(a) for x in a)
def sub(a,b): return tuple(x-y for x,y in zip(a,b))
def rz(v): return ((v[0]-v[1])/sqrt(2),(v[0]+v[1])/sqrt(2),v[2])
def action(A,x): return [dot(row,x) for row in A]
def rotate_vector(v): return [x for i in range(0,len(v),3) for x in rz(v[i:i+3])]
def rotate_matrix(A):
left=list(zip(*(rotate_vector(c) for c in zip(*A))))
return [rotate_vector(row) for row in left]
def err(a,b): return norm(sub(a,b))/(norm(a)+norm(b))
D=[4. if i%6<3 else 1. for i in range(24)]
def merr(A,B): return err([D[i]*A[i][j]*D[j] for i in range(24) for j in range(24)],[D[i]*B[i][j]*D[j] for i in range(24) for j in range(24)])
def qerr(a,b): return err([x/s for x,s in zip(a,D)],[x/s for x,s in zip(b,D)])
def rerr(a,b): return err([x*s for x,s in zip(a,D)],[x*s for x,s in zip(b,D)])
def build(X):
edge1=sub(X[1],X[0]); edge2=sub(X[3],X[0])
lx,ly=norm(edge1),norm(edge2); ex,ey=unit(edge1),unit(edge2)
d=unit(cross(ex,ey)); area=lx*ly
K=[[0.]*24 for _ in range(24)]
for xi in [-1/sqrt(3),1/sqrt(3)]:
for eta in [-1/sqrt(3),1/sqrt(3)]:
fields=[]
for sx,sy in [(-1,-1),(1,-1),(1,1),(-1,1)]:
nx=sx*(1+sy*eta)/(2*lx); ny=sy*(1+sx*xi)/(2*ly)
tx=(1+sy*eta)/4; ty=(1+sx*xi)/4
for c in range(3):
fields.append(([nx*ex[c],ny*ey[c],ny*ex[c]+nx*ey[c]],[0,0,0],[nx*d[c],ny*d[c]]))
for c in range(3):
fields.append(([0,0,0],[nx*ey[c],-ny*ex[c],ny*ey[c]-nx*ex[c]],[tx*ey[c],-ty*ex[c]]))
for i,(mi,bi,si) in enumerate(fields):
for j,(mj,bj,sj) in enumerate(fields):
K[i][j]+=area/4*(12*mi[0]*mj[0]+12*mi[1]*mj[1]+6*mi[2]*mj[2]+bi[0]*bj[0]+bi[1]*bj[1]+.5*bi[2]*bj[2]+5*dot(si,sj))
axis=min(range(3),key=lambda k:(abs(d[k]),k))
ta=unit(tuple(float(c==axis)-d[axis]*d[c] for c in range(3)))
tb=cross(d,ta); diag=[]
for i in range(4):
for tangent in [ta,tb]:
v=[0.]*24; v[6*i+3:6*i+6]=tangent
diag.append(dot(v,action(K,v)))
kd=fsum(diag)/8000
M=[[0.]*24 for _ in range(24)]
for i in range(4):
for a in range(3):
M[6*i+a][6*i+a]=area/4
for b in range(3):
K[6*i+3+a][6*i+3+b]+=kd*d[a]*d[b]
M[6*i+3+a][6*i+3+b]=area/48*(float(a==b)-d[a]*d[b])
return K,M,kd,d,ey,diag
a=(0.,1.,0.); b=(-.8,0.,.6)
X=[tuple(s*a[k]+t*b[k] for k in range(3)) for s,t in [(-2,-1),(2,-1),(2,1),(-2,1)]]
K,M,kd,d,ey,diags=build(X)
Kr,Mr,kdr,dr,eyr,diagsr=build([rz(x) for x in X])
load=[0.]*24; load[3:6]=[5*x/3 for x in ey]; lr=rotate_vector(load)
q=[0.]*24; qr=[0.]*24; q[5]=load[5]/K[5][5]; qr[5]=lr[5]/Kr[5][5]
r=sub(action(K,q),load); rr=sub(action(Kr,qr),lr)
targets=[float(F(19,4800)),float(F(10369,7500)),float(F(3,50)),float(F(10369,450)),float(F(7500,10369))]
actual=[kd,K[5][5],M[5][5],K[5][5]/M[5][5],q[5]]
for v,w in zip(actual,targets): assert abs(v-w)/(abs(v)+abs(w))<1e-12
cov=[merr(Kr,rotate_matrix(K)),merr(Mr,rotate_matrix(M)),qerr(qr,rotate_vector(q)),rerr(rr,rotate_vector(r))]
assert max(cov)<1e-12
assert abs(kd-kdr)/(abs(kd)+abs(kdr))<1e-12
assert abs(dot(d,load[3:6]))/norm(load[3:6])<1e-12
for A,v,f,residual in [(K,q,load,r),(Kr,qr,lr,rr)]:
assert abs(residual[5])/(abs(A[5][5]*v[5])+abs(f[5]))<=1e-10
print('partial_bc=',actual)
print('rotated_partial_bc=',[kdr,Kr[5][5],Mr[5][5],Kr[5][5]/Mr[5][5],qr[5]])
print('covariance_K_M_q_reaction=',cov)
print('fresh_rotary_diagonals=',diags,diagsr)
```
<a id="numerical-review-evidence--독립-rational-mass-oracle"></a>
### 독립 rational mass oracle
다음 coefficient-dictionary 적분은 production shape/J/질량 함수를 사용하지 않는다.
이전 문서의 rational fixture 자체는 재사용하지만 모든 계수·행합·first moment를 이번에
다시 적분한다. Kernel-level director fixture이며 input explicit-normal 지원을 추가하지 않는다.
```python
from fractions import Fraction as F
from itertools import permutations, product
from math import sqrt
def const(x): return {(0,0,0):F(x)}
def add(*args):
out={}
for a in args:
for p,c in a.items(): out[p]=out.get(p,F(0))+c
return {p:c for p,c in out.items() if c}
def scale(a,c): return {p:v*c for p,v in a.items() if v*c}
def mul(a,b):
out={}
for p,c in a.items():
for q,d in b.items():
key=tuple(x+y for x,y in zip(p,q));out[key]=out.get(key,F(0))+c*d
return {p:c for p,c in out.items() if c}
def diff(a,k):
out={}
for p,c in a.items():
if p[k]:
q=list(p);q[k]-=1;out[tuple(q)]=c*p[k]
return out
def integ(a): return sum((c*F(8,(p[0]+1)*(p[1]+1)*(p[2]+1)) for p,c in a.items() if all(v%2==0 for v in p)),F(0))
def value(a,x): return sum(float(c)*x[0]**p[0]*x[1]**p[1]*x[2]**p[2] for p,c in a.items())
v=[{tuple(int(k==i) for k in range(3)):F(1)} for i in range(3)]
N=[scale(mul(add(const(1),scale(v[0],sx)),add(const(1),scale(v[1],sy))),F(1,4)) for sx,sy in [(-1,-1),(1,-1),(1,1),(-1,1)]]
X=[(-1,-1,F(1,10)),(1,-1,-F(1,10)),(1,1,F(1,5)),(-1,1,-F(1,10))]
d=[(0,0,1),(F(3,5),0,F(4,5)),(F(2,3),F(1,3),F(2,3)),(0,F(3,5),F(4,5))]
z=scale(v[2],F(1,4));pos=[add(*(mul(N[i],add(const(X[i][c]),scale(z,d[i][c]))) for i in range(4))) for c in range(3)]
J={}
for perm in permutations(range(3)):
inversions=sum(perm[i]>perm[j] for i in range(3) for j in range(i+1,3))
term=const((-1)**inversions)
for c in range(3): term=mul(term,diff(pos[c],perm[c]))
J=add(J,term)
rhoJ=scale(J,F(3));zk=[const(1),z,mul(z,z)]
polys=[[[mul(mul(mul(rhoJ,N[i]),N[j]),zk[k]) for j in range(4)] for i in range(4)] for k in range(3)]
C=[[[integ(p) for p in row] for row in mat] for mat in polys]
rows=[[sum(row,F(0)) for row in mat] for mat in C]
assert [mat[0][0] for mat in C]==[F(17609,28800),F(11003,1440000),F(88177,6912000)]
assert [sum(row,F(0)) for row in rows]==[F(7743,1600),F(739,12000),F(517,5120)]
first=[sum((rows[0][i]*X[i][c]+rows[1][i]*d[i][c] for i in range(4)),F(0)) for c in range(3)]
assert first==[integ(mul(rhoJ,p)) for p in pos]
g=[(-sqrt(3/5),5/9),(0.,8/9),(sqrt(3/5),5/9)]
maxerr=0.;jvals=[]
for q in product(g,repeat=3): jvals.append(value(J,[s[0] for s in q]))
for k,i,j in product(range(3),range(4),range(4)):
approx=sum(value(polys[k][i][j],[s[0] for s in q])*q[0][1]*q[1][1]*q[2][1] for q in product(g,repeat=3))
maxerr=max(maxerr,abs(approx-float(C[k][i][j])))
assert min(jvals)>0 and maxerr<1e-12
central=[rows[2][i]-rows[1][i]**2/rows[0][i] for i in range(4)]
assert min(central)>0
print('mass_C11=',[str(mat[0][0]) for mat in C])
print('mass_rows=',[[str(x) for x in row] for row in rows])
print('mass_first_moment=',[str(x) for x in first])
print('mass_Jrange_Gauss_error_central=',min(jvals),max(jvals),maxerr,float(min(central)))
```
<a id="numerical-review-evidence--이번-실행-결과"></a>
### 이번 실행 결과
2026-09-08 PowerShell here-string에서 이 문서의 두 Python block을 추출하고
`subprocess.run([sys.executable,'-B','-'])`으로 각각 실행했다. Oracle 1/2 exit `0`이다.
| 항목 | 이번 직접 계산 |
| --- | --- |
| `kd`, `Kff`, `Mff` | `0.003958333333333333`, `1.3825333333333332`, `0.05999999999999998` |
| `lambda` 원/회전 | `23.04222222222223` / `23.042222222222208`; exact `10369/450 [T^-2]` |
| 단위 moment의 `thetaZ` 원/회전 | `0.7233098659465717` / `0.7233098659465714`; exact `7500/10369` |
| Complete `K`, `ML`, response, full reaction 공변성 ratio | `1.658e-16`, `7.851e-17`, `1.535e-16`, `1.706e-16` |
| 원/회전 free residual raw | `0`, `-1.1102230246251565e-16`; 기존 scaled `1e-10` 기준 충족 |
| Rational `C0_11,C1_11,C2_11` | `17609/28800`, `11003/1440000`, `88177/6912000` |
| `sum m,sum h,sum j` | `7743/1600`, `739/12000`, `517/5120` |
| Spatial first moment 두 독립식 | Exact equal: `(-79747/360000,-685951/2880000,49651/320000)` |
| 27점 J min/max | `0.1285991922161525` / `0.2701341411171808` |
| Gauss vs rational 최대 entry absolute error | `2.220446049250313e-16` |
| 최소 nodal central inertia | `0.022318161338791092 > 0` |
최초 oracle 1 exit `1`은 회전 후 raw free residual에 잘못 추가한 exact-zero assertion이었다.
반력은 일반 floating arithmetic이며 원 계약은 scaled residual `1e-10`이다.
이를 기존 기준으로 수정하고 raw 값을 보존했다. Exact constrained displacement zero 조건,
정식화 또는 승인 tolerance를 변경한 것이 아니다.
외부 solver, FEAST runtime, build/test, retained static fresh solve 및 HDF5–reference
comparison은 **NOT RUN**이다. 위 항등식의 통과는 구현/reference 통과가 아니다.
최종 정적 Python audit는 owned Markdown 5개, 상대 파일 링크 38개, requirement 27개와
case 27개의 유일·연속 identity, UTF-8/whitespace/final newline을 검사했고 exit `0`이었다.
두 oracle 모두 exit `0`; 이후 norm의 length congruence 명시를 코드에 반영하고 영향받은
첫 oracle를 재실행하여 exit `0` 및 위 최종 scaled ratio를 확인했다. 식·판정 한계는 불변이다.
@@ -1,88 +0,0 @@
# 외부 reference projection과 tolerance 적용
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; revision `r2` (2026-09-10 첫 구현의 외부 Value 5% 승인).
- 기본 보고서: [numerical-review](numerical-review.md#numerical-review); 기준: [requirements](requirements.md#requirements), [TOLERANCE](../TOLERANCE.md).
- 판정: 승인된 비교 계약 갱신. 실제 최신 판정은 [첫 구현 검토](implementation-review.md#implementation-first-version-review)에 기록한다.
## Eigen의 지정 원본과 logical identity
Input은 [shellNL-eigen-meshfine.inp](../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp),
reference는 같은 폴더의 [shellNL-eigen-meshfine eigenvalues.txt](../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine%20eigenvalues.txt)다.
이름·내용·확장자를 보존한다. 공식 FESA 결과는 입력 lexical sibling
`shellNL-eigen-meshfine_results.h5`이며 exact dataset path·metadata는 I/O 소유다.
Actual backend MKL FEAST, actual mass derived nodal block lumped인 결과만 비교한다.
이번 원본 TXT 직접 읽기에서 각 행은 `Frame: Mode i: Value = ... Freq = ... (cycles/time)`였다.
TXT 자체에는 step이 없다. 동일 `.inp`의 **유일한 frequency step `Step-2`**가 step authority이며
필수 count는 해당 `*FREQUENCY`의 N=10이다. Filename의 `shellNL`이나 Step-2라는 이름에서
preload를 추론하지 않는다. Source step이 유일하지 않으면 임의 step 선택으로 비교하지 않는다.
Stable logical row key는 `(reference case, source step name=Step-2, modal frame=Mode i,
mode index=i, logical quantity=eigenvalue, component=Value)`다. Matrix equation index나
행 위치를 identity로 쓰지 않는다. `i=1..10`의 오름차순 결과와 label로 직접 대응한다.
같은 Value를 갖는 다른 mode는 distinct identity다. 표시 precision이 같다는 이유로 exact
multiplicity를 단정하거나 average/deduplicate하지 않는다.
| Modal frame / mode | 원본 Value `[T^-2]` |
| --- | ---: |
| 1 | 219507 |
| 2 | 885523 |
| 3 | 885523 |
| 4 | 1855340 |
| 5 | 2740230 |
| 6 | 2775150 |
| 7 | 4149410 |
| 8 | 4149410 |
| 9 | 6733790 |
| 10 | 6733790 |
## Family의 독립 결정
공통 정책은 같은 model/step/**frame**/logical quantity/차원/좌표/판정 영향만 한 family에
허용한다. 원본은 Mode i 각각을 frame으로 명시하므로 `eigenvalue:Step-2:Mode-i`라는
**10개 singleton family**를 정의한다. 각각 scalar invariant 좌표, 단위 차원 `T^-2`,
component `Value`, `blocking`이다. 모든 mode를 한 frame으로 합치는 것은 원본 frame
의미를 삭제하며 낮은 mode의 scale을 높은 mode로 바꾸므로 채택하지 않는다.
이는 과거 singleton 결론을 자동 승계하거나 결과 오차를 본 뒤 고른 family가 아니다.
2026-09-10 사용자는 “5% 이내면 첫 구현이므로 Abaqus와의 고유치 정확도 향상은 추후에
진행하겠습니다. 구현을 마무리해주세요.”라고 승인했다. [Feature ADR](ADR.md)와
[공통 TOLERANCE의 한정 정책](../TOLERANCE.md)에 따라 `mitc4-eigen-first-implementation`
profile을 이 Feature의 외부 `Value`에만 적용한다.
각 family의 S=abs(reference Value), B=.01S와 행별 relative limit .05는 유지하며
relative RMS limit을 .05로 적용한다. 이번 양의 singleton에서 RMS=relative error이므로
각 Value는 **상대오차 5% 이하(inclusive)**일 때 통과한다. 행 판정과 RMS를 각각 기록하고
profile ID·실제 RMS 한계 .05를 보고한다. Near-zero, zero-reference-scale의 exact-zero,
named failure와 identity/finite 전검사는 공통 문서 그대로다. 다른 Feature·static family의
RMS .01, 이 Feature의 전체 c개 내부 검증 1e-10은 변경하지 않는다.
기존 r1의 singleton RMS1% 실패 기록은 당시 판정으로 보존한다. 이번 승인은 첫 구현의
외부 정확도 기준 변경이며 S3 해결·다른 필수 검증 면제·Abaqus 내부 알고리즘 동등성 승인이 아니다.
Frequency 변환, Freq fitting, mode shapes/변위/회전/stress/reaction은 새 eigen 외부 gate가 아니다.
File/dataset/component/schema 누락, wrong step/frame/quantity/backend/mass variant,
missing/extra/duplicate mode, 비유한 Value 또는 FESA mandatory 수치는 tolerance **전에** 실패한다.
TXT row 재정렬은 허용하되 모든 nonempty 행의 schema를 파싱하고 원본 Value를 수정하지 않는다.
Required scalar Value의 finite 검사를 별도 Freq 비교로 대신하지 않는다. Freq는 schema/의미
확인용이며 수치 acceptance에 넣지 않는다. 모든 family/row/error/scale/RMS/판정의 순서는 결정적이다.
## 남는 static portfolio
아래는 [새 requirements](requirements.md#requirements)의 기존 acceptance 보존이며 eigen family와 섞지 않는다.
| 역할 | 기존 원본과 비교 |
| --- | --- |
| `shell-s4`, `shell-s4-linear-limit` | [shell.inp](../../reference/shell/shell.inp), [shell displacements.csv](../../reference/shell/shell%20displacements.csv); 같은 fresh solve 재사용 가능하나 두 역할 evidence 구분 |
| `shellnl-s4-final` | [shellNL.inp](../../reference/shellNL/shellNL.inp), [shellNL displacements.csv](../../reference/shellNL/shellNL%20displacements.csv); factor-one accepted state |
| Nonlinear local reaction review | [shellNL reactions.csv](../../reference/shellNL/shellNL%20reactions.csv); RF1/2/3, physical spatial RM1/2 source-key·finite·inventory·error 보고는 review-only |
Static U1/U2/U3 global length는 blocking, UR1/UR2/UR3의 기존 fixed-initial global rotation
의미는 warning-only다. 같은 case/step/frame/차원/좌표/impact별 공통 family와 source
instance/node/component identity를 유지한다. Local reaction review는 내부 force/moment
balance·free residual blocking을 대체하지 않으며 RM3/stress를 새 gate로 추가하지 않는다.
제외된 네 예제는 원본·복사·cache·과거 결과로도 재사용하지 않는다. 정확한 제외 목록의
권위는 requirements다. 제외 pressure 예제의 fresh 외부 coverage는 없으며 synthetic
pressure kernel/하중/평형/schema/comparator는 유지한다. 이번 원본 열람은 지정 eigen 두
파일에 한정했고 static 파일은 경로 존재만 확인한다. Solver/reference pass 주장은 없다.
@@ -1,290 +0,0 @@
# MITC4 eigen 요구사항과 근거
<a id="requirements"></a>
<a id="requirements--mitc4-질량행렬feast-eigen-요구사항"></a>
## MITC4 질량행렬·FEAST eigen 요구사항
- Feature ID: `mitc4-shell-feast-eigen2`
- Requirement baseline revision: `r2` (2026-09-10, 사용자 승인에 따른 022 외부 accuracy 기준 변경)
- 상태: 요구사항 기준선 작성. 구현·수치 검증 또는 readiness 통과 기록이 아니다.
기준: [프로젝트 지침](../../AGENTS.md), [프로젝트 PRD](../PRD.md),
[ADR-028](../ADR.md#adr-028), [ARCHITECTURE](../ARCHITECTURE.md),
[TOLERANCE](../TOLERANCE.md). 현재 작업·checklist는 [PRD](PRD.md),
소유권은 [FEATURED_AGENTS](FEATURED_AGENTS.md), 결정은 [ADR](ADR.md)을 따른다.
근거 구분·기존 ID 대응·미결정은 [requirements-evidence](requirements.md#requirements-evidence)에 둔다.
<a id="requirements--범위와-해석-의미"></a>
### 범위와 해석 의미
Consistent mass를 계산하고 그 결과로부터 lumped mass를 유도하며 실제 무감쇠 선형
고유진동 해석은 **derived lumped mass와 MKL FEAST**를 사용한다. 같은 lumped mass를
modal residual·normalization·orthogonality와 외부 고유치 비교의 기준으로 사용한다.
Consistent와 lumped의 모든 속도장 energy 또는 spectrum 동일성은 요구하지 않는다.
원형상·무응력 상태의 단일 `*FREQUENCY`, homogeneous essential constraints와 기존
지원 partial rotation BC를 대상으로 한다. 기존 MITC4의 막·굽힘·횡전단, 단일층 균질
등방성 탄성, centered constant-thickness section, geometry-derived director, source
`S4`/`S4R`, 전역 6 DOF 의미를 유지한다. FESA는 독립 솔버이며 Abaqus 내부 정식화·적분·
stabilization·결과 생성의 동등성을 주장하지 않는다.
좌표 공변적인 numerical drilling stabilization 개선 및 영향받는 선형·비선형 정적/eigen
재검증은 범위에 포함한다. 기존 basis-dependent scale 선정과 그 공식 자체의 검사만
대체 대상이다. 물리 kernel·지원 BC·physical recovery·source identity와 결과 의미는
보존한다. Nonlinear objective drilling potential, 초기 reference에서 scale을 고정하는
lifecycle, 일관 residual/Hessian 의미도 유지한다. 상세 대체 공식은 이 문서에서 채택하지 않는다.
| 물리량 | 단위·좌표·identity 의미 |
| --- | --- |
| `rho`, thickness | mass/length³, length; 양의 유한한 일정 값, 사용자 일관 단위계이며 SI 추론·자동 변환 없음 |
| 병진 질량·회전 관성 | mass, mass·length²; 3 병진과 director 접평면 2 물리 회전, drilling은 물리 관성 없음 |
| 고유치 `lambda` | `omega²`, 1/time², 좌표계 불변 scalar; 원본 `Value`와 직접 비교 |
| 주파수 `f` | 양의 lambda에서 `sqrt(lambda)/(2*pi)`, cycles/time; 의미 확인용 파생량이며 외부 acceptance 대체량 아님 |
| Modal vector | Global physical DOF와 source instance/node/component에 연결; 진폭은 정규화된 모드이며 응답변위가 아님 |
| 결과 identity | Source step·mode와 scalar quantity를 식별; equation index·row 위치·source label을 혼동하지 않음 |
제외: prestress/선행 nonlinear state 전달, 다중 step, initial stress, 새 geometric stiffness
의미, 재료비선형, 감쇠·복소 고유치, 좌굴, 강제진동·시간적분, acoustic coupling, 혼합
beam/solid/shell, concentrated/nonstructural mass, composite/offset/variable thickness,
기존 미지원 shell geometry, residual modes, modal stress/reaction recovery.
별도 frequency interval/shift 사용자 기능, Lanczos/AMS 대체 backend, reference
생성·수정·복원과 외부 배포도 제외한다. Eigen 기능의 밀도 필수 조건을 기존 static에 확대하지 않는다.
<a id="requirements--requirement-verification-matrix"></a>
### Requirement verification matrix
각 행은 하나의 관찰 의무이며 acceptance는 해당 요구와 검증 조건을 충족하는 것이다.
현재 요청은 이 의무를 정의하는 **requirement 단계만** 수행한다. 아래 검증은 후속 솔버
작업의 의도이며 이번에 실행하지 않는다. 구체적인 수식·내부 수치 기준·FEAST controls와
I/O layout은 후속 전문 owner가 필요한 시점에 정의한다. 외부 tolerance는 공통 정책을 따른다.
출처: `U`=[새 Feature ADR](ADR.md)의 기존 명시 사용자 결정 적용,
`R`=[근거 문서](requirements.md#requirements-evidence)의 reference 관찰,
`P`=위 프로젝트 기준, `L`=[기존 shell 요구](../linear-static-mitc4-shell/requirements.md),
`N`=[기존 nonlinear I/O](../nonlinear-static-newton-raphson/io.md)의 공통 경로·실패 의미.
`Formulation`, `NR`, `I/O`, `Implementation`, `Physics`는 전문 책임이며 고정 호출 단계가 아니다.
각 행은 [기존 r3](../mitc4-shell-feast-eigen/requirements.md#requirements)의 같은 번호에 대응한다.
| Requirement ID | Shall statement | 측정 가능한 acceptance / verification method | 출처·후속 owner |
| --- | --- | --- | --- |
| FEM-REQ-MITC4-EIGEN2-001 | 솔버는 선행 상태 없는 원형상 무응력 모델의 단일 무감쇠 선형 고유진동 procedure를 실행해야 한다. | 지정 reference가 한 frequency step으로 선택되고 static/nonlinear preload 경로를 호출하지 않음; procedure 통합 테스트 | U, R, P; Formulation, I/O |
| FEM-REQ-MITC4-EIGEN2-002 | `S4`와 `S4R`는 기존 FESA MITC4 물리 kernel·director·전역 6 DOF 의미를 유지하고 numerical stabilization만 Requirement 027에 따라 개선해야 한다. | Physical contribution·mapping·recovery 의미 보존, source type만 다른 모델은 같은 mass·개선된 stiffness/eigen 경로와 별도 source metadata; 개선 전 전체 K의 수치 동일성을 요구하지 않음 | U, L; Formulation, I/O |
| FEM-REQ-MITC4-EIGEN2-003 | 모든 활성 shell의 밀도는 해당 section이 참조하는 material에서 하나의 finite `rho > 0`로 결정되어야 한다. | 여러 material의 올바른 연결 및 missing/duplicate/unresolved/nonpositive/nonfinite/dependent density 거부; semantic 양성·음성 테스트 | U, R, P; I/O |
| FEM-REQ-MITC4-EIGEN2-004 | 질량 계산은 기존 shell의 유효한 geometry·director와 양의 centered constant thickness를 사용해야 한다. | 기존 geometry/material/section 검증 재사용과 서로 다른 두께·밀도 연결 테스트; 부적합 요소를 질량 zero로 우회하지 않음 | L, P; Formulation, I/O |
| FEM-REQ-MITC4-EIGEN2-005 | 솔버는 MITC4 보간에 일관된 consistent mass를 계산하고 derived lumped mass 계산의 원본으로 제공해야 한다. | 독립 consistent mass/kinetic-energy oracle와 일치하고 같은 geometry/material/section의 consistent 결과가 Requirement 026의 입력임을 확인; 원본을 lumping으로 덮어쓰지 않음 | U, P; Formulation, NR |
| FEM-REQ-MITC4-EIGEN2-006 | 질량은 3개 병진 및 2개 director-tangent 회전의 물리 관성을 포함하고 numerical drilling에 물리 관성을 부여하지 않아야 한다. | Rigid translation의 총질량, 회전 관성·kinetic energy, director-parallel null action을 독립 검사; NR의 scale-aware 기준 | L, P; Formulation, NR |
| FEM-REQ-MITC4-EIGEN2-007 | 질량·강성은 동일한 physical DOF와 constraint 의미로 결정적으로 조립되어야 한다. | Scatter/source order, 대칭 구조, sequential/병렬 reduction 및 constrained motion 검증; 행렬 및 재실행 테스트 | P, L; Formulation, Implementation |
| FEM-REQ-MITC4-EIGEN2-008 | Massless numerical 좌표 처리는 개선된 stabilization과 lumped mass에 실제 global BC를 적용한 원 pencil의 유한 spectrum을 보존하며 FEAST admissibility를 만족해야 한다. | 지원 partial BC를 포함해 축소 전후 spectrum·constraint·원 free DOF residual 검증; 개선 전 K와의 spectrum 동일성 또는 consistent→lumped 동일성을 요구하지 않음. 인공 mass·임의 cutoff·clamp 금지 | U, P, L; Formulation, NR |
| FEM-REQ-MITC4-EIGEN2-009 | Mode-count 요청은 물리 spectrum의 낮은 순서에서 지정 개수의 고유쌍을 계산해야 한다. | Reference는 10개; 작은 독립 spectrum에서 첫 N개·multiplicity·zero rigid-mode case·요청수 초과/빈 물리계의 명시적 실패 확인. 부적합 음수 spectrum을 양수화하지 않음 | U, R; Formulation, NR, I/O |
| FEM-REQ-MITC4-EIGEN2-010 | 고유치 결과는 오름차순의 고유한 mode identity를 가지고 반복 고유값의 multiplicity를 보존해야 한다. | Repeated/clustered spectrum에서 row 수·순위·identity 및 재현성 확인; 같은 eigenvalue 값은 duplicate identity 오류가 아님 | R, P; NR, I/O |
| FEM-REQ-MITC4-EIGEN2-011 | 실제 고유치 계산은 consistent mass에서 유도한 lumped mass를 MKL FEAST에 사용해야 한다. | Consistent→lumped→FEAST 연결과 real adapter의 질량 입력·backend identity 확인; source Lanczos가 backend를 변경하지 않고 consistent나 다른 질량으로 reference에 맞추지 않음 | U; Formulation, Implementation |
| FEM-REQ-MITC4-EIGEN2-012 | FEAST 실패·미수렴·불충분 모드·비유한 eigenpair를 성공 결과로 반영해서는 안 된다. | 각 failure injection에서 안정된 diagnostic과 불완전 result 미공개 확인; bounded termination 테스트 | P; Formulation, I/O, Implementation |
| FEM-REQ-MITC4-EIGEN2-013 | 성공 eigenpair는 FEAST에서 사용한 동일 lumped mass로 modal residual·mass normalization·orthogonality 검증을 통과해야 한다. | 내부 modal vectors로 독립 residual/Gram 검사를 수행하고 잘못된 mass variant·eigenvector·mode pairing을 검출; NR가 내부 기준·scale 정의 | U, P, R; Formulation, NR, Physics |
| FEM-REQ-MITC4-EIGEN2-014 | 두 질량과 개선된 stabilized eigen 해석은 symmetry, kinetic-energy, coordinate invariance, rigid-body 및 density scaling 검증을 통과해야 한다. | 독립 mass oracle·invariants 및 동일 물리 BC를 보존하는 지원 partial-rotation 사례에서 재계산한 complete K와 eigen spectrum의 좌표 검증 필수. NR-MFE-001 반례를 필수 통과 사례로 포함하며 full-free/full-clamp만으로 대체하지 않음; density scaling 및 각 mass 고유 energy oracle 유지; NR가 내부 기준 정의 | U, P, L; Formulation, NR, Physics |
| FEM-REQ-MITC4-EIGEN2-015 | 지정 `.inp`의 `*FREQUENCY` 요청과 부수 옵션은 보존된 입력에서 명시적으로 mapping되어야 한다. | 원본 파일 변경 없이 실행; requested count와 mass normalization 유지; Lanczos/SIM 옵션의 FESA 처리 및 acoustic-free 모델에서 `ACOUSTIC COUPLING=ON`의 무해성/진단을 I/O에 명시 | U, R, P; I/O |
| FEM-REQ-MITC4-EIGEN2-016 | 승인 subset 밖의 모델·절차·옵션은 의미를 삭제하거나 근사해 실행하지 않고 진단해야 한다. | Exclusion inventory의 양성/음성 테스트; acoustic 요소, preload, damping, 비영 prescribed base state, 미지원 frequency fields 등의 silent no-op 없음 | P, R; I/O, Implementation |
| FEM-REQ-MITC4-EIGEN2-017 | 공식 HDF5는 source step·mode identity와 고유치의 물리량·단위·실제 backend·사용 질량 variant를 식별할 수 있어야 한다. | 입력 sibling `<stem>_results.h5`에서 10개 reference 대응 고유치와 선택 질량을 복원; additive schema/self-check 테스트. Mode-vector 영속 projection 필요성·layout은 I/O 소유 | U, P, N; I/O |
| FEM-REQ-MITC4-EIGEN2-018 | 내부 modal vectors는 global physical DOF·source identity와 연결되고 외부 mode-shape acceptance로 사용되지 않아야 한다. | Constraint 복원·source renumbering·mass normalization과 내부 verification evidence 재현; 비교기가 vector reference 파일을 요구하지 않음 | U, P; Formulation, NR, I/O |
| FEM-REQ-MITC4-EIGEN2-019 | State와 final HDF5는 검증된 candidate만 반영하고 제어된 실패에서 기존 유효 결과를 보존해야 한다. | Solve·validation·writer/finalization 실패 후 이전 state/final hash 보존; live log는 기존 `<stem>_log.txt` 독립 lifecycle 유지 | P, N; Formulation, I/O, Implementation |
| FEM-REQ-MITC4-EIGEN2-020 | 새 eigen 외부 검증은 지정 원본 TXT의 `Value`만 derived lumped mass로 계산한 FESA HDF5 고유치와 비교해야 한다. | 같은 지정 `.inp`·TXT, Mode 1~10 포함; mass variant 사후 선택 금지. Eigen `Freq`·변위·회전·stress·reaction·mode shape 외부 gate를 추가하지 않음. 승인된 기존 static 회귀는 별도 Requirement 024의 기존 계약 사용 | U, R; NR, I/O |
| FEM-REQ-MITC4-EIGEN2-021 | 비교기는 required identity의 missing/extra/duplicate/nonfinite와 quantity/schema 오류를 tolerance 전에 거부해야 한다. | 행 재정렬은 같은 mapping, mode label 중복·누락·추가·비유한 `Value`는 실패; 같은 값의 다른 mode는 허용; comparator 음성 테스트 | P, R; NR, I/O, Implementation |
| FEM-REQ-MITC4-EIGEN2-022 | 첫 구현의 외부 고유치 acceptance는 `docs/TOLERANCE.md`의 승인된 `mitc4-eigen-first-implementation` 예외를 적용해야 한다. | 같은 step/modal frame별 singleton Value의 relative/RMS가 각각5% 이하일 때 통과. Scale·zero-scale·identity/finite 사전검사와 보고는 공통 정책 유지. Policy ID와 RMS5%를 명시하며 frequency 대체·reference 보정 금지. 승인 근거는 Feature ADR-012 | U, P; NR, I/O |
| FEM-REQ-MITC4-EIGEN2-023 | 변경 동작은 의미 있는 테스트와 구성된 MSVC x64 Debug CMake/CTest 검증으로 확인해야 한다. | 가능한 버그 재현, 변경 중 관련 검사, 기능 완료 시 전체 build/test와 필수 reference 비교 1회; 새 warning 없음과 실제 FEAST runtime evidence. 아래 제외 예제 사용 0건 및 남은 필수 coverage와 실행 identity 대조; 형식적 RED·수동/자동 중복 실행을 요구하지 않음 | U, P; Implementation |
| FEM-REQ-MITC4-EIGEN2-024 | 기존 선형·비선형 정적해석은 승인된 stabilization 개선 외의 입력·출력·물리 의미를 보존하고 영향받는 correctness·reference 회귀를 통과해야 한다. | 아래 portfolio의 `shell`·`shellNL` 및 linear-limit 역할을 fresh solve로 검증하고 기존 comparison identity·판정 정책 유지; tangent/선형극한/평형·reaction/energy/state 검증. 제외 예제는 복사본·cache로도 재사용하지 않음. 개선 전 bitwise equality를 요구하지 않고 density 없는 기존 정적 모델도 유지 | U, P, L, N; Formulation, NR, Implementation, Physics |
| FEM-REQ-MITC4-EIGEN2-025 | 솔버 기능 완료 판단은 적용 계약과 모든 필수 검증 evidence를 추적하여 내려야 한다. | 각 요구와 독립 numerical review·analytical/invariant·필요한 physics/reference evidence 연결; 필수 실패·미실행·stale를 통과로 집계하지 않음. 사용자 제외·과거 결과·현재 실행 구분; 기존 명시 감사 요청은 아래 범위 경계대로 보존 | U, P; 메인, NR, Physics |
| FEM-REQ-MITC4-EIGEN2-026 | 솔버는 계산된 consistent mass에서 lumped mass를 유도하고 승인된 질량·관성 보존 계약을 검증해야 한다. | 유도 관계·독립 lumping oracle·총 병진 질량 보존, 차원/대칭성/물리 kinetic-energy 비음성, 물리 회전 관성과 drilling nullspace 의미 검사. Lumping 수식·좌표 block 처리·정확한 관성 불변식과 threshold는 Formulation/NR가 고정 | U, P, L; Formulation, NR |
| FEM-REQ-MITC4-EIGEN2-027 | 개선된 numerical drilling stabilization은 같은 물리 모델의 좌표·접평면 기저 선택에 공변적이고 기존 비물리 역할을 유지해야 한다. | 독립 재계산한 stabilization/complete K의 congruence, finite·대칭·양의 numerical stabilization, 물리 rigid modes 보존, physical recovery 제외 및 결정론 검증. Partial BC의 NR-MFE-001과 대응 정적 response를 필수 통과시키며 기존 static의 동일 scale 사용 경로도 정합 검증; 수식·threshold는 Formulation/NR 소유 | U, L; Formulation, NR, Implementation, Physics |
<a id="requirements--지정-reference와-남는-검증-범위"></a>
### 지정 reference와 남는 검증 범위
Eigen input은 `reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp`, 외부 reference는
같은 폴더의 `shellNL-eigen-meshfine eigenvalues.txt`를 그대로 사용한다. 입력의
`*FREQUENCY`가 requested count의 권위이며 현재 `N=10`이다. TXT `Mode 1~10`의 `Value`만
비교한다. 이름 `shellNL`·`Step-2`로 preload를 추정하지 않는다. TXT를 CSV로 변환하거나
canonical 이름·보조 metadata·provenance를 새 readiness 조건으로 요구하지 않는다.
Source의 blank bounds/shift/control fields, Lanczos/SIM 및 acoustic-free 모델 옵션은
최소 subset의 의미와 진단으로 다뤄야 하며 정확한 allowlist는 I/O 책임이다.
| 남는 대상 | 필수 관찰·비교 의미 |
| --- | --- |
| `reference/shell/shell.inp` + `shell displacements.csv` | Linear `shell-s4` 및 `shell-s4-linear-limit` 역할. Source instance/node/component와 해당 static step/frame, global U1/U2/U3 blocking·UR1/UR2/UR3 warning-only. 같은 fresh solve를 사용해도 두 역할의 evidence를 유지 |
| `reference/shellNL/shellNL.inp` + `shellNL displacements.csv` | `shellnl-s4-final`의 factor-one accepted state와 source identity; U blocking·UR warning-only, 기존 좌표 의미 유지 |
| `reference/shellNL/shellNL reactions.csv` | Local RF1/RF2/RF3와 physical spatial RM1/RM2의 source-key·finite·inventory·error 보고는 review-only 유지; RM3/stress를 새 numerical gate로 추가하지 않음 |
| Element·linear static 내부 검사 | Kernel/patch·rigid mode·physical recovery·partition/full residual·reaction·energy·source mapping; 같은 물리 BC/loads를 유지하는 좌표 변환에서 complete K와 partial-BC static response |
| Nonlinear 내부 검사 | 선형극한·tangent consistency·objectivity·factor-one 전역 force/moment balance·free residual·commit/rollback; Newton·convergence·하중·reaction 의미 유지 |
| 새 eigen 내부 검사 | 두 mass의 독립 oracle·질량/관성·drilling null·density scaling·rigid modes, 실제 constraints·finite spectrum·modal residual/Gram·순위/multiplicity·실패 보존; 알려진 `NR-MFE-001` partial-BC 반례를 포함한 좌표 검증 |
| 기타 기존 coverage | Pressure synthetic kernel/하중/평형·schema/comparator 및 무관한 beam 등 회귀 유지. 제외된 복합 시험에 남은 모델 검사가 섞여 있으면 retained fixture/evidence로 해당 관찰을 보존 |
모든 외부 수치 비교는 [TOLERANCE](../TOLERANCE.md)를 적용한다. 회귀는 개선 전 숫자의
bitwise equality가 아니라 승인된 물리·identity·공통 정책으로 판단한다. 내부 평형 acceptance와
reaction의 local distribution 검토는 별개다. 알려진 partial-BC 반례를 full-free/full-clamp
사례만으로 대체하거나 실패 수치를 기대값으로 재생성해 정당화하지 않는다.
<a id="requirements--사용자-제외-예제"></a>
### 사용자 제외 예제
다음 네 예제는 `reference/temp/` 아래 원본뿐 아니라 옛 경로, 복사 input, cached HDF5·log·
추출 결과를 통한 검증에서도 제외한다. 원본 열람·artifact audit·solve·비교·복원 또는
새 fixture로 위장한 재사용을 하지 않는다. 과거 기록은 이력이며 현재 성공 evidence가 아니다.
| 제외 예제 | 제외되는 외부 coverage |
| --- | --- |
| `shellNL-meshfine` | Fine static solve·변위 비교·reaction review |
| `shellNL-meshfine-pressure` | 해당 pressure 예제의 artifact audit·solve·결과 비교 |
| `shellNL-meshfine_02` | 별도 post-closure 예제의 검증 |
| `shellNL-dyn-meshfine` | 해당 예제의 검증 |
`reference/shellNL-eigen-meshfine`는 이 목록에 포함되지 않는다. 제외는 지원 기능과 내부
물리 검증 의무 삭제를 뜻하지 않는다. Pressure 예제에 대한 fresh 외부 coverage 부재는
명시적으로 보고한다. 과거 test 수 `362/352`를 새 완료 조건으로 사용하지 않고 실제 남은
의무·선택·실행·사용자 제외를 구분한다.
<a id="requirements--이번-완료와-후속-판단의-경계"></a>
### 이번 완료와 후속 판단의 경계
이번 완료는 요구·출처·coverage·링크의 정적 확인까지다. 구현/FEAST/build/test/reference,
독립 numerical/physics review와 release-readiness는 미실행이다. 기존 명시 release-readiness
감사 요청은 후속 요구 기록으로 보존하되 이번 요청의 실행 범위나 모든 기능의 고정 단계
의무로 확대하지 않는다. 메인이 필요한 후속 전문 작업과 evidence를 판단한다.
공통 문서·기존 Feature·source·test·reference는 읽기 전용이며 Git은 메인이 소유한다.
<a id="requirements-evidence"></a>
<a id="requirements-evidence--요구사항-근거와-적용-경계"></a>
## 요구사항 근거와 적용 경계
- Feature ID: `mitc4-shell-feast-eigen2`
- Requirement baseline revision: `r1`
- 작성일: `2026-09-08`
- 원본: [requirements.md](requirements.md#requirements), 현재 작업: [PRD](PRD.md).
기준은 [프로젝트 지침](../../AGENTS.md), [프로젝트 PRD](../PRD.md),
[ADR-028](../ADR.md#adr-028), [새 Feature ADR](ADR.md)이다. 이 문서는 근거와 미실행을
구분하며 새 수학·구현 acceptance 승인이나 solver readiness 판정이 아니다.
<a id="requirements-evidence--근거의-종류와-재사용"></a>
### 근거의 종류와 재사용
| 근거 | 재사용하는 내용 | 이번 기준선으로 가져오지 않는 것 |
| --- | --- | --- |
| 2026-09-08 사용자 요청과 [새 PRD](PRD.md) | 새 Feature 이름, requirement부터 재시작, 유용한 기존 자료 참고, 작업 중 commit; 최종 지시로 requirement 단계만 수행 | Research 이후 실행 권한·전체 단계 자동 진행·push 권한 |
| [기존 ADR](../mitc4-shell-feast-eigen/ADR.md)의 MFE-ADR-001/002/004/005 | MKL FEAST, consistent→derived lumped→eigen, 지정 reference의 Value-only, 입력의 mode count 권위 | Mass variant 선택 API, 다른 backend, 외부 mode-shape acceptance |
| 같은 ADR의 MFE-ADR-007 | 좌표 공변적 stabilization 개선 및 영향받는 static/eigen 검증의 명시 사용자 승인 | 특정 trace 공식 또는 기존 NR pass의 자동 채택 |
| 같은 ADR의 MFE-ADR-013 | reference/temp 네 예제와 옛 경로·복사·cache 검증 제외 | 과거 14개 blob·이동 commit·검사 수를 이번 재확인으로 보고 |
| [기존 requirements r3](../mitc4-shell-feast-eigen/requirements.md#requirements), [기존 evidence r3](../mitc4-shell-feast-eigen/requirements.md#requirements-evidence) | 27개 관찰 의무, 단위·identity·실패·남는 static/internal portfolio, 알려진 partial-BC 반례 | 기존 revision의 수식·threshold·영속 문자열이 새 Feature에 자동 승인되었다는 문구 |
| 기존 [research evidence](../mitc4-shell-feast-eigen/research.md#research-evidence), [formulation](../mitc4-shell-feast-eigen/formulation.md#formulation), [NR](../mitc4-shell-feast-eigen/numerical-review.md#numerical-review), [I/O](../mitc4-shell-feast-eigen/io.md#io) | 후속 전문 작업에서 필요한 근거·후보·반례를 찾을 위치 | 이번에 새로 조사·검토·검증한 evidence라는 주장 |
| 기존 [PRD 사용자 요구](../mitc4-shell-feast-eigen/PRD.md#사용자-요구와-승계-경계) | 명시 release-readiness 감사 요청의 이력 보존 | 옛 고정 9-stage 순회, Hook·phase 상태·중복 수동/자동 실행의 복원 |
요구사항 작성 당시 기존 r3 요구 문서는 **당시 worktree의 미커밋 자료**를 읽었다.
현재 링크는 정리된 해당 기록을 가리킨다. 당시 HEAD/commit에 동일 내용이 있었다고 가정하지 않는다. 과거 공개 문헌 조사도
기존 evidence에 기록된 당시 이력으로만 참조한다. 이번 작업은 외부 문헌 조사·정식화 유도·
독립 수치 검토를 수행하지 않았다.
기존 `NR-MFE-001`은 같은 물리 partial rotation BC에서 좌표를 회전하고 stiffness를
재계산할 때 나타난 반례다. 기존 evidence의 numerical 값은 재계산하지 않았다. `014/027`은
알려진 사례를 검증에서 배제하지 않는 의도를 승계한다. 이전 행렬을 단순 기저변환하는
검사만으로 geometry부터 재계산한 complete K의 공변성 검사를 대체하지 않는다.
기존 linear 요구 `FESA-REQ-LSMITC4-034/056`과
[nonlinear formulation §10.3](../nonlinear-static-newton-raphson/formulation.md#103-fixed-scale-and-potential)의
scale 선정 부분이 영향 대상이며 다른 물리·lifecycle 의미를 교체하지 않는다.
<a id="requirements-evidence--기존-id와-새-id-대응"></a>
### 기존 ID와 새 ID 대응
기존 열은 prefix `FEM-REQ-MITC4-EIGEN-`, 새 열은 prefix
`FEM-REQ-MITC4-EIGEN2-`를 생략한다. 27개 ID를 1:1로 대응하며 아래 요약은
요구사항 본문의 acceptance를 대신하지 않는다.
| 기존 suffix | 새 suffix | 보존하는 관찰 의무·변경 경계 |
| --- | --- | --- |
| `001` | `001` | 원형상·무응력 단일 무감쇠 procedure |
| `002` | `002` | S4/S4R의 기존 물리 의미와 stabilization 개선 분리 |
| `003` | `003` | Material/section의 양의 유한 밀도 연결과 진단 |
| `004` | `004` | 기존 geometry/director/thickness 유효성 |
| `005` | `005` | Consistent mass의 계산·독립 oracle·lumping 원본 |
| `006` | `006` | 물리 병진/회전 관성과 drilling null |
| `007` | `007` | 같은 DOF/constraint·결정적 조립 |
| `008` | `008` | 실제 partial BC에서 유한 spectrum 보존·FEAST admissibility |
| `009` | `009` | 입력 요청의 낮은 N개·zero modes·불가능 요청 진단 |
| `010` | `010` | 오름차순 mode identity·multiplicity |
| `011` | `011` | Derived lumped mass로 실제 MKL FEAST 실행 |
| `012` | `012` | Backend 실패·미수렴·불완전 모드의 성공 반영 금지 |
| `013` | `013` | 같은 lumped M의 residual·normalization·orthogonality |
| `014` | `014` | 두 mass와 complete K/eigen의 물리·좌표 불변식 |
| `015` | `015` | 원본 Frequency 및 부수 옵션의 명시적 의미 처리 |
| `016` | `016` | 미지원 모델·옵션의 silent no-op 거부 |
| `017` | `017` | HDF5 quantity·단위·source/mode/backend/mass 식별 |
| `018` | `018` | 내부 modal vectors와 source/physical DOF 대응 |
| `019` | `019` | 검증 candidate 반영과 state/final output 실패 보존 |
| `020` | `020` | 지정 eigen TXT Value-only 외부 비교 |
| `021` | `021` | Tolerance 전 identity/quantity/schema/finite 검사 |
| `022` | `022` | 공통 tolerance 유지; family는 후속 NR/I/O 정의 |
| `023` | `023` | 현행 behavior tests·관련 검사·완료 시 전체검증; 고정 RED/중복 실행 삭제 |
| `024` | `024` | 남는 shell/shellNL 및 내부 static 회귀·밀도 없는 static 유지 |
| `025` | `025` | 메인의 evidence 추적 완료 판단·필수 독립 검증; 고정 stage 삭제·감사 요청 이력 보존 |
| `026` | `026` | Consistent에서 유도한 lumped의 질량·관성 보존 검사 |
| `027` | `027` | 좌표 공변적 비물리 stabilization 및 partial-BC 정적/eigen 검증 |
<a id="requirements-evidence--현재-원본의-정적-관찰"></a>
### 현재 원본의 정적 관찰
아래는 메인이 `2026-09-08` 전달한 read-only 관찰이다. Python `pathlib`·regex·finite
검사와 keyword inventory는 exit `0`이었고 solver 실행은 아니다. Requirement owner는
원본을 다시 읽거나 hash·산술 검사를 반복하지 않았다. 과거 hash를 현재 확인값으로 옮기지 않는다.
| 대상 | 메인이 확인한 현재 사실 |
| --- | --- |
| `reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp` | 729 nodes, 676 S4 elements; density `2700.`, shell section `0.5, 5` |
| Step/BC | 한 `*Step, name=Step-2, nlgeom=NO, perturbation`; `Set-2` DOF 1~6의 homogeneous boundary 행 |
| Frequency | `eigensolver=Lanczos, sim, acoustic coupling=on, normalization=mass`; data `10, , , , ,` |
| `shellNL-eigen-meshfine eigenvalues.txt` | Mode IDs 1~10, finite Value, 중복 mode ID 없음 |
| Value 순서 | `219507, 885523, 885523, 1855340, 2740230, 2775150, 4149410, 4149410, 6733790, 6733790` |
| 표시값 반복 | `(2,3)`, `(7,8)`, `(9,10)`에서 같은 표시 Value; 이것만으로 실제 spectral multiplicity를 판정하지 않음 |
| 남는 static artifact | `rg --files`로 `reference/shell`·`reference/shellNL` 각각 inp 및 displacements/reactions/stresses CSV 존재 확인; 내용·수치 통과 확인은 아님 |
TXT의 표시 Value는 보정하지 않는다. 단위계는 수치 크기로 추론하지 않는다. 기존 관찰은
선행 static/load가 없는 단일 frequency 모델과 TXT의 분리된 Value/Freq를 기록한다.
입력의 유일한 step과 TXT mode를 연결할 수 있다는 것은 요구 정리를 위한 관찰이며,
comparison readiness·HDF5 projection·frame/family의 최종 정의는 후속 NR/I/O 책임이다.
`reference/temp` 원본은 이번에 읽거나 실행하지 않았다. 네 제외 예제와 남는 coverage의
원본은 [requirements](requirements.md#requirements--사용자-제외-예제)이며 과거 검사 개수나 cache로
현재 실행 검증을 대체하지 않는다.
<a id="requirements-evidence--후속-전문-판단과-사용자-결정-경계"></a>
### 후속 전문 판단과 사용자 결정 경계
아래는 requirement 작성의 blocker가 아니라 후속 작업이 필요할 때 구체화할 사항이다.
이번 요청으로 그 작업을 시작하지 않는다.
| 후속 owner | 필요한 판단·고정 경계 |
| --- | --- |
| Formulation | Consistent→lumped 유도, 정확한 관성 불변식·좌표 block, massless drilling과 실제 global BC의 유한 spectrum 보존, FEAST admissibility, 낮은 N개 완전성. 특정 quadrature·row-sum·projection/whitening 공식은 자동 채택하지 않음 |
| Formulation·NR | 공변 stabilization과 기존 nonlinear 초기 고정 scale lifecycle의 정합, partial-BC 반례·대응 static response 및 개선된 pencil 재검증. 기존 trace scale 공식·NR pass를 새 승인으로 간주하지 않음 |
| NR | 독립 내부 oracle·scale/threshold·검증 충분성·FEAST controls 검토. 외부 eigen Value는 blocking acceptance이며 비교 family는 공통 TOLERANCE의 같은 model/step/frame/quantity/차원/좌표/판정 영향 규칙 안에서 정의; 과거 singleton family 판정을 자동 채택하지 않음 |
| I/O | 최소 syntax/무해 옵션/진단, source step·mode·modal vector 의미와 HDF5 projection. Exact layout·영속 contract/stabilization 문자열은 이번에 고정하지 않음; 기존 public 호환성 보존 |
| 메인·Implementation·Physics | 실제 retained test 선택과 실행 evidence·독립 물리 판단. 옛 362/352 수, 미실행·실패·stale를 통과로 소급하지 않으며 명시 감사 요청은 후속 범위와 함께 관리 |
질량 흐름·backend·입력 count·Value-only·stabilization 개선·제외 목록은 기존 명시 결정으로
해결되어 재질문하지 않는다. 현재 추가 사용자 결정이 필요한 material conflict는 발견하지
않았다. 후속 증거가 새 물리 근사·지원 축소·공개 호환성/영속 schema의 비호환 변경 또는
acceptance 변경을 필요로 할 때만 근거와 함께 메인에게 반환한다. Reference 변경이나
공통 tolerance 완화로 충돌을 해소하지 않는다.
<a id="requirements-evidence--정적-확인과-미실행"></a>
### 정적 확인과 미실행
Requirement owner는 `Get-Content`·`rg`로 할당 관리문서, 기존 r3 요구·근거, 관련 사용자
ADR와 프로젝트 PRD/ARCHITECTURE/ADR-028/TOLERANCE 절을 읽었다. 명령 exit `0`.
`python -B -X utf8 -` 문서 작성 및 정적 검사는 exit `0`으로 27개 새 matrix ID의 유일성·연속성,
27개 old→new 대응과 상대 파일 링크 존재를 확인했다. 수정 대상은 할당된 두 문서이며
checklist는 PRD 한 곳에서 관리한다.
C++·FEAST·CMake/CTest·Harness·pytest·외부 solver·reference 수치 비교·독립 numerical/physics
review·release-readiness는 requirement-only 요청 때문에 미실행이다. 문서 완료는 이 검사의
통과나 새 수학·구현 acceptance 승인을 뜻하지 않는다. Source·test·공통 정책·기존 Feature·
phase·reference와 Git 작업은 변경하지 않았다.
-211
View File
@@ -1,211 +0,0 @@
# MITC4 eigen 연구와 근거
이 연구 기록의 후보·runtime gap은 조사 당시 상태다. 최종 채택식은 [정식화](formulation.md),
FEAST residual stopping과 비교 정책의 승인 변경은 [ADR](ADR.md), 실제 실행 범위는
[구현 검증](implementation-verification.md)을 따른다. 조사 시점의 trace stopping을 현재 설정으로 읽지 않는다.
<a id="research"></a>
<a id="research--mitc4-질량feast-연구-결과"></a>
## MITC4 질량·FEAST 연구 결과
- Feature ID: `mitc4-shell-feast-eigen2`
- Input baseline: `requirements r1`
- Research date: `2026-09-08`
- Status: `research evidence complete`; 현재 후속 작업 상태는 [PRD](PRD.md)의 checklist를 따른다.
[요구사항](requirements.md#requirements)과 [요구 근거](requirements.md#requirements-evidence)에 대한 연구다.
현재 후속 작업 권한은 메인이 전달한 최신 사용자 지시를 따르며, 요구 문서의 과거
requirement-only 완료 기록을 이번 연구의 실행 제한으로 해석하지 않는다.
기준은 [프로젝트 지침](../../AGENTS.md), [PRD](../PRD.md),
[ARCHITECTURE](../ARCHITECTURE.md), [ADR-028](../ADR.md#adr-028)이다.
출처별 locator·조건·검증 후보·gap은 [상세 근거](research.md#research-evidence)에 기록했다.
| 질문 / Requirement suffix | 결론과 인계 |
| --- | --- |
| Physical mass, consistent→lumped / 005,006,026 | MITC4 director 운동학에서 kinetic energy로 consistent mass를 유도할 수 있다. Scalar thickness moments를 consistent 계산에서 보존하고 node block으로 lumping하는 후보는 좌표 공변성과 drilling null을 설명한다. Global component row-sum은 부적합하다. 곡면의 first moment와 관성 보존 범위는 Formulation이 증명한다. |
| Partial BC와 FEAST SPD / 007,008,014 | 실제 global BC를 먼저 적용한 질량의 nullspace가 대상이다. UR3 일괄 제거는 성립하지 않는다. Massless Schur 제거의 정확성은 null block 가역성이 조건이며, FESA의 decoupling은 개선 K 구조에서 별도 증명이 필요하다. |
| Covariant drilling / 024,027 | 초기 physical rotational block의 trace는 접평면 기저 변경의 불변량이다. Trace 평균은 단순한 후보이나 채택은 Formulation 책임이다. Nonlinear scale은 초기값을 고정해야 기존 potential의 일관 미분을 유지한다. |
| Lowest N·multiplicity / 009–013 | FEAST는 구간 해법이다. SPD 변환·구간 밖 하한·count/solve 일치·독립 residual/Gram을 결합해야 최저 N 누락을 방지한다. 반복 고유값을 값으로 deduplicate하지 않는다. |
| Intel 세부 위험 / 012 | 공식 C `fpm[49]=1` count와 `fpm[5]=1` trace는 확인했다. Count-only 빈 구간의 `info=0,m0=0` 보장과 축소 workspace는 문서에 명시되지 않아 runtime 검증 gap으로 남는다. |
| 원본 syntax·Value-only / 015,020–022 | 지정 원본은 `10, , , , ,`이며 TXT Mode 1~10의 Value를 보존한다. Lanczos/SIM은 FESA FEAST backend 선택 근거가 아니다. 최종 allowlist·HDF5·comparison family는 I/O·NR 소유다. |
기존 feature의 연구·질량·eigen·stabilization 문서는 **연구 당시 worktree의 read-only 후보**로
읽었다. 과거 수식·NR 판정·runtime 결과를 이번 승인이나 새 통과로 가져오지 않았다.
특히 과거 singleton mode family는 연구 결론이 아니며 [공통 tolerance](../TOLERANCE.md)에
대해 NR가 새로 판단해야 한다.
검증 후보는 평판 다항 적분, 곡면 독립 kinetic energy, 실제 partial BC의 원 pencil 복원,
`NR-MFE-001` geometry 재계산과 대응 정적 response, frozen nonlinear 미분,
작은 zero/repeated/clustered spectrum, 지정 원본 Value 비교다. 세부는 상세 근거를 따른다.
이번에는 문헌·원본 syntax·문서 링크의 정적 확인만 수행했다. Solver, FEAST runtime,
build/test, reference 수치 비교와 독립 NR/Physics는 실행하지 않았다.
제외된 네 예제의 원본·복사·cache는 읽거나 사용하지 않았고 reference·공통 정책도 수정하지 않았다.
<a id="research-evidence"></a>
<a id="research-evidence--연구-근거검증-후보미해결-항목"></a>
## 연구 근거·검증 후보·미해결 항목
- Feature ID: `mitc4-shell-feast-eigen2`
- Input baseline: `requirements r1`
- Web access date: `2026-09-08`
- Main report: [research.md](research.md#research)
`Fact`는 이번 원문 확인, `Inference`는 수학적 적용 판단, `Candidate`는 후속 채택 후보,
`Gap`은 아직 확인하지 못한 사항이다. 수식·threshold·schema의 최종 계약을 정하지 않는다.
<a id="research-evidence--source-inventory"></a>
### Source inventory
| ID | Source / stable locator | 적용과 한계 |
| --- | --- | --- |
| S01 | Dvorkin & Bathe (1984), Engineering Computations 1, 77–88, DOI `10.1108/eb023562`, [author PDF](https://web.mit.edu/kjb/www/Publications_Prior_to_1998/A_Continuum_Mechanics_Based_Four-Node_Shell_Element_for_General_Nonlinear_Analysis.pdf), Eqs.(1),(2), p.81 및 Fig.7 vibration examples | Director 운동학·5 DOF·rigid mode의 원 연구. 곡면 lumping 또는 Abaqus 내부 알고리즘의 근거가 아님. |
| S02 | Voet, Sande & Buffa (2023), CMAME 410,116033, DOI `10.1016/j.cma.2023.116033`, [author preprint v2](https://arxiv.org/html/2212.03614v2), Definition 3.7, Remark 3.8 | Scalar/일반 행렬 lumping 이론. 절댓값 row-sum theorem을 shell drilling-null 보존으로 확대하지 않음. |
| S03 | Bathe & Wilson (1973), IJNME 6,213–226, DOI `10.1002/nme.1620060207`, [author PDF](https://web.mit.edu/kjb/www/Publications_Prior_to_1998/Solution_Methods_for_Eigenvalue_Problems_in_Structural_Mechanics.pdf), `STATIC CONDENSATION`, Eqs.(9)–(13) | Massless 제거·fill 증가. Massive DOF의 근사 condensation과 구분. |
| S04 | Intel oneMKL C Developer Reference, URL edition `2026-0`, page date `2026-04-28`, [Extended Eigensolver Functionality](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-functionality.html), generalized problem | Real symmetric generalized 문제의 SPD B 조건. 설치 runtime 일치 확인은 아님. |
| S05 | 같은 edition, [Input Parameters](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html), C-indexed `fpm[5]`, `[26]`, `[27]`, `[49]` | Count·trace·matrix checks. Standalone FEAST 또는 Fortran index와 혼동 금지. |
| S06 | 같은 edition, [Output Details](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-output-details.html), `info` table 및 마지막 remark | 실패·empty warning·endpoint와 isolated cluster 위험. Count-empty 특수 성공 보장 문구 없음. |
| S07 | 같은 edition, [feast_scsrgv/feast_hcsrgv](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/feast-scsrgv-feast-hcsrgv.html), `m0`, `x`, `epsout`, `m`, CSR parameters | Signature·capacity·endpoint-scaled trace. Count-only 작은/null workspace 보장 문구 없음. |
| S08 | Abaqus 2025 [FREQUENCY](https://docs.software.vt.edu/abaqusv2025/English/SIMACAEKEYRefMap/simakey-r-frequency.htm), optional parameters와 Lanczos data line | 공개 count·bound·normalization·SIM·acoustic syntax만 사용. FESA 내부 질량/해법의 동등성은 주장하지 않음. |
| P01 | [기존 mass](../mitc4-shell-feast-eigen/formulation.md#formulation-mass), [eigen](../mitc4-shell-feast-eigen/formulation.md#formulation-eigen), [stabilization](../mitc4-shell-feast-eigen/formulation.md#formulation-stabilization), [연구](../mitc4-shell-feast-eigen/research.md#research-evidence) | 연구 당시 worktree의 후보 유도·과거 근거 locator. 이번 독립 검증 또는 승인으로 간주하지 않음. |
| P02 | [요구사항](requirements.md#requirements), [요구 근거](requirements.md#requirements-evidence), [기존 nonlinear §10.3](../nonlinear-static-newton-raphson/formulation.md#103-fixed-scale-and-potential), [TOLERANCE](../TOLERANCE.md) | 요구·frozen lifecycle·acceptance 경계. 경험적 통과의 근거가 아님. |
<a id="research-evidence--r01--질량과-lumping"></a>
### R01 — 질량과 lumping
**Fact S01:** 입자 변위는 nodal translation과 두 director rotation으로 보간한다.
논문은 전역 3회전 표현으로 변환 가능함을 설명하고 여섯 rigid modes를 확인한다.
**Inference:** `v=sum Ni(ui_dot+z*(theta_i_dot cross di))`,
`T=1/2 integral rho |v|² dV`이면 `M_C=integral rho H^T H dV`이며
director-parallel rotation은 질량 null이다. MITC assumed shear는 strain 보간이므로
질량에 shear correction을 추가할 근거가 없다.
**Fact S02:** 일반 행렬의 absolute-row-sum과 nonnegative 행렬의 보통 row-sum은
구분된다. **Inference:** global rotary `P=I-dd^T`에 component row-sum을 적용하면
좌표 공변성·null을 잃는다. `d=(1,1,1)/sqrt(3)`에서는 `P*ones=0`이나 rank(P)=2다.
Translation/rotation의 무차별 행 합은 질량·질량×길이·질량×길이² 차원도 섞는다.
**Candidate P01 재검토:** Consistent 계산의 `Ck_ij=integral rho Ni Nj z^k dV`,
`k=0,1,2`를 보존하고 scalar row-sum을 node별 tensor block으로 재구성한다.
`sum Nj=1`, `Ni>=0`에서 node energy는 `integral rho Ni |Gi(z) qi_dot|² dV`이므로
양의 measure에서 비음성과 drilling null을 설명한다. Centered section이라도 곡면 J의
두께 의존성 때문에 first moment가 남을 수 있다. Flat parallel director에서만
rotary factor `t²/12`와 zero translation–rotation coupling이 직접 성립한다.
일반 orbital inertia·모든 velocity energy·consistent spectrum 동일성을 요구하지 않는다.
**검증 후보:** 직사각형 면적 A의 scalar mass는 `rho*t*A/36` 곱하기
`[[4,2,1,2],[2,4,2,1],[1,2,4,2],[2,1,2,4]]`인 직접 다항 적분 oracle;
회전 scalar 배율은 `t²/12`. 곡면은 production H/J를 재호출하지 않는 독립 velocity 적분,
node block positivity·moment 관계·두 mass의 좌표 congruence·density scaling을 검사한다.
Quadrature 차수·정확 관성 보존 범위는 Formulation/NR가 확정한다.
<a id="research-evidence--r02--실제-bc와-massless-reduction"></a>
### R02 — 실제 BC와 massless reduction
**Fact S03:** Mass가 `diag(Mp,0)`이고 massless stiffness `Kzz`가 가역이면
`Kr=Kpp-Kpz*Kzz^-1*Kzp`, `z=-Kzz^-1*Kzp*p`가 massless 방정식의 정확한 제거다.
Dense fill 가능성이 있다. **Inference:** 실제 global BC의 free injection C를 먼저
적용하여 `Mf=C^T M_L C`, `Kf=C^T K C`에서 positive/null 공간을 찾아야 한다.
기울어진 director와 partial rotation BC에서는 원래 drill 방향이 free 공간에 들어가지
않아 rotary free block이 SPD가 될 수 있다. UR3 또는 node당 1 DOF 일괄 삭제는 틀리다.
**Candidate:** 공통 nodal director, physical K의 drill null, positive scalar numerical
drilling 구조에서 `Kf Z=Z D`, `D>0`를 증명하면 `Kpz=0`인 sparse projection을 쓸 수 있다.
이 증명은 개선된 constrained pencil 대상이며 partial BC에 남는 stabilization을 지우지 않는다.
Nonlinear tangent 또는 prestressed 문제에 확장하지 않는다.
**검증 후보:** 비축정렬 director의 partial BC, null 없음/있음, 0 physical rank,
request>rank, `Kpz!=0`의 작은 manufactured pencil, 원 free residual 및 constraint 복원.
공통 K/M nullspace는 임의 pseudoinverse로 성공 처리하지 않는다.
<a id="research-evidence--r03--공변-stabilization과-frozen-nonlinear-scale"></a>
### R03 — 공변 stabilization과 frozen nonlinear scale
**Inference:** Orthogonal tangent basis 변경에서 `Ri'=Oi^T Ri Oi`이면
`trace(Ri')=trace(Ri)`다. 개별 대각값의 최솟값은 불변량이 아니다.
**Candidate:** 초기 physical rotational blocks의 trace 평균은 force×length 차원이며
PSD physical K에 비영 회전 강성이 있으면 양수다. Trace 양수만으로 전체 PSD를 입증하지는
못한다. 정확 집계·계수·유효성 판단은 Formulation 책임이며 reference tuning은 근거가 없다.
**Inference P02:** `Pi_d=kd*gamma^T gamma/2`에서 initial kd를 고정하면
`Dkd=D²kd=0`이고 기존 residual/Hessian 구조를 유지한다. Trial에서 재선정하면 추가 미분항이
필요하다. Objective gamma와 invariant initial kd가 모두 필요하며, positive kd만으로
일반 nonlinear Hessian의 SPD가 따르지 않는다.
**검증 후보:** Geometry부터 complete K·director·scale을 독립 재계산하는 좌표 회전,
node별 tangent 변경, 지원 partial BC `NR-MFE-001`와 같은 물리 load의 static response,
rigid physical motion·physical recovery 제외, nonlinear objective potential의 1·2차 미분과
initial scale immutability. 과거 반례 수치·새 trace 후보 기대값은 이번에 재계산하지 않았다.
<a id="research-evidence--r04--feast-countcompleteness의-확인과-gap"></a>
### R04 — FEAST count·completeness의 확인과 gap
**Fact S04/S05:** Generalized real symmetric 문제의 B는 SPD다. C-index
`fpm[49]=1`은 CSR 구간 전체 고유치 수를 `m0`로 반환하고 flag를 0으로 재설정한다.
`fpm[26]`은 CSR 검사, `[27]`은 B 양정치 검사이며 `[5]=1`은 trace stopping이다.
**Fact S07:** `epsout=|trace_i-trace_previous|/max(|emin|,|emax|)`;
`0<m0<=n`, 구간 multiplicity count 미만의 m0는 불충분하다. Count와 solve의 m0 및
allocation capacity를 분리해야 한다.
**Fact S06:** `info=0` 성공, `1` empty warning, `2` 미수렴, `3` 작은 subspace,
`4` subspace-only, `-4` B not SPD, `-5` count 오류이며 끝점이 고유치에 근접할 수 있다.
`emin>=emax`는 오류다. 매우 넓은 구간의 고립 cluster를 놓쳐 `info=1`일 수 있다.
따라서 빈 반환이나 작은 residual만으로 낮은 mode가 없음을 증명하지 못한다.
**Candidate:** SPD whitening 뒤 차원 일관적인 spectral lower bound와 bounded count
search를 연결하고, 구간 count와 solve row 수·Gram rank를 일치시킨 후 낮은 N개를 취한다.
N번째가 repeated cluster 안이면 내부 solve는 cluster 전체를 포함하고 외부 N개 identity는
count 요청을 따른다. 벡터 기저의 비유일성과 scalar multiplicity를 구분한다.
Zero modes를 양수 시작 구간으로 제외하거나 negative 값을 clamp하지 않는다.
**Gap G01:** 공식 표는 count-only empty case의 `info=0,m0=0`을 명시 보장하지 않는다.
성공 status와 count=0만 인정하는 guard는 fail-closed 후보지만, 이를 실제 runtime이 반환하여
전체 search가 진행되는지는 설치 oneMKL의 empty/occupied/endpoint 근접 probe가 필요하다.
`info=1`을 검증 없이 trusted zero count로 승격하지 않는다.
전체 spectrum 밖임을 독립 bound로 확보한 enclosing interval에서 성공 count가 n이면
전체 bracket의 완전성 근거가 된다. 선택적 empty-prefix 축소가 불가능해도 이 bracket을
유지하는 후보가 있으며, 비용·종료 조건과 채택은 Formulation이 판단한다.
**Gap G02:** Count-only의 작은/null x/e/res allocation 면제는 확인하지 못했다.
`m0=n`, `x[n*n]` 보수 allocation은 기존 후보이지 공식 최소 workspace 의무가 아니다.
설치 header/runtime와 memory·integer overflow를 구현 시 확인한다. 이 조사에서는 설치
runtime version·실행·peak memory를 측정하지 않았다.
**검증 후보:** 손으로 알려진 diagonal 및 직교 변환 SPD pencil의 첫 N개,
zero/negative/repeated/clustered/empty spectrum, N=rank, endpoint 근접, count/solve mismatch,
미수렴·allocation 실패, 원 lumped M residual·normalization·Gram. FEAST status만으로
physics/completeness를 통과 처리하지 않는다. 세부 bound·budget·threshold는 Formulation/NR 소유다.
<a id="research-evidence--r05--지정-원본과-공개-입력-의미"></a>
### R05 — 지정 원본과 공개 입력 의미
**이번 직접 정적 관찰:**
`reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp`의 끝부분은
`*Step, name=Step-2, nlgeom=NO, perturbation`,
`*Frequency, eigensolver=Lanczos, sim, acoustic coupling=on, normalization=mass`,
`10, , , , ,` 및 Set-2 DOF 1~6 boundary 행이다. 같은 폴더의
`shellNL-eigen-meshfine eigenvalues.txt`는 Mode 1~10, Value와 별도 Freq를 표시한다.
Value 반복 표시는 2/3, 7/8, 9/10에 있으며 표시 precision만으로 exact degeneracy를 단정하지 않는다.
전체 keyword inventory·node count는 [요구 근거](requirements.md#requirements-evidence)의 선행 정적 관찰이다.
**Fact S08:** Lanczos 첫 data field는 requested count, 다음 두 field는 cycles/time의
frequency bounds이며 blank는 해당 bound 미설정을 뜻한다. Shift와 controls도 별도 field다.
**Inference/인계:** FESA의 FEAST backend와 source Lanczos/SIM을 분리하고 acoustic-free
옵션의 처리·warning 및 비영 unsupported field 거부를 I/O가 명시한다. 공개 Abaqus syntax는
FESA mass/stabilization 내부 동등성의 근거가 아니다.
Value-only·공통 tolerance는 사용자 계약이다. Freq 변환·TXT 보정·CSV 복제·외부 mode-shape
gate를 추가하지 않는다. NR가 family를 새로 검토하고 I/O가 source step/mode projection을 정의한다.
<a id="research-evidence--정적-확인미실행"></a>
### 정적 확인·미실행
원 논문·공식 웹 문서 접근과 위 지정 원본 두 파일의 읽기는 수행했다. 연구 문서의 상대
파일 링크 존재와 UTF-8 replacement 문자 부재를 Python으로 검사했고 exit `0`이었다.
기존 문서·reference·코드·threshold·schema를 수정하지 않았다.
이번 산출물은 두 연구 문서뿐이며 Git은 메인이 소유한다. Build/test·FEAST runtime·외부 solver·
reference 비교·독립 NR/Physics는 연구 범위 밖으로 미실행이다. Configured vault 요청이 없어
`fem-theory-query`를 사용하지 않았다. 제외 예제의 원본·복사·cache 열람과 재사용은 없다.