# 아키텍처 ## 목표 FESA의 아키텍처 목표는 Abaqus `.inp` subset을 내부 semantic model로 변환하고, 유한요소 equation system을 구성해 구조해석 결과를 HDF5로 저장하며, reference comparison과 physics sanity가 가능한 C++17/MSVC 솔버 구조를 제공하는 것이다. 핵심 품질 속성: - FEM formulation traceability - explicit I/O contracts - sparse linear algebra backend isolation - deterministic verification - incremental feature addition - Harness 기반 TDD와 workspace validation ## 디렉토리 구조 ```text src/ fesa/ core/ # ids, status, diagnostics, units, small value types io/ abaqus/ # .inp lexer/parser, keyword subset, include policy hdf5/ # HDF5 result writer/reader, schema versioning model/ # semantic model: nodes, elements, sets, materials, sections, steps fem/ # DOF space, equation numbering, quadrature, shape functions elements/ # truss/bar, beam, plane, solid, shell element routines materials/ # elastic/plastic material contracts and state variables assembly/ # local-to-global mapping, sparse pattern, COO/CSR assembly constraints/ # essential BC, MPC, penalty or elimination policies solvers/ linear/ # MKL PARDISO backend, iterative backend boundary nonlinear/ # Newton control, residual/tangent norms, increments analysis/ # static, modal, dynamic, nonlinear procedure drivers results/ # recovery, field/history output, diagnostics validation/ # comparison metrics and tolerance helpers tests/ unit/ integration/ reference/ reference/ / model.inp metadata.json _displacements.csv _reactions.csv _internalforces.csv _stresses.csv .codex/ hooks/ # Codex hook scripts skills/ # FESA solver and Harness instructions docs/ # Product, architecture, ADR, workflow artifacts scripts/ execute.py # Phase step executor validate_workspace.py # Default validation entry point test_*.py # Harness self-tests phases/ # Optional generated phase plans ``` ## Harness Execution Layer `scripts/execute.py`: - creates or checks out `codex/` - refuses to run on a dirty worktree - requires per-step `allowed_paths` - stages only explicit allowed paths and runner housekeeping files - runs Python Harness self-tests and workspace validation before every runner-created commit ## 모듈 경계 - `core`는 외부 라이브러리에 의존하지 않는다. - `io/abaqus`는 syntax와 semantic mapping만 담당하고 해석 알고리즘을 알지 않는다. - `model`은 Abaqus keyword 문자열이 아니라 solver semantic model을 가진다. - `fem`은 DOF, interpolation, quadrature, local/global mapping을 제공하되 특정 analysis procedure에 종속되지 않는다. - `elements`와 `materials`는 local residual/tangent/stress recovery 계약을 제공한다. - `assembly`는 sparse pattern 생성과 local contribution 조립을 담당한다. - `constraints`는 essential BC, MPC, penalty/elimination 정책을 분리한다. - `solvers`는 MKL/TBB 세부 구현을 감추는 backend boundary를 가진다. - `analysis`는 step/history data를 받아 procedure를 실행하고 solver backend와 result writer를 조율한다. - `results`는 HDF5 schema를 통해 nodal, element, integration-point, diagnostic output을 분리한다. - test helper는 production parser/solver 내부 상태를 우회하지 않는다. ## 핵심 객체 모델 ```text Domain ├── Node ├── Element ├── Material ├── Property ├── NodeSet ├── ElementSet ├── BoundaryCondition ├── Load └── StepDefinition AnalysisModel ├── active elements ├── active loads ├── active boundary conditions ├── active properties/materials └── equation system view AnalysisState ├── displacement U ├── velocity V ├── acceleration A ├── temperature T ├── external force Fext ├── internal force Fint ├── residual R ├── current time / increment / iteration └── element state / integration point state DofManager ├── node dof definitions ├── constrained/free dof mapping ├── equation numbering ├── sparse matrix pattern ownership └── full/reduced vector reconstruction Analysis ├── LinearStaticAnalysis ├── NonlinearStaticAnalysis ├── DynamicAnalysis ├── FrequencyAnalysis └── HeatTransferAnalysis Element ├── Element1D │ ├── Truss │ └── Beam ├── Element2D │ ├── MITC3 │ └── MITC4 └── Element3D ├── Hexahedral ├── Tetrahedral ├── Wedge └── Pyramid BoundaryCondition ├── Fix ├── RBE2 └── RBE3 Load ├── NodalLoad ├── PressureLoad └── BodyForce Results ├── ResultStep ├── ResultFrame ├── FieldOutput └── HistoryOutput ``` ## 상태 관리 - `Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다. - `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않고 참조 또는 id 기반 view로 구성한다. - `DofManager`는 자유도와 방정식 번호를 전담한다. `Node` 또는 `Element` 내부에 equation id를 분산 저장하지 않는다. - `AnalysisState`는 해석 중 변하는 물리량과 반복 상태를 소유한다. Phase 1에서는 displacement 중심으로 최소 구현하되, 기하비선형과 thermal-stress coupling을 위해 element/internal state 확장 지점을 유지한다. - 결과는 `ResultStep` -> `ResultFrame` -> `FieldOutput`/`HistoryOutput` 구조로 관리한다. ## 데이터 흐름 ```text Abaqus input file -> InputParser -> Domain 생성 -> StepDefinition 루프 -> AnalysisModel 생성 -> DofManager로 자유도/방정식 번호 생성 -> sparse pattern 생성 -> Analysis 실행 -> Assembler로 전역 행렬/벡터 조립 -> BoundaryCondition 적용 -> LinearSolver 또는 nonlinear/time integration loop -> AnalysisState 갱신 -> ResultsWriter로 step/frame/history 저장 -> 다음 step 진행 ``` ## 해석 실행 흐름 `Analysis::run()`은 Template Method로 다음 큰 흐름을 고정한다. 해석 종류별 class는 필요한 단계만 재정의한다. ```text initialize buildAnalysisModel buildDofMap buildSparsePattern assemble applyBoundaryConditions solve updateState writeResults ``` 비선형 정적해석은 이 흐름을 Newton-Raphson 반복 루프 안에서 사용하고, 동적해석은 time step/frame 루프 안에서 사용한다. ## 설계 패턴 - Strategy Pattern: `Analysis`, `LinearSolver`, `TimeIntegrator`, `ConvergenceCriteria`를 교체 가능한 전략으로 둔다. - Template Method Pattern: `Analysis::run()`은 공통 실행 흐름을 고정하고 세부 단계는 procedure별로 재정의한다. - Factory + Registry Pattern: Abaqus keyword와 내부 객체 생성을 분리한다. 예: `*Element, type=S4` -> `MITC4ElementFactory`. - Adapter Pattern: MKL, TBB, HDF5 API는 solver core에 직접 노출하지 않는다. - Runtime Polymorphism: 요소, 재료, 하중, 경계조건은 base interface를 통해 다룬다. 대규모 모델 성능 최적화가 필요하면 assembly 내부에서 타입별 batch 처리 또는 kernel 분리를 추가한다. - RAII: MKL handle, HDF5 file/dataset, temporary solver workspace의 수명과 오류 처리를 wrapper에 묶는다. ## Sparse Matrix Policy - assembly는 초기에는 COO triplet 수집 후 CSR finalize를 기준으로 한다. - `SparseMatrix`는 solver core가 사용하는 추상 contract이고 MKL PARDISO backend는 CSR input contract만 받는다. - matrix symmetry, definiteness, singularity diagnostic을 구조화된 diagnostic으로 남긴다. - deterministic assembly를 위해 TBB element loop는 thread-local contribution buffer 또는 two-pass sparse assembly를 사용한다. ## Parallel Policy - 첫 번째 oneTBB 적용 지점은 element-local matrix/residual 계산이다. - 전역 sparse write는 thread-local buffer 또는 deterministic reduction으로 제한한다. - MKL 내부 thread와 TBB element loop가 oversubscription을 만들지 않도록 thread count와 task arena 정책을 명시한다. ## HDF5 Result Schema ```text /metadata /model/nodes /model/elements /steps//frames//nodal/displacement /steps//frames//nodal/reaction /steps//frames//element/stress /steps//frames//element/strain /diagnostics ``` Schema requirements: - schema version, units, coordinate system, solver version, source input identity를 metadata에 기록한다. - field output과 history output을 구분한다. - reference comparison을 위한 row identity는 node id, element id, integration point id, step/frame id를 포함한다. - FESA solver는 `results.h5`를 authoritative output으로 쓴다. - Abaqus reference results는 `reference//` 아래 CSV 파일이다. - Verification은 documented IDs, components, units, coordinate system, step/frame identity, tolerance 기준으로 FESA HDF5 rows와 Abaqus reference CSV rows를 비교한다. - FESA HDF5에서 추출한 deterministic CSV view는 optional debugging/review artifact이며 공식 solver output 또는 reference artifact가 아니다. ## Test Architecture - unit: parser, DOF map, shape functions, material law, sparse assembly, HDF5 schema - integration: small `.inp` to HDF5 end-to-end - reference: FESA `results.h5` rows and Abaqus reference CSV rows comparison - physics: equilibrium, sign, symmetry, rigid body mode, stress sanity - harness: hooks, phase executor, workspace validation ## Hook 흐름 ```text apply_patch/Edit/Write -> .codex/hooks/tdd-guard.py -> C++ production changes require related tests git commit command -> .codex/hooks/pre_commit_checks.py -> Python Harness self-tests -> scripts/validate_workspace.py ``` ## Validation 흐름 ```text HARNESS_VALIDATION_COMMANDS set -> run exact commands CMakePresets.json has msvc-debug configure preset -> cmake --preset msvc-debug -> cmake --build preset binary dir --config Debug -> ctest --test-dir preset binary dir -C Debug CMakeLists.txt exists -> cmake -S . -B build/msvc-debug -G "Visual Studio 17 2022" -A x64 -> cmake --build build/msvc-debug --config Debug -> ctest --test-dir build/msvc-debug --output-on-failure -C Debug No CMake project -> print guidance and exit successfully ```