docs: add linear static beam harness phase

This commit is contained in:
KOKO\Mimi
2026-08-09 01:35:44 +09:00
parent 3410828736
commit 6d6da7545c
36 changed files with 3524 additions and 54 deletions
+11 -1
View File
@@ -19,7 +19,8 @@
- 문서와 구현은 full Abaqus compatibility를 주장하지 않는다. 기능별로 승인된 Abaqus keyword subset만 지원한다. - 문서와 구현은 full Abaqus compatibility를 주장하지 않는다. 기능별로 승인된 Abaqus keyword subset만 지원한다.
- 공식 solver output은 HDF5 `results.h5`이다. - 공식 solver output은 HDF5 `results.h5`이다.
- reference 결과는 FESA와 같은 Abaqus `.inp` 모델을 Abaqus로 해석해 생성한 CSV 파일이다. - reference 결과는 FESA와 같은 Abaqus `.inp` 모델을 Abaqus로 해석해 생성한 CSV 파일이다.
- reference comparison은 FESA `results.h5`의 변위, 반력, 내력, 응력 dataset을 `reference/<model-id>/<model-id>_*.csv` 파일과 비교한다. - reference artifact의 정확한 경로와 파일명은 기능별 reference model contract를 따른다. 신규 모델은 `reference/<model-id>/<model-id>_*.csv` canonical 이름을 사용한다.
- 승인된 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로만 둔다.
## 아키텍처 규칙 ## 아키텍처 규칙
@@ -43,6 +44,15 @@
- Stop은 `.harness/config.json` 또는 자동 감지 결과에 따라 MSVC build와 test를 모두 검증한다. - Stop은 `.harness/config.json` 또는 자동 감지 결과에 따라 MSVC build와 test를 모두 검증한다.
- Generated phase execution outputs remain ignored under `phases/**/step*-output.json`. - Generated phase execution outputs remain ignored under `phases/**/step*-output.json`.
## 현재 승인된 V0 기능 계약
- `linear-static-3d-euler-beam`의 source of truth는 `docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`이다. 관련 문서를 변경하거나 구현할 때 이 계약의 의미를 임의로 넓히지 않는다.
- 입력 파일당 하나의 `*STEP, *STATIC``TYPE=B33`만 지원한다. B31을 Euler 요소로 매핑하지 않고 `unsupported-element-formulation`으로 거부한다.
- `*PART/*ASSEMBLY/*INSTANCE`는 identity instance와 stable source identity만 지원한다. instance transform과 nested assembly는 거부한다.
- 선형 정적 실행 순서는 stiffness assembly와 constrained partition 뒤 `Kff`를 factorize하고, 그 다음 load vector와 effective RHS를 조립해 substitution하는 순서를 유지한다.
- FESA는 output request와 무관하게 displacement, reaction, equilibrium end action, section resultant, generalized strain/resultant, axial `S11`을 HDF5에 기록한다. Beam stress의 Abaqus reference comparison은 N/A다.
- B33 reference row는 component별 Abaqus scale로 `absolute_floor + 1e-6 * reference_scale`을 적용한다. Reference 값을 zero-clamp하거나 누락 row를 무시하지 않는다.
- `reference/cantilever beam/` artifact는 rename, rewrite 또는 보정하지 않는다.
## 개발 프로세스 ## 개발 프로세스
- TDD를 기본으로 한다. 구현은 `RED -> GREEN -> VERIFY` 순서를 따른다. - TDD를 기본으로 한다. 구현은 `RED -> GREEN -> VERIFY` 순서를 따른다.
- CRITICAL: 빌드 경고를 새로 추가하지 말 것. - CRITICAL: 빌드 경고를 새로 추가하지 말 것.
+23 -7
View File
@@ -34,23 +34,23 @@ FESA의 architecture decision은 solver correctness, verification traceability,
**트레이드오프**: 초기 class 수가 늘어난다. Phase 1에서는 interface를 얇게 유지하고 displacement 중심 state부터 구현한다. **트레이드오프**: 초기 class 수가 늘어난다. Phase 1에서는 interface를 얇게 유지하고 displacement 중심 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-id>/` 아래 CSV 파일로 저장하며, verification은 FESA HDF5 rows와 Abaqus reference CSV rows를 documented IDs, components, units, coordinate system, step/frame identity, tolerance 기준으로 비교한다. **결정**: 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는 해당 기능 계약에 정확한 경로를 기록한 경우에만 허용한다.
**이유**: 구조해석 결과는 step/frame, field/history, node/element/integration point location, units, coordinate system, schema version을 함께 가져야 한다. HDF5는 이 계층 구조와 metadata를 안정적으로 표현한다. **이유**: 구조해석 결과는 step/frame, field/history, node/element/integration point location, units, coordinate system, schema version을 함께 가져야 한다. HDF5는 이 계층 구조와 metadata를 안정적으로 표현한다.
**트레이드오프**: reference comparison은 FESA HDF5 dataset identity와 Abaqus CSV row identity를 모두 관리해야 한다. FESA HDF5에서 추출한 deterministic CSV view는 디버깅/검토용 보조 artifact로 허용하지만, 공식 solver output이나 reference artifact로 취급하지 않는다. **트레이드오프**: reference comparison은 FESA HDF5 dataset identity와 Abaqus CSV row identity를 모두 관리해야 한다. FESA HDF5에서 추출한 deterministic CSV view는 디버깅/검토용 보조 artifact로 허용하지만, 공식 solver output이나 reference artifact로 취급하지 않는다.
### ADR-006: 해석 알고리즘과 수치 backend는 Strategy와 Adapter 경계 뒤에 둔다 ### ADR-006: 해석 알고리즘과 수치 backend는 Strategy와 Adapter 경계 뒤에 둔다
**결정**: `Analysis`, `LinearSolver`, `TimeIntegrator`, `ConvergenceCriteria`는 Strategy로 구성하고, MKL, TBB, HDF5 API는 adapter 계층 뒤에 둔다. **결정**: `Analysis`, `LinearSolver`, `TimeIntegrator`, `ConvergenceCriteria`는 Strategy로 구성하고, MKL, TBB, HDF5 API는 adapter 계층 뒤에 둔다. `Vector`는 contiguous `double`, `Matrix`는 row-major contiguous `double`을 소유하고 dense 연산은 MKL CBLAS를 사용한다. `SparseMatrix`는 이들과 상속 관계가 없는 0-based CSR 전용 타입이며, PARDISO factorization과 substitution은 `LinearSolver` 경계 뒤에서 분리한다.
**이유**: 선형 정적, 비선형 정적, 동적, frequency, heat transfer 해석은 공통 흐름을 공유하지만 알고리즘과 backend가 다르다. 외부 API를 core에 노출하면 테스트 double, backend 교체, dependency review가 어려워진다. **이유**: 선형 정적, 비선형 정적, 동적, frequency, heat transfer 해석은 공통 흐름을 공유하지만 알고리즘과 backend가 다르다. 외부 API를 core에 노출하면 테스트 double, backend 교체, dependency review가 어려워진다.
**트레이드오프**: 단일 기능만 구현할 때는 adapter가 다소 장황해 보일 수 있다. 하지만 solver backend와 result writer는 장기적으로 교체 가능해야 한다. **트레이드오프**: 단일 기능만 구현할 때는 adapter가 다소 장황해 보일 수 있다. Row-major dense storage와 CSR sparse storage를 따로 유지해야 하지만 backend 의존성과 dense/sparse 의미가 core 모델에 섞이지 않는다.
### ADR-007: Analysis 실행 흐름은 Template Method로 고정한다 ### ADR-007: Analysis 실행 흐름은 Template Method로 고정한다
**결정**: `Analysis::run()``initialize -> buildAnalysisModel -> buildDofMap -> buildSparsePattern -> assemble -> applyBoundaryConditions -> solve -> updateState -> writeResults` 흐름을 고정한다. **결정**: `Analysis::run()`공통 lifecycle을 고정한다. 선형 정적 V0의 순서는 `parse input -> initialize Domain -> build AnalysisModel -> build DOF map/sparse pattern -> assemble stiffness -> partition constraints -> factorize Kff -> assemble load -> form effective RHS -> substitute -> reconstruct displacement -> recover results -> write HDF5`다. 강성행렬 factorization은 하중벡터 조립보다 먼저 수행하고, factorization과 substitution을 하나의 불투명한 solve 호출로 합치지 않는다.
**이유**: 해석 procedure가 늘어나도 공통 실행 순서가 유지되어야 검증, logging, result writing, failure classification이 일관된다. **이유**: 해석 procedure가 늘어나도 공통 실행 순서가 유지되어야 검증, logging, result writing, failure classification이 일관된다. Factorization과 substitution을 분리하면 동일 강성행렬에 여러 RHS를 적용할 수 있고 각 실패 단계를 구조화된 diagnostic으로 분류할 수 있다.
**트레이드오프**: 특수 해석 절차가 공통 흐름에 맞지 않는 경우 hook point가 필요하다. 초기에는 선형 정적 해석을 기준으로 최소 hook만 둔다. **트레이드오프**: 특수 해석 절차가 공통 흐름에 맞지 않는 경우 hook point가 필요하다. 초기에는 선형 정적 해석을 기준으로 최소 hook만 둔다.
@@ -69,11 +69,11 @@ FESA의 architecture decision은 solver correctness, verification traceability,
**트레이드오프**: 초기 병렬화 범위가 제한된다. MKL 내부 thread와 TBB task arena의 oversubscription 정책을 별도로 문서화해야 한다. **트레이드오프**: 초기 병렬화 범위가 제한된다. MKL 내부 thread와 TBB task arena의 oversubscription 정책을 별도로 문서화해야 한다.
### ADR-010: Abaqus reference artifact는 사람이 생성하거나 명시 승인된 절차로만 갱신한다 ### ADR-010: Abaqus reference artifact는 사람이 생성하거나 명시 승인된 절차로만 갱신한다
**결정**: Agent는 Abaqus, Nastran 또는 reference solver를 직접 실행하지 않는다. reference artifact 생성, 수정, 복원은 명시 승인된 phase에서만 수행하고 provenance `metadata.json`에 기록한다. **결정**: Agent는 Abaqus, Nastran 또는 reference solver를 직접 실행하지 않는다. reference artifact 생성, 수정, 복원은 명시 승인된 phase에서만 수행한다. 신규 bundle의 provenance `metadata.json`에 기록한다. 승인된 `cantilever-beam-b33` legacy baseline은 source commit과 generator, units, coordinate system, schema, tolerance를 설계 및 Reference Model Contract가 대신 기록하므로 이 baseline에 한해서 `metadata.json``README.md`가 N/A다.
**이유**: reference 결과는 solver correctness의 기준이다. 생성 절차가 불명확하면 구현 결함과 reference artifact 오류를 구분할 수 없다. **이유**: reference 결과는 solver correctness의 기준이다. 생성 절차가 불명확하면 구현 결함과 reference artifact 오류를 구분할 수 없다.
**트레이드오프**: reference 준비가 느려질 수 있다. 대신 검증 기준의 신뢰도와 감사 가능성이 높아진다. **트레이드오프**: reference 준비가 느려질 수 있다. Legacy 예외는 일반 artifact 규칙을 복잡하게 하지만 exact path와 source commit을 고정하고 read-only로 취급해 감사 가능성을 유지한다.
### ADR-011: 구형 단일 검증 진입점 계약을 폐기한다 ### ADR-011: 구형 단일 검증 진입점 계약을 폐기한다
@@ -88,3 +88,19 @@ FESA의 architecture decision은 solver correctness, verification traceability,
**이유**: 테스트 파일 존재 검사, TDD 실행 증거, 전체 build/test는 서로 다른 책임이다. 이를 분리하면 Hook이 보장하는 범위를 과장하지 않으면서 Step 종료 시 green 상태를 강제할 수 있다. **이유**: 테스트 파일 존재 검사, TDD 실행 증거, 전체 build/test는 서로 다른 책임이다. 이를 분리하면 Hook이 보장하는 범위를 과장하지 않으면서 Step 종료 시 green 상태를 강제할 수 있다.
**트레이드오프**: PreToolUse만으로 구현 전 RED 실행을 증명할 수 없으므로 Implementation report에 RED/GREEN 명령과 결과를 기록해야 한다. C/C++가 없는 저장소는 Stop이 통과하므로 Harness Python 검증은 별도 acceptance command로 유지한다. **트레이드오프**: PreToolUse만으로 구현 전 RED 실행을 증명할 수 없으므로 Implementation report에 RED/GREEN 명령과 결과를 기록해야 한다. C/C++가 없는 저장소는 Stop이 통과하므로 Harness Python 검증은 별도 acceptance command로 유지한다.
### ADR-013: V0 선형 정적 해석은 단일 step B33 Euler beam으로 제한한다
**결정**: 첫 end-to-end 제품 기능은 입력 파일당 하나의 `*STEP, *STATIC`을 해석하는 2절점 3D EulerBernoulli beam이다. Abaqus `TYPE=B33`만 이 요소로 매핑하고 B31은 `unsupported-element-formulation`으로 거부한다. `*PART/*ASSEMBLY/*INSTANCE`는 여러 identity instance와 stable source identity를 지원하지만 instance transform, nested assembly, 다중 step은 지원하지 않는다. Output-request keyword는 승인 allowlist에서 warning 후 no-op 처리하고 FESA 기본 HDF5 결과는 항상 생성한다.
**이유**: B31은 transverse shear deformation을 포함하므로 EulerBernoulli 정식화와 의미가 다르다. 단일 step과 identity instance로 범위를 제한하면 parser wrapper, source identity, assembly, 해법 및 결과 복구를 end-to-end로 검증하면서 의미를 왜곡하지 않는다.
**트레이드오프**: 기존 Abaqus 모델 중 B31, instance transform, 다중 step 또는 `*DLOAD`를 사용하는 입력은 거부된다. 이후 기능은 별도 요구조건과 formulation/reference gate를 거쳐 추가한다.
### ADR-014: B33 cantilever baseline은 component-scale 혼합 tolerance로 비교한다
**결정**: `reference/cantilever beam/`의 B33 input, displacement CSV, reaction CSV, elemental-force CSV를 V0 reference baseline으로 사용한다. Displacement와 reaction은 node identity로, section resultant는 CSV node station과 정규화된 FESA element endpoint로 비교한다. 같은 model, step/frame, quantity, component에 대해 `reference_scale = max(abs(reference rows))`를 계산하고 모든 row에 `absolute_floor + 1e-6 * reference_scale`을 적용한다. SI displacement/rotation absolute floor는 `1e-9`, force/moment floor는 `1e-3`이다. Beam stress는 출력하되 Abaqus stress reference comparison은 N/A다.
**이유**: 자유단 moment처럼 이론적으로 0인 값에는 행별 상대오차가 정의되지 않으며 Abaqus 결과에 작은 수치 잔차가 남을 수 있다. Component scale을 사용하면 전체 물리량 크기에 비해 작은 잔차를 허용하면서 각 row를 결정적으로 판정할 수 있다.
**트레이드오프**: 큰 component scale은 zero row의 허용폭을 넓힌다. 이를 완화하기 위해 quantity와 component를 섞지 않고 Abaqus 값만 scale에 사용하며, 모든 row의 absolute/normalized error와 worst row를 보고하고 누락·추가·nonfinite row를 tolerance 전에 실패시킨다.
+142 -27
View File
@@ -11,6 +11,12 @@ FESA의 아키텍처 목표는 Abaqus `.inp` subset을 내부 semantic model로
- incremental feature addition - incremental feature addition
- Harness 기반 TDD - Harness 기반 TDD
현재 승인된 V0 end-to-end 기능은 `linear-static-3d-euler-beam`이다. 상세 계약의
source of truth는
`docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`이며, 이 문서는
그 계약을 전체 solver architecture의 모듈과 데이터 흐름에 배치한다. 아래에 나타난
비선형, 동적, thermal 및 다른 element 계층은 장기 확장 경계이며 V0 지원 범위가 아니다.
## 디렉토리 구조 ## 디렉토리 구조
```text ```text
src/ src/
@@ -31,9 +37,7 @@ src/
analysis/ # static, modal, dynamic, nonlinear procedure drivers analysis/ # static, modal, dynamic, nonlinear procedure drivers
results/ # recovery, field/history output, diagnostics results/ # recovery, field/history output, diagnostics
validation/ # comparison metrics and tolerance helpers validation/ # comparison metrics and tolerance helpers
math/ math/ # owning Vector, row-major Matrix, CSR SparseMatrix adapters
Vector/ # managing double array including vector operation, vector operation must use BLAS from MKL
Matrix/ # managing double array including matrix operation, matrix operation must use BLAS from MKL
tests/ tests/
unit/ unit/
integration/ integration/
@@ -83,6 +87,57 @@ Runner는 `git add -A`를 사용하므로 clean worktree 또는 별도 Git workt
- `results`는 HDF5 schema를 통해 nodal, element, integration-point, diagnostic output을 분리한다. - `results`는 HDF5 schema를 통해 nodal, element, integration-point, diagnostic output을 분리한다.
- test helper는 production parser/solver 내부 상태를 우회하지 않는다. - test helper는 production parser/solver 내부 상태를 우회하지 않는다.
## V0 입력 경계
V0 parser는 keyword와 parameter를 case-insensitive하게 해석하되 source label의 원문을
보존한다. 지원하는 model/procedure keyword는 다음과 같다.
- `*HEADING`
- `*PART`, `*END PART`
- `*NODE`
- `*ELEMENT, TYPE=B33`
- `*NSET`, `*ELSET`, including `GENERATE`
- `*MATERIAL`, `*ELASTIC`
- `*BEAM GENERAL SECTION, SECTION=GENERAL`
- `*SECTION POINTS`
- `*ASSEMBLY`, `*END ASSEMBLY`
- `*INSTANCE`, `*END INSTANCE`
- `*BOUNDARY`, `*CLOAD`
- `*STEP`, `*STATIC`, `*END STEP`
Part 내부 label은 `SourceEntityId { instance_name, source_label }`로 보존하고 Domain은
별도 stable internal index를 부여한다. 같은 part의 여러 identity instance는 허용하지만
translation/rotation data와 nested assembly는 구조화된 unsupported diagnostic으로
거부한다. 입력 파일당 하나의 static step만 허용하고 두 번째 step은 오류다.
`*PREPRINT`, `*RESTART`, `*TRANSVERSE SHEAR STIFFNESS`, `*OUTPUT, FIELD`,
`*OUTPUT, HISTORY`, `*NODE OUTPUT`, `*ELEMENT OUTPUT`, `*CONTACT OUTPUT` 및 그에 속한
미지원 output variable data는 warning 후 no-op 처리한다. 이 allowlist 밖의 미지원
model-affecting keyword는 오류다. FESA output은 Abaqus output request에 좌우되지 않는다.
## V0 beam과 section 계약
`EulerBeam3D`는 2절점과 절점당 `[UX, UY, UZ, URX, URY, URZ]` 6 DOF를 사용하며 축,
두 방향 EulerBernoulli 굽힘과 Saint-Venant 비틀림을 제공한다. Beam tangent를 local
`x`, Abaqus first section axis `n1`을 local `y`, `t x n1`을 local `z`로 둔다.
`*BEAM GENERAL SECTION``A, I11, I12, I22, J``Iy=I11`, `Iz=I22`로 매핑하고
V0는 `I12=0`만 허용한다. `E`, `G`, `A`, `Iy`, `Iz`, `J`는 양수여야 하며 zero-length
element와 tangent에 평행한 guide vector를 scale-aware tolerance로 거부한다.
요소 API는 stiffness, transformation, load와 recovery 책임을 분리한다.
```cpp
Matrix localStiffness() const;
Matrix globalStiffness() const;
Vector localEquivalentLoad(const ConstantLocalLineLoad& load) const;
BeamRecovery recover(const Vector& globalElementDisplacement) const;
```
`localEquivalentLoad`는 formulation의 constant local line-load kernel을 unit test하기
위한 계약이다. V0 parser는 `*DLOAD`나 distributed-load Domain object를 생성하지 않으므로
CLI pipeline에서는 이 kernel을 호출하지 않는다. Stiffness와 recovery는 formulation의
2점 Gauss rule과 부호 규약을 따른다.
## 핵심 객체 모델 ## 핵심 객체 모델
```text ```text
Domain Domain
@@ -159,8 +214,14 @@ Results
Vector Vector
Matrix Matrix
SparseMatrix
``` ```
이 객체 모델 중 V0 `Analysis` 구현은 `LinearStaticAnalysis` 하나이며 `AnalysisState`
full displacement, external/internal force, residual, constrained reaction, step/frame
identity와 element recovery rows만 할당한다. Velocity, acceleration, temperature,
iteration history와 nonlinear element state는 V0에서 할당하지 않는다.
## 상태 관리 ## 상태 관리
- `Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다. - `Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다.
- `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않고 참조 또는 id 기반 view로 구성한다. - `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않고 참조 또는 id 기반 view로 구성한다.
@@ -171,37 +232,46 @@ Matrix
## 데이터 흐름 ## 데이터 흐름
```text ```text
Abaqus input file Abaqus input file
-> InputParser -> syntax parse and semantic mapping
-> Domain 생성 -> immutable Domain 생성
-> StepDefinition 루프 -> 단일 step AnalysisModel view 생성
-> AnalysisModel 생성 -> DofManager DOF/scatter map/sparse pattern 생성
-> DofManager로 자유도/방정식 번호 생성 -> element stiffness 계산과 deterministic COO-to-CSR 조립
-> sparse pattern 생성 -> free/constrained partition 생성
-> Analysis 실행 -> LinearSolver::factorize(Kff)
-> Assembler로 전역 행렬/벡터 조립 -> full nodal load vector 조립
-> BoundaryCondition 적용 -> effective RHS = Ff - Kfc * dc
-> LinearSolver 또는 nonlinear/time integration loop -> LinearSolver::solve(rhs, df) substitution
-> AnalysisState 갱신 -> full displacement 복구
-> ResultsWriter로 step/frame/history 저장 -> reaction = K*d - F 및 element result 복구
-> 다음 step 진행 -> ResultsWriter로 results.h5 atomic finalization
``` ```
강성행렬 factorization은 하중벡터 조립보다 먼저 수행한다. 반력은 element end action의
별도 합이 아니라 조립된 전체 residual에서 구한다.
## 해석 실행 흐름 ## 해석 실행 흐름
`Analysis::run()`은 Template Method로 다음 흐름을 고정한다. 해석 종류별 class는 필요한 단계만 재정의한다. `Analysis::run()`은 Template Method로 다음 V0 흐름을 고정한다. 해석 종류별 class는
승인된 procedure contract 안에서 필요한 단계만 재정의한다.
```text ```text
initialize initialize
buildAnalysisModel buildAnalysisModel
buildDofMap buildDofMap
buildSparsePattern buildSparsePattern
assemble assembleStiffness
applyBoundaryConditions partitionConstraints
solve factorize
updateState assembleLoads
formEffectiveRhs
substitute
reconstructDisplacement
recoverResults
writeResults writeResults
``` ```
비선형 정적해석은 이 흐름을 Newton-Raphson 반복 루프 안에서 사용하고, 동적해석은 time step/frame 루프 안에서 사용한다. 비선형 정적 동적 해석은 V0 범위가 아니며 별도 ADR과 formulation을 승인한 뒤 이
lifecycle의 확장 지점을 사용한다.
## 설계 패턴 ## 설계 패턴
- Strategy Pattern: `Analysis`, `LinearSolver`, `TimeIntegrator`, `ConvergenceCriteria`를 교체 가능한 전략으로 둔다. - Strategy Pattern: `Analysis`, `LinearSolver`, `TimeIntegrator`, `ConvergenceCriteria`를 교체 가능한 전략으로 둔다.
@@ -213,10 +283,21 @@ writeResults
## Sparse Matrix Policy ## Sparse Matrix Policy
- assembly는 초기에는 COO triplet 수집 후 CSR finalize를 기준으로 한다. - assembly는 초기에는 COO triplet 수집 후 CSR finalize를 기준으로 한다.
- `SparseMatrix`solver core가 사용하는 추상 contract이고 MKL PARDISO backend는 CSR input contract만 받는다. - `SparseMatrix`0-based CSR 데이터를 소유하는 별도 타입이며 dense `Matrix`
상속하지 않는다. MKL PARDISO backend는 adapter 경계에서 필요한 descriptor와 indexing을
변환한다.
- matrix symmetry, definiteness, singularity diagnostic을 구조화된 diagnostic으로 남긴다. - matrix symmetry, definiteness, singularity diagnostic을 구조화된 diagnostic으로 남긴다.
- deterministic assembly를 위해 TBB element loop는 thread-local contribution buffer 또는 two-pass sparse assembly를 사용한다. - deterministic assembly를 위해 TBB element loop는 thread-local contribution buffer 또는 two-pass sparse assembly를 사용한다.
## Dense Math Policy
- `Vector`는 contiguous `double` 데이터와 크기를 소유하고 copy, dot, Euclidean norm,
scale, axpy를 MKL CBLAS adapter로 수행한다.
- `Matrix`는 row-major contiguous `double` 데이터와 dimensions를 소유하고
matrix-vector 및 matrix-matrix 연산에 `CBLAS_ROW_MAJOR`를 사용한다.
- 두 타입은 copy/move semantics와 bounds-checked access를 제공한다.
- MKL header와 MKL-specific type은 adapter implementation 밖으로 노출하지 않는다.
## Parallel Policy ## Parallel Policy
- 첫 번째 oneTBB 적용 지점은 element-local matrix/residual 계산이다. - 첫 번째 oneTBB 적용 지점은 element-local matrix/residual 계산이다.
- 전역 sparse write는 thread-local buffer 또는 deterministic reduction으로 제한한다. - 전역 sparse write는 thread-local buffer 또는 deterministic reduction으로 제한한다.
@@ -227,10 +308,12 @@ writeResults
/metadata /metadata
/model/nodes /model/nodes
/model/elements /model/elements
/steps/<step-name>/frames/<frame-id>/nodal/displacement /steps/<step-name>/frames/0/nodal/displacement
/steps/<step-name>/frames/<frame-id>/nodal/reaction /steps/<step-name>/frames/0/nodal/reaction
/steps/<step-name>/frames/<frame-id>/element/stress /steps/<step-name>/frames/0/element/end_force_local
/steps/<step-name>/frames/<frame-id>/element/strain /steps/<step-name>/frames/0/element/section_resultant
/steps/<step-name>/frames/0/element/generalized_strain
/steps/<step-name>/frames/0/element/stress_s11
/diagnostics /diagnostics
``` ```
@@ -242,3 +325,35 @@ 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 파일을 완성한 뒤 최종 경로로 교체하며 실패 시 불완전한
`results.h5`를 남기지 않는다.
## V0 결과 복구와 reference normalization
- Nodal displacement와 reaction은 global `[UX, UY, UZ, URX, URY, URZ]` 순서다.
- Equilibrium end action은 local `[FX,FY,FZ,MX,MY,MZ]`, endpoint section resultant는
`[N,T,My,Mz]`, generalized strain/resultant는 두 Gauss point에 기록한다.
- General beam section stress는 section point의 axial `S11`만 복구한다. Section point가
없으면 centroid `(0,0)``source=fesa-default`로 기록한다.
- 승인된 `reference/cantilever beam/cantilever beam elemental forces.csv`는 node station
기준 `SF1/SM1/SM2/SM3`을 제공한다. FESA endpoint를 동일한 section-cut 부호로
정규화하고 interior node의 두 endpoint가 tolerance 안에서 일치하는지 먼저 확인한 뒤
`SF1 -> N`, `SM1 -> My`, `SM2 -> Mz`, `SM3 -> T`로 비교한다.
- Reference tolerance는 같은 model, step/frame, quantity, component의 Abaqus rows에서
`reference_scale = max(abs(reference_value))`를 구하고 각 row에
`absolute_floor + 1e-6 * reference_scale`을 적용한다. SI displacement/rotation floor는
`1e-9`, force/moment floor는 `1e-3`이다.
- Beam stress는 HDF5 schema와 unit/analytical test로 검증하지만 Abaqus reference
comparison은 N/A다.
## CLI와 diagnostics
```powershell
fesa.exe <model.inp> --output <results.h5>
```
`--output`을 생략하면 현재 작업 디렉터리의 `results.h5`를 사용한다. Exit code는
`0=success`, `2=usage`, `3=input syntax/semantic mapping`, `4=model validation`,
`5=factorization/substitution`, `6=HDF5 output`으로 고정한다. Diagnostic은 `severity`,
`code`, `file`, `line`, `keyword`, `entity_identity`, `message`를 가지며 stderr에
deterministic한 순서로 출력한다.
+53 -19
View File
@@ -18,31 +18,46 @@ FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 유한요소법 기
4. 요소, 재료, 경계조건, 하중의 runtime-polymorphic base interface 4. 요소, 재료, 경계조건, 하중의 runtime-polymorphic base interface
5. sparse matrix pattern 생성, 전역 행렬/벡터 조립, 제약조건 적용 5. sparse matrix pattern 생성, 전역 행렬/벡터 조립, 제약조건 적용
6. `LinearSolver` adapter를 통한 MKL PARDISO backend와 향후 iterative solver 확장 6. `LinearSolver` adapter를 통한 MKL PARDISO backend와 향후 iterative solver 확장
7. HDF5 기반 `ResultStep` -> `ResultFrame` -> `FieldOutput`/`HistoryOutput` 저장 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 기반 개발 검증
## V0 범위 ## V0 범위
- 선형 정적 해석 파이프라인 구현 - 선형 정적 해석 파이프라인 구현
- 첫 end-to-end 기능 후보: Isoparametric 3D Euler beam element - 승인된 첫 end-to-end 기능: 2절점 3D EulerBernoulli beam, Abaqus `TYPE=B33`
- 입력 파일당 하나의 `*STEP, *STATIC`
- 절점당 자유도 `[UX, UY, UZ, URX, URY, URZ]`
- 축, 두 방향 굽힘, Saint-Venant 비틀림 및 선형 등방 탄성
- 최소 Abaqus keyword subset: - 최소 Abaqus keyword subset:
- `*HEADING` - `*HEADING`
- `*NODE` - `*PART`, `*END PART`
- `*ELEMENT` - `*NODE`, `*ELEMENT, TYPE=B33`
- `*NSET` - `*NSET`, `*ELSET`, including `GENERATE`
- `*ELSET`
- `*MATERIAL` - `*MATERIAL`
- `*ELASTIC` - `*ELASTIC`
- `*Beam General Section` - `*BEAM GENERAL SECTION, SECTION=GENERAL`
- `*SECTION POINTS`
- `*ASSEMBLY`, `*END ASSEMBLY`
- `*INSTANCE`, `*END INSTANCE`
- `*BOUNDARY` - `*BOUNDARY`
- `*CLOAD` - `*CLOAD`
- `*STEP` - `*STEP`, `*STATIC`, `*END STEP`
- `*STATIC` - `*PREPRINT`, `*RESTART`, `*TRANSVERSE SHEAR STIFFNESS`, `*OUTPUT, FIELD`,
- output request subset `*OUTPUT, HISTORY`, `*NODE OUTPUT`, `*ELEMENT OUTPUT`, `*CONTACT OUTPUT`과 그에 속한
미지원 variable data는 warning 후 no-op 처리
- 같은 part의 여러 identity instance와 stable source label mapping
- nonzero prescribed displacement를 포함한 free/constrained partition
- formulation의 constant local line-load equivalent nodal vector kernel. V0 parser와 CLI는
`*DLOAD`를 지원하거나 이 kernel을 호출하지 않음
- deterministic COO-to-CSR stiffness assembly
- MKL PARDISO 기반 sparse direct solver - MKL PARDISO 기반 sparse direct solver
- displacements, reactions, elemental forces 중심의 verification - stiffness factorization과 load-vector substitution 분리
- displacements, reactions, equilibrium end actions, section resultants, generalized results,
axial `S11` output
- HDF5 result schema v0 - HDF5 result schema v0
- FESA HDF5 to Abaqus reference CSV comparison 계약 - `fesa.exe <model.inp> --output <results.h5>` CLI
- 승인된 `reference/cantilever beam/` B33 결과와 displacement, reaction, section resultant
comparison; beam stress reference comparison은 N/A
## 기능 요구조건 ## 기능 요구조건
| ID | 요구조건 | Acceptance Criteria | Verification Method | | ID | 요구조건 | Acceptance Criteria | Verification Method |
@@ -51,18 +66,29 @@ FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 유한요소법 기
| FESA-PRD-002 | FESA는 입력 모델을 `Domain`으로 변환해야 한다. | nodes, elements, materials, properties, sets, loads, boundary conditions, step definitions가 semantic model에 보존된다. | parser integration test | | FESA-PRD-002 | FESA는 입력 모델을 `Domain`으로 변환해야 한다. | nodes, elements, materials, properties, sets, loads, boundary conditions, step definitions가 semantic model에 보존된다. | parser integration test |
| FESA-PRD-003 | FESA는 현재 step의 실행 view를 `AnalysisModel`로 구성해야 한다. | active elements, loads, boundary conditions, properties/materials가 Domain 복사 없이 참조 또는 id view로 연결된다. | analysis model unit test | | FESA-PRD-003 | FESA는 현재 step의 실행 view를 `AnalysisModel`로 구성해야 한다. | active elements, loads, boundary conditions, properties/materials가 Domain 복사 없이 참조 또는 id view로 연결된다. | analysis model unit test |
| FESA-PRD-004 | FESA는 equation numbering과 constraint/free mapping을 `DofManager`에 집중해야 한다. | Node/Element 내부에 equation id를 분산 저장하지 않는다. | code review, DofManager unit test | | FESA-PRD-004 | FESA는 equation numbering과 constraint/free mapping을 `DofManager`에 집중해야 한다. | Node/Element 내부에 equation id를 분산 저장하지 않는다. | code review, DofManager unit test |
| FESA-PRD-005 | FESA는 해석 중 변하는 물리량을 `AnalysisState`에 저장해야 한다. | displacement, force, residual, increment/iteration 상태가 step/frame 출력 연결다. | state unit test, integration test | | FESA-PRD-005 | FESA는 해석 중 변하는 물리량을 `AnalysisState`에 저장해야 한다. | V0 displacement, external/internal force, residual, constrained reaction, step/frame identity와 element recovery rows가 출력 연결되고 velocity, acceleration, temperature, iteration history는 할당하지 않는다. | state unit test, integration test |
| FESA-PRD-006 | FESA는 solver 결과를 HDF5 authoritative output `results.h5`로 저장해야 한다. | step/frame, field/history, metadata, diagnostics가 schema version과 함께 저장된다. | HDF5 schema test | | FESA-PRD-006 | FESA는 solver 결과를 HDF5 authoritative output `results.h5`로 저장해야 한다. | V0 step/frame field results, metadata, diagnostics가 schema version과 함께 저장된다. | HDF5 schema test |
| FESA-PRD-007 | FESA는 Abaqus reference CSV rows와 비교 가능한 deterministic row mapping을 제공해야 한다. | displacement, reaction, internal force, stress 등 검증 물리량의 row identity와 tolerance source가 명확하다. | reference comparison report | | FESA-PRD-007 | FESA는 Abaqus reference CSV rows와 비교 가능한 deterministic row mapping을 제공해야 한다. | displacement reaction은 node identity, B33 section resultant는 정규화된 node station identity로 비교하고 stress reference comparison은 N/A로 기록한다. | reference comparison report |
| FESA-PRD-008 | FESA의 production C++ 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현해야 한다. | 관련 C++ test file, RED 실패와 후속 GREEN 성공 증거가 있고 Stop의 전체 MSVC build/test가 통과한다. | implementation report, Hook guardrail, CTest | | FESA-PRD-008 | FESA의 production C++ 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현해야 한다. | 관련 C++ test file, RED 실패와 후속 GREEN 성공 증거가 있고 Stop의 전체 MSVC build/test가 통과한다. | implementation report, Hook guardrail, CTest |
| FESA-PRD-009 | FESA는 외부 라이브러리 API를 solver core에 직접 노출하지 않아야 한다. | MKL, TBB, HDF5 의존은 adapter module에 제한된다. | architecture review, dependency review | | FESA-PRD-009 | FESA는 외부 라이브러리 API를 solver core에 직접 노출하지 않아야 한다. | MKL, TBB, HDF5 의존은 adapter module에 제한된다. | architecture review, dependency review |
| FESA-PRD-010 | FESA 기능 완료는 reference comparison과 physics sanity 통과를 요구해야 한다. | 수치 tolerance와 물리 검토가 모두 pass이고 known limitation이 기록된다. | verification report, physics evaluation report | | FESA-PRD-010 | FESA 기능 완료는 reference comparison과 physics sanity 통과를 요구해야 한다. | 수치 tolerance와 물리 검토가 모두 pass이고 known limitation이 기록된다. | verification report, physics evaluation report |
| FESA-PRD-011 | V0는 입력 파일당 하나의 linear static step과 Abaqus B33 3D Euler beam만 해석해야 한다. | 단일 B33 model은 해석되고, B31과 두 번째 step은 구조화된 unsupported diagnostic으로 거부된다. | parser/semantic unit test, CLI integration test |
| FESA-PRD-012 | V0는 Part/Assembly/Instance wrapper와 source identity를 보존해야 한다. | 여러 identity instance의 node/element/set label이 stable internal ID로 deterministic하게 매핑되고 transform 또는 nested assembly는 거부된다. | semantic mapping unit test |
| FESA-PRD-013 | Output-request allowlist는 해석 의미를 변경하지 않아야 한다. | 승인 keyword와 variable data는 warning 후 no-op이고, allowlist 밖 model-affecting keyword는 오류이며 기본 결과는 output request와 무관하게 생성된다. | parser diagnostic test, HDF5 integration test |
| FESA-PRD-014 | 선형 정적 pipeline은 stiffness factorization과 load substitution을 분리해야 한다. | `Kff` factorization이 load vector assembly보다 먼저 수행되고, `rhs=Ff-Kfc*dc` substitution으로 full displacement를 복구한다. | orchestration test, solver-adapter test |
| FESA-PRD-015 | FESA는 V0 결과와 diagnostic을 안정된 외부 계약으로 출력해야 한다. | CLI가 `0=success`, `2=usage`, `3=input`, `4=model`, `5=solver`, `6=HDF5` exit code를 사용하고 diagnostic field가 계약과 일치하며 HDF5가 displacement, reaction, end force, section resultant, generalized strain/resultant, axial `S11`을 포함하고 실패 시 불완전한 최종 파일을 남기지 않는다. | CLI integration test, HDF5 schema/atomicity test |
| FESA-PRD-016 | Dense와 sparse math storage 및 backend 경계를 분리해야 한다. | `Vector`는 contiguous, `Matrix`는 row-major contiguous storage와 MKL CBLAS를 사용하고 `SparseMatrix`는 별도 0-based CSR 타입이며 MKL 타입이 public core API에 노출되지 않는다. | math unit test, dependency review |
| FESA-PRD-017 | B33 reference comparison은 component-scale 혼합 tolerance를 사용해야 한다. | 모든 matched row가 `abs_error <= absolute_floor + 1e-6 * reference_scale`을 만족하고 missing/extra/nonfinite row는 comparison 전에 실패한다. | reference comparison unit/integration test, verification report |
| FESA-PRD-018 | 승인된 B33 reference artifact는 read-only baseline으로 유지해야 한다. | `reference/cantilever beam/` 파일을 rename, rewrite, 보정하지 않고 exact legacy path로 읽으며 B33 element type과 expected headers를 artifact check에서 확인한다. | artifact inventory, Git diff review |
| FESA-PRD-019 | B33 beam section과 local axis를 Abaqus 의미에 맞게 매핑해야 한다. | `n1 -> local y`, `t x n1 -> local z`, `Iy=I11`, `Iz=I22`, `I12=0`을 적용하고 nonpositive property, zero-length element, tangent-parallel guide vector를 구조화된 model diagnostic으로 거부한다. | section-mapping unit test, element geometry test |
## 비기능 요구조건 ## 비기능 요구조건
- MSVC x64 Debug 환경에서 configure, build, CTest를 검증한다. - MSVC x64 Debug 환경에서 configure, build, CTest를 검증한다.
- reference test 결과는 deterministic해야 한다. - reference test 결과는 deterministic해야 한다.
- HDF5 schema는 versioned contract로 관리한다. - HDF5 schema는 versioned contract로 관리한다.
- tolerance policy는 absolute, relative, norm-based 기준을 구분한다. - B33 reference tolerance는 model, step/frame, quantity, component별 Abaqus scale만 사용한다.
- 승인된 SI B33 bundle의 absolute floor는 displacement/rotation `1e-9`, force/moment
`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를 우선한다. - 대규모 모델 성능 최적화보다 Phase 1 명확성, 테스트 가능성, 검증 traceability를 우선한다.
@@ -74,14 +100,22 @@ FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 유한요소법 기
4. I/O contract approved: Abaqus keyword subset, internal model mapping, HDF5 result contract, reference CSV comparison row contract가 승인되어 있다. 4. I/O contract approved: Abaqus keyword subset, internal model mapping, HDF5 result contract, reference CSV comparison row contract가 승인되어 있다.
5. Tests fail before implementation: C++/integration/reference test를 제품 코드보다 먼저 작성하고 같은 Step 안에서 RED 실패와 후속 GREEN 성공을 확인한다. 5. Tests fail before implementation: C++/integration/reference test를 제품 코드보다 먼저 작성하고 같은 Step 안에서 RED 실패와 후속 GREEN 성공을 확인한다.
6. CMake/CTest pass: MSVC/x64/Debug 기준 configure, build, test가 통과한다. 6. CMake/CTest pass: MSVC/x64/Debug 기준 configure, build, test가 통과한다.
7. Reference comparison pass: FESA `results.h5` rows와 Abaqus reference CSV rows가 documented IDs, components, units, coordinate system, step/frame identity, tolerance 기준 안에 있다. 7. Reference comparison pass: FESA `results.h5`의 displacement, reaction, section resultant rows가 승인된 B33 CSV와 documented identity 및 component-scale 혼합 tolerance 안에 있다. Beam stress comparison은 명시적 N/A다.
8. Physics sanity pass: equilibrium, reaction consistency, displacement direction, symmetry, stress sanity가 검토되어 있다. 8. Physics sanity pass: equilibrium, reaction consistency, displacement direction, symmetry, section-force consistency와 normalized residual이 검토되어 있다.
9. Release readiness pass: acceptance traceability, known limitations, release notes draft가 준비되어 있다. 9. Release readiness pass: acceptance traceability, known limitations, release notes draft가 준비되어 있다.
## 제외 사항 ## 제외 사항
- Abaqus full parser 호환 - Abaqus full parser 호환
- Abaqus B31/Timoshenko beam
- 다중 analysis step과 step 간 load/BC propagation
- instance translation/rotation, nested assembly 및 dependent/independent mesh semantics
- `I12 != 0`, taper, offset, release, curved beam, warping
- Abaqus `*DLOAD` 입력과 Domain distributed-load object
- 기하·재료비선형, dynamics, contact, thermal effects
- transverse shear stress와 torsional shear stress recovery
- beam stress에 대한 Abaqus reference comparison
- Abaqus, Nastran 또는 reference solver 직접 실행 자동화 - Abaqus, Nastran 또는 reference solver 직접 실행 자동화
- Agent가 Abaqus reference CSV 파일을 임의 생성 또는 수정하는 작업 - Agent가 Abaqus reference CSV 파일을 임의 생성 또는 수정하는 작업
- GUI 또는 postprocessor - GUI 또는 postprocessor
- Visual Studio `.sln`/`.vcxproj` 전용 MSBuild workflow - Visual Studio `.sln`/`.vcxproj` 전용 MSBuild workflow
- Explicit dynamics, contact, plasticity, shell end-to-end 구현 - plasticity shell end-to-end 구현
@@ -0,0 +1,282 @@
# Linear Static 3D Euler Beam Harness Phase Construction 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:** Create the approved 29-step Harness phase that drives the FESA V0 single-step B33 linear-static solver from upstream contracts through release readiness.
**Architecture:** The phase is a sequence of seven document gates, eighteen TDD implementation steps, and four final verification gates. Each `stepN.md` is self-contained, names its role/skill and owned paths, preserves the approved design as the source of truth, and delegates per-step commits and timestamps to `scripts/execute.py`.
**Tech Stack:** Markdown and JSON phase descriptors; C++17; MSVC x64 Debug; CMake/CTest; GoogleTest from `C:/git/googletest`; Intel oneMKL/oneTBB; HDF5; Python 3 Harness runner.
## Global Constraints
- The approved source of truth is `docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`; phase steps must not silently broaden or reinterpret it.
- The solver scope is one `*STEP, *STATIC` using Abaqus `TYPE=B33`; `TYPE=B31`, multiple steps, instance transforms, nested assemblies, and `*DLOAD` input remain unsupported.
- Runtime order keeps `Kff` factorization before load-vector assembly and separates factorization from substitution.
- Production C++ changes use `RED -> GREEN -> VERIFY`; every production file has a related GoogleTest file.
- Validation uses MSVC x64 Debug and the exact dependency cache variables in the approved design; production CMake must not hardcode the local GoogleTest path.
- `reference/cantilever beam/` is read-only and must not be renamed, rewritten, regenerated, or repaired by the phase.
- Beam stress is written and tested, but Abaqus stress reference comparison is explicitly N/A.
- Harness owns per-step commits and timestamps; a step must update only its phase status and must not invoke `git commit`.
- Before `python scripts/execute.py linear-static-3d-euler-beam`, use a clean worktree or a separate worktree because the current executor stages with `git add -A`.
---
### Task 1: Create Phase Indexes
**Files:**
- Create: `phases/index.json`
- Create: `phases/linear-static-3d-euler-beam/index.json`
**Interfaces:**
- Consumes: approved phase name and 29-step table from the design specification.
- Produces: top-level pending phase registration and contiguous step numbers `0..28` with kebab-case names.
- [ ] **Step 1: Register the phase**
```json
{
"phases": [
{ "dir": "linear-static-3d-euler-beam", "status": "pending" }
]
}
```
- [ ] **Step 2: Create the task index**
Use `project: "FESA Structural Solver"`, `phase: "linear-static-3d-euler-beam"`, and the exact step names from specification section 3. Do not add timestamps; the executor owns them.
- [ ] **Step 3: Validate both JSON files**
```powershell
Get-Content -Raw phases/index.json | ConvertFrom-Json | Out-Null
$phase = Get-Content -Raw phases/linear-static-3d-euler-beam/index.json | ConvertFrom-Json
if ($phase.steps.Count -ne 29) { throw 'Expected 29 steps' }
if (($phase.steps.step -join ',') -ne ((0..28) -join ',')) { throw 'Step numbers are not contiguous' }
```
- [ ] **Step 4: Executor commit checkpoint**
Do not run `git commit`; `scripts/execute.py` commits phase execution results. The phase-construction changes remain for the user to review and commit.
### Task 2: Create Upstream Contract Gate Steps
**Files:**
- Create: `phases/linear-static-3d-euler-beam/step0.md` through `step6.md`
**Interfaces:**
- Consumes: approved design, formulation, root project documents, gate-specific README files, and exact FESA skill contracts.
- Produces: requirements, research, formulation alignment, numerical review, I/O, reference-model, and implementation-plan documents.
- [ ] **Step 1: Define role and skill ownership**
```text
0 requirement-agent / fesa-requirements-baseline
1 research-agent / fesa-research-evidence + fem-theory-query
2 formulation-agent / fesa-formulation-spec
3 numerical-review-agent / fesa-numerical-review
4 io-definition-agent / fesa-io-contract
5 reference-model-agent / fesa-reference-models
6 implementation-planning-agent / fesa-cpp-msvc-tdd
```
- [ ] **Step 2: Make each document gate self-contained**
Each step names required input paths, the exact output path, mandatory sections/status, immutable decisions, executable PowerShell checks, status-update rules, and prohibited changes. Step 2 aligns the existing formulation without changing its approved mathematical meaning; Step 5 documents the approved legacy bundle exception without modifying `reference/`.
- [ ] **Step 3: Verify gate file structure**
```powershell
0..6 | ForEach-Object {
$path = "phases/linear-static-3d-euler-beam/step$_.md"
if (-not (Test-Path $path)) { throw "Missing $path" }
foreach ($section in @('## 읽어야 할 파일','## 작업','## Acceptance Criteria','## 검증 절차','## 금지사항')) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $section -Quiet)) {
throw "$path missing $section"
}
}
}
```
- [ ] **Step 4: Executor commit checkpoint**
Do not commit manually; the executor will commit each completed gate.
### Task 3: Create C++ TDD Implementation Steps
**Files:**
- Create: `phases/linear-static-3d-euler-beam/step7.md` through `step24.md`
**Interfaces:**
- Consumes: approved upstream documents produced by Steps 06.
- Produces: build foundation, core/model/parser/FEM/math/solver/result modules, tests, and `fesa.exe`.
- [ ] **Step 1: Lock module order and interfaces**
```cpp
Matrix EulerBeam3D::localStiffness() const;
Matrix EulerBeam3D::globalStiffness() const;
Vector EulerBeam3D::localEquivalentLoad(const ConstantLocalLineLoad&) const;
BeamRecovery EulerBeam3D::recover(const Vector& globalElementDisplacement) const;
class LinearSolver {
public:
virtual ~LinearSolver() = default;
virtual Status factorize(const SparseMatrix& matrix) = 0;
virtual Status solve(const Vector& rhs, Vector& solution) const = 0;
};
```
The remaining steps define signatures for diagnostics, semantic mapping, active views, DOF numbering, state, deterministic parallel assembly, constraints, load assembly, result recovery, HDF5 writing, and orchestration without exposing MKL/TBB/HDF5 types across adapter boundaries.
- [ ] **Step 2: Encode test-first execution in every production step**
Each Step 824 contains these independently verifiable actions:
```text
1. Add the named GoogleTest cases before production edits.
2. Build and run the targeted CTest regex; record the expected missing-behavior RED failure.
3. Add only the production behavior owned by the step.
4. Rebuild and run the targeted test to GREEN.
5. Run CTest discovery and the full CTest suite for VERIFY.
```
Step 7 creates the build/test foundation and proves at least one discovered test. Step 24 also provides the end-to-end CLI and test-only B33 reference comparison command used read-only by Step 26.
- [ ] **Step 3: Use the approved dependency configure command**
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
- [ ] **Step 4: Verify all implementation step descriptors**
```powershell
7..24 | ForEach-Object {
$path = "phases/linear-static-3d-euler-beam/step$_.md"
if (-not (Test-Path $path)) { throw "Missing $path" }
foreach ($text in @('MSVC x64 Debug','## Acceptance Criteria','## 금지사항')) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "$path missing $text"
}
}
}
```
- [ ] **Step 5: Executor commit checkpoint**
Do not commit manually; the executor creates one feature commit and one metadata commit per completed step.
### Task 4: Create Final Verification Gate Steps
**Files:**
- Create: `phases/linear-static-3d-euler-beam/step25.md` through `step28.md`
**Interfaces:**
- Consumes: completed solver, generated HDF5 result, approved read-only reference CSVs, and all upstream reports.
- Produces: build/test, reference-verification, physics-evaluation, and release-readiness reports.
- [ ] **Step 1: Define strict gate transitions**
```text
25 pass-for-reference-verification
-> 26 pass-for-physics-evaluation
-> 27 pass-for-release-agent
-> 28 ready-for-release
```
Each later step must block or emit the appropriate `needs-*` status when its required predecessor is not passing. Step 26 applies the exact component-scale mixed tolerance, Step 27 checks physical equilibrium and signs, and Step 28 audits traceability and limitations without publishing anything.
- [ ] **Step 2: Enforce read-only boundaries**
Steps 2628 must not edit source, tests, CMake, upstream contracts, reference artifacts, or tolerance policy. Step 26 must state stress comparison is N/A while requiring the stress output schema/test evidence.
- [ ] **Step 3: Verify the final gate descriptors**
```powershell
25..28 | ForEach-Object {
$path = "phases/linear-static-3d-euler-beam/step$_.md"
if (-not (Test-Path $path)) { throw "Missing $path" }
foreach ($text in @('## Acceptance Criteria','reference')) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "$path missing $text"
}
}
}
```
- [ ] **Step 4: Executor commit checkpoint**
Do not commit manually; Harness owns execution commits and timestamps.
### Task 5: Validate the Generated Phase
**Files:**
- Read: `docs/superpowers/plans/2026-08-09-linear-static-3d-euler-beam-harness-phase.md`
- Read: `phases/index.json`
- Read: `phases/linear-static-3d-euler-beam/index.json`
- Read: `phases/linear-static-3d-euler-beam/step0.md` through `step28.md`
**Interfaces:**
- Consumes: all generated planning artifacts.
- Produces: structural and source-contract verification evidence; no solver execution.
- [ ] **Step 1: Parse and cross-check JSON**
```powershell
$top = Get-Content -Raw phases/index.json | ConvertFrom-Json
$task = Get-Content -Raw phases/linear-static-3d-euler-beam/index.json | ConvertFrom-Json
if (($top.phases | Where-Object dir -eq 'linear-static-3d-euler-beam').status -ne 'pending') { throw 'Top-level phase registration is invalid' }
if ($task.project -ne 'FESA Structural Solver') { throw 'Project name mismatch' }
if ($task.phase -ne 'linear-static-3d-euler-beam') { throw 'Phase name mismatch' }
if ($task.steps.Count -ne 29) { throw 'Step count mismatch' }
```
- [ ] **Step 2: Check step/file correspondence and required sections**
```powershell
$task.steps | ForEach-Object {
$path = "phases/linear-static-3d-euler-beam/step$($_.step).md"
if (-not (Test-Path $path)) { throw "Missing $path" }
if ($_.status -ne 'pending') { throw "Non-pending step $($_.step)" }
}
```
- [ ] **Step 3: Scan for placeholders and whitespace errors**
```powershell
$markers = @(('T' + 'BD'), ('T' + 'ODO'), ('FIX' + 'ME'), ('PLACE' + 'HOLDER'),
('implement' + ' later'), ('Similar' + ' to Task'))
$unfinished = rg -n ($markers -join '|') `
docs/superpowers/plans/2026-08-09-linear-static-3d-euler-beam-harness-phase.md `
phases/linear-static-3d-euler-beam
if ($LASTEXITCODE -eq 0) { throw "Unfinished marker found:`n$unfinished" }
git diff --check
```
Expected: no placeholder matches and no whitespace errors. CRLF conversion warnings without whitespace error lines are acceptable.
- [ ] **Step 4: Confirm reference artifacts are untouched**
```powershell
git diff --name-only -- reference/
```
Expected: no output.
- [ ] **Step 5: Execution handoff**
After the phase-construction files and existing documentation edits are reviewed and committed, execute from a clean worktree:
```powershell
python scripts/execute.py linear-static-3d-euler-beam
```
Use `--push` only when remote publication is explicitly desired.
+8
View File
@@ -0,0 +1,8 @@
{
"phases": [
{
"dir": "linear-static-3d-euler-beam",
"status": "pending"
}
]
}
@@ -0,0 +1,35 @@
{
"project": "FESA Structural Solver",
"phase": "linear-static-3d-euler-beam",
"steps": [
{ "step": 0, "name": "requirements-baseline", "status": "pending" },
{ "step": 1, "name": "research-evidence", "status": "pending" },
{ "step": 2, "name": "formulation-alignment", "status": "pending" },
{ "step": 3, "name": "numerical-review", "status": "pending" },
{ "step": 4, "name": "io-contract", "status": "pending" },
{ "step": 5, "name": "reference-model-contract", "status": "pending" },
{ "step": 6, "name": "implementation-plan", "status": "pending" },
{ "step": 7, "name": "cmake-test-foundation", "status": "pending" },
{ "step": 8, "name": "core-diagnostics", "status": "pending" },
{ "step": 9, "name": "dense-math-adapters", "status": "pending" },
{ "step": 10, "name": "domain-model", "status": "pending" },
{ "step": 11, "name": "inp-syntax-parser", "status": "pending" },
{ "step": 12, "name": "inp-domain-mapping", "status": "pending" },
{ "step": 13, "name": "analysis-model", "status": "pending" },
{ "step": 14, "name": "dof-manager", "status": "pending" },
{ "step": 15, "name": "analysis-state", "status": "pending" },
{ "step": 16, "name": "euler-beam-element", "status": "pending" },
{ "step": 17, "name": "parallel-for-tbb", "status": "pending" },
{ "step": 18, "name": "sparse-assembly", "status": "pending" },
{ "step": 19, "name": "essential-constraints", "status": "pending" },
{ "step": 20, "name": "mkl-pardiso-solver", "status": "pending" },
{ "step": 21, "name": "load-assembly", "status": "pending" },
{ "step": 22, "name": "result-recovery", "status": "pending" },
{ "step": 23, "name": "hdf5-results-writer", "status": "pending" },
{ "step": 24, "name": "linear-static-cli", "status": "pending" },
{ "step": 25, "name": "build-test-verification", "status": "pending" },
{ "step": 26, "name": "reference-verification", "status": "pending" },
{ "step": 27, "name": "physics-sanity", "status": "pending" },
{ "step": 28, "name": "release-readiness", "status": "pending" }
]
}
+101
View File
@@ -0,0 +1,101 @@
# Step 0: Requirements Baseline
## 담당 역할과 필수 스킬
- 담당 역할: `requirement-agent`
- 필수 스킬: `fesa-requirements-baseline`
- 작업을 시작하기 전에 위 스킬의 `SKILL.md`를 끝까지 읽고 경계를 준수하라.
## 읽어야 할 파일
먼저 아래 파일을 읽고 승인된 범위와 프로젝트 규칙을 파악하라.
- `/AGENTS.md`
- `/docs/PRD.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/SOLVER_AGENT_DESIGN.md`
- `/docs/requirements/README.md`
- `/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/reference/cantilever beam/cantilever beam.inp`
승인된 설계 문서의 `status: approved`와 2026-08-09 amendment를 이 step의 사용자 승인
근거로 사용한다.
## 작업
`docs/requirements/linear-static-3d-euler-beam.md`를 생성하라. 문서는 다음 계약을
downstream agent가 추측 없이 사용할 수 있는 `shall` 요구조건과 검증 행렬로 바꿔야 한다.
- Metadata: `feature_id: linear-static-3d-euler-beam`, `status: approved`,
`owner_agent: requirement-agent`, 현재 날짜, 승인된 설계 경로를 기록한다.
- 목적, In Scope, Out Of Scope, Analysis Definition, Input Requirements, Output
Requirements, Verification Quantities, Tolerance Policy, Reference Artifact
Requirements, Requirement Verification Matrix, Downstream Handoff를 포함한다.
- 한 입력당 단일 `*STEP, *STATIC`, 2절점 3D EulerBernoulli, node당 6 DOF,
`TYPE=B33`만 지원하고 B31은 오류로 거부하는 요구조건을 분리한다.
- `*PART/*ASSEMBLY/*INSTANCE` identity wrapper, stable source identity, 여러 identity
instance 허용, transform/nested assembly 거부를 요구조건으로 만든다.
- 지원 keyword와 warning no-op allowlist를 정확히 열거하고 allowlist 밖 model-affecting
keyword는 오류로 요구한다.
- factorization-before-load 순서, nonzero prescribed displacement, deterministic
COO-to-CSR, MKL/TBB/HDF5 adapter 경계, CLI exit code, HDF5 schema/output을 요구한다.
- B33 legacy reference bundle은 read-only이며 exact filename을 보존하고 stress reference
comparison은 N/A지만 `S11` output과 test는 필수임을 명시한다.
- reference tolerance는 같은 model/step/frame/quantity/component의 read-only Abaqus
scale만 사용해 `absolute_floor + 1e-6 * reference_scale`을 모든 row에 적용한다.
SI floor는 displacement/rotation `1e-9`, force/moment `1e-3`이다.
- 모든 `must` 요구조건에 acceptance criterion, verification method, tolerance 또는 N/A,
downstream agent, status를 매핑한다. 숫자 ID는
`FESA-REQ-LS3DEB-001`부터 중복 없이 연속 부여한다.
설계가 이미 승인했으므로 새 정책 결정을 만들지 말고, 충돌을 발견하면 문서를 승인
상태로 꾸미지 말고 phase step을 `blocked`로 기록하라.
## Acceptance Criteria
```powershell
$path = 'docs/requirements/linear-static-3d-euler-beam.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @(
'feature_id: `linear-static-3d-euler-beam`',
'status: `approved`',
'## In Scope',
'## Out Of Scope',
'## Requirement Verification Matrix',
'TYPE=B33',
'TYPE=B31',
'absolute_floor + 1e-6 * reference_scale',
'reference/cantilever beam/'
)
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing contract text: $text"
}
}
$ids = Select-String -LiteralPath $path -Pattern 'FESA-REQ-LS3DEB-\d{3}' -AllMatches |
ForEach-Object { $_.Matches.Value }
if (($ids | Sort-Object -Unique).Count -lt 1) { throw 'No requirement ids found' }
git diff --check -- $path
```
## 검증 절차
1. Acceptance Criteria 명령을 실행한다.
2. 설계 문서 2절, 6절, 9절, 10절, 11절, 12절의 각 필수 계약이 최소 한 요구조건과
verification matrix row에 추적되는지 점검한다.
3. 수치값, 단위, 좌표계, artifact path가 설계와 정확히 일치하는지 확인한다.
4. `/phases/linear-static-3d-euler-beam/index.json`의 Step 0을 갱신한다.
- 성공: `status``completed`로 바꾸고 생성 파일과 승인 baseline을 `summary` 한 줄에 기록한다.
- 수정 3회 후 실패: `status: error``error_message`를 기록한다.
- 승인 설계와 프로젝트 문서가 충돌해 사용자 결정이 필요하면 `status: blocked`
`blocked_reason`을 기록하고 중단한다.
## 금지사항
- C++ API나 파일 구조를 설계하지 마라. 이유: Requirement Agent의 책임 범위를 넘는다.
- formulation 수식을 수정하지 마라. 이유: 수학 계약은 후속 gate가 담당한다.
- Abaqus 또는 reference solver를 실행하지 마라. 이유: 승인된 read-only artifact만 사용한다.
- `/reference/` 파일을 생성·수정·rename하지 마라. 이유: correctness baseline을 오염시킨다.
- 직접 commit하지 마라. 이유: Harness executor가 commit과 timestamp를 관리한다.
@@ -0,0 +1,80 @@
# Step 1: Research Evidence
## 담당 역할과 필수 스킬
- 담당 역할: `research-agent`
- 필수 스킬: `fesa-research-evidence`, `fem-theory-query`
- 두 스킬의 `SKILL.md`를 끝까지 읽고, FEM wiki query를 우선 사용하라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/SOLVER_AGENT_DESIGN.md`
- `/docs/research/README.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
Step 0 산출물과 phase index의 완료 summary를 확인한 뒤 작업하라.
## 작업
FEM wiki에서 다음 연구 질문을 query하고
`docs/research/linear-static-3d-euler-beam-research.md`를 생성하라.
- Abaqus B31과 B33의 formulation 차이 및 B33을 EulerBernoulli 의미로 사용하는 근거
- 2절점 spatial Euler beam의 cubic Hermite interpolation, 6 rigid modes, rank 6,
two-point Gauss exactness, local/global transformation과 end-force sign
- Abaqus general beam section의 `A, I11, I12, I22, J`, first axis `n1`, section
resultant `SF*`/`SM*`, axial `S11` 의미
- analytical cantilever axial/torsion/two-plane bending benchmark와 검증 가능한 물리량
- PARDISO SPD factorization, deterministic sparse assembly, reference comparison에 필요한
기술 근거와 적용 한계
문서는 Metadata(`status: ready-for-formulation`), Research Questions, Source Inventory,
Extracted Facts, Candidate Benchmarks, Verification Relevance, Applicability Limits,
Open Issues, Downstream Handoff를 포함해야 한다. Source Inventory에는 문서명, 제공 기관,
wiki page identity, 원 출처/매뉴얼 identity, reliability tier와 적용 범위를 기록한다.
확인된 사실과 설계에서 도출한 inference를 구분한다. 기존 정식화 식을 최종 승인하거나
새 tolerance를 만들지 않는다.
## Acceptance Criteria
```powershell
$path = 'docs/research/linear-static-3d-euler-beam-research.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @(
'status: `ready-for-formulation`',
'## Research Questions',
'## Source Inventory',
'## Extracted Facts',
'## Candidate Benchmarks',
'## Applicability Limits',
'B31',
'B33',
'Hermite',
'general beam section'
)
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing research evidence: $text"
}
}
git diff --check -- $path
```
## 검증 절차
1. Acceptance Criteria 명령을 실행한다.
2. 주요 claim마다 source tier 또는 inference 표시가 있는지 확인한다.
3. benchmark마다 target quantity와 검증할 수 없는 범위를 함께 기록했는지 확인한다.
4. Step 1을 `completed`와 한 줄 `summary`로 갱신한다. 반복 실패는 `error`, 실제 source
부재나 상충으로 사용자 판단이 필요하면 `blocked`로 기록한다.
## 금지사항
- 웹 검색 결과나 LLM 기억만을 source로 쓰지 마라. 이유: 사용자가 FEM wiki manual을 허용했다.
- formulation을 최종화하거나 C++ API를 설계하지 마라. 이유: downstream 책임이다.
- tolerance나 reference 값을 발명하지 마라. 이유: 승인 설계 값을 그대로 사용해야 한다.
- Abaqus 실행 및 `/reference/` 변경을 하지 마라. 이유: artifact는 read-only다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,102 @@
# Step 10: Domain Model
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/core/source_identity.hpp`
- `/include/fesa/core/status.hpp`
- `/src/fesa/CMakeLists.txt`
- `/tests/CMakeLists.txt`
## 소유 파일
- Create: `/include/fesa/model/model_types.hpp`
- Create: `/include/fesa/model/domain.hpp`
- Create: `/src/fesa/model/domain.cpp`
- Create: `/tests/unit/model/model_types_test.cpp`
- Create: `/tests/unit/model/domain_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
parser와 analysis가 공유할 immutable semantic model을 위 exact paths에 구현하라.
최소 model types는 다음을 포함한다.
```cpp
using EntityIndex = std::uint32_t;
struct Node { SourceEntityId sourceId; std::array<double, 3> coordinates; };
struct LinearElasticMaterial { std::string name; double youngsModulus; double poissonRatio; };
struct GeneralBeamSection {
std::string name; double area; double i11; double i12; double i22; double torsionalConstant;
std::array<double, 3> firstAxis; std::vector<std::array<double, 2>> sectionPoints;
};
struct EulerBeam3DDefinition {
SourceEntityId sourceId; std::array<EntityIndex, 2> nodeIndices;
EntityIndex materialIndex; EntityIndex sectionIndex;
};
struct BoundaryCondition { std::string target; int firstDof; int lastDof; double value; };
struct NodalLoad { std::string target; int dof; double magnitude; };
struct StaticStepDefinition { std::string name; std::vector<BoundaryCondition> boundaries;
std::vector<NodalLoad> loads; };
```
`PartDefinition``InstanceDefinition`은 source name, referenced part, identity-instance
restriction과 source-to-internal mapping을 보존한다. `NodeSet`, `ElementSet`,
part/instance/source label mapping을 포함한다. `Domain`은 vectors와
stable lookup을 소유하고 construction 완료 후 const access만 제공한다. 필요한 builder는
construction 경계에만 두고 Domain을 복사하지 않아도 view를 만들 수 있는 stable index를
보장한다. Node/element에는 equation ID를 저장하지 않는다.
Tests는 source identity equality/order, same-part multiple-instance distinction, stable
insertion order/index, deep ownership, const access, one static step storage, equation-ID 부재를
검증하고 `DomainModel` regex로 등록한다.
## Acceptance Criteria
RED targeted command 후 최소 구현으로 GREEN을 만든다.
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R DomainModel --output-on-failure
```
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R DomainModel --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. Domain tests를 먼저 추가하고 compile/test RED를 확인한다.
2. 최소 semantic types와 immutable Domain ownership으로 GREEN을 만든다.
3. full VERIFY와 public dependency direction을 확인한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 10 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 10을 `completed`로 갱신하고 model types/stable identity를 summary에 기록한다.
## 금지사항
- Abaqus keyword string을 Domain의 핵심 의미로 저장하지 마라. 이유: syntax/model 경계를 깨뜨린다.
- Domain에 equation numbering이나 mutable analysis vector를 넣지 마라. 이유: DofManager/AnalysisState 책임이다.
- parser를 이 step에서 구현하지 마라. 이유: Step 11–12 범위다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,102 @@
# Step 11: Abaqus INP Syntax Parser
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/core/diagnostic.hpp`
- `/include/fesa/core/status.hpp`
- `/src/fesa/CMakeLists.txt`
- `/tests/CMakeLists.txt`
- `/reference/cantilever beam/cantilever beam.inp`
## 소유 파일
- Create: `/include/fesa/io/abaqus/input_syntax.hpp`
- Create: `/include/fesa/io/abaqus/input_reader.hpp`
- Create: `/src/fesa/io/abaqus/input_reader.cpp`
- Create: `/tests/unit/io/abaqus/input_syntax_test.cpp`
- Create: `/tests/unit/io/abaqus/input_reader_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
keyword/data/comment lexical 및 syntax parsing만 위 exact paths에 구현하라. Semantic
Domain mapping은 Step 12에 남긴다. 최소 계약은 다음과 같다.
```cpp
struct KeywordParameter { std::string name; std::optional<std::string> value; };
struct DataLine { std::vector<std::string> fields; SourceLocation location; };
struct KeywordBlock {
std::string canonicalName;
std::string originalLine;
std::vector<KeywordParameter> parameters;
std::vector<DataLine> data;
SourceLocation location;
};
struct ParsedInput { std::vector<KeywordBlock> blocks; };
class AbaqusInputReader {
public:
Result<ParsedInput> read(const std::filesystem::path& inputPath) const;
};
```
Keyword와 parameter name은 uppercase canonical form으로 비교하되 parameter value와
data label 원문을 보존한다. `**` comment line은 무시하고 blank line, comma-separated
field, valueless parameter, line number와 file identity를 처리한다. Keyword/data 구분,
malformed keyword, keyword 전 data line, unreadable file은 structured diagnostic으로
반환한다. Wrapper 의미, keyword allowlist, numeric conversion은 구현하지 않는다.
Tests는 mixed case, comments, blank/empty trailing fields, parameters, source locations,
malformed syntax, legacy cantilever syntax parse를 포함하고 `InpSyntax` regex로 등록한다.
## Acceptance Criteria
RED targeted command:
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R InpSyntax --output-on-failure
```
GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R InpSyntax --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. syntax tests를 먼저 추가하고 reader 부재 RED를 확인한다.
2. semantic 판단이 없는 최소 reader로 GREEN을 만든다.
3. legacy input을 read-only fixture로 읽고 전체 VERIFY를 수행한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 11 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 11을 `completed`로 갱신하고 parsed syntax/source-location evidence를 summary에 기록한다.
## 금지사항
- B33/B31 또는 supported keyword 정책을 syntax reader에 넣지 마라. 이유: semantic mapper 책임이다.
- source label/value case를 canonicalize하지 마라. 이유: stable source identity를 보존해야 한다.
- `*INCLUDE` 같은 미승인 기능을 추가하지 마라. 이유: scope 밖이다.
- reference input을 수정하지 마라. 이유: read-only fixture다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,117 @@
# Step 12: INP to Domain Mapping
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/model/model_types.hpp`
- `/include/fesa/model/domain.hpp`
- `/src/fesa/model/domain.cpp`
- `/tests/unit/model/domain_test.cpp`
- `/include/fesa/io/abaqus/input_syntax.hpp`
- `/include/fesa/io/abaqus/input_reader.hpp`
- `/src/fesa/io/abaqus/input_reader.cpp`
- `/tests/unit/io/abaqus/input_reader_test.cpp`
- `/reference/cantilever beam/cantilever beam.inp`
## 소유 파일
- Create: `/include/fesa/io/abaqus/domain_mapper.hpp`
- Create: `/src/fesa/io/abaqus/domain_mapper.cpp`
- Create: `/tests/unit/io/abaqus/domain_mapper_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
ParsedInput을 검증된 immutable Domain으로 바꾸는 semantic mapper를 구현하라.
```cpp
class AbaqusDomainMapper {
public:
Result<Domain> map(const ParsedInput& input) const;
};
```
지원 범위는 승인 I/O contract와 정확히 같아야 한다.
- `*HEADING`, `*PART`/`*END PART`, `*NODE`, `*ELEMENT, TYPE=B33`,
`*NSET`/`*ELSET``GENERATE`, `*MATERIAL`/`*ELASTIC`,
`*BEAM GENERAL SECTION, SECTION=GENERAL`, `*SECTION POINTS`,
`*ASSEMBLY`/`*END ASSEMBLY`, `*INSTANCE`/`*END INSTANCE`,
`*BOUNDARY`, `*CLOAD`, `*STEP`/`*STATIC`/`*END STEP`를 mapping한다.
- 같은 part의 여러 identity instance를 deterministic stable internal IDs로 expand하고
`SourceEntityId {instance_name, source_label}`를 보존한다.
- assembly set의 `INSTANCE` parameter와 node/set target을 해석한다.
- `A,I11,I12,I22,J`, `E,nu`, `G=E/(2*(1+nu))`, `Iy=I11`, `Iz=I22`,
`n1 -> local y`를 mapping한다. `E>0`, `-1<nu<0.5`, 계산한 `G>0`과 section
properties의 positivity를 검증한다.
- `*STEP``NLGEOM`은 absent/`NO`만 accept하고 `YES`는 model diagnostic으로 거부한다.
`*STATIC`의 1개 또는 24개 time-control data field를 finite positive 값으로 읽되 V0는
하나의 final frame 0만 만든다. Step 앞의 model-level `*BOUNDARY`는 sole static step에
활성화하고 step 안 `*CLOAD`와 함께 `StaticStepDefinition`에 연결한다.
- B31은 `unsupported-element-formulation`, instance translation/rotation data는
`unsupported-instance-transform` diagnostic으로 거부한다. Second step, nested assembly,
`I12!=0`, invalid DOF, duplicate label, dangling target/reference, nonpositive properties,
invalid geometry에도 설계/I/O contract가 정한 structured diagnostic code를 반환한다.
- `*PREPRINT`, `*RESTART`, `*TRANSVERSE SHEAR STIFFNESS`, `*OUTPUT, FIELD`,
`*OUTPUT, HISTORY`, `*NODE OUTPUT`, `*ELEMENT OUTPUT`, `*CONTACT OUTPUT`와 그
output-variable data는 warning으로 보존하고 무시한다. 이 allowlist 밖 unknown keyword는
error다. FESA default outputs를 output request로 필터링하지 않는다.
Tests는 모든 supported keyword의 positive path, mixed case, Generate, multiple identity
instances, allowlist warning, unknown keyword, B31 rejection, transform/nested/multi-step,
duplicate/dangling/invalid numeric와 approved legacy input mapping을 포함하고
`InpDomainMapping` regex로 등록한다.
## Acceptance Criteria
RED targeted command:
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R InpDomainMapping --output-on-failure
```
GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R InpDomainMapping --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. semantic positive/negative tests를 production mapper보다 먼저 작성하고 RED를 확인한다.
2. 승인 subset에 필요한 최소 mapping/validation만 구현해 GREEN을 만든다.
3. diagnostic field/order와 Domain non-mutation을 점검하고 전체 VERIFY를 수행한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 12 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 12를 `completed`로 갱신하고 supported mapping/negative diagnostics를 summary에 기록한다.
## 금지사항
- B31을 Euler element로 alias하지 마라. 이유: 물리 formulation 의미가 다르다.
- transform을 무시하거나 fallback local axis를 선택하지 마라. 이유: 입력 의미를 왜곡한다.
- `*DLOAD` 또는 multiple-step propagation을 구현하지 마라. 이유: 승인 범위 밖이다.
- reference input/CSV를 수정하지 마라. 이유: read-only baseline이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,97 @@
# Step 13: AnalysisModel Active View
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/model/model_types.hpp`
- `/include/fesa/model/domain.hpp`
- `/src/fesa/model/domain.cpp`
- `/include/fesa/io/abaqus/domain_mapper.hpp`
- `/src/fesa/io/abaqus/domain_mapper.cpp`
- `/tests/unit/io/abaqus/domain_mapper_test.cpp`
- `/src/fesa/CMakeLists.txt`
- `/tests/CMakeLists.txt`
## 소유 파일
- Create: `/include/fesa/analysis/analysis_model.hpp`
- Create: `/src/fesa/analysis/analysis_model.cpp`
- Create: `/tests/unit/analysis/analysis_model_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
단일 static step에서 활성 entity를 stable index/reference view로 분류하는
`AnalysisModel`만 구현하라.
```cpp
class AnalysisModel {
public:
static Result<AnalysisModel> create(const Domain& domain);
const Domain& domain() const noexcept;
const StaticStepDefinition& step() const noexcept;
const std::vector<EntityIndex>& activeElements() const noexcept;
const std::vector<EntityIndex>& activeMaterials() const noexcept;
const std::vector<EntityIndex>& activeSections() const noexcept;
const std::vector<EntityIndex>& activeBoundaryConditions() const noexcept;
const std::vector<EntityIndex>& activeLoads() const noexcept;
};
```
AnalysisModel은 Domain 객체나 semantic entity를 복사·수정하지 않고, 자체 소유가 필요한
경우 stable ID 목록만 가진다. Element에서 reachable material/section을 deterministic한
internal index 순으로 deduplicate한다. 정확히 하나의 static step만 허용하며 missing 또는
multiple step은 structured diagnostic이다.
Tests는 active classification, stable ordering/deduplication, reference address identity,
Domain 불변성, missing/multiple step rejection을 포함하고 `AnalysisModel` regex로 등록한다.
## Acceptance Criteria
RED targeted command:
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R AnalysisModel --output-on-failure
```
GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R AnalysisModel --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. active-view tests를 먼저 작성하고 missing class/behavior RED를 확인한다.
2. stable ID view의 최소 구현으로 GREEN을 만든다.
3. Domain address/state 불변성과 전체 MSVC x64 Debug VERIFY를 확인한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 13 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 13을 `completed`로 바꾸고 active view/non-copy evidence를 summary에 기록한다.
## 금지사항
- Domain entity를 AnalysisModel에 복제하지 마라. 이유: source of truth가 분산된다.
- load/BC propagation이나 multi-step activation을 추가하지 마라. 이유: V0는 single step이다.
- equation number나 numeric state를 저장하지 마라. 이유: DofManager/AnalysisState 책임이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,104 @@
# Step 14: DofManager
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/model/domain.hpp`
- `/include/fesa/analysis/analysis_model.hpp`
- `/src/fesa/analysis/analysis_model.cpp`
- `/tests/unit/analysis/analysis_model_test.cpp`
- `/src/fesa/CMakeLists.txt`
- `/tests/CMakeLists.txt`
## 소유 파일
- Create: `/include/fesa/fem/dof_manager.hpp`
- Create: `/src/fesa/fem/dof_manager.cpp`
- Create: `/tests/unit/fem/dof_manager_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
node별 여섯 DOF, prescribed constraints, full/free numbering, element scatter map와 sparse
pattern을 단독 소유하는 `DofManager`를 구현하라.
```cpp
enum class DofComponent : std::uint8_t { ux, uy, uz, urx, ury, urz };
struct SparsePattern { std::vector<std::size_t> rowOffsets;
std::vector<std::size_t> columnIndices; };
class DofManager {
public:
static Result<DofManager> create(const AnalysisModel& model);
std::size_t fullDofCount() const noexcept;
std::size_t freeDofCount() const noexcept;
std::size_t constrainedDofCount() const noexcept;
std::size_t fullDof(EntityIndex node, DofComponent component) const;
std::optional<std::size_t> freeEquation(std::size_t fullDof) const;
const std::array<std::size_t, 12>& elementScatter(EntityIndex element) const;
const std::vector<std::size_t>& freeDofs() const noexcept;
const std::vector<std::size_t>& constrainedDofs() const noexcept;
const Vector& prescribedValues() const noexcept;
const SparsePattern& sparsePattern() const noexcept;
};
```
Node internal index와 fixed component 순서로 full DOF를 부여하고, free/constrained mapping도
stable하게 만든다. Boundary target expansion과 overlapping equal prescriptions를 처리하고,
서로 다른 prescribed value conflict는 diagnostic으로 거부한다. Sparse pattern은 active
element scatter에서 생성하고 각 row column을 sorted unique로 유지한다. Node/Element model
objects를 수정하지 않는다. `prescribedValues()``constrainedDofCount()` 크기이며
`constrainedDofs()`와 동일 순서의 `dc`를 반환한다.
Tests는 6-DOF numbering, set expansion, zero/nonzero constraints, overlapping/conflicting BC,
free equation mapping, 12-DOF element scatter, CSR pattern sorted uniqueness, full/reduced
round-trip를 포함하고 `DofManager` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R DofManager --output-on-failure
```
위 command의 RED를 확인한 뒤 구현하고 다음 GREEN/VERIFY를 실행한다.
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R DofManager --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. numbering/constraint/pattern tests를 먼저 작성하고 RED를 확인한다.
2. deterministic mapping에 필요한 최소 구현으로 GREEN을 만든다.
3. model objects에 equation ID가 추가되지 않았는지 review하고 full VERIFY를 수행한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 14 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 14를 `completed`로 갱신하고 numbering/pattern evidence를 summary에 기록한다.
## 금지사항
- equation ID를 Node나 Element에 저장하지 마라. 이유: DofManager 단독 ownership 계약이다.
- penalty method, MPC, RBE를 추가하지 마라. 이유: V0 essential elimination 범위 밖이다.
- sparse numeric values를 저장하지 마라. 이유: assembly step 책임이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,103 @@
# Step 15: AnalysisState
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/math/vector.hpp`
- `/include/fesa/analysis/analysis_model.hpp`
- `/include/fesa/fem/dof_manager.hpp`
- `/src/fesa/fem/dof_manager.cpp`
## 소유 파일
- Create: `/include/fesa/results/result_records.hpp`
- Create: `/include/fesa/analysis/analysis_state.hpp`
- Create: `/src/fesa/analysis/analysis_state.cpp`
- Create: `/tests/unit/results/result_records_test.cpp`
- Create: `/tests/unit/analysis/analysis_state_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
V0에서 실제 할당하는 mutable analysis quantities와 output row identity를 소유하는
`AnalysisState`를 위 exact paths에 구현하라. 최소 계약은 다음 의미를 가진다.
```cpp
struct StepFrameIdentity { std::string stepName; std::size_t frameIndex; };
struct EndpointResultRow { EntityIndex element; int endpoint; SourceEntityId node;
std::array<double, 6> endAction;
std::array<double, 4> sectionResultant; };
struct GaussResultRow { EntityIndex element; int gaussPoint;
std::array<double, 4> generalizedStrain;
std::array<double, 4> generalizedResultant; };
struct StressS11Row { EntityIndex element; int gaussPoint; std::size_t sectionPoint;
double x1; double x2; double s11; std::string source; };
class AnalysisState {
public:
static AnalysisState create(const DofManager& dofs, StepFrameIdentity identity);
Vector& displacement() noexcept;
Vector& externalForce() noexcept;
Vector& internalForce() noexcept;
Vector& residual() noexcept;
Vector& reaction() noexcept;
// const overloads and owned element-recovery row accessors
};
```
각 full vector 크기는 `fullDofCount()`이고 zero-initialized다. Reaction은 constrained value를
동일 full-index space에 두며 free component는 residual sanity에 사용할 수 있어야 한다.
Endpoint/Gauss/stress row는 stable element/point order로 저장한다. Velocity, acceleration,
temperature, iteration history, nonlinear state storage를 만들지 않는다.
Tests는 allocation/zero initialization, independent ownership, step/frame identity, row ordering,
copy/move policy, forbidden-state API 부재 review를 포함하고 `AnalysisState` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R AnalysisState --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R AnalysisState --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. state ownership tests를 먼저 작성하고 RED를 확인한다.
2. V0에서 필요한 field만 최소 구현해 GREEN을 만든다.
3. 전체 VERIFY와 output row identity/order를 확인한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 15 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 15를 `completed`로 갱신하고 allocated fields/omitted fields를 summary에 기록한다.
## 금지사항
- velocity, acceleration, temperature, nonlinear iteration history를 할당하지 마라. 이유: V0 범위 밖이다.
- Domain 정의를 state에 복사하지 마라. 이유: model/state ownership을 분리해야 한다.
- HDF5 API를 state에 노출하지 마라. 이유: ResultsWriter adapter 책임이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,113 @@
# Step 16: 3D Euler Beam Element
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/numerical-reviews/linear-static-3d-euler-beam-review.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/math/vector.hpp`
- `/include/fesa/math/matrix.hpp`
- `/include/fesa/model/model_types.hpp`
- `/include/fesa/results/result_records.hpp`
- `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
## 소유 파일
- Create: `/include/fesa/elements/euler_beam_3d.hpp`
- Create: `/src/fesa/elements/euler_beam_3d.cpp`
- Create: `/tests/unit/elements/euler_beam_3d_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
승인 formulation을 그대로 구현하는 2-node `EulerBeam3D` kernel을 작성하라.
```cpp
struct ConstantLocalLineLoad { double px; double py; double pz; double mx; };
struct BeamStressPoint { int gaussPoint; std::size_t sectionPoint; double x1; double x2;
double s11; std::string source; };
struct BeamRecovery {
std::array<std::array<double, 6>, 2> equilibriumEndActions;
std::array<std::array<double, 4>, 2> endpointSectionResultants;
std::array<std::array<double, 4>, 2> gaussGeneralizedStrains;
std::array<std::array<double, 4>, 2> gaussGeneralizedResultants;
std::vector<BeamStressPoint> stressPoints;
};
class EulerBeam3D {
public:
static Result<EulerBeam3D> create(/* two nodes, guide, E, G, A, Iy, Iz, J, section points */);
Matrix localStiffness() const;
Matrix globalStiffness() const;
Vector localEquivalentLoad(const ConstantLocalLineLoad& load) const;
BeamRecovery recover(const Vector& globalElementDisplacement) const;
};
```
- Local DOF order와 부호는 formulation의 12-component order를 그대로 쓴다.
- `R` rows는 `(ex,ey,ez)`, `T=diag(R,R,R,R)`, `dl=T*dg`, `Kg=T^T*Kl*T`다.
- `Kl`은 두 Gauss point로 `B^T D B`를 적분하고 closed-form과 normalized `1e-12`
검증한다. Production에서 1-point reduced integration을 사용하지 않는다.
- `coordinate_scale=max(1,norm(X1),norm(X2))`에 대해
`L>1e-12*coordinate_scale`, `norm(a_perp)>1e-12*max(1,norm(a))`를 요구한다.
`E,G,A,Iy,Iz,J>0`을 검증하고 fallback axis를 쓰지 않는다.
- line-load kernel은 constant `[px,py,pz,mx]` consistent vector만 제공한다. Parser/CLI load
object로 연결하지 않는다.
- Recovery는 equilibrium end action과 section resultants를 구분하고 two Gauss generalized
values 및 section point `S11=E(epsilon0+x2*kappa_y-x1*kappa_z)`를 생성한다. Element
identity가 없는 kernel-level `BeamStressPoint`를 Step 22가 `StressS11Row`로 감싼다.
Section point가 없으면 `(0,0), source=fesa-default` 하나를 사용한다.
Tests는 Hermite endpoint/derivative, B matrix, Gauss/closed stiffness, symmetry, six rigid
modes/rank 6, positive deformation energy, transform orthogonality/determinant/energy invariance,
line-load signs, axial/torsion/y-z bending analytical displacement/recovery, invalid geometry와
stress formula를 포함하고 `EulerBeam3D` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R EulerBeam3D --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R EulerBeam3D --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. formulation invariant/analytical tests를 먼저 작성해 RED를 확인한다.
2. 가장 작은 kernel 구현으로 GREEN을 만들고 normalized tolerance를 그대로 적용한다.
3. 수식/코드 component ordering을 대조하고 전체 MSVC x64 Debug VERIFY를 수행한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 16 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 16을 `completed`로 갱신하고 element/recovery test evidence를 summary에 기록한다.
## 금지사항
- B31/Timoshenko shear deformation을 섞지 마라. 이유: 승인 formulation이 아니다.
- 1-point bending integration이나 fallback orientation을 쓰지 마라. 이유: spurious mode/의미 왜곡 위험이다.
- transverse/torsional shear stress를 만들어내지 마라. 이유: section 정보가 부족하고 범위 밖이다.
- `*DLOAD` parser/CLI 지원을 추가하지 마라. 이유: kernel test만 승인됐다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,96 @@
# Step 17: oneTBB ParallelFor Adapter
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/core/status.hpp`
- `/include/fesa/elements/euler_beam_3d.hpp`
- `/src/fesa/elements/euler_beam_3d.cpp`
- `/tests/unit/elements/euler_beam_3d_test.cpp`
- `/cmake/FesaDependencies.cmake`
- `/src/fesa/CMakeLists.txt`
- `/tests/CMakeLists.txt`
## 소유 파일
- Create: `/include/fesa/assembly/parallel_for.hpp`
- Create: `/src/fesa/assembly/parallel_for.cpp`
- Create: `/tests/unit/assembly/parallel_for_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
solver core에서 oneTBB header/type을 숨기는 element-local loop adapter를 구현하라.
```cpp
class ParallelFor {
public:
virtual ~ParallelFor() = default;
virtual void execute(std::size_t count,
const std::function<void(std::size_t)>& body) const = 0;
};
class SerialParallelFor final : public ParallelFor { /* same contract */ };
class TbbParallelFor final : public ParallelFor { /* oneTBB implementation in .cpp */ };
```
각 index는 정확히 한 번 처리하고 `count==0`은 no-op이다. Element-local 결과는 호출자가
index-addressed storage에 기록해 scheduling과 무관한 ordering을 갖게 한다. Adapter는
전역 sparse matrix write나 reduction을 수행하지 않는다. Oversubscription 정책은
implementation comment와 test/implementation report에 남기고, 이 step에서 임의 global
thread setting을 바꾸지 않는다.
Tests는 zero/one/many counts, exact-once, serial/TBB semantic equivalence, stable
index-addressed output, exception propagation policy를 검증하고 `ParallelFor` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R ParallelFor --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R ParallelFor --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
$leaks = rg -n "oneapi/tbb|tbb/" include/fesa
if ($LASTEXITCODE -eq 0) { throw "oneTBB API leaked into public headers:`n$leaks" }
if ($LASTEXITCODE -ne 1) { throw 'Public-header dependency scan failed' }
```
마지막 scan은 public header에서 no-match여야 한다.
## 검증 절차
1. adapter conformance tests를 먼저 작성하고 RED를 확인한다.
2. Serial과 oneTBB 최소 구현으로 GREEN을 만든다.
3. public boundary scan과 전체 VERIFY를 실행한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 17 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 17을 `completed`로 갱신하고 deterministic-use contract를 summary에 기록한다.
## 금지사항
- 전역 sparse storage에 병렬 write하지 마라. 이유: ordering/race는 Step 18이 통제한다.
- TBB type/header를 public API에 노출하지 마라. 이유: adapter boundary 계약이다.
- process-wide thread count를 임의 변경하지 마라. 이유: MKL/TBB policy가 불명확해진다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,109 @@
# Step 18: Deterministic Sparse Assembly
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/math/vector.hpp`
- `/include/fesa/math/matrix.hpp`
- `/include/fesa/fem/dof_manager.hpp`
- `/include/fesa/elements/euler_beam_3d.hpp`
- `/include/fesa/assembly/parallel_for.hpp`
- `/src/fesa/assembly/parallel_for.cpp`
## 소유 파일
- Create: `/include/fesa/math/sparse_matrix.hpp`
- Create: `/src/fesa/math/sparse_matrix.cpp`
- Create: `/include/fesa/assembly/sparse_assembler.hpp`
- Create: `/src/fesa/assembly/sparse_assembler.cpp`
- Create: `/tests/unit/math/sparse_matrix_test.cpp`
- Create: `/tests/unit/assembly/sparse_assembler_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
element-local stiffness contributions를 deterministic하게 COO로 수집하고 0-based CSR로
finalize하는 별도 sparse module을 구현하라.
```cpp
struct CooContribution {
std::size_t row;
std::size_t column;
double value;
std::size_t elementOrder;
std::size_t localOrder;
};
class SparseMatrix {
public:
static Result<SparseMatrix> fromCoo(std::size_t rows, std::size_t columns,
std::vector<CooContribution> contributions,
const SparsePattern& expectedPattern);
std::size_t rows() const noexcept;
std::size_t columns() const noexcept;
const std::vector<std::size_t>& rowOffsets() const noexcept;
const std::vector<std::size_t>& columnIndices() const noexcept;
const std::vector<double>& values() const noexcept;
Vector multiply(const Vector& rhs) const;
Status validate() const;
};
```
`SparseMatrix``Matrix`를 상속하지 않는다. COO는 `(row,column,elementOrder,localOrder)`
stable sort한 후 duplicate를 고정 순서로 합산한다. Zero value 보존/제거 policy는
implementation plan과 I/O-independent math contract에 맞춰 하나로 고정하고 test한다.
Row offsets/column indices는 0-based, columns sorted unique, sizes/ranges consistent해야 한다.
Element stiffness 계산은 ParallelFor로 index-addressed buffer에 넣고 global reduction은
element internal index 순서로 수행한다.
Tests는 known matrix CSR/matrix-vector product, duplicate sum, invalid index/pattern, empty row, symmetry,
serial-vs-TBB byte-identical row/column/value vectors, repeated runs를 포함하고
`SparseAssembly` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R SparseAssembly --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R SparseAssembly --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. CSR invariant/determinism tests를 먼저 작성하고 RED를 확인한다.
2. ordered COO reduction과 CSR ownership의 최소 구현으로 GREEN을 만든다.
3. repeated serial/TBB equivalence와 전체 VERIFY를 수행한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 18 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 18을 `completed`로 갱신하고 CSR/determinism evidence를 summary에 기록한다.
## 금지사항
- `SparseMatrix`를 dense `Matrix`에서 상속하지 마라. 이유: storage/backend 의미가 다르다.
- TBB worker가 shared CSR value에 직접 쓰게 하지 마라. 이유: race와 nondeterminism이 생긴다.
- PARDISO-specific descriptor/index type을 public sparse API에 넣지 마라. 이유: Step 20 adapter 책임이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,99 @@
# Step 19: Essential Constraints and Matrix Partition
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/math/vector.hpp`
- `/include/fesa/math/sparse_matrix.hpp`
- `/include/fesa/fem/dof_manager.hpp`
- `/include/fesa/assembly/sparse_assembler.hpp`
- `/src/fesa/assembly/sparse_assembler.cpp`
## 소유 파일
- Create: `/include/fesa/constraints/essential_constraints.hpp`
- Create: `/src/fesa/constraints/essential_constraints.cpp`
- Create: `/tests/unit/constraints/essential_constraints_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
조립된 full CSR matrix를 DofManager의 stable free/constrained ordering으로 partition하고
full/reduced vector를 mapping하는 essential-constraint module을 구현하라.
```cpp
struct PartitionedStiffness {
SparseMatrix kff;
SparseMatrix kfc;
SparseMatrix kcf;
SparseMatrix kcc;
};
class EssentialConstraints {
public:
static Result<PartitionedStiffness> partition(const SparseMatrix& full,
const DofManager& dofs);
static Vector gatherFree(const Vector& full, const DofManager& dofs);
static Vector gatherConstrained(const Vector& full, const DofManager& dofs);
static Vector reconstructFull(const Vector& freeValues,
const Vector& constrainedValues,
const DofManager& dofs);
};
```
Partition은 numeric value와 row/column order를 보존하고 0-based CSR invariants를 다시
검증한다. `dc`는 DofManager prescribed values에서 가져오며 zero로 가정하지 않는다.
이 step은 load vector나 RHS를 조립하지 않고 matrix/vector mapping만 소유한다.
Tests는 hand-computed block extraction, no/all/mixed constraints, nonzero prescribed values,
full-free-constrained round trip, invalid dimensions/order를 검증하고
`EssentialConstraints` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R EssentialConstraints --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R EssentialConstraints --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. partition/mapping tests를 먼저 추가하고 RED를 확인한다.
2. elimination에 필요한 최소 block extraction으로 GREEN을 만든다.
3. nonzero `dc`와 전체 VERIFY를 확인한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 19 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 19를 `completed`로 갱신하고 partition/reconstruction evidence를 summary에 기록한다.
## 금지사항
- prescribed displacement를 zero로 덮어쓰지 마라. 이유: 승인된 nonzero BC를 깨뜨린다.
- penalty/MPC solver를 추가하지 마라. 이유: V0는 essential partition만 지원한다.
- RHS/load assembly를 이 step에 섞지 마라. 이유: factorization-before-load 순서를 검증해야 한다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,83 @@
# Step 2: Formulation Alignment
## 담당 역할과 필수 스킬
- 담당 역할: `formulation-agent`
- 필수 스킬: `fesa-formulation-spec`
- 스킬의 `SKILL.md`를 끝까지 읽고 수학 계약과 구현 계약의 경계를 지켜라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/SOLVER_AGENT_DESIGN.md`
- `/docs/formulations/README.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/research/linear-static-3d-euler-beam-research.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
Step 01 산출물과 완료 summary를 확인하라.
## 작업
기존 `docs/formulations/3d-isoparametric-euler-beam-formulation.md`를 승인된 V0 요구조건과
연구 근거에 맞춰 정렬하라. 기존 정식화의 정확한 수학적 의미를 유지해야 하며, 이
step은 새 요소를 다시 설계하는 작업이 아니다.
- Metadata의 source requirement/research 경로와 status를 실제 산출물에 맞게 바꾸고
`feature_id: 3d-isoparametric-euler-beam`, `status: ready-for-numerical-review`를 기록한다.
- 기존 strong/weak form, DOF 순서, `theta_y=-w'`, B matrix, constitutive matrix,
2-point Gauss, 12x12 stiffness, transformation, line-load vector, recovery 식을 유지한다.
- 승인된 입력 의미를 수학 계약에 연결한다: `n1 -> local y`, `t x n1 -> local z`,
`Iy=I11`, `Iz=I22`, `I12=0`, scale-aware geometry validation.
- equilibrium end action, endpoint section resultant, Gauss generalized values, section-point
axial `S11`을 구분하고 stress reference comparison은 N/A임을 분명히 한다.
- 기존 Open Issues 중 승인 설계에서 해결된 tolerance, orientation, HDF5 distinction,
requirement/research 부재 항목을 제거하거나 resolved decision으로 바꾼다.
- EulerBernoulli slenderness 적용 범위는 limitation으로 유지하되 승인되지 않은 임의
warning/error threshold를 추가하지 않는다.
수식 결함을 발견해 정확한 의미를 보존하면서 정렬할 수 없으면 문서를 조용히 수정하지
말고 Step 2를 `blocked`로 기록한다.
## Acceptance Criteria
```powershell
$path = 'docs/formulations/3d-isoparametric-euler-beam-formulation.md'
$required = @(
'status: `ready-for-numerical-review`',
'docs/requirements/linear-static-3d-euler-beam.md',
'docs/research/linear-static-3d-euler-beam-research.md',
'theta_y=-',
'2점 Gauss',
'equilibrium end action',
'section resultant',
'S11',
'n1'
)
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing aligned formulation contract: $text"
}
}
if (Select-String -LiteralPath $path -SimpleMatch 'status: `needs-research`' -Quiet) {
throw 'Stale formulation status remains'
}
git diff --check -- $path
```
## 검증 절차
1. Acceptance Criteria 명령을 실행한다.
2. 기존 수식의 DOF/component 순서와 부호가 승인 전 문서 의미와 동일한지 diff로 검토한다.
3. requirement/research의 모든 math handoff가 정식화 section 또는 limitation에 연결되는지 확인한다.
4. Step 2를 `completed`와 변경 요약으로 갱신한다. 수학 결함이나 upstream 충돌은
`blocked`, 반복 편집 실패는 `error`로 기록한다.
## 금지사항
- C++ class, header, storage API를 설계하지 마라. 이유: formulation은 수학 계약이다.
- 승인된 부호·DOF·적분 규칙을 편의상 바꾸지 마라. 이유: reference 의미가 달라진다.
- B31/Timoshenko 또는 `*DLOAD` parser 지원을 추가하지 마라. 이유: V0 범위 밖이다.
- Abaqus 실행 및 reference artifact 변경을 하지 마라. 이유: 이 gate는 문서 정렬만 담당한다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,110 @@
# Step 20: MKL PARDISO Linear Solver
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/core/status.hpp`
- `/include/fesa/core/diagnostic.hpp`
- `/include/fesa/math/vector.hpp`
- `/include/fesa/math/sparse_matrix.hpp`
- `/src/fesa/math/sparse_matrix.cpp`
- `/cmake/FesaDependencies.cmake`
## 소유 파일
- Create: `/include/fesa/solvers/linear/linear_solver.hpp`
- Create: `/include/fesa/solvers/linear/mkl_pardiso_solver.hpp`
- Create: `/src/fesa/solvers/linear/mkl_pardiso_solver.cpp`
- Create: `/tests/unit/solvers/linear/linear_solver_test.cpp`
- Create: `/tests/unit/solvers/linear/mkl_pardiso_solver_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
MKL PARDISO를 solver core에서 숨기며 SPD `Kff` factorization과 RHS substitution을 분리하는
adapter를 구현하라. Public interface는 승인된 계약과 동일해야 한다.
```cpp
class LinearSolver {
public:
virtual ~LinearSolver() = default;
virtual Status factorize(const SparseMatrix& matrix) = 0;
virtual Status solve(const Vector& rhs, Vector& solution) const = 0;
};
class MklPardisoSolver final : public LinearSolver {
public:
MklPardisoSolver();
~MklPardisoSolver() override;
Status factorize(const SparseMatrix& matrix) override;
Status solve(const Vector& rhs, Vector& solution) const override;
private:
class Impl;
std::unique_ptr<Impl> impl_;
};
```
Adapter는 0-based CSR을 명시적으로 처리하고 real symmetric positive definite matrix
descriptor를 사용한다. Factorization state/workspace를 RAII로 소유하고 destructor와
re-factorization에서 누수 없이 해제한다. 동일 factorization에 여러 RHS를 substitution할
수 있어야 한다. invalid CSR, solve-before-factorize, dimension mismatch, nonfinite RHS,
PARDISO singular/positive-definite failure를 deterministic structured diagnostic으로 반환한다.
MKL header/type은 `.cpp`/private Impl 밖에 노출하지 않는다.
Tests는 known SPD solution/residual `1e-10`, repeated RHS, re-factorization, invalid CSR,
singular/indefinite matrix, solve-before-factorize, dimension mismatch를 포함하고
`MklPardisoSolver` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R MklPardisoSolver --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R MklPardisoSolver --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
$leaks = rg -n "mkl\.h|MKL_INT|pardiso" include/fesa
if ($LASTEXITCODE -eq 0) { throw "PARDISO API leaked into public headers:`n$leaks" }
if ($LASTEXITCODE -ne 1) { throw 'Public-header dependency scan failed' }
```
마지막 scan은 public header에서 no-match여야 한다.
## 검증 절차
1. adapter tests를 먼저 작성하고 missing solver RED를 확인한다.
2. factorize/solve phase를 분리한 최소 PARDISO adapter로 GREEN을 만든다.
3. repeated RHS, RAII, residual, public boundary와 전체 VERIFY를 확인한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 20 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 20을 `completed`로 갱신하고 factorization/substitution evidence를 summary에 기록한다.
## 금지사항
- factorization과 solve를 하나의 opaque method로 합치지 마라. 이유: 승인 runtime order를 깨뜨린다.
- MKL type/header를 public interface에 노출하지 마라. 이유: adapter boundary 계약이다.
- singularity에 임의 regularization을 적용하지 마라. 이유: invalid model을 숨긴다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,94 @@
# Step 21: Nodal Load Assembly and Effective RHS
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/analysis/analysis_model.hpp`
- `/include/fesa/fem/dof_manager.hpp`
- `/include/fesa/constraints/essential_constraints.hpp`
- `/src/fesa/constraints/essential_constraints.cpp`
## 소유 파일
- Create: `/include/fesa/assembly/load_assembler.hpp`
- Create: `/src/fesa/assembly/load_assembler.cpp`
- Create: `/tests/unit/assembly/load_assembler_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
single-step `*CLOAD`를 full external force vector에 deterministic하게 조립하고 effective
free RHS를 만드는 module을 구현하라.
```cpp
class LoadAssembler {
public:
static Result<Vector> assembleFullNodalLoad(const AnalysisModel& model,
const DofManager& dofs);
static Result<Vector> effectiveFreeRhs(const Vector& fullLoad,
const SparseMatrix& kfc,
const Vector& prescribedValues,
const DofManager& dofs);
};
```
Node label/node set target은 semantic Domain의 expanded stable identity를 사용한다. 같은
full DOF의 multiple CLOAD는 source order로 합산하고 output vector ordering은 full DOF
ordering과 같다. `rhs=Ff-Kfc*dc`를 정확히 구현하며 `dc`는 constrained ordering으로 gather한다.
Nonfinite load와 dimension mismatch는 diagnostic이다. 이 module은 element line load나
`*DLOAD` object를 만들지 않는다.
Tests는 single node/set loads, multiple accumulation, six components, negative magnitude,
nonfinite rejection, constrained load partition, nonzero prescribed `Kfc*dc` hand calculation,
zero loads를 포함하고 `LoadAssembly` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R LoadAssembly --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R LoadAssembly --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. nodal load/effective RHS tests를 먼저 작성하고 RED를 확인한다.
2. nodal-only deterministic assembly와 RHS 최소 구현으로 GREEN을 만든다.
3. nonzero prescribed displacement와 전체 VERIFY를 확인한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 21 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 21을 `completed`로 갱신하고 load/RHS evidence를 summary에 기록한다.
## 금지사항
- factorization을 이 module에서 호출하지 마라. 이유: orchestration order는 Step 24가 소유한다.
- `*DLOAD` 또는 Domain distributed-load object를 추가하지 마라. 이유: V0 입력 범위 밖이다.
- prescribed displacement contribution을 생략하지 마라. 이유: `rhs=Ff-Kfc*dc` 계약이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,101 @@
# Step 22: Result Recovery
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/analysis/analysis_model.hpp`
- `/include/fesa/analysis/analysis_state.hpp`
- `/include/fesa/fem/dof_manager.hpp`
- `/include/fesa/elements/euler_beam_3d.hpp`
- `/include/fesa/math/sparse_matrix.hpp`
- `/include/fesa/constraints/essential_constraints.hpp`
- `/include/fesa/assembly/load_assembler.hpp`
## 소유 파일
- Create: `/include/fesa/results/result_recovery.hpp`
- Create: `/src/fesa/results/result_recovery.cpp`
- Create: `/tests/unit/results/result_recovery_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
full displacement로 전체 residual 반력과 element outputs를 복구해 AnalysisState에 채우는
module을 구현하라.
```cpp
class ResultRecovery {
public:
static Status recover(const AnalysisModel& model,
const DofManager& dofs,
const SparseMatrix& fullStiffness,
AnalysisState& state);
};
```
- `internalForce=K*d`, `residual=internalForce-externalForce`를 full space에서 계산하고
constrained DOF reaction을 residual에서 복구한다. Element end action을 별도 합산해
reaction을 만들지 않는다.
- Free residual normalized criterion은 `1e-10`이고 nonfinite를 실패시킨다.
- Active element internal index 순서로 global 12-DOF vector를 gather하고 `EulerBeam3D::recover`
결과를 endpoint/Gauss/stress rows에 안정적으로 저장한다.
- Equilibrium end action `[FX,FY,FZ,MX,MY,MZ]`, endpoint section resultant `[N,T,My,Mz]`,
Gauss generalized strain/resultant, section-point `S11`을 서로 다른 row/data로 유지한다.
- Reference용 node-station normalization helper는 동일 section-cut sign으로 endpoint를
변환하고 interior endpoint 불일치를 평균으로 숨기지 않으며, 일치한 경우 작은 stable
element ID를 대표 row로 선택한다.
Tests는 hand matrix reaction, nonzero prescribed displacement, free residual, axial/torsion/
y-z bending signs, end action vs section resultant distinction, stress point order/default centroid,
interior endpoint match/mismatch와 stable representative를 포함하고 `ResultRecovery` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R ResultRecovery --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R ResultRecovery --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
## 검증 절차
1. reaction/recovery/sign/normalization tests를 먼저 작성하고 RED를 확인한다.
2. residual 기반 최소 recovery 구현으로 GREEN을 만든다.
3. formulation component ordering과 full VERIFY를 확인한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 22 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 22를 `completed`로 갱신하고 recovered quantities/residual evidence를 summary에 기록한다.
## 금지사항
- reaction을 element endpoint 합산 경로로 계산하지 마라. 이유: nodal load와 nonzero BC를 놓친다.
- interior endpoint mismatch를 average로 숨기지 마라. 이유: tolerance failure evidence다.
- shear stress나 nodal stress averaging을 추가하지 마라. 이유: V0 recovery 범위 밖이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,127 @@
# Step 23: HDF5 Results Writer
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/core/diagnostic.hpp`
- `/include/fesa/model/domain.hpp`
- `/include/fesa/analysis/analysis_state.hpp`
- `/include/fesa/results/result_records.hpp`
- `/cmake/FesaDependencies.cmake`
## 소유 파일
- Create: `/include/fesa/results/results_writer.hpp`
- Create: `/include/fesa/io/hdf5/hdf5_results_writer.hpp`
- Create: `/src/fesa/io/hdf5/hdf5_results_writer.cpp`
- Create: `/tests/unit/results/results_writer_test.cpp`
- Create: `/tests/unit/io/hdf5/hdf5_results_writer_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
HDF5 API를 adapter 안에 숨기고 schema v0를 임시 파일에 완성한 후 final path로 교체하는
ResultsWriter를 구현하라.
```cpp
class ResultsWriter {
public:
virtual ~ResultsWriter() = default;
virtual Status write(const std::filesystem::path& outputPath,
const Domain& domain,
const AnalysisState& state,
const std::vector<Diagnostic>& diagnostics) = 0;
};
class Hdf5ResultsWriter final : public ResultsWriter {
public:
Status write(const std::filesystem::path& outputPath,
const Domain& domain,
const AnalysisState& state,
const std::vector<Diagnostic>& diagnostics) override;
};
```
다음 group/dataset을 exact path와 승인 shape/component order로 기록한다.
```text
/metadata
/model/nodes
/model/elements
/steps/<step-name>/frames/0/nodal/displacement
/steps/<step-name>/frames/0/nodal/reaction
/steps/<step-name>/frames/0/element/end_force_local
/steps/<step-name>/frames/0/element/section_resultant
/steps/<step-name>/frames/0/element/generalized_strain
/steps/<step-name>/frames/0/element/generalized_resultant
/steps/<step-name>/frames/0/element/stress_s11
/diagnostics
```
승인 설계의 schema 목록은 minimum contract이며, 별도 `generalized_resultant` dataset은
설계가 요구한 Gauss-point generalized resultant를 손실 없이 기록하기 위한 필수 sibling이다.
Metadata는 schema/solver version, source input identity, `user-consistent-unspecified` unit
label, coordinate convention, `B33 Euler-Bernoulli` formulation을 가진다. Model rows는 stable
internal ID와 instance/source label을 함께 쓴다. 모든 field에는 component/output-location
identity를 기록한다. HDF5 handle은 RAII로 닫고 failure 시 incomplete final `results.h5`
남기지 않는다. Existing final 교체도 Windows에서 실패 중간 상태를 만들지 않는 adapter
내 정책과 test를 제공한다. HDF5/Windows API type은 public header에 노출하지 않는다.
Tests는 complete schema/shape/metadata/identity/component, diagnostics warning, no section
points centroid, failed path/no partial final, successful replacement을 포함하고
`Hdf5ResultsWriter` regex로 등록한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R Hdf5ResultsWriter --output-on-failure
```
RED 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R Hdf5ResultsWriter --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
$leaks = rg -n "H5[A-Z_a-z0-9]*|hid_t" include/fesa
if ($LASTEXITCODE -eq 0) { throw "HDF5 API leaked into public headers:`n$leaks" }
if ($LASTEXITCODE -ne 1) { throw 'Public-header dependency scan failed' }
```
마지막 scan은 public header에서 no-match여야 한다.
## 검증 절차
1. schema/atomicity tests를 먼저 작성하고 writer 부재 RED를 확인한다.
2. exact schema와 RAII/temporary finalization의 최소 구현으로 GREEN을 만든다.
3. HDF5 inspection, failure cleanup, public boundary와 전체 VERIFY를 확인한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 23 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 23을 `completed`로 갱신하고 schema/atomicity evidence를 summary에 기록한다.
## 금지사항
- CSV를 공식 solver output으로 추가하지 마라. 이유: authoritative output은 HDF5 하나다.
- Abaqus output request로 dataset을 생략하지 마라. 이유: FESA default output은 항상 생성된다.
- HDF5 type/header를 public API에 노출하지 마라. 이유: adapter boundary 계약이다.
- 실패 후 incomplete final file을 남기지 마라. 이유: output integrity 계약이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,167 @@
# Step 24: Linear Static Orchestration and CLI
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 모든 C++ build/test와 최종 VERIFY는 MSVC x64 Debug 기준으로 수행한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/reference-models/linear-static-3d-euler-beam-reference-models.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/io/abaqus/input_reader.hpp`
- `/include/fesa/io/abaqus/domain_mapper.hpp`
- `/include/fesa/analysis/analysis_model.hpp`
- `/include/fesa/analysis/analysis_state.hpp`
- `/include/fesa/fem/dof_manager.hpp`
- `/include/fesa/assembly/parallel_for.hpp`
- `/include/fesa/assembly/sparse_assembler.hpp`
- `/include/fesa/constraints/essential_constraints.hpp`
- `/include/fesa/solvers/linear/linear_solver.hpp`
- `/include/fesa/assembly/load_assembler.hpp`
- `/include/fesa/results/result_recovery.hpp`
- `/include/fesa/results/results_writer.hpp`
- `/include/fesa/io/hdf5/hdf5_results_writer.hpp`
- `/src/fesa/CMakeLists.txt`
- `/tests/CMakeLists.txt`
- `/reference/cantilever beam/`의 승인된 네 파일
## 소유 파일
- Create: `/include/fesa/analysis/linear_static_analysis.hpp`
- Create: `/src/fesa/analysis/linear_static_analysis.cpp`
- Create: `/include/fesa/app/fesa_application.hpp`
- Create: `/src/fesa/app/fesa_application.cpp`
- Create: `/src/fesa/app/main.cpp`
- Create: `/tests/integration/analysis/linear_static_analysis_test.cpp`
- Create: `/tests/integration/app/fesa_application_test.cpp`
- Create: `/tests/reference/reference_comparison.hpp`
- Create: `/tests/reference/reference_comparison.cpp`
- Create: `/tests/reference/reference_comparison_test.cpp`
- Create: `/tests/reference/b33_reference_comparison_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
전체 single-step lifecycle과 `fesa.exe` CLI를 구현하고 Step 26이 재사용할 read-only
reference comparison test utility를 완성하라.
```cpp
struct AnalysisRequest { std::filesystem::path inputPath; std::filesystem::path outputPath; };
class Analysis {
public:
virtual ~Analysis() = default;
Status run(const AnalysisRequest& request);
protected:
virtual Status initialize(const AnalysisRequest& request) = 0;
virtual Status buildAnalysisModel() = 0;
virtual Status buildDofMapAndSparsePattern() = 0;
virtual Status assembleAndPartitionStiffness() = 0;
virtual Status factorize() = 0;
virtual Status assembleLoadsAndEffectiveRhs() = 0;
virtual Status substituteAndReconstruct() = 0;
virtual Status recoverAndWriteResults() = 0;
};
class LinearStaticAnalysis final : public Analysis { /* V0 hook implementations */ };
class FesaApplication {
public:
int run(const std::vector<std::string>& arguments);
};
```
`LinearStaticAnalysis::run`은 다음 event order를 exact하게 고정하고 각 실패를 diagnostic/
exit category에 연결한다.
```text
parse input -> Domain -> AnalysisModel -> DofManager/sparse pattern
-> parallel element stiffness -> deterministic COO-to-CSR
-> free/constrained partition -> factorize(Kff)
-> assemble full nodal load -> rhs=Ff-Kfc*dc
-> solve substitution -> reconstruct full displacement
-> residual/reaction/element recovery -> atomic HDF5 write
```
Spy/fake adapters를 사용한 orchestration test는 `factorize` event가 load assembly보다 먼저고
`solve`가 factorization을 재수행하지 않음을 검증한다. 실제 production default는
TbbParallelFor, MklPardisoSolver, Hdf5ResultsWriter를 사용한다.
CLI는 `fesa.exe <model.inp> --output <results.h5>`와 output 생략 시 current directory
`results.h5`를 지원한다. Exit code는 `0 success`, `2 usage`, `3 input syntax/semantic`,
`4 model validation`, `5 factorization/substitution`, `6 HDF5 output`이다. Error diagnostics는
stderr에 deterministic order로 쓰고 warning은 output diagnostics에도 보존한다. CMake
executable target은 내부 이름이 다르더라도 `OUTPUT_NAME fesa`를 설정해 Debug output이
실제로 `fesa.exe`가 되게 한다.
Test-only reference support를 `tests/reference/` 아래 구현하라.
- approved input으로 `.harness/build/reference/cantilever-beam-b33/results.h5`를 생성한다.
- legacy displacement/reaction/elemental-force CSV를 read-only로 parse하고 실제 CAE header
`U-U*`, `UR-UR*`, `RF-RF*`, `RM-RM*`, `SF-SF1`, `SM-SM*`을 canonical component로 normalize한다.
- row matching 전에 expected header, B33 input, unique identity, missing/extra/nonfinite를 검사한다.
- same model/step/frame/quantity/component의 Abaqus-only scale과
`absolute_floor + 1e-6*reference_scale`로 모든 row를 판정한다.
- section resultants는 node station과 `SF1->N`, `SM1->My`, `SM2->Mz`, `SM3->T`로 비교한다.
- Stress comparison은 N/A로 기록하되 HDF5 stress dataset/test 통과를 요구한다.
- max absolute, component-scale normalized, RMS, norm, worst row/component를
`.harness/build/reference/cantilever-beam-b33/comparison.json`에 결정적으로 기록한다.
- 같은 JSON에 matched FESA/reference rows, full free residual norm, applied/reaction force와
origin 기준 moment 합, endpoint consistency를 `physics_evidence`로 기록해 Step 27이
source/test 변경 없이 물리 sanity를 독립 검토할 수 있게 한다.
Tests는 orchestration order, CLI default/explicit output, all exit codes, output-request no-op,
approved input end-to-end, reference tolerance zero/near-zero/failure cases를 포함한다.
CTest regex/label은 `LinearStaticCli`, `ReferenceComparisonContract`,
`B33ReferenceComparison`으로 실행 가능하게 한다.
## Acceptance Criteria
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R "LinearStaticCli|ReferenceComparisonContract|B33ReferenceComparison" --output-on-failure
```
위 command에서 missing orchestration/CLI/reference utility RED를 확인한 후 구현한다.
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "LinearStaticCli|ReferenceComparisonContract|B33ReferenceComparison" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
if (-not (Test-Path '.harness/build/reference/cantilever-beam-b33/results.h5')) { throw 'Missing reference-run HDF5' }
if (-not (Test-Path '.harness/build/reference/cantilever-beam-b33/comparison.json')) { throw 'Missing comparison metrics' }
git diff --exit-code -- reference/
```
## 검증 절차
1. orchestration/CLI/reference contract tests를 먼저 작성하고 targeted RED를 확인한다.
2. exact lifecycle과 minimal CLI/test utility로 targeted GREEN을 만든다.
3. approved input end-to-end, comparison metrics, CTest discovery/full VERIFY를 실행한다.
4. reference artifacts가 unchanged인지 확인한다.
5. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 24 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output, 변경 파일과 generated HDF5/comparison evidence를 기록한다.
6. Step 24를 `completed`로 갱신하고 CLI path, exit codes, generated HDF5/metrics와
RED/GREEN/VERIFY evidence를 summary에 기록한다.
## 금지사항
- load assembly를 factorization 앞으로 옮기지 마라. 이유: 승인 runtime order와 반대다.
- factorize와 substitution을 합치지 마라. 이유: solver contract와 repeated RHS 검증을 깨뜨린다.
- B31/multiple-step/transform/`*DLOAD`를 지원하지 마라. 이유: V0 범위 밖이다.
- reference CSV를 보정·rename·rewrite하지 마라. 이유: comparison baseline을 오염시킨다.
- stress reference comparison을 만들어내지 마라. 이유: 승인 범위에서 명시적 N/A다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,85 @@
# Step 25: Build and Test Verification
## 담당 역할과 필수 스킬
- 담당 역할: `build-test-executor-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 이 step은 검증과 보고만 수행한다. 실패를 production 변경으로 덮지 않는다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/build-test-reports/README.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
- `/docs/numerical-reviews/linear-static-3d-euler-beam-review.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/reference-models/linear-static-3d-euler-beam-reference-models.md`
- `/CMakeLists.txt`와 모든 CMake/test registration
- `/phases/linear-static-3d-euler-beam/index.json`의 Step 724 summary
## 작업
fresh MSVC x64 Debug configure/build/test evidence를 수집해
`docs/build-test-reports/linear-static-3d-euler-beam.md`를 생성하라.
- Metadata status는 모든 gate 통과 시 `pass-for-reference-verification`이다.
- Environment/dependency revision과 config-resolved command를 기록한다.
- Configure, build, targeted feature tests, CTest discovery, full CTest 각각에 command,
start/end 또는 duration, exit code, stdout/stderr tail, verdict를 기록한다.
- CTest discovery가 하나 이상의 test를 포함하고 compiler metadata가 MSVC인지 확인한다.
- `/W4 /WX`로 새 product warning이 없는지 build output/CMake setting으로 확인한다.
- implementation report의 Step 724 RED/GREEN/VERIFY evidence가 모두 present인지 감사한다.
- 실패는 `configure | compile | link | test | reference-comparison | harness | environment |
upstream-contract` 중 하나로 분류하고 correction handoff를 기록한다.
## Acceptance Criteria
아래 명령을 fresh evidence로 실행한다.
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
$discovery = ctest --test-dir .harness/build -C Debug --show-only=json-v1 | ConvertFrom-Json
if ($discovery.tests.Count -lt 1) { throw 'CTest discovered zero tests' }
ctest --test-dir .harness/build -C Debug -L linear-static-3d-euler-beam --output-on-failure
ctest --test-dir .harness/build -C Debug --output-on-failure
```
Report structural check:
```powershell
$path = 'docs/build-test-reports/linear-static-3d-euler-beam.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @('status: `pass-for-reference-verification`', 'MSVC', 'x64', 'Debug',
'configure', 'build', 'show-only=json-v1', 'output-on-failure', 'exit code', 'duration')
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing build/test evidence: $text"
}
}
git diff --check -- $path
```
## 검증 절차
1. 모든 command를 새로 실행하고 실제 exit code/duration/output tail을 기록한다.
2. implementation evidence와 CTest discovered tests를 대조한다.
3. 모두 성공한 경우에만 report와 Step 25를 pass/completed로 갱신한다.
4. 실패 시 report에 정확한 classification과 correction handoff를 기록하고 Step 25를
`error`로 둔다. 환경/사용자 조치가 필수인 경우만 `blocked`로 둔다.
## 금지사항
- source, tests, CMake를 수정하지 마라. 이유: independent build/test gate다.
- 실패 test를 disable/filter-out하지 마라. 이유: 회귀를 숨긴다.
- reference artifact나 tolerance를 수정하지 마라. 이유: 이 gate의 책임 밖이다.
- command 결과를 추정하거나 이전 summary를 fresh evidence로 대체하지 마라. 이유: gate 신뢰성을 잃는다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,104 @@
# Step 26: Abaqus B33 Reference Verification
## 담당 역할과 필수 스킬
- 담당 역할: `reference-verification-agent`
- 필수 스킬: `fesa-reference-comparison`
- `ARTIFACT CHECK -> COMPARE -> CLASSIFY -> REPORT` 순서를 지켜라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/reference-verifications/README.md`
- `/docs/build-test-reports/linear-static-3d-euler-beam.md`
- `/docs/reference-models/linear-static-3d-euler-beam-reference-models.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
- `/reference/cantilever beam/cantilever beam.inp`
- `/reference/cantilever beam/cantilever beam displacements.csv`
- `/reference/cantilever beam/cantilever beam reactions.csv`
- `/reference/cantilever beam/cantilever beam elemental forces.csv`
- Step 24가 생성한 reference comparison test/command 계약과 build-directory result/metrics
## 작업
Build/Test report status가 `pass-for-reference-verification`인지 먼저 확인한다. 통과했다면
승인 input으로 solver output을 재생성하고, test-only comparison utility가 기록한 raw
normalized rows/metrics를 독립 검토해
`docs/reference-verifications/linear-static-3d-euler-beam-reference-verification.md`를 작성하라.
Artifact check:
- exact legacy 네 파일 존재, input `TYPE=B33`, expected CAE CSV headers, unique row keys,
finite values를 검사한다.
- 이 bundle은 승인된 예외이므로 `metadata.json`, `README.md`, stress CSV 부재만으로
차단하지 않는다. Contract에서 provenance/units/schema/stress N/A를 확인한다.
- generated HDF5 schema/version/units/coordinate/step-frame/source identity를 검사한다.
Comparison:
- displacement CSV `U-U1/U-U2/U-U3/UR-UR1/UR-UR2/UR-UR3`, reaction CSV
`RF-RF1/RF-RF2/RF-RF3/RM-RM1/RM-RM2/RM-RM3`, section-resultant CSV
`SF-SF1/SM-SM1/SM-SM2/SM-SM3`을 canonical component로 normalize한 뒤 exact
identity/component mapping으로 비교한다.
- CSV increment 1/time 1.0을 `(Step-1, frame 0)`으로 normalize한다.
- interior endpoint consistency를 먼저 검사하고 평균으로 숨기지 않는다.
- 같은 model/step/frame/quantity/component의 read-only reference rows에서만
`reference_scale=max(abs(reference_value_i))`를 계산한다.
- 모든 row에 `absolute_floor + 1e-6*reference_scale`을 적용한다. SI displacement/rotation
floor `1e-9`, force/moment floor `1e-3`; scale zero면 floor만 적용한다.
- Missing/extra/nonfinite/schema/identity mismatch는 tolerance 전에 fail한다.
- max absolute error, component-scale normalized error, RMS, norm, worst row/component를 기록한다.
- Stress reference comparison은 N/A라고 명시하고 HDF5 stress schema/unit test evidence를 연결한다.
모든 비교 통과 시 Metadata status는 `pass-for-physics-evaluation`이다. No-Change Assertion에
source/test/CMake/reference/tolerance가 모두 unchanged임을 기록한다.
## Acceptance Criteria
```powershell
if (-not (Select-String -LiteralPath 'docs/build-test-reports/linear-static-3d-euler-beam.md' `
-SimpleMatch 'status: `pass-for-reference-verification`' -Quiet)) {
throw 'Build/test gate is not passing'
}
ctest --test-dir .harness/build -C Debug -R B33ReferenceComparison -V --output-on-failure
$metricsPath = '.harness/build/reference/cantilever-beam-b33/comparison.json'
if (-not (Test-Path $metricsPath)) { throw 'Missing comparison metrics' }
$metrics = Get-Content -Raw $metricsPath | ConvertFrom-Json
if ($metrics.status -ne 'pass') { throw "Reference comparison failed: $($metrics.status)" }
git diff --exit-code -- reference/
```
```powershell
$path = 'docs/reference-verifications/linear-static-3d-euler-beam-reference-verification.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @('status: `pass-for-physics-evaluation`', '## Artifact Inventory',
'## Comparison Contract', '## Quantity Results', '## No-Change Assertion',
'cantilever-beam-b33', 'absolute_floor + 1e-6 * reference_scale', 'stress', 'N/A')
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing reference verification evidence: $text"
}
}
git diff --check -- $path
```
## 검증 절차
1. Artifact check를 comparison보다 먼저 완료한다.
2. B33ReferenceComparison을 fresh 실행하고 comparison JSON과 HDF5를 직접 확인한다.
3. 모든 row/metric/tolerance가 통과한 경우에만 report와 Step 26을 pass/completed로 갱신한다.
4. 실패는 정해진 classification과 handoff를 report에 기록하고 Step 26을 `error`로 둔다.
사용자/외부 artifact 조치가 필수인 경우만 `blocked`로 둔다.
## 금지사항
- source, tests, CMake, upstream contract를 수정하지 마라. 이유: independent comparison gate다.
- FESA 결과나 reference value로 scale/tolerance를 조정하지 마라. 이유: acceptance를 오염시킨다.
- row를 zero-clamp, 삭제, 평균 처리하지 마라. 이유: mismatch를 숨긴다.
- reference artifact를 생성·수정·rename하지 마라. 이유: read-only baseline이다.
- Abaqus를 실행하지 마라. 이유: 저장된 CSV만 authoritative reference다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,91 @@
# Step 27: Physics Sanity
## 담당 역할과 필수 스킬
- 담당 역할: `physics-evaluation-agent`
- 필수 스킬: `fesa-physics-sanity`
- reference tolerance를 다시 판정하지 말고 documented physical expectation만 평가하라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/physics-evaluations/README.md`
- `/docs/reference-verifications/linear-static-3d-euler-beam-reference-verification.md`
- `/docs/reference-models/linear-static-3d-euler-beam-reference-models.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/numerical-reviews/linear-static-3d-euler-beam-review.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/.harness/build/reference/cantilever-beam-b33/results.h5`
- `/.harness/build/reference/cantilever-beam-b33/comparison.json`
- `/reference/cantilever beam/`의 승인된 read-only artifact
## 작업
Reference Verification status가 `pass-for-physics-evaluation`인지 먼저 확인하고
`docs/physics-evaluations/linear-static-3d-euler-beam-physics-evaluation.md`를 생성하라.
다음 physical check를 documented expectation과 observed HDF5/comparison evidence로 각각
판정한다.
- global applied force + reaction force equilibrium
- origin 기준 applied/reaction force moment와 reaction moment equilibrium
- constrained DOF reaction consistency와 free residual normalized `1e-10`
- load 방향에 대한 displacement/rotation direction과 sign
- expected zero/symmetry components
- adjacent element endpoint section resultant consistency와 boundary end action balance
- local/global component mapping, section-force signs, `S11` location/sign sanity
- nonfinite, rigid-body-mode, 비정상 magnitude/energy 징후
- B33 cantilever가 검증하는 범위와 line-load/rotated/analytical unit test가 보완하는 coverage
각 check에 식, unit, coordinate system, observed value/norm, criterion, verdict를 기록한다.
Stress는 Abaqus reference comparison 없이 schema/unit/analytical evidence로만 sanity를
평가한다고 명시한다. 모든 documented check가 통과하면 Metadata와 Evaluation Verdict를
`pass-for-release-agent`로 둔다. No-Change Assertion을 포함한다.
## Acceptance Criteria
```powershell
$referenceReport = 'docs/reference-verifications/linear-static-3d-euler-beam-reference-verification.md'
if (-not (Select-String -LiteralPath $referenceReport `
-SimpleMatch 'status: `pass-for-physics-evaluation`' -Quiet)) {
throw 'Reference verification gate is not passing'
}
ctest --test-dir .harness/build -C Debug -R "EulerBeam3D|ResultRecovery|B33ReferenceComparison" --output-on-failure
if (-not (Test-Path '.harness/build/reference/cantilever-beam-b33/results.h5')) { throw 'Missing solver HDF5 evidence' }
if (-not (Test-Path '.harness/build/reference/cantilever-beam-b33/comparison.json')) { throw 'Missing normalized comparison/physics evidence' }
git diff --exit-code -- reference/
```
```powershell
$path = 'docs/physics-evaluations/linear-static-3d-euler-beam-physics-evaluation.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @('status: `pass-for-release-agent`', '## Input Evidence', '## Physics Checks',
'global equilibrium', 'reaction consistency', 'displacement direction',
'element force', 'stress', '## No-Change Assertion')
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing physics evidence: $text"
}
}
git diff --check -- $path
```
## 검증 절차
1. Passing reference report와 exact solver artifact identity를 확인한다.
2. 각 physical expectation을 HDF5/metrics/test evidence로 계산·검토한다.
3. 모두 통과한 경우에만 report와 Step 27을 pass/completed로 갱신한다.
4. 실패는 physics classification과 owning agent handoff를 기록하고 Step 27을 `error`로 둔다.
추가 reference model/사용자 결정이 필수이면 `blocked`로 둔다.
## 금지사항
- source, tests, CMake, upstream reports/contracts를 수정하지 마라. 이유: independent physics gate다.
- reference tolerance 성공을 다시 판정하거나 완화하지 마라. 이유: Step 26 책임이다.
- undocumented expectation으로 pass를 만들지 마라. 이유: 검토 traceability가 사라진다.
- Abaqus 실행 또는 reference artifact 변경을 하지 마라. 이유: read-only evidence다.
- release readiness를 승인하지 마라. 이유: Step 28 책임이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,100 @@
# Step 28: Release Readiness
## 담당 역할과 필수 스킬
- 담당 역할: `release-agent`
- 필수 스킬: `fesa-release-readiness`
- `GATE AUDIT -> TRACEABILITY CHECK -> RELEASE DOCUMENTATION -> RELEASE VERDICT` 순서를 지켜라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/PRD.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/releases/README.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/research/linear-static-3d-euler-beam-research.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/numerical-reviews/linear-static-3d-euler-beam-review.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/reference-models/linear-static-3d-euler-beam-reference-models.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
- `/docs/build-test-reports/linear-static-3d-euler-beam.md`
- `/docs/reference-verifications/linear-static-3d-euler-beam-reference-verification.md`
- `/docs/physics-evaluations/linear-static-3d-euler-beam-physics-evaluation.md`
- `/phases/linear-static-3d-euler-beam/index.json`의 모든 completed summary
## 작업
모든 gate evidence를 감사하고
`docs/releases/linear-static-3d-euler-beam-release.md`를 생성하라.
- 같은 feature ID, source design revision, implementation scope와 artifact identity가 모든
문서에서 일치하는지 확인한다.
- Build/Test `pass-for-reference-verification`, Reference Verification
`pass-for-physics-evaluation`, Physics Evaluation `pass-for-release-agent`를 필수로 요구한다.
- 모든 `FESA-REQ-LS3DEB-*` must requirement를 acceptance criterion, test ID, reference/
analytical evidence, final disposition에 연결한다.
- Release Scope, Gate Evidence Inventory, Acceptance Traceability, Validation Evidence,
Known Limitations, Release Notes Draft, Release Verdict, Handoff, No-Change Assertion을 작성한다.
- Known Limitations에는 B31, multiple steps, transforms/nested assembly, `I12!=0`, `*DLOAD`,
nonlinear/dynamic/contact/thermal, shear/warping stress, beam stress reference N/A, legacy
artifact exception을 포함한다.
- 모든 evidence가 present/passing이고 unresolved blocker가 없을 때만
`status: ready-for-release`와 같은 verdict를 발행한다.
이 verdict는 내부 feature readiness이며 publish, package, tag, push 또는 external release를
수행하는 권한이 아니다.
## Acceptance Criteria
```powershell
$gates = @{
'docs/build-test-reports/linear-static-3d-euler-beam.md' = 'status: `pass-for-reference-verification`'
'docs/reference-verifications/linear-static-3d-euler-beam-reference-verification.md' = 'status: `pass-for-physics-evaluation`'
'docs/physics-evaluations/linear-static-3d-euler-beam-physics-evaluation.md' = 'status: `pass-for-release-agent`'
}
foreach ($entry in $gates.GetEnumerator()) {
if (-not (Select-String -LiteralPath $entry.Key -SimpleMatch $entry.Value -Quiet)) {
throw "Gate is not passing: $($entry.Key)"
}
}
$phase = Get-Content -Raw 'phases/linear-static-3d-euler-beam/index.json' | ConvertFrom-Json
if (($phase.steps | Where-Object { $_.step -lt 28 -and $_.status -ne 'completed' }).Count -ne 0) {
throw 'One or more prerequisite phase steps are incomplete'
}
```
```powershell
$path = 'docs/releases/linear-static-3d-euler-beam-release.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @('status: `ready-for-release`', '## Release Scope', '## Gate Evidence Inventory',
'## Acceptance Traceability', '## Validation Evidence', '## Known Limitations',
'## Release Notes Draft', '## Release Verdict', '## No-Change Assertion',
'TYPE=B33', 'TYPE=B31', 'stress reference', 'N/A')
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing release evidence: $text"
}
}
git diff --check -- $path
git diff --exit-code -- reference/
```
## 검증 절차
1. Gate status와 feature/source identity를 먼저 감사한다.
2. 모든 must requirement의 test/reference/final disposition trace를 확인한다.
3. limitations와 N/A가 Release Notes Draft에 누락되지 않았는지 확인한다.
4. 모든 조건을 만족한 경우에만 report와 Step 28을 ready/completed로 갱신한다.
5. evidence가 missing/failing/contradictory면 적절한 `needs-*` verdict와 handoff를 report에
기록하고 Step 28을 `error`로 둔다. 사용자 결정이 필수인 경우만 `blocked`로 둔다.
## 금지사항
- source, tests, CMake, upstream gate report, reference artifact, tolerance를 수정하지 마라. 이유: audit 독립성이다.
- failed/missing gate를 override하지 마라. 이유: release verdict 신뢰성을 깨뜨린다.
- publish, deploy, package, tag, push를 수행하지 마라. 이유: 사용자 명시 권한이 없다.
- 직접 commit하지 마라. 이유: Harness executor가 phase metadata commit을 담당한다.
@@ -0,0 +1,79 @@
# Step 3: Numerical Review
## 담당 역할과 필수 스킬
- 담당 역할: `numerical-review-agent`
- 필수 스킬: `fesa-numerical-review`
- 스킬을 끝까지 읽고 formulation 작성자와 독립된 reviewer 관점으로 작업하라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/SOLVER_AGENT_DESIGN.md`
- `/docs/numerical-reviews/README.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/research/linear-static-3d-euler-beam-research.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
## 작업
`docs/numerical-reviews/linear-static-3d-euler-beam-review.md`를 생성해 구현 전 수치
검토를 수행하라.
- Metadata와 `Review Verdict`를 포함하고 통과 시
`status: pass-for-implementation-planning`을 사용한다.
- `[u,v,w,theta_x,theta_y,theta_z]` DOF 순서, `theta_y=-w'`, `My=-EIy*w''`, natural
boundary/end-action 부호를 독립 재유도한다.
- 4x12 B matrix와 12x12 closed-form stiffness의 대응, 2-point Gauss exactness,
symmetry, rank 6, six rigid modes, positive deformation energy를 검토한다.
- `R`, `T` orthogonality/right-handedness와 energy invariance를 검토한다.
- consistent constant line-load vector의 component와 부호를 검토하되 `*DLOAD` input은
범위 밖임을 유지한다.
- free/constrained partition, nonzero prescribed displacement, residual reaction,
SPD factorization 가정과 singularity/conditioning 위험을 검토한다.
- 구현 테스트 권고를 구체적 test id/criterion으로 제시하고 confirmed defect, risk,
open issue를 분리한다.
확인된 수학 결함이 하나라도 있으면 `pass-for-implementation-planning`을 발행하지 말고
`needs-formulation-revision`으로 보고한 뒤 phase step을 `blocked`로 기록한다.
## Acceptance Criteria
```powershell
$path = 'docs/numerical-reviews/linear-static-3d-euler-beam-review.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @(
'status: `pass-for-implementation-planning`',
'## Review Verdict',
'## Critical Findings',
'## Numerical Risk Assessment',
'## Consistency Checks',
'## Verification Readiness',
'rank 6',
'rigid',
'2-point'
)
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing numerical review evidence: $text"
}
}
git diff --check -- $path
```
## 검증 절차
1. Acceptance Criteria 명령을 실행한다.
2. review가 formulation을 직접 수정하지 않았는지 확인한다.
3. 모든 numerical risk가 test recommendation 또는 explicit limitation으로 연결되는지 확인한다.
4. 통과 시 Step 3을 `completed`와 verdict summary로 갱신한다. 수학 revision이 필요하면
`blocked`, 문서 생성 자체가 반복 실패하면 `error`로 기록한다.
## 금지사항
- formulation 문서를 직접 편집하지 마라. 이유: 독립 review evidence를 보존해야 한다.
- C++ API/file ownership을 설계하거나 구현하지 마라. 이유: 다음 gate 책임이다.
- reference comparison 성공을 판정하지 마라. 이유: solver 결과가 아직 없다.
- Abaqus 실행과 `/reference/` 변경을 하지 마라. 이유: read-only baseline이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,96 @@
# Step 4: I/O Contract
## 담당 역할과 필수 스킬
- 담당 역할: `io-definition-agent`
- 필수 스킬: `fesa-io-contract`
- 스킬을 끝까지 읽고 semantic contract만 정의하라. C++ API는 다음 gate가 담당한다.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/SOLVER_AGENT_DESIGN.md`
- `/docs/io-definitions/README.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/numerical-reviews/linear-static-3d-euler-beam-review.md`
- `/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
- `/reference/cantilever beam/cantilever beam.inp`
- `/reference/cantilever beam/cantilever beam displacements.csv`
- `/reference/cantilever beam/cantilever beam reactions.csv`
- `/reference/cantilever beam/cantilever beam elemental forces.csv`
## 작업
`docs/io-definitions/linear-static-3d-euler-beam-io.md`를 생성하라. Metadata status는
`ready-for-implementation-planning`으로 둔다.
- 지원 keyword별 위치, parameter, data grammar, case policy, source-location 보존,
duplicate/dangling reference validation을 표로 정의한다.
- `*PART/*ASSEMBLY/*INSTANCE` nesting grammar, 여러 identity instance, stable
`SourceEntityId`, assembly set의 `INSTANCE` parameter를 정의한다.
- B33 acceptance, B31 rejection, transform/nested assembly/multiple-step rejection code를
포함한다.
- `*STEP``NLGEOM`은 absent 또는 `NO`만 허용하고 `YES`는 거부한다. `*STATIC`의 승인
legacy data `initial increment, time period, minimum increment, maximum increment` 네 값을
accept하되 V0 결과 identity는 `(Step-1, frame 0)`으로 고정한다.
- `*BOUNDARY target, first_dof, last_dof[, value]`
`*CLOAD target, dof, magnitude`, DOF 1..6 의미를 정확히 정의한다.
- General section의 `A,I11,I12,I22,J`, material `E,nu`, `G`, guide vector/geometry
validation과 local axis mapping을 정의한다.
- `*PREPRINT`, `*RESTART`, `*TRANSVERSE SHEAR STIFFNESS`, `*OUTPUT, FIELD`,
`*OUTPUT, HISTORY`, `*NODE OUTPUT`, `*ELEMENT OUTPUT`, `*CONTACT OUTPUT` 및 그 output
variable data의 warning no-op allowlist와 unknown model-affecting keyword error를 분리한다.
- HDF5 schema v0의 exact dataset path, shape, row identity, component order, units label,
metadata, diagnostics, atomic finalization을 정의한다.
- legacy CSV header의 `U-U1/U-U2/U-U3`, `UR-UR1/UR-UR2/UR-UR3`,
`RF-RF1/RF-RF2/RF-RF3`, `RM-RM1/RM-RM2/RM-RM3`, `SF-SF1`,
`SM-SM1/SM-SM2/SM-SM3`을 canonical component로 바꾸는 규칙과
frame/instance/node-station normalization 및
`SF1->N`, `SM1->My`, `SM2->Mz`, `SM3->T`, interior endpoint consistency를 정의한다.
- 일반 end-action/section mapping은 `SF1->FX/N`, `SF3->FY`, `SF2->FZ`,
`SM3->MX/T`, `SM1->MY`, `SM2->MZ`로 정의한다. 승인 legacy comparison에는 CSV에
존재하는 `SF1/SM1/SM2/SM3`만 사용하고 `SF2/SF3`를 reference row로 만들어내지 않는다.
- component-scale tolerance와 missing/extra/nonfinite precheck를 정의한다.
- CLI syntax와 exit code `0,2,3,4,5,6`을 포함한다.
## Acceptance Criteria
```powershell
$path = 'docs/io-definitions/linear-static-3d-euler-beam-io.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @(
'status: `ready-for-implementation-planning`',
'## Abaqus Input Scope',
'## Syntax Policy',
'## Model Data Mapping',
'## Output HDF5 Schema',
'## FESA HDF5 to Reference CSV Comparison Schema',
'*OUTPUT, FIELD',
'SF1',
'/steps/<step-name>/frames/0/nodal/displacement',
'absolute_floor + 1e-6 * reference_scale'
)
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing I/O contract: $text"
}
}
git diff --check -- $path
```
## 검증 절차
1. Acceptance Criteria 명령을 실행한다.
2. 지원 keyword마다 purpose, required data, unsupported behavior가 있는지 확인한다.
3. HDF5 dataset과 reference CSV component/identity가 양방향으로 추적되는지 확인한다.
4. Step 4를 `completed`와 schema summary로 갱신한다. upstream 충돌은 `blocked`, 반복
생성 실패는 `error`로 기록한다.
## 금지사항
- parser나 HDF5 writer를 구현하지 마라. 이유: 이 step은 I/O 계약만 소유한다.
- full Abaqus compatibility를 주장하지 마라. 이유: 승인 subset만 지원한다.
- output request가 FESA 기본 output을 끄도록 정의하지 마라. 이유: 승인 의미와 반대다.
- reference CSV를 rewrite하거나 tolerance를 변경하지 마라. 이유: 승인 baseline이다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,88 @@
# Step 5: Reference Model Contract
## 담당 역할과 필수 스킬
- 담당 역할: `reference-model-agent`
- 필수 스킬: `fesa-reference-models`
- 스킬을 끝까지 읽고 artifact 설계와 artifact 생성의 경계를 준수하라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/SOLVER_AGENT_DESIGN.md`
- `/docs/reference-models/README.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/research/linear-static-3d-euler-beam-research.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/numerical-reviews/linear-static-3d-euler-beam-review.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
- `/reference/cantilever beam/cantilever beam.inp`
- `/reference/cantilever beam/cantilever beam displacements.csv`
- `/reference/cantilever beam/cantilever beam reactions.csv`
- `/reference/cantilever beam/cantilever beam elemental forces.csv`
## 작업
`docs/reference-models/linear-static-3d-euler-beam-reference-models.md`를 생성하라.
Metadata status는 `ready-for-implementation-planning`으로 둔다.
- code verification, analytical solution verification, B33 reference comparison을 분리한다.
- analytical inventory에 axial, torsion, local y/z bending, rotated beam, nonzero prescribed
displacement, invalid input cases를 포함하고 각 target quantity/test를 연결한다.
- 승인 reference record는 `model_id: cantilever-beam-b33`, logical schema
`abaqus-cae-report-csv-v0`, source commit `2b34d0b`, generator
`Abaqus/CAE Learning Edition 2024`, SI, `Step-1`, increment 1/time 1.0을 기록한다.
- exact legacy paths 네 개를 inventory에 기록하고 B33 element type, expected header,
unique row key, finite value artifact check를 요구한다.
- 이 legacy bundle에 한해서 `metadata.json`, `README.md`, stress CSV가 N/A이며 설계와
이 contract가 provenance/schema/tolerance/stress 사유를 대신 기록한다고 명시한다.
- 이후 reference model에는 canonical file names, metadata.json, README.md를 요구한다.
- displacement, reaction, section resultant coverage와 HDF5 dataset/CSV/component/tolerance를
연결하는 Coverage Matrix를 작성한다. Stress comparison은 N/A지만 output unit/analytical
verification을 연결한다.
- artifact 상태를 실제 파일 inventory에 따라 기록하되 reference 값을 재계산하지 않는다.
## Acceptance Criteria
```powershell
$path = 'docs/reference-models/linear-static-3d-euler-beam-reference-models.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$artifacts = @(
'reference/cantilever beam/cantilever beam.inp',
'reference/cantilever beam/cantilever beam displacements.csv',
'reference/cantilever beam/cantilever beam reactions.csv',
'reference/cantilever beam/cantilever beam elemental forces.csv'
)
foreach ($artifact in $artifacts) {
if (-not (Test-Path $artifact)) { throw "Missing approved artifact: $artifact" }
if (-not (Select-String -LiteralPath $path -SimpleMatch $artifact -Quiet)) {
throw "Artifact is not inventoried: $artifact"
}
}
$required = @('status: `ready-for-implementation-planning`', 'cantilever-beam-b33',
'2b34d0b', 'abaqus-cae-report-csv-v0', 'stress', 'N/A', '## Coverage Matrix')
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing reference contract: $text"
}
}
git diff --check -- $path
git diff --exit-code -- reference/
```
## 검증 절차
1. Acceptance Criteria 명령을 실행한다.
2. 네 legacy artifact가 exact path로만 참조되고 rename 제안이 없는지 확인한다.
3. 모든 must requirement가 model/test/quantity 또는 명시적 N/A에 연결되는지 확인한다.
4. Step 5를 `completed`와 inventory summary로 갱신한다. artifact 필수 조건 불충족은
승인된 legacy 예외를 먼저 적용한 뒤 실제 결함만 `blocked`로 기록한다.
## 금지사항
- Abaqus나 다른 reference solver를 실행하지 마라. 이유: 이 step은 계약만 준비한다.
- `/reference/` 아래 어떤 파일도 생성·수정·rename하지 마라. 이유: baseline은 read-only다.
- legacy bundle에 metadata/README/stress CSV를 요구해 차단하지 마라. 이유: 승인된 예외다.
- reference comparison을 수행하거나 pass를 선언하지 마라. 이유: solver result가 아직 없다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
@@ -0,0 +1,97 @@
# Step 6: Implementation Plan
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-planning-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 스킬의 planning workflow를 끝까지 읽고 코드나 테스트를 작성하지 않은 채 계획만 작성하라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/SOLVER_AGENT_DESIGN.md`
- `/docs/implementation-plans/README.md`
- `/docs/build-test-reports/README.md`
- `/docs/corrections/README.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/research/linear-static-3d-euler-beam-research.md`
- `/docs/formulations/3d-isoparametric-euler-beam-formulation.md`
- `/docs/numerical-reviews/linear-static-3d-euler-beam-review.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/reference-models/linear-static-3d-euler-beam-reference-models.md`
- `/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
- `/phases/linear-static-3d-euler-beam/step7.md`부터 `/step24.md`까지
## 작업
`docs/implementation-plans/linear-static-3d-euler-beam.md`를 생성하라. 승인 설계가 이
경로를 명시하므로 README의 기본 suffix보다 이 경로를 우선한다.
- Metadata와 Readiness Check를 작성하고 upstream status가 모두 준비된 경우
`status: ready-for-implementation`을 사용한다.
- Implementation Scope와 Non-goals를 승인 설계와 동일하게 기록한다.
- Step 724 각각을 독립 Work Breakdown task로 매핑하고 exact candidate source/header,
test, CMake file을 제시한다. 한 file은 한 책임을 가져야 한다.
- 각 task에 consumes/produces signature를 정의한다. 특히 `Vector`, row-major `Matrix`,
CSR `SparseMatrix`, `Domain`, `AnalysisModel`, `DofManager`, `AnalysisState`,
`EulerBeam3D`, `ParallelFor`, `LinearSolver`, `ResultsWriter`, orchestration API를 일관되게 쓴다.
- 각 production task에 GoogleTest test ID, RED condition, GREEN condition, targeted CTest
regex, full VERIFY command를 연결한다.
- parser negative cases, beam invariants/analytical cases, deterministic CSR, nonzero
prescribed displacement, PARDISO repeated RHS/singular diagnostics, HDF5 atomicity,
CLI/reference integration을 빠짐없이 배치한다.
- Requirement-to-task/test/reference Acceptance Traceability Matrix와 implementation report
evidence 형식을 포함한다.
- Step 24에서 test-only reference comparison executable/test를 완성해 Step 26이 source/test
변경 없이 다시 실행하고 report를 작성할 수 있게 계획한다.
- reference artifact, upstream contract, tolerance를 변경하는 correction을 금지한다.
## Acceptance Criteria
```powershell
$path = 'docs/implementation-plans/linear-static-3d-euler-beam.md'
if (-not (Test-Path $path)) { throw "Missing $path" }
$required = @(
'status: `ready-for-implementation`',
'## Readiness Check',
'## Work Breakdown',
'## TDD Test Plan',
'## CMake and CTest Plan',
'## Acceptance Traceability Matrix',
'cmake -S . -B .harness/build -A x64',
'ctest --test-dir .harness/build -C Debug --output-on-failure',
'reference/cantilever beam/'
)
foreach ($text in $required) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $text -Quiet)) {
throw "Missing implementation-plan contract: $text"
}
}
$modules = @('cmake-test-foundation','core-diagnostics','dense-math-adapters','domain-model',
'inp-syntax-parser','inp-domain-mapping','analysis-model','dof-manager','analysis-state',
'euler-beam-element','parallel-for-tbb','sparse-assembly','essential-constraints',
'mkl-pardiso-solver','load-assembly','result-recovery','hdf5-results-writer','linear-static-cli')
foreach ($module in $modules) {
if (-not (Select-String -LiteralPath $path -SimpleMatch $module -Quiet)) {
throw "Missing work-breakdown module: $module"
}
}
git diff --check -- $path
```
## 검증 절차
1. Acceptance Criteria 명령을 실행한다.
2. 모든 must requirement가 최소 한 task와 test에 연결되는지 확인한다.
3. later task가 사용하는 type/signature가 earlier task 정의와 정확히 같은지 대조한다.
4. 각 production task에 RED/GREEN/VERIFY command가 있고 reference step이 read-only인지 확인한다.
5. Step 6을 `completed`와 plan readiness summary로 갱신한다. upstream gate 미통과는
`blocked`, 반복 작성 실패는 `error`로 기록한다.
## 금지사항
- C++ source, test, CMake를 작성하거나 실행하지 마라. 이유: 이 step은 계획만 소유한다.
- upstream 요구조건·정식화·I/O·tolerance를 바꾸지 마라. 이유: 이미 승인된 계약이다.
- reference artifact를 생성·수정하지 마라. 이유: read-only baseline이다.
- API를 승인 문서와 모순되게 확정하지 마라. 이유: downstream task 간 계약이 깨진다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
+103
View File
@@ -0,0 +1,103 @@
# Step 7: CMake and GoogleTest Foundation
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
- 구현 전에 스킬과 Step 6 implementation plan을 끝까지 읽어라.
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md`
- `/docs/HARNESS_WORKFLOW.md`
- `/docs/HARNESS.md`
- `/CMakeLists.txt`가 이미 생겼다면 그 파일
## 소유 파일
- Create: `/CMakeLists.txt`
- Create: `/cmake/FesaDependencies.cmake`
- Create: `/include/fesa/build_info.hpp`
- Create: `/src/fesa/build_info.cpp`
- Create: `/src/fesa/CMakeLists.txt`
- Create: `/tests/CMakeLists.txt`
- Create: `/tests/unit/build_info_test.cpp`
- Create: `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
## 작업
MSVC x64 Debug에서 이후 모든 C++ step을 TDD로 실행할 최소 build/test foundation을
구현하라. Step 6이 정한 exact file layout을 우선하되 최소 책임은 다음과 같다.
- `CMakeLists.txt`: C++17, `enable_testing()`, FESA target 구성과 하위 CMake 진입점.
- `cmake/FesaDependencies.cmake`: cache variable `FESA_GTEST_SOURCE_DIR`을 검증하고
`C:/git/googletest`를 source tree로 받을 수 있게 한다. 이 절대경로를 default나
production source에 하드코딩하지 않는다. oneMKL, oneTBB, HDF5 CONFIG package를 찾고
dependency target 차이는 이 파일 안에서 정규화한다.
- `include/fesa/build_info.hpp`, `src/fesa/build_info.cpp`: HDF5 metadata가 재사용할
`std::string_view solverVersion() noexcept`의 최소 안정 API.
- `src/fesa/CMakeLists.txt`: `fesa_solver` static library와 FESA에만 `/W4 /WX` 적용.
- `tests/CMakeLists.txt`, `tests/unit/build_info_test.cpp`: GoogleTest 연결,
`gtest_discover_tests`, `BuildInfo` regex와 공통 `linear-static-3d-euler-beam` label을 가진
최소 제품 test. 이후 이 phase의 모든 CTest는 같은 공통 label을 상속한다.
- `docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`:
feature metadata, dependency/configure evidence와 Step 724별 RED/GREEN/VERIFY command,
exit code, 핵심 output, 변경 파일, requirement/test trace를 누적할 implementation report.
GoogleTest external target에는 `/W4 /WX`를 전파하지 않는다. MKL/TBB/HDF5 header나 type을
`build_info.hpp` 또는 다른 public header에 노출하지 않는다. 외부 checkout을 수정하거나
network fetch를 하지 않는다.
## Acceptance Criteria
먼저 `C:/git/googletest`의 revision을 read-only로 확인하라.
```powershell
if (-not (Test-Path 'C:/git/googletest/CMakeLists.txt')) { throw 'GoogleTest checkout is missing' }
$gtestRevision = git -C C:/git/googletest rev-parse HEAD
if ($gtestRevision -ne '04ee1b4f2aefdffb0135d7cf2a2c519fe50dabe4') {
throw "Unexpected GoogleTest revision: $gtestRevision"
}
```
구성·build·discovery·test를 실행한다.
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R BuildInfo --output-on-failure
$discovery = ctest --test-dir .harness/build -C Debug --show-only=json-v1 | ConvertFrom-Json
if ($discovery.tests.Count -lt 1) { throw 'CTest discovered zero tests' }
ctest --test-dir .harness/build -C Debug --output-on-failure
if (-not (Test-Path 'docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md')) {
throw 'Missing implementation evidence report'
}
```
## 검증 절차
1. build_info test를 먼저 작성하고 API가 없어 compile RED가 발생하는지 확인한 뒤
`build_info` production 파일을 추가한다.
2. 위 명령을 실행해 GREEN과 전체 VERIFY를 확인한다.
3. MSVC compiler metadata와 FESA target `/W4 /WX`, third-party warning 격리를 확인한다.
4. implementation report에 Step 7 RED/GREEN/VERIFY의 실제 command, exit code와 핵심
output을 기록한다.
5. Step 7을 `completed`로 바꾸고 build files, target names, dependency resolution을
`summary`에 기록한다. 설치 경로/환경이 실제로 없으면 `blocked`, 반복 구현 실패는
`error`로 기록한다.
## 금지사항
- dependency source를 vendor하거나 download하지 마라. 이유: 승인된 local install을 사용한다.
- GoogleTest 절대경로를 CMake default로 하드코딩하지 마라. 이유: cache variable 계약이다.
- FESA warning option을 third-party target에 적용하지 마라. 이유: 외부 코드 경고는 제품 책임이 아니다.
- 이후 solver module을 미리 만들지 마라. 이유: 이 step은 build/test foundation만 소유한다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
+109
View File
@@ -0,0 +1,109 @@
# Step 8: Core Diagnostics
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/io-definitions/linear-static-3d-euler-beam-io.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/build_info.hpp`
- `/src/fesa/CMakeLists.txt`
- `/tests/CMakeLists.txt`
## 소유 파일
- Create: `/include/fesa/core/source_identity.hpp`
- Create: `/include/fesa/core/diagnostic.hpp`
- Create: `/include/fesa/core/status.hpp`
- Create: `/src/fesa/core/diagnostic.cpp`
- Create: `/src/fesa/core/status.cpp`
- Create: `/tests/unit/core/source_identity_test.cpp`
- Create: `/tests/unit/core/diagnostic_test.cpp`
- Create: `/tests/unit/core/status_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
Step 6의 file plan을 따르며 core ID, source location, diagnostic, status/result type만 구현하라.
최소 public 계약은 아래 의미를 제공해야 한다.
```cpp
struct SourceLocation { std::filesystem::path file; std::size_t line; };
struct SourceEntityId { std::string instanceName; std::int64_t sourceLabel; };
enum class Severity { warning, error };
struct Diagnostic {
Severity severity;
std::string code;
SourceLocation location;
std::string keyword;
std::string entityIdentity;
std::string message;
};
class Status {
public:
static Status ok();
static Status failure(std::vector<Diagnostic> diagnostics);
bool isOk() const noexcept;
const std::vector<Diagnostic>& diagnostics() const noexcept;
};
template<class T> class Result;
```
`Result<T>`는 성공 value 또는 실패 `Status`를 소유하고 실패 value access를 거부한다.
Diagnostic ordering helper는 file, line, keyword, entity identity, code 순으로 stable하게
정렬한다. `core` public header는 MKL/TBB/HDF5에 의존하지 않는다.
위 exact 파일을 생성하고 각 production stem에 대응하는 test를 먼저 작성하라.
Test suite label/regex는
`CoreDiagnostics`로 식별 가능해야 한다.
## Acceptance Criteria
RED에서는 production 파일을 만들기 전에 다음 targeted command가 missing header/symbol로
실패하는 것을 확인하고 구현 report 또는 step summary용 evidence를 남긴다.
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R CoreDiagnostics --output-on-failure
```
구현 후 GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R CoreDiagnostics --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
```
Tests는 value/error exclusivity, move/copy, failed access, exact diagnostic fields와
deterministic ordering을 검증해야 한다.
## 검증 절차
1. GoogleTest를 먼저 추가하고 targeted RED를 관찰한다.
2. 최소 production 구현으로 targeted GREEN을 만든다.
3. 전체 MSVC x64 Debug build/CTest VERIFY를 실행한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 8 section에 실제 RED/GREEN/VERIFY command, exit code, 핵심 output과 변경 파일을 기록한다.
5. public header dependency를 검토하고 Step 8에 `completed`와 RED/GREEN/VERIFY 요약을 기록한다.
## 금지사항
- parser-specific keyword policy를 core에 넣지 마라. 이유: layer dependency를 역전시킨다.
- exception text에 backend-specific detail을 노출하지 마라. 이유: structured diagnostic이 계약이다.
- 기존 build/test 동작을 재구성하지 마라. 이유: Step 7 범위다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.
+113
View File
@@ -0,0 +1,113 @@
# Step 9: Dense Math Adapters
## 담당 역할과 필수 스킬
- 담당 역할: `implementation-agent`
- 필수 스킬: `fesa-cpp-msvc-tdd`
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
- `/docs/requirements/linear-static-3d-euler-beam.md`
- `/docs/implementation-plans/linear-static-3d-euler-beam.md`
- `/include/fesa/core/status.hpp`
- `/src/fesa/CMakeLists.txt`
- `/tests/CMakeLists.txt`
## 소유 파일
- Create: `/include/fesa/math/vector.hpp`
- Create: `/include/fesa/math/matrix.hpp`
- Create: `/src/fesa/math/vector.cpp`
- Create: `/src/fesa/math/matrix.cpp`
- Create: `/tests/unit/math/vector_test.cpp`
- Create: `/tests/unit/math/matrix_test.cpp`
- Modify: `/src/fesa/CMakeLists.txt`
- Modify: `/tests/CMakeLists.txt`
## 작업
연속 `double` storage를 소유하는 `Vector`와 row-major `Matrix`를 위 exact paths에
구현하라. Public 의미는 다음과 같아야 한다.
```cpp
class Vector {
public:
explicit Vector(std::size_t size, double value = 0.0);
std::size_t size() const noexcept;
double* data() noexcept;
const double* data() const noexcept;
double& operator[](std::size_t index);
const double& operator[](std::size_t index) const;
double dot(const Vector& rhs) const;
double norm() const;
void scale(double alpha);
void axpy(double alpha, const Vector& x);
};
class Matrix {
public:
Matrix(std::size_t rows, std::size_t columns, double value = 0.0);
std::size_t rows() const noexcept;
std::size_t columns() const noexcept;
double& operator()(std::size_t row, std::size_t column);
const double& operator()(std::size_t row, std::size_t column) const;
Vector multiply(const Vector& rhs) const;
Matrix multiply(const Matrix& rhs) const;
};
```
copy/move semantics를 검증하고 모든 index access는 bounds-checked여야 한다. dimension
mismatch는 `std::invalid_argument`, bounds 위반은 `std::out_of_range`로 일관되게 처리한다.
copy, dot, Euclidean norm, scale, axpy, GEMV, GEMM은 `.cpp` 내부 MKL CBLAS adapter를
사용한다. `mkl.h`, `MKL_INT`, `CBLAS_*`가 public header에 나타나면 안 된다.
Tests는 zero-size policy, ownership/deep-copy, move safety, bounds, mismatch, non-square
row-major GEMV/GEMM과 known BLAS values를 검증하고 `DenseMath` regex로 실행 가능하게 한다.
## Acceptance Criteria
RED targeted command:
```powershell
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R DenseMath --output-on-failure
```
GREEN/VERIFY:
```powershell
cmake -S . -B .harness/build -A x64 `
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R DenseMath --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
$leaks = rg -n "mkl\.h|MKL_INT|CBLAS_" include/fesa
if ($LASTEXITCODE -eq 0) { throw "MKL API leaked into public headers:`n$leaks" }
if ($LASTEXITCODE -ne 1) { throw 'Public-header dependency scan failed' }
```
마지막 `rg`는 no-match여야 한다.
## 검증 절차
1. `vector_test.cpp`, `matrix_test.cpp`를 먼저 작성하고 missing behavior RED를 확인한다.
2. 최소 adapter/ownership 구현으로 GREEN을 만든다.
3. 전체 MSVC x64 Debug VERIFY와 public-header dependency scan을 실행한다.
4. `/docs/implementation-plans/linear-static-3d-euler-beam-implementation-report.md`
Step 9 section에 실제 RED/GREEN/VERIFY command, exit code,
핵심 output과 변경 파일을 기록한다.
5. Step 9를 `completed`로 바꾸고 operations/test evidence를 summary에 기록한다.
## 금지사항
- `Matrix`를 sparse storage로 재사용하지 마라. 이유: CSR은 별도 타입이다.
- MKL type/header를 public API에 노출하지 마라. 이유: adapter boundary 계약이다.
- expression template이나 lazy evaluation을 추가하지 마라. 이유: 승인되지 않은 일반화다.
- 직접 commit하지 마라. 이유: Harness executor가 담당한다.