# Shell 과도 열전달 구현·검증 기록 - Feature ID: `shell-transient-heat-transfer` - Owner: 메인 assistant - 상태: 기존 전체 baseline 확보; 열해석 구현·검증 진행 중. 제품 검증 완료가 아니다. - 기준: [PRD](PRD.md), [ADR](ADR.md), [정식화](formulation.md), [독립 수치 검토](numerical-review.md), [공통 tolerance](../TOLERANCE.md). ## Production 변경 전 baseline 검사 대상 source revision은 `a3502c9b974bc17698d57438274408f29317ced4`다. 검사 도중 reference 두 파일만 `e6fd9e9`에 추가했으며 production source와 테스트는 변경하지 않았다. 정식화·계약 문서 편집은 별도 task checkout에서 수행했다. Windows MSVC x64 Debug, CMake/Ninja와 기존 설치된 의존성을 사용했다. MSVC toolset 14.51.36231, oneAPI MKL 2026.1, TBB 2023.1, HDF5 2.1.1 및 승인 local GoogleTest checkout을 사용했다. 머신별 절대 경로는 개인 실행 환경에만 둔다. 저장소에 `.harness/config.json`이 없어 직접 preset을 실행했다. | 실행 | Captured exit | 관찰 | | --- | --- | --- | | `cmake --preset windows-msvc-ninja-debug -DCMAKE_PROJECT_FESA_INCLUDE=` | 0 | Configure 완료; 추가 task source overlay 없음 | | `cmake --build --preset windows-msvc-ninja-debug --parallel 4` | 0 | 전체 baseline build 완료; compiler warning 검색 결과 없음 | | `ctest --preset windows-msvc-ninja-debug --show-only=json-v1` | 0 | 478개 검사 발견 | | `ctest --preset windows-msvc-ninja-debug --output-on-failure` | 8 | 478개: 475 PASS, 2 FAIL, 1 SKIP. 3480.67초; 전체 검사 제외 없음 | 실제 로그·argv·revision·exit·완료 시각은 로컬 `.dryforge/evidence/baseline-*.log`와 각 `.log.json`에 보존한다. 전체 CTest 로그도 `.dryforge/evidence/baseline-LastTest.log`에 복사해 후속 실행으로 덮어쓰이지 않도록 보존했다. Native CTest exit은 8이고 외부 PowerShell 실행 도구는 실패 exit 1을 반환했다. 아래 표는 실제 로그의 값을 요약한다. ### 기존 HHT 실패 `HhtShellPhysics.C08aRigidManufacturedOrbitFullCoordinateTimeConvergence`는 828.34초 실행 후 실패했다. 여섯 channel의 정의와 원래 판정은 `tests/unit/analysis/hht_shell_physics_test.cpp`의 해당 검사 그대로다. | 실패 metric | 실제 값 | 기존 기준 | | --- | --- | --- | | Channel 3 최종 refinement error / noise floor | `1.178006582488537e-6` / `1.664587376115457e-6` | error > noise floor | | Channel 5 마지막 시간격자의 최대 error | `5.675659240050177e-4` | <= `1e-4` | | Channel 5 두 refinement order | `1.0286686694389584`, `1.0289692381730642` | 각각 >= `1.8` | | Channel 5 error / noise floor | `5.675659240050177e-4` / `8.1556816896757325e-4` | error > noise floor | `HhtShellPhysics.C08bFreeFiniteRotationPlateSelfConvergenceAndPhysicalInvariants`는 2382.81초 실행 후 실패했다. 마지막 공통시간 차이는 다음과 같다. | Channel | 마지막 self-difference | 기존 기준 | | --- | --- | --- | | q_u | `5.5474274071377627e-6` | <= `1e-4` (이 항목은 통과) | | q_phi | `1.3870090193204238e-4` | <= `1e-4` | | v_u | `1.7761250930811503e-4` | <= `1e-4` | | v_phi | `1.15434079805253e-2` | <= `1e-4` | | a_u | `1.1979645042237048e-2` | <= `1e-4` | | a_phi | `8.6893881162834119e-1` | <= `1e-4` | q_phi/v_phi/a_u/a_phi의 마지막 두 관측 차수는 각각 `(-.1538334889569796,.17869938751647654)`, `(-.084636748464689021,.057860368459572473)`, `(.4062904963410236,.20093674620022031)`, `(-.15578672026532631,.17674898422982255)`로 기존 `>=1.8`에 미달했다. v_u의 마지막 차수도 `.85658192310858094`로 미달했다. Linear momentum drift의 마지막 세 값은 `3.8504721819452428e-14`, `4.8249991985258491e-14`, `2.004031863681472e-13`으로, 원래 strict decrease와 마지막 비율 `<=.6` 검사도 실패했다. 작은 값이라는 이유로 면제하지 않는다. 최종 energy/L drift는 `9.5590394502167011e-7` / `4.2974921804532845e-7`이었다. 이 실패 양상은 [기존 HHT physics 검토](../hht-implicit-dynamics/physics-evaluation.md)의 미해결 C08 범위와 일치하며 열해석 변경 이전에 재현했다. ### 기존 HHT N7 inconclusive `HhtTemporalVerification.C04aFinestReductionComparisonIsNumericallyResolved`는 기존 테스트의 명시 `GTEST_SKIP()` 분기로 SKIP이었다. Full/reduced acceleration defect `3.0790209097630861e-10`이 기존 비교 기준 `1e-10`보다 크지만 arithmetic/solve resolution `6.2961354117696263e-10` 이하인 경우를 N7 INCONCLUSIVE로 표시하는 원래 검사다. 원인과 범위를 `tests/unit/analysis/hht_temporal_verification_test.cpp:478` 및 실제 출력으로 대조했다. 환경 누락이나 열 기능의 미실행이 아니며, 이 항목을 PASS로 세지 않는다. 최종 전체 검사에서도 이 분류와 metric을 대조하고 새 skip으로 검증을 회피하지 않는다. 승인된 예외는 재현된 무관한 기존 HHT 실패의 별도 보존뿐이다. 마지막 전체 검사에서 동일 metric을 대조하여 새 실패·악화 여부를 확인한다. 기존 실패를 PASS/SKIP으로 바꾸거나 전체 CTest green으로 보고하지 않는다. 예상하지 못한 실패와 열해석 필수 실패는 자동 면제하지 않는다. ## Reference 복사와 원본 보존 `git worktree list --porcelain`으로 확인한 동일 저장소 `dev` checkout의 `reference/shell-thermal/`에서 다음 두 파일을 같은 상대 경로로 byte 그대로 복사했다. 원본과 복사본의 SHA256이 각각 일치했고, 복사본을 `e6fd9e9`에 기록했다. | 파일 | 원본과 복사본의 SHA256 | | --- | --- | | `shell-thermal.inp` | `955C8BEEC35CE53DA5F5DD48785CF8C12FCE726EBFDE7EAE40CF69DBF00D6EA4` | | `shell-thermal NodalTemperature.csv` | `765B0D0F64C24CDE6D033D6EF80E0267275A496C97E28D932466EB877810D3E5` | Abaqus 실행·reference 재생성·이름 변경·내용 보정은 수행하지 않았다. 이 hash 확인은 FESA/reference 수치 비교 통과 evidence가 아니다. ## 구현 및 최종 검증 ### 구현 전 수치 계약 정식화와 승인 범위의 정합, 전체 patch certificate, source 접속, 시간격자·오차·수렴·slab 검증 기준을 작성하고 독립 수치 검토를 마쳤다. 검토 대상 정식화의 마지막 수식 변경은 `dd409b5`, 독립 보고서의 최종 보완은 `6df5a17`이다. 설계상 blocking 지적은 해결했다. 소스 구현의 정확도 통과 판정은 아니다. - 전역 T-edge 좌표 검사를 source endpoint를 공유하는 후보로 제한하여 disconnected 접촉을 구별했다. - 입력 rounding-cell을 놓치는 시간격자 반례를 발견하고 정확한 cell overlap으로 보완했다. Production은 최대 122비트의 고정 폭 연산이며 새 임의정밀도 의존성을 요구하지 않는다. - 공간수렴 검증은 8/16/32/64 정사각 mesh, `T=.001`, 32증분으로 고정했다. 기존 관찰 차수 기준을 유지하고 시간오차/공간오차 비율의 최대값 `.006864`를 확인했다. 가장 큰 mesh의 온도·flux 원시 이력은 약 77.3MiB다. - 고정5점의 초기 slab 오차·warped 3×3 적분 오차는 별도로 정량화했다. 통합된 문서의 [독립 oracle 부록](numerical-oracle-scratch.md)의 Python block 5개를 메인이 다시 추출 실행했다. Captured Python exit 0, `ALL SCRATCH BLOCKS COMPLETED`를 확인했고 출력은 `.dryforge/evidence/t1-oracle-replay.log`에 보존했다. 기능 문서의 링크·anchor·요구사항 ID 및 `git diff --check`도 통과했다. 문서 변경을 이유로 solver build/CTest를 반복하지 않았다. ### Thermal semantic model 열물성·Domain·AnalysisModel semantic 구현을 `254247e`, `283628e`로 작성하고, 독립 코드 검토에서 해당 범위의 잔여 차단 항목이 없음을 확인했다. BC/CFLUX는 source DOF 11·15만 허용한다. 열 재료·단면의 local index와 전체 Domain material index를 구분하며, 구조 step 접근을 열 모델에 잘못 호출하면 명시적으로 실패한다. 두 단계 BC는 원본 수준별 정의를 보존하며 최종 상속·override는 후속 입력/실행 연결의 책임이다. Endpoint 제한의 행동 재현 검사에서 기존 구현이 12·13·14를 수용하여 CTest exit 8을 확인했고 수정 후 통과했다. 이전 API 누락에 의한 compile 실패는 행동 재현 evidence로 계산하지 않는다. 잘못된 물성·두께, 비활성 target, 초기값·BC 충돌, constrained CFlux 중복·순서 보존, 이동 후 소유 데이터 접근과 다중 재료 인덱스를 검사했다. 작업 checkout의 clean MSVC x64 Debug build와 최종 fixture 추가 후 incremental build는 각각 exit 0이다. 최종 관련 CTest는 **21/21 PASS**, exit 0이며 compiler warning은 검색되지 않았다. 실제 evidence는 `t2-correction-clean-build-build.log`, `t2-correction-final-build-build.log`, `t2-correction-final-regression-test.log` 및 각 명령·cwd·native exit JSON에 보존했다. 실행 당시 HEAD는 commit 전 `254247e`이고, 최종 검사 09:47:06 UTC 후 동일 수정분을 `283628e`로 기록했다. 검증 중 한국어 MSVC `/showIncludes` prefix가 CMake에서 잘못 decode되어 Ninja가 header dependency를 0개로 기록하는 환경 문제를 발견했다. Header 변경 후 이전 객체를 재사용하여 AnalysisModel 접근 오류가 발생했다. 개인 검증 환경에서 실제 UTF-8 prefix를 지정하고 clean build한 뒤 같은 객체의 dependency가 47개이며 관련 header를 포함함을 확인했다. 잘못된 추적 상태의 중간 incremental 결과는 최종 evidence로 사용하지 않는다. Production 변경 전 baseline은 175개 build action을 처음부터 실행한 결과로 유지한다. 공통 CMake source/test 등록 후 통합 checkout에서도 clean build exit 0, CTest inventory **487개**, 관련 semantic·기존 structural DOF 검사를 포함한 **29/29 PASS**를 확인했다. Evidence는 `.dryforge/evidence/semantic-integrated-{configure,build,test}.log`와 `semantic-integrated-serial-inventory.log`다. 최초 inventory와 test를 동시에 시작했을 때 GoogleTest discovery의 공용 JSON 생성이 경합하여 inventory exit 8이 발생했다. 직렬 inventory 재실행은 exit 0이며, 이후 같은 build tree의 discovery/test는 직렬 실행한다. ### Thermal DOF 매핑 `e71f3ad`, `17a2355`의 열 5성분 profile, 활성 절점 번호, 20-entry scatter, partition과 CSR 매핑을 독립 검토했다. Canonical 11..15 순서, 비연속 반복 절점, 잘못된 enum 범위, 구조/열 profile 오용을 거부한다. 미사용 절점이 중간에 있는 경우와 공유 edge·분리 영역, BC 상속·override, 실패 후 전체 mapping 보존을 확인했다. `t4-final3-build.log`는 native exit 0, `t4-final3-test.log`는 **13/13 PASS**, exit 0이다. 이 중 기존 structural DofManager 검사는 8개다. `t4-final2-inventory.log`의 491개는 discovery 수이며 전체 실행 수가 아니다. 검사 후 마지막 수정은 줄바꿈·들여쓰기뿐임을 독립 reviewer가 확인했고, 범위 내 잔여 차단 항목 없이 `7b9a36c`로 통합했다. 요소 kernel과 결합한 통합 검사는 kernel 완료 후 수행한다. PATH 밖의 설치된 clang-format을 확인한 뒤 새 semantic 파일의 서식을 적용했다. `8ba4d18`은 세 신규 파일의 서식 수정이며 관련 신규 header/source/test의 dry-run 검사는 exit 0이다. 앞선 수동 서식 확인을 formatter 실행으로 대신 주장하지 않는다. ### 시간격자 독립 실행 확인 요소 kernel과 분리된 시간격자 checkpoint `e33ee6a`를 독립 검토자가 별도 실행기로 컴파일했다. Production의 binary64 입력 cell 판정을 exact Fraction oracle의 **11,043개 사례**에 대조했고, 유효 11,030개와 입력·INC 거부 13개에서 불일치가 없었다. **66,023개 Frame 표본**의 저장 시각·실제 delta가 비트 단위로 일치했다. 기본 INC=100, 범위 밖 Frame 거부와 진단도 확인했다. MSVC `/Od /W4 /WX /fp:precise` standalone build, runner 및 비교기는 각각 native exit 0이다. 원래 subnormal 간격, open/closed midpoint, 최대 finite, 실제 shortened 마지막 증분과 거대한 count의 O(1) 사전검사를 포함한다. Evidence는 작업 checkout의 `.dryforge/review/time_grid_e33ee6a/`에 committed source manifest, 실제 출력, `comparison.json` 및 실행 명령으로 보존했다. 이는 시간격자에 한정한 evidence이며 kernel·procedure·physics의 최종 판정을 대신하지 않는다. 전체 thermal 검사, NT11 외부 수치 비교와 실제 결과의 독립 physics 평가는 아직 수행하지 않았다.