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

com.powsybl.openrao.loopflowcomputation.LoopFlowComputationImpl Maven / Gradle / Ivy

There is a newer version: 6.0.2
Show 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.loopflowcomputation;

import com.powsybl.openrao.commons.EICode;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.commons.Unit;
import com.powsybl.glsk.commons.ZonalData;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
import com.powsybl.openrao.data.cracapi.Instant;
import com.powsybl.openrao.data.cracapi.cnec.FlowCnec;
import com.powsybl.openrao.data.refprog.referenceprogram.ReferenceProgram;
import com.powsybl.openrao.sensitivityanalysis.SystematicSensitivityInterface;
import com.powsybl.openrao.sensitivityanalysis.SystematicSensitivityResult;
import com.powsybl.iidm.network.*;
import com.powsybl.sensitivity.SensitivityAnalysisParameters;
import com.powsybl.sensitivity.SensitivityVariableSet;

import java.util.*;
import java.util.stream.Stream;

import static java.util.Objects.requireNonNull;

/**
 * @author Pengbo Wang {@literal }
 * @author Baptiste Seguinot {@literal }
 */
public class LoopFlowComputationImpl implements LoopFlowComputation {
    protected ZonalData glsk;
    protected ReferenceProgram referenceProgram;
    protected Map glskMap;

    public LoopFlowComputationImpl(ZonalData glsk, ReferenceProgram referenceProgram) {
        this.glsk = requireNonNull(glsk, "glskProvider should not be null");
        this.referenceProgram = requireNonNull(referenceProgram, "referenceProgram should not be null");
        this.glskMap = buildRefProgGlskMap();
    }

    @Override
    public LoopFlowResult calculateLoopFlows(Network network, String sensitivityProvider, SensitivityAnalysisParameters sensitivityAnalysisParameters, Set flowCnecs, Instant outageInstant) {
        SystematicSensitivityInterface systematicSensitivityInterface = SystematicSensitivityInterface.builder()
                .withSensitivityProviderName(sensitivityProvider)
                .withParameters(sensitivityAnalysisParameters)
                .withPtdfSensitivities(glsk, flowCnecs, Collections.singleton(Unit.MEGAWATT))
                .withOutageInstant(outageInstant)
                .build();

        SystematicSensitivityResult ptdfsAndRefFlows = systematicSensitivityInterface.run(network);

        return buildLoopFlowsFromReferenceFlowAndPtdf(ptdfsAndRefFlows, flowCnecs, network);
    }

    @Override
    public LoopFlowResult buildLoopFlowsFromReferenceFlowAndPtdf(SystematicSensitivityResult alreadyCalculatedPtdfAndFlows, Set flowCnecs, Network network) {
        LoopFlowResult results = new LoopFlowResult();
        Map isInMainComponentMap = computeIsInMainComponentMap(network);
        for (FlowCnec flowCnec : flowCnecs) {
            flowCnec.getMonitoredSides().forEach(side -> {
                double refFlow = alreadyCalculatedPtdfAndFlows.getReferenceFlow(flowCnec, side);
                double commercialFLow = getGlskStream().filter(entry -> isInMainComponentMap.get(entry.getValue()))
                    .mapToDouble(entry -> alreadyCalculatedPtdfAndFlows.getSensitivityOnFlow(entry.getValue(), flowCnec, side) * referenceProgram.getGlobalNetPosition(entry.getKey()))
                    .sum();
                results.addCnecResult(flowCnec, side, refFlow - commercialFLow, commercialFLow, refFlow);
            });
        }
        return results;
    }

    private Map computeIsInMainComponentMap(Network network) {
        Map map = new HashMap<>();
        glskMap.values().forEach(linearGlsk -> map.putIfAbsent(linearGlsk, isInMainComponent(linearGlsk, network)));
        return map;
    }

    static boolean isInMainComponent(SensitivityVariableSet linearGlsk, Network network) {
        boolean atLeastOneGlskConnected = false;
        for (String glsk : linearGlsk.getVariablesById().keySet()) {
            Injection injection = getInjection(glsk, network);
            if (injection == null) {
                throw new OpenRaoException(String.format("%s is neither a generator nor a load nor a dangling line in the network. It is not a valid GLSK.", glsk));
            }
            // If bus is disconnected, then powsybl returns a null bus
            if (injection.getTerminal().getBusView().getBus() != null && injection.getTerminal().getBusView().getBus().isInMainConnectedComponent()) {
                atLeastOneGlskConnected = true;
            }
        }
        return atLeastOneGlskConnected;
    }

    static Injection getInjection(String injectionId, Network network) {
        Generator generator = network.getGenerator(injectionId);
        if (generator != null) {
            return generator;
        }
        Load load = network.getLoad(injectionId);
        if (load != null) {
            return load;
        }
        return network.getDanglingLine(injectionId);
    }

    protected Stream> getGlskStream() {
        return glskMap.entrySet().stream();
    }

    protected Map buildRefProgGlskMap() {

        Map refProgGlskMap = new HashMap<>();

        for (EICode area : referenceProgram.getListOfAreas()) {
            SensitivityVariableSet glskForArea = glsk.getData(area.getAreaCode());
            if (glskForArea == null) {
                OpenRaoLoggerProvider.BUSINESS_WARNS.warn("No GLSK found for reference area {}", area.getAreaCode());
            } else {
                refProgGlskMap.put(area, glskForArea);
            }
        }
        return refProgGlskMap;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy