From 5a235025703db0a0a37736278df73b465728cfed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EA=B2=BD=EC=A2=85?= Date: Fri, 5 Jun 2026 16:31:21 +0900 Subject: [PATCH] add initial plan --- AGENTS.md | 85 +++++- SOLVER_IMPLEMENT_INITIAL_PLAN.md | 313 +++++++++++++++++++ docs/ADR.md | 110 +++++-- docs/ARCHITECTURE.md | 338 ++++++++++++++++++--- docs/PRD.md | 112 ++++++- docs/SOLVER_ARCHITECTURE_INITIAL_DISIGN.md | 251 +++++++++++++++ 6 files changed, 1116 insertions(+), 93 deletions(-) create mode 100644 SOLVER_IMPLEMENT_INITIAL_PLAN.md create mode 100644 docs/SOLVER_ARCHITECTURE_INITIAL_DISIGN.md diff --git a/AGENTS.md b/AGENTS.md index ada05a7..82523d3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -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 python scripts/execute.py --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`. diff --git a/SOLVER_IMPLEMENT_INITIAL_PLAN.md b/SOLVER_IMPLEMENT_INITIAL_PLAN.md new file mode 100644 index 0000000..5ce3451 --- /dev/null +++ b/SOLVER_IMPLEMENT_INITIAL_PLAN.md @@ -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.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. diff --git a/docs/ADR.md b/docs/ADR.md index 1ba9166..2ab7130 100644 --- a/docs/ADR.md +++ b/docs/ADR.md @@ -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. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 1747640..6e91c9d 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -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/// +-> 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. diff --git a/docs/PRD.md b/docs/PRD.md index a6630fb..3f2b012 100644 --- a/docs/PRD.md +++ b/docs/PRD.md @@ -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. diff --git a/docs/SOLVER_ARCHITECTURE_INITIAL_DISIGN.md b/docs/SOLVER_ARCHITECTURE_INITIAL_DISIGN.md new file mode 100644 index 0000000..d3bb8d3 --- /dev/null +++ b/docs/SOLVER_ARCHITECTURE_INITIAL_DISIGN.md @@ -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을 과도하게 최적화하지 않는다. +