![JAR search and dependency download from the Maven repository](/logo.png)
com.powsybl.openrao.data.cracimpl.AbstractRemedialAction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of open-rao-crac-impl Show documentation
Show all versions of open-rao-crac-impl Show documentation
Object model for CRAC implementation
/*
* Copyright (c) 2019, RTE (http://www.rte-france.com)
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package com.powsybl.openrao.data.cracimpl;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.data.cracapi.Instant;
import com.powsybl.openrao.data.cracapi.RemedialAction;
import com.powsybl.openrao.data.cracapi.State;
import com.powsybl.openrao.data.cracapi.cnec.Cnec;
import com.powsybl.openrao.data.cracapi.cnec.FlowCnec;
import com.powsybl.openrao.data.cracapi.usagerule.*;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
import java.util.*;
import java.util.stream.Collectors;
/**
* Business object of a group of elementary remedial actions (range or network action).
*
* @author Viktor Terrier {@literal }
*/
public abstract class AbstractRemedialAction> extends AbstractIdentifiable implements RemedialAction {
protected String operator;
protected Set usageRules;
protected Integer speed;
private boolean computedUsageMethods = false;
private Map usageMethodPerState;
private Map usageMethodPerInstant;
protected AbstractRemedialAction(String id, String name, String operator, Set usageRules, Integer speed) {
super(id, name);
this.operator = operator;
this.usageRules = usageRules;
this.speed = speed;
}
void addUsageRule(UsageRule usageRule) {
computedUsageMethods = false;
this.usageRules.add(usageRule);
}
@Override
public OnContingencyStateAdderToRemedialAction newOnStateUsageRule() {
return new OnStateAdderToRemedialActionImpl(this);
}
@Override
public String getOperator() {
return operator;
}
@Override
public final Set getUsageRules() {
return usageRules;
}
@Override
public Optional getSpeed() {
return Optional.ofNullable(speed);
}
@Override
public UsageMethod getUsageMethod(State state) {
if (!computedUsageMethods) {
computeUsageMethodPerStateAndInstant();
computedUsageMethods = true;
}
if (usageMethodPerState.getOrDefault(state, UsageMethod.UNDEFINED).equals(usageMethodPerInstant.getOrDefault(state.getInstant(), UsageMethod.UNDEFINED))) {
return usageMethodPerInstant.getOrDefault(state.getInstant(), UsageMethod.UNDEFINED);
}
return UsageMethod.getStrongestUsageMethod(Set.of(
usageMethodPerState.getOrDefault(state, UsageMethod.UNDEFINED),
usageMethodPerInstant.getOrDefault(state.getInstant(), UsageMethod.UNDEFINED)));
}
private void computeUsageMethodPerStateAndInstant() {
usageMethodPerState = new HashMap<>();
usageMethodPerInstant = new HashMap<>();
for (UsageRule usageRule : usageRules) {
if (usageRule.getInstant().isPreventive()) {
updateMapWithValue(usageMethodPerInstant, usageRule.getInstant(), usageRule.getUsageMethod());
} else if (usageRule instanceof OnConstraint> oc) {
State state = oc.getCnec().getState();
if (usageRule.getInstant().equals(state.getInstant())) {
updateMapWithValue(usageMethodPerState, state, usageRule.getUsageMethod());
}
} else if (usageRule instanceof OnContingencyState ocs) {
State state = ocs.getState();
updateMapWithValue(usageMethodPerState, state, usageRule.getUsageMethod());
} else if (usageRule instanceof OnFlowConstraintInCountry || usageRule instanceof OnInstant) {
updateMapWithValue(usageMethodPerInstant, usageRule.getInstant(), usageRule.getUsageMethod());
} else {
throw new OpenRaoException(String.format("Usage rule of type %s is not implemented yet.", usageRule.getClass().getName()));
}
}
}
private void updateMapWithValue(Map map, Instant key, UsageMethod value) {
if (!map.containsKey(key)) {
map.put(key, value);
} else if (!value.equals(map.get(key))) {
map.put(key, UsageMethod.getStrongestUsageMethod(Set.of(map.get(key), value)));
}
}
private void updateMapWithValue(Map map, State key, UsageMethod value) {
if (!map.containsKey(key)) {
map.put(key, value);
} else if (!value.equals(map.get(key))) {
map.put(key, UsageMethod.getStrongestUsageMethod(Set.of(map.get(key), value)));
}
}
/**
* Retrieves cnecs associated to the remedial action's OnFlowConstraint and OnFlowConstraintInCountry usage rules.
*/
// TODO: move this method to RaoUtil
public Set getFlowCnecsConstrainingUsageRules(Set perimeterCnecs, Network network, State optimizedState) {
Set toBeConsideredCnecs = new HashSet<>();
Set usageRulesOnFlowConstraint = new HashSet<>();
usageRulesOnFlowConstraint.addAll(getUsageRules(OnConstraint.class, optimizedState).stream().filter(onConstraint -> onConstraint.getCnec() instanceof FlowCnec).toList());
usageRulesOnFlowConstraint.addAll(getUsageRules(OnFlowConstraintInCountry.class, optimizedState));
usageRulesOnFlowConstraint.forEach(usageRule -> toBeConsideredCnecs.addAll(getFlowCnecsConstrainingForOneUsageRule(usageRule, perimeterCnecs, network)));
return toBeConsideredCnecs;
}
// TODO: move this method to RaoUtil
public Set getFlowCnecsConstrainingForOneUsageRule(UsageRule usageRule, Set perimeterCnecs, Network network) {
if (usageRule instanceof OnConstraint> onConstraint && onConstraint.getCnec() instanceof FlowCnec flowCnec) {
return Set.of(flowCnec);
} else if (usageRule instanceof OnFlowConstraintInCountry onFlowConstraintInCountry) {
return perimeterCnecs.stream()
.filter(cnec -> !cnec.getState().getInstant().comesBefore(usageRule.getInstant()))
.filter(cnec -> onFlowConstraintInCountry.getContingency().isEmpty() || onFlowConstraintInCountry.getContingency().equals(cnec.getState().getContingency()))
.filter(cnec -> isCnecInCountry(cnec, onFlowConstraintInCountry.getCountry(), network)).collect(Collectors.toSet());
} else {
throw new OpenRaoException(String.format("This method should only be used for Ofc Usage rules not for this type of UsageRule: %s", usageRule.getClass().getName()));
}
}
private List getUsageRules(Class usageRuleClass, State state) {
return getUsageRules().stream().filter(usageRuleClass::isInstance).map(usageRuleClass::cast)
.filter(ofc -> state.getInstant().isAuto() ?
ofc.getUsageMethod(state).equals(UsageMethod.FORCED) :
ofc.getUsageMethod(state).equals(UsageMethod.AVAILABLE) || ofc.getUsageMethod(state).equals(UsageMethod.FORCED))
.toList();
}
private static boolean isCnecInCountry(Cnec> cnec, Country country, Network network) {
return cnec.getLocation(network).stream()
.filter(Optional::isPresent)
.map(Optional::get)
.anyMatch(cnecCountry -> cnecCountry.equals(country));
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AbstractRemedialAction> remedialAction = (AbstractRemedialAction>) o;
return super.equals(remedialAction)
&& new HashSet<>(usageRules).equals(new HashSet<>(remedialAction.getUsageRules()))
&& (operator != null && operator.equals(remedialAction.operator) || operator == null && remedialAction.operator == null);
}
@Override
public int hashCode() {
return super.hashCode();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy