78 lines
8.6 KiB
Markdown
78 lines
8.6 KiB
Markdown
# C++ 모듈화와 공개 API 정리
|
|
|
|
기존 B33/MITC4 솔버의 모델·local 계산·assembly·procedure·backend·I/O 책임을 분리하고 공개 header의 vendor 의존을 격리한 리팩터링이다. 새 물리·입력·해법·결과 schema 또는 tolerance를 도입하는 기능이 아니다. 현재 재사용할 구조·CLI·I/O·수치 비교 계약은 [solver-core](../solver-core/README.md)에 모았다.
|
|
|
|
## 설계와 실제 데이터 흐름
|
|
|
|
[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)는 직렬화한다.
|
|
|
|
[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을 공개하지 않는다.
|
|
|
|
## 보존한 입력·출력과 비교 의미
|
|
|
|
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가 소유한다.
|
|
|
|
## Refactor 코드 채택 후 구조
|
|
|
|
2026-10-18 통합은 FESADev `7438c827` 이력에 Refactor `11f09eeb`의 제품 `.h/.cpp`
|
|
274개와 직접 MSVC 빌드를 선별 도입한다. 옛 구현을 섞는 호환 계층이나 새 정식화는 추가하지 않는다.
|
|
[파일 manifest](merge-manifest.json)는 원본 Git blob과 working bytes, 보존·도입 방침을 구분하고,
|
|
[테스트 이관표](test-migration.tsv)는 양쪽 기존 identity·assertion·oracle와 최종 위치를 연결한다.
|
|
|
|
- [AnalysisProcedure](../../include/fesa/analysis/analysis_procedure.h)와
|
|
[factory](../../src/fesa/analysis/prepared_analysis.cpp)는 shell linear/nonlinear static,
|
|
eigen, HHT, thermal과 solid static/frequency/HHT를 선택한다. 실행 수명은 호출자 adapter보다 짧다.
|
|
[PreparedAnalysisOutcome](../../include/fesa/analysis/prepared_analysis_outcome.h)은 family별
|
|
typed completed payload를 유지하고, [결과 dispatch](../../src/fesa/results/prepared_results_writer.cpp)는
|
|
검증된 payload를 해당 writer로 보낸다. 기존 schema·atomic finalize 의미는 유지한다.
|
|
- [Element capabilities](../../include/fesa/elements/element_capabilities.h)는 ShellTrialElement,
|
|
SolidTrialElement, ShellInertiaElement, ThermalElement, ShellReferenceElement를 분리한다.
|
|
Adapter는 immutable kernel을 빌리므로 kernel의 수명과 주소가 안정적이어야 한다.
|
|
Equation·accepted history는 요소에 두지 않는다. Local layout과 full response를 typed로 보존한다.
|
|
- [EquilibriumAlgorithm/EquilibriumStep](../../src/fesa/analysis/equilibrium_algorithm.h)는
|
|
iteration 순서와 procedure-local typed pending candidate를 분리한다. Algorithm은 candidate를
|
|
소유하거나 type-erase하지 않는다. Static은1, mechanical HHT는0에서 시작하는 inclusive 순서를 유지하고,
|
|
procedure의 검증·commit 경계가 accepted state를 바꾼다.
|
|
- [ShellHhtIntegrator](../../src/fesa/analysis/hht_reduced_integrator.h)는 predictor·rate 계산·
|
|
physical-rate 복원을 분리한다. Chart/root/solver와 callback은 동기 borrowed view이며
|
|
rate 출력 buffer는 호출자 소유로 입력·서로와 alias하지 않는다. `RunReducedHhtStep`은
|
|
predictor→pending endpoint→commit 순서만 조정하고 accepted history를 소유하지 않는다.
|
|
- [PARDISO Session](../../src/fesa/solvers/linear/pardiso_session.h)은 private factor/solve/release
|
|
수명을 공통화한다. 기존1×1 TLS 회피의 범위를 vendor 전체 해결로 확대하지 않는다.
|
|
[SparsePattern](../../include/fesa/math/sparse_pattern.h)은 CSR 값 구조이며 지속 backend cache가 아니다.
|
|
[SpMV](../../src/fesa/math/sparse_matrix.cpp)는 여전히 호출마다 변환 배열·값 복사·handle을 소유한다.
|
|
|
|
수식·적분·reduction 순서·cache 수명에 영향이 있는 도입 차이는 manifest에 따로 분류했다.
|
|
출처 일치·compile·테스트 통과만으로 수치 동등성을 선언하지 않으며 독립 수치 검토와
|
|
영향받은 analytical/invariant·물리·reference 검증을 별도로 수행한다.
|
|
|
|
## 이번 병합의 현재 검증 상태
|
|
|
|
직접 MSVC와 CMake/Ninja의 Debug solver/CLI 및 세 테스트 target build가 완료됐다.
|
|
제품274개는 Refactor working bytes와 일치한다. 양쪽 실제 discovery는 unit849,
|
|
integration72, reference43으로 총964개이며 canonical identity가 일치한다.
|
|
최종 선별 실행은 CMake176개, Native15개, 합성 reference comparator28개,
|
|
Python145개가 failure/error/skip 없이 통과했다. 이는 전체964개 실행·실제 모델 비교 완료가 아니다.
|
|
근거는 작업 공간의 `.build/merge-verification/t2-20261018-01/`와
|
|
`t3-20261018-01/`에 있다. 원래 dev와 Refactor 저장소 및 기준자료는 보존했다.
|
|
|
|
2026-10-18 사용자 지시로 `reference/temp`는 검증에 사용하지 않는다. 정식 경로에 없는
|
|
`shellNL-meshfine`, `shellNL-meshfine_02`, `shellNL-meshfine-pressure` 자료는 복사·복원하지 않는다.
|
|
해당 실제 비교는 자료 미확보로 미완료이며 테스트를 skip 처리하거나 통과로 바꾸지 않는다.
|
|
전체 Debug 검증·독립 수치 검토·정식 자료의 필수 비교는 후속 실행 대상이다.
|
|
정리 전 필수 검증을 충족하지 못하면 테스트 삭제와 최종 병합 완료 판정을 진행하지 않는다.
|
|
문서 갱신 자체로 build/test를 추가 실행하지 않았다.
|