Skip to content

Implement loadflow for AC DC networks#1302

Open
2nisb wants to merge 69 commits intomainfrom
ac-dc-loadflow
Open

Implement loadflow for AC DC networks#1302
2nisb wants to merge 69 commits intomainfrom
ac-dc-loadflow

Conversation

@2nisb
Copy link

@2nisb 2nisb commented Nov 25, 2025

Please check if the PR fulfills these requirements

  • The commit message follows our guidelines
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)
  • A PR or issue has been opened in all impacted repositories (if any)

Does this PR already have an issue describing the problem?

No

What kind of change does this PR introduce?

Feature

What is the current behavior?

Open loadflow does not support DC detailed components from iidm

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

Open loadflow is able to modelize DC components (DcNode, DcLine, VoltageSourceConverter) and run loadflows on AC DC networks, with one unique jacobian matrix for the whole connected network.

Does this PR introduce a breaking change or deprecate an API?

  • Yes
  • No

If yes, please check if the following requirements are fulfilled

  • The Breaking Change or Deprecated label has been added
  • The migration steps are described in the following section

What changes might users need to make in their application due to this PR? (migration steps)

If you defined your own powsybl openloadflow implementation, you should:
Write your own implementations of LfAcDcConverter, LfVoltageSourceConverter and LfDcNode

Implement the following methods in your :

  • VoltageInitializer implementations:
    double getReactivePower(LfVoltageSourceConverter converter)
    double getActivePower(LfAcDcConverter converter)
    double getMagnitude(LfDcNode dcNode)
  • LfBus implementations:
    List<LfVoltageSourceConverter> getConverters()
    void addConverter(LfVoltageSourceConverter converter)

Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
@2nisb 2nisb force-pushed the ac-dc-loadflow branch 2 times, most recently from 0f96108 to b6155c2 Compare November 25, 2025 13:27
JB-H and others added 26 commits November 25, 2025 14:29
…2 to keep the convention of positiveness of flow when injecting into DC node

Creation of an equation term for Pdc contributing to AC Active power injection because Pdc must be per-unitized when used on the AC part Pac = Pdc / SB

Signed-off-by: JB-H <65605897+jb-h@users.noreply.github.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
…working)

Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Signed-off-by: Denis Bonnand <denis.bonnand@supergrid-institute.com>
Copy link
Member

Choose a reason for hiding this comment

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

Since AcEquationSystemCreator is already a big class, I would suggest creating a class AcEquationSystemForAcDcNetworkCreator that inherits from it , that implements all the additional equations specific to DC network.

Copy link

Choose a reason for hiding this comment

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

In this case would other classes such as AcVectorizedEquationSystemCreator and AsymmetricalAcEquationSystemCreator inherit from AcEquationSystemForAcDcNetworkCreator ?

If they don't, then they cannot benefit from the DC detailed model which seems unfortunate to me. But if they do inherit from it, I am not sure of getting the point of creating an AcEquationSystemForAcDcNetworkCreator except for seprating the code to limit the size of AcEquationSystemCreator

Copy link
Member

@SylvestreSakti SylvestreSakti Feb 6, 2026

Choose a reason for hiding this comment

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

Indeed you are right, we can leave it as it is (or if separating the code is needed, all the static methods createDcNodeEquation and createDcLineEquations could be separated in another class called by AcEquationSystemCreator but after some thoughts it is clear as it is)

Copy link
Member

@SylvestreSakti SylvestreSakti left a comment

Choose a reason for hiding this comment

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

Hello @2nisb and @bperr , thank you very much for your contribution. This is a great first step for AcDcNetwork load flow implementation !

I tried some first reviews, I still need time to get deeper into it. But as first remarks, for this current version, some issues may have to be resolved :

  • Scope of the AcDc load flow: There are some modes that are not supported yet with this, and we will have to avoid confusion by making sure the users are using the right parameters, for example, DC load flow is not supported yet (so DC initialization should not be used), Multi slack cannot work, some solvers such as Fast Decoupled cannot resolve it. Maybe exception could be thrown for all these cases.
  • Component management: The connected/synchronous components management has to be adjusted with this new kind of loadflow (some log messages may be confusing since we are still calling the network "{CC0 SC0}" even if there are multiple synchronous components in it, this has to be clarified)
  • Initialization: Using the VoltageInitializer to initialize the DC network equations may be misleading. Maybe it could be separated in another initializer. Moreover, it seems that active power and reactive power of the converters are initialized from the P and Q that are in the AC terminal, this depends on state variables of the network and would have to be used only for previous value initializer. The behavior of initialization seems still unclear for me.
  • Slack bus selection: I may be missing something but I don't understant the choice of having a converter as a slack bus. Can you clarify it ? (and also in the documentation)

