docs: define MITC4 mass and FEAST formulation

This commit is contained in:
KOKO\Mimi
2026-09-06 02:33:45 +09:00
parent a7c13ff378
commit 2c3a86aa69
8 changed files with 819 additions and 4 deletions
+9
View File
@@ -52,3 +52,12 @@
- 결정: 고유치 개수는 `.inp`의 `*FREQUENCY` data를 사용한다. 지정 input의 요청은 `10`개이며 reference 행수나 FEAST 내부 count 추정으로 요청 개수를 역추론하지 않는다.
- 근거: 2026-09-06 사용자 답변 “inp 파일의 고유치 개수를 사용합니다”; [r1 FEM-REQ-MITC4-EIGEN-009/015](requirements.md#requirement-verification-matrix).
- 영향: 기존 mode-count 의미의 확인이므로 contract revision은 `r1`을 유지한다. FEAST interval/subspace는 입력 요청의 낮은 N개와 multiplicity·누락 검증을 충족하기 위한 내부 처리이다. 새 입력 설정 기능을 추가하지 않는다.
## MFE-ADR-006 — 질량 lumping과 질량 없는 좌표의 정식화
- 상태: Formulation owner의 수학 계약으로 기록; 독립 Numerical Review 대기.
- 결정 owner: formulation-agent; 기록 owner: coordinator-agent.
- 결정: Consistent scalar moments를 같은 `3×3×3` volume quadrature로 계산하고 moment row-sum에서 nodal `6×6` block lumped mass를 유도한다. 기존 global 제약 뒤 analytic director null과 기존 stabilization의 decoupling을 이용해 finite 공간을 투영하고 sparse nodal whitening으로 FEAST에 연결한다.
- 근거: [Formulation 핵심 계약](formulation.md#핵심-계약), [mass M1~M10](formulation-mass.md), [eigen E1~E8](formulation-eigen.md).
- 영향: 곡면 coupling 및 mass/centroid·energy 차이를 명시하고 인공 drilling mass와 일반 dense Schur는 도입하지 않는다. Numerical Review는 수식·conditioning·FEAST controls·reference 준비를 독립 검토한다.
- 남은 검토: [V5](formulation-verification.md#v5-rigid-mode-coordinate-및-density-불변식)의 기존 basis-dependent stabilization 한계와 `FEM-REQ-MITC4-EIGEN-014` coordinate-invariance coverage 관계를 NR가 명시적으로 확인해야 한다. 이 기록으로 acceptance 범위를 조용히 좁히지 않는다.
@@ -37,5 +37,9 @@ Reference artifact와 공통 정책은 수정하지 않는다. 외부 solver 실
| [requirements-evidence.md](requirements-evidence.md) | requirement-agent | r1 | 원본 관찰·결정·정적 evidence audit 완료 |
| [research.md](research.md) | research-agent | r1 | Coordinator gate pass; primary source coverage |
| [research-evidence.md](research-evidence.md) | research-agent | r1 | 수식 후보·API·한계·verification 근거 audit 완료 |
| [formulation.md](formulation.md) | formulation-agent | r1 | Coordinator gate pass; 독립 NR 인계 |
| [formulation-mass.md](formulation-mass.md) | formulation-agent | r1 | M1~M10·적분·lumping·보존량 수학 계약 |
| [formulation-eigen.md](formulation-eigen.md) | formulation-agent | r1 | E1~E8·제약/null·FEAST·복원 수학 계약 |
| [formulation-verification.md](formulation-verification.md) | formulation-agent | r1 | V1~V7·검증식·NR 수치 기준 인계 |
아직 작성되지 않은 specialist 보고서는 목록에 승인 산출물로 등록하지 않는다.
+2 -1
View File
@@ -3,7 +3,7 @@
- Feature ID: `mitc4-shell-feast-eigen`
- Owner: `coordinator-agent`
- Input contract revision: `r1`
- 검토 상태: requirements 및 research r1 gate pass; 구현용 정식화 준비.
- 검토 상태: requirements·research·formulation r1 gate pass; 독립 numerical/reference review 진행.
기준: [프로젝트 지침](../../AGENTS.md), [프로젝트 PRD](../PRD.md), [프로젝트 ADR](../ADR.md).
지역 지침과 문서 목록은 [FEATURED_AGENTS.md](FEATURED_AGENTS.md), 상태 원본은 [coordination.md](coordination.md)를 따른다.
@@ -42,3 +42,4 @@ Reference는 선행 preload 없는 단일 frequency step의 10모드이며 상
두 질량 계산의 연결에 관한 [MFE-ADR-002](ADR.md#mfe-adr-002--mitc4-질량-이산화)는 사용자 후속 요구로 확정되었다.
실제 FEAST mass는 [MFE-ADR-004](ADR.md#mfe-adr-004--feast에-사용하는-질량행렬)에 따라 lumped로 승인되었다. 상세 lumping 수식은 Research/Formulation owner가 정의한다.
Primary-source 근거와 적용 한계는 [research](research.md), 상세 근거는 [research-evidence](research-evidence.md)에 있으며 최종 수식·수치 기준의 승인을 대신하지 않는다.
구현용 수학 계약과 상세 문서의 연결은 [formulation](formulation.md)에 있다. 수치 acceptance 및 reference readiness는 NR 판정 전이다.
+21 -3
View File
@@ -3,9 +3,9 @@
- Feature ID: `mitc4-shell-feast-eigen`
- Owner: `coordinator-agent`
- Contract revision: `r1` (사용자 최종 질량 요구를 반영한 requirements baseline)
- Stage: `formulation`
- Outcome: `pass` (research gate)
- Next owner: `formulation-agent`
- Stage: `numerical-review`
- Outcome: `pass` (formulation gate; 독립 numerical 판정 전)
- Next owner: `numerical-review-agent`
- Attempt: `0`
- Completion: 미완료
- Failure classification / retry key: `null`
@@ -23,6 +23,7 @@
| requirements r0 초안 | [requirements](requirements.md), [관찰·결정 evidence](requirements-evidence.md) | needs-user-decision; 질량 선택 미승인으로 baseline pass 보류 |
| requirements r1 | [requirements](requirements.md), [관찰·결정 evidence](requirements-evidence.md), MFE-ADR-002/004 사용자 명시 결정 | pass; 26개 must와 owner/revision/hash 검증, 미결정 0 |
| research r1 | [research](research.md), [primary-source 상세 근거](research-evidence.md) | pass; primary source 11개 그룹·프로젝트 근거2개, 26개 requirement coverage 및 API 보장 한계 확인 |
| formulation r1 | [기본 수학 계약](formulation.md), [mass](formulation-mass.md), [eigen](formulation-eigen.md), [verification](formulation-verification.md) | pass; owner/revision/상세 수식·26개 coverage·정적 evidence 확인, 독립 수치판정은 NR 소유 |
공통 문서 및 reference 파일 목록의 read-only 조사 명령은 exit code `0`으로 완료했다.
확인된 reference 파일은 `shellNL-eigen-meshfine.inp`, `shellNL-eigen-meshfine eigenvalues.txt`이며 실제 의미와 readiness는 담당 owner가 검토한다.
@@ -31,6 +32,16 @@ Root의 시작 Git 조사에서 worktree clean을 확인했다. 구현·build/te
## 현재 bounded dispatch
Formulation owner의 r1 `pass` envelope와 실제 기본/상세 문서 4개를 감사하여 numerical-review로 전이한다.
Owner 정적 검사는 `4`문서, `38` local links, requirement coverage `26`, issues `0`, `python -B -` exit `0` 및 `git diff --check` exit `0`이다.
Coordinator는 모든 상세 문서의 metadata·수식/단위/identity/오류/검증/한계 절과 링크를 읽고 필수 항목 존재를 확인했으며 수학적 correctness verdict를 대신하지 않았다.
NR는 수학 correctness와 reference-model readiness를 모두 검토하고 명시된 metric/zero branch의 수치값, FEAST controls·bounded budgets 및 필수 verification portfolio를 고정한다.
Root의 두 독립 감사 포인트를 필수 handoff로 포함한다: count 기능의 실제 API 보장보다 강한 completeness를 주장하지 않을 것;
기존 basis-dependent drilling stabilization과 `FEM-REQ-MITC4-EIGEN-014`의 coordinate-invariance coverage 관계를 명시하여 acceptance의 조용한 축소를 막을 것.
현재 새 사용자 미결정이나 implementation correction은 없다.
### Formulation 이력
Research owner의 r1 `pass` 반환을 Coordinator가 감사하여 formulation으로 전이한다.
연구 기본/상세 문서의 owner, r1, source locators, Fact/Derivation/Candidate 구분, 실제 명령 exit code 및 미실행 항목을 확인했다.
연구 문서 SHA-256: `research.md` = `c044031f844798f32bedc95fd998c181f965fbac00c3ed8f594a48d0164b8956`,
@@ -39,6 +50,10 @@ Coordinator local-link audit은 Feature 8문서/끊긴 링크0, exit code `0`; `
설치 header와 공식 count 기능 존재는 runtime 또는 완전성의 자동 통과 증거가 아니다. 실제 API의 수치적 한계, endpoint/count 실패, 독립 작은 spectrum 검증이 연구 보고서에 기록되었다.
Formulation owner는 approved MITC4 geometry에 대한 consistent 적분, derived block lumping·물리 관성·massless drilling/constraints,
FEAST의 낮은 N개 계산·복원·실패 보존 및 modal evidence 식을 구현 가능한 계약으로 작성한다. 최종 numerical/reference acceptance는 다음 NR가 독립 검토한다.
Research checkpoint는 Root가 `a7c13ff` (`docs: record MITC4 mass and FEAST research evidence`)로 완료 문서 6개를 커밋했고 이후 clean을 확인했다.
Formulation owner의 중간 관찰은 기존 `Tphys/Tdrill`과 양의 nodal drilling 강성에 기반한 `Kpz=0` 증명,
곡면의 `C1` coupling을 유지하는 derived block lumping과 `3×3×3` mass 적분 차수 검토이다.
이는 작성 중인 정식화의 owner 관찰이며 formulation 또는 numerical gate 통과를 뜻하지 않는다.
### Research 및 baseline 이력
@@ -99,6 +114,9 @@ Root read-only 환경 조사에서 다음 설치 경로를 확인했다. 이 목
VS `18/Community` DevShell script/dll이 존재하며 Ninja는 현재 PATH에 없다. Planning/Executor는 각 실행 subprocess의 MSVC x64 Developer 환경과 dependency 환경을 명시해야 한다.
Root는 global environment, Hook state/code를 변경하지 않았다.
추가 Root read-only 확인: Python `3.11.15`, oneMKL `mkl_rt.lib`/`bin/mkl_rt.3.dll` 및 FEAST 선언이 존재한다.
현재 작업 경로는 primary `C:/git/FESADev`의 linked worktree이며 branch는 `Eigen`이다.
Implementation profile은 `gpt-5.6-terra` / `xhigh` / `workspace-write`이고 실제 configure/link/runtime는 아직 미실행이다.
현재 `.harness/config.json`은 없고 preset과 `.harness/config.example.json`은 있다.
Planning은 자동 감지 결과와 승인 MSVC preset을 대조하여 실행명령 및 Hook backend를 명시해야 한다.
@@ -0,0 +1,279 @@
# 제약 후 질량 공간, 유한 spectrum과 FEAST
- Feature ID: `mitc4-shell-feast-eigen`
- Owner: `formulation-agent`
- Input contract revision: `r1`
- 기본 보고서: [formulation.md](formulation.md)
[질량 유도 M1~M10](formulation-mass.md), [research evidence](research-evidence.md)의
`S03`~`S08`, `P01`, `R03/R04`를 적용한다. 아래 reduction은 기존 stabilized stiffness와
**derived lumped mass**의 pencil에 정확히 대응한다.
## E1. 조립, 단위 scaling과 실제 global 제약
Element gather `A_e`를 stable source node/component 순서로 정의하면
`K=sum A_e^T K_e A_e`, `M=sum A_e^T M_L,e A_e`이다. 이하 `M`은 항상 lumped이다.
Element contribution→stable COO key→고정 순서 reduction으로 두 행렬을 조립한다.
Lumped nodal block이므로 `M`의 node 간 block은 0이다. Worker는 global storage를
동시에 갱신하지 않는다. Source identity와 equation index는 다른 번호다.
혼합 단위를 가진 6 DOF를 그대로 Euclidean norm으로 합하지 않는다.
활성 shell의 기존 최대 edge 길이들 중 최대값 `ell>0 [L]`을 characteristic length로
선택하고 `D=blockdiag(ell I3,I3)`를 node마다 둔다. `q=D y`에서 `y`는 무차원,
`Khat=D^T K D [ML²/T²]`, `Mhat=D^T M D [ML²]`이다.
이는 congruence이며 physics와 lambda를 변경하지 않는다.
원 global homogeneous BC의 free injection을 `C`라 한다. 고정 DOF의 행은 0,
free DOF의 행은 하나의 1이며 free 순서는 DofManager의 stable 순서다.
\[
y=C y_f,\qquad K_f=C^TKhat C,\qquad M_f=C^TMhat C. \tag{E1}
\]
Nonzero prescribed base state는 이 procedure의 입력 오류다. 먼저 local 회전을 임의
삭제한 뒤 global BC를 적용하지 않는다. 특히 global `UR3`와 drilling은 같지 않다.
## E2. Null/positive basis를 node마다 결정
각 active node의 원 질량 null은 M8로부터 `z_i=[0;d_i]` 한 방향이다.
따라서 node별 실제 free 좌표에서 null이 존재하는 필요충분조건은
**constrained rotational component마다 해당 `d_i` 성분이 정확히 0**인 것이다.
그때 `Z_i=C_i^T z_i`는 unit null vector이며 otherwise null dimension은 0이다.
Translation constraint는 이 판정에 영향을 주지 않는다. 모든 회전이 고정이면 null도 없다.
이 판정은 analytic nullspace와 실제 입력 BC의 교집합이다. 작은 nonzero constrained
director 성분을 임계값으로 0으로 바꾸지 않는다. 거의 정렬된 경우 작은 양의 physical
mass가 남을 수 있으며 이를 보존한다. Numerical conditioning 검증을 통과하지 못하면
명시적 실패로 처리하고 free DOF를 추가 삭제하지 않는다.
각 node에서 `Z_i`의 Euclidean 직교 여공간 basis를 `P_i^f`라 한다.
회전 3개가 free이면 기존 tangent basis `(a_i,b_i)`를 사용할 수 있다. Free 회전 2개
안에 null이 있으면 그 평면에서 `d_i`에 수직인 단위벡터 하나, 회전 1개가 null이면
positive 회전 basis는 없다. Free translation axis는 그대로 유지한다.
Null이 없으면 `P_i^f=I`다. Source component 순서, basis sign/tie는 고정한다.
Householder 등 동등한 작은 orthogonal construction을 쓸 수 있으나 physical rank를
수치 eigenvalue cutoff로 정하지 않는다.
\[
P=\operatorname{blockdiag}(P_i^f),\quad Z=\operatorname{blockdiag}(Z_i),\quad
[P\ Z]^T[P\ Z]=I,\quad M_p=P^TM_fP\succ0,\quad M_fZ=0. \tag{E2}
\]
여기서 `P_i^f`와 [M2의 tangent projector](formulation-mass.md)는 서로 다른 기호다.
실제 positive dimension `n=cols(P)`, null dimension `nz=cols(Z)`이다.
Reference의 full clamped flat mesh에서는 625개 interior node,
`nf=3750`, `nz=625`, `n=3125`가 예상된다. 실제 assembly와 rank evidence로 확인한다.
## E3. 기존 stiffness에서 decoupling의 정확한 증명
공통 node director는 [shell geometry](../../src/fesa/model/shell_geometry.cpp)가 한 번
정의하고 [ElementFactory::CreateShell](../../src/fesa/elements/element_factory.cpp)이
node identity로 각 element에 전달한다. [MITC4 kernel](../../src/fesa/elements/mitc4_shell.cpp)의
`PhysicalTransformation20`, `DrillingTransformation4`, `EvaluateStiffness`는 M4를 구현한다.
한 node에만 `[0;d_i]`가 있는 full vector `z_i`에 대해 `T_p A_e z_i=0`이다.
Drilling 부분은 해당 node에만 작용하므로
\[
Khat z_i=\kappa_i z_i,\qquad
\kappa_i=\sum_{e\ni i}k_{d,e}>0,\qquad
K_f Z=Z\operatorname{diag}(\kappa_i). \tag{E3}
\]
마지막 등식은 E2에서 `z_i`가 **실제로 free space에 있을 때** 성립한다.
따라서
\[
K_{pz}=P^TK_fZ=0,\quad K_{zz}=Z^TK_fZ=\operatorname{diag}(\kappa_i)\succ0,
\quad K_p=P^TK_fP,\qquad K_p p=\lambda M_p p. \tag{E4}
\]
Finite mode의 massless 성분은 `z=0`이다. 이 projection은 arbitrary small coupling을
버리는 근사가 아니라 승인된 physical/drilling separation의 항등식이다.
Null이 없는 부분 제약 node에서는 `P=I`이고 기존 drilling contribution이 `K_p`에
그대로 남는다. 이를 빼면 원 constrained stabilized pencil을 바꾸므로 금지한다.
실제 floating-point matrix와 basis의 `M_f Z`, `K_fZ-Z diag(kappa)`, `P^T Z`를
별도 evidence로 남긴다. 증명된 analytic null만 구조적으로 제거하고 계산된 tiny coupling을
근거 없이 threshold로 버리지 않는다. 이 항등식의 roundoff 검증 및 복원 후 full free
residual이 NR 기준을 넘으면 assembly/director/conditioning 실패로 중단한다.
추가 massless mode를 찾아 제거하거나 기존 K를 재조정하지 않는다.
## E4. 일반 Schur 식과 비정상 rank의 의미
E3의 구조가 없는 일반 symmetric pencil을 비교하면, `Kzz`가 가역일 때만
\[
z=-K_{zz}^{-1}K_{zp}p,\quad
(K_{pp}-K_{pz}K_{zz}^{-1}K_{zp})p=\lambda M_p p. \tag{E5}
\]
이는 massless row를 푼 정확한 elimination이며 massive DOF의 근사 Guyan reduction이
아니다. 예를 들어 `K=[[6,2],[2,4]]`, `M=diag(2,0)`이면
`lambda=5/2`, `z=-p/2`이다. 첫 행만 남기는 `lambda=3`은 잘못이다.
E5는 independent small-pencil 검산과 잘못된 projection을 잡는 기준이다.
이 Feature의 production shell 경로에는 E3이 적용되므로 일반 dense Schur 구현을 요구하지
않는다. E3과 불일치하는 input을 E5로 자동 fallback하여 승인 geometry 문제를 숨기지 않는다.
- `nz=0`: null 처리 없이 실제 constrained `Kf,Mf`의 문제다.
- Local positive rank 0: 모든 free DOF가 null이면 해당 node의 finite 좌표는 없고
양의 `Kzz`에 의해 그 free coordinate는 0으로 복원한다. Fully constrained node도
finite 좌표 0개다. 다른 node의 유효 finite 좌표는 계속 보존한다.
- Global `n=0` 또는 `N>n`: 요청 모드가 존재할 수 없으므로 명시적 model/solve 실패다.
정적 해석의 유효 `0×0 Kff` 계약과 이 양의 mode-count 요구를 혼동하지 않는다.
- 예상 `Kzz`가 singular/nonpositive이거나 활성 node에 mass contribution이 없음:
유효 shell의 E3 전제가 깨진 것이다. Common `K/M` null이면 임의 lambda에 대한
indeterminate direction이며 ordinary finite eigenmode가 아니다. 제거하거나 pseudoinverse,
stiffness/mass epsilon으로 정규화하지 않고 진단한다.
- 일반 indefinite `Kzz`의 singular/nonzero `Kpz` case는 descriptor-pencil의 추가
constraint를 요구한다. 이번 positive stabilized shell과 다른 문제이며 자동 해석하지 않는다.
## E5. SPD whitening, 복원과 sparsity
`M_p`는 node별 최대 `6×6` SPD block이다. 각 block을 Cholesky하여
`M_p=L L^T`를 얻고 다음을 정의한다.
\[
A=L^{-1}K_pL^{-T},\quad p=L^{-T}x,\quad
A x=\lambda I x,\quad
\phi=D C P L^{-T}x. \tag{E6}
\]
Inverse를 dense global matrix로 만들지 않고 작은 block triangular solve로 congruence를
구성한다. `phi`는 source node의 global 6 DOF로 복원되고 constrained entries는 정확히 0이다.
`phi^T M phi=x^T x`다. Identity mass를 전달하는 E6도 실제 lumped mass에서 얻은
generalized SPD 문제다. Consistent mass 또는 인공 unit physical mass로 바꾼 것이 아니다.
Projection/whitening은 node 간 topology를 늘리지 않는다. 기존 node coupling마다 작은
dense block만 생기며 전체 `O(n²)` Schur matrix와 dense inverse를 피한다.
Sparse shifted FEAST factorization 자체의 fill은 별도 존재한다. Full `M_C`는 element별
`24×24`와 세 `4×4` moment로 검증할 수 있고 global dense consistent matrix는 불필요하다.
Allocation/nnz/factorization memory 실패는 불완전 모드의 성공이 아니라 명시적 failure다.
## E6. 유한 search interval과 요청 개수
요청 `N`은 `.inp *FREQUENCY`의 양의 정수이며 현재 reference는 10이다.
Reference Value/Freq/행수는 interval, scale, count 또는 parameter 선정에 사용하지 않는다.
먼저 `s=||A||inf [T^-2]`를 안정된 합으로 계산한다. `s>0`이면 `B=A/s`로 두고,
반환값은 `lambda=s mu`다. `A=0`이면 `s=min_e E_e/(rho_e ell²)>0`라는
모델 유래 time scale을 사용하며 `B=0`이다. 이 zero-matrix case도 N개의 0 모드를
FEAST에서 계산·검증한다. Invalid/underflow/overflow scale을 임의 1로 바꾸지 않는다.
각 행의 off-diagonal absolute sum을 `r_i`라 하면 Gershgorin에 의해
`min_i(Bii-ri)<=mu<=max_i(Bii+ri)`다. 안정된 directed-outward accumulation 또는
동등하게 증명된 roundoff bound를 포함하여 finite enclosure `[gL,gU]`를 만든다.
`B=0`에서는 알고리즘용 dimensionless enclosure `[-1,1]`을 사용한다.
Nonzero B의 endpoint margin은 NR가 정할 dimensionless coefficient와 `||B||inf` 및
endpoint ULP로 결정하고, outward `nextafter`를 적용해 `a0<gL<=gU<b0`를 확보한다.
이는 물리 mass/eigenvalue floor나 zero clamp가 아니다.
CSR count `c(a,b)`는 endpoint가 분리된 interval에 대해 Intel `fpm[49]=1`이 반환한
count와 status다. `c(a0,b0)=n`을 먼저 확인한다. 다음은 finite search의 결정적 규칙이다.
1. 모든 count는 원 enclosing lower bound `a0`부터의 prefix count로 평가한다.
`lo=a0`의 알려진 prefix count는 0, `hi=b0`의 count는 n이다.
Upper search에서 midpoint `v`의 count가 `N` 미만이면 `lo=v`, 아니면 `hi=v`로 둔다.
성공한 `hi`와 count를 항상 보존한다. `N<=count<=min(n,2N+8)`인 upper endpoint를
얻으면 이 최적화를 끝낼 수 있다. 이는 workspace 목표이며 N의 변경이나 mode cap이 아니다.
2. Cluster 때문에 목표 count로 줄일 수 없어도 `count>=N`인 마지막 safe upper를 쓴다.
Representable midpoint가 없거나 NR endpoint separation 폭에 도달하면 subdivision을
끝낸다. 경계에 있는 반복 고유치의 일부만 count하도록 tolerance를 조정하지 않는다.
3. 불필요하게 먼 lower bound를 줄이기 위해 `a=a0`, 위에서 얻은 `b=hi`로 시작한다.
`v=(a+b)/2`의 prefix count가 0이면 `a=v`로 이동하고, 양수이면 이 하한 축소를 끝낸다.
따라서 `(a0,a)`의 empty-prefix evidence를 잃지 않는다. 아주 작은 고립 cluster에서
넓은 구간이 검색 실패를 유발하는 Intel의 경고를 이 과정과 후검증으로 다룬다.
4. 최종 `(a,b)`에서 다시 count하여 `c>=N`이고 알려진 prefix와 일치함을 확인한다.
Capacity는 `m0=min(n,max(c+8,ceil(3c/2)))`로 한다. `c=n`이면 `m0=n`이다.
Checked integer arithmetic을 쓰며 큰 multiplicity도 전체 count를 수용한다.
5. Solve 성공 후 모든 `c`개를 독립 검증하고 정렬하여 첫 N개를 결과 candidate에 넣는다.
같은 eigenvalue의 multiplicity를 지우거나 평균내지 않는다. N번째가 repeated/cluster의
내부에 있으면 내부 계산 group은 보존하고 출력 row는 정확히 N개다.
Midpoint·endpoint 이동은 overflow-safe하게 수행한다. NR는 count-call budget,
endpoint separation coefficient와 perturbation 횟수를 구현 전에 고정한다. Budget은
각 search 및 endpoint 재시도까지 포함하는 유한 정수다. `-5` 등의 endpoint 실패 시
기록된 bracket 안에서 NR가 정한 간격으로 양옆의 endpoint 후보를 순서대로 평가하며,
성공한 prefix/count evidence 없이는 bracket을 갱신하지 않는다. 마지막 valid bracket이
없거나 count monotonicity/total count가 맞지 않으면 실패다. Search 최적화 budget에
도달하면 이미 검증된 enclosing bracket을 쓸 수 있으나 실패한 count를 성공으로 바꾸지 않는다.
Postsolve에서는 returned `m=c`, finite paired vectors/values, Gram rank, interval 내부
및 endpoints와의 separation을 확인한다. Endpoint에 너무 가깝거나 `info=1/2/3`,
count/solve mismatch이면 NR가 정한 유한 회수 안에서 safe bracket 확대·재count·capacity
확대만 허용한다. 매번 count/solve history를 보존한다. 그 뒤에도 불일치하면 실패하고
부분 모드 또는 다른 eigensolver로 fallback하지 않는다. Formulation은 이 수학적 알고리즘을
NR에 인계한다. 구현 진입 bundle은 다음 stage가 수치값·budget을 고정한 뒤 완성된다.
Full enclosing bound, empty-prefix, interval count와 solve-count/Gram 검증은 낮은 N개의
누락을 탐지하는 서로 다른 evidence다. Intel의 documented total count를 모든 conditioning,
endpoint 및 floating-point 상황의 completeness theorem으로 확대하지 않는다.
독립 known-spectrum의 zero/negative/cluster/repeated/size1/request=n case와 실제
설치 runtime 검증이 필수 연결점이며 선택 및 수치 기준은 NR가 소유한다.
## E7. FEAST 경계와 deterministic 실행
Actual eigenpairs는 `dfeast_scsrgv`로 E6의 `(A,I)` 또는 E6에서 동일하게 scale한
`(B,I)`를 풀어 구한다. Real symmetric, SPD second matrix, `n>0`,
`0<m0<=n`, strict finite `emin<emax`를 만족한다. `uplo=U`로 A와 identity mass의
각 CSR을 전달하며 row/column 증가 순서, duplicate-free, 1-based row pointer,
terminal `nnz+1`을 검증한다. 두 pattern이 같을 필요는 없다.
`MKL_INT`, `n`, `nnz+1`, column index와 `n*m0*sizeof(double)`의 변환/곱은 checked다.
FEAST vendor type과 scratch resource는 private backend에만 있다.
Call마다 `feastinit`한 128-entry parameter 배열에서 이번 call의 설정을 채운다.
CSR check, SPD check를 켜고 subspace-only mode는 끈다. Zero mode에도 적용할 수 있도록
trace stopping을 사용하고 독립 residual을 반드시 후검증한다. `epsout`만으로 pass하지
않는다. Contour points, stopping exponent, finite loop bound는 NR가 정한다.
User initial subspace를 선택하고 고정 seed/명시된 integer generator 및 고정 QR 순서로
full-column-rank 초기 공간을 만든다. `m0=n`에서는 identity를 쓴다.
Initial guess가 모든 eigenspace와 충분히 overlap한다는 보장은 없으므로 count/solve/Gram
검증으로 부족한 projection을 검출한다. Seed를 바꾸며 통과할 때까지 반복하지 않는다.
Backend의 thread/재현 설정과 seed는 실행 evidence에 기록한다. 동일 source 입력의
sparse structure, reduction, row 및 diagnostic 순서는 고정하며 repeated mode의 개별
벡터 방향은 수학적으로 유일하지 않다는 제한을 유지한다.
Solve는 `e,res`의 m0 entries와 column-major `x[n*m0]`를 준비하며 첫 m columns만
소비한다. Count call의 m0는 output count로 overwrite되므로 solve 요청수/실제 allocation
capacity와 분리한다. 설치 API가 count-only workspace의 작은 용량을 명시하지 않은
경우 보수적으로 count scratch는 `m0=n`, `x[n*n]`까지 준비하고 count 단계 사이에
재사용한다. Solve 전 해제할 수 있다. Reference n=3125에서 이 scratch는 약 78.1 MB
(74.5 MiB)이고 10모드의 실제 solve subspace는 이보다 작다. Count용 보수적 allocation은
dense Schur와 별개지만 `O(n²)` memory 비용이므로 Planning/Implementation이 peak 및
shifted sparse factorization fill을 측정한다. Allocation 실패 시 N을 줄이지 않는다.
Intel 근거: [API/storage/capacity](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/feast-scsrgv-feast-hcsrgv.html),
[C-index parameter와 count](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-input-parameters.html),
[status/endpoint/고립 cluster 주의](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/extended-eigensolver-output-details.html).
2026-09-06 확인. `info=0` 이외의 빈 interval, 미수렴, subspace 부족, count/inner solver,
allocation 또는 SPD 실패는 status와 stage를 보존하여 진단한다. Count success는 eigenpair
success가 아니며, caller의 count authority는 끝까지 `.inp`다.
## E8. Mode identity, normalization과 상태
모든 returned eigenpair를 lambda 오름차순으로 함께 정렬한다. Equal lambda의 tie는
original solver column order로 안정 정렬한다. Near-equal 값을 평균하거나 merge하지 않는다.
양의 modal mass로 column별 normalize하고, 가장 큰 absolute scaled global component의
sign이 양수가 되도록 한다(source DOF 순서로 tie 결정). 서로 다른 eigenvalues의 벡터를
Gram 보정 목적으로 임의 혼합하지 않는다. Failed orthogonality는 solve/validation 실패다.
정확한 repeated eigenspace의 다른 orthonormal basis는 같은 해이고 mode-shape external
matching은 없다. Density scaling/좌표 테스트는 repeated group의 projector로 비교한다.
Normalized `phi^T M phi=1`의 수치 convention에서 `phi_u`의 차원은 `M^-1/2`,
`phi_theta`는 `M^-1/2 L^-1`이고 modal amplitude가 `M^1/2 L`를 가진다.
Mode vector는 실제 응답 변위가 아니다. Scalar `lambda [T^-2]`와 source step/mode
identity를 분리하고 internal node/equation number를 source label로 노출하지 않는다.
원형상·density 검증→consistent/moment 검증→lumped 검증→K/M 조립→실제 BC→E2~E6
admissibility→E6~E7 FEAST→global 복원/독립 검증→candidate 결과 순서다.
반환 lambda는 부호를 보존한다. NR 기준상 유의한 음수는 불안정/invalid spectrum 실패,
near-zero는 분류와 raw value를 함께 유지하며 0으로 clamp하지 않는다.
양수에서만 `f=sqrt(lambda)/(2pi)`를 파생한다. 정확한 0은 f=0이고 작은 음수에는
실수 frequency를 만들지 않는다. 이 validity의 저장 방식은 I/O owner가 정한다.
N개 검증이 끝나기 전에 accepted state를 바꾸지 않는다. 검증된 candidate HDF5를
완성·검증·close한 뒤 final replacement를 수행하고 성공 뒤 준비된 state를 교환한다.
Replacement 이후 state 교환은 실패하지 않도록 준비한다. 제어된 solve/validation/write/
finalization failure에서 이전 accepted state와 기존 final HDF5를 보존한다.
Crash/power loss까지 원자성을 새로 주장하지 않는다. Live log lifecycle은 별도다.
Modal residual의 constrained 성분을 static reaction으로 출력하지 않는다.
@@ -0,0 +1,213 @@
# MITC4 consistent mass와 nodal block lumping 유도
- Feature ID: `mitc4-shell-feast-eigen`
- Owner: `formulation-agent`
- Input contract revision: `r1`
- 기본 보고서: [formulation.md](formulation.md)
근거는 [research evidence](research-evidence.md)의 `S01`, `S02`, `P01`, `R01`~`R03`이다.
아래 유도는 FESA의 승인된 운동학에 대한 것이며 Abaqus 내부 질량과의 동등성 주장이 아니다.
## M1. 변수, 원형상과 운동학
길이·질량·시간 차원을 각각 `L`, `M`, `T`라 한다. 각 element는 원형상 좌표
`X_i [L]`, 기존 patch에서 얻은 공통 unit nodal director `d_i`, 일정한 centered thickness
`t>0 [L]`, section의 material에서 결정된 일정 density `rho>0 [M/L³]`를 사용한다.
`E>0 [M/(LT²)]`, `-1<nu<0.5`와 기존 단일층 등방성 plane-stress 재료를 유지한다.
모든 입력 및 중간 결과는 finite여야 한다. 여기의 `t`는 두께이며 시간은 `tau`로 쓴다.
자연 좌표는 `(xi,eta,zeta) in [-1,1]^3`, source node 순서는
`(-1,-1),(1,-1),(1,1),(-1,1)`이다. 다음 형상함수와 실제 volume mapping을 사용한다.
\[
N_i=\tfrac14(1+\xi_i\xi)(1+\eta_i\eta),\quad z=t\zeta/2,\quad
X=\sum_iN_i(X_i+z d_i),\quad J=\det[X_{,\xi},X_{,\eta},X_{,\zeta}],
\quad dV=J\,d\xi d\eta d\zeta. \tag{M1}
\]
`sum Ni=1`, `Ni>=0`이다. Interpolated director를 normalization하여 M1의 geometry를
변경하지 않는다. 기존 kernel의 `EvaluateGeometry`와 같은 Jacobian 및 부호를 사용한다.
기존 [정식화](../linear-static-mitc4-shell/formulation.md)의 §§3~5, 8~11이
director 생성, tangent frame `(a_i,b_i,d_i)`, 기하 허용 조건과 MITC strain을 소유한다.
전역 nodal 좌표는 `q_i=[u_X,u_Y,u_Z,theta_X,theta_Y,theta_Z]^T`이다.
`u [L]`, `theta [1]`이고 양의 director 변화는 `theta cross d`이다. 다음 map을 정의한다.
\[
S_i=-[d_i]_\times,\quad P_i=I-d_i d_i^T=S_i^TS_i,\quad
G_i(z)=[I_3\ \ zS_i],\quad H=[N_1G_1\ \cdots\ N_4G_4]. \tag{M2}
\]
따라서 입자 변위/속도는 `u(X)=Hq`, `v(X)=H q_dot`이다. Physical nodal coordinates
`[u_X,u_Y,u_Z,alpha,beta]`에서 회전 열은 `[-z b_i, z a_i]`이다.
`alpha=a_i^T theta`, `beta=b_i^T theta`, `gamma=d_i^T theta`이며
`S_i d_i=0`이다. 20↔24 변환은 기존 `PhysicalTransformation20`/`DrillingTransformation4`
그대로이다. MITC assumed shear와 `5/6` shear factor는 strain/stiffness에만 작용한다.
속도 보간과 질량에 이 factor를 적용하지 않는다.
## M2. Strong/weak form과 기존 stiffness
원형상·무응력 상태의 소변형 무감쇠 자유진동에 대해 continuum parent는
`rho u_ddot = div sigma`, `sigma=C_ps:epsilon`, `sigma_33=0`이다.
자유 표면·자유 edge의 generalized traction은 0이고 essential data는 동차 global DOF
제약이다. 허용한 thickness 운동학과 MITC projection에 제한한 약형은
\[
\int_{\Omega_0}\rho\,\delta u^T\ddot u\,dV+
\int_{\Omega_0}\delta\bar e^T C_5\bar e\,dV+
\delta\gamma^T K_d\gamma=0. \tag{M3}
\]
원형상 elastic Hessian은 기존 stiffness다.
\[
C_5=\operatorname{diag}\left(
\frac{E}{1-\nu^2}\begin{bmatrix}1&\nu&0\\\nu&1&0\\0&0&(1-\nu)/2\end{bmatrix},
\frac56\frac{E}{2(1+\nu)}I_2\right),
\quad K_{20}=\sum_{g\in2\times2\times2}\bar B_g^TC_5\bar B_gJ_gw_g,
\]
\[
K_e=T_p^TK_{20}T_p+T_d^T(k_d I_4)T_d,\quad
k_d=10^{-3}\min\{(K_{20})_{rr}>0:r\text{는 tangent rotation}}. \tag{M4}
\]
`bar e=[epsilon11,epsilon22,gamma12,gamma13,gamma23]`이고 M4는 새 선택이 아니라
기존 [정식화 §12](../linear-static-mitc4-shell/formulation.md) 및
[실제 kernel](../../src/fesa/elements/mitc4_shell.cpp)의 고정 계약이다.
Drilling energy는 수치 stabilization이며 물리 strain/stress가 아니다.
`K_e q_e`는 내부 elastic generalized force, `M_L,e q_ddot,e`는 inertia다.
최종 반이산식은 `M_L q_ddot + Kq=0`이다. Harmonic ansatz
`q(phi,tau)=phi cos(omega tau)`에서 `Kphi=lambda M_L phi`, `lambda=omega² [T^-2]`를 얻는다.
새 constitutive/history state, geometric stiffness, damping, preload, nonlinear tangent,
time integrator 또는 modal stress/reaction recovery는 없다.
## M3. Consistent matrix와 충분한 quadrature
`T_C=1/2 integral rho |H q_dot|² dV`에서
\[
C^{(k)}_{ij}=\int_{\Omega_0}\rho N_iN_j z^k dV\quad(k=0,1,2),
\qquad
(M_C)_{ij}=\begin{bmatrix}
C^{(0)}_{ij}I_3&C^{(1)}_{ij}S_j\\
C^{(1)}_{ij}S_i^T&C^{(2)}_{ij}S_i^TS_j
\end{bmatrix}. \tag{M5}
\]
세 scalar moment matrix는 각각 symmetric `4×4`이다. 차원은 `C(k) [M L^k]`,
mass의 `uu/u-theta/theta-theta` block은 각각 `M/ML/ML²`이다.
`M_C [24×24]`는 global block 형식이며 20 physical mass의 congruence와 동일하다.
원본 `M_C`와 그것을 구성한 `C(0..2)`를 완성·검증한 후 lumping 입력으로 사용한다.
Global consistent sparse matrix를 eigen solve에 조립할 필요는 없지만 계산 원본을
lumped 결과로 덮어쓰거나 별도의 mass를 생성한 뒤 consistent에서 유도했다고 부르지 않는다.
M1은 각 자연 좌표에 최대 1차이다. Jacobian의 세 열의 최대 다항 차수는 각각
`(0,1,1)`, `(1,0,1)`, `(1,1,0)`이므로 determinant의 성분별 최대 차수는 `(2,2,2)`다.
`Ni Nj z^k J`의 차수는 최대 `(4,4,k+2)`, 즉 `(4,4,4)`이다. 따라서 **질량에는
3×3×3 Gauss–Legendre**를 사용한다. 각 축의 points는
`[-sqrt(3/5),0,+sqrt(3/5)]`, weights는 `[5/9,8/9,5/9]`이다.
3-point rule의 5차 정확성으로 M5의 모든 항을 이 geometry에서 정확 적분한다
(floating-point roundoff 제외). 추가 density/thickness 변화를 가정한 결론이 아니다.
Loop 순서는 증가하는 `xi`, 그 안의 `eta`, 가장 안의 `zeta`, 이후 `i<=j`, `k=0,1,2`로
고정하고 대칭 항을 복사한다. Mass 계산의 27개 실제 평가점에서도 기존 geometry
predicate를 적용한다. `J<=0`, nonfinite frame/basis 등의 실패를 weight 절댓값,
점 생략이나 flat replacement로 수리하지 않는다. 기존 stiffness 8-point 경로는 변경하지
않는다. 이 검사는 27점에서의 positivity를 보장하며 volume 모든 위치의 injectivity에
대한 새 theorem이나 기존 warp/curvature 범위의 확대를 주장하지 않는다.
왜곡된 flat element라도 같은 식을 쓴다. 서로 다른 director가 있으면 `J(zeta)`의 1차 항
때문에 `C(1)`이 0이 아닐 수 있다. Centered section만을 이유로 coupling을 버리거나
`C(2)=t² C(0)/12`를 일반식으로 사용하지 않는다.
## M4. 계산된 consistent moment에서 nodal block 유도
각 node의 세 row sum과 질량 block을 정의한다.
\[
m_i=\sum_j C^{(0)}_{ij},\quad h_i=\sum_j C^{(1)}_{ij},\quad
j_i=\sum_j C^{(2)}_{ij},\qquad
L_i=\begin{bmatrix}m_iI_3&h_iS_i\\h_iS_i^T&j_iP_i\end{bmatrix},
\quad M_{L,e}=\operatorname{blockdiag}(L_1,L_2,L_3,L_4). \tag{M6}
\]
이는 scalar moment row sum 후 tensor로 재구성하는 **nodal block lumping**이다.
Global 전체 행의 합, absolute row sum, diagonal scaling 또는 nodal quadrature와
혼용하지 않는다. 같은 source node의 incident element block은 기존 source element 순서로
합한다. 공통 `d_i` 때문에 조립 후에도 M6 형태다. Local와 global에서 diagonal이 아닌
`6×6` coupling은 허용한 lumped mass의 일부다.
`sum Nj=1`을 M5에 대입하면 정확히
\[
(m_i,h_i,j_i)=\int\rho N_i(1,z,z^2)dV,\quad
L_i=\int\rho N_i G_i(z)^TG_i(z)dV. \tag{M7}
\]
`m_i>0`, `j_i>0`, `m_i j_i-h_i²>0`이다. 마지막 부등식은 양의 measure에 대해
`z`가 상수가 아닌 점(양의 두께 및 서로 다른 thickness Gauss점)과 strict
Cauchy–Schwarz에서 따른다. 이를 이용하면
\[
q_i^TL_iq_i=m_i\left|u_i+\frac{h_i}{m_i}S_i\theta_i\right|^2+
\left(j_i-\frac{h_i^2}{m_i}\right)|S_i\theta_i|^2. \tag{M8}
\]
따라서 `L_i`의 rank는 5, null은 정확히 `[0;d_i]`의 span이다.
`zbar_i=h_i/m_i [L]`, `j_i-h_i²/m_i [ML²]`는 node에 할당된 thickness
measure의 centroid와 central tangent inertia다. 음/영 variance나 nonfinite를 clamp하지
않고 mass 검증 실패로 처리한다. 모든 노드에 최소 한 활성 shell이 연결되어야 한다.
M6의 유도 연결은 `C(k)` 원본→row sum→block reconstruction으로 추적한다.
동시에 M7을 독립 직접 적분하여 두 결과의 일치를 검증할 수 있다.
서로 다른 nodal frame의 rotary component를 직접 더하지 않는다.
## M5. 보존되는 양과 근사되는 양
모든 등식은 동일 원형상·density와 quadrature measure에 관한 것이다.
1. 총 병진 질량 `m=sum mi=integral rho dV` 및 모든 uniform translation의 kinetic
energy가 consistent와 정확히 같다. 각 방향의 total mass가 `m`이며 `trace(Muu)`를
총 질량이라고 정의하지 않는다.
2. Thickness scalar moment는 `sum hi=integral rho z dV`,
`sum ji=integral rho z² dV`다. 각 nodal tangent tensor는 `ji Pi`이고 drilling inertia는
0이다. 이는 물리 director의 회전 관성 정의이며 모든 rigid rotation의 전체 tensor를
consistent와 같게 만드는 계약은 아니다.
3. Lumping measure의 위치를 `x_i(z)=X_i+z d_i`로 보면 spatial first moment
`sum_i(mi Xi+hi di)=integral rho X dV`이므로 center of mass가 보존된다.
Node의 `Xi`에만 `mi`를 놓고 `hi di`를 누락하면 곡면에서 이 등식이 깨진다.
4. `v_i(z)=u_dot_i+z S_i theta_dot_i`에 대해 Jensen identity가 다음을 준다.
\[
\dot q^T(M_L-M_C)\dot q=
\frac12\int\rho\sum_{i,j}N_iN_j|v_i-v_j|^2dV\ \ge0. \tag{M9}
\]
두 kinetic energy의 차이는 M9의 절반이다. Equality는 positive-weight point마다 모든
`v_i`가 같을 때 성립한다. 일반 속도장 및 rigid angular motion의 orbital inertia는
달라질 수 있으며 lumped 값이 그 quadratic form에서 작아지지 않는다.
Rigid spatial rotation은 `u_i=Omega cross Xi`, `theta_i=Pi Omega`로 재현된다.
이때 M9는 nodal 위치 분산으로 생기는 angular-inertia 차이를 정확히 설명한다.
두 spectrum의 동일성, arbitrary mesh의 특정 수렴 차수 또는 Abaqus lumping 동등성을
acceptance로 요구하지 않는다. Smooth refinement에서 차이가 감소하는지는 독립 evidence다.
Proper orthogonal global rotation `Q`에 대해 `D_Q=blockdiag(Q,Q)`를 두면
`S(Qd)=Q S(d) Q^T`, `L'_i=D_Q L_i D_Q^T`이며 consistent에도 같은 congruence가
성립한다. 이는 tangent basis 선택과 독립적이다. Constraint도 같은 물리 공간으로 변환한
경우에만 spectrum의 좌표 불변성을 비교한다.
## M6. 직접 적분 가능한 평판 oracle
평행 director와 affine 직사각형 면적 `A`에서는
\[
C^{(0)}=\frac{\rho t A}{36}
\begin{bmatrix}4&2&1&2\\2&4&2&1\\1&2&4&2\\2&1&2&4\end{bmatrix},
\quad C^{(1)}=0,\quad C^{(2)}=\frac{t^2}{12}C^{(0)}. \tag{M10}
\]
각 node는 `mi=rho t A/4`, `hi=0`, `ji=rho t³ A/48`이다.
이는 production quadrature를 호출하지 않고 다항 적분으로 얻는 oracle다.
곡면에서는 M5~M9와 independent volume integration을 사용한다.
두께 `t` 변경 시 stiffness와 rotary inertia는 다른 차수로 변하므로 전체 spectrum에
하나의 thickness power law를 강제하지 않는다.
@@ -0,0 +1,222 @@
# 질량과 modal candidate의 검증식 및 Numerical Review 인계
- Feature ID: `mitc4-shell-feast-eigen`
- Owner: `formulation-agent`
- Input contract revision: `r1`
- 기본 보고서: [formulation.md](formulation.md)
[질량 식 M1~M10](formulation-mass.md), [축소·복원 식 E1~E8](formulation-eigen.md)의
기호를 사용한다. 이 문서는 측정량과 zero branch를 정의하며 수치 acceptance 값과
필수 benchmark 선정은 Numerical Review가 독립 검토하여 고정한다.
외부 기준의 수치는 [TOLERANCE](../TOLERANCE.md)를 그대로 적용한다.
## V1. 공통 scale과 zero branch
행렬·벡터 norm을 계산하기 전에 E1의 길이 congruence를 적용한다. 질량은 모두
`ML²`, stiffness는 `ML²/T²` 단위가 된 행렬에서 norm을 계산한다. Element-only
oracle에서는 `ell=Le`를 사용하고 assembled 비교에는 동일 global `ell`을 사용한다.
Norm과 sum-of-squares는 overflow/underflow를 피하는 scaled accumulation을 사용한다.
입력/행렬/각 eigenpair가 finite인지 먼저 검사한다.
이 문서의 모든 ratio `a/b`는 `b>0`에서만 계산한다. `a=b=0`이면 해당 항등식의
zero-case metric은 0이다. `b=0,a!=0`이면 named zero-scale failure이며 무한값/NaN
metric으로 성공 결과를 만들지 않는다. `max(1,b)`, arbitrary floor 또는 zero clamp는 없다.
대칭성은 `eta_sym(Q)=||Q-Q^T||F/||Q||F`이다. Diagonal copy로 생성한 symmetry와
독립 quadratic-work 검증은 구분한다. Cross-basis equality `R=S`는
`||R-S||F/(||R||F+||S||F)`로 측정한다. Mass/stiffness를 같은 norm의 분모에 직접 더하지
않고 필요한 lambda나 시간 scale을 곱한다.
## V2. 질량, rank와 보존 검증
- M10의 entrywise scalar oracle와 `M_C` quadratic form을 독립 적분과 비교한다.
계수·부호/두께 차수가 같은지를 component별 확인한 뒤 전체 norm을 사용한다.
- M5에서 구성한 `M_C`와 원본 moment, M6의 row-sum 결과, M7의 independent direct
integration을 따로 비교한다. 변조한 C(1)/C(2)가 lumped 결과 및 검증에 반영되는지
확인하여 두 mass 계산이 끊긴 우회 경로를 잡는다.
- Mass original과 derived 모두 `d_i` 방향의 null action을 검사한다.
Element/global scaled matrix에서 `eta_null=||Mhat z||2/(||Mhat||F ||z||2)`를 쓴다.
Lumped는 M8의 양의 두 항 및 physical positive-space Cholesky로 rank5를 검증한다.
Consistent physical 20-coordinate matrix도 positive여야 한다. 잘못된 quadrature에
의한 추가 hourglass/null mass를 허용하지 않는다.
- `mi>0`, `ji>0`, `zi=hi/mi`, `vi=ji/mi-zi²>0`를 검사한다.
`vi/ell²`, `|hi|/sqrt(mi ji)`는 dimensionless conditioning evidence다.
양의 `vi`를 낮은 rank로 바꾸는 기준을 두지 않는다. Direct centered integral
`integral rho Ni (z-zi)² dV`와 `ji-hi²/mi`의 일치는 cancellation을 드러낸다.
- Scaled node positive mass의 Cholesky reconstruction error와 reciprocal condition
estimate를 기록한다. 후자는 작은 block inverse action의 norm으로 계산할 수 있다.
물리 positive/null rank는 E2로 정하고 ill-conditioning은 별도 실패다.
- 총 질량은 uniform translation의 `q^TMq/|u|²`, geometry 적분의 `m=sum mi`를
비교한다. Spatial centroid는 M5의 scalar moment로 얻은
`sum(mi Xi+hi di)`와 독립 `integral rho X dV`를 비교한다.
좌표 원점으로 인한 cancellation을 피하려면 한 source node `Xref`를 공통 원점으로
잡고 first moment 차이를 `m ell`로 나눈다.
- M9의 `Delta=q_dot^T(M_L-M_C)q_dot`와 nonnegative pairwise integral을 독립 비교한다.
Scale은 `q_dot^T M_L q_dot + q_dot^T M_C q_dot`이며 zero motion/null-only field는
별도 zero branch다. Arbitrary velocity에서 equality를 요구하지 않는다.
## V3. Reduction과 full modal residual
`y_f=C^T D^-1 phi`, `k=||Kf||F`, `m=||Mf||F`라 두면
\[
r_f=K_f y_f-\lambda M_f y_f,\qquad
\eta_r=\frac{\|r_f\|_2}{(k+|\lambda|m)\|y_f\|_2}. \tag{V1}
\]
이것이 **모든 원 free DOF**의 inertia/elastic force balance다. 물리 공간에
project한 residual만으로 drilling/null 복원 오류를 놓치지 않는다.
`Kf y_f` 및 `Mf y_f`를 solve에 사용한 축소 matrix를 재사용하지 않고 원 조립값에서
검산한다. `Mf`는 actual lumped이며 consistent로 바꾸면 잘못된 metric이다.
`lambda=0`에서도 `k>0`이면 유효한 denominator가 있다. `Kf=0,lambda=0`은 zero branch,
zero eigenvector는 normalization 이전부터 실패다.
Whitened solve의 추가 metric은 `eta_w=||A x-lambda x||2 /
((||A||F+|lambda|)||x||2)`다. Backend `res/epsout`, eta_w, eta_r은 서로 다른 evidence다.
E3의 identity도 다음으로 검산한다.
\[
\eta_{KZ}=\frac{\|K_fZ-Z\operatorname{diag}(\kappa)\|_F}
{\|K_f\|_F\|Z\|_F+\|Z\operatorname{diag}(\kappa)\|_F},\quad
\eta_{MZ}=\frac{\|M_fZ\|_F}{\|M_f\|_F\|Z\|_F},\quad
\eta_{PZ}=\|P^TZ\|_F. \tag{V2}
\]
`nz=0`이면 V2는 적용 대상 없음으로 기록한다. M8/E3의 analytic proof가 먼저이고
V2 threshold만으로 새로운 nullspace를 발견하거나 coupling을 생략하지 않는다.
Kzz positivity와 `n/nz/nf`를 source node별 예상 null 여부와 연결한다.
Constraint metric은 `||(I-CC^T)D^-1 phi||2/||D^-1 phi||2`이며 source에 복원한
constrained components 자체도 exact zero를 확인한다.
## V4. Mass normalization, Gram, energy와 Rayleigh
각 mode의 generalized mass `g_i=phi_i^T M phi_i=y_i^T Mf y_i`는 finite, strictly
positive여야 한다. `phi_i <- phi_i/sqrt(g_i)`로 normalization한 뒤 재계산한다.
계산된 전체 c개 column에 대해
\[
G_{ij}=\phi_i^T M\phi_j,\quad
\eta_{norm,i}=|G_{ii}-1|,\quad
\eta_{orth,ij}=\frac{|G_{ij}|}{\sqrt{G_{ii}G_{jj}}}\ (i\ne j),\quad
\eta_G=\frac{\|G-I\|_F}{\sqrt c}. \tag{V3}
\]
Column pairing과 linear independence를 확인하며 FEAST의 c와 N을 구분한다.
부족한 rank를 같은 vector 복사로 채우면 V3에서 실패한다.
\[
h_i=y_i^TK_fy_i,\quad R_i=h_i/g_i,\qquad
\eta_{energy,i}=\frac{|h_i-\lambda_i g_i|}
{(k+|\lambda_i|m)\|y_i\|_2^2}. \tag{V4}
\]
`R_i [T^-2]`는 Rayleigh quotient다. V4는 eigenvalue가 0인 경우에도 쓸 수 있고
`|R_i-lambda_i|/|lambda_i|`만을 강제하지 않는다. 단위 modal amplitude에서 elastic
energy는 `h_i/2`, peak kinetic energy는 `lambda_i g_i/2`다. Physical/drilling 분해가
필요한 내부 검산에서는 `h_phys+h_drill=h_i`를 확인하되 별도의 drilling-energy
acceptance나 output quantity를 추가하지 않는다.
## V5. Rigid mode, coordinate 및 density 불변식
Free valid shell/patch의 rigid fields는 `u_i=c+Omega cross Xi`,
`theta_i=(I-di di^T)Omega`이다. 그 span에는 세 병진과 세 회전이 있다.
각 vector의 scaled K action을 `||Khat y||2/(||Khat||F ||y||2)`로 검증하고
mass Gram rank로 여섯 물리 움직임의 independence를 확인한다.
`Omega`의 full normal 성분을 UR에 넣어 drilling energy를 자극한 field는 이 테스트가 아니다.
Physical rigid zero eigenvalues는 finite mass 모드이고 E2의 massless drilling과 다르다.
Clamped reference에 여섯 zero mode를 요구하지 않는다.
Global rigid coordinate rotation에서 두 질량과 **physical stiffness**의 congruence 및
E1~E6 spectrum 불변성을 검사한다. Free rotation 3개 또는 rotation 3개 전체 고정의
node로 이루어진 사례는 finite 공간의 drilling 항이 0이므로 이 검증에 적합하다.
기존 `kd=min(physical tangent diagonals)*10^-3`는 선택한 tangent basis에 의존할 수 있다.
따라서 재계산한 kd까지 임의 회전에서 동일 scalar라 가정하거나 부분 회전 BC에 남는
stabilization의 좌표 불변성을 새로 주장하지 않는다. 같은 kd를 유지한 단순 tensor
변환이면 complete K도 congruent하지만 별도 geometry에서 kd를 재선정한 경우와 다르다.
기존 stabilization 의미를 유지하는 한계이며 coefficient를 바꾸지 않는다.
Rotation 후 이전 global component BC를 그대로 두고 같은 문제라고 주장하거나
새 MPC 입력 기능을 추가하지 않는다.
모든 density를 동일 `c_rho>0`로 바꾸고 geometry/material stiffness/BC를 유지하면
\[
M_C'=c_\rho M_C,\quad M_L'=c_\rho M_L,\quad
\lambda_i'=\lambda_i/c_\rho,\quad
\Phi'=\Phi Q/\sqrt{c_\rho}. \tag{V5}
\]
단일 simple eigenvalue에서는 Q가 sign이고 repeated group에서는 orthogonal mixing이다.
Eigenvalue scaling error는 `|c_rho lambda_i'-lambda_i|/s`로 측정한다
(`s`는 baseline E6 operator time scale). Group vector 비교는
`U=L^T P^T C^T D^-1 Phi`, `U'=L^T P^T C^T D^-1(sqrt(c_rho) Phi')`로 정의한
projector 차이 `||UU^T-U'U'^T||F/sqrt(2r)`를 사용한다. r은 group dimension이다.
Dense projector를 구성하지 않고 orthonormal U/U'의 cross-Gram으로 같은 norm을 계산할
수 있다. Arbitrary clustered-but-distinct vectors를 회전하여 다른 eigenpairs로 만들지 않는다.
## V6. Lowest N, cluster, near-zero와 오류 판정 소유권
E6 count/solve history는 각 `(a,b)`, prefix empty evidence, status, count, m0,
returned m, loop/epsout, bounds source와 final selected ranks를 보존한다.
모든 returned pair에 interval separation을 검사하고 requested N개만 검사하지 않는다.
Near-zero/negative 분류 scale은 `s` 또는 그와 동등한 E6 operator scale이며 reference
최소값이나 arbitrary absolute frequency가 아니다. Raw lambda는 바꾸지 않는다.
NR가 구현 전에 결정해야 할 항목은 다음과 같다.
| 대상 | 수치값/필수 검사 소유권과 필요한 scale |
| --- | --- |
| Matrix symmetry, moment/oracle/centroid/M9 | V1/V2의 same-unit norm, total mass 및 `m ell`; roundoff/독립 적분 오차 분리 |
| Null/orthogonal basis, KZ/MZ, mass conditioning | M8/E2 analytic rank, V2 및 작은 positive block condition; near-null 삭제 금지 |
| Residual, Gram, energy, rigid modes | V1~V4, V5 K-action; machine precision·차원·conditioning 근거 |
| Near-zero/negative/cluster 분류 | `|lambda|/s`, pairwise `|lambda_i-lambda_j|/s`; raw value 보존 |
| FEAST control | Contour points/precision exponent/refinement bound, finite count/endpoint/solve retry budget |
| Endpoint safety | Operator scale와 ULP, count monotonicity, enclosing total n, solve/count 및 full-rank Gram |
| Independent test portfolio | 평판 M10, warped/director-varying M5~M9, 비축정렬/부분 BC/E5 오류 case, FEAST known spectra, density/rigid/좌표 tests |
| External reference | 원본 input+TXT Value, mode/frame identity와 singleton 여부, common family 및 blocking 판정 |
Small independent pencil은 손으로 대각화 가능한 값을 사용하고 동일 production
mass/reduction/eigensolver를 기대값 계산에 호출하지 않는다. API wrapper의 injected status
검사와 실제 FEAST runtime known-spectrum 검사는 모두 필요하다. Size1, N=n, repeated
group>N, tight cluster, zero/negative, empty interval, insufficient subspace, count collision,
unresolved conditioning 및 allocation/index failure가 해당 공식 계약을 검증한다.
Case의 구체적 목록·숫자는 NR가 정하고 Planning이 tests와 TDD steps에 연결한다.
외부 비교는 지정 [원본 input](../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp)과
[원본 TXT](../../reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine%20eigenvalues.txt)의
`Value`만 사용한다. `lambda [T^-2]`, source `Step-2`, mode 1..10이 의미적 대응이다.
Frequency 재계산, mode shape correlation이나 다른 mass variant의 더 가까운 결과 선택으로
이를 대체하지 않는다. Mode/frame은 NR/I/O가 common same-frame family 규칙에 맞춰
정의하고 missing/extra/duplicate/nonfinite를 tolerance 전에 거부한다.
Schema 경로/저장 field/public diagnostic 이름은 I/O owner의 계약이다.
## V7. 실행 evidence와 남는 위험
Formulation 단계에서는 승인 문서와 실제 source를 read-only로 대조하고 자체 수식을
전개했다. 다음 입력은 변경하지 않았다: requirements/research, 관리문서, source/tests/build,
Harness, 공통 tolerance 및 원본 reference. External solver, CMake/CTest, Harness, FEAST
runtime, numerical reference comparison은 실행하지 않았다. 이 문서는 수치 통과 evidence가 아니다.
`Get-Content`, scoped `rg`로 M4의 변환·stabilization과 공통 nodal frame 전달을 확인했다.
한 scoped `rg` 호출은 존재하지 않는 `runtime_element_factory.cpp`와 PowerShell literal
glob 경로 때문에 exit `1`이었다. `rg --files`/`rg -n ... src/fesa`로 실제
`element_factory.cpp`, `shell_geometry.cpp`를 찾아 재조회했고 exit `0`이었다.
Intel parameter/API/status의 공식 문서를 2026-09-06 다시 열어 count 의미,
endpoint/count failure와 m0 capacity를 확인했다(E7의 URL 및 research S05~S07).
`Get-FileHash`는 exit `0`이며 원본 SHA-256은 upstream과 같다.
Input: `913b1abc604e62bc5f995bf5523924e17ea03925102a7bd22d39226ba0ea7339`.
TXT: `20d97ca3fd51f5b956f2c1ed7565557c68f74e61e41b913748515ef43a0f7f0b`.
Owned 4개 문서를 `python -B -` read-only here-script(`pathlib`, `re`,
`urllib.parse.unquote`)로 정적 검사했다. Owner/Feature/revision, 26개 requirement
coverage, 상대 링크 실재, trailing whitespace/final newline, display-math delimiter와
언어 혼입을 검사했다. Exit `0`, documents `4`, local links `38`, requirements `26`,
issues `0`이다. `git diff --check`도 exit `0`이며 Coordinator 소유 `coordination.md`의
LF/CRLF warning만 출력되었다. 새 untracked owned 문서의 whitespace는 위 Python 검사로
별도 확인했다. `git status --short`에서 owned 4개와 타 owner coordination 변경을 구분했으며
stage/commit 또는 타 owner 수정은 하지 않았다.
잔여 위험은 매우 얇은 shell/거의 정렬된 부분 BC의 mass conditioning, geometry quadrature
검사점 밖의 전역 injectivity 한계, floating-point FEAST count/endpoint와 repeated subspace,
count scratch 및 shifted factorization memory다. NR가 위 metric·수치 기준·case를 고정하고
Implementation이 실제 설치 backend와 reference evidence를 제시해야 해소된다.
@@ -0,0 +1,69 @@
# MITC4 질량행렬과 FEAST 고유치 정식화
- Feature ID: `mitc4-shell-feast-eigen`
- Owner: `formulation-agent`
- Input contract revision: `r1`
- 요청 outcome: `pass`; 다음 owner: `numerical-review-agent`.
- 상태: 독립 numerical review 요청이며 자기 승인이나 workflow 전이가 아니다.
필수 입력은 [FEATURED_AGENTS](FEATURED_AGENTS.md), [PRD](PRD.md), [ADR](ADR.md),
[requirements](requirements.md), [requirements evidence](requirements-evidence.md),
[research](research.md), [research evidence](research-evidence.md)이다.
[프로젝트 지침](../../AGENTS.md), [프로젝트 PRD](../PRD.md), [ARCHITECTURE](../ARCHITECTURE.md),
[공통 ADR](../ADR.md), [TOLERANCE](../TOLERANCE.md), [agent 계약](../SOLVER_AGENT_DESIGN.md),
[문서 소유권](../FEATURE_DOCUMENTATION.md)을 적용했다.
## 핵심 계약
1. 기존 원형상 MITC4 운동학·강성·director·global 6 DOF 의미를 유지한다.
Physical 3 translation/2 tangent rotation의 consistent mass와 구성 scalar moments를
같은 Jacobian으로 계산한다. Trilinear mapping의 mass integrand는 각 축 최대 4차이므로
mass는 3×3×3 Gauss로 충분하며 곡면의 odd-thickness coupling을 유지한다.
식과 단위·strong/weak form: [mass M1~M5](formulation-mass.md).
2. 계산된 consistent moment를 row-sum하여 global nodal 6×6 block lumped mass를 만든다.
총 병진 질량·spatial centroid·할당된 thickness moments를 보존하고 drilling은 정확한 null이다.
일반 운동에너지 차이는 nonnegative Jensen identity로 명시한다.
보존/근사 범위와 독립 평판 oracle: [mass M6~M10](formulation-mass.md).
3. 실제 homogeneous global constraints를 먼저 적용한다. Free space에 완전히 포함된
director null만 분리한다. 기존 nodal stabilization에 의해 Kpz=0, Kzz>0임을 입증하여
finite spectrum을 nodal projection으로 보존하며 부분 BC에 남는 stabilization은 유지한다.
Sparse block whitening, rank 예외와 global 복원: [eigen E1~E5](formulation-eigen.md).
4. Actual FEAST mass와 모든 modal 검증은 derived lumped다. `.inp`의 N을 유지하고
finite enclosure·prefix count·cluster capacity·count/solve 일치와 독립 eigenpair 검증을
결합한다. Endpoint/conditioning 한계를 count theorem으로 과장하지 않는다.
Backend 경계와 bounded search, 상태 보존: [eigen E6~E8](formulation-eigen.md).
## Requirement coverage
아래 ID는 모두 `FEM-REQ-MITC4-EIGEN-` 접두사다. Requirements matrix의 acceptance 원본을
복제하지 않으며 formulation의 기여와 다음 owner를 구분한다.
| IDs | 정식화/검증 연결 | 후속 확인 |
| --- | --- | --- |
| `001`, `002`, `004` | mass M1~M4: 원형상, 기존 MITC4·director·재료·기하·단위 | NR, I/O |
| `003` | mass M1/M5: 양의 일정 rho와 section별 연결 전제 | I/O semantic validation |
| `005`, `006`, `026` | mass M5~M10, verification V2: consistent→lumped, coupling, positivity/null, 보존/근사 | NR independent oracle |
| `007`, `008` | eigen E1~E5, verification V3: stable assembly, 실제 BC/null, finite spectrum 및 복원 | NR rank/conditioning |
| `009`, `010`, `011`, `012` | eigen E6~E8, verification V6: 낮은 N, multiplicity, 실제 FEAST, 유한 실패 | NR numerical controls, real runtime |
| `013`, `014`, `018` | verification V1~V5: lumped residual/Gram/energy/rigid/density/좌표, source/global 복원 | NR, Physics |
| `015`, `016` | mass M2 및 eigen E1/E6: 무감쇠 단일 procedure·동차 BC·input N authority | I/O exact syntax/no-op/exclusion |
| `017`, `019` | eigen E8: lambda/normalization 의미, source identity, candidate/final 보존 | I/O additive schema/failure |
| `020`, `021`, `022` | verification V6: 지정 TXT Value-only, identity 사전검사/common tolerance | NR family, I/O mapping |
| `023`, `024`, `025` | 기존 K 경로 유지 및 owned 수식/evidence 연결; 실행 결과는 주장하지 않음 | Planning TDD/MSVC/회귀, Physics/Release closure |
## Evidence와 handoff
실제 kernel의 PhysicalTransformation20/DrillingTransformation4와 kd 선택식,
ElementFactory의 공통 nodal director 전달을 대조했다. 원본 두 reference의 SHA-256은
requirements/research와 일치한다. 출처와 실제 read/hash 명령·미실행/위험은
[verification V7](formulation-verification.md)에 있다.
Source/reference/upstream을 편집하지 않았고 수치 실행 결과를 통과로 보고하지 않는다.
현재 새 physics/scope/compatibility 선택이나 사용자 미결정은 없다.
Numerical Review는 [verification V6](formulation-verification.md)의 dimensionless metric,
zero branch, analytic rank와 finite algorithm을 독립 검토하여 threshold, FEAST control/budget,
필수 benchmark 및 reference mode/frame family를 고정한다. I/O는 영속 schema를 정의한다.
이번 formulation stage는 완결된 수학 계약을 NR에 인계하며, 실제 구현 진입에 필요한
전체 계약 bundle은 NR의 수치 기준과 후속 I/O/planning 이후 완성된다.
Count의 floating-point 한계, near-null conditioning, shifted sparse fill와 보수적 count
scratch 비용은 아직 실제 runtime evidence가 필요하다. Release readiness를 주장하지 않는다.