package holeg; import classes.AbstractCanvasObject; import classes.HolonObject; import classes.Node; import holeg.model.*; import holeg.power_flow.ComplexNumber; import holeg.simple_grid.SimpleGridBuilder; import holeg.simple_grid.SimpleGridEdge; import holeg.simple_grid.SimpleGridNode; import holeg.ui.PowerFlowAnalysisMenu; import holeg.ui.SolveResultMessageBox; import ui.controller.FlexManager; import ui.controller.SingletonControl; import ui.model.*; import java.util.HashMap; public class HolegGateway { private static Grid convert(MinimumNetwork network, int iteration, FlexManager flexManager) { SimpleGridBuilder gridBuilder = new SimpleGridBuilder(); HashMap canvasToGrid = new HashMap<>(); for (HolonObject object : network.getHolonObjectList()) { double power = object.getEnergyAtTimeStep(iteration); SimpleGridNode node; if (power <= 0) node = gridBuilder.addHouse(new ComplexNumber(-power, 0)); else node = gridBuilder.addGenerator(new ComplexNumber(power, 0)); node.tag = object; if (object.getElements().stream().anyMatch(e -> e.getEleName().equalsIgnoreCase("SLACK"))) node.typeByDesign = NodeType.Slack; else if (object.getElements().stream().anyMatch(e -> e.getEleName().equalsIgnoreCase("TRANSFORMER"))) node.typeByDesign = NodeType.Transformer; else node.typeByDesign = NodeType.Bus; canvasToGrid.put(object, node); } for (AbstractCanvasObject object : network.getNodeAndSwitches()) { SimpleGridNode node = gridBuilder.addHouse(new ComplexNumber(0, 0)); node.tag = object; node.typeByDesign = NodeType.Bus; canvasToGrid.put(object, node); } for (IntermediateCableWithState cable : network.getEdgeList()) { SimpleGridNode a = canvasToGrid.get(cable.getModel().getA()); SimpleGridNode b = canvasToGrid.get(cable.getModel().getB()); if (a == null || b == null) continue; SimpleGridEdge edge = gridBuilder.connect(a, b, cable.getModel().getRealLength()); edge.overrideImpedance = new ComplexNumber(cable.getModel().getOverrideResistance(), cable.getModel().getOverrideReactance()); edge.overrideShuntSusceptance = cable.getModel().getOverrideShuntSusceptance(); edge.tag = cable; } return gridBuilder.getGrid(); } private static void decorateNetwork(MinimumNetwork network, int iteration, FlexManager flexManager, DecoratedNetwork decoratedNetwork, Grid grid) { synchronized (decoratedNetwork.getLockObject()) { decoratedNetwork.clear(); for (GridNode node : grid.getNodes()) { SimpleGridNode simpleNode = (SimpleGridNode) node; if (node.getPowerGeneration().lenSquared() > 0) decoratedNetwork.getSupplierList().add(new Supplier((HolonObject) simpleNode.tag, (float) node.getPowerGeneration().real, 0, simpleNode.voltage, simpleNode.phaseDegrees, simpleNode.typeSolved == NodeType.Slack)); else if (node.getPowerConsumption().lenSquared() > 0) decoratedNetwork.getConsumerList().add(new Consumer((HolonObject) simpleNode.tag, (float) node.getPowerConsumption().real, simpleNode.voltage, simpleNode.phaseDegrees, Math.cos(simpleNode.getPowerConsumption().angle()), simpleNode.typeSolved == NodeType.Slack)); else if (simpleNode.tag instanceof HolonObject) decoratedNetwork.getPassivNoEnergyList().add(new Passiv((HolonObject) simpleNode.tag)); } for (GridEdge edge : grid.getEdges()) { SimpleGridEdge simpleGridEdge = (SimpleGridEdge) edge; decoratedNetwork.getDecoratedCableList().add( new DecoratedCable( ((IntermediateCableWithState) simpleGridEdge.tag).getModel(), DecoratedCable.CableState.Working, (float) simpleGridEdge.power.real, (float) simpleGridEdge.loss.real)); } decoratedNetwork.calculateStates(); } } public static void solve(HolegPowerFlowContext context, MinimumNetwork minimumNetwork, int iteration, FlexManager flexManager, DecoratedNetwork network) { boolean solve = !PowerFlowAnalysisMenu.getInstance().areUpdatesDisabled(); Grid grid = convert(minimumNetwork, iteration, flexManager); // Check if the grid is equal to the one already solved if (context != null) { for (Grid lastSolved : context.lastSolvedGrids) { if (GridComparator.isEqual(lastSolved, grid)) { decorateNetwork(minimumNetwork, iteration, flexManager, network, lastSolved); return; } } // Only remember grid when solving if (solve) { // Keep size constrained to 32 saved grids if (context.lastSolvedGrids.size() >= 32) context.lastSolvedGrids.remove(0); // Grid is updated by solver directly, so we can save the reference to the grid context.lastSolvedGrids.add(grid); } } // Stop old solver if (context != null && context.solverJob != null) { try { context.solverJob.interrupt(); context.solverJob.join(200); } catch(InterruptedException ignored) { } context.solverJob = null; } // Create solver job Thread solverJob = new Thread(() -> { long start = System.nanoTime(); GridSolverResult result = null; if (solve) { HolegPowerFlow powerFlow = new HolegPowerFlow(); result = powerFlow.solve(grid, PowerFlowSettings.getDefault()); } // Decorate network decorateNetwork(minimumNetwork, iteration, flexManager, network, grid); if (context != null) context.solverTimeMilliseconds = (System.nanoTime() - start) / 1e6f; SingletonControl.getInstance().getControl().calculateVisual(); // Show result if (result != null && PowerFlowAnalysisMenu.getInstance().shouldShowResult()) SolveResultMessageBox.show(result); }); // Wait or save solver job try { if (context == null || context.settings.waitForSolverJob) { solverJob.start(); solverJob.join(); } else { decorateNetwork(minimumNetwork, iteration, flexManager, network, grid); context.solverJob = solverJob; solverJob.start(); } } catch(InterruptedException e) { e.printStackTrace(); } } }