I made some first remarks that can be discussed on the code.

Here are next steps that I have in mind, that are maybe out of the scope of this PR, but that we will have to adress later :

  • This has been implemented for AC load flow, but DC load flow has to be implemented (I am not sure how the DC initialization works now)
  • Still there are some DC components that are not supported such as DC switch, or LCC converters
  • Security analysis and Sensitivity analysis will have to be addressed

@jeandemanged may have another view on this so we can discuss about it

bperr added 5 commits January 16, 2026 10:12
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
…dflow

Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
@bperr
Copy link

bperr commented Jan 27, 2026

Hello,
Thanks a lot for your feedbakcs
I have covered some aspects you mentionned including modes that are not supported with ac-dc networks (explicit error and documentation) and the initialization.

I'll clarify the slack bus selection issue and the component management during this week hopefully.

@bperr
Copy link

bperr commented Feb 3, 2026

Hello,

I looked more deeply into the management of slack buses in Open Load Flow, and I think a few points need to be clarified.

The idea of selecting the slack bus through the converters makes sense if an outer loop allowing their targetPac to be modified is implemented, as is already the case for generators in the DistributedSlackOuterLoop. Since this feature is not implemented yet for converters, I suggest removing the LARGEST_CONVERTER option for now.

Further investigation of this outer loop revealed that, in the case of a network with two AC islands, the DistributedSlackOuterLoop considers the total active‑power mismatch across the entire LfNetwork object. In our situation, this object may contain several AC islands, each with its own slack bus and its own power balance to maintain. As a result, the AC–DC load flow currently provides correct results only for embedded DC networks. Fixing this behaviour for networks with multiple AC islands will require additional development.

To be clear, the equations within a single Newton–Raphson iteration behave correctly; the issue only arises when balancing the active power at the slack bus when the distributedSlack parameter is set to true (which is the default).

Our proposal is as follows:

In this PR:

  • Remove the LARGEST_CONVERTER option from the slack‑bus selection method.
  • Restrict the AC–DC load flow to networks with a single AC island (there is no limitation on the number of DC islands). This will be documented, and an exception will be thrown if a network containing two AC islands is provided as input.

In a future PR:

  • Properly handle networks with several AC islands, both in terms of component management and in the handling of slack buses and other outer loops.

Are you aligned with this approach? Do you have any suggestions on how to address this topic?

@bperr bperr requested a review from SylvestreSakti February 4, 2026 08:55
bperr added 2 commits February 6, 2026 11:03
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
@SylvestreSakti
Copy link
Member

Hello @bperr

Thank you for your answers and corrections ! The idea of having a load flow working first for a single AC component seems to me as a nice and clean first step indeed. I am aligned with you point of view, and we could then make it more generic with multiple islands (having in mind that the distributed slack outerloop will have to handle multiple components).

The idea of selecting the slack bus through the converters makes sense if an outer loop allowing their targetPac to be modified is implemented, as is already the case for generators in the DistributedSlackOuterLoop.

Nevertheless, this still looks unclear for me. I think there are two concepts to dissociate for slack active power distribution :

  • The slack bus : where the active power imbalance is "stored" during the load flow before "spreading" this imbalance everywhere on the network
  • The elements that participate in the slack distribution : usually the generators that absorb this imbalance

Unless very specific issues of Newton Raphson convergence, the slack bus can be anywhere on the network (and there is nothing related to the targetP on the generators that are in this specific bus), so I am still unsure why we would want to have a slack bus at the largest converter place (we could clarify that for a next PR then 😃 )

bperr added 2 commits February 6, 2026 15:26
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
@bperr
Copy link

bperr commented Feb 6, 2026

Hello @SylvestreSakti
Thanks for your feedback !
I pushed the necessary modifications to ensure there is only one AC component.
As you suggested, I also moved the Equation terms relative to DC network in their own package. However, for the moment I haven't moved the DC part of AcEquationSystemCreator to another class, what is your final opinion on this topic ?

