feat: add domain model foundation

This commit is contained in:
김경종
2026-06-08 16:40:04 +09:00
parent e4e2f57808
commit fdeac602f4
38 changed files with 2685 additions and 5 deletions
+60
View File
@@ -0,0 +1,60 @@
{
"project": "FESA Structural Solver",
"phase": "domain-model-foundation",
"steps": [
{
"step": 0,
"name": "domain-contract",
"status": "completed",
"summary": "Created the Domain model foundation implementation plan with ownership boundaries, TDD tasks, and validation commands."
},
{
"step": 1,
"name": "cmake-test-bootstrap",
"status": "completed",
"summary": "Added root CMake/CTest bootstrap for fesa_domain_tests and fixed validation CMake path resolution on Windows."
},
{
"step": 2,
"name": "core-id-types",
"status": "completed",
"summary": "Added ModelTypes.hpp with 64-bit ids and fixed six-DOF ordering covered by C++ tests."
},
{
"step": 3,
"name": "node-and-domain-storage",
"status": "completed",
"summary": "Implemented Node and Domain node storage with duplicate and missing lookup tests."
},
{
"step": 4,
"name": "element-definition-storage",
"status": "completed",
"summary": "Added MITC4 element definition storage with connectivity preservation and missing-node validation tests."
},
{
"step": 5,
"name": "model-attribute-storage",
"status": "completed",
"summary": "Added material, shell property, node set, and element set storage with duplicate and missing-reference tests."
},
{
"step": 6,
"name": "boundary-load-step-storage",
"status": "completed",
"summary": "Added boundary condition, nodal load, and linear static step storage with missing-reference tests."
},
{
"step": 7,
"name": "domain-invariants",
"status": "completed",
"summary": "Locked down const retrieval and failed-insert count stability with invariant tests."
},
{
"step": 8,
"name": "validation-report-handoff",
"status": "completed",
"summary": "Recorded build/test evidence, updated handoff docs, and marked the phase completed."
}
]
}
+77
View File
@@ -0,0 +1,77 @@
# Step 0: domain-contract
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/PLAN.md`
- `/docs/PROGRESS.md`
- `/docs/WORKNOTE.md`
- `/docs/AGENT_RULES.md`
- `/docs/PRD.md`
- `/docs/ADR.md`
- `/docs/ARCHITECTURE.md`
- `/docs/implementation-plans/README.md`
## Task
Create `/docs/implementation-plans/domain-model-foundation-implementation-plan.md`.
The document must define the first C++ implementation slice for the `Domain` model container. It must explicitly state:
- `Domain` owns parsed model definitions only.
- Included model definitions: nodes, elements, materials, shell properties, node sets, element sets, boundary conditions, nodal loads, and analysis step definitions.
- Excluded state: equation ids, sparse matrix state, displacement vectors, residuals, reactions, current time, iteration counters, and element integration point state.
- `DofManager` owns equation numbering.
- `AnalysisModel` owns step-local execution views.
- `AnalysisState` owns mutable solution and iteration state.
- All ids use signed 64-bit storage.
- Node DOF order is `U1, U2, U3, UR1, UR2, UR3`.
- Units are user-consistent and not enforced by `Domain`.
- No Abaqus, Nastran, reference solver, HDF5 result, MKL, or TBB behavior is implemented in this phase.
Use the implementation-plan README template. Set:
- `feature_id: domain-model-foundation`
- `status: ready-for-implementation`
- `owner_agent: implementation-planning-agent`
- `date: 2026-06-08`
Include a work breakdown and TDD test plan for the following downstream steps:
1. CMake/CTest bootstrap.
2. Core id and DOF types.
3. Node and node storage.
4. Element definition storage.
5. Material, property, and set storage.
6. Boundary condition, nodal load, and step storage.
7. Domain invariant tests.
8. Validation report and handoff.
## Tests To Write First
This is a documentation planning step. Do not write C++ production code in this step.
## Acceptance Criteria
Run:
```powershell
python -m unittest discover -s scripts -p "test_*.py"
python scripts/validate_workspace.py
```
The current repository may still take the no-CMake informational path until Step 1 creates CMake files.
Update `/phases/domain-model-foundation/index.json` step 0:
- On success: `"status": "completed"` and a one-line `"summary"`.
- On repeated failure: `"status": "error"` and a concrete `"error_message"`.
- On user decision needed: `"status": "blocked"` and a concrete `"blocked_reason"`.
## Do Not
- Do not create C++ headers, sources, tests, or CMake files in this step.
- Do not change requirements, formulation, I/O contracts, reference artifacts, or tolerance policy.
- Do not run Abaqus, Nastran, or any reference solver.
+70
View File
@@ -0,0 +1,70 @@
# Step 1: cmake-test-bootstrap
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/AGENT_RULES.md`
- `/docs/ADR.md`
- `/docs/ARCHITECTURE.md`
- `/docs/implementation-plans/domain-model-foundation-implementation-plan.md`
- `/phases/domain-model-foundation/index.json`
- `/phases/domain-model-foundation/step0.md`
## Task
Create the minimum C++17/MSVC/CMake/CTest project structure needed to run Domain tests.
Allowed files:
- Create `/CMakeLists.txt`
- Create `/include/fesa/core/.gitkeep` only if needed to preserve the directory before headers exist
- Create `/src/core/.gitkeep` only if needed to preserve the directory before sources exist
- Create `/tests/core/domain_bootstrap_test.cpp`
CMake requirements:
- `cmake_minimum_required(VERSION 3.20)`
- Project name: `FESA`
- Language: CXX
- Set C++ standard to 17 and require it.
- Create interface or library target `fesa_core`.
- Add include directory `/include`.
- Enable testing.
- Create test executable `fesa_domain_tests`.
- Register CTest name `domain.bootstrap`.
- Apply CTest labels `domain;core`.
## Tests To Write First
Write `/tests/core/domain_bootstrap_test.cpp` before adding any production C++ code. It should be a minimal self-contained executable with `main()` returning 0 only when the C++ test harness is running.
Example intended behavior:
```cpp
int main() {
return 0;
}
```
This step does not implement Domain behavior yet. The purpose is to prove the MSVC/CTest path exists.
## Acceptance Criteria
Run:
```powershell
cmake -S . -B build/msvc-debug -G "Visual Studio 17 2022" -A x64
cmake --build build/msvc-debug --config Debug
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain.bootstrap
python -m unittest discover -s scripts -p "test_*.py"
python scripts/validate_workspace.py
```
Update `/phases/domain-model-foundation/index.json` step 1 with `completed`, `error`, or `blocked`.
## Do Not
- Do not add Domain, Node, Element, solver, parser, MKL, TBB, or HDF5 implementation in this step.
- Do not add JavaScript, TypeScript, npm, or non-MSVC fallback tooling.
+76
View File
@@ -0,0 +1,76 @@
# Step 2: core-id-types
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/AGENT_RULES.md`
- `/docs/ADR.md`
- `/docs/ARCHITECTURE.md`
- `/docs/implementation-plans/domain-model-foundation-implementation-plan.md`
- `/CMakeLists.txt`
- `/tests/core/domain_bootstrap_test.cpp`
## Task
Introduce core id aliases and DOF ordering constants.
Allowed files:
- Create `/include/fesa/core/ModelTypes.hpp`
- Modify `/tests/core/domain_bootstrap_test.cpp` or create `/tests/core/model_types_test.cpp`
- Modify `/CMakeLists.txt` only to register the new test file if a separate test executable is created
Required API:
```cpp
namespace fesa::core {
using Id = std::int64_t;
using NodeId = Id;
using ElementId = Id;
using MaterialId = Id;
using PropertyId = Id;
using StepId = Id;
enum class Dof : std::uint8_t {
U1 = 0,
U2 = 1,
U3 = 2,
UR1 = 3,
UR2 = 4,
UR3 = 5
};
constexpr std::size_t kDofPerNode = 6;
}
```
## Tests To Write First
Write a failing C++ test that includes `fesa/core/ModelTypes.hpp` before creating the header.
The test must verify:
- `sizeof(fesa::core::Id) == 8`
- `kDofPerNode == 6`
- `Dof::U1` through `Dof::UR3` have ordinal values 0 through 5
Run the targeted CTest and verify it fails because the header is missing. Then implement the header.
## Acceptance Criteria
Run:
```powershell
cmake --build build/msvc-debug --config Debug
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain
python scripts/validate_workspace.py
```
Update `/phases/domain-model-foundation/index.json` step 2 with `completed`, `error`, or `blocked`.
## Do Not
- Do not add model storage in this step.
- Do not add equation numbering or solver state.
+63
View File
@@ -0,0 +1,63 @@
# Step 3: node-and-domain-storage
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/AGENT_RULES.md`
- `/docs/ADR.md`
- `/docs/ARCHITECTURE.md`
- `/docs/implementation-plans/domain-model-foundation-implementation-plan.md`
- `/include/fesa/core/ModelTypes.hpp`
- `/CMakeLists.txt`
## Task
Implement the first useful `Node` and `Domain` slice.
Allowed files:
- Create `/include/fesa/core/Node.hpp`
- Create `/include/fesa/core/Domain.hpp`
- Create `/src/core/Domain.cpp`
- Create or modify `/tests/core/domain_storage_test.cpp`
- Modify `/CMakeLists.txt` to compile the source and register the test
Required behavior:
- `Node` stores `NodeId` and three coordinates as `double`.
- `Domain::addNode(Node)` inserts a node.
- Duplicate node ids throw `std::invalid_argument`.
- `Domain::findNode(NodeId)` returns a pointer or `nullptr`.
- `Domain::node(NodeId)` returns a const reference or throws `std::out_of_range`.
- `Domain::nodeCount()` returns the stored node count.
- `Domain` must not expose mutable node references.
## Tests To Write First
Write failing tests before creating production headers/sources:
- Add and retrieve one node by id.
- Missing node returns `nullptr` from `findNode`.
- Missing node throws from `node`.
- Duplicate node id throws.
Run the targeted CTest and verify failure due to missing API. Then implement the minimal code.
## Acceptance Criteria
Run:
```powershell
cmake --build build/msvc-debug --config Debug
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain
python scripts/validate_workspace.py
```
Update `/phases/domain-model-foundation/index.json` step 3 with `completed`, `error`, or `blocked`.
## Do Not
- Do not add elements, materials, properties, sets, loads, or steps yet.
- Do not store equation ids, displacement vectors, residuals, reactions, or solver state.
+65
View File
@@ -0,0 +1,65 @@
# Step 4: element-definition-storage
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/AGENT_RULES.md`
- `/docs/ADR.md`
- `/docs/ARCHITECTURE.md`
- `/docs/implementation-plans/domain-model-foundation-implementation-plan.md`
- `/include/fesa/core/Domain.hpp`
- `/include/fesa/core/Node.hpp`
- `/include/fesa/core/ModelTypes.hpp`
- `/tests/core/domain_storage_test.cpp`
## Task
Add element definition storage without implementing element stiffness or MITC4 formulation.
Allowed files:
- Create `/include/fesa/core/ElementDefinition.hpp`
- Modify `/include/fesa/core/Domain.hpp`
- Modify `/src/core/Domain.cpp`
- Modify `/tests/core/domain_storage_test.cpp`
Required behavior:
- `ElementDefinition` stores `ElementId`, type enum/string for `MITC4`, four `NodeId` connectivity entries, and a `PropertyId`.
- `Domain::addElement(ElementDefinition)` inserts an element.
- Duplicate element ids throw `std::invalid_argument`.
- Element connectivity must contain exactly four node ids for the MITC4 definition.
- Adding an element with a missing node id throws `std::invalid_argument`.
- `Domain::findElement(ElementId)` returns pointer or `nullptr`.
- `Domain::element(ElementId)` returns const reference or throws `std::out_of_range`.
- `Domain::elementCount()` returns the stored element count.
## Tests To Write First
Write failing tests before production changes:
- Add an element with four existing nodes and retrieve connectivity in order.
- Duplicate element id throws.
- Element referencing a missing node throws.
- Missing element lookup follows the `findElement` and `element` contracts.
Run targeted CTest and verify RED before implementation.
## Acceptance Criteria
Run:
```powershell
cmake --build build/msvc-debug --config Debug
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain
python scripts/validate_workspace.py
```
Update `/phases/domain-model-foundation/index.json` step 4 with `completed`, `error`, or `blocked`.
## Do Not
- Do not implement element stiffness, Jacobians, shape functions, sparse assembly, or solver behavior.
- Do not add parser behavior.
+66
View File
@@ -0,0 +1,66 @@
# Step 5: model-attribute-storage
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/AGENT_RULES.md`
- `/docs/ADR.md`
- `/docs/ARCHITECTURE.md`
- `/docs/implementation-plans/domain-model-foundation-implementation-plan.md`
- `/include/fesa/core/Domain.hpp`
- `/include/fesa/core/ElementDefinition.hpp`
- `/tests/core/domain_storage_test.cpp`
## Task
Add minimal material, shell property, node set, and element set storage.
Allowed files:
- Create `/include/fesa/core/MaterialDefinition.hpp`
- Create `/include/fesa/core/PropertyDefinition.hpp`
- Modify `/include/fesa/core/Domain.hpp`
- Modify `/src/core/Domain.cpp`
- Modify `/tests/core/domain_storage_test.cpp`
Required behavior:
- `LinearElasticMaterialDefinition` stores material id, Young's modulus, and Poisson's ratio.
- `ShellPropertyDefinition` stores property id, material id, and thickness.
- `Domain` stores node sets and element sets by string name.
- Duplicate material ids, property ids, or set names throw `std::invalid_argument`.
- Adding a shell property with missing material id throws `std::invalid_argument`.
- Node sets can only reference existing nodes.
- Element sets can only reference existing elements.
- All retrieval APIs return const data.
## Tests To Write First
Write failing tests before production changes:
- Add material and shell property, then retrieve them.
- Duplicate material/property id throws.
- Shell property referencing missing material throws.
- Node set stores existing node ids in input order.
- Element set stores existing element ids in input order.
- Sets referencing missing ids throw.
Run targeted CTest and verify RED before implementation.
## Acceptance Criteria
Run:
```powershell
cmake --build build/msvc-debug --config Debug
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain
python scripts/validate_workspace.py
```
Update `/phases/domain-model-foundation/index.json` step 5 with `completed`, `error`, or `blocked`.
## Do Not
- Do not implement constitutive matrices, shell section stiffness, units conversion, or parser behavior.
+66
View File
@@ -0,0 +1,66 @@
# Step 6: boundary-load-step-storage
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/AGENT_RULES.md`
- `/docs/ADR.md`
- `/docs/ARCHITECTURE.md`
- `/docs/implementation-plans/domain-model-foundation-implementation-plan.md`
- `/include/fesa/core/Domain.hpp`
- `/include/fesa/core/ModelTypes.hpp`
- `/tests/core/domain_storage_test.cpp`
## Task
Add boundary condition, nodal load, and analysis step definition storage.
Allowed files:
- Create `/include/fesa/core/BoundaryCondition.hpp`
- Create `/include/fesa/core/LoadDefinition.hpp`
- Create `/include/fesa/core/StepDefinition.hpp`
- Modify `/include/fesa/core/Domain.hpp`
- Modify `/src/core/Domain.cpp`
- Modify `/tests/core/domain_storage_test.cpp`
Required behavior:
- A boundary condition stores node id, constrained `Dof`, and prescribed value.
- A nodal load stores node id, `Dof`, and value.
- A linear static step definition stores step id, name, boundary condition indices or ids, and load indices or ids.
- Adding BC/load for a missing node throws `std::invalid_argument`.
- Duplicate step ids throw `std::invalid_argument`.
- Stored BCs, loads, and steps are returned as const data.
## Tests To Write First
Write failing tests before production changes:
- Add and retrieve a boundary condition on an existing node.
- Add and retrieve a nodal load on an existing node.
- Missing-node BC/load throws.
- Add a linear static step referencing stored BC/load entries.
- Duplicate step id throws.
Run targeted CTest and verify RED before implementation.
## Acceptance Criteria
Run:
```powershell
cmake --build build/msvc-debug --config Debug
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain
python scripts/validate_workspace.py
```
Update `/phases/domain-model-foundation/index.json` step 6 with `completed`, `error`, or `blocked`.
## Do Not
- Do not apply boundary conditions to matrices.
- Do not compute reactions.
- Do not add solver state, displacements, equation ids, or sparse matrix behavior.
+61
View File
@@ -0,0 +1,61 @@
# Step 7: domain-invariants
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/AGENT_RULES.md`
- `/docs/ADR.md`
- `/docs/ARCHITECTURE.md`
- `/docs/implementation-plans/domain-model-foundation-implementation-plan.md`
- `/include/fesa/core/Domain.hpp`
- `/src/core/Domain.cpp`
- `/tests/core/domain_storage_test.cpp`
## Task
Add tests and small API cleanup to lock down `Domain` invariants.
Allowed files:
- Modify `/include/fesa/core/Domain.hpp`
- Modify `/src/core/Domain.cpp`
- Modify `/tests/core/domain_storage_test.cpp`
- Modify `/docs/implementation-plans/domain-model-foundation-implementation-plan.md` only if a test traceability table needs correction
Required invariants:
- `Domain` does not expose mutable references to stored objects.
- `Domain` has no equation id, displacement, residual, reaction, current time, iteration, sparse matrix, MKL, TBB, or HDF5 members.
- Retrieval does not create missing objects implicitly.
- Insert operations preserve input ids and ordering where the API promises ordering.
- Error types remain deterministic: duplicate ids use `std::invalid_argument`; missing required references use `std::invalid_argument`; direct missing lookup uses `std::out_of_range`.
## Tests To Write First
Write failing compile/runtime tests before API cleanup:
- A const `Domain` can retrieve model definitions.
- Missing direct lookup throws without changing counts.
- Failed insert due to missing reference does not change the relevant count.
- Existing node, element, material, property, set, BC, load, and step counts remain stable after failed inserts.
Run targeted CTest and verify RED before implementation.
## Acceptance Criteria
Run:
```powershell
cmake --build build/msvc-debug --config Debug
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain
python scripts/validate_workspace.py
```
Update `/phases/domain-model-foundation/index.json` step 7 with `completed`, `error`, or `blocked`.
## Do Not
- Do not add new solver features beyond invariant enforcement.
- Do not refactor unrelated files.
+63
View File
@@ -0,0 +1,63 @@
# Step 8: validation-report-handoff
## Read First
Read these files before editing:
- `/AGENTS.md`
- `/docs/AGENT_RULES.md`
- `/docs/build-test-reports/README.md`
- `/docs/PROGRESS.md`
- `/docs/WORKNOTE.md`
- `/phases/domain-model-foundation/index.json`
- All Domain files created by previous steps
## Task
Run final verification and write the handoff evidence.
Allowed files:
- Create `/docs/build-test-reports/domain-model-foundation-build-test.md`
- Modify `/docs/PROGRESS.md`
- Modify `/docs/WORKNOTE.md` only if a failed approach, environment issue, or trap was encountered
- Modify `/phases/domain-model-foundation/index.json`
- Modify `/phases/index.json`
The build/test report must include:
- command log summary with exit codes
- command discovery path
- configure/build/CTest status
- failure classification or `N/A`
- failed test inventory or `N/A`
- no-change assertion for reference artifacts and tolerance policies
## Tests To Write First
This is a validation/reporting step. Do not write new C++ production behavior.
## Acceptance Criteria
Run:
```powershell
git status --short --branch
git remote -v
python -m unittest discover -s scripts -p "test_*.py"
python scripts/validate_workspace.py
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R domain
git diff --check
```
Update:
- `/phases/domain-model-foundation/index.json` step 8 with `completed`, `error`, or `blocked`.
- `/phases/index.json` phase status to `completed` only if all steps are completed.
- `/docs/PROGRESS.md` with the executed validation evidence.
## Do Not
- Do not claim MITC4 implementation, numerical correctness, reference comparison success, or release readiness.
- Do not run Abaqus, Nastran, or any reference solver.
- Do not edit reference artifacts.
+8
View File
@@ -0,0 +1,8 @@
{
"phases": [
{
"dir": "domain-model-foundation",
"status": "completed"
}
]
}