diff --git a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java index e6cd79c4ea..ba4ee49204 100644 --- a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java +++ b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java @@ -23,17 +23,19 @@ import com.powsybl.math.matrix.MatrixFactory; import com.powsybl.math.matrix.SparseMatrixFactory; import com.powsybl.openloadflow.ac.DefaultOuterLoopConfig; +import com.powsybl.openloadflow.ac.equations.AcEquationSystemCreationParameters; import com.powsybl.openloadflow.ac.nr.DcValueVoltageInitializer; -import com.powsybl.openloadflow.ac.nr.DefaultNewtonRaphsonStoppingCriteria; +import com.powsybl.openloadflow.ac.nr.NewtonRaphsonParameters; import com.powsybl.openloadflow.ac.nr.NewtonRaphsonStatus; -import com.powsybl.openloadflow.ac.nr.NewtonRaphsonStoppingCriteria; import com.powsybl.openloadflow.ac.outerloop.*; import com.powsybl.openloadflow.dc.DcLoadFlowEngine; import com.powsybl.openloadflow.dc.DcLoadFlowParameters; import com.powsybl.openloadflow.dc.DcLoadFlowResult; +import com.powsybl.openloadflow.dc.equations.DcEquationSystemCreationParameters; import com.powsybl.openloadflow.equations.PreviousValueVoltageInitializer; import com.powsybl.openloadflow.equations.UniformValueVoltageInitializer; import com.powsybl.openloadflow.equations.VoltageInitializer; +import com.powsybl.openloadflow.network.LfNetworkParameters; import com.powsybl.openloadflow.network.NetworkSlackBusSelector; import com.powsybl.openloadflow.network.PerUnit; import com.powsybl.openloadflow.network.SlackBusSelector; @@ -142,8 +144,6 @@ public static AcLoadFlowParameters createAcParameters(Network network, MatrixFac VoltageInitializer voltageInitializer = getVoltageInitializer(parameters); - NewtonRaphsonStoppingCriteria stoppingCriteria = new DefaultNewtonRaphsonStoppingCriteria(); - LOGGER.info("Slack bus selector: {}", slackBusSelector.getClass().getSimpleName()); LOGGER.info("Voltage level initializer: {}", voltageInitializer.getClass().getSimpleName()); LOGGER.info("Distributed slack: {}", parameters.isDistributedSlack()); @@ -168,25 +168,30 @@ public static AcLoadFlowParameters createAcParameters(Network network, MatrixFac LOGGER.info("Outer loops: {}", outerLoops.stream().map(OuterLoop::getType).collect(Collectors.toList())); } - return new AcLoadFlowParameters(slackBusSelector, - voltageInitializer, - stoppingCriteria, - outerLoops, matrixFactory, - parametersExt.hasVoltageRemoteControl(), - parameters.isPhaseShifterRegulationOn(), - parameters.isTransformerVoltageControlOn(), - parametersExt.getLowImpedanceBranchMode() == OpenLoadFlowParameters.LowImpedanceBranchMode.REPLACE_BY_MIN_IMPEDANCE_LINE, - parameters.isTwtSplitShuntAdmittance(), - breakers, - parametersExt.getPlausibleActivePowerLimit(), - forceA1Var, - parametersExt.isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds(), - branchesWithCurrent, - parameters.getConnectedComponentMode() == LoadFlowParameters.ConnectedComponentMode.MAIN, - parameters.getCountriesToBalance(), - parameters.isDistributedSlack() && parameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD, - parametersExt.isVoltagePerReactivePowerControl(), - parametersExt.hasReactivePowerRemoteControl()); + var networkParameters = new LfNetworkParameters(slackBusSelector, + parametersExt.hasVoltageRemoteControl(), + parametersExt.getLowImpedanceBranchMode() == OpenLoadFlowParameters.LowImpedanceBranchMode.REPLACE_BY_MIN_IMPEDANCE_LINE, + parameters.isTwtSplitShuntAdmittance(), + breakers, + parametersExt.getPlausibleActivePowerLimit(), + parametersExt.isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds(), + parameters.getConnectedComponentMode() == LoadFlowParameters.ConnectedComponentMode.MAIN, + parameters.getCountriesToBalance(), + parameters.isDistributedSlack() && parameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD, + parameters.isPhaseShifterRegulationOn(), + parameters.isTransformerVoltageControlOn(), + parametersExt.isVoltagePerReactivePowerControl(), + parametersExt.hasReactivePowerRemoteControl()); + + var equationSystemCreationParameters = new AcEquationSystemCreationParameters(forceA1Var, branchesWithCurrent); + + var newtonRaphsonParameters = new NewtonRaphsonParameters() + .setVoltageInitializer(voltageInitializer); + + return new AcLoadFlowParameters(networkParameters, + equationSystemCreationParameters, + newtonRaphsonParameters, + outerLoops, matrixFactory); } private LoadFlowResult runAc(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt, Reporter reporter) { @@ -251,7 +256,9 @@ private LoadFlowResult runAc(Network network, LoadFlowParameters parameters, Ope return new LoadFlowResultImpl(ok, Collections.emptyMap(), null, componentResults); } - private LoadFlowResult runDc(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt, Reporter reporter) { + private static DcLoadFlowParameters createDcParameters(Network network, MatrixFactory matrixFactory, + LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt, + boolean forcePhaseControlOffAndAddAngle1Var) { SlackBusSelector slackBusSelector = getSlackBusSelector(network, parameters, parametersExt); LOGGER.info("Slack bus selector: {}", slackBusSelector.getClass().getSimpleName()); @@ -262,18 +269,37 @@ private LoadFlowResult runDc(Network network, LoadFlowParameters parameters, Ope LOGGER.info("Add ratio to lines with different nominal voltage at both ends: {}", parametersExt.isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds()); LOGGER.info("Connected component mode: {}", parameters.getConnectedComponentMode()); - DcLoadFlowParameters dcParameters = new DcLoadFlowParameters(slackBusSelector, - matrixFactory, - true, - parameters.isDcUseTransformerRatio(), - parameters.isDistributedSlack(), - parameters.getBalanceType(), - forcePhaseControlOffAndAddAngle1Var, - parametersExt.getPlausibleActivePowerLimit(), - parametersExt.isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds(), - true, - parameters.getConnectedComponentMode() == LoadFlowParameters.ConnectedComponentMode.MAIN, - parameters.getCountriesToBalance()); + var networkParameters = new LfNetworkParameters(slackBusSelector, + false, + false, + false, + false, + parametersExt.getPlausibleActivePowerLimit(), + false, + parameters.getConnectedComponentMode() == LoadFlowParameters.ConnectedComponentMode.MAIN, + parameters.getCountriesToBalance(), + parameters.isDistributedSlack() && parameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD, + false, + false, + false, + false); + + var equationSystemCreationParameters = new DcEquationSystemCreationParameters(true, + false, + forcePhaseControlOffAndAddAngle1Var, + parameters.isDcUseTransformerRatio()); + + return new DcLoadFlowParameters(networkParameters, + equationSystemCreationParameters, + matrixFactory, + parameters.isDistributedSlack(), + parameters.getBalanceType(), + true); + } + + private LoadFlowResult runDc(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt, Reporter reporter) { + + var dcParameters = createDcParameters(network, matrixFactory, parameters, parametersExt, forcePhaseControlOffAndAddAngle1Var); List results = new DcLoadFlowEngine(network, dcParameters, reporter) .run(reporter); 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 6b66e0b16b..284b85e2ec 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -29,7 +29,8 @@ public final class AcEquationSystem { private AcEquationSystem() { } - private static void createBusEquations(LfNetwork network, VariableSet variableSet, AcEquationSystemCreationParameters creationParameters, + private static void createBusEquations(LfNetwork network, VariableSet variableSet, + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters, EquationSystem equationSystem) { for (LfBus bus : network.getBuses()) { if (bus.isSlack()) { @@ -37,11 +38,11 @@ private static void createBusEquations(LfNetwork network, VariableSet v = equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V); @@ -57,15 +58,15 @@ private static void createBusEquations(LfNetwork network, VariableSet variableSet, EquationSystem equationSystem, - AcEquationSystemCreationParameters creationParameters) { + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters) { Optional optVoltageControl = bus.getVoltageControl(); if (optVoltageControl.isPresent()) { VoltageControl voltageControl = optVoltageControl.get(); if (voltageControl.isVoltageControlLocal()) { - createLocalVoltageControlEquation(bus, variableSet, equationSystem, creationParameters); + createLocalVoltageControlEquation(bus, variableSet, equationSystem, networkParameters, creationParameters); } else if (bus.isVoltageControlled()) { // remote controlled: set voltage equation on this controlled bus - createVoltageControlledBusEquations(voltageControl, equationSystem, variableSet, creationParameters); + createVoltageControlledBusEquations(voltageControl, equationSystem, variableSet, networkParameters, creationParameters); } if (bus.isVoltageControllerEnabled()) { @@ -77,13 +78,14 @@ private static void createGeneratorControlEquations(LfBus bus, VariableSet variableSet, EquationSystem equationSystem, AcEquationSystemCreationParameters creationParameters) { + private static void createLocalVoltageControlEquation(LfBus bus, VariableSet variableSet, EquationSystem equationSystem, + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters) { EquationTerm vTerm = EquationTerm.createVariableTerm(bus, AcVariableType.BUS_V, variableSet, bus.getV().eval()); bus.setV(vTerm); if (bus.hasGeneratorsWithSlope()) { // 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, creationParameters, variableSet, equationSystem, vTerm); + createBusWithSlopeEquation(bus, slope, networkParameters, creationParameters, variableSet, equationSystem, vTerm); return; } equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V).addTerm(vTerm); @@ -107,7 +109,7 @@ private static void createShuntEquations(VariableSet variableSet } private static void createVoltageControlledBusEquations(VoltageControl voltageControl, EquationSystem equationSystem, VariableSet variableSet, - AcEquationSystemCreationParameters creationParameters) { + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters) { LfBus controlledBus = voltageControl.getControlledBus(); // create voltage equation at voltage controlled bus @@ -123,11 +125,12 @@ private static void createVoltageControlledBusEquations(VoltageControl voltageCo vEq.setActive(false); } else { // create reactive power distribution equations at voltage controller buses (except one) - createReactivePowerDistributionEquations(equationSystem, variableSet, creationParameters, controllerBuses); + createReactivePowerDistributionEquations(equationSystem, variableSet, networkParameters, creationParameters, controllerBuses); } } - private static List> createReactiveTerms(LfBus controllerBus, VariableSet variableSet, AcEquationSystemCreationParameters creationParameters) { + private static List> createReactiveTerms(LfBus controllerBus, VariableSet variableSet, + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters) { List> terms = new ArrayList<>(); for (LfBranch branch : controllerBus.getBranches()) { EquationTerm q; @@ -141,9 +144,9 @@ private static List> createReactive q = EquationTerm.multiply(EquationTerm.createVariableTerm(branch, AcVariableType.DUMMY_Q, variableSet), -1); } } else { - boolean deriveA1 = creationParameters.isPhaseControl() && branch.isPhaseController() + boolean deriveA1 = networkParameters.isPhaseControl() && branch.isPhaseController() && branch.getDiscretePhaseControl().filter(dpc -> dpc.getMode() == Mode.CONTROLLER).isPresent(); - boolean deriveR1 = creationParameters.isTransformerVoltageControl() && branch.isVoltageController(); + boolean deriveR1 = networkParameters.isTransformerVoltageControl() && branch.isVoltageController(); if (branch.getBus1() == controllerBus) { LfBus otherSideBus = branch.getBus2(); q = otherSideBus != null ? new ClosedBranchSide1ReactiveFlowEquationTerm(branch, controllerBus, otherSideBus, variableSet, deriveA1, deriveR1) @@ -164,13 +167,13 @@ private static List> createReactive } public static void createReactivePowerDistributionEquations(EquationSystem equationSystem, VariableSet variableSet, - AcEquationSystemCreationParameters creationParameters, + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters, List controllerBuses) { double[] qKeys = createReactiveKeys(controllerBuses); // we choose first controller bus as reference for reactive power LfBus firstControllerBus = controllerBuses.get(0); - List> firstControllerBusReactiveTerms = createReactiveTerms(firstControllerBus, variableSet, creationParameters); + List> firstControllerBusReactiveTerms = createReactiveTerms(firstControllerBus, variableSet, networkParameters, creationParameters); // create a reactive power distribution equation for all the other controller buses for (int i = 1; i < controllerBuses.size(); i++) { @@ -181,7 +184,7 @@ public static void createReactivePowerDistributionEquations(EquationSystem zero = equationSystem.createEquation(controllerBus.getNum(), AcEquationType.ZERO_Q); zero.setData(new DistributionData(firstControllerBus.getNum(), c)); // for later use zero.addTerms(firstControllerBusReactiveTerms); - zero.addTerms(createReactiveTerms(controllerBus, variableSet, creationParameters).stream().map(term -> EquationTerm.multiply(term, -c)).collect(Collectors.toList())); + zero.addTerms(createReactiveTerms(controllerBus, variableSet, networkParameters, creationParameters).stream().map(term -> EquationTerm.multiply(term, -c)).collect(Collectors.toList())); } } @@ -337,14 +340,14 @@ private static void createDiscreteVoltageControlEquation(LfBus bus, VariableSet }); } - private static void createBusWithSlopeEquation(LfBus bus, double slope, AcEquationSystemCreationParameters creationParameters, VariableSet variableSet, + private static void createBusWithSlopeEquation(LfBus bus, double slope, LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters, VariableSet variableSet, EquationSystem equationSystem, EquationTerm vTerm) { // 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 Equation eq = equationSystem.createEquation(bus.getNum(), AcEquationType.BUS_V_SLOPE); eq.addTerm(vTerm); - List> controllerBusReactiveTerms = createReactiveTerms(bus, variableSet, creationParameters); + List> controllerBusReactiveTerms = createReactiveTerms(bus, variableSet, networkParameters, creationParameters); eq.setData(new DistributionData(bus.getNum(), slope)); // for later use for (EquationTerm eqTerm : controllerBusReactiveTerms) { eq.addTerm(EquationTerm.multiply(eqTerm, slope)); @@ -369,7 +372,7 @@ public static void createR1DistributionEquations(EquationSystem variableSet, - AcEquationSystemCreationParameters creationParameters, + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters, EquationSystem equationSystem) { EquationTerm p1 = null; EquationTerm q1 = null; @@ -377,11 +380,11 @@ private static void createImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2 EquationTerm q2 = null; EquationTerm i1 = null; EquationTerm i2 = null; - boolean deriveA1 = creationParameters.isPhaseControl() && branch.isPhaseController() + boolean deriveA1 = networkParameters.isPhaseControl() && branch.isPhaseController() && branch.getDiscretePhaseControl().filter(dpc -> dpc.getMode() != DiscretePhaseControl.Mode.OFF).isPresent(); deriveA1 = deriveA1 || (creationParameters.isForceA1Var() && branch.hasPhaseControlCapability()); boolean createCurrent = creationParameters.getBranchesWithCurrent() == null || creationParameters.getBranchesWithCurrent().contains(branch.getId()); - boolean deriveR1 = creationParameters.isTransformerVoltageControl() && branch.isVoltageController(); + boolean deriveR1 = networkParameters.isTransformerVoltageControl() && branch.isVoltageController(); if (bus1 != null && bus2 != null) { p1 = new ClosedBranchSide1ActiveFlowEquationTerm(branch, bus1, bus2, variableSet, deriveA1, deriveR1); q1 = new ClosedBranchSide1ReactiveFlowEquationTerm(branch, bus1, bus2, variableSet, deriveA1, deriveR1); @@ -412,7 +415,7 @@ private static void createImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2 } sp1.addTerm(p1); branch.setP1(p1); - if (creationParameters.isPhaseControl()) { + if (networkParameters.isPhaseControl()) { createBranchActivePowerTargetEquation(branch, DiscretePhaseControl.ControlledSide.ONE, equationSystem, variableSet, p1); } } @@ -432,7 +435,7 @@ private static void createImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2 } sp2.addTerm(p2); branch.setP2(p2); - if (creationParameters.isPhaseControl()) { + if (networkParameters.isPhaseControl()) { createBranchActivePowerTargetEquation(branch, DiscretePhaseControl.ControlledSide.TWO, equationSystem, variableSet, p2); } } @@ -446,7 +449,7 @@ private static void createImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2 createReactivePowerControlBranchEquation(branch, ReactivePowerControl.ControlledSide.TWO, equationSystem, q2); } - if ((creationParameters.isForceA1Var() && branch.hasPhaseControlCapability()) || (creationParameters.isPhaseControl() && branch.isPhaseController() + if ((creationParameters.isForceA1Var() && branch.hasPhaseControlCapability()) || (networkParameters.isPhaseControl() && branch.isPhaseController() && branch.getDiscretePhaseControl().filter(dpc -> dpc.getMode() == Mode.LIMITER).isPresent())) { EquationTerm.VariableEquationTerm a1 = EquationTerm.createVariableTerm(branch, AcVariableType.BRANCH_ALPHA1, variableSet); branch.setA1(a1); @@ -467,13 +470,13 @@ private static void createImpedantBranch(LfBranch branch, LfBus bus1, LfBus bus2 } } - private static void createBranchEquations(LfNetwork network, VariableSet variableSet, AcEquationSystemCreationParameters creationParameters, - EquationSystem equationSystem) { + private static void createBranchEquations(LfNetwork network, VariableSet variableSet, LfNetworkParameters networkParameters, + AcEquationSystemCreationParameters creationParameters, EquationSystem equationSystem) { // create zero and non zero impedance branch equations network.getBranches().stream() .filter(b -> !LfNetwork.isZeroImpedanceBranch(b)) - .forEach(b -> createImpedantBranch(b, b.getBus1(), b.getBus2(), variableSet, creationParameters, equationSystem)); + .forEach(b -> createImpedantBranch(b, b.getBus1(), b.getBus2(), variableSet, networkParameters, creationParameters, equationSystem)); // create zero and non zero impedance branch equations network.getBranches().stream() @@ -482,24 +485,34 @@ private static void createBranchEquations(LfNetwork network, VariableSet create(LfNetwork network) { - return create(network, new VariableSet<>()); + return create(network, new LfNetworkParameters()); } public static EquationSystem create(LfNetwork network, VariableSet variableSet) { - return create(network, variableSet, new AcEquationSystemCreationParameters(false, false)); + return create(network, variableSet, new LfNetworkParameters()); } - public static EquationSystem create(LfNetwork network, VariableSet variableSet, AcEquationSystemCreationParameters creationParameters) { + public static EquationSystem create(LfNetwork network, LfNetworkParameters networkParameters) { + return create(network, new VariableSet<>(), networkParameters); + } + + public static EquationSystem create(LfNetwork network, VariableSet variableSet, + LfNetworkParameters networkParameters) { + return create(network, variableSet, networkParameters, new AcEquationSystemCreationParameters()); + } + + public static EquationSystem create(LfNetwork network, VariableSet variableSet, + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters) { Objects.requireNonNull(network); Objects.requireNonNull(variableSet); Objects.requireNonNull(creationParameters); EquationSystem equationSystem = new EquationSystem<>(true); - createBusEquations(network, variableSet, creationParameters, equationSystem); - createBranchEquations(network, variableSet, creationParameters, equationSystem); + createBusEquations(network, variableSet, networkParameters, creationParameters, equationSystem); + createBranchEquations(network, variableSet, networkParameters, creationParameters, equationSystem); - network.addListener(new AcEquationSystemUpdater(equationSystem, variableSet, creationParameters)); + network.addListener(new AcEquationSystemUpdater(equationSystem, variableSet, networkParameters, creationParameters)); return equationSystem; } diff --git a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemCreationParameters.java b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemCreationParameters.java index 50f969d7bf..b7d1e25349 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemCreationParameters.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemCreationParameters.java @@ -13,37 +13,19 @@ */ public class AcEquationSystemCreationParameters { - private final boolean phaseControl; - - private final boolean transformerVoltageControl; - private final boolean forceA1Var; private final Set branchesWithCurrent; - public AcEquationSystemCreationParameters(boolean phaseControl, boolean transformerVoltageControl) { - this(phaseControl, transformerVoltageControl, false); - } - - public AcEquationSystemCreationParameters(boolean phaseControl, boolean transformerVoltageControl, boolean forceA1Var) { - this(phaseControl, transformerVoltageControl, forceA1Var, null); + public AcEquationSystemCreationParameters() { + this(false, null); } - public AcEquationSystemCreationParameters(boolean phaseControl, boolean transformerVoltageControl, boolean forceA1Var, Set branchesWithCurrent) { - this.phaseControl = phaseControl; - this.transformerVoltageControl = transformerVoltageControl; + public AcEquationSystemCreationParameters(boolean forceA1Var, Set branchesWithCurrent) { this.forceA1Var = forceA1Var; this.branchesWithCurrent = branchesWithCurrent; } - public boolean isPhaseControl() { - return phaseControl; - } - - public boolean isTransformerVoltageControl() { - return transformerVoltageControl; - } - public boolean isForceA1Var() { return forceA1Var; } 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 d1059c7644..30da832283 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -26,11 +26,15 @@ public class AcEquationSystemUpdater extends AbstractLfNetworkListener { private final VariableSet variableSet; + private final LfNetworkParameters networkParameters; + private final AcEquationSystemCreationParameters creationParameters; - public AcEquationSystemUpdater(EquationSystem equationSystem, VariableSet variableSet, AcEquationSystemCreationParameters creationParameters) { + public AcEquationSystemUpdater(EquationSystem equationSystem, VariableSet variableSet, + LfNetworkParameters networkParameters, AcEquationSystemCreationParameters creationParameters) { this.equationSystem = Objects.requireNonNull(equationSystem); this.variableSet = Objects.requireNonNull(variableSet); + this.networkParameters = Objects.requireNonNull(networkParameters); this.creationParameters = Objects.requireNonNull(creationParameters); } @@ -57,7 +61,7 @@ private void updateControlledBus(VoltageControl voltageControl, EquationSystem @@ -21,8 +27,15 @@ public class DcValueVoltageInitializer implements VoltageInitializer { @Override - public void prepare(LfNetwork network, MatrixFactory matrixFactory, Reporter reporter) { - if (new DcLoadFlowEngine(network, matrixFactory, false).run(reporter, network).getStatus() != LoadFlowResult.ComponentResult.Status.CONVERGED) { + public void prepare(LfNetwork network, LfNetworkParameters networkParameters, MatrixFactory matrixFactory, Reporter reporter) { + DcLoadFlowParameters parameters = new DcLoadFlowParameters(networkParameters, + new DcEquationSystemCreationParameters(false, false, false, true), + matrixFactory, + false, + LoadFlowParameters.BalanceType.PROPORTIONAL_TO_GENERATION_P_MAX, + false); + DcLoadFlowEngine engine = new DcLoadFlowEngine(List.of(network), parameters); + if (engine.run(reporter, network).getStatus() != LoadFlowResult.ComponentResult.Status.CONVERGED) { throw new PowsyblException("DC loadflow failed, impossible to initialize voltage angle from DC values"); } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/nr/NewtonRaphson.java b/src/main/java/com/powsybl/openloadflow/ac/nr/NewtonRaphson.java index 7b635da826..7278eff5a0 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/nr/NewtonRaphson.java +++ b/src/main/java/com/powsybl/openloadflow/ac/nr/NewtonRaphson.java @@ -13,6 +13,7 @@ import com.powsybl.openloadflow.equations.*; import com.powsybl.openloadflow.network.LfBus; import com.powsybl.openloadflow.network.LfNetwork; +import com.powsybl.openloadflow.network.LfNetworkParameters; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -27,26 +28,30 @@ public class NewtonRaphson { private final LfNetwork network; + private final LfNetworkParameters networkParameters; + + private final NewtonRaphsonParameters parameters; + private final MatrixFactory matrixFactory; private final EquationSystem equationSystem; - private final NewtonRaphsonStoppingCriteria stoppingCriteria; - private int iteration = 0; private final JacobianMatrix j; private final TargetVector targetVector; - public NewtonRaphson(LfNetwork network, MatrixFactory matrixFactory, EquationSystem equationSystem, JacobianMatrix j, - TargetVector targetVector, NewtonRaphsonStoppingCriteria stoppingCriteria) { + public NewtonRaphson(LfNetwork network, LfNetworkParameters networkParameters, NewtonRaphsonParameters parameters, MatrixFactory matrixFactory, + EquationSystem equationSystem, JacobianMatrix j, + TargetVector targetVector) { this.network = Objects.requireNonNull(network); + this.networkParameters = Objects.requireNonNull(networkParameters); + this.parameters = Objects.requireNonNull(parameters); this.matrixFactory = Objects.requireNonNull(matrixFactory); this.equationSystem = Objects.requireNonNull(equationSystem); this.j = Objects.requireNonNull(j); this.targetVector = Objects.requireNonNull(targetVector); - this.stoppingCriteria = Objects.requireNonNull(stoppingCriteria); } private NewtonRaphsonStatus runIteration(double[] fx, double[] x) { @@ -78,7 +83,7 @@ private NewtonRaphsonStatus runIteration(double[] fx, double[] x) { } // test stopping criteria and log norm(fx) - NewtonRaphsonStoppingCriteria.TestResult testResult = stoppingCriteria.test(fx); + NewtonRaphsonStoppingCriteria.TestResult testResult = parameters.getStoppingCriteria().test(fx); LOGGER.debug("|f(x)|={}", testResult.getNorm()); @@ -164,14 +169,14 @@ public void updateNetwork(double[] x) { } } - public NewtonRaphsonResult run(NewtonRaphsonParameters parameters, Reporter reporter) { - Objects.requireNonNull(parameters); + public NewtonRaphsonResult run(Reporter reporter) { + Objects.requireNonNull(reporter); // initialize state vector VoltageInitializer voltageInitializer = iteration == 0 ? parameters.getVoltageInitializer() : new PreviousValueVoltageInitializer(); - voltageInitializer.prepare(network, matrixFactory, reporter); + voltageInitializer.prepare(network, networkParameters, matrixFactory, reporter); double[] x = createStateVector(network, equationSystem, voltageInitializer); diff --git a/src/main/java/com/powsybl/openloadflow/ac/nr/NewtonRaphsonParameters.java b/src/main/java/com/powsybl/openloadflow/ac/nr/NewtonRaphsonParameters.java index ab82cf06c2..dcc196798f 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/nr/NewtonRaphsonParameters.java +++ b/src/main/java/com/powsybl/openloadflow/ac/nr/NewtonRaphsonParameters.java @@ -26,6 +26,8 @@ public int getMaxIteration() { return maxIteration; } + private final NewtonRaphsonStoppingCriteria stoppingCriteria = new DefaultNewtonRaphsonStoppingCriteria(); + public NewtonRaphsonParameters setMaxIteration(int maxIteration) { if (maxIteration < 1) { throw new IllegalArgumentException("Invalid max iteration value: " + maxIteration); @@ -42,4 +44,8 @@ public NewtonRaphsonParameters setVoltageInitializer(VoltageInitializer voltageI this.voltageInitializer = Objects.requireNonNull(voltageInitializer); return this; } + + public NewtonRaphsonStoppingCriteria getStoppingCriteria() { + return stoppingCriteria; + } } diff --git a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcLoadFlowParameters.java index a9966f377f..2fc9e687fb 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcLoadFlowParameters.java @@ -6,108 +6,48 @@ */ package com.powsybl.openloadflow.ac.outerloop; -import com.powsybl.iidm.network.Country; import com.powsybl.math.matrix.MatrixFactory; -import com.powsybl.openloadflow.ac.nr.NewtonRaphsonStoppingCriteria; -import com.powsybl.openloadflow.equations.VoltageInitializer; -import com.powsybl.openloadflow.network.SlackBusSelector; +import com.powsybl.openloadflow.ac.equations.AcEquationSystemCreationParameters; +import com.powsybl.openloadflow.ac.nr.NewtonRaphsonParameters; +import com.powsybl.openloadflow.network.LfNetworkParameters; -import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Set; /** * @author Geoffroy Jamgotchian */ public class AcLoadFlowParameters { - private final SlackBusSelector slackBusSelector; + private final LfNetworkParameters networkParameters; - private VoltageInitializer voltageInitializer; + private final AcEquationSystemCreationParameters equationSystemCreationParameters; - private final NewtonRaphsonStoppingCriteria stoppingCriteria; + private final NewtonRaphsonParameters newtonRaphsonParameters; private final List outerLoops; private final MatrixFactory matrixFactory; - private final boolean voltageRemoteControl; - - private final boolean phaseControl; - - private final boolean transformerVoltageControlOn; - - private final boolean minImpedance; - - private final boolean twtSplitShuntAdmittance; - - private final boolean breakers; - - private double plausibleActivePowerLimit; - - private final boolean forceA1Var; - - private final boolean addRatioToLinesWithDifferentNominalVoltageAtBothEnds; - - private final Set branchesWithCurrent; - - private final boolean computeMainConnectedComponentOnly; - - private final Set countriesToBalance; - - private final boolean distributedOnConformLoad; - - private final boolean voltagePerReactivePowerControl; - - private final boolean reactivePowerRemoteControl; - - public AcLoadFlowParameters(SlackBusSelector slackBusSelector, VoltageInitializer voltageInitializer, - NewtonRaphsonStoppingCriteria stoppingCriteria, List outerLoops, - MatrixFactory matrixFactory, boolean voltageRemoteControl, - boolean phaseControl, boolean transformerVoltageControlOn, boolean minImpedance, - boolean twtSplitShuntAdmittance, boolean breakers, double plausibleActivePowerLimit, - boolean forceA1Var, boolean addRatioToLinesWithDifferentNominalVoltageAtBothEnds, - Set branchesWithCurrent, boolean computeMainConnectedComponentOnly, - Set countriesToBalance, boolean distributedOnConformLoad, - boolean voltagePerReactivePowerControl, - boolean reactivePowerRemoteControl) { - this.slackBusSelector = Objects.requireNonNull(slackBusSelector); - this.voltageInitializer = Objects.requireNonNull(voltageInitializer); - this.stoppingCriteria = Objects.requireNonNull(stoppingCriteria); + public AcLoadFlowParameters(LfNetworkParameters networkParameters, AcEquationSystemCreationParameters equationSystemCreationParameters, + NewtonRaphsonParameters newtonRaphsonParameters, List outerLoops, MatrixFactory matrixFactory) { + this.networkParameters = Objects.requireNonNull(networkParameters); + this.equationSystemCreationParameters = Objects.requireNonNull(equationSystemCreationParameters); + this.newtonRaphsonParameters = Objects.requireNonNull(newtonRaphsonParameters); this.outerLoops = Objects.requireNonNull(outerLoops); this.matrixFactory = Objects.requireNonNull(matrixFactory); - this.voltageRemoteControl = voltageRemoteControl; - this.phaseControl = phaseControl; - this.transformerVoltageControlOn = transformerVoltageControlOn; - this.minImpedance = minImpedance; - this.twtSplitShuntAdmittance = twtSplitShuntAdmittance; - this.breakers = breakers; - this.plausibleActivePowerLimit = plausibleActivePowerLimit; - this.forceA1Var = forceA1Var; - this.addRatioToLinesWithDifferentNominalVoltageAtBothEnds = addRatioToLinesWithDifferentNominalVoltageAtBothEnds; - this.branchesWithCurrent = branchesWithCurrent; - this.computeMainConnectedComponentOnly = computeMainConnectedComponentOnly; - this.countriesToBalance = countriesToBalance; - this.distributedOnConformLoad = distributedOnConformLoad; - this.voltagePerReactivePowerControl = voltagePerReactivePowerControl; - this.reactivePowerRemoteControl = reactivePowerRemoteControl; } - public SlackBusSelector getSlackBusSelector() { - return slackBusSelector; + public LfNetworkParameters getNetworkParameters() { + return networkParameters; } - public VoltageInitializer getVoltageInitializer() { - return voltageInitializer; + public AcEquationSystemCreationParameters getEquationSystemCreationParameters() { + return equationSystemCreationParameters; } - public void setVoltageInitializer(VoltageInitializer voltageInitializer) { - this.voltageInitializer = voltageInitializer; - } - - public NewtonRaphsonStoppingCriteria getStoppingCriteria() { - return stoppingCriteria; + public NewtonRaphsonParameters getNewtonRaphsonParameters() { + return newtonRaphsonParameters; } public List getOuterLoops() { @@ -117,64 +57,4 @@ public List getOuterLoops() { public MatrixFactory getMatrixFactory() { return matrixFactory; } - - public boolean isVoltageRemoteControl() { - return voltageRemoteControl; - } - - public boolean isPhaseControl() { - return phaseControl; - } - - public boolean isTransformerVoltageControlOn() { - return transformerVoltageControlOn; - } - - public boolean isMinImpedance() { - return minImpedance; - } - - public boolean isTwtSplitShuntAdmittance() { - return twtSplitShuntAdmittance; - } - - public boolean isBreakers() { - return breakers; - } - - public double getPlausibleActivePowerLimit() { - return plausibleActivePowerLimit; - } - - public boolean isForceA1Var() { - return forceA1Var; - } - - public boolean isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds() { - return addRatioToLinesWithDifferentNominalVoltageAtBothEnds; - } - - public Set getBranchesWithCurrent() { - return branchesWithCurrent; - } - - public boolean isComputeMainConnectedComponentOnly() { - return computeMainConnectedComponentOnly; - } - - public Set getCountriesToBalance() { - return Collections.unmodifiableSet(countriesToBalance); - } - - public boolean isDistributedOnConformLoad() { - return distributedOnConformLoad; - } - - public boolean isVoltagePerReactivePowerControl() { - return voltagePerReactivePowerControl; - } - - public boolean isReactivePowerRemoteControl() { - return reactivePowerRemoteControl; - } } 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 db9c566a75..a0aab5faae 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java +++ b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcloadFlowEngine.java @@ -9,11 +9,9 @@ import com.powsybl.commons.PowsyblException; import com.powsybl.commons.reporter.Reporter; import com.powsybl.openloadflow.ac.equations.AcEquationSystem; -import com.powsybl.openloadflow.ac.equations.AcEquationSystemCreationParameters; import com.powsybl.openloadflow.ac.equations.AcEquationType; import com.powsybl.openloadflow.ac.equations.AcVariableType; import com.powsybl.openloadflow.ac.nr.NewtonRaphson; -import com.powsybl.openloadflow.ac.nr.NewtonRaphsonParameters; import com.powsybl.openloadflow.ac.nr.NewtonRaphsonResult; import com.powsybl.openloadflow.ac.nr.NewtonRaphsonStatus; import com.powsybl.openloadflow.equations.*; @@ -50,21 +48,7 @@ public AcloadFlowEngine(LfNetwork network, AcLoadFlowParameters parameters) { } public static List createNetworks(Object network, AcLoadFlowParameters parameters, Reporter reporter) { - LfNetworkParameters networkParameters = new LfNetworkParameters(parameters.getSlackBusSelector(), - parameters.isVoltageRemoteControl(), - parameters.isMinImpedance(), - parameters.isTwtSplitShuntAdmittance(), - parameters.isBreakers(), - parameters.getPlausibleActivePowerLimit(), - parameters.isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds(), - parameters.isComputeMainConnectedComponentOnly(), - parameters.getCountriesToBalance(), - parameters.isDistributedOnConformLoad(), - parameters.isPhaseControl(), - parameters.isVoltageRemoteControl(), - parameters.isVoltagePerReactivePowerControl(), - parameters.isReactivePowerRemoteControl()); - return LfNetwork.load(network, networkParameters, reporter); + return LfNetwork.load(network, parameters.getNetworkParameters(), reporter); } public LfNetwork getNetwork() { @@ -104,8 +88,7 @@ private static class RunningContext { } private void runOuterLoop(OuterLoop outerLoop, LfNetwork network, EquationSystem equationSystem, VariableSet variableSet, - NewtonRaphson newtonRaphson, NewtonRaphsonParameters nrParameters, RunningContext runningContext, - Reporter reporter) { + NewtonRaphson newtonRaphson, RunningContext runningContext, Reporter reporter) { Reporter olReporter = reporter.createSubReporter("OuterLoop", "Outer loop ${outerLoopType}", "outerLoopType", outerLoop.getType()); // for each outer loop re-run Newton-Raphson until stabilization @@ -120,7 +103,7 @@ private void runOuterLoop(OuterLoop outerLoop, LfNetwork network, EquationSystem LOGGER.debug("Start outer loop iteration {} (name='{}')", outerLoopIteration, outerLoop.getType()); // if not yet stable, restart Newton-Raphson - runningContext.lastNrResult = newtonRaphson.run(nrParameters, reporter); + runningContext.lastNrResult = newtonRaphson.run(reporter); if (runningContext.lastNrResult.getStatus() != NewtonRaphsonStatus.CONVERGED) { return; } @@ -253,10 +236,7 @@ public AcLoadFlowResult run(Reporter reporter) { LOGGER.info("Start AC loadflow on network {}", network); variableSet = new VariableSet<>(); - AcEquationSystemCreationParameters creationParameters = new AcEquationSystemCreationParameters( - parameters.isPhaseControl(), parameters.isTransformerVoltageControlOn(), parameters.isForceA1Var(), - parameters.getBranchesWithCurrent()); - equationSystem = AcEquationSystem.create(network, variableSet, creationParameters); + equationSystem = AcEquationSystem.create(network, variableSet, parameters.getNetworkParameters(), parameters.getEquationSystemCreationParameters()); j = new JacobianMatrix<>(equationSystem, parameters.getMatrixFactory()); targetVector = new TargetVector<>(network, equationSystem, AcloadFlowEngine::initTarget); } else { @@ -264,12 +244,11 @@ public AcLoadFlowResult run(Reporter reporter) { } RunningContext runningContext = new RunningContext(); - NewtonRaphson newtonRaphson = new NewtonRaphson(network, parameters.getMatrixFactory(), equationSystem, j, targetVector, parameters.getStoppingCriteria()); - - NewtonRaphsonParameters nrParameters = new NewtonRaphsonParameters().setVoltageInitializer(parameters.getVoltageInitializer()); + NewtonRaphson newtonRaphson = new NewtonRaphson(network, parameters.getNetworkParameters(), parameters.getNewtonRaphsonParameters(), + parameters.getMatrixFactory(), equationSystem, j, targetVector); // run initial Newton-Raphson - runningContext.lastNrResult = newtonRaphson.run(nrParameters, reporter); + runningContext.lastNrResult = newtonRaphson.run(reporter); // continue with outer loops only if initial Newton-Raphson succeed if (runningContext.lastNrResult.getStatus() == NewtonRaphsonStatus.CONVERGED) { @@ -287,7 +266,7 @@ public AcLoadFlowResult run(Reporter reporter) { // outer loops are nested: inner most loop first in the list, outer most loop last for (OuterLoop outerLoop : parameters.getOuterLoops()) { - runOuterLoop(outerLoop, network, equationSystem, variableSet, newtonRaphson, nrParameters, runningContext, reporter); + runOuterLoop(outerLoop, network, equationSystem, variableSet, newtonRaphson, runningContext, reporter); // continue with next outer loop only if last Newton-Raphson succeed if (runningContext.lastNrResult.getStatus() != NewtonRaphsonStatus.CONVERGED) { diff --git a/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java b/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java index 4c442e8a64..d13d7a0cbf 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java +++ b/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java @@ -8,16 +8,16 @@ import com.powsybl.commons.reporter.Report; import com.powsybl.commons.reporter.Reporter; -import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.loadflow.LoadFlowResult; -import com.powsybl.math.matrix.MatrixFactory; import com.powsybl.openloadflow.OpenLoadFlowReportConstants; import com.powsybl.openloadflow.dc.equations.DcEquationSystem; -import com.powsybl.openloadflow.dc.equations.DcEquationSystemCreationParameters; import com.powsybl.openloadflow.dc.equations.DcEquationType; import com.powsybl.openloadflow.dc.equations.DcVariableType; import com.powsybl.openloadflow.equations.*; -import com.powsybl.openloadflow.network.*; +import com.powsybl.openloadflow.network.DiscretePhaseControl; +import com.powsybl.openloadflow.network.LfBranch; +import com.powsybl.openloadflow.network.LfBus; +import com.powsybl.openloadflow.network.LfNetwork; import com.powsybl.openloadflow.network.util.ActivePowerDistribution; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -40,17 +40,8 @@ public class DcLoadFlowEngine { private double[] targetVector; - public DcLoadFlowEngine(LfNetwork network, MatrixFactory matrixFactory, boolean setVToNan) { - this.networks = Collections.singletonList(network); - parameters = new DcLoadFlowParameters(new FirstSlackBusSelector(), matrixFactory, setVToNan); - } - public DcLoadFlowEngine(Object network, DcLoadFlowParameters parameters, Reporter reporter) { - LfNetworkParameters lfNetworkParameters = new LfNetworkParameters(parameters.getSlackBusSelector(), false, false, false, false, - parameters.getPlausibleActivePowerLimit(), false, parameters.isComputeMainConnectedComponentOnly(), parameters.getCountriesToBalance(), - parameters.isDistributedSlack() && parameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD, - false, false, false, false); - this.networks = LfNetwork.load(network, lfNetworkParameters, reporter); + this.networks = LfNetwork.load(network, parameters.getNetworkParameters(), reporter); this.parameters = Objects.requireNonNull(parameters); } @@ -78,8 +69,7 @@ public List run(Reporter reporter) { } public DcLoadFlowResult run(Reporter reporter, LfNetwork pNetwork) { - DcEquationSystemCreationParameters creationParameters = new DcEquationSystemCreationParameters(parameters.isUpdateFlows(), false, parameters.isForcePhaseControlOffAndAddAngle1Var(), parameters.isUseTransformerRatio()); - EquationSystem equationSystem = DcEquationSystem.create(pNetwork, new VariableSet<>(), creationParameters); + EquationSystem equationSystem = DcEquationSystem.create(pNetwork, new VariableSet<>(), parameters.getEquationSystemCreationParameters()); LoadFlowResult.ComponentResult.Status status = LoadFlowResult.ComponentResult.Status.FAILED; try (JacobianMatrix j = new JacobianMatrix<>(equationSystem, parameters.getMatrixFactory())) { diff --git a/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowParameters.java index 44daaafd07..320228a69a 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowParameters.java @@ -6,79 +6,51 @@ */ package com.powsybl.openloadflow.dc; -import com.powsybl.iidm.network.Country; import com.powsybl.loadflow.LoadFlowParameters; import com.powsybl.math.matrix.MatrixFactory; -import com.powsybl.openloadflow.network.SlackBusSelector; -import com.powsybl.openloadflow.util.ParameterConstants; +import com.powsybl.openloadflow.dc.equations.DcEquationSystemCreationParameters; +import com.powsybl.openloadflow.network.LfNetworkParameters; -import java.util.Collections; import java.util.Objects; -import java.util.Set; /** * @author Geoffroy Jamgotchian */ public class DcLoadFlowParameters { - private final SlackBusSelector slackBusSelector; + private final LfNetworkParameters networkParameters; - private final MatrixFactory matrixFactory; - - private final boolean updateFlows; + private final DcEquationSystemCreationParameters equationSystemCreationParameters; - private final boolean useTransformerRatio; + private final MatrixFactory matrixFactory; private final boolean distributedSlack; private final LoadFlowParameters.BalanceType balanceType; - private final boolean forcePhaseControlOffAndAddAngle1Var; - - private final double plausibleActivePowerLimit; - - private final boolean addRatioToLinesWithDifferentNominalVoltageAtBothEnds; - private final boolean setVToNan; - private final boolean computeMainConnectedComponentOnly; - - private final Set countriesToBalance; - - public DcLoadFlowParameters(SlackBusSelector slackBusSelector, MatrixFactory matrixFactory, boolean setVToNan) { - this(slackBusSelector, matrixFactory, false, true, false, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_GENERATION_P_MAX, false, - ParameterConstants.PLAUSIBLE_ACTIVE_POWER_LIMIT_DEFAULT_VALUE, false, setVToNan, true, LoadFlowParameters.DEFAULT_COUNTRIES_TO_BALANCE); - } - - public DcLoadFlowParameters(SlackBusSelector slackBusSelector, MatrixFactory matrixFactory, boolean updateFlows, - boolean useTransformerRatio, boolean distributedSlack, LoadFlowParameters.BalanceType balanceType, - boolean forcePhaseControlOffAndAddAngle1Var, double plausibleActivePowerLimit, - boolean addRatioToLinesWithDifferentNominalVoltageAtBothEnds, boolean setVToNan, boolean computeMainConnectedComponentOnly, - Set countriesToBalance) { - this.slackBusSelector = Objects.requireNonNull(slackBusSelector); + public DcLoadFlowParameters(LfNetworkParameters networkParameters, DcEquationSystemCreationParameters equationSystemCreationParameters, + MatrixFactory matrixFactory, boolean distributedSlack, LoadFlowParameters.BalanceType balanceType, + boolean setVToNan) { + this.networkParameters = Objects.requireNonNull(networkParameters); + this.equationSystemCreationParameters = Objects.requireNonNull(equationSystemCreationParameters); this.matrixFactory = Objects.requireNonNull(matrixFactory); - this.updateFlows = updateFlows; - this.useTransformerRatio = useTransformerRatio; this.distributedSlack = distributedSlack; this.balanceType = balanceType; - this.forcePhaseControlOffAndAddAngle1Var = forcePhaseControlOffAndAddAngle1Var; - this.plausibleActivePowerLimit = plausibleActivePowerLimit; - this.addRatioToLinesWithDifferentNominalVoltageAtBothEnds = addRatioToLinesWithDifferentNominalVoltageAtBothEnds; this.setVToNan = setVToNan; - this.computeMainConnectedComponentOnly = computeMainConnectedComponentOnly; - this.countriesToBalance = countriesToBalance; } - public SlackBusSelector getSlackBusSelector() { - return slackBusSelector; + public LfNetworkParameters getNetworkParameters() { + return networkParameters; } - public MatrixFactory getMatrixFactory() { - return matrixFactory; + public DcEquationSystemCreationParameters getEquationSystemCreationParameters() { + return equationSystemCreationParameters; } - public boolean isUpdateFlows() { - return updateFlows; + public MatrixFactory getMatrixFactory() { + return matrixFactory; } public boolean isDistributedSlack() { @@ -89,32 +61,7 @@ public LoadFlowParameters.BalanceType getBalanceType() { return balanceType; } - public boolean isUseTransformerRatio() { - return useTransformerRatio; - } - - public boolean isForcePhaseControlOffAndAddAngle1Var() { - return forcePhaseControlOffAndAddAngle1Var; - } - - public double getPlausibleActivePowerLimit() { - return plausibleActivePowerLimit; - } - - public boolean isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds() { - return addRatioToLinesWithDifferentNominalVoltageAtBothEnds; - } - public boolean isSetVToNan() { return setVToNan; } - - public boolean isComputeMainConnectedComponentOnly() { - return computeMainConnectedComponentOnly; - } - - public Set getCountriesToBalance() { - return Collections.unmodifiableSet(countriesToBalance); - } - } diff --git a/src/main/java/com/powsybl/openloadflow/equations/PreviousValueVoltageInitializer.java b/src/main/java/com/powsybl/openloadflow/equations/PreviousValueVoltageInitializer.java index 7f30373231..b53724da78 100644 --- a/src/main/java/com/powsybl/openloadflow/equations/PreviousValueVoltageInitializer.java +++ b/src/main/java/com/powsybl/openloadflow/equations/PreviousValueVoltageInitializer.java @@ -11,6 +11,7 @@ import com.powsybl.math.matrix.MatrixFactory; import com.powsybl.openloadflow.network.LfBus; import com.powsybl.openloadflow.network.LfNetwork; +import com.powsybl.openloadflow.network.LfNetworkParameters; /** * @author Geoffroy Jamgotchian @@ -18,7 +19,7 @@ public class PreviousValueVoltageInitializer implements VoltageInitializer { @Override - public void prepare(LfNetwork network, MatrixFactory matrixFactory, Reporter reporter) { + public void prepare(LfNetwork network, LfNetworkParameters networkParameters, MatrixFactory matrixFactory, Reporter reporter) { // nothing to do } diff --git a/src/main/java/com/powsybl/openloadflow/equations/UniformValueVoltageInitializer.java b/src/main/java/com/powsybl/openloadflow/equations/UniformValueVoltageInitializer.java index 6e18037123..05283056e5 100644 --- a/src/main/java/com/powsybl/openloadflow/equations/UniformValueVoltageInitializer.java +++ b/src/main/java/com/powsybl/openloadflow/equations/UniformValueVoltageInitializer.java @@ -10,6 +10,7 @@ import com.powsybl.math.matrix.MatrixFactory; import com.powsybl.openloadflow.network.LfBus; import com.powsybl.openloadflow.network.LfNetwork; +import com.powsybl.openloadflow.network.LfNetworkParameters; /** * @author Geoffroy Jamgotchian @@ -17,7 +18,7 @@ public class UniformValueVoltageInitializer implements VoltageInitializer { @Override - public void prepare(LfNetwork network, MatrixFactory matrixFactory, Reporter reporter) { + public void prepare(LfNetwork network, LfNetworkParameters networkParameters, MatrixFactory matrixFactory, Reporter reporter) { // nothing to do } diff --git a/src/main/java/com/powsybl/openloadflow/equations/VoltageInitializer.java b/src/main/java/com/powsybl/openloadflow/equations/VoltageInitializer.java index 1f7e38f6fa..096f04d344 100644 --- a/src/main/java/com/powsybl/openloadflow/equations/VoltageInitializer.java +++ b/src/main/java/com/powsybl/openloadflow/equations/VoltageInitializer.java @@ -10,13 +10,14 @@ import com.powsybl.math.matrix.MatrixFactory; import com.powsybl.openloadflow.network.LfBus; import com.powsybl.openloadflow.network.LfNetwork; +import com.powsybl.openloadflow.network.LfNetworkParameters; /** * @author Geoffroy Jamgotchian */ public interface VoltageInitializer { - void prepare(LfNetwork network, MatrixFactory matrixFactory, Reporter reporter); + void prepare(LfNetwork network, LfNetworkParameters networkParameters, MatrixFactory matrixFactory, Reporter reporter); double getMagnitude(LfBus bus); diff --git a/src/main/java/com/powsybl/openloadflow/network/LfNetworkParameters.java b/src/main/java/com/powsybl/openloadflow/network/LfNetworkParameters.java index bb44a6985d..51e17f62a9 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfNetworkParameters.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfNetworkParameters.java @@ -35,7 +35,7 @@ public class LfNetworkParameters { private final Set countriesToBalance; - private boolean distributedOnConformLoad; + private final boolean distributedOnConformLoad; private final boolean phaseControl; @@ -45,6 +45,10 @@ public class LfNetworkParameters { private final boolean reactivePowerRemoteControl; + public LfNetworkParameters() { + this(new FirstSlackBusSelector()); + } + public LfNetworkParameters(SlackBusSelector slackBusSelector) { this(slackBusSelector, false, false, false, false, ParameterConstants.PLAUSIBLE_ACTIVE_POWER_LIMIT_DEFAULT_VALUE, false, diff --git a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java index 94ebd9c49d..9e9c95976f 100644 --- a/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sa/AcSecurityAnalysis.java @@ -185,7 +185,7 @@ private PostContingencyResult runPostContingencySimulation(LfNetwork network, Ac LfContingency.deactivateEquations(lfContingency, engine.getEquationSystem(), deactivatedEquations, deactivatedEquationTerms); // restart LF on post contingency equation system - engine.getParameters().setVoltageInitializer(new PreviousValueVoltageInitializer()); + engine.getParameters().getNewtonRaphsonParameters().setVoltageInitializer(new PreviousValueVoltageInitializer()); AcLoadFlowResult postContingencyLoadFlowResult = engine.run(Reporter.NO_OP); boolean postContingencyComputationOk = postContingencyLoadFlowResult.getNewtonRaphsonStatus() == NewtonRaphsonStatus.CONVERGED; Map, LimitViolation> postContingencyLimitViolations = new LinkedHashMap<>(); diff --git a/src/main/java/com/powsybl/openloadflow/sensi/AcSensitivityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sensi/AcSensitivityAnalysis.java index ed08c17998..a4fb9766b6 100644 --- a/src/main/java/com/powsybl/openloadflow/sensi/AcSensitivityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sensi/AcSensitivityAnalysis.java @@ -122,7 +122,7 @@ private void calculatePostContingencySensitivityValues(List createJacobianMatrix(LfNe return new JacobianMatrix<>(equationSystem, matrixFactory); } + private static DcLoadFlowParameters createDcLoadFlowParameters(SlackBusSelector slackBusSelector, MatrixFactory matrixFactory, + LoadFlowParameters lfParameters, OpenLoadFlowParameters lfParametersExt) { + var networkParameters = new LfNetworkParameters(slackBusSelector, + false, + false, + false, + false, + lfParametersExt.getPlausibleActivePowerLimit(), + lfParametersExt.isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds(), + true, + lfParameters.getCountriesToBalance(), + lfParameters.isDistributedSlack() && lfParameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD, + false, + false, + false, + false); + + var equationSystemCreationParameters = new DcEquationSystemCreationParameters(true, + true, + true, + lfParameters.isDcUseTransformerRatio()); + + return new DcLoadFlowParameters(networkParameters, + equationSystemCreationParameters, + matrixFactory, + lfParameters.isDistributedSlack(), + lfParameters.getBalanceType(), + true); + } + public void analyse(Network network, List contingencies, List variableSets, LoadFlowParameters lfParameters, OpenLoadFlowParameters lfParametersExt, SensitivityFactorReader factorReader, SensitivityValueWriter valueWriter, Reporter reporter) { @@ -732,16 +762,12 @@ public void analyse(Network network, List contingencies, LOGGER.info("Running DC sensitivity analysis with {} factors and {} contingencies", lfFactors.size(), contingencies.size()); - // create DC load flow engine for setting the function reference - DcLoadFlowParameters dcLoadFlowParameters = new DcLoadFlowParameters(slackBusSelector, matrixFactory, - true, lfParameters.isDcUseTransformerRatio(), lfParameters.isDistributedSlack(), lfParameters.getBalanceType(), true, - lfParametersExt.getPlausibleActivePowerLimit(), lfParametersExt.isAddRatioToLinesWithDifferentNominalVoltageAtBothEnds(), true, true, lfParameters.getCountriesToBalance()); + var dcLoadFlowParameters = createDcLoadFlowParameters(slackBusSelector, matrixFactory, lfParameters, lfParametersExt); + DcLoadFlowEngine dcLoadFlowEngine = new DcLoadFlowEngine(lfNetworks, dcLoadFlowParameters); // create DC equation system for sensitivity analysis - DcEquationSystemCreationParameters dcEquationSystemCreationParameters = new DcEquationSystemCreationParameters(dcLoadFlowParameters.isUpdateFlows(), true, - dcLoadFlowParameters.isForcePhaseControlOffAndAddAngle1Var(), lfParameters.isDcUseTransformerRatio()); - EquationSystem equationSystem = DcEquationSystem.create(lfNetwork, new VariableSet<>(), dcEquationSystemCreationParameters); + EquationSystem equationSystem = DcEquationSystem.create(lfNetwork, new VariableSet<>(), dcLoadFlowParameters.getEquationSystemCreationParameters()); writeSkippedFactors(lfFactors, valueWriter); diff --git a/src/test/java/com/powsybl/openloadflow/ac/NonImpedantBranchWithBreakerIssueTest.java b/src/test/java/com/powsybl/openloadflow/ac/NonImpedantBranchWithBreakerIssueTest.java index afffce167c..76d74f826f 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/NonImpedantBranchWithBreakerIssueTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/NonImpedantBranchWithBreakerIssueTest.java @@ -9,7 +9,8 @@ import com.powsybl.iidm.network.Bus; import com.powsybl.iidm.network.Network; import com.powsybl.math.matrix.DenseMatrixFactory; -import com.powsybl.openloadflow.ac.nr.DefaultNewtonRaphsonStoppingCriteria; +import com.powsybl.openloadflow.ac.equations.AcEquationSystemCreationParameters; +import com.powsybl.openloadflow.ac.nr.NewtonRaphsonParameters; import com.powsybl.openloadflow.ac.outerloop.AcLoadFlowParameters; import com.powsybl.openloadflow.ac.outerloop.AcloadFlowEngine; import com.powsybl.openloadflow.equations.UniformValueVoltageInitializer; @@ -39,10 +40,13 @@ void busBreakerAndNonImpedantBranchIssue() { LfNetworkParameters networkParameters = new LfNetworkParameters(slackBusSelector, false, false, false, breakers, ParameterConstants.PLAUSIBLE_ACTIVE_POWER_LIMIT_DEFAULT_VALUE, false, true, Collections.emptySet(), false, false, false, false, false); + AcEquationSystemCreationParameters equationSystemCreationParameters = new AcEquationSystemCreationParameters(false, Collections.emptySet()); + NewtonRaphsonParameters newtonRaphsonParameters = new NewtonRaphsonParameters() + .setVoltageInitializer(new UniformValueVoltageInitializer()); LfNetwork lfNetwork = LfNetwork.load(network, networkParameters).get(0); - AcLoadFlowParameters acLoadFlowParameters = new AcLoadFlowParameters(slackBusSelector, new UniformValueVoltageInitializer(), new DefaultNewtonRaphsonStoppingCriteria(), - Collections.emptyList(), new DenseMatrixFactory(), false, false, false, false, false, breakers, ParameterConstants.PLAUSIBLE_ACTIVE_POWER_LIMIT_DEFAULT_VALUE, - false, true, Collections.emptySet(), true, Collections.emptySet(), false, false, false); + AcLoadFlowParameters acLoadFlowParameters = new AcLoadFlowParameters(networkParameters, equationSystemCreationParameters, + newtonRaphsonParameters, Collections.emptyList(), + new DenseMatrixFactory()); new AcloadFlowEngine(lfNetwork, acLoadFlowParameters) .run(); lfNetwork.updateState(false, false, false, false, false, false); @@ -63,9 +67,12 @@ void busBreakerAndNonImpedantBranchIssueRef() { ParameterConstants.PLAUSIBLE_ACTIVE_POWER_LIMIT_DEFAULT_VALUE, false, true, Collections.emptySet(), false, false, false, false, false); LfNetwork lfNetwork = LfNetwork.load(network, networkParameters).get(0); - AcLoadFlowParameters acLoadFlowParameters = new AcLoadFlowParameters(slackBusSelector, new UniformValueVoltageInitializer(), new DefaultNewtonRaphsonStoppingCriteria(), - Collections.emptyList(), new DenseMatrixFactory(), false, false, false, false, false, breakers, ParameterConstants.PLAUSIBLE_ACTIVE_POWER_LIMIT_DEFAULT_VALUE, - false, true, Collections.emptySet(), true, Collections.emptySet(), false, false, false); + AcEquationSystemCreationParameters equationSystemCreationParameters = new AcEquationSystemCreationParameters(false, Collections.emptySet()); + NewtonRaphsonParameters newtonRaphsonParameters = new NewtonRaphsonParameters() + .setVoltageInitializer(new UniformValueVoltageInitializer()); + AcLoadFlowParameters acLoadFlowParameters = new AcLoadFlowParameters(networkParameters, equationSystemCreationParameters, + newtonRaphsonParameters, Collections.emptyList(), + new DenseMatrixFactory()); new AcloadFlowEngine(lfNetwork, acLoadFlowParameters) .run(); lfNetwork.updateState(false, false, false, false, false, false);