Files
FESADev/docs/ADR.md
2026-04-21 01:12:24 +09:00

5.3 KiB

Architecture Decision Records

철학

솔버의 높은 성능과 정확도, Abaqus와의 높은 호환성


ADR-001: Runtime Polymorphism 기반 Solver Core

결정: 요소, 재료, 하중, 경계조건, 해석 알고리즘은 base interface와 runtime polymorphism 기반으로 확장한다.

이유: FESA는 MITC4 Shell 요소에서 시작하지만 RBE2/RBE3, 압력하중, 비선형 정적해석, 동적해석, 열전달, 1D/3D 요소로 확장될 예정이다. 초기에는 정확도와 테스트 가능성이 가장 중요하므로, 각 물리 객체를 독립적으로 테스트하고 교체할 수 있는 구조가 필요하다.

트레이드오프: virtual dispatch 비용과 객체 분산에 따른 캐시 효율 저하가 발생할 수 있다. 대규모 모델 성능이 필요한 영역은 Assembler, element kernel, sparse solver 계층에서 batch 처리 또는 타입별 최적화를 추가한다.


ADR-002: Immutable Domain + Mutable AnalysisState

결정: 입력 모델 정의는 Domain에 보존하고 가능한 한 불변으로 취급한다. 해석 중 변하는 displacement, velocity, acceleration, temperature, force, residual, iteration 정보는 AnalysisState에 분리한다.

이유: 선형 정적해석, 기하비선형 정적해석, 동적해석, 열전달 및 thermal-stress coupling은 서로 다른 상태 변수를 필요로 한다. 모델 정의와 해석 상태를 분리하면 restart, 결과 저장, reference 비교, 테스트가 쉬워진다.

트레이드오프: Domain, AnalysisModel, AnalysisState 사이의 참조/id 관리가 필요하다. 단순한 단일 해석 코드보다 초기 구조가 복잡하지만, 다중 step 및 비선형/동적 확장성을 얻는다.


ADR-003: Step/Frame/Field/History 결과 모델

결정: 해석 결과는 ResultStep, ResultFrame, FieldOutput, HistoryOutput 구조로 저장한다.

이유: 정적해석, 비선형 increment, 동적 time frame, history output을 같은 결과 모델로 다루기 위해 Abaqus와 유사한 step/frame/history 개념이 필요하다. HDF5 저장 구조와 reference 결과 비교도 이 구조를 기준으로 설계한다.

트레이드오프: Phase 1 선형 정적해석만 놓고 보면 결과 구조가 다소 무겁다. 그러나 Phase 2 이후의 비선형 반복, Phase 3 동해석, reaction/history 검증을 위해 초기에 최소 구조를 잡는 편이 낫다.


ADR-004: Strategy + Template Method 기반 Analysis 실행

결정: 해석 알고리즘은 Analysis strategy로 분리하고, 공통 실행 흐름은 template method로 관리한다.

이유: 선형 정적해석, Newton-Raphson 비선형 정적해석, HHT 동적해석, 열전달 해석은 조립, 경계조건 적용, solver 호출, 상태 갱신, 결과 저장이라는 공통 흐름을 공유한다. 공통 흐름을 유지하면서 해석별 반복 구조만 바꾸는 방식이 중복을 줄인다.

트레이드오프: 공통 template이 지나치게 커지면 해석별 특수성이 숨겨질 수 있다. 따라서 Analysis는 전체 흐름을 조율하고, assembly, solver, convergence, time integration은 별도 strategy로 분리한다.


ADR-005: Factory + Registry 기반 Abaqus Input 객체 생성

결정: Abaqus input keyword와 내부 객체 생성을 factory/registry 계층으로 분리한다. Phase 1 입력 범위에는 *Node, *Element, *Nset, *Elset, *Material, *Elastic, *Shell Section, *Boundary, *Cload, *Step을 포함한다.

이유: Abaqus input format 호환성을 유지하면서 요소/재료/하중/경계조건 타입을 계속 추가해야 한다. parser 본체가 모든 타입을 직접 생성하면 확장할수록 변경 비용과 회귀 위험이 커진다.

트레이드오프: registry 초기화와 타입 매핑 코드가 추가된다. 대신 새 keyword나 element type을 추가할 때 parser core의 변경을 최소화할 수 있다.


ADR-006: External Library Adapter Boundary

결정: MKL, TBB, HDF5는 solver core에 직접 노출하지 않고 adapter/wrapper 계층 뒤에서 사용한다.

이유: FESA의 핵심 도메인 모델과 해석 알고리즘이 특정 외부 라이브러리 API에 강하게 결합되면 테스트와 교체가 어려워진다. SparseMatrix, Vector, LinearSolver, ParallelFor, ResultsWriter 같은 경계를 통해 외부 의존성을 제한한다.

트레이드오프: wrapper 계층 구현 비용이 추가된다. 성능이 민감한 부분에서는 adapter가 불필요한 복사를 만들지 않도록 API를 신중히 설계해야 한다.


ADR-007: DofManager가 자유도와 방정식 번호를 전담

결정: node와 element 내부에 equation id를 분산 저장하지 않고, DofManager가 자유도 정의, constrained/free dof mapping, equation numbering, sparse pattern 생성을 전담한다.

이유: 대규모 모델, 경계조건, RBE2/RBE3, 비선형 재조립, thermal-stress coupling에서는 자유도 관리가 solver 품질과 성능에 직접 영향을 준다. 자유도 관리를 별도 객체로 분리하면 경계조건 적용과 행렬 조립이 명확해진다.

트레이드오프: element 계산 시 node id에서 equation id로 변환하는 조회 비용이 생긴다. 이 비용은 assembly precompute 또는 element connectivity cache로 줄인다.