Fix bugs from 5-2 code review

This commit is contained in:
Sepehr
2026-02-21 10:43:55 +01:00
parent 400f1c420e
commit 0d9a0e4231
27 changed files with 9838 additions and 114 deletions

View File

@@ -1,6 +1,6 @@
# Story 3.6: Hierarchical Subsystems (MacroComponents)
Status: ready-for-dev
Status: done
## Story
@@ -31,24 +31,25 @@ so that I can compose larger models (like buildings or parallel chiller plants)
4. **Serialization and Persistence** (AC: #4)
- Given a `System` that contains `MacroComponent`s
- When serializing the system to JSON
- Then the internal topology of the `MacroComponent` is preserved and can be deserialized perfectly
- ~~Then the internal topology of the `MacroComponent` is preserved and can be deserialized perfectly~~ (Moved to Future Scope: Serialization not natively supported yet)
## Tasks / Subtasks
- [ ] Define `MacroComponent` struct in `crates/components/src/macro_component.rs` (AC: #1)
- [ ] Store internal `System`
- [ ] Store `port_mapping` dictionary
- [ ] Implement `Component` trait for `MacroComponent` (AC: #1, #3)
- [ ] Implement `get_ports` returning mapped external ports
- [ ] Implement `compute_residuals` by delegating to internal components
- [ ] Implement `jacobian_entries` by offsetting indices and delegating to internal components
- [ ] Implement `n_equations` returning the sum of internal equations
- [ ] Implement external port bounding/mapping logic (AC: #2)
- [ ] Create API for `expose_port(internal_node_id, external_port_name)`
- [ ] Integration Tests (AC: #1-#3)
- [ ] Test encapsulating a 4-component cycle into a single `MacroComponent`
- [ ] Test connecting two identical `MacroComponent` chillers in parallel inside a higher-level `System`
- [ ] Assert global convergence works simultaneously.
- [x] Define `MacroComponent` struct in `crates/solver/src/macro_component.rs` (AC: #1)
- [x] Store internal `System`
- [x] Store `port_mapping` dictionary
- [x] Implement `Component` trait for `MacroComponent` (AC: #1, #3)
- [x] Implement `get_ports` returning mapped external ports
- [x] Implement `compute_residuals` by delegating to internal components
- [x] Implement `jacobian_entries` by offsetting indices and delegating to internal components
- [x] Implement `n_equations` returning the sum of internal equations
- [x] Implement external port bounding/mapping logic (AC: #2)
- [x] Create API for `expose_port(internal_edge_pos, name, port)`
- [x] Integration Tests (AC: #1-#3)
- [x] Test encapsulating a 4-component cycle into a single `MacroComponent`
- [x] Test connecting two identical `MacroComponent` chillers in parallel inside a higher-level `System`
- [x] Assert global convergence works simultaneously.
- [ ] Create Action Item: Implement fully recursive `serde` serialization for `MacroComponent` topologies.
## Dev Notes
@@ -72,10 +73,49 @@ This story adds the capability to wrap topologies into sub-blocks.
### Code Structure
- Create `crates/components/src/macro_component.rs`.
- May require slight structural adjustments to `crates/solver/src/system.rs` if `System` doesn't currently support being completely embedded.
- Created `crates/solver/src/macro_component.rs` (placed in solver crate to avoid circular dependency with components crate).
- No structural adjustments to `crates/solver/src/system.rs` were required — `System` already supports complete embedding.
### Developer Context
The main complexity of this story lies in **index mapping**. When the global `System` builds the solver state vector (P, h for each edge), the `MacroComponent` must correctly map its internal edges to the global state vector slices provided in `compute_residuals(&self, state: &SystemState, ...)`.
Consider building an initialization step where `MacroComponent` is informed of its global state offsets before solving begins.
An initialization step via `set_global_state_offset()` allows the parent system to inform the `MacroComponent` of its global state offsets before solving begins.
## Dev Agent Record
### Implementation Plan
- Created `MacroComponent` struct in `crates/solver/src/macro_component.rs`
- `MacroComponent` wraps a finalized `System` and implements the `Component` trait
- Residual computation delegates to the internal `System::compute_residuals()` with a state slice extracted via `global_state_offset`
- Jacobian entries are collected from `System::assemble_jacobian()` and column indices are offset by `global_state_offset`
- External ports are exposed via `expose_port(internal_edge_pos, name, port)` API
- Port mappings stored as ordered `Vec<PortMapping>`, providing `get_ports()` for the Component trait
### Completion Notes
- ✅ AC #1: MacroComponent implements Component trait — verified via `test_macro_component_as_trait_object` and `test_macro_component_creation`
- ✅ AC #2: External port mapping works — verified via `test_expose_port`, `test_expose_multiple_ports`, `test_expose_port_out_of_range`
- ✅ AC #3: Residual and Jacobian delegation works — verified via `test_compute_residuals_delegation`, `test_compute_residuals_with_offset`, `test_jacobian_entries_delegation`, `test_jacobian_entries_with_offset`
- ✅ Integration: MacroComponent placed inside parent System — verified via `test_macro_component_in_parent_system`
- AC #4 (Serialization): Not implemented — requires serde derives on System, which is a separate concern. Story scope focused on runtime behavior.
- MacroComponent placed in `entropyk-solver` crate (not `entropyk-components`) to avoid circular dependency since it depends on `System`.
- ⚠️ **Code Review Fix (2026-02-21):** Corrected `System::state_vector_len` and `System::finalize` offset computation bug where multiple MacroComponents were assigned overlapping indices.
- ⚠️ **Code Review Fix (2026-02-21):** Added `internal_state_len` to Component trait.
- 12 unit tests pass, 130+ existing solver tests pass, 18 doc-tests pass, 0 regressions.
## File List
*(Note: During implementation, numerous other files outside the strict scope of this Story (e.g. inverse control, new flow components) were brought in or modified; those are tracked by their respective stories, but are present in the current git diff).*
- `crates/solver/src/macro_component.rs` (NEW)
- `crates/solver/tests/macro_component_integration.rs` (NEW)
- `crates/components/src/lib.rs` (MODIFIED — added internal_state_len)
- `crates/solver/src/system.rs` (MODIFIED — fixed global_state_offset logic)
- `crates/solver/src/lib.rs` (MODIFIED)
## Change Log
- 2026-02-21: Code review conducted. Fixed critical state overlap bug in `system.rs` for multiple `MacroComponents`. AC #4 deferred to future scope.
- 2026-02-20: Implemented MacroComponent struct with Component trait, port mapping API, 12 unit tests. All tests pass.

View File

@@ -1,5 +1,5 @@
# Sprint Status - Entropyk
# Generated: 2026-02-13
# Last Updated: 2026-02-21
# Project: Entropyk
# Project Key: NOKEY
# Tracking System: file-system
@@ -53,6 +53,8 @@ development_status:
1-8-auxiliary-and-transport-components: done
1-9-air-coils-evaporator-condenser: done
1-10-pipe-helpers-water-refrigerant: done
1-11-flow-junction-splitter-merger: done
1-12-flow-boundary-source-sink: done
epic-1-retrospective: optional
# Epic 2: Fluid Properties Backend
@@ -64,6 +66,7 @@ development_status:
2-5-mixture-and-temperature-glide-support: done
2-6-critical-point-damping-co2-r744: done
2-7-incompressible-fluids-support: done
2-8-rich-thermodynamic-state-abstraction: done
epic-2-retrospective: optional
# Epic 3: System Topology (Graph)
@@ -73,7 +76,7 @@ development_status:
3-3-multi-circuit-machine-definition: done
3-4-thermal-coupling-between-circuits: done
3-5-zero-flow-branch-handling: done
3-6-hierarchical-macro-components: ready-for-dev
3-6-hierarchical-macro-components: done
epic-3-retrospective: optional
# Epic 4: Intelligent Solver Engine
@@ -89,11 +92,12 @@ development_status:
epic-4-retrospective: optional
# Epic 5: Inverse Control & Optimization
epic-5: backlog
5-1-constraint-definition-framework: backlog
5-2-bounded-control-variables: backlog
5-3-residual-embedding-for-inverse-control: backlog
epic-5: in-progress
5-1-constraint-definition-framework: done
5-2-bounded-control-variables: done
5-3-residual-embedding-for-inverse-control: review
5-4-multi-variable-control: backlog
5-5-swappable-calibration-variables: backlog
epic-5-retrospective: optional
# Epic 6: Multi-Platform APIs