add uncommitted files
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"project": "FESA",
|
||||
"phase": "domain-and-input-skeleton",
|
||||
"steps": [
|
||||
{
|
||||
"step": 0,
|
||||
"name": "semantic-domain-and-origin-types",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"step": 1,
|
||||
"name": "domain-validation",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"step": 2,
|
||||
"name": "abaqus-scoped-syntax-parser",
|
||||
"status": "pending"
|
||||
},
|
||||
{
|
||||
"step": 3,
|
||||
"name": "active-instance-domain-normalization",
|
||||
"status": "pending"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
# Step 0: Semantic Domain and Origin Types
|
||||
|
||||
## 읽어야 할 파일
|
||||
|
||||
- `/AGENTS.md`
|
||||
- `/docs/PRD.md`
|
||||
- `/docs/ARCHITECTURE.md`
|
||||
- `/docs/ADR.md`
|
||||
- `/docs/superpowers/specs/2026-07-29-abaqus-assembly-reference-design.md`
|
||||
- `/docs/superpowers/plans/2026-07-29-fesa-phase-1.md`
|
||||
- `/include/fesa/core/entity_id.hpp`
|
||||
- `/include/fesa/core/vec3.hpp`
|
||||
- `/include/fesa/core/diagnostic.hpp`
|
||||
|
||||
## 작업
|
||||
|
||||
정규화된 solver semantic model의 값 타입과 불변 조회 계약을 만든다.
|
||||
|
||||
- `include/fesa/model/` 아래 `ids.hpp`, `entity_origin.hpp`, `node.hpp`,
|
||||
`material.hpp`, `beam_section.hpp`, `beam_element.hpp`, `entity_set.hpp`,
|
||||
`step_definition.hpp`, `domain.hpp`를 만든다.
|
||||
- 핵심 타입:
|
||||
|
||||
```cpp
|
||||
struct EntityOrigin final {
|
||||
std::string part_name;
|
||||
std::string instance_name;
|
||||
std::int64_t local_label;
|
||||
};
|
||||
struct Node final { NodeId id; EntityOrigin origin; Vec3 position; };
|
||||
struct BeamElement final {
|
||||
ElementId id;
|
||||
EntityOrigin origin;
|
||||
std::array<NodeId, 2> nodes;
|
||||
MaterialId material;
|
||||
SectionId section;
|
||||
};
|
||||
```
|
||||
|
||||
- `BeamSection`은 \(A,I_y,I_z,J,A_{sy},A_{sz}\), orientation과 recovery point를
|
||||
가진다. 전단값 출처는 `enum class ShearPropertySource { input, phase1_default };`
|
||||
로 표현한다.
|
||||
- flat mesh는 빈 `part_name/instance_name`, 계층형 mesh는 실제 이름을 사용한다.
|
||||
- 먼저 값 보존과 origin 조회가 실패하는 테스트를 작성한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
```powershell
|
||||
cmake --build --preset windows-debug
|
||||
ctest --preset windows-debug -R "ModelTypes|EntityOrigin" --output-on-failure
|
||||
ctest --preset windows-debug --output-on-failure
|
||||
```
|
||||
|
||||
## 검증 절차
|
||||
|
||||
1. 테스트를 먼저 작성하고 compile failure를 확인한다.
|
||||
2. 저장과 읽기에 필요한 최소 API만 구현한다.
|
||||
3. `model` public header에 Abaqus/MKL/TBB/HDF5 타입이 없는지 확인한다.
|
||||
4. focused 및 전체 테스트를 실행하고 index를 갱신한다.
|
||||
|
||||
## 금지사항
|
||||
|
||||
- parser record를 `Domain`에 저장하지 마라. 이유: syntax/semantic 경계를 깨뜨린다.
|
||||
- 여러 Instance container를 만들지 마라. 이유: Phase 1은 단일 Instance다.
|
||||
- equation 번호를 Node/Element에 저장하지 마라. 이유: DofManager 책임이다.
|
||||
@@ -0,0 +1,63 @@
|
||||
# Step 1: Domain Validation
|
||||
|
||||
## 읽어야 할 파일
|
||||
|
||||
- `/AGENTS.md`
|
||||
- `/docs/PRD.md`
|
||||
- `/docs/ARCHITECTURE.md`
|
||||
- `/docs/ADR.md`
|
||||
- `/docs/superpowers/plans/2026-07-29-fesa-phase-1.md`
|
||||
- `/include/fesa/model/`
|
||||
- `/tests/unit/model/`
|
||||
|
||||
이전 step의 타입 이름과 필드를 변경하지 말고 builder validation을 추가하라.
|
||||
|
||||
## 작업
|
||||
|
||||
`DomainBuilder`가 모든 semantic entity를 검증한 뒤 불변 `Domain` 하나를 생성하게
|
||||
한다.
|
||||
|
||||
```cpp
|
||||
struct DomainBuildResult final {
|
||||
std::optional<Domain> domain;
|
||||
std::vector<Diagnostic> diagnostics;
|
||||
};
|
||||
|
||||
class DomainBuilder final {
|
||||
public:
|
||||
void add_node(Node);
|
||||
void add_material(IsotropicElastic);
|
||||
void add_section(BeamSection);
|
||||
void add_beam_element(BeamElement);
|
||||
void add_node_set(NodeSet);
|
||||
void add_element_set(ElementSet);
|
||||
void set_step(StepDefinition);
|
||||
[[nodiscard]] DomainBuildResult build() &&;
|
||||
};
|
||||
```
|
||||
|
||||
- 중복 internal ID, 중복 origin, missing reference, invalid \(E,\nu,A,I,J,A_s\),
|
||||
nonfinite 값, zero-length element, invalid orientation, section/material 누락,
|
||||
충돌 BC를 각각 실패 테스트로 먼저 작성한다.
|
||||
- 내부 dense lookup과 origin lookup을 만들되 public mutable access는 제공하지 않는다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
```powershell
|
||||
cmake --build --preset windows-debug
|
||||
ctest --preset windows-debug -R "DomainBuilder|DomainValidation" --output-on-failure
|
||||
ctest --preset windows-debug --output-on-failure
|
||||
```
|
||||
|
||||
## 검증 절차
|
||||
|
||||
1. 각 거부 조건의 실패 테스트를 먼저 확인한다.
|
||||
2. 하나의 오류가 다른 오류를 숨기지 않도록 가능한 진단을 수집한다.
|
||||
3. valid Domain test와 전체 CTest를 실행한다.
|
||||
4. index summary에 검증 규칙과 생성 파일을 기록한다.
|
||||
|
||||
## 금지사항
|
||||
|
||||
- 잘못된 입력값을 자동 보정하지 마라. 이유: explicit diagnostic 계약을 위반한다.
|
||||
- solver 또는 parser validation을 이 builder에 넣지 마라. 이유: 모듈 책임이 다르다.
|
||||
- mutable Domain accessor를 추가하지 마라. 이유: 해석 중 모델 불변성을 깨뜨린다.
|
||||
@@ -0,0 +1,74 @@
|
||||
# Step 2: Abaqus Scoped Syntax Parser
|
||||
|
||||
## 읽어야 할 파일
|
||||
|
||||
- `/AGENTS.md`
|
||||
- `/docs/PRD.md`
|
||||
- `/docs/ARCHITECTURE.md`
|
||||
- `/docs/ADR.md`
|
||||
- `/docs/superpowers/specs/2026-07-29-abaqus-assembly-reference-design.md`
|
||||
- `/docs/superpowers/plans/2026-07-29-fesa-phase-1.md`
|
||||
- `/include/fesa/core/source_location.hpp`
|
||||
- `/include/fesa/core/diagnostic.hpp`
|
||||
|
||||
## 작업
|
||||
|
||||
Abaqus keyword를 해석하지 않고 scope가 보존된 syntax tree로 읽는 parser를 만든다.
|
||||
|
||||
```cpp
|
||||
struct DeckRecord final {
|
||||
std::string keyword;
|
||||
std::map<std::string, std::string, std::less<>> parameters;
|
||||
std::vector<std::vector<std::string>> data;
|
||||
SourceLocation source;
|
||||
};
|
||||
struct ParsedPart final {
|
||||
std::string name;
|
||||
std::vector<DeckRecord> records;
|
||||
SourceLocation source;
|
||||
};
|
||||
struct ParsedInstance final {
|
||||
std::string name;
|
||||
std::string part_name;
|
||||
std::vector<std::vector<std::string>> transform_data;
|
||||
SourceLocation source;
|
||||
};
|
||||
struct ParsedAssembly final {
|
||||
std::string name;
|
||||
std::vector<ParsedInstance> instances;
|
||||
std::vector<DeckRecord> records;
|
||||
SourceLocation source;
|
||||
};
|
||||
struct ParsedDeck final {
|
||||
std::vector<DeckRecord> global_records;
|
||||
std::vector<ParsedPart> parts;
|
||||
std::optional<ParsedAssembly> assembly;
|
||||
};
|
||||
[[nodiscard]] ParseDeckResult parse_deck(const std::filesystem::path&);
|
||||
```
|
||||
|
||||
- flat fixture와 단일 Part/Assembly/Instance fixture를 먼저 만든다.
|
||||
- case-insensitive keyword, comment, blank line, comma field, UTF-8, source line,
|
||||
scope 종료 오류를 테스트한다.
|
||||
- 이 step은 syntax만 파싱하며 active Part를 선택하지 않는다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
```powershell
|
||||
cmake --build --preset windows-debug
|
||||
ctest --preset windows-debug -R "AbaqusParser|ScopedDeck" --output-on-failure
|
||||
ctest --preset windows-debug --output-on-failure
|
||||
```
|
||||
|
||||
## 검증 절차
|
||||
|
||||
1. parser test를 작성하고 실패를 확인한다.
|
||||
2. `io/abaqus`에 lexer/parser만 최소 구현한다.
|
||||
3. source location과 scope tree를 assertion한다.
|
||||
4. 전체 테스트 후 index를 갱신한다.
|
||||
|
||||
## 금지사항
|
||||
|
||||
- Domain을 생성하지 마라. 이유: 다음 semantic normalization step의 책임이다.
|
||||
- unknown keyword를 일반적으로 무시하지 마라. 이유: 명시적 입력 계약을 훼손한다.
|
||||
- Instance 변환을 적용하지 마라. 이유: Phase 1에서 거부할 syntax 정보로 보존한다.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Step 3: Active Instance Domain Normalization
|
||||
|
||||
## 읽어야 할 파일
|
||||
|
||||
- `/AGENTS.md`
|
||||
- `/docs/PRD.md`
|
||||
- `/docs/ARCHITECTURE.md`
|
||||
- `/docs/ADR.md`
|
||||
- `/docs/superpowers/specs/2026-07-29-abaqus-assembly-reference-design.md`
|
||||
- `/include/fesa/model/domain_builder.hpp`
|
||||
- `/include/fesa/io/abaqus/deck_record.hpp`
|
||||
- `/include/fesa/io/abaqus/parser.hpp`
|
||||
- `/tests/fixtures/abaqus/minimal_cantilever.inp`
|
||||
- `/tests/fixtures/abaqus/minimal_part_instance_cantilever.inp`
|
||||
|
||||
## 작업
|
||||
|
||||
flat 또는 단일 무변환 Instance 입력을 동일한 `Domain`으로 변환한다.
|
||||
|
||||
```cpp
|
||||
[[nodiscard]] DomainBuildResult map_deck_to_domain(const ParsedDeck& deck);
|
||||
```
|
||||
|
||||
- 먼저 두 fixture가 동등한 활성 절점·요소·재료·단면·하중·BC를 만드는 통합
|
||||
테스트를 작성한다.
|
||||
- 계층형 deck은 정확히 하나의 Assembly와 Instance를 요구한다.
|
||||
- transform data가 있거나 Part reference가 없으면 source diagnostic을 반환한다.
|
||||
- Instance가 참조하지 않는 Part는 Domain에 포함하지 않는다.
|
||||
- origin에는 실제 Part/Instance/local label을 보존한다.
|
||||
- 전단강성이 없으면 \(A_{sy}=A_{sz}=5A/6\), `SCF=0`,
|
||||
`ShearPropertySource::phase1_default`를 사용한다.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
```powershell
|
||||
cmake --build --preset windows-debug
|
||||
ctest --preset windows-debug -R "DeckToDomain|ActiveInstance" --output-on-failure
|
||||
ctest --preset windows-debug --output-on-failure
|
||||
```
|
||||
|
||||
## 검증 절차
|
||||
|
||||
1. public parser와 mapper를 사용하는 실패 테스트를 확인한다.
|
||||
2. syntax record를 복제해 Domain에 저장하지 않고 semantic 값으로 변환한다.
|
||||
3. unreferenced Part exclusion과 provenance를 assertion한다.
|
||||
4. focused/full test 후 index summary를 갱신한다.
|
||||
|
||||
## 금지사항
|
||||
|
||||
- 여러 Instance를 평탄화하지 마라. 이유: Phase 1 범위 밖이다.
|
||||
- 변환 좌표를 조용히 무시하지 마라. 이유: 잘못된 해석 모델을 만든다.
|
||||
- 테스트에서 Domain을 직접 구성하지 마라. 이유: production 경로를 우회한다.
|
||||
Reference in New Issue
Block a user