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

com.powsybl.openrao.searchtreerao.result.impl.FlowResultImpl Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2021, 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.result.impl;

import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.State;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.iidm.network.TwoSides;
import com.powsybl.openrao.data.raoresult.api.ComputationStatus;
import com.powsybl.openrao.searchtreerao.commons.RaoUtil;
import com.powsybl.openrao.searchtreerao.result.api.FlowResult;
import com.powsybl.openrao.sensitivityanalysis.SystematicSensitivityResult;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static java.lang.String.format;

/**
 * @author Joris Mancini {@literal }
 */
public class FlowResultImpl implements FlowResult {
    protected final SystematicSensitivityResult systematicSensitivityResult;
    private final Map> commercialFlows;
    private final Map> ptdfZonalSums;
    private final FlowResult fixedCommercialFlows;
    private final FlowResult fixedPtdfZonalSums;
    private final Map marginMapMW = new ConcurrentHashMap<>();
    private final Map marginMapA = new ConcurrentHashMap<>();

    public FlowResultImpl(SystematicSensitivityResult systematicSensitivityResult,
                          Map> commercialFlows,
                          Map> ptdfZonalSums) {
        this(systematicSensitivityResult, commercialFlows, null, ptdfZonalSums, null);
    }

    public FlowResultImpl(SystematicSensitivityResult systematicSensitivityResult,
                          FlowResult fixedCommercialFlows,
                          FlowResult fixedPtdfZonalSums) {
        this(systematicSensitivityResult, null, fixedCommercialFlows, null, fixedPtdfZonalSums);
    }

    public FlowResultImpl(SystematicSensitivityResult systematicSensitivityResult,
                           Map> commercialFlows,
                           FlowResult fixedCommercialFlows,
                           Map> ptdfZonalSums,
                           FlowResult fixedPtdfZonalSums) {
        this.systematicSensitivityResult = systematicSensitivityResult;
        if (commercialFlows == null && fixedCommercialFlows == null
            || commercialFlows != null && fixedCommercialFlows != null) {
            throw new OpenRaoException("Either commercialFlows or fixedCommercialFlows should be non null");
        }
        if (ptdfZonalSums == null && fixedPtdfZonalSums == null
            || ptdfZonalSums != null && fixedPtdfZonalSums != null) {
            throw new OpenRaoException("Either ptdfZonalSums or fixedPtdfZonalSums should be non null");
        }
        this.commercialFlows = commercialFlows;
        this.ptdfZonalSums = ptdfZonalSums;
        this.fixedCommercialFlows = fixedCommercialFlows;
        this.fixedPtdfZonalSums = fixedPtdfZonalSums;
    }

    @Override
    public double getFlow(FlowCnec flowCnec, TwoSides side, Unit unit) {
        if (unit == Unit.MEGAWATT) {
            return systematicSensitivityResult.getReferenceFlow(flowCnec, side);
        } else if (unit == Unit.AMPERE) {
            double intensity = systematicSensitivityResult.getReferenceIntensity(flowCnec, side);
            if (Double.isNaN(intensity) || Math.abs(intensity) <= 1e-6) {
                return systematicSensitivityResult.getReferenceFlow(flowCnec, side) * RaoUtil.getFlowUnitMultiplier(flowCnec, side, Unit.MEGAWATT, Unit.AMPERE);
            } else {
                return intensity;
            }
        } else {
            throw new OpenRaoException("Unknown unit for flow.");
        }
    }

    @Override
    public double getFlow(FlowCnec flowCnec, TwoSides side, Unit unit, Instant instant) {
        if (unit == Unit.MEGAWATT) {
            return systematicSensitivityResult.getReferenceFlow(flowCnec, side, instant);
        } else if (unit == Unit.AMPERE) {
            double intensity = systematicSensitivityResult.getReferenceIntensity(flowCnec, side, instant);
            if (Double.isNaN(intensity) || Math.abs(intensity) <= 1e-6) {
                return systematicSensitivityResult.getReferenceFlow(flowCnec, side, instant) * RaoUtil.getFlowUnitMultiplier(flowCnec, side, Unit.MEGAWATT, Unit.AMPERE);
            } else {
                return intensity;
            }
        } else {
            throw new OpenRaoException("Unknown unit for flow.");
        }
    }

    @Override
    public double getCommercialFlow(FlowCnec flowCnec, TwoSides side, Unit unit) {
        if (unit != Unit.MEGAWATT) {
            throw new OpenRaoException("Commercial flows only in MW.");
        }
        if (fixedCommercialFlows != null) {
            return fixedCommercialFlows.getCommercialFlow(flowCnec, side, unit);
        } else {
            if (!commercialFlows.containsKey(flowCnec) || !commercialFlows.get(flowCnec).containsKey(side)) {
                throw new OpenRaoException(format("No commercial flow on the CNEC %s on side %s", flowCnec.getName(), side));
            }
            return commercialFlows.get(flowCnec).get(side);
        }
    }

    @Override
    public double getPtdfZonalSum(FlowCnec flowCnec, TwoSides side) {
        if (fixedPtdfZonalSums != null) {
            return fixedPtdfZonalSums.getPtdfZonalSum(flowCnec, side);
        } else {
            if (!ptdfZonalSums.containsKey(flowCnec) || !ptdfZonalSums.get(flowCnec).containsKey(side)) {
                throw new OpenRaoException(format("No PTDF computed on the CNEC %s on side %s", flowCnec.getName(), side));
            }
            return ptdfZonalSums.get(flowCnec).get(side);
        }
    }

    @Override
    public Map> getPtdfZonalSums() {
        if (fixedPtdfZonalSums != null) {
            return fixedPtdfZonalSums.getPtdfZonalSums();
        } else {
            return ptdfZonalSums;
        }
    }

    @Override
    public ComputationStatus getComputationStatus() {
        return convert(systematicSensitivityResult.getStatus());
    }

    @Override
    public ComputationStatus getComputationStatus(State state) {
        return convert(systematicSensitivityResult.getStatus(state));
    }

    private ComputationStatus convert(SystematicSensitivityResult.SensitivityComputationStatus sensiStatus) {
        return switch (sensiStatus) {
            case FAILURE -> ComputationStatus.FAILURE;
            case SUCCESS -> ComputationStatus.DEFAULT;
            case PARTIAL_FAILURE -> ComputationStatus.PARTIAL_FAILURE;
        };
    }

    @Override
    public double getMargin(FlowCnec flowCnec, Unit unit) {
        if (unit.equals(Unit.MEGAWATT)) {
            return checkMarginMapAndGet(flowCnec, unit, marginMapMW);
        } else if (unit.equals(Unit.AMPERE)) {
            return checkMarginMapAndGet(flowCnec, unit, marginMapA);
        } else {
            throw new OpenRaoException(String.format("Wrong unit for flow cnec: %s", unit));
        }
    }

    private double checkMarginMapAndGet(FlowCnec flowCnec, Unit unit, Map marginMap) {
        if (marginMap.containsKey(flowCnec)) {
            return marginMap.get(flowCnec);
        }
        double margin = flowCnec.getMonitoredSides().stream()
            .map(side -> getMargin(flowCnec, side, unit))
            .min(Double::compareTo).orElseThrow();
        marginMap.put(flowCnec, margin);
        return margin;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy