feat(cpp-object-oriented-modular-refactoring): step 2 - architecture-boundaries

This commit is contained in:
KOKO\Mimi
2026-08-16 03:27:17 +09:00
parent f289b437df
commit f43fbd7dd1
2 changed files with 213 additions and 43 deletions
+81 -5
View File
@@ -35,7 +35,12 @@ solution과 test command를 명시한 직접 MSBuild 프로젝트도 검증할
**트레이드오프**: 사용자는 기존 Abaqus input file을 그대로 사용할 수 없을 수 있다. 대신 지원 범위와 실패 원인이 명확해진다.
### ADR-004: Domain, AnalysisModel, DofManager, AnalysisState를 분리한다
**결정**: `Domain`입력 모델 정의를 소유하고, `AnalysisModel`은 현재 step의 실행 view를 제공하며, `DofManager`는 equation numbering과 constrained/free mapping을 전담하고, `AnalysisState`는 해석 중 변하는 물리량을 소유한다.
**결정**: `Domain``ElementDefinition`, `ElementProperty`, `Material`
`StepDefinition` 입력 모델 정의를 `std::unique_ptr`로 단독 소유하고 const access와
stable collection index를 제공한다. `AnalysisModel`은 Domain 수명 안에서 stable index와
const reference만 사용하는 non-owning current-step view다. `DofManager`는 equation
numbering과 constrained/free mapping을 전담하고, `AnalysisState`는 해석 중 변하는
물리량을 소유한다.
**이유**: 모델 정의, step activation, equation system, transient/nonlinear state가 섞이면 parser, assembler, solver, result writer가 강하게 결합된다. 분리된 상태 모델은 선형 정적 해석에서 시작해 비선형, 동적, thermal coupling으로 확장하기 쉽다.
@@ -57,12 +62,25 @@ solution과 test command를 명시한 직접 MSBuild 프로젝트도 검증할
**트레이드오프**: 단일 기능만 구현할 때는 adapter가 다소 장황해 보일 수 있다. Row-major dense storage와 CSR sparse storage를 따로 유지해야 하지만 backend 의존성과 dense/sparse 의미가 core 모델에 섞이지 않는다.
### ADR-007: Analysis 실행 흐름은 Template Method로 고정한다
**결정**: `Analysis::run()`은 공통 lifecycle을 고정한다. 선형 정적 V0의 순서는 `parse input -> initialize Domain -> build AnalysisModel -> build DOF map/sparse pattern -> assemble stiffness -> partition constraints -> factorize Kff -> assemble load -> form effective RHS -> substitute -> reconstruct displacement -> recover results -> write HDF5`다. 강성행렬 factorization은 하중벡터 조립보다 먼저 수행하고, factorization과 substitution을 하나의 불투명한 solve 호출로 합치지 않는다.
### ADR-007: Analysis base는 최소 실행 계약만 제공한다
**결정**: `Analysis` base는 virtual `Analysis::Run(const AnalysisRequest&)`만 제공하고
linear-static-specific protected hook을 정의하지 않는다. 승인된 선형 정적 순서인
`parse input -> initialize Domain -> build AnalysisModel -> build DOF map/sparse pattern ->
assemble stiffness -> partition constraints -> factorize Kff -> assemble load -> form effective
RHS -> substitute -> reconstruct displacement -> recover results -> write HDF5`
`LinearStaticAnalysis::Run()`의 private lifecycle로 유지한다. 강성행렬 factorization은
하중벡터 조립보다 먼저 수행하고 factorization과 substitution을 하나의 불투명한 solve
호출로 합치지 않는다.
**이유**: 해석 procedure가 늘어나도 공통 실행 순서가 유지되어야 검증, logging, result writing, failure classification이 일관된다. Factorization과 substitution을 분리하면 동일 강성행렬에 여러 RHS를 적용할 수 있고 각 실패 단계를 구조화된 diagnostic으로 분류할 수 있다.
**이유**: 현재 여덟 단계는 linear static equation, state와 failure taxonomy에 특화되어
있다. 최소 base contract는 이 순서의 검증 가능성을 보존하면서 승인되지 않은 dynamic,
eigenvalue 또는 nonlinear procedure에 같은 protected hook과 사용하지 않는 state를
강제하지 않는다. Factorization과 substitution 분리는 동일 강성행렬에 여러 RHS를 적용할
수 있고 각 실패 단계를 구조화된 diagnostic으로 분류하게 한다.
**트레이드오프**: 특수 해석 절차가 공통 흐름에 맞지 않는 경우 hook point가 필요하다. 초기에는 선형 정적 해석을 기준으로 최소 hook만 둔다.
**트레이드오프**: Procedure 사이의 lifecycle code는 base Template Method로 자동 재사용되지
않는다. 두 번째 procedure가 승인되면 실제로 같은 단계만 focused collaborator로 추출하되,
linear-static hook 사이에 조건문으로 새 physics를 삽입하지 않는다.
### ADR-008: Sparse assembly는 deterministic COO-to-CSR 경로로 시작한다
**결정**: 초기 assembly는 element-local contribution을 COO triplet으로 수집한 뒤 CSR로 finalize한다. MKL PARDISO backend는 CSR input contract를 받는다.
@@ -230,3 +248,61 @@ displacement 검증 목적에 맞지 않는다. 고정 절대오차는 현재
**트레이드오프**: Model scale이 크게 달라지면 고정 절대오차의 상대적 엄격도가 달라질 수
있다. 따라서 이 값은 현재 승인된 MITC4 S4 case의 기능 완료 기준이며 개발 완료 후
별도 reference-verification evidence와 함께 재점검한다.
### ADR-021: Semantic definition과 runtime solver contract를 분리한다
**결정**: Domain-owned semantic definition과 analysis-time numerical object를 다음
dependency 방향으로 분리한다.
```text
Domain owns ElementDefinition / ElementProperty / Material / StepDefinition
AnalysisModel is a non-owning stable-index view into Domain
ElementFactory creates runtime Element candidates from compatible definitions
DofManager -> ElementDofLayout
SparseAssembler -> ElementStiffnessContribution
ResultRecovery -> ElementResultBundle
LoadAssembler -> ordered LoadContribution
EssentialConstraintPolicy -> ConstraintDefinition
Analysis <- LinearStaticAnalysis
```
`Domain`의 polymorphic semantic collection은 `std::unique_ptr` 단독 ownership과 stable
vector position을 사용한다. `ElementDefinition`은 source identity, connectivity와
property/material identity를 제공하고 runtime `Element`는 DOF layout, stiffness와 result
recovery를 제공한다. `ElementFactory`가 definition/property/material compatibility를
중앙에서 검사하며 unknown 또는 incompatible 조합은 fail-closed diagnostic으로 거부한다.
Consumer는 B33/MITC4 concrete type branch를 분산시키지 않고 runtime contract를 사용한다.
Linear-static candidate가 runtime `Element``std::unique_ptr`로 소유하고 consumer는 그
수명에 한정된 non-owning view만 사용한다.
`Material` base에는 identity, source location과 lifetime 이외의 future capability를
추가하지 않는다. 현재 isotropic linear elasticity가 실제로 요구하는 data는 concrete
material에 둔다. Density, anisotropy, plastic state, temperature와 rate dependency는
optional field 또는 no-op virtual method로 미리 할당하지 않는다. `ElementProperty`
현재 beam/shell 의미를 각 concrete type에 둔다.
`Load`는 ordered `LoadContribution`을 생성하고 global full-DOF accumulation은
`LoadAssembler`가 단독 소유한다. `BoundaryCondition``ConstraintDefinition`을 생성하고
`EssentialConstraintPolicy`가 prescribed-displacement elimination과 reconstruction을
소유한다. Distributed/body load와 MPC/penalty/Lagrange-multiplier enforcement는 이번
결정으로 구현된 기능이 아니다.
Abaqus Domain mapper, result recovery와 HDF5 writer는 기존 public facade를 유지하면서
각각 topology/material-property/step-final-assembly, equilibrium/beam/shell/atomic-state,
RAII/model-result-dataset/self-check/atomic-finalization 책임으로 private implementation을
나눈다.
**이유**: Semantic identity와 runtime kernel을 같은 concrete record에 두면 DofManager,
SparseAssembler, ResultRecovery, parser와 output이 B33/MITC4 storage를 함께 알아야 한다.
Definition/factory/runtime contract와 contribution/policy 경계를 분리하면 stable source
identity와 deterministic reduction owner를 유지하면서 실제 두 element 구현을 공통
consumer로 연결할 수 있다. Focused facade 분할은 외부 계약을 바꾸지 않고 큰 translation
unit의 서로 다른 failure-atomicity 책임을 검토 가능하게 한다.
**트레이드오프**: Base object, factory와 contribution record가 늘고 checked compatibility에
한 단계의 indirection이 생긴다. 대신 `std::shared_ptr`, speculative `Clone()`, global
registry와 future-only material/analysis capability는 도입하지 않는다. B33/MITC4의 승인된
formulation, 연산·reduction 순서, sign, units, coordinates와 result identity가 이
리팩터링보다 우선하며 HDF5 schema, reference artifact와 ADR-014/ADR-020 tolerance는
변경하지 않는다. MITC3, solid, dynamic과 plastic behavior는 별도 feature gate 전까지
구현된 것으로 간주하지 않는다.