All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.powsybl.openrao.searchtreerao.commons.objectivefunctionevaluator.MnecViolationCostEvaluator Maven / Gradle / Ivy

/*
 * Copyright (c) 2020, 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.searchtreerao.commons.objectivefunctionevaluator;

import com.powsybl.openrao.commons.Unit;
import com.powsybl.contingency.Contingency;
import com.powsybl.openrao.data.cracapi.cnec.Cnec;
import com.powsybl.openrao.data.cracapi.cnec.FlowCnec;
import com.powsybl.openrao.data.raoresultapi.ComputationStatus;
import com.powsybl.openrao.raoapi.parameters.extensions.MnecParametersExtension;
import com.powsybl.openrao.searchtreerao.result.api.FlowResult;
import com.powsybl.openrao.searchtreerao.result.api.RangeActionActivationResult;
import com.powsybl.openrao.searchtreerao.result.api.SensitivityResult;
import org.apache.commons.lang3.tuple.Pair;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * An evaluator that computes the virtual cost resulting from the violation of
 * the MNEC minimum margin soft constraint
 *
 * @author Peter Mitri {@literal }
 */
public class MnecViolationCostEvaluator implements CostEvaluator {
    private final Set flowCnecs;
    private final Unit unit;
    private final FlowResult initialFlowResult;
    private final double mnecAcceptableMarginDecrease;
    private final double mnecViolationCost;

    public MnecViolationCostEvaluator(Set flowCnecs, Unit unit, FlowResult initialFlowResult, MnecParametersExtension mnecParametersExtension) {
        this.flowCnecs = flowCnecs;
        this.unit = unit;
        this.initialFlowResult = initialFlowResult;
        mnecAcceptableMarginDecrease = mnecParametersExtension.getAcceptableMarginDecrease();
        mnecViolationCost = mnecParametersExtension.getViolationCost();
    }

    @Override
    public String getName() {
        return "mnec-cost";
    }

    private double computeCost(FlowResult flowResult, FlowCnec mnec) {
        double initialMargin = initialFlowResult.getMargin(mnec, unit);
        double currentMargin = flowResult.getMargin(mnec, unit);
        return Math.max(0, Math.min(0, initialMargin - mnecAcceptableMarginDecrease) - currentMargin);
    }

    @Override
    public Pair> computeCostAndLimitingElements(FlowResult flowResult, RangeActionActivationResult rangeActionActivationResult, SensitivityResult sensitivityResult, ComputationStatus sensitivityStatus, Set contingenciesToExclude) {
        if (Math.abs(mnecViolationCost) < 1e-10) {
            return Pair.of(0., new ArrayList<>());
        }
        double totalMnecMarginViolation = 0;
        List costlyElements = getCostlyElements(flowResult, contingenciesToExclude);
        for (FlowCnec mnec : costlyElements) {
            Optional contingency = mnec.getState().getContingency();
            if (mnec.isMonitored() && (mnec.getState().getContingency().isEmpty() || contingency.isPresent() && !contingenciesToExclude.contains(contingency.get().getId()))) {
                totalMnecMarginViolation += computeCost(flowResult, mnec);
            }
        }
        return Pair.of(mnecViolationCost * totalMnecMarginViolation, costlyElements);
    }

    @Override
    public Unit getUnit() {
        return unit;
    }

    private List getCostlyElements(FlowResult flowResult, Set contingenciesToExclude) {
        List sortedElements = flowCnecs.stream()
            .filter(cnec -> cnec.getState().getContingency().isEmpty() || !contingenciesToExclude.contains(cnec.getState().getContingency().get().getId()))
            .filter(Cnec::isMonitored)
            .collect(Collectors.toMap(
                Function.identity(),
                cnec -> computeCost(flowResult, cnec)
            ))
            .entrySet().stream()
            .filter(entry -> entry.getValue() != 0)
            .sorted(Comparator.comparingDouble(Map.Entry::getValue))
            .map(Map.Entry::getKey)
            .collect(Collectors.toList());
        Collections.reverse(sortedElements);

        return sortedElements;
    }

    @Override
    public Set getFlowCnecs() {
        return flowCnecs;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy