Compare commits
2 Commits
4998ad615e
...
b7b5fc3835
| Author | SHA1 | Date | |
|---|---|---|---|
| b7b5fc3835 | |||
| 4bb05d23eb |
@@ -10,11 +10,12 @@
|
|||||||
- Abaqus `.inp` keyword subset input
|
- Abaqus `.inp` keyword subset input
|
||||||
|
|
||||||
## 프로젝트 정체성
|
## 프로젝트 정체성
|
||||||
- FESA는 유한요소법 기반 구조해석 솔버 개발 프로젝트이다.
|
- FESA는 유한요소법 기반 구조해석 솔버를 단계적으로 구축하고 검증하는 프로젝트이다. 목표는 Abaqus를 흉내 내는 parser를 만드는 것이 아니라, 승인된 입력 범위에서 물리적으로 설명 가능하고 재현 가능한 해석 결과를 만드는 것이다.
|
||||||
|
- 새 기능은 입력 keyword만 인식하거나 element kernel만 존재한다고 완성된 것이 아니다. Semantic model, equation system, 해법, 결과 복구, HDF5 외부 계약과 독립 검증 evidence가 하나의 추적 가능한 기능을 이뤄야 한다.
|
||||||
- 프로젝트의 배경, 목적, 사용자, 범위는 `docs/PRD.md`에서 확인한다.
|
- 프로젝트의 배경, 목적, 사용자, 범위는 `docs/PRD.md`에서 확인한다.
|
||||||
- 전체 아키텍처와 모듈별 책임은 `docs/ARCHITECTURE.md`에서 확인한다.
|
- 전체 아키텍처와 모듈별 책임은 `docs/ARCHITECTURE.md`에서 확인한다.
|
||||||
- 주요 아키텍처 결정과 그 이유 및 트레이드오프는 `docs/ADR.md`에서 확인한다.
|
- 주요 아키텍처 결정과 그 이유 및 트레이드오프는 `docs/ADR.md`에서 확인한다.
|
||||||
- AI 에이전트는 설계나 구현 결정을 내리기 전에 위 문서 중 작업과 관련된 내용을 참조한다.
|
- AI 에이전트는 설계나 구현 결정을 내리기 전에 PRD에서 제품 범위를, ARCHITECTURE에서 소유권과 데이터 흐름을, ADR에서 이미 결정된 트레이드오프를 먼저 확인한다. 기능별 의미는 `docs/requirements/`, `docs/formulations/`, `docs/io-definitions/`, `docs/reference-models/`의 승인 문서를 source of truth로 삼는다.
|
||||||
- Harness는 솔버 자체가 아니라 요구조건, TDD, phase 실행, 검증을 통제하는 개발 운영 인프라이다. 전체 실행 흐름은 `docs/HARNESS_WORKFLOW.md`, 설치와 설정은 `docs/HARNESS.md`를 따른다.
|
- Harness는 솔버 자체가 아니라 요구조건, TDD, phase 실행, 검증을 통제하는 개발 운영 인프라이다. 전체 실행 흐름은 `docs/HARNESS_WORKFLOW.md`, 설치와 설정은 `docs/HARNESS.md`를 따른다.
|
||||||
- 문서와 구현은 full Abaqus compatibility를 주장하지 않는다. 기능별로 승인된 Abaqus keyword subset만 지원한다.
|
- 문서와 구현은 full Abaqus compatibility를 주장하지 않는다. 기능별로 승인된 Abaqus keyword subset만 지원한다.
|
||||||
- 공식 solver output은 HDF5 `results.h5`이다.
|
- 공식 solver output은 HDF5 `results.h5`이다.
|
||||||
@@ -23,18 +24,42 @@
|
|||||||
- 승인된 B33 baseline은 예외적으로 `reference/cantilever beam/`의 기존 space-containing 파일명을 read-only legacy alias로 사용한다.
|
- 승인된 B33 baseline은 예외적으로 `reference/cantilever beam/`의 기존 space-containing 파일명을 read-only legacy alias로 사용한다.
|
||||||
- CSV는 FESA 공식 output이 아니며, FESA HDF5에서 추출한 deterministic CSV view는 비교 디버깅/검토용 보조 artifact로만 둔다.
|
- CSV는 FESA 공식 output이 아니며, FESA HDF5에서 추출한 deterministic CSV view는 비교 디버깅/검토용 보조 artifact로만 둔다.
|
||||||
|
|
||||||
## 아키텍처 규칙
|
## FESA 개발의 핵심 원칙
|
||||||
|
|
||||||
|
### 물리와 수치 계약
|
||||||
|
|
||||||
|
- CRITICAL: 구현보다 요구조건, 정식화, 부호, 단위, 좌표계, row identity와 tolerance 계약을 먼저 고정한다. 구현 편의를 위해 승인된 의미를 조용히 바꾸지 않는다.
|
||||||
|
- CRITICAL: 해석 결과가 유한하고 선형계가 풀렸다는 사실만으로 correctness를 주장하지 않는다. Equilibrium, reaction, rigid-body mode, energy, symmetry와 reference identity를 기능에 맞게 검증한다.
|
||||||
|
- Source label/instance identity와 internal index/equation index를 구분한다. Stable source identity는 진단, 결과, reference mapping 전 구간에서 보존한다.
|
||||||
|
- 병렬 실행 여부와 관계없이 같은 입력은 같은 sparse structure, reduction order, result row order와 diagnostic order를 만들어야 한다.
|
||||||
|
- Scale-aware validation은 formulation과 I/O 계약의 기준을 사용한다. 임의의 `max(1, ...)`, zero clamp, 누락 row 무시 또는 불일치 평균으로 오류를 숨기지 않는다.
|
||||||
|
|
||||||
|
### 소유권과 의존성
|
||||||
|
|
||||||
- CRITICAL: C++ 빌드는 CMake/MSVC/x64/Debug 기준으로 검증한다.
|
- CRITICAL: C++ 빌드는 CMake/MSVC/x64/Debug 기준으로 검증한다.
|
||||||
- CRITICAL: 새 기능 또는 동작 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현한다.
|
- CRITICAL: 새 기능 또는 동작 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현한다.
|
||||||
- CRITICAL: C++ production file을 바꿀 때는 관련 C++ test file이 있어야 한다.
|
- CRITICAL: C++ production file을 바꿀 때는 관련 C++ test file이 있어야 한다.
|
||||||
- CRITICAL: Abaqus reference artifact 생성, 수정, 복원은 명시적으로 요청된 phase에서만 수행한다.
|
- CRITICAL: Abaqus reference artifact 생성, 수정, 복원은 명시적으로 요청된 phase에서만 수행한다.
|
||||||
- CRITICAL: public header와 implementation 의존성 방향을 역전하지 말 것
|
- CRITICAL: public header와 implementation 의존성 방향을 역전하지 않는다.
|
||||||
- CRITICAL: 사람 개발자가 검토하기 쉽도록 코드를 작성할것. 그리고 주석도 필수로 작성할 것.
|
- CRITICAL: 사람이 계약과 수치식을 대조할 수 있는 단순한 코드를 작성한다. 주석은 코드가 이미 말하는 동작보다 부호, 수명, 순서, backend 제약처럼 비자명한 이유를 설명한다.
|
||||||
- Domain은 입력 파일에서 생성된 전체 모델 정의를 소유하고, 파싱 이후 가능한 한 불변으로 취급한다.
|
- Domain은 입력 파일에서 생성된 전체 모델 정의를 소유하고, 파싱 이후 가능한 한 불변으로 취급한다.
|
||||||
- AnalysisModel은 현재 step에서 활성화된 elements, loads, boundary conditions, properties/materials의 view를 제공하며 Domain을 복사하지 않는다.
|
- AnalysisModel은 현재 step에서 활성화된 elements, loads, boundary conditions, properties/materials의 non-owning view를 제공하며 Domain을 복사하지 않는다. 따라서 Domain은 AnalysisModel보다 오래 살아야 한다.
|
||||||
- DofManager는 node별 자유도 정의, constrained/free mapping, equation numbering, sparse pattern ownership을 전담한다. Node 또는 Element 내부에 equation id를 분산 저장하지 않는다.
|
- DofManager는 node별 자유도 정의, constrained/free mapping, equation numbering, sparse pattern ownership을 전담한다. Node 또는 Element 내부에 equation id를 분산 저장하지 않는다.
|
||||||
- AnalysisState는 displacement, velocity, acceleration, temperature, external/internal force, residual, time/increment/iteration, element state를 소유한다.
|
- AnalysisState는 해당 procedure가 실제로 사용하는 mutable solution과 recovery row만 소유한다. V0는 full displacement/external/internal force/residual/reaction과 step/frame 및 beam recovery rows만 보관하며 미래 state를 미리 할당하지 않는다.
|
||||||
- MKL, TBB, HDF5 API는 solver core에 직접 노출하지 않는다. `LinearSolver`, `ParallelFor`, `ResultsWriter`, `Vector`, `Matrix`, `SparseMatrix` adapter 경계 뒤에 둔다.
|
- MKL, TBB, HDF5, Win32 API와 vendor type은 public solver core에 노출하지 않는다. `LinearSolver`, `ParallelFor`, `ResultsWriter`, `Vector`, `Matrix`, `SparseMatrix` 경계 뒤에 둔다.
|
||||||
|
- 해석 단계는 실패할 수 있는 candidate를 완성하고 검증한 뒤 소유 state/output에 반영한다. 실패 시 기존 state와 기존 최종 HDF5를 가능한 계약 범위에서 보존한다.
|
||||||
|
|
||||||
|
### 선형 정적 해석 불변식
|
||||||
|
|
||||||
|
- `Analysis::run()`의 실제 단계와 객체별 책임은 `docs/ARCHITECTURE.md`의 해석 실행 흐름을 따른다.
|
||||||
|
- Full stiffness를 stable free/constrained 순서로 `Kff/Kfc/Kcf/Kcc`에 분할하고, `Kff` factorization을 load assembly보다 먼저 수행한다.
|
||||||
|
- Effective RHS는 `Ff - Kfc * dc`이며 substitution 뒤 full displacement를 복구한다. 모든 DOF가 constrained인 유효한 모델의 `0 x 0 Kff`를 singular error로 바꾸지 않는다.
|
||||||
|
- Reaction과 free-equilibrium evidence는 조립된 full residual `K*d - F`에서 구한다. Constrained 성분은 physical reaction이고 free 성분은 residual evidence다.
|
||||||
|
- Sparse assembly는 element-local contribution과 stable COO ordering, 고정된 reduction을 사용한다. 병렬 worker가 global CSR storage를 직접 갱신하지 않는다.
|
||||||
|
- Element end action, positive-local-x section resultant, Gauss generalized result와 section-point stress는 서로 다른 identity와 부호 계약을 가진다. Station mismatch를 평균으로 합치지 않는다.
|
||||||
|
|
||||||
|
### 개발 운영 인프라
|
||||||
|
|
||||||
- Codex custom agent의 `model_reasoning_effort` 기본값은 `extra high`로 둔다.
|
- Codex custom agent의 `model_reasoning_effort` 기본값은 `extra high`로 둔다.
|
||||||
- Harness runner는 `scripts/execute.py`에 둔다.
|
- Harness runner는 `scripts/execute.py`에 둔다.
|
||||||
- `scripts/execute.py`는 `feat-<phase-name>` branch prefix를 사용한다.
|
- `scripts/execute.py`는 `feat-<phase-name>` branch prefix를 사용한다.
|
||||||
@@ -53,6 +78,15 @@
|
|||||||
- B33 reference row는 component별 Abaqus scale로 `absolute_floor + 1e-6 * reference_scale`을 적용한다. Reference 값을 zero-clamp하거나 누락 row를 무시하지 않는다.
|
- B33 reference row는 component별 Abaqus scale로 `absolute_floor + 1e-6 * reference_scale`을 적용한다. Reference 값을 zero-clamp하거나 누락 row를 무시하지 않는다.
|
||||||
- `reference/cantilever beam/` artifact는 rename, rewrite 또는 보정하지 않는다.
|
- `reference/cantilever beam/` artifact는 rename, rewrite 또는 보정하지 않는다.
|
||||||
|
|
||||||
|
## 기능을 추가할 때의 판단 기준
|
||||||
|
|
||||||
|
- 새 element는 요구조건과 formulation을 승인한 뒤 semantic mapping, property/material 연결, DOF/scatter, local kernel, deterministic assembly, recovery, HDF5 row identity, reference/physics evidence를 함께 설계한다.
|
||||||
|
- 새 load 또는 constraint는 parser 인식만 추가하지 않는다. Source target resolution, stable application order, full-space assembly, partition/effective RHS, diagnostic과 결과 의미까지 연결한다.
|
||||||
|
- 새 analysis procedure는 기존 선형 정적 lifecycle에 조건문을 누적하지 않는다. 필요한 state, equation, solver lifecycle과 recovery contract를 별도 요구조건·ADR·formulation으로 정의한다.
|
||||||
|
- 새 backend는 기존 public interface를 유지하고 vendor lifecycle, integer/index conversion, runtime dependency와 failure translation을 adapter 내부에 격리한다.
|
||||||
|
- 새 output quantity는 계산식뿐 아니라 units, coordinate system, source/internal identity, HDF5 schema, mandatory 여부, reference projection과 tolerance를 동시에 정의한다.
|
||||||
|
- Element API에 kernel이 존재하는 것과 Abaqus keyword/CLI에서 그 기능을 노출하는 것은 별도 계약이다. 예를 들어 V0의 line-load kernel은 `*DLOAD` 지원을 뜻하지 않는다.
|
||||||
|
|
||||||
## 개발 프로세스
|
## 개발 프로세스
|
||||||
- TDD를 기본으로 한다. 구현은 `RED -> GREEN -> VERIFY` 순서를 따른다.
|
- TDD를 기본으로 한다. 구현은 `RED -> GREEN -> VERIFY` 순서를 따른다.
|
||||||
- CRITICAL: 빌드 경고를 새로 추가하지 말 것.
|
- CRITICAL: 빌드 경고를 새로 추가하지 말 것.
|
||||||
@@ -88,7 +122,9 @@ AI 에이전트는 유한요소 구조해석 지식이 필요할 때 FEM wiki를
|
|||||||
| 물리 검토 | `physics-evaluation-agent` | `fesa-physics-sanity` | `docs/physics-evaluations/<feature-id>-physics-evaluation.md` |
|
| 물리 검토 | `physics-evaluation-agent` | `fesa-physics-sanity` | `docs/physics-evaluations/<feature-id>-physics-evaluation.md` |
|
||||||
| 배포 준비 | `release-agent` | `fesa-release-readiness` | `docs/releases/<feature-id>-release.md` |
|
| 배포 준비 | `release-agent` | `fesa-release-readiness` | `docs/releases/<feature-id>-release.md` |
|
||||||
|
|
||||||
## 명령어
|
## 최소 검증 진입점
|
||||||
|
|
||||||
|
세부 target graph, dependency normalization과 Windows runtime staging은 `docs/ARCHITECTURE.md`와 실제 CMake 파일을 따른다. `.harness/config.json`이 존재하면 그 설정을 우선한다.
|
||||||
|
|
||||||
### Harness Python 검증
|
### Harness Python 검증
|
||||||
|
|
||||||
@@ -106,18 +142,19 @@ python scripts/execute.py <phase-name> --push
|
|||||||
### CMake/CTest 프로젝트
|
### CMake/CTest 프로젝트
|
||||||
|
|
||||||
```powershell
|
```powershell
|
||||||
cmake -S . -B .harness/build -A x64
|
$gtestSource = "C:/path/to/googletest"
|
||||||
|
$mklDir = "C:/path/to/oneAPI/mkl/lib/cmake/mkl"
|
||||||
|
$tbbDir = "C:/path/to/oneAPI/tbb/lib/cmake/tbb"
|
||||||
|
$hdf5Dir = "C:/path/to/HDF5/cmake"
|
||||||
|
|
||||||
|
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||||
|
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||||
|
"-DMKL_DIR=$mklDir" `
|
||||||
|
"-DTBB_DIR=$tbbDir" `
|
||||||
|
"-DHDF5_DIR=$hdf5Dir"
|
||||||
cmake --build .harness/build --config Debug
|
cmake --build .harness/build --config Debug
|
||||||
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
ctest --test-dir .harness/build -C Debug --output-on-failure
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
```
|
```
|
||||||
|
|
||||||
### Visual Studio solution 프로젝트
|
`FESA_GTEST_SOURCE_DIR`는 approved local GoogleTest source checkout을 반드시 가리켜야 한다. MKL/TBB/HDF5가 기본 package search에서 발견되지 않는 환경에서는 나머지 세 config directory도 명시한다. FESA 제품 검증은 solution-only MSBuild가 아니라 CMake target과 CTest를 기준으로 한다.
|
||||||
|
|
||||||
```powershell
|
|
||||||
MSBuild.exe MyProject.sln /m /p:Configuration=Debug /p:Platform=x64
|
|
||||||
.\build\tests\Debug\MyProjectTests.exe
|
|
||||||
```
|
|
||||||
|
|
||||||
실제 solution, preset, 테스트 명령은 `.harness/config.json`과 프로젝트 문서를
|
|
||||||
우선한다.
|
|
||||||
|
|||||||
+70
-1
@@ -39,7 +39,7 @@ solution과 test command를 명시한 직접 MSBuild 프로젝트도 검증할
|
|||||||
|
|
||||||
**이유**: 모델 정의, step activation, equation system, transient/nonlinear state가 섞이면 parser, assembler, solver, result writer가 강하게 결합된다. 분리된 상태 모델은 선형 정적 해석에서 시작해 비선형, 동적, thermal coupling으로 확장하기 쉽다.
|
**이유**: 모델 정의, step activation, equation system, transient/nonlinear state가 섞이면 parser, assembler, solver, result writer가 강하게 결합된다. 분리된 상태 모델은 선형 정적 해석에서 시작해 비선형, 동적, thermal coupling으로 확장하기 쉽다.
|
||||||
|
|
||||||
**트레이드오프**: 초기 class 수가 늘어난다. Phase 1에서는 interface를 얇게 유지하고 displacement 중심 state부터 구현한다.
|
**트레이드오프**: 초기 class 수가 늘어난다. V0에서는 interface를 얇게 유지하고 실제 선형 정적 frame에 필요한 state만 구현한다.
|
||||||
|
|
||||||
### ADR-005: 공식 결과 파일은 HDF5로 하고 reference 결과는 Abaqus CSV로 둔다
|
### ADR-005: 공식 결과 파일은 HDF5로 하고 reference 결과는 Abaqus CSV로 둔다
|
||||||
**결정**: FESA solver의 authoritative result output은 `results.h5` HDF5이다. Abaqus reference results는 기능별 reference model contract가 지정한 `reference/<model-id>/` 아래 CSV 파일로 저장하며, verification은 FESA HDF5 rows와 Abaqus reference CSV rows를 documented IDs, components, units, coordinate system, step/frame identity, tolerance 기준으로 비교한다. 신규 reference는 canonical 파일명을 사용하고, 승인된 기존 bundle의 legacy alias는 해당 기능 계약에 정확한 경로를 기록한 경우에만 허용한다.
|
**결정**: FESA solver의 authoritative result output은 `results.h5` HDF5이다. Abaqus reference results는 기능별 reference model contract가 지정한 `reference/<model-id>/` 아래 CSV 파일로 저장하며, verification은 FESA HDF5 rows와 Abaqus reference CSV rows를 documented IDs, components, units, coordinate system, step/frame identity, tolerance 기준으로 비교한다. 신규 reference는 canonical 파일명을 사용하고, 승인된 기존 bundle의 legacy alias는 해당 기능 계약에 정확한 경로를 기록한 경우에만 허용한다.
|
||||||
@@ -112,3 +112,72 @@ solution과 test command를 명시한 직접 MSBuild 프로젝트도 검증할
|
|||||||
**이유**: 자유단 moment처럼 이론적으로 0인 값에는 행별 상대오차가 정의되지 않으며 Abaqus 결과에 작은 수치 잔차가 남을 수 있다. Component scale을 사용하면 전체 물리량 크기에 비해 작은 잔차를 허용하면서 각 row를 결정적으로 판정할 수 있다.
|
**이유**: 자유단 moment처럼 이론적으로 0인 값에는 행별 상대오차가 정의되지 않으며 Abaqus 결과에 작은 수치 잔차가 남을 수 있다. Component scale을 사용하면 전체 물리량 크기에 비해 작은 잔차를 허용하면서 각 row를 결정적으로 판정할 수 있다.
|
||||||
|
|
||||||
**트레이드오프**: 큰 component scale은 zero row의 허용폭을 넓힌다. 이를 완화하기 위해 quantity와 component를 섞지 않고 Abaqus 값만 scale에 사용하며, 모든 row의 absolute/normalized error와 worst row를 보고하고 누락·추가·nonfinite row를 tolerance 전에 실패시킨다.
|
**트레이드오프**: 큰 component scale은 zero row의 허용폭을 넓힌다. 이를 완화하기 위해 quantity와 component를 섞지 않고 Abaqus 값만 scale에 사용하며, 모든 row의 absolute/normalized error와 worst row를 보고하고 누락·추가·nonfinite row를 tolerance 전에 실패시킨다.
|
||||||
|
|
||||||
|
### ADR-015: 외부 CMake target을 FESA 경계로 정규화하고 Windows runtime closure를 명시한다
|
||||||
|
|
||||||
|
**결정**: MKL, TBB, HDF5 CONFIG package가 제공하는 target은 dependency module에서
|
||||||
|
`Fesa::MKL`, `Fesa::TBB`, `Fesa::HDF5`로 정규화한다. Product target은 이 경계만
|
||||||
|
`PRIVATE` link하고 public header에 vendor/Win32 type을 노출하지 않는다. Approved Windows
|
||||||
|
환경에서는 packaged shared HDF5 C target을 우선하며, CLI와 test executable 옆에 TBB,
|
||||||
|
MKL, OpenMP, Intel math runtime, HDF5를 포함한 실제 runtime DLL closure를 POST_BUILD로
|
||||||
|
stage한다.
|
||||||
|
|
||||||
|
**이유**: Package version이나 shared/static variant에 따라 imported target 이름과 숨은
|
||||||
|
runtime dependency가 달라질 수 있다. Configure와 link 성공만 확인하면 GoogleTest
|
||||||
|
discovery 또는 배포된 CLI가 `0xc0000135`로 실패할 수 있다. FESA-owned target과 명시적
|
||||||
|
runtime closure는 module code와 실행 환경을 package 세부사항에서 분리한다.
|
||||||
|
|
||||||
|
**트레이드오프**: Windows staging CMake가 길어지고 새 dynamic dependency마다 runtime
|
||||||
|
audit가 필요하다. 대신 개인 설치 경로를 source에 하드코딩하거나 developer `PATH`에
|
||||||
|
의존하지 않고 build tree executable을 재현 가능하게 실행할 수 있다.
|
||||||
|
|
||||||
|
### ADR-016: 결정론과 failure atomicity를 correctness contract로 취급한다
|
||||||
|
|
||||||
|
**결정**: Parallel element 계산은 index별 독립 buffer만 쓰고, COO tuple ordering과
|
||||||
|
floating-point sum은 join 이후 고정된 serial 순서로 수행한다. Result recovery, solver
|
||||||
|
output, HDF5 writer는 candidate를 완성·검증한 뒤 caller-owned state 또는 final file에
|
||||||
|
commit한다. HDF5는 same-directory temporary file을 checked close/reopen한 후에만 atomic
|
||||||
|
finalization한다.
|
||||||
|
|
||||||
|
**이유**: Reference comparison과 물리 검토는 row identity와 작은 수치 차이에 민감하다.
|
||||||
|
Thread scheduling 또는 중간 실패가 sparse bytes, result order, 이전 output을 바꾸면 같은
|
||||||
|
입력에 대한 evidence를 신뢰할 수 없다.
|
||||||
|
|
||||||
|
**트레이드오프**: Serial reduction과 candidate copy가 throughput과 memory를 더 사용할 수
|
||||||
|
있다. 성능 최적화는 동일한 ordering, failure preservation, reference 결과를 증명할 때만
|
||||||
|
대체할 수 있으며, nondeterministic global sparse write는 허용하지 않는다.
|
||||||
|
|
||||||
|
### ADR-017: Essential constraint는 stable elimination으로 적용하고 reaction은 full residual로 정의한다
|
||||||
|
|
||||||
|
**결정**: V0는 DofManager의 stable free/constrained order로 full stiffness를
|
||||||
|
`Kff/Kfc/Kcf/Kcc`로 분할하고 `Kff * df = Ff - Kfc * dc`를 푼 뒤 full displacement를
|
||||||
|
복구한다. 모든 DOF가 constrained인 모델의 `0 x 0 Kff`는 유효한 trivial factorization과
|
||||||
|
empty substitution이다. Recovery의 full residual `r = K*d - F`를 reaction vector로
|
||||||
|
보존하며 constrained entry는 physical reaction, free entry는 equilibrium evidence다.
|
||||||
|
|
||||||
|
**이유**: Equation numbering과 prescribed displacement를 한 owner가 관리하면 nonzero
|
||||||
|
constraint, no/all/mixed constraint가 같은 수식과 stable order를 사용한다. Full residual은
|
||||||
|
element end action을 별도로 합산하는 경로보다 조립·하중·해법 전체의 equilibrium을 직접
|
||||||
|
검증한다.
|
||||||
|
|
||||||
|
**트레이드오프**: Full K와 네 partition을 유지하는 메모리 비용이 있고 reaction vector의
|
||||||
|
free entry가 정확한 0이라고 가정할 수 없다. V0에는 penalty, MPC, Lagrange multiplier를
|
||||||
|
혼합하지 않으며, 추가 constraint policy는 별도 formulation과 equation/output 계약을
|
||||||
|
요구한다.
|
||||||
|
|
||||||
|
### ADR-018: Kernel 존재와 제품 노출을 분리하고 계층형 검증을 요구한다
|
||||||
|
|
||||||
|
**결정**: Local element/load/recovery kernel이 존재해도 syntax, semantic Domain mapping,
|
||||||
|
analysis orchestration, mandatory HDF5와 diagnostic 계약이 연결되지 않으면 CLI 지원으로
|
||||||
|
간주하지 않는다. 검증은 unit, integration, reference comparison, physics sanity를 서로
|
||||||
|
대체할 수 없는 계층으로 유지한다. Reference가 가능하지 않은 quantity는 명시적 N/A와
|
||||||
|
analytical/schema/physics 대체 evidence를 요구한다.
|
||||||
|
|
||||||
|
**이유**: Unit test는 수식과 validation을, integration test는 lifetime과 호출 순서를,
|
||||||
|
reference comparison은 외부 solver와의 수치 일치를, physics sanity는 공통-mode 오류와
|
||||||
|
model adequacy를 검출한다. 한 계층의 성공만으로 parser exposure 또는 물리 correctness를
|
||||||
|
추론하면 지원 범위와 검증 강도가 과장된다.
|
||||||
|
|
||||||
|
**트레이드오프**: 작은 기능도 여러 계약과 evidence를 함께 준비해야 하므로 개발 속도가
|
||||||
|
느려진다. 대신 `*DLOAD`처럼 kernel은 있지만 입력에 노출되지 않은 기능, stress처럼
|
||||||
|
mandatory output이지만 Abaqus reference가 N/A인 기능을 정확하게 표현할 수 있다.
|
||||||
|
|||||||
+130
-131
@@ -17,39 +17,32 @@ source of truth는
|
|||||||
그 계약을 전체 solver architecture의 모듈과 데이터 흐름에 배치한다. 아래에 나타난
|
그 계약을 전체 solver architecture의 모듈과 데이터 흐름에 배치한다. 아래에 나타난
|
||||||
비선형, 동적, thermal 및 다른 element 계층은 장기 확장 경계이며 V0 지원 범위가 아니다.
|
비선형, 동적, thermal 및 다른 element 계층은 장기 확장 경계이며 V0 지원 범위가 아니다.
|
||||||
|
|
||||||
## 디렉토리 구조
|
## 현재 구현된 디렉토리 구조
|
||||||
```text
|
```text
|
||||||
|
include/fesa/ # backend-neutral public C++ API
|
||||||
src/
|
src/
|
||||||
fesa/
|
fesa/
|
||||||
core/ # ids, status, diagnostics, units, small value types
|
analysis/ # Analysis lifecycle, V0 LinearStaticAnalysis
|
||||||
|
app/ # CLI application and main
|
||||||
|
assembly/ # deterministic stiffness/load assembly, ParallelFor adapter
|
||||||
|
constraints/ # essential-constraint elimination and reconstruction
|
||||||
|
core/ # source identity, status, diagnostics
|
||||||
|
elements/ # V0 EulerBeam3D kernel and recovery
|
||||||
|
fem/ # DOF/equation numbering and sparse pattern
|
||||||
io/
|
io/
|
||||||
abaqus/ # .inp lexer/parser, keyword subset, include policy
|
abaqus/ # .inp syntax reader and semantic Domain mapper
|
||||||
hdf5/ # HDF5 result writer/reader, schema versioning
|
hdf5/ # private HDF5 writer and atomic finalization
|
||||||
model/ # semantic model: nodes, elements, sets, materials, sections, steps
|
math/ # owning Vector, row-major Matrix, 0-based CSR SparseMatrix
|
||||||
fem/ # DOF space, equation numbering, quadrature, shape functions
|
model/ # concrete V0 semantic records and immutable Domain
|
||||||
elements/ # truss/bar, beam, plane, solid, shell element routines
|
results/ # recovery records, full residual, ResultsWriter boundary
|
||||||
materials/ # elastic/plastic material contracts and state variables
|
|
||||||
assembly/ # local-to-global mapping, sparse pattern, COO/CSR assembly
|
|
||||||
constraints/ # essential BC, MPC, penalty or elimination policies
|
|
||||||
solvers/
|
solvers/
|
||||||
linear/ # MKL PARDISO backend, iterative backend boundary
|
linear/ # LinearSolver interface and MKL PARDISO adapter
|
||||||
nonlinear/ # Newton control, residual/tangent norms, increments
|
|
||||||
analysis/ # static, modal, dynamic, nonlinear procedure drivers
|
|
||||||
results/ # recovery, field/history output, diagnostics
|
|
||||||
validation/ # comparison metrics and tolerance helpers
|
|
||||||
math/ # owning Vector, row-major Matrix, CSR SparseMatrix adapters
|
|
||||||
tests/
|
tests/
|
||||||
unit/
|
unit/ # local contracts and failure paths
|
||||||
integration/
|
integration/ # analysis orchestration and CLI contracts
|
||||||
reference/
|
reference/ # HDF5-to-Abaqus projection and comparison
|
||||||
reference/
|
reference/
|
||||||
<model-id>/
|
<model-id>/ # approved read-only Abaqus input/CSV bundle
|
||||||
model.inp
|
|
||||||
metadata.json
|
|
||||||
<model-id>_displacements.csv
|
|
||||||
<model-id>_reactions.csv
|
|
||||||
<model-id>_internalforces.csv
|
|
||||||
<model-id>_stresses.csv
|
|
||||||
.agents/
|
.agents/
|
||||||
skills/ # Harness and review skills
|
skills/ # Harness and review skills
|
||||||
.codex/
|
.codex/
|
||||||
@@ -64,6 +57,10 @@ scripts/
|
|||||||
phases/ # Optional generated phase plans
|
phases/ # Optional generated phase plans
|
||||||
```
|
```
|
||||||
|
|
||||||
|
`materials/`, nonlinear/dynamic analysis, MPC/penalty policies, general element factories,
|
||||||
|
history output과 production validation module은 장기 확장 경계이지 현재 구현된 module이
|
||||||
|
아니다. 새 디렉토리와 추상 계층은 승인된 기능이 실제로 필요로 할 때 추가한다.
|
||||||
|
|
||||||
## Harness Execution Layer
|
## Harness Execution Layer
|
||||||
|
|
||||||
Harness는 solver core와 분리된 세 계층의 개발 운영 인프라다.
|
Harness는 solver core와 분리된 세 계층의 개발 운영 인프라다.
|
||||||
@@ -74,17 +71,47 @@ Harness는 solver core와 분리된 세 계층의 개발 운영 인프라다.
|
|||||||
|
|
||||||
Runner는 `git add -A`를 사용하므로 clean worktree 또는 별도 Git worktree가 실행 전제다. 전체 동작 계약은 `docs/HARNESS_WORKFLOW.md`, 설치와 `.harness/config.json` 설정은 `docs/HARNESS.md`를 source of truth로 삼는다.
|
Runner는 `git add -A`를 사용하므로 clean worktree 또는 별도 Git worktree가 실행 전제다. 전체 동작 계약은 `docs/HARNESS_WORKFLOW.md`, 설치와 `.harness/config.json` 설정은 `docs/HARNESS.md`를 source of truth로 삼는다.
|
||||||
|
|
||||||
|
## CMake target과 dependency graph
|
||||||
|
|
||||||
|
Root CMake project는 C++17, extension off, CMake 3.25 이상을 요구하고
|
||||||
|
`cmake/FesaDependencies.cmake`, `src/fesa`, `tests`를 차례로 구성한다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
MKL CONFIG package ─> Fesa::MKL ─┐
|
||||||
|
TBB CONFIG package ─> Fesa::TBB ─┼─> fesa_solver (STATIC) ─> fesa_cli
|
||||||
|
HDF5 CONFIG package ─> Fesa::HDF5 ─┘ │
|
||||||
|
├─> fesa_unit_tests
|
||||||
|
approved local GoogleTest source ─> GTest targets ├─> fesa_integration_tests
|
||||||
|
└─> fesa_reference_tests
|
||||||
|
```
|
||||||
|
|
||||||
|
- `FESA_GTEST_SOURCE_DIR`는 네트워크 fetch 대신 승인된 local GoogleTest source checkout을 가리키는 필수 cache path다.
|
||||||
|
- MKL, TBB, HDF5는 CONFIG package로 탐지한다. Package search가 설치를 찾지 못하면 `MKL_DIR`, `TBB_DIR`, `HDF5_DIR`를 configure 때 지정한다.
|
||||||
|
- Package별 imported target 이름은 `Fesa::MKL`, `Fesa::TBB`, `Fesa::HDF5`로 정규화한다. Product module은 vendor target 이름을 직접 선택하지 않는다.
|
||||||
|
- HDF5 package가 shared와 static C target을 모두 제공하면 approved Windows environment에서는 shared target을 우선한다. Static archive의 숨은 compiler-runtime 요구가 link interface 밖으로 새는 것을 피하기 위한 결정이다.
|
||||||
|
- `fesa_solver`는 외부 dependency를 `PRIVATE`으로 link하고 `/W4 /WX`를 사용한다. 따라서 public header는 MKL/TBB/HDF5/Win32 type을 포함하지 않아야 한다.
|
||||||
|
- Test executable은 unit, integration, reference 경계를 분리하며 `fesa_tests` target은 세 executable을 build하는 aggregate target이다. Reference target에만 source/build root compile definition을 제공한다.
|
||||||
|
|
||||||
|
### Windows runtime closure
|
||||||
|
|
||||||
|
Configure 성공은 executable이 GoogleTest discovery 또는 CLI 실행 시 필요한 DLL을 찾는다는
|
||||||
|
뜻이 아니다. `fesa_cli`와 세 test executable의 POST_BUILD 단계는 TBB, MKL thread/core/default
|
||||||
|
dispatch, OpenMP, `libmmd.dll`, HDF5를 포함한 imported-target runtime DLL을 executable 옆에
|
||||||
|
복사한다. 새 dynamic backend를 도입할 때는 link 성공뿐 아니라 clean environment에서의
|
||||||
|
post-build discovery/실행까지 runtime closure로 다뤄야 한다. 개인 설치 absolute path를
|
||||||
|
CMake source에 기록하지 말고 config package와 imported target metadata를 확장한다.
|
||||||
|
|
||||||
## 모듈 경계
|
## 모듈 경계
|
||||||
- `core`는 외부 라이브러리에 의존하지 않는다.
|
- `core`는 외부 라이브러리에 의존하지 않는다.
|
||||||
- `io/abaqus`는 syntax와 semantic mapping만 담당하고 해석 알고리즘을 알지 않는다.
|
- `io/abaqus`는 syntax와 semantic mapping만 담당하고 해석 알고리즘을 알지 않는다.
|
||||||
- `model`은 Abaqus keyword 문자열이 아니라 solver semantic model을 가진다.
|
- `model`은 Abaqus keyword 문자열이 아니라 solver semantic model을 가진다.
|
||||||
- `fem`은 DOF, interpolation, quadrature, local/global mapping을 제공하되 특정 analysis procedure에 종속되지 않는다.
|
- `fem`의 `DofManager`는 DOF, equation ordering, scatter와 sparse pattern을 소유한다.
|
||||||
- `elements`와 `materials`는 local residual/tangent/stress recovery 계약을 제공한다.
|
- `elements`는 local/global stiffness, transformation, optional load kernel과 recovery를 제공한다. V0 material/section은 concrete Domain record다.
|
||||||
- `assembly`는 sparse pattern 생성과 local contribution 조립을 담당한다.
|
- `assembly`는 element-local contribution과 full nodal load를 stable full-DOF space에 조립한다.
|
||||||
- `constraints`는 essential BC, MPC, penalty/elimination 정책을 분리한다.
|
- `constraints`는 V0 essential BC elimination과 full/reduced vector 변환을 담당한다. MPC와 penalty는 현재 범위가 아니다.
|
||||||
- `solvers`는 MKL/TBB 세부 구현을 감추는 backend boundary를 가진다.
|
- `solvers`는 `LinearSolver` 뒤에 MKL PARDISO 세부 구현을 감춘다. TBB는 `assembly/ParallelFor`, HDF5는 `results/ResultsWriter` 경계 뒤에 각각 격리된다.
|
||||||
- `analysis`는 step/history data를 받아 procedure를 실행하고 solver backend와 result writer를 조율한다.
|
- `analysis`는 step/history data를 받아 procedure를 실행하고 solver backend와 result writer를 조율한다.
|
||||||
- `results`는 HDF5 schema를 통해 nodal, element, integration-point, diagnostic output을 분리한다.
|
- `results`는 full residual과 beam rows를 복구하고 backend-neutral writer contract를 제공한다. HDF5 schema 구현은 `io/hdf5`가 담당한다.
|
||||||
- test helper는 production parser/solver 내부 상태를 우회하지 않는다.
|
- test helper는 production parser/solver 내부 상태를 우회하지 않는다.
|
||||||
|
|
||||||
## V0 입력 경계
|
## V0 입력 경계
|
||||||
@@ -139,95 +166,51 @@ CLI pipeline에서는 이 kernel을 호출하지 않는다. Stiffness와 recover
|
|||||||
2점 Gauss rule과 부호 규약을 따른다.
|
2점 Gauss rule과 부호 규약을 따른다.
|
||||||
|
|
||||||
## 핵심 객체 모델
|
## 핵심 객체 모델
|
||||||
|
|
||||||
```text
|
```text
|
||||||
Domain
|
Domain
|
||||||
├── Node
|
├── owns nodes, B33 elements, materials, beam sections, sets
|
||||||
├── Element
|
├── owns boundary conditions, nodal loads, one static step
|
||||||
├── Material
|
└── owns source path/identity and mapping warnings
|
||||||
├── Property
|
|
||||||
├── NodeSet
|
|
||||||
├── ElementSet
|
|
||||||
├── BoundaryCondition
|
|
||||||
├── Load
|
|
||||||
└── StepDefinition
|
|
||||||
|
|
||||||
AnalysisModel
|
AnalysisModel
|
||||||
├── active elements
|
├── non-owning view into Domain
|
||||||
├── active loads
|
├── stable active element/BC/load indices
|
||||||
├── active boundary conditions
|
└── reachable material/section indices
|
||||||
├── active properties/materials
|
|
||||||
└── equation system view
|
DofManager
|
||||||
|
├── owns node x [UX,UY,UZ,URX,URY,URZ] full-DOF numbering
|
||||||
|
├── owns stable free/constrained order and prescribed values
|
||||||
|
├── owns element scatter maps
|
||||||
|
└── owns full-space CSR structural pattern
|
||||||
|
|
||||||
AnalysisState
|
AnalysisState
|
||||||
├── displacement U
|
├── displacement U
|
||||||
├── velocity V
|
|
||||||
├── acceleration A
|
|
||||||
├── temperature T
|
|
||||||
├── external force Fext
|
├── external force Fext
|
||||||
├── internal force Fint
|
├── internal force Fint
|
||||||
├── residual R
|
├── residual R and full-index reaction
|
||||||
├── current time / increment / iteration
|
├── StepFrameIdentity
|
||||||
└── element state / integration point state
|
└── endpoint, Gauss and S11 recovery rows
|
||||||
|
|
||||||
DofManager
|
|
||||||
├── node dof definitions
|
|
||||||
├── constrained/free dof mapping
|
|
||||||
├── equation numbering
|
|
||||||
├── sparse matrix pattern ownership
|
|
||||||
└── full/reduced vector reconstruction
|
|
||||||
|
|
||||||
Analysis
|
Analysis
|
||||||
├── LinearStaticAnalysis
|
└── LinearStaticAnalysis
|
||||||
├── NonlinearStaticAnalysis
|
|
||||||
├── DynamicAnalysis
|
|
||||||
├── FrequencyAnalysis
|
|
||||||
└── HeatTransferAnalysis
|
|
||||||
|
|
||||||
Element
|
|
||||||
├── Element1D
|
|
||||||
│ ├── Truss
|
|
||||||
│ └── Beam
|
|
||||||
├── Element2D
|
|
||||||
│ ├── MITC3
|
|
||||||
│ └── MITC4
|
|
||||||
└── Element3D
|
|
||||||
├── Hexahedral
|
|
||||||
├── Tetrahedral
|
|
||||||
├── Wedge
|
|
||||||
└── Pyramid
|
|
||||||
|
|
||||||
BoundaryCondition
|
|
||||||
├── Fix
|
|
||||||
├── RBE2
|
|
||||||
└── RBE3
|
|
||||||
|
|
||||||
Load
|
|
||||||
├── NodalLoad
|
|
||||||
├── PressureLoad
|
|
||||||
└── BodyForce
|
|
||||||
|
|
||||||
Results
|
|
||||||
├── ResultStep
|
|
||||||
├── ResultFrame
|
|
||||||
├── FieldOutput
|
|
||||||
└── HistoryOutput
|
|
||||||
|
|
||||||
Vector
|
Vector
|
||||||
Matrix
|
Matrix
|
||||||
SparseMatrix
|
SparseMatrix
|
||||||
```
|
```
|
||||||
|
|
||||||
이 객체 모델 중 V0 `Analysis` 구현은 `LinearStaticAnalysis` 하나이며 `AnalysisState`는
|
Nonlinear/static, dynamic, frequency, heat-transfer procedure와 general element/material/load
|
||||||
full displacement, external/internal force, residual, constrained reaction, step/frame
|
base hierarchy는 이 구조 위의 가능한 확장 방향일 뿐 현재 public API가 아니다. 사용 사례가
|
||||||
identity와 element recovery rows만 할당한다. Velocity, acceleration, temperature,
|
승인되기 전에 V0 concrete record를 speculative hierarchy로 감싸지 않는다.
|
||||||
iteration history와 nonlinear element state는 V0에서 할당하지 않는다.
|
|
||||||
|
|
||||||
## 상태 관리
|
## 상태 관리
|
||||||
- `Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다.
|
- `Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다.
|
||||||
- `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않고 참조 또는 id 기반 view로 구성한다.
|
- `LinearStaticAnalysis`가 `Domain`을 소유하고, 그 뒤에 `AnalysisModel`, `DofManager`, `AnalysisState`, stiffness/RHS를 순서대로 만든다. 재사용 시에는 역순으로 해제하여 이전 Domain을 가리키는 view를 남기지 않는다.
|
||||||
|
- `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않으므로 Domain이 반드시 더 오래 살아야 한다.
|
||||||
- `DofManager`는 자유도와 방정식 번호를 전담한다. `Node` 또는 `Element` 내부에 equation id를 분산 저장하지 않는다.
|
- `DofManager`는 자유도와 방정식 번호를 전담한다. `Node` 또는 `Element` 내부에 equation id를 분산 저장하지 않는다.
|
||||||
- `AnalysisState`는 해석 중 변하는 물리량과 반복 상태를 소유한다. Phase 1에서는 displacement 중심으로 최소 구현하되, 기하비선형과 thermal-stress coupling을 위해 element/internal state 확장 지점을 유지한다.
|
- `AnalysisState`는 V0 frame에 필요한 다섯 full-DOF vector와 recovery rows만 소유한다. Velocity, acceleration, temperature, iteration history, nonlinear element state는 해당 procedure가 승인될 때 별도 계약으로 추가한다.
|
||||||
- 결과는 `ResultStep` -> `ResultFrame` -> `FieldOutput`/`HistoryOutput` 구조로 관리한다.
|
- Result recovery는 모든 candidate vector/row를 검증한 뒤 state에 반영한다. 실패한 recovery가 앞선 유효 state를 부분적으로 덮어쓰지 않아야 한다.
|
||||||
|
|
||||||
## 데이터 흐름
|
## 데이터 흐름
|
||||||
```text
|
```text
|
||||||
@@ -243,51 +226,47 @@ Abaqus input file
|
|||||||
-> effective RHS = Ff - Kfc * dc
|
-> effective RHS = Ff - Kfc * dc
|
||||||
-> LinearSolver::solve(rhs, df) substitution
|
-> LinearSolver::solve(rhs, df) substitution
|
||||||
-> full displacement 복구
|
-> full displacement 복구
|
||||||
-> reaction = K*d - F 및 element result 복구
|
-> full residual/reaction = K*d - F 및 element result 복구
|
||||||
-> ResultsWriter로 results.h5 atomic finalization
|
-> ResultsWriter로 results.h5 atomic finalization
|
||||||
```
|
```
|
||||||
|
|
||||||
강성행렬 factorization은 하중벡터 조립보다 먼저 수행한다. 반력은 element end action의
|
강성행렬 factorization은 하중벡터 조립보다 먼저 수행한다. 반력은 element end action의
|
||||||
별도 합이 아니라 조립된 전체 residual에서 구한다.
|
별도 합이 아니라 조립된 전체 residual에서 구한다. Constrained component는 physical
|
||||||
|
reaction이고 free component는 equilibrium residual evidence로 full-index vector에 남긴다.
|
||||||
|
|
||||||
## 해석 실행 흐름
|
## 해석 실행 흐름
|
||||||
`Analysis::run()`은 Template Method로 다음 V0 흐름을 고정한다. 해석 종류별 class는
|
`Analysis::run()`은 Template Method로 다음 여덟 hook의 순서와 fail-fast 경계를 고정한다.
|
||||||
승인된 procedure contract 안에서 필요한 단계만 재정의한다.
|
|
||||||
|
|
||||||
```text
|
| 순서 | Hook | 주요 작업과 생성되는 소유 객체 | 순서/실패 불변식 |
|
||||||
initialize
|
| --- | --- | --- | --- |
|
||||||
buildAnalysisModel
|
| 1 | `initialize(request)` | `.inp` syntax read, semantic map, owned immutable `Domain`, sorted warnings | 이전 run의 dependent object를 역순으로 제거하고 parse/map 실패를 input category로 반환한다. |
|
||||||
buildDofMap
|
| 2 | `buildAnalysisModel()` | non-owning `AnalysisModel` view | Domain을 복사하지 않으며 Domain lifetime 안에서만 사용한다. |
|
||||||
buildSparsePattern
|
| 3 | `buildDofMapAndSparsePattern()` | `DofManager`, zero-initialized `AnalysisState` | Stable full/free/constrained numbering과 structural pattern을 한 소유자에게 둔다. |
|
||||||
assembleStiffness
|
| 4 | `assembleAndPartitionStiffness()` | full CSR K와 `Kff/Kfc/Kcf/Kcc` | Element-local buffer를 deterministic하게 reduce하고 structural zero와 stable order를 보존한다. |
|
||||||
partitionConstraints
|
| 5 | `factorize()` | retained `Kff` factorization | 모든 load assembly보다 먼저 호출한다. Valid fully constrained model의 `0 x 0 Kff`는 trivial success다. |
|
||||||
factorize
|
| 6 | `assembleLoadsAndEffectiveRhs()` | full F와 `Ff-Kfc*dc` | Semantic load source order와 finite sum을 보존하며 solver를 호출하지 않는다. |
|
||||||
assembleLoads
|
| 7 | `substituteAndReconstruct()` | free solution과 full displacement | Factorization을 재수행하지 않고 substitution한 뒤 prescribed value를 stable order로 복구한다. |
|
||||||
formEffectiveRhs
|
| 8 | `recoverAndWriteResults()` | full residual/reaction, beam rows, final HDF5 | Recovery candidate를 원자적으로 commit하고 writer 성공 뒤에만 최종 output을 교체한다. |
|
||||||
substitute
|
|
||||||
reconstructDisplacement
|
|
||||||
recoverResults
|
|
||||||
writeResults
|
|
||||||
```
|
|
||||||
|
|
||||||
비선형 정적 및 동적 해석은 V0 범위가 아니며 별도 ADR과 formulation을 승인한 뒤 이
|
비선형 정적 및 동적 해석은 V0 범위가 아니며 별도 ADR과 formulation을 승인한 뒤 이
|
||||||
lifecycle의 확장 지점을 사용한다.
|
lifecycle과 state/equation 계약을 확장한다. 기존 hook 사이에 조용히 반복·증분·시간 적분
|
||||||
|
동작을 삽입하지 않는다.
|
||||||
|
|
||||||
## 설계 패턴
|
## 설계 패턴
|
||||||
- Strategy Pattern: `Analysis`, `LinearSolver`, `TimeIntegrator`, `ConvergenceCriteria`를 교체 가능한 전략으로 둔다.
|
- Strategy/Adapter Pattern: 현재 교체 가능한 public 경계는 `LinearSolver`, `ParallelFor`, `ResultsWriter`다. Vendor API는 concrete adapter implementation 안에만 둔다.
|
||||||
- Template Method Pattern: `Analysis::run()`은 공통 실행 흐름을 고정하고 세부 단계는 procedure별로 재정의한다.
|
- Template Method Pattern: `Analysis::run()`은 공통 실행 흐름을 고정하고 세부 단계는 procedure별로 재정의한다.
|
||||||
- Factory + Registry Pattern: Abaqus keyword와 내부 객체 생성을 분리한다. 예: `*Element, type=S4` -> `MITC4ElementFactory`.
|
- Syntax/Semantic separation: `AbaqusInputReader`는 syntax record를 만들고 `AbaqusDomainMapper`가 승인된 keyword 의미를 concrete Domain record로 변환한다.
|
||||||
- Adapter Pattern: MKL, TBB, HDF5 API는 solver core에 직접 노출하지 않는다.
|
- Runtime Polymorphism: V0에서는 backend 경계에만 사용한다. 요소/재료/하중 base hierarchy와 factory/registry는 두 번째 실제 구현이 필요해질 때 trade-off를 다시 결정한다.
|
||||||
- Runtime Polymorphism: 요소, 재료, 하중, 경계조건은 base interface를 통해 다룬다. 대규모 모델 성능 최적화가 필요하면 assembly 내부에서 타입별 batch 처리 또는 kernel 분리를 추가한다.
|
|
||||||
- RAII: MKL handle, HDF5 file/dataset, temporary solver workspace의 수명과 오류 처리를 wrapper에 묶는다.
|
- RAII: MKL handle, HDF5 file/dataset, temporary solver workspace의 수명과 오류 처리를 wrapper에 묶는다.
|
||||||
|
|
||||||
## Sparse Matrix Policy
|
## Sparse Matrix Policy
|
||||||
- assembly는 초기에는 COO triplet 수집 후 CSR finalize를 기준으로 한다.
|
- Assembly는 element마다 index-addressed contribution buffer를 만들고, join 뒤 COO tuple을 stable order로 정렬해 한 thread에서 순서대로 합산한 후 CSR로 finalize한다.
|
||||||
- `SparseMatrix`는 0-based CSR 데이터를 소유하는 별도 타입이며 dense `Matrix`를
|
- `SparseMatrix`는 0-based CSR 데이터를 소유하는 별도 타입이며 dense `Matrix`를
|
||||||
상속하지 않는다. MKL PARDISO backend는 adapter 경계에서 필요한 descriptor와 indexing을
|
상속하지 않는다. MKL PARDISO backend는 adapter 경계에서 필요한 descriptor와 indexing을
|
||||||
변환한다.
|
변환한다.
|
||||||
- matrix symmetry, definiteness, singularity diagnostic을 구조화된 diagnostic으로 남긴다.
|
- CSR row offset, sorted-unique column, dimensions, finite values를 construction boundary에서 검증하며 structural zero를 삭제하지 않는다.
|
||||||
- deterministic assembly를 위해 TBB element loop는 thread-local contribution buffer 또는 two-pass sparse assembly를 사용한다.
|
- Parallel worker는 global sparse matrix나 shared reduction accumulator를 직접 갱신하지 않는다. Worker별 failure slot과 contribution만 쓰고, deterministic reduction은 join 뒤에 수행한다.
|
||||||
|
- Matrix symmetry와 factorization/substitution failure는 solver adapter가 구조화된 solver diagnostic으로 번역한다. 승인되지 않은 regularization이나 fallback으로 singularity를 숨기지 않는다.
|
||||||
|
|
||||||
## Dense Math Policy
|
## Dense Math Policy
|
||||||
|
|
||||||
@@ -299,8 +278,9 @@ lifecycle의 확장 지점을 사용한다.
|
|||||||
- MKL header와 MKL-specific type은 adapter implementation 밖으로 노출하지 않는다.
|
- MKL header와 MKL-specific type은 adapter implementation 밖으로 노출하지 않는다.
|
||||||
|
|
||||||
## Parallel Policy
|
## Parallel Policy
|
||||||
- 첫 번째 oneTBB 적용 지점은 element-local matrix/residual 계산이다.
|
- `ParallelFor`는 `[0,count)` index-addressed 독립 작업만 노출하며 `SerialParallelFor`와 `TbbParallelFor`가 같은 observable contract를 가진다.
|
||||||
- 전역 sparse write는 thread-local buffer 또는 deterministic reduction으로 제한한다.
|
- 첫 oneTBB 적용 지점은 element-local stiffness 계산이다. 각 callback은 자기 index의 output slot만 쓴다.
|
||||||
|
- 전역 sparse write와 부동소수 reduction은 parallel callback 밖의 deterministic 단계로 제한한다.
|
||||||
- MKL 내부 thread와 TBB element loop가 oversubscription을 만들지 않도록 thread count와 task arena 정책을 명시한다.
|
- MKL 내부 thread와 TBB element loop가 oversubscription을 만들지 않도록 thread count와 task arena 정책을 명시한다.
|
||||||
|
|
||||||
## HDF5 Result Schema
|
## HDF5 Result Schema
|
||||||
@@ -325,8 +305,10 @@ Schema requirements:
|
|||||||
- Abaqus reference results는 `reference/<model-id>/` 아래 CSV 파일이다.
|
- Abaqus reference results는 `reference/<model-id>/` 아래 CSV 파일이다.
|
||||||
- Verification은 documented IDs, components, units, coordinate system, step/frame identity, tolerance 기준으로 FESA HDF5 rows와 Abaqus reference CSV rows를 비교한다.
|
- Verification은 documented IDs, components, units, coordinate system, step/frame identity, tolerance 기준으로 FESA HDF5 rows와 Abaqus reference CSV rows를 비교한다.
|
||||||
- FESA HDF5에서 추출한 deterministic CSV view는 optional debugging/review artifact이며 공식 solver output 또는 reference artifact가 아니다.
|
- FESA HDF5에서 추출한 deterministic CSV view는 optional debugging/review artifact이며 공식 solver output 또는 reference artifact가 아니다.
|
||||||
- Writer는 임시 HDF5 파일을 완성한 뒤 최종 경로로 교체하며 실패 시 불완전한
|
- Writer는 final과 같은 directory의 임시 HDF5에 전체 schema를 쓴 뒤 flush, checked close,
|
||||||
`results.h5`를 남기지 않는다.
|
read-only reopen/self-check를 수행한다. Existing final은 `ReplaceFileW`, 새 final은
|
||||||
|
`MoveFileExW(..., MOVEFILE_WRITE_THROUGH)`로 완료하며 실패 시 temporary artifact를
|
||||||
|
정리하고 불완전한 파일을 정상 `results.h5`로 노출하지 않는다.
|
||||||
|
|
||||||
## V0 결과 복구와 reference normalization
|
## V0 결과 복구와 reference normalization
|
||||||
|
|
||||||
@@ -357,3 +339,20 @@ fesa.exe <model.inp> --output <results.h5>
|
|||||||
`5=factorization/substitution`, `6=HDF5 output`으로 고정한다. Diagnostic은 `severity`,
|
`5=factorization/substitution`, `6=HDF5 output`으로 고정한다. Diagnostic은 `severity`,
|
||||||
`code`, `file`, `line`, `keyword`, `entity_identity`, `message`를 가지며 stderr에
|
`code`, `file`, `line`, `keyword`, `entity_identity`, `message`를 가지며 stderr에
|
||||||
deterministic한 순서로 출력한다.
|
deterministic한 순서로 출력한다.
|
||||||
|
|
||||||
|
## 기능 확장 플레이북
|
||||||
|
|
||||||
|
다음 표는 코드 위치만이 아니라 함께 바뀌어야 하는 계약 경계를 나타낸다. 한 열만
|
||||||
|
구현하고 다른 열을 생략하면 internal utility 또는 실험 kernel일 수는 있어도 제품 기능은
|
||||||
|
아니다.
|
||||||
|
|
||||||
|
| 기능 유형 | 시작 전에 고정할 것 | 주요 구현 경계 | 함께 검증할 것 | 피해야 할 shortcut |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| 새 element/material | DOF, interpolation, constitutive law, integration, local axes/sign, invalid geometry/property | Domain record와 mapper, element kernel, DofManager scatter/pattern, SparseAssembler, ResultRecovery | rigid modes/rank/energy, patch·analytical test, rotated coordinates, reference/physics | 기존 TYPE을 비슷한 kernel에 alias, source ID와 internal index 혼용, 검증 전 범용 hierarchy 추가 |
|
||||||
|
| 새 load/constraint | Abaqus target grammar, application order, units, follower 여부, prescribed-value 의미 | Syntax/mapper, Domain target, full-space LoadAssembler 또는 constraint partition, diagnostics | set/direct target ambiguity, multi-instance identity, nonfinite sum, `Ff-Kfc*dc`, reaction | Element load kernel 존재를 parser 지원으로 간주, penalty를 elimination에 몰래 혼합 |
|
||||||
|
| 새 analysis procedure | governing equation, state variables, increment/time lifecycle, tangent/residual, convergence와 output frame | 별도 Analysis implementation, procedure-specific state/equation owner, solver interface extension | orchestration order, failure atomicity, restart/frame identity, numerical benchmark | V0 hook 사이에 조건문으로 반복/시간 적분 삽입, 사용하지 않는 future state 선할당 |
|
||||||
|
| 새 numerical backend | matrix/index contract, lifecycle, reusable state, failure taxonomy, thread/runtime policy | 기존 `LinearSolver` 또는 `ParallelFor` interface의 concrete adapter, CMake normalized target | empty/dimension/extreme-scale input, repeated call, failed-output preservation, clean runtime discovery | Vendor type을 public header에 노출, silent fallback/regularization, absolute install path 고정 |
|
||||||
|
| 새 output/reference quantity | 물리 정의, location, sign, units, coordinates, stable row identity, mandatory 여부, tolerance | Result record/recovery, AnalysisState, ResultsWriter/HDF5 schema, comparator projection | schema dtype/shape, ordering, nonfinite rejection, identity inventory, reference N/A 대체 evidence | 서로 다른 result identity 혼합, station mismatch 평균, output request로 mandatory result 제거 |
|
||||||
|
|
||||||
|
모든 확장은 PRD의 제품 완료 정의와 요구조건→정식화→I/O→구현→reference→physics gate를
|
||||||
|
따른다. 기존 feature contract에 없는 범위를 편의상 “Abaqus compatible”이라고 넓히지 않는다.
|
||||||
|
|||||||
+27
-3
@@ -15,13 +15,26 @@ FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 유한요소법 기
|
|||||||
1. Abaqus `.inp` keyword subset parser와 내부 `Domain` semantic model 생성
|
1. Abaqus `.inp` keyword subset parser와 내부 `Domain` semantic model 생성
|
||||||
2. `AnalysisModel`, `DofManager`, `AnalysisState` 기반의 step별 equation system 구성
|
2. `AnalysisModel`, `DofManager`, `AnalysisState` 기반의 step별 equation system 구성
|
||||||
3. 선형 정적 해석을 시작점으로 하는 `Analysis` procedure 계층
|
3. 선형 정적 해석을 시작점으로 하는 `Analysis` procedure 계층
|
||||||
4. 요소, 재료, 경계조건, 하중의 runtime-polymorphic base interface
|
4. Stable source identity를 보존하는 concrete V0 node, B33 element, material, section, boundary, load record
|
||||||
5. sparse matrix pattern 생성, 전역 행렬/벡터 조립, 제약조건 적용
|
5. sparse matrix pattern 생성, 전역 행렬/벡터 조립, 제약조건 적용
|
||||||
6. `LinearSolver` adapter를 통한 MKL PARDISO backend와 향후 iterative solver 확장
|
6. `LinearSolver`, `ParallelFor`, `ResultsWriter` interface를 통한 MKL PARDISO, oneTBB, HDF5 backend 격리
|
||||||
7. HDF5 기반 versioned step/frame field-result 저장과 향후 history-output 확장 경계
|
7. HDF5 기반 versioned step/frame field-result 저장과 향후 history-output 확장 경계
|
||||||
8. FESA HDF5 rows와 `reference/<model-id>/` 아래 Abaqus reference CSV rows의 직접 비교
|
8. FESA HDF5 rows와 `reference/<model-id>/` 아래 Abaqus reference CSV rows의 직접 비교
|
||||||
9. CMake/MSVC/x64/Debug, CTest 기반 개발 검증
|
9. CMake/MSVC/x64/Debug, CTest 기반 개발 검증
|
||||||
|
|
||||||
|
Element/material 계층의 일반적인 runtime polymorphism, iterative solver, history output은 장기 확장 방향이다. 현재 제품 계약으로 간주하지 않으며, 실제 사용 사례와 성능·수명 요구가 승인되기 전에 추상 base class를 미리 추가하지 않는다.
|
||||||
|
|
||||||
|
## 사용자 관점 제품 흐름
|
||||||
|
|
||||||
|
1. 사용자는 승인된 Abaqus `.inp` subset으로 모델과 단일 analysis step을 기술한다.
|
||||||
|
2. FESA는 syntax를 읽은 뒤 semantic mapping과 model validation을 수행한다. 지원하지 않는 모델 의미는 구조화된 diagnostic과 안정된 exit code로 거부한다.
|
||||||
|
3. 해석 procedure는 active model view, DOF/equation map과 sparse system을 만들고, essential constraint elimination을 적용해 선형계를 factorize하고 substitution한다.
|
||||||
|
4. FESA는 full displacement를 복구하고 equilibrium residual/reaction과 element 결과를 계산한다.
|
||||||
|
5. 성공 시 output request와 무관한 mandatory 결과, metadata와 diagnostic을 versioned `results.h5`에 기록한다. 실패 시 불완전한 최종 결과 파일을 정상 결과처럼 남기지 않는다.
|
||||||
|
6. 검증 workflow는 HDF5 row를 승인된 Abaqus reference CSV identity에 투영해 tolerance를 판정하고, 별도로 equilibrium과 물리적 타당성을 검토한다.
|
||||||
|
|
||||||
|
Parser keyword, element kernel, solver backend 또는 output dataset 중 하나만 추가된 상태는 end-to-end 제품 기능이 아니다. 같은 기능의 입력 의미부터 외부 결과와 검증까지 연결되어야 한다.
|
||||||
|
|
||||||
## V0 범위
|
## V0 범위
|
||||||
- 선형 정적 해석 파이프라인 구현
|
- 선형 정적 해석 파이프라인 구현
|
||||||
- 승인된 첫 end-to-end 기능: 2절점 3D Euler–Bernoulli beam, Abaqus `TYPE=B33`
|
- 승인된 첫 end-to-end 기능: 2절점 3D Euler–Bernoulli beam, Abaqus `TYPE=B33`
|
||||||
@@ -59,6 +72,17 @@ FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 유한요소법 기
|
|||||||
- 승인된 `reference/cantilever beam/` B33 결과와 displacement, reaction, section resultant
|
- 승인된 `reference/cantilever beam/` B33 결과와 displacement, reaction, section resultant
|
||||||
comparison; beam stress reference comparison은 N/A
|
comparison; beam stress reference comparison은 N/A
|
||||||
|
|
||||||
|
## 신규 기능의 제품 완료 정의
|
||||||
|
|
||||||
|
새로운 element, load, constraint, material, analysis procedure 또는 output quantity는 다음 조건을 모두 만족할 때 FESA 제품 기능으로 취급한다.
|
||||||
|
|
||||||
|
1. 지원 범위와 제외 범위, 실패 category, units/coordinates/identity, tolerance가 요구조건과 I/O 계약에 명시되어 있다.
|
||||||
|
2. 필요한 FEM 정식화와 recovery/sign convention이 검토되었고, 수치 위험과 검증 문제를 numerical review가 다룬다.
|
||||||
|
3. Syntax와 semantic mapping이 내부 모델에 안정된 source identity로 연결되며 잘못된 입력을 fail-closed로 거부한다. Kernel만 제공하는 기능은 parser/CLI 지원 여부를 별도로 표시한다.
|
||||||
|
4. DOF, sparse pattern, assembly, constraint, solver lifecycle과 mutable state ownership이 기존 아키텍처에 연결되거나 승인된 새 procedure 경계를 가진다.
|
||||||
|
5. Mandatory HDF5 schema와 diagnostic, CLI 실패 의미가 정의되고 failure path가 기존 state 또는 최종 output을 오염시키지 않는다.
|
||||||
|
6. Unit test가 local 수식과 validation을, integration test가 orchestration과 외부 계약을, reference comparison과 physics sanity가 수치·물리 타당성을 각각 증명한다. Reference가 N/A이면 그 이유와 대체 evidence를 명시한다.
|
||||||
|
|
||||||
## 기능 요구조건
|
## 기능 요구조건
|
||||||
| ID | 요구조건 | Acceptance Criteria | Verification Method |
|
| ID | 요구조건 | Acceptance Criteria | Verification Method |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
@@ -91,7 +115,7 @@ FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 유한요소법 기
|
|||||||
`1e-3`이며 relative coefficient는 `1e-6`이다.
|
`1e-3`이며 relative coefficient는 `1e-6`이다.
|
||||||
- parser, solver, HDF5 writer는 실패 원인을 구조화된 diagnostic으로 보고한다.
|
- parser, solver, HDF5 writer는 실패 원인을 구조화된 diagnostic으로 보고한다.
|
||||||
- oneMKL, oneTBB, HDF5는 CMake에서 명시 탐지하고 실패 원인을 분류한다.
|
- oneMKL, oneTBB, HDF5는 CMake에서 명시 탐지하고 실패 원인을 분류한다.
|
||||||
- 대규모 모델 성능 최적화보다 Phase 1 명확성, 테스트 가능성, 검증 traceability를 우선한다.
|
- 대규모 모델 성능 최적화보다 V0의 명확성, 테스트 가능성, 검증 traceability를 우선한다.
|
||||||
|
|
||||||
## Acceptance Gates
|
## Acceptance Gates
|
||||||
1. Requirements approved: 기능 범위, 제외 범위, 입력, 출력, tolerance, 검증 물리량이 정의되어 있다.
|
1. Requirements approved: 기능 범위, 제외 범위, 입력, 출력, tolerance, 검증 물리량이 정의되어 있다.
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
# FESA Core Documentation Extension Playbook Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** 미래 AI Agent가 FESA에 기능을 추가할 때 실제 해석 흐름, 소유권, CMake 설정, 수치 불변식과 검증 경계를 바로 찾을 수 있도록 핵심 문서를 보강한다.
|
||||||
|
|
||||||
|
**Architecture:** 같은 사실을 네 문서에 반복하지 않고 문서별 책임을 분리한다. AGENTS는 프로젝트 배경·목적·핵심 개발 원칙, PRD는 사용자 관점의 제품 계약, ARCHITECTURE는 구현 구조·빌드 흐름·확장 지점, ADR은 장기 의사결정을 담당한다.
|
||||||
|
|
||||||
|
**Tech Stack:** Markdown, C++17/MSVC, CMake/CTest, Intel oneAPI MKL/TBB, HDF5, Abaqus `.inp` subset
|
||||||
|
|
||||||
|
## Global Constraints
|
||||||
|
|
||||||
|
- 수정 범위는 `AGENTS.md`, `docs/PRD.md`, `docs/ARCHITECTURE.md`, `docs/ADR.md`와 이 작업의 spec/plan 문서뿐이다.
|
||||||
|
- phase 완료 이력, commit hash, 현재 테스트 총개수는 핵심 문서에 기록하지 않는다.
|
||||||
|
- 승인되지 않은 Abaqus keyword와 해석 기능을 지원하는 것처럼 서술하지 않는다.
|
||||||
|
- project hook과 Harness는 실행하지 않는다.
|
||||||
|
- production, test, CMake, reference artifact는 수정하지 않는다.
|
||||||
|
- direct 검증은 `git diff --check`와 문서·코드·CMake 사이의 정적 대조만 사용한다.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: 프로젝트 배경과 핵심 개발 지침 보강
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `AGENTS.md`
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Consumes: root CMake options, normalized dependency targets, `Analysis::run()` lifecycle, public dependency boundaries
|
||||||
|
- Produces: FESA의 목적과 개발 판단 기준, 문서 탐색 순서, 최소 검증 진입점
|
||||||
|
|
||||||
|
- [x] **Step 1: 프로젝트 목적과 문서 역할을 선명하게 한다**
|
||||||
|
|
||||||
|
FESA가 검증 가능한 구조해석 솔버라는 점, full Abaqus clone이 아니라 승인된 feature contract를 누적하는 프로젝트라는 점, PRD/ARCHITECTURE/ADR와 기능별 계약의 역할을 기록한다.
|
||||||
|
|
||||||
|
- [x] **Step 2: 개발 시 훼손하면 안 되는 핵심 원칙을 추가한다**
|
||||||
|
|
||||||
|
물리·수치 계약 우선, stable identity, 명시적 소유권, 결정론성, backend isolation, failure atomicity, 공식 HDF5와 read-only reference 원칙을 상위 수준 지침으로 추가한다. 상세 lifecycle은 ARCHITECTURE로 연결한다.
|
||||||
|
|
||||||
|
- [x] **Step 3: 기능 확장 판단 기준을 추가한다**
|
||||||
|
|
||||||
|
입력 계약, semantic model, kernel/assembly, solve/recovery, HDF5/reference/physics evidence가 함께 변경되어야 함을 명시한다.
|
||||||
|
|
||||||
|
- [x] **Step 4: 최소 검증 진입점의 부정확한 예제를 정리한다**
|
||||||
|
|
||||||
|
`FESA_GTEST_SOURCE_DIR`가 빠진 configure와 실제 target이 아닌 `MyProject.sln` 예제를 제거한다. 상세 package/runtime 설명은 ARCHITECTURE로 연결한다.
|
||||||
|
|
||||||
|
- [x] **Step 5: 최소 build 명칭을 실제 CMake 옵션과 대조한다**
|
||||||
|
|
||||||
|
Run: `rg -n "FESA_GTEST_SOURCE_DIR|MKL_DIR|TBB_DIR|HDF5_DIR|Fesa::MKL|Fesa::TBB|Fesa::HDF5" CMakeLists.txt cmake/FesaDependencies.cmake src/fesa/CMakeLists.txt tests/CMakeLists.txt AGENTS.md`
|
||||||
|
|
||||||
|
Expected: AGENTS의 변수와 target 이름이 실제 CMake 정의와 일치한다.
|
||||||
|
|
||||||
|
### Task 2: 제품 계약과 기능 정의 보강
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `docs/PRD.md`
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Consumes: 승인된 V0 input/output/diagnostic 범위
|
||||||
|
- Produces: 사용자 관점 end-to-end 흐름과 신규 기능의 완료 정의
|
||||||
|
|
||||||
|
- [x] **Step 1: 제품 흐름을 입력→해석→HDF5→검증으로 명확히 한다**
|
||||||
|
|
||||||
|
Syntax parse, semantic validation, linear solve, recovery, mandatory HDF5, optional reference comparison의 사용자 관찰 가능 결과를 기록한다.
|
||||||
|
|
||||||
|
- [x] **Step 2: 현재 구현과 장기 방향을 구분한다**
|
||||||
|
|
||||||
|
현재 concrete V0 model과 backend polymorphism을 정확히 기술하고, runtime-polymorphic element/material 확장은 미래 방향으로 표시한다.
|
||||||
|
|
||||||
|
- [x] **Step 3: 신규 제품 기능의 Definition of Done을 추가한다**
|
||||||
|
|
||||||
|
입력 노출, semantic mapping, solver lifecycle, result schema, diagnostics, unit/integration/reference/physics evidence가 모두 있어야 제품 기능으로 간주한다고 명시한다.
|
||||||
|
|
||||||
|
### Task 3: 실제 아키텍처와 확장 지점 보강
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `docs/ARCHITECTURE.md`
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Consumes: `src/fesa`와 `tests`의 실제 target/module graph
|
||||||
|
- Produces: ownership/lifetime, 8-stage lifecycle, CMake/runtime graph, extension playbook
|
||||||
|
|
||||||
|
- [x] **Step 1: directory/target 설명에서 구현과 계획을 구분한다**
|
||||||
|
|
||||||
|
현재 존재하는 static solver library, CLI, unit/integration/reference test target을 명시하고 계획된 디렉터리는 계획이라고 표시한다.
|
||||||
|
|
||||||
|
- [x] **Step 2: 소유권과 8단계 실행 흐름을 표로 추가한다**
|
||||||
|
|
||||||
|
각 단계의 입력, 출력, 소유 객체, 실패 범주와 순서 불변식을 기록한다.
|
||||||
|
|
||||||
|
- [x] **Step 3: CMake dependency와 Windows runtime staging을 설명한다**
|
||||||
|
|
||||||
|
normalized `Fesa::*` targets, shared HDF5 preference, private product linkage, CLI/test executable 옆 runtime DLL staging을 기록한다.
|
||||||
|
|
||||||
|
- [x] **Step 4: 기능 유형별 확장 플레이북을 추가한다**
|
||||||
|
|
||||||
|
element, load/constraint, analysis procedure, backend, output/reference quantity별 변경 지점과 금지되는 shortcut을 기록한다.
|
||||||
|
|
||||||
|
### Task 4: 장기 아키텍처 결정을 추가한다
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `docs/ADR.md`
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Consumes: 실제 CMake/runtime, deterministic assembly, essential constraints, layered verification behavior
|
||||||
|
- Produces: 향후 구현이 지켜야 할 결정과 trade-off
|
||||||
|
|
||||||
|
- [x] **Step 1: 외부 의존성 정규화와 runtime closure ADR을 추가한다**
|
||||||
|
|
||||||
|
Vendor target 이름을 `Fesa::*`로 정규화하고 public header에는 노출하지 않으며 Windows executable runtime closure를 staging하는 결정을 기록한다.
|
||||||
|
|
||||||
|
- [x] **Step 2: 결정론성과 failure atomicity ADR을 추가한다**
|
||||||
|
|
||||||
|
Stable COO/reduction, state/output candidate-commit, atomic HDF5 finalization이 성능 옵션이 아니라 correctness contract임을 기록한다.
|
||||||
|
|
||||||
|
- [x] **Step 3: 구속 제거와 full residual ADR을 추가한다**
|
||||||
|
|
||||||
|
`Kff`, `Ff-Kfc*dc`, valid 0x0 system, reaction=`Kd-F`의 결정과 penalty/MPC 비범위를 기록한다.
|
||||||
|
|
||||||
|
- [x] **Step 4: 계층형 검증 ADR을 추가한다**
|
||||||
|
|
||||||
|
Kernel 존재와 parser/CLI 노출을 구분하고 unit→integration→reference→physics gate가 각기 다른 오류를 검출한다는 결정을 기록한다.
|
||||||
|
|
||||||
|
### Task 5: 문서 전용 정적 검증
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Verify: `AGENTS.md`
|
||||||
|
- Verify: `docs/PRD.md`
|
||||||
|
- Verify: `docs/ARCHITECTURE.md`
|
||||||
|
- Verify: `docs/ADR.md`
|
||||||
|
|
||||||
|
**Interfaces:**
|
||||||
|
- Consumes: Tasks 1–4의 문서 변경
|
||||||
|
- Produces: 문서 범위·형식·사실 일치 evidence
|
||||||
|
|
||||||
|
- [x] **Step 1: 변경 범위를 확인한다**
|
||||||
|
|
||||||
|
Run: `git status --short`
|
||||||
|
|
||||||
|
Expected: production, test, CMake, reference 경로 변경이 없다.
|
||||||
|
|
||||||
|
- [x] **Step 2: whitespace 오류를 확인한다**
|
||||||
|
|
||||||
|
Run: `git diff --check`
|
||||||
|
|
||||||
|
Expected: exit 0.
|
||||||
|
|
||||||
|
- [x] **Step 3: stale 예제와 승인되지 않은 범위 암시를 검사한다**
|
||||||
|
|
||||||
|
Run: `rg -n "MyProject|full Abaqus compatibility|B31.*지원|현재 테스트.*[0-9]+" AGENTS.md docs/PRD.md docs/ARCHITECTURE.md docs/ADR.md`
|
||||||
|
|
||||||
|
Expected: stale solution 예제와 지원 범위 확대 문구가 없다. Full compatibility/B31은 거부 또는 비범위 문맥에서만 나타난다.
|
||||||
|
|
||||||
|
- [x] **Step 4: 명령·target·lifecycle 이름을 원본과 대조한다**
|
||||||
|
|
||||||
|
Run: `rg -n "FESA_GTEST_SOURCE_DIR|Fesa::MKL|Fesa::TBB|Fesa::HDF5|assembleAndPartitionStiffness|assembleLoadsAndEffectiveRhs|recoverAndWriteResults" AGENTS.md docs/ARCHITECTURE.md cmake/FesaDependencies.cmake src/fesa/analysis/linear_static_analysis.cpp`
|
||||||
|
|
||||||
|
Expected: 문서의 명칭과 구현/CMake 명칭이 일치한다.
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# FESA Core Documentation Extension Playbook Design
|
||||||
|
|
||||||
|
## 목적
|
||||||
|
|
||||||
|
`AGENTS.md`, `docs/PRD.md`, `docs/ARCHITECTURE.md`, `docs/ADR.md`를 현재 구현에 맞게 보강한다. 작업 완료 이력이나 일시적인 테스트 개수 대신, 다음 기능을 추가할 AI Agent가 바로 사용할 수 있는 해석 흐름, 소유권, 빌드 설정, 수치 불변식, 확장 경계를 기록한다.
|
||||||
|
|
||||||
|
## 문서별 책임
|
||||||
|
|
||||||
|
- `AGENTS.md`: FESA의 배경과 목적, 전체 프로젝트에서 훼손하면 안 되는 개발 원칙, 문서 탐색 순서와 기능 확장 시의 판단 기준을 제공한다. 상세 구현·빌드 매뉴얼의 대체물이 아니다.
|
||||||
|
- `docs/PRD.md`: 사용자가 관찰하는 제품 흐름, 구현된 V0 지원 경계, 신규 기능이 제품 기능으로 인정되기 위한 조건을 정의한다.
|
||||||
|
- `docs/ARCHITECTURE.md`: 실제 모듈과 target, 객체 소유권, 8단계 해석 수명주기, CMake dependency/runtime graph, 기능 유형별 확장 지점을 설명한다.
|
||||||
|
- `docs/ADR.md`: 정규화된 외부 의존성, 결정론적·failure-atomic 경계, 구속 제거와 full residual, 계층형 검증을 장기 결정으로 남긴다.
|
||||||
|
|
||||||
|
## 기록할 구현 사실
|
||||||
|
|
||||||
|
1. 입력은 syntax parse와 semantic mapping을 거쳐 불변 `Domain`이 되고, `AnalysisModel`은 이를 복사하지 않는 view이다.
|
||||||
|
2. `Analysis::run()`은 initialize, model view, DOF/pattern, stiffness/partition, factorization, load/effective RHS, solve/reconstruct, recovery/write 순서를 고정한다.
|
||||||
|
3. `DofManager`가 full/free/constrained numbering과 0-based CSR pattern을 단독 소유하며, Node/Element에는 equation ID를 저장하지 않는다.
|
||||||
|
4. assembly는 element-local buffer, stable COO order, serial ordered reduction으로 결정론적 CSR을 만든다. global sparse storage를 병렬로 직접 갱신하지 않는다.
|
||||||
|
5. essential constraints는 full K를 `Kff/Kfc/Kcf/Kcc`로 분할하고 `Ff - Kfc*dc`를 푼다. fully constrained 0x0 `Kff`도 유효하다.
|
||||||
|
6. reaction/equilibrium evidence는 full residual `K*d - F`를 사용한다. constrained 성분은 physical reaction이고 free 성분은 equilibrium residual이다.
|
||||||
|
7. 외부 API는 `LinearSolver`, `ParallelFor`, `ResultsWriter`와 math adapter 뒤에 둔다. public header에 MKL/TBB/HDF5/Win32 type을 노출하지 않는다.
|
||||||
|
8. HDF5 writer는 같은 directory의 temporary file, checked close/reopen self-check, atomic finalization을 사용한다.
|
||||||
|
9. element end action, section resultant, generalized result, stress identity와 sign convention을 섞지 않으며 station mismatch를 평균내지 않는다.
|
||||||
|
|
||||||
|
## 빌드 및 검증 설계
|
||||||
|
|
||||||
|
- direct build는 Visual Studio generator, x64, Debug를 명시한다. 상세 target graph와 runtime 설명은 `docs/ARCHITECTURE.md`에 두고, `AGENTS.md`에는 최소 검증 진입점만 둔다.
|
||||||
|
- `FESA_GTEST_SOURCE_DIR`는 필수 local source path이다. `MKL_DIR`, `TBB_DIR`, `HDF5_DIR`는 설치 환경에서 package discovery가 되지 않으면 명시한다.
|
||||||
|
- production은 `Fesa::MKL`, `Fesa::TBB`, `Fesa::HDF5` normalized target만 사용한다.
|
||||||
|
- Windows에서는 CLI와 GoogleTest discovery 전에 MKL/TBB/HDF5 및 transitive oneAPI runtime DLL이 executable 옆에 staging되어야 한다.
|
||||||
|
- 문서 작업 검증은 project hook/Harness를 실행하지 않고 `git diff --check`, 링크·경로·명령·target 이름의 정적 대조로 제한한다.
|
||||||
|
|
||||||
|
## 기능 확장 플레이북
|
||||||
|
|
||||||
|
- 새 element: 요구조건/정식화/I/O mapping을 먼저 고정하고 kernel, model mapping, DOF pattern, assembly, recovery, output, reference/physics evidence를 함께 확장한다.
|
||||||
|
- 새 load/constraint: semantic target identity, stable source order, full-space vector/matrix, partition/effective RHS, diagnostics와 output을 함께 검토한다.
|
||||||
|
- 새 analysis procedure: 기존 V0 lifecycle을 조용히 변경하지 않고 별도 orchestration/state/equation 계약과 gate를 정의한다.
|
||||||
|
- 새 numerical backend: public interface를 유지하고 adapter 내부에만 vendor API, lifecycle, runtime dependency를 격리한다.
|
||||||
|
- 새 output/reference quantity: mandatory HDF5 schema, units/coordinates/identity, recovery sign, comparison projection과 tolerance를 동시에 정의한다.
|
||||||
|
|
||||||
|
## 범위 제한
|
||||||
|
|
||||||
|
- phase 완료 이력, commit hash, 현재 테스트 총개수 같은 일시적 사실을 핵심 문서에 넣지 않는다.
|
||||||
|
- full Abaqus compatibility, B31 지원, transform/nested assembly, distributed-load parser exposure 등 승인되지 않은 범위를 암시하지 않는다.
|
||||||
|
- 문서 보강 외 production, test, CMake, reference artifact를 수정하지 않는다.
|
||||||
Reference in New Issue
Block a user