/* * @(#)AcscParserHelper.java * * Copyright (C) 2008 www.interpss.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE * as published by the Free Software Foundation; either version 2.1 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * @Author Mike Zhou * @Version 1.0 * @Date 08/11/2010 * * Revision History * ================ * */ package org.ieee.odm.model.acsc; import static org.ieee.odm.ODMObjectFactory.OdmObjFactory; import javax.xml.bind.JAXBElement; import org.ieee.odm.common.ODMException; import org.ieee.odm.model.AbstractModelParser; import org.ieee.odm.model.IODMModelParser; import org.ieee.odm.model.aclf.AclfParserHelper; import org.ieee.odm.model.base.BaseDataSetter; import org.ieee.odm.model.base.ODMModelDataUtil; import org.ieee.odm.schema.ApparentPowerUnitType; import org.ieee.odm.schema.BusGenDataXmlType; import org.ieee.odm.schema.BusLoadDataXmlType; import org.ieee.odm.schema.BusXmlType; import org.ieee.odm.schema.GroundingEnumType; import org.ieee.odm.schema.GroundingXmlType; import org.ieee.odm.schema.LineShortCircuitXmlType; import org.ieee.odm.schema.LoadflowBusXmlType; import org.ieee.odm.schema.LoadflowGenDataXmlType; import org.ieee.odm.schema.LoadflowLoadDataXmlType; import org.ieee.odm.schema.LoadflowNetXmlType; import org.ieee.odm.schema.PSXfrShortCircuitXmlType; import org.ieee.odm.schema.ShortCircuitBusEnumType; import org.ieee.odm.schema.ShortCircuitBusXmlType; import org.ieee.odm.schema.ShortCircuitGenDataXmlType; import org.ieee.odm.schema.ShortCircuitLoadDataXmlType; import org.ieee.odm.schema.ShortCircuitNetXmlType; import org.ieee.odm.schema.XformerConnectionXmlType; import org.ieee.odm.schema.XfrShortCircuitXmlType; import org.ieee.odm.schema.YUnitType; import org.ieee.odm.schema.YXmlType; import org.ieee.odm.schema.ZUnitType; import org.ieee.odm.schema.ZXmlType; /** * Acsc ODM model parser helper utility functions * * @author mzhou * */ public class AcscParserHelper extends AclfParserHelper { /** * create Acsc equiv gen * * @return */ /* public static JAXBElement<ShortCircuitGenDataXmlType> createAcscEquivGen() { ShortCircuitGenDataXmlType equivGen = OdmObjFactory.createShortCircuitGenDataXmlType(); return OdmObjFactory.createAcscEquivGen(equivGen); } */ /** * get Acsc Gen Data object on the acscBus with id = genId * * @param acscBus * @param genId * @return null if acscGenData not found */ public static ShortCircuitGenDataXmlType getAcscContritueGen(ShortCircuitBusXmlType acscBus, String genId) throws ODMException { for (JAXBElement<? extends LoadflowGenDataXmlType> elem : acscBus.getGenData().getContributeGen()) { ShortCircuitGenDataXmlType scGenData = (ShortCircuitGenDataXmlType)elem.getValue(); if(scGenData.getId()!=null){ if (scGenData.getId().equals(genId)) return scGenData; } else throw new ODMException("The ID of one existing Generator is NULL for bus#"+acscBus.getId()); } throw new ODMException("Generator not found, ID: " + genId + "@Bus:" + acscBus.getId()); } /** * create a Acsc Contributing Generator object * */ public static ShortCircuitGenDataXmlType createAcscContributeGen(ShortCircuitBusXmlType busRec) { BusGenDataXmlType genData = busRec.getGenData(); /* this should never happen if (genData == null) { genData = OdmObjFactory.createBusGenDataXmlType(); busRec.setGenData(genData); genData.setEquivGen(createAcscEquivGen()); } */ // some model does not need ContributeGenList ShortCircuitGenDataXmlType contribGen = OdmObjFactory.createShortCircuitGenDataXmlType(); genData.getContributeGen().add(OdmObjFactory.createAcscContributeGen(contribGen)); return contribGen; } /** * create Acsc equiv load * * @return */ /* public static JAXBElement<ShortCircuitLoadDataXmlType> createAcscEquivLoad() { ShortCircuitLoadDataXmlType equivLoad = OdmObjFactory.createShortCircuitLoadDataXmlType(); return OdmObjFactory.createAcscEquivLoad(equivLoad); } */ /** * create a ShortCircuit Contribution Load object * */ public static ShortCircuitLoadDataXmlType createAcscContributeLoad(ShortCircuitBusXmlType busRec) { BusLoadDataXmlType loadData = busRec.getLoadData(); /* this should never happen if (loadData == null) { loadData = OdmObjFactory.createBusLoadDataXmlType(); busRec.setLoadData(loadData); ShortCircuitLoadDataXmlType equivLoad = OdmObjFactory.createShortCircuitLoadDataXmlType(); loadData.setEquivLoad(OdmObjFactory.createAcscEquivLoad(equivLoad)); } */ ShortCircuitLoadDataXmlType contribLoad = OdmObjFactory.createShortCircuitLoadDataXmlType(); loadData.getContributeLoad().add(OdmObjFactory.createAcscContributeLoad(contribLoad)); return contribLoad; } /** * create directed or solid grounding xfr connection xml Type * @return */ public static XformerConnectionXmlType createDirectedGroundingConnection(){ XformerConnectionXmlType xfrConnect = OdmObjFactory.createXformerConnectionXmlType(); GroundingXmlType ground = OdmObjFactory.createGroundingXmlType(); ground.setGroundingConnection(GroundingEnumType.SOLID_GROUNDED); xfrConnect.setGrounding(ground); return xfrConnect; } /** * create impdeance grounding xfr connection xml Type * ZG = rg + j* xg * @param rg * @param xg * @return */ public static XformerConnectionXmlType createZGroundingConnection(double rg, double xg){ XformerConnectionXmlType xfrConnect = OdmObjFactory.createXformerConnectionXmlType(); GroundingXmlType ground = OdmObjFactory.createGroundingXmlType(); ground.setGroundingConnection(GroundingEnumType.Z_GROUNDED); ground.setGroundingZ(BaseDataSetter.createZValue(rg, xg, ZUnitType.PU)); xfrConnect.setGrounding(ground); return xfrConnect; } /** * create ungrounding xfr connection xml Type * @return */ public static XformerConnectionXmlType createUnGroundingConnection(){ XformerConnectionXmlType xfrConnect = OdmObjFactory.createXformerConnectionXmlType(); GroundingXmlType ground = OdmObjFactory.createGroundingXmlType(); ground.setGroundingConnection(GroundingEnumType.UNGROUNDED); xfrConnect.setGrounding(ground); return xfrConnect; } /** * create bus EquivData info * * @param parser * @return */ public static boolean createBusScEquivData(IODMModelParser parser) throws ODMException { createBusScEquivGenData(parser); createBusScEquivLoadData(parser); return true; } /** * consolidate bus scGenContributionList to the equiv gen * */ @SuppressWarnings("unchecked") public static boolean createBusScEquivGenData(IODMModelParser parser ) throws ODMException { LoadflowNetXmlType baseCaseNet = ((AbstractModelParser<ShortCircuitNetXmlType>) parser).getNet(); double sysMVABase = baseCaseNet.getBasePower().getValue(); if(baseCaseNet.getBasePower().getUnit()==ApparentPowerUnitType.MVA){ //target unit, do nothing } else if(baseCaseNet.getBasePower().getUnit()==ApparentPowerUnitType.KVA) sysMVABase *=0.001; else if (baseCaseNet.getBasePower().getUnit() == ApparentPowerUnitType.VA) sysMVABase *= 0.000001; else throw new ODMException("Wrong system baseMVA.unit, " + baseCaseNet.getBasePower().getUnit()); for ( JAXBElement<? extends BusXmlType> busXml : baseCaseNet.getBusList().getBus()) { ShortCircuitBusXmlType scBusXml = (ShortCircuitBusXmlType)busXml.getValue(); if(scBusXml.getScCode()==ShortCircuitBusEnumType.CONTRIBUTING ) { /* this should never happen && scBusXml.getGenData().getEquivGen()!=null && scBusXml.getGenData().getContributeGen()!=null){ */ //Consolidate the positive and negative sequence to scEquivLoadData ShortCircuitGenDataXmlType defaultGen = getDefaultScGen(scBusXml.getGenData()); // gen z is init as a large Z, or open circuit ZXmlType equivPosZ = null; ZXmlType equivNegZ = null; ZXmlType equivZeroZ = null; for( JAXBElement<? extends LoadflowGenDataXmlType> scContriGenEle : scBusXml.getGenData().getContributeGen()) { ShortCircuitGenDataXmlType contriGenData = (ShortCircuitGenDataXmlType) scContriGenEle.getValue(); /* * ZSource is based on GEN MVABASE, therefore, it requires to convert it to system MVABASE * before setting it to BusScZ */ double machRatedMva = contriGenData.getMvaBase().getValue(); if (contriGenData.getMvaBase().getUnit() == ApparentPowerUnitType.MVA) // possible unit PU, W, KW, MW, HP; ; // do nothing else if (contriGenData.getMvaBase().getUnit() == ApparentPowerUnitType.KVA) machRatedMva *= 0.001; else if (contriGenData.getMvaBase().getUnit() == ApparentPowerUnitType.VA) machRatedMva *= 0.000001; else { throw new ODMException("Wrong acscGen.retedMachPower.unit, " + contriGenData.getMvaBase().getUnit()); } double factor =sysMVABase/ machRatedMva; ZXmlType z1=contriGenData.getPotiveZ(); ZXmlType zSource = contriGenData.getSourceZ(); if(z1 == null ){ //check ZSOURCE } ZXmlType z11 = ODMModelDataUtil.ZXmlMultiplyDouble(z1, factor); if(equivPosZ ==null) equivPosZ = z11; else{ equivPosZ =ODMModelDataUtil.addParallelZ(equivPosZ, z11); } if(contriGenData.getNegativeZ()!=null){ ZXmlType z2=contriGenData.getNegativeZ(); ZXmlType z21 = ODMModelDataUtil.ZXmlMultiplyDouble(z2, factor); if(equivNegZ==null) equivNegZ = z21; else{ equivNegZ =ODMModelDataUtil.addParallelZ(equivNegZ, z21); } } //TODO It is very hard to consolidate the grounding Zg of multi-generators , since they are in series of ZZERO of gens if(contriGenData.getZeroZ()!=null){ ZXmlType z0=contriGenData.getZeroZ(); ZXmlType z01 = ODMModelDataUtil.ZXmlMultiplyDouble(z0, factor); if(equivZeroZ==null) equivZeroZ = z01; else{ equivZeroZ =ODMModelDataUtil.addParallelZ(equivZeroZ, z01); } } /* if(contriGenData.getZeroZ()!=null){ z=contriGenData.getZeroZ(); //Based on PSS/E convention, if Tap-up transformer is modeled as part of generator //then, the generator is open from the zero sequence network, which can be model by LargeBusZ , or not adding ScZ. boolean zeroOpen =(contriGenData.getXfrZ()==null)? false:(contriGenData.getXfrZ().getIm()==0)?false:true; if(!zeroOpen && z.getIm()!=0)acscBus.addScGenZ(new Complex(z.getRe()*factor, z.getIm()*factor),SequenceCode.ZERO); } */ } // generator data is modeled at the equivalent Gen level or has been consolidated already. //if no sequence data provided, gen z is init as a large Z, or open circuit if(equivPosZ !=null ){ /* equivPosZ =BaseDataSetter.createZValue(0, 1.0e10, ZUnitType.PU); equivNegZ =BaseDataSetter.createZValue(0, 1.0e10, ZUnitType.PU); equivZeroZ =BaseDataSetter.createZValue(0, 1.0e10, ZUnitType.PU); ODMLogger.getLogger().warning("posZ of gen is not provided, Bus Id, GenId #"+scBusXml.getId()); */ defaultGen.setPotiveZ(equivPosZ); defaultGen.setNegativeZ(equivNegZ); defaultGen.setZeroZ(equivZeroZ); } } } return true; } public static ShortCircuitGenDataXmlType getDefaultScGen(BusGenDataXmlType genData) { if (genData.getContributeGen().size() == 0) genData.getContributeGen().add(OdmObjFactory.createContributeGen( OdmObjFactory.createShortCircuitGenDataXmlType())); return (ShortCircuitGenDataXmlType)genData.getContributeGen().get(0).getValue(); } public static ShortCircuitLoadDataXmlType getDefaultScLoad(BusLoadDataXmlType loadData) { if (loadData.getContributeLoad().size() == 0) loadData.getContributeLoad().add(OdmObjFactory.createContributeLoad( OdmObjFactory.createShortCircuitLoadDataXmlType())); return (ShortCircuitLoadDataXmlType)loadData.getContributeLoad().get(0).getValue(); } /** * consolidate bus scLoadContributionList to the equiv load * @throws ODMException * */ @SuppressWarnings("unchecked") public static boolean createBusScEquivLoadData(IODMModelParser parser ) throws ODMException { LoadflowNetXmlType baseCaseNet = ((AbstractModelParser<LoadflowNetXmlType>) parser).getNet(); for ( JAXBElement<? extends BusXmlType> busXml : baseCaseNet.getBusList().getBus()) { ShortCircuitBusXmlType scBusXml = (ShortCircuitBusXmlType)busXml.getValue(); if(scBusXml.getLoadData()!=null){ ShortCircuitLoadDataXmlType defaultLoad = getDefaultScLoad(scBusXml.getLoadData()); YXmlType equivShuntNegY = null; YXmlType equivShuntZeroY = null; if(scBusXml.getLoadData().getContributeLoad()!=null){ for( JAXBElement<? extends LoadflowLoadDataXmlType> scContriLoadEle : scBusXml.getLoadData().getContributeLoad()) { ShortCircuitLoadDataXmlType contriLoadData = (ShortCircuitLoadDataXmlType) scContriLoadEle.getValue(); //Negative sequence Y if(contriLoadData.getShuntLoadNegativeY()!=null){ if(equivShuntNegY == null)equivShuntNegY = contriLoadData.getShuntLoadNegativeY(); else { ODMModelDataUtil.addParallelY(equivShuntNegY,contriLoadData.getShuntLoadNegativeY()); } } else{ // negative sequence load data is not provided in the input data, assume y2 = equivY1 //TODO const P and I load need to be processed and adjusted differently for load flow based //short circuit analysis or building sequence network /* * Use unit voltage vmag=1.0 to initialize the equivalent shuntY * * equivY_0 = load.conjugate(); * * For load flow-based short circuit analysis, * equivY_actual = equivY_0/ v^2 for Constant Power load * = equivY_0* v for Constant current load * */ // However, now the sequence load modeling does not treated them separately } if(contriLoadData.getShuntLoadZeroY()!=null){ if(equivShuntZeroY == null)equivShuntZeroY = contriLoadData.getShuntLoadZeroY(); else { ODMModelDataUtil.addParallelY(equivShuntZeroY,contriLoadData.getShuntLoadZeroY()); } } //else, zero sequence load is open, do nothing } } // we assume Y is in pu on the system base if(equivShuntNegY!=null) { equivShuntNegY.setUnit(YUnitType.PU); defaultLoad.setShuntLoadNegativeY(equivShuntNegY); } if(equivShuntZeroY!=null) { equivShuntZeroY.setUnit(YUnitType.PU); defaultLoad.setShuntLoadZeroY(equivShuntZeroY); } } } return true; } }