From d76602a0f1b47a3ca53c0e050d1af4b40ab1ed55 Mon Sep 17 00:00:00 2001 From: "KOKO\\Mimi" Date: Sat, 17 Oct 2026 22:34:12 +0900 Subject: [PATCH] docs: consolidate solver knowledge and preserve formulation originals --- docs/README.md | 59 ++--- docs/calculation-performance/README.md | 37 +++ .../README.md | 33 +-- docs/hex8-structural-analysis/README.md | 183 ++++++++------- docs/hht-implicit-dynamics/README.md | 177 +++++++++----- ...rmulation-c08b-newton-research-20261012.md | 118 ++++++++++ .../formulation-dae-research-20261012.md | 200 ++++++++++++++++ ...lation-graph-certificate-draft-20261012.md | 64 ++++++ ...lation-historical-docs-cleanup-20261004.md | 215 ++++++++++++++++++ ...nertia-historical-docs-cleanup-20261004.md | 209 +++++++++++++++++ .../formulation-momentum-research-20261012.md | 79 +++++++ docs/linear-static-3d-euler-beam/README.md | 88 ++++--- docs/linear-static-mitc4-shell/README.md | 90 +++++--- docs/mitc4-shell-feast-eigen/README.md | 67 +++++- docs/mitc4-shell-feast-eigen2/README.md | 98 +++++--- .../nonlinear-static-newton-raphson/README.md | 90 +++++--- docs/shell-surface-pressure-load/README.md | 93 +++++--- docs/shell-transient-heat-transfer/README.md | 149 +++++++++--- docs/solver-core/README.md | 71 ++++++ 19 files changed, 1740 insertions(+), 380 deletions(-) create mode 100644 docs/calculation-performance/README.md create mode 100644 docs/hht-implicit-dynamics/formulation-c08b-newton-research-20261012.md create mode 100644 docs/hht-implicit-dynamics/formulation-dae-research-20261012.md create mode 100644 docs/hht-implicit-dynamics/formulation-graph-certificate-draft-20261012.md create mode 100644 docs/hht-implicit-dynamics/formulation-historical-docs-cleanup-20261004.md create mode 100644 docs/hht-implicit-dynamics/formulation-inertia-historical-docs-cleanup-20261004.md create mode 100644 docs/hht-implicit-dynamics/formulation-momentum-research-20261012.md create mode 100644 docs/solver-core/README.md diff --git a/docs/README.md b/docs/README.md index e92e065..378ff6f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,48 +1,15 @@ -# FESA 문서 안내 +# FESA 기술 문서 -현재 계약, 기능의 재사용 정보, 실제 검증 결과와 과거 개발 이력을 구분한다. -기능 구현과 기능 검증 완료는 다르며, 문서 정리로 과거 실행을 현재 통과로 바꾸지 않는다. +현재 구현의 목적·경계·소유권·검증 한계를 기능별로 요약한다. 정식화 원문은 유도와 당시 가정을 보존하며 현재 채택 여부는 README에서 구분한다. 문서 정리는 새 build/test 또는 외부 검증 통과를 뜻하지 않는다. -## 공통 기준 - -| 확인할 내용 | 원본 문서 | -| --- | --- | -| 제품 목적·지원 범위·승인 요구사항 | [PRD](PRD.md), [business-rules](business-rules.md) | -| 모듈·데이터 흐름·소유권·수명 | [ARCHITECTURE](ARCHITECTURE.md) | -| CLI·입력·결과·비교 identity | [contracts](contracts.md) | -| 외부 수치 비교와 승인 예외 | [TOLERANCE](TOLERANCE.md) | -| 개발·수치 구현에서 지킬 규칙 | [standards](standards.md), [CODINGSTYLE](CODINGSTYLE.md), [engineering-notes](engineering-notes.md) | -| 환경 준비·실행·build/test | [operations](operations.md), [HARNESS](HARNESS.md), [HARNESS_WORKFLOW](HARNESS_WORKFLOW.md) | -| 실행 권한·데이터 취급 | [security](security.md) | -| 전문 작업·skill·기능 문서 소유권 | [SOLVER_AGENT_DESIGN](SOLVER_AGENT_DESIGN.md), [SOLVER_SKILL_DESIGN](SOLVER_SKILL_DESIGN.md), [FEATURE_DOCUMENTATION](FEATURE_DOCUMENTATION.md) | -| 승인 결정과 변경 이유 | [ADR](ADR.md), [결정 목록](tracking/decisions/index.md) | -| 현재 구현·검증과 잔여 문제 | [현황](tracking/status.md), [미해결 문제](tracking/findings.md) | - -공통 요약과 상세 계약이 충돌하면 내용을 최신 날짜만으로 덮어쓰지 않는다. 승인된 의미와 -실제 구현·검사 대상 revision을 대조하고, 물리·acceptance 변경은 별도로 판단한다. - -## 기능별 진입점 - -각 진입점에서 목적·범위, 수식·I/O, 사용법·Handoff, 검증·수정·한계를 연결한다. - -| 기능 | 문서 | -| --- | --- | -| B33 선형 정적 Beam | [linear-static-3d-euler-beam](linear-static-3d-euler-beam/README.md) | -| MITC4 선형 정적 Shell | [linear-static-mitc4-shell](linear-static-mitc4-shell/README.md) | -| MITC4 비선형 정적 Newton–Raphson | [nonlinear-static-newton-raphson](nonlinear-static-newton-raphson/README.md) | -| Shell 표면 압력 | [shell-surface-pressure-load](shell-surface-pressure-load/README.md) | -| MITC4 질량·FEAST 현재 구현 | [mitc4-shell-feast-eigen2](mitc4-shell-feast-eigen2/README.md) | -| 이전 MFE의 요구·채택 유도·반례 근거 | [mitc4-shell-feast-eigen](mitc4-shell-feast-eigen/README.md) | -| HHT implicit dynamics | [hht-implicit-dynamics](hht-implicit-dynamics/README.md) | -| Shell transient heat transfer | [shell-transient-heat-transfer](shell-transient-heat-transfer/README.md) | -| C++ 모듈화와 공개 API 정리 | [cpp-object-oriented-modular-refactoring](cpp-object-oriented-modular-refactoring/README.md) | - -## 개발 이력과 원문 - -[개발 결정·폐기된 운영 계획](development-history.md)은 승인 출처와 중요한 교훈을 연결한다. -[MITC4 보충 기록](MITC4_SUPP.md)은 실제 실패·계약 변경·예상 TDD RED를 구분한다. -[초기 작성 노트](archive/ProjectInitialPlanNote.md)는 역사 자료이고 현재 작업 계획이 아니다. -`reference-papers/`는 논문·발췌·이미지 원문이며 기능 검증 통과의 근거와는 구분한다. - -현재 checkout에 없는 개인 로그·생성 결과는 당시 evidence 위치로 표시한다. 저장소에 있는 -검사 코드·reference 원본·검증 보고서와 다른 자료이므로 실제 파일이 제공된 것으로 해석하지 않는다. +- [솔버 공통 구조·입출력·수치 비교](solver-core/README.md) +- [3D Euler beam](linear-static-3d-euler-beam/README.md) +- [MITC4 선형 정적 shell](linear-static-mitc4-shell/README.md) +- [MITC4 비선형 정적](nonlinear-static-newton-raphson/README.md) +- [Shell 표면 압력](shell-surface-pressure-load/README.md) +- [이전 eigen 유도](mitc4-shell-feast-eigen/README.md) · [현재 FEAST eigen](mitc4-shell-feast-eigen2/README.md) +- [Shell HHT 동역학](hht-implicit-dynamics/README.md) +- [Hex8 구조해석](hex8-structural-analysis/README.md) +- [Shell 열전달](shell-transient-heat-transfer/README.md) +- [계산 성능](calculation-performance/README.md) +- [C++ 모듈화](cpp-object-oriented-modular-refactoring/README.md) diff --git a/docs/calculation-performance/README.md b/docs/calculation-performance/README.md new file mode 100644 index 0000000..48316a6 --- /dev/null +++ b/docs/calculation-performance/README.md @@ -0,0 +1,37 @@ +# 계산 성능 개선 + +Hex8와 reduced-coordinate shell HHT의 실제 병목을 VTune으로 조사하고, 승인된 물리·입력·정밀도·결과 의미를 유지하며 실행 시간을 줄이는 작업이다. 새 요소·하중·적분법·공용 cache framework 추가는 범위 밖이다. 요구사항 `FEM-REQ-PERF-001..009`의 시간 목표와 검증은 별개이며 현재 최종 완료 상태는 아니다. + +## 채택한 계산 경로와 수명 + +[Matrix::Multiply](../../src/fesa/math/matrix.cpp)는 dense GEMV/GEMM, [SparseMatrix::Multiply](../../src/fesa/math/sparse_matrix.cpp)는 CSR validate·finite/RHS/checked MKL_INT 확인 후 `mkl_sparse_d_create_csr → mkl_sparse_d_mv → destroy`를 사용한다. Const 호출마다 변환 배열·values 복사·handle을 소유하므로 copy/move·동시 호출에 backend pointer를 공유하지 않는다. Empty shape도 입력 검증 뒤 zero vector를 반환한다. 지속 symbolic cache나 scalar fallback은 없다. 호출마다 CSR 배열 복사 비용이 있으므로 MKL 연결만으로 전체 성능 향상을 주장하지 않는다. + +[Dense adapter](../../src/fesa/math/dense_blas_internal.cpp)가 MKL 세부를 감싸고 [PARDISO](../../src/fesa/solvers/linear/mkl_pardiso_solver.cpp)와 [tangent solver](../../src/fesa/solvers/linear/mkl_pardiso_tangent_solver.cpp)가 factor/solve/release를 소유한다. 성공한 동일 matrix의 여러 RHS는 재사용하지만 새 matrix·실패 분해의 stale factor는 쓰지 않는다. 기본1×1 SPD 호출의 기존 heap failure에만 local1-thread/TLS 복원을 적용했으며 vendor 원인은 미확정이다. Public core에 MKL 타입을 노출하지 않는다. + +[Hex8 high+low](../../src/fesa/elements/hex8_high_low.cpp)는 normalized pair의 원래 graph·ordered reduction·RN64 observable을 유지한다. [LinearTangentCache](../../src/fesa/elements/hex8_linear_tangent_cache.h)는 동일 요소 복사본 사이의 불변 paired Hessian 두24×24 matrix만 `call_once`로 준비하고 nonlinear trial은 접근하지 않는다. [Packet 경계](../../src/fesa/elements/hex8_pair_simd.h)·[AVX2 구현](../../src/fesa/elements/hex8_pair_simd_avx2.cpp)·[dispatch](../../src/fesa/elements/hex8_pair_simd_dispatch.cpp)는 독립 b-lane의 순서를 유지하고 지원되지 않는 환경은 원래 scalar 경로를 사용한다. 이는 실패한 수치 계산을 다른 물리식으로 재시도하는 fallback이 아니다. + +[HHT trial context](../../src/fesa/analysis/hht_dynamic_internal.h)와 [reduced procedure](../../src/fesa/analysis/hht_reduced_procedure.cpp)는 position 의존량과 rate 의존량의 재사용 수명을 구분한다. [Nonlinear shell](../../src/fesa/elements/nonlinear_mitc4_shell.cpp)의 private Jet 영 seed는 정의된 numeric zero/도함수 provenance만 최적화하고 NaN/Inf·singular composition 실패를 지우지 않는다. 절점6×6 outer/full24 scatter 후보는 관련 검사가 통과했어도 단일 micro 차이 약1.44%와 production 호출 빈도 미확인으로 보류·복원됐으며 현재 채택 경로가 아니다. + +일반 Float64 행렬 곱은 MKL을 쓰지만 작은 고정 좌표 계산, high+low·보상 누적·outward interval 인증은 해당 정밀도와 오차 의미를 보존한다. Thermal RHS를 두 행곱 차로 재배치한 후보는 cancellation oracle를 깨뜨려 폐기했다. 현재 entry association `(c/delta)*(old-g)-k*g`와 row 순서를 유지한다. 연산 순서·zero 부호·floating exception 상태도 실제 계약에 필요한 범위에서 검증한다. + +## 시간·결과·reference 계약 + +공통 CLI·source identity·lease·atomic HDF5·비교 기준은 [solver-core](../solver-core/README.md), 물리 의미는 [Hex8](../hex8-structural-analysis/README.md)·[HHT](../hht-implicit-dynamics/README.md)를 따른다. Time step·increment·Newton gate·질량·적분점·출력량·schema·정밀도를 성능 때문에 줄이거나 바꾸지 않는다. + +기준 환경은 Ryzen7 5800H Windows/MSVC x64 최적화 Release다. 동일 thread·runtime·전원·compiler 조건에서 워밍업 없이 모델별 별도 process를 한 번 측정한다. Process 시작 요청 직전부터 정상 종료 직후까지 읽기·계산·복구·로그·HDF5 close/final 교체를 모두 포함한다. 빌드·입력 복사·VTune·비교는 구간 밖이다. Debug 시간·CPU 합계·계측 elapsed·반복 중 최솟값을 목표 판정에 쓰지 않는다. + +| 원본 case | 목표 초 | 기존 단일 baseline 초 | 당시 수치 비교 | +| --- | ---: | ---: | --- | +| hexa_nonlinearstatic | 2 | 10.914924 | U/constrained RF/point S 통과 | +| hexa_dynnonlinear | 100 | 402.069447 | 101-frame 전체 U 통과 | +| shellNL-dyn-meshfine | 100 | 6372.325621 | 729-node inventory·101-frame 확인,9-node U blocking 통과·UR warning200 entries | + +이 baseline은 세 목표 모두 미달이다. 최종 source의 세 모델 새 결과·공식 시간·전체 Debug·필수 reference·독립 검토가 모두 필요하다. 공유 consumer 회귀에는 Hex8 원본5개(정적2·고유치·동적2)의 기존 비교도 포함한다. 수치 판정은 source/frame/component·finite/schema 검사를 먼저 통과하고 공통 near-zero1%·일반 행5%·family RMS1%·zero-scale exact-zero를 적용한다. MITC4 eigen 예외를 Hex8에 쓰지 않는다. + +## 실제 근거와 남은 범위 + +Hex8 기하 packet 수정본의 관련 Debug/Release82개씩, 독립 snapshot9,804행·전체 bytes 일치 기록이 있다. 이전 Release ordered-overflow 사례는 값 bit가 같아도 INVALID FE/MXCSR가 달라 실패했다. Nonfinite 첫 sum에서 원래 checked scalar bridge로 돌아가 error 계산을 생략하는 수정 후 통과했으며 flags clear·기대값 완화로 숨기지 않았다. 이 검증을 전체 모델 시간이나 모든 source의 현재 PASS로 확대하지 않는다. + +그 수정본의 단일 동적 개발 실행은 native0·117.7986225초로 완료됐으나100초 목표 초과다.101 U frame 비교는 blocking PASS, 최대 relative RMS 약2.155586e-6이었다. Outer wrapper는 종료 자식의 null StartTime 처리에서1로 끝났고 실제 FESA native0·후속 comparator0과 구분한다. 이전135.9302297초와의 차이는 서로 다른 source의 단일 개발 표본이며 반복 통계나 특정 함수 비용이 아니다. + +Shell 명시 영 seed 이후 SW60 수집은 partial이며 collector native4·target 종료 미관측, increment1까지 진행했다. 함수 sample의 Jet 산술·할당·작은 MKL 호출·OpenMP spin은 비용 후보지만 sample 부재를 cache hit 보장으로 바꾸거나 nested inclusive CPU를 합산해 wall time을 만들지 않는다. 전체 shell100초·최종 전체 Debug·원본5개 재실행·최종 물리 평가는 미완료다. 보류 후보의 PASS를 복원 source나 최신 통합본에 승계하지 않는다. diff --git a/docs/cpp-object-oriented-modular-refactoring/README.md b/docs/cpp-object-oriented-modular-refactoring/README.md index 03e6e95..391db7b 100644 --- a/docs/cpp-object-oriented-modular-refactoring/README.md +++ b/docs/cpp-object-oriented-modular-refactoring/README.md @@ -1,21 +1,26 @@ # C++ 모듈화와 공개 API 정리 -## 목적과 개발 결과 +기존 B33/MITC4 솔버의 모델·local 계산·assembly·procedure·backend·I/O 책임을 분리하고 공개 header의 vendor 의존을 격리한 리팩터링이다. 새 물리·입력·해법·결과 schema 또는 tolerance를 도입하는 기능이 아니다. 현재 재사용할 구조·CLI·I/O·수치 비교 계약은 [solver-core](../solver-core/README.md)에 모았다. -모델·요소·assembly·procedure·backend·I/O 책임을 분리하고 공개 header의 vendor 의존을 -격리했다. Naming/format/header guard·Doxygen 계약과 HDF5/reference 동작의 보존을 확인했다. -당시 revision·명령·수치 결과와 환경 실패는 [검증 기록](verification.md)에 남긴다. +## 설계와 실제 데이터 흐름 -## 재사용 Handoff +[Domain](../../include/fesa/model/domain.h)은 의미 모델을 소유하고 [AnalysisModel](../../include/fesa/analysis/analysis_model.h)은 더 짧게 사는 non-owning view다. [DofManager](../../include/fesa/fem/dof_manager.h)는 equation·partition·pattern을 소유한다. [Element](../../include/fesa/elements/element.h)의 typed local contribution은 [SparseAssembler](../../src/fesa/assembly/sparse_assembler.cpp)에서 결정적 순서로 조립된다. [LinearStaticProcedureExecutor](../../include/fesa/analysis/linear_static_procedure.h)는 caller-owned 실행/선형해법 adapter를 참조하고 실행에 필요한 state만 만든다. [ResultRecovery](../../include/fesa/results/result_recovery.h)는 위치·단위·부호를 가진 결과를 복구하고 [HDF5 writer](../../src/fesa/io/hdf5/hdf5_results_writer.cpp)는 직렬화한다. -현재 architecture·수명은 [ARCHITECTURE](../ARCHITECTURE.md), C++ 규약은 -[CODINGSTYLE](../CODINGSTYLE.md), 실행은 [operations](../operations.md)를 따른다. -실제 공개 header와 대응 src consumer를 함께 읽으며 `.hpp` 시절의 API명·임시 Step 명령을 -다시 도입하지 않는다. 원본 reference와 물리·tolerance를 리팩터링 편의로 바꾸지 않는다. +[FesaApplication](../../src/fesa/app/fesa_application.cpp)이 객체·lexical output path·lease·실행 수명을 조합한다. 공개 API는 `include/fesa/`, 구현은 대응 `src/fesa/`에 두며 vendor handle과 오류 번호는 private 수치/I/O adapter 뒤에 둔다. 공개 API 이름을 예전 `.hpp` 시절 표기로 복원하거나 parser에서 concrete numerical storage를 직접 소유하지 않는다. Polymorphic base의 public virtual destructor, 단독 소유의 unique_ptr·RAII, self-contained include guard와 source identity를 유지한다. -## 실패와 교훈 +이 경계는 현재 eigen·dynamic·thermal·solid가 확장한 구조의 기반이다. 당시 static 리팩터링 성공을 나중에 추가된 모든 절차의 재검증으로 해석하지 않는다. 특히 trial/commit과 파일 final replacement는 다른 실패 경계다. 내부 accepted frame이 있어도 전체 해석이 실패하면 미완성 정상 final을 공개하지 않는다. -상속된 `FESA_HARNESS_CODEX_SANDBOX`로 Python default 계약 검사가 실패했던 사례는 환경 -오분류를 피하는 근거다. Clang-format의 변경 유무와 exit를 분리하고 link 성공만으로 -MSVC runtime·dependency 설정이 완성됐다고 판단하지 않는다. 그때의 pass는 현재 codebase -전체의 재검증 결과가 아니다. +## 보존한 입력·출력과 비교 의미 + +CLI는 입력 `.inp` 하나, lexical sibling HDF5·log, warning/오류 진단과 exit 의미를 유지했다. B33는 node·element endpoint·section point를, MITC4는 instance/node·element/point identity를 보존한다. 같은 node에 모인 endpoint action을 평균하거나 physical shell strain에 numerical drilling 값을 섞지 않는다. 정적 schema0·canonical frame0의 mandatory dataset·dtype·shape는 리팩터링 편의를 위해 바꾸지 않는다. + +현재 수치 비교는 common family의 row5%·RMS1% 및 identity/finite 사전검사를 따른다. 과거 리팩터링 보고서에는 B33 `absolute_floor+1e-6*reference_scale`와 S4 fixed absolute1e-5로 수행한 당시 비교가 있다. B33176/176행, S4294/294행 통과 기록은 그 옛 기준·revision의 evidence이며 현재 common policy로 다시 판정한 결과가 아니다. Beam stress는 당시 Abaqus 외부 비교 N/A였고 analytical/unit·HDF5 schema evidence와 구분한다. + +## 교훈과 검증 한계 + +- Naming·format·header guard·Doxygen와 dependency 경계를 정리해도 displacement만으로 stress/reaction·수명·실패 보존이 증명되지는 않는다. Header 변경은 대응 src consumer까지 함께 확인한다. +- Dense 크기 곱 overflow는 할당 전에 확인한다. Public API의 Status/Result와 backend exception 변환은 원래 실패 의미를 보존해야 한다. +- 상속된 환경 변수가 검사 실패의 원인이었던 사례가 있다. 환경 오류와 solver 결함을 구분한다. Formatter의 변경 유무와 native exit, link 성공과 runtime DLL 준비를 따로 판단한다. +- 과거 실행 절차를 현재 실행 계획으로 복원하지 않는다. CTest와 별도 Python suite의 성공을 합치지 않는다. + +이 문서 작업에서는 build/test를 실행하지 않았다. 당시 모듈화와 reference의 bounded 검증은 남기되 최신 전체 회귀·외부 배포 준비 완료를 선언하지 않는다. 현재 물리적 미해결 사항은 각 기능 README가 소유한다. diff --git a/docs/hex8-structural-analysis/README.md b/docs/hex8-structural-analysis/README.md index cd3912c..21c9106 100644 --- a/docs/hex8-structural-analysis/README.md +++ b/docs/hex8-structural-analysis/README.md @@ -1,105 +1,122 @@ # Hex8 구조해석 -개인 연구용 FESA에 8절점 육면체의 선형 강성, Total Lagrangian–StVK 기하비선형 -내력·접선 강성과 기준 형상의 row-sum lumped 질량을 추가한다. 요소당 병진 자유도는24개다. +## 범위와 현재 근거 -2026-10-11 [HEX8-ADR-010](ADR.md)이 질량 정책을 변경했다. 아래 기존 구현의 실행 결과는 -consistent M의 당시 evidence이며 lumped 변경본 재검증은 [PRD](PRD.md)의 현재 checklist를 따른다. +8절점 육면체 C3D8의 요소당24 병진 DOF로 선형/비선형 정적, unstressed generalized +고유치와 선형/비선형 HHT 동해석을 제공한다. 2026-10-10 mean-volume 강성과 10-11 row-sum lumped 질량을 승인했다. **Mean-volume 강성· +reference row-sum lumped 질량**이 현재 정책이다. 현재 구현·원본5개 비교·검토·인계는 +확보했으나 최신 전체 통합 완료(FEM-REQ-HEX8-024)는 보류다. -2026-10-13 현재 구현·필수 원본5개 비교·검토·인계를 마쳤다. 이번 확인은 -Debug 관련 C++91 PASS·Hex8 비교기 Python96 PASS 및 보존된 원본5개 결과의 -현재 비교기 재대조 PASS다. 새 장시간 원본 실행이나 전체 CTest는 수행하지 않았다. -정적2·고유치의 원본 결과는 Debug, 동적2는 Release에서 생성한 기존 근거다. -Hex8 경로의 source 동일성과 독립 검토, 성능 최적화로 넘길 범위는 -[최종 인계](final-handoff.md)에 기록했다. +2026-10-13의 관련 Debug C++91/91·비교기 Python96개가 PASS였고, 현재 비교기로 보존된 +정적2·고유치1·동적2 결과를 재대조해 모두 PASS였다. 새 장시간 원본 실행이나 전체 CTest는 +수행하지 않았다. 정적/고유치 결과는 당시 Debug, 동적2는 Release 산출물이다. Hex8 직접 +실행·질량·복구·출력 source 동일성은 확인했으나 전체 공용 binary 동일성이나 전체 green을 +주장하지 않는다. Shell의 최신 C08b·원본·전체 Debug 사용자 중단은 [HHT 요약](../hht-implicit-dynamics/README.md)을 따른다. -초기 lumped 변경본의 관련38개·Python137개·전체789개의 결과와 당시 Shell -실패는 [채택·재검증 보고서](lumped-mass-adoption.md)의 과거 이력이다. -당시 C08b runtime 실패는 후속 승인된 초기 Newton 정책으로 해소됐고, -ADR-018의 C09와 공식 Release C08a7도 통과했다. 최신 C08b·Shell 원본·전체 -Debug는 사용자 중단이며, 전체 검증은 성능 최적화 후 진행한다. -FEM-REQ-HEX8-024의 최종 통합 완료 판정은 보류한다. -선형/비선형 정적, reference lumped-mass frequency, -선형/비선형 HHT 동해석을 typed state에서 공식 HDF5와 CLI까지 연결한다. +## 채택 방법과 이유 -다음 단락은 변경 전 consistent mass 구현의 이력이다. +[기본 정식화](formulation.md)와 [정밀도 정식화](precision-formulation.md)가 상세 수식을 +보존한다. 강성·복구·reference mass 적분은 2×2×2다. 선형 infinitesimal strain 또는 +TL–StVK Green strain에서 deviatoric energy를 점별 적분하고, 체적 energy는 +`kappa*V*theta_bar^2/2`, `theta_bar=sum(w_g*tr(E_g))/V`로 계산한다. Pointwise bulk의 +과도한 강성을 줄이는 채택이며 center/unweighted mean, Fbar, mean-J와 다르다. +Force와 Kmat/Kgeo/Kt는 같은 energy의 gradient/Hessian이다. 평균의 미분에는 서로 다른 +GP 간 coupling도 포함하며 local StVK tangent로 대체하지 않는다. -강성·질량·복구에2×2×2 reference 적분점을 사용한다. 2026-10-10 승인으로 deviatoric 항과 -요소 평균 infinitesimal/Green trace 체적 energy를 사용한다. 변경본 구현·내부 검증은 완료했고 -두 정적 원본의 U/RF/S 및 두 동적 원본의101-frame U 필수 비교도 PASS다. -실제 정적·동적 원본의 독립 수치·물리 검토도 bounded PASS다. 전체787 CTest는 -784 PASS·기존 Shell FAIL2·SKIP1(native8)으로 종료했고 추가170개는 모두 PASS다. -전체 green은 아니다. 2026-10-11 제공된 modal Value 원본과 실제 비교했으나 -최저10개 중7개가1% RMS 기준을 초과했다. 최대 차이는5번 고유치의20.2513%이며 -[최종 비교](verification.md#2026-10-11-제공된-고유치-원본의-최종-비교)에 근거를 기록한다. -필수 modal 불일치가 해결되기 전 기능 검증 완료는 대기다. 전체 Python도 기존 collection5 -오류로 native2·실행0개다. +Mass는 full reference consistent24×24 matrix의 **행합을 BC 축소 전에** 구한 대각 matrix다. +Warped 요소의 모든 node를 rho*V/8로 치환하지 않는다. Eigen normalization·HHT inertia· +reaction·kinetic energy·momentum은 같은 reference M을 사용한다. Current geometry에 따라 +mass를 재계산하지 않는다. 이 질량 변경은 입력 선택 option을 추가하지 않는다. -구현과 기능 검증 완료는 다르다. 원본 정적2·동적2의 필수 수치 비교, 사용자 modal Value와 -최신 전체 회귀·최종 검토가 완료 조건이다. 현재 상태는 [PRD checklist](PRD.md#현재-checklist), -선택과 승인 이력은 [ADR](ADR.md)에 있다. +Solid HHT는 normalized high+low로 전체 physical state와 이력을 유지한다. Element의 +상대변위 `u_a-u_0`에서 strain/force를 만들고 `Ghat_0=-sum(a>0)G_a`를 실제 gradient와 +미분에 함께 사용한다. Tiny Green strain은 sym(H)+H^T H/2로 계산한다. Predictor·rates· +full residual·recovery·work·energy·momentum·다음 accepted state에 low를 보존한다. +Backend에는 RN64 operator/RHS를 전달하지만 acceptance는 full pair에서 검사한다. +공식 F64 출력은 전체 값의 RN64 observable이며 low를 별도 영속 field로 내보내지 않는다. +Rounded 출력만 다시 넣어 엄격한 내부 gate의 같은 PASS를 기대하지 않는다. Restart는 없다. -## 사용법 +Whole-cell positive Jacobian은 outward-rounded interval/Bernstein subdivision으로 인증한다. +현재 좌표는 X+u_high+u_low 전체를 포함한다. Depth10/cell budget65536에서 인증되지 않는 +uncertain 형상도 실패하며 |detJ|·clamp·자동 다른 요소로 정상화하지 않는다. -[공통 환경·빌드 방법](../operations.md)에 따라 MSVC x64 Debug 실행 파일과 dependency DLL을 -준비한다. CLI는 입력 `.inp` 하나를 받으며 입력의 lexical parent에 `_results.h5`와 -`_log.txt`를 생성한다. `--output`은 지원하지 않는다. +## 입력·출력·reference mapping -Read-only 원본에서 직접 실행하지 않고 별도 폴더에 복사한 입력으로 실행한다. 저장소 루트의 -다음 예시는 제공된 선형 정적 입력을 사용한다. +Single Part/identity Instance의 Solid-only C3D8, SOLID SECTION, 상수 isotropic ELASTIC을 +지원한다. Frequency/HHT는 양의 DENSITY가 필요하다. 실제 BC/CLOAD는 DOF1–3이다. +Exact-zero 회전 BC4–6만 source warning/no-op이며 비영 회전 BC와 값0을 포함한 모든 +회전 CLOAD는 거부한다. 정적 비영 prescribed는 absolute target이고 비선형 factor가 +force/target에 함께 적용된다. HHT는 zero BC/initial u,v와 fixed DYNAMIC,DIRECT schedule, +TABULAR step-time relative CLOAD amplitude의 linear interpolation/end hold를 지원한다. +Static/BC amplitude·TOTAL TIME·smoothing은 제외한다. Source FREQUENCY LANCZOS/SIM +표기와 내부 generalized MKL FEAST를 구분한다. [공통 solver 요약](../solver-core/README.md)에 +CLI·lease·공통 수치 정책이 있다. CLI는 입력 sibling에 결과를 쓰며 --output은 지원하지 않는다. -```powershell -New-Item -ItemType Directory -Path '.harness/hex8-example' -Force -Copy-Item -LiteralPath 'reference/hexa/hexa_linearstatic.inp' -Destination '.harness/hex8-example/hexa_linearstatic.inp' -& '.harness/build-ninja-msvc-debug/src/fesa/fesa.exe' '.harness/hex8-example/hexa_linearstatic.inp' -$LASTEXITCODE -``` +Schema version1, feature_id=hex8-structural-analysis, +`mass_formulation=lumped-reference`, `component_order=node-major; UX,UY,UZ`다. +기존 consistent-reference 파일을 metadata만 바꿔 재사용하지 않는다. F64/U64/U8은 explicit +little-endian, 문자열은 UTF-8이고 모든 physical 값은 finite다. -Native exit0과 이번 입력의 `source_input_identity`를 함께 확인한다. 기존 결과 파일의 존재만으로 -이번 실행의 성공을 판단하지 않는다. 해석·로그·쓰기·readback·close·final 교체 실패에서는 기존 -최종 HDF5를 보존한다. +| 결과 | Shape·의미 | +| --- | --- | +| frame nodal/displacement, reaction, residual | [N,3]; U, constrained projection RF, full R는 별도 | +| frame solid/stress, solid/strain | [E,8,6]; global Cauchy S11/S22/S33/S12/S13/S23, infinitesimal 또는 Green strain의 tensor shear | +| dynamic nodal/velocity, acceleration, algorithmic_acceleration | [N,3]; v, physical a, auxiliary A | +| dynamic energy/work/balance·linear/angular momentum | 같은 full pair의 RN64; balance=T+U-T0-U0-W, W는 endpoint force 사다리꼴 work | +| /steps/Step-1/eigen/modes, frequencies, vectors | eigenvalue와 cycles/time 구분; vectors [modes,N,3], phi^T M phi=1 | +| eigen/verification/pairs, eta_gram, max_eta_orth | 반환한 모든 pair의 residual·normalization·직교 검증량 | -입력은 single Part/identity Instance의 Solid-only `C3D8`, `SOLID SECTION`, 상수 등방성 -`ELASTIC`을 사용한다. Frequency와 동해석에는 양의 `DENSITY`가 필요하다. 실제 BC/CLOAD는 -DOF1–3이다. 승인된 exact-zero 회전 BC4–6만 source 경고와 no-op으로 처리하며, 비영 회전 -BC와 값0을 포함한 모든 회전 CLOAD는 거부한다. Unsupported 의미를 기본값으로 흡수하지 않는다. +Strain은 실제 point kinematics이며 평균 strain으로 바꾸지 않는다. Cauchy stress의 +isotropic 항이 모든 점에서 같은 pressure라는 뜻도 아니다. Extrapolation/절점 평균은 없다. -정적 해석은 지정 변위·집중하중, 비선형은 full Newton을 사용한다. 동해석은 fixed -`DYNAMIC,DIRECT` schedule, 영 초기 변위·속도와 영 지정 BC를 사용하며 CLOAD의 -`TABULAR` step-time relative amplitude·선형 보간·끝 값 유지를 지원한다. Frequency의 원본 -LANCZOS 표기는 보존하지만 내부 해법은 generalized MKL FEAST다. 상세 subset과 실패 의미는 -[I/O 계약](io.md), field·shape는 [PRD017](PRD.md#fem-req-hex8-017--hdf5-계약)을 따른다. +Reference/hexa의5 INP·8 CSV와 hexa_freq.txt는 read-only다. 442nodes/300elements, +E=2.1e11,nu=.3,rho=7850, Step-1이다. Static DIRECT h=.1/T=1의 Increment10에서 U/RF/S를 +각각 blocking family로 비교한다. U/RF 전체442 inventory 뒤 RF만 실제 constrained 성분으로 +투영하며 free RF와 FESA free residual을 비교하지 않는다. Stress는300×8×6 전부다. +Dynamic h=.1/T=10의101 frames 각각442×3 U family이며 Amp-1=(0,0),(.1,1),(10,1)이다. +Frequency TXT의 Mode1..10 Value=lambda를 eigen/modes.eigenvalue와 직접 비교한다. +Freq를 lambda로 변환하거나 mode를 근접 재매칭하지 않는다. -## 결과와 다른 기능 개발의 참조점 +Key는 case/step/increment/instance/source node 또는 element/IntPt/component다. +IntPt 순서는 `---,+--,-+-,++-,--+,+-+,-++,+++`이며 node 순서와3/4·7/8이 다르다. +Missing/extra/duplicate/nonfinite/schema/mass 오류는 tolerance 전에 실패한다. S=max|reference|, +near-zero band/error limit .01S, 일반 relative .05, family RMS/S .01, S=0 exact-zero이며 +Shell eigen의5% RMS 예외는 적용하지 않는다. Coordinate는 reference 위치다. -Nodal 결과는 `N×3`, 적분점 stress/strain은 `E×8×6`이다. Source node/element/IntPt identity를 -보존하고 절점 평균·외삽을 하지 않는다. Stress는 global Cauchy, strain은 선형 infinitesimal -또는 비선형 Green–Lagrange이며 shear 성분은 tensor다. 반력과 전체 residual은 구분한다. -Frequency는 modes/vectors와 모든 반환 pair의 검증량을 별도 eigen 경로에 저장한다. +## 실제 코드와 수명 -HHT는 변위·속도·physical a·algorithmic A와 force·energy·history를 normalized high+low로 -유지한다. 공식 Float64는 전체 물리량의 RN64 observable이며 low를 별도 영속 field로 내보내지 -않는다. 출력 배열만으로 엄격한 내부 gate를 다시 계산해 같은 판정을 기대하지 않는다. -Restart는 지원하지 않는다. [정밀도 정식화](precision-formulation.md)는 같은 gradient의 -내력·미분, 산술 범위와 반올림 의미를 다음 개발에 전달한다. +[Hex8Element](../../include/fesa/elements/hex8_element.h)의 ComputeStiffness/ComputeMass, +EvaluateLinear/EvaluateNonlinear 및 high+low 대응 함수가 local response를 제공한다. +[기본 kernel](../../src/fesa/elements/hex8_element.cpp), +[paired kernel](../../src/fesa/elements/hex8_high_low.cpp), +[형상 인증](../../src/fesa/elements/hex8_geometry.cpp)은 immutable reference cache와 독립 trial을 사용한다. +[HighLow arithmetic](../../src/fesa/math/high_low_arithmetic.h)은 RN·FTZ/DAZ 환경과 지원 product +범위를 검사하고 unsupported underflow/overflow를 실패로 전파한다. Universal correctly-rounded +106-bit 보장은 아니다. Reduction 순서를 바꾸는 최적화도 수치 변경이다. -[정식화](formulation.md)는 K/M·접선·형상 인증·물리량의 기준이다. -[수치 기준](numeric-controls.md)은 엄격한 내부 gate와 외부 tolerance를 구분한다. -[원본 mapping](reference-model.md)은 case/frame/source identity·point 순서·RF projection을 -소유한다. 독립 평가의 범위는 [수치 검토](numerical-review.md)와 [물리 검토](physics-review.md), -실패와 수정 근거는 [lessons](lessons.md)에 보존한다. -원본 고유치 불일치의 [질량·요소 설정 조사](reference-mass-investigation.md)는 공식 -Abaqus row-sum mass 설명과 별도 K/M 분리 계산을 기록한다. Mean K+lumped M의 -수치 재현은 채택 전 연구 이력이다. 현재 [HEX8-ADR-010](ADR.md)의 production 변경본은 -[별도 새 실행](lumped-mass-adoption.md#원본-비교)으로 원본5개 비교 PASS를 확인했다. +Domain이 정의를 소유하고 DofManager가3N numbering/scatter를 소유한다. Stable local contribution을 +ordered assembly한 뒤 [Solid static](../../src/fesa/analysis/solid_static_procedure.cpp), +[frequency](../../src/fesa/analysis/solid_frequency_procedure.cpp), +[SolidHhtDynamicProcedureExecutor](../../src/fesa/analysis/solid_hht_dynamic_procedure.cpp)가 typed state를 +만든다. [SolidDynamicAnalysisState](../../include/fesa/analysis/solid_dynamic_analysis_state.h)의 +accepted full pairs가 다음 predictor의 원본이다. Domain은 view보다, 호출자 adapter는 Execute보다 +오래 살아야 한다. [Solid writer](../../src/fesa/io/hdf5/solid_hdf5_results_writer.cpp)는 완결 결과를 +write/close/reopen/self-check 후 atomic finalize하며 실패 candidate는 history와 기존 final을 보존한다. -## 적용 한계 +## 수치 의미와 검증 한계 -체적 projection의 conditioning·안정성과 남은 굽힘 shear locking을 검증하고, -다른 요소 formulation으로 자동 대체하지 않는다. Warped geometry는 보수적으로 cell 전체의 Jacobian 양성을 인증하며 -uncertain geometry/trial도 실패한다. StVK 선택과 입력 호환성은 외부 solver의 내부 재료·체적 -처리·시간 알고리즘 동등성을 보증하지 않는다. +Solid HHT physical residual r=Ma+f-F는 모든 원래 free 성분에서 +`|r_i|/(|Ma_i|+|f_i|+|F_i|)<=1e-10`, zero scale exact-zero다. Weighted 식과 +`(1+alpha)r_new-alpha*r_old`의 identity·update는 uncancelled scale의1e-12이며 old residual을 +0으로 치환하지 않는다. q/v/a/A fresh correction은 h와 reference length로 무차원화해1e-10, +증분당100 corrections를 유지한다. Geometry/recovery/finite/gate를 모두 통과한 trial만 commit한다. -Reduced/hybrid/incompatible·20절점 요소, 소성·contact, mixed Shell–Solid mesh, 압력·체적력, -시간변화 지정 BC·비영 초기 상태, adaptive/explicit dynamics와 restart는 범위 밖이다. -한 원본 U의 일치만으로 physical a·에너지·일반 mesh나 장시간 정확성을 검증했다고 주장하지 않는다. +과거 consistent mass의 modal7/10 FAIL·최대20.2513%와 Python collection5 오류는 당시 이력이다. +Lumped 변경본의 새 원본5개 PASS와 후속 재대조가 이를 대체하는 해당 범위 근거이며 과거 전체787의 +784 PASS/2 FAIL/1 SKIP이나 전체789/802를 새 전체 green으로 합산하지 않는다. + +Reduced/hybrid/incompatible/20절점, plasticity/contact, mixed shell-solid, pressure/body load, +시간변화 BC·비영 초기상태, adaptive/explicit/restart는 제외한다. Mean-volume의 conditioning· +warped stability·남은 bending shear locking, 임의 큰 변형/mesh/시간간격은 일반 보증 범위 밖이다. +원본 U 일치만으로 physical a·장시간 에너지·전체 시간수렴을 검증했다고 주장하지 않는다. +최적화 후 최종 source의 전체 MSVC Debug build/CTest·필수 원본·독립 물리 확인이 남는다. diff --git a/docs/hht-implicit-dynamics/README.md b/docs/hht-implicit-dynamics/README.md index f1949dc..16fd28e 100644 --- a/docs/hht-implicit-dynamics/README.md +++ b/docs/hht-implicit-dynamics/README.md @@ -1,70 +1,129 @@ # HHT implicit dynamics -## 목적과 현재 상태 +## 범위와 현재 상태 -2026-10-11 [HHT-ADR-012](ADR.md)에 따라 nodal lumped kinetic mass로 변경한다. -변경본의 관성·convective 항·접선·state/HDF5 관련 Debug 검사38개와 Python 비교기137개가 -통과했고, 같은 production 소스의 Release 원본 U 101-frame 비교 PASS·UR 경고200건을 -확인했다. 독립 수치·물리 검토는 bounded PASS다. [채택 보고서](../hex8-structural-analysis/lumped-mass-adoption.md)에 -검증 구성과 한계를 기록한다. 새 전체 Debug CTest789개는 자연 종료했다(native8: -784 PASS·4 FAIL·1 SKIP). Stale Hex8 test 두 개는 수정 후 공식 focused 검사에서 PASS다. -이 실행 당시 C08a 시간 정확도 FAIL·C08b 새 Newton 회전 예외 및 C04a SKIP이 남았다. -2026-10-12 사용자 요청으로 [두 시작점 정책](newton-start-policy.md)을 구현했다. 관련37개 -Debug 회귀와 독립 수치 검토가 완료됐다. 전체802 CTest는 제외 없이 자연 종료했다 -(11384.61초·native8:799 PASS·C08 정확도 FAIL2·기존 C04a SKIP1). 실제 C08b의5개 grid와 -새65-frame runtime 회귀에서 회전 예외가 해소됐으며 fresh 원본 U101 families PASS· -UR 경고200건과 독립 kinetic/balance 대조를 확인했다. Source·원본·binary identity는 -검증 전후 일치한다. Runtime 해결을 시간 정확도 해결로 해석하지 않는다. -다음 기존 consistent 구현의 이력과 원본 변위 통과를 현재 전체 검증으로 승계하지 않는다. 실제 shell의 -C08a/C08b 시간수렴 실패는 미해결이다. 구현됨과 기능 검증 완료를 구분한다. +MITC4 shell의 유한회전 기하비선형 동해석이다. S4/S4R은 FESA-MITC4로 해석하며 +외부 solver 내부 알고리즘과의 동등성을 뜻하지 않는다. 현재 채택 경로는 +**nodal-lumped-kinetic 질량, reduced-coordinate HHT, 초기 null의 고정 직교 보완기저, +shell schema v2**다. 과거 consistent 질량·full-coordinate v1 근거를 변경본 통과로 승계하지 않는다. -## 계약과 사용법 +2026-10-13 기록에서 ADR-018의 실제 C09와 공식 Release C08a 7-grid는 통과했다. +최신 전체 Debug는 856개 중 44개 PASS 후 사용자 중단됐고 Release C08b도 중단됐다. +당시 원본 Release 해석은 증분99·t=9.9까지 accepted 로그만 남아 HDF5 비교가 불가능했다. +사용자 중단 exit -1은 수치 FAIL이나 PASS가 아니다. 이후 2026-10-14 성능 baseline은 +원본을6372.325621초/native0으로 완료하고 schema v2·729nodes/101frames를 확인했다. +9-node U blocking 비교는 PASS(최대 relative RMS .0022824245), UR은 경고200건이었다. +이는 baseline source의 결과다. 최신 최적화 source의 새 원본 비교·C08b·전체 회귀·독립 +전체 물리 판정은 남아 있으며 전체 green이 아니다. [성능 요약](../calculation-performance/README.md)을 함께 본다. -2026-10-12 후속 [HHT-ADR-014](ADR.md)로 P 판정·C08b 최종 finer grid와 reduced shell -HHT/schema v2 구현을 승인받았다. 실제 채택식은 -[축소 좌표 정식화](formulation-reduced-coordinate.md), -[carried-A arithmetic/noise](formulation-carried-a-noise.md), -[schema v2 상세](io-reduced-coordinate.md)를 따른다. 현재 구현과 검증은 진행 중이며 -기존 v1 결과·실패 이력을 변경본 통과로 승계하지 않는다. +## 채택 방법과 산술 의미 -- [PRD](PRD.md)·[ADR](ADR.md)·[요구사항](requirements.md): 범위·미해결·현재 checklist. -- [정식화](formulation.md), [유한회전 관성](formulation-inertia.md), - [가속도 복구 후보](formulation-acceleration-recovery.md): 채택식과 미채택 후보 구분. -- [I/O](io-contract.md), [reference 계약](reference-model.md), - [전체 변위 비교표](displacement-comparison-tables.md). -- [수치 기준](numerical-controls.md), [검증 사례](verification-cases.md), - [수학 검산](numerical-review.md#numerical-review), [연구](research.md#research). -- [구현 검토·실패·수정](implementation-numerical-review.md), [물리 평가](physics-evaluation.md). -- [Consistent/lumped 질량 비교 실험](mass-comparison.md): 채택 전 private 비교 이력과 후속 승인; production 재검증과 구별. -- [Newton 회전 실패 원인·해결 후보](newton-rotation-investigation.md): 변경 전 moving-null 접선 상쇄의 독립 대조와 private 후보 실험. -- [두 시작점 정책의 구현·검증](newton-start-policy.md): HHT-ADR-013 실제 정책·시행착오·현재 evidence·적용 한계. C08 시간 정확도와 구분. -- [시간 정확도·P 감소 실패의 해결 후보 조사](research.md#temporal-remediation-research): 축소 좌표·속도 수준 DAE 적분·시간 해상도·합산의 조사와 채택 경계. Solver 변경 또는 실패 폐쇄를 뜻하지 않는다. -- [시간 정확도·P 후속 검증](temporal-remediation.md): 소형 DAE 독립 검산, 실제 finer-grid와 carried-A private 산술 후보, P strict-decrease 계약 문제. 기존 C08 FAIL과 미채택 알고리즘을 구분한다. -- [Reduced C08 구현](implementation-c08-reduced.md): 실제 controller·N7·전체 산술 이력 및 좌표 증분 누적의 경계. -- [C08a 추가 refinement 결정](c08a-refinement-proposal.md): HHT-ADR-015로 승인된 두 변경과 승인 전 진단 evidence. 변경본 공식 검증은 별도로 수행한다. -- [N3 좌표 표현 결정](c08-n3-coordinate-representation-proposal.md): HHT-ADR-016으로 승인된 exact pair 증분 검사와 RN-even 저장 검사. 승인과 변경본 검증 완료를 구분한다. -- [병진 유지 Newton 명세](c09-channel-newton-proposal.md), [독립 검토와 N7 대응](numerical-review-channel-newton.md): HHT-ADR-017로 승인된 제한 보정·부분 행렬 N2-L 검사·full-model defect 보존. [C09 산술 진단](c09-newton-rounding-diagnostic.md)의 endpoint 존재증거와 자연 trajectory 검증을 구분한다. -- [Channel Newton 구현과 실행 기록](implementation-channel-newton.md): private helper/자연 proper-Q 진단과 configured 검증의 범위를 구분한다. -- [유한회전 공변성 실패 진단](channel-newton-covariance-diagnostic.md), [초기 null 직교 보완공간 제안](fixed-null-basis-proposal.md): 실제 selector recurrence 반례와 HHT-ADR-018로 승인된 basis/integrator 변경의 경계. -- [고정 null 기저 상세 정식화](formulation-fixed-null-basis.md), [독립 수치 검토](numerical-review-fixed-null-basis.md): sparse projection/lift, 혼합 부분구속 chart, augmented scaled operator, 초기 상태와 CA/N7의 구현 계약. 정적 수식 검토와 변경본 실행 검증은 별도다. -- [고정 null 기저 구현과 실행 기록](implementation-fixed-null-basis.md): 실제 scaled solve, basis 계수 오차 반경, global 좌표 반복 감지와 현재 검증의 범위. -- [고정 null 기저 물리 평가](physics-evaluation-fixed-null-basis.md): 새 C09의 실제 검증 범위, 강제 강체 병진의 독립 한계 계산과 reference 물리 검산의 진행 상태. -- [사용자 중단 시점 비교](interrupted-validation-comparison.md): Debug44개 완료와 Release 요약 일치, 원본99증분의 수렴 로그, 현재 HDF5 부재로 인한 Abaqus 비교 한계 및 후속 실행 순서. +[기본 정식화](formulation.md), [관성](formulation-inertia.md), +[축소 좌표](formulation-reduced-coordinate.md), [고정 null 기저](formulation-fixed-null-basis.md)가 +수식의 상세 원본이다. 초기 null과 실제 free 공간의 교집합에서 고정 sparse 열 Lp/Lz를 +만들고 coupled graph root를 풀어 full `q=Q(p,t)`를 재구성한다. v와 physical a는 Q의 +chain rule로 복원한다. 부분 회전구속을 full clamp로 바꾸거나 모든 node에 동일 reduced +차원을 강제하지 않는다. Fixed patch 밖에서 검증된 history transport가 없으면 실패한다. -환경·명령은 [operations](../operations.md)를 따른다. I/O의 지원 `*DYNAMIC, DIRECT` subset과 고정 HHT 계수, -출력의 물리적 가속도와 보조 acceleration 구분을 확인한다. +HHT 계수는 `alpha=-.05,beta=.275625,gamma=.55`다. Private p/vp/ap/Ar가 적분 이력이며 +`Ar_n=(1+alpha)ap_n-alpha*ap_(n-1)`다. 공개 full `A_n=(1+alpha)a_n-alpha*a_(n-1)`는 +**full-chart 진단용 filter combination**이고 full q/v의 predictor driver가 아니다. +Frame0은 `q0=v0=0,A0=a0`이며 full 초기평형·hidden consistency를 만족해야 한다. +공개 A 또는 Qp*Ar로 private history나 restart를 구성할 수 없다. -## 재사용 Handoff +관성력 `I=M(q)a+c(q,v)`, 접선, 에너지·운동량은 같은 nodal kinetic measure에서 계산한다. +Lumped는 회전 block의 scalar diagonal 치환이 아니다. Epsilon inertia로 null을 없애지 않는다. +Primitive hidden-gradient authority, tiny director increment와 coefficient-first inertia contraction은 +큰 병진과 작은 회전의 소실을 줄이는 구현이다. Force·tangent·recovery는 같은 state/energy를 +사용한다. [Carried-A 산술](formulation-carried-a-noise.md)은 noise indicator의 범위를, +[가속도 복구 후보](formulation-acceleration-recovery.md)는 채택 경로와 다른 후보를 설명한다. -Eigen의 기존 nodal block lumped mass는 유지하고 HHT도 동일한 scalar moments의 nodal kinetic measure를 사용한다. HHT의 회전 의존 M·convective force·접선과 운동량은 같은 measure로 계산하며 scalar diagonal 치환은 하지 않는다. Total rotation-vector -chart의 generalized moment와 spatial moment도 다르다. Physical a와 algorithmic A를 바꾸어 -쓰지 않으며 moving-null 제약과 동적·대수 초기평형을 유지한다. 같은 trial에서 full residual, -inertia와 tangent를 계산하고 실패 candidate가 accepted history를 변경하지 않게 한다. +## 입력·출력·reference 계약 -## 실패·시행착오·다음 작업 +Single Part/identity Instance, homogeneous centered shell, 상수 isotropic elastic material과 +양의 DENSITY, NLGEOM=YES인 단일 `*DYNAMIC, DIRECT`를 지원한다. INC 기본값은100이며 +양의 uint32 증분 상한이다. h<=T이고 double(N)*h==T, N<=INC를 요구한다. h/T/INC는 정수 증분 수와 binary64 +n*h의 exact schedule로 검증한다. 영 BC·영 초기 q/v·일정 global 병진 CLOAD만 허용한다. +사용자 계수, adaptive/explicit, amplitude/follower/분포하중, 회전 CLOAD, 비영/시간변화 BC, +비영 초기조건, restart는 제외한다. 허용된 `*RESTART, WRITE, FREQUENCY=0`은 warning no-op이다. +CLI·lease·공통 identity/비교 정책은 [solver 공통 요약](../solver-core/README.md)을 따른다. -C08 두 실패는 열해석 전후 전체617개 회귀에서도 baseline metric과 동일했다. -가속도 복구 후보는 아직 채택하지 않았다. C09–C11의 잔여 coverage와 전체 physics 완료도 -남아 있다. 굽힘 단면력의 두께 계수 `M=t^3 C kappa/12` 수정은14 focused tests 및 원본 -HDF5 대조의 별도 evidence이며 동해석 전체의 완료를 뜻하지 않는다. -과거475 PASS/1 SKIP의 제외 실행과 최신 전체 회귀를 합치지 않는다. +Schema identity는 `(hht-implicit-dynamics,hht-implicit-dynamics,2)`다. +`/metadata::time_integration_formulation`은 +`reduced-coordinate-HHT-with-physical-rate-reconstruction`, +`mass_formulation=nodal-lumped-kinetic`, +`acceleration_convention=physical-endpoint-and-auxiliary-separated`다. +모든 result dataset version도 2이며 A의 quantity_semantics는 +`full-chart-HHT-filter-combination-not-predictor-driver`다. 잘못된 marker·혼합 version·mass· +inventory·nonfinite는 dynamic-output-schema 실패다. Historical v1 reader branch는 +과거 full-coordinate 결과만 읽으며 marker를 보충하거나 v2로 재표시하지 않는다. + +각 `/steps/Step-1/frames/`의 주요 F64 little-endian 결과는 다음과 같다. + +| 상대 경로 | Shape와 의미 | +| --- | --- | +| nodal/displacement, velocity, acceleration, algorithmic_acceleration | [N,6]; translation/global total rotation-vector chart의 q/v/physical a/public A | +| nodal/angular_velocity, angular_acceleration | [N,3]; Jl*phidot 및 Jl*phiddot+DJl[phidot]phidot | +| nodal/triad, director | [N,3,3], [N,3] | +| nodal/generalized_inertia_force, generalized_internal_force, generalized_external_force, generalized_residual, generalized_reaction | [N,6]; residual=I+f-F, generalized reaction=constrained projection | +| nodal/reaction | [N,6]; support-on-structure spatial RF/RM, moment는 Jl^-T 변환 | +| element/shell/local_frame, generalized_strain, section_resultant, stress | [E,4,3,3], [E,4,8], [E,4,8], [E,4,3,3]; stress는 bottom/middle/top × S11/S22/S12 | +| global/energy, global/equilibrium | [5] kinetic/physical/drill/work/defect, [6] 관성 포함 force/moment balance | + +Row는 model source inventory와 결합한다. Generalized moment와 spatial moment, physical a와 +A, drilling force와 physical stress를 혼합하지 않는다. 영 BC는 q/v/a/A exact zero다. +일정 외력의 work는 `F*^T(qn-q0)`, defect는 `T+Uphysical+Udrill-E0-W`다. +Momentum·hidden 진단 전체가 HDF5 필수 dataset인 것은 아니다. + +Reference는 reference/shellNL-dyn-meshfine의 INP와 displacements CSV다. 전체729-node/ +101-frame identity·finite를 먼저 확인한 뒤 고정9-node subset으로 투영한다. Instance/node/ +Step-1/increment0..100으로 join하며 CSV decimal n/10과 binary double(n)*double(.1)을 각각 +검증한다. U는 displacement 앞3성분, UR은 뒤3성분이다. Frame별27 scalars의 U blocking· +UR warning-only 총202 families다. S=max|reference|, near-zero band/error limit .01S, +일반 상대오차 .05, family RMS/S .01, S=0 exact-zero다. Warning-only여도 schema/identity/ +nonfinite 오류는 blocking이다. CSV에는 V/a/A/energy가 없어 변위 일치로 이들을 검증할 수 없다. + +## 코드 흐름과 수명 + +[HhtDynamicProcedureExecutor::Execute](../../src/fesa/analysis/hht_dynamic_procedure.cpp)는 +[ExecuteReducedHht](../../src/fesa/analysis/hht_reduced_procedure.cpp)로 연결된다. +[FixedChart/FixedBasisColumn](../../src/fesa/analysis/hht_reduced_internal.h)과 +[BuildFixedChart·SolveEmbeddingRoot·rate/augmented operators](../../src/fesa/analysis/hht_reduced_operators.cpp)는 +analysis-private다. Sparse support가 projection/lift authority이며 DOF label만으로 단일 +성분 injection을 가정하지 않는다. Domain은 non-owning AnalysisModel보다 오래 살아야 하고 +호출자 소유 solver/parallel adapter는 Execute 동안 유효해야 한다. + +Private chart/history와 [DynamicAnalysisState](../../include/fesa/analysis/dynamic_analysis_state.h)의 +full accepted frame은 같은 acceptance 뒤 commit한다. Full residual·recovery·finite·constraint +검증 전에 일부 이력을 commit하지 않는다. [DynamicHdf5ResultsWriter](../../src/fesa/io/hdf5/dynamic_hdf5_results_writer.cpp)는 +완결 이력을 write/close/reopen/self-check한 뒤 final을 교체한다. 실패 candidate는 기존 final을 +보존한다. Accepted history는 실행 중 메모리에 있어 강제 종료 로그만으로 복구되지 않는다. + +## 검증 기준·교훈·남은 한계 + +N2 full force/moment·q/v/a/A correction은 채널별 1e-10, 실제 scaled solve backward error는 +1e-12다. N3 update는 상쇄 전 same-unit scale의 1e-12와 exact-zero branch를 유지한다. +Pair increment의 exact expansion 검사와 RN-even 저장 검사는 별도다. Hidden 위치 조건·rank/ +regularity를 유지하되 hidden rate 진단을 임의 Newton gate로 바꾸지 않는다. 일반 dynamic +operator에 대칭성을 강제하지 않는다. 일반 nonlinear HHT energy에 매 frame 보존·감소를 +요구하거나 numerical dissipation을 physical damping으로 기록하지 않는다. + +시간 검증은 q/v/physical a의 마지막 두 refinement 감소·차수 >=1.8 및 finest normalized +error <=1e-4를 요구한다. N7 read-only linear/nonlinear defect solves와 arithmetic indicator는 +100배 separation을 확인하며 state polishing이 아니다. 원본의 성긴 dt/T1≈7.4567에서 +변위 일치와 시간 정확도를 구분한다. + +과거 전체617의 HHT2 FAIL/1 SKIP, lumped 전체789의784 PASS/4 FAIL/1 SKIP, 후속802의 +799 PASS/2 FAIL/1 SKIP은 각 당시 source 이력이다. 초기 C08b runtime 예외는 두 시작점 +정책으로 해소됐고 후속 C09/C08a7 통과와 구분한다. 최신 Debug h=1/64 완료 요약의 이전 +Release 일치는 전체 raw state bitwise나 전체 시간수렴 증거가 아니다. 원본 accepted residual +최대 병진1.889238010e-15·회전1.452384011e-15도 Abaqus 변위 오차가 아니다. +C08b finer-grid·최신 최적화 source의 원본 HDF5 비교·전체 회귀·전체 물리 closure가 남는다. + +## 보존한 과거 수식과 연구의 위치 + +| 원본 | 현재 해석 | +| --- | --- | +| [2026-10-04 본식](formulation-historical-docs-cleanup-20261004.md), [관성 원본](formulation-inertia-historical-docs-cleanup-20261004.md) | 당시 consistent 정책의 수식·검토 이력이다. 현재 lumped/reduced/fixed-null 정책이 우선한다. | +| [C08b Newton 연구](formulation-c08b-newton-research-20261012.md), [DAE 연구](formulation-dae-research-20261012.md) | 원인·후보 조사이며 모든 Newton/DAE 후보의 채택을 뜻하지 않는다. | +| [운동량 연구](formulation-momentum-research-20261012.md), [graph certificate 초안](formulation-graph-certificate-draft-20261012.md) | 불변량·controller/certificate 연구의 원본이다. 현재 acceptance나 엄밀한 전역 오차 보증을 자동 대체하지 않는다. | \ No newline at end of file diff --git a/docs/hht-implicit-dynamics/formulation-c08b-newton-research-20261012.md b/docs/hht-implicit-dynamics/formulation-c08b-newton-research-20261012.md new file mode 100644 index 0000000..c39422d --- /dev/null +++ b/docs/hht-implicit-dynamics/formulation-c08b-newton-research-20261012.md @@ -0,0 +1,118 @@ +# C08b Newton 잔차 재정식화 후보 + +상태: 연구 후보이며 production 채택·수치 정확도 승인이 아니다. 2026-10-12 formulation owner 작업은 이 문서만 소유한다. 질량·시간적분·내력·초기화·tolerance·원본을 바꾸지 않는다. 독립 numerical review와 실제 prototype 결과는 별도 owner가 소유한다. + +계약: [기존 정식화](../../docs/hht-implicit-dynamics/formulation.md), [관성·null 상세 §4](../../docs/hht-implicit-dynamics/formulation-inertia.md#4-mass-null과-초기-일관성), [ADR-010/012](../../docs/hht-implicit-dynamics/ADR.md). 실제 trial은 [analysis.json](analysis.json)에 있으며 아래 기전 설명은 그 수치를 바탕으로 한 조사 후보이다. + +## 1. 적용 가정과 보존량 + +우선 대상은 9 nodes, 54 DOFs가 모두 free인 C08b 평판 fixture이다. 절점 순서는 기존 source identity이며 각 node의 좌표는 `q_i=(u_x,u_y,u_z,phi_x,phi_y,phi_z)`다. 시간별 미지수는 total rotation chart의 `q`; `v(q),a(q),A(q)`는 기존 HHT/Newmark 종속량이다. Director는 `d=exp([phi]x)d0`, `B=D_phi d=-[d]x J_l`이며 `|phi|0`의 초기 director hemisphere와 + +\[ +R(d,\sigma)=R_{swing}(d;d_0)\exp([d_0]_\times\sigma),\qquad +\phi=\operatorname{Log}R +\] + +이다. `R_swing d0=d`이므로 d·시간 rate와 kinetic mapping은 σ와 무관하다. 이 frame의 local M_r는 대수 spin branch와 무관하지만 η에 따른 configuration dependence와 관성 곡률은 남는다. Existing principal rotation/swing/twist 범위를 통과해야 하며 η hemisphere 또는 Log branch가 바뀌면 silent rechart할 수 없다. 고정 generalized force를 이 chart로 옮길 때에는 원 covector를 `Q_p^T F`로 pullback한다. 임의의 spatial torque로 재해석하지 않는다. + +### 6.2 실제 보유 operator와 부족한 operator + +| 수식 operator | 현재 확인된 capability | Reduced exact full Newton의 gap | +| --- | --- | --- | +| g, Dg | Internal force와 K_int, 외력은 별도 owner | 기존 force/assembly 의미 보존하여 사용 가능 | +| D²g[v,v] | Optional `coordinate_direction`의 `force_directional_second`; U의3차 contraction | Mixed D²g[p,r]는 polarization으로 구할 수 있지만 비용·산술을 검토해야 함. D³g는 API에 없음 | +| Internal ψ, Dψ, D²ψ | `drilling_constraint`, gradient, Hessian에 **raw γ가 아닌** `k_de*S_i*gamma_ei`를 저장 | Shared node assembly·동일 unit n 확인 필요. Full ψ에는 external null work가 추가됨 | +| D³ψ 방향 contractions | Scalar Jet 내부 `mixed_second[j]`는 `D³scalar[e_j,v,v]`를 수송하지만 constraint용 반환 field에는 노출되지 않음 | 실제 scalar ψ에 대한 third contraction과 mixed polarization의 의미·finite 여부·독립 검산이 필요. Production API 추가는 미승인 | +| n, Dn, D²n[v,v] | `DynamicRotationKinematics`의 unit null, gradient, directional_second | Force가 있는 ψ의 D³n와 일반 mixed second contraction 공개 operator가 없음 | +| I, DqI, DvI, M | 기존 nonlinear inertia evaluation | Q·rate를 적용한 전체 chain rule와 DQ_p 항을 새 reduced assembly에서 연결해야 함 | +| Force의 시간미분 | 현재 C08a oracle는 Fdot/Fddot | Mixed-time third ψ에는 F'''까지 필요할 수 있음. 현 oracle를 F'''가 이미 있는 것으로 보고하지 않음 | + +일반적인 `psi=N^Tg`의 직접 미분은 + +\[ +D\psi[p]=(DN[p])^Tg+N^TDg[p], +\] +\[ +D^2\psi[p,r]=(D^2N[p,r])^Tg+(DN[p])^TDg[r] ++(DN[r])^TDg[p]+N^TD^2g[p,r], +\] +\[ +\begin{aligned} +D^3\psi[p,r,s]={}&(D^3N[p,r,s])^Tg ++\sum_{sym}(D^2N[p,r])^TDg[s]\\ +&+\sum_{sym}(DN[p])^TD^2g[r,s]+N^TD^3g[p,r,s]. +\end{aligned} +\] + +마지막 식의 각 `sum_sym`은 서로 다른3항의 합이다. 이 경로는 D³g, 즉 내부 energy의4차 미분까지 요구한다. 그러나 **현 shell의 정확 scalar identity로 더 낮은 차수 경로가 가능하다.** Source는 `n_i^T grad(U_phys)=0`, `Dgamma_ej[n_i]=delta_ij*S_i`, `S_i=1/|J_l^-1 d_i|`를 사용하여 + +\[ +\psi_i(q,t)=\sum_{e\ni i}k_{de}S_i(q)\gamma_{ei}(q)-n_i(q)^TF_i(t) +\] + +를 직접 평가한다. 이 identity와 assembled nodal null convention을 독립 검증하면 scalar ψ의3차 미분으로 충분하며 generic U의4차 tensor를 만들 필요가 없다. C08b의 F=0에서는 ψ의 내부 scalar 3차 contraction이 핵심 gap이다. API의 `drilling_constraint_gradient/Hessian`를 raw γ의 미분이라 오해하지 않는다. 원 ψ의 단순화는 내력에서 U_drill를 제거하는 근거가 아니다. + +F(t)가 q-independent이고 n은 q-only인 C08a convention에서는 + +\[ +\psi_{qt}[p]=-Dn[p]^TF',\quad +\psi_{qqt}[p,r]=-D^2n[p,r]^TF',\quad +\psi_{qtt}[p]=-Dn[p]^TF'',\quad \psi_{ttt}=-n^TF'''. +\] + +Pure q의 third 항에는 `-D³n^T F`도 필요하다. Constant public CLOAD에서는 F'/F''/F'''가0이지만 F가 nonzero이면 pure-q null 미분항은 사라지지 않는다. Synthetic time-dependent potential에는 위 force-only 단축식 대신 전체 ψ 미분을 쓴다. + +### 6.3 Implicit embedding 미분의 최소 인계 + +`tilde Q(p,t)=(Q(p,t),t)`로 time을 추가한 chart를 쓰면 pure/mixed derivatives를 같은 규칙으로 처리할 수 있다. `A=D tilde Q[a]`, `B=D tilde Q[b]`, `C=D tilde Q[c]`라 놓으면 대수 좌표의2차·3차 방향 미분은 + +\[ +G\,D^2z[a,b]=-D^2\psi[A,B], +\] +\[ +G\,D^3z[a,b,c]=-D^3\psi[A,B,C] +-\sum_{sym}D^2\psi[D^2\tilde Q[a,b],C]. +\] + +p/t의 affine identity 부분은2차 이상에서0이며 RHS는 이전 단계의 Q 미분을 포함한다. 이 규칙은 Q_pp, Q_pt, Q_tt와 δR에 필요한 Q_ppp/Q_ppt/Q_ptt를 제공한다. Dense global3·4차 tensor 전체를 요구하는 것은 아니지만, 실제 필요한 mixed directional contractions와 같은 G의 정확한 solve가 필요하다. Perturbed algebraic root solve를 사용한 FD reduced tangent는 **private diagnostic** 경로로 연구할 수 있다. 이는 production analytic δR의 capability gap을 닫거나 새 수치기준을 승인하지 않는다. + +부분 BC에서는 먼저 exact zero-constrained lift를 정의하고 실제 admissible null의 dimension을 정해야 한다. Constraint가 nodal null을 가르면 단순히 그 null의 constrained 성분을 삭제해서는 안 된다. p/z 수와 G 크기는 실제 rank와 함께 정하며 rank·pivot·chart 변경 규약을 정하지 않은 채 all-free5/node를 보편적으로 쓰지 않는다. Empty-null은 기존 full-coordinate 문제로 환원된다. + +이 후보가 C08b의 큰 physical-complement fixed-grid 오차를 고친다는 보장은 없다. Actual prototype에는 current5grids의 full q/v/physical-a 및 공간 rates, 초기/최대/최종 오차 위치, dynamic spectrum·mode amplitude·omega*h, 원 free E/reaction, hidden0/1/2, energy/P/L을 함께 비교하는 조건을 남긴다. 국소 제거의 null-rate 개선과 고주파 temporal resolution의 개선 여부를 별도로 판단해야 한다. diff --git a/docs/hht-implicit-dynamics/formulation-graph-certificate-draft-20261012.md b/docs/hht-implicit-dynamics/formulation-graph-certificate-draft-20261012.md new file mode 100644 index 0000000..09a6af8 --- /dev/null +++ b/docs/hht-implicit-dynamics/formulation-graph-certificate-draft-20261012.md @@ -0,0 +1,64 @@ +# ADR-018 graph BL/solve certificate controller draft + +Status: private design only. Shared test source is frozen while the configured +Debug focused run is active. + +## Scope + +Stored `ConstraintRowOperators::{gradient,hessian,time_gradient,third_directional_gradient}` +are exact binary64 inputs. The draft certifies only fixed-basis contraction and +linear graph-solve arithmetic. It does not certify AD/FE operator formation, +root branch sensitivity, or nonlinear history. + +## Test-local data + +`GraphArithmeticCertificate` should retain dense-small matrices/vectors: +`Ghat`, `P_hat`, `BG`, `BP`, `bhat`, `Bb`, `R`, `Hbar`, `Q`, `rbar`, `Bx`. +It is private to `hht_shell_physics_test.cpp`. + +For every graph row and basis column, replay source order: + +1. Iterate `row.gradient`, then `column.support`; match full DOF. +2. Product radius is `ProductRadius(C, 0, L, BL)`. +3. Reduce matching products in `RateSumRadius` source order. + +This yields stored `Ghat=C*Lz`, `P_hat=C*Lp`, and entrywise `BG/BP`. +The same replay builds RHS radii for `P*vp`, `P*ap`, Hessian/time contractions. +No zero-BL fallback is allowed. + +## Inverse action + +For each canonical unit RHS, use the existing graph solver and N2-L check to +obtain one stored column of `R`. Replay `I-Ghat*R` with product/sum radii to +make nonnegative `Hbar`. Require finite values and `thetaH=||Hbar||inf<1`. +Construct + +`Q[i,j] = abs(R[i,j]) + (abs(R)*Hbar*1)[i] / lower(1-thetaH)`. + +All bound additions/divisions use existing outward helpers. Failure of the +positive lower denominator or either theta is INCONCLUSIVE, not a radius reset. + +## Uncertain solve + +Replay `rhat=bhat-Ghat*xhat`; combine absolute residual and rounding into +`rbar`. With actual RHS bound `Bb`: + +`y = Q*(rbar + Bb + BG*abs(xhat))`, `A=Q*BG`, `thetaG=||A||inf`. + +Require `thetaG<1`; set + +`Bx[i] = y[i] + rowSum(A,i)*normInf(y)/lower(1-thetaG)`. + +Undo any actual rate scaling before using `Bx` in physical lifted radii. + +## Tests + +Add only after the current focused run closes: +- small chart with plane coefficient value zero / positive BL, proving BG/BP + remain nonzero after an omitted-BL mutation; +- 1x1 and 4x4 source-order graph replay, N2-L checked; +- one thetaH and one thetaG failure must return incomplete; +- use a known 4x4 perturbation from the independent 32-case probe as a + behavior oracle, without copying implementation equations as its oracle. + +No production API, tolerance, grid, or sparse global inverse is added. diff --git a/docs/hht-implicit-dynamics/formulation-historical-docs-cleanup-20261004.md b/docs/hht-implicit-dynamics/formulation-historical-docs-cleanup-20261004.md new file mode 100644 index 0000000..c1ec22a --- /dev/null +++ b/docs/hht-implicit-dynamics/formulation-historical-docs-cleanup-20261004.md @@ -0,0 +1,215 @@ +# HHT implicit dynamics 정식화 + +- 상태: `independently-reviewed-candidate; physics-and-validation-pending`. +- Owner: `formulation-agent`, 2026-09-22. 문서 gate 산출물이며 구현 승인이나 수치 검증 통과가 아니다. +- 기준: [프로젝트 지침](../../AGENTS.md), [제품 PRD](../PRD.md), [공통 ADR](../ADR.md#adr-028), [Feature PRD](PRD.md), [요구사항](requirements.md), [연구](research.md). +- 관성의 전개식·초기 일관성·정확도 근거는 [formulation-inertia](formulation-inertia.md)가 소유한다. 영속 schema, C++ 저장 구조와 tolerance는 정의하지 않는다. + +## 1. 결론과 적용 범위 + +**추천 후보는 유한회전 kinetic energy에서 유도한 관성력과, 물리적 가속도 `a` / 알고리즘 가속도 `A`를 분리하는 HHT 확장이다.** 일정 질량의 표준 HHT force weighting으로 정확히 환원한다. 단순히 `M(q)`를 기존 일정 질량 잔차에 대입하는 식은 추천하지 않는다. 이 차이는 [상세 §5](formulation-inertia.md#5-시간-정확도와-대안의-경계)에 유도한다. + +**사용자가 shell 속도 보간의 운동에너지를 그대로 적분하는 consistent mass를 선택했다.** 따라서 HHT 기본값과 이번 구현 범위는 consistent mass다. 같은 운동학의 scalar-moment nodal lumped 식은 비교용 이론 및 기존 eigen 회귀 참고이며 이번 HHT 구현 요구가 아니다. 선행 eigen 결과나 동적 reference와의 적합도로 선택한 것이 아니다. 유한회전 지원 범위를 작은 회전으로 축소하지 않는다. + +아래 HHT 확장과 `0+` 초기화는 FESA 채택 제안이다. 이번 consistent mass 선택이 다른 physics·알고리즘·공개 output 계약 전체의 승인을 의미하지 않는다. + +| 구분 | 정식화 경계 | +| --- | --- | +| 물리 | 초기 형상 기준 Total Lagrangian FESA-MITC4, 큰 변위·유한회전, 작은 탄성 변형률, 균질 등방 선형 탄성, 고정 두께 | +| 시간 | 단일 step, `DIRECT`, `h=0.1`, `T=10`, `t_n=n h`, 초기 frame 및 100 increments. `INC=1000`은 increment 상한 | +| 하중/구속 | `t=0+`부터 node `2`의 global 1–3 force 각각 `−100000`; 외곽 지정 DOF 1–6은 모든 시점에 0 | +| 초기값 | `q_0=v_0=0`; `a_0`는 동적 초기 평형·대수 일관성으로 구하며 `A_0=a_0` | +| 제외 | 물리적 damping, contact, 소성·손상, follower/분포하중, nodal moment 입력 확대, 임의 amplitude, 시간변화 구속, adaptive/cutback, multi-step/restart, 다른 요소 dynamics | + +원본 INP의 section-point 입력 `5`를 새 질량 또는 내력 quadrature 지정으로 해석하지 않는다. Abaqus 내부 요소·질량·회전·초기화와의 동등성은 목표가 아니다. + +## 2. 좌표·운동학·재료와 내력 + +절점 좌표 순서는 정확히 + +\[ +q_i=[u_x,u_y,u_z,\phi_X,\phi_Y,\phi_Z]_i^T,\quad v=\dot q,\quad a=\ddot q. +\] + +`u`는 global translation, `phi`는 **초기 형상과 고정 global basis에 대한 total rotation vector**다. 각 절점에서 + +\[ +R_i=\exp([\phi_i]_\times),\quad Q_i=R_iQ_i^0,\quad d_i=R_i d_i^0, +\quad \|\phi_i\|<\pi . +\] + +Newton correction은 `q←q+Δq`이고, orientation은 그 total `phi`에서 다시 평가한다. Incremental rotation을 별도로 누적하거나 accepted step마다 chart/reference를 재설정하지 않는다. 기존 principal chart, director opposition, swing/twist, 양의 Jacobian 및 polar factor 유효성 경계를 보존한다. 실패 trial을 clamp하거나 재정규화하여 통과시키지 않는다. + +\[ +x(\xi,\eta,\zeta;q)=\sum_i N_i(X_i+u_i+z d_i),\quad z=t\zeta/2, +\quad dV_0=J_0\,d\xi d\eta d\zeta . +\] + +`N_i`는 기존 bilinear MITC4 shape function이다. Interpolated director `ΣN_i d_i`를 단위화하지 않는다. 정확한 각속도와 각가속도는 + +\[ +\omega_i=J_l(\phi_i)v_{\phi i},\qquad +\dot\omega_i=J_l(\phi_i)a_{\phi i}+DJ_l(\phi_i)[v_{\phi i}]v_{\phi i}, +\] +\[ +\dot d_i=\omega_i\times d_i,\qquad +\ddot d_i=\dot\omega_i\times d_i+\omega_i\times(\omega_i\times d_i). +\] + +따라서 `v_phi`와 `a_phi`는 공간 각속도·각가속도가 아니다. `A_phi`는 이 물리 회복식에 넣지 않는다. `J_l`과 미분의 구현 가능한 정의는 [상세 §1](formulation-inertia.md#1-회전과-관성의-미분)에 있다. + +물리 내력은 기존 [비선형 정식화 §§6–13](../nonlinear-static-newton-raphson/formulation.md)를 따른다. Green–Lagrange strain의 MITC assumed shear와 fixed-reference local engineering strain +`ē=[E11,E22,2E12,2E13,2E23]`에 대해 + +\[ +U_{phys}=\frac12\int_{\Omega_0}\bar e^TC_5\bar e\,dV_0,\quad +C_5=\operatorname{diag}(C_{ps},(5/6)G I_2),\quad G=E/[2(1+\nu)], +\] +\[ +C_{ps}=\frac{E}{1-\nu^2} +\begin{bmatrix}1&\nu&0\\\nu&1&0\\0&0&(1-\nu)/2\end{bmatrix}. +\] + +Objective numerical drilling potential은 기존 polar-corotation / swing-twist angle `χ_ei`와 초기 고정 stiffness `k_de`를 그대로 사용한다: + +\[ +U_{drill}=\frac12\sum_{e,i}k_{de}\chi_{ei}(q)^2,\quad +f_{int}=\nabla_q(U_{phys}+U_{drill}),\quad K_{int}=\nabla_q^2(U_{phys}+U_{drill}). +\] + +Drilling stiffness는 물리적 회전 관성이 아니다. `U_phys`와 `U_drill`을 구별하여 에너지 evidence를 계산하고, drill stress/resultant를 만들지 않는다. 재료 내부변수·소성 update는 없다. 재사용 대상 [evaluator](../../src/fesa/elements/nonlinear_mitc4_shell.cpp)의 `PhysicalEnergy`, `DrillingEnergy`, `EvaluateInternalResidualAndTangent`도 이 구분에 대조한다. 현재 공개 equilibrium/recovery 결과는 `physical_strain_energy`만 노출하므로 drill energy evidence의 전달은 후속 구현 작업이며 현 API가 이를 이미 제공한다고 보지 않는다. + +## 3. 질량·관성·연속 평형 + +`B_i=D_phi d_i=−[d_i]_× J_l(phi_i)`이고 `C_ij^(k)=∫rho N_iN_j z^k dV_0`이다. 채택한 consistent `T_C`와 비교용 lumped `T_L`은 다음과 같다. + +\[ +T_C=\frac12\int_{\Omega_0}\rho\left|\sum_iN_i(v_{ui}+zB_iv_{\phi i})\right|^2dV_0, +\] +\[ +T_L=\frac12\sum_i\left(m_i|v_{ui}|^2+2s_i v_{ui}\cdot B_iv_{\phi i} ++j_i|B_iv_{\phi i}|^2\right),\quad +(m_i,s_i,j_i)=\sum_j(C_{ij}^{(0)},C_{ij}^{(1)},C_{ij}^{(2)}). +\] + +비교용 lumped 식은 scalar moment의 row sum 후 tensor를 재구성하며 global matrix row sum이 아니다. 이번 HHT에는 `T=T_C`, `M=M_C`를 사용하고 artificial drilling inertia는 허용하지 않는다. `T=½v^T M(q)v`의 질량행렬은 회전에 의존한다. 관성 covector는 + +\[ +\boxed{I(q,v,a)=\frac{d}{dt}\partial_vT-\partial_qT=M(q)a+c(q,v)}, +\qquad c_i=\sum_{j,k}\frac12(M_{ij,k}+M_{ik,j}-M_{jk,i})v_jv_k. +\] + +고정 구속을 제외한 모든 admissible `δq`에 대해 + +\[ +\delta q^T E=0,\quad E=I+f_{int}-F(t), +\qquad F(t)=F^\star\ (t\ge0+). +\] + +이는 parent `rho_0 ẍ=Div_0 P`, `P=F_def S`의 가상일 이산화다. 강형의 `F_def`는 deformation gradient이며 nodal force `F`와 구별한다. 물리적 damping은 0이다. Tangent에는 `DM·a`, convective force의 configuration/velocity 미분을 모두 포함한다. 구체적인 matrix block, quadrature, derivative action과 null 조건은 [상세 §§1–4](formulation-inertia.md)에 고정한다. + +## 4. 초기화와 HHT 시간적분 후보 + +음수 alpha 관례를 사용한다: + +\[ +-\frac13\le\alpha\le0,\quad \gamma=\frac12-\alpha,\quad +\beta=\frac14(1-\alpha)^2. +\] + +기본값은 `alpha=−0.05`, `beta=0.275625`, `gamma=0.55`다. [공개 기본값 근거](research.md#3-reference-입력의-공개-의미)와 [Sandia의 결합계수](https://www.sandia.gov/files/sierra/SM_Users_5_20/main/implicit/integration.html)를 따른다. `alpha=0`은 평균가속도 Newmark다. 이 범위는 일반 유한회전 문제의 무조건 안정성이나 큰 시간간격의 정확도를 보증하지 않는다. 별도 `beta/gamma` 입력을 승인한 의미도 아니다. + +**FESA 초기화 후보 계약:** frame 0은 `t=0+`, `q_0=v_0=0`, 전값 `F_0=F*`다. `M_ff(q_0)a_f0=F_f0−f_int,f(q_0)`와 [mass-null 일관성](formulation-inertia.md#4-mass-null과-초기-일관성)을 함께 풀어 `a_0`를 구한다. `A_0=a_0`, `g_0=f_int(q_0)−F_0`를 정의한다. `g_0=0` 또는 `a_0=0`을 임의 대입하지 않는다. 이는 공개 STEP 의미에 맞춘 FESA 계약 제안이며 Abaqus의 숨은 첫 history 생성 절차를 확인한 주장이 아니다. + +[Brüls–Arnold (2008), 식 (5)–(8)](https://orbi.uliege.be/bitstream/2268/27088/1/pa_BrulsArnold2008_TheGeneralizedAlphaSchemeAsALinearMultistepIntegrator.pdf)의 보조가속도 형식을 `alpha_m=0`, `alpha_f=−alpha`로 전문화한다. 아래 `a`는 물리적 좌표 가속도, `A`는 시간적분 보조변수다: + +\[ +\boxed{A_{n+1}=(1+\alpha)a_{n+1}-\alpha a_n}, +\] +\[ +q_{n+1}=q_n+h v_n+h^2[(1/2-\beta)A_n+\beta A_{n+1}], +\qquad v_{n+1}=v_n+h[(1-\gamma)A_n+\gamma A_{n+1}], +\] +\[ +\boxed{E_f(q_{n+1},v_{n+1},a_{n+1},t_{n+1})=0.} +\] + +같은 fixed-global chart의 `a_n`만 history로 사용한다. 정확도 적용 조건과 source의 singular-mass 한계는 상세 §5에 명시한다. Shell drilling DAE까지 증명되었다고 보지 않는다. + +Newton 미지수는 전체 좌표의 free 성분 `q_f,n+1`이다. `q_c=v_c=a_c=A_c=0`를 항상 유지한다. Predictor와 trial 종속량은 + +\[ +q_p=q_n+h v_n+h^2(1/2-\beta)A_n,\quad v_p=v_n+h(1-\gamma)A_n, +\] +\[ +A(q)=\frac{q-q_p}{\beta h^2},\quad +v(q)=v_p+\frac{\gamma}{\beta h}(q-q_p),\quad +a(q)=\frac{A(q)+\alpha a_n}{1+\alpha}. +\] + +동일 trial에서 `E`를 평가하고 매 반복 full tangent를 갱신한다: + +\[ +\boxed{K_{eff}p=D_qI[p]+\frac{\gamma}{\beta h}D_vI[p] ++\frac{M(q)p}{(1+\alpha)\beta h^2}+K_{int}p},\quad +(K_{eff})_{ff}\Delta q_f=-E_f,\quad\Delta q_c=0. +\] + +여기서 `D_qI`는 `v,a`를 고정한 편미분이다. 외력은 고정 global force이므로 `D_qF=0`이다. 관성 convective 항 때문에 `K_eff` 대칭을 일반적으로 가정하지 않는다. 모든 DOF가 구속되면 free solve는 비어 있고 full reaction을 회복한다. Singular mass만으로 모델을 거부하거나 epsilon mass를 추가하지 않으며, 유효 접선의 singularity·대수 regularity 실패는 별도로 진단한다. + +## 5. 잔차·반력·에너지의 구별 + +일정 `M`에서 `g=f_int−F`라 두면, 앞선 endpoint physical equilibrium `M a_n+g_n=0`을 이용하여 + +\[ +R_{HHT}:=M A_{n+1}+(1+\alpha)g_{n+1}-\alpha g_n +=(1+\alpha)E_{n+1}-\alpha E_n. +\] + +따라서 free 방정식은 표준 force-weighted HHT와 같다. **표준 HHT의 Newmark 가속도를 이 문서에서는 `A`라 부른다.** 이를 `a`로 오인하면 출력·반력이 달라진다. 구성 의존 질량에는 위 `M A+weighted g` 식을 그대로 적용하지 않는다. 추천 후보의 Newton residual은 endpoint `E_f`이며, HHT filter 결함 `A_{n+1}−(1+alpha)a_{n+1}+alpha a_n`은 별도 운동학 evidence다. + +구속 selector `C_u,C_phi`에 대한 endpoint 반력은 + +\[ +F_i^{react}=C_{u,i}E_{u,i},\quad m_{\phi,i}^{react}=C_{\phi,i}E_{\phi,i},\quad +M_i^{react}=J_l(\phi_i)^{-T}m_{\phi,i}^{react}. +\] + +부호는 structure에 작용하는 support force/moment다. Free `E_f`는 평형 evidence이고 반력이 아니다. `R_HHT,c`는 이전 반력이 섞인 알고리즘량이며 endpoint 반력으로 저장하면 안 된다. Moment는 `m_phi·δphi=M_spatial·δtheta`에 의해 변환한다. Numerical drill의 force/work는 물리적 section stress와 분리한다. + +연속계의 에너지 관계는 `d(T+U_phys+U_drill)/dt=v^TF`다. 일정 dead force와 고정 경계에서는 + +\[ +W_{0\to n}=F^{\star T}(q_n-q_0),\quad +\Delta\mathcal E_n=T(q_n,v_n)+U_{phys}(q_n)+U_{drill}(q_n)-\mathcal E_0-W_{0\to n}. +\] + +`ΔE_n`은 이산 에너지 결함이며 물리 damping energy가 아니다. HHT의 일반 비선형 문제에서 매 frame 단조 감소나 정확한 momentum 보존을 요구하지 않는다. 무감쇠 선형 `alpha=0`의 보존성, 음수 alpha의 선형 고주파 소산과 비선형 work/energy 수렴은 따로 검증한다. + +## 6. 증분·실패·회복 순서 + +1. 승인 subset, source identity, 재료·geometry·quadrature 및 고정 구속을 확인한다. Consistent mass의 moment·rank/positivity 조건과 초기 대수 일관성을 검사한다. +2. 초기 상태 및 `F_0`, `a_0`, `A_0`를 완성하여 frame 0을 검증한다. 초기화 실패를 zero acceleration으로 대체하지 않는다. +3. `t_n=n h`의 직전 committed `q,v,a,A`에서 predictor를 만들고, 고정 구속을 적용한다. `INC`와 정확한 종료 increment를 검사한다. +4. 각 Newton trial에서 total rotation, 내력·tangent, 관성·tangent와 `E`를 같은 state로 계산하고 free correction을 푼다. 병진/회전 correction 및 force/moment residual을 각각 scale-aware로 검사한다. 수치 한계·iteration 상한은 Numerical Review/I/O 소유다. +5. 수렴 후 같은 trial에서 physical acceleration, triad/director, endpoint reaction, 물리적 strain/stress/resultant, 에너지 및 null-constraint evidence를 회복·검증한다. 고정 reference frame과 element Gauss/section-point identity는 기존 정적 회복을 보존하며 nodal averaging은 하지 않는다. +6. `time,increment,q,v,a,A,orientation,forces,recovery,evidence`가 한 identity를 이루는 candidate만 원자적으로 commit한다. 모든 101 accepted frames를 보존한다. Newton iteration은 time frame이 아니다. +7. 비수렴·invalid chart/geometry·nonfinite·선형 solve·회복·출력 실패는 trial을 폐기하고 마지막 committed 상태/history와 기존 최종 HDF5를 보존한다. 고정 `DIRECT`를 cutback/adaptive로 바꾸거나 실패 frame을 성공으로 내보내지 않는다. + +공식 출력은 lexical sibling `_results.h5`다. `U/UR`, 물리적 `v/a`, `omega/omega_dot`, algorithmic `A`, 반력과 에너지의 **공개 여부 및 영속 schema는 미결정**이다. Algorithmic `A`를 physical acceleration이라는 이름으로 공개해서는 안 된다. 출력 선택과 무관하게 검증에는 서로 구별되는 내부 quantity가 필요하다. + +## 7. 검증 인계와 미해결 결정 + +| 항목 | 필수 evidence / 남은 경계 | +| --- | --- | +| HHT 계수·initialization | 표준 일정 질량 HHT와 algebraic reduction; SDOF 자유진동/STEP onset 및 `a_0=F/m`; `alpha=0` 한계 | +| 관성·회전 | Consistent mass의 총질량, uniform translation, 유한회전 angular motion, `d·ḋ=0`, `d·d̈+|ḋ|²=0`, objectivity, kinetic-energy derivative·tangent directional derivative | +| mass-null | 구성 의존 null, `ψ=0`과 초기 1·2차 일관성; coupled massless DAE에서 q/v/a 시간 수렴, finite-rotation drill coupling. 이 source theorem의 직접 적용은 미확인 | +| 정확도 | Smooth `M(q)` manufactured case의 q/v/a를 h,h/2,h/4로 검산; constant-M와 variable-M를 분리. STEP의 시작 불연속과 이후 smooth 구간을 분리 | +| 에너지·반력 | 관성 구속 평형, generalized/spatial moment work, algorithmic/endpoint reaction 구별, `T/U_phys/U_drill/W`와 momentum evidence | +| 구현 lifecycle | 동일 state tangent, 실패 rollback, time/frame 순서, deterministic assembly와 반복 결과 | +| 외부 reference | 지정 원본 101 frames × 9 nodes, frame/instance/node/component의 exact mapping; U blocking / UR warning-only 및 공통 TOLERANCE. V/A/energy correctness는 해당 CSV에 coverage 없음 | + +수식 후보의 [독립 검토](numerical-review.md)는 완료되었으며 표시된 수식에서 새 오류는 발견되지 않았다. 질량 선택은 consistent로 확정되었다. 구현 전 남은 계약은 (1) HHT 확장·초기화의 FESA 채택과 나머지 physics 범위, (2) initial algebraic regularity와 trial 실패 판정의 수치 기준, (3) 공식 output 의미의 공개 범위/I/O다. 이 선택 후 구현할 수 있는 수식 후보이며, 실제 유한회전 shell의 drilling DAE·관성 tangent·q/v/a 시간 수렴은 **구현 후 기능 acceptance에 필요한 검증**이다. 부모 문헌의 nonsingular-mass 조건을 shell mass-null에 자동 적용하지 않되, 모든 shell DAE의 보편적 수렴 증명을 코드 작성의 선행 조건으로 요구하지 않는다. 현재 문서 완료나 제한된 probe를 전체 solver 승인·검증 통과로 표시하지 않는다. + +이번 owner 작업은 기존 정식화·source 대조, 일차 문헌 대조와 수식 유도 및 문서 정적 검토다. [독립 시간정확도 검산](numerical-review-probes.md)은 variable-mass SDOF와 moving-null 예제에서 추천 후보의 약 2차 q/v/physical-a 수렴을 관찰했고 naive 확대의 약 1차 오차를 구별했다. 이는 shell solver 검증이나 일반 drilling DAE 증명을 대신하지 않는다. Build/test·solver/reference 실행은 문서 작업 범위가 아니므로 미실행이다. 독립 검산과 Numerical Review 결과는 해당 owner의 보고서가 소유하며 본 문서가 스스로 승인하지 않는다. diff --git a/docs/hht-implicit-dynamics/formulation-inertia-historical-docs-cleanup-20261004.md b/docs/hht-implicit-dynamics/formulation-inertia-historical-docs-cleanup-20261004.md new file mode 100644 index 0000000..669f99a --- /dev/null +++ b/docs/hht-implicit-dynamics/formulation-inertia-historical-docs-cleanup-20261004.md @@ -0,0 +1,209 @@ +# 유한회전 관성·초기화·HHT 상세 + +[주 정식화](formulation.md)의 구현 수식 상세다. 상태와 미결정 항목은 주 문서를 따른다. 아래 전개는 명시한 FESA 운동학에서의 자체 유도이며 Abaqus 내부 절차의 기술이 아니다. + +사용자 선택에 따라 이번 HHT 기본 및 구현 질량은 consistent `T_C/M_C`다. Lumped 식은 비교용 이론·기존 eigen 회귀 참고로 보존하며 이번 HHT 구현·검증 요구를 추가하지 않는다. 다른 physics·알고리즘·공개 output의 승인은 이 선택과 별개다. + +## 1. 회전과 관성의 미분 + +`P=[phi]_×`, `theta=|phi|`에 대해 + +\[ +J_l=I+\frac{1-\cos\theta}{\theta^2}P ++\frac{\theta-\sin\theta}{\theta^3}P^2,\qquad B=Dd=-[d]_\times J_l. +\] + +0에서 scalar coefficient는 analytic series를 사용한다. `v_phi,a_phi`는 fixed-chart 시간미분이다. 방향 `p,s,r`에 대한 director 미분을 +`B p=Dd[p]`, `C[p,s]=D²d[p,s]`, `D3[p,s,r]=D³d[p,s,r]`라 정의하면 + +\[ +C[p,s]=(DJ_l[s]p)\times d+(J_lp)\times((J_ls)\times d), +\] +\[ +\begin{aligned} +D3[p,s,r]={}&(D^2J_l[s,r]p)\times d+(DJ_l[s]p)\times B r\\ +&+(DJ_l[r]p)\times B s+(J_lp)\times C[s,r]. +\end{aligned} +\] + +방향 교환에 대한 대칭성이 필요하다. 정확한 미분을 scalar coefficient의 비특이 series까지 구현하기 위한 동등한 정의는 + +\[ +D^k\exp_P[H_1,\ldots,H_k] +=\sum_{m=k}^{\infty}\frac1{m!} +\sum_{\sigma\in S_k}\ \sum_{r_0+\cdots+r_k=m-k} +P^{r_0}H_{\sigma(1)}P^{r_1}\cdots H_{\sigma(k)}P^{r_k},\quad k=1,2,3. +\] + +여기서 `H=[direction]_×`이고 오른쪽에 `d0`를 곱하면 필요한 director derivative다. 이는 수렴하는 해석적 정의이며 production에서 무한합을 그대로 계산하라는 뜻이 아니다. Rodrigues/Fréchet/정확한 미분으로 같은 도함수를 계산하고 finite difference는 독립 검증에 사용한다. + +물질점에 대해 `H=D_q x`, `B_x[p,s]=D²_q x[p,s]`, `C_x[p,s,r]=D³_q x[p,s,r]`로 쓰면 + +\[ +H p=\sum_iN_i(p_{ui}+zB_i p_{\phi i}),\quad +B_x[p,s]=\sum_iN_i z C_i[p_{\phi i},s_{\phi i}], +\] +\[ +C_x[p,s,r]=\sum_iN_i zD3_i[p_{\phi i},s_{\phi i},r_{\phi i}],\quad +\dot x=Hv,\quad \ddot x=Ha+B_x[v,v]. +\] + +Consistent 관성 covector와 partial derivative action은 다음으로 직접 조립 가능하다: + +\[ +I_C=\int\rho H^T\{Ha+B_x[v,v]\}\,dV_0, +\quad M_C=\int\rho H^TH\,dV_0, +\] +\[ +\begin{aligned} +D_qI_C[p]=\int\rho\big(&B_x[p,\cdot]^T\{Ha+B_x[v,v]\}\\ +&+H^T\{B_x[p,a]+C_x[p,v,v]\}\big)dV_0,\\ +D_vI_C[p]&=2\int\rho H^TB_x[v,p]\,dV_0,\qquad D_aI_C[p]=M_Cp. +\end{aligned} +\] + +첫 항 `B_x[p,·]^T ẍ`를 빼면 단순 current-mass tangent에 불과하다. `B_x[p,a]`, `C_x[p,v,v]`, `2B_x[v,δv]`도 생략하지 않는다. `T`의 Euler–Lagrange 전개에서 `D H`의 대칭성에 의해 `d(H^T)/dt`와 `∂q T` 항이 상쇄되어 위 식을 얻는다. 원형상 밀도·measure는 시간에 따라 갱신하지 않는다. + +비교용 lumped 식에는 `x_i(z)=X_i+u_i+z d_i`, `H_i=D_q x_i`를 사용하여 위 적분을 `Σ_i ∫rho N_i (·)_i dV_0`로 바꾼다. `N_i`는 q와 무관하므로 동일한 derivative action이 성립한다. 별도의 경험적 gyroscopic 또는 Coriolis 보정항을 추가하지 않는다. + +## 2. 채택 질량·비교식과 적분 + +주 문서의 scalar moment로 + +\[ +(M_C)_{ij}=\begin{bmatrix} +C_{ij}^{(0)}I_3&C_{ij}^{(1)}B_j\\ +C_{ij}^{(1)}B_i^T&C_{ij}^{(2)}B_i^TB_j +\end{bmatrix},\quad +(M_L)_{ii}=\begin{bmatrix}m_iI_3&s_iB_i\\s_iB_i^T&j_iB_i^TB_i\end{bmatrix}, +\quad (M_L)_{ij}=0\ (i\ne j). +\] + +`rho`의 차원은 `mass/length³`, `(C0,C1,C2)` 및 `(m,s,j)`의 차원은 `(mass,mass·length,mass·length²)`다. `M_uu/M_uphi/M_phiphi`는 각각 같은 세 차원, residual translation은 force, rotation은 force·length이다. `v_u,a_u`는 `length/time,length/time²`; `v_phi,a_phi,omega,omega_dot`는 `1/time,1/time²`. 각도 단위는 rad이며 SI를 추정하지 않는다. + +Moments는 현행 [eigen2 mass 계약 M2–M3](../mitc4-shell-feast-eigen2/formulation-mass-stabilization.md#m2-consistent-scalar-moments와-적분)의 `3×3×3` Gauss–Legendre를 기준으로 하며, 그 scalar-moment lumping은 비교식에만 사용한다. 긴 유도는 선행 [mass 계약 M3](../mitc4-shell-feast-eigen/formulation-mass.md#m3-consistent-matrix와-충분한-quadrature)에 있다. 점은 `−sqrt(3/5),0,+sqrt(3/5)`, weight는 `5/9,8/9,5/9`, 순서는 증가하는 `xi→eta→zeta`다. Geometry가 bilinear degenerated shell이고 rho/t가 일정할 때 `Ni Nj z^k J0`의 축별 차수는 최대 4여서 이 moment 적분은 정확하다. `B_i`와 그 도함수는 nodal 값이므로 현재 관성과 tangent도 같은 moment를 사용한다. + +모든 27 mass 점에서 finite positive `J0`와 기존 geometry predicate를 확인한다. Current trial도 내력 8점·tying·center·recovery와 추가 inertia 평가점에서 허용 geometry를 만족해야 한다. `abs(J)`, 점 생략, 강제 평면화는 없다. 물리 내력·물리 에너지와 section recovery는 기존 `2×2×2` 적분, drill potential은 기존 element-level 합을 보존한다. + +Lumped positivity 조건은 `m_i>0`, `j_i−s_i²/m_i>0`다: + +\[ +2T_{L,i}=m_i\left|v_{ui}+(s_i/m_i)B_iv_{\phi i}\right|^2 ++(j_i-s_i^2/m_i)|B_iv_{\phi i}|^2. +\] + +두 질량식은 총질량 `Σm_i=∫rho dV0`, uniform translation energy, scalar thickness moments를 공유한다. 일반 속도장과 rigid angular motion의 orbital inertia는 다르다. 같은 현재 nodal `w_i=v_ui+z dDot_i`에 대해 + +\[ +T_L-T_C=\frac14\int\rho\sum_{i,j}N_iN_j|w_i-w_j|^2dV_0\ge0. +\] + +따라서 consistent와 lumped의 동적 응답이나 spectrum 동일성을 가정하지 않는다. 평판의 `s_i=0`, `j_i=t²m_i/12`를 warped geometry 일반식으로 사용하지 않는다. 사용자는 보간된 shell 속도의 운동에너지를 직접 적분하는 consistent mass를 선택했으며 기존 eigen의 lumped 계약은 변경하지 않는다. + +## 3. 객관성·운동량·회복 + +공간에서 강체속도를 가하면 `v_ui=V+Omega×(Xi+ui)`, `v_phii=J_l^−1 Omega`이고 `dDot_i=Omega×d_i`다. Consistent는 `xDot=V+Omega×x`를 재현하고, lumped는 각 `x_i(z)`의 같은 강체속도를 적분한다. 따라서 각자의 운동에너지 measure로 회전 관성을 검증해야 한다. + +Consistent의 물리적 총운동량·각운동량은 + +\[ +P=\int\rho\dot x\,dV_0,\quad L_O=\int\rho(x-O)\times\dot x\,dV_0. +\] + +Lumped는 `Σ_i ∫rho N_i xDot_i dV0`, `Σ_i ∫rho N_i(x_i−O)×xDot_i dV0`다. 이 정의에서 시간미분한 `Pdot,Ldot`와 외력·support reaction의 총 force/moment를 대조한다. Kinematic 변환은 algorithmic `A`가 아닌 물리적 `a`로 평가한다. Objective `U_phys+U_drill`의 전체 내력은 강체 가상운동에 일을 하지 않아야 한다. Numerical drill의 개별 nodal moment를 physical stress/resultant로 오인하지 않는다. + +고정 proper global frame change 아래 모든 벡터·구속·하중을 함께 변환하면 scalar `T`, `U`와 virtual work가 불변이어야 한다. 기준축 일부만 회전시킨 비교는 이 검증에 해당하지 않는다. 중간 회전 branch를 통과하는 rechart는 지원하지 않는다. + +## 4. Mass-null과 초기 일관성 + +`B_i`는 rank 2이며 instantaneous drilling 방향은 + +\[ +n_i(q)=\begin{bmatrix}0\\J_l(\phi_i)^{-1}d_i\end{bmatrix},\quad +B_iJ_l^{-1}d_i=0. +\] + +Consistent와 lumped 모두 이 방향에 `M n_i=0`, `n_i^T I=0`이다. 이 null은 일반적으로 `[0;d0]` 또는 고정 global `UR3`가 아니다. 필요한 geometry/rank 조건 아래 물리적 5 DOF/node 외 추가 null이 없는지 검사한다. 구속 후에는 `M_ff`와 free admissible variation 안에서의 null basis `N(q)`를 사용하며, constrained component를 단순 삭제한 nodal null을 그대로 basis라 부르지 않는다. + +`g=f_int−F`라 두면 연속 대수 조건은 + +\[ +\psi(q,t):=N(q)^Tg_f(q,t)=0. +\] + +Physical energy는 director-parallel virtual work가 0이다. 본 force-only subset에서 `psi`는 numerical drill channel의 stationarity를 포함한다. Drilling stiffness는 algebraic coordinate를 결정할 수 있지만 mass rank를 바꾸지는 않는다. `N`의 q 미분도 포함하여 + +\[ +\psi_q v_f+\psi_t=0,\qquad +\psi_q a_f+\psi_{qq}[v_f,v_f]+2\psi_{qt}v_f+\psi_{tt}=0 +\] + +를 초기 연속 일관성으로 요구한다. 첫 시간은 `0+`이며 이후 constant load의 우측 도함수 `Fdot=Fddot=0`를 사용한다. STEP jump를 impulse로 해석하여 초기 velocity를 바꾸지 않는다. + +`q0=v0=0`, 고정 zero boundary에서는 다음 절차로 `a0`를 정할 수 있다. + +1. `psi(q0,0+)=0`와 1차 조건을 확인한다. 여기서 물리적 initial acceleration을 풀기 전부터 불일관하면 실패다. +2. `b=F_f0−f_int,f(q0)−c_f(q0,v0)`에 `N0^T b=0`이 필요하다. 양의 질량 부분공간에서 `M_ff a_P=b`, `N0^T a_P=0`인 particular solution을 구한다. +3. `a_f0=a_P+N0 eta`를 놓고 + +\[ +(\psi_qN0)\eta=-\psi_q a_P-\psi_{qq}[v0,v0]-2\psi_{qt}v0-\psi_{tt} +\] + +를 푼다. 이 subset에서 우변 뒤 세 항은 0이다. `psi_qN0`가 nonsingular여야 초기 acceleration이 유일하게 정해진다. 단순 Moore–Penrose solve 결과를 그대로 가속도라고 채택하거나 massless acceleration을 0으로 놓지 않는다. + +초기점에서는 `g0`가 병진 force를 포함하므로 `D N` 항을 형식적으로 삭제하지 않는다. 다만 zero rotation에서 실제 vanished 항은 식으로 확인할 수 있다. Null basis의 normalization/부호는 물리적 판정에 영향을 주지 않으며 source identity와 결정적 순서를 유지한다. + +Bounds/regularity는 다음을 포함한다: 양의 `rho,t`; reference/current valid geometry; `||phi||=0 mode subset만 생성한다. +`verification`에는 전체 c개 residual·Gram·null 검사와 backend call/control evidence를 보존한다. -Trace stopping은 전체 c개의 독립 residual을 만족하지 못했고 C-index `fpm[5]=0`의 -residual stopping으로 수정했다. 초기 외부 RMS1% 불일치는 사용자 승인 후 첫 구현 -policy로 판정했으며 과거 실패 기록을 바꾸지 않았다. 최대 외부 상대차는 약4.261331%다. -S3 public static 평형 충돌과 Abaqus Value 정확도 개선은 보류다. 실제512회 vendor 호출· -HDF5 close-error 전체 주입 및 모든 모델의 정확도를 검증했다고 주장하지 않는다. +| 원본 | 비교 계약 | +| --- | --- | +| `reference/shellNL-eigen-meshfine/shellNL-eigen-meshfine.inp` | 유일한 source frequency step `Step-2`, N=10 | +| 같은 폴더 `shellNL-eigen-meshfine eigenvalues.txt` | `Frame: Mode : Value = ... Freq = ... (cycles/time)` | + +Step·mode ID·Value·time^-2를 직접 대응하며 TXT Freq로 lambda를 재구성하지 않는다. +Duplicate/missing/extra mode·malformed/nonfinite·unit/mass/backend/schema 오류는 tolerance 전에 실패한다. +동일 Value의 서로 다른 mode는 합치거나 평균하지 않는다. +승인된 named policy `mitc4-eigen-first-implementation`은 mode별 singleton의 +relative row error와 relative RMS를 각각 `<=5%` inclusive로 검사한다. +Report는 policy_id와 relative_rms_tolerance를 기록한다. +이 예외는 다른 공통 family의 row 5%·RMS 1%를 바꾸지 않는다. +전체 c개 독립 내부 residual·Gram 등 `1e-10` 기준도 그대로다. + +## 구현·데이터 흐름·수명 + +[Mitc4Shell::Mass](../../include/fesa/elements/mitc4_shell.h)와 [kernel](../../src/fesa/elements/mitc4_shell.cpp)이 local mass를 만든다. +[LinearFrequencyProcedureExecutor::Execute](../../include/fesa/analysis/linear_frequency_procedure.h)는 +[실제 procedure](../../src/fesa/analysis/linear_frequency_procedure.cpp)에서 stable assembly·modal candidate를 소유한다. +[BuildEigenReduction](../../src/fesa/analysis/eigen_reduction.h)은 constrained lift·null split·whitening을 만든다. +[MklFeastEigenSolver::Solve](../../include/fesa/solvers/eigen/mkl_feast_eigen_solver.h)는 private vendor adapter다. +Domain→local K/M→ordered assembly→reduced solve→global phi 복원→all-c 검증→N 선택 순서다. +[EigenHdf5ResultsWriter](../../include/fesa/io/hdf5/eigen_hdf5_results_writer.h)는 검증 state를 직렬화한다. +출력 close/self-check/atomic replace 실패는 candidate를 폐기하고 기존 final을 보존한다. + +## 실제 evidence와 미해결 범위 + +2026-09-10 사용자 승인 첫 구현에서 전체 417/417 PASS와 원본 10 Value의 모드별5% 통과 기록이 있다. +최대 외부 상대차는 약 `4.261331%`다. 이전 RMS1% 불일치 이력은 소급 PASS로 고치지 않는다. +이 기록은 당시 revision의 evidence이며 이번 문서 정리는 새 build/test를 실행하지 않았다. +Rational mass oracle·Jensen energy·좌표 재계산 공변성·density scaling·all-c 실패 주입이 보완 근거다. +S3 public static 평형 충돌과 Abaqus Value 정확도 개선은 후속 보류다. +실제 512회 vendor 호출 또는 실제 HDF5 close-error의 모든 조합을 주입한 것은 아니다. +Retained shell/shellNL 회귀와 내부 검증 의무를 유지하며 `reference/temp` 제외 예제를 재사용하지 않는다. diff --git a/docs/nonlinear-static-newton-raphson/README.md b/docs/nonlinear-static-newton-raphson/README.md index bdf34bd..4ee0a56 100644 --- a/docs/nonlinear-static-newton-raphson/README.md +++ b/docs/nonlinear-static-newton-raphson/README.md @@ -1,38 +1,72 @@ -# MITC4 비선형 정적 해석 +# MITC4 비선형 정적 Newton 해석 -## 목적과 현재 범위 +## 목적과 경계 -유한회전 total chart, 같은 trial의 residual/tangent, Newton·증분·rollback를 구현한 기능이다. 역사적 기능 검증과 현재 통합 회귀의 범위를 구분한다. -최근 dev 통합 회귀는 [전체 현황](../tracking/status.md)에 연결하며, 과거 release 판정은 -[release.md](release.md)에 남긴다. 문서 정리는 새 기능 검증이나 재승인을 뜻하지 않는다. +등방 선형탄성 MITC4의 기하 비선형 정적 응답을 full Newton으로 계산한다. +재료 비선형·contact·arc length·line search·자동 cutback은 이 기능에 포함하지 않는다. +고정 global dead nodal force/moment와 factor-one prescribed target을 공통 load factor로 증가시킨다. +후속 pressure 확장은 [shell pressure](../shell-surface-pressure-load/README.md)를 따른다. +공통 소유권·실행은 [solver-core](../solver-core/README.md), 자세한 수식은 [정식화](formulation.md)다. -## 계약과 재사용 Handoff +## 채택한 수식과 이유 -- [요구사항·acceptance](requirements.md): 지원·제외와 기존 요구사항 ID. -- [정식화](formulation.md): 수식·가정·부호·좌표계·복구 위치. -- [I/O](io.md): 입력 subset·진단·source identity·결과 schema. -- [Reference 모델](reference-model.md): 원본과 비교량·행 identity·적용 범위. -- [독립 수치 검토](numerical-review.md): 검산·위험·반례와 수정 확인. -- [검증·물리 결과](verification.md): 실제 실행한 명령·수치·실패·미실행·한계. -- [연구 근거](research.md): 정식화에 필요한 출처와 적용 경계. +고정 reference의 Total Lagrangian geometry와 finite rotation-vector total chart를 사용한다. +초기 director/frame에서 같은 trial의 기하·strain·internal force·consistent tangent를 계산한다. +Rotation-vector generalized moment와 global spatial moment는 일의 짝이 다르다. +반력의 공개 moment 복구에서 chart 변환을 적용하며 성분명 변경으로 대체하지 않는다. +Physical MITC strain·constitutive response와 objective numerical drilling potential을 분리한다. +Drilling scale은 초기 상태에서 정하고 trial마다 다시 tuning하지 않는다. +평형 residual은 internal minus external이며 follower load가 있으면 tangent는 +`Kint-dFext/dq`다. Unsymmetric tangent를 대칭화하지 않는다. -공통 소유권은 [ARCHITECTURE](../ARCHITECTURE.md)를 따른다. Element는 local 계산, -Assembly는 결정적 reduction, Procedure는 trial/commit, Recovery는 물리 의미, -Writer는 직렬화를 담당한다. 새 기능에서 기존 stage/phase 실행 계획을 재사용하지 않는다. -현재 공개 API는 `include/fesa/`, 실제 구현은 `src/fesa/`와 대응 검사를 확인한다. +## 입력과 결과 대응 -## 사용법 +`*STEP,NLGEOM=YES` 아래 단일 `*STATIC`을 사용한다. +Data는 `initial_increment,time_period,minimum_increment,maximum_increment` 네 양수다. +`time_period=1.0`이며 initial increment가 고정 h다. 최소·최대 값은 호환성 metadata다. +h의 ordinal multiple과 마지막 exact factor one을 사용하고 실패 시 increment를 줄여 재시도하지 않는다. +`S4|S4R`, centered `*SHELL SECTION`, `*ELASTIC`, identity instance와 DOF 1–6 BC를 사용한다. +`*CLOAD`는 global dead load이며 aggregate drilling-direction moment는 거부한다. +Composite·offset·instance transform·amplitude·MPC·restart·다중 step은 범위 밖이다. -환경 준비·build·CTest·CLI 기본 사용은 [operations](../operations.md), 입력과 결과의 -공통 계약은 [contracts](../contracts.md)를 따른다. 이 기능의 keyword·option 허용 범위는 -위 I/O 계약을 확인한다. 과거 보고서의 machine 경로·임시 command를 현재 기본값으로 쓰지 않는다. +HDF5 nonlinear schema `1`은 `Step-1`의 accepted frame과 load factor를 보존한다. +각 `/steps/Step-1/frames/`에 displacement, reaction 및 4 GP physical shell recovery가 있다. +Bottom/middle/top stress 위치를 보존하며 nodal stress로 평균하지 않는다. +실패 iteration은 accepted frame이 아니며 Newton log와 최종 HDF5는 서로 다른 수명이다. -## 개발 과정과 주의사항 +| Reference bundle | 대응과 의미 | +| --- | --- | +| `reference/shell/` | linear-limit 회귀, 비선형 응답 evidence 아님 | +| `reference/shellNL/` | 49 nodes·36 S4의 factor-one final displacement | +| `reference/shellNL-meshfine/` | 729 nodes·676 S4의 factor-one final displacement | +| `reference/shellNL-meshfine_02/` | 별도 후속 final-state 비교, 앞 사례의 단순 대체 아님 | -기존 단계별 계획·coordination은 완료된 실행 운영 기록이어서 제거했다. 승인된 요구사항· -수식·검토·실제 검증 결과는 위 문서에 보존한다. Git `858e87b`의 이전 경로는 당시 원문을 -조회하는 용도로만 사용하며 현행 작업 지침이 아니다. +각 bundle의 같은 stem `displacements.csv`에서 frame·instance·source node를 맞춘다. +U1–3는 blocking, UR1–3는 warning-only다. Constrained local RF1–3와 spatial RM1–2는 review-only다. +RM3와 stress는 external comparison family를 만들지 않는다. +Fine optional stress의 malformed node label `ss`는 비차단 inventory 문제이며 원본을 보정하지 않는다. +Family의 reference-only `S=max(abs(ref))`에 대해 near-zero `abs(ref)<=0.01*S`는 +error `<=0.01*S`, 나머지는 relative error `<=5%`, family RMS/S `<=1%`를 함께 검사한다. +Zero-scale은 exact zero다. Blocking·warning·review의 수치와 판정 영향을 구분한다. +내부 accepted free residual·force/moment 평형의 normalized 기준은 `1e-10`이다. -- 실패한 trial·candidate는 기존 accepted state와 최종 결과를 변경하지 않아야 한다. -- 같은 trial의 기하·내력·하중·접선을 사용하고 generalized rotation moment와 spatial moment를 구분한다. -- [수정·실패 기록](lessons.md)에 원인과 검증 결과를 보존한다. +## 구현과 상태 수명 + +[NonlinearMitc4Shell](../../include/fesa/elements/nonlinear_mitc4_shell.h)은 immutable evaluator다. +`EvaluateInternalResidualAndTangent`는 한 trial의 내력·접선·물리 복구를 함께 돌려준다. +[Kernel 구현](../../src/fesa/elements/nonlinear_mitc4_shell.cpp)은 accepted state를 소유하지 않는다. +[NonlinearStaticProcedureExecutor](../../include/fesa/analysis/nonlinear_static_procedure.h)의 +`Execute`가 증분·trial·수렴·commit을 소유한다. +[Procedure 구현](../../src/fesa/analysis/nonlinear_static_procedure.cpp)은 최대 100 Newton iterations를 허용한다. +Domain→non-owning model→stable full/free DOF→local trial response→ordered assembly→tangent solve 흐름이다. +수렴과 내부 검증을 마친 상태만 accepted collection에 추가한다. +실패 trial은 이전 accepted state와 기존 final HDF5를 오염시키지 않아야 한다. + +## 검증에서 배운 점과 남은 경계 + +기존 nonlinear reference와 rollback·finite rotation·tangent·equilibrium 검증 기록이 있다. +이는 새 revision의 build/test 통과를 의미하지 않으며 이번 작업은 문서 정리만 수행한다. +Reaction은 단일 global 합만 맞춰 local reaction 정확성을 대체할 수 없다. +큰 자세 변화와 원점 이동에서 spatial moment balance를 함께 확인해야 한다. +외부 U 통과는 warning UR 또는 review RF/RM의 수치 일치를 뜻하지 않는다. +현재 prescribed path와 단일재료 shell 사례가 arbitrary nonlinear 모델의 수렴을 보장하지 않는다. diff --git a/docs/shell-surface-pressure-load/README.md b/docs/shell-surface-pressure-load/README.md index 19239a1..6f12a0d 100644 --- a/docs/shell-surface-pressure-load/README.md +++ b/docs/shell-surface-pressure-load/README.md @@ -1,38 +1,77 @@ # Shell 표면 압력 -## 목적과 현재 범위 +## 목적과 경계 -SURFACE의 SPOS/SNEG와 DSLOAD의 P를 사용하는 압력의 방향·면적·follower tangent 및 선형/비선형 조립를 구현한 기능이다. 역사적 기능 검증과 현재 통합 회귀의 범위를 구분한다. -최근 dev 통합 회귀는 [전체 현황](../tracking/status.md)에 연결하며, 과거 release 판정은 -[release.md](release.md)에 남긴다. 문서 정리는 새 기능 검증이나 재승인을 뜻하지 않는다. +Named shell surface의 균일 signed `DSLOAD P`를 선형·비선형 정적 해석에 조립한다. +선형은 reference geometry, `NLGEOM=YES`는 current geometry의 follower pressure다. +4절점 `S4|S4R` 중앙면만 대상이며 offset·director face·edge/body load는 포함하지 않는다. +공통 계약은 [solver-core](../solver-core/README.md), 유도 원문은 [정식화](formulation.md)다. -## 계약과 재사용 Handoff +## 방향·면적·접선 -- [요구사항·acceptance](requirements.md): 지원·제외와 기존 요구사항 ID. -- [정식화](formulation.md): 수식·가정·부호·좌표계·복구 위치. -- [I/O](io.md): 입력 subset·진단·source identity·결과 schema. -- [Reference 모델](reference-model.md): 원본과 비교량·행 identity·적용 범위. -- [독립 수치 검토](numerical-review.md): 검산·위험·반례와 수정 확인. -- [검증·물리 결과](verification.md): 실제 실행한 명령·수치·실패·미실행·한계. -- [연구 근거](research.md): 정식화에 필요한 출처와 적용 경계. +Connectivity의 `g_xi×g_eta=a`를 양의 oriented area vector로 둔다. +Side multiplier s는 `SPOS=+1`, `SNEG=-1`이며 force density는 `-lambda*p*s*a`다. +따라서 양의 P는 선택한 면의 outward normal 반대 방향이다. +음의 P는 그대로 부호를 뒤집으며 abs·clamp로 바꾸지 않는다. +Bilinear shape로 nodal force를 적분하고 고정 Gauss 순서로 누적한다. +Current area의 방향과 크기를 함께 미분하여 `Kext=dFext/dq`를 계산한다. +Newton tangent에는 `Kint-Kext`로 들어가며 follower tangent는 일반적으로 비대칭이다. +Pressure geometry는 translation만 사용하므로 rotational force와 tangent row/column은 exact zero다. +Thick shell의 실제 offset face traction으로 임의 확장하지 않는다. -공통 소유권은 [ARCHITECTURE](../ARCHITECTURE.md)를 따른다. Element는 local 계산, -Assembly는 결정적 reduction, Procedure는 trial/commit, Recovery는 물리 의미, -Writer는 직렬화를 담당한다. 새 기능에서 기존 stage/phase 실행 계획을 재사용하지 않는다. -현재 공개 API는 `include/fesa/`, 실제 구현은 `src/fesa/`와 대응 검사를 확인한다. +## 입력과 결과 대응 -## 사용법 +Assembly 안이며 instance block 밖에서 다음 형태를 사용한다. -환경 준비·build·CTest·CLI 기본 사용은 [operations](../operations.md), 입력과 결과의 -공통 계약은 [contracts](../contracts.md)를 따른다. 이 기능의 keyword·option 허용 범위는 -위 I/O 계약을 확인한다. 과거 보고서의 machine 경로·임시 command를 현재 기본값으로 쓰지 않는다. +```text +*SURFACE, TYPE=ELEMENT, NAME=Surf-1 +, SPOS +*DSLOAD +Surf-1, P, +``` -## 개발 과정과 주의사항 +Surface member는 source element·side로 정규화한다. +같은 side의 중복 facet은 warning 후 하나로 만들고 양쪽 side 충돌은 실패한다. +반면 같은 DSLOAD 행은 각각의 additive load record이며 합법적으로 누적한다. +Part/instance-level surface, node surface, 다른 face label, `*DLOAD`는 지원하지 않는다. +DSLOAD `AMPLITUDE`, `FOLLOWER`, `OP`, `REF NODE` 및 unknown parameter는 거부한다. +Follower 여부는 procedure로 결정하며 keyword 옵션을 조용히 무시하지 않는다. +양의 Jacobian·nondegenerate oriented area·finite force/tangent를 검사한다. -기존 단계별 계획·coordination은 완료된 실행 운영 기록이어서 제거했다. 승인된 요구사항· -수식·검토·실제 검증 결과는 위 문서에 보존한다. Git `858e87b`의 이전 경로는 당시 원문을 -조회하는 용도로만 사용하며 현행 작업 지침이 아니다. +결과는 기존 linear schema0 또는 nonlinear schema1의 displacement/reaction·shell recovery다. +별도의 가상 pressure stress 또는 nodal averaged stress를 추가하지 않는다. +Nonlinear 비교는 exact factor-one accepted frame만 사용한다. -- 실패한 trial·candidate는 기존 accepted state와 최종 결과를 변경하지 않아야 한다. -- 같은 trial의 기하·내력·하중·접선을 사용하고 generalized rotation moment와 spatial moment를 구분한다. -- [수정·실패 기록](lessons.md)에 원인과 검증 결과를 보존한다. +| 원본 bundle | 비교 의미 | +| --- | --- | +| `reference/shellNL-meshfine-pressure/shellNL-meshfine-pressure.inp` | 729 nodes, 676 S4의 nonlinear follower pressure | +| 같은 stem `displacements.csv` | U1–3 blocking, UR1–3 warning-only | +| 같은 stem `reactions.csv` | review-only | +| 같은 stem `stresses.csv` | 수치 equality 비교에서 제외 | + +CSV의 frame·instance·source node와 component를 HDF5 nodal row에 직접 대응한다. +Shared row/schema/finite precheck는 tolerance 이전 조건이며 warning family에도 적용한다. +Reference-only `S=max(abs(ref))`에 대해 `abs(ref)<=0.01*S`는 error `<=0.01*S`, +나머지는 relative error `<=5%`, family RMS/S `<=1%`를 요구한다. `S=0`은 exact zero다. +내부 free residual·전역 force/moment balance는 normalized `1e-10`을 사용한다. + +## 구현과 수명 + +[EvaluateShellSurfacePressure](../../include/fesa/loads/shell_surface_pressure.h)는 +24 DOF force와 양의 external derivative를 돌려주는 stateless local kernel이다. +[실제 구현](../../src/fesa/loads/shell_surface_pressure.cpp)은 reference/current geometry를 선택한다. +[AssembleSurfacePressure](../../include/fesa/assembly/surface_pressure_assembler.h)는 +Domain의 surface/load identity를 stable full DOF contribution으로 조립한다. +[Assembler 구현](../../src/fesa/assembly/surface_pressure_assembler.cpp)을 대조한다. +Surface와 load definition은 Domain 소유이며 procedure의 trial displacement는 빌려 사용한다. +Local 계산→ordered reduction→내력과 외력 결합→free solve→accepted recovery 순서다. +Candidate 실패가 기존 accepted state·최종 결과를 바꾸지 않아야 한다. + +## 검증 의미와 교훈 + +기존 방향·합력·moment·강체 회전·finite-difference tangent 및 지정 reference 검증 기록이 있다. +문서 정리는 이번 revision의 새 실행 evidence가 아니다. +DSLOAD와 DLOAD의 부호 규칙을 섞거나 reference area로 follower load를 계산하면 안 된다. +같은 trial의 force/tangent를 함께 써야 Newton 일관성을 유지한다. +외부 displacement 일치만으로 압력 tangent나 local reaction 정확성을 추론하지 않는다. +한 개의 지정 shell pressure bundle은 arbitrary closed surface·offset face·contact pressure 검증이 아니다. diff --git a/docs/shell-transient-heat-transfer/README.md b/docs/shell-transient-heat-transfer/README.md index d684d4f..e297cf1 100644 --- a/docs/shell-transient-heat-transfer/README.md +++ b/docs/shell-transient-heat-transfer/README.md @@ -1,36 +1,133 @@ # Shell transient heat transfer -## 목적과 개발 결과 +## 범위와 현재 상태 -5개 두께 온도점을 가진 Q4×two-P2 shell의 단일 uncoupled transient heat transfer다. -K/C, Backward Euler, 온도·24개 Fourier flux trace·열용량을 포함한 반력, 입력·CLI·atomic -HDF5 저장을 구현했다. 추가139개 검사 모두 PASS이며 전체617개는614 PASS·기존 HHT2 FAIL·1 SKIP다. -새 필수 reference 모델·NT11 CSV가 준비 중이므로 외부 검증 완료 상태는 아니다. +DS4 4절점 shell의 5개 두께 온도점을 사용하는 단일 uncoupled transient heat transfer다. +Q4×two-P2 요소의 K/C, Backward Euler, 온도·24개 Fourier flux trace·열저장 포함 반력, +입력·CLI·atomic HDF5를 구현했다. 당시 추가139개 검사는 모두 PASS이고 전체617개는 +614 PASS·기존 HHT2 FAIL·1 SKIP(native8)이었다. 이 문서 정리에서는 build/test를 재실행하지 않았다. +새 필수 reference 모델·NT11 CSV가 준비 중이므로 외부 검증 완료나 전체 green 상태가 아니다. -## 계약과 사용법 +## 채택 방법과 물리 의미 -- [PRD](PRD.md)·[ADR](ADR.md): 승인 범위·제외·현재 checklist·reference 진단 전환. -- [정식화](formulation.md): geometry·station·K/C·BE·flux·반력의 정확한 의미. -- [설계와 Handoff](design.md): 계산 방법과 모듈 연결. -- [독립 수치 검토](numerical-review.md), [oracle 재현](verification-oracles.md). -- [구현·전체 회귀](implementation-verification.md), [물리 평가](physics-evaluation.md), - [원본 reference 불일치](reference-comparison-conflict.md). +[정식화](formulation.md)가 geometry·보간·행렬·시간격자·판정의 상세 원본이다. +한 node의 source DOF11..15는 zeta=[-1,-.5,0,.5,1]이며 11/13/15가 bottom/mid/top이다. +요소는 node-major20 DOF로 면내 Q4와 두 구간 C0 P2 두께 보간을 결합한다. 다섯 독립2D 판이 +아니며 두께 미분으로 station 사이를 결합한다. Midsurface metric·법선의 thin-shell +product-domain이고 thickness offset의 곡률 보정은 생략한다. Fold·두께 단차는 같은 normalized +station을 공유하는 이상화이며 실제3D 접합부 전도와 동등하지 않다. -환경·CLI는 [operations](../operations.md), 승인 keyword와 결과 schema는 PRD 상세 계약을 -따른다. Source DOF11/13/15는 bottom/mid/top이며 공개 지정온도·절점 열률은11/15만 지원한다. -Edge 열입력·열-구조 연성·복합재 단면·온도의존 물성은 이번 범위가 아니다. +Consistent capacity를 사용하고 lumping·인공 확산·음수 온도 clamp는 하지 않는다. 면내3×3 +Gauss와 정확 P2 thickness Z0/Z1로 `C=rho*c*(h/2)*(M⊗Z0)`, +`K=k*((h/2)*(S⊗Z0)+(2/h)*(M⊗Z1))`를 만든다. 별도9×2×3=54 직접 적분점은 검산 위치이며 +아래24 flux trace와 다르다. 퇴화·뒤집힘·self-crossing·불일치 side는 실패하고 |detJ|로 보정하지 않는다. -## 재사용 Handoff와 교훈 +BE는 `A=C/delta+K`, `b=Q+C*Told/delta`다. Free RHS에는 +`C_fc*Told_c/delta-A_fc*g_new`가 포함된다. Raw 초기 온도를 t=0에 보존하고 첫 양의 시점부터 +지정온도를 부과한다. 첫 BC jump를 초기 projection으로 없애지 않는다. 일정 계수·delta에서 +A_ff factorization을 재사용하며 실제 마지막 간격이 짧을 때만 재분해한다. n*dt로 생성한 +시간격자는 마지막을 입력 T_end로 저장한다. dt>T_end이면 한 증분이다. 단열 K의 상수 null은 +양의 C가 있는 transient A의 singularity를 뜻하지 않는다. -Consistent capacity와 raw 초기값을 유지하고 첫 BC jump를 투영하거나 음수를 clamp하지 않는다. -중립면의 양쪽 flux trace를 평균하지 않는다. Fold/두께 단차의 station 공유는 실제3D 접촉 전도와 -동등하지 않다. 초기 두께 경계층의 국소 flux/반력, 일반 곡면 전체 응답·점열원 수렴은 검증 한계다. -기존 NT11 비교는729행 중87행 FAIL·RMS/S 약0.0496741을 보존한 diagnostic이며 tolerance는 그대로다. -Slab 에너지/반력 oracle index 오류는 수정 후 전체 focused 검사를 다시 실행했다. +## 공개 입력과 제외 범위 -## 다음 작업과 보존 자료 +기존 Part/identity Instance·node/set subset과 DS4, SHELL SECTION의 상수 양의 두께, +CONDUCTIVITY/DENSITY/SPECIFIC HEAT의 상수 양의 k/rho/c를 사용한다. +`*INITIAL CONDITIONS, TYPE=TEMPERATURE`의 signed finite T는 target node/Nset의5점에 +동일 적용하고 미지정은0이다. 공개 BOUNDARY와 CFLUX는 DOF11/15만 지원한다. +CFLUX의 signed P는 모델로 들어오는 power이며 면적·두께를 곱하지 않는다. Source row 순서로 +중복 하중을 더하고 constrained 입력도 full Q에 남긴다. 자연 경계는 단열이다. -새 모델·CSV의 별도 경로, source identity·시점·hash를 확정하고 필수 family를 실제 비교한다. -dev 병합은 사용자의 통합 승인이고 외부 검증 통과 승인이 아니다. -삭제한 worktree의 자료는 dev checkout 기준 -`.dryforge/retained/shell-transient-heat-transfer-20261004/`에 보존했고 경로 대응은 구현 검증 보고서에 있다. +Model/step BC 각각의 동일 target 충돌을 검사한 뒤 step 값이 model 값을 덮어쓴다. +동일 값 중복은 허용하고 다른 값은 오류다. 생략 BC 값은0이다. 단일 `*HEAT TRANSFER`의 +END 생략 또는 PERIOD와 dt,T_end를 지원한다. 시간변화/amplitude, 내부 station 직접 BC/CFLUX, +edge 열입력, 열-구조 연성, composite, 온도의존 물성, 절점별 두께와 사용자 station 수는 제외한다. +[공통 solver 요약](../solver-core/README.md)에 CLI·source identity·lease·공통 tolerance가 있다. +사용자 일관 단위를 쓰며 SI를 추정하지 않는다. + +## 복구와 HDF5 계약 + +Flux는 같은 보간의 직접 미분 `q_global=-k*B*T_e`이며 power/area다. +면내2×2 Gauss 네 위치 × 두께 trace `[-1+,-.5,0-,0+,.5,1-]`의24 위치를 구별한다. +C0 중앙면의 양쪽 두께 도함수를 평균하지 않는다. Local frame R=[e1,e2,n]의 열은 global +축 성분이며 local flux=R^T*q_global로 후처리한다. Bottom 외향 법선은 -n, top은+n이다. + +반력은 `r=C*(Tnew-Told)/delta+K*Tnew-Q`의 constrained projection이다. 양수는 모델에 +추가 공급되는 열이며 전도 flux의 절점 평균과 다르다. Free residual·열에너지는 내부 검증량이고 +필수 공개 dataset을 임의로 추가하지 않는다. + +Schema version U64=1, feature_id=shell-transient-heat-transfer, +analysis_procedure=uncoupled-transient-heat-transfer, +internal_formulation=FESA-Q4-P2x2-thermal-shell, +integration_rule=surface-3x3-gauss; thickness-exact-P2x2, +time_integration=backward-euler다. Metadata에는 source_step_name·source_input_identity· +nominal_time_increment·time_period를 기록한다. 모든 숫자는 explicit little-endian F64/U64/U8/I8, +문자열은 UTF-8이며 mandatory finite·shape·identity를 검사한다. Compound padding은 계약이 아니다. + +| 경로 | Shape·mapping | +| --- | --- | +| /model/nodes, elements, thermal_materials, shell_sections | Source identity/연결·k/rho/c·두께와 provenance | +| /model/thermal_node_ids, thermal_element_ids | U64[N], U64[E]; 활성 row의 stable model ID | +| /model/temperature_dofs, temperature_zeta | U64[5]=11..15, F64[5]=[-1,-.5,0,.5,1] | +| /model/thermal_constraint_mask, thermal_reaction_dofs | U8[N,5], compound[P]=(internal_node_id,source_dof); node/station 순서, P=0도 유지 | +| /model/thermal_flux_inplane_coordinates, thermal_flux_zeta, thermal_flux_trace_side | [4,2], [6], I8[6]=[1,0,-1,1,0,-1] | +| /model/thermal_flux_local_frames | F64[E,4,3,3]; global component × local axis | +| /steps/Step-1/accepted_frames | frame_index/increment_index U64, time/time_increment F64, is_initial U8; raw initial 포함 | +| frames/n/nodal/temperature | F64[N,5], NT11..NT15; initial과 completed 모두 존재 | +| frames/n/nodal/reaction_heat_rate | F64[P], RFL, power, positive into-model; completed만 존재 | +| frames/n/element/heat_flux | F64[E,4,6,3], QX/QY/QZ global; completed만 존재 | + +위 frames 상대 경로의 부모는 /steps/Step-1이다. 실제 source step 이름은 metadata에서 +구별한다. Frame0은 time=delta=0,is_initial=1이며 flux/reaction dataset이 **없다**. +이를 NaN·계산된0으로 채우지 않는다. 완료 frame은 실제 양의 delta를 저장한다. +Diagnostics는 source/severity/code/message의 기존 convention을 보존한다. + +## 코드 흐름과 수명 + +[Abaqus step mapper](../../src/fesa/io/abaqus/step_definition_mapper.cpp)가 semantic Domain을 +만들고 [ThermalShell::Create/Recover](../../src/fesa/elements/thermal_shell.cpp)와 +[thermal geometry](../../src/fesa/elements/thermal_shell_geometry.cpp)가 local K/C·flux를 제공한다. +열 kernel은 구조 displacement Element::Recover를 전용하지 않는다. +[AssembleThermal](../../src/fesa/assembly/thermal_assembler.cpp)은 DofManager scatter와 stable +source 순서로 K/C/Q를 조립한다. C를 structural mass에 저장하지 않는다. + +[TransientHeatProcedureExecutor::Execute](../../src/fesa/analysis/transient_heat_procedure.cpp)는 +[ThermalTimeGrid](../../src/fesa/analysis/thermal_time_grid.cpp), +[BE algebra와 residual certificates](../../src/fesa/analysis/thermal_transient_algebra.cpp)를 사용해 +solve→full temperature→residual/flux/finite/수지 검사→commit을 수행한다. 호출자 소유 solver와 +parallel adapter는 Execute보다 오래 살아야 하고 Domain은 non-owning model보다 오래 살아야 한다. +[ThermalAnalysisState::Create/MakeCompletedFrame/CommitAcceptedFrame](../../include/fesa/analysis/thermal_analysis_state.h)는 +inventory와 accepted history를 소유한다. Create 뒤 Domain/model/assembly 참조를 남기지 않아 +state가 이들보다 오래 살 수 있다. 거부된 candidate는 기존 frames를 바꾸지 않는다. + +[Thermal writer](../../src/fesa/io/hdf5/thermal_hdf5_results_writer.cpp)와 +[self-check](../../src/fesa/io/hdf5/thermal_hdf5_self_check.cpp)는 candidate close 뒤 재개방해 +schema/identity/초기값·완료 BC·frame completeness를 확인한다. Reader close까지 성공한 뒤 +final을 교체한다. Write/candidate close/self-check/reader close/finalize 실패에서 기존 final을 보존한다. + +## 검증 의미와 재사용 교훈 + +Residual backward error는 `D_f=||A_ff||inf*||T_f||inf+||b_f||inf`의 reduced-system scale을 +사용한다. 큰 constrained 값의 full BE scale로 이를 바꾸면 RHS 상쇄 오류를 숨길 수 있다. +Direct full residual과 독립 signed construction의 enclosure 교집합으로 같은 stored-data 잔차를 +인증하며 빈 교집합은 실패다. D_f=0은 exact-zero 증명이 필요하고 interval이0을 포함한다는 +이유만으로 통과하지 않는다. 수지 bound에 방정식 구성 오차를 tolerance처럼 더하지 않는다. + +독립2-DOF C=[[2,1],[1,2]],K=[[1,-1],[-1,1]],delta=.5,old=0,g=1 fixture의 +첫 free=-.2·다음=.04·reaction4.8/1.44가 초기 용량 결합을 검출한다. 당시 시간차수 +.981712..997660, 온도 공간차수1.996702..2.006577, gradient .997220..999826을 확인했다. +Slab의24해석·147456증분과 독립 oracle는 고정5점 두께 오차 plateau와 초기 침투 깊이를 +구분했다. Slab energy/reaction oracle index 오류는 수정 후 focused 전체를 다시 실행했다. + +기존 reference Step-1/t37/DOF11 NT11은676DS4/729nodes다. CSV에 instance 열이 없어 +hash-checked 입력의 유일 instance와 결합하며 node source identity로 bottom 값을 비교한다. +원본87/729행 FAIL, RMS/S=.049674084615673214, max abs≈245.262946500919로 +공통 .01 RMS 기준을 넘었다. 독립 정식화 oracle도 같은 불일치를 보였다. 사용자 선택으로 +원 정식화·tolerance를 유지하고 이 비교만 diagnostic/nonblocking으로 분류했다. +진단 분류 테스트 PASS를 외부 수치 PASS로 바꾸지 않는다. 음수 NT11도 clamp하지 않는다. +새 모델/CSV의 별도 identity·시점·hash를 확정한 필수 비교가 남아 있다. + +초기 두께 경계층의 local flux/reaction, 일반 curved mesh의 전역 응답·점열원 수렴·실제3D +접합부는 검증 한계다. 단일 NT11 시점으로 다른 station·flux·반력·전체 시간 정확도를 +검증했다고 주장하지 않는다. +Dev 통합 승인은 새 필수 reference 통과 승인이 아니다. diff --git a/docs/solver-core/README.md b/docs/solver-core/README.md new file mode 100644 index 0000000..eccb3b6 --- /dev/null +++ b/docs/solver-core/README.md @@ -0,0 +1,71 @@ +# 솔버 공통 구조와 계약 + +FESA는 C++17 이상·Windows MSVC x64 Debug·CMake/CTest를 기준으로 하는 개인 연구용 솔버다. 승인된 Abaqus 입력 subset을 독립 모델로 해석하고 HDF5를 쓴다. Source spelling의 수용은 Abaqus 내부 요소·적분·알고리즘과의 동등성을 뜻하지 않는다. 외부 배포 형태·지원 환경·dependency 재배포 조건은 아직 정해지지 않았다. + +## 책임과 수명 + +[FesaApplication](../../include/fesa/app/fesa_application.h)과 [구현](../../src/fesa/app/fesa_application.cpp)이 입력·모델·해석·출력을 조합한다. [AbaqusDomainMapper](../../include/fesa/io/abaqus/domain_mapper.h)는 source 문법을 [Domain](../../include/fesa/model/domain.h)의 의미 모델로 연결한다. Domain은 node/element/material/property/step 정의와 source identity를 소유한다. [AnalysisModel::Create](../../include/fesa/analysis/analysis_model.h)는 복사하지 않는 active-step view이므로 Domain이 더 오래 살아야 한다. + +[DofManager](../../include/fesa/fem/dof_manager.h)가 DOF profile·equation·full/free/constrained mapping·sparse pattern을 소유한다. Node·Element·backend가 equation을 따로 발급하지 않는다. [ElementFactory](../../include/fesa/elements/element_factory.h)는 정의를 local 계산 객체로 연결한다. Element/material/load는 local 응답, [SparseAssembler](../../src/fesa/assembly/sparse_assembler.cpp)는 전역 누적, procedure executor는 trial·해법·수렴·accepted state, [ResultRecovery](../../include/fesa/results/result_recovery.h)는 물리량, writer는 직렬화·readback·finalize를 담당한다. + +병렬 local 계산은 자기 index buffer만 쓴다. Global CSR·진단·결과는 stable source/element 순서로 누적하며 hash 순서나 worker 완료 순서에 의존하지 않는다. Public core는 MKL/TBB/HDF5/Win32 타입을 노출하지 않는다. [PARDISO](../../src/fesa/solvers/linear/mkl_pardiso_solver.cpp)·[FEAST](../../src/fesa/solvers/eigen/mkl_feast_eigen_solver.cpp)·HDF5 handle은 private adapter가 관리하며 expected failure는 `Status`/`Result`로 변환한다. + +선형 정적은 full K를 stable partition하고 Kff를 load assembly보다 먼저 factorize한다. 유효한 all-constrained의 빈 free system은 singular가 아니다. 반력과 free 평형은 같은 full residual에서 복구한다. 비선형·동해석은 같은 trial의 geometry/force/tangent를 쓰고 모든 gate를 통과한 candidate만 commit한다. 실패 trial의 cache·chart·history가 accepted state나 final HDF5를 바꾸지 않는다. 불변 reference cache와 trial-dependent 응답을 구분하며 다른 trial의 factorization을 추정 재사용하지 않는다. + +## CLI와 입력 + +`fesa.exe `는 비어 있지 않은 입력 경로 하나만 받는다. `.inp`는 대소문자를 구별하지 않으며 `--output`은 없다. 상대 경로는 호출 cwd 기준 lexical normalization하고 symlink/junction/short name을 resolve해 결과 위치를 바꾸지 않는다. 결과는 입력 lexical sibling `_results.h5`, 로그는 `_log.txt`다. 결과 경로에 `.fesa.lock`을 붙인 lease는 정상 handle 종료 때 제거된다. 점유 또는 lease 생성 실패는 output failure다. Candidate 기록·self-check·close가 끝난 뒤 final을 교체하며 실패하면 이전 final을 보존한다. 로그는 실패 진단으로 갱신될 수 있고, 기존 HDF5 존재만으로 새 실행 성공을 판정하지 않는다. + +| Exit | 의미 | +| ---: | --- | +| 0 | 선택 해석과 최종 저장 성공 | +| 2 | Usage·입력 확장자 오류 | +| 3 | 읽기·문법·미지원 입력 | +| 4 | 모델 의미·구성·유효성 | +| 5 | 해법 실패 | +| 6 | Lease·로그·HDF5 저장 실패 | + +stderr 진단은 결정적 순서의 탭 구분 `severity=... code=... file=... line=... keyword=... entity_identity=... message=...` field이며 빈 source field도 보존한다. Backend 번호를 CLI exit로 그대로 반환하지 않는다. 경고가 있는 성공도 가능하다. + +입력은 physical `.inp` 하나다. 종결자 제외256 ASCII bytes 이내, printable ASCII/tab, LF/CRLF·빈 줄·`**` comment·keyword parameter continuation을 처리한다. Keyword/parameter/enum/name lookup은 ASCII case-insensitive지만 원문·line은 보존한다. 같은 값의 중복 parameter도 거부하며 comma의 빈 field를 없애지 않는다. Identity instance의 part/assembly와 하나의 step이 기본이다. Instance transform·INCLUDE·contact·MPC·비탄성·혼합 beam/shell 또는 shell/solid는 공개 subset이 아니다. Label·instance/source identity와 내부 index는 다르다. Keyword와 DOF의 정확한 허용 범위는 기능별 요약을 따른다. + +## 결과와 reference 비교 + +HDF5 reader는 feature identity·version·procedure discriminator를 함께 읽는다. 기존 linear static schema0에는 `analysis_procedure`가 없으며 이를 새 필수값으로 만들지 않는다. Nonlinear static schema1, eigen의 `eigen_schema_version=1`, 현재 shell HHT schema2와 역사적 full-coordinate schema1, solid·thermal 결과는 별도 계약이다. `Step-1`은 storage slot이다. Frequency source step은 step attribute, HHT·thermal은 metadata에서 읽고 기존 static에 source step 이름이 별도 저장됐다고 가정하지 않는다. Float64/fixed-width integer는 little-endian, 문자열은 UTF-8이며 compound는 field name/type/extent로 읽어 C++ padding에 의존하지 않는다. Input identity는 실제 읽은 bytes에 결속된다. + +Source instance/node/element/point/endpoint·step/frame·component로 일대일 대응한다. Missing/extra/duplicate row, component/schema 누락, identity 불일치, NaN/Inf는 tolerance 전에 실패한다. 위치·단위·좌표·부호가 다른 값을 평균하거나 nearest-position matching하지 않는다. Reference INP/CSV/TXT 원본을 결과에 맞춰 수정·보정·zero-clamp하지 않는다. + +공통 comparison family는 같은 case·step/frame·logical quantity·단위 차원·좌표계·판정 영향으로 묶는다. Reference만으로 `S=max|r_i|`, `B=0.01S`를 계산한다. `|r_i|<=B`이면 `|f_i-r_i|<=B`, 나머지 행은 상대오차 `<=0.05`다. 모든 행과 `sqrt(mean((f-r)^2))/S<=0.01`을 동시에 만족해야 한다. 독립 absolute tolerance·`max(1,S)` floor는 없고 `S=0`이면 FESA도 모두 exact zero여야 한다. 사전검사는 항상 blocking이며 warning-only family의 수치 실패는 경고다. 행·family·경고 순서와 원본 값·scale·metric·policy를 재현 가능하게 기록한다. + +Named exception **`mitc4-eigen-first-implementation`**(2026-09-10 승인)은 eigen2의 source modal frame별 blocking singleton `Value`에만 행 상대5%·RMS5%를 적용한다. Near-zero·zero-scale·identity/finite 검사는 유지하고 `policy_id`와 RMS0.05를 기록한다. 다른 기능·정적 U/UR/reaction은 공통 RMS1%이며 Hex8 eigen에 이 예외를 확대하지 않는다. 내부 eigen residual·정규화·직교성 `1e-10`도 유지한다. 예외는 S3 평형 충돌이나 외부 알고리즘 동등성의 해결이 아니다. + +## 개발 교훈과 검증 경계 + +수식·적분·reduction 순서·cache 수명의 변경은 수치 변경이다. Analytical/invariant·독립 numerical review·실제 물리 평형·시간수렴·reference의 검증 범위는 다르다. 프로세스 exit0·link 성공·CTest·Python suite·외부 비교를 서로 대신하지 않는다. 미실행/중단/옛 revision evidence를 현재 PASS로 승계하지 않는다. 문서만 바뀌면 source·링크·원문 보존의 정적 검토를 하고 build/test를 실행하지 않는다. + +Configure/build/test의 compiler·구성·build tree를 함께 맞추고 discovery0건·다른 compiler를 실패로 다룬다. MSVC runtime DLL staging을 확인하며 개발자 PATH의 우연한 성공을 배포 검증으로 삼지 않는다. Dense allocation 크기 곱 overflow는 할당 전에 검사한다. Header는 self-contained `.h`/guard, 파일·namespace snake_case, 타입·함수 PascalCase, 변수 snake_case, class member trailing `_`, Google 기반2-space format을 따른다. Vendor target에 FESA warning 정책을 강제하지 않는다. + +현재 공백은 shell HHT의 최신 전체 검증·시간수렴, thermal 새 필수 reference, eigen S3 partial-BC 정적 충돌, 성능 목표 미달이다. 각 기능에 구체 한계를 보존한다. 기존1×1 PARDISO 반복의 heap failure는 SpMV 없는 baseline에서도 재현됐고 vendor 원인은 미확정이다. 기본 정책의 해당 크기에만 local1-thread/TLS 복원을 적용했으며 보조100회 성공을 라이브러리 전체 해결로 확대하지 않는다. + +## 빌드와 직접 검사 + +MSVC x64 Developer PowerShell에서 저장소 root를 작업 디렉터리로 사용한다. CMake3.25 이상, +Ninja, 로컬 GoogleTest source checkout과 MKL·TBB·HDF5 개발 package가 필요하다. +`FESA_GTEST_SOURCE_DIR`은 GoogleTest의 CMakeLists.txt가 있는 source root이고, +`MKL_DIR`·`TBB_DIR`·`HDF5_DIR`은 각각 package config 파일이 있는 디렉터리다. +환경 변수에 로컬 경로를 지정한 뒤 [CMake presets](../../CMakePresets.json)의 직접 명령을 사용한다. + +```powershell +cmake --preset windows-msvc-ninja-debug +cmake --build --preset windows-msvc-ninja-debug +ctest --preset windows-msvc-ninja-debug --show-only=json-v1 +ctest --preset windows-msvc-ninja-debug --output-on-failure +``` + +Debug build tree는 `build/windows-msvc-ninja-debug`, 별도 Release는 +`build/windows-msvc-ninja-release`이며 configure/build preset 이름도 각각 대응한다. +Debug와 Release의 binary·test inventory·evidence를 섞지 않는다. CTest discovery와 실제 +종료 코드를 함께 확인한다. Python 검사가 필요하면 해당 suite를 별도로 실행하며 CTest에 +포함됐다고 추론하지 않는다. [CMake](../../CMakeLists.txt)의 `fesa_docs` target은 Doxygen을 +찾았을 때만 생성되므로 선택적 API 문서 산출물이다. CLI executable은 각 build tree의 +`src/fesa/fesa.exe`이며 dependency runtime DLL을 함께 준비한다.