238 lines
18 KiB
Markdown
238 lines
18 KiB
Markdown
# MITC4 eigen 구현 및 실행 결과
|
||
|
||
- Feature: `mitc4-shell-feast-eigen2`; Owner: 메인 assistant; 갱신 2026-09-10 KST.
|
||
- 현재 판정: **사용자 승인 첫 구현 범위 PASS**. FEAST 잔차 초과를 해소했고 외부10개 Value가 모드별5% 기준을 충족한다. S3와 후속 정확도 개선은 보류한다.
|
||
아래 2026-09-10 결과가 최신이며 2026-09-09 trace 실행은 당시 evidence로 보존한다.
|
||
- 기준: [프로젝트 지침](../../AGENTS.md), [PRD](PRD.md), [ADR](ADR.md),
|
||
[정식화](formulation.md), [수치 controls](numerical-review-controls.md), [I/O](io.md#io).
|
||
- 독립 검토: [수치](implementation-review.md#implementation-numerical-review),
|
||
[S3 정적 계약](implementation-review.md#implementation-numerical-review-s3-static),
|
||
[물리](implementation-review.md#implementation-physics-review), [FEAST 종료 변경](implementation-review.md#implementation-feast-residual-review), [첫 구현 최종 검토](implementation-review.md#implementation-first-version-review).
|
||
|
||
## 2026-09-10 첫 구현의 5% 수용과 검증 보강
|
||
|
||
사용자는 첫 구현의 Abaqus Value 차이를 모드별5%까지 수용하고 정확도 향상과 S3는 후속으로
|
||
진행하도록 명시했다. [공통 ADR-029](../ADR.md#adr-029), [Feature ADR-012](ADR.md#mfe2-adr-012--첫-구현의-외부-고유치-5-수용)에 따라
|
||
`mitc4-eigen-first-implementation`의 상대오차/RMS를 각각5%로 적용한다. 기존 singleton
|
||
identity·공통 사전검사와 내부 all-c1e-10은 유지하며 다른 기능은 기존 RMS1%다.
|
||
비교 보고서에는 policy_id와 relative_rms_tolerance를 기록한다. 아래 과거1% 판정은 소급 수정하지 않는다.
|
||
|
||
| 보강 | 실제 관찰 |
|
||
| --- | --- |
|
||
| C25 외부 policy | 합성 output의 ±5% 경계와 바로 밖, zero/nonfinite·nonmodal family 거부, 다른 공통 policy RMS1% 보존. 변경 전3%/5% 비교 실패를 확인한 뒤 새 정책으로 통과 |
|
||
| C02/03 mass | Warped C0/C1/C2 48개 rational 성분·row·first spatial moment, 24×24 consistent/lumped cross block 및 독립 pairwise Jensen energy. 차원별 scale과 D-congruence Frobenius 사용 |
|
||
| C05/06 covariance·assembly | Proper Q+shift 재계산, 서로 다른 rho/t/material 두 요소의 공유 절점 mass7/64·modal normalization·source order 변경 |
|
||
| C19/21 backend | Raw tiny-negative/정확한 -tau_zero 보존과 경계 바로 밖 거부, fatal/count 모순·monotonicity·returned mismatch·nonfinite·요청 N 밖의 residual/Gram 실패, certified fallback·변경된 구간 retry |
|
||
| C22 budget·storage | Production-used private helper의 511/512·363/364·SIZE_MAX 및 곱/저장 한계, 실제 allocation try 안의 bad_alloc 주입, initial info1의 정확히3회 종료·MKL thread 복원 |
|
||
| C24 final 보존 | Eigen writer의 valid final을 Win32 delete-sharing lock으로 보호하여 실제 replacement 실패를 만들고 byte 보존·self-check 확인. 공통 finalizer의 기존 실패 테스트도 유지 |
|
||
|
||
오류 주입은 `src/fesa/solvers/eigen/`의 private thread-local seam으로만 수행한다.
|
||
일반 실행에서는 hook이 없으며 vendor 호출·수치식·control·공개 API를 유지한다. Bounds/storage
|
||
helper는 기존 검사를 옮겨 production과 테스트가 같은 조건을 사용한다. 모든 vendor/OS 오류
|
||
조합을 실행한 것은 아니며 actual512회 vendor 호출이나 실제 HDF5 close-error 주입은 하지 않았다.
|
||
Close 실패는 기존 checked-close→exception→candidate 정리/기존 final 보존 제어 흐름을 정적으로 대조했다.
|
||
|
||
| 실행 | 결과 |
|
||
| --- | --- |
|
||
| policy 변경 전 focused | 기존 RMS1% 때문에3% 및 ±5% 사례 실패. `.harness/eigen-first-implementation-red.log` |
|
||
| policy/원본 focused | 10/10 PASS, 원본10개 Value 포함. `.harness/eigen-first-implementation-focused.log` |
|
||
| coverage 최초 focused | 30/31 PASS. C06 합성 BC 위치만 input 계약 위반으로 실패했고 model-level로 수정 |
|
||
| 수정 mass focused | 6/6 PASS. `.harness/eigen-first-implementation-mass.log` |
|
||
| 최종 monotonicity/raw 경계 focused | 2/2 PASS. `.harness/eigen-first-implementation-boundaries.log` |
|
||
| 구성된 전체 build/test | `python scripts/execute.py` exit0, configure/build/discovery/test 모두 exit0. **417/417 PASS**: unit339·integration42·reference36, 166.86초. `.harness/eigen-first-implementation-full-run.log`, 상세 `.harness/eigen-first-implementation-full-ctest.log` |
|
||
|
||
최종 전체 실행 후 공식 HDF5를 read-only로 다시 추출했다
|
||
(`.harness/eigen-first-implementation-metrics.log`). 원본10개 Value의 최대 상대오차는
|
||
`4.261331%`, 전체 c=22 최대 독립 잔차는 `1.605467212112365e-13`으로 아래 residual
|
||
실행과 같다. 새 profile의 외부 비교와 내부 `1e-10` 기준을 모두 통과했다. Compiler warning을
|
||
추가하지 않았으며 Python Harness suite는 변경 범위가 아니므로 실행하지 않았다.
|
||
|
||
추가 테스트 작성 중 nested initializer와 lambda capture의 컴파일 오류를 수정한 뒤 MSVC x64
|
||
Debug build가 성공했다. 실패한 빌드 뒤 등록되지 않은 테스트의 `No tests were found`를 PASS로
|
||
계산하지 않았다. [첫 구현 독립 검토](implementation-review.md#implementation-first-version-review)는 새 oracle와
|
||
failure/acceptance evidence·전체 실행을 대조하고 **사용자 승인 첫 구현 범위 PASS**로 판정했다.
|
||
임의 모델 정확도나 외부 release를 보장하는 판정은 아니다.
|
||
|
||
## 2026-09-10 FEAST residual stopping 변경 결과
|
||
|
||
[ADR-011](ADR.md#mfe2-adr-011--feast-residual-stopping과-s3-후속-분리)의 사용자 승인에 따라 backend의 C-index
|
||
`fpm[5]`만 `1→0`으로 변경하고 HDF5 writer의 실제 control 검증도 `0`으로 맞췄다.
|
||
`fpm[2]=12`, `[3]=20`, seed/thread/구간/capacity/실패 정책과 모든 독립 tolerance는 유지했다.
|
||
S3, K/M·질량 축소·회복 수식, reference artifact는 변경하지 않았다.
|
||
|
||
새 테스트는 실제 backend snapshot과 저장한 HDF5의 `[5]=0`을 확인하고 trace 값으로
|
||
변조한 candidate를 거부하면서 기존 최종 파일을 보존하는지 검사한다. 변경 전 `[5]=1`
|
||
때문에 두 검사가 실패한 뒤 최소 source 수정으로 통과했다.
|
||
|
||
| 실행 | 결과 |
|
||
| --- | --- |
|
||
| 변경 전 backend/HDF5 focused CTest | 2/2 실패, `[5]=1` 확인. `.harness/feast-residual-red.log` |
|
||
| MSVC x64 Debug 3개 test target build | exit0, 새 compiler warning 없음 |
|
||
| 변경 후 backend/writer/원본 reference focused CTest | 12개 중 11 통과, exit1. 영·혼합 영·반복·근접 고유값, thread 복원, control readback/변조 거부 통과. 원본은 해석 성공 후 외부 Value 비교에서 실패 |
|
||
| `python scripts/execute.py` | build 성공, runner exit1 / CTest exit8. **395개 중 394 통과**, 원본 Value reference 1개 실패. 178.42초; unit320, integration42, reference33 |
|
||
| 공식 HDF5 read-only 추출 | 전체 c개 metric과 실제 controls·backend call·10개 Value를 확인. Focused와 full 실행의 modes/vectors/eigenpair_checks/base_fpm dataset bytes 동일 |
|
||
|
||
전체 실행은 `.harness/feast-residual-full-run.log`, 상세 CTest는
|
||
`.harness/feast-residual-full-ctest.log`, focused는 `.harness/feast-residual-focused.log`다.
|
||
Read-only 추출 스크립트와 JSON은 최종적으로 ignored build directory에 보관했다.
|
||
재현 명령은 `uv run --with h5py python .harness/build-ninja-msvc-debug/extract_feast_residual.py`이며,
|
||
그 directory의 `feast-residual-metrics.json`과 `feast-residual-full-metrics.json`이 각 실행의 기록이다.
|
||
개인 환경·추출 스크립트·기계 생성 로그/결과는 커밋하지 않는다. 이 작업에서 Python Harness suite는 실행하지 않았다.
|
||
|
||
원본 결과 HDF5(당시 경로: `../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine_results.h5`, 현재 checkout에 없음)는
|
||
이번 실제 해석이 새로 생성한 공식 sibling output이다. 생성과 closed-file self-check는 성공했고,
|
||
기존 외부 INP/TXT의 실행 전후 bytes는 reference test에서 보존을 확인했다.
|
||
|
||
| Metric | 새 결과 |
|
||
| --- | ---: |
|
||
| 요청 N / 계산 c / m0 | 10 / 22 / 33 |
|
||
| Count / solve calls | 25 / 1 |
|
||
| FEAST info / loop | 0 / 6 (기존 trace는 4회) |
|
||
| 전체 c 최대 rho_B | `1.605467212112365e-13` |
|
||
| 최대 original-free eta_r / whitened eta_w | `9.981033437726324e-15` / `7.315529163435965e-15` |
|
||
| eta_gram / max_eta_orth | `1.3777964580680282e-15` / `1.6958335496991244e-15` |
|
||
| 최대 backend_res | `8.280018892001454e-13` |
|
||
| epsout (trace 변화 진단량) | `2.4227135616446226e-17` |
|
||
|
||
전체 22개는 각각 독립 `1e-10` 기준을 통과한다. 기존 실패 column20의
|
||
`rho_B=1.48674481038207483e-10` 대비 같은 column의 잔차가 약926배 감소했다.
|
||
기존 trace 진단에서 추출한 첫10개 Value 대비 새 Value의 최대 상대 변화는 약`2.74e-14`다.
|
||
따라서 이 개선은 고유쌍의 대수적 잔차 개선이며 외부 reference와의 일치를 보장하지 않는다.
|
||
|
||
| Mode | FESA Value (표시 반올림) | Abaqus Value | 상대오차 / singleton RMS (%) |
|
||
| --- | ---: | ---: | ---: |
|
||
| 1 | 218267.149475 | 219507 | 0.564834 |
|
||
| 2 | 873571.591115 | 885523 | 1.349644 |
|
||
| 3 | 873571.591115 | 885523 | 1.349644 |
|
||
| 4 | 1816890.360227 | 1855340 | 2.072377 |
|
||
| 5 | 2669030.373076 | 2740230 | 2.598308 |
|
||
| 6 | 2703557.194039 | 2775150 | 2.579781 |
|
||
| 7 | 4013818.213002 | 4149410 | 3.267737 |
|
||
| 8 | 4013818.213002 | 4149410 | 3.267737 |
|
||
| 9 | 6446840.913563 | 6733790 | 4.261331 |
|
||
| 10 | 6446840.913563 | 6733790 | 4.261331 |
|
||
|
||
모드별 singleton family와 [공통 tolerance](../TOLERANCE.md)를 그대로 적용했다.
|
||
모든 행은 상대오차5% 이내지만 Mode2–10은 RMS1%를 초과하여 blocking FAIL이다.
|
||
이는 이전에는 residual 실패 때문에 도달하지 못했던 비교 결과다. 원인은 이번 변경에서
|
||
확정하지 않았으며 질량·drilling 정식화나 tolerance를 결과에 맞춰 수정하지 않았다.
|
||
독립 수치 검토는 이번 종료 제어 변경을 PASS로 판단했으나 외부 acceptance는 FAIL로 구분했다.
|
||
S3의 알려진 실패와 아래 기존 세부 coverage 제한도 남는다.
|
||
|
||
## 2026-09-09 trace stopping 구현 이력
|
||
|
||
## 구현된 경로
|
||
|
||
`DENSITY/FREQUENCY` 입력과 source Step-2/N → 별도 Frequency Domain/step →
|
||
27점 consistent moments와 derived nodal lumped mass → 실제 global BC 우선 null/positive
|
||
분해 → nodal Cholesky whitening과 sparse congruence → 실제 MKL FEAST → 전체 c개 검증 →
|
||
N개 mass-normalized global vectors와 scalar → additive eigen HDF5와 closed-file self-check를 연결했다.
|
||
Prepared analysis와 application은 frequency를 독립 procedure/state/writer로 dispatch한다.
|
||
|
||
초기 drilling scale은 physical rotary 8개 diagonal의 zero를 포함한 평균으로 바꿨다.
|
||
기존 nonlinear trial/commit 상태 코드는 변경하지 않았다. 성공·실패 때 source identity를 보존하고,
|
||
실패한 solve/validation/candidate로 기존 최종 HDF5를 교체하지 않는다.
|
||
TXT comparator는 `Value`만 비교하며 같은 값의 별도 mode ID를 유지한다.
|
||
|
||
## 실행 evidence
|
||
|
||
개인 설정의 `mfe-workspace-msvc-ninja-debug` preset, CMake/MSVC x64 Debug,
|
||
MKL 2026.1 ILP64를 사용했다. 설치 경로·개인 preset은 커밋하지 않는다.
|
||
|
||
| 실행 | 결과와 의미 |
|
||
| --- | --- |
|
||
| `cmake --build --preset mfe-workspace-msvc-ninja-debug --target fesa_unit_tests fesa_integration_tests fesa_reference_tests` | exit 0, `/W4 /WX` 빌드 |
|
||
| 초기 `python scripts/execute.py` | exit 1, 392개 중 387 통과·5 실패. 입력 회귀 4개와 원본 eigen 1개 |
|
||
| 입력·FEAST·procedure·writer focused CTest | 수정 후 41/41 통과, exit 0. 기존 입력 4개 회귀 포함 |
|
||
| 수정된 Householder/count 이후 원본 eigen + FEAST focused CTest | 8/9 통과, 원본 eigen 실패, exit 1 |
|
||
| 최종 `python scripts/execute.py` | build exit 0, runner exit 1 / CTest exit 8. **395개 중 394 통과·원본 eigen 1개 실패**, 155.31초. Unit 320개, integration 42개, reference 33개 |
|
||
|
||
최종 전체 실행 로그는 `.harness/eigen2-full-run.log`, CTest 상세는
|
||
`.harness/eigen2-full-ctest.log`에 남긴다. 생성 로그·결과는 source와 함께 커밋하지 않는다.
|
||
Test discovery의 CMake 4.4 POST_BUILD 임시 JSON 충돌을 확인해 세 target을 `PRE_TEST`로
|
||
변경했다. 초기 392개 CTest name/실행 binary 대응을 실제 `--gtest_list_tests`와 대조했고
|
||
누락·중복·다른 binary로의 등록이 없었다. 이후 추가한 3개를 포함한 최종 395개도 같은 방법으로 확인했다.
|
||
|
||
HDF5의 duplicate model node ID가 self-check를 통과하는 실패를 재현한 뒤 source/model
|
||
compound member의 정확한 type/value readback을 추가했다. 수정된 검사에서 같은 변조는 거부됐다.
|
||
NaN vector, 불일치 scalar/cluster/constraint, 악화된 residual/rcond/Gram의 candidate 거부와
|
||
이전 최종 파일의 byte 보존도 확인했다. 이 검사는 실제 물리 residual 계산을 대신하지 않는다.
|
||
|
||
## 원본 eigen의 차단 결과
|
||
|
||
실행한 파일은 [원본 INP](../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp)다.
|
||
원본 INP/TXT의 실행 전후 bytes를 비교해 보존했다. 제외된 예제의 원본·복사본·cache는 사용하지 않았다.
|
||
|
||
| 관찰 | 실제 값 |
|
||
| --- | ---: |
|
||
| node / element | 729 / 676 |
|
||
| full / free / null / finite DOF | 4374 / 3750 / 625 / 3125 |
|
||
| 요청 N / 계산 c / m0 | 10 / 22 / 33 |
|
||
| 총 backend 호출 / 마지막 solve ordinal | 26 / 25 |
|
||
| FEAST info / loop | 0 / 4 |
|
||
| 실패 solver column | 20, 즉 계산된 21번째 모드 |
|
||
| mu | 4.81673637615627741e-03 |
|
||
| full CSR rho_B | 1.48674481038207483e-10 |
|
||
| FEAST가 받은 upper 대칭 행렬의 rho_B | 1.48674481542089335e-10 |
|
||
| full/upper action 차이 norm | 1.38724134018909290e-17 |
|
||
| backend res / epsout | 7.75636151025973760e-10 / 2.82488401287762986e-14 |
|
||
|
||
`rho_B<=1e-10`은 전체 c개에 적용된다. 요청한 10개 밖의 모드라는 이유로 생략하지 않았다.
|
||
초기 Householder의 cancellation을 수정하고 positive R·relative pivot·Gram를 확인한 뒤에도
|
||
실패가 재현됐다. 물리 모드 복원 전에 실패하며 upper/full 차이로 설명되지 않는다.
|
||
FEAST의 `info=0`이나 trace stopping은 별도 residual 기준 통과가 아니다.
|
||
[Intel parameter 설명](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html)에
|
||
따르면 현재 고정 `fpm[5]=1`은 trace stopping이며, 이번 4회 종료는 maximum20 소진이 아니다.
|
||
|
||
따라서 원본 모델의 **성공 HDF5 및 10개 Value의 외부 tolerance 비교는 미완료**다.
|
||
기존/복사 결과를 가져와 fresh 통과로 바꾸지 않았고 tolerance·seed·FEAST controls를 바꾸지 않았다.
|
||
|
||
## 유지 회귀와 남은 검증 범위
|
||
|
||
Retained shell/shellNL/linear-limit의 fresh 변위 reference, force/moment/free residual,
|
||
Newton tangent/objectivity/energy/rollback와 pressure synthetic 검사는 초기 전체 실행에서 통과했다.
|
||
수치 비교 통과는 아래 물리 문제를 덮지 않는다.
|
||
|
||
- **S3 상위 계약 충돌:** direct pencil의 `lambda=10369/450`,
|
||
`thetaZ=7500/10369`와 full `Kq-F`의 회전 공변성은 통과했다. 그러나 public static 실행은
|
||
drilling에 의한 정확한 미평형 모멘트 때문에 실패한다. 별도 재현 테스트의 성공은 이 실패를
|
||
올바르게 검출했다는 뜻이며, 지원 범위의 정적 해석 성공이 아니다.
|
||
- **기존 PE-IMP-01:** nonlinear 굽힘 단면력 복구가 stress 적분과 불일치한다.
|
||
`t=0.5`에서 약 2배이며 해당 nonlinear source는 HEAD 대비 변경되지 않았다.
|
||
물리 보고서에 근거와 기존 구현 owner를 남겼다. 현재 작업에서 별도 수식 수정은 하지 않았다.
|
||
- Mass flat/warped scalar oracle, row moments, Jensen energy, m1/2/4 mesh work,
|
||
partial-BC complete K/ML, rigid modes, off-diagonal whitening, near-aligned conditioning,
|
||
rho×4 및 length×1024 단위 변환, actual FEAST known/zero/repeated/close-Givens spectra는 검사했다.
|
||
**27개 case의 모든 세부 관찰을 완료했다고 주장하지 않는다.**
|
||
- 특히 E2-C02의 모든 warped Ck 독립 적분, C03 perturbation 전파, C05 rational Q+shift와
|
||
full-row-sum mutation, C06 이종 section 공유 node mass assembly, C21/22의 vendor-status/
|
||
budget/allocation 실패 주입 전체, C24의 close/replace 실패 주입 전체는 추가 evidence가 필요하다.
|
||
|
||
## 2026-09-09 당시 후속 제안
|
||
|
||
현재 요구·정식화·NR·I/O의 수치를 구현 결과에 맞춰 조용히 바꾸지 않는다.
|
||
[프로젝트 지침](../../AGENTS.md)의 Physics/지원 범위/acceptance 변경 및 미해결 필수 계약 충돌
|
||
경계에 따라 다음 재검토를 제안했다. 당시에는 **미승인 제안**이었으며,
|
||
이후 1번의 residual stopping만 ADR-011로 승인·실행했다. 2번 S3는 사용자 요청으로 후속 검토한다.
|
||
|
||
1. `rho_B<=1e-10`과 전체 c 검증을 유지하면서 FEAST 종료 제어를 재검토한다.
|
||
`fpm[5]=0` residual stopping은 검토 후보이며, actual runtime·zero/repeated/endpoint/
|
||
실패 controls 검증과 독립 NR 이후 채택 여부를 결정한다. Maximum loop 증가만으로
|
||
이번 원인이 해결된다고 가정하지 않는다.
|
||
2. S3에서 승인된 drilling 정식화·full residual reaction·공간 평형·부분 global rotation BC를
|
||
함께 만족시키는 계약을 formulation/NR로 다시 정리한다. 임의 torque 제거·평균·tolerance
|
||
완화 또는 새 unsupported 분류로 성공처럼 처리하지 않는다.
|
||
3. 수정 계약이 확정되면 영향받는 mass-null reduction/정적·비선형/eigen 검증과 위 미완료
|
||
case들을 완성하고 원본 HDF5→Value 비교 및 전체 검증을 다시 수행한다.
|
||
|
||
기존 Feature/phase의 사용자 변경 16개는 시작 시 raw Git object hash와 동일했다.
|
||
공통 AGENTS/PRD/ADR, reference INP/TXT/CSV와 개인 build 설정은 커밋 범위에서 제외한다.
|
||
|
||
## Git 기록
|
||
|
||
- `e74ac24 docs: record eigen2 implementation scope and verification plan`
|
||
- `22c9d44 feat: add eigen2 frequency pipeline and fail-closed validation`
|
||
|
||
구현 commit은 source·test·CMake 39개 파일의 진행분이며 acceptance 완료 commit이 아니다.
|
||
이 결과 및 독립 검토 문서는 별도 `docs:` commit으로 보존한다. Push는 수행하지 않았다.
|