-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Connect transformers during generator connection #2989
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,18 +12,30 @@ | |
import com.powsybl.computation.ComputationManager; | ||
import com.powsybl.iidm.modification.topology.NamingStrategy; | ||
import com.powsybl.iidm.modification.util.VoltageRegulationUtils; | ||
import com.powsybl.iidm.network.Bus; | ||
import com.powsybl.iidm.network.Generator; | ||
import com.powsybl.iidm.network.IdentifiableType; | ||
import com.powsybl.iidm.network.Network; | ||
import com.powsybl.iidm.network.Terminal; | ||
import com.powsybl.iidm.network.TwoWindingsTransformer; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
import org.jgrapht.alg.util.Pair; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* @author Olivier Perrin {@literal <olivier.perrin at rte-france.com>} | ||
*/ | ||
public final class ConnectGenerator extends AbstractNetworkModification { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(ConnectGenerator.class); | ||
|
||
private final String generatorId; | ||
|
||
public ConnectGenerator(String generatorId) { | ||
|
@@ -54,5 +66,50 @@ static void connect(Generator g) { | |
VoltageRegulationUtils.getTargetVForRegulatingElement(g.getNetwork(), g.getRegulatingTerminal().getBusView().getBus(), g.getId(), IdentifiableType.GENERATOR) | ||
.ifPresent(g::setTargetV); | ||
} | ||
connectTransformersOfGenerator(g); | ||
} | ||
|
||
/** | ||
* Checks if the generator is connected to the network through transformers and, if it is the case, connect them too. | ||
* If it is not the case, nothing is modified | ||
*/ | ||
private static void connectTransformersOfGenerator(Generator generator) { | ||
Bus genBus = getBus(generator.getTerminal()); | ||
Set<TwoWindingsTransformer> transformers = generator.getTerminal().getVoltageLevel().getTwoWindingsTransformerStream() | ||
.filter(twt -> genBus.equals(getBus(twt.getTerminal1())) || genBus.equals(getBus(twt.getTerminal2()))) | ||
.collect(Collectors.toSet()); | ||
Map<String, Pair<Boolean, Boolean>> twtConnectionInitialState = new HashMap<>(); | ||
transformers.forEach(twt -> { | ||
LOGGER.info("Connecting twoWindingsTransformer {} linked to generator {}", twt.getId(), generator.getId()); | ||
twtConnectionInitialState.put(twt.getId(), Pair.of(twt.getTerminal1().isConnected(), twt.getTerminal2().isConnected())); | ||
twt.getTerminals().forEach(Terminal::connect); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why connecting all transformers? one of them should be enough. Maybe we could add a parameter to the network modification to let the user decide. |
||
}); | ||
// If, even after connecting the transformer, the generator remains disconnected from the main component, we remove the unnecessary transformer connection. | ||
if (!generator.getTerminal().getBusBreakerView().getConnectableBus().isInMainConnectedComponent()) { | ||
revertInitialState(generator, transformers, twtConnectionInitialState); | ||
Comment on lines
+88
to
+89
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should avoid doing something and then revert it. In order to do so you could check beforehand if the two-winding transformers are connected to the main connected component. |
||
} | ||
} | ||
|
||
private static void revertInitialState(Generator generator, Set<TwoWindingsTransformer> transformers, Map<String, Pair<Boolean, Boolean>> twtConnectionInitialState) { | ||
transformers.forEach(twt -> { | ||
LOGGER.info("Generator {} could not be connected to the main component, reset initial status for twoWindingsTransformer {}", generator.getId(), twt.getId()); | ||
Pair<Boolean, Boolean> initialTerminalStatus = twtConnectionInitialState.get(twt.getId()); | ||
applyTerminalStatus(twt.getTerminal1(), initialTerminalStatus.getFirst()); | ||
applyTerminalStatus(twt.getTerminal2(), initialTerminalStatus.getSecond()); | ||
}); | ||
} | ||
|
||
private static void applyTerminalStatus(Terminal terminal, boolean connect) { | ||
if (connect) { | ||
terminal.connect(); | ||
} else { | ||
terminal.disconnect(); | ||
} | ||
|
||
} | ||
|
||
private static Bus getBus(Terminal terminal) { | ||
return terminal.getBusBreakerView().getConnectableBus(); | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -128,8 +128,12 @@ public double scale(Network n, double asked, ScalingParameters parameters) { | |
Terminal t = g.getTerminal(); | ||
if (!t.isConnected()) { | ||
if (parameters.isReconnect()) { | ||
new ConnectGenerator(g.getId()).apply(n); | ||
LOGGER.info("Connecting {}", g.getId()); | ||
if (!connectGeneratorToMainComponent(n, g)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You have to extract more lines in order to reduce the method complexity, it is still at 18 (with a maximum allowed fixed at 15) |
||
// If the generator is still disconnected from main component, we should not change the active power setPoint | ||
LOGGER.info("Generator {} could not be connected, discarded from scaling", g.getId()); | ||
return 0.; | ||
} | ||
|
||
} else { | ||
LOGGER.info("Generator {} is not connected, discarded from scaling", g.getId()); | ||
return 0.; | ||
|
@@ -139,6 +143,7 @@ public double scale(Network n, double asked, ScalingParameters parameters) { | |
double oldTargetP = g.getTargetP(); | ||
double minimumTargetP = minimumTargetP(g); | ||
double maximumTargetP = maximumTargetP(g); | ||
|
||
if (!parameters.isAllowsGeneratorOutOfActivePowerLimits() && (oldTargetP < minimumTargetP || oldTargetP > maximumTargetP)) { | ||
LOGGER.error("Error scaling GeneratorScalable {}: Initial P is not in the range [Pmin, Pmax], skipped", id); | ||
return 0.; | ||
|
@@ -163,6 +168,12 @@ public double scale(Network n, double asked, ScalingParameters parameters) { | |
return done; | ||
} | ||
|
||
private static boolean connectGeneratorToMainComponent(Network n, Generator g) { | ||
LOGGER.info("Connecting {}", g.getId()); | ||
new ConnectGenerator(g.getId()).apply(n); | ||
return g.getTerminal().isConnected() && g.getTerminal().getBusBreakerView().getConnectableBus().isInMainConnectedComponent(); | ||
} | ||
|
||
/** | ||
* Compute the percentage of asked power available for the scale. It takes into account the scaling convention | ||
* specified by the user and the sign of the asked power. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't fully check that the generator is connected to the network through transformers. Indeed,