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

com.farao_community.farao.dichotomy.api.DichotomyEngine 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.farao_community.farao.dichotomy.api;

import com.farao_community.farao.dichotomy.api.exceptions.DichotomyException;
import com.farao_community.farao.dichotomy.api.exceptions.GlskLimitationException;
import com.farao_community.farao.dichotomy.api.exceptions.RaoInterruptionException;
import com.farao_community.farao.dichotomy.api.exceptions.ShiftingException;
import com.farao_community.farao.dichotomy.api.exceptions.ValidationException;
import com.farao_community.farao.dichotomy.api.index.Index;
import com.farao_community.farao.dichotomy.api.index.IndexStrategy;
import com.farao_community.farao.dichotomy.api.results.DichotomyResult;
import com.farao_community.farao.dichotomy.api.results.DichotomyStepResult;
import com.farao_community.farao.dichotomy.api.results.ReasonInvalid;
import com.farao_community.farao.dichotomy.api.utils.Formatter;
import com.powsybl.iidm.network.Network;

import java.util.Objects;

import static com.farao_community.farao.dichotomy.api.logging.DichotomyLoggerProvider.BUSINESS_LOGS;
import static com.farao_community.farao.dichotomy.api.logging.DichotomyLoggerProvider.BUSINESS_WARNS;

/**
 * Dichotomy engine.
 *
 * 

This is a generic engine to perform a dichotomy on an IIDM network. The generic algorithm is as follows: a target * index is defined according to the {@link IndexStrategy}, then according to this value a shift on the network is * performed by the {@link NetworkShifter}. After the shift a validation is performed and gathers the results in the * {@link DichotomyStepResult}. Thanks to the index, in the end a {@link DichotomyResult} is defined that would define * a highest secure step and a lower unsecure step to characterize the dichotomy.

* * @author Sebastien Murgey {@literal } * @author Vincent Bochet {@literal } */ public class DichotomyEngine { private static final int DEFAULT_MAX_ITERATION_NUMBER = 100; private final Index index; private final IndexStrategy indexStrategy; private final InterruptionStrategy interruptionStrategy; private final NetworkShifter networkShifter; private final NetworkValidator networkValidator; private final int maxIteration; private final String taskId; /** * Use this constructor to use the engine WITHOUT soft-interruption feature */ public DichotomyEngine(Index index, IndexStrategy indexStrategy, NetworkShifter networkShifter, NetworkValidator networkValidator) { this(index, indexStrategy, null, networkShifter, networkValidator, null); } /** * Use this constructor to use the engine with the soft-interruption feature */ public DichotomyEngine(Index index, IndexStrategy indexStrategy, InterruptionStrategy interruptionStrategy, NetworkShifter networkShifter, NetworkValidator networkValidator, String taskId) { this(index, indexStrategy, interruptionStrategy, networkShifter, networkValidator, DEFAULT_MAX_ITERATION_NUMBER, taskId); } /** * Use this constructor to use the engine WITHOUT soft-interruption feature */ public DichotomyEngine(Index index, IndexStrategy indexStrategy, NetworkShifter networkShifter, NetworkValidator networkValidator, int maxIteration) { this(index, indexStrategy, null, networkShifter, networkValidator, maxIteration, null); } /** * Use this constructor to use the engine with the soft-interruption feature */ public DichotomyEngine(Index index, IndexStrategy indexStrategy, InterruptionStrategy interruptionStrategy, NetworkShifter networkShifter, NetworkValidator networkValidator, int maxIteration, String taskId) { if (maxIteration < 3) { throw new DichotomyException("Max number of iterations of the dichotomy engine should be at least 3."); } this.index = Objects.requireNonNull(index); this.indexStrategy = Objects.requireNonNull(indexStrategy); this.interruptionStrategy = interruptionStrategy; this.networkShifter = networkShifter; this.networkValidator = Objects.requireNonNull(networkValidator); this.maxIteration = maxIteration; this.taskId = taskId; } public DichotomyResult run(Network network) { int iterationCounter = 0; String initialVariant = network.getVariantManager().getWorkingVariantId(); while (!indexStrategy.precisionReached(index) && iterationCounter < maxIteration) { double nextValue = indexStrategy.nextValue(index); DichotomyStepResult lastDichotomyStepResult = !index.testedSteps().isEmpty() ? index.testedSteps().get(index.testedSteps().size() - 1).getRight() : null; if (interruptionStrategy != null && interruptionStrategy.shouldTaskBeInterruptedSoftly(taskId)) { DichotomyResult dichotomyResult = DichotomyResult.buildFromIndex(index); dichotomyResult.setInterrupted(true); return dichotomyResult; } else { BUSINESS_LOGS.info(String.format("Next dichotomy step: %s", Formatter.formatDoubleDecimals(nextValue))); DichotomyStepResult dichotomyStepResult = validate(nextValue, network, initialVariant, lastDichotomyStepResult); if (dichotomyStepResult.isValid()) { BUSINESS_LOGS.info(String.format("Network at dichotomy step %s is secure", Formatter.formatDoubleDecimals(nextValue))); } else if (dichotomyStepResult.getReasonInvalid().equals(ReasonInvalid.RAO_INTERRUPTION)) { BUSINESS_LOGS.info(String.format("Got interrupted before it could determine whether the network at dichotomy step %s is secure or not", Formatter.formatDoubleDecimals(nextValue))); } else { BUSINESS_LOGS.info(String.format("Network at dichotomy step %s is unsecure", Formatter.formatDoubleDecimals(nextValue))); } if (!dichotomyStepResult.getReasonInvalid().equals(ReasonInvalid.RAO_INTERRUPTION)) { index.addDichotomyStepResult(nextValue, dichotomyStepResult); } iterationCounter++; } } if (iterationCounter == maxIteration) { BUSINESS_WARNS.warn("Max number of iteration {} reached during dichotomy, research precision has not been reached.", maxIteration); } return DichotomyResult.buildFromIndex(index); } private DichotomyStepResult validate(double stepValue, Network network, String initialVariant, DichotomyStepResult lastDichotomyStepResult) { String newVariant = variantName(stepValue, initialVariant); network.getVariantManager().cloneVariant(initialVariant, newVariant); network.getVariantManager().setWorkingVariant(newVariant); try { networkShifter.shiftNetwork(stepValue, network); return networkValidator.validateNetwork(network, lastDichotomyStepResult); } catch (GlskLimitationException e) { BUSINESS_WARNS.warn(String.format("GLSK limits have been reached for step value %s", Formatter.formatDoubleDecimals(stepValue))); return DichotomyStepResult.fromFailure(ReasonInvalid.GLSK_LIMITATION, e.getMessage()); } catch (ShiftingException | ValidationException e) { BUSINESS_WARNS.warn(String.format("Validation failed for step value %s", Formatter.formatDoubleDecimals(stepValue))); return DichotomyStepResult.fromFailure(ReasonInvalid.VALIDATION_FAILED, e.getMessage()); } catch (RaoInterruptionException e) { BUSINESS_WARNS.warn(String.format("RAO interrupted during step value %.2f", stepValue)); return DichotomyStepResult.fromFailure(ReasonInvalid.RAO_INTERRUPTION, e.getMessage()); } finally { network.getVariantManager().setWorkingVariant(initialVariant); network.getVariantManager().removeVariant(newVariant); } } private String variantName(double stepValue, String initialVariant) { return String.format("%s-ScaledBy-%d", initialVariant, (int) stepValue); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy