Skip to content

feat: implement non linear pst#615

Open
BenjPetr wants to merge 8 commits into
mainfrom
feat/implement_non_linear_pst
Open

feat: implement non linear pst#615
BenjPetr wants to merge 8 commits into
mainfrom
feat/implement_non_linear_pst

Conversation

@BenjPetr

@BenjPetr BenjPetr commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Signed-off-by: Benjamin Petrick 170433522+BenjPetr@users.noreply.github.com

Checklist

Please check if the PR fulfills these requirements:

  • PR Title follows conventional commit messages
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • All commits in this PR are DCO signed-off (see CONTRIBUTING.md)

Does this PR already have an issue describing the problem?

Fixes #

What is the new behavior (if this is a feature change)?

Does this PR introduce a breaking change?

  • Yes
  • No

BenjPetr added 2 commits July 6, 2026 18:09
Signed-off-by: Benjamin Petrick <170433522+BenjPetr@users.noreply.github.com>
Signed-off-by: Benjamin Petrick <170433522+BenjPetr@users.noreply.github.com>
Comment thread packages/dc_solver_pkg/src/toop_engine_dc_solver/jax/nodal_inj_optim.py Outdated
BenjPetr added 2 commits July 9, 2026 18:13
…ic_flows() as part of an action

Signed-off-by: Benjamin Petrick <170433522+BenjPetr@users.noreply.github.com>
… anything anymore

Signed-off-by: Benjamin Petrick <170433522+BenjPetr@users.noreply.github.com>
@BenjPetr BenjPetr marked this pull request as ready for review July 9, 2026 17:22
Copilot AI review requested due to automatic review settings July 9, 2026 17:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 adds runtime support for non-linear phase-shifting transformers (PSTs) in the DC solver by introducing per-tap branch-parameter (susceptance) handling, along with a small terminology cleanup in the topology optimizer where PST-related results are renamed for clarity.

Changes:

  • Add backend + preprocessing support for per-tap PST susceptance and keep non-linear PSTs controllable through preprocessing.
  • Introduce JAX-side PST helpers and a low-rank PTDF update path for tap-dependent branch-parameter changes.
  • Rename nodal_injections_optimizedpst_tap_results across topology optimizer + solver outputs and update tests accordingly.

Reviewed changes

Copilot reviewed 29 out of 29 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/topology_optimizer_pkg/tests/dc/repertoire/test_discrete_me_repertoire.py Updates genotype construction to use pst_tap_results.
packages/topology_optimizer_pkg/tests/dc/repertoire/test_discrete_map_elites.py Updates PST optimization assertions/accessors to pst_tap_results.
packages/topology_optimizer_pkg/tests/dc/genetic_functions/test_initialization.py Adjusts test genotypes to use pst_tap_results.
packages/topology_optimizer_pkg/tests/dc/genetic_functions/test_evolution_functions.py Updates deduplication-related assertions for PST results.
packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/scoring_functions.py Propagates PST tap results through scoring + topology conversion.
packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/mutation/mutate.py Mutations now thread through pst_tap_results.
packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/genotype.py Renames genotype field and keeps PST taps in deduplication.
packages/topology_optimizer_pkg/src/toop_engine_topology_optimizer/dc/genetic_functions/crossover.py Carries PST tap results through crossover.
packages/interfaces_pkg/src/toop_engine_interfaces/backend.py Adds default interface method to provide per-tap susceptance values.
packages/dc_solver_pkg/tests/preprocessing/test_preprocess.py Updates expectations: non-linear PSTs remain controllable.
packages/dc_solver_pkg/tests/postprocessing/test_validate_loadflow_results.py Adds validation coverage for non-linear PST tap scenarios.
packages/dc_solver_pkg/tests/postprocessing/test_postprocess_powsybl.py Expands PST validation to cover non-linear PST grids and scenarios.
packages/dc_solver_pkg/tests/jax/test_pst.py New focused tests for PST helper logic (linear, parallel, non-linear).
packages/dc_solver_pkg/tests/jax/test_nodal_inj_optim.py Removes legacy tests tied to the old nodal-injection optimization path.
packages/dc_solver_pkg/tests/jax/test_aggregate_results.py Renames loadflow result field usage to pst_tap_results.
packages/dc_solver_pkg/src/toop_engine_dc_solver/preprocess/preprocess.py Preserves non-linear PST controllability; reduces PST susceptance tap lists with branch reduction.
packages/dc_solver_pkg/src/toop_engine_dc_solver/preprocess/powsybl/powsybl_backend.py Uses has_pst_tap for controllable mask; computes per-tap susceptance for Powsybl PSTs.
packages/dc_solver_pkg/src/toop_engine_dc_solver/preprocess/pandapower/pandapower_backend.py Adds per-tap susceptance values (constant across taps for PandaPower path).
packages/dc_solver_pkg/src/toop_engine_dc_solver/preprocess/network_data.py Adds phase_shift_susceptance_taps to NetworkData and validates alignment.
packages/dc_solver_pkg/src/toop_engine_dc_solver/preprocess/convert_to_jax.py Carries per-tap susceptance + linearity metadata into JAX NodalInjectionInformation.
packages/dc_solver_pkg/src/toop_engine_dc_solver/postprocess/validate_loadflow_results.py Tightens default validation tolerances and exposes parameter model in tests.
packages/dc_solver_pkg/src/toop_engine_dc_solver/jax/types.py Extends NodalInjectionInformation and renames solver output field to pst_tap_results.
packages/dc_solver_pkg/src/toop_engine_dc_solver/jax/pst.py New PST helper module to prepare taps, write angles, and update N-0 flows.
packages/dc_solver_pkg/src/toop_engine_dc_solver/jax/nodal_inj_optim.py Reduces module scope to start-option helper(s) only.
packages/dc_solver_pkg/src/toop_engine_dc_solver/jax/inputs.py Persists/loads new PST metadata fields and validates shapes.
packages/dc_solver_pkg/src/toop_engine_dc_solver/jax/compute_batch.py Applies PST tap state during batch solve and updates PTDF for non-linear PST susceptance changes.
packages/dc_solver_pkg/src/toop_engine_dc_solver/jax/branch_parameter_changes.py New low-rank PTDF update for simultaneous branch-parameter changes (e.g., PST tap-dependent susceptance).
packages/dc_solver_pkg/src/toop_engine_dc_solver/jax/aggregate_results.py Updates PST metric aggregation to use pst_tap_results.
benchmarks/benchmark_run_single_device_epoch.py Updates benchmark plumbing for renamed PST result field.

