HolegGateway.java 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. package holeg;
  2. import classes.AbstractCanvasObject;
  3. import classes.HolonObject;
  4. import classes.Node;
  5. import holeg.model.*;
  6. import holeg.power_flow.ComplexNumber;
  7. import holeg.simple_grid.SimpleGridBuilder;
  8. import holeg.simple_grid.SimpleGridEdge;
  9. import holeg.simple_grid.SimpleGridNode;
  10. import holeg.ui.PowerFlowAnalysisMenu;
  11. import holeg.ui.SolveResultMessageBox;
  12. import ui.controller.FlexManager;
  13. import ui.controller.SingletonControl;
  14. import ui.model.*;
  15. import java.util.HashMap;
  16. public class HolegGateway {
  17. private static Grid convert(MinimumNetwork network, int iteration, FlexManager flexManager) {
  18. SimpleGridBuilder gridBuilder = new SimpleGridBuilder();
  19. HashMap<AbstractCanvasObject, SimpleGridNode> canvasToGrid = new HashMap<>();
  20. for (HolonObject object : network.getHolonObjectList()) {
  21. double power = object.getEnergyAtTimeStep(iteration);
  22. SimpleGridNode node;
  23. // Create house or generator
  24. if (power <= 0)
  25. node = gridBuilder.addHouse(new ComplexNumber(-power, 0));
  26. else
  27. node = gridBuilder.addGenerator(new ComplexNumber(power, 0));
  28. node.tag = object;
  29. // Find type by design
  30. if (object.getElements().stream().anyMatch(e -> e.getEleName().equalsIgnoreCase("SLACK")))
  31. node.typeByDesign = NodeType.Slack;
  32. else if (object.getElements().stream().anyMatch(e -> e.getEleName().equalsIgnoreCase("TRANSFORMER")))
  33. node.typeByDesign = NodeType.Transformer;
  34. else
  35. node.typeByDesign = NodeType.Bus;
  36. canvasToGrid.put(object, node);
  37. }
  38. // Add all switches and nodes
  39. for (AbstractCanvasObject object : network.getNodeAndSwitches()) {
  40. SimpleGridNode node = gridBuilder.addHouse(new ComplexNumber(0, 0));
  41. node.tag = object;
  42. node.typeByDesign = NodeType.Bus;
  43. canvasToGrid.put(object, node);
  44. }
  45. // Add all cables
  46. for (IntermediateCableWithState cable : network.getEdgeList()) {
  47. SimpleGridNode a = canvasToGrid.get(cable.getModel().getA());
  48. SimpleGridNode b = canvasToGrid.get(cable.getModel().getB());
  49. if (a == null || b == null)
  50. continue;
  51. SimpleGridEdge edge = gridBuilder.connect(a, b, cable.getModel().getRealLength());
  52. edge.overrideImpedance = new ComplexNumber(cable.getModel().getOverrideResistance(), cable.getModel().getOverrideReactance());
  53. edge.overrideShuntSusceptance = cable.getModel().getOverrideShuntSusceptance();
  54. edge.tag = cable;
  55. }
  56. return gridBuilder.getGrid();
  57. }
  58. private static void decorateNetwork(MinimumNetwork network, int iteration, FlexManager flexManager, DecoratedNetwork decoratedNetwork, Grid grid) {
  59. synchronized (decoratedNetwork.getLockObject()) {
  60. decoratedNetwork.clear();
  61. // Convert all nodes
  62. for (GridNode node : grid.getNodes()) {
  63. SimpleGridNode simpleNode = (SimpleGridNode) node;
  64. // Create supplier, consumer or passiv object
  65. if (node.getPowerGeneration().lenSquared() > 0)
  66. decoratedNetwork.getSupplierList().add(new Supplier((HolonObject) simpleNode.tag, (float) node.getPowerGeneration().real, 0, simpleNode.voltage, simpleNode.phaseDegrees, simpleNode.typeSolved == NodeType.Slack));
  67. else if (node.getPowerConsumption().lenSquared() > 0)
  68. 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));
  69. else if (simpleNode.tag instanceof HolonObject)
  70. decoratedNetwork.getPassivNoEnergyList().add(new Passiv((HolonObject) simpleNode.tag));
  71. }
  72. // Convert all edges
  73. for (GridEdge edge : grid.getEdges()) {
  74. SimpleGridEdge simpleGridEdge = (SimpleGridEdge) edge;
  75. decoratedNetwork.getDecoratedCableList().add(
  76. new DecoratedCable(
  77. ((IntermediateCableWithState) simpleGridEdge.tag).getModel(),
  78. DecoratedCable.CableState.Working,
  79. (float) simpleGridEdge.power.real,
  80. (float) simpleGridEdge.loss.real));
  81. }
  82. decoratedNetwork.calculateStates();
  83. }
  84. }
  85. public static void solve(HolegPowerFlowContext context, MinimumNetwork minimumNetwork, int iteration, FlexManager flexManager, DecoratedNetwork network) {
  86. boolean solve = !PowerFlowAnalysisMenu.getInstance().areUpdatesDisabled();
  87. Grid grid = convert(minimumNetwork, iteration, flexManager);
  88. // Create settings when null
  89. if (context != null && context.settings == null)
  90. context.settings = PowerFlowSettings.getDefault();
  91. // Check if the grid is equal to one already solved
  92. if (context != null && context.settings.onlyUpdateGridWhenChanged) {
  93. for (Grid lastSolved : context.lastSolvedGrids) {
  94. if (GridComparator.isEqual(lastSolved, grid)) {
  95. decorateNetwork(minimumNetwork, iteration, flexManager, network, lastSolved);
  96. return;
  97. }
  98. }
  99. // Only remember grid when solving
  100. if (solve) {
  101. // Keep size constrained to 32 saved grids
  102. if (context.lastSolvedGrids.size() >= 32)
  103. context.lastSolvedGrids.remove(0);
  104. // Grid is updated by solver directly, so we can save the reference to the grid
  105. context.lastSolvedGrids.add(grid);
  106. }
  107. }
  108. // Stop old solver
  109. if (context != null && context.solverJob != null) {
  110. try {
  111. context.solverJob.interrupt();
  112. // wait till old solver job has finished or is interrupted
  113. context.solverJob.join(200);
  114. }
  115. catch(InterruptedException ignored) {
  116. }
  117. context.solverJob = null;
  118. }
  119. // Create solver job
  120. Thread solverJob = new Thread(() -> {
  121. long start = System.nanoTime();
  122. GridSolverResult result = null;
  123. // Starting solving when requested
  124. if (solve) {
  125. HolegPowerFlow powerFlow = new HolegPowerFlow();
  126. result = powerFlow.solve(grid, context.settings);
  127. }
  128. // Decorate network
  129. decorateNetwork(minimumNetwork, iteration, flexManager, network, grid);
  130. if (context != null)
  131. context.solverTimeMilliseconds = (System.nanoTime() - start) / 1e6f;
  132. // Update canvas and other visuals
  133. SingletonControl.getInstance().getControl().calculateVisual();
  134. // Show result message box
  135. if (result != null && PowerFlowAnalysisMenu.getInstance().shouldShowResult())
  136. SolveResultMessageBox.show(result);
  137. });
  138. // Wait or save solver job
  139. try {
  140. if (context == null || context.settings.waitForSolverJob) {
  141. // Start and wait till solver job is finished
  142. solverJob.start();
  143. solverJob.join();
  144. }
  145. else {
  146. // Render the non-solved grid and start the real solver job
  147. decorateNetwork(minimumNetwork, iteration, flexManager, network, grid);
  148. context.solverJob = solverJob;
  149. solverJob.start();
  150. }
  151. }
  152. catch(InterruptedException e) {
  153. e.printStackTrace();
  154. }
  155. }
  156. }