HolegGateway.java 9.9 KB

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