add initial plan

This commit is contained in:
김경종
2026-06-05 16:31:21 +09:00
parent 9b31adfd15
commit 5a23502570
6 changed files with 1116 additions and 93 deletions
+70 -15
View File
@@ -1,36 +1,81 @@
# Project: FESA Harness
# Project: FESA Structural Solver
## 목적
FESA는 Abaqus, Nastran 같은 유한요소법 기반 구조해석 솔버를 C++17/MSVC 환경에서 개발하는 프로젝트다. 현재 우선 대상은 MITC4 4절점 shell element 기반 선형정적 구조해석 기능이다.
## 기술 스택
- C++17 이상
- MSVC on Windows
- CMake + CTest
- Harness scripts in Python 3
- Intel oneAPI MKL: CSR matrix와 PARDISO 선형해법
- Intel oneAPI TBB: 병렬 요소 계산과 병렬 후처리
- HDF5 C library: 해석 결과와 reference 결과 저장
- Python 3: Harness, validation, phase execution, self-test
## 아키텍처 규칙
## 기본 개발 워크플로우
솔버 기능 개발은 아래 순서를 기본으로 한다.
1. 솔버 기능에 대한 요구조건 정의
2. 책, 논문 등 연구자료 조사
3. 코드 구현을 위한 유한요소 정식화
4. 솔버 입출력 데이터 정의
5. TDD 방법 사용을 위한 개발 솔버와 reference 솔버 테스트모델 작성
6. 코드 구현
7. reference 솔버의 해석 결과와 구현 솔버의 해석 결과 비교 검증
8. 결과 차이가 tolerance 범위 내에 들어오면 구현 완료
9. 솔버 기능 배포
각 단계 산출물은 `docs/requirements/`, `docs/research/`, `docs/formulations/`, `docs/io-definitions/`, `docs/reference-models/`, `docs/implementation-plans/`, `docs/reference-verifications/`, `docs/releases/` 아래에 기록한다.
## 검증 기준
- CRITICAL: 기본 검증 경로는 `python scripts/validate_workspace.py`이다.
- CRITICAL: C++ 빌드는 CMake/MSVC/x64/Debug 기준으로 검증한다.
- CRITICAL: 새 기능 또는 동작 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현한다.
- CRITICAL: Abaqus reference artifact나 solver 코드 복원은 명시적으로 요청된 phase에서만 수행한다.
- Codex custom agent의 `model_reasoning_effort` 기본값은 `extra high`로 둔다.
- Harness runner는 `scripts/execute.py`에 둔다.
- Codex hook 정책은 `.codex/hooks/`에 둔다.
- Harness planning/review instructions are stored in `.codex/skills/`.
- Generated phase execution outputs remain ignored under `phases/**/step*-output.json`.
- CRITICAL: C++ production file을 변경할 때는 관련 C++ test file이 같은 변경 또는 기존 코드에 있어야 한다.
- CRITICAL: Abaqus, Nastran, reference solver는 agent가 직접 실행하지 않는다. 사람이 생성하거나 승인된 절차로 생성한 reference artifact만 사용한다.
- CRITICAL: 해석 결과 비교 tolerance는 단일 기준 `1e-5`를 사용한다. 각 성분은 `abs(error) <= 1e-5` 또는 `relative(error) <= 1e-5`를 만족해야 한다.
## 개발 프로세스
- TDD를 기본으로 한다. C++ production file을 바꿀 때는 관련 C++ test file이 있어야 한다.
- 커밋 전 hook은 Harness Python self-test와 workspace validation을 실행해야 한다.
- 커밋 메시지는 conventional commits 형식을 따른다: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`.
- 계획이 필요한 장기 작업은 Harness phase로 나누고, 각 step은 독립 실행 가능해야 한다.
## MITC4 초기 구현 범위
- Feature id: `mitc4-linear-static-shell`
- Analysis: linear static, small displacement/small rotation
- Element: 4-node MITC4 shell, 6 DOF per node
- DOF order: `U1, U2, U3, UR1, UR2, UR3`
- Material/section: single-layer isotropic linear elastic shell section
- Input: Abaqus `.inp` subset
- Output: HDF5 result file
- Reference: stored Abaqus S4R primary reference; Abaqus S4 is diagnostic
- Required compared quantities: nodal displacement, reaction, element internal force/resultant, stress
## Architecture Rules
- OpenSees와 유사하게 `Domain`, `Node`, `Element`, `Material/Section`, `Analysis`, `SystemOfEqn`, `Recorder/ResultWriter` 책임을 분리한다.
- OpenSees source 구조는 참고하되 raw pointer ownership이나 과도한 inheritance는 복제하지 않는다. FESA는 C++17 RAII와 명확한 ownership을 사용한다.
- Element 계산, assembly, solver, I/O, reference comparison은 테스트 가능한 작은 모듈로 분리한다.
- `Domain`은 입력 모델 정의를 보존하고 파싱 이후 가능한 한 불변으로 취급한다.
- 해석 중 변하는 값은 `AnalysisState`에 둔다. Node/Element/Domain에 solver state나 equation id를 분산 저장하지 않는다.
- 현재 step의 실행 view는 `AnalysisModel`로 분리한다.
- Abaqus keyword와 내부 객체 생성은 parser 본체가 아니라 factory/registry 계층으로 분리한다.
- MKL, TBB, HDF5 직접 호출은 adapter 계층 뒤에 둔다.
- TBB 병렬화는 deterministic 결과를 유지해야 한다. 전역 조립은 thread-local contribution을 만든 뒤 deterministic merge를 수행한다.
- MKL PARDISO와 TBB thread oversubscription을 피하기 위해 thread count 정책을 기록한다.
- HDF5 writer는 HDF5 C API 위에 FESA 내부 RAII wrapper를 둔다.
- 경계조건은 constrained DOF 제거 방식으로 적용하고, reaction은 full vector 기준 `K_full * U_full - F_full`로 계산한다.
- 기본 실수 precision은 `double`이고, id/index/equation numbering은 int64 기반으로 설계한다.
- 단위계는 강제하지 않으며, 결과 부호와 shell output component naming은 Abaqus 규약을 따른다.
- Mesh quality 진단은 1차 범위에서 제외하지만 singular system 진단은 필수다.
## 명령어
```bash
```powershell
python -m unittest discover -s scripts -p "test_*.py"
python scripts/validate_workspace.py
python scripts/execute.py <phase-dir>
python scripts/execute.py <phase-dir> --push
```
MITC4 CTest 예시:
```powershell
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -L mitc4
```
## MSVC 검증 기본값
- Generator: `Visual Studio 17 2022`
- Platform: `x64`
@@ -43,3 +88,13 @@ Override variables:
- `HARNESS_CMAKE_PLATFORM`
- `HARNESS_CMAKE_CONFIG`
- `HARNESS_BUILD_DIR`
- `MKLROOT`
- `TBBROOT`
- `HDF5_ROOT`
- `HDF5_DIR`
## 커밋 및 문서화
- 커밋 전 hook은 Harness Python self-test와 workspace validation을 실행해야 한다.
- 커밋 메시지는 conventional commits 형식을 따른다: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`.
- 계획이 필요한 장기 작업은 Harness phase로 나누고, 각 step은 독립 실행 가능해야 한다.
- Generated phase execution outputs remain ignored under `phases/**/step*-output.json`.
+313
View File
@@ -0,0 +1,313 @@
# MITC4 Linear Static Shell Solver Initial Implementation Plan
## Summary
FESA will implement an initial finite element structural solver feature named `mitc4-linear-static-shell`. The feature reads an Abaqus-style input file, builds an internal finite element model, performs linear static analysis with a MITC4 shell element, writes HDF5 results, and verifies those results against stored Abaqus reference artifacts.
The implementation must follow the full solver development workflow:
1. Define solver feature requirements.
2. Research books, papers, manuals, and related solver implementations.
3. Write the finite element formulation required for code implementation.
4. Define solver input and output data contracts.
5. Create TDD test models for both FESA and the reference solver.
6. Implement code.
7. Compare FESA results against reference solver results for nodal displacement, reaction, element internal force, and stress.
8. Mark implementation complete only when result differences are within tolerance.
9. Release the solver feature.
## Scope
Feature id: `mitc4-linear-static-shell`
Included:
- Linear static structural analysis.
- MITC4 4-node shell element.
- Six DOF per node: `U1, U2, U3, UR1, UR2, UR3`.
- Single-layer isotropic linear elastic shell section.
- Abaqus `.inp` subset input.
- Intel oneAPI MKL CSR/PARDISO sparse linear solve.
- Intel oneAPI TBB parallel element computation and result recovery.
- HDF5 solver result output.
- Stored Abaqus S4R primary reference comparison.
- Stored Abaqus S4 diagnostic reference comparison.
Excluded:
- Nastran BDF input.
- Nonlinear geometry.
- Nonlinear material.
- Dynamic analysis.
- Buckling/eigenvalue analysis.
- Composite/layered shell section.
- Contact.
- Agent-run Abaqus or Nastran execution.
- Reference artifact generation by agents.
- OpenSees API compatibility.
## Architecture
Use OpenSees as an architectural reference, not as an API clone. FESA should use modern C++17 ownership and small testable modules.
Primary conceptual modules:
- `Domain`: model container for nodes, elements, constraints, loads, materials, sections, and analysis metadata.
- `Node`: id, coordinates, and six ordered DOFs.
- `Element`: abstract element behavior for stiffness, internal force, result recovery, and connectivity.
- `ShellMITC4Element`: four-node MITC4 implementation with 24 element DOFs.
- `Material/Section`: isotropic elastic shell section with membrane, bending, shear, and stress recovery contract.
- `Analysis`: linear static analysis driver.
- `SystemOfEqn`: DOF numbering, constraints, CSR assembly, MKL PARDISO solve.
- `ResultWriter`: HDF5 output.
- `ReferenceComparator`: HDF5 reference comparison.
## Step 1: Requirements Baseline
Create `docs/requirements/mitc4-linear-static-shell.md`.
The requirement document must define:
- analysis type: linear static
- element type: MITC4 shell
- DOF order: `U1, U2, U3, UR1, UR2, UR3`
- material: isotropic linear elastic
- section: uniform shell thickness
- input: Abaqus `.inp` subset
- output: HDF5
- verification quantities: nodal displacement, reaction, element internal force/resultant, stress
- tolerance: single value `1e-5`
- pass rule: `abs(error) <= 1e-5` or `relative(error) <= 1e-5`
Acceptance criteria:
- Every must requirement has a verification method.
- Every numerical output requirement has component names and units policy.
- Reference artifact needs are listed under `references/mitc4-linear-static-shell/`.
## Step 2: Research Evidence
Create `docs/research/mitc4-linear-static-shell-research.md`.
Research must cover:
- Dvorkin-Bathe continuum mechanics based four-node shell formulation.
- MITC4 mixed interpolation of tensorial components.
- Assumed transverse shear strain interpolation and shear locking.
- OpenSees `ShellMITC4` class structure and resultants.
- Abaqus S4/S4R behavior as practical reference elements.
- Patch tests and Scordelis-Lo shell benchmark.
The research document must separate verified source facts from implementation inference.
## Step 3: FEM Formulation
Create `docs/formulations/mitc4-linear-static-shell-formulation.md`.
The formulation must define:
- reference coordinates and node ordering.
- shell midsurface interpolation.
- director and local coordinate basis policy.
- six-DOF nodal displacement vector.
- membrane, bending, transverse shear strain measures.
- MITC transverse shear tying/interpolation.
- isotropic shell constitutive matrix.
- element stiffness expression.
- 2x2 Gauss integration.
- drill stiffness policy.
- stress and resultant recovery.
- invalid Jacobian and degenerate element checks.
Default drill stiffness policy:
- v0 hardcodes `alpha=1`.
- `Ktt = alpha * min_eigenvalue(D_membrane)`.
- Input override is deferred to a later phase.
## Step 4: I/O Contract
Create `docs/io-definitions/mitc4-linear-static-shell-io.md`.
Input subset:
- `*NODE`
- `*ELEMENT, TYPE=S4`
- `*ELEMENT, TYPE=S4R`
- `*MATERIAL`
- `*ELASTIC`
- `*SHELL SECTION`
- `*BOUNDARY`
- `*CLOAD`
- `*STEP`
Output format:
- HDF5 file.
- No CSV output is required for this feature.
Required HDF5 layout:
```text
/metadata
feature_id
solver_version
model_id
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
```
Required result components:
- displacement: `U1, U2, U3, UR1, UR2, UR3`
- reaction: `RF1, RF2, RF3, RM1, RM2, RM3`
- element force/resultant: `N11, N22, N12, M11, M22, M12, Q13, Q23`
- stress: `S11, S22, S12, S13, S23`
## Step 5: TDD Reference Models
Create `docs/reference-models/mitc4-linear-static-shell-reference-models.md`.
Reference policy:
- FESA agents do not run Abaqus or Nastran.
- Stored Abaqus S4R HDF5 artifacts are the primary pass/fail reference.
- Stored Abaqus S4 HDF5 artifacts are diagnostic only.
Initial model portfolio:
- membrane patch
- bending patch
- transverse shear patch
- twist patch
- coarse Scordelis-Lo shell
Each model bundle must include:
```text
references/mitc4-linear-static-shell/<model-id>/
model.inp
metadata.json
abaqus_s4r/results.h5
abaqus_s4/results.h5
README.md
```
`metadata.json` must record:
- model id
- source/provenance
- Abaqus version
- element type
- units
- output locations
- tolerance `1e-5`
- compared quantities
- known limitations
## Step 6: Code Implementation Plan
Create `docs/implementation-plans/mitc4-linear-static-shell-implementation-plan.md`.
Implementation must be TDD-first:
1. Write failing parser tests.
2. Implement minimum Abaqus `.inp` parser behavior.
3. Write failing MITC4 element tests.
4. Implement shape functions, Jacobian checks, MITC shear interpolation, stiffness, and recovery.
5. Write failing assembly tests.
6. Implement DOF numbering, constraint handling, and deterministic CSR assembly.
7. Write failing MKL PARDISO solve tests.
8. Implement solver wrapper and reaction recovery.
9. Write failing TBB deterministic parallel tests.
10. Implement TBB parallel element computations with deterministic merge.
11. Write failing HDF5 schema tests.
12. Implement HDF5 C API RAII wrapper and result writer.
13. Write failing reference comparison tests.
14. Implement HDF5 reference comparator.
15. Run full validation.
Required validation commands:
```powershell
python -m unittest discover -s scripts -p "test_*.py"
python scripts/validate_workspace.py
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -L mitc4
```
## Step 7: Reference Verification
Create `docs/reference-verifications/mitc4-linear-static-shell-reference-verification.md`.
Comparison inputs:
- FESA `results.h5`
- stored Abaqus S4R `results.h5`
- diagnostic Abaqus S4 `results.h5`
- metadata tolerance and schema version
Compared quantities:
- nodal displacement
- nodal reaction
- element internal force/resultant
- stress
Matching rules:
- node id for nodal quantities
- element id plus Gauss point id for element quantities
- component name for scalar comparisons
Pass rule:
```text
abs(error) <= 1e-5 OR relative(error) <= 1e-5
```
Report:
- compared quantity
- number of matched rows
- missing rows
- extra rows
- maximum absolute error
- maximum relative error
- worst id
- worst component
- pass/fail
## Step 8: Completion Decision
Implementation is complete only when:
- all required tests pass;
- CMake/MSVC/x64/Debug build passes;
- all required HDF5 result quantities compare within tolerance `1e-5`;
- no required reference artifact is missing;
- failures are not hidden as known limitations.
If comparison fails, classify the failure as one of:
- missing reference artifact
- schema mismatch
- id mismatch
- unit or coordinate mismatch
- formulation defect
- implementation defect
- tolerance failure
- reference artifact issue
Then return to the owning workflow step.
## Step 9: Release
Create `docs/releases/mitc4-linear-static-shell-release.md`.
Release document must include:
- feature id and scope
- supported input keywords
- supported outputs
- dependency versions
- test model list
- reference comparison summary
- tolerance policy
- known limitations
- validation commands and status
Release is not approved by build success alone. Release requires reference comparison success and documented limitations.
## Dependency Plan
MKL:
- Use oneAPI MKL through `MKLROOT` or known oneAPI path.
- Use CSR matrix storage and PARDISO for the global linear system.
TBB:
- Use oneAPI TBB through `TBBROOT` or known oneAPI path.
- Parallelize element-local stiffness and result recovery.
- Use deterministic merge for global assembly.
HDF5:
- FESA provides an internal RAII wrapper around the HDF5 C API.
- The HDF5 C library itself must be supplied through `HDF5_ROOT` or `HDF5_DIR`.
- HDF5 is required for solver output and reference comparison.
## Assumptions
- Abaqus reference artifacts are generated outside the agent workflow.
- S4R is the primary reference for pass/fail.
- S4 is diagnostic and does not determine pass/fail.
- The single tolerance value is `1e-5`.
- The initial implementation prioritizes correctness and traceability over broad element coverage.
+91 -19
View File
@@ -1,34 +1,106 @@
# Architecture Decision Records
## 철학
Harness는 현재 프로젝트의 실제 기술 스택을 반영해야 한다. C++/MSVC 프로젝트에서 npm, Next.js, TypeScript test naming을 기본값으로 두면 agent prompt와 hook policy가 잘못된 구현을 유도한다.
## ADR-001: Solver Development Workflow Is Stage-Gated
**Decision**: FESA solver features must follow this workflow: requirements, research, formulation, I/O contract, TDD reference models, implementation, reference comparison, tolerance decision, release.
---
**Reason**: Structural solver correctness depends on more than code execution. Requirements, mathematical formulation, input/output contracts, reference artifacts, numerical comparison, and release evidence must be traceable.
### ADR-001: C++ 전용 Harness
**결정**: Harness scaffold는 C++/MSVC 전용으로 운영한다. JavaScript/TypeScript fallback은 유지하지 않는다.
**Tradeoff**: Initial feature delivery is slower. The benefit is that implementation agents do not invent formulation, tolerance, or reference assumptions during coding.
**이유**: FESA 개발 환경은 MSVC 기반 C++이다. 언어별 fallback을 남기면 validation, TDD guard, acceptance criteria가 흐려진다.
## ADR-002: C++17/MSVC/CMake/CTest Remain The Baseline
**Decision**: The project targets C++17 or newer, MSVC on Windows, CMake, and CTest. Default validation uses Visual Studio 17 2022, x64, Debug.
**트레이드오프**: 같은 Harness scaffold를 JS/TS 프로젝트에 재사용할 수 없다. 필요하면 별도 template이나 language registry를 새 ADR로 설계한다.
**Reason**: The project is a Windows/MSVC structural solver. CMake/CTest gives a consistent build and test entry point for both harness validation and feature development.
### ADR-002: CMake/MSVC/x64/Debug 기본 검증
**결정**: 기본 workspace validation은 CMake, Visual Studio 17 2022 generator, x64 platform, Debug config, CTest로 수행한다.
**Tradeoff**: Visual Studio solution-only workflows and non-MSVC toolchains are not the primary path. They can be introduced by explicit ADR when needed.
**이유**: MSVC 환경에서 CMake/CTest는 source tree가 복원되거나 새 C++ project가 추가될 때 가장 일관된 build/test entry point다.
## ADR-003: MITC4 Linear Static Shell Is The Initial Solver Feature
**Decision**: The first solver implementation target is `mitc4-linear-static-shell`: a 4-node MITC4 shell element for linear static structural analysis.
**트레이드오프**: Visual Studio solution-only project는 기본 지원하지 않는다. 명시적으로 필요하면 `HARNESS_VALIDATION_COMMANDS`로 override한다.
**Reason**: MITC4 is a meaningful shell element target with strong research and OpenSees reference structure. It exercises element formulation, assembly, solver, I/O, and reference verification without immediately requiring nonlinear or dynamic analysis.
### ADR-003: 엄격한 C++ TDD Guard
**결정**: C++ production file 변경은 관련 C++ test file이 없으면 차단한다.
**Tradeoff**: This is more complex than a truss/bar bootstrap. The project accepts the complexity because MITC4 is the requested initial element.
**이유**: Harness의 핵심 목적은 agent가 검증 없는 C++ 변경을 만들지 않도록 하는 것이다. Header 중심 C++ 구조에서도 module 또는 basename 기반 테스트 존재를 확인한다.
## ADR-004: OpenSees-Inspired Architecture, Modern C++ Ownership
**Decision**: FESA follows OpenSees-like conceptual boundaries: `Domain`, `Node`, `Element`, `Material/Section`, `Analysis`, `SystemOfEqn`, and `Recorder/ResultWriter`. It does not clone OpenSees raw ownership style.
**트레이드오프**: 초기 scaffolding 작업에서 guard가 엄격하게 느껴질 수 있다. 문서, CMake 설정, Harness metadata는 guard 대상에서 제외한다.
**Reason**: OpenSees provides a useful solver architecture vocabulary, while modern C++17 RAII gives safer ownership and testable module boundaries.
### ADR-004: Harness 자체 테스트 우선
**결정**: commit hook은 먼저 Python Harness self-test를 실행한 뒤 workspace validation을 실행한다.
**Tradeoff**: FESA classes will not be drop-in compatible with OpenSees. Similarity is architectural, not API compatibility.
**이유**: 현재 저장소에는 C++ source tree가 없을 수 있다. Harness가 스스로 검증 가능해야 이후 phase generation과 source restoration을 안전하게 진행할 수 있다.
## ADR-005: MKL PARDISO For Global Linear Solves
**Decision**: FESA uses Intel oneAPI MKL CSR matrices and PARDISO for the initial global linear static solve.
**트레이드오프**: commit 시간이 조금 늘어난다. 대신 hook/validation regressions를 빠르게 잡는다.
**Reason**: Shell models need sparse linear algebra beyond toy dense solvers. MKL is already aligned with the Windows/MSVC toolchain and provides production-grade direct sparse solving.
**Tradeoff**: oneAPI MKL becomes a required dependency for real solver builds. The CMake configuration must detect `MKLROOT` or a known oneAPI installation path.
## ADR-006: TBB For Parallel Element Work
**Decision**: FESA uses Intel oneAPI TBB for parallel element stiffness, residual/result recovery, and other embarrassingly parallel solver phases.
**Reason**: Element-level computation is a natural parallelism boundary. TBB integrates with oneAPI and avoids designing a custom thread pool.
**Tradeoff**: Global assembly must be deterministic. FESA will use thread-local contribution buffers and deterministic merge rather than concurrent writes into global CSR arrays.
## ADR-007: HDF5 For Solver And Reference Results
**Decision**: FESA writes solver results to HDF5 and compares against stored HDF5 reference artifacts.
**Reason**: Shell results contain structured mesh, step/frame, nodal, element, Gauss point, resultant, stress, metadata, and tolerance data. HDF5 is better suited than flat CSV for this result hierarchy.
**Tradeoff**: HDF5 becomes a required dependency. FESA will provide an internal RAII wrapper over the HDF5 C API, but the actual HDF5 C library must be supplied by `HDF5_ROOT` or `HDF5_DIR`.
## ADR-008: Single Tolerance Policy
**Decision**: Reference comparison uses a single tolerance value `1e-5`. A compared scalar passes when absolute error or relative error is within `1e-5`.
**Reason**: A single tolerance policy is simple, explicit, and matches the current project decision.
**Tradeoff**: Quantity-specific scaling is deferred. If future models show that one global tolerance is too strict or too loose for some quantities, a new ADR must revise this policy.
## ADR-009: Agents Do Not Run Reference Solvers
**Decision**: Abaqus, Nastran, and other reference solvers are not run by agents. Agents only consume stored reference artifacts.
**Reason**: Reference solver execution requires licensing, environment control, provenance, and human approval. Stored artifacts make validation reproducible inside the harness.
**Tradeoff**: Implementation can be blocked until required reference artifacts are supplied.
## ADR-010: Domain, AnalysisModel, And AnalysisState Are Separate
**Decision**: `Domain` owns parsed model definition, `AnalysisModel` owns the active step execution view, and `AnalysisState` owns mutable solution and iteration state.
**Reason**: This prevents equation ids, displacement vectors, residuals, and future nonlinear/time states from leaking into input model objects. It also keeps the static solver compatible with future nonlinear, dynamic, and thermal workflows.
**Tradeoff**: The initial implementation has more object boundaries than a single monolithic model container.
## ADR-011: Factory/Registry Handles Input Object Creation
**Decision**: Abaqus keyword parsing and internal object creation are separated through factory/registry mechanisms.
**Reason**: Adding elements, materials, loads, boundary conditions, sets, or properties should not require rewriting parser control flow.
**Tradeoff**: The first parser implementation needs a small registry layer before many object types exist.
## ADR-012: Boundary Conditions Use DOF Elimination
**Decision**: Essential boundary conditions are applied by constrained DOF elimination. Reactions are recovered from the full system as `K_full * U_full - F_full`.
**Reason**: This gives a clear reduced solve while preserving physically meaningful reaction recovery for reference comparison.
**Tradeoff**: The implementation must preserve enough full-system information for reaction recovery instead of only storing the reduced matrix.
## ADR-013: Results Use Step/Frame/Field/History Model
**Decision**: HDF5 results are organized by step, frame, field output, and history output.
**Reason**: The same result model can support static, nonlinear, dynamic, heat-transfer, and thermal-stress analyses.
**Tradeoff**: The v0 linear static output is more structured than a flat single-step result file.
## ADR-014: Double Precision And 64-Bit Numbering
**Decision**: Solver scalar calculations use `double`; ids, sparse indices, and equation numbering are designed around int64 boundaries.
**Reason**: Structural solver verification needs double precision, and large sparse systems should not be blocked by 32-bit numbering assumptions.
**Tradeoff**: Memory use may be higher than a 32-bit-only implementation.
## ADR-015: Units Are User-Consistent, Not Enforced
**Decision**: FESA does not enforce a unit system. Inputs and reference artifacts must be unit-consistent and record units in metadata.
**Reason**: Abaqus-style workflows commonly rely on user-consistent units.
**Tradeoff**: The solver cannot automatically detect every unit mismatch. Reference metadata and validation reports must make unit assumptions visible.
+294 -44
View File
@@ -1,58 +1,308 @@
# 아키텍처
# FESA Solver Architecture
## 목표
이 저장소의 현재 책임은 C++/MSVC 프로젝트를 위한 Codex Harness scaffold를 제공하는 것이다. Harness는 phase execution, edit guard, commit validation, workspace validation을 분리해서 관리한다.
FESA는 C++17/MSVC 기반 유한요소 구조해석 솔버다. 초기 구현은 MITC4 4절점 shell element의 선형정적 해석이며, 이후 비선형 정적해석, 비선형 동적해석, 열전달 및 thermal-stress coupling, 1D/3D 요소로 확장한다.
## 디렉토리 구조
초기 구현은 정확도와 테스트 가능성을 우선한다. 단, 대규모 모델을 목표로 하므로 자유도 관리, 희소 행렬 조립, 선형 솔버, 병렬 실행 계층은 초기부터 성능 확장이 가능하도록 분리한다.
## 개발 프로세스 구조
```text
.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
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
```
## 데이터 흐름
## 설계 원칙
- `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
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
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/
```
## Hook 흐름
```text
apply_patch/Edit/Write
-> .codex/hooks/tdd-guard.py
-> C++ production changes require related tests
The current repository may not yet contain all directories. They are intended ownership boundaries for implementation planning.
git commit command
-> .codex/hooks/pre_commit_checks.py
-> Python Harness self-tests
-> scripts/validate_workspace.py
## Core Runtime Objects
- `Domain`: owns model definitions 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 parsed model definition and should not store 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
### 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
```text
Abaqus input file
-> InputParser
-> Factory/Registry object creation
-> Domain
-> 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
```
## Validation 흐름
## 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:
```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
initialize
buildAnalysisModel
buildDofMap
buildSparsePattern
assemble
applyBoundaryConditions
solve
updateState
writeResults
```
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.
### 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
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.
+97 -15
View File
@@ -1,22 +1,104 @@
# PRD: C++/MSVC Harness
# PRD: FESA MITC4 Linear Static Shell Solver
## 목
Codex Harness가 C++/MSVC 프로젝트에서 phase planning, TDD guard, commit validation, workspace validation을 일관되게 수행하게 한다.
## 목
FESA는 유한요소 input 파일을 읽어 구조해석을 수행하고, 절점과 요소의 해석 결과를 출력하는 C++ 구조해석 솔버를 제공한다. 초기 제품 기능은 MITC4 4절점 shell element 기반 선형정적 해석이다.
## 사용자
- Windows/MSVC 기반 C++ 개발자
- Harness phase를 작성하고 실행하는 Codex agent
- Harness 결과를 검토하는 reviewer
- 구조해석 솔버를 개발하는 C++/MSVC 개발자
- Abaqus/Nastran 계열 input과 결과 검증 방식을 이해하는 해석 엔지니어
- reference solver 결과와 FESA 결과를 비교해 기능 release를 판단하는 reviewer
- Codex/FESA agent workflow로 기능을 단계별 구현하는 agent
## 문제 정의
구조해석 솔버는 단순히 코드를 빌드하는 것만으로 정확성을 판단할 수 없다. 요소 정식화, 입력 mapping, 선형해법, 결과 출력, reference solver 비교, tolerance 판정이 모두 명시되어야 한다. FESA는 이 과정을 문서화된 단계와 자동 검증으로 묶어 구현 실수를 줄인다.
## 핵심 기능
1. CMake/MSVC/x64/Debug 기반 workspace validation
2. C++ source/header 변경에 대한 엄격한 TDD guard
3. npm 없이 Python self-test와 CMake/CTest 검증을 수행하는 pre-commit hook
4. C++ 프로젝트에 맞는 Harness workflow/review prompt
5. CMake project가 아직 없어도 Harness 자체 테스트가 가능한 no-op validation path
1. Abaqus `.inp` subset 입력
- `*NODE`, `*ELEMENT`, `*MATERIAL`, `*ELASTIC`, `*SHELL SECTION`, `*BOUNDARY`, `*CLOAD`, `*STEP` 지원
- unsupported keyword는 명시적 diagnostic을 낸다.
2. MITC4 shell 선형정적 해석
- 4-node quadrilateral shell
- 6 DOF per node: `U1, U2, U3, UR1, UR2, UR3`
- isotropic linear elastic shell section
- 2x2 Gauss integration
- membrane, bending, transverse shear resultants
3. Sparse system solve
- CSR global stiffness assembly
- Intel oneAPI MKL PARDISO direct solver
- constrained DOF 처리와 reaction recovery
4. Parallel computation
- Intel oneAPI TBB 기반 element stiffness/result recovery 병렬화
- deterministic assembly merge
5. HDF5 result output
- mesh metadata
- nodal displacement
- nodal reaction
- element internal force/resultant
- element stress
6. Reference solver verification
- stored Abaqus S4R reference HDF5 artifact와 비교
- Abaqus S4 artifact는 diagnostic reference로 보관
- nodal displacement, reaction, element internal force, stress 비교
- tolerance `1e-5` 단일 기준
7. Solver state and result model
- `Domain`, `AnalysisModel`, `AnalysisState` 분리
- step/frame/field/history HDF5 결과 구조
- constrained DOF 제거와 full-system reaction recovery
8. Extensible object creation
- Abaqus parser와 element/material/load/boundary factory registry 분리
- 향후 1D/3D 요소, nonlinear, dynamic, thermal 기능 추가를 위한 module boundary 유지
## 성공 기준
- MITC4 요구조건, 연구, 정식화, I/O, reference model, 구현 계획, reference verification, release 문서가 작성되어 있다.
- 모든 C++ production 변경은 관련 테스트가 먼저 작성되고 실패가 확인된 뒤 구현된다.
- MSVC x64 Debug CMake build와 CTest가 통과한다.
- 다음 테스트모델이 stored Abaqus S4R reference와 `abs-or-rel 1e-5` 이내로 일치한다.
- membrane patch
- bending patch
- transverse shear patch
- twist patch
- coarse Scordelis-Lo shell
- HDF5 output schema가 reference comparison에 필요한 모든 id, component, step/frame, units, metadata를 포함한다.
- Essential boundary condition reaction은 `K_full * U_full - F_full` 기준으로 계산되어 reference reaction과 비교 가능하다.
- Singular system 또는 solver factorization 실패는 명시적 diagnostic으로 보고된다.
## 제외 사항
- 이전 FESA solver source tree 복원
- JavaScript/TypeScript fallback 유지
- Abaqus reference artifact 생성 또는 solver reference 비교 구현
- Visual Studio `.sln`/`.vcxproj` 전용 MSBuild workflow
- Nastran BDF parser
- nonlinear static analysis
- geometric nonlinearity
- dynamic analysis
- eigen/buckling analysis
- material plasticity
- layered composite shell section
- contact analysis
- Abaqus/Nastran 실행 자동화
- reference artifact 자동 생성
- OpenSees API 호환성
- Phase 1 mesh quality scoring
## 확장 로드맵
MITC4 선형정적 기능이 reference 검증을 통과한 뒤 다음 기능을 별도 요구조건과 정식화 문서로 진행한다.
1. nonlinear static analysis
2. nonlinear dynamic analysis
3. heat transfer and thermal-stress coupling
4. 1D truss/beam and 3D solid elements
5. additional material models and properties
## Dependency Requirements
- MSVC and CMake must be available for C++ build validation.
- Intel oneAPI MKL must be available through `MKLROOT` or known oneAPI installation paths.
- Intel oneAPI TBB must be available through `TBBROOT` or known oneAPI installation paths.
- HDF5 C library must be supplied through `HDF5_ROOT` or `HDF5_DIR`.
- Python 3 must be available for harness validation and phase execution.
## Release Requirements
Solver feature release is allowed only when:
1. Requirements are approved.
2. Research evidence and formulation are reviewed.
3. I/O contract and HDF5 schema are fixed.
4. Reference model artifacts exist and provenance is documented.
5. C++ TDD implementation passes CTest.
6. Reference comparison passes tolerance `1e-5`.
7. Known limitations are written in the release document.
+251
View File
@@ -0,0 +1,251 @@
# 솔버 설계 문서
## 목표
FESA는 MITC4 Shell 요소 기반 구조해석에서 시작해 비선형 정적해석, 비선형 동적해석, 열전달 및 thermal-stress coupling, 1D/3D 요소까지 확장하는 유한요소 솔버이다.
초기 구현은 정확도와 테스트 가능성을 우선한다. 단, 대규모 모델을 목표로 하므로 자유도 관리, 희소 행렬 조립, 선형 솔버, 병렬 실행 계층은 초기부터 성능 확장이 가능하도록 분리한다.
## 설계 원칙
- Domain 객체는 입력 모델의 의미를 보존하고 가능한 한 불변에 가깝게 유지한다.
- 해석 중 변하는 물리량과 반복 상태는 AnalysisState에 명시적으로 분리한다.
- 요소, 재료, 하중, 경계조건, 해석 알고리즘은 런타임 다형성 기반으로 확장한다.
- 결과는 step/frame/field/history 개념으로 저장하여 정적, 비선형, 동적, 열전달 해석을 같은 결과 모델로 다룬다.
- 외부 라이브러리(MKL, TBB, HDF5)는 adapter 계층 뒤에 둔다.
- Abaqus input 호환성은 파서와 factory/registry 계층에서 관리한다.
- shell node는 6자유도이고, 단위계는 강제하지 않으며, 결과 부호는 Abaqus 규약을 따른다.
- 경계조건은 constrained DOF 제거 방식으로 적용하고, reaction은 full vector 기준 `K_full * U_full - F_full`로 계산한다.
- 기본 실수 precision은 `double`이고, 대규모 모델을 위해 id/index/equation numbering은 int64 기반으로 설계한다.
- Mesh quality 진단은 1차 범위에서 제외한다. 대신 singular system 진단은 필수로 제공한다.
## 디렉토리 구조
```
src/
├── Analysis/ # Static, nonlinear static, dynamic, heat transfer analysis
├── Assembly/ # 전역 행렬/벡터 조립, sparse pattern 생성
├── Boundary/ # Fix, RBE2, RBE3 등 경계조건
├── Core/ # Domain, AnalysisModel, AnalysisState, DofManager
├── Element/ # Node, Element, MITC4 등 요소 구현
├── IO/ # Abaqus input parser, HDF5 results writer
├── Load/ # NodalLoad, PressureLoad, BodyForce 등 하중
├── Math/ # Vector, Matrix, SparseMatrix, MKL adapter
├── Material/ # LinearElastic 등 재료 모델
├── Property/ # ShellProperty, 1D/2D/3D property
├── Results/ # Step, Frame, FieldOutput, HistoryOutput
└── Util/ # 공통 유틸리티, 로깅, 검증 보조 함수
```
## 핵심 클래스 구조
```
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
```
## 디자인 패턴
### 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()`에서 고정하고, 세부 단계는 해석 종류별로 재정의한다.
기본 흐름:
```
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 분리를 추가한다.
## 상태 관리
### Domain
`Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다.
포함 대상:
- nodes, elements
- materials, properties
- node sets, element sets
- loads, boundary conditions
- analysis step definitions
### AnalysisModel
`AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않고 참조 또는 id 기반 view로 구성한다.
포함 대상:
- active elements
- active loads
- active boundary conditions
- active property/material references
- current equation system view
### DofManager
`DofManager`는 자유도와 방정식 번호를 전담한다. Node 또는 Element 내부에 equation id를 분산 저장하지 않는다.
책임:
- node별 활성 자유도 정의
- constrained/free dof mapping
- equation numbering
- sparse matrix pattern 생성에 필요한 connectivity 제공
- 경계조건 적용 전후의 dof view 관리
### 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 확장 지점을 유지한다.
### Results State
결과는 `ResultStep` -> `ResultFrame` -> `FieldOutput`/`HistoryOutput` 구조로 관리한다.
- `ResultStep`: 해석 step 단위 결과
- `ResultFrame`: 정적해석의 load increment 또는 동적해석의 time frame
- `FieldOutput`: node/element field 결과
- `HistoryOutput`: 특정 node, element, set, reaction, energy 등의 이력 결과
## 데이터 흐름
```
Abaqus input file
-> InputParser
-> Domain 생성
-> StepDefinition 루프
-> AnalysisModel 생성
-> DofManager로 자유도/방정식 번호 생성
-> sparse pattern 생성
-> Analysis 실행
-> Assembler로 전역 행렬/벡터 조립
-> BoundaryCondition 적용
-> LinearSolver 또는 nonlinear/time integration loop
-> AnalysisState 갱신
-> ResultsWriter로 step/frame/history 저장
-> 다음 step 진행
```
## 성능 확장 방향
- 행렬 조립은 element 단위 병렬화를 고려해 설계한다.
- 전역 행렬은 대규모 모델을 위해 sparse matrix를 기본으로 한다.
- MKL 기반 direct solver를 우선 지원하되, solver interface는 iterative solver를 추가할 수 있게 둔다.
- 대규모 sparse solve를 위해 MKL `pardiso_64`를 사용할 수 있도록 64-bit sparse index 경계를 유지한다.
- TBB 병렬화는 요소 stiffness 계산, element force 계산, assembly precompute 등 독립 작업부터 적용한다.
- 정확도 검증이 끝나기 전에는 MITC4 element formulation을 과도하게 최적화하지 않는다.