def CreateRegXfmr(self, model, node1, node2, reg_data, reg_type_data): print(reg_type_data) tr = PowerTransformer(model) tr.name = "xfmr_" + reg_data["name"] tr.substation_name = ("" if not isinstance(reg_data["substation"], str) else reg_data["substation"]) tr.feeder_name = ("" if not isinstance(reg_data["feeder"], str) else reg_data["feeder"]) tr.from_element = node1 tr.to_element = node2 tr.normhkva = (float(reg_data["kv"][0]) * float(reg_type_data.iloc[-1]["Ampacity"]) * 3) tr.loadloss = float(1) tr.noload_loss = float(0.1) # TODO fix the noload losses here tr.install_type = "PADMOUNT" tr.reactances.append([10.0]) tr.phase_shift = 0 tr.is_center_tap = False # Set transformer position node_pos = Position(model) node_pos.long = float(self.nxGraph.node[node2]["x"]) node_pos.lat = float(self.nxGraph.node[node2]["y"]) tr.positions.append(node_pos) for i in range(2): nPhases = len(reg_data["phases"]) wdg = Winding(model) kV = float(self.nxGraph[node1][node2]["kv"][0]) * 1000 wdg.resistance = 0.5 wdg.nominal_voltage = kV if nPhases == 1 else 1.732 * kV wdg.connection_type = self.nxGraph[node1][node2]["conn"][i] wdg.rated_power = (float(reg_data["kv"][0]) * float(reg_type_data.iloc[-1]["Ampacity"]) * 1000) wdg.voltage_type = 0 if i == 0 else 2 phases = reg_data["phases"] LDCr = reg_data["LDCr"] LDCx = reg_data["LDCx"] Vset = reg_data["Vpu"] Vub = reg_data["fhhp"] Vlb = reg_data["fhlp"] for j, ZippedData in enumerate( zip(phases, LDCr, LDCx, Vlb, Vub, Vset)): phase, r, x, vu, vl, vs = ZippedData nSteps = 33 vPerStep = (float(vu) - float(vl)) / nSteps Tap = int((float(vs) - 1) / vPerStep) print("Tap: ", Tap) phswdg = PhaseWinding(model) ix = self.phase_2_index[phase][0] phswdg.phase = phase phswdg.tap_position = float(Tap) phswdg.compensator_r = float(r) phswdg.compensator_x = float(x) wdg.phase_windings.append(phswdg) tr.windings.append(wdg) return tr.name
def parse_transformers(self, model): xfmrs = self.filter_edges_by_class("transformer") xfmr_types = self.nxGraph.graph["Transformer"] for xfmr in xfmrs: node1, node2 = xfmr # Get the transformer type tr_types = set(self.nxGraph[node1][node2]["equipment"]) tr_types.discard("NONE") if tr_types: # tr data from library tr_type = list(tr_types)[0] winding_data = xfmr_types[xfmr_types["Equipment Identifier"] == tr_type] # create transformer phases = self.nxGraph[node1][node2]["phases"] nPhases = len(phases) nwdgs = 2 if np.isnan( self.nxGraph[node1][node2]["hasTertiary"]) else 3 X_R_ratio = float(winding_data["X/R Ratio- Phase A"].iloc[0]) Zpercentage = float( winding_data["Percent Impedance- Zps"].iloc[0]) r_percent = np.sqrt(Zpercentage**2 / (X_R_ratio**2 + 1)) x_percent = np.sqrt(Zpercentage**2 - r_percent**2) tr = PowerTransformer(model) tr.name = node2.replace("node_", "tr_") tr.substation_name = ("" if not isinstance( self.nxGraph[node1][node2]["substation"], str) else self.nxGraph[node1][node2]["substation"]) tr.feeder_name = ("" if not isinstance( self.nxGraph[node1][node2]["feeder"], str) else self.nxGraph[node1][node2]["feeder"]) tr.from_element = node1 tr.to_element = node2 tr.normhkva = sum([ float(winding_data["Single Phase Base kVA- Zps"].iloc[0]), float(winding_data["Single Phase Base kVA- Zpt"].iloc[0]), float(winding_data["Single Phase Base kVA- Zst"].iloc[0]), ]) tr.noload_loss = float( winding_data["No-Load Loss- Zps"].iloc[0]) / float( winding_data["Single Phase Base kVA- Zps"].iloc[0]) tr.install_type = ("PADMOUNT" if bool( winding_data["Is Pad Mounted Transformer"].iloc[0]) else "POLEMOUNT") tr.reactances.append(float(x_percent)) tr.phase_shift = 0 tr.is_center_tap = int( self.nxGraph[node1][node2]["is center tapped"]) # Set transformer position node_pos = Position(model) node_pos.long = float(self.nxGraph.node[node2]["x"]) node_pos.lat = float(self.nxGraph.node[node2]["y"]) tr.positions.append(node_pos) for i in range(nwdgs): wdg = Winding(model) wdg.resistance = r_percent / nwdgs kV = float(self.nxGraph[node1][node2]["kv"][i]) * 1000 wdg.nominal_voltage = kV if nPhases == 1 else 1.732 * kV wdg.connection_type = self.nxGraph[node1][node2]["conn"][i] wdg.rated_power = ( float(winding_data["Single Phase Rated kVA- Zps"]) * 1000) wdg.voltage_type = 0 if i == 0 else 2 for j, phase in enumerate(phases): phswdg = PhaseWinding(model) ix = self.phase_2_index[phase][0] phswdg.phase = phase phswdg.tap_position = 1.0 # self.nxGraph[node1][node2]['kv'][i] phswdg.compensator_r = 0 phswdg.compensator_x = 0 wdg.phase_windings.append(phswdg) tr.windings.append(wdg)
def test_ephasor_writer(): from ditto.writers.ephasor.write import Writer from ditto.models.node import Node from ditto.models.line import Line from ditto.models.load import Load from ditto.models.regulator import Regulator from ditto.models.wire import Wire from ditto.models.capacitor import Capacitor from ditto.models.powertransformer import PowerTransformer from ditto.models.winding import Winding from ditto.models.phase_winding import PhaseWinding from ditto.store import Store from ditto.models.base import Unicode from ditto.models.power_source import PowerSource from ditto.models.feeder_metadata import Feeder_metadata m = Store() src = PowerSource( m, name="f1_src", phases=[Unicode("A"), Unicode("B"), Unicode("C")], nominal_voltage=12470, connecting_element="n1", is_sourcebus=True, ) meta = Feeder_metadata(m, name="f1", nominal_voltage=12470, headnode="f1_src", substation="f1_src") node1 = Node(m, name="n1", feeder_name="f1") node2 = Node(m, name="n2", feeder_name="f1") node3 = Node(m, name="n3", feeder_name="f1") wirea = Wire(m, gmr=1.3, X=2, Y=20) wiren = Wire(m, gmr=1.2, X=2, Y=20) line1 = Line( m, name="l1", wires=[wirea, wiren], from_element="n1", to_element="n2", feeder_name="f1", ) load1 = Load(m, name="load1", feeder_name="f1") phase_winding = PhaseWinding(m, phase=u"A") winding1 = Winding( m, phase_windings=[phase_winding], connection_type="Y", nominal_voltage=12.47, rated_power=25, resistance=10, ) winding2 = Winding( m, phase_windings=[phase_winding], connection_type="Y", nominal_voltage=6.16, rated_power=25, resistance=10, ) transformer1 = PowerTransformer( m, name="t1", from_element="n2", to_element="n3", windings=[winding1, winding2], feeder_name="f1", ) transformer1.reactances.append(6) # reg1 = Regulator(m, name='t1_reg', connected_transformer='t1', connected_winding=2, pt_ratio=60, delay=2) # cap1 = Capacitor(m, name='cap1', connecting_element='n2', num_phases=3, nominal_voltage=7.2, var=300, connection_type='Y') m.set_names() t = tempfile.TemporaryDirectory() writer = Writer(output_path=t.name, log_path="./") writer.write(m)
def test_opendss_writer(): from ditto.writers.opendss.write import Writer from ditto.models.node import Node from ditto.models.line import Line from ditto.models.load import Load from ditto.models.regulator import Regulator from ditto.models.wire import Wire from ditto.models.capacitor import Capacitor from ditto.models.powertransformer import PowerTransformer from ditto.models.winding import Winding # from ditto.model import Model from ditto.store import Store from ditto.models.storage import Storage from ditto.models.phase_storage import PhaseStorage from ditto.models.base import Unicode from ditto.models.base import Float from ditto.models.power_source import PowerSource from ditto.models.phase_load import PhaseLoad m = Store() node1 = Node(m, name="n1") node2 = Node(m, name="n2") node3 = Node(m, name="n3") wirea = Wire(m, gmr=1.3, X=2, Y=20) wiren = Wire(m, gmr=1.2, X=2, Y=20) line1 = Line(m, name="l1", wires=[wirea, wiren]) phase_load1 = PhaseLoad(m, p=5400, q=2615.3394) load1 = Load(m, name="load1", phase_loads=[phase_load1]) winding1 = Winding( m, connection_type="W", nominal_voltage=12.47, rated_power=25, ) winding2 = Winding( m, connection_type="W", nominal_voltage=6.16, rated_power=25, ) transformer1 = PowerTransformer( m, name="t1", from_element="n2", to_element="n3", windings=[winding1, winding2], feeder_name="f1", ) transformer1.reactances.append(6) reg1 = Regulator( m, name="t1_reg", connected_transformer="t1", pt_ratio=60, delay=2, ) cap1 = Capacitor( m, name="cap1", nominal_voltage=7.2, connection_type="Y", ) print(line1.impedance_matrix) # Storage testing phase_storage_A = PhaseStorage(m, phase="A", p=15.0, q=5.0) phase_storage_B = PhaseStorage(m, phase="B", p=16.0, q=6.0) storage = Storage( m, name="store1", connecting_element="n3", nominal_voltage=12470.0, rated_power=10000.0, rated_kWh=100.0, stored_kWh=75.5, reserve=20.0, discharge_rate=25.0, charge_rate=18.7, charging_efficiency=15.3, discharging_efficiency=22.0, resistance=20, reactance=10, model_=1, phase_storages=[phase_storage_A, phase_storage_B], ) # PV systems testing PV_system = PowerSource( m, name="PV1", is_sourcebus=False, nominal_voltage=12470, phases=[Unicode("A"), Unicode("C")], rated_power=20000.0, connection_type="D", cutout_percent=30.0, cutin_percent=15.3, resistance=14.0, reactance=5.2, v_max_pu=100, v_min_pu=60, power_factor=0.9, ) t = tempfile.TemporaryDirectory() writer = Writer(output_path=t.name) # writer.write_wiredata(m) # writer.write_linegeometry(m) # writer.write_linecodes(m) writer.write_storages(m) writer.write_PVs(m) writer.write_lines(m) writer.write_loads(m) writer.write_transformers(m) writer.write_regulators(m) writer.write_capacitors(m)
def parse_transformers(self, model): xfmrs = self.filter_edges_by_class('transformer') xfmr_types = self.nxGraph.graph['Transformer'] for xfmr in xfmrs: node1, node2 = xfmr # Get the transformer type tr_types = set(self.nxGraph[node1][node2]['equipment']) tr_types.discard('NONE') if tr_types: # tr data from library tr_type = list(tr_types)[0] winding_data = xfmr_types[xfmr_types['Equipment Identifier'] == tr_type] # create transformer phases = self.nxGraph[node1][node2]['phases'] nPhases = len(phases) nwdgs = 2 if np.isnan( self.nxGraph[node1][node2]['hasTertiary']) else 3 X_R_ratio = float(winding_data['X/R Ratio- Phase A'].iloc[0]) Zpercentage = float( winding_data['Percent Impedance- Zps'].iloc[0]) r_percent = np.sqrt(Zpercentage**2 / (X_R_ratio**2 + 1)) x_percent = np.sqrt(Zpercentage**2 - r_percent**2) tr = PowerTransformer(model) tr.name = node2.replace('node_', 'tr_') tr.substation_name = '' if not isinstance(self.nxGraph[node1][node2]['substation'], str) else \ self.nxGraph[node1][node2]['substation'] tr.feeder_name = '' if not isinstance(self.nxGraph[node1][node2]['feeder'], str) else \ self.nxGraph[node1][node2]['feeder'] tr.from_element = node1 tr.to_element = node2 tr.normhkva = sum([ float(winding_data['Single Phase Base kVA- Zps'].iloc[0]), float(winding_data['Single Phase Base kVA- Zpt'].iloc[0]), float(winding_data['Single Phase Base kVA- Zst'].iloc[0]) ]) tr.noload_loss = float( winding_data['No-Load Loss- Zps'].iloc[0]) / float( winding_data['Single Phase Base kVA- Zps'].iloc[0]) tr.install_type = 'PADMOUNT' if bool( winding_data['Is Pad Mounted Transformer'].iloc[0] ) else 'POLEMOUNT' tr.reactances.append(float(x_percent)) tr.phase_shift = 0 tr.is_center_tap = int( self.nxGraph[node1][node2]['is center tapped']) # Set transformer position node_pos = Position(model) node_pos.long = float(self.nxGraph.node[node2]['x']) node_pos.lat = float(self.nxGraph.node[node2]['y']) tr.positions.append(node_pos) for i in range(nwdgs): wdg = Winding(model) wdg.resistance = r_percent / nwdgs kV = float(self.nxGraph[node1][node2]['kv'][i]) * 1000 wdg.nominal_voltage = kV if nPhases == 1 else 1.732 * kV wdg.connection_type = self.nxGraph[node1][node2]['conn'][i] wdg.rated_power = float( winding_data['Single Phase Rated kVA- Zps']) * 1000 wdg.voltage_type = 0 if i == 0 else 2 for j, phase in enumerate(phases): phswdg = PhaseWinding(model) ix = self.phase_2_index[phase][0] phswdg.phase = phase phswdg.tap_position = 1.0 #self.nxGraph[node1][node2]['kv'][i] phswdg.compensator_r = 0 phswdg.compensator_x = 0 wdg.phase_windings.append(phswdg) tr.windings.append(wdg)
def parse_transformers(self, model, **kwargs): """Transformer parser. :param model: DiTTo model :type model: DiTTo model :returns: 1 for success, -1 for failure :rtype: int """ # Assume that each transformer has one from node and one to node. connection_map = {'Delta':'D','Wye':'Y'} transformer_panel_map = {} for element in self.geojson_content["features"]: if 'properties' in element and 'DSId' in element['properties'] and 'id' in element['properties']: if element['properties']['DSId'] in transformer_panel_map: transformer_panel_map[element['properties']['DSId']].append(element['properties']['id']) else: transformer_panel_map[element['properties']['DSId']] = [element['properties']['id']] for element in self.geojson_content["features"]: if 'properties' in element and 'district_system_type' in element['properties'] and element['properties']['district_system_type'] == 'Transformer': transformer_id = element['properties']['id'] transformer = PowerTransformer(model) if transformer_id in transformer_panel_map: if len(transformer_panel_map[transformer_id]) <2: print("No from and to elements found tor transformer") if len(transformer_panel_map[transformer_id]) >2: print("Warning - the transformer "+transformer_id+" should have a from and to element - "+str(len(transformer_panel_map[transformer_id]))+" junctions on the transformer") if len(transformer_panel_map[transformer_id]) >=2: for db_transformer in self.equipment_data['transformer_properties']: if element['properties']['equipment'][0] == db_transformer['nameclass']: transformer.from_element = transformer_panel_map[transformer_id][0] transformer.to_element = transformer_panel_map[transformer_id][1] #NOTE: Need to figure out correct from and to directions here. transformer.name = transformer_id transformer.reactances = [float(db_transformer['reactance'])] transformer.is_center_tap = db_transformer['is_center_tap'] windings = [Winding(model),Winding(model)] connections = db_transformer['connection'].split('-') if transformer.is_center_tap: windings.append(Winding(model)) transformer.reactances.append(float(db_transformer['reactance'])) transformer.reactances.append(float(db_transformer['reactance'])) #TODO: map reactance values correctly for center-taps for i in range(len(windings)): phase_windings = [] for phase in db_transformer['phases']: pw = PhaseWinding(model) pw.phase = phase phase_windings.append(pw) windings[i].phase_windings = phase_windings windings[i].rated_power = float(db_transformer['kva'])*1000 if i<1: windings[i].nominal_voltage = float(db_transformer['high_voltage'])*1000 windings[i].connection_type = connection_map[connections[0]] windings[i].voltage_type = 0 windings[i].resistance = float(db_transformer['resistance']) else: windings[i].nominal_voltage = float(db_transformer['low_voltage'])*1000 windings[i].connection_type = connection_map[connections[1]] windings[i].voltage_type = 1 windings[i].resistance = float(db_transformer['resistance']) transformer.windings = windings return 1