-
Notifications
You must be signed in to change notification settings - Fork 44
Observability: full observability check meshed network without voltage phasor #1136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Observability: full observability check meshed network without voltage phasor #1136
Conversation
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
…observability-check-meshed-network-without-voltage-phasor
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a comprehensive observability checking algorithm for meshed power grid networks without voltage phasor sensors. The implementation adds a spanning tree algorithm based on nodal measurements and connectivity analysis to determine network observability for non-radial (meshed) topologies.
- Adds new meshed network observability algorithm with spanning tree construction
- Introduces bidirectional neighbor network structure and connectivity status tracking
- Refactors existing functions for better organization and adds observability namespace
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
test_observability.cpp | Updates test calls to use new observability namespace |
observability.hpp | Core implementation with new meshed network algorithm, data structures, and refactored functions |
newton_raphson_se_solver.hpp | Updates observability check call to use new namespace |
iterative_linear_se_solver.hpp | Updates observability check call to use new namespace |
Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Outdated
Show resolved
Hide resolved
Signed-off-by: Jerry Guo <[email protected]>
Validation test case with meshed topology in |
Signed-off-by: Jerry Guo <[email protected]>
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Outdated
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Outdated
Show resolved
Hide resolved
|
||
ObservabilitySensorsResult result{.flow_sensors = std::vector<int8_t>(y_bus_structure.row_indptr.back(), 0), | ||
.voltage_phasor_sensors = std::vector<int8_t>(n_bus, 0), | ||
.bus_injections = std::vector<int8_t>(n_bus + 1, 0), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpick: The n+1
trick with the number of sensors at the n+1
spot might be useful for voltage_phasor_sensors
and flow_sensors
as well, since we count them anyway later on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably a good follow up, as it depends on what will happen with the radial check. Resolving for now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unresolving: I dont really like the n+1 trick. The extra .back() makes the intent really confusing. Why not have a counter within the struct itself?
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Outdated
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Outdated
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Outdated
Show resolved
Hide resolved
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Outdated
Show resolved
Hide resolved
for (auto& neighbour : local_neighbour_list[to_node].direct_neighbours) { | ||
if (neighbour.bus == from_node) { | ||
// Change to downstream connection (from from_node to to_node perspective) | ||
neighbour.status = ConnectivityStatus::node_downstream_measured; | ||
break; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This pattern happens a lot, maybe a good idea to make it a helper function.
power_grid_model_c/power_grid_model/include/power_grid_model/math_solver/observability.hpp
Outdated
Show resolved
Hide resolved
…ll-conditioned system / meshed Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
…ork-without-voltage-phasor
…-voltage-phasor' into feature/reconfigure-test-case-for-full-observability-check
// upper triangle for branch flow measurement | ||
for (Idx ybus_index = y_bus_structure.bus_entry[row] + 1; ybus_index != y_bus_structure.row_indptr[row + 1]; | ||
++ybus_index) { | ||
for (Idx ybus_index = current_bus_entry + 1; ybus_index != y_bus_structure.row_indptr[bus + 1]; ++ybus_index) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can fill the "expand_neighbour_list" info in this loop too using the col_indices
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See #1136 (comment)
This also contradicts the 'single responsibility' paradigm you are promoting.
}; | ||
Idx bus; // this bus index | ||
ConnectivityStatus status{ConnectivityStatus::has_no_measurement}; // this bus connectivity status | ||
std::vector<neighbour> direct_neighbours; // list of direct connected neighbours |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As discussed yesterday, we can store the neighbour list in YBusStructure order. Adding a note here, but lets think about it later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of scope here. And into future improvement ideas discussion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correction: the list is the product/output of a wrapper function/object in between the YBus and the Observability check module. Not in the YBus.
Signed-off-by: Jerry Guo <[email protected]>
…-voltage-phasor' into feature/reconfigure-test-case-for-full-observability-check
Signed-off-by: Jerry Guo <[email protected]>
…-voltage-phasor' into feature/reconfigure-test-case-for-full-observability-check
Signed-off-by: Jerry Guo <[email protected]>
…-voltage-phasor' into feature/reconfigure-test-case-for-full-observability-check
…-case-for-full-observability-check Observability: re-configure relevant test cases for full observability check
Signed-off-by: Jerry Guo <[email protected]>
Signed-off-by: Jerry Guo <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file was already reviewed. See #1139.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file was already reviewed. See #1139.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file was already reviewed. See #1139.
|
Implement Meshed Network Observability Check
Summary
This PR implements #1085 a comprehensive observability checking algorithm for meshed power grid networks without voltage phasor sensors. The implementation adds a spanning tree algorithm based on nodal measurements and connectivity analysis to determine network observability for non-radial (meshed) topologies.
Key Changes
Algorithm Implementation
New Spanning Tree Algorithm for Meshed Networks
sufficient_condition_meshed_without_voltage_phasor()
: Main entry point for meshed network observability checkingstarting_from_node()
: Core spanning tree construction algorithm that attempts to build a spanning tree using available measurementsprepare_starting_nodes()
: Smart starting point selection algorithm that prioritizes nodes without measurements and no edge measurementsData Structures
New Connectivity Status Enum
ConnectivityStatus
enum with 7 states to track measurement usage:is_not_connected
(-1): Not connected, redundanthas_no_measurement
(0): Connected but no measurement availablenode_measured
(0b010): Node has unused measurementnode_downstream_measured
(0b001): Branch discovered with downstream measurementnode_upstream_measured
(0b100): Branch discovered with upstream measurementbranch_native_measured
(0b111): Branch has its own measurement, unusedbranch_measured_used
(0b101): Branch measurement already usedNew Neighbor Network Structure
ObservabilityNNResult
: Represents network topology with direct neighbor connectionsexpand_neighbour_list()
Algorithm Features
Multi-Priority Spanning Tree Construction
Smart Measurement Reassignment
reassign_nodal_measurement()
: Dynamically reassigns nodal measurements during backtrackingRefactored Codfe
Enhanced Network Scanning
count_observability_sensors()
→scan_network_sensors()
Improved Function Organization
necessary_observability_condition()
→necessary_condition()
sufficient_observability_condition()
→sufficient_condition_radial_with_voltage_phasor()
observability
for better code organizationSome Performance Optimizations
Early Exit Conditions
bus_injections.back() > n_bus - 2
, network is immediately observablemax_iterations = n_bus²
Improvements
Variable Naming Consistency
row
→bus
for clarityn_bus
sizing