def convert_branch(branch: Branch): """ :param branch: :return: """ if branch.branch_type == BranchType.Line: return Line(bus_from=branch.bus_from, bus_to=branch.bus_to, name=branch.name, r=branch.R, x=branch.X, b=branch.B, rate=branch.rate, active=branch.active, tolerance=branch.tolerance, cost=branch.Cost, mttf=branch.mttf, mttr=branch.mttr, r_fault=branch.r_fault, x_fault=branch.x_fault, fault_pos=branch.fault_pos, length=branch.length, temp_base=branch.temp_base, temp_oper=branch.temp_oper, alpha=branch.alpha, rate_prof=branch.rate_prof, Cost_prof=branch.Cost_prof, active_prof=branch.active_prof, temp_oper_prof=branch.temp_oper_prof) elif branch.branch_type == BranchType.Transformer: return Transformer2W(bus_from=branch.bus_from, bus_to=branch.bus_to, name=branch.name, r=branch.R, x=branch.X, b=branch.B, rate=branch.rate, active=branch.active, tolerance=branch.tolerance, cost=branch.Cost, mttf=branch.mttf, mttr=branch.mttr, tap=branch.tap_module, shift_angle=branch.angle, vset=branch.vset, bus_to_regulated=branch.bus_to_regulated, temp_base=branch.temp_base, temp_oper=branch.temp_oper, alpha=branch.alpha, template=branch.template, rate_prof=branch.rate_prof, Cost_prof=branch.Cost_prof, active_prof=branch.active_prof, temp_oper_prof=branch.temp_oper_prof) else: return branch
def test_demo_5_node(root_path=ROOT_PATH): np.core.arrayprint.set_printoptions(precision=4) grid = MultiCircuit() # Add buses bus1 = Bus('Bus 1', vnom=20) grid.add_bus(bus1) gen1 = Generator('Slack Generator', voltage_module=1.0) grid.add_generator(bus1, gen1) bus2 = Bus('Bus 2', vnom=20) grid.add_bus(bus2) grid.add_load(bus2, Load('load 2', P=40, Q=20)) bus3 = Bus('Bus 3', vnom=20) grid.add_bus(bus3) grid.add_load(bus3, Load('load 3', P=25, Q=15)) bus4 = Bus('Bus 4', vnom=20) grid.add_bus(bus4) grid.add_load(bus4, Load('load 4', P=40, Q=20)) bus5 = Bus('Bus 5', vnom=20) grid.add_bus(bus5) grid.add_load(bus5, Load('load 5', P=50, Q=20)) # add branches (Lines in this case) grid.add_line(Line(bus1, bus2, 'line 1-2', r=0.05, x=0.11, b=0.02)) grid.add_line(Line(bus1, bus3, 'line 1-3', r=0.05, x=0.11, b=0.02)) grid.add_line(Line(bus1, bus5, 'line 1-5', r=0.03, x=0.08, b=0.02)) grid.add_line(Line(bus2, bus3, 'line 2-3', r=0.04, x=0.09, b=0.02)) grid.add_line(Line(bus2, bus5, 'line 2-5', r=0.04, x=0.09, b=0.02)) grid.add_line(Line(bus3, bus4, 'line 3-4', r=0.06, x=0.13, b=0.03)) grid.add_line(Line(bus4, bus5, 'line 4-5', r=0.04, x=0.09, b=0.02)) # grid.plot_graph() print('\n\n', grid.name) FileSave(grid, 'demo_5_node.json').save() options = PowerFlowOptions(SolverType.NR, verbose=False) power_flow = PowerFlowDriver(grid, options) power_flow.run() print_power_flow_results(power_flow=power_flow) v = np.array([1., 0.9553, 0.9548, 0.9334, 0.9534]) all_ok = np.isclose(np.abs(power_flow.results.voltage), v, atol=1e-3) return all_ok
def test_line_losses_1(): """ Basic line losses test. """ test_name = "test_line_losses_1" grid = MultiCircuit(name=test_name) Sbase = 100 # MVA grid.Sbase = Sbase grid.time_profile = None grid.logger = Logger() # Create buses Bus0 = Bus(name="Bus0", vnom=25, is_slack=True) Bus1 = Bus(name="Bus1", vnom=25) grid.add_bus(Bus0) grid.add_bus(Bus1) # Create load grid.add_load(Bus1, Load(name="Load0", P=1.0, Q=0.4)) # Create slack bus grid.add_generator(Bus0, Generator(name="Utility")) # Create cable (r and x should be in pu) grid.add_branch( Line(bus_from=Bus0, bus_to=Bus1, name="Cable1", r=0.01, x=0.05)) # Run non-linear load flow options = PowerFlowOptions(verbose=True) power_flow = PowerFlowDriver(grid, options) power_flow.run() # Check solution approx_losses = round(1000 * power_flow.results.losses[0], 3) solution = complex(0.116, 0.58) # Expected solution from GridCal # Tested on ETAP 16.1.0 and pandapower print( "\n=================================================================") print(f"Test: {test_name}") print( "=================================================================\n") print(f"Results: {approx_losses}") print(f"Solution: {solution}") print() print("Buses:") for i, b in enumerate(grid.buses): print(f" - bus[{i}]: {b}") print() print("Branches:") branches = grid.get_branches() for b in branches: print(f" - {b}:") print(f" R = {round(b.R, 4)} pu") print(f" X = {round(b.X, 4)} pu") print(f" X/R = {round(b.X/b.R, 2)}") print() print("Voltages:") for i in range(len(grid.buses)): print( f" - {grid.buses[i]}: voltage={round(power_flow.results.voltage[i], 3)} pu" ) print() print("Losses:") for i in range(len(branches)): print( f" - {branches[i]}: losses={round(power_flow.results.losses[i], 3)} MVA" ) print() print("Loadings (power):") for i in range(len(branches)): print( f" - {branches[i]}: loading={round(power_flow.results.Sf[i], 3)} MVA" ) print() print("Loadings (current):") for i in range(len(branches)): print( f" - {branches[i]}: loading={round(power_flow.results.If[i], 3)} pu" ) print() assert approx_losses == solution
def scene_mouse_release_event(self, event): """ Finalize the branch creation if its drawing ends in a terminal @param event: @return: """ # Clear or finnish the started connection: if self.started_branch: pos = event.scenePos() items = self.diagramScene.items(pos) # get the item (the terminal) at the mouse position for item in items: if type(item) is TerminalItem: # connect only to terminals if item.parent is not self.started_branch.fromPort.parent: # forbid connecting to itself self.started_branch.setToPort(item) item.hosting_connections.append(self.started_branch) self.started_branch.bus_to = item.parent if self.started_branch.bus_from.api_object.is_dc != self.started_branch.bus_to.api_object.is_dc: # different DC status -> VSC name = 'VSC ' + str(len(self.circuit.vsc_devices) + 1) obj = VSC(bus_from=self.started_branch.bus_from.api_object, bus_to=self.started_branch.bus_to.api_object, name=name) obj.graphic_obj = VscGraphicItem(fromPort=self.started_branch.fromPort, toPort=self.started_branch.toPort, diagramScene=self.diagramScene, branch=obj) elif self.started_branch.bus_from.api_object.is_dc and self.started_branch.bus_to.api_object.is_dc: # both buses are DC name = 'Dc line ' + str(len(self.circuit.dc_lines) + 1) obj = DcLine(bus_from=self.started_branch.bus_from.api_object, bus_to=self.started_branch.bus_to.api_object, name=name) obj.graphic_obj = DcLineGraphicItem(fromPort=self.started_branch.fromPort, toPort=self.started_branch.toPort, diagramScene=self.diagramScene, branch=obj) else: # Same DC status -> line / trafo v1 = self.started_branch.bus_from.api_object.Vnom v2 = self.started_branch.bus_to.api_object.Vnom if abs(v1 - v2) > 1.0: name = 'Transformer ' + str(len(self.circuit.transformers2w) + 1) obj = Transformer2W(bus_from=self.started_branch.bus_from.api_object, bus_to=self.started_branch.bus_to.api_object, name=name) obj.graphic_obj = TransformerGraphicItem(fromPort=self.started_branch.fromPort, toPort=self.started_branch.toPort, diagramScene=self.diagramScene, branch=obj) else: name = 'Line ' + str(len(self.circuit.lines) + 1) obj = Line(bus_from=self.started_branch.bus_from.api_object, bus_to=self.started_branch.bus_to.api_object, name=name) obj.graphic_obj = LineGraphicItem(fromPort=self.started_branch.fromPort, toPort=self.started_branch.toPort, diagramScene=self.diagramScene, branch=obj) # add the new object to the circuit self.circuit.add_branch(obj) # update the connection placement obj.graphic_obj.fromPort.update() obj.graphic_obj.toPort.update() # set the connection placement obj.graphic_obj.setZValue(-1) # if self.started_branch.toPort is None: self.started_branch.remove_widget() # release this pointer self.started_branch = None