com.farao_community.farao.data.crac_impl.AbstractRemedialAction Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of farao-crac-impl Show documentation
Show all versions of farao-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.farao_community.farao.data.crac_impl;
import com.farao_community.farao.data.crac_api.Instant;
import com.farao_community.farao.data.crac_api.RemedialAction;
import com.farao_community.farao.data.crac_api.State;
import com.farao_community.farao.data.crac_api.cnec.Cnec;
import com.farao_community.farao.data.crac_api.cnec.FlowCnec;
import com.farao_community.farao.data.crac_api.usage_rule.*;
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 List usageRules;
protected Integer speed = null;
protected AbstractRemedialAction(String id, String name, String operator, List usageRules, Integer speed) {
super(id, name);
this.operator = operator;
this.usageRules = usageRules;
this.speed = speed;
}
protected AbstractRemedialAction(String id, String name, String operator, List usageRules) {
super(id, name);
this.operator = operator;
this.usageRules = usageRules;
}
void addUsageRule(UsageRule usageRule) {
this.usageRules.add(usageRule);
}
@Override
public OnContingencyStateAdderToRemedialAction newOnStateUsageRule() {
return new OnStateAdderToRemedialActionImpl(this);
}
@Override
public String getOperator() {
return operator;
}
@Override
public final List getUsageRules() {
return usageRules;
}
@Override
public Optional getSpeed() {
return Optional.ofNullable(speed);
}
@Override
public UsageMethod getUsageMethod(State state) {
Set usageMethods = usageRules.stream()
.map(usageRule -> usageRule.getUsageMethod(state))
.collect(Collectors.toSet());
if (usageMethods.contains(UsageMethod.UNAVAILABLE)) {
return UsageMethod.UNAVAILABLE;
} else if (usageMethods.contains(UsageMethod.AVAILABLE)) {
return UsageMethod.AVAILABLE;
} else if (usageMethods.contains(UsageMethod.TO_BE_EVALUATED)) {
return UsageMethod.TO_BE_EVALUATED;
} else if (usageMethods.contains(UsageMethod.FORCED)) {
return UsageMethod.FORCED;
} else {
return UsageMethod.UNAVAILABLE;
}
}
/**
* Evaluates if the remedial action is available depending on its UsageMethod.
* If TO_BE_EVALUATED condition has not been evaluated, default behavior is false
*/
@Override
public boolean isRemedialActionAvailable(State state) {
return isRemedialActionAvailable(state, false);
}
/**
* Evaluates if the remedial action is available depending on its UsageMethod.
* When UsageMethod is TO_BE_EVALUATED, condition has to have been evaluated previously
*/
@Override
public boolean isRemedialActionAvailable(State state, boolean evaluatedCondition) {
switch (getUsageMethod(state)) {
case AVAILABLE:
return true;
case TO_BE_EVALUATED:
return evaluatedCondition;
default:
return false;
}
}
/**
* Retrieves cnecs associated to the remedial action's OnFlowConstraint and OnFlowConstraintInCountry usage rules.
*/
public Set getFlowCnecsConstrainingUsageRules(Set perimeterCnecs, Network network, State optimizedState) {
Set toBeConsideredCnecs = new HashSet<>();
// OnFlowConstraint
List onFlowConstraintUsageRules = getUsageRules().stream().filter(OnFlowConstraint.class::isInstance).map(OnFlowConstraint.class::cast)
.filter(ofc -> ofc.getUsageMethod(optimizedState).equals(UsageMethod.TO_BE_EVALUATED)).collect(Collectors.toList());
onFlowConstraintUsageRules.forEach(onFlowConstraint -> toBeConsideredCnecs.add(onFlowConstraint.getFlowCnec()));
// OnFlowConstraintInCountry
List onFlowConstraintInCountryUsageRules = getUsageRules().stream().filter(OnFlowConstraintInCountry.class::isInstance).map(OnFlowConstraintInCountry.class::cast)
.filter(ofc -> ofc.getUsageMethod(optimizedState).equals(UsageMethod.TO_BE_EVALUATED)).collect(Collectors.toList());
onFlowConstraintInCountryUsageRules.forEach(onFlowConstraintInCountry -> {
Map> allowedCnecInstantPerRaInstant = Map.of(
Instant.PREVENTIVE, Set.of(Instant.PREVENTIVE, Instant.OUTAGE, Instant.CURATIVE),
Instant.AUTO, Set.of(Instant.AUTO),
Instant.CURATIVE, Set.of(Instant.CURATIVE)
);
toBeConsideredCnecs.addAll(perimeterCnecs.stream()
.filter(cnec -> allowedCnecInstantPerRaInstant.get(onFlowConstraintInCountry.getInstant()).contains(cnec.getState().getInstant()))
.filter(cnec -> isCnecInCountry(cnec, onFlowConstraintInCountry.getCountry(), network))
.collect(Collectors.toSet()));
});
return toBeConsideredCnecs;
}
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();
}
}