From 6b9cd7eba63732553314b34c6252a9fb266450e4 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 8 Nov 2021 09:34:49 +0100 Subject: [PATCH 01/37] Element disabling notification Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystemUpdater.java | 14 ++++++++++++++ .../openloadflow/network/AbstractElement.java | 17 ++++++++++++++++- .../openloadflow/network/AbstractLfBranch.java | 12 ------------ .../network/AbstractLfNetworkListener.java | 5 +++++ .../powsybl/openloadflow/network/LfBranch.java | 4 ---- .../com/powsybl/openloadflow/network/LfBus.java | 4 ---- .../powsybl/openloadflow/network/LfElement.java | 4 ++++ .../openloadflow/network/LfNetworkListener.java | 2 ++ .../network/impl/AbstractLfBus.java | 4 +--- .../openloadflow/network/impl/LfBranchImpl.java | 2 +- .../openloadflow/network/impl/LfLegBranch.java | 6 +++++- .../openloadflow/network/impl/LfLoads.java | 8 +------- .../sa/AbstractSecurityAnalysis.java | 7 ++++--- .../openloadflow/sa/AcSecurityAnalysis.java | 9 +++++++++ 14 files changed, 62 insertions(+), 36 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index 3b8d76cba5..c271d964d8 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -133,4 +133,18 @@ public void onVoltageControlModeChange(DiscreteVoltageControl voltageControl, Di } } } + + @Override + public void onDisableChange(LfElement element, boolean disabled) { + switch (element.getType()) { + case BUS: + // TODO + break; + case BRANCH: + // TODO + break; + case SHUNT_COMPENSATOR: + throw new IllegalStateException("Shunt compensator disabling is not implemented"); + } + } } diff --git a/src/main/java/com/powsybl/openloadflow/network/AbstractElement.java b/src/main/java/com/powsybl/openloadflow/network/AbstractElement.java index 13785c451c..851a7a5d57 100644 --- a/src/main/java/com/powsybl/openloadflow/network/AbstractElement.java +++ b/src/main/java/com/powsybl/openloadflow/network/AbstractElement.java @@ -11,12 +11,14 @@ /** * @author Geoffroy Jamgotchian */ -public abstract class AbstractElement { +public abstract class AbstractElement implements LfElement { protected final LfNetwork network; protected int num = -1; + protected boolean disabled = false; + protected Object userObject; protected AbstractElement(LfNetwork network) { @@ -31,6 +33,19 @@ public void setNum(int num) { this.num = num; } + public boolean isDisabled() { + return disabled; + } + + public void setDisabled(boolean disabled) { + if (disabled != this.disabled) { + this.disabled = disabled; + for (LfNetworkListener listener : network.getListeners()) { + listener.onDisableChange(this, disabled); + } + } + } + public LfNetwork getNetwork() { return network; } diff --git a/src/main/java/com/powsybl/openloadflow/network/AbstractLfBranch.java b/src/main/java/com/powsybl/openloadflow/network/AbstractLfBranch.java index 509782f684..fa4b8aecf9 100644 --- a/src/main/java/com/powsybl/openloadflow/network/AbstractLfBranch.java +++ b/src/main/java/com/powsybl/openloadflow/network/AbstractLfBranch.java @@ -67,8 +67,6 @@ public void setAcceptableDuration(int acceptableDuration) { protected DiscreteVoltageControl discreteVoltageControl; - protected boolean disabled = false; - protected boolean spanningTreeEdge = false; protected Evaluable a1; @@ -221,16 +219,6 @@ public void setDiscreteVoltageControl(DiscreteVoltageControl discreteVoltageCont this.discreteVoltageControl = discreteVoltageControl; } - @Override - public boolean isDisabled() { - return disabled; - } - - @Override - public void setDisabled(boolean disabled) { - this.disabled = disabled; - } - public double computeApparentPower1() { double p = getP1().eval(); double q = getQ1().eval(); diff --git a/src/main/java/com/powsybl/openloadflow/network/AbstractLfNetworkListener.java b/src/main/java/com/powsybl/openloadflow/network/AbstractLfNetworkListener.java index e7f63dec4b..ecfd0dfe6f 100644 --- a/src/main/java/com/powsybl/openloadflow/network/AbstractLfNetworkListener.java +++ b/src/main/java/com/powsybl/openloadflow/network/AbstractLfNetworkListener.java @@ -50,4 +50,9 @@ public void onGenerationReactivePowerTargetChange(LfBus bus, double oldGeneratio public void onPhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition) { // empty } + + @Override + public void onDisableChange(LfElement element, boolean disabled) { + // empty + } } diff --git a/src/main/java/com/powsybl/openloadflow/network/LfBranch.java b/src/main/java/com/powsybl/openloadflow/network/LfBranch.java index adba83ab77..0707f0c6df 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfBranch.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfBranch.java @@ -79,10 +79,6 @@ default List getLimits2(LimitType type) { BranchResult createBranchResult(double preContingencyP1, double branchInContingencyP1); - boolean isDisabled(); - - void setDisabled(boolean disabled); - double computeApparentPower1(); double computeApparentPower2(); diff --git a/src/main/java/com/powsybl/openloadflow/network/LfBus.java b/src/main/java/com/powsybl/openloadflow/network/LfBus.java index 008826d9c1..092dca56f8 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfBus.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfBus.java @@ -129,10 +129,6 @@ default double getHighVoltageLimit() { void setDiscreteVoltageControl(DiscreteVoltageControl discreteVoltageControl); - boolean isDisabled(); - - void setDisabled(boolean disabled); - void setP(Evaluable p); Evaluable getP(); diff --git a/src/main/java/com/powsybl/openloadflow/network/LfElement.java b/src/main/java/com/powsybl/openloadflow/network/LfElement.java index 6fcb45f007..cb6e7642f0 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfElement.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfElement.java @@ -19,6 +19,10 @@ public interface LfElement { void setNum(int num); + boolean isDisabled(); + + void setDisabled(boolean disabled); + LfNetwork getNetwork(); Object getUserObject(); diff --git a/src/main/java/com/powsybl/openloadflow/network/LfNetworkListener.java b/src/main/java/com/powsybl/openloadflow/network/LfNetworkListener.java index 6342720e47..ddf71a5774 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfNetworkListener.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfNetworkListener.java @@ -26,4 +26,6 @@ public interface LfNetworkListener { void onGenerationReactivePowerTargetChange(LfBus bus, double oldGenerationTargetQ, double newGenerationTargetQ); void onPhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition); + + void onDisableChange(LfElement element, boolean disabled); } diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java index 6f624d9c8d..7235122f2a 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java @@ -55,7 +55,7 @@ public abstract class AbstractLfBus extends AbstractElement implements LfBus { protected final List shunts = new ArrayList<>(); - protected LfLoads lfLoads = new LfLoads(network); + protected final LfLoads lfLoads = new LfLoads(); protected boolean ensurePowerFactorConstantByLoad = false; @@ -71,8 +71,6 @@ public abstract class AbstractLfBus extends AbstractElement implements LfBus { protected DiscreteVoltageControl discreteVoltageControl; - protected boolean disabled = false; - protected Evaluable p = NAN; protected Evaluable q = NAN; diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/LfBranchImpl.java b/src/main/java/com/powsybl/openloadflow/network/impl/LfBranchImpl.java index 662a0dd9b3..349a2ca977 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfBranchImpl.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfBranchImpl.java @@ -204,7 +204,7 @@ public Evaluable getI2() { @Override public BranchResult createBranchResult(double preContingencyP1, double branchInContingencyP1) { double flowTransfer = Double.NaN; - if (preContingencyP1 != Double.NaN && branchInContingencyP1 != Double.NaN) { + if (!Double.isNaN(preContingencyP1) && !Double.isNaN(branchInContingencyP1)) { flowTransfer = (p1.eval() * PerUnit.SB - preContingencyP1) / branchInContingencyP1; } double currentScale1 = PerUnit.ib(branch.getTerminal1().getVoltageLevel().getNominalV()); diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/LfLegBranch.java b/src/main/java/com/powsybl/openloadflow/network/impl/LfLegBranch.java index bd0b2cc032..427974bb90 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfLegBranch.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfLegBranch.java @@ -94,9 +94,13 @@ private int getLegNum() { } } + public static String getId(String twtId, int legNum) { + return twtId + "_leg_" + legNum; + } + @Override public String getId() { - return twt.getId() + "_leg_" + getLegNum(); + return getId(twt.getId(), getLegNum()); } @Override diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/LfLoads.java b/src/main/java/com/powsybl/openloadflow/network/impl/LfLoads.java index daa89a78d0..1955c7dbc8 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfLoads.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfLoads.java @@ -8,8 +8,6 @@ import com.powsybl.iidm.network.Load; import com.powsybl.iidm.network.extensions.LoadDetail; -import com.powsybl.openloadflow.network.AbstractElement; -import com.powsybl.openloadflow.network.LfNetwork; import com.powsybl.openloadflow.network.PerUnit; import java.util.ArrayList; @@ -18,7 +16,7 @@ /** * @author Anne Tilloy */ -public class LfLoads extends AbstractElement { +public class LfLoads { private final List loads = new ArrayList<>(); @@ -30,10 +28,6 @@ public class LfLoads extends AbstractElement { private boolean isInitialized; - protected LfLoads(LfNetwork network) { - super(network); - } - public void add(Load load, boolean distributedOnConformLoad) { loads.add(load); this.distributedOnConformLoad = distributedOnConformLoad; // TODO: put in constructor instead diff --git a/src/main/java/com/powsybl/openloadflow/sa/AbstractSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/AbstractSecurityAnalysis.java index 29a8d3e4ea..f7593d7ed8 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/AbstractSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/AbstractSecurityAnalysis.java @@ -15,6 +15,7 @@ import com.powsybl.openloadflow.OpenLoadFlowParameters; import com.powsybl.openloadflow.graph.GraphDecrementalConnectivity; import com.powsybl.openloadflow.network.*; +import com.powsybl.openloadflow.network.impl.LfLegBranch; import com.powsybl.openloadflow.network.util.ActivePowerDistribution; import com.powsybl.security.*; import com.powsybl.security.interceptors.SecurityAnalysisInterceptor; @@ -251,9 +252,9 @@ protected void addMonitorInfo(LfNetwork network, StateMonitor monitor, Collectio } private ThreeWindingsTransformerResult createThreeWindingsTransformerResult(String threeWindingsTransformerId, LfNetwork network) { - LfBranch leg1 = network.getBranchById(threeWindingsTransformerId + "_leg_1"); - LfBranch leg2 = network.getBranchById(threeWindingsTransformerId + "_leg_2"); - LfBranch leg3 = network.getBranchById(threeWindingsTransformerId + "_leg_3"); + LfBranch leg1 = network.getBranchById(LfLegBranch.getId(threeWindingsTransformerId, 1)); + LfBranch leg2 = network.getBranchById(LfLegBranch.getId(threeWindingsTransformerId, 2)); + LfBranch leg3 = network.getBranchById(LfLegBranch.getId(threeWindingsTransformerId, 3)); double i1Base = PerUnit.ib(leg1.getBus1().getNominalV()); double i2Base = PerUnit.ib(leg2.getBus1().getNominalV()); double i3Base = PerUnit.ib(leg3.getBus1().getNominalV()); diff --git a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java index 4fe56ba589..bab818af34 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java @@ -1,3 +1,9 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ package com.powsybl.openloadflow.sa; import com.google.common.base.Stopwatch; @@ -41,6 +47,9 @@ import java.util.function.Supplier; import java.util.stream.Collectors; +/** + * @author Geoffroy Jamgotchian + */ public class AcSecurityAnalysis extends AbstractSecurityAnalysis { protected AcSecurityAnalysis(Network network, LimitViolationDetector detector, LimitViolationFilter filter, From eff37b84c938e0b585dfa183b512cda2cd20a8c0 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 8 Nov 2021 09:46:11 +0100 Subject: [PATCH 02/37] Fix Signed-off-by: Geoffroy Jamgotchian --- .../java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java index bab818af34..f2fc651d5a 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java @@ -48,7 +48,7 @@ import java.util.stream.Collectors; /** - * @author Geoffroy Jamgotchian + * */ public class AcSecurityAnalysis extends AbstractSecurityAnalysis { From f5142d506ff8711a7f862e4d93809244e6531979 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 8 Nov 2021 21:56:35 +0100 Subject: [PATCH 03/37] Refactoring Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 85 +++++++++++-------- 1 file changed, 48 insertions(+), 37 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index ca4567a45e..7e3da36da6 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -29,30 +29,36 @@ public final class AcEquationSystem { private AcEquationSystem() { } - private static void createBusEquations(LfNetwork network, LfNetworkParameters networkParameters, - EquationSystem equationSystem, VariableSet variableSet, - AcEquationSystemCreationParameters creationParameters) { - for (LfBus bus : network.getBuses()) { - if (bus.isSlack()) { - equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_PHI).addTerm(EquationTerm.createVariableTerm(bus, AcVariableType.BUS_PHI, variableSet)); - equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_P).setActive(false); - } + private static void createBusEquation(LfBus bus, LfNetworkParameters networkParameters, + EquationSystem equationSystem, VariableSet variableSet, + AcEquationSystemCreationParameters creationParameters) { + if (bus.isSlack()) { + equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_PHI).addTerm(EquationTerm.createVariableTerm(bus, AcVariableType.BUS_PHI, variableSet)); + equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_P).setActive(false); + } - createGeneratorControlEquations(bus, networkParameters, equationSystem, variableSet, creationParameters); + createGeneratorControlEquations(bus, networkParameters, equationSystem, variableSet, creationParameters); - createShuntEquations(bus, equationSystem, variableSet); + createShuntEquations(bus, equationSystem, variableSet); - if (networkParameters.isTransformerVoltageControl()) { - createDiscreteVoltageControlEquation(bus, equationSystem, variableSet); - } - Equation v = equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V); - if (v.getTerms().isEmpty()) { - v.setActive(false); - EquationTerm vTerm = EquationTerm.createVariableTerm(bus, AcVariableType.BUS_V, variableSet, bus.getV().eval()); - v.addTerm(vTerm); - bus.setV(vTerm); - v.setUpdateType(EquationSystem.EquationUpdateType.AFTER_NR); - } + if (networkParameters.isTransformerVoltageControl()) { + createDiscreteVoltageControlEquation(bus, equationSystem, variableSet); + } + Equation v = equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V); + if (v.getTerms().isEmpty()) { + v.setActive(false); + EquationTerm vTerm = EquationTerm.createVariableTerm(bus, AcVariableType.BUS_V, variableSet, bus.getV().eval()); + v.addTerm(vTerm); + bus.setV(vTerm); + v.setUpdateType(EquationSystem.EquationUpdateType.AFTER_NR); + } + } + + private static void createBusesEquations(LfNetwork network, LfNetworkParameters networkParameters, + EquationSystem equationSystem, VariableSet variableSet, + AcEquationSystemCreationParameters creationParameters) { + for (LfBus bus : network.getBuses()) { + createBusEquation(bus, networkParameters, equationSystem, variableSet, creationParameters); } } @@ -87,9 +93,9 @@ private static void createLocalVoltageControlEquation(LfBus bus, LfNetworkParame // take first generator with slope: network loading ensures that there's only one generator with slope double slope = bus.getGeneratorsControllingVoltageWithSlope().get(0).getSlope(); createBusWithSlopeEquation(bus, slope, networkParameters, equationSystem, variableSet, vTerm, creationParameters); - return; + } else { + equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V).addTerm(vTerm); } - equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V).addTerm(vTerm); } private static void createReactivePowerControlBranchEquation(LfBranch branch, ReactivePowerControl.ControlledSide controlledSide, @@ -482,19 +488,24 @@ private static void createImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2 } } - private static void createBranchEquations(LfNetwork network, LfNetworkParameters networkParameters, - EquationSystem equationSystem, VariableSet variableSet, - AcEquationSystemCreationParameters creationParameters) { - - // create zero and non zero impedance branch equations - network.getBranches().stream() - .filter(b -> !LfNetwork.isZeroImpedanceBranch(b)) - .forEach(b -> createImpedantBranch(b, b.getBus1(), b.getBus2(), networkParameters, equationSystem, variableSet, creationParameters)); + private static void createBranchEquations(LfBranch branch, LfNetworkParameters networkParameters, + EquationSystem equationSystem, VariableSet variableSet, + AcEquationSystemCreationParameters creationParameters) { + if (LfNetwork.isZeroImpedanceBranch(branch)) { + if (branch.isSpanningTreeEdge()) { + createNonImpedantBranch(branch, branch.getBus1(), branch.getBus2(), equationSystem, variableSet); + } + } else { + createImpedantBranch(branch, branch.getBus1(), branch.getBus2(), networkParameters, equationSystem, variableSet, creationParameters); + } + } - // create zero and non zero impedance branch equations - network.getBranches().stream() - .filter(b -> LfNetwork.isZeroImpedanceBranch(b) && b.isSpanningTreeEdge()) - .forEach(b -> createNonImpedantBranch(b, b.getBus1(), b.getBus2(), equationSystem, variableSet)); + private static void createBranchesEquations(LfNetwork network, LfNetworkParameters networkParameters, + EquationSystem equationSystem, VariableSet variableSet, + AcEquationSystemCreationParameters creationParameters) { + for (LfBranch branch : network.getBranches()) { + createBranchEquations(branch, networkParameters, equationSystem, variableSet, creationParameters); + } } public static EquationSystem create(LfNetwork network) { @@ -522,8 +533,8 @@ public static EquationSystem create(LfNetwork ne EquationSystem equationSystem = new EquationSystem<>(true); - createBusEquations(network, networkParameters, equationSystem, variableSet, creationParameters); - createBranchEquations(network, networkParameters, equationSystem, variableSet, creationParameters); + createBusesEquations(network, networkParameters, equationSystem, variableSet, creationParameters); + createBranchesEquations(network, networkParameters, equationSystem, variableSet, creationParameters); EquationSystemPostProcessor.findAll().forEach(pp -> pp.onCreate(equationSystem, variableSet)); From 064d1a7f3e6e9932780b2721e18fcc89a4bdc945 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 8 Nov 2021 22:25:30 +0100 Subject: [PATCH 04/37] Renaming Signed-off-by: Geoffroy Jamgotchian --- .../openloadflow/ac/equations/AcEquationSystemUpdater.java | 4 ++-- .../com/powsybl/openloadflow/equations/TargetVector.java | 2 +- .../openloadflow/network/AbstractLfNetworkListener.java | 6 +++--- .../powsybl/openloadflow/network/DiscretePhaseControl.java | 2 +- .../openloadflow/network/DiscreteVoltageControl.java | 2 +- .../com/powsybl/openloadflow/network/LfNetworkListener.java | 6 +++--- .../java/com/powsybl/openloadflow/network/PiModelArray.java | 2 +- 7 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index c271d964d8..055486e1b5 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -88,7 +88,7 @@ public void onVoltageControlChange(LfBus controllerBus, boolean newVoltageContro } @Override - public void onPhaseControlModeChange(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode oldMode, DiscretePhaseControl.Mode newMode) { + public void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode oldMode, DiscretePhaseControl.Mode newMode) { boolean on = newMode != DiscretePhaseControl.Mode.OFF; // activate/de-activate phase control equation @@ -101,7 +101,7 @@ public void onPhaseControlModeChange(DiscretePhaseControl phaseControl, Discrete } @Override - public void onVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode oldMode, DiscreteVoltageControl.Mode newMode) { + public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode oldMode, DiscreteVoltageControl.Mode newMode) { LfBus bus = voltageControl.getControlled(); if (newMode == DiscreteVoltageControl.Mode.OFF) { diff --git a/src/main/java/com/powsybl/openloadflow/equations/TargetVector.java b/src/main/java/com/powsybl/openloadflow/equations/TargetVector.java index b59fd629d8..9cec416ed8 100644 --- a/src/main/java/com/powsybl/openloadflow/equations/TargetVector.java +++ b/src/main/java/com/powsybl/openloadflow/equations/TargetVector.java @@ -74,7 +74,7 @@ public void onGenerationReactivePowerTargetChange(LfBus bus, double oldGeneratio } @Override - public void onPhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition) { + public void onDiscretePhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition) { invalidateValues(); } diff --git a/src/main/java/com/powsybl/openloadflow/network/AbstractLfNetworkListener.java b/src/main/java/com/powsybl/openloadflow/network/AbstractLfNetworkListener.java index ecfd0dfe6f..6c614d69d7 100644 --- a/src/main/java/com/powsybl/openloadflow/network/AbstractLfNetworkListener.java +++ b/src/main/java/com/powsybl/openloadflow/network/AbstractLfNetworkListener.java @@ -17,12 +17,12 @@ public void onVoltageControlChange(LfBus controllerBus, boolean newVoltageContro } @Override - public void onPhaseControlModeChange(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode oldMode, DiscretePhaseControl.Mode newMode) { + public void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode oldMode, DiscretePhaseControl.Mode newMode) { // empty } @Override - public void onVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode oldMode, DiscreteVoltageControl.Mode newMode) { + public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode oldMode, DiscreteVoltageControl.Mode newMode) { // empty } @@ -47,7 +47,7 @@ public void onGenerationReactivePowerTargetChange(LfBus bus, double oldGeneratio } @Override - public void onPhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition) { + public void onDiscretePhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition) { // empty } diff --git a/src/main/java/com/powsybl/openloadflow/network/DiscretePhaseControl.java b/src/main/java/com/powsybl/openloadflow/network/DiscretePhaseControl.java index b0871cf8d3..581b8d47b7 100644 --- a/src/main/java/com/powsybl/openloadflow/network/DiscretePhaseControl.java +++ b/src/main/java/com/powsybl/openloadflow/network/DiscretePhaseControl.java @@ -78,7 +78,7 @@ public void setMode(Mode mode) { Mode oldMode = this.mode; this.mode = mode; for (LfNetworkListener listener : controller.getNetwork().getListeners()) { - listener.onPhaseControlModeChange(this, oldMode, mode); + listener.onDiscretePhaseControlModeChange(this, oldMode, mode); } } } diff --git a/src/main/java/com/powsybl/openloadflow/network/DiscreteVoltageControl.java b/src/main/java/com/powsybl/openloadflow/network/DiscreteVoltageControl.java index 69077b5fd6..0ab646c01c 100644 --- a/src/main/java/com/powsybl/openloadflow/network/DiscreteVoltageControl.java +++ b/src/main/java/com/powsybl/openloadflow/network/DiscreteVoltageControl.java @@ -45,7 +45,7 @@ public void setMode(Mode mode) { Mode oldMode = this.mode; this.mode = mode; for (LfNetworkListener listener : controlled.getNetwork().getListeners()) { - listener.onVoltageControlModeChange(this, oldMode, mode); + listener.onDiscreteVoltageControlModeChange(this, oldMode, mode); } } } diff --git a/src/main/java/com/powsybl/openloadflow/network/LfNetworkListener.java b/src/main/java/com/powsybl/openloadflow/network/LfNetworkListener.java index ddf71a5774..34482341e0 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfNetworkListener.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfNetworkListener.java @@ -13,9 +13,9 @@ public interface LfNetworkListener { void onVoltageControlChange(LfBus controllerBus, boolean newVoltageControllerEnabled); - void onPhaseControlModeChange(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode oldMode, DiscretePhaseControl.Mode newMode); + void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode oldMode, DiscretePhaseControl.Mode newMode); - void onVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode oldMode, DiscreteVoltageControl.Mode newMode); + void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode oldMode, DiscreteVoltageControl.Mode newMode); void onLoadActivePowerTargetChange(LfBus bus, double oldLoadTargetP, double newLoadTargetP); @@ -25,7 +25,7 @@ public interface LfNetworkListener { void onGenerationReactivePowerTargetChange(LfBus bus, double oldGenerationTargetQ, double newGenerationTargetQ); - void onPhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition); + void onDiscretePhaseControlTapPositionChange(PiModel piModel, int oldPosition, int newPosition); void onDisableChange(LfElement element, boolean disabled); } diff --git a/src/main/java/com/powsybl/openloadflow/network/PiModelArray.java b/src/main/java/com/powsybl/openloadflow/network/PiModelArray.java index 3de2257d05..02a1cf3130 100644 --- a/src/main/java/com/powsybl/openloadflow/network/PiModelArray.java +++ b/src/main/java/com/powsybl/openloadflow/network/PiModelArray.java @@ -172,7 +172,7 @@ public boolean updateTapPosition(Direction direction) { } if (hasChange) { for (LfNetworkListener listener : network.getListeners()) { - listener.onPhaseControlTapPositionChange(this, oldTapPosition, tapPosition); + listener.onDiscretePhaseControlTapPositionChange(this, oldTapPosition, tapPosition); } } return hasChange; From c5144cbe249839b5fc3519dc5c2954f4adf78015 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 8 Nov 2021 22:53:19 +0100 Subject: [PATCH 05/37] Merge Signed-off-by: Geoffroy Jamgotchian --- .../java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java index f2fc651d5a..29453614ce 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java @@ -47,9 +47,6 @@ import java.util.function.Supplier; import java.util.stream.Collectors; -/** - * - */ public class AcSecurityAnalysis extends AbstractSecurityAnalysis { protected AcSecurityAnalysis(Network network, LimitViolationDetector detector, LimitViolationFilter filter, From 8c84b28a1f60eaa9a086cdff60e0691010674709 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 8 Nov 2021 23:55:37 +0100 Subject: [PATCH 06/37] Refactor bus/branch state Signed-off-by: Geoffroy Jamgotchian --- .../openloadflow/network/BranchState.java | 37 +++++----- .../openloadflow/network/BusState.java | 67 +++++++------------ .../openloadflow/sa/AcSecurityAnalysis.java | 8 +-- .../sensi/AcSensitivityAnalysis.java | 6 +- .../sensi/DcSensitivityAnalysis.java | 25 +++---- 5 files changed, 60 insertions(+), 83 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/network/BranchState.java b/src/main/java/com/powsybl/openloadflow/network/BranchState.java index 7f6930ac9b..7cbd0a8106 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BranchState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BranchState.java @@ -7,46 +7,45 @@ package com.powsybl.openloadflow.network; import java.util.Collection; -import java.util.Map; -import java.util.function.Function; +import java.util.List; +import java.util.Objects; import java.util.stream.Collectors; /** * @author Gael Macherel */ public class BranchState { + + private final LfBranch branch; + private final double a1; private final double r1; private final boolean disabled; - public BranchState(LfBranch b) { - PiModel piModel = b.getPiModel(); + public BranchState(LfBranch branch) { + this.branch = Objects.requireNonNull(branch); + PiModel piModel = branch.getPiModel(); a1 = piModel.getA1(); r1 = piModel.getR1(); - disabled = b.isDisabled(); + disabled = branch.isDisabled(); } - public void restoreBranchState(LfBranch branch) { + public void restore() { PiModel piModel = branch.getPiModel(); piModel.setA1(a1); piModel.setR1(r1); branch.setDisabled(disabled); } - /** - * Get the map of the states of given branches, indexed by the branch itself - * @param branches the bus for which the state is returned - * @return the map of the states of given branches, indexed by the branch itself - */ - public static Map createBranchStates(Collection branches) { - return branches.stream().collect(Collectors.toMap(Function.identity(), BranchState::new)); + public static BranchState save(LfBranch branch) { + return new BranchState(branch); + } + + public static List save(Collection branches) { + return branches.stream().map(BranchState::save).collect(Collectors.toList()); } - /** - * Set the branch states based on the given map of states - * @param branchStates the map containing the branches states, indexed by branches - */ - public static void restoreBranchStates(Map branchStates) { - branchStates.forEach((b, state) -> state.restoreBranchState(b)); + public static void restore(Collection branchStates) { + branchStates.forEach(BranchState::restore); } } diff --git a/src/main/java/com/powsybl/openloadflow/network/BusState.java b/src/main/java/com/powsybl/openloadflow/network/BusState.java index dbc6bbaef0..b8aeae0c19 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BusState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BusState.java @@ -7,14 +7,18 @@ package com.powsybl.openloadflow.network; import java.util.Collection; -import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.stream.Collectors; /** * @author Florian Dupuy */ public class BusState { + + private final LfBus bus; + private final double angle; private final double loadTargetP; private final double loadTargetQ; @@ -23,18 +27,21 @@ public class BusState { private final boolean isVoltageControllerEnabled; private final double generationTargetQ; - public BusState(LfBus b) { - this.angle = b.getAngle(); - this.loadTargetP = b.getLoadTargetP(); - this.loadTargetQ = b.getLoadTargetQ(); - this.generatorsTargetP = b.getGenerators().stream().collect(Collectors.toMap(LfGenerator::getId, LfGenerator::getTargetP)); - this.disabled = b.isDisabled(); - this.isVoltageControllerEnabled = b.isVoltageControllerEnabled(); - this.generationTargetQ = b.getGenerationTargetQ(); + public BusState(LfBus bus) { + this.bus = Objects.requireNonNull(bus); + this.angle = bus.getAngle(); + this.loadTargetP = bus.getLoadTargetP(); + this.loadTargetQ = bus.getLoadTargetQ(); + this.generatorsTargetP = bus.getGenerators().stream().collect(Collectors.toMap(LfGenerator::getId, LfGenerator::getTargetP)); + this.disabled = bus.isDisabled(); + this.isVoltageControllerEnabled = bus.isVoltageControllerEnabled(); + this.generationTargetQ = bus.getGenerationTargetQ(); } - public void restoreBusState(LfBus bus) { - restoreBusActiveState(bus); + public void restore() { + bus.setAngle(angle); + bus.setLoadTargetP(loadTargetP); + bus.getGenerators().forEach(g -> g.setTargetP(generatorsTargetP.get(g.getId()))); bus.setLoadTargetQ(loadTargetQ); bus.setGenerationTargetQ(generationTargetQ); bus.setDisabled(disabled); @@ -42,41 +49,15 @@ public void restoreBusState(LfBus bus) { bus.setVoltageControlSwitchOffCount(0); } - public void restoreBusActiveState(LfBus bus) { - bus.setAngle(angle); - bus.setLoadTargetP(loadTargetP); - bus.getGenerators().forEach(g -> g.setTargetP(generatorsTargetP.get(g.getId()))); - } - - /** - * Get the map of the states of given buses, indexed by the bus itself - * @param buses the bus for which the state is returned - * @return the map of the states of given buses, indexed by the bus itself - */ - public static Map createBusStates(Collection buses) { - Map busStates = new HashMap<>(); - addBusStates(buses, busStates); - return busStates; + public static BusState save(LfBus bus) { + return new BusState(bus); } - public static void addBusStates(Collection busesToSave, Map busStates) { - busesToSave.forEach(lfBus -> busStates.put(lfBus, new BusState(lfBus))); + public static List save(Collection buses) { + return buses.stream().map(BusState::save).collect(Collectors.toList()); } - /** - * Set the bus states based on the given map of states - * @param busStates the map containing the bus states, indexed by buses - */ - public static void restoreBusStates(Map busStates) { - busStates.forEach((b, state) -> state.restoreBusState(b)); - } - - /** - * Set the bus states based on the given map of states - * @param busStates the map containing the bus states, indexed by buses - */ - public static void restoreBusActiveStates(Map busStates) { - busStates.forEach((b, state) -> state.restoreBusActiveState(b)); + public static void restore(Collection busStates) { + busStates.forEach(BusState::restore); } } - diff --git a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java index 29453614ce..9559cf7364 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java @@ -132,8 +132,8 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List busStates = BusState.createBusStates(network.getBuses()); - Map branchStates = BranchState.createBranchStates(network.getBranches()); + List busStates = BusState.save(network.getBuses()); + List branchStates = BranchState.save(network.getBranches()); for (LfBus bus : network.getBuses()) { bus.setVoltageControlSwitchOffCount(0); } @@ -160,8 +160,8 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List contingencies, .flatMap(contingency -> LfContingency.create(contingency, lfNetwork, connectivity, false).stream()) .collect(Collectors.toList()); - Map busStates = BusState.createBusStates(lfNetwork.getBuses()); + List busStates = BusState.save(lfNetwork.getBuses()); // Contingency not breaking connectivity for (LfContingency lfContingency : lfContingencies.stream().filter(lfContingency -> lfContingency.getBuses().isEmpty()).collect(Collectors.toSet())) { @@ -290,7 +290,7 @@ public void analyse(Network network, List contingencies, }); calculatePostContingencySensitivityValues(contingencyFactors, lfContingency, lfNetwork, engine, factorGroups, slackParticipationByBus, lfParameters, lfParametersExt, lfContingency.getId(), lfContingency.getIndex(), valueWriter, reporter, hasTransformerBusTargetVoltage); - BusState.restoreBusStates(busStates); + BusState.restore(busStates); } // Contingency breaking connectivity @@ -327,7 +327,7 @@ public void analyse(Network network, List contingencies, calculatePostContingencySensitivityValues(contingencyFactors, lfContingency, lfNetwork, engine, factorGroups, slackParticipationByBusForThisConnectivity, lfParameters, lfParametersExt, lfContingency.getId(), lfContingency.getIndex(), valueWriter, reporter, hasTransformerBusTargetVoltage); - BusState.restoreBusStates(busStates); + BusState.restore(busStates); connectivity.reset(); } diff --git a/src/main/java/com/powsybl/openloadflow/sensi/DcSensitivityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sensi/DcSensitivityAnalysis.java index e5eabadba7..831b21b7a7 100644 --- a/src/main/java/com/powsybl/openloadflow/sensi/DcSensitivityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sensi/DcSensitivityAnalysis.java @@ -174,14 +174,14 @@ protected DenseMatrix setReferenceActivePowerFlows(DcLoadFlowEngine dcLoadFlowEn List participatingElements, Collection disabledBuses, Collection disabledBranches, Reporter reporter) { - Map busStates = new HashMap<>(); + List busStates = Collections.emptyList(); if (lfParameters.isDistributedSlack()) { - busStates = BusState.createBusStates(participatingElements.stream() + busStates = BusState.save(participatingElements.stream() .map(ParticipatingElement::getLfBus) .collect(Collectors.toSet())); } // the A1 variables will be set to 0 for disabledBranches, so we need to restore them at the end - Map branchStates = BranchState.createBranchStates(disabledBranches); + List branchStates = BranchState.save(disabledBranches); dcLoadFlowEngine.run(equationSystem, j, disabledBuses, disabledBranches, reporter); @@ -190,9 +190,9 @@ protected DenseMatrix setReferenceActivePowerFlows(DcLoadFlowEngine dcLoadFlowEn } if (lfParameters.isDistributedSlack()) { - BusState.restoreBusActiveStates(busStates); + BusState.restore(busStates); } - BranchState.restoreBranchStates(branchStates); + BranchState.restore(branchStates); double[] dx = dcLoadFlowEngine.getTargetVector(); return new DenseMatrix(dx.length, 1, dx); @@ -578,7 +578,7 @@ private void processGenerator(LfNetwork lfNetwork, Generator generator, } private void applyInjectionContingencies(Network network, LfNetwork lfNetwork, PropagatedContingency contingency, - Set participatingGeneratorsToRemove, Map busStates, + Set participatingGeneratorsToRemove, List busStates, LoadFlowParameters lfParameters) { // it applies on the network the loss of DC lines contained in the contingency. // it applies on the network the loss of generators contained in the contingency. @@ -600,12 +600,9 @@ private void applyInjectionContingencies(Network network, LfNetwork lfNetwork, P processGenerator(lfNetwork, generator, generators); } - Collection busesToSave = new HashSet<>(); - lccs.stream().map(Pair::getKey).forEach(busesToSave::add); - vscs.stream().map(LfGenerator::getBus).forEach(busesToSave::add); - generators.stream().map(LfGenerator::getBus).forEach(busesToSave::add); - - BusState.addBusStates(busesToSave, busStates); + lccs.stream().map(Pair::getKey).forEach(b -> busStates.add(BusState.save(b))); + vscs.stream().map(LfGenerator::getBus).forEach(b -> busStates.add(BusState.save(b))); + generators.stream().map(LfGenerator::getBus).forEach(b -> busStates.add(BusState.save(b))); for (Pair busAndlcc : lccs) { LfBus bus = busAndlcc.getKey(); @@ -656,7 +653,7 @@ public void calculateContingencySensitivityValues(PropagatedContingency continge // if we have a contingency including the loss of a DC line or a generator // if we have a contingency including the loss of a generator - Map busStates = new HashMap<>(); + List busStates = new ArrayList<>(); Set participatingGeneratorsToRemove = new HashSet<>(); applyInjectionContingencies(network, lfNetwork, contingency, participatingGeneratorsToRemove, busStates, lfParameters); @@ -681,7 +678,7 @@ public void calculateContingencySensitivityValues(PropagatedContingency continge calculateSensitivityValues(factors, newFactorStates, contingenciesStates, newFlowStates, contingencyElements, contingency, valueWriter); - BusState.restoreBusStates(busStates); + BusState.restore(busStates); if (participatingElementsChanged) { setBaseCaseSensitivityValues(factorGroups, factorStates); } From a3a692917993e5a352150f5926a82bf3928c50ae Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 9 Nov 2021 00:04:30 +0100 Subject: [PATCH 07/37] Fix branche state Signed-off-by: Geoffroy Jamgotchian --- .../powsybl/openloadflow/network/BranchState.java | 10 ++++++++++ .../com/powsybl/openloadflow/network/BusState.java | 12 ++++++------ 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/network/BranchState.java b/src/main/java/com/powsybl/openloadflow/network/BranchState.java index 7cbd0a8106..4823441124 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BranchState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BranchState.java @@ -20,6 +20,8 @@ public class BranchState { private final double a1; private final double r1; + private final DiscretePhaseControl.Mode discretePhaseControlMode; + private final DiscreteVoltageControl.Mode discreteVoltageControlMode; private final boolean disabled; public BranchState(LfBranch branch) { @@ -27,6 +29,8 @@ public BranchState(LfBranch branch) { PiModel piModel = branch.getPiModel(); a1 = piModel.getA1(); r1 = piModel.getR1(); + discretePhaseControlMode = branch.getDiscretePhaseControl().map(DiscretePhaseControl::getMode).orElse(null); + discreteVoltageControlMode = branch.getDiscreteVoltageControl().map(DiscreteVoltageControl::getMode).orElse(null); disabled = branch.isDisabled(); } @@ -34,6 +38,12 @@ public void restore() { PiModel piModel = branch.getPiModel(); piModel.setA1(a1); piModel.setR1(r1); + if (discretePhaseControlMode != null) { + branch.getDiscretePhaseControl().ifPresent(control -> control.setMode(discretePhaseControlMode)); + } + if (discreteVoltageControlMode != null) { + branch.getDiscreteVoltageControl().ifPresent(control -> control.setMode(discreteVoltageControlMode)); + } branch.setDisabled(disabled); } diff --git a/src/main/java/com/powsybl/openloadflow/network/BusState.java b/src/main/java/com/powsybl/openloadflow/network/BusState.java index b8aeae0c19..b0908cf4e4 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BusState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BusState.java @@ -23,9 +23,9 @@ public class BusState { private final double loadTargetP; private final double loadTargetQ; private final Map generatorsTargetP; - private final boolean disabled; - private final boolean isVoltageControllerEnabled; private final double generationTargetQ; + private final boolean isVoltageControllerEnabled; + private final boolean disabled; public BusState(LfBus bus) { this.bus = Objects.requireNonNull(bus); @@ -33,20 +33,20 @@ public BusState(LfBus bus) { this.loadTargetP = bus.getLoadTargetP(); this.loadTargetQ = bus.getLoadTargetQ(); this.generatorsTargetP = bus.getGenerators().stream().collect(Collectors.toMap(LfGenerator::getId, LfGenerator::getTargetP)); - this.disabled = bus.isDisabled(); - this.isVoltageControllerEnabled = bus.isVoltageControllerEnabled(); this.generationTargetQ = bus.getGenerationTargetQ(); + this.isVoltageControllerEnabled = bus.isVoltageControllerEnabled(); + this.disabled = bus.isDisabled(); } public void restore() { bus.setAngle(angle); bus.setLoadTargetP(loadTargetP); - bus.getGenerators().forEach(g -> g.setTargetP(generatorsTargetP.get(g.getId()))); bus.setLoadTargetQ(loadTargetQ); + bus.getGenerators().forEach(g -> g.setTargetP(generatorsTargetP.get(g.getId()))); bus.setGenerationTargetQ(generationTargetQ); - bus.setDisabled(disabled); bus.setVoltageControllerEnabled(isVoltageControllerEnabled); bus.setVoltageControlSwitchOffCount(0); + bus.setDisabled(disabled); } public static BusState save(LfBus bus) { From a4d12938d0bae12e27595efc1c50834c03aa266e Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 9 Nov 2021 21:25:57 +0100 Subject: [PATCH 08/37] Cleanup Signed-off-by: Geoffroy Jamgotchian --- .../openloadflow/network/impl/AbstractLfBus.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java index 7235122f2a..3ccedad25c 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java @@ -493,16 +493,6 @@ public void setDiscreteVoltageControl(DiscreteVoltageControl discreteVoltageCont this.discreteVoltageControl = discreteVoltageControl; } - @Override - public boolean isDisabled() { - return disabled; - } - - @Override - public void setDisabled(boolean disabled) { - this.disabled = disabled; - } - @Override public void setP(Evaluable p) { this.p = Objects.requireNonNull(p); From 3dab170fdf2200669a42a8c167c60e7b5d1589b9 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 9 Nov 2021 22:00:55 +0100 Subject: [PATCH 09/37] Refactoring Signed-off-by: Geoffroy Jamgotchian --- .../network/impl/LfNetworkLoaderImpl.java | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/LfNetworkLoaderImpl.java b/src/main/java/com/powsybl/openloadflow/network/impl/LfNetworkLoaderImpl.java index 22c6aefb88..8155bbf798 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfNetworkLoaderImpl.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfNetworkLoaderImpl.java @@ -586,20 +586,23 @@ private static void createDiscreteVoltageControl(LfNetwork lfNetwork, RatioTapCh return; } - Optional candidateDiscreteVoltageControl = controlledBus.getDiscreteVoltageControl() - .filter(dvc -> controlledBus.isDiscreteVoltageControlled()); - if (candidateDiscreteVoltageControl.isPresent()) { + double regulatingTerminalNominalV = rtc.getRegulationTerminal().getVoltageLevel().getNominalV(); + double targetValue = rtc.getTargetV() / regulatingTerminalNominalV; + + controlledBus.getDiscreteVoltageControl().ifPresentOrElse(vc -> { LOGGER.trace("Controlled bus {} already has a transformer voltage control: a shared control is created", controlledBus.getId()); - candidateDiscreteVoltageControl.get().addController(controllerBranch); - controllerBranch.setDiscreteVoltageControl(candidateDiscreteVoltageControl.get()); - } else { - double regulatingTerminalNominalV = rtc.getRegulationTerminal().getVoltageLevel().getNominalV(); - DiscreteVoltageControl discreteVoltageControl = new DiscreteVoltageControl(controlledBus, - DiscreteVoltageControl.Mode.VOLTAGE, rtc.getTargetV() / regulatingTerminalNominalV); - discreteVoltageControl.addController(controllerBranch); - controllerBranch.setDiscreteVoltageControl(discreteVoltageControl); - controlledBus.setDiscreteVoltageControl(discreteVoltageControl); - } + if (FastMath.abs(vc.getTargetValue() - targetValue) > TARGET_V_EPSILON) { + LOGGER.warn("Controlled bus {} already has a transformer voltage control with a different target voltage: {} and {}", + controlledBus.getId(), vc.getTargetValue(), targetValue); + } + vc.addController(controllerBranch); + controllerBranch.setDiscreteVoltageControl(vc); + }, () -> { + DiscreteVoltageControl discreteVoltageControl = new DiscreteVoltageControl(controlledBus, DiscreteVoltageControl.Mode.VOLTAGE, targetValue); + discreteVoltageControl.addController(controllerBranch); + controllerBranch.setDiscreteVoltageControl(discreteVoltageControl); + controlledBus.setDiscreteVoltageControl(discreteVoltageControl); + }); } private static LfBus getLfBus(Terminal terminal, LfNetwork lfNetwork, boolean breakers) { From 321021137bc5e6b2144529ba05bc135374120456 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 9 Nov 2021 22:38:32 +0100 Subject: [PATCH 10/37] Refactoring Signed-off-by: Geoffroy Jamgotchian --- .../TransformerVoltageControlOuterLoop.java | 23 ++++++------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java index 12532a8076..4599c9a780 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java +++ b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java @@ -10,14 +10,12 @@ import com.powsybl.openloadflow.ac.outerloop.OuterLoop; import com.powsybl.openloadflow.ac.outerloop.OuterLoopContext; import com.powsybl.openloadflow.ac.outerloop.OuterLoopStatus; -import com.powsybl.openloadflow.network.*; +import com.powsybl.openloadflow.network.DiscreteVoltageControl; +import com.powsybl.openloadflow.network.LfBranch; +import com.powsybl.openloadflow.network.PiModel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - /** * @author Anne Tilloy */ @@ -34,17 +32,10 @@ public String getType() { public OuterLoopStatus check(OuterLoopContext context, Reporter reporter) { if (context.getIteration() == 0) { - List voltageControlsOn = context.getNetwork().getBuses().stream() - .map(bus -> bus.getDiscreteVoltageControl().filter(dvc -> bus.isDiscreteVoltageControlled())) - .filter(Optional::isPresent) - .map(Optional::get) - .collect(Collectors.toList()); - - // switch off regulating transformers - voltageControlsOn.forEach(this::switchOffVoltageControl); - - // if at least one transformer has been switched off wee need to continue - return voltageControlsOn.isEmpty() ? OuterLoopStatus.STABLE : OuterLoopStatus.UNSTABLE; + context.getNetwork().getBuses().stream() + .flatMap(bus -> bus.getDiscreteVoltageControl().filter(dvc -> bus.isDiscreteVoltageControlled()).stream()) + .forEach(this::switchOffVoltageControl); + return OuterLoopStatus.UNSTABLE; } return OuterLoopStatus.STABLE; From 4676db62fbe0071dbb1cc2e29101ee0099ffec91 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 10 Nov 2021 15:13:35 +0100 Subject: [PATCH 11/37] Refactoring Signed-off-by: Geoffroy Jamgotchian --- .../network/AbstractLfBranch.java | 20 +++++++++---------- .../openloadflow/network/BranchState.java | 5 ----- .../openloadflow/network/BusState.java | 5 +++++ .../network/impl/LfBranchImpl.java | 6 +++--- .../network/impl/LfLegBranch.java | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/network/AbstractLfBranch.java b/src/main/java/com/powsybl/openloadflow/network/AbstractLfBranch.java index fa4b8aecf9..0edeb3baa8 100644 --- a/src/main/java/com/powsybl/openloadflow/network/AbstractLfBranch.java +++ b/src/main/java/com/powsybl/openloadflow/network/AbstractLfBranch.java @@ -63,7 +63,7 @@ public void setAcceptableDuration(int acceptableDuration) { private final PiModel piModel; - protected DiscretePhaseControl phaseControl; + protected DiscretePhaseControl discretePhaseControl; protected DiscreteVoltageControl discreteVoltageControl; @@ -137,27 +137,27 @@ public PiModel getPiModel() { @Override public Optional getDiscretePhaseControl() { - return Optional.ofNullable(phaseControl); + return Optional.ofNullable(discretePhaseControl); } @Override public void setDiscretePhaseControl(DiscretePhaseControl discretePhaseControl) { - this.phaseControl = discretePhaseControl; + this.discretePhaseControl = discretePhaseControl; } @Override public boolean isPhaseController() { - return phaseControl != null && phaseControl.getController() == this; + return discretePhaseControl != null && discretePhaseControl.getController() == this; } @Override public boolean isPhaseControlled() { - return phaseControl != null && phaseControl.getControlled() == this; + return discretePhaseControl != null && discretePhaseControl.getControlled() == this; } @Override public boolean isPhaseControlled(DiscretePhaseControl.ControlledSide controlledSide) { - return isPhaseControlled() && phaseControl.getControlledSide() == controlledSide; + return isPhaseControlled() && discretePhaseControl.getControlledSide() == controlledSide; } protected void updateTapPosition(PhaseTapChanger ptc) { @@ -171,11 +171,11 @@ protected void updateTapPosition(RatioTapChanger rtc, double ptcRho, double rho) } protected void checkTargetDeadband(double p) { - double distance = Math.abs(p - phaseControl.getTargetValue()); // in per unit system - if (distance > phaseControl.getTargetDeadband() / 2) { + double distance = Math.abs(p - discretePhaseControl.getTargetValue()); // in per unit system + if (distance > discretePhaseControl.getTargetDeadband() / 2) { LOGGER.warn("The active power on side {} of branch {} ({} MW) is out of the target value ({} MW) +/- deadband/2 ({} MW)", - phaseControl.getControlledSide(), getId(), p, - phaseControl.getTargetValue() * PerUnit.SB, phaseControl.getTargetDeadband() / 2 * PerUnit.SB); + discretePhaseControl.getControlledSide(), getId(), p, + discretePhaseControl.getTargetValue() * PerUnit.SB, discretePhaseControl.getTargetDeadband() / 2 * PerUnit.SB); } } diff --git a/src/main/java/com/powsybl/openloadflow/network/BranchState.java b/src/main/java/com/powsybl/openloadflow/network/BranchState.java index 4823441124..1c61d3264a 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BranchState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BranchState.java @@ -21,7 +21,6 @@ public class BranchState { private final double a1; private final double r1; private final DiscretePhaseControl.Mode discretePhaseControlMode; - private final DiscreteVoltageControl.Mode discreteVoltageControlMode; private final boolean disabled; public BranchState(LfBranch branch) { @@ -30,7 +29,6 @@ public BranchState(LfBranch branch) { a1 = piModel.getA1(); r1 = piModel.getR1(); discretePhaseControlMode = branch.getDiscretePhaseControl().map(DiscretePhaseControl::getMode).orElse(null); - discreteVoltageControlMode = branch.getDiscreteVoltageControl().map(DiscreteVoltageControl::getMode).orElse(null); disabled = branch.isDisabled(); } @@ -41,9 +39,6 @@ public void restore() { if (discretePhaseControlMode != null) { branch.getDiscretePhaseControl().ifPresent(control -> control.setMode(discretePhaseControlMode)); } - if (discreteVoltageControlMode != null) { - branch.getDiscreteVoltageControl().ifPresent(control -> control.setMode(discreteVoltageControlMode)); - } branch.setDisabled(disabled); } diff --git a/src/main/java/com/powsybl/openloadflow/network/BusState.java b/src/main/java/com/powsybl/openloadflow/network/BusState.java index b0908cf4e4..738f04a1c7 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BusState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BusState.java @@ -25,6 +25,7 @@ public class BusState { private final Map generatorsTargetP; private final double generationTargetQ; private final boolean isVoltageControllerEnabled; + private final DiscreteVoltageControl.Mode discreteVoltageControlMode; private final boolean disabled; public BusState(LfBus bus) { @@ -35,6 +36,7 @@ public BusState(LfBus bus) { this.generatorsTargetP = bus.getGenerators().stream().collect(Collectors.toMap(LfGenerator::getId, LfGenerator::getTargetP)); this.generationTargetQ = bus.getGenerationTargetQ(); this.isVoltageControllerEnabled = bus.isVoltageControllerEnabled(); + discreteVoltageControlMode = bus.getDiscreteVoltageControl().map(DiscreteVoltageControl::getMode).orElse(null); this.disabled = bus.isDisabled(); } @@ -46,6 +48,9 @@ public void restore() { bus.setGenerationTargetQ(generationTargetQ); bus.setVoltageControllerEnabled(isVoltageControllerEnabled); bus.setVoltageControlSwitchOffCount(0); + if (discreteVoltageControlMode != null) { + bus.getDiscreteVoltageControl().ifPresent(control -> control.setMode(discreteVoltageControlMode)); + } bus.setDisabled(disabled); } diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/LfBranchImpl.java b/src/main/java/com/powsybl/openloadflow/network/impl/LfBranchImpl.java index 349a2ca977..d51bf35c83 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfBranchImpl.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfBranchImpl.java @@ -250,14 +250,14 @@ public void updateState(boolean phaseShifterRegulationOn, boolean isTransformerV branch.getTerminal2().setP(p2.eval() * PerUnit.SB); branch.getTerminal2().setQ(q2.eval() * PerUnit.SB); - if (phaseShifterRegulationOn && isPhaseController() && phaseControl.getMode() != DiscretePhaseControl.Mode.CONTROLLER) { + if (phaseShifterRegulationOn && isPhaseController() && discretePhaseControl.getMode() != DiscretePhaseControl.Mode.CONTROLLER) { // it means there is a regulating phase tap changer located on that branch updateTapPosition(((TwoWindingsTransformer) branch).getPhaseTapChanger()); } - if (phaseShifterRegulationOn && isPhaseControlled() && phaseControl.getMode() != DiscretePhaseControl.Mode.LIMITER) { + if (phaseShifterRegulationOn && isPhaseControlled() && discretePhaseControl.getMode() != DiscretePhaseControl.Mode.LIMITER) { // check if the target value deadband is respected - checkTargetDeadband(phaseControl.getControlledSide() == DiscretePhaseControl.ControlledSide.ONE ? p1.eval() : p2.eval()); + checkTargetDeadband(discretePhaseControl.getControlledSide() == DiscretePhaseControl.ControlledSide.ONE ? p1.eval() : p2.eval()); } if (isTransformerVoltageControlOn && isVoltageController()) { // it means there is a regulating ratio tap changer diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/LfLegBranch.java b/src/main/java/com/powsybl/openloadflow/network/impl/LfLegBranch.java index 427974bb90..4fd6a86b18 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfLegBranch.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfLegBranch.java @@ -133,12 +133,12 @@ public void updateState(boolean phaseShifterRegulationOn, boolean isTransformerV leg.getTerminal().setP(p.eval() * PerUnit.SB); leg.getTerminal().setQ(q.eval() * PerUnit.SB); - if (phaseShifterRegulationOn && isPhaseController() && phaseControl.getMode() == DiscretePhaseControl.Mode.OFF) { + if (phaseShifterRegulationOn && isPhaseController() && discretePhaseControl.getMode() == DiscretePhaseControl.Mode.OFF) { // it means there is a regulating phase tap changer located on that leg updateTapPosition(leg.getPhaseTapChanger()); } - if (phaseShifterRegulationOn && isPhaseControlled() && phaseControl.getControlledSide() == DiscretePhaseControl.ControlledSide.ONE) { + if (phaseShifterRegulationOn && isPhaseControlled() && discretePhaseControl.getControlledSide() == DiscretePhaseControl.ControlledSide.ONE) { // check if the target value deadband is respected checkTargetDeadband(p.eval()); } From 613fce0227f5ea70c919181a600a15deb4c0648a Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 10 Nov 2021 15:38:29 +0100 Subject: [PATCH 12/37] Refactoring Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystemUpdater.java | 43 +++++++++++-------- 1 file changed, 26 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index 055486e1b5..1a984900a6 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -13,7 +13,6 @@ import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -38,7 +37,7 @@ public AcEquationSystemUpdater(EquationSystem eq this.networkParameters = Objects.requireNonNull(networkParameters); } - private void updateControlledBus(VoltageControl voltageControl, EquationSystem equationSystem, VariableSet variableSet) { + private void updateVoltageControl(VoltageControl voltageControl) { LfBus controlledBus = voltageControl.getControlledBus(); Set controllerBuses = voltageControl.getControllerBuses(); @@ -66,29 +65,30 @@ private void updateControlledBus(VoltageControl voltageControl, EquationSystem qEq = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.BUS_Q); qEq.setActive(false); - Optional vc = controllerBus.getVoltageControl(); - if (vc.isPresent() && controllerBus.isVoltageControllerEnabled()) { - updateControlledBus(vc.get(), equationSystem, variableSet); - } + controllerBus.getVoltageControl() + .filter(bus -> controllerBus.isVoltageControllerEnabled()) + .ifPresent(this::updateVoltageControl); } else { // switch PV/PQ Equation qEq = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.BUS_Q); qEq.setActive(true); - Optional vc = controllerBus.getVoltageControl(); - if (vc.isPresent() && controllerBus.hasVoltageControllerCapability()) { - updateControlledBus(vc.get(), equationSystem, variableSet); - } + controllerBus.getVoltageControl() + .filter(bus -> controllerBus.hasVoltageControllerCapability()) + .ifPresent(this::updateVoltageControl); } } @Override - public void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode oldMode, DiscretePhaseControl.Mode newMode) { + public void onVoltageControlChange(LfBus controllerBus, boolean newVoltageControllerEnabled) { + updateVoltageControl(controllerBus, newVoltageControllerEnabled); + } + + private void updateDiscretePhaseControl(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode newMode) { boolean on = newMode != DiscretePhaseControl.Mode.OFF; // activate/de-activate phase control equation @@ -101,12 +101,16 @@ public void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl, } @Override - public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode oldMode, DiscreteVoltageControl.Mode newMode) { - LfBus bus = voltageControl.getControlled(); + public void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl, DiscretePhaseControl.Mode oldMode, DiscretePhaseControl.Mode newMode) { + updateDiscretePhaseControl(phaseControl, newMode); + } + + private void updateDiscreteVoltageControl(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) { + LfBus controlledBus = voltageControl.getControlled(); if (newMode == DiscreteVoltageControl.Mode.OFF) { // de-activate transformer voltage control equation - equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V) + equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_V) .setActive(false); for (LfBranch controllerBranch : voltageControl.getControllers()) { @@ -120,7 +124,7 @@ public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageCon } else { // newMode == DiscreteVoltageControl.Mode.VOLTAGE // activate transformer voltage control equation - equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V) + equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_V) .setActive(true); // add transformer distribution equations @@ -134,6 +138,11 @@ public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageCon } } + @Override + public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode oldMode, DiscreteVoltageControl.Mode newMode) { + updateDiscreteVoltageControl(voltageControl, newMode); + } + @Override public void onDisableChange(LfElement element, boolean disabled) { switch (element.getType()) { From d3ab1c7d63eeaadb660aef470e22ecdbee76ad45 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 10 Nov 2021 20:31:11 +0100 Subject: [PATCH 13/37] Fix Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 4 ++-- .../ac/equations/AcEquationType.java | 19 +++++++++--------- .../ac/outerloop/AcloadFlowEngine.java | 4 ---- .../equations/EquationSystemTest.java | 20 +++++++++---------- 4 files changed, 21 insertions(+), 26 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index 0e8661dd6a..588aef4dd8 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -476,13 +476,13 @@ private static void createImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2 } if (i1 != null) { - Equation i = equationSystem.createEquation(bus1.getNum(), AcEquationType.BUS_I).addTerm(i1); + Equation i = equationSystem.createEquation(bus1.getNum(), AcEquationType.BRANCH_I).addTerm(i1); i.setUpdateType(EquationSystem.EquationUpdateType.AFTER_NR); // only update those equations after the newton raphson branch.setI1(i1); } if (i2 != null) { - Equation i = equationSystem.createEquation(bus2.getNum(), AcEquationType.BUS_I).addTerm(i2); + Equation i = equationSystem.createEquation(bus2.getNum(), AcEquationType.BRANCH_I).addTerm(i2); i.setUpdateType(EquationSystem.EquationUpdateType.AFTER_NR); // only update those equations after the newton raphson branch.setI2(i2); } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationType.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationType.java index 7806e71b56..5881b90185 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationType.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationType.java @@ -13,21 +13,20 @@ * @author Geoffroy Jamgotchian */ public enum AcEquationType implements Quantity { - BUS_P("p", ElementType.BUS), - BUS_I("b_i", ElementType.BUS), - BUS_Q("q", ElementType.BUS), + BUS_P("bus_p", ElementType.BUS), + BUS_Q("bus_q", ElementType.BUS), BUS_V("v", ElementType.BUS), BUS_V_SLOPE("v_slope", ElementType.BUS), BUS_PHI("\u03C6", ElementType.BUS), - BRANCH_P("t", ElementType.BRANCH), - BRANCH_I("i", ElementType.BRANCH), - BRANCH_Q("q", ElementType.BRANCH), + BRANCH_P("branch_p", ElementType.BRANCH), + BRANCH_I("branch_i", ElementType.BRANCH), + BRANCH_Q("branch_q", ElementType.BRANCH), BRANCH_ALPHA1("\u03B1" + "1", ElementType.BRANCH), BRANCH_RHO1("\u03C1" + "1", ElementType.BRANCH), - ZERO_Q("z_q", ElementType.BUS), - ZERO_V("z_v", ElementType.BRANCH), - ZERO_PHI("z_\u03C6", ElementType.BRANCH), - ZERO_RHO1("z_\u03C1", ElementType.BRANCH); + ZERO_Q("zero_q", ElementType.BUS), + ZERO_V("zero_v", ElementType.BRANCH), + ZERO_PHI("zero_\u03C6", ElementType.BRANCH), + ZERO_RHO1("zero_\u03C1", ElementType.BRANCH); private final String symbol; diff --git a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java index bbcdecee4c..1e6e3e0e0e 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java +++ b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java @@ -184,10 +184,6 @@ public static void initTarget(Equation equation, targets[equation.getColumn()] = LfBranch.getDiscretePhaseControlTarget(network.getBranch(equation.getNum()), DiscretePhaseControl.Unit.MW); break; - case BRANCH_I: - targets[equation.getColumn()] = LfBranch.getDiscretePhaseControlTarget(network.getBranch(equation.getNum()), DiscretePhaseControl.Unit.A); - break; - case BRANCH_Q: targets[equation.getColumn()] = getReactivePowerControlTarget(network.getBranch(equation.getNum())); break; diff --git a/src/test/java/com/powsybl/openloadflow/equations/EquationSystemTest.java b/src/test/java/com/powsybl/openloadflow/equations/EquationSystemTest.java index 78ef8eb274..d6ee5404c1 100644 --- a/src/test/java/com/powsybl/openloadflow/equations/EquationSystemTest.java +++ b/src/test/java/com/powsybl/openloadflow/equations/EquationSystemTest.java @@ -137,12 +137,12 @@ void writeAcSystemTest() throws IOException { String ref = String.join(System.lineSeparator(), "v0 = v0", "φ0 = φ0", - "p1 = ac_p_closed_2(v0, v1, φ0, φ1) + ac_p_closed_1(v1, v2, φ1, φ2) + ac_p_closed_1(v1, v2, φ1, φ2)", - "q1 = ac_q_closed_2(v0, v1, φ0, φ1) + ac_q_closed_1(v1, v2, φ1, φ2) + ac_q_closed_1(v1, v2, φ1, φ2)", - "p2 = ac_p_closed_2(v1, v2, φ1, φ2) + ac_p_closed_2(v1, v2, φ1, φ2) + ac_p_closed_1(v2, v3, φ2, φ3)", - "q2 = ac_q_closed_2(v1, v2, φ1, φ2) + ac_q_closed_2(v1, v2, φ1, φ2) + ac_q_closed_1(v2, v3, φ2, φ3)", - "p3 = ac_p_closed_2(v2, v3, φ2, φ3)", - "q3 = ac_q_closed_2(v2, v3, φ2, φ3)") + "bus_p1 = ac_p_closed_2(v0, v1, φ0, φ1) + ac_p_closed_1(v1, v2, φ1, φ2) + ac_p_closed_1(v1, v2, φ1, φ2)", + "bus_q1 = ac_q_closed_2(v0, v1, φ0, φ1) + ac_q_closed_1(v1, v2, φ1, φ2) + ac_q_closed_1(v1, v2, φ1, φ2)", + "bus_p2 = ac_p_closed_2(v1, v2, φ1, φ2) + ac_p_closed_2(v1, v2, φ1, φ2) + ac_p_closed_1(v2, v3, φ2, φ3)", + "bus_q2 = ac_q_closed_2(v1, v2, φ1, φ2) + ac_q_closed_2(v1, v2, φ1, φ2) + ac_q_closed_1(v2, v3, φ2, φ3)", + "bus_p3 = ac_p_closed_2(v2, v3, φ2, φ3)", + "bus_q3 = ac_q_closed_2(v2, v3, φ2, φ3)") + System.lineSeparator(); assertEquals(ref, writer.toString()); } @@ -197,8 +197,8 @@ void currentMagnitudeTest() { double[] x = NewtonRaphson.createStateVector(mainNetwork, equationSystem, new UniformValueVoltageInitializer()); equationSystem.updateEquations(x, EquationSystem.EquationUpdateType.AFTER_NR); LfBranch branch = mainNetwork.getBranchById("NHV1_NHV2_1"); - EquationTerm i1 = equationSystem.getEquation(branch.getBus1().getNum(), AcEquationType.BUS_I).orElse(null).getTerms().get(1); - EquationTerm i2 = equationSystem.getEquation(branch.getBus2().getNum(), AcEquationType.BUS_I).orElse(null).getTerms().get(0); + EquationTerm i1 = equationSystem.getEquation(branch.getBus1().getNum(), AcEquationType.BRANCH_I).orElseThrow().getTerms().get(1); + EquationTerm i2 = equationSystem.getEquation(branch.getBus2().getNum(), AcEquationType.BRANCH_I).orElseThrow().getTerms().get(0); Variable v1var = variableSet.getVariable(branch.getBus1().getNum(), AcVariableType.BUS_V); Variable v2var = variableSet.getVariable(branch.getBus2().getNum(), AcVariableType.BUS_V); Variable ph1var = variableSet.getVariable(branch.getBus1().getNum(), AcVariableType.BUS_PHI); @@ -227,7 +227,7 @@ void currentMagnitudeOpenBranchSide2Test() { double[] x = NewtonRaphson.createStateVector(mainNetwork, equationSystem, new UniformValueVoltageInitializer()); equationSystem.updateEquations(x, EquationSystem.EquationUpdateType.AFTER_NR); LfBranch branch = mainNetwork.getBranchById("NHV1_NHV2_1"); - EquationTerm i1 = equationSystem.getEquation(branch.getBus1().getNum(), AcEquationType.BUS_I).orElse(null).getTerms().stream().filter(OpenBranchSide2CurrentMagnitudeEquationTerm.class::isInstance).findAny().get(); + EquationTerm i1 = equationSystem.getEquation(branch.getBus1().getNum(), AcEquationType.BRANCH_I).orElseThrow().getTerms().stream().filter(OpenBranchSide2CurrentMagnitudeEquationTerm.class::isInstance).findAny().get(); Variable v1var = variableSet.getVariable(branch.getBus1().getNum(), AcVariableType.BUS_V); Variable ph1var = variableSet.getVariable(branch.getBus1().getNum(), AcVariableType.BUS_PHI); assertEquals(0.559170, i1.der(v1var), 10E-6); @@ -247,7 +247,7 @@ void currentMagnitudeOpenBranchSide1Test() { double[] x = NewtonRaphson.createStateVector(mainNetwork, equationSystem, new UniformValueVoltageInitializer()); equationSystem.updateEquations(x, EquationSystem.EquationUpdateType.AFTER_NR); LfBranch branch = mainNetwork.getBranchById("NHV1_NHV2_1"); - EquationTerm i2 = equationSystem.getEquation(branch.getBus2().getNum(), AcEquationType.BUS_I).orElse(null).getTerms().stream().filter(OpenBranchSide1CurrentMagnitudeEquationTerm.class::isInstance).findAny().get(); + EquationTerm i2 = equationSystem.getEquation(branch.getBus2().getNum(), AcEquationType.BRANCH_I).orElseThrow().getTerms().stream().filter(OpenBranchSide1CurrentMagnitudeEquationTerm.class::isInstance).findAny().get(); Variable v2var = variableSet.getVariable(branch.getBus2().getNum(), AcVariableType.BUS_V); Variable ph2var = variableSet.getVariable(branch.getBus2().getNum(), AcVariableType.BUS_PHI); assertEquals(0.55917, i2.der(v2var), 10E-6); From 4ac5cfeed9685172891bc15fd4808caf9548f084 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 10 Nov 2021 21:22:38 +0100 Subject: [PATCH 14/37] Cleanup Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystemUpdater.java | 6 +++--- .../powsybl/openloadflow/network/impl/AbstractLfBus.java | 8 ++++++++ 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index 1a984900a6..83d6efe6b4 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -66,15 +66,14 @@ private void updateVoltageControl(VoltageControl voltageControl) { } private void updateVoltageControl(LfBus controllerBus, boolean newVoltageControllerEnabled) { + Equation qEq = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.BUS_Q); if (newVoltageControllerEnabled) { // switch PQ/PV - Equation qEq = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.BUS_Q); qEq.setActive(false); controllerBus.getVoltageControl() .filter(bus -> controllerBus.isVoltageControllerEnabled()) .ifPresent(this::updateVoltageControl); } else { // switch PV/PQ - Equation qEq = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.BUS_Q); qEq.setActive(true); controllerBus.getVoltageControl() @@ -153,7 +152,8 @@ public void onDisableChange(LfElement element, boolean disabled) { // TODO break; case SHUNT_COMPENSATOR: - throw new IllegalStateException("Shunt compensator disabling is not implemented"); + // TODO + break; } } } diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java index 3ccedad25c..e5ce889043 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBus.java @@ -519,6 +519,14 @@ public BusResults createBusResult() { return new BusResults(getVoltageLevelId(), getId(), getV().eval() * scale, getAngle()); } + @Override + public void setDisabled(boolean disabled) { + super.setDisabled(disabled); + for (LfShunt shunt : shunts) { + shunt.setDisabled(disabled); + } + } + @Override public String toString() { return getId(); From 14dae465af659638961e6c7ce6af55bfba83120a Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 5 Jan 2022 22:49:19 +0100 Subject: [PATCH 15/37] Refactor discrete voltage control Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 137 +++++++++++------- .../ac/equations/AcEquationSystemUpdater.java | 35 +---- .../ac/outerloop/AcloadFlowEngine.java | 9 +- 3 files changed, 86 insertions(+), 95 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index 8726547407..b18c252b05 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -36,8 +36,11 @@ private static void createBusEquation(LfBus bus, LfNetworkParameters networkPara createShuntEquations(bus, equationSystem); - if (networkParameters.isTransformerVoltageControl() || networkParameters.isShuntVoltageControl()) { - createDiscreteVoltageControlEquation(bus, equationSystem); + if (networkParameters.isTransformerVoltageControl()) { + createTransformerVoltageControlEquations(bus, equationSystem); + } + if (networkParameters.isShuntVoltageControl()) { + createShuntVoltageControlEquations(bus, equationSystem); } Equation v = equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V); if (v.getTerms().isEmpty()) { @@ -229,6 +232,20 @@ private static void createReactivePowerDistributionEquations(Collection c } } + private static void createBusWithSlopeEquation(LfBus bus, double slope, LfNetworkParameters networkParameters, + EquationSystem equationSystem, + EquationTerm vTerm, AcEquationSystemCreationParameters creationParameters) { + // we only support one generator controlling voltage with a non zero slope at a bus. + // equation is: V + slope * qSVC = targetV + // which is modeled here with: V + slope * (sum_branch qBranch) = TargetV - slope * qLoads + slope * qGenerators + equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V_WITH_SLOPE) + .addTerm(vTerm) + .addTerms(createReactiveTerms(bus, networkParameters, equationSystem.getVariableSet(), creationParameters) + .stream() + .map(term -> term.multiply(slope)) + .collect(Collectors.toList())); + } + private static void createNonImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2, EquationSystem equationSystem) { Optional> v1 = equationSystem.getEquation(bus1.getNum(), AcEquationType.BUS_TARGET_V); @@ -318,85 +335,99 @@ private static void createBranchActivePowerTargetEquation(LfBranch branch, Discr }); } - private static void createDiscreteVoltageControlEquation(LfBus bus, EquationSystem equationSystem) { + private static void createTransformerVoltageControlEquations(LfBus bus, EquationSystem equationSystem) { bus.getTransformerVoltageControl() - .filter(tvc -> bus.isTransformerVoltageControlled()) - .map(TransformerVoltageControl::getControllers) - .ifPresent(controllers -> { + .filter(voltageControl -> bus.isTransformerVoltageControlled()) + .ifPresent(voltageControl -> { + // create voltage target equation at controlled bus EquationTerm vTerm = equationSystem.getVariable(bus.getNum(), AcVariableType.BUS_V) .createTerm(); equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).addTerm(vTerm); bus.setCalculatedV(vTerm); - // add transformer distribution equations - createR1DistributionEquations(controllers, equationSystem); + // add transformer ratio distribution equations + createR1DistributionEquations(voltageControl.getControllers(), equationSystem); - for (LfBranch controllerBranch : controllers) { - // we also create an equation that will be used later to maintain R1 variable constant - // this equation is now inactive + // we also create an equation per controller that will be used later to maintain R1 variable constant + for (LfBranch controllerBranch : voltageControl.getControllers()) { equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1) - .addTerm(equationSystem.getVariable(controllerBranch.getNum(), AcVariableType.BRANCH_RHO1).createTerm()) - .setActive(false); + .addTerm(equationSystem.getVariable(controllerBranch.getNum(), AcVariableType.BRANCH_RHO1).createTerm()); } + + updateTransformerVoltageControlEquations(voltageControl, equationSystem); }); + } + + public static void createR1DistributionEquations(List controllerBranches, + EquationSystem equationSystem) { + for (int i = 0; i < controllerBranches.size(); i++) { + LfBranch controllerBranch = controllerBranches.get(i); + // r1 at controller branch i + // r1_i = sum_j(r1_j) / controller_count where j are all the controller branches + // 0 = sum_j(r1_j) / controller_count - r1_i + // which can be rewritten in a more simple way + // 0 = (1 / controller_count - 1) * r1_i + sum_j(r1_j) / controller_count where j are all the controller branches except i + EquationTerm r1 = equationSystem.getVariable(controllerBranch.getNum(), AcVariableType.BRANCH_RHO1) + .createTerm(); + Equation zero = equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO) + .addTerm(r1.multiply(() -> 1d / controllerBranches.size() - 1)); + for (LfBranch otherControllerBranch : controllerBranches) { + if (otherControllerBranch != controllerBranch) { + EquationTerm otherR1 = equationSystem.getVariable(otherControllerBranch.getNum(), AcVariableType.BRANCH_RHO1) + .createTerm(); + zero.addTerm(otherR1.multiply(() -> 1d / controllerBranches.size())); + } + } + } + } + + static void updateTransformerVoltageControlEquations(TransformerVoltageControl voltageControl, EquationSystem equationSystem) { + // activate voltage target equation if control is on + equationSystem.getEquation(voltageControl.getControlled().getNum(), AcEquationType.BUS_TARGET_V) + .orElseThrow() + .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE); + List controllerBranches = voltageControl.getControllers(); + for (int i = 0; i < controllerBranches.size(); i++) { + LfBranch controllerBranch = controllerBranches.get(i); + + // activate all rho1 equations if voltage control is off + equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1) + .orElseThrow() + .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.OFF); + + // activate rho1 distribution equations except one if control is on + equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO) + .orElseThrow() + .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE && i < controllerBranches.size() - 1); + } + } + + private static void createShuntVoltageControlEquations(LfBus bus, EquationSystem equationSystem) { bus.getShuntVoltageControl() - .filter(svc -> bus.isShuntVoltageControlled()) - .map(ShuntVoltageControl::getControllers) - .ifPresent(controllers -> { + .filter(voltageControl -> bus.isShuntVoltageControlled()) + .ifPresent(voltageControl -> { EquationTerm vTerm = equationSystem.getVariable(bus.getNum(), AcVariableType.BUS_V) .createTerm(); equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V).addTerm(vTerm); bus.setCalculatedV(vTerm); // add shunt distribution equations - createBDistributionEquations(controllers, equationSystem); + createBDistributionEquations(voltageControl.getControllers(), equationSystem); - for (LfBus controllerBus : controllers) { + for (LfBus controllerBus : voltageControl.getControllers()) { // we also create an equation that will be used later to maintain B variable constant // this equation is now inactive controllerBus.getControllerShunt() .ifPresent(shunt -> - equationSystem.createEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) - .addTerm(equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B).createTerm()) - .setActive(false) + equationSystem.createEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) + .addTerm(equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B).createTerm()) + .setActive(false) ); } }); } - private static void createBusWithSlopeEquation(LfBus bus, double slope, LfNetworkParameters networkParameters, - EquationSystem equationSystem, - EquationTerm vTerm, AcEquationSystemCreationParameters creationParameters) { - // we only support one generator controlling voltage with a non zero slope at a bus. - // equation is: V + slope * qSVC = targetV - // which is modeled here with: V + slope * (sum_branch qBranch) = TargetV - slope * qLoads + slope * qGenerators - equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_TARGET_V_WITH_SLOPE) - .addTerm(vTerm) - .addTerms(createReactiveTerms(bus, networkParameters, equationSystem.getVariableSet(), creationParameters) - .stream() - .map(term -> term.multiply(slope)) - .collect(Collectors.toList())); - } - - public static void createR1DistributionEquations(List controllerBranches, - EquationSystem equationSystem) { - if (controllerBranches.size() > 1) { - // we choose first controller branch as reference for R1 - LfBranch firstControllerBranch = controllerBranches.get(0); - - // create a R1 distribution equation for all the other controller branches - for (int i = 1; i < controllerBranches.size(); i++) { - LfBranch controllerBranch = controllerBranches.get(i); - Equation zero = equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO) - .addTerm(equationSystem.getVariable(controllerBranch.getNum(), AcVariableType.BRANCH_RHO1).createTerm()) - .addTerm(equationSystem.getVariable(firstControllerBranch.getNum(), AcVariableType.BRANCH_RHO1).createTerm() - .minus()); - zero.setData(new DistributionData(firstControllerBranch.getNum(), 1)); // for later use - } - } - } - public static void createBDistributionEquations(List controllerBuses, EquationSystem equationSystem) { if (controllerBuses.size() > 1) { diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index bec92b03d4..7a858f9e3d 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -75,39 +75,6 @@ public void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl, updateDiscretePhaseControl(phaseControl, newMode); } - private void updateTransformerVoltageControl(TransformerVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) { - LfBus controlledBus = voltageControl.getControlled(); - if (newMode == DiscreteVoltageControl.Mode.OFF) { - - // de-activate transformer voltage control equation - equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V) - .setActive(false); - - for (LfBranch controllerBranch : voltageControl.getControllers()) { - // activate constant R1 equation - equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1) - .setActive(true); - - // clean transformer distribution equations - equationSystem.removeEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO); - } - } else { // newMode == DiscreteVoltageControl.Mode.VOLTAGE - - // activate transformer voltage control equation - equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V) - .setActive(true); - - // add transformer distribution equations - AcEquationSystem.createR1DistributionEquations(voltageControl.getControllers(), equationSystem); - - for (LfBranch controllerBranch : voltageControl.getControllers()) { - // de-activate constant R1 equation - equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1) - .setActive(false); - } - } - } - private void updateShuntVoltageControl(ShuntVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) { LfBus controlledBus = voltageControl.getControlled(); if (newMode == DiscreteVoltageControl.Mode.OFF) { @@ -147,7 +114,7 @@ private void updateShuntVoltageControl(ShuntVoltageControl voltageControl, Discr @Override public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) { if (voltageControl instanceof TransformerVoltageControl) { - updateTransformerVoltageControl((TransformerVoltageControl) voltageControl, newMode); + AcEquationSystem.updateTransformerVoltageControlEquations((TransformerVoltageControl) voltageControl, equationSystem); } else if (voltageControl instanceof ShuntVoltageControl) { updateShuntVoltageControl((ShuntVoltageControl) voltageControl, newMode); } diff --git a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java index ea187f2ea6..debba93aa4 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java +++ b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java @@ -139,13 +139,6 @@ private static double getReactivePowerDistributionTarget(LfNetwork network, int return target; } - private static double getRho1DistributionTarget(LfNetwork network, int num, DistributionData data) { - LfBranch controllerBranch = network.getBranch(num); - LfBranch firstControllerBranch = network.getBranch(data.getFirstControllerElementNum()); - // as a first and very simple ratio distribution strategy, we keep the gap between the 2 ratios constant - return controllerBranch.getPiModel().getR1() - firstControllerBranch.getPiModel().getR1(); - } - private static double getBDistributionTarget(LfNetwork network, int num, DistributionData data) { LfShunt controllerShunt = network.getShunt(num); LfShunt firstControllerShunt = network.getShunt(data.getFirstControllerElementNum()); @@ -220,7 +213,7 @@ public static void initTarget(Equation equation, break; case DISTR_RHO: - targets[equation.getColumn()] = getRho1DistributionTarget(network, equation.getElementNum(), equation.getData()); + targets[equation.getColumn()] = 0; break; case DISTR_B: From 20658be9992e70c219b4db3e6603d06d33d783b4 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 5 Jan 2022 23:13:40 +0100 Subject: [PATCH 16/37] Refactor shunt voltage control Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 76 +++++++++++++------ .../ac/equations/AcEquationSystemUpdater.java | 50 +++--------- .../ac/outerloop/AcloadFlowEngine.java | 9 +-- 3 files changed, 64 insertions(+), 71 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index b18c252b05..c28f02eb9e 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -413,40 +413,72 @@ private static void createShuntVoltageControlEquations(LfBus bus, EquationSystem bus.setCalculatedV(vTerm); // add shunt distribution equations - createBDistributionEquations(voltageControl.getControllers(), equationSystem); + createShuntSusceptanceDistributionEquations(voltageControl.getControllers(), equationSystem); for (LfBus controllerBus : voltageControl.getControllers()) { // we also create an equation that will be used later to maintain B variable constant // this equation is now inactive controllerBus.getControllerShunt() .ifPresent(shunt -> - equationSystem.createEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) - .addTerm(equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B).createTerm()) - .setActive(false) + equationSystem.createEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) + .addTerm(equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B).createTerm()) ); } + + updateShuntVoltageControlEquations(voltageControl, equationSystem); }); } - public static void createBDistributionEquations(List controllerBuses, - EquationSystem equationSystem) { - if (controllerBuses.size() > 1) { - // we choose first controller bus as reference for B - Optional firstControllerShunt = controllerBuses.get(0).getControllerShunt(); - - if (firstControllerShunt.isPresent()) { - // create a B distribution equation for all the other controller buses - for (int i = 1; i < controllerBuses.size(); i++) { - Optional controllerShunt = controllerBuses.get(i).getControllerShunt(); - if (controllerShunt.isPresent()) { - Equation zero = equationSystem.createEquation(controllerShunt.get().getNum(), AcEquationType.DISTR_B) - .addTerm(equationSystem.getVariable(controllerShunt.get().getNum(), AcVariableType.SHUNT_B).createTerm()) - .addTerm(equationSystem.getVariable(firstControllerShunt.get().getNum(), AcVariableType.SHUNT_B).createTerm() - .minus()); - zero.setData(new DistributionData(firstControllerShunt.get().getNum(), 1)); // for later use + public static void createShuntSusceptanceDistributionEquations(List controllerBuses, + EquationSystem equationSystem) { + for (int i = 0; i < controllerBuses.size(); i++) { + LfBus controllerBus = controllerBuses.get(i); + controllerBus.getControllerShunt() + .ifPresent(shunt -> { + // shunt b at controller bus i + // b_i = sum_j(b_j) / controller_count where j are all the controller buses + // 0 = sum_j(b_j) / controller_count - b_i + // which can be rewritten in a more simple way + // 0 = (1 / controller_count - 1) * b_i + sum_j(b_j) / controller_count where j are all the controller buses except i + EquationTerm shuntB = equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B) + .createTerm(); + Equation zero = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.DISTR_B) + .addTerm(shuntB.multiply(() -> 1d / controllerBuses.size() - 1)); + for (LfBus otherControllerBus : controllerBuses) { + if (otherControllerBus != controllerBus) { + otherControllerBus.getControllerShunt() + .ifPresent(otherShunt -> { + EquationTerm otherShuntB = equationSystem.getVariable(otherShunt.getNum(), AcVariableType.SHUNT_B) + .createTerm(); + zero.addTerm(otherShuntB.multiply(() -> 1d / controllerBuses.size())); + }); + } } - } - } + }); + } + } + + static void updateShuntVoltageControlEquations(ShuntVoltageControl voltageControl, EquationSystem equationSystem) { + // activate voltage target equation if control is on + equationSystem.getEquation(voltageControl.getControlled().getNum(), AcEquationType.BUS_TARGET_V) + .orElseThrow() + .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE); + + List controllerBuses = voltageControl.getControllers(); + for (int i = 0; i < controllerBuses.size(); i++) { + LfBus controllerBus = controllerBuses.get(i); + + // activate all b target equations if voltage control is off + controllerBus.getControllerShunt().ifPresent(shunt -> + equationSystem.getEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) + .orElseThrow() + .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.OFF) + ); + + // activate shunt b distribution equations except one if control is on + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_B) + .orElseThrow() + .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE && i < controllerBuses.size() - 1); } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index 7a858f9e3d..6ca8e94384 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -32,7 +32,8 @@ private void updateVoltageControl(VoltageControl voltageControl) { // we only support one controlling static var compensator without any other controlling generators // we don't support controller bus that wants to control back voltage with slope. if (!firstControllerBus.isVoltageControllerEnabled()) { - equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V_WITH_SLOPE).setActive(false); + equationSystem.getEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V_WITH_SLOPE) + .orElseThrow().setActive(false); } } else { if (voltageControl.isVoltageControlLocal()) { @@ -47,7 +48,8 @@ private void updateVoltageControl(VoltageControl voltageControl) { private void updateVoltageControl(LfBus controllerBus, boolean newVoltageControllerEnabled) { // active/de-activate bus target reactive power equation to switch bus PV or PQ - equationSystem.createEquation(controllerBus.getNum(), AcEquationType.BUS_TARGET_Q) + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.BUS_TARGET_Q) + .orElseThrow() .setActive(!newVoltageControllerEnabled); updateVoltageControl(controllerBus.getVoltageControl().orElseThrow()); @@ -62,11 +64,13 @@ private void updateDiscretePhaseControl(DiscretePhaseControl phaseControl, Discr boolean on = newMode != DiscretePhaseControl.Mode.OFF; // activate/de-activate phase control equation - equationSystem.createEquation(phaseControl.getControlled().getNum(), AcEquationType.BRANCH_TARGET_P) + equationSystem.getEquation(phaseControl.getControlled().getNum(), AcEquationType.BRANCH_TARGET_P) + .orElseThrow() .setActive(on); // de-activate/activate constant A1 equation - equationSystem.createEquation(phaseControl.getController().getNum(), AcEquationType.BRANCH_TARGET_ALPHA1) + equationSystem.getEquation(phaseControl.getController().getNum(), AcEquationType.BRANCH_TARGET_ALPHA1) + .orElseThrow() .setActive(!on); } @@ -75,48 +79,12 @@ public void onDiscretePhaseControlModeChange(DiscretePhaseControl phaseControl, updateDiscretePhaseControl(phaseControl, newMode); } - private void updateShuntVoltageControl(ShuntVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) { - LfBus controlledBus = voltageControl.getControlled(); - if (newMode == DiscreteVoltageControl.Mode.OFF) { - - // de-activate transformer or shunt voltage control equation - equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V) - .setActive(false); - - for (LfBus controllerBus : voltageControl.getControllers()) { - controllerBus.getControllerShunt().ifPresent(shunt -> { - // activate constant B equation - equationSystem.createEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) - .setActive(true); - - // clean shunt distribution equations - equationSystem.removeEquation(shunt.getNum(), AcEquationType.DISTR_B); - }); - } - } else { // newMode == DiscreteVoltageControl.Mode.VOLTAGE - - // de-activate transformer or shunt voltage control equation - equationSystem.createEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V) - .setActive(false); - - // add shunt distribution equations - AcEquationSystem.createBDistributionEquations(voltageControl.getControllers(), equationSystem); - - for (LfBus controllerBus : voltageControl.getControllers()) { - controllerBus.getControllerShunt().ifPresent(shunt -> - // de-activate constant B equation - equationSystem.createEquation(shunt.getNum(), AcEquationType.BRANCH_TARGET_RHO1) - .setActive(false)); - } - } - } - @Override public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageControl, DiscreteVoltageControl.Mode newMode) { if (voltageControl instanceof TransformerVoltageControl) { AcEquationSystem.updateTransformerVoltageControlEquations((TransformerVoltageControl) voltageControl, equationSystem); } else if (voltageControl instanceof ShuntVoltageControl) { - updateShuntVoltageControl((ShuntVoltageControl) voltageControl, newMode); + AcEquationSystem.updateShuntVoltageControlEquations((ShuntVoltageControl) voltageControl, equationSystem); } } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java index debba93aa4..5a01d5d269 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java +++ b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java @@ -139,13 +139,6 @@ private static double getReactivePowerDistributionTarget(LfNetwork network, int return target; } - private static double getBDistributionTarget(LfNetwork network, int num, DistributionData data) { - LfShunt controllerShunt = network.getShunt(num); - LfShunt firstControllerShunt = network.getShunt(data.getFirstControllerElementNum()); - // as a first and very simple B distribution strategy, we keep the gap between the 2 B constant - return controllerShunt.getB() - firstControllerShunt.getB(); - } - private static double createBusWithSlopeTarget(LfBus bus) { // take first generator with slope: network loading ensures that there's only one generator with slope double slope = bus.getGeneratorsControllingVoltageWithSlope().get(0).getSlope(); @@ -217,7 +210,7 @@ public static void initTarget(Equation equation, break; case DISTR_B: - targets[equation.getColumn()] = getBDistributionTarget(network, equation.getElementNum(), equation.getData()); + targets[equation.getColumn()] = 0; break; default: From 75f6543b0215cb8e3fb182d9ab19231689f7a02f Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Wed, 5 Jan 2022 23:20:17 +0100 Subject: [PATCH 17/37] Cleanup Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 20 +++++++++++-------- .../ac/equations/AcEquationType.java | 2 +- .../ac/outerloop/AcloadFlowEngine.java | 5 +---- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index c28f02eb9e..b1b1f2ba74 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -382,10 +382,12 @@ public static void createR1DistributionEquations(List controllerBranch } static void updateTransformerVoltageControlEquations(TransformerVoltageControl voltageControl, EquationSystem equationSystem) { + boolean on = voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE; + // activate voltage target equation if control is on equationSystem.getEquation(voltageControl.getControlled().getNum(), AcEquationType.BUS_TARGET_V) .orElseThrow() - .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE); + .setActive(on); List controllerBranches = voltageControl.getControllers(); for (int i = 0; i < controllerBranches.size(); i++) { @@ -394,12 +396,12 @@ static void updateTransformerVoltageControlEquations(TransformerVoltageControl v // activate all rho1 equations if voltage control is off equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1) .orElseThrow() - .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.OFF); + .setActive(!on); // activate rho1 distribution equations except one if control is on equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO) .orElseThrow() - .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE && i < controllerBranches.size() - 1); + .setActive(on && i < controllerBranches.size() - 1); } } @@ -442,7 +444,7 @@ public static void createShuntSusceptanceDistributionEquations(List contr // 0 = (1 / controller_count - 1) * b_i + sum_j(b_j) / controller_count where j are all the controller buses except i EquationTerm shuntB = equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B) .createTerm(); - Equation zero = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.DISTR_B) + Equation zero = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) .addTerm(shuntB.multiply(() -> 1d / controllerBuses.size() - 1)); for (LfBus otherControllerBus : controllerBuses) { if (otherControllerBus != controllerBus) { @@ -459,10 +461,12 @@ public static void createShuntSusceptanceDistributionEquations(List contr } static void updateShuntVoltageControlEquations(ShuntVoltageControl voltageControl, EquationSystem equationSystem) { + boolean on = voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE; + // activate voltage target equation if control is on equationSystem.getEquation(voltageControl.getControlled().getNum(), AcEquationType.BUS_TARGET_V) .orElseThrow() - .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE); + .setActive(on); List controllerBuses = voltageControl.getControllers(); for (int i = 0; i < controllerBuses.size(); i++) { @@ -472,13 +476,13 @@ static void updateShuntVoltageControlEquations(ShuntVoltageControl voltageContro controllerBus.getControllerShunt().ifPresent(shunt -> equationSystem.getEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) .orElseThrow() - .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.OFF) + .setActive(!on) ); // activate shunt b distribution equations except one if control is on - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_B) + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) .orElseThrow() - .setActive(voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE && i < controllerBuses.size() - 1); + .setActive(on && i < controllerBuses.size() - 1); } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationType.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationType.java index c026626bd3..91b4e0bc5d 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationType.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationType.java @@ -27,7 +27,7 @@ public enum AcEquationType implements Quantity { ZERO_V("zero_v", ElementType.BRANCH), // zero impedance branch, voltage magnitude equality ZERO_PHI("zero_\u03C6", ElementType.BRANCH), // zero impedance branch, voltage angle equality DISTR_RHO("distr_\u03C1", ElementType.BRANCH), // remote transformer voltage control ratio distribution - DISTR_B("distr_b", ElementType.SHUNT_COMPENSATOR); // remote transformer voltage control ratio distribution + DISTR_SHUNT_B("distr_b", ElementType.SHUNT_COMPENSATOR); // shunt remote voltage control susceptance distribution private final String symbol; diff --git a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java index 5a01d5d269..e1b3249e78 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java +++ b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java @@ -206,10 +206,7 @@ public static void initTarget(Equation equation, break; case DISTR_RHO: - targets[equation.getColumn()] = 0; - break; - - case DISTR_B: + case DISTR_SHUNT_B: targets[equation.getColumn()] = 0; break; From 049da926d58989fcab74797df884a90cf05d49a3 Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Thu, 6 Jan 2022 11:15:20 +0100 Subject: [PATCH 18/37] Add some tests. Signed-off-by: Anne Tilloy --- .../TransformerVoltageControlOuterLoop.java | 2 +- .../openloadflow/ac/AcLoadFlowShuntTest.java | 4 +- .../network/VoltageControlNetworkFactory.java | 65 ++++++++++++++++++- .../sa/OpenSecurityAnalysisTest.java | 62 ++++++++++++++++++ 4 files changed, 129 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java index 7d3ab5ce08..acb0d004c4 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java +++ b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java @@ -56,7 +56,7 @@ private void switchOffVoltageControl(TransformerVoltageControl vc) { double r1Value = piModel.getR1(); piModel.roundR1ToClosestTap(); double roundedR1Value = piModel.getR1(); - LOGGER.trace("Round voltage shift of '{}': {} -> {}", controllerBranch.getId(), r1Value, roundedR1Value); + LOGGER.info("Round voltage shift of '{}': {} -> {}", controllerBranch.getId(), r1Value, roundedR1Value); } } } diff --git a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java index 2afb9d085d..193fdfcad7 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java @@ -197,7 +197,7 @@ void testVoltageControl() { @Test void testRemoteVoltageControl() { - Network network = VoltageControlNetworkFactory.createWithShuntRemoteControl(); + Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); ShuntCompensator shuntCompensator2 = network.getShuntCompensator("SHUNT2"); shuntCompensator2.setVoltageRegulatorOn(false); ShuntCompensator shuntCompensator3 = network.getShuntCompensator("SHUNT3"); @@ -340,7 +340,7 @@ void testLocalVoltageControl3() { @Test void testSharedRemoteVoltageControl() { - Network network = VoltageControlNetworkFactory.createWithShuntRemoteControl(); + Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); parameters.setSimulShunt(true); ShuntCompensator shuntCompensator2 = network.getShuntCompensator("SHUNT2"); ShuntCompensator shuntCompensator3 = network.getShuntCompensator("SHUNT3"); diff --git a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java index a9df0a9430..4cf9161976 100644 --- a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java +++ b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java @@ -397,7 +397,70 @@ public static Network createNetworkWithT3wt() { return network; } - public static Network createWithShuntRemoteControl() { + public static Network createWithTransformerSharedRemoteControl() { + + Network network = createNetworkWithT2wt(); + + TwoWindingsTransformer t2wt2 = network.getSubstation("SUBSTATION").newTwoWindingsTransformer() + .setId("T2wT2") + .setVoltageLevel1("VL_2") + .setVoltageLevel2("VL_3") + .setRatedU1(132.0) + .setRatedU2(33.0) + .setR(17.0) + .setX(10.0) + .setG(0.00573921028466483) + .setB(0.000573921028466483) + .setBus1("BUS_2") + .setBus2("BUS_3") + .add(); + + t2wt2.newRatioTapChanger() + .beginStep() + .setRho(0.9) + .setR(0.1089) + .setX(0.01089) + .setG(0.8264462809917356) + .setB(0.08264462809917356) + .endStep() + .beginStep() + .setRho(1.0) + .setR(0.121) + .setX(0.0121) + .setG(0.8264462809917356) + .setB(0.08264462809917356) + .endStep() + .beginStep() + .setRho(1.1) + .setR(0.1331) + .setX(0.01331) + .setG(0.9090909090909092) + .setB(0.09090909090909092) + .endStep() + .setTapPosition(0) + .setLoadTapChangingCapabilities(true) + .setRegulating(false) + .setTargetV(33.0) + .setRegulationTerminal(network.getLoad("LOAD_3").getTerminal()) + .add(); + TwoWindingsTransformer t2wt = network.getTwoWindingsTransformer("T2wT2"); + t2wt.getRatioTapChanger() + .setTargetDeadband(0) + .setRegulating(true) + .setTapPosition(0) + .setRegulationTerminal(t2wt.getTerminal2()) + .setTargetV(34.0); + t2wt2.getRatioTapChanger() + .setTargetDeadband(0) + .setRegulating(true) + .setTapPosition(0) + .setRegulationTerminal(t2wt.getTerminal2()) + .setTargetV(34.0); + + return network; + } + + public static Network createWithShuntSharedRemoteControl() { Network network = Network.create("shunt-remote-control-test", "code"); diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index 3f821d436f..e4f3e6860a 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -755,4 +755,66 @@ void testSAmodeACAllBranchMonitoredFlowTransfer() { assertEquals(1.66, brl14l13.getP1(), 1e-2); assertEquals(0.66, brl14l13.getFlowTransfer(), 1e-2); } + + @Test + void testSAWithRemoteSharedControl() { + // FIXME + Network network = VoltageControlNetworkFactory.createWithGeneratorRemoteControl(); + SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); + LoadFlowParameters lfParameters = new LoadFlowParameters(); + OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); + lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); + saParameters.setLoadFlowParameters(lfParameters); + ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() + .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) + .collect(Collectors.toList()); + + OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); + CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), + new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, + contingenciesProvider, Collections.emptyList()); + SecurityAnalysisResult result = futureResult.join().getResult(); + } + + @Test + void testSAWithTransformerRemoteSharedControl() { + // FIXME + Network network = VoltageControlNetworkFactory.createWithTransformerSharedRemoteControl(); + SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); + LoadFlowParameters lfParameters = new LoadFlowParameters(); + lfParameters.setTransformerVoltageControlOn(true); + OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); + lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); + saParameters.setLoadFlowParameters(lfParameters); + ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() + .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) + .collect(Collectors.toList()); + + OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); + CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), + new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, + contingenciesProvider, Collections.emptyList()); + SecurityAnalysisResult result = futureResult.join().getResult(); + } + + @Test + void testSAWithShuntRemoteSharedControl() { + // FIXME + Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); + SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); + LoadFlowParameters lfParameters = new LoadFlowParameters(); + lfParameters.setSimulShunt(true); + OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); + lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); + saParameters.setLoadFlowParameters(lfParameters); + ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() + .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) + .collect(Collectors.toList()); + + OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); + CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), + new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, + contingenciesProvider, Collections.emptyList()); + SecurityAnalysisResult result = futureResult.join().getResult(); + } } From 360b542f7373c0f9fe96fd45cb70ff99798d9551 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Thu, 6 Jan 2022 21:51:11 +0100 Subject: [PATCH 19/37] Merge Signed-off-by: Geoffroy Jamgotchian --- .../openloadflow/ac/TransformerVoltageControlOuterLoop.java | 2 +- .../java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java index acb0d004c4..7d3ab5ce08 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java +++ b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java @@ -56,7 +56,7 @@ private void switchOffVoltageControl(TransformerVoltageControl vc) { double r1Value = piModel.getR1(); piModel.roundR1ToClosestTap(); double roundedR1Value = piModel.getR1(); - LOGGER.info("Round voltage shift of '{}': {} -> {}", controllerBranch.getId(), r1Value, roundedR1Value); + LOGGER.trace("Round voltage shift of '{}': {} -> {}", controllerBranch.getId(), r1Value, roundedR1Value); } } } diff --git a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java index e626ce9195..92ab5ff95d 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java @@ -378,7 +378,7 @@ void testNoShuntVoltageControl2() { @Test void testNoShuntVoltageControl3() { - Network network = VoltageControlNetworkFactory.createWithShuntRemoteControl(); + Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); TwoWindingsTransformer twt = network.getTwoWindingsTransformer("tr1"); twt.newRatioTapChanger() .setTargetDeadband(0) From a79d21f36a726c63f8f8b20d307db370a1b34d56 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Thu, 6 Jan 2022 22:18:09 +0100 Subject: [PATCH 20/37] Try to fix SA Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 5 ++++- .../openloadflow/network/VoltageControl.java | 2 +- .../network/VoltageControlNetworkFactory.java | 11 +++++++++++ .../openloadflow/sa/OpenSecurityAnalysisTest.java | 14 ++++++++++---- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index 39f24b3817..acfa941ab0 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -136,7 +136,10 @@ static void updateRemoteVoltageControlEquations(VoltageControl voltageControl, E // ensure reactive keys are up-to-date voltageControl.updateReactiveKeys(); - Set controllerBuses = voltageControl.getControllerBuses(); + List controllerBuses = voltageControl.getControllerBuses() + .stream() + .filter(b -> !b.isDisabled()) + .collect(Collectors.toList()); List enabledControllerBuses = new ArrayList<>(controllerBuses.size()); List disabledControllerBuses = new ArrayList<>(controllerBuses.size()); for (LfBus controllerBus : controllerBuses) { diff --git a/src/main/java/com/powsybl/openloadflow/network/VoltageControl.java b/src/main/java/com/powsybl/openloadflow/network/VoltageControl.java index db13d62578..a423c5c974 100644 --- a/src/main/java/com/powsybl/openloadflow/network/VoltageControl.java +++ b/src/main/java/com/powsybl/openloadflow/network/VoltageControl.java @@ -73,7 +73,7 @@ public void updateReactiveKeys() { // no reactive dispatch on PQ buses, so we set the key to 0 for (int i = 0; i < controllerBuses.size(); i++) { LfBus controllerBus = controllerBuses.get(i); - if (!controllerBus.isVoltageControllerEnabled()) { + if (controllerBus.isDisabled() || !controllerBus.isVoltageControllerEnabled()) { reactiveKeys[i] = 0d; } } diff --git a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java index 4cf9161976..005feccf98 100644 --- a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java +++ b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java @@ -13,6 +13,17 @@ */ public class VoltageControlNetworkFactory extends AbstractLoadFlowNetworkFactory { + /** + * g1 g2 g3 + * | | | + * b1 b2 b3 + * | | | + * 8 tr1 8 tr2 8 tr3 + * | | | + * +------ b4 -----+ + * | + * l4 + */ public static Network createWithGeneratorRemoteControl() { Network network = Network.create("generator-remote-control-test", "code"); diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index e4f3e6860a..877b06d448 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -770,10 +770,16 @@ void testSAWithRemoteSharedControl() { .collect(Collectors.toList()); OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); - CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), - new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, - contingenciesProvider, Collections.emptyList()); - SecurityAnalysisResult result = futureResult.join().getResult(); + SecurityAnalysisReport saReport = osaProvider.run(network, + network.getVariantManager().getWorkingVariantId(), + new DefaultLimitViolationDetector(), + new LimitViolationFilter(), + null, + saParameters, + contingenciesProvider, + Collections.emptyList()) + .join(); + assertEquals(3, saReport.getResult().getPostContingencyResults().size()); } @Test From 0c7a45437021d97769eef66ff009c8ef12a22349 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Thu, 6 Jan 2022 22:55:26 +0100 Subject: [PATCH 21/37] Fix SA Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 60 +++++++++++-------- .../ac/equations/AcEquationSystemUpdater.java | 8 +++ 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index acfa941ab0..5227bc0610 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -138,36 +138,48 @@ static void updateRemoteVoltageControlEquations(VoltageControl voltageControl, E List controllerBuses = voltageControl.getControllerBuses() .stream() - .filter(b -> !b.isDisabled()) + .filter(b -> !b.isDisabled()) // discard disabled controller buses .collect(Collectors.toList()); - List enabledControllerBuses = new ArrayList<>(controllerBuses.size()); - List disabledControllerBuses = new ArrayList<>(controllerBuses.size()); - for (LfBus controllerBus : controllerBuses) { - if (controllerBus.isVoltageControllerEnabled()) { - enabledControllerBuses.add(controllerBus); - } else { - disabledControllerBuses.add(controllerBus); - } - } - // activate voltage control at controlled bus only if at least one controller bus is enabled Equation vEq = equationSystem.getEquation(voltageControl.getControlledBus().getNum(), AcEquationType.BUS_TARGET_V) .orElseThrow(); - vEq.setActive(!enabledControllerBuses.isEmpty()); - // deactivate reactive power distribution equation on all disabled (PQ) buses - for (LfBus controllerBus : disabledControllerBuses) { - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) - .orElseThrow() - .setActive(false); - } + if (voltageControl.getControlledBus().isDisabled()) { + // if controlled bus is disabled, we disable all voltage control equations + vEq.setActive(false); + for (LfBus controllerBus : controllerBuses) { + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .orElseThrow() + .setActive(false); + } + } else { + List enabledControllerBuses = new ArrayList<>(controllerBuses.size()); + List disabledControllerBuses = new ArrayList<>(controllerBuses.size()); + for (LfBus controllerBus : controllerBuses) { + if (controllerBus.isVoltageControllerEnabled()) { + enabledControllerBuses.add(controllerBus); + } else { + disabledControllerBuses.add(controllerBus); + } + } - // activate reactive power distribution equation at all enabled controller buses except one (first) - for (int i = 0; i < enabledControllerBuses.size(); i++) { - LfBus controllerBus = enabledControllerBuses.get(i); - var qDistrEq = equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) - .orElseThrow(); - qDistrEq.setActive(i != 0); + // activate voltage control at controlled bus only if at least one controller bus is enabled + vEq.setActive(!enabledControllerBuses.isEmpty()); + + // deactivate reactive power distribution equation on all disabled (PQ) buses + for (LfBus controllerBus : disabledControllerBuses) { + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .orElseThrow() + .setActive(false); + } + + // activate reactive power distribution equation at all enabled controller buses except one (first) + for (int i = 0; i < enabledControllerBuses.size(); i++) { + boolean active = i != 0; + LfBus controllerBus = enabledControllerBuses.get(i); + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .ifPresent(qDistrEq -> qDistrEq.setActive(active)); + } } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index 6ca8e94384..95bac9d518 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -87,4 +87,12 @@ public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageCon AcEquationSystem.updateShuntVoltageControlEquations((ShuntVoltageControl) voltageControl, equationSystem); } } + + @Override + public void onDisableChange(LfElement element, boolean disabled) { + if (element.getType() == ElementType.BUS) { + LfBus bus = (LfBus) element; + bus.getVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateRemoteVoltageControlEquations(voltageControl, equationSystem)); + } + } } From 440d49a1d2ac12005d42e6b20478d9e956264674 Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Fri, 7 Jan 2022 10:11:53 +0100 Subject: [PATCH 22/37] Add assertions. Signed-off-by: Anne Tilloy --- .../sa/OpenSecurityAnalysisTest.java | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index 877b06d448..ec14d6e1aa 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -758,7 +758,6 @@ void testSAmodeACAllBranchMonitoredFlowTransfer() { @Test void testSAWithRemoteSharedControl() { - // FIXME Network network = VoltageControlNetworkFactory.createWithGeneratorRemoteControl(); SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); LoadFlowParameters lfParameters = new LoadFlowParameters(); @@ -768,18 +767,34 @@ void testSAWithRemoteSharedControl() { ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) .collect(Collectors.toList()); + List monitors = new ArrayList<>(); + Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); - SecurityAnalysisReport saReport = osaProvider.run(network, + CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, contingenciesProvider, - Collections.emptyList()) - .join(); - assertEquals(3, saReport.getResult().getPostContingencyResults().size()); + Collections.emptyList(), + monitors); + SecurityAnalysisResult result = futureResult.join().getResult(); + + // pre-contingency tests + PreContingencyResult preContingencyResult = result.getPreContingencyResult(); + BranchResult tr2PreContingencyResults = preContingencyResult.getPreContingencyBranchResult("tr2"); + assertEquals(69.924, tr2PreContingencyResults.getQ1(), 1e-2); + assertEquals(-66.879, tr2PreContingencyResults.getQ2(), 1e-2); + + // post-contingency tests + PostContingencyResult postContingencyResultTr1 = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr1")).findFirst().get(); + assertEquals("tr1", postContingencyResultTr1.getContingency().getId()); + BranchResult tr2Results = postContingencyResultTr1.getBranchResult("tr2"); + assertEquals(108.145, tr2Results.getQ1(), 1e-2); + assertEquals(-101.258, tr2Results.getQ2(), 1e-2); } @Test From fd656101813da744ad7223c52c42b3d157437ae4 Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Fri, 7 Jan 2022 13:39:05 +0100 Subject: [PATCH 23/37] Fix tests. Signed-off-by: Anne Tilloy --- .../sa/OpenSecurityAnalysisTest.java | 49 ++++++++++++++----- 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index ec14d6e1aa..057d847a89 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -785,21 +785,19 @@ void testSAWithRemoteSharedControl() { // pre-contingency tests PreContingencyResult preContingencyResult = result.getPreContingencyResult(); - BranchResult tr2PreContingencyResults = preContingencyResult.getPreContingencyBranchResult("tr2"); - assertEquals(69.924, tr2PreContingencyResults.getQ1(), 1e-2); - assertEquals(-66.879, tr2PreContingencyResults.getQ2(), 1e-2); + assertEquals(-67.375, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + assertEquals(-66.879, preContingencyResult.getPreContingencyBranchResult("tr2").getQ2(), 1e-2); + assertEquals(-65.744, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); // post-contingency tests - PostContingencyResult postContingencyResultTr1 = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr1")).findFirst().get(); - assertEquals("tr1", postContingencyResultTr1.getContingency().getId()); - BranchResult tr2Results = postContingencyResultTr1.getBranchResult("tr2"); - assertEquals(108.145, tr2Results.getQ1(), 1e-2); - assertEquals(-101.258, tr2Results.getQ2(), 1e-2); + PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr1")).findFirst().get(); + assertEquals("tr1", postContingencyResult.getContingency().getId()); + assertEquals(-101.257, postContingencyResult.getBranchResult("tr2").getQ2(), 1e-2); + assertEquals(-98.742, postContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); } @Test void testSAWithTransformerRemoteSharedControl() { - // FIXME Network network = VoltageControlNetworkFactory.createWithTransformerSharedRemoteControl(); SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); LoadFlowParameters lfParameters = new LoadFlowParameters(); @@ -810,17 +808,29 @@ void testSAWithTransformerRemoteSharedControl() { ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) .collect(Collectors.toList()); + List monitors = new ArrayList<>(); + Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, - contingenciesProvider, Collections.emptyList()); + contingenciesProvider, Collections.emptyList(), monitors); SecurityAnalysisResult result = futureResult.join().getResult(); + + // pre-contingency tests + PreContingencyResult preContingencyResult = result.getPreContingencyResult(); + assertEquals(-2.665, preContingencyResult.getPreContingencyBranchResult("T2wT2").getQ2(), 1e-2); + assertEquals(-3.071, preContingencyResult.getPreContingencyBranchResult("T2wT").getQ1(), 1e-2); + + // post-contingency tests + PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("T2wT")).findFirst().get(); + assertEquals("T2wT", postContingencyResult.getContingency().getId()); + assertEquals(0.0, postContingencyResult.getBranchResult("T2wT2").getQ2(), 1e-2); // FIXME } @Test void testSAWithShuntRemoteSharedControl() { - // FIXME Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); LoadFlowParameters lfParameters = new LoadFlowParameters(); @@ -831,11 +841,26 @@ void testSAWithShuntRemoteSharedControl() { ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) .collect(Collectors.toList()); + List monitors = new ArrayList<>(); + Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, - contingenciesProvider, Collections.emptyList()); + contingenciesProvider, Collections.emptyList(), monitors); SecurityAnalysisResult result = futureResult.join().getResult(); + + // pre-contingency tests + PreContingencyResult preContingencyResult = result.getPreContingencyResult(); + assertEquals(-807.198, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + assertEquals(390.433, preContingencyResult.getPreContingencyBranchResult("tr2").getQ2(), 1e-2); + assertEquals(416.767, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); + + // post-contingency tests + PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr2")).findFirst().get(); + assertEquals("tr2", postContingencyResult.getContingency().getId()); + assertEquals(-807.198, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + assertEquals(0.01855, postContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); // FIXME } } From 25cff4d17d3da583c455121d00b1d310d59e2f5e Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 10 Jan 2022 10:57:20 +0100 Subject: [PATCH 24/37] Fix merge Signed-off-by: Geoffroy Jamgotchian --- .../com/powsybl/openloadflow/ac/equations/AcEquationSystem.java | 2 +- .../openloadflow/ac/equations/AcEquationSystemUpdater.java | 2 +- .../java/com/powsybl/openloadflow/network/VoltageControl.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index 4db2d76d95..5c1841bd87 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -156,7 +156,7 @@ static void updateRemoteVoltageControlEquations(VoltageControl voltageControl, E List enabledControllerBuses = new ArrayList<>(controllerBuses.size()); List disabledControllerBuses = new ArrayList<>(controllerBuses.size()); for (LfBus controllerBus : controllerBuses) { - if (controllerBus.isVoltageControllerEnabled()) { + if (controllerBus.isVoltageControlEnabled()) { enabledControllerBuses.add(controllerBus); } else { disabledControllerBuses.add(controllerBus); diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index 91b2890f4d..cf900cca24 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -31,7 +31,7 @@ private void updateVoltageControl(VoltageControl voltageControl) { if (firstControllerBus.hasGeneratorsWithSlope()) { // we only support one controlling static var compensator without any other controlling generators // we don't support controller bus that wants to control back voltage with slope. - if (!firstControllerBus.isVoltageControllerEnabled()) { + if (!firstControllerBus.isVoltageControlEnabled()) { equationSystem.getEquation(controlledBus.getNum(), AcEquationType.BUS_TARGET_V_WITH_SLOPE) .orElseThrow().setActive(false); } diff --git a/src/main/java/com/powsybl/openloadflow/network/VoltageControl.java b/src/main/java/com/powsybl/openloadflow/network/VoltageControl.java index a423c5c974..ea9eef8177 100644 --- a/src/main/java/com/powsybl/openloadflow/network/VoltageControl.java +++ b/src/main/java/com/powsybl/openloadflow/network/VoltageControl.java @@ -73,7 +73,7 @@ public void updateReactiveKeys() { // no reactive dispatch on PQ buses, so we set the key to 0 for (int i = 0; i < controllerBuses.size(); i++) { LfBus controllerBus = controllerBuses.get(i); - if (controllerBus.isDisabled() || !controllerBus.isVoltageControllerEnabled()) { + if (controllerBus.isDisabled() || !controllerBus.isVoltageControlEnabled()) { reactiveKeys[i] = 0d; } } From ed0a2c30fb77a8056036eca8ff8f619dbdac37ca Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Mon, 10 Jan 2022 15:44:05 +0100 Subject: [PATCH 25/37] Fix security analysis with voltage controls. Signed-off-by: Anne Tilloy --- .../TransformerVoltageControlOuterLoop.java | 2 +- .../ac/equations/AcEquationSystem.java | 101 ++++++++++++------ .../ac/equations/AcEquationSystemUpdater.java | 7 ++ .../openloadflow/network/BusModeState.java | 36 +++++++ .../openloadflow/network/BusState.java | 10 -- .../openloadflow/sa/AcSecurityAnalysis.java | 10 +- .../ac/AcLoadFlowTransformerControlTest.java | 71 ++---------- .../network/VoltageControlNetworkFactory.java | 16 ++- .../sa/OpenSecurityAnalysisTest.java | 34 ++++-- 9 files changed, 168 insertions(+), 119 deletions(-) create mode 100644 src/main/java/com/powsybl/openloadflow/network/BusModeState.java diff --git a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java index 7d3ab5ce08..acb0d004c4 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java +++ b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java @@ -56,7 +56,7 @@ private void switchOffVoltageControl(TransformerVoltageControl vc) { double r1Value = piModel.getR1(); piModel.roundR1ToClosestTap(); double roundedR1Value = piModel.getR1(); - LOGGER.trace("Round voltage shift of '{}': {} -> {}", controllerBranch.getId(), r1Value, roundedR1Value); + LOGGER.info("Round voltage shift of '{}': {} -> {}", controllerBranch.getId(), r1Value, roundedR1Value); } } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index 5c1841bd87..17d6ab528e 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -397,26 +397,43 @@ public static void createR1DistributionEquations(List controllerBranch } static void updateTransformerVoltageControlEquations(TransformerVoltageControl voltageControl, EquationSystem equationSystem) { - boolean on = voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE; + List controllerBranches = voltageControl.getControllers() + .stream() + .filter(b -> !b.isDisabled()) // discard disabled controller branches + .collect(Collectors.toList()); + + boolean on = voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE && !controllerBranches.isEmpty(); // activate voltage target equation if control is on - equationSystem.getEquation(voltageControl.getControlled().getNum(), AcEquationType.BUS_TARGET_V) - .orElseThrow() - .setActive(on); + Equation vEq = equationSystem.getEquation(voltageControl.getControlled().getNum(), AcEquationType.BUS_TARGET_V) + .orElseThrow(); - List controllerBranches = voltageControl.getControllers(); - for (int i = 0; i < controllerBranches.size(); i++) { - LfBranch controllerBranch = controllerBranches.get(i); + if (voltageControl.getControlled().isDisabled()) { + // if controlled bus is disabled, we disable all transformer voltage control equations + vEq.setActive(false); + for (LfBranch controllerBranch : controllerBranches) { + equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.DISTR_Q) + .orElseThrow() + .setActive(false); + } + } else { + vEq.setActive(on); + if (!voltageControl.getControllers().equals(controllerBranches)) { + createR1DistributionEquations(controllerBranches, equationSystem); + } + for (int i = 0; i < controllerBranches.size(); i++) { + LfBranch controllerBranch = controllerBranches.get(i); - // activate all rho1 equations if voltage control is off - equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1) - .orElseThrow() - .setActive(!on); + // activate all rho1 equations if voltage control is off + equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.BRANCH_TARGET_RHO1) + .orElseThrow() + .setActive(!on); - // activate rho1 distribution equations except one if control is on - equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO) - .orElseThrow() - .setActive(on && i < controllerBranches.size() - 1); + // activate rho1 distribution equations except one if control is on + equationSystem.getEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO) + .orElseThrow() + .setActive(on && i < controllerBranches.size() - 1); + } } } @@ -476,28 +493,46 @@ public static void createShuntSusceptanceDistributionEquations(List contr } static void updateShuntVoltageControlEquations(ShuntVoltageControl voltageControl, EquationSystem equationSystem) { - boolean on = voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE; + List controllerBuses = voltageControl.getControllers() + .stream() + .filter(b -> !b.isDisabled()) // discard disabled controller buses + .collect(Collectors.toList()); - // activate voltage target equation if control is on - equationSystem.getEquation(voltageControl.getControlled().getNum(), AcEquationType.BUS_TARGET_V) - .orElseThrow() - .setActive(on); + boolean on = voltageControl.getMode() == DiscreteVoltageControl.Mode.VOLTAGE && !controllerBuses.isEmpty(); - List controllerBuses = voltageControl.getControllers(); - for (int i = 0; i < controllerBuses.size(); i++) { - LfBus controllerBus = controllerBuses.get(i); + // activate voltage target equation if control is on + Equation vEq = equationSystem.getEquation(voltageControl.getControlled().getNum(), AcEquationType.BUS_TARGET_V) + .orElseThrow(); - // activate all b target equations if voltage control is off - controllerBus.getControllerShunt().ifPresent(shunt -> - equationSystem.getEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) + if (voltageControl.getControlled().isDisabled()) { + // if controlled bus is disabled, we disable all transformer voltage control equations + vEq.setActive(false); + for (LfBus controllerBus : controllerBuses) { + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) .orElseThrow() - .setActive(!on) - ); - - // activate shunt b distribution equations except one if control is on - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) - .orElseThrow() - .setActive(on && i < controllerBuses.size() - 1); + .setActive(false); + } + } else { + // activate voltage target equation if control is on + vEq.setActive(on); + if (!voltageControl.getControllers().equals(controllerBuses)) { + createShuntSusceptanceDistributionEquations(controllerBuses, equationSystem); + } + for (int i = 0; i < controllerBuses.size(); i++) { + LfBus controllerBus = controllerBuses.get(i); + + // activate all b target equations if voltage control is off + controllerBus.getControllerShunt().ifPresent(shunt -> + equationSystem.getEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) + .orElseThrow() + .setActive(!on) + ); + + // activate shunt b distribution equations except one if control is on + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) + .orElseThrow() + .setActive(on && i < controllerBuses.size() - 1); + } } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index cf900cca24..49208c6161 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -93,6 +93,13 @@ public void onDisableChange(LfElement element, boolean disabled) { if (element.getType() == ElementType.BUS) { LfBus bus = (LfBus) element; bus.getVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateRemoteVoltageControlEquations(voltageControl, equationSystem)); + bus.getTransformerVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateTransformerVoltageControlEquations(voltageControl, equationSystem)); + bus.getShuntVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateShuntVoltageControlEquations(voltageControl, equationSystem)); + } + if (element.getType() == ElementType.BRANCH) { + LfBranch branch = (LfBranch) element; + branch.getTransformerVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateTransformerVoltageControlEquations(voltageControl, equationSystem)); + // TODO phase control. } } } diff --git a/src/main/java/com/powsybl/openloadflow/network/BusModeState.java b/src/main/java/com/powsybl/openloadflow/network/BusModeState.java new file mode 100644 index 0000000000..5d4f7b9dcf --- /dev/null +++ b/src/main/java/com/powsybl/openloadflow/network/BusModeState.java @@ -0,0 +1,36 @@ +/** + * Copyright (c) 2021, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +package com.powsybl.openloadflow.network; + +/** + * @author Anne Tilloy + */ +public class BusModeState extends ElementState { + + private final DiscreteVoltageControl.Mode transformerVoltageControlMode; + private final DiscreteVoltageControl.Mode shuntVoltageControlMode; + + public BusModeState(LfBus bus) { + super(bus); + transformerVoltageControlMode = bus.getTransformerVoltageControl().map(TransformerVoltageControl::getMode).orElse(null); + shuntVoltageControlMode = bus.getShuntVoltageControl().map(ShuntVoltageControl::getMode).orElse(null); + } + + @Override + public void restore() { + if (transformerVoltageControlMode != null) { + element.getTransformerVoltageControl().ifPresent(control -> control.setMode(transformerVoltageControlMode)); + } + if (shuntVoltageControlMode != null) { + element.getShuntVoltageControl().ifPresent(control -> control.setMode(shuntVoltageControlMode)); + } + } + + public static BusModeState save(LfBus bus) { + return new BusModeState(bus); + } +} diff --git a/src/main/java/com/powsybl/openloadflow/network/BusState.java b/src/main/java/com/powsybl/openloadflow/network/BusState.java index 1687cc59b9..fb90777584 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BusState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BusState.java @@ -15,8 +15,6 @@ public class BusState extends BusDcState { private final double loadTargetQ; private final double generationTargetQ; private final boolean voltageControlEnabled; - private final DiscreteVoltageControl.Mode transformerVoltageControlMode; - private final DiscreteVoltageControl.Mode shuntVoltageControlMode; private final boolean disabled; public BusState(LfBus bus) { @@ -25,8 +23,6 @@ public BusState(LfBus bus) { this.loadTargetQ = bus.getLoadTargetQ(); this.generationTargetQ = bus.getGenerationTargetQ(); this.voltageControlEnabled = bus.isVoltageControlEnabled(); - transformerVoltageControlMode = bus.getTransformerVoltageControl().map(TransformerVoltageControl::getMode).orElse(null); - shuntVoltageControlMode = bus.getShuntVoltageControl().map(ShuntVoltageControl::getMode).orElse(null); this.disabled = bus.isDisabled(); } @@ -38,12 +34,6 @@ public void restore() { element.setGenerationTargetQ(generationTargetQ); element.setVoltageControlEnabled(voltageControlEnabled); element.setVoltageControlSwitchOffCount(0); - if (transformerVoltageControlMode != null) { - element.getTransformerVoltageControl().ifPresent(control -> control.setMode(transformerVoltageControlMode)); - } - if (shuntVoltageControlMode != null) { - element.getShuntVoltageControl().ifPresent(control -> control.setMode(shuntVoltageControlMode)); - } element.setDisabled(disabled); } diff --git a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java index 4e6cc89668..969202ef00 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java @@ -112,6 +112,8 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List preContingencyBranchResults = new ArrayList<>(); List preContingencyBusResults = new ArrayList<>(); List preContingencyThreeWindingsTransformerResults = new ArrayList<>(); + List branchStates = ElementState.save(network.getBranches(), BranchState::save); + List busModeStates = ElementState.save(network.getBuses(), BusModeState::save); // run pre-contingency simulation try (AcloadFlowEngine engine = new AcloadFlowEngine(network, acParameters)) { @@ -133,7 +135,6 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List busStates = ElementState.save(network.getBuses(), BusState::save); - List branchStates = ElementState.save(network.getBranches(), BranchState::save); for (LfBus bus : network.getBuses()) { bus.setVoltageControlSwitchOffCount(0); } @@ -145,12 +146,12 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List { // only process contingencies that impact the network - for (LfBus bus : lfContingency.getBuses()) { - bus.setDisabled(true); - } for (LfBranch branch : lfContingency.getBranches()) { branch.setDisabled(true); } + for (LfBus bus : lfContingency.getBuses()) { + bus.setDisabled(true); + } distributedMismatch(network, lfContingency.getActivePowerLoss(), loadFlowParameters, openLoadFlowParameters); @@ -162,6 +163,7 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List r.getContingency().getId().equals("T2wT")).findFirst().get(); - assertEquals("T2wT", postContingencyResult.getContingency().getId()); - assertEquals(0.0, postContingencyResult.getBranchResult("T2wT2").getQ2(), 1e-2); // FIXME + PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("T2wT2")).findFirst().get(); + assertEquals("T2wT2", postContingencyResult.getContingency().getId()); + assertEquals(-0.572, postContingencyResult.getBranchResult("T2wT").getQ1(), 1e-2); // this assertion is not so relevant. It is more relevant to look at the logs. + } + + @Test + void testSAWithTransformerRemoteSharedControl2() { + Network network = VoltageControlNetworkFactory.createWithTransformerSharedRemoteControl(); + SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); + LoadFlowParameters lfParameters = new LoadFlowParameters(); + lfParameters.setTransformerVoltageControlOn(true); + OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); + lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); + saParameters.setLoadFlowParameters(lfParameters); + List contingencies = List.of(new Contingency("N-2", List.of(new BranchContingency("T2wT"), new BranchContingency("T2wT2")))); + ContingenciesProvider contingenciesProvider = n -> contingencies; + List monitors = new ArrayList<>(); + Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); + + OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); + CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), + new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, + contingenciesProvider, Collections.emptyList(), monitors); + SecurityAnalysisResult result = futureResult.join().getResult(); } @Test @@ -861,6 +883,6 @@ void testSAWithShuntRemoteSharedControl() { PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr2")).findFirst().get(); assertEquals("tr2", postContingencyResult.getContingency().getId()); assertEquals(-807.198, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); - assertEquals(0.01855, postContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); // FIXME + assertEquals(473.418, postContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); } } From fbbc4245a1356ea356d56cdcec6613d9c30b90a5 Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Mon, 10 Jan 2022 16:20:57 +0100 Subject: [PATCH 26/37] Fix after review. Signed-off-by: Anne Tilloy --- .../TransformerVoltageControlOuterLoop.java | 2 +- .../ac/equations/AcEquationSystem.java | 28 ++++++++----------- .../network/impl/LfShuntImpl.java | 2 +- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java index acb0d004c4..7d3ab5ce08 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java +++ b/src/main/java/com/powsybl/openloadflow/ac/TransformerVoltageControlOuterLoop.java @@ -56,7 +56,7 @@ private void switchOffVoltageControl(TransformerVoltageControl vc) { double r1Value = piModel.getR1(); piModel.roundR1ToClosestTap(); double roundedR1Value = piModel.getR1(); - LOGGER.info("Round voltage shift of '{}': {} -> {}", controllerBranch.getId(), r1Value, roundedR1Value); + LOGGER.trace("Round voltage shift of '{}': {} -> {}", controllerBranch.getId(), r1Value, roundedR1Value); } } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index 17d6ab528e..28530ab751 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -375,8 +375,9 @@ private static void createTransformerVoltageControlEquations(LfBus bus, Equation public static void createR1DistributionEquations(List controllerBranches, EquationSystem equationSystem) { - for (int i = 0; i < controllerBranches.size(); i++) { - LfBranch controllerBranch = controllerBranches.get(i); + List enabledControllerBranches = controllerBranches.stream().filter(b -> !b.isDisabled()).collect(Collectors.toList()); + for (int i = 0; i < enabledControllerBranches.size(); i++) { + LfBranch controllerBranch = enabledControllerBranches.get(i); // r1 at controller branch i // r1_i = sum_j(r1_j) / controller_count where j are all the controller branches // 0 = sum_j(r1_j) / controller_count - r1_i @@ -385,12 +386,12 @@ public static void createR1DistributionEquations(List controllerBranch EquationTerm r1 = equationSystem.getVariable(controllerBranch.getNum(), AcVariableType.BRANCH_RHO1) .createTerm(); Equation zero = equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO) - .addTerm(r1.multiply(() -> 1d / controllerBranches.size() - 1)); - for (LfBranch otherControllerBranch : controllerBranches) { + .addTerm(r1.multiply(() -> 1d / enabledControllerBranches.size() - 1)); + for (LfBranch otherControllerBranch : enabledControllerBranches) { if (otherControllerBranch != controllerBranch) { EquationTerm otherR1 = equationSystem.getVariable(otherControllerBranch.getNum(), AcVariableType.BRANCH_RHO1) .createTerm(); - zero.addTerm(otherR1.multiply(() -> 1d / controllerBranches.size())); + zero.addTerm(otherR1.multiply(() -> 1d / enabledControllerBranches.size())); } } } @@ -418,9 +419,6 @@ static void updateTransformerVoltageControlEquations(TransformerVoltageControl v } } else { vEq.setActive(on); - if (!voltageControl.getControllers().equals(controllerBranches)) { - createR1DistributionEquations(controllerBranches, equationSystem); - } for (int i = 0; i < controllerBranches.size(); i++) { LfBranch controllerBranch = controllerBranches.get(i); @@ -465,8 +463,9 @@ private static void createShuntVoltageControlEquations(LfBus bus, EquationSystem public static void createShuntSusceptanceDistributionEquations(List controllerBuses, EquationSystem equationSystem) { - for (int i = 0; i < controllerBuses.size(); i++) { - LfBus controllerBus = controllerBuses.get(i); + List enabledControllerBuses = controllerBuses.stream().filter(b -> !b.isDisabled()).collect(Collectors.toList()); + for (int i = 0; i < enabledControllerBuses.size(); i++) { + LfBus controllerBus = enabledControllerBuses.get(i); controllerBus.getControllerShunt() .ifPresent(shunt -> { // shunt b at controller bus i @@ -477,14 +476,14 @@ public static void createShuntSusceptanceDistributionEquations(List contr EquationTerm shuntB = equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B) .createTerm(); Equation zero = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) - .addTerm(shuntB.multiply(() -> 1d / controllerBuses.size() - 1)); - for (LfBus otherControllerBus : controllerBuses) { + .addTerm(shuntB.multiply(() -> 1d / enabledControllerBuses.size() - 1)); + for (LfBus otherControllerBus : enabledControllerBuses) { if (otherControllerBus != controllerBus) { otherControllerBus.getControllerShunt() .ifPresent(otherShunt -> { EquationTerm otherShuntB = equationSystem.getVariable(otherShunt.getNum(), AcVariableType.SHUNT_B) .createTerm(); - zero.addTerm(otherShuntB.multiply(() -> 1d / controllerBuses.size())); + zero.addTerm(otherShuntB.multiply(() -> 1d / enabledControllerBuses.size())); }); } } @@ -515,9 +514,6 @@ static void updateShuntVoltageControlEquations(ShuntVoltageControl voltageContro } else { // activate voltage target equation if control is on vEq.setActive(on); - if (!voltageControl.getControllers().equals(controllerBuses)) { - createShuntSusceptanceDistributionEquations(controllerBuses, equationSystem); - } for (int i = 0; i < controllerBuses.size(); i++) { LfBus controllerBus = controllerBuses.get(i); diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/LfShuntImpl.java b/src/main/java/com/powsybl/openloadflow/network/impl/LfShuntImpl.java index cea5cf501e..b821392344 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfShuntImpl.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfShuntImpl.java @@ -161,7 +161,7 @@ private void roundBToClosestSection(double b, Controller controller) { smallestDistance = distance; } } - LOGGER.info("Round B shift of shunt '{}': {} -> {}", controller.getId(), b, controller.getB()); + LOGGER.trace("Round B shift of shunt '{}': {} -> {}", controller.getId(), b, controller.getB()); } @Override From 2959c7e1c960aef99dc4ac5c7a996c4c76945af3 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 10 Jan 2022 16:53:34 +0100 Subject: [PATCH 27/37] Fix Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 22 +++++++++---------- 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index 28530ab751..dcbbf4da3d 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -375,9 +375,8 @@ private static void createTransformerVoltageControlEquations(LfBus bus, Equation public static void createR1DistributionEquations(List controllerBranches, EquationSystem equationSystem) { - List enabledControllerBranches = controllerBranches.stream().filter(b -> !b.isDisabled()).collect(Collectors.toList()); - for (int i = 0; i < enabledControllerBranches.size(); i++) { - LfBranch controllerBranch = enabledControllerBranches.get(i); + for (int i = 0; i < controllerBranches.size(); i++) { + LfBranch controllerBranch = controllerBranches.get(i); // r1 at controller branch i // r1_i = sum_j(r1_j) / controller_count where j are all the controller branches // 0 = sum_j(r1_j) / controller_count - r1_i @@ -386,12 +385,12 @@ public static void createR1DistributionEquations(List controllerBranch EquationTerm r1 = equationSystem.getVariable(controllerBranch.getNum(), AcVariableType.BRANCH_RHO1) .createTerm(); Equation zero = equationSystem.createEquation(controllerBranch.getNum(), AcEquationType.DISTR_RHO) - .addTerm(r1.multiply(() -> 1d / enabledControllerBranches.size() - 1)); - for (LfBranch otherControllerBranch : enabledControllerBranches) { + .addTerm(r1.multiply(() -> 1d / controllerBranches.stream().filter(b -> !b.isDisabled()).count() - 1)); + for (LfBranch otherControllerBranch : controllerBranches) { if (otherControllerBranch != controllerBranch) { EquationTerm otherR1 = equationSystem.getVariable(otherControllerBranch.getNum(), AcVariableType.BRANCH_RHO1) .createTerm(); - zero.addTerm(otherR1.multiply(() -> 1d / enabledControllerBranches.size())); + zero.addTerm(otherR1.multiply(() -> 1d / controllerBranches.stream().filter(b -> !b.isDisabled()).count())); } } } @@ -463,9 +462,8 @@ private static void createShuntVoltageControlEquations(LfBus bus, EquationSystem public static void createShuntSusceptanceDistributionEquations(List controllerBuses, EquationSystem equationSystem) { - List enabledControllerBuses = controllerBuses.stream().filter(b -> !b.isDisabled()).collect(Collectors.toList()); - for (int i = 0; i < enabledControllerBuses.size(); i++) { - LfBus controllerBus = enabledControllerBuses.get(i); + for (int i = 0; i < controllerBuses.size(); i++) { + LfBus controllerBus = controllerBuses.get(i); controllerBus.getControllerShunt() .ifPresent(shunt -> { // shunt b at controller bus i @@ -476,14 +474,14 @@ public static void createShuntSusceptanceDistributionEquations(List contr EquationTerm shuntB = equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B) .createTerm(); Equation zero = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) - .addTerm(shuntB.multiply(() -> 1d / enabledControllerBuses.size() - 1)); - for (LfBus otherControllerBus : enabledControllerBuses) { + .addTerm(shuntB.multiply(() -> 1d / controllerBuses.stream().filter(b -> !b.isDisabled() && b.getControllerShunt().isPresent()).count() - 1)); + for (LfBus otherControllerBus : controllerBuses) { if (otherControllerBus != controllerBus) { otherControllerBus.getControllerShunt() .ifPresent(otherShunt -> { EquationTerm otherShuntB = equationSystem.getVariable(otherShunt.getNum(), AcVariableType.SHUNT_B) .createTerm(); - zero.addTerm(otherShuntB.multiply(() -> 1d / enabledControllerBuses.size())); + zero.addTerm(otherShuntB.multiply(() -> 1d / controllerBuses.stream().filter(b -> !b.isDisabled() && b.getControllerShunt().isPresent()).count())); }); } } From a503da8769f681887ea41c1e8b94eca7b7b84c5d Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 10 Jan 2022 18:03:23 +0100 Subject: [PATCH 28/37] Fix Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index dcbbf4da3d..53f4f671cc 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -462,24 +462,23 @@ private static void createShuntVoltageControlEquations(LfBus bus, EquationSystem public static void createShuntSusceptanceDistributionEquations(List controllerBuses, EquationSystem equationSystem) { - for (int i = 0; i < controllerBuses.size(); i++) { - LfBus controllerBus = controllerBuses.get(i); + for (LfBus controllerBus : controllerBuses) { controllerBus.getControllerShunt() - .ifPresent(shunt -> { + .ifPresent(controllerShunt -> { // shunt b at controller bus i // b_i = sum_j(b_j) / controller_count where j are all the controller buses // 0 = sum_j(b_j) / controller_count - b_i // which can be rewritten in a more simple way // 0 = (1 / controller_count - 1) * b_i + sum_j(b_j) / controller_count where j are all the controller buses except i - EquationTerm shuntB = equationSystem.getVariable(shunt.getNum(), AcVariableType.SHUNT_B) + EquationTerm shuntB = equationSystem.getVariable(controllerShunt.getNum(), AcVariableType.SHUNT_B) .createTerm(); - Equation zero = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) + Equation zero = equationSystem.createEquation(controllerShunt.getNum(), AcEquationType.DISTR_SHUNT_B) .addTerm(shuntB.multiply(() -> 1d / controllerBuses.stream().filter(b -> !b.isDisabled() && b.getControllerShunt().isPresent()).count() - 1)); for (LfBus otherControllerBus : controllerBuses) { if (otherControllerBus != controllerBus) { otherControllerBus.getControllerShunt() - .ifPresent(otherShunt -> { - EquationTerm otherShuntB = equationSystem.getVariable(otherShunt.getNum(), AcVariableType.SHUNT_B) + .ifPresent(otherControllerShunt -> { + EquationTerm otherShuntB = equationSystem.getVariable(otherControllerShunt.getNum(), AcVariableType.SHUNT_B) .createTerm(); zero.addTerm(otherShuntB.multiply(() -> 1d / controllerBuses.stream().filter(b -> !b.isDisabled() && b.getControllerShunt().isPresent()).count())); }); @@ -505,27 +504,28 @@ static void updateShuntVoltageControlEquations(ShuntVoltageControl voltageContro // if controlled bus is disabled, we disable all transformer voltage control equations vEq.setActive(false); for (LfBus controllerBus : controllerBuses) { - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) + controllerBus.getControllerShunt().ifPresent(controllerShunt -> equationSystem.getEquation(controllerShunt.getNum(), AcEquationType.DISTR_SHUNT_B) .orElseThrow() - .setActive(false); + .setActive(false)); } } else { // activate voltage target equation if control is on vEq.setActive(on); - for (int i = 0; i < controllerBuses.size(); i++) { - LfBus controllerBus = controllerBuses.get(i); + List controllerShunts = controllerBuses.stream() + .flatMap(b -> b.getControllerShunt().stream()) + .collect(Collectors.toList()); + for (int i = 0; i < controllerShunts.size(); i++) { + LfShunt controllerShunt = controllerShunts.get(i); // activate all b target equations if voltage control is off - controllerBus.getControllerShunt().ifPresent(shunt -> - equationSystem.getEquation(shunt.getNum(), AcEquationType.SHUNT_TARGET_B) - .orElseThrow() - .setActive(!on) - ); + equationSystem.getEquation(controllerShunt.getNum(), AcEquationType.SHUNT_TARGET_B) + .orElseThrow() + .setActive(!on); // activate shunt b distribution equations except one if control is on - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_SHUNT_B) + equationSystem.getEquation(controllerShunt.getNum(), AcEquationType.DISTR_SHUNT_B) .orElseThrow() - .setActive(on && i < controllerBuses.size() - 1); + .setActive(on && i < controllerShunts.size() - 1); } } } From 4e63cd045dc90c1cf9ea921e910e17eb713b6b2f Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Mon, 10 Jan 2022 23:03:28 +0100 Subject: [PATCH 29/37] Fix KLU issue Signed-off-by: Geoffroy Jamgotchian --- .../openloadflow/equations/EquationUtil.java | 23 +++++++++++++++++++ .../network/VoltageControlNetworkFactory.java | 11 +++++++++ .../sa/OpenSecurityAnalysisTest.java | 17 +++++++------- 3 files changed, 43 insertions(+), 8 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/equations/EquationUtil.java b/src/main/java/com/powsybl/openloadflow/equations/EquationUtil.java index c4674b9a96..a7dce23296 100644 --- a/src/main/java/com/powsybl/openloadflow/equations/EquationUtil.java +++ b/src/main/java/com/powsybl/openloadflow/equations/EquationUtil.java @@ -9,9 +9,11 @@ import com.powsybl.openloadflow.network.ElementType; import com.powsybl.openloadflow.network.LfBranch; import com.powsybl.openloadflow.network.LfBus; +import com.powsybl.openloadflow.network.LfShunt; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.Collection; import java.util.List; @@ -64,6 +66,27 @@ public static & Quantity, E extends Enum & Quantity> void deactivatedEquationTerms.add(equationTerm); } } + + List shunts = new ArrayList<>(2); + bus.getShunt().ifPresent(shunts::add); + bus.getControllerShunt().ifPresent(shunts::add); + for (LfShunt shunt : shunts) { + // deactivate all equations related to a shunt + for (Equation equation : equationSystem.getEquations(ElementType.SHUNT_COMPENSATOR, shunt.getNum())) { + if (equation.isActive()) { + equation.setActive(false); + deactivatedEquations.add(equation); + } + } + + // deactivate all equation terms related to a shunt + for (EquationTerm equationTerm : equationSystem.getEquationTerms(ElementType.SHUNT_COMPENSATOR, shunt.getNum())) { + if (equationTerm.isActive()) { + equationTerm.setActive(false); + deactivatedEquationTerms.add(equationTerm); + } + } + } } } diff --git a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java index d614eaa409..9ff0ea7d2a 100644 --- a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java +++ b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java @@ -485,6 +485,17 @@ public static Network createWithTransformerSharedRemoteControl() { return network; } + /** + * g1 SHUNT2 SHUNT3 + * | | | + * b1 b2 b3 + * | | | + * 8 tr1 8 tr2 8 tr3 + * | | | + * +------ b4 -----+ + * | + * l4 + */ public static Network createWithShuntSharedRemoteControl() { Network network = Network.create("shunt-remote-control-test", "code"); diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index 31ae1a230d..76032643d0 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -13,6 +13,7 @@ import com.powsybl.contingency.Contingency; import com.powsybl.contingency.ContingencyContext; import com.powsybl.iidm.network.Branch; +import com.powsybl.iidm.network.Identifiable; import com.powsybl.iidm.network.Network; import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory; import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory; @@ -718,7 +719,7 @@ void testSAmodeACAllBranchMonitoredFlowTransfer() { .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) .collect(Collectors.toList()); - Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); List monitors = new ArrayList<>(); monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); @@ -768,7 +769,7 @@ void testSAWithRemoteSharedControl() { .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) .collect(Collectors.toList()); List monitors = new ArrayList<>(); - Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); @@ -809,7 +810,7 @@ void testSAWithTransformerRemoteSharedControl() { .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) .collect(Collectors.toList()); List monitors = new ArrayList<>(); - Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); @@ -841,7 +842,7 @@ void testSAWithTransformerRemoteSharedControl2() { List contingencies = List.of(new Contingency("N-2", List.of(new BranchContingency("T2wT"), new BranchContingency("T2wT2")))); ContingenciesProvider contingenciesProvider = n -> contingencies; List monitors = new ArrayList<>(); - Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); @@ -864,7 +865,7 @@ void testSAWithShuntRemoteSharedControl() { .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) .collect(Collectors.toList()); List monitors = new ArrayList<>(); - Set allBranchIds = network.getBranchStream().map(b -> b.getId()).collect(Collectors.toSet()); + Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); @@ -880,9 +881,9 @@ void testSAWithShuntRemoteSharedControl() { assertEquals(416.767, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); // post-contingency tests - PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr2")).findFirst().get(); - assertEquals("tr2", postContingencyResult.getContingency().getId()); + PostContingencyResult tr2ContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr2")).findFirst().orElseThrow(); + assertEquals("tr2", tr2ContingencyResult.getContingency().getId()); assertEquals(-807.198, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); - assertEquals(473.418, postContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); + assertEquals(473.418, tr2ContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); } } From cbd20b0c9951989a976c6c1e961703528717d8b8 Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Tue, 11 Jan 2022 13:52:52 +0100 Subject: [PATCH 30/37] Fix update in case of local voltage control. Signed-off-by: Anne Tilloy --- .../ac/equations/AcEquationSystem.java | 36 ++++++++++--------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index 53f4f671cc..b5ec9d47b8 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -147,10 +147,12 @@ static void updateRemoteVoltageControlEquations(VoltageControl voltageControl, E if (voltageControl.getControlledBus().isDisabled()) { // if controlled bus is disabled, we disable all voltage control equations vEq.setActive(false); - for (LfBus controllerBus : controllerBuses) { - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) - .orElseThrow() - .setActive(false); + if (!voltageControl.isVoltageControlLocal()) { + for (LfBus controllerBus : controllerBuses) { + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .orElseThrow() + .setActive(false); + } } } else { List enabledControllerBuses = new ArrayList<>(controllerBuses.size()); @@ -166,19 +168,21 @@ static void updateRemoteVoltageControlEquations(VoltageControl voltageControl, E // activate voltage control at controlled bus only if at least one controller bus is enabled vEq.setActive(!enabledControllerBuses.isEmpty()); - // deactivate reactive power distribution equation on all disabled (PQ) buses - for (LfBus controllerBus : disabledControllerBuses) { - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) - .orElseThrow() - .setActive(false); - } + if (!voltageControl.isVoltageControlLocal()) { + // deactivate reactive power distribution equation on all disabled (PQ) buses + for (LfBus controllerBus : disabledControllerBuses) { + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .orElseThrow() + .setActive(false); + } - // activate reactive power distribution equation at all enabled controller buses except one (first) - for (int i = 0; i < enabledControllerBuses.size(); i++) { - boolean active = i != 0; - LfBus controllerBus = enabledControllerBuses.get(i); - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) - .ifPresent(qDistrEq -> qDistrEq.setActive(active)); + // activate reactive power distribution equation at all enabled controller buses except one (first) + for (int i = 0; i < enabledControllerBuses.size(); i++) { + boolean active = i != 0; + LfBus controllerBus = enabledControllerBuses.get(i); + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .ifPresent(qDistrEq -> qDistrEq.setActive(active)); + } } } } From e01d7fcfcca2b052e5f85537093f0a0d70563d33 Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Tue, 11 Jan 2022 17:20:45 +0100 Subject: [PATCH 31/37] Try to improve unit tests. Signed-off-by: Anne Tilloy --- .../openloadflow/ac/AcLoadFlowShuntTest.java | 4 +- .../network/VoltageControlNetworkFactory.java | 148 +++++++++++++++++- .../sa/OpenSecurityAnalysisTest.java | 32 ++-- 3 files changed, 163 insertions(+), 21 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java index 92ab5ff95d..91b22c65e9 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java @@ -204,7 +204,7 @@ void testRemoteVoltageControl() { parameters.setSimulShunt(true); LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isOk()); - assertVoltageEquals(433.749, network.getBusBreakerView().getBus("b4")); + assertVoltageEquals(434.603, network.getBusBreakerView().getBus("b4")); assertEquals(0, shuntCompensator2.getSectionCount()); assertEquals(10, shuntCompensator3.getSectionCount()); } @@ -346,7 +346,7 @@ void testSharedRemoteVoltageControl() { ShuntCompensator shuntCompensator3 = network.getShuntCompensator("SHUNT3"); LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isOk()); - assertVoltageEquals(406.971, network.getBusBreakerView().getBus("b4")); + assertVoltageEquals(406.776, network.getBusBreakerView().getBus("b4")); assertEquals(10, shuntCompensator2.getSectionCount()); assertEquals(10, shuntCompensator3.getSectionCount()); } diff --git a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java index 9ff0ea7d2a..61c2610213 100644 --- a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java +++ b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java @@ -158,6 +158,140 @@ public static Network createWithGeneratorRemoteControl() { return network; } + public static Network createWithIdenticalTransformers() { + + Network network = Network.create("generator-remote-control-test", "code"); + + Substation s = network.newSubstation() + .setId("s") + .add(); + VoltageLevel vl1 = s.newVoltageLevel() + .setId("vl1") + .setNominalV(20) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + Bus b1 = vl1.getBusBreakerView().newBus() + .setId("b1") + .add(); + VoltageLevel vl2 = s.newVoltageLevel() + .setId("vl2") + .setNominalV(20) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + Bus b2 = vl2.getBusBreakerView().newBus() + .setId("b2") + .add(); + VoltageLevel vl3 = s.newVoltageLevel() + .setId("vl3") + .setNominalV(20) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + Bus b3 = vl3.getBusBreakerView().newBus() + .setId("b3") + .add(); + VoltageLevel vl4 = s.newVoltageLevel() + .setId("vl4") + .setNominalV(400) + .setTopologyKind(TopologyKind.BUS_BREAKER) + .add(); + Bus b4 = vl4.getBusBreakerView().newBus() + .setId("b4") + .add(); + Load l4 = vl4.newLoad() + .setId("l4") + .setBus("b4") + .setConnectableBus("b4") + .setP0(299.6) + .setQ0(200) + .add(); + Generator g1 = b1.getVoltageLevel() + .newGenerator() + .setId("g1") + .setBus("b1") + .setConnectableBus("b1") + .setEnergySource(EnergySource.THERMAL) + .setMinP(0) + .setMaxP(200) + .setTargetP(100) + .setTargetV(413.4) // 22 413.4 + .setVoltageRegulatorOn(true) + .setRegulatingTerminal(l4.getTerminal()) + .add(); + Generator g2 = b2.getVoltageLevel() + .newGenerator() + .setId("g2") + .setBus("b2") + .setConnectableBus("b2") + .setEnergySource(EnergySource.THERMAL) + .setMinP(0) + .setMaxP(200) + .setTargetP(100) + .setTargetV(413.4) + .setVoltageRegulatorOn(true) + .setRegulatingTerminal(l4.getTerminal()) + .add(); + Generator g3 = b3.getVoltageLevel() + .newGenerator() + .setId("g3") + .setBus("b3") + .setConnectableBus("b3") + .setEnergySource(EnergySource.THERMAL) + .setMinP(0) + .setMaxP(200) + .setTargetP(100) + .setTargetV(413.4) + .setVoltageRegulatorOn(true) + .setRegulatingTerminal(l4.getTerminal()) + .add(); + TwoWindingsTransformer tr1 = s.newTwoWindingsTransformer() + .setId("tr1") + .setVoltageLevel1(b1.getVoltageLevel().getId()) + .setBus1(b1.getId()) + .setConnectableBus1(b1.getId()) + .setVoltageLevel2(vl4.getId()) + .setBus2(b4.getId()) + .setConnectableBus2(b4.getId()) + .setRatedU1(20.5) + .setRatedU2(399) + .setR(1) + .setX(30) + .setG(0) + .setB(0) + .add(); + TwoWindingsTransformer tr2 = s.newTwoWindingsTransformer() + .setId("tr2") + .setVoltageLevel1(b2.getVoltageLevel().getId()) + .setBus1(b2.getId()) + .setConnectableBus1(b2.getId()) + .setVoltageLevel2(vl4.getId()) + .setBus2(b4.getId()) + .setConnectableBus2(b4.getId()) + .setRatedU1(20.5) + .setRatedU2(399) + .setR(1) + .setX(30) + .setG(0) + .setB(0) + .add(); + TwoWindingsTransformer tr3 = s.newTwoWindingsTransformer() + .setId("tr3") + .setVoltageLevel1(b3.getVoltageLevel().getId()) + .setBus1(b3.getId()) + .setConnectableBus1(b3.getId()) + .setVoltageLevel2(vl4.getId()) + .setBus2(b4.getId()) + .setConnectableBus2(b4.getId()) + .setRatedU1(20.5) + .setRatedU2(399) + .setR(1) + .setX(30) + .setG(0) + .setB(0) + .add(); + + return network; + } + public static Network createTransformerBaseNetwork(String id) { Network network = Network.create(id, "test"); @@ -607,10 +741,10 @@ public static Network createWithShuntSharedRemoteControl() { .setVoltageLevel2(vl4.getId()) .setBus2(b4.getId()) .setConnectableBus2(b4.getId()) - .setRatedU1(20.2) - .setRatedU2(398) + .setRatedU1(20.5) + .setRatedU2(399) .setR(1) - .setX(36) + .setX(30) .setG(0) .setB(0) .add(); @@ -622,10 +756,10 @@ public static Network createWithShuntSharedRemoteControl() { .setVoltageLevel2(vl4.getId()) .setBus2(b4.getId()) .setConnectableBus2(b4.getId()) - .setRatedU1(21.3) - .setRatedU2(397) - .setR(2) - .setX(50) + .setRatedU1(20.5) + .setRatedU2(399) + .setR(1) + .setX(30) .setG(0) .setB(0) .add(); diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index 76032643d0..26075b7d78 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -759,7 +759,7 @@ void testSAmodeACAllBranchMonitoredFlowTransfer() { @Test void testSAWithRemoteSharedControl() { - Network network = VoltageControlNetworkFactory.createWithGeneratorRemoteControl(); + Network network = VoltageControlNetworkFactory.createWithIdenticalTransformers(); SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); LoadFlowParameters lfParameters = new LoadFlowParameters(); OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); @@ -786,15 +786,15 @@ void testSAWithRemoteSharedControl() { // pre-contingency tests PreContingencyResult preContingencyResult = result.getPreContingencyResult(); - assertEquals(-67.375, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); - assertEquals(-66.879, preContingencyResult.getPreContingencyBranchResult("tr2").getQ2(), 1e-2); - assertEquals(-65.744, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); + assertEquals(-66.667, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + assertEquals(-66.667, preContingencyResult.getPreContingencyBranchResult("tr2").getQ2(), 1e-2); + assertEquals(-66.667, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); // post-contingency tests PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr1")).findFirst().get(); assertEquals("tr1", postContingencyResult.getContingency().getId()); - assertEquals(-101.257, postContingencyResult.getBranchResult("tr2").getQ2(), 1e-2); - assertEquals(-98.742, postContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); + assertEquals(-99.999, postContingencyResult.getBranchResult("tr2").getQ2(), 1e-2); + assertEquals(-99.999, postContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); } @Test @@ -850,6 +850,14 @@ void testSAWithTransformerRemoteSharedControl2() { new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, contingenciesProvider, Collections.emptyList(), monitors); SecurityAnalysisResult result = futureResult.join().getResult(); + // pre-contingency tests + PreContingencyResult preContingencyResult = result.getPreContingencyResult(); + assertEquals(-6.181, preContingencyResult.getPreContingencyBranchResult("LINE_12").getQ2(), 1e-2); + + // post-contingency tests + PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("N-2")).findFirst().get(); + assertEquals("N-2", postContingencyResult.getContingency().getId()); + assertEquals(-7.499, postContingencyResult.getBranchResult("LINE_12").getQ2(), 1e-2); } @Test @@ -857,7 +865,7 @@ void testSAWithShuntRemoteSharedControl() { Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); LoadFlowParameters lfParameters = new LoadFlowParameters(); - lfParameters.setSimulShunt(true); + lfParameters.setSimulShunt(true); // FIXME KLU issue if false OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); saParameters.setLoadFlowParameters(lfParameters); @@ -876,14 +884,14 @@ void testSAWithShuntRemoteSharedControl() { // pre-contingency tests PreContingencyResult preContingencyResult = result.getPreContingencyResult(); - assertEquals(-807.198, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); - assertEquals(390.433, preContingencyResult.getPreContingencyBranchResult("tr2").getQ2(), 1e-2); - assertEquals(416.767, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); + assertEquals(-809.466, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + assertEquals(404.733, preContingencyResult.getPreContingencyBranchResult("tr2").getQ2(), 1e-2); + assertEquals(404.733, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); // post-contingency tests PostContingencyResult tr2ContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr2")).findFirst().orElseThrow(); assertEquals("tr2", tr2ContingencyResult.getContingency().getId()); - assertEquals(-807.198, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); - assertEquals(473.418, tr2ContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); + assertEquals(-809.466, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + assertEquals(461.993, tr2ContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); // FIXME? } } From 1ca5b62c6fecbf69b1a545d64ad63df51a719da3 Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Tue, 11 Jan 2022 19:48:18 +0100 Subject: [PATCH 32/37] Fix tests. Signed-off-by: Anne Tilloy --- .../powsybl/openloadflow/ac/AcLoadFlowShuntTest.java | 12 ++++++------ .../network/VoltageControlNetworkFactory.java | 10 +++++----- .../openloadflow/sa/OpenSecurityAnalysisTest.java | 12 ++++++------ 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java index 91b22c65e9..a5958a5a2b 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/AcLoadFlowShuntTest.java @@ -204,9 +204,9 @@ void testRemoteVoltageControl() { parameters.setSimulShunt(true); LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isOk()); - assertVoltageEquals(434.603, network.getBusBreakerView().getBus("b4")); + assertVoltageEquals(399.602, network.getBusBreakerView().getBus("b4")); assertEquals(0, shuntCompensator2.getSectionCount()); - assertEquals(10, shuntCompensator3.getSectionCount()); + assertEquals(27, shuntCompensator3.getSectionCount()); } @Test @@ -346,9 +346,9 @@ void testSharedRemoteVoltageControl() { ShuntCompensator shuntCompensator3 = network.getShuntCompensator("SHUNT3"); LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isOk()); - assertVoltageEquals(406.776, network.getBusBreakerView().getBus("b4")); - assertEquals(10, shuntCompensator2.getSectionCount()); - assertEquals(10, shuntCompensator3.getSectionCount()); + assertVoltageEquals(399.819, network.getBusBreakerView().getBus("b4")); + assertEquals(13, shuntCompensator2.getSectionCount()); + assertEquals(13, shuntCompensator3.getSectionCount()); } @Test @@ -415,7 +415,7 @@ void testNoShuntVoltageControl3() { ShuntCompensator shuntCompensator3 = network.getShuntCompensator("SHUNT3"); LoadFlowResult result = loadFlowRunner.run(network, parameters); assertTrue(result.isOk()); - assertVoltageEquals(419.690, network.getBusBreakerView().getBus("b4")); + assertVoltageEquals(407.978, network.getBusBreakerView().getBus("b4")); assertEquals(0, shuntCompensator2.getSectionCount()); assertEquals(0, shuntCompensator3.getSectionCount()); } diff --git a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java index 61c2610213..377c07ea28 100644 --- a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java +++ b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java @@ -685,7 +685,7 @@ public static Network createWithShuntSharedRemoteControl() { .setMinP(0) .setMaxP(200) .setTargetP(100) - .setTargetV(25) + .setTargetV(21) .setVoltageRegulatorOn(true) .add(); ShuntCompensator shunt2 = b2.getVoltageLevel().newShuntCompensator() @@ -698,8 +698,8 @@ public static Network createWithShuntSharedRemoteControl() { .setTargetV(400) .setTargetDeadband(5.0) .newLinearModel() - .setMaximumSectionCount(10) - .setBPerSection(-1E-1) + .setMaximumSectionCount(50) + .setBPerSection(-1E-2) .setGPerSection(0.0) .add() .add(); @@ -713,8 +713,8 @@ public static Network createWithShuntSharedRemoteControl() { .setTargetV(400) .setTargetDeadband(5.0) .newLinearModel() - .setMaximumSectionCount(10) - .setBPerSection(-1E-1) + .setMaximumSectionCount(50) + .setBPerSection(-1E-2) .setGPerSection(0.0) .add() .add(); diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index 26075b7d78..f99529e17f 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -865,7 +865,7 @@ void testSAWithShuntRemoteSharedControl() { Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); LoadFlowParameters lfParameters = new LoadFlowParameters(); - lfParameters.setSimulShunt(true); // FIXME KLU issue if false + lfParameters.setSimulShunt(true); OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); saParameters.setLoadFlowParameters(lfParameters); @@ -884,14 +884,14 @@ void testSAWithShuntRemoteSharedControl() { // pre-contingency tests PreContingencyResult preContingencyResult = result.getPreContingencyResult(); - assertEquals(-809.466, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); - assertEquals(404.733, preContingencyResult.getPreContingencyBranchResult("tr2").getQ2(), 1e-2); - assertEquals(404.733, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); + assertEquals(-108.596, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + assertEquals(54.298, preContingencyResult.getPreContingencyBranchResult("tr2").getQ2(), 1e-2); + assertEquals(54.298, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); // post-contingency tests PostContingencyResult tr2ContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr2")).findFirst().orElseThrow(); assertEquals("tr2", tr2ContingencyResult.getContingency().getId()); - assertEquals(-809.466, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); - assertEquals(461.993, tr2ContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); // FIXME? + assertEquals(-108.596, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + assertEquals(107.543, tr2ContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); } } From 8d21addf22436fabbfe6ad1b18695c10dd430028 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 11 Jan 2022 21:26:49 +0100 Subject: [PATCH 33/37] Cleanup Signed-off-by: Geoffroy Jamgotchian --- .../ac/equations/AcEquationSystem.java | 36 +++++++++---------- .../ac/equations/AcEquationSystemUpdater.java | 5 ++- 2 files changed, 18 insertions(+), 23 deletions(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java index b5ec9d47b8..53f4f671cc 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -147,12 +147,10 @@ static void updateRemoteVoltageControlEquations(VoltageControl voltageControl, E if (voltageControl.getControlledBus().isDisabled()) { // if controlled bus is disabled, we disable all voltage control equations vEq.setActive(false); - if (!voltageControl.isVoltageControlLocal()) { - for (LfBus controllerBus : controllerBuses) { - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) - .orElseThrow() - .setActive(false); - } + for (LfBus controllerBus : controllerBuses) { + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .orElseThrow() + .setActive(false); } } else { List enabledControllerBuses = new ArrayList<>(controllerBuses.size()); @@ -168,21 +166,19 @@ static void updateRemoteVoltageControlEquations(VoltageControl voltageControl, E // activate voltage control at controlled bus only if at least one controller bus is enabled vEq.setActive(!enabledControllerBuses.isEmpty()); - if (!voltageControl.isVoltageControlLocal()) { - // deactivate reactive power distribution equation on all disabled (PQ) buses - for (LfBus controllerBus : disabledControllerBuses) { - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) - .orElseThrow() - .setActive(false); - } + // deactivate reactive power distribution equation on all disabled (PQ) buses + for (LfBus controllerBus : disabledControllerBuses) { + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .orElseThrow() + .setActive(false); + } - // activate reactive power distribution equation at all enabled controller buses except one (first) - for (int i = 0; i < enabledControllerBuses.size(); i++) { - boolean active = i != 0; - LfBus controllerBus = enabledControllerBuses.get(i); - equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) - .ifPresent(qDistrEq -> qDistrEq.setActive(active)); - } + // activate reactive power distribution equation at all enabled controller buses except one (first) + for (int i = 0; i < enabledControllerBuses.size(); i++) { + boolean active = i != 0; + LfBus controllerBus = enabledControllerBuses.get(i); + equationSystem.getEquation(controllerBus.getNum(), AcEquationType.DISTR_Q) + .ifPresent(qDistrEq -> qDistrEq.setActive(active)); } } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index 49208c6161..e4a5871a2e 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -92,11 +92,10 @@ public void onDiscreteVoltageControlModeChange(DiscreteVoltageControl voltageCon public void onDisableChange(LfElement element, boolean disabled) { if (element.getType() == ElementType.BUS) { LfBus bus = (LfBus) element; - bus.getVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateRemoteVoltageControlEquations(voltageControl, equationSystem)); + bus.getVoltageControl().ifPresent(this::updateVoltageControl); bus.getTransformerVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateTransformerVoltageControlEquations(voltageControl, equationSystem)); bus.getShuntVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateShuntVoltageControlEquations(voltageControl, equationSystem)); - } - if (element.getType() == ElementType.BRANCH) { + } else if (element.getType() == ElementType.BRANCH) { LfBranch branch = (LfBranch) element; branch.getTransformerVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateTransformerVoltageControlEquations(voltageControl, equationSystem)); // TODO phase control. From 34784a3a37cbd2e9d7e9aa937828a5fba63f96a6 Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 11 Jan 2022 22:00:56 +0100 Subject: [PATCH 34/37] Cleanup Signed-off-by: Geoffroy Jamgotchian --- .../sa/OpenSecurityAnalysisTest.java | 146 ++++++------------ 1 file changed, 48 insertions(+), 98 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index f99529e17f..ee22c8479e 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -681,10 +681,10 @@ private static void assertAlmostEquals(ThreeWindingsTransformerResult expected, /** * Runs a security analysis with default parameters + most meshed slack bus selection */ - private static SecurityAnalysisResult runSecurityAnalysis(Network network, List contingencies, List monitors) { + private static SecurityAnalysisResult runSecurityAnalysis(Network network, List contingencies, List monitors, + LoadFlowParameters lfParameters) { SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); - LoadFlowParameters lfParameters = new LoadFlowParameters(); OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters() .setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED); lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); @@ -704,31 +704,24 @@ private static SecurityAnalysisResult runSecurityAnalysis(Network network, List< return futureResult.join().getResult(); } + private static SecurityAnalysisResult runSecurityAnalysis(Network network, List contingencies, List monitors) { + return runSecurityAnalysis(network, contingencies, monitors, new LoadFlowParameters()); + } + + private static List createAllBranchesMonitors(Network network) { + Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); + return List.of(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); + } + @Test - void testSAmodeACAllBranchMonitoredFlowTransfer() { + void testSaModeAcAllBranchMonitoredFlowTransfer() { Network network = FourBusNetworkFactory.create(); - SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); - LoadFlowParameters lfParameters = new LoadFlowParameters(); - OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters() - .setSlackBusSelectionMode(SlackBusSelectionMode.MOST_MESHED); - lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); - saParameters.setLoadFlowParameters(lfParameters); - - // Testing all contingencies at once - ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() - .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) - .collect(Collectors.toList()); - Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); + List contingencies = allBranches(network); - List monitors = new ArrayList<>(); - monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); + List monitors = createAllBranchesMonitors(network); - OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), EvenShiloachGraphDecrementalConnectivity::new); - CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), - new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, - contingenciesProvider, Collections.emptyList(), monitors); - SecurityAnalysisResult result = futureResult.join().getResult(); + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors); assertEquals(5, result.getPostContingencyResults().size()); @@ -758,31 +751,14 @@ void testSAmodeACAllBranchMonitoredFlowTransfer() { } @Test - void testSAWithRemoteSharedControl() { + void testSaWithRemoteSharedControl() { Network network = VoltageControlNetworkFactory.createWithIdenticalTransformers(); - SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); - LoadFlowParameters lfParameters = new LoadFlowParameters(); - OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); - lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); - saParameters.setLoadFlowParameters(lfParameters); - ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() - .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) - .collect(Collectors.toList()); - List monitors = new ArrayList<>(); - Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); - monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); - OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); - CompletableFuture futureResult = osaProvider.run(network, - network.getVariantManager().getWorkingVariantId(), - new DefaultLimitViolationDetector(), - new LimitViolationFilter(), - null, - saParameters, - contingenciesProvider, - Collections.emptyList(), - monitors); - SecurityAnalysisResult result = futureResult.join().getResult(); + List contingencies = allBranches(network); + + List monitors = createAllBranchesMonitors(network); + + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors); // pre-contingency tests PreContingencyResult preContingencyResult = result.getPreContingencyResult(); @@ -798,27 +774,17 @@ void testSAWithRemoteSharedControl() { } @Test - void testSAWithTransformerRemoteSharedControl() { + void testSaWithTransformerRemoteSharedControl() { Network network = VoltageControlNetworkFactory.createWithTransformerSharedRemoteControl(); - SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); - LoadFlowParameters lfParameters = new LoadFlowParameters(); - lfParameters.setTransformerVoltageControlOn(true); - OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); - lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); - saParameters.setLoadFlowParameters(lfParameters); - ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() - .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) - .collect(Collectors.toList()); - List monitors = new ArrayList<>(); - Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); - monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); - OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); - CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), - new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, - contingenciesProvider, Collections.emptyList(), monitors); - SecurityAnalysisResult result = futureResult.join().getResult(); + LoadFlowParameters lfParameters = new LoadFlowParameters() + .setTransformerVoltageControlOn(true); + + List contingencies = allBranches(network); + + List monitors = createAllBranchesMonitors(network); + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, lfParameters); // pre-contingency tests PreContingencyResult preContingencyResult = result.getPreContingencyResult(); assertEquals(-0.659, preContingencyResult.getPreContingencyBranchResult("T2wT2").getQ1(), 1e-2); @@ -831,56 +797,40 @@ void testSAWithTransformerRemoteSharedControl() { } @Test - void testSAWithTransformerRemoteSharedControl2() { + void testSaWithTransformerRemoteSharedControl2() { Network network = VoltageControlNetworkFactory.createWithTransformerSharedRemoteControl(); - SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); - LoadFlowParameters lfParameters = new LoadFlowParameters(); - lfParameters.setTransformerVoltageControlOn(true); - OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); - lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); - saParameters.setLoadFlowParameters(lfParameters); + + LoadFlowParameters lfParameters = new LoadFlowParameters() + .setTransformerVoltageControlOn(true); + List contingencies = List.of(new Contingency("N-2", List.of(new BranchContingency("T2wT"), new BranchContingency("T2wT2")))); - ContingenciesProvider contingenciesProvider = n -> contingencies; - List monitors = new ArrayList<>(); - Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); - monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); - OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); - CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), - new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, - contingenciesProvider, Collections.emptyList(), monitors); - SecurityAnalysisResult result = futureResult.join().getResult(); + List monitors = createAllBranchesMonitors(network); + + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, lfParameters); + // pre-contingency tests PreContingencyResult preContingencyResult = result.getPreContingencyResult(); assertEquals(-6.181, preContingencyResult.getPreContingencyBranchResult("LINE_12").getQ2(), 1e-2); // post-contingency tests - PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("N-2")).findFirst().get(); + PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("N-2")).findFirst().orElseThrow(); assertEquals("N-2", postContingencyResult.getContingency().getId()); assertEquals(-7.499, postContingencyResult.getBranchResult("LINE_12").getQ2(), 1e-2); } @Test - void testSAWithShuntRemoteSharedControl() { + void testSaWithShuntRemoteSharedControl() { Network network = VoltageControlNetworkFactory.createWithShuntSharedRemoteControl(); - SecurityAnalysisParameters saParameters = new SecurityAnalysisParameters(); - LoadFlowParameters lfParameters = new LoadFlowParameters(); - lfParameters.setSimulShunt(true); - OpenLoadFlowParameters olfParameters = new OpenLoadFlowParameters(); - lfParameters.addExtension(OpenLoadFlowParameters.class, olfParameters); - saParameters.setLoadFlowParameters(lfParameters); - ContingenciesProvider contingenciesProvider = n -> n.getBranchStream() - .map(b -> new Contingency(b.getId(), new BranchContingency(b.getId()))) - .collect(Collectors.toList()); - List monitors = new ArrayList<>(); - Set allBranchIds = network.getBranchStream().map(Identifiable::getId).collect(Collectors.toSet()); - monitors.add(new StateMonitor(ContingencyContext.all(), allBranchIds, Collections.emptySet(), Collections.emptySet())); - OpenSecurityAnalysisProvider osaProvider = new OpenSecurityAnalysisProvider(new DenseMatrixFactory(), () -> new NaiveGraphDecrementalConnectivity<>(LfBus::getNum)); - CompletableFuture futureResult = osaProvider.run(network, network.getVariantManager().getWorkingVariantId(), - new DefaultLimitViolationDetector(), new LimitViolationFilter(), null, saParameters, - contingenciesProvider, Collections.emptyList(), monitors); - SecurityAnalysisResult result = futureResult.join().getResult(); + LoadFlowParameters lfParameters = new LoadFlowParameters() + .setSimulShunt(true); + + List contingencies = allBranches(network); + + List monitors = createAllBranchesMonitors(network); + + SecurityAnalysisResult result = runSecurityAnalysis(network, contingencies, monitors, lfParameters); // pre-contingency tests PreContingencyResult preContingencyResult = result.getPreContingencyResult(); From 3bce6f6dca09bb8e1b184af97cf0b274495d23be Mon Sep 17 00:00:00 2001 From: Geoffroy Jamgotchian Date: Tue, 11 Jan 2022 22:27:21 +0100 Subject: [PATCH 35/37] Cleanup Signed-off-by: Geoffroy Jamgotchian --- .../network/VoltageControlNetworkFactory.java | 36 +++++++++---------- .../sa/OpenSecurityAnalysisTest.java | 21 ++++++----- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java index 377c07ea28..7510e31cd0 100644 --- a/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java +++ b/src/test/java/com/powsybl/openloadflow/network/VoltageControlNetworkFactory.java @@ -70,7 +70,7 @@ public static Network createWithGeneratorRemoteControl() { .setP0(299.6) .setQ0(200) .add(); - Generator g1 = b1.getVoltageLevel() + b1.getVoltageLevel() .newGenerator() .setId("g1") .setBus("b1") @@ -83,7 +83,7 @@ public static Network createWithGeneratorRemoteControl() { .setVoltageRegulatorOn(true) .setRegulatingTerminal(l4.getTerminal()) .add(); - Generator g2 = b2.getVoltageLevel() + b2.getVoltageLevel() .newGenerator() .setId("g2") .setBus("b2") @@ -96,7 +96,7 @@ public static Network createWithGeneratorRemoteControl() { .setVoltageRegulatorOn(true) .setRegulatingTerminal(l4.getTerminal()) .add(); - Generator g3 = b3.getVoltageLevel() + b3.getVoltageLevel() .newGenerator() .setId("g3") .setBus("b3") @@ -109,7 +109,7 @@ public static Network createWithGeneratorRemoteControl() { .setVoltageRegulatorOn(true) .setRegulatingTerminal(l4.getTerminal()) .add(); - TwoWindingsTransformer tr1 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr1") .setVoltageLevel1(b1.getVoltageLevel().getId()) .setBus1(b1.getId()) @@ -124,7 +124,7 @@ public static Network createWithGeneratorRemoteControl() { .setG(0) .setB(0) .add(); - TwoWindingsTransformer tr2 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr2") .setVoltageLevel1(b2.getVoltageLevel().getId()) .setBus1(b2.getId()) @@ -139,7 +139,7 @@ public static Network createWithGeneratorRemoteControl() { .setG(0) .setB(0) .add(); - TwoWindingsTransformer tr3 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr3") .setVoltageLevel1(b3.getVoltageLevel().getId()) .setBus1(b3.getId()) @@ -204,7 +204,7 @@ public static Network createWithIdenticalTransformers() { .setP0(299.6) .setQ0(200) .add(); - Generator g1 = b1.getVoltageLevel() + b1.getVoltageLevel() .newGenerator() .setId("g1") .setBus("b1") @@ -217,7 +217,7 @@ public static Network createWithIdenticalTransformers() { .setVoltageRegulatorOn(true) .setRegulatingTerminal(l4.getTerminal()) .add(); - Generator g2 = b2.getVoltageLevel() + b2.getVoltageLevel() .newGenerator() .setId("g2") .setBus("b2") @@ -230,7 +230,7 @@ public static Network createWithIdenticalTransformers() { .setVoltageRegulatorOn(true) .setRegulatingTerminal(l4.getTerminal()) .add(); - Generator g3 = b3.getVoltageLevel() + b3.getVoltageLevel() .newGenerator() .setId("g3") .setBus("b3") @@ -243,7 +243,7 @@ public static Network createWithIdenticalTransformers() { .setVoltageRegulatorOn(true) .setRegulatingTerminal(l4.getTerminal()) .add(); - TwoWindingsTransformer tr1 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr1") .setVoltageLevel1(b1.getVoltageLevel().getId()) .setBus1(b1.getId()) @@ -258,7 +258,7 @@ public static Network createWithIdenticalTransformers() { .setG(0) .setB(0) .add(); - TwoWindingsTransformer tr2 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr2") .setVoltageLevel1(b2.getVoltageLevel().getId()) .setBus1(b2.getId()) @@ -273,7 +273,7 @@ public static Network createWithIdenticalTransformers() { .setG(0) .setB(0) .add(); - TwoWindingsTransformer tr3 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr3") .setVoltageLevel1(b3.getVoltageLevel().getId()) .setBus1(b3.getId()) @@ -676,7 +676,7 @@ public static Network createWithShuntSharedRemoteControl() { .setP0(299.6) .setQ0(0) .add(); - Generator g1 = b1.getVoltageLevel() + b1.getVoltageLevel() .newGenerator() .setId("g1") .setBus("b1") @@ -688,7 +688,7 @@ public static Network createWithShuntSharedRemoteControl() { .setTargetV(21) .setVoltageRegulatorOn(true) .add(); - ShuntCompensator shunt2 = b2.getVoltageLevel().newShuntCompensator() + b2.getVoltageLevel().newShuntCompensator() .setId("SHUNT2") .setBus("b2") .setConnectableBus("b2") @@ -703,7 +703,7 @@ public static Network createWithShuntSharedRemoteControl() { .setGPerSection(0.0) .add() .add(); - ShuntCompensator shunt3 = b3.getVoltageLevel().newShuntCompensator() + b3.getVoltageLevel().newShuntCompensator() .setId("SHUNT3") .setBus("b3") .setConnectableBus("b3") @@ -718,7 +718,7 @@ public static Network createWithShuntSharedRemoteControl() { .setGPerSection(0.0) .add() .add(); - TwoWindingsTransformer tr1 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr1") .setVoltageLevel1(b1.getVoltageLevel().getId()) .setBus1(b1.getId()) @@ -733,7 +733,7 @@ public static Network createWithShuntSharedRemoteControl() { .setG(0) .setB(0) .add(); - TwoWindingsTransformer tr2 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr2") .setVoltageLevel1(b2.getVoltageLevel().getId()) .setBus1(b2.getId()) @@ -748,7 +748,7 @@ public static Network createWithShuntSharedRemoteControl() { .setG(0) .setB(0) .add(); - TwoWindingsTransformer tr3 = s.newTwoWindingsTransformer() + s.newTwoWindingsTransformer() .setId("tr3") .setVoltageLevel1(b3.getVoltageLevel().getId()) .setBus1(b3.getId()) diff --git a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java index ee22c8479e..f8ce158f34 100644 --- a/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java +++ b/src/test/java/com/powsybl/openloadflow/sa/OpenSecurityAnalysisTest.java @@ -750,6 +750,13 @@ void testSaModeAcAllBranchMonitoredFlowTransfer() { assertEquals(0.66, brl14l13.getFlowTransfer(), 1e-2); } + private static PostContingencyResult getPostContingencyResult(SecurityAnalysisResult result, String contingencyId) { + return result.getPostContingencyResults().stream() + .filter(r -> r.getContingency().getId().equals(contingencyId)) + .findFirst() + .orElseThrow(); + } + @Test void testSaWithRemoteSharedControl() { Network network = VoltageControlNetworkFactory.createWithIdenticalTransformers(); @@ -767,8 +774,7 @@ void testSaWithRemoteSharedControl() { assertEquals(-66.667, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); // post-contingency tests - PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr1")).findFirst().get(); - assertEquals("tr1", postContingencyResult.getContingency().getId()); + PostContingencyResult postContingencyResult = getPostContingencyResult(result, "tr1"); assertEquals(-99.999, postContingencyResult.getBranchResult("tr2").getQ2(), 1e-2); assertEquals(-99.999, postContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); } @@ -791,8 +797,7 @@ void testSaWithTransformerRemoteSharedControl() { assertEquals(-0.659, preContingencyResult.getPreContingencyBranchResult("T2wT").getQ1(), 1e-2); // post-contingency tests - PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("T2wT2")).findFirst().get(); - assertEquals("T2wT2", postContingencyResult.getContingency().getId()); + PostContingencyResult postContingencyResult = getPostContingencyResult(result, "T2wT2"); assertEquals(-0.572, postContingencyResult.getBranchResult("T2wT").getQ1(), 1e-2); // this assertion is not so relevant. It is more relevant to look at the logs. } @@ -814,8 +819,7 @@ void testSaWithTransformerRemoteSharedControl2() { assertEquals(-6.181, preContingencyResult.getPreContingencyBranchResult("LINE_12").getQ2(), 1e-2); // post-contingency tests - PostContingencyResult postContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("N-2")).findFirst().orElseThrow(); - assertEquals("N-2", postContingencyResult.getContingency().getId()); + PostContingencyResult postContingencyResult = getPostContingencyResult(result, "N-2"); assertEquals(-7.499, postContingencyResult.getBranchResult("LINE_12").getQ2(), 1e-2); } @@ -839,9 +843,8 @@ void testSaWithShuntRemoteSharedControl() { assertEquals(54.298, preContingencyResult.getPreContingencyBranchResult("tr3").getQ2(), 1e-2); // post-contingency tests - PostContingencyResult tr2ContingencyResult = result.getPostContingencyResults().stream().filter(r -> r.getContingency().getId().equals("tr2")).findFirst().orElseThrow(); - assertEquals("tr2", tr2ContingencyResult.getContingency().getId()); - assertEquals(-108.596, preContingencyResult.getPreContingencyBranchResult("tr1").getQ2(), 1e-2); + PostContingencyResult tr2ContingencyResult = getPostContingencyResult(result, "tr2"); + assertEquals(-107.543, tr2ContingencyResult.getBranchResult("tr1").getQ2(), 1e-2); assertEquals(107.543, tr2ContingencyResult.getBranchResult("tr3").getQ2(), 1e-2); } } From 99122691d797a36bb459bb60590cf22a8856d47e Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Wed, 12 Jan 2022 09:46:52 +0100 Subject: [PATCH 36/37] Remove TODO. Signed-off-by: Anne Tilloy --- .../openloadflow/ac/equations/AcEquationSystemUpdater.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java index e4a5871a2e..04288edbf6 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -98,7 +98,6 @@ public void onDisableChange(LfElement element, boolean disabled) { } else if (element.getType() == ElementType.BRANCH) { LfBranch branch = (LfBranch) element; branch.getTransformerVoltageControl().ifPresent(voltageControl -> AcEquationSystem.updateTransformerVoltageControlEquations(voltageControl, equationSystem)); - // TODO phase control. } } } From 750180d87209cf3af3fa7d39c16cee3890bbb7f7 Mon Sep 17 00:00:00 2001 From: Anne Tilloy Date: Wed, 12 Jan 2022 13:18:53 +0100 Subject: [PATCH 37/37] Fix AS. Signed-off-by: Anne Tilloy --- .../java/com/powsybl/openloadflow/network/BranchState.java | 5 +++++ .../java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/main/java/com/powsybl/openloadflow/network/BranchState.java b/src/main/java/com/powsybl/openloadflow/network/BranchState.java index 5e4e12d97b..2396ee5f90 100644 --- a/src/main/java/com/powsybl/openloadflow/network/BranchState.java +++ b/src/main/java/com/powsybl/openloadflow/network/BranchState.java @@ -14,6 +14,7 @@ public class BranchState extends ElementState { private final double a1; private final double r1; private final DiscretePhaseControl.Mode discretePhaseControlMode; + private final DiscreteVoltageControl.Mode transformerVoltageControlMode; private final boolean disabled; public BranchState(LfBranch branch) { @@ -22,6 +23,7 @@ public BranchState(LfBranch branch) { a1 = piModel.getA1(); r1 = piModel.getR1(); discretePhaseControlMode = branch.getDiscretePhaseControl().map(DiscretePhaseControl::getMode).orElse(null); + transformerVoltageControlMode = branch.getTransformerVoltageControl().map(TransformerVoltageControl::getMode).orElse(null); disabled = branch.isDisabled(); } @@ -33,6 +35,9 @@ public void restore() { if (discretePhaseControlMode != null) { element.getDiscretePhaseControl().ifPresent(control -> control.setMode(discretePhaseControlMode)); } + if (transformerVoltageControlMode != null) { + element.getTransformerVoltageControl().ifPresent(control -> control.setMode(transformerVoltageControlMode)); + } element.setDisabled(disabled); } diff --git a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java index 969202ef00..cc0fd30b50 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java @@ -135,6 +135,8 @@ private SecurityAnalysisResult runSimulations(LfNetwork network, List busStates = ElementState.save(network.getBuses(), BusState::save); + ElementState.restore(busModeStates); + ElementState.restore(branchStates); for (LfBus bus : network.getBuses()) { bus.setVoltageControlSwitchOffCount(0); }