|
@@ -13,11 +13,17 @@ import holeg.ui.SolveResultMessageBox;
|
|
import ui.controller.FlexManager;
|
|
import ui.controller.FlexManager;
|
|
import ui.controller.SingletonControl;
|
|
import ui.controller.SingletonControl;
|
|
import ui.model.*;
|
|
import ui.model.*;
|
|
|
|
+import ui.view.GUI;
|
|
|
|
|
|
|
|
+import javax.swing.*;
|
|
|
|
+import java.awt.*;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
|
|
+import java.util.List;
|
|
import java.util.stream.Collectors;
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
public class HolegGateway {
|
|
public class HolegGateway {
|
|
|
|
+ private static ThreadLocal<Boolean> onlyUpdateVisual = new ThreadLocal<Boolean>();
|
|
|
|
+
|
|
private static Grid convert(MinimumNetwork network, int iteration, FlexManager flexManager) {
|
|
private static Grid convert(MinimumNetwork network, int iteration, FlexManager flexManager) {
|
|
SimpleGridBuilder gridBuilder = new SimpleGridBuilder();
|
|
SimpleGridBuilder gridBuilder = new SimpleGridBuilder();
|
|
HashMap<AbstractCanvasObject, SimpleGridNode> canvasToGrid = new HashMap<>();
|
|
HashMap<AbstractCanvasObject, SimpleGridNode> canvasToGrid = new HashMap<>();
|
|
@@ -74,9 +80,9 @@ public class HolegGateway {
|
|
|
|
|
|
// Create supplier, consumer or passiv object
|
|
// Create supplier, consumer or passiv object
|
|
if (node.getPowerGeneration().lenSquared() > 0)
|
|
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));
|
|
|
|
|
|
+ decoratedNetwork.getSupplierList().add(new Supplier((HolonObject) simpleNode.tag, (float) node.getPowerGeneration().real, 0, simpleNode.getVoltage(), simpleNode.phaseDegrees, simpleNode.getTypeByDesign() == NodeType.Slack));
|
|
else if (node.getPowerConsumption().lenSquared() > 0)
|
|
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));
|
|
|
|
|
|
+ decoratedNetwork.getConsumerList().add(new Consumer((HolonObject) simpleNode.tag, (float) node.getPowerConsumption().real, simpleNode.getVoltage(), simpleNode.phaseDegrees, Math.cos(simpleNode.getPowerConsumption().angle()), simpleNode.getTypeByDesign() == NodeType.Slack));
|
|
else if (simpleNode.tag instanceof HolonObject)
|
|
else if (simpleNode.tag instanceof HolonObject)
|
|
decoratedNetwork.getPassivNoEnergyList().add(new Passiv((HolonObject) simpleNode.tag));
|
|
decoratedNetwork.getPassivNoEnergyList().add(new Passiv((HolonObject) simpleNode.tag));
|
|
}
|
|
}
|
|
@@ -133,7 +139,28 @@ public class HolegGateway {
|
|
return context;
|
|
return context;
|
|
}
|
|
}
|
|
|
|
|
|
- public static synchronized void solve(PowerFlowSettings settings, MinimumNetwork minimumNetwork, int iteration, FlexManager flexManager, DecoratedNetwork network) {
|
|
|
|
|
|
+ public static void solve(PowerFlowSettings settings, MinimumNetwork minimumNetwork, int iteration, FlexManager flexManager, DecoratedNetwork network) {
|
|
|
|
+ Thread solverWrapper = new Thread(() -> {
|
|
|
|
+ try {
|
|
|
|
+ solveInternal(settings, minimumNetwork, iteration, flexManager, network);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ SolveResultMessageBox.showInternalError(e);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ try {
|
|
|
|
+ solverWrapper.setName("Solver Wrapper " + Long.toHexString(solverWrapper.getId()));
|
|
|
|
+ solverWrapper.start();
|
|
|
|
+ solverWrapper.join(4000);
|
|
|
|
+ if (solverWrapper.isAlive()) {
|
|
|
|
+ solverWrapper.stop();
|
|
|
|
+ SolveResultMessageBox.showSolverTookTooLongToStart();
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ SolveResultMessageBox.showInternalError(e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private static void solveInternal(PowerFlowSettings settings, MinimumNetwork minimumNetwork, int iteration, FlexManager flexManager, DecoratedNetwork network) {
|
|
// Find context
|
|
// Find context
|
|
HolegPowerFlowContext context = getContextFromHolonObjects(minimumNetwork.getHolonObjectList());
|
|
HolegPowerFlowContext context = getContextFromHolonObjects(minimumNetwork.getHolonObjectList());
|
|
if (context == null)
|
|
if (context == null)
|
|
@@ -143,7 +170,7 @@ public class HolegGateway {
|
|
solve(settings, context, minimumNetwork, iteration, flexManager, network);
|
|
solve(settings, context, minimumNetwork, iteration, flexManager, network);
|
|
}
|
|
}
|
|
|
|
|
|
- private static synchronized void solve(PowerFlowSettings settings, HolegPowerFlowContext context, MinimumNetwork minimumNetwork, int iteration, FlexManager flexManager, DecoratedNetwork network) {
|
|
|
|
|
|
+ private static void solve(PowerFlowSettings settings, HolegPowerFlowContext context, MinimumNetwork minimumNetwork, int iteration, FlexManager flexManager, DecoratedNetwork network) {
|
|
if (settings == null)
|
|
if (settings == null)
|
|
throw new IllegalArgumentException("settings is null");
|
|
throw new IllegalArgumentException("settings is null");
|
|
if (context == null)
|
|
if (context == null)
|
|
@@ -160,73 +187,87 @@ public class HolegGateway {
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
|
|
|
|
- boolean solve = !PowerFlowAnalysisMenu.getInstance().areUpdatesDisabled();
|
|
|
|
- Grid grid = convert(minimumNetwork, iteration, flexManager);
|
|
|
|
-
|
|
|
|
- // Check if the grid is equal to one already solved
|
|
|
|
- if (settings.onlyUpdateGridWhenChanged) {
|
|
|
|
- for (Grid lastSolved : context.lastSolvedGrids) {
|
|
|
|
- if (GridComparator.isEqual(lastSolved, grid)) {
|
|
|
|
- decorateNetwork(minimumNetwork, iteration, flexManager, network, lastSolved);
|
|
|
|
- return;
|
|
|
|
|
|
+ synchronized (context.lock) {
|
|
|
|
+ boolean solve = !PowerFlowAnalysisMenu.getInstance().areUpdatesDisabled();
|
|
|
|
+ Grid grid = convert(minimumNetwork, iteration, flexManager);
|
|
|
|
+
|
|
|
|
+ // Check if the grid is equal to one already solved
|
|
|
|
+ if (settings.onlyUpdateGridWhenChanged) {
|
|
|
|
+ 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);
|
|
|
|
|
|
+ // 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);
|
|
|
|
|
|
+ // Grid is updated by solver directly, so we can save the reference to the grid
|
|
|
|
+ context.lastSolvedGrids.add(grid);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- }
|
|
|
|
-
|
|
|
|
- // Stop old solver
|
|
|
|
- context.stopSolver();
|
|
|
|
-
|
|
|
|
- // Create solver job
|
|
|
|
- Thread solverJob = new Thread(() -> {
|
|
|
|
- long start = System.nanoTime();
|
|
|
|
- GridSolverResult result = null;
|
|
|
|
|
|
|
|
- // Starting solving when requested
|
|
|
|
- if (solve) {
|
|
|
|
- HolegPowerFlow powerFlow = new HolegPowerFlow();
|
|
|
|
- result = powerFlow.solve(grid, settings);
|
|
|
|
|
|
+ // We got no solution for this grid
|
|
|
|
+ if (onlyUpdateVisual.get() != null && onlyUpdateVisual.get()) {
|
|
|
|
+ decorateNetwork(minimumNetwork, iteration, flexManager, network, grid);
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
|
|
|
|
- // Decorate network
|
|
|
|
- decorateNetwork(minimumNetwork, iteration, flexManager, network, grid);
|
|
|
|
- context.solverTimeMilliseconds = (System.nanoTime() - start) / 1e6f;
|
|
|
|
-
|
|
|
|
- // Update canvas and other visuals
|
|
|
|
- context.showGridForVisual = grid;
|
|
|
|
- SingletonControl.getInstance().getControl().calculateStateAndVisualForCurrentTimeStep();
|
|
|
|
-
|
|
|
|
- // Show result message box
|
|
|
|
- if (result != null && PowerFlowAnalysisMenu.getInstance().shouldShowResult())
|
|
|
|
- SolveResultMessageBox.show(result);
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- // Wait or save solver job
|
|
|
|
- try {
|
|
|
|
- if (settings.waitForSolverJob) {
|
|
|
|
- // Start and wait till solver job is finished
|
|
|
|
- solverJob.start();
|
|
|
|
- solverJob.join();
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- // Render the non-solved grid and start the real solver job
|
|
|
|
- decorateNetwork(minimumNetwork, iteration, flexManager, network, grid);
|
|
|
|
- context.solverJob = solverJob;
|
|
|
|
- solverJob.start();
|
|
|
|
|
|
+ // Stop old solver
|
|
|
|
+ context.stopSolver();
|
|
|
|
+
|
|
|
|
+ // Create solver job
|
|
|
|
+ Thread solverJob = new Thread(() -> {
|
|
|
|
+ try {
|
|
|
|
+ long start = System.nanoTime();
|
|
|
|
+ GridSolverResult result = null;
|
|
|
|
+
|
|
|
|
+ // Starting solving when requested
|
|
|
|
+ if (solve) {
|
|
|
|
+ HolegPowerFlow powerFlow = new HolegPowerFlow();
|
|
|
|
+ result = powerFlow.solve(grid, settings);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Decorate network
|
|
|
|
+ decorateNetwork(minimumNetwork, iteration, flexManager, network, grid);
|
|
|
|
+ context.solverTimeMilliseconds = (System.nanoTime() - start) / 1e6f;
|
|
|
|
+
|
|
|
|
+ // Update canvas and other visuals
|
|
|
|
+ context.showGridForVisual = grid;
|
|
|
|
+ onlyUpdateVisual.set(true);
|
|
|
|
+ SingletonControl.getInstance().getControl().calculateStateAndVisualForCurrentTimeStep();
|
|
|
|
+ onlyUpdateVisual.set(false);
|
|
|
|
+
|
|
|
|
+ // Show result message box
|
|
|
|
+ if (result != null && PowerFlowAnalysisMenu.getInstance().shouldShowResult())
|
|
|
|
+ SolveResultMessageBox.show(result);
|
|
|
|
+ }
|
|
|
|
+ catch(Exception e) {
|
|
|
|
+ SolveResultMessageBox.showInternalError(e);
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ solverJob.setName("Solver 0x" + Integer.toHexString(context.hashCode()));
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // Wait or save solver job
|
|
|
|
+ try {
|
|
|
|
+ if (settings.waitForSolverJob) {
|
|
|
|
+ // Start and wait till solver job is finished
|
|
|
|
+ solverJob.start();
|
|
|
|
+ solverJob.join();
|
|
|
|
+ } else {
|
|
|
|
+ // Render the non-solved grid and start the real solver job
|
|
|
|
+ decorateNetwork(minimumNetwork, iteration, flexManager, network, grid);
|
|
|
|
+ context.solverJob = solverJob;
|
|
|
|
+ solverJob.start();
|
|
|
|
+ }
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- catch(InterruptedException e) {
|
|
|
|
- e.printStackTrace();
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|