HolegGateway.java 9.8 KB

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