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을 그대로 사용할 수 없을 수 있다. 대신 지원 범위와 실패 원인이 명확해진다. **트레이드오프**: 사용자는 기존 Abaqus input file을 그대로 사용할 수 없을 수 있다. 대신 지원 범위와 실패 원인이 명확해진다.
### ADR-004: Domain, AnalysisModel, DofManager, AnalysisState를 분리한다 ### 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으로 확장하기 쉽다. **이유**: 모델 정의, 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 모델에 섞이지 않는다. **트레이드오프**: 단일 기능만 구현할 때는 adapter가 다소 장황해 보일 수 있다. Row-major dense storage와 CSR sparse storage를 따로 유지해야 하지만 backend 의존성과 dense/sparse 의미가 core 모델에 섞이지 않는다.
### ADR-007: Analysis 실행 흐름은 Template Method로 고정한다 ### ADR-007: Analysis base는 최소 실행 계약만 제공한다
**결정**: `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 호출로 합치지 않는다. **결정**: `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 경로로 시작한다 ### ADR-008: Sparse assembly는 deterministic COO-to-CSR 경로로 시작한다
**결정**: 초기 assembly는 element-local contribution을 COO triplet으로 수집한 뒤 CSR로 finalize한다. MKL PARDISO backend는 CSR input contract를 받는다. **결정**: 초기 assembly는 element-local contribution을 COO triplet으로 수집한 뒤 CSR로 finalize한다. MKL PARDISO backend는 CSR input contract를 받는다.
@@ -230,3 +248,61 @@ displacement 검증 목적에 맞지 않는다. 고정 절대오차는 현재
**트레이드오프**: Model scale이 크게 달라지면 고정 절대오차의 상대적 엄격도가 달라질 수 **트레이드오프**: Model scale이 크게 달라지면 고정 절대오차의 상대적 엄격도가 달라질 수
있다. 따라서 이 값은 현재 승인된 MITC4 S4 case의 기능 완료 기준이며 개발 완료 후 있다. 따라서 이 값은 현재 승인된 MITC4 S4 case의 기능 완료 기준이며 개발 완료 후
별도 reference-verification evidence와 함께 재점검한다. 별도 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 전까지
구현된 것으로 간주하지 않는다.
+132 -38
View File
@@ -32,7 +32,7 @@ src/
assembly/ # deterministic stiffness/load assembly, ParallelFor adapter assembly/ # deterministic stiffness/load assembly, ParallelFor adapter
constraints/ # essential-constraint elimination and reconstruction constraints/ # essential-constraint elimination and reconstruction
core/ # source identity, status, diagnostics core/ # source identity, status, diagnostics
elements/ # V0 EulerBeam3D kernel and recovery elements/ # current B33/MITC4 kernels and recovery
fem/ # DOF/equation numbering and sparse pattern fem/ # DOF/equation numbering and sparse pattern
io/ io/
abaqus/ # .inp syntax reader and semantic Domain mapper abaqus/ # .inp syntax reader and semantic Domain mapper
@@ -62,9 +62,11 @@ scripts/
phases/ # Optional generated phase plans phases/ # Optional generated phase plans
``` ```
`materials/`, nonlinear/dynamic analysis, MPC/penalty policies, general element factories, `materials/`, `properties/`, `loads/`와 checked `ElementFactory`는 승인된 C++ modular
history output과 production validation module은 장기 확장 경계이지 현재 구현된 module refactoring의 target boundary이며 후속 implementation Step에서 추가한다.
아니다. 새 디렉토리와 추상 계층은 승인된 기능이 실제로 필요로 할 때 추가한다. documentation-only Step 시점에는 현재 구현 디렉토리로 표시하지 않는다. Density,
plasticity, anisotropy, nonlinear/dynamic analysis, MPC/penalty, history output과 production
validation module은 계속 장기 확장 경계이며 별도 승인 기능이 필요하다.
## Harness Execution Layer ## Harness Execution Layer
@@ -109,16 +111,86 @@ CMake source에 기록하지 말고 config package와 imported target metadata
## 모듈 경계 ## 모듈 경계
- `core`는 외부 라이브러리에 의존하지 않는다. - `core`는 외부 라이브러리에 의존하지 않는다.
- `io/abaqus`는 syntax와 semantic mapping만 담당하고 해석 알고리즘을 알지 않는다. - `io/abaqus`는 syntax와 semantic mapping만 담당하고 해석 알고리즘을 알지 않는다.
- `model`은 Abaqus keyword 문자열이 아니라 solver semantic model을 가진다. - `model`은 Abaqus keyword 문자열이 아니라 solver semantic model을 가지며 `Domain`
non-owning `AnalysisModel`의 수명 경계를 소유한다.
- `materials``properties`는 Domain이 소유하는 semantic identity와 현재 승인된
isotropic elasticity 및 beam/shell property data만 제공한다.
- `elements`는 Domain-owned `ElementDefinition`, runtime numerical `Element`, checked
`ElementFactory`와 element-local stiffness/recovery contract를 제공한다.
- `fem``DofManager`는 DOF, equation ordering, scatter와 sparse pattern을 소유한다. - `fem``DofManager`는 DOF, equation ordering, scatter와 sparse pattern을 소유한다.
- `elements`는 local/global stiffness, transformation, optional load kernel과 recovery를 제공한다. V0 material/section은 concrete Domain record다. - `assembly`는 runtime element contribution과 ordered load contribution을 stable full-DOF
- `assembly`는 element-local contribution과 full nodal load를 stable full-DOF space에 조립한다. space에 조립한다. Contribution producer는 global storage를 직접 갱신하지 않는다.
- `constraints`는 V0 essential BC elimination과 full/reduced vector 변환을 담당한다. MPC와 penalty는 현재 범위가 아니다. - `loads`는 semantic target과 magnitude를 소유하고 ordered `LoadContribution`을 생성한다.
- `constraints``ConstraintDefinition` 생성과 V0 essential BC elimination 및 full/reduced
vector 변환을 분리한다. MPC와 penalty는 현재 범위가 아니다.
- `solvers``LinearSolver` 뒤에 MKL PARDISO 세부 구현을 감춘다. TBB는 `assembly/ParallelFor`, HDF5는 `results/ResultsWriter` 경계 뒤에 각각 격리된다. - `solvers``LinearSolver` 뒤에 MKL PARDISO 세부 구현을 감춘다. TBB는 `assembly/ParallelFor`, HDF5는 `results/ResultsWriter` 경계 뒤에 각각 격리된다.
- `analysis`는 step/history data를 받아 procedure를 실행하고 solver backend와 result writer를 조율한다. - `analysis`는 step/history data를 받아 procedure를 실행하고 solver backend와 result writer를 조율한다.
- `results`는 full residual과 beam rows를 복구하고 backend-neutral writer contract를 제공한다. HDF5 schema 구현은 `io/hdf5`가 담당한다. - `results`는 full residual과 B33/MITC4 rows를 복구하고 backend-neutral writer contract를
제공한다. HDF5 schema 구현은 `io/hdf5`가 담당한다.
- test helper는 production parser/solver 내부 상태를 우회하지 않는다. - test helper는 production parser/solver 내부 상태를 우회하지 않는다.
## 승인된 리팩터링 dependency와 ownership
다음 graph는 C++ object-oriented modular refactoring의 구현 방향을 고정한다. `owns`
단독 수명 소유권을, 나머지 화살표는 왼쪽 consumer가 오른쪽 contract를 사용한다는
뜻이다. 이 graph는 기존 B33/MITC4 물리 기능을 늘리지 않는다.
```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
```
승인된 B33/MITC4 formulation, operation/reduction order, sign, units, coordinates와 row
identity는 이 ownership 리팩터링보다 우선한다. HDF5 schema, reference artifact와
ADR-014/ADR-020 tolerance도 변경하지 않는다.
`Domain``ElementDefinition`, `ElementProperty`, `Material``StepDefinition` base
object를 `std::unique_ptr`로 단독 소유하고 const access를 제공한다. Collection position은
기존 stable `EntityIndex` 의미를 유지한다. `AnalysisModel`과 solver consumer는 ownership을
가져오지 않고 Domain 수명 안에서 stable index 또는 const reference만 사용한다.
`std::shared_ptr`, speculative `Clone()`과 global registry는 이 계약에 포함되지 않는다.
`ElementDefinition`은 source identity, source element type, connectivity와
property/material identity를 보존하는 semantic object다. Runtime `Element`는 active
`ElementDofLayout`, `ElementStiffnessContribution``ElementResultBundle`을 제공하는
numerical kernel이다. `ElementFactory`만 compatible definition/property/material 조합을
검사해 runtime candidate를 만들며 unknown 또는 incompatible 조합을 기존
`Status`/`Result<T>` diagnostic으로 fail-closed 처리한다. `DofManager`,
`SparseAssembler``ResultRecovery`는 B33/MITC4 concrete storage가 아니라 위 runtime
contract를 소비한다. Linear-static candidate는 runtime `Element`
`std::vector<std::unique_ptr<Element>>`로 소유하고, consumer에는 그 owner 수명 안에서만
유효한 non-owning `ElementView`를 제공한다.
`Material` base는 identity, source location과 수명 의미만 공유한다. 현재 concrete
isotropic linear elasticity에 필요한 capability만 사용하며 density, anisotropy, plastic
state, temperature 또는 rate dependency를 optional field나 no-op method로 미리 추가하지
않는다. `ElementProperty`도 beam/shell이 실제 사용하는 data만 각 concrete type에 둔다.
`Load`는 semantic target과 magnitude를 소유하고 source order가 보존된
`LoadContribution`을 생성한다. Global vector의 deterministic accumulation은
`LoadAssembler`만 수행한다. `BoundaryCondition``ConstraintDefinition`을 생성하고
`EssentialConstraintPolicy`가 prescribed displacement의 stable elimination과
reconstruction을 수행한다. Future distributed/body load와 MPC enforcement는 구현된
기능이 아니며 별도 승인 계약 없이 이 경계에 branch나 optional state를 추가하지 않는다.
책임이 큰 facade는 외부 계약을 유지한 채 private implementation만 다음 owner로 나눈다.
- Abaqus Domain mapping: topology, material/property, step/load/boundary mapping과 final
Domain assembly
- Result recovery: global equilibrium, beam recovery, shell recovery와 atomic state commit
- HDF5 writing: RAII/primitives, model datasets, result datasets, self-check와 atomic
finalization
이 분할은 parser diagnostic, `ResultsWriter` boundary, HDF5 schema 또는 final-file
atomicity를 변경하지 않는다.
## V0 입력 경계 ## V0 입력 경계
V0 parser는 keyword와 parameter를 case-insensitive하게 해석하되 source label의 원문을 V0 parser는 keyword와 parameter를 case-insensitive하게 해석하되 source label의 원문을
@@ -174,14 +246,23 @@ CLI pipeline에서는 이 kernel을 호출하지 않는다. Stiffness와 recover
```text ```text
Domain Domain
├── owns nodes, B33 elements, materials, beam sections, sets ├── owns nodes, sets and source identity
├── owns boundary conditions, nodal loads, one static step ├── owns unique_ptr<ElementDefinition / ElementProperty / Material>
├── owns StepDefinition with Load / BoundaryCondition definitions
└── owns source path/identity and mapping warnings └── owns source path/identity and mapping warnings
AnalysisModel AnalysisModel
├── non-owning view into Domain ├── non-owning stable-index view into Domain
├── stable active element/BC/load indices ├── stable active element/BC/load definition indices
└── reachable material/section indices └── reachable material/property indices
ElementFactory
└── creates checked runtime Element candidates
Element
├── exposes ElementDofLayout
├── produces ElementStiffnessContribution
└── recovers ElementResultBundle
DofManager DofManager
├── owns node x [UX,UY,UZ,URX,URY,URZ] full-DOF numbering ├── owns node x [UX,UY,UZ,URX,URY,URZ] full-DOF numbering
@@ -205,12 +286,15 @@ Matrix
SparseMatrix SparseMatrix
``` ```
Nonlinear/static, dynamic, frequency, heat-transfer procedure와 general element/material/load 위 abstract boundary는 현재 B33/MITC4, isotropic linear elasticity, beam/shell property,
base hierarchy는 이 구조 위의 가능한 확장 방향일 뿐 현재 public API가 아니다. 사용 사례가 concentrated nodal load, prescribed displacement와 linear static procedure를 연결하는 데
승인되기 전에 V0 concrete record를 speculative hierarchy로 감싸지 않는다. 필요한 최소 계약이다. MITC3, solid, dynamic, frequency, heat-transfer와 plastic behavior는
구현된 기능이 아니며 승인된 사용 사례 전에 future-only method나 state를 base에 추가하지
않는다.
## 상태 관리 ## 상태 관리
- `Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다. - `Domain`은 입력 파일에서 만들어진 전체 모델 정의를 `std::unique_ptr`로 단독 소유한다.
파싱 이후에는 가능한 한 불변으로 취급하고 stable collection index를 바꾸지 않는다.
- `LinearStaticAnalysis``Domain`을 소유하고, 그 뒤에 `AnalysisModel`, `DofManager`, `AnalysisState`, stiffness/RHS를 순서대로 만든다. 재사용 시에는 역순으로 해제하여 이전 Domain을 가리키는 view를 남기지 않는다. - `LinearStaticAnalysis``Domain`을 소유하고, 그 뒤에 `AnalysisModel`, `DofManager`, `AnalysisState`, stiffness/RHS를 순서대로 만든다. 재사용 시에는 역순으로 해제하여 이전 Domain을 가리키는 view를 남기지 않는다.
- `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않으므로 Domain이 반드시 더 오래 살아야 한다. - `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않으므로 Domain이 반드시 더 오래 살아야 한다.
- `DofManager`는 자유도와 방정식 번호를 전담한다. `Node` 또는 `Element` 내부에 equation id를 분산 저장하지 않는다. - `DofManager`는 자유도와 방정식 번호를 전담한다. `Node` 또는 `Element` 내부에 equation id를 분산 저장하지 않는다.
@@ -223,15 +307,16 @@ Abaqus input file
-> syntax parse and semantic mapping -> syntax parse and semantic mapping
-> immutable Domain 생성 -> immutable Domain 생성
-> 단일 step AnalysisModel view 생성 -> 단일 step AnalysisModel view 생성
-> DofManager DOF/scatter map/sparse pattern 생성 -> ElementFactory가 compatible definition에서 runtime Element candidate 생성
-> element stiffness 계산과 deterministic COO-to-CSR 조립 -> DofManager가 ElementDofLayout으로 DOF/scatter map/sparse pattern 생성
-> free/constrained partition 생성 -> ElementStiffnessContribution의 deterministic COO-to-CSR 조립
-> ConstraintDefinition의 stable essential-constraint partition 생성
-> LinearSolver::factorize(Kff) -> LinearSolver::factorize(Kff)
-> full nodal load vector 조립 -> ordered LoadContribution의 full nodal load vector 조립
-> effective RHS = Ff - Kfc * dc -> effective RHS = Ff - Kfc * dc
-> LinearSolver::solve(rhs, df) substitution -> LinearSolver::solve(rhs, df) substitution
-> full displacement 복구 -> full displacement 복구
-> full residual/reaction = K*d - F 및 element result 복구 -> full residual/reaction = K*d - F 및 ElementResultBundle 복구
-> ResultsWriter로 results.h5 atomic finalization -> ResultsWriter로 results.h5 atomic finalization
``` ```
@@ -240,28 +325,37 @@ Abaqus input file
reaction이고 free component는 equilibrium residual evidence로 full-index vector에 남긴다. reaction이고 free component는 equilibrium residual evidence로 full-index vector에 남긴다.
## 해석 실행 흐름 ## 해석 실행 흐름
`Analysis::run()`은 Template Method로 다음 여덟 hook의 순서와 fail-fast 경계를 고정한다.
| 순서 | Hook | 주요 작업과 생성되는 소유 객체 | 순서/실패 불변식 | `Analysis` base는 procedure-specific protected hook을 정의하지 않고 최소 실행 계약인
`Analysis::Run(const AnalysisRequest&)`만 제공한다. 다음 여덟 단계의 순서와 fail-fast
경계는 `LinearStaticAnalysis::Run()`의 private lifecycle이며 다른 procedure에 강제되지
않는다.
| 순서 | Private stage | 주요 작업과 생성되는 소유 객체 | 순서/실패 불변식 |
| --- | --- | --- | --- | | --- | --- | --- | --- |
| 1 | `initialize(request)` | `.inp` syntax read, semantic map, owned immutable `Domain`, sorted warnings | 이전 run의 dependent object를 역순으로 제거하고 parse/map 실패를 input category로 반환한다. | | 1 | `Initialize(request)` | `.inp` syntax read, semantic map, owned immutable `Domain`, sorted warnings | 이전 run의 dependent object를 역순으로 제거하고 parse/map 실패를 input category로 반환한다. |
| 2 | `buildAnalysisModel()` | non-owning `AnalysisModel` view | Domain을 복사하지 않으며 Domain lifetime 안에서만 사용한다. | | 2 | `BuildAnalysisModel()` | non-owning `AnalysisModel` view | Domain을 복사하지 않으며 Domain lifetime 안에서만 사용한다. |
| 3 | `buildDofMapAndSparsePattern()` | `DofManager`, zero-initialized `AnalysisState` | Stable full/free/constrained numbering과 structural pattern을 한 소유자에게 둔다. | | 3 | `BuildDofMapAndSparsePattern()` | `DofManager`, zero-initialized `AnalysisState` | Stable full/free/constrained numbering과 structural pattern을 한 소유자에게 둔다. |
| 4 | `assembleAndPartitionStiffness()` | full CSR K와 `Kff/Kfc/Kcf/Kcc` | Element-local buffer를 deterministic하게 reduce하고 structural zero와 stable order를 보존한다. | | 4 | `AssembleAndPartitionStiffness()` | full CSR K와 `Kff/Kfc/Kcf/Kcc` | Element-local buffer를 deterministic하게 reduce하고 structural zero와 stable order를 보존한다. |
| 5 | `factorize()` | retained `Kff` factorization | 모든 load assembly보다 먼저 호출한다. Valid fully constrained model의 `0 x 0 Kff`는 trivial success다. | | 5 | `Factorize()` | retained `Kff` factorization | 모든 load assembly보다 먼저 호출한다. Valid fully constrained model의 `0 x 0 Kff`는 trivial success다. |
| 6 | `assembleLoadsAndEffectiveRhs()` | full F와 `Ff-Kfc*dc` | Semantic load source order와 finite sum을 보존하며 solver를 호출하지 않는다. | | 6 | `AssembleLoadsAndEffectiveRhs()` | full F와 `Ff-Kfc*dc` | Semantic load source order와 finite sum을 보존하며 solver를 호출하지 않는다. |
| 7 | `substituteAndReconstruct()` | free solution과 full displacement | Factorization을 재수행하지 않고 substitution한 뒤 prescribed value를 stable order로 복구한다. | | 7 | `SubstituteAndReconstruct()` | free solution과 full displacement | Factorization을 재수행하지 않고 substitution한 뒤 prescribed value를 stable order로 복구한다. |
| 8 | `recoverAndWriteResults()` | full residual/reaction, beam rows, final HDF5 | Recovery candidate를 원자적으로 commit하고 writer 성공 뒤에만 최종 output을 교체한다. | | 8 | `RecoverAndWriteResults()` | full residual/reaction, B33/MITC4 rows, final HDF5 | Recovery candidate를 원자적으로 commit하고 writer 성공 뒤에만 최종 output을 교체한다. |
비선형 정적 및 동적 해석은 V0 범위가 아니며 별도 ADR과 formulation을 승인한 뒤 이 비선형 정적 및 동적 해석은 V0 범위가 아니며 별도 ADR과 formulation을 승인한 뒤 이
lifecycle과 state/equation 계약을 확장한다. 기존 hook 사이에 조용히 반복·증분·시간 적분 lifecycle과 state/equation 계약을 별도 procedure에 정의한다. LinearStaticAnalysis의
동작을 삽입하지 않는다. private stage 사이에 조용히 반복·증분·시간 적분 동작을 삽입하지 않는다.
## 설계 패턴 ## 설계 패턴
- Strategy/Adapter Pattern: 현재 교체 가능한 public 경계는 `LinearSolver`, `ParallelFor`, `ResultsWriter`다. Vendor API는 concrete adapter implementation 안에만 둔다. - Strategy/Adapter Pattern: `Analysis::Run(const AnalysisRequest&)`, `LinearSolver`,
- Template Method Pattern: `Analysis::run()`은 공통 실행 흐름을 고정하고 세부 단계는 procedure별로 재정의한다. `ParallelFor`, `ResultsWriter`가 현재 승인된 public 실행/backend 경계다. Vendor API는
concrete adapter implementation 안에만 둔다.
- Procedure-owned lifecycle: `Analysis`는 protected Template Method hook을 공유하지 않고
`LinearStaticAnalysis`가 승인된 여덟 단계 lifecycle을 private하게 소유한다.
- Syntax/Semantic separation: `AbaqusInputReader`는 syntax record를 만들고 `AbaqusDomainMapper`가 승인된 keyword 의미를 concrete Domain record로 변환한다. - Syntax/Semantic separation: `AbaqusInputReader`는 syntax record를 만들고 `AbaqusDomainMapper`가 승인된 keyword 의미를 concrete Domain record로 변환한다.
- Runtime Polymorphism: V0에서는 backend 경계에만 사용한다. 요소/재료/하중 base hierarchy와 factory/registry는 두 번째 실제 구현이 필요해질 때 trade-off를 다시 결정한다. - Runtime Polymorphism: backend와 승인된 analysis/element/material/property/load/boundary
경계에만 사용한다. Factory compatibility는 중앙에서 fail-closed로 검사하며 global
registry 또는 future-only capability를 추가하지 않는다.
- RAII: MKL handle, HDF5 file/dataset, temporary solver workspace의 수명과 오류 처리를 wrapper에 묶는다. - RAII: MKL handle, HDF5 file/dataset, temporary solver workspace의 수명과 오류 처리를 wrapper에 묶는다.
## Sparse Matrix Policy ## Sparse Matrix Policy