modify documents

This commit is contained in:
KOKO\Mimi
2026-10-04 03:32:59 +09:00
parent 858e87be64
commit c1d5cc3c0d
176 changed files with 9615 additions and 25355 deletions
+9 -9
View File
@@ -20,9 +20,9 @@
- 상태: 기존 명시 사용자 결정의 재시작 기준으로서 기록. 새로운 수학·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) r3. 기존 ADR에는 질량 사용·개선 범위·제외에 관한 사용자 답변이 명시되어 있다.
- 근거: 기존 [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에 동일 내용이 있다고 주장하지 않는다.
- 한계: 이 결정 당시 일부 기존 r3 문서는 당시 worktree의 미커밋 자료였다. 필요한 요구의 실제 의미와 제외 목록은 새 requirements에 독립적으로 명시하고 이전 HEAD에 동일 내용이 있다고 주장하지 않는다.
## MFE2-ADR-003 — 참고 자료와 새 evidence의 경계
@@ -53,13 +53,13 @@
- 결정: [정식화](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-evidence.md)에서 count-only 빈 구간 및 작은 workspace 보장이 확인되지 않았다. 보수적 workspace와 실제 runtime·memory 검증 의무를 남기며 backend 통과를 선언하지 않는다.
- 근거·한계: [연구 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-evidence.md). Geometry부터 complete K·질량·부분 제약 정적 응답을 재계산하여 `lambda=10369/450` 및 좌표 공변성을 확인했다. 별도 rational mass oracle도 새로 실행했다.
- 근거: [검토](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다.
@@ -67,7 +67,7 @@
## MFE2-ADR-008 — Eigen I/O의 additive 계약과 이번 작업 종료
- 상태: 요청 범위의 I/O 정의 완료 및 메인 계약 대조 완료, 2026-09-08. Owner: io-definition-agent; 기록: 메인 assistant.
- 결정: [I/O](io.md)의 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)`를 추가한다.
- 결정: [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를 추가하지 않는다.
@@ -78,12 +78,12 @@
- 상태: 사용자 명시 요청, 2026-09-09 KST. Owner: 메인 assistant.
- 근거: “implementation 단계를 진행해주세요”, “implementation 단계에서 30분 제한은 없습니다”.
- 결정: 확정된 r1 계약을 구현하고 동작별 테스트·실제 FEAST·남는 필수 회귀/reference와 독립 검토를 진행한다. 30분 시간 제한을 적용하지 않는다.
- 영향: [구현 계획](implementation-plan.md)의 파일 소유권으로 병행 작업하고 메인이 CMake 등록·빌드·통합·커밋을 조정한다. 수치/공개 schema/지원 범위를 구현 결과에 맞춰 변경하지 않는다. 공통 문서·기존 사용자 변경·reference를 보존한다.
- 영향: [구현 계획](README.md#재사용-handoff)의 파일 소유권으로 병행 작업하고 메인이 CMake 등록·빌드·통합·커밋을 조정한다. 수치/공개 schema/지원 범위를 구현 결과에 맞춰 변경하지 않는다. 공통 문서·기존 사용자 변경·reference를 보존한다.
## MFE2-ADR-010 — 실제 실행에서 드러난 계약 충돌
- 상태: 문제 기록·후속 제안, **수치 계약 변경 미승인**. Owner: 메인 assistant.
- 근거: [실행 결과](implementation-verification.md), [독립 수치 검토](implementation-numerical-review.md), [S3 검토](implementation-numerical-review-s3-static.md).
- 근거: [실행 결과](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로 변경한다.
@@ -95,7 +95,7 @@
- 결정: 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-feast-residual-review.md)에 새 실행을 기록한다. 기존 trace 실패 evidence는 당시 결과로 보존한다.
- 검증: [실행 결과](implementation-verification.md) 및 [독립 수치 검토](implementation-review.md#implementation-feast-residual-review)에 새 실행을 기록한다. 기존 trace 실패 evidence는 당시 결과로 보존한다.
- 범위: S3 정식화·부분 회전 BC·reaction·평형 기준은 변경하지 않고 알려진 충돌을 후속 과제로 유지한다. S3를 해결하거나 unsupported로 재분류한 결정이 아니다. 외부 reference와 공통 tolerance도 유지한다.
## MFE2-ADR-012 — 첫 구현의 외부 고유치 5% 수용
@@ -105,5 +105,5 @@
- 결정: [공통 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-first-version-review.md)에 새 정책의 fresh 검증 및 제한을 기록한다. 과거1% 비교 실패는 당시 계약의 이력으로 보존한다.
- 결과: [구현 결과](implementation-verification.md)와 [첫 구현 독립 검토](implementation-review.md#implementation-first-version-review)에 새 정책의 fresh 검증 및 제한을 기록한다. 과거1% 비교 실패는 당시 계약의 이력으로 보존한다.
- 통합 승인: 사용자는 구현·검증 완료 후 `dev` 병합과 push를 명시 요청했다. 메인은 통과한 변경을 커밋하고 `dev`에 반영하며 관련 없는 사용자 worktree 변경은 보존한다. 외부 release/tag 승인으로 확대하지 않는다.
@@ -1,46 +1,22 @@
# MITC4 Shell Mass·FEAST Eigen 2 작업 지침
# mitc4-shell-feast-eigen2 문서·작업 지침
- Feature ID: `mitc4-shell-feast-eigen2`
- Owner: 메인 assistant
- Requirement baseline revision: `r2` (외부 고유치5% 수용)
- 현재 상태: [ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)의 residual stopping과 [ADR-012](ADR.md#mfe2-adr-012--첫-구현의-외부-고유치-5-수용)의 외부5% 기준으로 첫 구현 검증을 완료했다. 전체417개 검사와 독립 검토는 PASS다. C5 controls·I/O mapping은 r2이며 S3와 정확도 향상은 후속 과제로 유지한다.
- 목적: MITC4 질량행렬과 FEAST 고유진동 해석의 요구사항을 이론·수학·수치 검토·입출력 계약으로 구체화한다.
- 현재 checklist: [PRD](PRD.md#현재-checklist).
- 문서 진입점·목적·사용법·Handoff: [README](README.md).
- 현재 범위·checklist: [PRD](PRD.md); 결정·승인·대체 이력: [ADR](ADR.md).
- 적용 범위: 해당 기능의 문서. 자동 로드되는 코드 영역 `AGENTS.md`가 아니다.
기준: [프로젝트 지침](../../AGENTS.md), [프로젝트 PRD](../PRD.md),
[공통 ADR](../ADR.md#adr-028), [ARCHITECTURE](../ARCHITECTURE.md),
[Feature 문서 관리](../FEATURE_DOCUMENTATION.md), [TOLERANCE](../TOLERANCE.md).
기준: [프로젝트 지침](../../AGENTS.md), [ARCHITECTURE](../ARCHITECTURE.md),
[Feature 문서 관리](../FEATURE_DOCUMENTATION.md), [공통 tolerance](../TOLERANCE.md).
## 지역 지침
## 보존할 계약과 인계
- 기존 `docs/mitc4-shell-feast-eigen/`의 현재 worktree 문서는 읽기 전용 참고 자료다. 일부 r3 기록은 미커밋 상태이므로 HEAD의 내용과 동일하다고 가정하지 않는다.
- 기존 명시 사용자 요구와 물리·검증 의도는 출처를 연결하여 정리한다. 과거 agent stage, phase 상태, 수치 검토 통과와 환경 복구 기록은 새 작업의 승인·실행 evidence가 아니다.
- 전문 보고서의 수행·미실행은 해당 작업 시점의 기록이다. 현재 완료 상태는 PRD checklist가 소유하며 requirement-only 시점의 미실행 기록을 이후 전문 검토의 부재로 해석하지 않는다.
- 새 요구사항은 `FEM-REQ-MITC4-EIGEN2-###` ID를 사용한다. 기존 ID는 추적용 대응 관계에만 남긴다.
- Requirement는 관찰 가능한 동작·범위·검증 의도를 소유한다. 특정 lumping/축소 수식, FEAST parameter, HDF5 layout, 수치 threshold는 새로 결정하지 않는다.
- `reference/temp` 예제는 원본·옛 경로·복사본·cache를 통해서도 검증에 사용하지 않는다. 제외 목록은 requirements의 원본 정의를 따른다.
- 구현 변경은 [implementation-plan](implementation-plan.md)의 할당 source·test·build 등록과 이 Feature 문서에 제한한다. 기존 Feature·phase의 사용자 변경과 reference는 보존한다.
- 문서·단일 kernel/backend의 완료를 solver 기능 완료로 보고하지 않는다. 필요한 실제 실행·독립 검토 evidence를 확인한다.
- 사용자는 implementation 단계의 30분 제한을 명시 해제했다. 이전 문서 단계의 시간 제한은 이력이다.
수식·I/O·수치 기준의 원본은 README에서 연결한 전문 문서를 따른다. 기능을 재개할 때
관련 계약과 실제 실행 revision·미해결 항목을 함께 읽는다. 과거 stage pass나 현재 문서
정리를 solver 검증 통과로 계산하지 않는다. 요구사항·ADR ID와 승인 이력을 유지한다.
메인은 PRD·ADR·진입점·문서 참조를 관리하고 전문 작업자는 할당한 본문과 관련 범위만 수정한다.
기존 개인 설정·reference·다른 작업자의 변경을 보존하며 실패를 tolerance 완화로 숨기지 않는다.
문서만 수정하면 정적 검토를 수행하고, 동작 변경에는 관련 검사와 필요한 독립 검토를 수행한다.
## 문서 목록과 소유권
| 문서 | Owner | 역할 |
| --- | --- | --- |
| [FEATURED_AGENTS.md](FEATURED_AGENTS.md) | 메인 assistant | Feature 지역 지침·문서 목록 |
| [PRD.md](PRD.md) | 메인 assistant | 사용자 요청·범위 요약·현재 checklist |
| [ADR.md](ADR.md) | 메인 assistant | 새 작업의 결정·기존 자료 적용 경계 |
| [requirements.md](requirements.md) | requirement-agent | 원자적 요구사항·acceptance intent·검증 matrix |
| [requirements-evidence.md](requirements-evidence.md) | requirement-agent | 재사용 근거·기존 요구 대응·reference 정적 관찰·미해결 사항 |
| [research.md](research.md), [research-evidence.md](research-evidence.md) | research-agent | 일차 출처·적용 판단·검증 후보·미해결 근거 |
| [formulation.md](formulation.md), [질량·stabilization](formulation-mass-stabilization.md), [eigen](formulation-eigen.md) | formulation-agent | 구현 가능한 수학 계약·기존 유도 채택 경계 |
| [numerical-review.md](numerical-review.md), [evidence](numerical-review-evidence.md), [controls](numerical-review-controls.md), [cases](numerical-review-cases.md), [reference-model](reference-model.md) | numerical-review-agent | 독립 수학 검토·실제 검산·수치 기준·검증 사례·외부 비교 의미 |
| [io.md](io.md), [input](io-input.md), [schema](io-schema.md), [mapping](io-mapping.md) | io-definition-agent | 입력·진단·내부 소유권·영속 결과·비교 projection 계약 |
| [implementation-plan.md](implementation-plan.md) | 메인 assistant | 구현 할당·검증 순서와 실행 경계 |
| [implementation-verification.md](implementation-verification.md) | 메인 assistant | 실제 구현·실행·실패·남은 evidence와 후속 결정 |
| [구현 수치 검토](implementation-numerical-review.md), [검토 이력](implementation-numerical-review-history.md), [S3 정적 검토](implementation-numerical-review-s3-static.md) | numerical-review-agent | 구현의 독립 수치 대조와 계약 충돌 |
| [구현 물리 검토](implementation-physics-review.md) | physics-evaluation-agent | 실제 retained 결과의 물리 evidence·범위와 기존 문제 |
| [FEAST 종료 제어 검토](implementation-feast-residual-review.md) | numerical-review-agent | 사용자 승인 residual stopping의 독립 검토와 새 실행 판정 |
| [첫 구현 검토](implementation-first-version-review.md) | numerical-review-agent | 승인된5% 범위·필수 coverage 보강·실행 및 제한의 독립 확인 |
반환은 결과·변경 파일·정적 확인·미해결 항목으로 충분하다. Git 경로 선택·커밋과 최종 결과 확인은 메인이 수행한다.
현재 첫 구현은 FEAST residual stopping·모드별5% 정책의 승인 범위다. 다른 기능의 RMS1%를
바꾸지 않는다. `reference/temp` 제외 portfolio를 cache·복사본으로 재사용하지 않는다.
S3 public static 충돌과 외부 정확도 개선은 보류이며, HHT consistent kinetic mass와 구분한다.
+25 -84
View File
@@ -9,36 +9,13 @@
[공통 ADR](../ADR.md#adr-028). 지역 지침은 [FEATURED_AGENTS](FEATURED_AGENTS.md),
결정 근거는 [Feature ADR](ADR.md)을 따른다.
## 사용자 요청과 적용 범위
## 사용자 결정과 현재 적용 범위
2026-09-08 사용자는 기존 작업을 `mitc4-shell-feast-eigen2`라는 이름으로 requirement부터
다시 시작하고, 기존 `docs/mitc4-shell-feast-eigen/`의 유용한 문서를 참고하며 작업 중
변경사항을 Git에 커밋하도록 요청했다. 이어 **모든 단계를 진행하지 말고 requirement
단계만 진행**하도록 범위를 명시했다.
이후 사용자가 **research부터 io-definition까지** 진행하도록 요청했다. 당시 범위는 research,
formulation, 독립 numerical review, I/O 계약 문서와 단계별 커밋이다. 구현 계획·코드,
solver build/test·reference 비교와 release 감사는 포함하지 않는다.
별도 coordinator나 phase 상태기계를 만들지 않는다.
작업시간 제한은 30분이다. 시작은 2026-09-08 12:07:56 UTC이며 12:37:56 UTC에 도달하면
진행 중인 작업을 중지하고 실제 완료·미완료 항목과 지연 이유를 보고한다.
2026-09-09 KST 사용자는 **implementation 단계를 진행**하도록 요청하고 **implementation
단계의 30분 제한은 없다**고 명시했다. 현재 범위는 [구현 계획](implementation-plan.md)에 따른
코드·테스트·실제 FEAST 및 필수 reference/회귀 검증과 작업별 커밋이다. 앞의 30분 제한은
완료된 문서 작업의 이력이다. 원본 reference 생성·변경과 release는 포함하지 않는다. Push는 아래 후속 요청으로 승인되었다.
2026-09-10 사용자는 FEAST 종료 조건을 trace에서 residual로 변경하고 S3는 추후 고려하도록
명시했다. [ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)에 따라 backend·저장 control 검증·관련 문서를 갱신하며,
기존 독립 잔차와 외부 tolerance, 질량·drilling 수식은 유지한다.
이어 사용자는 “5% 이내면 첫 구현이므로 Abaqus와의 고유치 정확도 향상은 추후에 진행”하고
구현을 마무리하도록 요청했다. [ADR-012](ADR.md#mfe2-adr-012--첫-구현의-외부-고유치-5-수용)의
모드별 외부5% 정책을 적용하고 나머지 필수 검증을 보강한다. S3 보류는 유지한다.
사용자는 구현과 검증 완료 후 `dev` 병합 및 push도 명시 승인했다. 관련 변경을 커밋하고
검증한 tree를 `dev`에 병합한 뒤 원격 `dev`에 반영한다. 기존 사용자 변경과 reference 원본은 보존한다.
새 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 운영 요청은 현재 기능 개발의 제약·권한이 아니다.
## 솔버 기능의 요구 범위 요약
@@ -53,7 +30,7 @@ solver build/test·reference 비교와 release 감사는 포함하지 않는다.
6. `reference/temp`로 제외된 예제는 검증에 사용하지 않는다. 남는 정적 회귀와 내부 물리 검증 의무를 명시한다.
지속할 상세 계약이 필요하므로 요구사항과 verification matrix 원본은
[requirements.md](requirements.md)에 둔다. 이 PRD에는 수식·threshold·schema를 중복 정의하지 않는다.
[requirements.md](requirements.md#requirements)에 둔다. 이 PRD에는 수식·threshold·schema를 중복 정의하지 않는다.
## Acceptance 요약과 원본
@@ -61,64 +38,28 @@ solver build/test·reference 비교와 release 감사는 포함하지 않는다.
| 영역 | Requirement IDs | 요구되는 결과와 검증 의도 |
| --- | --- | --- |
| 입력·물리 범위 | [001~004, 015~016](requirements.md#requirement-verification-matrix) | 밀도·section·geometry·boundary·mode 요청의 의미를 보존하고 미지원 조합을 명확히 진단 |
| 질량·stabilization | [005~008, 014, 026~027](requirements.md#requirement-verification-matrix) | 두 질량의 유도 관계, 물리 관성·drilling null, 대칭성·에너지·좌표 공변성 검증 |
| FEAST·modal evidence | [009~013](requirements.md#requirement-verification-matrix) | 실제 backend, 낮은 N개·multiplicity, 동일 사용 질량의 residual·normalization·orthogonality 및 실패 보존 |
| 결과·reference | [017~022](requirements.md#requirement-verification-matrix) | HDF5 source/mode identity, Value-only 대응, completeness·finite 사전검사와 공통 tolerance |
| 회귀·완료 | [023~025](requirements.md#requirement-verification-matrix) | 제외 예제를 사용하지 않는 남은 static·내부 물리 검증, 필요한 실제 실행 evidence와 미실행의 구분 |
| 입력·물리 범위 | [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-evidence.md)를 따른다.
각 영역의 원자적 ID·검증 방법·출처는 requirements 및 [근거 문서](requirements.md#requirements-evidence)를 따른다.
과거 문서의 `pass`, 362/352 test count나 stage 완료를 이 baseline의 실행 결과로 사용하지 않는다.
## 현재 checklist
- [x] 새 Feature ID·작업 브랜치와 requirement-only 범위를 설정한다.
- [x] 기존 자료의 참고·승계·후속 재검토 경계를 정한다.
- [x] Requirement specialist가 새 요구사항·verification matrix와 근거를 작성한다.
- [x] 메인이 사용자 요구 coverage, 전문 owner 경계와 미해결 사항을 정적으로 확인한다.
- [x] 상대 링크·ID를 검사하고 커밋 대상이 새 Feature 문서 5개뿐인지 확인한다.
- [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 평형 계약 충돌의 후속 검토.
- [x] Research: [연구](research.md)와 [근거](research-evidence.md)에 일차 출처·질량/축소/stabilization 후보 및 실제 runtime 확인이 필요한 FEAST 두 항목을 기록했다.
- [x] Formulation: [정식화](formulation.md)에 질량·공변 stabilization·constraint-first 축소·FEAST·복구 수학 계약을 작성했다. 독립 numerical review는 별도 항목이다.
- [x] Numerical review: [독립 검토](numerical-review.md)는 `pass-for-io-definition`이다. 새 수학 oracle 2개와 27개 verification cases, 내부 controls 및 Value-only reference family를 정의했다. 실제 solver 검증은 미실행이다.
- [x] I/O definition: [I/O 계약](io.md)에 입력·진단·additive eigen schema·source step/mode mapping·실패 보존과 검증 의무를 정의했다.
- [x] 신규 문서의 링크·계약 일관성, 27개 요구사항의 NR/I/O coverage와 변경 범위를 정적으로 확인하고 단계별 변경을 커밋한다.
## 실행과 미검증 범위
이 checklist는 문서 작업 상태다. Solver 구현·실제 FEAST 실행·회귀 및 외부 reference 비교의 통과를 뜻하지 않는다.
- [x] 질량·stabilization과 독립 analytical/invariant 테스트 구현·검증. S3 public static 충돌은 아래 후속 항목으로 분리한다.
- [x] 실제 FEAST backend·count/cluster/zero/실패 controls와 runtime 검증. 실행한 대표 실패 경로와 미주입 한계는 결과 보고서에 구분한다.
- [x] Density/Frequency semantic·source identity·진단 및 입력 테스트. 기존 정적 PREPRINT 회귀를 보존했다.
- [x] Constraint-first 축소·modal recovery·별도 eigen state/procedure 구현.
- [x] HDF5 additive schema·candidate 보존·Value comparator 및 통합 테스트.
- [x] 제외 예제 사용 없이 남는 static/내부 회귀·전체 build/test·필수 reference 실행: 417/417 PASS.
- [x] 관련 독립 numerical/physics 확인과 결과·한계 기록. 첫 구현 독립 판정은 승인된 범위에서 PASS다.
- [x] 승인된 FEAST residual stopping과 HDF5 control 검증을 함께 적용하고 변경 전 실패·변경 후 검사를 확인한다.
- [x] 원본 eigen의 전체 c개 독립 잔차·복구·HDF5 생성을 확인하고 종료 제어의 독립 수치 검토를 받는다.
- [x] 원본 eigen 10개 Value가 사용자 승인 모드별5% 기준을 충족한다. 최대 상대오차는 약4.261331%다.
후속 보류 항목:
- [ ] Abaqus와의 외부 Value 정확도를 개선한다. 이전 RMS1% 기준의 Mode2–10 불일치는 이력으로 보존한다.
- [ ] S3 public static 정적 평형 계약 충돌은 사용자 요청에 따라 후속 검토한다.
현재 구현·실행은 [implementation-verification](implementation-verification.md)에 기록했다.
실제 mass/reduction/FEAST/procedure/HDF5 경로와 전체 실행을 확인했고 원본 eigen의 전체 c
residual 실패는 residual stopping으로 해소했다. [첫 구현 독립 검토](implementation-first-version-review.md)는
승인된5%·S3 보류 범위에서 PASS다. 실제512회 vendor 호출과 HDF5 close-error 주입은 수행하지
않았으며 대표 실패 경로·정적 대조의 범위를 보고서에 기록했다. 기존 nonlinear recovery 문제와
제외 pressure 예제의 coverage 부재를 해결한 것으로 해석하지 않는다.
## 이전 문서 단계의 결과와 구현 입력
Research부터 I/O까지 요청한 문서 작업과 독립 수학 검산을 30분 제한 안에 완료했다.
19개 Feature 문서의 링크·UTF-8·diff와 27개 요구/검증 case identity·coverage를 확인했다.
기존 Feature/phase의 사용자 변경 16개는 보존했다. Source·test·config·reference는 변경하지 않았다.
다음 작업의 입력은 [정식화](formulation.md), [독립 검토](numerical-review.md),
[controls](numerical-review-controls.md), [cases](numerical-review-cases.md), [I/O](io.md)다.
문서 단계 종료 당시 Density/Frequency semantic·mass/FEAST·eigen state/writer 구현, 실제
backend와 MSVC build/test·reference·물리 검증은 미실행이었다. 현재 사용자가 승인한 구현은
[implementation-plan](implementation-plan.md)에 따라 이 후속 실행을 포함하며, 진행 상태는
위 checklist를 따른다. Pressure 제외 예제의 fresh 외부 coverage 부재는 유지한다.
[실행 보고서](implementation-verification.md)와 [구현 독립 검토](implementation-review.md)는
당시 명령·수치·수정 전 실패·실제 주입 범위를 기록한다. 실제512회 vendor 호출과 HDF5
close-error 전체 주입은 하지 않았다. 이후 통합 회귀는 [전체 현황](../tracking/status.md)이
연결하며 첫 구현 범위를 release 또는 임의 모델 정확도 보증으로 확대하지 않는다.
+38
View File
@@ -0,0 +1,38 @@
# MITC4 질량·FEAST 고유치해석
## 목적과 개발 결과
MITC4 consistent mass에서 유도한 nodal block lumping, 공변 drilling stabilization,
실제 경계조건을 먼저 적용하는 finite-space reduction과 실제 MKL FEAST를 구현했다.
사용자 승인 첫 구현 범위에서 2026-09-10 전체 417/417 PASS 기록이 있다.
현재 통합 회귀와 이 기능 당시의 검증은 [전체 현황](../tracking/status.md)에서 구분한다.
## 계약과 사용법
- [PRD](PRD.md)·[ADR](ADR.md): 모드별 외부5% 수용, residual stopping, S3 후속 보류.
- [요구사항](requirements.md#requirements): MFE2 ID·verification matrix와 이전 MFE 대응.
- [정식화](formulation.md), [질량·stabilization](formulation-mass-stabilization.md),
[축소·FEAST](formulation-eigen.md): 물리 질량·drill null·constraint-first 축소.
- [I/O](io.md#io): Density/Frequency keyword·N·결과 source/mode identity·HDF5 controls.
- [Reference](reference-model.md): Value-only 대응과 승인 first-implementation policy.
- [내부 수치 기준](numerical-review-controls.md), [검증 사례](numerical-review-cases.md),
[독립 수학 검산](numerical-review.md#numerical-review), [연구](research.md#research).
- [실행 결과](implementation-verification.md), [구현 독립 검토·교훈](implementation-review.md).
실행 환경·CLI는 [operations](../operations.md)를 따른다. Keyword/option 허용 범위와
HDF5 control 값은 I/O 계약을 확인한다. 외부5% 정책을 다른 해석의 RMS1%에 확대하지 않는다.
## 재사용 Handoff
질량·축소·FEAST state는 frequency의 소유다. HHT의 consistent kinetic mass를 이 lumped
modal 질량으로 대체하지 않는다. Partial rotational BC를 full clamp로 바꾸거나 임의
drilling inertia를 추가하지 않는다. 이전 MFE 유도의 채택 경계는 정식화 표를 따른다.
실제 public core·private backend 경계는 [ARCHITECTURE](../ARCHITECTURE.md)에 연결한다.
## 실패와 남은 범위
Trace stopping은 전체 c개의 독립 residual을 만족하지 못했고 C-index `fpm[5]=0`의
residual stopping으로 수정했다. 초기 외부 RMS1% 불일치는 사용자 승인 후 첫 구현
policy로 판정했으며 과거 실패 기록을 바꾸지 않았다. 최대 외부 상대차는 약4.261331%다.
S3 public static 평형 충돌과 Abaqus Value 정확도 개선은 보류다. 실제512회 vendor 호출·
HDF5 close-error 전체 주입 및 모든 모델의 정확도를 검증했다고 주장하지 않는다.
@@ -2,7 +2,7 @@
Feature `mitc4-shell-feast-eigen2`, formulation r1. [기본 보고서](formulation.md)와
[질량·stabilization](formulation-mass-stabilization.md)의 기호를 사용한다.
Intel evidence는 [research R04/G01/G02](research-evidence.md)에 따른다.
Intel evidence는 [research R04/G01/G02](research.md#research-evidence)에 따른다.
## E1. 실제 BC를 먼저 적용한다
+13 -16
View File
@@ -1,7 +1,7 @@
# MITC4 질량·공변 stabilization·FEAST 정식화
- Feature: `mitc4-shell-feast-eigen2`; Owner: `formulation-agent`; 정식화 revision: `r1`.
- 입력: [requirements r1](requirements.md), [근거](requirements-evidence.md), [Feature ADR](ADR.md).
- 입력: [requirements r1](requirements.md#requirements), [근거](requirements.md#requirements-evidence), [Feature ADR](ADR.md).
- 기준: [프로젝트 지침](../../AGENTS.md), [PRD](../PRD.md), [ADR-028](../ADR.md#adr-028), [ARCHITECTURE](../ARCHITECTURE.md).
- 상태: 독립 numerical review에 인계하는 수학 계약. 구현·runtime·reference 통과 선언이 아니다.
@@ -31,14 +31,14 @@ Numerical scale은 초기 physical rotary diagonal 8개 trace 평균의 `10^-3`
| 이전 자료 | 이번 채택 | 이번에 채택하지 않는 부분 |
| --- | --- | --- |
| [mass M1–M10](../mitc4-shell-feast-eigen/formulation-mass.md) | 동일 geometry·H 보간, moments, 27점 정확성, block lumping 및 Jensen identity; 새 상세에 재기재 | 이전 revision·readiness 진술 |
| [stabilization S1–S6](../mitc4-shell-feast-eigen/formulation-stabilization.md) | trace 평균 후보를 이번 식으로 선택; 공변성, frozen objective potential, 반례 exact target | S7의 옛 reference portfolio 및 과거 해소 판정 |
| [eigen E1–E5/E8](../mitc4-shell-feast-eigen/formulation-eigen.md) | constraint-first analytic split, nodal whitening, global recovery 원리 | E6/E7의 빈 count 성공 가정·기존 수치 controls 자동 승계 |
| [verification V1–V5](../mitc4-shell-feast-eigen/formulation-verification.md) | 같은 단위의 residual/Gram·energy·covariance·density 측정량 | 기존 tolerance 값·test 수·gate·실행 portfolio |
| [mass M1–M10](../mitc4-shell-feast-eigen/formulation.md#formulation-mass) | 동일 geometry·H 보간, moments, 27점 정확성, block lumping 및 Jensen identity; 새 상세에 재기재 | 이전 revision·readiness 진술 |
| [stabilization S1–S6](../mitc4-shell-feast-eigen/formulation.md#formulation-stabilization) | trace 평균 후보를 이번 식으로 선택; 공변성, frozen objective potential, 반례 exact target | S7의 옛 reference portfolio 및 과거 해소 판정 |
| [eigen E1–E5/E8](../mitc4-shell-feast-eigen/formulation.md#formulation-eigen) | constraint-first analytic split, nodal whitening, global recovery 원리 | E6/E7의 빈 count 성공 가정·기존 수치 controls 자동 승계 |
| [verification V1–V5](../mitc4-shell-feast-eigen/formulation.md#formulation-verification) | 같은 단위의 residual/Gram·energy·covariance·density 측정량 | 기존 tolerance 값·test 수·gate·실행 portfolio |
질량 및 trace 평균은 FESA 운동학에서 유도한 선택이다. 외부 source가 이 lumping/scale을
지정한다고 주장하지 않는다. 최신 API 근거와 검토 한계는 [research](research.md)와
[research evidence](research-evidence.md)에 연결한다. FEAST count의 `fpm[49]=1`과
지정한다고 주장하지 않는다. 최신 API 근거와 검토 한계는 [research](research.md#research)와
[research evidence](research.md#research-evidence)에 연결한다. FEAST count의 `fpm[49]=1`과
residual stopping의 `fpm[5]=0`은 C-index다. 종료 제어는 [ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)과
[controls C5](numerical-review-controls.md#c5-fixed-lower-enclosure와-bounded-upper-search)의 승인된 변경을 적용한다.
빈 count interval의 `info=0,m0=0`과 작은
@@ -53,16 +53,13 @@ scratch 허용은 보장된 vendor 계약으로 채택하지 않는다.
같은 물리 partial BC 및 admissible tangent moment를 사용하는 정적 대응도 검사한다.
Nonlinear scale immutability·objective energy·일관 residual/Hessian·선형극한을 재검증한다.
외부 portfolio는 오직 새 [requirements의 지정 범위](requirements.md)를 따른다.
외부 portfolio는 오직 새 [requirements의 지정 범위](requirements.md#requirements)를 따른다.
`shell`, `shellNL`, `shellNL-eigen-meshfine`의 retained 의무와 synthetic 내부 검사를 유지한다.
제외된 네 예제는 원본·복사본·cache·과거 결과로 재사용하지 않는다. Eigen 외부 비교는
원본 TXT의 `Value`이며 [공통 tolerance](../TOLERANCE.md)를 변경하지 않는다.
NR가 내부 수치 기준, FEAST control·endpoint separation·bounded call budget·seed를
독립 검토하여 고정해야 한다. 실제 설치 runtime의 count/solve·zero/cluster/full-capacity
동작과 memory는 후속 실행 evidence다. Numerical review 전 수학적 correctness를
스스로 승인하지 않는다. I/O owner는 입력 allowlist, result schema·identity 및 실패 진단을
정의한다. 이 문서는 신규 physical scope 또는 영속 layout을 추가하지 않는다.
문서 작업에는 build/test를 실행하지 않는다. 링크·식·소스 경계의 정적 대조를 수행하며
실제 solver·reference 검증은 미실행으로 남긴다.
내부 수치 기준, FEAST control·endpoint separation·bounded call budget·seed의 독립 판정은
[numerical review](numerical-review.md)와 [controls](numerical-review-controls.md)에 기록했다.
입력 allowlist, result schema·identity 및 실패 진단은 [I/O](io.md)를 따른다.
실제 설치 runtime·reference 결과와 미실행 한계는 [구현 검증](implementation-verification.md),
S3 후속 범위는 [현재 PRD](PRD.md)에 기록했다. 이 수학 계약 자체를 실행 통과로 해석하지 않는다.
@@ -1,71 +0,0 @@
# 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-schema.md), [TOLERANCE](../TOLERANCE.md).
## 판단과 필요한 확인
| 항목 | 독립 판단 |
| --- | --- |
| 종료 기준 | [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를 중복 실행하지 않고 메인의 실행 로그를 대조했다.
## 새 실행 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 완료로 확장하지 않는다.
## 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-numerical-review.md)의 별도 제한으로 남는다.
@@ -1,67 +0,0 @@
# 첫 구현 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).
## 승인 경계와 수치 판단
원본 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-feast-residual-review.md)의 원본 최대 Value 오차
`4.2613310845%`는 승인된 새 5% 범위 안이다. 새 comparator의 실제 focused 실행에서
원본 10개 family가 통과했다. 기존 1% FAIL 기록은 당시 판정으로 보존한다. 수식·DOF·단위·적분·
mass·whitening·복구·state update는 이번 외부 정책으로 바뀌지 않는다.
## 필수 보강과 추가 검증 한계
| 분류 | 요구·현재 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 결과를 대조한다.
## 실행 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-evidence.md)의 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-physics-review.md)의 기존
nonlinear recovery 제한도 이 변경으로 해소됐다고 주장하지 않는다.
@@ -1,99 +0,0 @@
# 수정 전 구현 수치 검토 기록
아래는 최초 검토 당시 관찰이다. 현재 판정·수정 상태는 [현재 보고서](implementation-numerical-review.md)를 따른다.
# 구현 독립 수치 검토
- 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), [공통 tolerance](../TOLERANCE.md).
## 수정 사항
### 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 계약 변경은 필요하지 않다.
### 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을 함께 연결하여 고정 절대 단위에 의존하지 않음을 확인한다.
## 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의 성공 또는 실패를 새로 주장하지 않는다.
## 정적 대조에서 일치한 구현
| 경로·행 | 확인 내용 |
| --- | --- |
| [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와 연결해야 함 |
## 아직 연결해야 하는 검증
다음은 할당된 [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는 이번 할당 파일 범위 밖의 후속 연결 사항이다.
## 실행 경계와 잔여 위험
이번에는 문서·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다.
@@ -1,65 +0,0 @@
# S3 partial-BC 정적 평형 불일치
- Feature: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; 검토일: `2026-09-09`.
- Finding: **NR-IMP-10 / upstream-contract-conflict**. [현재 보고서](implementation-numerical-review.md)의 추가 검토다.
- 입력: [S3 정식화](formulation-mass-stabilization.md), [E2-C09](numerical-review-cases.md), 채택 [C7](../mitc4-shell-feast-eigen/numerical-review-controls.md), 기존 [linear formulation §14.1](../linear-static-mitc4-shell/formulation.md), [linear I/O §6.5](../linear-static-mitc4-shell/io.md).
## 독립 수치 결론
`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-evidence.md)의 첫 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 재실행이 아니다.
## 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 진단으로 바꾼 결정은 아니다.
@@ -1,100 +0,0 @@
# 구현 독립 수치 검토
- 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), [공통 tolerance](../TOLERANCE.md).
- 최초 finding·scalar 반례는 [이전 검토 상세](implementation-numerical-review-history.md)에 보존한다. 아래는 후속 수정본에 대한 현재 판정이다.
## 이전 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 확인 |
## 최신 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은 별도로 남는다.
## 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 실패가 추가됐다.
## 원본 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 실행 경로를 대조했다.
## 남은 검증과 실행 경계
- **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-numerical-review-s3-static.md)을 참조한다. 메인은 수정된 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다.
@@ -1,60 +0,0 @@
# 구현 결과 물리 검토
- 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 승인을 만들지 않는다.
## 직접 확인한 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), 같은 폴더 `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) |
| 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/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 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:1243)를 확인했다. 두께 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 물리 타당성을 주장할 수 없다.
## 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-numerical-review-s3-static.md)의 `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 결함 분리 추적이다.
@@ -1,46 +0,0 @@
# MITC4 eigen 구현 계획
- Feature: `mitc4-shell-feast-eigen2`; Owner: 메인 assistant.
- 기준: [프로젝트 지침](../../AGENTS.md), [PRD](../PRD.md), [ADR](../ADR.md),
[정식화](formulation.md), [NR controls](numerical-review-controls.md),
[검증 사례](numerical-review-cases.md), [I/O](io.md).
- 실행 권한·현재 checklist는 [Feature PRD](PRD.md), 시간 제한 해제는 [Feature ADR](ADR.md)의 ADR-009를 따른다.
## 변경 묶음과 소유권
| 묶음 | Owner / 실제 경로 | 구현과 검증 |
| --- | --- | --- |
| 질량·stabilization | implementation-agent `eigen2_mass_impl`; `include/fesa/elements/mitc4_shell.h`, `src/fesa/elements/mitc4_shell.cpp`, 해당 element unit tests | 27점 consistent moments→derived lumped, trace mean. 독립 flat/warped mass, drill null·좌표/부분 BC와 기존 물리 kernel 검사 |
| FEAST backend | implementation-agent `eigen2_feast_impl`; 새 `include/fesa/solvers/eigen/`, `src/fesa/solvers/eigen/`와 unit tests | 실제 MKL 호출, fixed-lower count/search, controls·checked storage·all-c 검증·실패 evidence. 실제 known spectra/zero/repeated/endpoint 및 thread 복원 |
| 입력·Domain | implementation-agent `eigen2_input_impl`; `model_types.h`, `domain.h/.cpp`, `domain_mapping_context.cpp`, eigen mapper/model tests | Material별 density, 독립 Frequency payload와 common boundary view, source Step-2/N 보존, exact allowlist와 fail-closed 진단 |
| 축소·procedure·state | 메인; 새 `analysis/eigen_*`, 관련 `AnalysisModel`/`DofManager`/prepared/application 연결 | 실제 BC→analytic null→nodal SPD whitening, sparse congruence, original-free 복구·정규화/Gram/에너지, 후보 state. 작은 직접 pencil 및 partial-BC 통합 검증 |
| 결과·비교·회귀 | 메인 또는 후속 명시 할당 owner; 새 eigen HDF5 writer/self-check, eigen reference comparator, 해당 tests와 기존 제외 inventory 변경 | Static schema 유지, source identity·N/c 구분, candidate 보존, TXT Value-only 공통 tolerance, retained static와 synthetic coverage |
| 빌드·Git·Feature 기록 | 메인; `src/fesa/CMakeLists.txt`, `tests/CMakeLists.txt`, 이 Feature의 관리/결과 문서 | 동시 빌드 충돌 방지, 명시 경로별 stage/commit, 사용자 변경 보존 |
서로 다른 owner의 파일을 덮어쓰지 않는다. Shared API는 구현 전에 메인에 전달하고 불일치는
계약 원본과 대조하여 수정한다. Vendor type은 private adapter에만 둔다. 이미 승인된 수식을
다시 선택하거나 시간 절약을 위해 dense global Schur·인공 mass·lower mode 누락을 허용하지 않는다.
## 검증 순서
1. 현재 설정의 configure/build와 검사 inventory를 확인한다. 가능한 결함 재현 후 최소 수정하고
[27개 사례](numerical-review-cases.md)와 [IO-T01–11](io.md)에 각 테스트를 연결한다.
2. 묶음별 unit/integration 검사를 실행한다. Actual FEAST probe는 mock으로 대체하지 않는다.
수학/자료 조립을 변경하면 필요한 독립 numerical 검토를 받는다.
3. CLI→원본 입력→HDF5→TXT Value comparison을 fresh 실행한다. 원본 TXT/CSV를 수정하거나
제외 예제의 옛 경로·복사본·cache로 성공 evidence를 만들지 않는다.
4. 영향받는 shell/shellNL/linear-limit, nonlinear tangent/objectivity/평형·state,
pressure synthetic·기타 기존 회귀를 보존한다. 제외된 복합 테스트의 retained 관찰은 분리한다.
5. 기능 완료 시 구성된 전체 build/test와 필수 reference를 한 번 실행하고 독립 물리 검토와
실제 결과·실패·미실행을 기록한다. 실패 수치를 expected로 복사하지 않는다. 외부 고유치
기준은 [ADR-012](ADR.md#mfe2-adr-012--첫-구현의-외부-고유치-5-수용)의 사용자 승인5%를 적용한다.
현재 `.harness/config.json`은 `mfe-workspace-msvc-ninja-debug` configure/build/test preset과
`.harness/build-ninja-msvc-debug`를 선택한다. 개인 preset의 dependency 경로는 commit하지 않는다.
Focused 실행은 해당 CMake target/CTest filter, 전체 검증은 `python scripts/execute.py`다.
메인이 빌드 실행을 직렬화한다. C++에는 MSVC x64 Debug `/W4 /WX` 기준을 적용한다.
실제 runtime·known spectra와 원본 모델을 실행했다. 현재 결과·수정 범위와 미완료 검증은
[implementation-verification](implementation-verification.md)에 기록한다. All-c residual은
ADR-011의 residual stopping으로 해소했다. ADR-012의 첫 구현 범위에서 외부5% 비교와
필수 mass/실패 보존 evidence를 확인하며 S3는 명시된 후속 과제로 유지한다.
@@ -0,0 +1,519 @@
# 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 제한도 이 변경으로 해소됐다고 주장하지 않는다.
@@ -4,10 +4,10 @@
- 현재 판정: **사용자 승인 첫 구현 범위 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).
- 독립 검토: [수치](implementation-numerical-review.md),
[S3 정적 계약](implementation-numerical-review-s3-static.md),
[물리](implementation-physics-review.md), [FEAST 종료 변경](implementation-feast-residual-review.md), [첫 구현 최종 검토](implementation-first-version-review.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% 수용과 검증 보강
@@ -49,7 +49,7 @@ Close 실패는 기존 checked-close→exception→candidate 정리/기존 final
추가 테스트 작성 중 nested initializer와 lambda capture의 컴파일 오류를 수정한 뒤 MSVC x64
Debug build가 성공했다. 실패한 빌드 뒤 등록되지 않은 테스트의 `No tests were found`를 PASS로
계산하지 않았다. [첫 구현 독립 검토](implementation-first-version-review.md)는 새 oracle와
계산하지 않았다. [첫 구현 독립 검토](implementation-review.md#implementation-first-version-review)는 새 oracle와
failure/acceptance evidence·전체 실행을 대조하고 **사용자 승인 첫 구현 범위 PASS**로 판정했다.
임의 모델 정확도나 외부 release를 보장하는 판정은 아니다.
@@ -79,7 +79,7 @@ Read-only 추출 스크립트와 JSON은 최종적으로 ignored build directory
그 directory의 `feast-residual-metrics.json`과 `feast-residual-full-metrics.json`이 각 실행의 기록이다.
개인 환경·추출 스크립트·기계 생성 로그/결과는 커밋하지 않는다. 이 작업에서 Python Harness suite는 실행하지 않았다.
원본 [결과 HDF5](../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine_results.h5)는
원본 결과 HDF5(당시 경로: `../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine_results.h5`, 현재 checkout에 없음)는
이번 실제 해석이 새로 생성한 공식 sibling output이다. 생성과 closed-file self-check는 성공했고,
기존 외부 INP/TXT의 실행 전후 bytes는 reference test에서 보존을 확인했다.
-140
View File
@@ -1,140 +0,0 @@
# MITC4 eigen 입력·진단 계약
- Feature ID: `mitc4-shell-feast-eigen2`
- Owner: `io-definition-agent`
- Contract revision: `r1`
- 기본 보고서: [io.md](io.md)
## 문법과 기존 지원 범위
기존 [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로 축소하지 않는다.
## 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로 검증한다.
## 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 내부 구현의 동등성을 주장하지 않는다.
## 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를 추정하지 않는다.
## 진단
기존 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-mapping.md#실패와-공개-lifecycle) | 5 |
| Log/candidate/self-check/finalization | 기존 output category | 6 |
Usage2/success0와 stderr escaping은 기존 공통 CLI 계약이다. 지원되는 입력의 conditioning
실패를 input subset 축소나 인공 mass/zero clamp로 우회하지 않는다.
-138
View File
@@ -1,138 +0,0 @@
# MITC4 eigen 내부 mapping·reference projection
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `io-definition-agent`; Contract revision: `r2` (외부 Value acceptance만 변경).
- 기본 보고서: [io.md](io.md). 수학 원본: [formulation-eigen](formulation-eigen.md).
## 내부 소유권과 identity
| Owner | 필수 의미와 mapping |
| --- | --- |
| ParsedInput | 실제 input bytes의 기존 content identity, lexical path, keyword/parameter presence·raw 값·빈 data slot·source line |
| Domain | 전체 geometry/source topology, section→material→constant rho, 원형상 director, homogeneous BC, sole Frequency definition; 파싱 후 가능한 불변 |
| Frequency definition | source step raw/canonical name, step/Frequency/data 위치, requested N, 각 option의 explicit presence/effective value, no-op warning inventory; storage Step-1과 구별 |
| AnalysisModel | Domain보다 짧은 수명의 활성 shell/material/section/BC/procedure const non-owning view |
| DofManager | Source node×고정 6 DOF, full/free/constrained injection, stable equation IDs/scatter/sparse pattern; Node/Element에 equation ID를 저장하지 않음 |
| Assembly/procedure | 실제 consistent moment→derived lumped→개선 K, 같은 source scatter/reduction; E1~E7의 constraint-first split·whitening·FEAST·복구·all-c validation |
| Private backend | Vendor CSR/index/workspace/FEAST control·runtime·call evidence; MKL type/header를 public core에 노출하지 않음 |
| Eigen state | Candidate/accepted 분리, N개의 paired raw scalar/global vectors, source mapping, c개 validation evidence; static/Newton state를 mode count로 재사용하지 않음 |
| ResultsWriter | Validated state serialization→closed candidate self-check→final replacement; 물리값·identity 재계산/보정으로 실패를 숨기지 않음 |
Source `(instance_name,numeric source label)`과 raw spelling, internal model row, free equation
index, FEAST column, sorted rank, public mode ID는 별개다. Instance expansion/declaration의 기존
model 순서와 DOF `UX,UY,UZ,URX,URY,URZ` 순서를 유지한다. Source renumbering 비교는
geometry/connectivity/BC 대응을 함께 사용하며 숫자가 우연히 같은 internal ID를 source key로
대체하지 않는다. Repeated eigenvalues는 별개 rank이며 특정 vector 방향의 유일성을 요구하지 않는다.
Raw consistent 계산을 lumped로 덮어쓰지 않는다. Global dense mass dump는 필수 결과가 아니다.
실제 constrained free space에서만 analytic null을 제거하며 tiny positive mass를 rank cutoff로
삭제하지 않는다. `requested N`, finite dimension n, count의 overwritten m0, allocated m0,
solve returned m, validated c, public N을 각기 보존한다. 모든 c를 검증한 뒤 첫 N을 공개한다.
## 실패와 공개 lifecycle
Public CLI·path·lock·log는 [현재 공통 계약 §7.1](../nonlinear-static-newton-raphson/io.md#71-public-output-names-log-and-lifecycle)을
유지한다. `fesa.exe <model.inp>`이며 output override를 추가하지 않는다. Input lexical sibling은
`<stem>_results.h5`와 `<stem>_log.txt`다. 마지막 `.inp` extension만 제거하고 basename case·
앞선 dot은 보존한다. Symlink/junction을 resolve해 결과 위치를 바꾸지 않는다.
1. Usage 검증→derived pair의 exclusive nonblocking ownership→live log open/truncate.
2. Parse/model/solve/all-c validation을 candidate에서 수행한다. 기존 accepted state/final은 유지한다.
3. Candidate state를 완성하고 log close 성공을 확인한다. 같은 directory의 exclusive-create private
HDF5 candidate를 write/flush/close/reopen/self-check하고 모든 handle을 닫는다.
4. Final replace가 성공한 뒤 준비된 state를 no-fail swap한다. 이후 allocation/validation/callback
failure를 남기지 않는다. 실패 candidate는 authoritative 결과가 아니다.
제어된 solve/validation/write/flush/close/reopen/self-check/replace 실패에서 이전 valid final과
state를 보존한다. 이전 final이 없으면 만들지 않는다. Log는 별도 live lifecycle이며 rollback하지
않는다. Eigen log에는 Newton iteration/FEAST trace를 새로 쓰지 않고 정상 log는 zero-byte다.
Backend evidence는 아래 result/Status에 둔다. Lock 실패는 기존 log/final도 건드리지 않는다.
Candidate 정리는 best effort이며 다른 run 파일을 삭제하지 않는다. Crash/power-loss 전체 원자성은
약속하지 않는다. Reference `.inp`/TXT/CSV는 read-only이며 output으로 덮어쓰지 않는다.
| Solver 실패 / exit5 | Stable code·필수 context |
| --- | --- |
| Analytic mass space·null identity 오류 | invalid-eigen-mass-space: node/DOF/n/nz·실패 identity |
| Positive block conditioning 실패 | eigen-mass-conditioning: node·metric·관측값·NR limit |
| Checked index/capacity 또는 CSR | eigen-index-overflow / invalid-eigen-csr: n,nnz,N,m0와 실패 bound |
| Workspace allocation | eigen-allocation-failed: 역할·checked byte request; N 축소 없음 |
| Fatal FEAST status | eigen-feast-failed: raw info, call kind/ordinal, interval, allocated m0 |
| Count/solve 수·monotonicity 불일치 | eigen-count-inconsistent: 실제 count history·certified interval |
| Endpoint separation | eigen-endpoint-separation: raw endpoints·nearest returned value·NR limit |
| Mandatory search budget 소진 | eigen-search-budget-exhausted: attempts·마지막 safe bracket·fallback 가능 여부 |
| Significant negative spectrum | negative-eigenvalue-spectrum: raw lambda/mu/s·rank·NR limit |
| Nonfinite/invalid conversion/frequency | invalid-eigenvalue-result: raw quantity·stage·source step |
| Pair/Gram/original-free residual/energy 실패 | eigenpair-validation-failed: metric·value·limit·solver column/rank |
선택적 upper-prefix 최적화에서 인증되지 않은 empty/count status는 count0으로 바꾸지 않는다.
Formulation E4와 NR가 허용한 safe bracket fallback은 실패를 은폐한 성공 count가 아니며
actual attempted call·종료 이유를 evidence에 남긴다. Mandatory final count/solve/validation 실패는
부분 결과로 성공하지 않는다. Count workspace의 작은/null scratch를 문헌 보장으로 가정하지 않는다.
Failure Status는 Frequency 위치와 지금까지의 chronological call context를 포함한다.
Undefined vendor outputs는 읽지 않고 unavailable로 표시한다. Allocation 실패의 부속 message
생성은 기존 best-effort diagnostic 한계를 따른다.
## 원본 TXT grammar와 prechecks
Input은 `reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp`, reference는 같은 폴더의
`shellNL-eigen-meshfine eigenvalues.txt`다. 이름 변경, TXT rewrite, CSV 변환, companion
README/metadata/version/provenance 추가를 요구하지 않는다. TXT에 step이 없으므로 지정 input의
**유일한 frequency source step Step-2**에 대응한다. 이름에서 ODB frame index를 추정하지 않는다.
LF/CRLF logical line에서 space/tab-only 행은 건너뛴다. 나머지는 아래 case-sensitive full-match다.
`ws=[ \t]*`, `ws1=[ \t]+`; id는 checked positive int64 decimal이다.
```text
number := [+-]?(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)(?:[Ee][+-]?[0-9]+)?
id := [0-9]+
row := ws 'Frame:' ws1 'Mode' ws1 id ':' ws1 'Value' ws '=' ws number
ws1 'Freq' ws '=' ws number ws1 '(cycles/time)' ws
```
Header/footer/comment/BOM/extra token/malformed row는 schema 실패다. Value는 finite binary64
full conversion이며 range error를 거부한다. Freq는 숫자 token 구조만 검사하며 수치 변환·
물리 일치·오차 판정에 사용하지 않는다. Freq에서 Value를 재구성하지 않는다. 같은 numeric mode
ID의 재등장은 duplicate이며 같은 Value의 다른 mode는 정상이다.
Tolerance 전에 다음을 순서대로 완료한다.
1. 지정 input/TXT와 HDF5 존재, eigen discriminator, source_input_identity를 현재 입력의
lexical path와 기존 byte-content identity에 대조한다. Static output·unknown eigen schema를 거부한다.
2. Input sole source step/N을 직접 읽어 HDF5 source step·requested/public count와 대응한다.
N을 TXT row 수나 검증 c에서 추론하지 않는다. 현재 양쪽 required mode inventory는 1..10이다.
3. TXT 모든 nonblank row를 parse하고 duplicate/missing/extra/nonfinite를 거부한다. Malformed-row
skip/dictionary overwrite/값 sorting으로 source mode identity를 바꾸지 않는다.
4. HDF5 mandatory dataset/type/shape, units·quantity·실제 backend·mass variant·normalization,
source/model identities, modes ID 1..N, paired vector shape, raw eigenvalue finite를 검사한다.
HDF5 순서 오류는 reader 재정렬로 숨기지 않는다. 값이 같아도 ID가 다르면 multiplicity다.
5. `(case,source_step_name,mode_id,component=Value)`로 one-to-one join하고 mode ID 순서로 출력한다.
TXT row reorder는 허용한다. `modes.eigenvalue`만 FESA scalar authority다. c개 검증 table,
frequencies, vectors 또는 static fields에서 fallback하지 않는다.
## Family와 보고
[NR reference-model](reference-model.md)이 정의하는 family는 `(case,source step,modal-frame=mode_id,quantity=eigenvalue,
dimension=time^-2,coordinates=scalar,impact=blocking)`다. Mode별 frame은 10개 singleton
family이며 하나의 storage table이라고 서로 합치지 않는다. 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)의
retained shell/shellNL/linear-limit portfolio와 기존 source step/frame·U blocking·UR warning-only,
nonlinear reaction review-only 의미를 유지한다. 제외 네 예제는 원본·복사·cache로도 사용하지 않는다.
-182
View File
@@ -1,182 +0,0 @@
# MITC4 eigen authoritative HDF5 schema
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `io-definition-agent`; Contract revision: `r1`.
- 기본 보고서: [io.md](io.md). 수치 원본: [formulation-eigen](formulation-eigen.md),
[NR controls](numerical-review-controls.md).
## 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는 최종 전체 검증 수다.
## 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로 추적한다.
## 공개 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 비교를 유발하지 않는다.
## 전체 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 계약을 함께 재검토해야 한다.
## 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 계산을 통과로 인정하지 않는다.
+513 -15
View File
@@ -1,12 +1,20 @@
# MITC4 eigen I/O 계약
# 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), [formulation r1](formulation.md).
- 입력 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
@@ -23,20 +31,22 @@ N개의 global mass-normalized vectors는 내부 검증을 위해 필수이며
| 상세 문서 | 권위와 내용 |
| --- | --- |
| [io-input](io-input.md) | Supported syntax/defaults, source scope, rho/BC mapping, no-op allowlist, fail-closed diagnostics |
| [io-schema](io-schema.md) | Authoritative HDF5 types/shapes/units, source step·mode identity, all-c evidence, self-check |
| [io-mapping](io-mapping.md) | Domain/AnalysisModel/DOF/state ownership, candidate/failure lifecycle, TXT grammar·prechecks·Value projection |
| [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-input.md#step와-frequency)를 직접 대조했다.
공개 Abaqus convention은 [입력 문서의 공식 출처](io.md#io-input--step와-frequency)를 직접 대조했다.
Lanczos/SIM은 source compatibility 정보이며 실제 algorithm 동등성을 주장하지 않는다.
ACOUSTIC COUPLING=ON은 acoustic-free 모델에서만 적용 대상 없음으로 처리한다.
물리량은 사용자 일관 units이며 SI로 추론하지 않는다. Meaningful unsupported input은 실패한다.
## 현재 source와의 차이
<a id="io--현재-source와의-차이"></a>
### 설계 당시 source와의 차이
2026-09-08 지정 source를 읽기 전용으로 직접 확인했다. 아래는 후속 구현 의무이며 현재
동작이 구현되었다는 의미가 아니다. 기존 Feature 문서의 pass·workflow·trace schema는 승계하지 않았다.
2026-09-08 설계 당시 지정 source를 읽기 전용으로 확인한 기록이다. 아래 표는 당시의
미구현 연결을 설명하며 현재 구현 상태를 뜻하지 않는다. 연결 후 실행 결과와 남은 한계는
[구현 검증](implementation-verification.md)을 따른다. 기존 Feature의 pass를 승계하지 않았다.
| 실제 확인 파일 | 확인 결과와 필요한 연결 |
| --- | --- |
@@ -46,10 +56,11 @@ ACOUSTIC COUPLING=ON은 acoustic-free 모델에서만 적용 대상 없음으로
| [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)와 연결된 상세가 권위다.
집계하지 않는다. 수치 기준·oracle는 [NR](numerical-review.md#numerical-review)와 연결된 상세가 권위다.
| ID | 필수 관찰 | Requirement suffix |
| --- | --- | --- |
@@ -65,7 +76,8 @@ Requirement prefix는 `FEM-REQ-MITC4-EIGEN2-`다. 아래 검증을 문서 작업
| 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를 대조했다.
@@ -75,9 +87,10 @@ optional upper search 종료·certified fallback, normalized final phi metrics
변경은 없다. 새 mode shape 외부 acceptance, CSV mandate, reference 보조 metadata, full matrix
mandatory dump, lower/empty-prefix 검색 schema를 추가하지 않았다.
현재 source의 density/Frequency/state/writer 연결은 미구현이다. Research G01/G02의 installed
이 I/O 정의를 작성할 당시 density/Frequency/state/writer 연결은 미구현이었다. Research G01/G02의 installed
FEAST 동작·workspace와 실제 peak memory, retained regression/새 eigen reference 및 physics
검증은 후속 실행 의무다. Safe enclosure fallback이 runtime 확인을 대신하지 않는다.
검증은 당시 후속 실행 의무였다. 현재 실행·미실행 범위는 [구현 검증](implementation-verification.md)에
기록했다. Safe enclosure fallback이 runtime 확인을 대신하지 않는다.
문서만 수정하므로 build/test/Harness/FEAST/외부 solver를 실행하지 않았다. Source/test/reference와
제외 네 예제의 원본·복사·cache는 수정·검증에 사용하지 않았다.
@@ -85,3 +98,488 @@ FEAST 동작·workspace와 실제 peak memory, retained regression/새 eigen ref
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,11 +1,11 @@
# 필수 검증 사례와 요구사항 연결
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; revision `r2` (2026-09-10, E2-C25의 승인된 첫 구현 profile 반영).
- 기본 보고서: [numerical-review](numerical-review.md); 판정 수치: [controls](numerical-review-controls.md).
- 아래는 구현의 필수 관찰이다. 문서 r1 시점의 실제 수학 oracle는 [evidence](numerical-review-evidence.md)이며,
최신 실행·미실행 분류는 [첫 구현 검토](implementation-first-version-review.md)를 따른다.
- 기본 보고서: [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-cases.md)의 synthetic fixture와
[이전 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는 채택하지 않는다.
@@ -46,7 +46,7 @@ E2-C17/18/22는 mock만으로 충족하지 않는다. E2-C21의 실패 주입은
설정하거나 동일 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-first-version-review.md)의 evidence와 구분한다.
이후 실행 여부는 [첫 구현 검토](implementation-review.md#implementation-first-version-review)의 evidence와 구분한다.
E2-C26은 excluded original/copied/cached examples를 절대로 사용하지 않는다.
제외된 혼합 시험에 있던 retained shellNL force/moment balance·free force/moment residual
@@ -1,20 +1,20 @@
# 내부 수치 기준과 FEAST controls
- Feature ID: `mitc4-shell-feast-eigen2`; Owner: `numerical-review-agent`; revision `r2` (2026-09-10, C5 종료 제어만 변경).
- 기본 보고서: [numerical-review](numerical-review.md); 수식: [새 formulation](formulation.md).
- 기본 보고서: [numerical-review](numerical-review.md#numerical-review); 수식: [새 formulation](formulation.md).
- IEEE binary64의 내부 검증 계약이며 [외부 TOLERANCE](../TOLERANCE.md)를 변경하지 않는다.
- 아래 `NOT RUN`은 r1 문서 검토 당시의 기록이다. 변경된 C5의 실제 실행 판정은
[종료 제어 구현 검토](implementation-feast-residual-review.md)를 따른다.
[종료 제어 구현 검토](implementation-review.md#implementation-feast-residual-review)를 따른다.
## C1–C4, C6, C7의 독립 검토 후 명시 채택
[이전 controls](../mitc4-shell-feast-eigen/numerical-review-controls.md)의 C1, C2-01~14와
[이전 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-verification.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`은 서로 다른 값이다.
@@ -64,7 +64,7 @@ residual stopping, CSR/SPD checks와 count flag reset을 확인했다. 위 값
그대로다. Vendor residual의 정규화와 독립 rho_B를 동일시하지 않으며 `info=0`도 독립 검증을
대체하지 않는다. `epsout`은 trace 변화 진단량으로 보존하고 새 residual 오차로 재해석하지 않는다.
기존 trace 실행의 pass/fail·loop·epsout은 당시 controls의 이력이다. Zero/mixed-zero/repeated
및 원본 모델의 새 실행과 미해결 위험은 [종료 제어 구현 검토](implementation-feast-residual-review.md)에
및 원본 모델의 새 실행과 미해결 위험은 [종료 제어 구현 검토](implementation-review.md#implementation-feast-residual-review)에
구분한다. S3·물리 정식화·공통 외부 tolerance는 이 결정으로 변경하지 않는다.
Gershgorin off-diagonal absolute row sum은 매 합산 뒤 `nextafter(+infinity)`로 outward
@@ -119,6 +119,6 @@ Count `x[n*n]`, `e[n]`, `res[n]` 보수 storage와 identity initial subspace를
container max_size 및 `min(SIZE_MAX,PTRDIFF_MAX)`를 overflow **전** 검사한다.
Global inverse를 만들지 않으며 allocation/shifted factorization 실패는 명시적으로 종료한다.
Count n² scratch는 최소 memory 보장이나 전체 peak memory 추정이 아니다.
[Research G01/G02](research-evidence.md)의 installed empty/occupied/endpoint/count reset,
[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,191 +0,0 @@
# 독립 수학 검산 evidence
- Feature ID: `mitc4-shell-feast-eigen2`
- Owner: `numerical-review-agent`
- 검토일: `2026-09-08`; 기본 보고서: [numerical-review](numerical-review.md).
- 대상: 새 requirement r1. 아래는 Python 표준 라이브러리만 사용하는 수학 검산이며 C++/FEAST 실행이 아니다.
## 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-evidence.md)의
평판 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)
```
## 독립 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)))
```
## 이번 실행 결과
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,12 +1,20 @@
# 독립 Numerical Review
# 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), [evidence](requirements-evidence.md),
[새 research](research.md), [새 formulation r1](formulation.md), [TOLERANCE](../TOLERANCE.md).
- 입력: [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개와 식·실패 경계를 대조했다.
@@ -25,13 +33,14 @@
| 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-evidence.md)에 있다.
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는 미채택.
@@ -46,7 +55,8 @@ I/O는 정확한 입력 allowlist·diagnostic·영속 HDF5 경로 및 source/mod
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**이다.
@@ -62,3 +72,200 @@ locking·accuracy, 27점 밖 geometry injectivity 및 floating count의 정확
확인된 수학 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,8 +1,8 @@
# 외부 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); 기준: [requirements](requirements.md), [TOLERANCE](../TOLERANCE.md).
- 판정: 승인된 비교 계약 갱신. 실제 최신 판정은 [첫 구현 검토](implementation-first-version-review.md)에 기록한다.
- 기본 보고서: [numerical-review](numerical-review.md#numerical-review); 기준: [requirements](requirements.md#requirements), [TOLERANCE](../TOLERANCE.md).
- 판정: 승인된 비교 계약 갱신. 실제 최신 판정은 [첫 구현 검토](implementation-review.md#implementation-first-version-review)에 기록한다.
## Eigen의 지정 원본과 logical identity
@@ -69,7 +69,7 @@ Required scalar Value의 finite 검사를 별도 Freq 비교로 대신하지 않
## 남는 static portfolio
아래는 [새 requirements](requirements.md)의 기존 acceptance 보존이며 eigen family와 섞지 않는다.
아래는 [새 requirements](requirements.md#requirements)의 기존 acceptance 보존이며 eigen family와 섞지 않는다.
| 역할 | 기존 원본과 비교 |
| --- | --- |
@@ -1,129 +0,0 @@
# 요구사항 근거와 적용 경계
- Feature ID: `mitc4-shell-feast-eigen2`
- Requirement baseline revision: `r1`
- Owner: `requirement-agent`
- 작성일: `2026-09-08`
- 원본: [requirements.md](requirements.md), 현재 작업: [PRD](PRD.md).
기준은 [프로젝트 지침](../../AGENTS.md), [프로젝트 PRD](../PRD.md),
[ADR-028](../ADR.md#adr-028), [새 Feature ADR](ADR.md)이다. 이 문서는 근거와 미실행을
구분하며 새 수학·구현 acceptance 승인이나 solver readiness 판정이 아니다.
## 근거의 종류와 재사용
| 근거 | 재사용하는 내용 | 이번 기준선으로 가져오지 않는 것 |
| --- | --- | --- |
| 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), [기존 evidence r3](../mitc4-shell-feast-eigen/requirements-evidence.md) | 27개 관찰 의무, 단위·identity·실패·남는 static/internal portfolio, 알려진 partial-BC 반례 | 기존 revision의 수식·threshold·영속 문자열이 새 Feature에 자동 승인되었다는 문구 |
| 기존 [research evidence](../mitc4-shell-feast-eigen/research-evidence.md), [formulation](../mitc4-shell-feast-eigen/formulation.md), [NR](../mitc4-shell-feast-eigen/numerical-review.md), [I/O](../mitc4-shell-feast-eigen/io.md) | 후속 전문 작업에서 필요한 근거·후보·반례를 찾을 위치 | 이번에 새로 조사·검토·검증한 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 의미를 교체하지 않는다.
## 기존 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 검증 |
## 현재 원본의 정적 관찰
아래는 메인이 `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#사용자-제외-예제)이며 과거 검사 개수나 cache로
현재 실행 검증을 대체하지 않는다.
## 후속 전문 판단과 사용자 결정 경계
아래는 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 완화로 충돌을 해소하지 않는다.
## 정적 확인과 미실행
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 작업은 변경하지 않았다.
+158 -10
View File
@@ -1,17 +1,24 @@
# MITC4 질량행렬·FEAST eigen 요구사항
# 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 기준 변경)
- Owner: `requirement-agent`
- 상태: 요구사항 기준선 작성. 구현·수치 검증 또는 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-evidence.md)에 둔다.
근거 구분·기존 ID 대응·미결정은 [requirements-evidence](requirements.md#requirements-evidence)에 둔다.
## 범위와 해석 의미
<a id="requirements--범위와-해석-의미"></a>
### 범위와 해석 의미
Consistent mass를 계산하고 그 결과로부터 lumped mass를 유도하며 실제 무감쇠 선형
고유진동 해석은 **derived lumped mass와 MKL FEAST**를 사용한다. 같은 lumped mass를
@@ -46,7 +53,8 @@ beam/solid/shell, concentrated/nonstructural mass, composite/offset/variable thi
별도 frequency interval/shift 사용자 기능, Lanczos/AMS 대체 backend, reference
생성·수정·복원과 외부 배포도 제외한다. Eigen 기능의 밀도 필수 조건을 기존 static에 확대하지 않는다.
## Requirement verification matrix
<a id="requirements--requirement-verification-matrix"></a>
### Requirement verification matrix
각 행은 하나의 관찰 의무이며 acceptance는 해당 요구와 검증 조건을 충족하는 것이다.
현재 요청은 이 의무를 정의하는 **requirement 단계만** 수행한다. 아래 검증은 후속 솔버
@@ -54,11 +62,11 @@ beam/solid/shell, concentrated/nonstructural mass, composite/offset/variable thi
I/O layout은 후속 전문 owner가 필요한 시점에 정의한다. 외부 tolerance는 공통 정책을 따른다.
출처: `U`=[새 Feature ADR](ADR.md)의 기존 명시 사용자 결정 적용,
`R`=[근거 문서](requirements-evidence.md)의 reference 관찰,
`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)의 같은 번호에 대응한다.
각 행은 [기존 r3](../mitc4-shell-feast-eigen/requirements.md#requirements)의 같은 번호에 대응한다.
| Requirement ID | Shall statement | 측정 가능한 acceptance / verification method | 출처·후속 owner |
| --- | --- | --- | --- |
@@ -90,7 +98,8 @@ I/O layout은 후속 전문 owner가 필요한 시점에 정의한다. 외부 to
| 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 |
## 지정 reference와 남는 검증 범위
<a id="requirements--지정-reference와-남는-검증-범위"></a>
### 지정 reference와 남는 검증 범위
Eigen input은 `reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp`, 외부 reference는
같은 폴더의 `shellNL-eigen-meshfine eigenvalues.txt`를 그대로 사용한다. 입력의
@@ -115,7 +124,8 @@ bitwise equality가 아니라 승인된 물리·identity·공통 정책으로
reaction의 local distribution 검토는 별개다. 알려진 partial-BC 반례를 full-free/full-clamp
사례만으로 대체하거나 실패 수치를 기대값으로 재생성해 정당화하지 않는다.
## 사용자 제외 예제
<a id="requirements--사용자-제외-예제"></a>
### 사용자 제외 예제
다음 네 예제는 `reference/temp/` 아래 원본뿐 아니라 옛 경로, 복사 input, cached HDF5·log·
추출 결과를 통한 검증에서도 제외한다. 원본 열람·artifact audit·solve·비교·복원 또는
@@ -133,10 +143,148 @@ reaction의 local distribution 검토는 별개다. 알려진 partial-BC 반례
명시적으로 보고한다. 과거 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 작업은 변경하지 않았다.
@@ -1,156 +0,0 @@
# 연구 근거·검증 후보·미해결 항목
- Feature ID: `mitc4-shell-feast-eigen2`
- Owner: `research-agent`
- Input baseline: `requirements r1`
- Web access date: `2026-09-08`
- Main report: [research.md](research.md)
`Fact`는 이번 원문 확인, `Inference`는 수학적 적용 판단, `Candidate`는 후속 채택 후보,
`Gap`은 아직 확인하지 못한 사항이다. 수식·threshold·schema의 최종 계약을 정하지 않는다.
## 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-mass.md), [eigen](../mitc4-shell-feast-eigen/formulation-eigen.md), [stabilization](../mitc4-shell-feast-eigen/formulation-stabilization.md), [연구](../mitc4-shell-feast-eigen/research-evidence.md) | 현재 worktree의 후보 유도·과거 근거 locator. 이번 독립 검증 또는 승인으로 간주하지 않음. |
| P02 | [요구사항](requirements.md), [요구 근거](requirements-evidence.md), [기존 nonlinear §10.3](../nonlinear-static-newton-raphson/formulation.md#103-fixed-scale-and-potential), [TOLERANCE](../TOLERANCE.md) | 요구·frozen lifecycle·acceptance 경계. 경험적 통과의 근거가 아님. |
## 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가 확정한다.
## 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로 성공 처리하지 않는다.
## 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 후보 기대값은 이번에 재계산하지 않았다.
## 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 소유다.
## 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-evidence.md)의 선행 정적 관찰이다.
**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을 정의한다.
## 정적 확인·미실행
원 논문·공식 웹 문서 접근과 위 지정 원본 두 파일의 읽기는 수행했다. 연구 문서의 상대
파일 링크 존재와 UTF-8 replacement 문자 부재를 Python으로 검사했고 exit `0`이었다.
기존 문서·reference·코드·threshold·schema를 수정하지 않았다.
이번 산출물은 두 연구 문서뿐이며 Git은 메인이 소유한다. Build/test·FEAST runtime·외부 solver·
reference 비교·독립 NR/Physics는 연구 범위 밖으로 미실행이다. Configured vault 요청이 없어
`fem-theory-query`를 사용하지 않았다. 제외 예제의 원본·복사·cache 열람과 재사용은 없다.
+181 -5
View File
@@ -1,17 +1,27 @@
# MITC4 질량·FEAST 연구 결과
# 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`
- Owner: `research-agent`
- Input baseline: `requirements r1`
- Research date: `2026-09-08`
- Status: `research evidence complete`; 현재 후속 작업 상태는 [PRD](PRD.md)의 checklist를 따른다.
[요구사항](requirements.md)과 [요구 근거](requirements-evidence.md)에 대한 연구다.
[요구사항](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-evidence.md)에 기록했다.
출처별 locator·조건·검증 후보·gap은 [상세 근거](research.md#research-evidence)에 기록했다.
| 질문 / Requirement suffix | 결론과 인계 |
| --- | --- |
@@ -22,7 +32,7 @@ requirement-only 완료 기록을 이번 연구의 실행 제한으로 해석하
| 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 후보**로
기존 feature의 연구·질량·eigen·stabilization 문서는 **연구 당시 worktree의 read-only 후보**로
읽었다. 과거 수식·NR 판정·runtime 결과를 이번 승인이나 새 통과로 가져오지 않았다.
특히 과거 singleton mode family는 연구 결론이 아니며 [공통 tolerance](../TOLERANCE.md)에
대해 NR가 새로 판단해야 한다.
@@ -33,3 +43,169 @@ requirement-only 완료 기록을 이번 연구의 실행 제한으로 해석하
이번에는 문헌·원본 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 열람과 재사용은 없다.