MarginCalculationContext.java
/**
* Copyright (c) 2024, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.dynawo.margincalculation;
import com.powsybl.contingency.Contingency;
import com.powsybl.dynawo.*;
import com.powsybl.dynawo.margincalculation.loadsvariation.LoadVariationAreaAutomationSystem;
import com.powsybl.dynawo.margincalculation.loadsvariation.LoadsProportionalScalable;
import com.powsybl.dynawo.margincalculation.loadsvariation.LoadsVariation;
import com.powsybl.dynawo.models.BlackBoxModel;
import com.powsybl.dynawo.models.loads.AbstractLoad;
import com.powsybl.dynawo.algorithms.ContingencyEventModels;
import com.powsybl.dynawo.algorithms.ContingencyEventModelsFactory;
import com.powsybl.dynawo.xml.DynawoData;
import com.powsybl.iidm.modification.scalable.Scalable;
import com.powsybl.iidm.modification.scalable.ScalingParameters;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Network;
import java.util.*;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
/**
* @author Laurent Issertial {@literal <laurent.issertial at rte-france.com>}
*/
public final class MarginCalculationContext extends DynawoSimulationContext {
private final MarginCalculationParameters marginCalculationParameters;
private final List<ContingencyEventModels> contingencyEventModels;
private final LoadVariationModels loadVariationModels;
public static class Builder extends AbstractContextBuilder<Builder> {
private final List<Contingency> contingencies;
private final List<LoadsVariation> loadsVariations;
private MarginCalculationParameters parameters;
private LoadVariationModels loadVariationModels;
private List<ContingencyEventModels> contingencyEventModels;
public Builder(Network network, List<BlackBoxModel> dynamicModels, List<Contingency> contingencies,
List<LoadsVariation> loadsVariations) {
super(network, dynamicModels);
this.contingencies = contingencies;
this.loadsVariations = loadsVariations;
}
public Builder marginCalculationParameters(MarginCalculationParameters parameters) {
this.parameters = Objects.requireNonNull(parameters);
return self();
}
@Override
protected void setupData() {
if (parameters == null) {
parameters = MarginCalculationParameters.load();
}
finalStepConfig = configureFinalStep(parameters, loadsVariations);
super.setupData();
}
@Override
protected void setupMacroConnections() {
super.setupMacroConnections();
setupLoadVariationModels();
setupContingencyEventModels();
}
@Override
protected void setupSimulationTime() {
this.simulationTime = new SimulationTime(parameters.getStartTime(), parameters.getMarginCalculationStartTime());
this.finalStepTime = new SimulationTime(simulationTime.stopTime(), finalStepConfig.stopTime());
}
private void setupLoadVariationModels() {
LoadVariationAreaAutomationSystem loadVariationArea = new LoadVariationAreaAutomationSystem(loadsVariations,
parameters.getLoadIncreaseStartTime(),
parameters.getLoadIncreaseStopTime(),
configureScaling(network));
loadVariationModels = LoadVariationModels.createFrom(blackBoxModelSupplier, loadVariationArea, dynamicModelsParameters::add,
dynawoParameters.getNetworkParameters(), DynawoSimulationConstants.getSimulationParFile(network), reportNode);
}
private void setupContingencyEventModels() {
this.contingencyEventModels = ContingencyEventModelsFactory.createFrom(contingencies,
parameters.getContingenciesStartTime(), network, blackBoxModelSupplier, reportNode);
}
@Override
protected Builder self() {
return this;
}
@Override
public MarginCalculationContext build() {
setup();
return new MarginCalculationContext(this);
}
private static FinalStepConfig configureFinalStep(MarginCalculationParameters parameters, List<LoadsVariation> loadsVariations) {
return switch (parameters.getLoadModelsRule()) {
case ALL_LOADS -> new FinalStepConfig(parameters.getStopTime(), AbstractLoad.class::isInstance);
case TARGETED_LOADS -> {
Set<String> loadIds = loadsVariations.stream()
.flatMap(l -> l.loads().stream())
.map(Identifiable::getId)
.collect(Collectors.toSet());
yield new FinalStepConfig(parameters.getStopTime(),
bbm -> bbm instanceof AbstractLoad eBbm && loadIds.contains(eBbm.getDynamicModelId()));
}
};
}
private static BiConsumer<LoadsProportionalScalable, Double> configureScaling(Network network) {
ScalingParameters scalingParameters = new ScalingParameters()
.setScalingConvention(Scalable.ScalingConvention.LOAD)
.setConstantPowerFactor(true);
return (s, v) -> s.scale(network, v, scalingParameters);
}
}
private MarginCalculationContext(Builder builder) {
super(builder);
this.marginCalculationParameters = builder.parameters;
this.contingencyEventModels = builder.contingencyEventModels;
this.loadVariationModels = builder.loadVariationModels;
}
public MarginCalculationParameters getMarginCalculationParameters() {
return marginCalculationParameters;
}
public List<ContingencyEventModels> getContingencyEventModels() {
return contingencyEventModels;
}
public DynawoData getLoadVariationAreaDydData() {
return loadVariationModels;
}
}