This commit is contained in:
김경종
2026-06-10 10:03:11 +09:00
parent 87529c811a
commit 0912ee6f3b
174 changed files with 414 additions and 8544 deletions
+44 -315
View File
@@ -1,329 +1,58 @@
# FESA Solver Architecture
# 아키텍처
## 목표
FESA는 C++17/MSVC 기반 유한요소 구조해석 솔버다. 초기 구현은 MITC4 4절점 shell element의 선형정적 해석이며, 이후 비선형 정적해석, 비선형 동적해석, 열전달 및 thermal-stress coupling, 1D/3D 요소로 확장한다.
이 저장소의 현재 책임은 C++/MSVC 프로젝트를 위한 Codex Harness scaffold를 제공하는 것이다. Harness는 phase execution, edit guard, commit validation, workspace validation을 분리해서 관리한다.
초기 구현은 정확도와 테스트 가능성을 우선한다. 단, 대규모 모델을 목표로 하므로 자유도 관리, 희소 행렬 조립, 선형 솔버, 병렬 실행 계층은 초기부터 성능 확장이 가능하도록 분리한다.
## 개발 프로세스 구조
## 디렉토리 구조
```text
Feature request
-> requirements
-> research evidence
-> FEM formulation
-> I/O contract
-> reference model and artifact contract
-> TDD implementation plan
-> C++ implementation
-> build/test validation
-> HDF5 reference comparison
-> physics/release review
.codex/
├── hooks/ # Codex hook scripts
└── skills/ # Harness planning/review instructions
docs/ # Project and Harness guidance
scripts/
├── execute.py # Phase step executor
├── validate_workspace.py
└── test_*.py # Harness self-tests
phases/ # Optional generated phase plans
```
## 설계 원칙
- `Domain`은 입력 모델의 의미를 보존하고 파싱 이후 가능한 한 불변에 가깝게 유지한다.
- 해석 중 변하는 물리량과 반복 상태는 `AnalysisState`에 명시적으로 분리한다.
- 현재 step에서 활성화되는 실행 view는 `AnalysisModel`이 담당하며, `Domain`을 복사하지 않는다.
- 요소, 재료, 하중, 경계조건, 해석 알고리즘은 런타임 다형성 기반으로 확장한다.
- 결과는 step/frame/field/history 개념으로 저장하여 정적, 비선형, 동적, 열전달 해석을 같은 결과 모델로 다룬다.
- 외부 라이브러리인 MKL, TBB, HDF5는 adapter 계층 뒤에 둔다.
- Abaqus input 호환성은 parser와 factory/registry 계층에서 관리한다.
- shell node는 6자유도이고, 결과 자유도 순서는 `U1, U2, U3, UR1, UR2, UR3`이다.
- 단위계는 강제하지 않는다. 입력과 reference artifact metadata에 기록된 일관 단위계를 그대로 사용한다.
- 결과 부호와 shell output component naming은 Abaqus 규약을 따른다.
- 경계조건은 constrained DOF 제거 방식으로 적용하고, reaction은 full vector 기준 `K_full * U_full - F_full`로 계산한다.
- 기본 실수 precision은 `double`이다.
- 대규모 모델을 위해 id, index, equation numbering은 int64 기반으로 설계한다.
- Mesh quality 진단은 1차 범위에서 제외한다. 대신 singular system 진단은 필수로 제공한다.
## Directory Structure
## 데이터 흐름
```text
include/fesa/
analysis/ # Static, nonlinear static, dynamic, heat transfer analysis interfaces
assembly/ # Global matrix/vector assembly and sparse pattern creation
boundary/ # Fix, RBE2, RBE3 and future constraint objects
core/ # Domain, AnalysisModel, AnalysisState, DofManager
element/ # Node, Element, MITC4 and future elements
io/ # Abaqus input parser and HDF5 result writer
load/ # NodalLoad, PressureLoad, BodyForce
math/ # Vector, Matrix, SparseMatrix, MKL adapter
material/ # LinearElastic and future material models
property/ # ShellProperty and 1D/2D/3D properties
results/ # ResultStep, ResultFrame, FieldOutput, HistoryOutput
util/ # Diagnostics, logging, validation helpers
verification/ # HDF5 reference comparison utilities
src/
analysis/
assembly/
boundary/
core/
element/
io/
load/
math/
material/
property/
results/
util/
verification/
tests/
parser/
element/
assembly/
solver/
hdf5/
reference/
User-approved task
-> Harness phase files under phases/
-> scripts/execute.py injects AGENTS.md and docs/*.md
-> Codex executes one step at a time
-> step updates phases/{phase}/index.json
-> validation runs through scripts/validate_workspace.py
```
The current repository may not yet contain all directories. They are intended ownership boundaries for implementation planning.
## Core Runtime Objects
- `Domain`: owns the validated runtime model object graph created from input: nodes, elements, materials, properties, sets, boundary conditions, loads, and step definitions.
- `AnalysisModel`: step-local execution view over active elements, loads, boundary conditions, properties, materials, and equation system view.
- `AnalysisState`: owns changing physical quantities and iteration/time state such as displacement, velocity, acceleration, temperature, forces, residual, current time, increment, and element/integration-point state.
- `Node`: stores node id, coordinates, and six DOF values in order `U1, U2, U3, UR1, UR2, UR3`.
- `Element`: computes local stiffness, internal force/resultants, stress recovery, and connectivity.
- `ShellMITC4Element`: 4 nodes, 24 DOF, 2x2 Gauss integration, MITC transverse shear interpolation.
- `Material`: base contract for material behavior.
- `Property`: element property and section data, including shell thickness.
- `LinearElasticShellSection`: isotropic elastic shell section with thickness and shear correction.
- `DofManager`: active DOF definitions, constrained/free DOF mapping, equation numbering, sparse pattern ownership, and full/reduced vector reconstruction.
- `Assembler`: gathers element contributions into deterministic global sparse data.
- `SparseMatrix`: internal sparse matrix abstraction backed by MKL-compatible CSR for v0.
- `LinearSolver`: solver interface implemented initially by `MklPardisoSolver`.
- `Analysis`: strategy interface for `LinearStaticAnalysis` and future nonlinear/dynamic/thermal analyses.
- `Hdf5ResultWriter`: writes mesh, metadata, nodal results, element resultants, stresses, field output, and history output.
- `ReferenceComparator`: compares FESA HDF5 output with stored reference HDF5 artifacts using tolerance `1e-5`.
## State Ownership
### Domain
`Domain` represents the validated model definition as runtime objects and should not store parser DTOs, equation ids, solver vectors, current displacement, or iteration state.
Included:
- nodes and elements
- materials and properties
- node sets and element sets
- loads and boundary conditions
- analysis step definitions
Parser-style definition records may exist as temporary input or factory records, but they are not persistent `Domain` storage. `Domain` owns runtime objects such as `Element`, `Material`, `ShellProperty`, `Load`, and `BoundaryCondition`.
### AnalysisModel
`AnalysisModel` is built per active step. It references `Domain` objects by id or stable reference and defines what participates in the current solve.
Included:
- active elements
- active loads
- active boundary conditions
- active property/material references
- current equation system view
### DofManager
`DofManager` centralizes all equation numbering. Node or Element objects must not independently own equation ids.
Responsibilities:
- define active node DOFs
- map constrained and free DOFs
- assign equation numbers
- provide connectivity for sparse matrix pattern generation
- reconstruct full vectors from reduced solution vectors
### AnalysisState
`AnalysisState` stores mutable quantities and future nonlinear/time history extension points.
Included:
- displacement, velocity, acceleration
- temperature
- external force, internal force, residual
- current time, increment, Newton iteration
- element state and integration point state
Phase 1 uses displacement-centered state only, but the structure must not block geometric nonlinear and thermal-stress extensions.
### Results State
Results use:
- `ResultStep`: analysis step result group
- `ResultFrame`: static load increment or dynamic time frame
- `FieldOutput`: node/element field results
- `HistoryOutput`: selected node, element, set, reaction, or energy histories
## Data Flow
## Hook 흐름
```text
Abaqus input file
-> InputParser
-> temporary parsed records
-> Factory/Registry object creation
-> Domain runtime object graph
-> StepDefinition loop
-> AnalysisModel
-> DofManager
-> sparse pattern creation
-> TBB parallel element stiffness computation
-> deterministic CSR assembly
-> constrained DOF elimination
-> MKL PARDISO solve
-> full displacement vector reconstruction
-> reaction recovery by K_full * U_full - F_full
-> TBB parallel element result recovery
-> HDF5 step/frame/field/history output
-> HDF5 reference comparison
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
```
## Patterns
### Strategy
Used for swappable analysis and numerical algorithms:
- `Analysis`: `LinearStaticAnalysis`, `NonlinearStaticAnalysis`, `DynamicAnalysis`, `HeatTransferAnalysis`
- `LinearSolver`: `MklPardisoSolver`, future iterative solver
- `TimeIntegrator`: future Newmark/HHT
- `ConvergenceCriteria`: future residual, displacement, and energy norms
### Template Method
`Analysis::run()` owns the high-level execution order:
## Validation 흐름
```text
initialize
buildAnalysisModel
buildDofMap
buildSparsePattern
assemble
applyBoundaryConditions
solve
updateState
writeResults
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
```
Nonlinear static analysis will reuse this sequence inside Newton-Raphson loops. Dynamic analysis will reuse it inside time step/frame loops.
### Factory + Registry
Abaqus input keywords map to internal object factories:
- `*ELEMENT, TYPE=S4` -> `MITC4ElementFactory`
- `*ELEMENT, TYPE=S4R` -> `MITC4ElementFactory`
- `*MATERIAL`, `*ELASTIC` -> `LinearElasticMaterialFactory`
- `*SHELL SECTION` -> `ShellPropertyFactory`
- `*BOUNDARY` -> `FixBoundaryFactory`
- `*CLOAD` -> `NodalLoadFactory`
- `*NSET`, `*ELSET` -> set registry
Adding an element, material, load, or boundary condition should not require rewriting the parser core.
### Adapter
MKL, TBB, and HDF5 APIs are not exposed directly to solver core objects.
Adapter targets:
- `SparseMatrix`, `Vector`, `Matrix`
- `LinearSolver`
- `ParallelFor`
- `ResultsWriter`
This allows test doubles and future dependency replacement without changing solver physics code.
### HDF5 Dependency Discovery
The current local Windows/MSVC HDF5 installation is:
```text
C:\Program Files\HDF_Group\HDF5\2.1.1
```
Implementation planning should use the HDF5 C API through the adapter layer, not the HDF5 C++ API. CMake discovery should prefer one of these explicit environment variables before falling back to default package search:
```powershell
$env:HDF5_ROOT = "C:\Program Files\HDF_Group\HDF5\2.1.1"
$env:HDF5_DIR = "C:\Program Files\HDF_Group\HDF5\2.1.1\cmake"
```
The expected local artifacts are `include\hdf5.h`, `lib\hdf5.lib`, `bin\hdf5.dll`, and `cmake\hdf5-config.cmake`. `h5dump.exe -V` should report HDF5 `2.1.1` on this machine.
### Runtime Polymorphism
Elements, materials, loads, and boundary conditions are handled through base interfaces. Phase 1 prioritizes clarity and testability. If large-model performance requires it later, assembly internals may add type-specific batch kernels.
## MITC4 Result Contract
Nodal displacement output:
```text
node_id, U1, U2, U3, UR1, UR2, UR3
```
Nodal reaction output:
```text
node_id, RF1, RF2, RF3, RM1, RM2, RM3
```
Element internal force/resultant output at Gauss points:
```text
element_id, gauss_id, xi, eta, N11, N22, N12, M11, M22, M12, Q13, Q23
```
Stress output:
```text
element_id, gauss_id, section_point, S11, S22, S12, S13, S23
```
## HDF5 Layout
```text
/metadata
feature_id
solver_version
model_id
hdf5_version
schema_version
units
tolerance
reference_solver
/mesh/nodes
/mesh/elements/mitc4/connectivity
/results/step_000/frame_000/nodal/displacement
/results/step_000/frame_000/nodal/reaction
/results/step_000/frame_000/element/forces
/results/step_000/frame_000/element/stress
/results/step_000/frame_000/history
```
## Parallelism And Sparse Assembly
TBB parallelism is allowed for element-local computations, element force recovery, assembly precompute, and independent postprocessing.
Global assembly must remain deterministic:
```text
parallel element loop
-> thread-local sparse contribution buffers
-> stable sort by (row, column)
-> deterministic sum
-> CSR arrays
```
The sparse matrix path must preserve 64-bit index boundaries so MKL `pardiso_64` can be used for large models.
The solver must avoid uncontrolled MKL/TBB oversubscription. Thread-count decisions are part of analysis metadata and validation reports.
## Validation Flow
```text
python scripts/validate_workspace.py
-> CMake configure
-> MSVC Debug build
-> CTest
-> feature-specific reference comparison tests
```
When no CMake project exists yet, validation may report the harness no-op path. Once solver code is introduced, CMake/CTest validation is mandatory.
## Reference Artifact Flow
Agents do not run Abaqus or Nastran.
```text
Human-approved Abaqus run
-> stored HDF5 reference artifact under references/<feature>/<model-id>/
-> FESA solver HDF5 output
-> ReferenceComparator
-> pass/fail using abs-or-rel 1e-5
```
For `mitc4-linear-static-shell`, Abaqus S4R is primary and S4 is diagnostic.
## Performance Extension Direction
- Sparse matrix storage is the default global system representation.
- MKL direct solver is the first supported solver, but `LinearSolver` must allow future iterative solvers.
- Element stiffness and result recovery should be designed for type-specific batch kernels later, but not optimized before correctness evidence exists.
- MITC4 formulation should remain clear and reviewable until patch and reference comparisons pass.