feat(cpp-object-oriented-modular-refactoring): step 2 - architecture-boundaries
This commit is contained in:
+81
-5
@@ -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
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user