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

com.powsybl.openrao.searchtreerao.commons.ToolProvider 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.commons;

import com.powsybl.openrao.commons.*;
import com.powsybl.openrao.commons.logs.OpenRaoLoggerProvider;
import com.powsybl.openrao.data.crac.api.Instant;
import com.powsybl.openrao.data.crac.api.cnec.Cnec;
import com.powsybl.openrao.data.crac.api.cnec.FlowCnec;
import com.powsybl.openrao.data.crac.api.rangeaction.RangeAction;
import com.powsybl.openrao.data.crac.loopflowextension.LoopFlowThreshold;
import com.powsybl.openrao.data.refprog.referenceprogram.ReferenceProgram;
import com.powsybl.openrao.loopflowcomputation.LoopFlowComputation;
import com.powsybl.openrao.loopflowcomputation.LoopFlowComputationImpl;
import com.powsybl.openrao.raoapi.RaoInput;
import com.powsybl.openrao.raoapi.parameters.RaoParameters;
import com.powsybl.openrao.raoapi.parameters.extensions.LoopFlowParametersExtension;
import com.powsybl.openrao.raoapi.parameters.extensions.RelativeMarginsParametersExtension;
import com.powsybl.openrao.sensitivityanalysis.AppliedRemedialActions;
import com.powsybl.openrao.sensitivityanalysis.SystematicSensitivityInterface;
import com.powsybl.glsk.commons.ZonalData;
import com.powsybl.glsk.commons.ZonalDataImpl;
import com.powsybl.iidm.network.Country;
import com.powsybl.iidm.network.Network;
import com.powsybl.sensitivity.SensitivityVariableSet;

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

/**
 * @author Joris Mancini {@literal }
 */
public final class ToolProvider {
    private Network network;
    private RaoParameters raoParameters;
    private ReferenceProgram referenceProgram;
    private ZonalData glskProvider;
    private AbsolutePtdfSumsComputation absolutePtdfSumsComputation;
    private LoopFlowComputation loopFlowComputation;

    private ToolProvider() {
        // Should not be used
    }

    public AbsolutePtdfSumsComputation getAbsolutePtdfSumsComputation() {
        return absolutePtdfSumsComputation;
    }

    public LoopFlowComputation getLoopFlowComputation() {
        return loopFlowComputation;
    }

    private boolean hasLoopFlowExtension(FlowCnec cnec) {
        return !Objects.isNull(cnec.getExtension(LoopFlowThreshold.class));
    }

    public Set getLoopFlowCnecs(Set allCnecs) {
        LoopFlowParametersExtension loopFlowParameters = raoParameters.getExtension(LoopFlowParametersExtension.class);
        if (raoParameters.hasExtension(LoopFlowParametersExtension.class) && !loopFlowParameters.getCountries().isEmpty()) {
            return allCnecs.stream()
                .filter(cnec -> hasLoopFlowExtension(cnec) && cnecIsInCountryList(cnec, network, loopFlowParameters.getCountries()))
                .collect(Collectors.toSet());
        } else {
            return allCnecs.stream()
                .filter(this::hasLoopFlowExtension)
                .collect(Collectors.toSet());
        }
    }

    static boolean cnecIsInCountryList(Cnec cnec, Network network, Set loopflowCountries) {
        return cnec.getLocation(network).stream().anyMatch(country -> country.isPresent() && loopflowCountries.contains(country.get()));
    }

    public SystematicSensitivityInterface getSystematicSensitivityInterface(Set cnecs,
                                                                            Set> rangeActions,
                                                                            boolean computePtdfs,
                                                                            boolean computeLoopFlows, Instant outageInstant) {
        return getSystematicSensitivityInterface(cnecs, rangeActions, computePtdfs, computeLoopFlows, null, outageInstant);
    }

    public SystematicSensitivityInterface getSystematicSensitivityInterface(Set cnecs,
                                                                            Set> rangeActions,
                                                                            boolean computePtdfs,
                                                                            boolean computeLoopFlows,
                                                                            AppliedRemedialActions appliedRemedialActions,
                                                                            Instant outageInstant) {

        SystematicSensitivityInterface.SystematicSensitivityInterfaceBuilder builder = SystematicSensitivityInterface.builder()
            .withSensitivityProviderName(raoParameters.getLoadFlowAndSensitivityParameters().getSensitivityProvider())
            .withParameters(raoParameters.getLoadFlowAndSensitivityParameters().getSensitivityWithLoadFlowParameters())
            .withRangeActionSensitivities(rangeActions, cnecs, Collections.singleton(Unit.MEGAWATT))
            .withAppliedRemedialActions(appliedRemedialActions)
            .withOutageInstant(outageInstant);

        if (!raoParameters.getLoadFlowAndSensitivityParameters().getSensitivityWithLoadFlowParameters().getLoadFlowParameters().isDc()) {
            builder.withLoadflow(cnecs, Collections.singleton(Unit.AMPERE));
        }

        if (computePtdfs && computeLoopFlows) {
            Set eic = getEicForObjectiveFunction();
            eic.addAll(getEicForLoopFlows());
            builder.withPtdfSensitivities(getGlskForEic(eic), cnecs, Collections.singleton(Unit.MEGAWATT));
        } else if (computeLoopFlows) {
            Set loopflowCnecs = getLoopFlowCnecs(cnecs);
            builder.withPtdfSensitivities(getGlskForEic(getEicForLoopFlows()), loopflowCnecs, Collections.singleton(Unit.MEGAWATT));
        } else if (computePtdfs) {
            builder.withPtdfSensitivities(getGlskForEic(getEicForObjectiveFunction()), cnecs, Collections.singleton(Unit.MEGAWATT));
        }

        return builder.build();
    }