private void createMultipleSlackBusesEquations(EquationSystem<AcVariableType, AcEquationType> equationSystem) {
List<LfBus> slackBuses = network.getSlackBuses();
if (slackBuses.size() > 1) {
if (network instanceof LfAcDcNetwork acDcNetwork && slackBuses.size() > acDcNetwork.getAcSubNetworks().size()) {
Copy link
Member

Choose a reason for hiding this comment

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

If the scope of this PR is limited to one AC component, the multiple slacks may be supported ?

Copy link

Choose a reason for hiding this comment

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

Indeed, with one AC component, multiple slack is supported !

Move DC nominal voltage check to LfNetworkLoaderImpl

Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
@bperr
Copy link

bperr commented Feb 19, 2026

Hi,
I just added a single commit that changes the current sign convention in DC network. The currrents that are added in the DC node current balance equation are now the currents that flowing out of the node (to be coherent with the active and reactive power balance of AC buses).
Let me know if you are okay with this convention

Copy link
Member

@jeandemanged jeandemanged left a comment

Choose a reason for hiding this comment

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

Hello @bperr @2nisb cc @SylvestreSakti ,

Apologies for late feedback, here my first comments about documentation/functional part.

Comment on lines +27 to +28
However, it is currently restricted to embedded DC networks, meaning that the global network should only contain one AC
network.
Copy link
Member

Choose a reason for hiding this comment

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

terms/definitions to be clarified:

  • "network" vs. "island/component"
  • "embedded": my understanding is that it means all AC Terminals of DC converters of a given DC island/component must be in the same AC island/component, correct ?
  • "should only contain one AC network": would 2 AC islands, each with their own "embedded" DC island work ?, e.g.:
    • ConnectedComponent 0 with synchronous component 0 and DC component 0
    • ConnectedComponent 1 with synchronous component 1 and DC component 1

Copy link

Choose a reason for hiding this comment

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

I reformulated the documentation to be clearer. Let me know if this seems correct now
To my understanding

  • A network object represents set of connected component
  • A connected component is a collection of AC and DC island/component that are connected through AC/DC converters.
  • An island/component is a set of buses of the same type (meaning either all AC or all DC) connected through equipments like lines, transformers,etc...

So to answer your last points:

  • yes a DC island is embedded when it is connected to only one AC island. It is an "internal" connection, meaning it does not connect two different AC island.
  • I reformulated this point in the documentation, in a single Connected component, there should be only one AC island (and no restriction on the number of DC island). Therefore, as you suggested a network with two connected component with each one AC island and some embeded DC islands can be processed by this load flow


## AC DC flows computing

AC DC lows computing in OpenLoadFLow is similar to AC flows computing, but with AC and DC equations in the same system.
Copy link
Member

Choose a reason for hiding this comment

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

typo

Suggested change
AC DC lows computing in OpenLoadFLow is similar to AC flows computing, but with AC and DC equations in the same system.
AC DC flows computing in OpenLoadFLow is similar to AC flows computing, but with AC and DC equations in the same system.

Copy link

Choose a reason for hiding this comment

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

Typo fixed


### DC node

At least one DC node must be connected to the ground in each DC network, its potential is therefore set to 0.
Copy link
Member

@jeandemanged jeandemanged Feb 19, 2026

Choose a reason for hiding this comment

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

See https://powsybl.readthedocs.io/projects/powsybl-core/en/stable/grid_model/network_subnetwork.html#ac-dc-converter about symmetrical/asymmetrical scheme

absence of DC Ground should be possible to model symmetrical

When the ControlMode of the converter is set to V_DC, the converter controls DC voltage at its DC Terminals. TargetVdc is the desired target DC voltage, and is the voltage difference between DC Node 1 and DC Node 2. TargetVdc may be either positive or negative. Negative value may be used to model reverse polarity operation in case of LCCs. No explicit attribute specifies whether the DC is a symmetrical or asymmetrical scheme. The scheme symmetrical or asymmetrical is derived implicitly by either the presence or absence of a DC Ground connected to the DC system:

If a DC Ground is connected, the configuration is asymmetrical, and the converter imposes the target voltage difference between the converter DC Node 1 and the DC Node 2 to be equal to TargetVdc

If no DC Ground is present, the configuration is symmetrical, in this case the converter provides internally an implicit DC Ground and imposes:

+TargetVdc / 2 at the converter DC Node 1

-TargetVdc / 2 at the converter DC Node 2

Copy link

Choose a reason for hiding this comment

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

For the moment DC ground are required in OLF so symmetrical configuration is not supported. I updated the docs to specify it.

As mentionned, a workaround is to add a DC ground and connect it to the two DC terminal of the converters with a very high resistance. This is implemented in a test for example purpose, but it is not a clean way to handle symetrical configuration. This will be addressed in a future PR

### Voltage source converters

Let consider a network that is composed of one AC network, and one DC network.
The voltage source converter is the link between AC and DC networks, it is linked to **one** AC bus at one side, and two
Copy link
Member

Choose a reason for hiding this comment

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

one AC bus

See https://powsybl.readthedocs.io/projects/powsybl-core/en/stable/grid_model/network_subnetwork.html#ac-dc-converter

AC/DC Converter transfers power between AC and DC grids. Its connectivity is modeled with:

  • either one or two AC Terminals,
  • exactly two DC Terminals

Need to document that the second optional AC terminal is currently not supported by OLF

Copy link

Choose a reason for hiding this comment

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

I added a sentence to make it explicit.
I also added an exception if a converter has a second AC terminal


$\sum_{i} I_i - \frac{V_1 - V_2}{R}= 0$ for dcNode2

### Voltage source converters
Copy link
Member

Choose a reason for hiding this comment

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

See https://powsybl.readthedocs.io/projects/powsybl-core/en/stable/grid_model/network_subnetwork.html#ac-dc-converter

Need to document that LCCs in detailed model are currently not supported by OLF

Copy link

Choose a reason for hiding this comment

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

I added a section to specify it.
I also added an exception if there is an LCC in the network

Comment on lines +379 to +393
If the converter is in `P_PCC` control mode, we add an equation to impose $P_{AC}$ :

$P_{AC}$ = $P_{Ref}$

Else the converter is in `V_DC` control mode, and we add an equation to impose the voltage between its two DC nodes :

$V_{1} - V_{2} = V_{Ref}$

Similarly, if the converter controls reactive power, we add an equation to impose $Q_{AC}$ :

$Q_{AC}$ = $Q_{Ref}$

Else the converter controls the AC voltage, and we add an equation to impose $V_{AC}$:

$V_{AC}= V_{Ref}$
Copy link
Member

Choose a reason for hiding this comment

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

Expectation is that:

  • target active power
  • target reactive power or target voltage

are at PCC (Point of Common Coupling) Terminal, not converter AC Terminal. If this is not the case, clarify it.

Copy link

Choose a reason for hiding this comment

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

In the case of VSC with only one AC terminal, is not the PCC the same thing as the converter terminal ?

For VSC converters having a single AC Terminal, it is valid for the PCC Terminal to be the converter terminal itself.

Currently, the AC LfBus controlled by the converter is selected through the converter Terminal1, but it can easilly be changed to the converter PccTerminal


with:
- $P_{AC}$ the power injected by the converter to the AC side
- $P_{Loss}>0$ the converter losses depending on AC current. Its computation is detailed in the next subsection.
Copy link
Member

Choose a reason for hiding this comment

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

Copy link

Choose a reason for hiding this comment

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

The ConverterDcCurrentEquationTerm has been updated to use the DC current instead.

Comment on lines +414 to +432
If the converter acts as rectifier, AC injects power in DC, thus $P_{DC}>0$ and $P_{AC}<0$, so we have :

$$
|P_{DC}| = -P_{AC} - P_{Loss}
$$
$$
|P_{DC}| = |P_{AC}| - P_{Loss}
$$

And if the converter acts as inverter, DC injects power in AC, thus $P_{DC}<0$ and $P_{AC}>0$, so we have :

$$
|P_{DC}| = P_{AC} + P_{Loss}
$$
$$
|P_{AC}| = |P_{DC}| - P_{Loss}
$$

In both cases, there is a loss of power when passing through the converter.
Copy link
Member

@jeandemanged jeandemanged Feb 19, 2026

Choose a reason for hiding this comment

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

with commonly agreed load sign convention (+ meaning into converter, - meaning out of converter), and Ploss >= 0 this reduces simply to

Pac + Pdc = Ploss

Copy link

Choose a reason for hiding this comment

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

Ok, I updated the sign convention in the code and docs


In both cases, there is a loss of power when passing through the converter.

#### Loss Calculation
Copy link
Member

Choose a reason for hiding this comment

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

See previous comment Iac vs. Idc


The default value is `false`.

**Note:** With AC-DC network load flow, the following parameters are restricted:
Copy link
Member

Choose a reason for hiding this comment

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

Describe what happens when conditions not met (e.g. exception?)

Maybe add other conditions based on models not yet supported:

  • network with detailed model LCC converter
  • network with detailed model VSC converter with 2 AC Terminals

Copy link

Choose a reason for hiding this comment

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

Indeed, an exception is thrown for all these cases. I clarified this point in the documentation.

@github-project-automation github-project-automation bot moved this from In Progress to Waiting for review in Release 03/2026 Feb 19, 2026
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
Signed-off-by: b.perreyon <baptiste.perreyon@supergrid-institute.com>
@sonarqubecloud
Copy link

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

Projects

Status: Waiting for review

Development

Successfully merging this pull request may close these issues.

5 participants