diff --git a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java index 33418ac76c..c7acd0b87e 100644 --- a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java +++ b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowParameters.java @@ -101,6 +101,8 @@ public class OpenLoadFlowParameters extends AbstractExtension SPECIFIC_PARAMETERS_NAMES = List.of(SLACK_BUS_SELECTION_PARAM_NAME, SLACK_BUSES_IDS_PARAM_NAME, LOW_IMPEDANCE_BRANCH_MODE_PARAM_NAME, @@ -120,7 +122,8 @@ public class OpenLoadFlowParameters extends AbstractExtension properties) { .ifPresent(prop -> this.setMaxRealisticVoltage(Double.parseDouble(prop))); Optional.ofNullable(properties.get(REACTIVE_RANGE_CHECK_MODE_NAME)) .ifPresent(prop -> this.setReactiveRangeCheckMode(ReactiveRangeCheckMode.valueOf(prop))); + Optional.ofNullable(properties.get(LOW_IMPEDANCE_THRESHOLD_NAME)) + .ifPresent(prop -> this.setLowImpedanceThreshold(Double.parseDouble(prop))); return this; } @@ -486,6 +506,7 @@ public String toString() { ", minRealisticVoltage=" + minRealisticVoltage + ", maxRealisticVoltage=" + maxRealisticVoltage + ", reactiveRangeCheckMode=" + reactiveRangeCheckMode + + ", lowImpedanceThreshold=" + lowImpedanceThreshold + ')'; } @@ -573,10 +594,10 @@ static VoltageInitializer getExtendedVoltageInitializer(LoadFlowParameters param return getVoltageInitializer(parameters, networkParameters, matrixFactory, reporter); case VOLTAGE_MAGNITUDE: - return new VoltageMagnitudeInitializer(parameters.isTransformerVoltageControlOn(), matrixFactory); + return new VoltageMagnitudeInitializer(parameters.isTransformerVoltageControlOn(), matrixFactory, networkParameters.getLowImpedanceThreshold()); case FULL_VOLTAGE: - return new FullVoltageInitializer(new VoltageMagnitudeInitializer(parameters.isTransformerVoltageControlOn(), matrixFactory), + return new FullVoltageInitializer(new VoltageMagnitudeInitializer(parameters.isTransformerVoltageControlOn(), matrixFactory, networkParameters.getLowImpedanceThreshold()), new DcValueVoltageInitializer(networkParameters, parameters.isDistributedSlack(), parameters.getBalanceType(), @@ -613,7 +634,8 @@ static LfNetworkParameters getNetworkParameters(LoadFlowParameters parameters, O .setHvdcAcEmulation(parameters.isHvdcAcEmulation()) .setMinPlausibleTargetVoltage(parametersExt.getMinPlausibleTargetVoltage()) .setMaxPlausibleTargetVoltage(parametersExt.getMaxPlausibleTargetVoltage()) - .setReactiveRangeCheckMode(parametersExt.getReactiveRangeCheckMode()); + .setReactiveRangeCheckMode(parametersExt.getReactiveRangeCheckMode()) + .setLowImpedanceThreshold(parametersExt.getLowImpedanceThreshold()); } public static AcLoadFlowParameters createAcParameters(Network network, LoadFlowParameters parameters, OpenLoadFlowParameters parametersExt, @@ -696,7 +718,8 @@ public static DcLoadFlowParameters createDcParameters(LoadFlowParameters paramet .setHvdcAcEmulation(false) // FIXME .setMinPlausibleTargetVoltage(parametersExt.getMinPlausibleTargetVoltage()) .setMaxPlausibleTargetVoltage(parametersExt.getMaxPlausibleTargetVoltage()) - .setReactiveRangeCheckMode(ReactiveRangeCheckMode.MAX); // not useful for DC. + .setReactiveRangeCheckMode(ReactiveRangeCheckMode.MAX) // not useful for DC. + .setLowImpedanceThreshold(parametersExt.getLowImpedanceThreshold()); var equationSystemCreationParameters = new DcEquationSystemCreationParameters(true, false, diff --git a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java index c2bd424725..453e2c88b3 100644 --- a/src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java +++ b/src/main/java/com/powsybl/openloadflow/OpenLoadFlowProvider.java @@ -33,6 +33,7 @@ import com.powsybl.openloadflow.network.LfBranch; import com.powsybl.openloadflow.network.LfBus; import com.powsybl.openloadflow.network.LfNetwork; +import com.powsybl.openloadflow.network.LfNetworkParameters; import com.powsybl.openloadflow.network.impl.LfNetworkLoaderImpl; import com.powsybl.openloadflow.network.impl.Networks; import com.powsybl.openloadflow.util.*; @@ -127,7 +128,7 @@ private LoadFlowResult runAc(Network network, LoadFlowParameters parameters, Rep parameters.isDistributedSlack() && (parameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_LOAD || parameters.getBalanceType() == LoadFlowParameters.BalanceType.PROPORTIONAL_TO_CONFORM_LOAD) && parametersExt.isLoadPowerFactorConstant(), parameters.isDc()); // zero or low impedance branch flows computation - computeZeroImpedanceFlows(result.getNetwork(), parameters.isDc()); + computeZeroImpedanceFlows(result.getNetwork(), parameters.isDc(), parametersExt.getLowImpedanceThreshold()); } LoadFlowResult.ComponentResult.Status status; @@ -159,11 +160,11 @@ private LoadFlowResult runAc(Network network, LoadFlowParameters parameters, Rep return new LoadFlowResultImpl(ok, Collections.emptyMap(), null, componentResults); } - private void computeZeroImpedanceFlows(LfNetwork network, boolean dc) { - Graph zeroImpedanceSubGraph = network.createZeroImpedanceSubGraph(dc); + private void computeZeroImpedanceFlows(LfNetwork network, boolean dc, double lowImpedanceThreshold) { + Graph zeroImpedanceSubGraph = network.createZeroImpedanceSubGraph(dc, lowImpedanceThreshold); if (!zeroImpedanceSubGraph.vertexSet().isEmpty()) { SpanningTreeAlgorithm.SpanningTree spanningTree = new KruskalMinimumSpanningTree<>(zeroImpedanceSubGraph).getSpanningTree(); - new ZeroImpedanceFlows(zeroImpedanceSubGraph, spanningTree).compute(dc); + new ZeroImpedanceFlows(zeroImpedanceSubGraph, spanningTree).compute(dc, lowImpedanceThreshold); } } @@ -178,18 +179,19 @@ private LoadFlowResult runDc(Network network, LoadFlowParameters parameters, Rep Networks.resetState(network); - List componentsResult = results.stream().map(r -> processResult(network, r, parameters)).collect(Collectors.toList()); + List componentsResult = results.stream().map(r -> processResult(network, r, parameters, dcParameters.getNetworkParameters())).collect(Collectors.toList()); boolean ok = results.stream().anyMatch(r -> r.getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED); return new LoadFlowResultImpl(ok, Collections.emptyMap(), null, componentsResult); } - private LoadFlowResult.ComponentResult processResult(Network network, DcLoadFlowResult pResult, LoadFlowParameters parameters) { - if (pResult.getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED && parameters.isWriteSlackBus()) { + private LoadFlowResult.ComponentResult processResult(Network network, DcLoadFlowResult result, LoadFlowParameters parameters, + LfNetworkParameters networkParameters) { + if (result.getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED && parameters.isWriteSlackBus()) { SlackTerminal.reset(network); } - if (pResult.getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED) { - pResult.getNetwork().updateState(false, + if (result.getStatus() == LoadFlowResult.ComponentResult.Status.CONVERGED) { + result.getNetwork().updateState(false, parameters.isWriteSlackBus(), parameters.isPhaseShifterRegulationOn(), parameters.isTransformerVoltageControlOn(), @@ -197,16 +199,16 @@ private LoadFlowResult.ComponentResult processResult(Network network, DcLoadFlow false, true); // zero or low impedance branch flows computation - computeZeroImpedanceFlows(pResult.getNetwork(), true); + computeZeroImpedanceFlows(result.getNetwork(), true, networkParameters.getLowImpedanceThreshold()); } return new LoadFlowResultImpl.ComponentResultImpl( - pResult.getNetwork().getNumCC(), - pResult.getNetwork().getNumSC(), - pResult.getStatus(), + result.getNetwork().getNumCC(), + result.getNetwork().getNumSC(), + result.getStatus(), 0, - pResult.getNetwork().getSlackBus().getId(), - pResult.getSlackBusActivePowerMismatch() * PerUnit.SB, + result.getNetwork().getSlackBus().getId(), + result.getSlackBusActivePowerMismatch() * PerUnit.SB, Double.NaN); } diff --git a/src/main/java/com/powsybl/openloadflow/ac/VoltageMagnitudeInitializer.java b/src/main/java/com/powsybl/openloadflow/ac/VoltageMagnitudeInitializer.java index 9310c597ca..572dc34b12 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/VoltageMagnitudeInitializer.java +++ b/src/main/java/com/powsybl/openloadflow/ac/VoltageMagnitudeInitializer.java @@ -34,6 +34,8 @@ public class VoltageMagnitudeInitializer implements VoltageInitializer { private static final Logger LOGGER = LoggerFactory.getLogger(VoltageMagnitudeInitializer.class); + private final double lowImpedanceThreshold; + public enum InitVmEquationType implements Quantity { BUS_TARGET_V("v", ElementType.BUS), BUS_ZERO("bus_z", ElementType.BUS); @@ -87,7 +89,7 @@ public static final class InitVmBusEquationTerm extends AbstractBusEquationTerm< private final TDoubleArrayList der; - public InitVmBusEquationTerm(LfBus bus, VariableSet variableSet) { + public InitVmBusEquationTerm(LfBus bus, VariableSet variableSet, double lowImpedanceThreshold) { super(bus); Map> neighbors = bus.findNeighbors(); @@ -108,7 +110,7 @@ public InitVmBusEquationTerm(LfBus bus, VariableSet variable double r = 0; for (LfBranch neighborBranch : neighborBranches) { PiModel piModel = neighborBranch.getPiModel(); - double x = Math.max(Math.abs(piModel.getX()), LfBranch.LOW_IMPEDANCE_THRESHOLD); // to void issue with negative reactances + double x = Math.max(Math.abs(piModel.getX()), lowImpedanceThreshold); // to avoid issues with negative reactances b += 1 / x; r += neighborBranch.getBus1() == bus ? 1 / piModel.getR1() : piModel.getR1(); } @@ -157,9 +159,10 @@ protected String getName() { private final MatrixFactory matrixFactory; - public VoltageMagnitudeInitializer(boolean transformerVoltageControlOn, MatrixFactory matrixFactory) { + public VoltageMagnitudeInitializer(boolean transformerVoltageControlOn, MatrixFactory matrixFactory, double lowImpedanceThreshold) { this.transformerVoltageControlOn = transformerVoltageControlOn; this.matrixFactory = Objects.requireNonNull(matrixFactory); + this.lowImpedanceThreshold = lowImpedanceThreshold; } private static void initTarget(Equation equation, LfNetwork network, double[] targets) { @@ -202,7 +205,7 @@ public void prepare(LfNetwork network) { .addTerm(v); } else { equationSystem.createEquation(bus.getNum(), InitVmEquationType.BUS_ZERO) - .addTerm(new InitVmBusEquationTerm(bus, equationSystem.getVariableSet())) + .addTerm(new InitVmBusEquationTerm(bus, equationSystem.getVariableSet(), lowImpedanceThreshold)) .addTerm(v.minus()); } } 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 934d1e6ef0..666c261686 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystem.java @@ -25,7 +25,8 @@ private AcEquationSystem() { private static void createBusEquation(LfBus bus, EquationSystem equationSystem, - AcEquationSystemCreationParameters creationParameters) { + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { var p = equationSystem.createEquation(bus, AcEquationType.BUS_TARGET_P); bus.setP(p); var q = equationSystem.createEquation(bus, AcEquationType.BUS_TARGET_Q); @@ -38,7 +39,7 @@ private static void createBusEquation(LfBus bus, p.setActive(false); } - createGeneratorControlEquations(bus, equationSystem, creationParameters); + createGeneratorControlEquations(bus, equationSystem, creationParameters, lowImpedanceThreshold); createShuntEquations(bus, equationSystem); @@ -59,22 +60,24 @@ private static void createBusEquation(LfBus bus, private static void createBusesEquations(LfNetwork network, EquationSystem equationSystem, - AcEquationSystemCreationParameters creationParameters) { + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { for (LfBus bus : network.getBuses()) { - createBusEquation(bus, equationSystem, creationParameters); + createBusEquation(bus, equationSystem, creationParameters, lowImpedanceThreshold); } } private static void createGeneratorControlEquations(LfBus bus, EquationSystem equationSystem, - AcEquationSystemCreationParameters creationParameters) { + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { bus.getVoltageControl() .ifPresent(voltageControl -> { if (bus.isVoltageControlled()) { if (voltageControl.isVoltageControlLocal()) { - createLocalVoltageControlEquation(bus, equationSystem, creationParameters); + createLocalVoltageControlEquation(bus, equationSystem, creationParameters, lowImpedanceThreshold); } else { - createRemoteVoltageControlEquations(voltageControl, equationSystem, creationParameters); + createRemoteVoltageControlEquations(voltageControl, equationSystem, creationParameters, lowImpedanceThreshold); } updateGeneratorVoltageControl(voltageControl, equationSystem); } @@ -83,7 +86,8 @@ private static void createGeneratorControlEquations(LfBus bus, private static void createLocalVoltageControlEquation(LfBus bus, EquationSystem equationSystem, - AcEquationSystemCreationParameters creationParameters) { + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { EquationTerm vTerm = equationSystem.getVariable(bus.getNum(), AcVariableType.BUS_V) .createTerm(); bus.setCalculatedV(vTerm); @@ -96,7 +100,7 @@ private static void createLocalVoltageControlEquation(LfBus bus, // which is modeled here with: V + slope * (sum_branch qBranch) = TargetV - slope * qLoads + slope * qGenerators equationSystem.createEquation(bus, AcEquationType.BUS_TARGET_V_WITH_SLOPE) .addTerm(vTerm) - .addTerms(createReactiveTerms(bus, equationSystem.getVariableSet(), creationParameters) + .addTerms(createReactiveTerms(bus, equationSystem.getVariableSet(), creationParameters, lowImpedanceThreshold) .stream() .map(term -> term.multiply(slope)) .collect(Collectors.toList())); @@ -153,7 +157,8 @@ private static void createShuntEquations(LfBus bus, EquationSystem equationSystem, - AcEquationSystemCreationParameters creationParameters) { + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { LfBus controlledBus = voltageControl.getControlledBus(); // create voltage equation at voltage controlled bus @@ -173,12 +178,12 @@ private static void createRemoteVoltageControlEquations(VoltageControl voltageCo // which can be rewritten in a more simple way // 0 = (qPercent_i - 1) * q_i + qPercent_i * sum_j(q_j) where j are all the voltage controller buses except i Equation zero = equationSystem.createEquation(controllerBus, AcEquationType.DISTR_Q) - .addTerms(createReactiveTerms(controllerBus, equationSystem.getVariableSet(), creationParameters).stream() + .addTerms(createReactiveTerms(controllerBus, equationSystem.getVariableSet(), creationParameters, lowImpedanceThreshold).stream() .map(term -> term.multiply(() -> controllerBus.getRemoteVoltageControlReactivePercent() - 1)) .collect(Collectors.toList())); for (LfBus otherControllerBus : voltageControl.getControllerBuses()) { if (otherControllerBus != controllerBus) { - zero.addTerms(createReactiveTerms(otherControllerBus, equationSystem.getVariableSet(), creationParameters).stream() + zero.addTerms(createReactiveTerms(otherControllerBus, equationSystem.getVariableSet(), creationParameters, lowImpedanceThreshold).stream() .map(term -> term.multiply(controllerBus::getRemoteVoltageControlReactivePercent)) .collect(Collectors.toList())); } @@ -243,11 +248,13 @@ static void updateRemoteVoltageControlEquations(VoltageControl voltageControl, E } private static List> createReactiveTerms(LfBus controllerBus, - VariableSet variableSet, AcEquationSystemCreationParameters creationParameters) { + VariableSet variableSet, + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { List> terms = new ArrayList<>(); for (LfBranch branch : controllerBus.getBranches()) { EquationTerm q; - if (branch.isZeroImpedanceBranch(false)) { + if (branch.isZeroImpedanceBranch(false, lowImpedanceThreshold)) { if (!branch.isSpanningTreeEdge()) { continue; } @@ -736,10 +743,11 @@ private static void createHvdcAcEmulationEquations(LfHvdc hvdc, EquationSystem equationSystem, - AcEquationSystemCreationParameters creationParameters) { + EquationSystem equationSystem, + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { // create zero and non zero impedance branch equations - if (branch.isZeroImpedanceBranch(false)) { + if (branch.isZeroImpedanceBranch(false, lowImpedanceThreshold)) { if (branch.isSpanningTreeEdge()) { createNonImpedantBranch(branch, branch.getBus1(), branch.getBus2(), equationSystem); } @@ -750,25 +758,27 @@ private static void createBranchEquations(LfBranch branch, private static void createBranchesEquations(LfNetwork network, EquationSystem equationSystem, - AcEquationSystemCreationParameters creationParameters) { + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { for (LfBranch branch : network.getBranches()) { - createBranchEquations(branch, equationSystem, creationParameters); + createBranchEquations(branch, equationSystem, creationParameters, lowImpedanceThreshold); } } public static EquationSystem create(LfNetwork network) { - return create(network, new AcEquationSystemCreationParameters()); + return create(network, new AcEquationSystemCreationParameters(), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); } public static EquationSystem create(LfNetwork network, - AcEquationSystemCreationParameters creationParameters) { + AcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { Objects.requireNonNull(network); Objects.requireNonNull(creationParameters); EquationSystem equationSystem = new EquationSystem<>(true); - createBusesEquations(network, equationSystem, creationParameters); - createBranchesEquations(network, equationSystem, creationParameters); + createBusesEquations(network, equationSystem, creationParameters, lowImpedanceThreshold); + createBranchesEquations(network, equationSystem, creationParameters, lowImpedanceThreshold); for (LfHvdc hvdc : network.getHvdcs()) { createHvdcAcEmulationEquations(hvdc, equationSystem); @@ -776,7 +786,7 @@ public static EquationSystem create(LfNetwork ne EquationSystemPostProcessor.findAll().forEach(pp -> pp.onCreate(equationSystem)); - network.addListener(new AcEquationSystemUpdater(equationSystem)); + network.addListener(new AcEquationSystemUpdater(equationSystem, lowImpedanceThreshold)); return equationSystem; } 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 72d3ea70d6..e8a9fc2288 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java +++ b/src/main/java/com/powsybl/openloadflow/ac/equations/AcEquationSystemUpdater.java @@ -19,8 +19,11 @@ public class AcEquationSystemUpdater extends AbstractLfNetworkListener { private final EquationSystem equationSystem; - public AcEquationSystemUpdater(EquationSystem equationSystem) { + private final double lowImpedanceThreshold; + + public AcEquationSystemUpdater(EquationSystem equationSystem, double lowImpedanceThreshold) { this.equationSystem = Objects.requireNonNull(equationSystem); + this.lowImpedanceThreshold = lowImpedanceThreshold; } @Override @@ -45,7 +48,7 @@ public void onShuntVoltageControlChange(LfShunt controllerShunt, boolean newVolt } private void updateElementEquations(LfElement element, boolean enable) { - if (element instanceof LfBranch && ((LfBranch) element).isZeroImpedanceBranch(false)) { + if (element instanceof LfBranch && ((LfBranch) element).isZeroImpedanceBranch(false, lowImpedanceThreshold)) { LfBranch branch = (LfBranch) element; if (branch.isSpanningTreeEdge()) { // depending on the switch status, we activate either v1 = v2, ph1 = ph2 equations diff --git a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcLoadFlowContext.java b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcLoadFlowContext.java index 3fae7b87d5..7df9bad98b 100644 --- a/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcLoadFlowContext.java +++ b/src/main/java/com/powsybl/openloadflow/ac/outerloop/AcLoadFlowContext.java @@ -49,7 +49,8 @@ public AcLoadFlowParameters getParameters() { public EquationSystem getEquationSystem() { if (equationSystem == null) { - equationSystem = AcEquationSystem.create(network, parameters.getEquationSystemCreationParameters()); + equationSystem = AcEquationSystem.create(network, parameters.getEquationSystemCreationParameters(), + parameters.getNetworkParameters().getLowImpedanceThreshold()); } return equationSystem; } diff --git a/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java b/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java index 88bbab5bc0..317245e6f4 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java +++ b/src/main/java/com/powsybl/openloadflow/dc/DcLoadFlowEngine.java @@ -66,7 +66,8 @@ public List run(Reporter reporter) { } private DcLoadFlowResult run(Reporter reporter, LfNetwork network) { - EquationSystem equationSystem = DcEquationSystem.create(network, parameters.getEquationSystemCreationParameters()); + EquationSystem equationSystem = DcEquationSystem.create(network, parameters.getEquationSystemCreationParameters(), + parameters.getNetworkParameters().getLowImpedanceThreshold()); 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/equations/DcEquationSystem.java b/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystem.java index 7bbbc6c3a7..fee553af74 100644 --- a/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystem.java +++ b/src/main/java/com/powsybl/openloadflow/dc/equations/DcEquationSystem.java @@ -106,13 +106,13 @@ private static void createImpedantBranch(EquationSystem equationSystem, - DcEquationSystemCreationParameters creationParameters) { + DcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { List nonImpedantBranches = new ArrayList<>(); - for (LfBranch branch : network.getBranches()) { LfBus bus1 = branch.getBus1(); LfBus bus2 = branch.getBus2(); - if (branch.isZeroImpedanceBranch(true)) { + if (branch.isZeroImpedanceBranch(true, lowImpedanceThreshold)) { if (bus1 != null && bus2 != null) { nonImpedantBranches.add(branch); } @@ -137,11 +137,12 @@ private static void createBranches(LfNetwork network, EquationSystem create(LfNetwork network, DcEquationSystemCreationParameters creationParameters) { + public static EquationSystem create(LfNetwork network, DcEquationSystemCreationParameters creationParameters, + double lowImpedanceThreshold) { EquationSystem equationSystem = new EquationSystem<>(creationParameters.isIndexTerms()); createBuses(network, equationSystem); - createBranches(network, equationSystem, creationParameters); + createBranches(network, equationSystem, creationParameters, lowImpedanceThreshold); EquationSystemPostProcessor.findAll().forEach(pp -> pp.onCreate(equationSystem)); diff --git a/src/main/java/com/powsybl/openloadflow/network/LfBranch.java b/src/main/java/com/powsybl/openloadflow/network/LfBranch.java index 120d89697d..9708edc832 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfBranch.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfBranch.java @@ -21,8 +21,6 @@ */ public interface LfBranch extends LfElement { - double LOW_IMPEDANCE_THRESHOLD = Math.pow(10, -8); // in per unit - enum BranchType { LINE, TRANSFO_2, @@ -141,7 +139,7 @@ default List getLimits2(LimitType type) { double computeApparentPower2(); - boolean isZeroImpedanceBranch(boolean dc); + boolean isZeroImpedanceBranch(boolean dc, double lowImpedanceThreshold); void setSpanningTreeEdge(boolean spanningTreeEdge); @@ -176,5 +174,5 @@ static double getDiscretePhaseControlTarget(LfBranch branch, DiscretePhaseContro boolean isConnectedAtBothSides(); - void setMinZ(boolean dc); + void setMinZ(boolean dc, double lowImpedanceThreshold); } diff --git a/src/main/java/com/powsybl/openloadflow/network/LfNetwork.java b/src/main/java/com/powsybl/openloadflow/network/LfNetwork.java index 1febf6fa31..8a22611a23 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfNetwork.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfNetwork.java @@ -451,10 +451,10 @@ public void reportBalance(Reporter reporter) { this, activeGeneration, activeLoad, reactiveGeneration, reactiveLoad); } - public void fix(boolean minImpedance, boolean dc) { + public void fix(boolean minImpedance, boolean dc, double lowImpedanceThreshold) { if (minImpedance) { for (LfBranch branch : branches) { - branch.setMinZ(dc); + branch.setMinZ(dc, lowImpedanceThreshold); } } } @@ -500,7 +500,7 @@ public static List load(T network, LfNetworkLoader networkLoad List lfNetworks = networkLoader.load(network, parameters, reporter); for (LfNetwork lfNetwork : lfNetworks) { Reporter reporterNetwork = Reports.createPostLoadingProcessingReporter(lfNetwork.getReporter()); - lfNetwork.fix(parameters.isMinImpedance(), parameters.isDc()); + lfNetwork.fix(parameters.isMinImpedance(), parameters.isDc(), parameters.getLowImpedanceThreshold()); lfNetwork.validate(parameters.isDc(), reporterNetwork); if (lfNetwork.isValid()) { lfNetwork.reportSize(reporterNetwork); @@ -517,8 +517,8 @@ public static List load(T network, LfNetworkLoader networkLoad * The graph is intentionally not cached as a parameter so far, to avoid the complexity of invalidating it if changes occur * @return the zero-impedance subgraph */ - public Graph createZeroImpedanceSubGraph(boolean dc) { - return createSubGraph(branch -> branch.isZeroImpedanceBranch(dc) + public Graph createZeroImpedanceSubGraph(boolean dc, double lowImpedanceThreshold) { + return createSubGraph(branch -> branch.isZeroImpedanceBranch(dc, lowImpedanceThreshold) && branch.getBus1() != null && branch.getBus2() != null); } diff --git a/src/main/java/com/powsybl/openloadflow/network/LfNetworkParameters.java b/src/main/java/com/powsybl/openloadflow/network/LfNetworkParameters.java index d3ad23298f..667b6af53b 100644 --- a/src/main/java/com/powsybl/openloadflow/network/LfNetworkParameters.java +++ b/src/main/java/com/powsybl/openloadflow/network/LfNetworkParameters.java @@ -6,6 +6,7 @@ */ package com.powsybl.openloadflow.network; +import com.powsybl.commons.PowsyblException; import com.powsybl.iidm.network.Country; import com.powsybl.openloadflow.OpenLoadFlowParameters; import com.powsybl.openloadflow.graph.EvenShiloachGraphDecrementalConnectivityFactory; @@ -29,6 +30,8 @@ public class LfNetworkParameters { public static final double MAX_PLAUSIBLE_TARGET_VOLTAGE_DEFAULT_VALUE = 1.2; + public static final double LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE = Math.pow(10, -8); // in per unit + public static final OpenLoadFlowParameters.ReactiveRangeCheckMode REACTIVE_RANGE_CHECK_MODE_DEFAULT_VALUE = OpenLoadFlowParameters.ReactiveRangeCheckMode.MAX; private SlackBusSelector slackBusSelector = new FirstSlackBusSelector(); @@ -75,6 +78,8 @@ public class LfNetworkParameters { private OpenLoadFlowParameters.ReactiveRangeCheckMode reactiveRangeCheckMode = REACTIVE_RANGE_CHECK_MODE_DEFAULT_VALUE; + private double lowImpedanceThreshold = LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE; + public SlackBusSelector getSlackBusSelector() { return slackBusSelector; } @@ -255,6 +260,18 @@ public LfNetworkParameters setMaxPlausibleTargetVoltage(double maxPlausibleTarge return this; } + public double getLowImpedanceThreshold() { + return lowImpedanceThreshold; + } + + public LfNetworkParameters setLowImpedanceThreshold(double lowImpedanceThreshold) { + if (lowImpedanceThreshold <= 0) { + throw new PowsyblException("lowImpedanceThreshold must be greater than 0"); + } + this.lowImpedanceThreshold = lowImpedanceThreshold; + return this; + } + public OpenLoadFlowParameters.ReactiveRangeCheckMode getReactiveRangeCheckMode() { return reactiveRangeCheckMode; } @@ -297,6 +314,7 @@ public String toString() { ", maxPlausibleTargetVoltage=" + maxPlausibleTargetVoltage + ", loaderPostProcessorSelection=" + loaderPostProcessorSelection + ", reactiveRangeCheckMode=" + reactiveRangeCheckMode + + ", lowImpedanceThreshold=" + lowImpedanceThreshold + ')'; } } diff --git a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBranch.java b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBranch.java index 8715e6ee35..9161caee22 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBranch.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/AbstractLfBranch.java @@ -244,11 +244,11 @@ public double computeApparentPower2() { } @Override - public boolean isZeroImpedanceBranch(boolean dc) { + public boolean isZeroImpedanceBranch(boolean dc, double lowImpedanceThreshold) { if (dc) { - return FastMath.abs(piModel.getX()) < LOW_IMPEDANCE_THRESHOLD; + return FastMath.abs(piModel.getX()) < lowImpedanceThreshold; } else { - return piModel.getZ() < LOW_IMPEDANCE_THRESHOLD; + return piModel.getZ() < lowImpedanceThreshold; } } @@ -287,9 +287,9 @@ public boolean isConnectedAtBothSides() { } @Override - public void setMinZ(boolean dc) { - if (piModel.setMinZ(LOW_IMPEDANCE_THRESHOLD, dc)) { - LOGGER.trace("Branch {} has a low impedance, set to min {}", getId(), LOW_IMPEDANCE_THRESHOLD); + public void setMinZ(boolean dc, double lowImpedanceThreshold) { + if (piModel.setMinZ(lowImpedanceThreshold, dc)) { + LOGGER.trace("Branch {} has a low impedance, set to min {}", getId(), lowImpedanceThreshold); } } } 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 fc6b51acfe..bfe85b976b 100644 --- a/src/main/java/com/powsybl/openloadflow/network/impl/LfNetworkLoaderImpl.java +++ b/src/main/java/com/powsybl/openloadflow/network/impl/LfNetworkLoaderImpl.java @@ -316,13 +316,13 @@ public void visitHvdcConverterStation(HvdcConverterStation converterStation) return lfBus; } - private static void addBranch(LfNetwork lfNetwork, LfBranch lfBranch, LfNetworkLoadingReport report, boolean dc) { + private static void addBranch(LfNetwork lfNetwork, LfBranch lfBranch, LfNetworkLoadingReport report, boolean dc, double lowImpedanceThreshold) { boolean connectedToSameBus = lfBranch.getBus1() == lfBranch.getBus2(); if (connectedToSameBus) { LOGGER.trace("Discard branch '{}' because connected to same bus at both ends", lfBranch.getId()); report.branchesDiscardedBecauseConnectedToSameBusAtBothEnds++; } else { - if (lfBranch.isZeroImpedanceBranch(dc)) { + if (lfBranch.isZeroImpedanceBranch(dc, lowImpedanceThreshold)) { LOGGER.trace("Branch {} is non impedant", lfBranch.getId()); report.nonImpedantBranches++; } @@ -336,7 +336,7 @@ private static void createBranches(List lfBuses, LfNetwork lfNetwork, Loa LfBus lfBus1 = getLfBus(branch.getTerminal1(), lfNetwork, parameters.isBreakers()); LfBus lfBus2 = getLfBus(branch.getTerminal2(), lfNetwork, parameters.isBreakers()); LfBranchImpl lfBranch = LfBranchImpl.create(branch, lfNetwork, lfBus1, lfBus2, parameters.isTwtSplitShuntAdmittance()); - addBranch(lfNetwork, lfBranch, report, parameters.isDc()); + addBranch(lfNetwork, lfBranch, report, parameters.isDc(), parameters.getLowImpedanceThreshold()); postProcessors.forEach(pp -> pp.onBranchAdded(branch, lfBranch)); } @@ -347,7 +347,7 @@ private static void createBranches(List lfBuses, LfNetwork lfNetwork, Loa lfBuses.add(lfBus2); LfBus lfBus1 = getLfBus(danglingLine.getTerminal(), lfNetwork, parameters.isBreakers()); LfBranch lfBranch = LfDanglingLineBranch.create(danglingLine, lfNetwork, lfBus1, lfBus2); - addBranch(lfNetwork, lfBranch, report, parameters.isDc()); + addBranch(lfNetwork, lfBranch, report, parameters.isDc(), parameters.getLowImpedanceThreshold()); postProcessors.forEach(pp -> { pp.onBusAdded(danglingLine, lfBus2); pp.onBranchAdded(danglingLine, lfBranch); @@ -363,9 +363,9 @@ private static void createBranches(List lfBuses, LfNetwork lfNetwork, Loa LfLegBranch lfBranch1 = LfLegBranch.create(lfNetwork, lfBus1, lfBus0, t3wt, t3wt.getLeg1(), parameters.isTwtSplitShuntAdmittance()); LfLegBranch lfBranch2 = LfLegBranch.create(lfNetwork, lfBus2, lfBus0, t3wt, t3wt.getLeg2(), parameters.isTwtSplitShuntAdmittance()); LfLegBranch lfBranch3 = LfLegBranch.create(lfNetwork, lfBus3, lfBus0, t3wt, t3wt.getLeg3(), parameters.isTwtSplitShuntAdmittance()); - addBranch(lfNetwork, lfBranch1, report, parameters.isDc()); - addBranch(lfNetwork, lfBranch2, report, parameters.isDc()); - addBranch(lfNetwork, lfBranch3, report, parameters.isDc()); + addBranch(lfNetwork, lfBranch1, report, parameters.isDc(), parameters.getLowImpedanceThreshold()); + addBranch(lfNetwork, lfBranch2, report, parameters.isDc(), parameters.getLowImpedanceThreshold()); + addBranch(lfNetwork, lfBranch3, report, parameters.isDc(), parameters.getLowImpedanceThreshold()); postProcessors.forEach(pp -> { pp.onBusAdded(t3wt, lfBus0); pp.onBranchAdded(t3wt, lfBranch1); @@ -432,7 +432,7 @@ private static void createTransformersVoltageControls(LfNetwork lfNetwork, boole } private static void createSwitches(List switches, LfNetwork lfNetwork, List postProcessors, - LfNetworkLoadingReport report, boolean dc) { + LfNetworkLoadingReport report, boolean dc, double lowImpedanceThreshold) { if (switches != null) { for (Switch sw : switches) { VoltageLevel vl = sw.getVoltageLevel(); @@ -441,18 +441,18 @@ private static void createSwitches(List switches, LfNetwork lfNetwork, L LfBus lfBus1 = lfNetwork.getBusById(bus1.getId()); LfBus lfBus2 = lfNetwork.getBusById(bus2.getId()); LfSwitch lfSwitch = new LfSwitch(lfNetwork, lfBus1, lfBus2, sw); - addBranch(lfNetwork, lfSwitch, report, dc); + addBranch(lfNetwork, lfSwitch, report, dc, lowImpedanceThreshold); postProcessors.forEach(pp -> pp.onBranchAdded(sw, lfSwitch)); } } } private static void fixAllVoltageControls(LfNetwork lfNetwork, boolean minImpedance, boolean transformerVoltageControl, - boolean dc) { + boolean dc, double lowImpedanceThreshold) { // If min impedance is set, there is no zero-impedance branch if (!minImpedance) { // Merge the discrete voltage control in each zero impedance connected set - List> connectedSets = new ConnectivityInspector<>(lfNetwork.createZeroImpedanceSubGraph(dc)).connectedSets(); + List> connectedSets = new ConnectivityInspector<>(lfNetwork.createZeroImpedanceSubGraph(dc, lowImpedanceThreshold)).connectedSets(); connectedSets.forEach(connectedSet -> mergeVoltageControls(connectedSet, transformerVoltageControl)); } } @@ -746,18 +746,18 @@ private LfNetwork create(int numCC, int numSC, List buses, List swi } if (parameters.isBreakers()) { - createSwitches(switches, lfNetwork, postProcessors, report, parameters.isDc()); + createSwitches(switches, lfNetwork, postProcessors, report, parameters.isDc(), parameters.getLowImpedanceThreshold()); } if (!parameters.isDc()) { // Fixing voltage controls need to be done after creating switches, as the zero-impedance graph is changed with switches fixAllVoltageControls(lfNetwork, parameters.isMinImpedance(), parameters.isTransformerVoltageControl(), - parameters.isDc()); + parameters.isDc(), parameters.getLowImpedanceThreshold()); } if (!parameters.isMinImpedance()) { // create zero impedance equations only on minimum spanning forest calculated from zero impedance sub graph - Graph zeroImpedanceSubGraph = lfNetwork.createZeroImpedanceSubGraph(parameters.isDc()); + Graph zeroImpedanceSubGraph = lfNetwork.createZeroImpedanceSubGraph(parameters.isDc(), parameters.getLowImpedanceThreshold()); if (!zeroImpedanceSubGraph.vertexSet().isEmpty()) { SpanningTreeAlgorithm.SpanningTree spanningTree = new KruskalMinimumSpanningTree<>(zeroImpedanceSubGraph).getSpanningTree(); for (LfBranch branch : spanningTree.getEdges()) { diff --git a/src/main/java/com/powsybl/openloadflow/network/util/ZeroImpedanceFlows.java b/src/main/java/com/powsybl/openloadflow/network/util/ZeroImpedanceFlows.java index d81d0b8ce1..079b51c67d 100644 --- a/src/main/java/com/powsybl/openloadflow/network/util/ZeroImpedanceFlows.java +++ b/src/main/java/com/powsybl/openloadflow/network/util/ZeroImpedanceFlows.java @@ -35,7 +35,7 @@ public ZeroImpedanceFlows(Graph zeroImpedanceSubGraph, Spanning this.tree = spanningTree; } - public void compute(boolean dc) { + public void compute(boolean dc, double lowImpedanceThreshold) { Set processed = new HashSet<>(); graph.vertexSet().forEach(lfBus -> { @@ -43,7 +43,7 @@ public void compute(boolean dc) { return; } TreeByLevels treeByLevels = new TreeByLevels(graph, tree, lfBus); - treeByLevels.updateFlows(dc); + treeByLevels.updateFlows(dc, lowImpedanceThreshold); processed.addAll(treeByLevels.getProcessedLfBuses()); }); @@ -104,7 +104,7 @@ private static LfBus getOtherSideBus(LfBranch branch, LfBus bus) { return branch.getBus1().equals(bus) ? branch.getBus2() : branch.getBus1(); } - private void updateFlows(boolean dc) { + private void updateFlows(boolean dc, double lowImpedanceThreshold) { Map descendantZeroImpedanceFlow = new HashMap<>(); // traverse the tree from leaves to root @@ -112,7 +112,7 @@ private void updateFlows(boolean dc) { int level = levels.size() - 1; while (level >= 1) { levels.get(level).forEach(bus -> { - PQ balance = balanceWithImpedance(bus, dc); + PQ balance = balanceWithImpedance(bus, dc, lowImpedanceThreshold); PQ z0flow = getDescendantZeroImpedanceFlow(descendantZeroImpedanceFlow, bus); PQ branchFlow = balance.add(z0flow); @@ -124,7 +124,7 @@ private void updateFlows(boolean dc) { } } - private PQ balanceWithImpedance(LfBus bus, boolean dc) { + private PQ balanceWithImpedance(LfBus bus, boolean dc, double lowImpedanceThreshold) { // balance considering injections and flow from lines with impedance // take care of the sign @@ -132,7 +132,7 @@ private PQ balanceWithImpedance(LfBus bus, boolean dc) { // only lines with impedance List adjacentBranchesWithImpedance = bus.getBranches().stream() - .filter(branch -> !branch.isZeroImpedanceBranch(dc)).collect(Collectors.toList()); + .filter(branch -> !branch.isZeroImpedanceBranch(dc, lowImpedanceThreshold)).collect(Collectors.toList()); adjacentBranchesWithImpedance.forEach(branch -> { PQ branchFlow = getBranchFlow(branch, bus); diff --git a/src/main/java/com/powsybl/openloadflow/sensi/DcSensitivityAnalysis.java b/src/main/java/com/powsybl/openloadflow/sensi/DcSensitivityAnalysis.java index 426ad48e33..833fe355ab 100644 --- a/src/main/java/com/powsybl/openloadflow/sensi/DcSensitivityAnalysis.java +++ b/src/main/java/com/powsybl/openloadflow/sensi/DcSensitivityAnalysis.java @@ -832,7 +832,8 @@ public void analyse(Network network, List contingencies, var dcLoadFlowParameters = createDcLoadFlowParameters(lfNetworkParameters, matrixFactory, lfParameters); // create DC equation system for sensitivity analysis - EquationSystem equationSystem = DcEquationSystem.create(lfNetwork, dcLoadFlowParameters.getEquationSystemCreationParameters()); + EquationSystem equationSystem = DcEquationSystem.create(lfNetwork, dcLoadFlowParameters.getEquationSystemCreationParameters(), + dcLoadFlowParameters.getNetworkParameters().getLowImpedanceThreshold()); // next we only work with valid factors var validFactorHolder = writeInvalidFactors(allFactorHolder, resultWriter); diff --git a/src/test/java/com/powsybl/openloadflow/FullVoltageInitializerTest.java b/src/test/java/com/powsybl/openloadflow/FullVoltageInitializerTest.java index bca05d0c57..1309078600 100644 --- a/src/test/java/com/powsybl/openloadflow/FullVoltageInitializerTest.java +++ b/src/test/java/com/powsybl/openloadflow/FullVoltageInitializerTest.java @@ -34,7 +34,7 @@ void testEsgTuto1() { SlackBusSelector slackBusSelector = new FirstSlackBusSelector(); LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), slackBusSelector).get(0); MatrixFactory matrixFactory = new DenseMatrixFactory(); - FullVoltageInitializer initializer = new FullVoltageInitializer(new VoltageMagnitudeInitializer(false, matrixFactory), + FullVoltageInitializer initializer = new FullVoltageInitializer(new VoltageMagnitudeInitializer(false, matrixFactory, LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE), new DcValueVoltageInitializer(new LfNetworkParameters().setSlackBusSelector(slackBusSelector), false, LoadFlowParameters.BalanceType.PROPORTIONAL_TO_GENERATION_P_MAX, diff --git a/src/test/java/com/powsybl/openloadflow/OpenLoadFlowParametersTest.java b/src/test/java/com/powsybl/openloadflow/OpenLoadFlowParametersTest.java index bc23d03281..d3f3daf019 100644 --- a/src/test/java/com/powsybl/openloadflow/OpenLoadFlowParametersTest.java +++ b/src/test/java/com/powsybl/openloadflow/OpenLoadFlowParametersTest.java @@ -210,6 +210,19 @@ void testPlausibleTargetVoltage() { assertEquals(30.0, network.getGenerator("GEN").getRegulatingTerminal().getBusView().getBus().getV(), DELTA_MISMATCH); } + @Test + void testLowImpedanceThreshold() throws IOException { + Path cfgDir = Files.createDirectory(fileSystem.getPath("config")); + Path cfgFile = cfgDir.resolve("configLowImpedanceThreshold.yml"); + + Files.copy(getClass().getResourceAsStream("/configLowImpedanceThreshold.yml"), cfgFile); + PlatformConfig platformConfig = new PlatformConfig(new YamlModuleConfigRepository(cfgFile), cfgDir); + + LoadFlowParameters parameters = LoadFlowParameters.load(platformConfig); + OpenLoadFlowParameters olfParameters = parameters.getExtension(OpenLoadFlowParameters.class); + assertEquals(1.0E-2, olfParameters.getLowImpedanceThreshold()); + } + @Test void testUpdateParameters() { Map parametersMap = new HashMap<>(); diff --git a/src/test/java/com/powsybl/openloadflow/OpenLoadFlowProviderTest.java b/src/test/java/com/powsybl/openloadflow/OpenLoadFlowProviderTest.java index cbb58e19e8..d7994922c4 100644 --- a/src/test/java/com/powsybl/openloadflow/OpenLoadFlowProviderTest.java +++ b/src/test/java/com/powsybl/openloadflow/OpenLoadFlowProviderTest.java @@ -50,7 +50,7 @@ void test() { void testDcParameters() { Network network = Mockito.mock(Network.class); DcLoadFlowParameters dcParameters = OpenLoadFlowParameters.createDcParameters(network, new LoadFlowParameters().setReadSlackBus(true), new OpenLoadFlowParameters(), new DenseMatrixFactory(), new EvenShiloachGraphDecrementalConnectivityFactory<>(), true); - assertEquals("DcLoadFlowParameters(networkParameters=LfNetworkParameters(slackBusSelector=NetworkSlackBusSelector, connectivityFactory=EvenShiloachGraphDecrementalConnectivityFactory, generatorVoltageRemoteControl=false, minImpedance=false, twtSplitShuntAdmittance=false, breakers=false, plausibleActivePowerLimit=5000.0, computeMainConnectedComponentOnly=true, countriesToBalance=[], distributedOnConformLoad=false, phaseControl=false, transformerVoltageControl=false, voltagePerReactivePowerControl=false, reactivePowerRemoteControl=false, dc=true, reactiveLimits=false, hvdcAcEmulation=false, minPlausibleTargetVoltage=0.8, maxPlausibleTargetVoltage=1.2, loaderPostProcessorSelection=[], reactiveRangeCheckMode=MAX), equationSystemCreationParameters=DcEquationSystemCreationParameters(updateFlows=true, indexTerms=false, forcePhaseControlOffAndAddAngle1Var=true, useTransformerRatio=true), matrixFactory=DenseMatrixFactory, distributedSlack=true, balanceType=PROPORTIONAL_TO_GENERATION_P_MAX, setVToNan=true)", + assertEquals("DcLoadFlowParameters(networkParameters=LfNetworkParameters(slackBusSelector=NetworkSlackBusSelector, connectivityFactory=EvenShiloachGraphDecrementalConnectivityFactory, generatorVoltageRemoteControl=false, minImpedance=false, twtSplitShuntAdmittance=false, breakers=false, plausibleActivePowerLimit=5000.0, computeMainConnectedComponentOnly=true, countriesToBalance=[], distributedOnConformLoad=false, phaseControl=false, transformerVoltageControl=false, voltagePerReactivePowerControl=false, reactivePowerRemoteControl=false, dc=true, reactiveLimits=false, hvdcAcEmulation=false, minPlausibleTargetVoltage=0.8, maxPlausibleTargetVoltage=1.2, loaderPostProcessorSelection=[], reactiveRangeCheckMode=MAX, lowImpedanceThreshold=1.0E-8), equationSystemCreationParameters=DcEquationSystemCreationParameters(updateFlows=true, indexTerms=false, forcePhaseControlOffAndAddAngle1Var=true, useTransformerRatio=true), matrixFactory=DenseMatrixFactory, distributedSlack=true, balanceType=PROPORTIONAL_TO_GENERATION_P_MAX, setVToNan=true)", dcParameters.toString()); } @@ -58,7 +58,7 @@ void testDcParameters() { void testAcParameters() { Network network = Mockito.mock(Network.class); AcLoadFlowParameters acParameters = OpenLoadFlowParameters.createAcParameters(network, new LoadFlowParameters().setReadSlackBus(true), new OpenLoadFlowParameters(), new DenseMatrixFactory(), new EvenShiloachGraphDecrementalConnectivityFactory<>(), Reporter.NO_OP, false, false); - assertEquals("AcLoadFlowParameters(networkParameters=LfNetworkParameters(slackBusSelector=NetworkSlackBusSelector, connectivityFactory=EvenShiloachGraphDecrementalConnectivityFactory, generatorVoltageRemoteControl=true, minImpedance=false, twtSplitShuntAdmittance=false, breakers=false, plausibleActivePowerLimit=5000.0, computeMainConnectedComponentOnly=true, countriesToBalance=[], distributedOnConformLoad=false, phaseControl=false, transformerVoltageControl=false, voltagePerReactivePowerControl=false, reactivePowerRemoteControl=false, dc=false, reactiveLimits=true, hvdcAcEmulation=true, minPlausibleTargetVoltage=0.8, maxPlausibleTargetVoltage=1.2, loaderPostProcessorSelection=[], reactiveRangeCheckMode=MAX), equationSystemCreationParameters=AcEquationSystemCreationParameters(forceA1Var=false), newtonRaphsonParameters=NewtonRaphsonParameters(maxIteration=30, minRealisticVoltage=0.5, maxRealisticVoltage=1.5, stoppingCriteria=DefaultNewtonRaphsonStoppingCriteria), outerLoops=[DistributedSlackOuterLoop, ReactiveLimitsOuterLoop], matrixFactory=DenseMatrixFactory, voltageInitializer=UniformValueVoltageInitializer)", + assertEquals("AcLoadFlowParameters(networkParameters=LfNetworkParameters(slackBusSelector=NetworkSlackBusSelector, connectivityFactory=EvenShiloachGraphDecrementalConnectivityFactory, generatorVoltageRemoteControl=true, minImpedance=false, twtSplitShuntAdmittance=false, breakers=false, plausibleActivePowerLimit=5000.0, computeMainConnectedComponentOnly=true, countriesToBalance=[], distributedOnConformLoad=false, phaseControl=false, transformerVoltageControl=false, voltagePerReactivePowerControl=false, reactivePowerRemoteControl=false, dc=false, reactiveLimits=true, hvdcAcEmulation=true, minPlausibleTargetVoltage=0.8, maxPlausibleTargetVoltage=1.2, loaderPostProcessorSelection=[], reactiveRangeCheckMode=MAX, lowImpedanceThreshold=1.0E-8), equationSystemCreationParameters=AcEquationSystemCreationParameters(forceA1Var=false), newtonRaphsonParameters=NewtonRaphsonParameters(maxIteration=30, minRealisticVoltage=0.5, maxRealisticVoltage=1.5, stoppingCriteria=DefaultNewtonRaphsonStoppingCriteria), outerLoops=[DistributedSlackOuterLoop, ReactiveLimitsOuterLoop], matrixFactory=DenseMatrixFactory, voltageInitializer=UniformValueVoltageInitializer)", acParameters.toString()); } @@ -86,7 +86,7 @@ void testGetExtendedVoltageInitializer() { @Test void specificParametersTest() { OpenLoadFlowProvider provider = new OpenLoadFlowProvider(); - assertEquals(20, provider.getSpecificParametersNames().size()); + assertEquals(21, provider.getSpecificParametersNames().size()); LoadFlowParameters parameters = new LoadFlowParameters(); provider.loadSpecificParameters(Collections.emptyMap()) diff --git a/src/test/java/com/powsybl/openloadflow/ac/VoltageMagnitudeInitializerTest.java b/src/test/java/com/powsybl/openloadflow/ac/VoltageMagnitudeInitializerTest.java index 4d47191bea..8c1bdaf5a9 100644 --- a/src/test/java/com/powsybl/openloadflow/ac/VoltageMagnitudeInitializerTest.java +++ b/src/test/java/com/powsybl/openloadflow/ac/VoltageMagnitudeInitializerTest.java @@ -43,7 +43,7 @@ public static void assertBusVoltage(LfNetwork network, VoltageInitializer initia void testEsgTuto1() { Network network = EurostagTutorialExample1Factory.create(); LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), new FirstSlackBusSelector()).get(0); - VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory()); + VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory(), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); initializer.prepare(lfNetwork); assertBusVoltage(lfNetwork, initializer, "VLGEN_0", 1.020833, 0); assertBusVoltage(lfNetwork, initializer, "VLHV1_0", 1.074561, 0); @@ -55,7 +55,7 @@ void testEsgTuto1() { void testIeee14() { Network network = IeeeCdfNetworkFactory.create14(); LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), new FirstSlackBusSelector()).get(0); - VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory()); + VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory(), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); initializer.prepare(lfNetwork); assertBusVoltage(lfNetwork, initializer, "VL1_0", 1.06, 0); assertBusVoltage(lfNetwork, initializer, "VL2_0", 1.045, 0); @@ -78,7 +78,7 @@ void testZeroImpedanceBranch() { Network network = IeeeCdfNetworkFactory.create14(); network.getLine("L9-14-1").setX(0); LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), new FirstSlackBusSelector()).get(0); - VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory()); + VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory(), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); initializer.prepare(lfNetwork); assertBusVoltage(lfNetwork, initializer, "VL1_0", 1.06, 0); assertBusVoltage(lfNetwork, initializer, "VL2_0", 1.045, 0); @@ -101,7 +101,7 @@ void testZeroImpedanceBranchConnectedToPvBus() { Network network = IeeeCdfNetworkFactory.create14(); network.getLine("L6-11-1").setX(0); LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), new FirstSlackBusSelector()).get(0); - VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory()); + VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory(), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); initializer.prepare(lfNetwork); assertBusVoltage(lfNetwork, initializer, "VL1_0", 1.06, 0); assertBusVoltage(lfNetwork, initializer, "VL2_0", 1.045, 0); @@ -141,7 +141,7 @@ void testParallelBranch() { .setB2(0) .add(); LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), new FirstSlackBusSelector()).get(0); - VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory()); + VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory(), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); initializer.prepare(lfNetwork); assertBusVoltage(lfNetwork, initializer, "VL1_0", 1.06, 0); assertBusVoltage(lfNetwork, initializer, "VL2_0", 1.045, 0); @@ -163,7 +163,7 @@ void testParallelBranch() { void testZeroImpedanceLoop() { Network network = Importers.importData("XIIDM", new ResourceDataSource("init_v_zero_imp_loop", new ResourceSet("/", "init_v_zero_imp_loop.xiidm")), null); LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), new FirstSlackBusSelector()).get(0); - VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory()); + VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(false, new DenseMatrixFactory(), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); initializer.prepare(lfNetwork); assertBusVoltage(lfNetwork, initializer, "B_0", 0.982318, 0); assertBusVoltage(lfNetwork, initializer, "D_0", 0.982318, 0); @@ -197,7 +197,7 @@ void testWithTransformerVoltageControl() { LfNetworkParameters networkParameters = new LfNetworkParameters() .setTransformerVoltageControl(true); LfNetwork lfNetwork = LfNetwork.load(network, new LfNetworkLoaderImpl(), networkParameters).get(0); - VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(true, new DenseMatrixFactory()); + VoltageMagnitudeInitializer initializer = new VoltageMagnitudeInitializer(true, new DenseMatrixFactory(), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); initializer.prepare(lfNetwork); assertBusVoltage(lfNetwork, initializer, "VL1_0", 1.06, 0); assertBusVoltage(lfNetwork, initializer, "VL2_0", 1.045, 0); diff --git a/src/test/java/com/powsybl/openloadflow/dc/DcLoadFlowMatrixTest.java b/src/test/java/com/powsybl/openloadflow/dc/DcLoadFlowMatrixTest.java index f0b9783618..57d3288302 100644 --- a/src/test/java/com/powsybl/openloadflow/dc/DcLoadFlowMatrixTest.java +++ b/src/test/java/com/powsybl/openloadflow/dc/DcLoadFlowMatrixTest.java @@ -20,6 +20,7 @@ import com.powsybl.openloadflow.network.FirstSlackBusSelector; import com.powsybl.openloadflow.network.LfBus; import com.powsybl.openloadflow.network.LfNetwork; +import com.powsybl.openloadflow.network.LfNetworkParameters; import com.powsybl.openloadflow.network.impl.Networks; import com.powsybl.openloadflow.network.util.UniformValueVoltageInitializer; import org.junit.jupiter.api.Test; @@ -58,7 +59,7 @@ void buildDcMatrix() { LfNetwork mainNetwork = lfNetworks.get(0); DcEquationSystemCreationParameters creationParameters = new DcEquationSystemCreationParameters(true, false, false, true); - EquationSystem equationSystem = DcEquationSystem.create(mainNetwork, creationParameters); + EquationSystem equationSystem = DcEquationSystem.create(mainNetwork, creationParameters, LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); for (LfBus b : mainNetwork.getBuses()) { equationSystem.createEquation(b.getNum(), DcEquationType.BUS_TARGET_P); @@ -106,7 +107,7 @@ void buildDcMatrix() { lfNetworks = Networks.load(network, new FirstSlackBusSelector()); mainNetwork = lfNetworks.get(0); - equationSystem = DcEquationSystem.create(mainNetwork, creationParameters); + equationSystem = DcEquationSystem.create(mainNetwork, creationParameters, LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); j = new JacobianMatrix<>(equationSystem, matrixFactory).getMatrix(); diff --git a/src/test/java/com/powsybl/openloadflow/equations/EquationSystemTest.java b/src/test/java/com/powsybl/openloadflow/equations/EquationSystemTest.java index dd84ea46a6..703cdf1ae2 100644 --- a/src/test/java/com/powsybl/openloadflow/equations/EquationSystemTest.java +++ b/src/test/java/com/powsybl/openloadflow/equations/EquationSystemTest.java @@ -173,7 +173,7 @@ void writeDcSystemTest() { List lfNetworks = Networks.load(EurostagTutorialExample1Factory.create(), new FirstSlackBusSelector()); LfNetwork network = lfNetworks.get(0); - EquationSystem equationSystem = DcEquationSystem.create(network, new DcEquationSystemCreationParameters(true, false, false, true)); + EquationSystem equationSystem = DcEquationSystem.create(network, new DcEquationSystemCreationParameters(true, false, false, true), LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); String ref = String.join(System.lineSeparator(), "bus_target_φ0 = φ0", "bus_target_p1 = dc_p_2(φ0, φ1) + dc_p_1(φ1, φ2) + dc_p_1(φ1, φ2)", diff --git a/src/test/java/com/powsybl/openloadflow/network/impl/LfSwitchTest.java b/src/test/java/com/powsybl/openloadflow/network/impl/LfSwitchTest.java index b92d718ed5..db7fb272c6 100644 --- a/src/test/java/com/powsybl/openloadflow/network/impl/LfSwitchTest.java +++ b/src/test/java/com/powsybl/openloadflow/network/impl/LfSwitchTest.java @@ -17,8 +17,8 @@ import com.powsybl.openloadflow.equations.EquationTerm; import com.powsybl.openloadflow.equations.VariableSet; import com.powsybl.openloadflow.graph.EvenShiloachGraphDecrementalConnectivityFactory; -import com.powsybl.openloadflow.network.LfBranch; import com.powsybl.openloadflow.network.LfNetwork; +import com.powsybl.openloadflow.network.LfNetworkParameters; import com.powsybl.openloadflow.network.NodeBreakerNetworkFactory; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -68,7 +68,7 @@ void getterTest() { @Test void setterTest() { - lfSwitch.getPiModel().setX(LfBranch.LOW_IMPEDANCE_THRESHOLD); //FIXME + lfSwitch.getPiModel().setX(LfNetworkParameters.LOW_IMPEDANCE_THRESHOLD_DEFAULT_VALUE); VariableSet variableSet = new VariableSet<>(); EquationTerm p1 = new ClosedBranchSide1ActiveFlowEquationTerm(lfSwitch, lfSwitch.getBus1(), lfSwitch.getBus2(), variableSet, false, false); diff --git a/src/test/resources/configLowImpedanceThreshold.yml b/src/test/resources/configLowImpedanceThreshold.yml new file mode 100644 index 0000000000..e7a157c7a0 --- /dev/null +++ b/src/test/resources/configLowImpedanceThreshold.yml @@ -0,0 +1,2 @@ +open-loadflow-default-parameters: + lowImpedanceThreshold: 1.0E-2 diff --git a/src/test/resources/debug-parameters.json b/src/test/resources/debug-parameters.json index 6666d7aadc..47e57a0bd8 100644 --- a/src/test/resources/debug-parameters.json +++ b/src/test/resources/debug-parameters.json @@ -36,6 +36,7 @@ "maxPlausibleTargetVoltage" : 1.2, "minRealisticVoltage" : 0.5, "maxRealisticVoltage" : 1.5, + "lowImpedanceThreshold" : 1.0E-8, "reactiveRangeCheckMode" : "MAX" } }