    Set getEicForObjectiveFunction() {
        if (!raoParameters.hasExtension(RelativeMarginsParametersExtension.class)) {
            throw new OpenRaoException("No relative margins parameters were defined");
        }
        return raoParameters.getExtension(RelativeMarginsParametersExtension.class).getPtdfBoundaries().stream().
            flatMap(boundary -> boundary.getEiCodes().stream()).
            map(EICode::getAreaCode).
            collect(Collectors.toSet());
    }

    Set getEicForLoopFlows() {
        return referenceProgram.getListOfAreas().stream().
            map(EICode::getAreaCode).
            collect(Collectors.toSet());
    }

    ZonalData getGlskForEic(Set listEicCode) {
        Map glskBoundaries = new HashMap<>();

        for (String eiCode : listEicCode) {
            SensitivityVariableSet linearGlsk = glskProvider.getData(eiCode);
            if (Objects.isNull(linearGlsk)) {
                OpenRaoLoggerProvider.TECHNICAL_LOGS.warn("No GLSK found for CountryEICode {}", eiCode);
            } else {
                glskBoundaries.put(eiCode, linearGlsk);
            }
        }

        return new ZonalDataImpl<>(glskBoundaries);
    }

    public static ToolProviderBuilder create() {
        return new ToolProviderBuilder();
    }

    public static final class ToolProviderBuilder {
        private Network network;
        private RaoParameters raoParameters;
        private ReferenceProgram referenceProgram;
        private ZonalData glskProvider;
        private LoopFlowComputation loopFlowComputation;
        private AbsolutePtdfSumsComputation absolutePtdfSumsComputation;

        public ToolProviderBuilder withNetwork(Network network) {
            this.network = network;
            return this;
        }

        public ToolProviderBuilder withRaoParameters(RaoParameters raoParameters) {
            this.raoParameters = raoParameters;
            return this;
        }

        public ToolProviderBuilder withLoopFlowComputation(ReferenceProgram referenceProgram, ZonalData glskProvider, LoopFlowComputation loopFlowComputation) {
            this.referenceProgram = referenceProgram;
            this.glskProvider = glskProvider;
            this.loopFlowComputation = loopFlowComputation;
            return this;
        }

        public ToolProviderBuilder withAbsolutePtdfSumsComputation(ZonalData glskProvider, AbsolutePtdfSumsComputation absolutePtdfSumsComputation) {
            this.glskProvider = glskProvider;
            this.absolutePtdfSumsComputation = absolutePtdfSumsComputation;
            return this;
        }

        public ToolProvider build() {
            Objects.requireNonNull(network);
            Objects.requireNonNull(raoParameters);
            ToolProvider toolProvider = new ToolProvider();
            toolProvider.network = network;
            toolProvider.raoParameters = raoParameters;
            toolProvider.referenceProgram = referenceProgram;
            toolProvider.glskProvider = glskProvider;
            toolProvider.loopFlowComputation = loopFlowComputation;
            toolProvider.absolutePtdfSumsComputation = absolutePtdfSumsComputation;
            return toolProvider;
        }
    }

    public static ToolProvider buildFromRaoInputAndParameters(RaoInput raoInput, RaoParameters raoParameters) {

        ToolProvider.ToolProviderBuilder toolProviderBuilder = ToolProvider.create()
            .withNetwork(raoInput.getNetwork())
            .withRaoParameters(raoParameters);
        if (raoInput.getReferenceProgram() != null) {
            toolProviderBuilder.withLoopFlowComputation(
                raoInput.getReferenceProgram(),
                raoInput.getGlskProvider(),
                new LoopFlowComputationImpl(
                    raoInput.getGlskProvider(),
                    raoInput.getReferenceProgram()
                )
            );
        }
        if (raoParameters.getObjectiveFunctionParameters().getType().relativePositiveMargins()) {
            if (!raoParameters.hasExtension(RelativeMarginsParametersExtension.class)) {
                throw new OpenRaoException("No relative margins parameters were defined with objective function " + raoParameters.getObjectiveFunctionParameters().getType());
            }
            toolProviderBuilder.withAbsolutePtdfSumsComputation(
                raoInput.getGlskProvider(),
                new AbsolutePtdfSumsComputation(
                    raoInput.getGlskProvider(),
                        raoParameters.getExtension(RelativeMarginsParametersExtension.class).getPtdfBoundaries()
                )
            );
        }
        return toolProviderBuilder.build();
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy