docs: add linear static beam harness phase
This commit is contained in:
@@ -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" }
|
||||
]
|
||||
}
|
||||
@@ -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 Euler–Bernoulli, 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을 Euler–Bernoulli 의미로 사용하는 근거
|
||||
- 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개 또는 2–4개 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 0–1 산출물과 완료 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으로 바꾼다.
|
||||
- Euler–Bernoulli 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 7–24 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 7–24 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 7–24 각각을 독립 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가 담당한다.
|
||||
@@ -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 7–24별 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가 담당한다.
|
||||
@@ -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가 담당한다.
|
||||
@@ -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가 담당한다.
|
||||
Reference in New Issue
Block a user