@BenjPetr

BenjPetr commented Jul 9, 2026

Copy link
Copy Markdown
Collaborator Author

changes:

  • rename nodal_injections_optimized -> pst_tap_results
    (as nothing is optimized anymore)
  • add pst branch parameter update to compute_bsdf_lodf_static_flows
    AND it's alpha update to compute_symmetric_batch() with if pst_tap_indices

tldr: no injections are optimized, psts are now better represented as an action and include branch parameter updates

representation.
"""

phase_shift_susceptance: Float[Array, " n_phase_shifters"]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we rename this to pst_susceptance

class NodalInjectionInformation(eqx.Module):
"""Holds the nodal injection optimization data required by the DC solver."""

phase_shift_branch_indices: Int[Array, " n_phase_shifters"]

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the difference between this and the controllable_pst_indices if now all PSTs should be controllable?

@spetznick-elia spetznick-elia left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall incredible! I think the data structures need some refactoring: We introduce the nonlinear PSTs into the set of controllable ones. We do no need to distinguish between them anymore.



def test_exclude_nonlinear_psts_from_controllable_drops_nonlinear_group_member(
def test_exclude_nonlinear_psts_from_controllable_keeps_nonlinear_group_member(

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be renamed I guess

Signed-off-by: Benjamin Petrick <170433522+BenjPetr@users.noreply.github.com>

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

somewhat similar to modf, but a different file, as it allows for updated_susceptance instead of a full outage delta

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is part one of a pst change

  1. Paramter change -> non linear pst
  2. injection change -> PSDF

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nothing is optimized anymore -> move to pst file

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all nodal pst functions

@@ -1286,10 +1294,10 @@ def compute_separation_set_for_stations(


def exclude_nonlinear_psts_from_controllable(network_data: NetworkData) -> NetworkData:

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this can be removed?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think in my latest fix i also excluded them directly in the backend. So this willhave t be adjusted

The list order matches phase_shift_taps and controllable_phase_shift_mask.
"""

phase_shift_linearity: Bool[np.ndarray, " n_controllable_pst"]

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can stay for now, if we want to do nodal optimization later on again for linear + HVDC

BenjPetr added 2 commits July 9, 2026 20:57
Signed-off-by: Benjamin Petrick <170433522+BenjPetr@users.noreply.github.com>
…_battery_hvdc_svc_3w_trafo()

Signed-off-by: Benjamin Petrick <170433522+BenjPetr@users.noreply.github.com>
alphas = np.linspace(alpha_min, alpha_max, len(taps))
x_vals = np.abs(np.linspace(x_min, x_max, len(taps)))
r_vals = np.abs(np.linspace(r_min, r_max, len(taps)))
rho_vals = np.ones(len(taps)) if is_linear else np.linspace(rho_min, rho_max, len(taps))

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This addition makes sure asymmetrical PST work as well.
The way the taps are imported make this change automatically possible with no further changes
see get_phase_shift_susceptance_taps()
effective_x_taps

@@ -57,17 +57,14 @@ def __getitem__(self, key: Union[slice, int, jnp.ndarray]) -> "MODFMatrix":


class NodalInjectionInformation(eqx.Module):

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now rather a PstInformation?

Signed-off-by: Benjamin Petrick <170433522+BenjPetr@users.noreply.github.com>
@sonarqube-mccs

sonarqube-mccs Bot commented Jul 9, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants