Files
FESADev/docs/ProjectInitialPlanNote.md
T
2026-06-11 17:18:03 +09:00

537 lines
30 KiB
Markdown

# FESA 초기 문서 완성 계획 노트
## 메타데이터
- 작성일: 2026-06-10
- 목적: `AGENTS.md`, `docs/PRD.md`, `docs/ARCHITECTURE.md`를 유한요소법 기반 구조해석 솔버 개발 프로젝트 문서로 완성하기 위한 조사 내용과 실행 계획 정리
- 사용한 로컬 스킬: `.codex/skills/fem-theory-query`
- 사용하지 않은 스킬: `.codex/skills/harness-workflow`
- 현재 전제: C++17 이상, MSVC, CMake, CTest, Intel oneAPI MKL, Intel oneAPI TBB, Abaqus `.inp` 입력, HDF5 결과 저장
## 성공 기준
- `AGENTS.md`는 이 프로젝트에서 Codex agent가 따라야 할 솔버 개발 원칙, 금지사항, 검증 경로, agent/skill 사용 규칙을 명확히 정의한다.
- `docs/PRD.md`는 FESA 구조해석 솔버의 제품 목표, v0/v1 범위, 기능 요구조건, 비기능 요구조건, 검증 gate를 정의한다.
- `docs/ARCHITECTURE.md`는 C++ 솔버 코드 구조, 모듈 경계, 데이터 흐름, 외부 라이브러리 경계, 테스트 구조를 구현 계획에 쓸 수 있을 정도로 정의한다.
- 세 문서는 기존 Harness 규칙을 없애지 않고, 솔버 개발 워크플로우의 운영 기반으로 흡수한다.
- 문서 완성 후 기본 검증 경로는 계속 `python scripts/validate_workspace.py`이다.
## 현재 저장소 기준선
- 현재 `AGENTS.md`, `docs/PRD.md`, `docs/ARCHITECTURE.md`는 주로 C++/MSVC Harness scaffold를 설명한다.
- `docs/SOLVER_AGENT_DESIGN.md``docs/SOLVER_SKILL_DESIGN.md`는 이미 FESA 솔버 개발 workflow를 요구조건, 연구, 정식화, I/O, reference model, 구현, reference 비교, 물리 검토, release로 분해해 둔 좋은 기준 문서다.
- `.codex/agents`에는 `requirement-agent`, `research-agent`, `formulation-agent`, `io-definition-agent`, `reference-model-agent`, `implementation-agent`, `reference-verification-agent`, `physics-evaluation-agent`, `release-agent` 등 workflow별 agent가 이미 존재한다.
- `.codex/skills`에는 `fesa-requirements-baseline`, `fesa-research-evidence`, `fesa-formulation-spec`, `fesa-io-contract`, `fesa-reference-models`, `fesa-cpp-msvc-tdd`, `fesa-reference-comparison`, `fesa-physics-sanity`, `fesa-release-readiness`가 이미 존재한다.
결론: 세 문서는 "Harness 프로젝트" 문서가 아니라 "FESA 구조해석 솔버 프로젝트" 문서로 승격해야 한다. 다만 Harness 검증, TDD guard, phase 실행기는 솔버 개발을 통제하는 운영 인프라로 남긴다.
## 로컬 FEM 위키 조사 요약
`fem-theory-query` 스킬 지침에 따라 `D:\Obsidian\MultiPhysicsVault`의 FEM 위키를 우선 확인했다.
참고한 주요 위키 페이지:
- `[[Finite Element Method]]`: FEM은 연속체를 요소로 이산화하고, nodal DOF 기반 보간, 요소 방정식, 전역 조립, 경계조건 적용, 선형/비선형 대수계 풀이로 이어진다.
- `[[Finite Element Program Implementation]]`: 구현은 입력 파싱, element-local 계산, global DOF mapping, sparse assembly, equation solve, stress/result recovery, output/reporting으로 나뉜다.
- `[[Abaqus Input File Syntax]]`: Abaqus 입력은 keyword/data/comment line 기반이며 model data와 history data를 분리한다.
- `[[Abaqus Output Database and Results Files]]`: Abaqus 결과는 field output, history output, diagnostics, restart/status/message 성격의 데이터를 구분한다.
- `[[Static Equilibrium Equation Solvers]]`: 선형 정적 해석은 sparse 직접/반복 솔버, 제약조건 처리, 반력 복구, matrix property 확인이 핵심이다.
- `[[Finite Element Modeling and Convergence Checks]]`: 결과 신뢰성은 코드 실행 성공이 아니라 mesh, element choice, boundary/load consistency, convergence, equilibrium, stress interpretation 검토에 달려 있다.
위키 기반 핵심 판단:
- FESA 문서의 중심 개념은 "요소 정식화"만이 아니라 "입력 모델 계약 -> 내부 semantic model -> equation system -> result contract -> reference validation"이어야 한다.
- Abaqus `.inp` 호환은 full compatibility가 아니라 기능별 supported keyword subset으로 제한해 문서화해야 한다.
- 결과 HDF5는 단순 파일 포맷 선택이 아니라 step/frame, field/history, coordinate system, units, output location, schema version을 담는 결과 계약이어야 한다.
- 기능 완료 판정은 CTest 통과와 별개로 reference comparison, physics sanity, release readiness gate를 모두 통과해야 한다.
## 웹 조사 요약
확인일은 2026-06-10이다. 공식 문서와 공개 프로젝트 문서 위주로 확인했다.
### FEM 코드 구조와 설계 패턴
- OOFEM은 object-oriented finite element framework를 지향하며, 공개 저장소 구조에서 `src/core`, `src/sm` 구조해석 모듈, `src/dss` 직접 sparse solver, `tests``benchmarks`를 분리한다. 이는 FESA도 `core`, `structural mechanics`, `solver backend`, `tests/references`를 분리해야 한다는 근거가 된다.
- 출처: [OOFEM DOAJ article](https://doaj.org/article/f41d83fc936b48ae8e98de41392a9051), [OOFEM GitHub README](https://github.com/oofem/oofem)
- MFEM은 mesh, finite element space, linear/bilinear/nonlinear form, coefficient, boundary condition 같은 개념을 명확히 분리한다. FESA는 이를 그대로 라이브러리화하기보다, structural solver에 맞춰 `Mesh`, `DofSpace`, `ElementRoutine`, `MaterialModel`, `Assembler`, `AnalysisProcedure` 경계를 갖는 편이 적절하다.
- 출처: [MFEM FEM documentation](https://mfem.org/fem/), [MFEM GitHub README](https://github.com/mfem/mfem)
- MOOSE의 Kernel 시스템은 weak form 항을 residual/Jacobian contributor로 분리하고 quadrature point 단위에서 평가한다. FESA의 비선형 확장을 고려하면 element/material routine은 residual, tangent, state update를 같은 계약 안에서 제공해야 한다.
- 출처: [MOOSE Kernels System](https://mooseframework.inl.gov/releases/moose/2022-06-13/syntax/Kernels/), [MOOSE NonlinearSystem](https://mooseframework.inl.gov/source/systems/NonlinearSystem.html)
### Abaqus 입력과 reference 검증
- Abaqus `.inp`는 keyword line, data line, comment line으로 구성되며 keyword/parameter는 대소문자를 구분하지 않는다. FESA parser는 이 일반 규칙과 기능별 keyword subset을 분리해서 설계해야 한다.
- 출처: [Abaqus Input Syntax Rules](https://docs.software.vt.edu/abaqusv2024/English/SIMACAEMODRefMap/simamod-c-inputsyntax.htm)
- Abaqus model은 model data와 history data로 나뉘며, `*STEP` 이후의 history data가 analysis procedure, load, boundary condition, output request를 정의한다. FESA 내부 모델도 이 구분을 유지해야 parser와 analysis procedure가 섞이지 않는다.
- 출처: [Abaqus Model Definition](https://docs.software.vt.edu/abaqusv2024/English/SIMACAEMODRefMap/simamod-c-model.htm)
- Abaqus Verification Guide와 Benchmarks Guide는 작은 검증 문제, 외부 benchmark, NAFEMS 계열 benchmark로 정확도와 수렴성을 확인하는 방식을 제시한다. FESA reference model portfolio도 smoke, analytical, patch, benchmark, regression 모델을 구분해야 한다.
- 출처: [Abaqus Verification Guide](https://docs.software.vt.edu/abaqusv2024/English/SIMACAEVERRefMap/simaver-c-ov.htm), [Abaqus Benchmarks Guide](https://docs.software.vt.edu/abaqusv2024/English/SIMACAEBMKRefMap/simabmk-c-ov.htm)
### 결과 저장과 HDF5
- Abaqus ODB는 field output, history output, diagnostic information을 구분한다. FESA의 HDF5 결과 schema도 같은 성격 구분을 가져야 후처리와 reference 비교가 안정적이다.
- 출처: [Abaqus Requesting Output to the Output Database](https://docs.software.vt.edu/abaqusv2024/English/SIMACAEOUTRefMap/simaout-c-dboutput-requestingoutput-odb.htm)
- HDF5 C++ API는 file, group, dataset, attribute, datatype, dataspace 개념을 제공하며 RAII, exception 기반 오류 처리, type-safe interface를 지원한다. FESA 결과 writer는 HDF5 C++ API 또는 얇은 RAII wrapper를 통해 schema version, units, coordinate system, step/frame metadata를 attribute/dataset으로 기록해야 한다.
- 출처: [HDF5 C++ API Introduction](https://support.hdfgroup.org/documentation/hdf5/latest/h5_cpp_intro.html)
### MKL/TBB 사용 방향
- Intel oneMKL은 sparse solver, Sparse BLAS, PARDISO를 제공한다. PARDISO는 CSR 계열 sparse storage를 쓰므로 FESA 전역 행렬 표현은 CSR/COO-to-CSR 조립 경로를 기준으로 설계해야 한다.
- 출처: [oneMKL PARDISO reference](https://www.intel.com/content/www/us/en/docs/onemkl/developer-reference-fortran/2024-1/onemkl-pardiso-parallel-direct-sparse-solver-iface.html)
- Intel oneMKL은 CMake config file을 제공하며 `MKLConfig.cmake``find_package()` 경로로 사용할 수 있다. FESA CMake는 oneMKL 발견 실패를 명확한 configure error 또는 optional feature error로 처리해야 한다.
- 출처: [Intel oneMKL CMake config](https://www.intel.com/content/www/us/en/docs/onemkl/developer-guide-linux/2026-0/using-the-cmake-config-file.html)
- oneTBB `parallel_for`는 iteration space를 chunk로 나누어 병렬 실행한다. FESA에서 1차 병렬화 후보는 element-level local matrix/residual 계산이다.
- 출처: [oneTBB parallel_for](https://uxlfoundation.github.io/oneTBB/main/tbb_userguide/parallel_for_os.html)
- oneMKL의 일부 함수 영역은 oneTBB로 thread된다. 특히 PARDISO는 reordering/factorization 단계에서 oneTBB thread를 사용하지만 solve 단계는 sequential로 호출된다고 문서화되어 있다. FESA는 element loop 병렬화와 MKL 내부 병렬화가 서로 oversubscription을 만들지 않도록 thread policy를 문서화해야 한다.
- 출처: [oneMKL functions threaded with oneTBB](https://www.intel.com/content/www/us/en/docs/onemkl/developer-guide-linux/2026-0/functions-thread-with-intel-thread-build-blocks.html)
## FESA 권장 코드 구조
문서 계획 단계의 후보 구조이며, 실제 구현 전 `ARCHITECTURE.md`에서 확정한다.
```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/
references/
<feature-id>/
<model-id>/
model.inp
metadata.json
reference.h5
csv/
deterministic comparison views
```
### 모듈 경계 원칙
- `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 조립을 담당한다.
- `solvers`는 MKL/TBB 세부 구현을 감추는 backend boundary를 가진다.
- `analysis`는 step/history data를 받아 procedure를 실행하고, solver backend와 result writer를 조율한다.
- `results`는 HDF5 schema를 통해 nodal, element, integration-point, diagnostic output을 분리한다.
## 핵심 클래스 구조 후보
아래 구조는 `docs/ARCHITECTURE.md`에 반영할 개념적 class map이다. `1DElement`, `2DElement`, `3DElement` 같은 이름은 분류 표현이며, 실제 C++ 식별자는 `Element1D`처럼 유효한 이름으로 확정한다.
```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
├── 1DElement
│ ├── Truss
│ └── Beam
├── 2DElement
│ ├── MITC3
│ └── MITC4
└── 3DElement
├── Hexahedral
├── Tetrahedral
├── Wedge
└── Pyramid
BoundaryCondition
├── Fix
├── RBE2
└── RBE3
Load
├── NodalLoad
├── PressureLoad
└── BodyForce
Results
├── ResultStep
├── ResultFrame
├── FieldOutput
└── HistoryOutput
InputParser
ResultsWriter
Assembler
LinearSolver
Vector
Matrix
SparseMatrix
```
문서화 시 핵심 책임은 다음처럼 구분한다.
- `Domain`은 입력 파일에서 생성된 전체 모델 정의를 소유한다.
- `AnalysisModel`은 현재 step에서 활성화된 해석 객체 view를 제공한다.
- `DofManager`는 자유도 정의, 제약/free mapping, equation numbering, sparse pattern ownership을 전담한다.
- `AnalysisState`는 해석 중 변하는 물리량과 반복 상태를 소유한다.
- `Analysis` 계층은 procedure별 실행 전략을 제공한다.
- `Element`, `Material`, `Load`, `BoundaryCondition`은 base interface를 통해 다루되, Phase 1에서는 명확성과 테스트 가능성을 성능 최적화보다 우선한다.
## 권장 설계 패턴
- Strategy Pattern: 해석 알고리즘과 수치 알고리즘을 교체 가능하게 구성한다.
- `Analysis`: `LinearStaticAnalysis`, `NonlinearStaticAnalysis`, `DynamicAnalysis`, `HeatTransferAnalysis`
- `LinearSolver`: `MKLPardisoSolver`, 향후 iterative solver
- `TimeIntegrator`: `HHTIntegrator`, 향후 Newmark 등
- `ConvergenceCriteria`: residual norm, displacement norm, energy norm
- Template Method Pattern: 해석 실행의 큰 흐름은 `Analysis::run()`에서 고정하고, 세부 단계는 해석 종류별로 재정의한다.
```text
initialize
buildAnalysisModel
buildDofMap
buildSparsePattern
assemble
applyBoundaryConditions
solve
updateState
writeResults
```
비선형 정적해석은 위 흐름을 Newton-Raphson 반복 루프 안에서 사용하고, 동적해석은 time step/frame 루프 안에서 사용한다.
- Factory + Registry Pattern: Abaqus input keyword와 내부 객체 생성을 분리한다.
- `*Element, type=S4` -> `MITC4ElementFactory`
- `*Material`, `*Elastic` -> `LinearElasticMaterialFactory`
- `*Boundary` -> `FixBoundaryFactory`
- `*Cload` -> `NodalLoadFactory`
- `*Nset`, `*Elset` -> set registry
요소, 재료, 하중, 경계조건 타입 추가 시 parser 본체의 변경을 최소화한다.
- Adapter Pattern: MKL, TBB, HDF5 API는 solver core에 직접 노출하지 않는다.
- `SparseMatrix`, `Vector`, `Matrix`
- `LinearSolver`
- `ParallelFor`
- `ResultsWriter`
외부 라이브러리 교체 또는 테스트 double 사용이 가능하도록 adapter 계층에서 의존성을 제한한다.
- Runtime Polymorphism: 요소, 재료, 하중, 경계조건은 base interface를 통해 다룬다. Phase 1에서는 명확성과 테스트 가능성을 우선하고, 대규모 모델 성능 최적화가 필요할 경우 assembly 내부에서 타입별 batch 처리 또는 kernel 분리를 추가한다.
- RAII: MKL handle, HDF5 file/dataset, temporary solver workspace는 수명과 오류 처리를 wrapper에 묶는다.
- Data-oriented core: global vectors, sparse matrix arrays, DOF maps, element connectivity는 cache locality와 deterministic assembly를 우선한다.
- Deterministic assembly: TBB element loop는 thread-local contribution buffer 또는 two-pass sparse assembly를 사용해 reference comparison의 재현성을 해치지 않도록 한다.
- Explicit diagnostics: parser warning, unsupported keyword, singular matrix, rigid body mode, convergence failure, HDF5 schema mismatch를 구조화된 diagnostic으로 남긴다.
## 상태 관리 모델
### 1. `Domain`
`Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다.
포함 대상:
- nodes, elements
- materials, properties
- node sets, element sets
- loads, boundary conditions
- analysis step definitions
### 2. `AnalysisModel`
`AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않고 참조 또는 id 기반 view로 구성한다.
포함 대상:
- active elements
- active loads
- active boundary conditions
- active property/material references
- current equation system view
### 3. `DofManager`
`DofManager`는 자유도와 방정식 번호를 전담한다. `Node` 또는 `Element` 내부에 equation id를 분산 저장하지 않는다.
책임:
- node별 활성 자유도 정의
- constrained/free dof mapping
- equation numbering
- sparse matrix pattern 생성에 필요한 connectivity 제공
- 경계조건 적용 전후의 dof view 관리
- full/reduced vector reconstruction
### 4. `AnalysisState`
`AnalysisState`는 해석 중 변하는 물리량과 반복 상태를 소유한다.
포함 대상:
- displacement, velocity, acceleration
- temperature
- external force, internal force, residual
- current time, increment, Newton iteration
- element state, integration point state
Phase 1에서는 displacement 중심으로 최소 구현하되, 기하비선형과 thermal-stress coupling을 위해 element/internal state 확장 지점을 유지한다.
### 5. Results State
결과는 `ResultStep` -> `ResultFrame` -> `FieldOutput`/`HistoryOutput` 구조로 관리한다.
- `ResultStep`: 해석 step 단위 결과
- `ResultFrame`: 정적해석의 load increment 또는 동적해석의 time frame
- `FieldOutput`: node/element field 결과
- `HistoryOutput`: 특정 node, element, set, reaction, energy 등의 이력 결과
## 권장 데이터 흐름
`docs/ARCHITECTURE.md`에는 아래 흐름을 solver 실행의 표준 경로로 반영한다.
```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 진행
```
## 세 문서별 완성 계획
### 1. `AGENTS.md`
목표: Codex agent의 행동 규칙을 FESA 솔버 개발에 맞게 재정의한다.
포함할 내용:
- 프로젝트 정체성: FESA는 C++17/MSVC 기반 FEM 구조해석 솔버이며 Harness는 개발 통제 인프라다.
- 절대 규칙:
- 기본 검증은 `python scripts/validate_workspace.py`.
- C++ production 변경은 관련 C++ test 선행.
- Abaqus reference artifact 생성/복원은 명시 승인된 phase에서만 수행.
- `harness-workflow` 사용은 사용자가 허용할 때까지 금지.
- full Abaqus compatibility를 주장하지 않고 기능별 keyword subset만 지원.
- 개발 workflow:
1. 요구조건 분석
2. 연구자료 조사
3. 유한요소 정식화
4. I/O 계약 정의
5. TDD 및 reference model 준비
6. C++ 구현
7. reference 비교
8. physics sanity
9. release readiness
- agent/skill map: 기존 `.codex/agents`와 `.codex/skills/fesa-*`를 workflow 단계에 연결.
- 문서 산출물 위치: `docs/requirements`, `docs/research`, `docs/formulations`, `docs/io-definitions`, `docs/reference-models`, `docs/reference-verifications`, `docs/physics-evaluations`, `docs/releases`.
- dependency policy: oneMKL, oneTBB, HDF5는 CMake에서 명시 탐지하고, 실패 시 원인을 분류한다.
검증:
- `python -m unittest discover -s scripts -p "test_*.py"`
- `python scripts/validate_workspace.py`
### 2. `docs/PRD.md`
목표: FESA solver product requirements를 정의한다.
권장 섹션:
- Product Vision: Abaqus `.inp` subset을 입력으로 받아 구조해석 결과를 HDF5로 저장하고, reference 결과와 비교 가능한 C++ solver.
- Users:
- solver developer
- verification reviewer
- analyst preparing Abaqus-compatible input subsets
- Codex agent workflow operator
- V0 Scope:
- 선형 정적 해석 골격
- 최소 Abaqus keyword subset: `*HEADING`, `*NODE`, `*ELEMENT`, `*NSET`, `*ELSET`, `*MATERIAL`, `*ELASTIC`, section keyword, `*BOUNDARY`, `*CLOAD`, `*STEP`, `*STATIC`, output request subset
- 1D truss/bar를 첫 번째 end-to-end feature 후보로 둔다.
- HDF5 result schema v0와 reference comparison view를 정의한다.
- V1 Scope:
- 2D plane stress/strain
- 3D solid
- sparse assembly/MKL PARDISO
- TBB element loop 병렬화
- reference model portfolio 확장
- Out of Scope:
- Abaqus full parser 호환
- Abaqus 직접 실행 자동화
- GUI/postprocessor
- Explicit dynamics, contact, plasticity, shell은 초기 범위 제외 또는 후속 feature
- Functional Requirements:
- parser, semantic model, equation assembly, solver, result recovery, HDF5 output, diagnostics, reference comparison.
- Nonfunctional Requirements:
- MSVC x64 Debug 검증
- deterministic results for reference tests
- schema versioning
- reproducible tolerance policy
- clear unsupported keyword diagnostics
- Acceptance Gates:
- requirements approved
- research evidence complete
- formulation reviewed
- I/O contract approved
- tests fail before implementation
- CMake/CTest pass
- reference comparison pass
- physics sanity pass
- release readiness pass
검증:
- PRD의 모든 `must` 요구조건은 acceptance criteria와 verification method를 가져야 한다.
- PRD의 범위는 `SOLVER_AGENT_DESIGN.md`, `SOLVER_SKILL_DESIGN.md`, 각 `docs/*/README.md`와 충돌하지 않아야 한다.
### 3. `docs/ARCHITECTURE.md`
목표: 구현자가 바로 TDD 계획으로 넘길 수 있는 code architecture를 정의한다.
권장 섹션:
- Architectural Goals:
- FEM formulation traceability
- explicit I/O contracts
- sparse linear algebra backend isolation
- deterministic verification
- incremental feature addition
- Layered Architecture:
- CLI/application layer
- Abaqus input adapter
- semantic model
- FEM kernel
- assembly and constraints
- solver backend
- analysis procedure
- result output/HDF5
- validation/test harness
- Data Flow:
```text
Abaqus .inp
-> lexer/parser
-> keyword AST or records
-> semantic model
-> DOF numbering
-> element/material local evaluation
-> sparse assembly
-> constraints
-> MKL solver
-> recovery
-> HDF5 result
-> reference comparison/physics sanity
```
- Dependency Rules:
- `core`는 외부 라이브러리에 의존하지 않는다.
- `io/hdf5`만 HDF5에 직접 의존한다.
- `solvers/linear/mkl`만 oneMKL에 직접 의존한다.
- `parallel` 또는 `assembly` 일부만 oneTBB에 직접 의존한다.
- test helper는 production parser/solver 내부 상태를 우회하지 않는다.
- Sparse Matrix Policy:
- assembly는 처음에는 COO triplet 수집 후 CSR finalize를 기준으로 한다.
- MKL PARDISO backend는 CSR input contract를 문서화한다.
- matrix symmetry, definiteness, singularity diagnostic을 결과에 남긴다.
- Parallel Policy:
- element-local computation 병렬화를 첫 번째 TBB 적용 지점으로 둔다.
- 전역 sparse write는 thread-local buffer 또는 deterministic reduction으로 제한한다.
- MKL thread count와 TBB task arena 정책을 명시한다.
- HDF5 Schema:
```text
/metadata
/model/nodes
/model/elements
/steps/<step-name>/frames/<frame-id>/nodal/displacement
/steps/<step-name>/frames/<frame-id>/nodal/reaction
/steps/<step-name>/frames/<frame-id>/element/stress
/steps/<step-name>/frames/<frame-id>/element/strain
/diagnostics
```
- Test Architecture:
- unit: parser, DOF map, shape functions, material law, sparse assembly, HDF5 schema
- integration: small `.inp` to HDF5 end-to-end
- reference: Abaqus artifact comparison
- physics: equilibrium, sign, symmetry, rigid body mode, stress sanity
검증:
- architecture의 각 모듈은 최소 하나의 test category와 연결되어야 한다.
- 외부 dependency는 adapter boundary 없이 core module에 직접 들어오면 안 된다.
## 기존 skill/agent workflow와 문서 연결
| Solver workflow | Agent | Skill | 문서 산출물 |
| --- | --- | --- | --- |
| 요구조건 분석 | `requirement-agent` | `fesa-requirements-baseline` | `docs/requirements/<feature-id>.md` |
| 연구자료 조사 | `research-agent` | `fesa-research-evidence`, `fem-theory-query` | `docs/research/<feature-id>-research.md` |
| 유한요소 정식화 | `formulation-agent` | `fesa-formulation-spec` | `docs/formulations/<feature-id>-formulation.md` |
| 수치 검토 | `numerical-review-agent` | `fesa-numerical-review` | `docs/numerical-reviews/<feature-id>-review.md` |
| I/O 정의 | `io-definition-agent` | `fesa-io-contract` | `docs/io-definitions/<feature-id>-io.md` |
| reference model | `reference-model-agent` | `fesa-reference-models` | `docs/reference-models/<feature-id>-reference-models.md` |
| 구현 계획/구현 | `implementation-planning-agent`, `implementation-agent` | `fesa-cpp-msvc-tdd` | tests, source, implementation report |
| build/test | `build-test-executor-agent` | `fesa-cpp-msvc-tdd` | `docs/build-test-reports/<feature-id>.md` |
| correction | `correction-agent` | `fesa-cpp-msvc-tdd` | `docs/corrections/<feature-id>.md` |
| reference 비교 | `reference-verification-agent` | `fesa-reference-comparison` | `docs/reference-verifications/<feature-id>-reference-verification.md` |
| 물리 검토 | `physics-evaluation-agent` | `fesa-physics-sanity` | `docs/physics-evaluations/<feature-id>-physics-evaluation.md` |
| 배포 준비 | `release-agent` | `fesa-release-readiness` | `docs/releases/<feature-id>-release.md` |
## HDF5와 deterministic CSV view 정합성 결정
프로젝트 문서와 skill의 reference comparison 경로는 HDF5 authoritative output과 deterministic CSV view 구조를 기준으로 정리한다.
결정:
- FESA solver의 정식 결과 파일은 HDF5로 한다.
- solver output은 `results.h5`, stored reference output은 `reference.h5`를 authoritative artifact로 둔다.
- reference comparison을 위해 HDF5 dataset에서 `csv/displacements.csv`, `csv/reactions.csv`, `csv/element_forces.csv`, `csv/stresses.csv` 같은 deterministic CSV view를 추출할 수 있다.
- CSV view는 row identity와 사람이 검토 가능한 비교 view일 뿐이며 authoritative storage가 아니다.
- `fesa-reference-comparison`, `fesa-io-contract`, `fesa-reference-models`, 관련 agent 문서는 이 구조를 기준으로 유지한다.
## 주요 리스크와 열린 질문
- 첫 end-to-end feature를 1D truss/bar로 확정할지, 2D plane stress까지 포함할지 결정이 필요하다. 문서 계획상 v0는 1D truss/bar가 가장 안전하다.
- oneMKL interface는 LP64와 ILP64 중 하나를 선택해야 한다. 초기 MSVC/x64/Debug에서는 LP64를 기본 후보로 두고 대형 모델 전환 시 ILP64를 검토한다.
- MKL 내부 thread와 TBB element loop가 동시에 활성화될 때 oversubscription을 피할 정책이 필요하다.
- HDF5 C++ API를 직접 쓸지, C API 위에 프로젝트 RAII wrapper를 둘지 결정이 필요하다. 초기에는 wrapper를 두고 내부 구현은 C++ API로 시작하는 편이 문서 요구에 맞다.
- Abaqus `.inp` include path, quoted labels, abbreviated keywords, unsupported keyword diagnostics는 parser 요구조건에서 명확히 다뤄야 한다.
- reference artifact 생성은 agent가 직접 하지 않는다는 기존 제약을 유지해야 한다. 사람이 생성한 artifact의 provenance를 `metadata.json`에 남긴다.
## 실행 순서 제안
1. `AGENTS.md` 개정
- Harness 중심 문구를 FESA solver 중심으로 확장한다.
- 기존 검증 명령과 TDD guard는 유지한다.
- agent/skill workflow와 금지사항을 명시한다.
- 검증: Python self-test, workspace validation.
2. `docs/PRD.md` 개정
- 현재 "C++/MSVC Harness" PRD를 FESA solver PRD로 대체 또는 대폭 확장한다.
- v0/v1 scope, functional/nonfunctional requirements, out-of-scope, acceptance gates를 작성한다.
- 검증: 요구조건마다 verification method와 acceptance criteria가 있는지 수동 리뷰.
3. `docs/ARCHITECTURE.md` 개정
- 현재 Harness architecture를 FESA solver architecture로 확장한다.
- Harness architecture는 "development operations layer"로 남긴다.
- 모듈 구조, dependency rules, data flow, HDF5 schema, MKL/TBB policy, test architecture를 작성한다.
- 검증: module/test mapping과 dependency rule 수동 리뷰.
4. 문서 정합성 점검
- `docs/SOLVER_AGENT_DESIGN.md`, `docs/SOLVER_SKILL_DESIGN.md`, `docs/*/README.md`와 용어/경로 충돌을 점검한다.
- `python -m unittest discover -s scripts -p "test_*.py"` 실행.
- `python scripts/validate_workspace.py` 실행.
## 후속 작업 후보
- HDF5 result schema ADR 작성.
- Abaqus `.inp` v0 keyword subset ADR 작성.
- MKL/TBB threading policy ADR 작성.
- HDF5 result schema와 deterministic CSV view exporter의 구체 schema/test 작성.
- 첫 기능 `linear-truss-1d`의 `docs/requirements/linear-truss-1d.md` 작성.