diff --git a/docs/hex8-structural-analysis/ADR.md b/docs/hex8-structural-analysis/ADR.md new file mode 100644 index 0000000..650d338 --- /dev/null +++ b/docs/hex8-structural-analysis/ADR.md @@ -0,0 +1,49 @@ +# Hex8 기능 결정 기록 + +Feature ID: `hex8-structural-analysis`. 상태: 사용자 승인된 구현 계약. +기준: [프로젝트 지침](../../AGENTS.md), [공통 PRD](../PRD.md), [공통 ADR](../ADR.md). +상세 행동은 [PRD](PRD.md), 수식은 [formulation](formulation.md)을 따른다. +아래 결정은 ready 인터뷰 및 최종 승인 뒤 go 실행 요청으로 확정했다. 구현/검증 통과를 의미하지 않는다. + +## HEX8-ADR-001 — Full-integration TL–StVK + +**선택:** 8절점 일반 등매개 육면체, 3개 병진 DOF,2×2×2 전체 Gauss 적분, +Total Lagrangian–St. Venant–Kirchhoff의 energy/internal force/material+geometric tangent. +**이유와 영향:** 큰 회전·작은 elastic strain을 대상으로 같은 energy의 미분 일관성을 검증한다. +Reduced/SRI/hourglass/hybrid/incompatible mode는 첫 범위에 없다. 굽힘/체적 잠김과 +거의 비압축성 conditioning 한계를 공개한다. Abaqus C3D8 내부 처리와 동일하다고 주장하지 않는다. + +## HEX8-ADR-002 — Constant reference consistent mass + +**선택:** M은 기준 밀도와 형상의 rho NiNj I 적분이며 eigen과 linear/nonlinear HHT에 동일하게 사용한다. +**영향:** 전역 sparse generalized K/M가 필요하다. Shell nodal whitening·null-space 처리나 +row-sum lumping을 호환 경로로 쓰지 않는다. Solid에는 회전/convective 관성이나 drilling이 없다. + +## HEX8-ADR-003 — End-to-end Solid-only 절차 + +**선택:** Linear/nonlinear static, 원형상 unloaded frequency, linear/nonlinear HHT와 공식 HDF5를 연결한다. +Nodal force와 static 영/비영 prescribed displacement만 지원하며 mixed Beam/Shell/Solid·pressure/ +body force·prestressed modes는 제외한다. Dynamic은 initial q/v0, fixed zero BC·fixed step이다. +**영향:** Model/DOF/state/writer에 Solid의3성분 분기가 필요하며 dummy6성분 결과로 대체하지 않는다. + +## HEX8-ADR-004 — Reference ramp와 integration-point stress + +**선택:** 제공된 dynamic 원본에 필요한 TABULAR/STEP TIME/RELATIVE piecewise-linear CLOAD +amplitude를 지원한다. 사용자 최종 답변 `1A, 2B 적분점 응력 결과로 수정했습니다.`에 따라 +수정된 static S의8점6성분을 필수 비교한다. Static/BC amplitude·비영 초기 상태는 추가하지 않는다. +**영향:** 곡선별 source load block을 보존하고 endpoint/initial force를 평가한다. Point key는 +element/IntPt/component이며 elemental-nodal stress·평균·외삽으로 바꾸지 않는다. + +## HEX8-ADR-005 — 독립 검증과 필수 외부 비교 + +**선택:** 분석/불변량·독립 numerical/physics 검토·실제 전체 Debug 회귀 및 승인 원본 비교를 결합한다. +**영향:** 공통 row5%/RMS1%를 유지한다. MITC4 eigen RMS5% scoped exception은 적용하지 않는다. +원본 frequency Value 부재는 필수 비교 미실행이며 기능 검증 완료 대기다. 제공된4개 응답 case와 +독립 eigen 검증은 진행한다. 기존 HHT baseline FAIL/SKIP을 신규 문제와 구분하며 전체 green을 주장하지 않는다. + +## HEX8-ADR-006 — 기존 프로젝트와 소유권 유지 + +**선택:** Absent local marker에도 사용자 선택 A에 따라 기존 AGENTS/docs 맥락을 유지한다. +**영향:** Foundation과 공통 요구/결정을 재작성하지 않는다. Feature 문서는 자체 계약과 필요한 +handoff/evidence만 소유한다. Shared CMake/factory와 prepared/HDF5 연결에 단일 writer를 둔다. +Failed candidate/출력 실패에서 accepted history와 기존 final HDF5를 보존한다. diff --git a/docs/hex8-structural-analysis/FEATURED_AGENTS.md b/docs/hex8-structural-analysis/FEATURED_AGENTS.md new file mode 100644 index 0000000..e7a9f38 --- /dev/null +++ b/docs/hex8-structural-analysis/FEATURED_AGENTS.md @@ -0,0 +1,37 @@ +# Hex8 구조해석 작업 지침 + +Feature ID: `hex8-structural-analysis`. 사용자 승인: 2026-10-08 ready 문서 승인 및 go 실행 요청. +개인 연구용 FESA에 full-integration Hex8의 선형/기하비선형 강성·일관 질량과 +static/frequency/HHT 절차를 추가한다. 코드 존재와 기능 검증 완료를 구분한다. + +상위 기준은 [프로젝트 지침](../../AGENTS.md), [공통 PRD](../PRD.md), +[공통 ADR](../ADR.md), [기능 문서 관리](../FEATURE_DOCUMENTATION.md)다. +현재 요구와 유일한 checklist는 [PRD](PRD.md), 선택 이력은 [ADR](ADR.md)에 있다. + +| 문서 | 책임·용도 | +| --- | --- | +| [formulation](formulation.md) | 3D local 계산, energy/force/tangent, mass·HHT와 검증 불변량 | +| [io](io.md) | 입력 의미·typed 경계·공식 결과 metadata/units·진단 | +| [numeric controls](numeric-controls.md) | 수치 scale·zero branch·tuning·독립 검사 기준 | +| [reference model](reference-model.md) | read-only 원본 inventory·quantity/key/point/time mapping | +| [numerical review](numerical-review.md) | 작성자와 독립된 정식화/controls 검토의 결과 | + +메인이 문서·공유 연결·완료 판단을 소유한다. Kernel owner는 Hex8 local 계산/복구 payload와 +직접 consumer를, semantic owner는 Domain/parser/3성분 DOF/load/assembly를 소유한다. +Static/eigen/dynamic owner는 별도 Solid state와 executor를 소유한다. 중앙 prepared/result/CLI/ +HDF5 dispatch는 한 owner가 연결하고, 공용 CMake/factory 등록은 메인이 병합 후 처리한다. +다른 owner의 변경을 revert하거나 중앙 파일에 병행 writer를 추가하지 않는다. + +이 기능은 Solid-only·3N이다. Shell의6N/drilling/null/회전 state나 nodal mass reduction을 +사용하지 않는다. 요소 행렬은24×24, output은 N×3와 E×8×6이다. Geometry는 cell 전체의 +positive Jacobian을 보수적으로 인증하고 uncertain geometry/trial을 명시적으로 실패시킨다. +절점 순서와 IntPt 순서를 구분하며 tensor shear와 engineering shear를 혼용하지 않는다. + +원본 `reference/hexa/`는 read-only다. 외부 tolerance를 완화하거나 reference를 생성·보정하지 +않는다. Frequency 원본 modal Value가 없는 동안 구현은 계속할 수 있으나 전체 기능 검증은 +완료하지 않는다. 동적 reference는101 frame 전체 U, 정적은 U/constrained RF/Gauss Cauchy S가 필수다. + +새 정식화와 구현 수치 변경은 독립 numerical review를, 실제 결과는 필요한 독립 physics +평가를 거친다. 일반 승인 작업마다 승인 gate를 추가하지 않는다. Physics·영속 schema·acceptance +변경 또는 해결되지 않은 필수 reference 충돌만 메인이 사용자에게 근거와 영향을 전달한다. +Dev 통합·push/release는 별도 명시된 사용자 결정이다. diff --git a/docs/hex8-structural-analysis/PRD.md b/docs/hex8-structural-analysis/PRD.md new file mode 100644 index 0000000..eac24c7 --- /dev/null +++ b/docs/hex8-structural-analysis/PRD.md @@ -0,0 +1,436 @@ +# Hex8 구조해석 제품 요구사항 + +Feature ID: `hex8-structural-analysis`. 작성일: 2026-10-08. 상태: 사용자 승인된 구현 계약; 검증 완료 대기. +기준 저장소: `dev`, `2382d3af7ef335bef216d963540f2e9bd2befd68`. + +## 목적과 선택 이유 + +개인 연구용 FESA에 8절점 육면체의 선형 강성, 기하비선형 내력·접선 강성, 일관 질량을 +구현하고 입력부터 정적·고유치·동해석과 HDF5 결과까지 연결한다. 요소 행렬 계산만으로 +완료하지 않는다. 기존 프로젝트를 유지하며 새 프로젝트 기준을 재작성하지 않는다. + +첫 구현은 큰 회전·작은 탄성 변형률을 대상으로 한다. 전체 8점 적분과 Total Lagrangian +St. Venant–Kirchhoff 식을 선택해 에너지·내력·접선의 일관성을 독립 검증한다. 일관 질량은 +고유치와 동해석 모두에 사용한다. 집중 질량이나 안정화로 계산 결과를 맞추지 않는다. +일반 등매개 육면체를 지원하지만 full integration의 굽힘·체적 잠김 한계는 공개한다. + +초기 합의의 일정 동하중에 더해, 제공된 reference의 ramp를 처리하도록 구간별 선형 +집중력 amplitude를 포함한다. 지정 변위의 시간 변화나 비영 초기 변위·속도까지 확대하지 않는다. + +상위 기준: [공통 요구](../PRD.md), [구조](../ARCHITECTURE.md), +[외부 계약](../contracts.md), [수치 정책](../TOLERANCE.md), +[기능 기록](../FEATURE_DOCUMENTATION.md). 기존 상세 계약을 구현 편의로 덮어쓰지 않는다. + +지역 지침과 문서 목록은 [FEATURED_AGENTS](FEATURED_AGENTS.md), 결정은 [ADR](ADR.md), +상세 유도는 [formulation](formulation.md), 입력/내부 API는 [io](io.md), 수치 controls는 +[numeric-controls](numeric-controls.md), 원본 mapping은 [reference-model](reference-model.md)을 따른다. + +## 요구사항과 계산 계약 + +### FEM-REQ-HEX8-001 — 지원 해석과 모델 + +육면체 단독 모델에서 선형 정적, 기하비선형 정적, 원형상·무응력 선형 frequency, +선형 및 기하비선형 HHT 동해석을 지원한다. 한 입력에 단일 step·단일 procedure이며 +기존 Part/identity Instance·target/set subset을 재사용한다. 혼합 Beam/Shell/Solid 모델은 거부한다. +서로 다른 유효한 영역에 재료를 배정할 수 있지만 한 요소 내부의 재료는 균질하다. + +### FEM-REQ-HEX8-002 — 요소·형상·순서 + +Source `C3D8`을 FESA Hex8로 연결하고 source 표기·instance·element/node label을 보존한다. +`C3D8R`, `C3D8I`, `C3D8H`, 20절점 요소를 alias로 수용하지 않는다. 요소는 서로 다른 +8개 절점과 병진 `[UX,UY,UZ]`를 가지며 local 행렬은 node-major 24×24다. + +자연 좌표 절점 순서는 다음과 같다. + +| 절점 | ξ | η | ζ | +| --- | ---: | ---: | ---: | +| 1 | -1 | -1 | -1 | +| 2 | +1 | -1 | -1 | +| 3 | +1 | +1 | -1 | +| 4 | -1 | +1 | -1 | +| 5 | -1 | -1 | +1 | +| 6 | +1 | -1 | +1 | +| 7 | +1 | +1 | +1 | +| 8 | -1 | +1 | +1 | + +\(N_a=(1+\xi_a\xi)(1+\eta_a\eta)(1+\zeta_a\zeta)/8\), +\(X=\sum N_aX_a\), \(u=\sum N_au_a\). J0의 column은 자연 좌표에 대한 X 미분이다. +\(G_a=\nabla_XN_a=J_0^{-T}\nabla_\xi N_a\)를 사용한다. +뒤틀린 면·기울어진 모서리를 허용한다. 비유한·중복/퇴화 절점, 반전·접힌 형상은 거부한다. +유효성은 자연 cell의 양의 Jacobian을 확인하는 보수적 검증으로 정의하고, 적분점만 양수인 +접힌 cell을 정상으로 선언하지 않는다. 양성을 판정하지 못한 형상은 명시적 진단으로 거부한다. +현재 형상의 반전도 trial 실패다. `abs(det J)`·절점 재배열·epsilon 보정은 금지한다. + +### FEM-REQ-HEX8-003 — 재료와 단위 + +상수 등방성 탄성 \(E>0,-1<\nu<0.5\)와 기준 밀도 \(\rho_0>0\)를 사용한다. +모든 값과 파생 Lamé 상수는 finite여야 한다. 밀도는 고유치·동해석에서 필수이며 정적 +입력의 양의 density는 보존하되 강성에 사용하지 않는다. 입력 일관 단위를 유지한다. +\(\mu=E/[2(1+\nu)]\), \(\lambda=E\nu/[(1+\nu)(1-2\nu)]\)다. +거의 비압축성인 입력을 다른 재료식으로 바꾸지 않으며 잠김과 conditioning을 구분해 보고한다. + +### FEM-REQ-HEX8-004 — 적분 규칙 + +강성·내력·접선·질량·에너지에 동일한 2×2×2 Gauss 규칙을 사용한다. +각 축은 ±1/√3, weight=1이며 volume weight는 det J0다. 출력 point ID는 +`1:---, 2:+--, 3:-+-, 4:++-, 5:--+, 6:+-+, 7:-++, 8:+++` 순서다. +절점 순서와 적분점 순서를 혼동하지 않는다. 감소 적분·선택적 체적 적분·hourglass 항은 없다. +일반 뒤틀린 요소에서 8점 질량이나 비선형 적분이 연속체 적분과 항상 exact하다고 주장하지 않는다. +높은 차수 적분 oracle는 정확도·한계의 검사이며 production 규칙의 자동 변경이 아니다. + +### FEM-REQ-HEX8-005 — 선형 강성 + +미소변형률 \(\epsilon=\operatorname{sym}\nabla_Xu\), \(\sigma=\lambda\operatorname{tr}\epsilon I+2\mu\epsilon\). +공학 전단 벡터 순서는 `[ε11,ε22,ε33,2ε12,2ε13,2ε23]`, 응력은 +`[S11,S22,S33,S12,S13,S23]`다. 일의 짝이 되는 B0와 C를 사용해 +\(K_0=\sum_g B_{0g}^TCB_{0g}\det J_{0g}\), \(f_{int}=K_0u\)를 계산한다. +대칭성·6개 강체 영모드·상수 변형률 patch·단위와 scale을 독립 검증한다. + +### FEM-REQ-HEX8-006 — 비선형 내력과 접선 + +기준 형상에서 \(F=I+\sum_a u_a\otimes G_a\), +\(E_G=(F^TF-I)/2\), \(W=\lambda(\operatorname{tr}E_G)^2/2+\mu E_G:E_G\), +\(S=\lambda\operatorname{tr}E_GI+2\mu E_G\), \(P=FS\)다. +\(f_{ai}=\sum_g P_{iJ}G_{aJ}\det J_{0g}\)와 같은 에너지의 일관 미분 +\(K_t=K_{mat}+K_{geo}\)를 반환한다. + +\[ +A_{iJkL}=\delta_{ik}S_{LJ}+F_{iI}\mathbb C_{IJLN}F_{kN},\qquad +(K_t)_{ai,bk}=\sum_gG_{aJ}A_{iJkL}G_{bL}\det J_{0g}. +\] + +\(\mathbb C_{IJLN}=\lambda\delta_{IJ}\delta_{LN}+\mu(\delta_{IL}\delta_{JN}+\delta_{IN}\delta_{JL})\). +기하 항은 \(\delta_{ik}G_a^TSG_b\), 나머지는 재료항이다. Kgeo만으로 전체 비선형 강성을 +대체하지 않는다. 내부 API는 두 항과 합, 내력·에너지·복구량을 구별한다. 같은 trial에서 +계산하며 유한차분 접선을 production 계산으로 사용하지 않는다. 강체 유한회전의 zero +strain/energy, 에너지 gradient·내력 tangent, 좌표 공변성, 선형극한을 검사한다. + +### FEM-REQ-HEX8-007 — 일관 질량 + +\((M_e)_{ai,bj}=\delta_{ij}\sum_g\rho_0N_aN_b\det J_{0g}\)를 사용한다. +기준 형상과 밀도로 정해져 변형·시간에 따라 바뀌지 않으며 회전 자유도·drilling 관성은 없다. +고유치와 동해석은 같은 전역 일관 M을 사용한다. Row-sum lumping·nodal block 치환은 금지한다. +대칭 양정성·각 병진 방향 총질량·좌표 회전·독립 적분을 검증한다. 전역 행렬은 sparse로 조립한다. + +### FEM-REQ-HEX8-008 — 경계와 집중력 + +`*BOUNDARY`와 `*CLOAD`는 DOF1–3만 허용한다. DOF4–6은 값이 0이어도 거부한다. +정적은 영/비영 지정 변위를 지원하고, 선형은 \(K_{ff}u_f=F_f-K_{fc}u_c\)다. +비선형 정적에서는 지정 값과 외력을 같은 load factor로 증가시켜 이전 accepted 상태에서 +Newton을 수행한다. 동해석은 고정 exact-zero 경계만 지원한다. 동일 resolved node/DOF의 +집중력은 source 순서로 합산한다. 모든 자유도가 constrained인 유효한 모델은 empty free +system으로 처리한다. 미구속 자유 강체의 정적 특이성은 질량·임의 고정점으로 보정하지 않는다. + +### FEM-REQ-HEX8-009 — 동하중 amplitude + +육면체 dynamic에서 모델-level `*AMPLITUDE, NAME=...`의 TABULAR, STEP TIME, +VALUE=RELATIVE만 지원한다. 각 선택자는 생략 시 이 값이며 명시된 동일 값도 허용한다. +유일한 이름과 한 개 이상 finite `(t,A)` pair, `t>=0`·strictly increasing 시간을 요구한다. +한 row의 여러 pair와 여러 data row를 허용한다. Knot은 원 값, 내부는 구간별 선형 보간, +범위 밖은 첫/마지막 값 유지다. Unresolved/duplicate 이름, 같은 시간, 역순·홀수 항목, +nonfinite, 다른 정의·시간 기준·값 종류·smoothing 옵션은 명시적 실패다. + +`*CLOAD, AMPLITUDE=name`의 \(F(t)=A(t)F_{base}\)를 source 순서로 합산한다. +각 load block의 curve를 보존하며 서로 다른 curve를 미리 하나의 base force로 합치지 않는다. +Amplitude 없는 CLOAD는 `0+`부터 일정 하중이다. 표의 첫 시간/값을 강제로 0으로 만들지 않는다. +현재 reference Amp-1은 `(0,0),(0.1,1),(10,1)`이다. 지정 변위 amplitude와 static amplitude, +TOTAL TIME·SMOOTH STEP·주기 하중·물리적 damping은 이번 범위가 아니다. + +### FEM-REQ-HEX8-010 — 공개 입력과 CLI + +기존 lexical/source identity를 재사용하고 `*SOLID SECTION, ELSET=..., MATERIAL=...`와 +생략 또는 blank data row를 허용한다. Thickness/plane stress/axisymmetric 의미를 추가하지 않는다. +`*STATIC`과 `*STATIC, DIRECT`의 고정 증분 subset을 지원한다. DIRECT의 `h,T`가 양수이며 +`N*h==T`, `N<=INC`를 만족해야 한다. 일반 STATIC의 기존 load-factor subset도 유지한다. +`*FREQUENCY`의 mode 수가 권위이며 Lanczos/SIM source 옵션은 실제 MKL FEAST와 구별한다. +`*DYNAMIC, DIRECT`는 `NLGEOM=NO` 또는 `YES`, 고정 h/T와 INC를 지원한다. +Static/frequency/dynamic 각각의 기존 무해한 출력 요청 subset 및 제공 원본의 PRESELECT 요청을 +명시적으로 검증한다. Output no-op이 필수 결과의 삭제·선택 기능이 되지 않는다. +기존 CLI 입력·lexical sibling 결과/로그 경로·exit category를 유지한다. + +### FEM-REQ-HEX8-011 — 소유권과 전역 조립 + +Domain은 의미·재료/section·topology·amplitude를, DofManager는 3N full/free mapping과 +scatter/pattern을, element는 local 계산을, analysis는 state/trial/commit을 소유한다. +공유 sparse 직접 쓰기 없이 source 순서의 결정적 누적을 유지한다. 6N Shell layout이나 +회전 영공간에 Hex8을 끼워 넣지 않는다. 사용되지 않는 절점·잘못된 scatter는 fail-closed다. + +내부 C++ API의 행동 계약은 다음과 같다. 구체적인 class/method 이름은 구현 계획의 영역이다. + +| 연산 | 입력·출력과 불변량 | +| --- | --- | +| 요소 생성 | 검증된 source topology·기준 좌표·재료로 immutable 요소 생성; 실패는 기존 Result/Status | +| 선형 평가 | K0[24,24]·M[24,24], 주어진 u[24]의 f[24]·W·8점 복구량 | +| 비선형 trial 평가 | u[24]에서 f[24], Kmat/Kgeo/Kt[24,24], W, 8점 Cauchy/Green tensor; 호출이 accepted state를 변경하지 않음 | +| 조립·절차 실행 | Domain과 3N DOF mapping으로 sparse K/M 및 검증된 procedure별 결과; source 순서 유지 | +| 기록 | 완결된 accepted 결과만 받는 Solid writer; 검증 실패 시 기존 final 파일 보존 | + +길이·성분 불일치와 nonfinite trial을 실패로 반환하며 vendor handle/type은 공개 API에 노출하지 않는다. + +### FEM-REQ-HEX8-012 — 선형 정적 + +Kff solve 후 prescribed 값을 정확히 복구하고 full residual `K0u-F`를 계산한다. +Constrained 성분은 반력, free 성분은 평형 잔차이며 서로 별도 dataset으로 보존한다. +완료 load factor의 결과를 frame0으로 저장한다. 빈 free solve와 solver 실패를 구별한다. + +### FEM-REQ-HEX8-013 — 비선형 정적 + +Accepted 증분별 q·내외력·응력·에너지와 convergence evidence를 보존한다. Newton은 +\(f_{int}(u)-F\)의 free residual과 일관 tangent를 사용한다. 불안정 tangent를 SPD라고 +가정하지 않는다. Recovery까지 검증한 candidate만 accept하며 실패 증분은 공개하지 않는다. +현재 일반 Newton controls를 재사용할 때 물리 3성분·force/length 단위에 맞는 적용을 검토한다. +회전·모멘트의 dummy channel은 만들지 않는다. 초기 tuning default는 기존 정적 기준의 +force residual/translation correction 상대 `1e-2`, scale0 absolute `1e-3`의 해당 입력 +force/length 단위, 증분당 최대100 iteration이다. 분모·분자·branch·단위·판정을 남긴다. +내부 solver tuning 조정은 독립 검토와 재검증을 기록하며 외부 acceptance를 바꾸지 않는다. + +### FEM-REQ-HEX8-014 — 일반화 고유치 + +실제 동차 경계 적용 후 \(K_{ff}\phi=\omega^2M_{ff}\phi\)의 최저 N 모드를 구한다. +반복 고유치를 제거하지 않고 실제 3N 공간으로 복구해 mass-normalize한다. 해석 출력에는 +lambda, frequency, mode vector와 residual/Gram evidence를 구별한다. 음수값을 abs/clamp하지 않는다. +강체 모드·cluster 경계·모드 누락·empty free/과도한 N을 검증한다. +\(\|K\phi-\lambda M\phi\|/[(\|K\|+|\lambda|\|M\|)\|\phi\|]\), +\(|\phi^TM\phi-1|\)와 mass Gram 오차는 `1e-10` 이하를 요구하며 zero denominator는 +exact-zero 분기로 처리한다. 모든 backend 반환 pair를 검증한 뒤 공개 N을 선택한다. +Shell 전용 nodal whitening을 일관 M에 적용하지 않는다. 실제 generalized-SPD sparse +FEAST 또는 일관 문제를 정확히 보존하는 변환을 사용한다. Sparse pencil을 바꿔 수렴시키지 않는다. + +### FEM-REQ-HEX8-015 — HHT 동해석 + +초기 q/v=0, constrained q/v/a/A=0이다. \(M_{ff}a_{0f}=F_f(0+)-f_{int,f}(0)\), +\(A_0=a_0\)로 초기화한다. Amplitude가 0이면 그 초기 힘을 그대로 사용한다. +공개 계수는 기존 HHT의 `alpha=-0.05`, `beta=0.275625`, `gamma=0.55`다. +Predictor/Newmark 갱신은 auxiliary A를 사용하고 +\(A_{n+1}=(1+\alpha)a_{n+1}-\alpha a_n\)로 physical a와 구별한다. + +\[ +R=M A_{n+1}+(1+\alpha)(f_{n+1}-F(t_{n+1}))-\alpha(f_n-F(t_n)), +\quad K_{eff}=M/(\beta h^2)+(1+\alpha)K_t. +\] + +이 weighted residual은 이전 physical endpoint 평형을 포함하며, 같은 관계로 환산한 +endpoint 잔차를 쓰는 것도 동등성 검증을 전제로 허용한다. 서로 다른 표현의 tangent와 +reaction을 혼용하지 않는다. Amplitude는 실제 각 endpoint에서 평가하고 한 step의 힘을 +고정해두거나 잘못된 시간에서 한 번만 평가하지 않는다. 질량은 상수이므로 Shell의 +회전 chart·moving-null·convective 관성은 이 절차에 없다. 선형은 K0, 비선형은 Kt를 사용한다. +물리 반력은 constrained \(Ma+f_{int}-F(t)\), free endpoint residual은 별도 evidence다. +초기부터 마지막까지 `n=0..N`, `time=double(n)*h`, exact schedule `N*h==T`를 유지한다. +마지막 증분 축소·adaptive time·restart는 지원하지 않는다. +동적 초기 tuning default는 기존 HHT의 normalized residual/correction `1e-10`, +Newmark update 일치 `1e-12`, 증분당 최대100 iteration이다. Force 잔차의 scale은 +같은 endpoint의 uncancelled inertia/internal/external force로 만들며 scale0은 exact-zero다. +Correction은 기준 형상의 양의 길이 L로 u를, L/h와 L/h²로 v와 physical/auxiliary a를 +정규화해 각각 확인한다. 회전 channel을 복제하거나 잔차를 보정한 뒤 accept하지 않는다. + +### FEM-REQ-HEX8-016 — 응력·변형률 복구 + +8개 적분점에서 선형 global Cauchy stress·미소변형률, 비선형 +\(\sigma=FSF^T/\det F\)와 기준 global Green–Lagrange strain을 복구한다. +Tensor strain 성분은 `[11,22,33,12,13,23]`의 실제 shear이며 B 계산용 engineering shear와 +구별한다. 적분점 평균·절점 외삽·nodal smoothing을 하지 않는다. Cauchy stress와 PK2를 +같은 이름으로 저장하지 않는다. 기본 공식 응력은 Cauchy다. Frequency의 +mode vector를 물리 응답 변위/응력으로 복구하지 않는다. + +### FEM-REQ-HEX8-017 — HDF5 계약 + +새 형식은 `/metadata`의 `feature_id=hex8-structural-analysis`, `schema_version=1`과 +`analysis_procedure`로 식별한다. 값 집합은 `linear-static`, `nonlinear-static-full-newton`, +`linear-frequency`, `hht-linear-dynamics`, `hht-nonlinear-dynamics`다. +`element_formulation=FESA-Hex8`, `integration_rule=gauss-2x2x2`, +`mass_formulation=consistent-reference`, source step 이름·입력 byte identity·단위 의미를 보존한다. + +Model row의 source instance/label은 기존 model identity 의미를 유지하되 Solid topology/section +분기를 추가한다. Node row는 Domain 선언 순서다. `/model/nodal_constraint_mask`는 U8[N,3], +free0/constrained1이다. 다음 mandatory compound field 순서와 dtype을 사용한다. +U64/U8/F64는 각각 unsigned 64/8-bit integer와 Float64 little-endian이며 문자열은 UTF-8다. + +| model 경로 | field 순서·dtype | +| --- | --- | +| `/model/nodes` | `internal_node_id:U64, instance_name:string, source_label:string, coordinates:F64[3]` | +| `/model/elements` | `internal_element_id:U64, instance_name:string, source_label:string, source_element_type:string, internal_formulation:string, node_internal_ids:U64[8], solid_section_internal_id:U64, material_internal_id:U64` | +| `/model/solid/materials` | `internal_material_id:U64, name:string, youngs_modulus:F64, poisson_ratio:F64, density_present:U8, density:F64` | +| `/model/solid/sections` | `internal_section_id:U64, source_file:string, source_line:U64, source_elset:string, material_internal_id:U64` | +| `/model/solid_integration_points` | `internal_element_id:U64, point_id:U8, natural_coordinates:F64[3], reference_coordinates:F64[3]` | + +Internal ID는 각 inventory의 zero-based index이고 point ID는1–8이다. 요소는 Domain 선언 순서, +integration-point row는 element-major/point-major다. `density_present`는0/1이고 부재 시 +`density=0`은 저장 placeholder이며 해석 밀도로 사용하지 않는다. 필수 밀도 절차에서는 부재를 +writer 이전에 거부한다. 원본 positive density가 있는 정적 모델은 이를 그대로 기록한다. + +| 경로 또는 frame 상대 경로 | shape / 의미 | +| --- | --- | +| `/steps/Step-1/accepted_frames` | 아래 정의한 비선형 정적/동적 compound table | +| `/steps/Step-1/frames//nodal/displacement` | [N,3], U1/U2/U3 | +| `nodal/reaction` / `nodal/residual` | 각각 [N,3], 반력은 free exact0, residual은 full endpoint/static residual | +| `solid/stress` / `solid/strain` | [E,8,6], point 순서·global frame·Cauchy 또는 Green/infinitesimal 의미 attribute | +| `global/strain_energy` | scalar; accepted physical elastic energy | +| 동적 `nodal/velocity`, `acceleration`, `algorithmic_acceleration` | 각각 [N,3], V·physical a·auxiliary A | +| 동적 `global/kinetic_energy`, `external_work`, `energy_balance_error` | scalar; 서로 다른 양, 계산 정의 attribute | +| 동적 `global/linear_momentum`, `angular_momentum` | [3], global O=(0,0,0) 기준 | +| `/steps/Step-1/eigen/modes`, `frequencies`, `vectors` | 아래 정의한 mode records, frequency subset, F64[Nmode,Nnode,3] mass-normalized vector | + +위 `Step-1`은 기존 storage step key이고 source step 이름은 metadata에 별도 보존한다. +모든 물리 배열·scalar는 F64다. Accepted table은 아래 field를 정확히 이 순서로 가진다. + +- 비선형 정적: `frame_index:U64, increment_index:U64, load_factor:F64, iteration_count:U64, is_factor_one:U8`. +- 동적: `frame_index:U64, increment_index:U64, time:F64, iteration_count:U64, is_initial:U8`. + +Flag는0/1이다. Static linear에는 accepted table이 없다. 비선형 정적 frame0은 첫 accepted +증분이고 baseline factor0은 공개 frame이 아니다. Dynamic은 frame=increment=n, +initial의 iteration_count=0이며 이후 값은 실제 accepted Newton/선형 solve 횟수다. +Final-static flag는 마지막 factor1 frame에만1이다. + +Eigen `modes`는 `mode_id:U64, eigenvalue:F64, classification:U8, cluster_id:U64`, +`frequencies`는 `mode_id:U64, frequency:F64`다. Mode/cluster ID는1부터 증가하며 mode는 +lambda 오름차순이다. Classification 집합은0=rigid-near-zero, 1=positive다. 검증된 near-zero +음수 lambda도 원 값으로 남기고 frequency row를 만들지 않으며 유의한 음수는 solver failure다. +Nonnegative lambda에만 `frequency=sqrt(lambda)/(2*pi)`를 기록한다. 초기 tuning default는 +`lambda_scale=max_i(abs(Kff_ii)/Mff_ii)`에서 `abs(lambda/lambda_scale)<=1e-9`를 near-zero, +인접 normalized gap `>1e-8`을 새 cluster로 분류한다. 양의 M diagonal과 finite positive +lambda_scale을 확인한다. 이 scale은 FEAST interval의 스펙트럼 상한으로 주장하지 않는다. +기능 numeric-controls에 scale·설정·독립 검증을 기록하고 저장 lambda를 보정하지 않는다. +`/steps/Step-1/eigen/verification/pairs`는 backend가 반환한 모든 검증 pair의 table이며 +`sorted_rank:U64, solver_column:U64, eigenvalue:F64, modal_mass:F64, rayleigh_quotient:F64, eta_r:F64, eta_norm:F64, eta_energy:F64`다. +Backend column은0-based, rank는1-based다. 같은 verification group의 `eta_gram`, +`max_eta_orth`는 F64 scalar다. Backend 고유 trace는 기존 공개 의미로 추가 기록할 수 있으나 +필수 original K/M 검증량을 다른 operator의 잔차로 대체하지 않는다. + +Static frame0은 완료 결과, nonlinear static frame은 accepted 증분, dynamic frame0은 initial이다. +Frequency에는 static/dynamic frame dataset을 요구하지 않는다. 각 결과에 component_names, +unit dimensions, coordinate/location, step/frame/time 또는 load_factor 의미를 명시한다. +Self-check는 위 dtype/field 순서·shape·identity·flag·finite·frame schedule와 accepted 값의 +readback 일치를 검증한다. 기능 I/O 문서는 이 계약을 상세화하며 다른 field 집합으로 바꾸지 않는다. +기존 Beam/Shell/Thermal 파일의 required dataset이나 schema를 바꾸지 않는다. +Full/element matrix dump는 공식 결과에 포함하지 않는다. + +### FEM-REQ-HEX8-018 — 물리 수지와 에너지 + +정적은 힘·모멘트 평형, 동적은 운동량 변화율과 applied/support 힘·모멘트를 검사한다. +Consistent M으로 \(T=v^TMv/2\), \(U=\sum W_g\det J_{0g}\)를 계산한다. +외력 일은 endpoint force와 displacement increment의 trapezoid 누적이며 초기0, +`energy_balance_error=T+U-T0-U0-Wext`다. 현재 BC는 동적 exact0여서 support work=0이다. +HHT의 알고리즘 소산과 quadrature에 따른 work 오차를 설명하며 각 frame exact conservation을 +강제하지 않는다. Alpha0 내부 검사에서는 선형 무하중 보존을 독립 확인한다. +Moment와 angular momentum은 현재 위치와 consistent interpolation의 kinetic 식으로 평가한다. + +### FEM-REQ-HEX8-019 — 실패와 진단 + +미지원 physics/옵션, geometry/trial 반전, 비유한 값, singular/invalid matrix, 수렴 실패, +backend resource 실패를 source/entity와 함께 명시적으로 보고한다. Invalid model과 +solver failure, output failure를 기존 category로 구분한다. 실패 candidate는 마지막 +accepted state/history와 기존 final HDF5를 변경하지 않는다. Write·readback·close·atomic +replace 실패를 검사한다. 로그 보존과 final 결과 보존은 서로 다른 계약이다. + +### FEM-REQ-HEX8-020 — 결정론 + +Serial/parallel local 계산에서 source identity·equation/scatter·ordered reduction·결과 row와 +진단 순서를 재현한다. 같은 수치 설정에서 반복 실행 결과를 검증한다. Modal sign은 +최대 절대 성분의 최초 source-order index를 양수로 고정한다. 반복 고유값의 벡터별 일치는 +외부 비교하지 않으며 해당 공간의 mass Gram·residual·subspace 불변량으로 검증한다. + +## 검증과 완료 조건 + +### FEM-REQ-HEX8-021 — 독립 수치·물리 검증 + +정식화·numeric controls를 독립 검토한 뒤 의미 있는 local/integration 검사를 수행한다. +검사 oracle는 production 식·assembly를 단순 복제하지 않는다. 최소 사례는 다음과 같다. + +1. 정육면체의 독립 정확 적분 K/M, 다항 patch, 6 rigid modes, total mass·scale·좌표변환. +2. 비대칭 왜곡·뒤틀린 요소의 Jacobian, folded/inverted/degenerate 및 비유한 입력. +3. 유한 rigid rotation과 strained-then-rotated 상태, 에너지 gradient·tangent directional + difference의 step sweep, Kmat/Kgeo 분리와 zero-state Kt=K0. +4. 비영 BC·전체 구속·static singular 모델·성공/실패 state와 HDF5 보존. +5. 실제 generalized K/M 고유쌍의 독립 dense 작은 모델 oracle, density scaling, + clustered/rigid modes·최저 N·original-free residual/Gram. +6. 선형 oscillator의 해석해 및 alpha0, amplitude knot 전/정확/후·초기 a·서로 다른 curve, + 비선형 constant-mass 제조해의 전체 u/v/physical a 시간수렴. +7. 실제 Hex8 mesh의 h/h2/h4 응답·가속도·힘/모멘트/에너지 수지, 큰 회전과 작은 strain, + spatial mesh refinement·full-integration 잠김 한계, serial/parallel 결정론. + +내부 zero/noise scale과 conditioning 기준은 수식·정밀도·oracle에 근거한 기능별 +numeric controls로 정하고 독립 검토한다. 외부 5%/1%를 내부 정확성 기준으로 사용하지 않는다. +시간수렴은 변위만 맞는 사례로 대신하지 않으며 유의한 오차 구간과 미분량 차수를 함께 판정한다. + +### FEM-REQ-HEX8-022 — 필수 reference + +2026-10-08 확인된 원본은 `reference/hexa/`다. 모두 read-only다. + +| case | 입력 | 결과·필수 family | +| --- | --- | --- | +| 선형 정적 | `hexa_linearstatic.inp` | `_U.csv`, `_RF.csv`, `_S.csv`: 완료 frame의 U1–3, constrained RF1–3, Cauchy S 6성분 | +| 비선형 정적 | `hexa_nonlinearstatic.inp` | 동일 suffix: 완료 load-factor frame의 U·RF·적분점 Cauchy S | +| 선형 동적 | `hexa_dynlinear.inp` | `hexa_dynlinear_U.csv`: initial 포함 101 frame U1–3 전체 | +| 비선형 동적 | `hexa_dynnonlinear.inp` | `hexa_dynnonlinear_U.csv`: initial 포함 101 frame U1–3 전체 | +| Frequency | `hexa_freq.inp` | 원본 modal Value 결과 아직 없음. 사용자 준비 자료로 최저10 modes를 비교해야 함 | + +현재 inventory는 442 nodes, 300 elements다. 정적 U/RF 각442행, 수정된 정적 S 각2400행의 +`IntPt=1..8`, 동적 U 각각44642행이다. 기존 elemental-nodal 응력 CSV의 위치 계약을 +사용하지 않는다. 동적 V/A·reaction/energy reference는 없으므로 독립 검증이 필수다. +필요한 고유치 원본이 없으면 그 비교는 미실행이고 전체 기능 완료도 대기다. +원본 추가 전이라도 독립 구현·검증 작업은 계속할 수 있다. + +### FEM-REQ-HEX8-023 — 비교 identity와 수치 정책 + +Nodal key는 case/source step/increment/instance/node/component, stress key는 +case/source step/frame/instance/element/IntPt/component다. CSV header의 공백은 lexical +정규화하되 source row를 삭제·평균하거나 nonfinite를 보정하지 않는다. 좌표와 point convention은 +원본 precision을 고려한 보조 검증이며 nearest-position matching으로 ID를 추정하지 않는다. +Dynamic은 integer increment로 대응한 뒤 각 source decimal time과 binary64 n*h schedule을 +검증한다. Static은 마지막 factor-one frame에 대응하고 storage frame 번호가 같다고 가정하지 않는다. + +정적 U-global·RF-global·S-global은 서로 다른 blocking family, 동적 U-global은 frame별 +blocking family다. RF는 원본 전체442행 inventory를 먼저 확인한 뒤 실제 constrained components를 +투영한다. Free RF를 FESA free residual로 비교하지 않는다. S는 각 case/frame의 300×8×6을 +포함한다. Modal Value는 mode별 singleton blocking family이며 외부 mode-shape 비교는 비목표다. +Missing/extra/duplicate/identity/nonfinite 오류는 tolerance 이전 실패다. +공통 정책의 S=max|reference|, B=.01S, 일반 row relative≤.05, family RMS/S≤.01, +S=0 exact-zero를 적용한다. MITC4 eigen의 RMS5% 예외는 육면체에 적용하지 않는다. +Source C3D8의 입력 호환성과 Abaqus 내부 integration/constitutive/time-algorithm 동등성은 +서로 다르다. 불일치 시 정식화·reference identity·절차를 조사하며 acceptance를 임의 완화하지 않는다. + +### FEM-REQ-HEX8-024 — 회귀·완료 판정 + +구현 완료 시 실제 설정의 MSVC x64 Debug 전체 build/CTest와 필수 reference 비교, +독립 수치·물리 검토가 필요하다. 최신 source revision·명령·native exit·metric·hash를 기록한다. +모든 신규/영향 검사 PASS, 모든 필수 reference PASS, 미해결 신규 physics 오류0이 완료 조건이다. +기존 HHT C08 두 FAIL·C04a SKIP의 과거 기록은 baseline으로 직접 재확인하고, 동일하다면 +기존 미해결로 별도 보고한다. 전체 suite를 green이라 부르거나 제외 실행으로 대체하지 않는다. +기존 오류를 새 오류와 섞거나 현재 작업의 성공을 위해 Shell/Thermal 수식·policy를 변경하지 않는다. +Reference·필수 실행이 대기라면 구현/내부 검증 완료와 기능 검증 완료를 분리한다. + +## 범위 밖 + +20절점·tetra·wedge·hybrid/incompatible/reduced 요소, lumped 선택 API, 큰 strain용 다른 +재료·소성·contact·물리 damping·압력·중력·체적력·시간변화 BC·비영 초기 q/v, +mixed mesh·Shell–Solid 연결·prestressed modes·좌굴·다중 step/restart·adaptive/explicit dynamics, +열-구조 연성·matrix dump·외부 배포·release-readiness는 포함하지 않는다. + +## 방법과 자료의 한계 + +StVK는 선택한 탄성 regime의 FESA 모델이며 Abaqus `*ELASTIC, NLGEOM=YES`와 내부 +유한변형 재료 알고리즘이 동일하다고 주장하지 않는다. Full 8점은 Abaqus C3D8의 체적 +처리까지 그대로 재현하겠다는 선택이 아니다. 제공 결과의 일치만으로 다른 regime을 보증하지 않는다. + +Amplitude의 step-time·상대 값·선형 보간·끝 값 유지 의미는 +[Abaqus 공식 설명](https://docs.software.vt.edu/abaqusv2025/English/SIMACAEPRCRefMap/simaprc-c-amplitude.htm)을 따른다. +Generalized sparse FEAST의 공개 진입점은 +[Intel 공식 문서](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-c/2026-0/feast-scsrgv-feast-hcsrgv.html)에서 확인했다. +이는 설치 runtime·빈 interval·workspace·정식화 검증 evidence를 대신하지 않는다. + +## 현재 checklist + +- [ ] 수식·입출력·numeric controls·원본 mapping 정리 및 독립 numerical review 완료 +- [ ] Hex8 K0/consistent M/비선형 f/Kmat/Kgeo/Kt·형상·복구 kernel 검증 +- [ ] Solid Domain/parser/3N DOF/ordered assembly/amplitude 검증 +- [ ] 선형·비선형 정적 accepted state/반력/잔차 검증 +- [ ] Generalized consistent-mass frequency·최저 N·original-pencil 검증 +- [ ] 선형·비선형 HHT u/v/physical a·시간수렴·수지 검증 +- [ ] 공식 HDF5/CLI/self-check/실패 final 보존 검증 +- [ ] 정적2·동적2 원본 필수 family 비교 PASS +- [ ] 사용자 원본 최저10 modal Value 제공 및 필수 비교 PASS +- [ ] 최신 전체 MSVC Debug build/CTest·기존 baseline 대조 완료 +- [ ] Independent numerical/physics blocker0·범위/한계/evidence 기록 완료 + +현재는 계약 문서를 작성 중이며 solver implementation/numerical/reference PASS를 주장하지 않는다. +원본 frequency 결과 부재는 구현 진행을 막지 않지만 기능 검증 완료를 막는다. diff --git a/docs/hex8-structural-analysis/formulation.md b/docs/hex8-structural-analysis/formulation.md new file mode 100644 index 0000000..83ae6cd --- /dev/null +++ b/docs/hex8-structural-analysis/formulation.md @@ -0,0 +1,168 @@ +# Hex8 정식화와 검증 불변량 + +적용: [PRD](PRD.md)의 FEM-REQ-HEX8-002–007,012–018,021. +물리 선택은 [ADR](ADR.md)에 있다. 이 문서는 승인된 식의 구현용 유도이며 +외부 결과에 맞추어 physics를 바꾸는 권한이 아니다. 수치 controls는 +[별도 원본](numeric-controls.md), 출력 tensor/identity는 [I/O](io.md)를 따른다. + +## Shape·기준 geometry·적분 + +절점 signs는 `---,+--,++-,-+-,--+,+-+,+++,-++`다. Point signs는 +`---,+--,-+-,++-,--+,+-+,-++,+++`, coordinate는 각 ±1/√3이고 weight1이다. + +\[ +N_a={1\over8}(1+\xi_a\xi)(1+\eta_a\eta)(1+\zeta_a\zeta),\quad +J_{0,iJ}=\sum_aX_{ai}N_{a,J},\quad G_a=J_0^{-T}\nabla_\xi N_a. +\] + +J0 column은 자연 ξ/η/ζ 미분이다. Gauss reference 위치는 ΣNaXa, volume weight는 det J0다. +Translation 차이를 먼저 사용해 large coordinate offset의 취소 오차를 줄일 수 있지만 +기준 좌표와 source identity는 변경하지 않는다. Shape의 partition of unity·linear reproduction와 +gradient 합0을 검증한다. Invalid det/inverse는 abs/clamp나 corner 재배열로 숨기지 않는다. + +## Cell 전체의 Jacobian 인증 + +Trilinear map의 det J는 각 자연 좌표에 대해 최대2차인 tensor polynomial이다. +`s=(ξ+1)/2,t=(η+1)/2,r=(ζ+1)/2`에서 degree(2,2,2) Bernstein basis로 표현할 수 있다. +각 축 -1/0/+1의27개 determinant 값에서 다음1D 변환을 세 축에 적용한다. + +\[ +b_0=p(-1),\quad b_2=p(1),\quad b_1=2p(0)-(p(-1)+p(1))/2. +\] + +Bernstein basis는 nonnegative이고 합1이므로 모든 coefficient의 양의 lower bound는 +cell 전체 det>0를 보증한다. 모든 sample가 양수인 것만으로는 충분하지 않다. +Coefficient bound가 불확실하면 de Casteljau midpoint subdivision 후 child cell을 검사한다. +Sample의 nonpositive upper bound 또는 완전히 nonpositive cell은 invalid이며, depth/resource +한계에서도 positive를 인증하지 못하면 uncertain geometry failure다. + +인증용 연산은 outward-rounded interval arithmetic으로 수행한다. Addition/subtraction/ +multiplication·변환·subdivision·current Xa+ua까지 실제 FP 오차를 포함하며 NaN/Inf/overflow를 +거부한다. 단순 coefficient estimate에 임의 epsilon을 더해 positive라고 선언하지 않는다. +Current geometry에도 같은 인증을 적용하고 point det F>0를 확인한다. Trial failure가 reference +cache나 accepted state를 변경하지 않는다. 세부 종료 controls는 numeric-controls를 따른다. + +## Linear elasticity와 K0 + +\(\mu=E/[2(1+\nu)],\lambda=E\nu/[(1+\nu)(1-2\nu)]\). +\(E>0,-1<\nu<.5\)에서 bulk/shear modulus가 양수다. Engineering strain vector는 +`[ε11,ε22,ε33,2ε12,2ε13,2ε23]`; stress vector는 실제 shear stress다. +Normal C block은 diagonal λ+2μ/off-diagonal λ, shear diagonal μ다. + +\[ +K_0=\sum_g B_g^TCB_gw_g,\qquad f=K_0u,\qquad U={1\over2}u^TK_0u. +\] + +동일 point의 block 형태는 \(\lambda G_{ai}G_{bk}+\mu\delta_{ik}G_a\cdot G_b+ +\mu G_{ak}G_{bi}\)다. B/Voigt 코드와 독립 tensor/polynomial oracle를 구분한다. +Unconstrained K0는 symmetry/PSD 및6 rigid modes를 가지며 BC 적용 후 mechanism/singularity를 +solver가 명시적으로 처리한다. Full integration 잠김을 안정화로 바꾸지 않는다. + +## Total Lagrangian energy·내력·접선 + +\[ +F=I+\sum_a u_a\otimes G_a,\quad E_G=(F^TF-I)/2, +\quad W={\lambda\over2}(\operatorname{tr}E_G)^2+\mu E_G:E_G. +\] + +\(S=\partial W/\partial E_G=\lambda\operatorname{tr}(E_G)I+2\mu E_G\), +\(P=FS\). \(\delta E_G=\operatorname{sym}(F^T\delta F)\)이므로 +\(\delta W=P:\delta F\), \(\delta F=\sum\delta u_a\otimes G_a\)다. + +\[ +U=\sum W_gw_g,\quad f_{ai}=\sum P_{iJ}G_{aJ}w_g. +\] + +\(\delta P=\delta F S+F\delta S\)를 분리하면 + +\[ +\mathbb C_{IJLN}=\lambda\delta_{IJ}\delta_{LN} ++\mu(\delta_{IL}\delta_{JN}+\delta_{IN}\delta_{JL}), +\] +\[ +(K_{geo})_{ai,bk}=\sum\delta_{ik}G_{aJ}S_{LJ}G_{bL}w_g, +\quad (K_{mat})_{ai,bk}=\sum G_{aJ}F_{iI}\mathbb C_{IJLN}F_{kN}G_{bL}w_g. +\] + +Kt=Kmat+Kgeo는 energy Hessian이며 load-independent CLOAD tangent는0이다. +S는 symmetric이고 total Kt도 symmetric이나 stressed trial에서 SPD라고 가정하지 않는다. +Zero state에서 F=I/S=0/geo=0/total=K0다. 유한 rigid R에서 F=R, Green/W/f는0이며 +strained 상태를 global R로 회전하면 energy invariant·force/tangent covariance를 만족해야 한다. +Affine deformation의 energy/stress 및 multi-element constant-stress patch가 독립 oracle다. + +공식 비선형 stress는 \(\sigma=FSF^T/\det F\), Green strain은 기준 global tensor다. +Linear 공식 strain은 infinitesimal tensor다. 저장 strain의 shear는 실제 tensor 성분이고 +B 계산용 engineering shear의 절반이다.8점 값을 그대로 저장한다. + +## Consistent mass와 generalized eigen + +\[ +M_{ai,bj}=\delta_{ij}\sum_g\rho_0N_aN_bw_g, +\quad T={1\over2}v^TMv. +\] + +M은 reference-state 상수다. Positive weights와8점 interpolation matrix의 full rank에서 SPD가 +따른다. Axis-aligned brick의 scalar block은 \(\rho V/216\)에 각 축 sign이 같으면2/다르면1인 +세 factor의 곱이다. Direction별 총합은 rho V, row sum은 rho V/8다. Production에서는 lump하지 않는다. + +8점 shape evaluation의 minimum singular value 제곱은1/27이다. Exact local quadrature에서 +\(m_{e,lower}=\rho\min_gw_g/27\)는 local M의 positive lower bound다. Global scatter·principal free +restriction에도 active-node incidence를 고려한 lower bound가 보존된다. 예를 들어 모든 active +node에 적어도 하나의 element가 있는 경우 min_e bound는 conservative global lower bound다. +실제 FP matrix의 roundoff와 SPD evidence를 포함해야 하며 이 수학적 식만으로 설치 backend의 +실행을 검증했다고 주장하지 않는다. + +\(K_{ff}\phi=\lambda M_{ff}\phi\)를 풀며 constrained component0으로 복구하고 +\(\phi^TM\phi=1\), \(f=\sqrt\lambda/(2\pi)\)를 구분한다. Proven mass lower bound가 있다면 +\(\lambda_{max}\le\|K_{ff}\|_\infty/m_{lower}\)는 search upper-bound 근거가 된다. +Diagonal ratio classification scale 자체는 upper bound가 아니다. 검색/count의 실제 증거와 +모든 backend pair의 original K/M 잔차·mass norm/Gram을 검증한 뒤 최저 N을 공개한다. +Repeated modes는 cluster/subspace로 판단하며 arbitrary rotation의 개별 vector를 외부 비교하지 않는다. + +## Static partition과 accepted 상태 + +Linear은 Kff uf=Ff−Kfc uc다. Nonlinear free residual은 fint−F이고 Ktff correction을 풀되 +prescribed 값을 factor별 absolute target으로 복구한다. 외력과 prescribed target을 같은 factor로 +증가시키며 이전 accepted state로부터 trial을 시작한다. Empty free solve는 유효한 recovery +경로다. Constrained reaction/full residual을 구분하고 모든 required recovery가 끝나야 commit한다. + +## HHT constant-mass 식 + +Public alpha=−.05, beta=(1−alpha)²/4=.275625, gamma=.5−alpha=.55다. +Algorithmic A와 physical endpoint a를 구분한다. + +\[ +u_p=u_n+hv_n+h^2(.5-\beta)A_n,\quad +v_p=v_n+h(1-\gamma)A_n, +\] +\[ +A_{n+1}=(u_{n+1}-u_p)/(\beta h^2),\quad +v_{n+1}=v_p+\gamma hA_{n+1},\quad +a_{n+1}=(A_{n+1}+\alpha a_n)/(1+\alpha). +\] +\[ +R=MA_{n+1}+(1+\alpha)(f_{n+1}-F_{n+1})-\alpha(f_n-F_n), +\quad K_{eff}=M/(\beta h^2)+(1+\alpha)K_t. +\] + +이전 free endpoint가 \(Ma_n+f_n-F_n=0\)이면 R=(1+alpha)(Ma_next+f_next−F_next)다. +Endpoint 표현을 쓰면 tangent도1/(1+alpha)로 함께 환산해야 한다. Incomplete previous endpoint를 +동등하다고 가정하거나 weighted force에서 reaction을 계산하지 않는다. Physical reaction은 +Ma+f−F의 constrained projection이다. Initial u/v0에서 Mff a0=Ff(0+)−ff(0), A0=a0다. +곡선은 endpoints에서 실제 평가하며 prescribed dynamic q/v/a/A는 exact0다. + +Physical momenta는 interpolated current x/v를 사용해 \(p=\int\rho v\,dV_0\), +\(L=\int x\times\rho v\,dV_0\)다.8점 consistent quadrature와 nodal mass 표현이 일치해야 한다. +Angular-momentum rate는 \(\int x\times\rho a\,dV_0\)이며 v×v 항은0이다. +External/support moment는 같은 current 위치로 구한다. HHT 및 force trapezoid work는 frame별 +exact energy conservation을 의미하지 않는다. Wext는 endpoint force·du trapezoid 누적, +error=T+U−T0−U0−Wext다. Alpha0 linear unforced benchmark에서는 독립 보존을 확인한다. + +## 정식화 검증 경계 + +Analytic brick/affine energy, independent tensor polynomial integrals,6 rigid modes, scaling/ +covariance, gradient/tangent directional step sweep와 small-load limit를 결합한다. Warped geometry는 +independent higher-order quadrature로 discretization error를 보고한다. Generalized eigen은 +작은 independent dense oracle와 original sparse-pencil metrics로 검증한다. HHT는 analytic +oscillator/비선형 constant-mass 제조해에서 u/v/physical a·h/h2/h4 수렴을 검증한다. +외부 comparison의5%/1%로 이 내부 검사를 대신하지 않는다. diff --git a/docs/hex8-structural-analysis/io.md b/docs/hex8-structural-analysis/io.md new file mode 100644 index 0000000..6e63623 --- /dev/null +++ b/docs/hex8-structural-analysis/io.md @@ -0,0 +1,119 @@ +# Hex8 입출력과 내부 전달 계약 + +권위 있는 field/enum/shape·지원 입력·진단/실패 의미는 [PRD](PRD.md)의 +FEM-REQ-HEX8-008–011,016–020,022–023다. Public CLI·path/lease/exit는 +[공통 계약](../contracts.md), tolerance는 [TOLERANCE](../TOLERANCE.md)를 따른다. +이 문서는 그 계약을 구현 경계까지 상세화한다. Physics 선택은 [ADR](ADR.md)를 따른다. + +## Source 입력과 실패 경계 + +기존 single Part/identity Instance/set/target subset을 재사용하고 source spelling/location/ +instance/label과 internal index를 구분한다. C3D8의8 distinct nodes와 SOLID SECTION의 elset/ +material 연결, constant E/nu 및 procedure별 density capability를 검증한다. Blank section row는 +허용하되 thickness/material orientation·다른 solid type를 default로 흡수하지 않는다. + +BC/CLOAD는 DOF1–3만 허용한다. Static 비영 prescribed는 absolute target이며 nonlinear의 +factor가 force/target 모두에 적용된다. Frequency는 homogeneous BC, dynamic은 exact-zero BC와 +initial q/v0만 허용한다. Unused node·mixed element·alias element·unknown set/material/source +identity·bad density/geometry·unsupported meaningful keyword는 model/input failure다. + +TABULAR amplitude는 canonical name uniqueness를 검증하며 raw name/location을 보존한다. +TIME=STEP TIME/VALUE=RELATIVE/DEFINITION=TABULAR의 생략 default와 명시 동일 값만 지원한다. +One/many rows의 pair를 flatten해 finite time>=0/strict increasing/value finite를 검사한다. +Knot 원 값·linear interpolation·end hold를 사용한다. Curve 없는 CLOAD는 initial0+부터 constant다. +다른 curve를 사용하는 load block은 미리 하나의 base vector로 합치지 않는다. Static/BC amplitude, +TOTAL TIME/SMOOTH STEP/smoothing option을 fail-closed로 거부한다. + +STATIC DIRECT는 h/T/INC의 fixed schedule을 지원하며 nonlinear load factor는 n*h/T다. +기존 일반 STATIC fixed-factor subset도 유지한다. DYNAMIC DIRECT h/T/INC는 integer n과 +binary64 n*h로 대응한다. FREQUENCY의 N은 source mode request이며 LANCZOS/SIM option 표기와 +실제 generalized MKL FEAST를 metadata/diagnostic에서 구분한다. Provided PRESELECT/무해한 +output/restart 요청은 명시된 no-op이고 required 공식 결과를 삭제하는 selector가 아니다. + +## T2/T3와 이후 절차의 typed 경계 + +다음 class/method 이름은 구현 계획용 초기 interface다. 같은 행동/배열 크기·소유권을 유지하는 +repository-conforming 이름 조정은 허용하며 physics/schema 수정은 아니다. + +- `Hex8Element`는 기존 Element interface의 linear `ComputeStiffness`와 `Recover`를 제공한다. + Create 입력은 internal element index, source/local layout, 기준 좌표8×3, 기존 isotropic + elastic material와 optional density다. 생성에 아직 없는 Solid Domain/section 타입을 요구하지 + 않아 T2/T3를 분리한다. Layout은8 source-order nodes×UX/UY/UZ다. +- Explicit `EvaluateLinear(u)`/`EvaluateNonlinear(u)`는 immutable element의 local u[24]를 받아 + f[24], Kmat/Kgeo/Kt[24,24], strain energy와8 typed integration-point rows를 반환한다. + Linear은 material=K0/geo=0, nonlinear은 같은 trial의 energy 미분이다. `ComputeMass()`는 + local consistent24×24 Matrix contribution이며 absent density이면 실패한다. +- Typed Solid point row는 internal element index, point ID1–8, natural/reference coordinate3, + Cauchy stress6·infinitesimal/Green tensor strain6를 가진다. Identity/상수 coordinates를 trial마다 + 다른 source row로 만들지 않는다. Generic recovery variant의 Solid payload는 별도 type이다. +- Semantic Domain은 Solid element/section/material/density·amplitude 정의를 소유한다. + DOF profile은 `kSolidStructural`에 해당하는3-component 구조이며 `FullDof`, free/constrained, + generic `ElementScatter`, sparse pattern의 기존 공개 의미를 유지한다. 동작별 node component + count를 조회해6으로 고정된 loops를 Solid branch에서 제거한다. +- Matrix assembly는 local layout+24×24 contribution의 stable ordered reduction이다. Mass/stiffness + storage는 같은 full-space pattern이며 free restriction은 실제 constraint mask를 사용한다. + Runtime factory 연결은 Domain material/coords를 Hex8 Create에 전달하는 단일 owner가 수행한다. +- Static/eigen/dynamic executor는 procedure별 typed outcome/state를 반환한다. Accepted frames는 + source identity·3N physical arrays·8점 result·physical scalars와 validation evidence를 소유한다. + Eigen은 modes/vector/all-pair check/Gram을 소유하고 static displacement frame으로 위장하지 않는다. +- Trial은 accepted history의 독립 값이며 invalid geometry/finite/recovery/iteration failure는 + commit하지 않는다. Static force/correction·dynamic force/rate channels의 raw norm/scale/branch/ + unit/pass와 increment/iteration을 기록한다. 필요한 failure evidence는 Status/로그까지 전달한다. + Shared Shell4-channel logger에 dummy rotation/moment convergence를 만들지 않는다. +- Central prepared outcome·writer/CLI 연결은 T7의 한 owner다. Vendor objects는 private adapter에 + 두고 공개 Matrix/Vector/Result/Status 경계를 유지한다. + +## HDF5 metadata와 결과 attribute + +Model/accepted/eigen compound field 집합과 순서·dtype는 PRD017 그대로다. New Solid schema1과 +procedure/element/integration/mass attributes로 식별하고 기존 file contract는 유지한다. +Required strings는 UTF-8, numeric은 explicit little-endian U64/U8/F64다. +Metadata의 추가 공개 의미는 다음과 같다. + +| attribute | 값/의미 | +| --- | --- | +| `source_input_identity` | 실제 읽은 원본 byte identity; 기존 공통 hashing 의미 | +| `source_step_name` | 입력 raw step 이름; storage key Step-1과 별도 | +| `unit_system_label` | `user-consistent-unspecified` | +| `coordinate_convention` | `global-cartesian; reference-strain; current-cauchy-stress` | +| `component_order` | `node-major; UX,UY,UZ` | + +Physical dataset은 `component_names`와 `unit_dimensions`를 UTF-8 string으로 기록한다. +각 frame dataset에는 `frame_index:U64`, `increment_index:U64` 및 해당 `time:F64` 또는 +`load_factor:F64`, `coordinate_system=global-cartesian`, 필요한 `location`을 붙인다. +Result array의 leading node/element inventory와 component list를 self-check한다. + +| quantity | component_names / unit_dimensions / 필요한 의미 | +| --- | --- | +| displacement | `U1,U2,U3` / `length` | +| reaction/residual | `RF1,RF2,RF3` 또는 `R1,R2,R3` / `force`; reaction은 constrained projection | +| stress | `S11,S22,S33,S12,S13,S23` / `force/length^2`; `stress_measure=cauchy`, `location=integration-point` | +| strain | `E11,E22,E33,E12,E13,E23` / `dimensionless`; `strain_measure=infinitesimal` 또는 `green-lagrange`, `shear_convention=tensor` | +| velocity | `V1,V2,V3` / `length/time` | +| physical/algorithmic acceleration | `A1,A2,A3` / `length/time^2`; 각각 `acceleration_kind=physical`/`algorithmic` | +| strain/kinetic energy, work, balance error | `scalar` / `force*length`; 각 계산 정의를 별도 `definition` attribute로 기록 | +| linear/angular momentum | `P1,P2,P3` 또는 `L1,L2,L3` / `mass*length/time` 또는 `mass*length^2/time`; angular origin은 global0 | +| lambda/frequency | `eigenvalue` 또는 `frequency` / `1/time^2` 또는 `1/time`; 서로 다른 eigen table field | +| mode vectors | `UX,UY,UZ` / `mass-normalized`; `normalization=phi^T*M*phi=1` | + +Strain-energy definition은 linear `0.5*u^T*K0*u`, nonlinear `sum(W*detJ0)`다. +Kinetic은 `0.5*v^T*M*v`, work는 `sum(0.5*(F_old+F_new)*delta_u)`이며 initial0이다. +Balance error는 `T+U-T0-U0-Wext`이고 HHT numerical dissipation을0으로 보정하지 않는다. +Constrained mask/prescribed 의미·point ordering은 model inventory에서 확인한다. + +## 출력 candidate와 self-check + +Writer는 완결된 accepted state만 받는다. Dtype/정확한 compound member/order·shape·source +IDs·finite·flags·frame/increment/time/factor·physical3 component·eigen norm/검증량을 확인한다. +Write 후 readback 값을 candidate와 대조하고 close까지 성공한 뒤 atomic replace한다. +잘못된 payload, 임시 write/readback/close/replace 실패에서 기존 final HDF5를 보존한다. +File 존재와 이번 실행 성공은 별개이며 CLI native exit와 stored source identity를 확인한다. + +## Comparison projection + +Quantity/key/family와 원본 준비 상태는 [reference-model](reference-model.md)에 있다. +Static은 final factor-one source increment를 FESA final accepted frame에 대응한다. Dynamic은 +integer increment0..N과 decimal source time을 n*h에 대응한다. RF는 constrained projection, +S는 element/IntPt와6 global Cauchy component다. 좌표는 보조검사이고 ID 추정에 쓰지 않는다. +Modal Value는 원본이 제공되면 quantity/units/mode/step을 확인하며 최저10 eigenvalues를 +singleton families로 비교한다. Missing 원본·nonfinite/identity/completeness 오류는 미실행/실패다. diff --git a/docs/hex8-structural-analysis/numeric-controls.md b/docs/hex8-structural-analysis/numeric-controls.md new file mode 100644 index 0000000..c0918c4 --- /dev/null +++ b/docs/hex8-structural-analysis/numeric-controls.md @@ -0,0 +1,79 @@ +# Hex8 numeric controls + +행동/외부 acceptance 원본은 [PRD](PRD.md), 식은 [formulation](formulation.md)이다. +여기의 내부 tuning default는 독립 numerical review와 영향 재검증을 기록해 조정할 수 있다. +외부 [common-reference-tolerance](../TOLERANCE.md) 및 승인 physics/schema는 변경하지 않는다. + +## 계산·형상 인증 + +모든 input/파생 값/결과를 finite 검증하고 positive Jacobian·밀도·material capability를 확인한다. +Production 계산 precision은 Float64다. Whole-cell 인증은 outward interval coefficient bounds와 +subdivision이며 estimate-only positive 검사와 abs(det J)를 허용하지 않는다. +Depth default10, 처리한 cell budget default65536이며 uncertain 시 fail-closed다. 이 값은 +resource/precision tuning이고 accepted geometry의 positive 조건을 완화하는 tolerance가 아니다. +현재 Xa+ua를 인증할 때 addition uncertainty도 포함한다. Failed trial은 immutable cache를 보존한다. + +## 정적 Newton + +Force residual numerator는 free residual infinity norm이다. 기존 +`nonlinear_static_control.cpp::EvaluateResidualChannel`과 같이 free external infinity norm이 +exact0이면 denominator=0의 absolute branch를 선택한다. External이 nonzero이면 같은 trial의 +free internal/external infinity norm maximum을 relative denominator로 사용한다. +Translation correction numerator는 fresh free correction infinity norm, scale은 현재 증분의 +free translation increment infinity norm이다. 기존 force/translation norm·branch 의미를 유지한다. +순수 prescribed 변위 문제에서 fint_free 자체를 denominator로 사용해 residual ratio가 항상1이 +되게 만들지 않는다. Nonfinite/크기 불일치는 branch와 관계없이 실패다. +Relative branch limit1e-2, exact-zero scale branch absolute1e-3의 force 또는 length 단위다. +Max iteration100/increment가 default다. Moment/rotation dummy channel은 없다. +Raw norms·branch·threshold unit·iteration·passed를 기록한다. 수렴은 recovery/geometry까지 +검증한 candidate에만 적용하며 normalized residual만 수정해 accept하지 않는다. + +## 동적 Newton와 update + +Residual은 physical free endpoint에서 평가한다. Componentwise uncancelled scale +Si=|(Ma)i|+|finti|+|Fi|, normalized metric은 max_i(|ri|/Si)다. Si=0은 ri=0을 요구하며 +그 외의 zero branch는 failure다. Internal cancellation으로 작은 residual이 나온 것만 평가하지 않는다. +Weighted residual을 사용할 때도 physical endpoint와 동일한 scale/판정을 함께 기록한다. + +L은 reference nodal bounding-box 대각 길이로 finite positive다. Correction u/L, h·dv/L, +h²·da/L, h²·dA/L를 모두 확인한다. Residual/correction limit1e-10, update equality1e-12, +max iteration100이 default다. Update scale은 동일 단위의 uncancelled formula term 합이며 scale0은 +exact-zero다. 빈 free vector는 vacuous convergence이며 required prescribed/recovery validation은 유지한다. + +## Eigen 검증과 분류 + +Vector norm은 Euclidean, matrix norm은 Frobenius로 original free pencil을 평가한다. +eta_r=||Kphi−lambda Mphi||/((||K||F+|lambda|||M||F)||phi||2), +eta_norm=|phiᵀMphi−1|, +eta_energy=|phiᵀKphi−lambda phiᵀMphi|/((||K||F+|lambda|||M||F)||phi||2²)다. +Zero denominator는 numerator exact0이면0, 아니면 failure다. All returned-pair limits는1e-10. +eta_gram은 ||PhiᵀM Phi−I||F, max_eta_orth는 normalized off-diagonal maximum이고 limit1e-10다. + +분류 scale=max_i |Kii|/Mii는 finite positive여야 하며 default normalized near-zero1e-9, +인접 cluster gap1e-8이다. 유의한 negative lambda는 실패한다. Near-zero negative는 원 값으로 +남기고 frequency를 만들지 않는다. 이 분류 scale은 FEAST interval upper bound가 아니다. +실제 search/count·SPD/roundoff budget은 backend 연결에서 검증하며 최저 N 보장 근거를 기록한다. + +## 독립 local/temporal 검사의 수치 기준 + +Zero 기대량에는 임의 absolute floor 대신 same-unit uncancelled term scale 또는 수식에 따른 +strain/force/energy scale을 사용한다. Initial invariant budget은 double eps와 연산 길이·geometry +condition 추정에 비례하는512 eps scale이다. Scale0은 exact-zero다. Conditioning 때문에 budget이 +물리 결함을 가릴 정도로 커지면 검사를 통과시키지 않고 모델/검사 유효 범위를 보고한다. + +Directional difference는 signed direction과 h sweep으로 truncation/roundoff 구간을 확인한다. +기본 목표는 유의한 nonzero oracle scale에 대해 gradient/tangent 최적 구간 relative1e-7 이하다. +한 h에서 가까운 값만 고르지 않고 예상 error curve·analytic affine 사례·zero-state linear limit를 +함께 확인한다. 필요 budget 수정은 oracle conditioning과 independent review evidence로 설명한다. + +HHT temporal case는 analytic/manufactured u/v/physical a를 각각 평가한다. Smooth forcing 구간의 +기본 목표는 h/h2/h4에서 observed order1.8 이상이며 noise floor에 가까운 quantity는 다른 유의한 +case/time/step 범위로 검사한다. Knot를 가로지른 비매끄러운 forcing을 smooth-order 증거로 쓰지 않는다. +Spatial refinement·locking은 수렴 경향과 적용 한계의 검사이며 reference tolerance를 재정의하지 않는다. + +## 원본 비교 + +Reference-only S/B, row5%, RMS1%, exact-zero는 common policy를 따른다. Identity/finite/completeness +오류를 tolerance로 처리하지 않는다. Stress point 좌표는 출력 precision에 따른 auxiliary convention +검사이며 ID matching은 element/IntPt다. Input/CSV raw SHA는 현재 working-tree byte 기준이며 +Git LF blob과 Windows CRLF bytes를 혼동하지 않는다. 실제 읽은 원본 byte identity를 evidence에 남긴다. diff --git a/docs/hex8-structural-analysis/numerical-review.md b/docs/hex8-structural-analysis/numerical-review.md new file mode 100644 index 0000000..f3b7ad3 --- /dev/null +++ b/docs/hex8-structural-analysis/numerical-review.md @@ -0,0 +1,54 @@ +# Hex8 독립 수치 검토 + +검토 대상은 [PRD](PRD.md), [formulation](formulation.md), [numeric controls](numeric-controls.md), +[I/O](io.md), [reference mapping](reference-model.md)이다. 2026-10-08 작성자와 독립된 +`hex8_t1_numerical` reviewer가 문서·관련 코드·원본을 대조했다. 수식에 추가 blocker는 없으나 +아래 필수 원본/입력 계약 충돌은 사용자 결정 대기다. 실제 solver 수치 PASS가 아니다. + +## HEX8-NR-001 — 영 회전 경계와 필수 원본 충돌 + +현재 PRD008/I/O는 BC/CLOAD DOF4–6을 값0이어도 거부한다. 그러나 모든 필수 INP에 +`Set-1, 4, 4`, `Set-1, 5, 5`, `Set-1, 6, 6`의 생략된 영 지정값이 있다. +Static2/frequency는794–796행, dynamic2는796–798행이다. Read-only 원본을 그대로 +사용하면5개 모두 input failure이므로 end-to-end integration/필수 비교를 진행할 수 없다. + +원본의 영 회전 BC만 warning/no-op으로 수용하는 입력 호환 예외와, strict 거부를 유지하고 +사용자가 원본을 수정하는 두 대안을 사용자에게 제시했다. 현재 승인 대기이며 silent ignore/ +원본 preprocessing을 적용하지 않았다. Kernel 수식에는 이 충돌과 무관한 수치 blocker가 없다. + +## 독립 검토에서 정리한 내용 + +초기 static convergence 문서의 max(internal_free,external_free) branch는 prescribed-only에서 +residual=internal_free라 ratio1을 만들어 수렴을 막을 수 있었다. Draft를 기존 +`EvaluateResidualChannel`의 external_free exact0 absolute branch로 수정했다. Reviewer는 수정 후 +기존 source219–246과의 일치를 확인했다. 승인 physics/schema/external acceptance는 바꾸지 않았다. + +Reviewer의 독립 표준-library 산술 확인은 exit0이며 TL tangent relative 최적 오차 약4.59e-11, +Bernstein27 재구성 최대오차7.77e-16, mass Walsh 최소 모드값.03703703703703707≈1/27, +scalar HHT u/v/physical a 관측 차수 약2.00/1.98–1.99/2.00이었다. 초기 NumPy 계산은 모듈 +부재로 exit1이었고 표준-library 계산으로 대체했다. 문서/코드/원본 읽기 명령은 exit0, +glob discovery 검색 하나는 exit1이었다. File edit/build/test/external solver 실행은 하지 않았다. +이 숫자는 문서 식의 독립 산술 확인이며 production kernel/backend/mesh 검증 evidence가 아니다. + +TL energy/Hessian·engineering/tensor shear, degree(2,2,2) Jacobian 인증, mass SPD와 real/FP bound +구분, original generalized K/M·최저 N, HHT a/A·weighted/endpoint tangent·초기 force/physical +reaction, typed/HDF5·failed accepted 보존에는 문서 수식의 추가 blocker가 없었다. + +검토해야 할 주요 위험은 다음과 같다. + +- J0의 column/gradient 변환과 point3/4·7/8 순서; det J polynomial Bernstein 변환과 outward + interval/subdivision이 whole-cell 양성을 보증하는지, uncertain/resource failure가 보수적인지. +- TL energy variation에서 material/geometric tangent의 index와 work conjugacy, + rigid rotation/strain objectivity·zero-state 선형극한과 unaveraged Cauchy/Green recovery. +- 8점 consistent M의 SPD·총질량·reference 상수성·local spectral bound와 실제 sparse pencil + roundoff/control의 구분; Shell null/nodal whitening 미사용 및 lowest-N count 검증. +- HHT auxiliary/physical acceleration·weighted/endpoint residual의 동등 조건·tangent scale, + initialization/amplitude endpoints·physical reaction·u/v/a 시간수렴과 numerical dissipation. +- Static/Newton의 approved defaults·force/length 단위·zero-scale branch, internal oracle budget과 + 외부 reference acceptance 분리, geometry/finite/recovery 이후 atomic state/output commit. +- Original required U/RF/Gauss S·dynamic101 frame projection·frequency 미제공 상태를 정확히 + 구분하는지. Coordinate sanity 확인을 stress/reference correctness로 승격하지 않는지. + +이 risk는 이후 실제 interval primitive/subdivision·brick/warped oracle·tangent step sweep· +generalized runtime/count·prescribed-only state·HHT mesh 시간수렴·formal HDF5/reference 사전검사로 +검증해야 한다. 아직 실행하지 않은 solver build/test/reference를 PASS로 적지 않는다. diff --git a/docs/hex8-structural-analysis/reference-model.md b/docs/hex8-structural-analysis/reference-model.md new file mode 100644 index 0000000..1e63411 --- /dev/null +++ b/docs/hex8-structural-analysis/reference-model.md @@ -0,0 +1,71 @@ +# Hex8 원본과 비교 mapping + +기준은 [PRD](PRD.md)의 FEM-REQ-HEX8-022–023와 [공통 수치 정책](../TOLERANCE.md)이다. +Source revision은2382d3a이며 사용자 제공 `reference/hexa/`의5 INP·8 CSV를 read-only로 사용한다. +아래 hash는 현재 Windows working-tree raw bytes(CRLF) 기준이며 Git LF blob hash와 구분한다. + +## 원본 inventory + +442 nodes/300 C3D8 elements, material E=2.1e11/nu=.3/rho=7850, source Step-1이다. +Static DIRECT h=.1/T=1의 마지막 Increment10을 비교하고 nonlinear은 NLGEOM=YES다. +Dynamic DIRECT h=.1/T=10의 Increment0..100 전체를 비교한다. Amp-1은 `(0,0),(.1,1),(10,1)`다. +Frequency는 original unstressed 상태의10 modes 요청이며 결과 Value는 아직 제공되지 않았다. + +| 원본 | CSV rows | SHA-256 raw | +| --- | ---: | --- | +| `hexa_dynlinear.inp` | — | `f8db81b8ea56b689ab0ad892e6a84b7c6a0162c9d3ff95328ea99722f3de078e` | +| `hexa_dynlinear_U.csv` | 44642 | `623c20489e8cc18d23fa1728563ce5a26059f321861514ef8569e3d204ef6cb5` | +| `hexa_dynnonlinear.inp` | — | `1685f86f844e8020bf46e1747b949699ac9aff0d7570bd21ec95109399365ff9` | +| `hexa_dynnonlinear_U.csv` | 44642 | `f5832a24577f54838bb49dec86a0dc9668cf43e78953f718a9d3635e0f574226` | +| `hexa_freq.inp` | — | `42cbcec2a8b738f8b6d2c1e13114b8840dccdde6fc3e6f8a43a3272e85d82347` | +| `hexa_linearstatic.inp` | — | `67183909c5dc962a4d4b65ffb81f7bd65b72e89a5d015c8369a8e0226347a647` | +| `hexa_linearstatic_RF.csv` | 442 | `3e04e71ec075ffef098cf4870d77f9c400557fccb375369da8bf67cf67c1e36b` | +| `hexa_linearstatic_S.csv` | 2400 | `8840a502b9d28a91e5685349301a56fed37d2ac62327b71304716b714db577e8` | +| `hexa_linearstatic_U.csv` | 442 | `1ff49aea3ec601cfd796d6a2fb6a4f91be3fc3de9426cdf3744d981216d4bd5f` | +| `hexa_nonlinearstatic.inp` | — | `7858254025b96c6bfe3fb6498605ecf9c473425c2bc3593f5fbdc6902fd7c6cb` | +| `hexa_nonlinearstatic_RF.csv` | 442 | `3ba67a4fb75b2ce3edee13d35b2ea66ac7d52fc16e612c086ed1122a834fee7b` | +| `hexa_nonlinearstatic_S.csv` | 2400 | `a8866a730f0d65b1e3921d504d255b72158b4a2b9ee30fc691712d94982b07ba` | +| `hexa_nonlinearstatic_U.csv` | 442 | `bd6c2fe2b2bb2ffb0bc2ea52f67513c3967a396b5707bbebc9533fde7be25ac6` | + +## Quantity와 identity + +Static U1/U2/U3 global, RF1/RF2/RF3의 constrained projection, integration-point Cauchy +S11/S22/S33/S12/S13/S23 각각 blocking family다. U/RF는442-row 전체 inventory를 먼저 확인하고, +RF만 실제 constrained components로 투영한다. Free Abaqus RF와 FESA free residual을 비교하지 않는다. +Stress는300×8×6 전부 포함하며 elemental-nodal stress·절점 외삽·평균으로 변환하지 않는다. +Dynamic U는101 frame 각각442×3인 독립 blocking family다. Frequency Value는 mode별 singleton이며 +MITC4 eigen scoped5% RMS 예외를 적용하지 않는다. + +Key는 source case/step/frame 또는 increment/canonical instance/node 또는 element/IntPt/component다. +CSV header whitespace만 lexical 정규화하고 duplicate/missing/extra/nonfinite required value를 +tolerance 전에 실패시킨다. `PART-1-1`과 input raw `Part-1-1`은 기존 Abaqus case 의미로 대응한다. +FESA storage Step-1/frame0과 source name/Increment10의 서로 다른 의미를 유지한다. +Dynamic은 integer increment로 match 후 source decimal time과 binary64 n*h를 대조한다. +Original coordinate는 reference 위치이며 nonlinear current 위치로 바꾸어 맞추지 않는다. + +## Integration point convention의 보조 확인 + +Natural node 순서는 `---,+--,++-,-+-,--+,+-+,+++,-++`, IntPt 순서는 +`---,+--,-+-,++-,--+,+-+,-++,+++`다. 뒤의3/4·7/8을 node 순서와 혼동하지 않는다. +전체300×8 point에서 고정 element/IntPt key로 입력 shape의 기준 위치를 계산해 CSV X/Y/Z와 +대조했다. 선형/비선형 S 모두 최대 absolute coordinate difference는 +`[1.4328052233558708e-7,1.4747179877261374e-7,2.4956611142101792e-6]`이었다. + +이 보조 확인의 budget은 coordinate 성분의 uncancelled shape sum에16×float32 eps를 곱했다. +모든 point에서 maximum budget ratio=.112265였다. 이는 단정밀도 수준의 원본 출력 해상도를 +기준으로 한 convention sanity check이며 실제 원본 precision metadata의 증명이나 stress값의 +PASS가 아니다. Nearest-position matching을 수행하지 않았고 어떤 좌표/ID/값도 수정하지 않았다. + +명령은 `python .dryforge/inspect-reference.py`, native exit0이었다. 로컬 raw 보고서는 +`.harness/hex8-evidence/reference-inventory.json`이며 해당 ignored evidence를 지속할 사용자 파일로 +오인하지 않는다. Formal comparator의 identity/coordinate controls는 동일 의미를 실제 tests로 검증한다. + +## 비교 정책과 준비 대기 + +Common policy: reference-only S=max abs, B=.01S, near-zero error<=B, 일반 relative<=.05, +family RMS/S<=.01, S=0 exact-zero다. 다른 quantities/units/frame을 합쳐 scale을 바꾸지 않는다. +Frequency 원본 quantity/units/mode/step/hash는 제공 후 먼저 확인한다. 결과를 생성·추정하거나 +FESA 결과를 reference로 사용하지 않는다. 필수 원본 부재는 미실행/기능 검증 대기다. + +Dynamic V/A/reaction/energy의 외부 자료는 없어 independent physical/temporal 검증이 필수다. +현재 inventory/convention 확인은 parser 실행·FESA 수치 결과 비교·기능 검증 PASS가 아니다. diff --git a/docs/tracking/findings.md b/docs/tracking/findings.md index 6871440..4082ede 100644 --- a/docs/tracking/findings.md +++ b/docs/tracking/findings.md @@ -1,5 +1,20 @@ # 미해결 문제 +## Hex8 필수 원본과 영 회전 경계 입력 계약의 충돌 + +- 조건·현상: 승인된 Hex8 입력 계약은 BC DOF4–6을 값0이어도 거부하지만, + `reference/hexa/`의 필수5 INP 모두 `Set-1, 4, 4`, `Set-1, 5, 5`, `Set-1, 6, 6`의 + 생략된 영 지정값을 포함한다. 정적2/frequency는794–796행, 동적2는796–798행이다. +- 영향: 엄격한 계약을 그대로 구현하면5개 원본 모두 input failure로 필수 비교가 불가능하다. + 독립 kernel 수식에 대한 blocker와는 별개다. +- 현재 해결하지 못하는 이유: 승인된 입력 의미를 변경하거나 원본을 수정할 권한을 + 임의로 추정하지 않는다. 영 회전 BC만 경고/no-op으로 수용하는 예외 또는 엄격한 거부 유지와 + 사용자 원본 수정 중 한정된 결정을 요청한 상태다. +- 다음 접근: 사용자 답변에 따라 [기능 PRD](../hex8-structural-analysis/PRD.md), + [I/O](../hex8-structural-analysis/io.md), [결정](../hex8-structural-analysis/ADR.md)을 일치시키고 + 승인된 의미를 parser 테스트로 검증한다. [독립 수치 검토](../hex8-structural-analysis/numerical-review.md)의 + HEX8-NR-001을 해소하며 원본/source identity와 비영 회전 경계·회전 CLOAD 거부는 보존한다. + ## HHT shell의 시간수렴 - 조건·현상: 실제 shell의 두 시간수렴 사례에서 요구한 수렴 성능을 만족하지 못한