docs: add linear static beam harness phase
This commit is contained in:
+23
-7
@@ -34,23 +34,23 @@ FESA의 architecture decision은 solver correctness, verification traceability,
|
||||
**트레이드오프**: 초기 class 수가 늘어난다. Phase 1에서는 interface를 얇게 유지하고 displacement 중심 state부터 구현한다.
|
||||
|
||||
### 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를 안정적으로 표현한다.
|
||||
|
||||
**트레이드오프**: 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 경계 뒤에 둔다
|
||||
**결정**: `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가 어려워진다.
|
||||
|
||||
**트레이드오프**: 단일 기능만 구현할 때는 adapter가 다소 장황해 보일 수 있다. 하지만 solver backend와 result writer는 장기적으로 교체 가능해야 한다.
|
||||
**트레이드오프**: 단일 기능만 구현할 때는 adapter가 다소 장황해 보일 수 있다. Row-major dense storage와 CSR sparse storage를 따로 유지해야 하지만 backend 의존성과 dense/sparse 의미가 core 모델에 섞이지 않는다.
|
||||
|
||||
### 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만 둔다.
|
||||
|
||||
@@ -69,11 +69,11 @@ FESA의 architecture decision은 solver correctness, verification traceability,
|
||||
**트레이드오프**: 초기 병렬화 범위가 제한된다. MKL 내부 thread와 TBB task arena의 oversubscription 정책을 별도로 문서화해야 한다.
|
||||
|
||||
### 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 준비가 느려질 수 있다. 대신 검증 기준의 신뢰도와 감사 가능성이 높아진다.
|
||||
**트레이드오프**: reference 준비가 느려질 수 있다. Legacy 예외는 일반 artifact 규칙을 복잡하게 하지만 exact path와 source commit을 고정하고 read-only로 취급해 감사 가능성을 유지한다.
|
||||
|
||||
### ADR-011: 구형 단일 검증 진입점 계약을 폐기한다
|
||||
|
||||
@@ -88,3 +88,19 @@ FESA의 architecture decision은 solver correctness, verification traceability,
|
||||
**이유**: 테스트 파일 존재 검사, TDD 실행 증거, 전체 build/test는 서로 다른 책임이다. 이를 분리하면 Hook이 보장하는 범위를 과장하지 않으면서 Step 종료 시 green 상태를 강제할 수 있다.
|
||||
|
||||
**트레이드오프**: 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 Euler–Bernoulli 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을 포함하므로 Euler–Bernoulli 정식화와 의미가 다르다. 단일 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
@@ -11,6 +11,12 @@ FESA의 아키텍처 목표는 Abaqus `.inp` subset을 내부 semantic model로
|
||||
- incremental feature addition
|
||||
- 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
|
||||
src/
|
||||
@@ -31,9 +37,7 @@ src/
|
||||
analysis/ # static, modal, dynamic, nonlinear procedure drivers
|
||||
results/ # recovery, field/history output, diagnostics
|
||||
validation/ # comparison metrics and tolerance helpers
|
||||
math/
|
||||
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
|
||||
math/ # owning Vector, row-major Matrix, CSR SparseMatrix adapters
|
||||
tests/
|
||||
unit/
|
||||
integration/
|
||||
@@ -83,6 +87,57 @@ Runner는 `git add -A`를 사용하므로 clean worktree 또는 별도 Git workt
|
||||
- `results`는 HDF5 schema를 통해 nodal, element, integration-point, diagnostic output을 분리한다.
|
||||
- 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를 사용하며 축,
|
||||
두 방향 Euler–Bernoulli 굽힘과 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
|
||||
Domain
|
||||
@@ -159,8 +214,14 @@ Results
|
||||
|
||||
Vector
|
||||
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`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다.
|
||||
- `AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않고 참조 또는 id 기반 view로 구성한다.
|
||||
@@ -171,37 +232,46 @@ Matrix
|
||||
## 데이터 흐름
|
||||
```text
|
||||
Abaqus input file
|
||||
-> InputParser
|
||||
-> Domain 생성
|
||||
-> StepDefinition 루프
|
||||
-> AnalysisModel 생성
|
||||
-> DofManager로 자유도/방정식 번호 생성
|
||||
-> sparse pattern 생성
|
||||
-> Analysis 실행
|
||||
-> Assembler로 전역 행렬/벡터 조립
|
||||
-> BoundaryCondition 적용
|
||||
-> LinearSolver 또는 nonlinear/time integration loop
|
||||
-> AnalysisState 갱신
|
||||
-> ResultsWriter로 step/frame/history 저장
|
||||
-> 다음 step 진행
|
||||
-> syntax parse and semantic mapping
|
||||
-> immutable Domain 생성
|
||||
-> 단일 step AnalysisModel view 생성
|
||||
-> DofManager DOF/scatter map/sparse pattern 생성
|
||||
-> element stiffness 계산과 deterministic COO-to-CSR 조립
|
||||
-> free/constrained partition 생성
|
||||
-> LinearSolver::factorize(Kff)
|
||||
-> full nodal load vector 조립
|
||||
-> effective RHS = Ff - Kfc * dc
|
||||
-> LinearSolver::solve(rhs, df) substitution
|
||||
-> full displacement 복구
|
||||
-> reaction = K*d - F 및 element result 복구
|
||||
-> ResultsWriter로 results.h5 atomic finalization
|
||||
```
|
||||
|
||||
강성행렬 factorization은 하중벡터 조립보다 먼저 수행한다. 반력은 element end action의
|
||||
별도 합이 아니라 조립된 전체 residual에서 구한다.
|
||||
|
||||
## 해석 실행 흐름
|
||||
`Analysis::run()`은 Template Method로 다음 큰 흐름을 고정한다. 해석 종류별 class는 필요한 단계만 재정의한다.
|
||||
`Analysis::run()`은 Template Method로 다음 V0 흐름을 고정한다. 해석 종류별 class는
|
||||
승인된 procedure contract 안에서 필요한 단계만 재정의한다.
|
||||
|
||||
```text
|
||||
initialize
|
||||
buildAnalysisModel
|
||||
buildDofMap
|
||||
buildSparsePattern
|
||||
assemble
|
||||
applyBoundaryConditions
|
||||
solve
|
||||
updateState
|
||||
assembleStiffness
|
||||
partitionConstraints
|
||||
factorize
|
||||
assembleLoads
|
||||
formEffectiveRhs
|
||||
substitute
|
||||
reconstructDisplacement
|
||||
recoverResults
|
||||
writeResults
|
||||
```
|
||||
|
||||
비선형 정적해석은 이 흐름을 Newton-Raphson 반복 루프 안에서 사용하고, 동적해석은 time step/frame 루프 안에서 사용한다.
|
||||
비선형 정적 및 동적 해석은 V0 범위가 아니며 별도 ADR과 formulation을 승인한 뒤 이
|
||||
lifecycle의 확장 지점을 사용한다.
|
||||
|
||||
## 설계 패턴
|
||||
- Strategy Pattern: `Analysis`, `LinearSolver`, `TimeIntegrator`, `ConvergenceCriteria`를 교체 가능한 전략으로 둔다.
|
||||
@@ -213,10 +283,21 @@ writeResults
|
||||
|
||||
## Sparse Matrix Policy
|
||||
- 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으로 남긴다.
|
||||
- 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
|
||||
- 첫 번째 oneTBB 적용 지점은 element-local matrix/residual 계산이다.
|
||||
- 전역 sparse write는 thread-local buffer 또는 deterministic reduction으로 제한한다.
|
||||
@@ -227,10 +308,12 @@ writeResults
|
||||
/metadata
|
||||
/model/nodes
|
||||
/model/elements
|
||||
/steps/<step-name>/frames/<frame-id>/nodal/displacement
|
||||
/steps/<step-name>/frames/<frame-id>/nodal/reaction
|
||||
/steps/<step-name>/frames/<frame-id>/element/stress
|
||||
/steps/<step-name>/frames/<frame-id>/element/strain
|
||||
/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/stress_s11
|
||||
/diagnostics
|
||||
```
|
||||
|
||||
@@ -242,3 +325,35 @@ Schema requirements:
|
||||
- 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를 비교한다.
|
||||
- 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
@@ -18,31 +18,46 @@ FESA는 Abaqus `.inp` keyword subset을 입력으로 받아 유한요소법 기
|
||||
4. 요소, 재료, 경계조건, 하중의 runtime-polymorphic base interface
|
||||
5. sparse matrix pattern 생성, 전역 행렬/벡터 조립, 제약조건 적용
|
||||
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의 직접 비교
|
||||
9. CMake/MSVC/x64/Debug, CTest 기반 개발 검증
|
||||
|
||||
## V0 범위
|
||||
- 선형 정적 해석 파이프라인 구현
|
||||
- 첫 end-to-end 기능 후보: Isoparametric 3D Euler beam element
|
||||
- 승인된 첫 end-to-end 기능: 2절점 3D Euler–Bernoulli beam, Abaqus `TYPE=B33`
|
||||
- 입력 파일당 하나의 `*STEP, *STATIC`
|
||||
- 절점당 자유도 `[UX, UY, UZ, URX, URY, URZ]`
|
||||
- 축, 두 방향 굽힘, Saint-Venant 비틀림 및 선형 등방 탄성
|
||||
- 최소 Abaqus keyword subset:
|
||||
- `*HEADING`
|
||||
- `*NODE`
|
||||
- `*ELEMENT`
|
||||
- `*NSET`
|
||||
- `*ELSET`
|
||||
- `*PART`, `*END PART`
|
||||
- `*NODE`, `*ELEMENT, TYPE=B33`
|
||||
- `*NSET`, `*ELSET`, including `GENERATE`
|
||||
- `*MATERIAL`
|
||||
- `*ELASTIC`
|
||||
- `*Beam General Section`
|
||||
- `*BEAM GENERAL SECTION, SECTION=GENERAL`
|
||||
- `*SECTION POINTS`
|
||||
- `*ASSEMBLY`, `*END ASSEMBLY`
|
||||
- `*INSTANCE`, `*END INSTANCE`
|
||||
- `*BOUNDARY`
|
||||
- `*CLOAD`
|
||||
- `*STEP`
|
||||
- `*STATIC`
|
||||
- output request subset
|
||||
- `*STEP`, `*STATIC`, `*END STEP`
|
||||
- `*PREPRINT`, `*RESTART`, `*TRANSVERSE SHEAR STIFFNESS`, `*OUTPUT, FIELD`,
|
||||
`*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
|
||||
- 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
|
||||
- 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 |
|
||||
@@ -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-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-005 | FESA는 해석 중 변하는 물리량을 `AnalysisState`에 저장해야 한다. | displacement, force, residual, increment/iteration 상태가 step/frame 출력과 연결된다. | 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-007 | FESA는 Abaqus reference CSV rows와 비교 가능한 deterministic row mapping을 제공해야 한다. | displacement, reaction, internal force, stress 등 검증 물리량의 row identity와 tolerance source가 명확하다. | reference comparison report |
|
||||
| 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`로 저장해야 한다. | 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은 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-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-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를 검증한다.
|
||||
- reference test 결과는 deterministic해야 한다.
|
||||
- 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으로 보고한다.
|
||||
- oneMKL, oneTBB, HDF5는 CMake에서 명시 탐지하고 실패 원인을 분류한다.
|
||||
- 대규모 모델 성능 최적화보다 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가 승인되어 있다.
|
||||
5. Tests fail before implementation: C++/integration/reference test를 제품 코드보다 먼저 작성하고 같은 Step 안에서 RED 실패와 후속 GREEN 성공을 확인한다.
|
||||
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 기준 안에 있다.
|
||||
8. Physics sanity pass: equilibrium, reaction consistency, displacement direction, symmetry, stress sanity가 검토되어 있다.
|
||||
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, section-force consistency와 normalized residual이 검토되어 있다.
|
||||
9. Release readiness pass: acceptance traceability, known limitations, release notes draft가 준비되어 있다.
|
||||
|
||||
## 제외 사항
|
||||
- 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 직접 실행 자동화
|
||||
- Agent가 Abaqus reference CSV 파일을 임의 생성 또는 수정하는 작업
|
||||
- GUI 또는 postprocessor
|
||||
- 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 0–6.
|
||||
- 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 8–24 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 26–28 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.
|
||||
Reference in New Issue
Block a user