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

com.powsybl.cgmes.conversion.elements.transformers.ThreeWindingsTransformerConversion Maven / Gradle / Ivy

There is a newer version: 6.6.0
Show newest version
/**
 * Copyright (c) 2019, 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.cgmes.conversion.elements.transformers;

import com.powsybl.cgmes.conversion.Context;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.conversion.RegulatingControlMappingForTransformers.CgmesRegulatingControlPhase;
import com.powsybl.cgmes.conversion.RegulatingControlMappingForTransformers.CgmesRegulatingControlRatio;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.ThreeWindingsTransformerAdder.LegAdder;
import com.powsybl.iidm.network.extensions.ThreeWindingsTransformerPhaseAngleClock;
import com.powsybl.iidm.network.util.TwtData;
import com.powsybl.triplestore.api.PropertyBags;

/**
 * ThreeWindingsTransformer Cgmes Conversion
 * 

* Cgmes conversion for transformers (two and three windings) is divided into four stages: load, interpret, convert and set. *

* Load
* Native CGMES data is loaded from the triple store query and is put in the CGMES model object (CgmesT3xModel). *

* Interpret
* CgmesT3xModel data is mapped to a more general three windings transformer model (InterpretedT3xModel) * according to a predefined configured alternative. It is an elemental process as the only objective is to put * Cgmes data in the fields of the general three windings transformer model. * All possible alternatives and the default one are defined in conversion class. See {@link Conversion}
* InterpretedT3xModel supports ratioTapChanger and phaseTapChanger at each end of any leg. Shunt admittances * can also be defined at both ends of each leg and allows to specify the end of the structural ratio by leg. *

* Convert
* Converts the interpreted model (InterpretedT3xModel) to the converted model object (ConvertedT3xModel).
* The ConvertedT3xModel only allows to define ratioTapChanger and phaseTapChanger at the network side of any leg. * Shunt admittances and structural ratio must be also at the network side.
* To do this process the following methods are applied to each leg:
* moveTapChangerFrom2To1: To move a tapChanger from star bus side to network side
* combineTapChanger: To reduce two tapChangers to one
* moveRatioFrom2To1: To move structural ratio from star bus side to network side
* Finally shunt admittance of both ends of the leg are added to network side. This step is an approximation and only * will be possible to reproduce the exact case result if Cgmes shunts are defined at network side or * are split and the LoadflowParameter splitShuntAdmittance option is selected.
* See {@link TapChangerConversion} *

* Set
* A direct map from ConvertedT3xModel to IIDM model *

* @author Luma Zamarreño * @author José Antonio Marqués */ public class ThreeWindingsTransformerConversion extends AbstractTransformerConversion { public ThreeWindingsTransformerConversion(PropertyBags ends, Context context) { super(CgmesNames.POWER_TRANSFORMER, ends, context); } @Override public void convert() { CgmesT3xModel cgmesT3xModel = new CgmesT3xModel(ps, context); InterpretedT3xModel interpretedT3xModel = new InterpretedT3xModel(cgmesT3xModel, context.config()); ConvertedT3xModel convertedT3xModel = new ConvertedT3xModel(interpretedT3xModel, context); setToIidm(convertedT3xModel); } public static void calculateVoltageAndAngleInStarBus(ThreeWindingsTransformer twt) { ThreeWindingsTransformerPhaseAngleClock phaseAngleClock = twt.getExtensionByName("threeWindingsTransformerPhaseAngleClock"); int phaseAngleClock2 = 0; int phaseAngleClock3 = 0; if (phaseAngleClock != null) { phaseAngleClock2 = phaseAngleClock.getPhaseAngleClockLeg2(); phaseAngleClock3 = phaseAngleClock.getPhaseAngleClockLeg3(); } boolean splitShuntAdmittance = false; TwtData twtData = new TwtData(twt, phaseAngleClock2, phaseAngleClock3, 0.0, false, splitShuntAdmittance); double starBusV = twtData.getStarU(); double starBusTheta = Math.toDegrees(twtData.getStarTheta()); if (!Double.isNaN(starBusV) && !Double.isNaN(starBusTheta)) { twt.setProperty("v", Double.toString(starBusV)); twt.setProperty("angle", Double.toString(starBusTheta)); } } private void setToIidm(ConvertedT3xModel convertedT3xModel) { ThreeWindingsTransformerAdder txadder = substation() .map(Substation::newThreeWindingsTransformer) .orElseThrow(() -> new PowsyblException("Substation null! Transformer must be within a substation")) .setRatedU0(convertedT3xModel.ratedU0); identify(txadder); LegAdder l1adder = txadder.newLeg1(); setToIidmWindingAdder(convertedT3xModel.winding1, l1adder); connect(l1adder, 1); l1adder.add(); LegAdder l2adder = txadder.newLeg2(); setToIidmWindingAdder(convertedT3xModel.winding2, l2adder); connect(l2adder, 2); l2adder.add(); LegAdder l3adder = txadder.newLeg3(); setToIidmWindingAdder(convertedT3xModel.winding3, l3adder); connect(l3adder, 3); l3adder.add(); ThreeWindingsTransformer tx = txadder.add(); addAliasesAndProperties(tx); convertedTerminals( tx.getLeg1().getTerminal(), tx.getLeg2().getTerminal(), tx.getLeg3().getTerminal()); setToIidmWindingTapChanger(convertedT3xModel, convertedT3xModel.winding1, tx, context); setToIidmWindingTapChanger(convertedT3xModel, convertedT3xModel.winding2, tx, context); setToIidmWindingTapChanger(convertedT3xModel, convertedT3xModel.winding3, tx, context); setRegulatingControlContext(convertedT3xModel, tx); addCgmesReferences(tx, convertedT3xModel.winding1.end1.ratioTapChanger); addCgmesReferences(tx, convertedT3xModel.winding1.end1.phaseTapChanger); addCgmesReferences(tx, convertedT3xModel.winding2.end1.ratioTapChanger); addCgmesReferences(tx, convertedT3xModel.winding2.end1.phaseTapChanger); addCgmesReferences(tx, convertedT3xModel.winding3.end1.ratioTapChanger); addCgmesReferences(tx, convertedT3xModel.winding3.end1.phaseTapChanger); } private static void setToIidmWindingAdder(ConvertedT3xModel.ConvertedWinding convertedModelWinding, LegAdder ladder) { ladder.setR(convertedModelWinding.r) .setX(convertedModelWinding.x) .setG(convertedModelWinding.end1.g) .setB(convertedModelWinding.end1.b) .setRatedU(convertedModelWinding.end1.ratedU); if (convertedModelWinding.ratedS != null) { ladder.setRatedS(convertedModelWinding.ratedS); } } private static void setToIidmWindingTapChanger(ConvertedT3xModel convertedT3xModel, ConvertedT3xModel.ConvertedWinding convertedModelWinding, ThreeWindingsTransformer tx, Context context) { setToIidmRatioTapChanger(convertedT3xModel, convertedModelWinding, tx); setToIidmPhaseTapChanger(convertedT3xModel, convertedModelWinding, tx, context); } private static void setToIidmRatioTapChanger(ConvertedT3xModel convertedT3xModel, ConvertedT3xModel.ConvertedWinding convertedWinding, ThreeWindingsTransformer tx) { TapChanger rtc = convertedWinding.end1.ratioTapChanger; if (rtc == null) { return; } RatioTapChangerAdder rtca = newRatioTapChanger(convertedT3xModel, tx, convertedWinding.end1.terminal); setToIidmRatioTapChanger(rtc, rtca); } private static void setToIidmPhaseTapChanger(ConvertedT3xModel convertedT3xModel, ConvertedT3xModel.ConvertedWinding convertedWinding, ThreeWindingsTransformer tx, Context context) { TapChanger ptc = convertedWinding.end1.phaseTapChanger; if (ptc == null) { return; } PhaseTapChangerAdder ptca = newPhaseTapChanger(convertedT3xModel, tx, convertedWinding.end1.terminal); setToIidmPhaseTapChanger(ptc, ptca, context); } private static RatioTapChangerAdder newRatioTapChanger(ConvertedT3xModel convertedT3xModel, ThreeWindingsTransformer tx, String terminal) { if (convertedT3xModel.winding1.end1.terminal.equals(terminal)) { return tx.getLeg1().newRatioTapChanger(); } else if (convertedT3xModel.winding2.end1.terminal.equals(terminal)) { return tx.getLeg2().newRatioTapChanger(); } else if (convertedT3xModel.winding3.end1.terminal.equals(terminal)) { return tx.getLeg3().newRatioTapChanger(); } return null; } private static PhaseTapChangerAdder newPhaseTapChanger(ConvertedT3xModel convertedT3xModel, ThreeWindingsTransformer tx, String terminal) { if (convertedT3xModel.winding1.end1.terminal.equals(terminal)) { return tx.getLeg1().newPhaseTapChanger(); } else if (convertedT3xModel.winding2.end1.terminal.equals(terminal)) { return tx.getLeg2().newPhaseTapChanger(); } else if (convertedT3xModel.winding3.end1.terminal.equals(terminal)) { return tx.getLeg3().newPhaseTapChanger(); } return null; } private void setRegulatingControlContext(ConvertedT3xModel convertedT3xModel, ThreeWindingsTransformer tx) { CgmesRegulatingControlRatio rcRtc1 = setContextRegulatingDataRatio(convertedT3xModel.winding1.end1.ratioTapChanger); CgmesRegulatingControlPhase rcPtc1 = setContextRegulatingDataPhase(convertedT3xModel.winding1.end1.phaseTapChanger); CgmesRegulatingControlRatio rcRtc2 = setContextRegulatingDataRatio(convertedT3xModel.winding2.end1.ratioTapChanger); CgmesRegulatingControlPhase rcPtc2 = setContextRegulatingDataPhase(convertedT3xModel.winding2.end1.phaseTapChanger); CgmesRegulatingControlRatio rcRtc3 = setContextRegulatingDataRatio(convertedT3xModel.winding3.end1.ratioTapChanger); CgmesRegulatingControlPhase rcPtc3 = setContextRegulatingDataPhase(convertedT3xModel.winding3.end1.phaseTapChanger); context.regulatingControlMapping().forTransformers().add(tx.getId(), rcRtc1, rcPtc1, rcRtc2, rcPtc2, rcRtc3, rcPtc3); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy