package ui.controller; import java.util.ArrayList; import java.util.HashMap; import classes.CpsEdge; import classes.CpsNode; import classes.AbstractCpsObject; import classes.HolonElement; import classes.HolonObject; import classes.HolonSwitch; import classes.SubNet; import ui.model.Model; import ui.view.MyCanvas; public class SimulationManager { private Model model; private ArrayList objectsToHandle; private ArrayList allConnections; private ArrayList subNets; private MyCanvas canvas; private int timeStep; private boolean simMode; private HashMap tagTable = new HashMap(); public SimulationManager(Model m) { canvas = null; model = m; subNets = new ArrayList(); simMode = model.getIsSimulation(); } /** * calculates the flow of the edges and the supply for objects * * @param x */ public void calculateStateForTimeStep(int x) { simMode = model.getIsSimulation(); timeStep = x; searchForSubNets(); for (SubNet singleSubNet : subNets) { ResetConnections(singleSubNet.getObjects().get(0), new ArrayList(), new ArrayList()); } for (SubNet singleSubNet : subNets) { float production = calculateEnergy("prod", singleSubNet, timeStep); float consumption = calculateEnergy("cons", singleSubNet, timeStep); float minConsumption = calculateMinimumEnergy(singleSubNet, timeStep); setFlow(singleSubNet, simMode); for (HolonObject hl : singleSubNet.getObjects()) { if (!(hl.getState() == 0) && !(hl.getState() == 3)) { for (int i = 0; i < hl.getConnections().size(); i++) { CpsEdge edge = hl.getConnectedTo().get(i); if (edge.getState() && edge.getFlow() > 0 || edge.getCapacity() == -1) { // 0 = no energy, 1 = not supplied, 2 = supplied, 3 // = producer, 4 = partially supplied if ((production + consumption) >= 0) { hl.setState(2); } if ((production + consumption) < 0) { if ((production + minConsumption) >= 0) { hl.setState(4); } else if (hl.checkIfPartiallySupplied(timeStep)) { hl.setState(4); } else { hl.setState(1); } } break; } hl.setState(1); } if (hl.checkIfPartiallySupplied(timeStep) && !(hl.getState() == 2)) { hl.setState(4); } } } } canvas.repaint(); } public void setFlow(SubNet sN, boolean simulation) { if (simulation) { setFlowSimulation(sN); } else { setFlowModelation(sN); } } public void setFlowModelation(SubNet sN) { for (HolonObject hl : sN.getObjects()) { float energy = hl.getCurrentEnergyAtTimeStep(timeStep); if (energy > 0) { for (CpsEdge e : sN.getEdges()) { e.setFlow(e.getFlow() + energy); e.calculateState(simMode); } } } } public void setFlowSimulation(SubNet sN) { ArrayList producers = new ArrayList(); AbstractCpsObject tmp = null; tagTable = new HashMap(); for (HolonObject hl : sN.getObjects()) { float energy = hl.getCurrentEnergyAtTimeStep(timeStep); if (energy > 0) { tagTable.put(hl.getID(), energy); hl.addTag(hl.getID()); for (CpsEdge edge : hl.getConnections()) { if (edge.getState()) { if (edge.getA().getID() == hl.getID()) { edge.getB().addTag(hl.getID()); tmp = edge.getB(); } if (edge.getB().getID() == hl.getID()) { edge.getA().addTag(hl.getID()); tmp = edge.getA(); } edge.setFlow(edge.getFlow() + energy); edge.calculateState(true); edge.addTag(hl.getID()); if (edge.getState() && !producers.contains(tmp)) { producers.add(tmp); } } } } } setFlowSimRec(producers, 0); } public void setFlowSimRec(ArrayList nodes, int iter) { ArrayList newNodes = new ArrayList(); ArrayList pseudoTags = new ArrayList(); AbstractCpsObject tmp = null; if (nodes.size() != 0) { for (AbstractCpsObject cps : nodes) { for (CpsEdge edge : cps.getConnections()) { for (Integer tag : cps.getTag()) { if (edge.getState() && !(edge.getTags().contains(tag))) { edge.setFlow(edge.getFlow() + tagTable.get(tag)); edge.calculateState(true); edge.addTag(tag); if (edge.getA().getID() == cps.getID()) { tmp = edge.getB(); } if (edge.getB().getID() == cps.getID()) { tmp = edge.getA(); } if (tmp.getPseudoTags() != null) { pseudoTags.addAll(tmp.getPseudoTags()); } pseudoTags.addAll(cps.getTag()); tmp.setPseudoTags(mergeLists(tmp.getTag(), pseudoTags)); if (!edge.getState()) { newNodes.remove(edge.getA()); newNodes.remove(edge.getB()); if (edge.getA().getID() == cps.getID()) { edge.getB().getPseudoTags().removeAll(edge.getTags()); } if (edge.getB().getID() == cps.getID()) { edge.getA().getPseudoTags().removeAll(edge.getTags()); } } if (edge.getState() && !(newNodes.contains(tmp))) { newNodes.add(tmp); } } } edge.calculateState(true); } } // printNodes(newNodes); setPseudoTags(newNodes); setFlowSimRec(newNodes, iter + 1); } } public void setPseudoTags(ArrayList nodes) { for (AbstractCpsObject node : nodes) { node.setTags(node.getPseudoTags()); } } public void printNodes(ArrayList nodes) { System.out.println("new Nodes:"); for (AbstractCpsObject node : nodes) { System.out.println(node.getID()); } } public String getString(ArrayList tags) { String result = ""; for (Integer i : tags) { result = result + ", " + i; } return result; } public ArrayList mergeLists(ArrayList A, ArrayList B) { ArrayList result = new ArrayList(); for (Integer i : A) { if (!(result.contains(i))) { result.add(i); } } for (Integer j : B) { if (!(result.contains(j))) { result.add(j); } } return result; } public void ResetConnections(AbstractCpsObject cps, ArrayList visitedObj, ArrayList visitedEdges) { visitedObj.add(cps.getID()); cps.resetTags(); for (CpsEdge e : cps.getConnections()) { if (!(visitedEdges.contains(e))) { e.setFlow(0); e.calculateState(simMode); e.setTags(new ArrayList()); visitedEdges.add(e); if (!(visitedObj.contains(e.getA().getID()))) { ResetConnections(e.getA(), visitedObj, visitedEdges); e.getA().resetTags(); } if (!(visitedObj.contains(e.getB().getID()))) { ResetConnections(e.getB(), visitedObj, visitedEdges); e.getB().resetTags(); } } } } /** * calculates the energy of either all producers or consumers * * @param type * @param sN * @return */ public float calculateEnergy(String type, SubNet sN, int x) { float energy = 0; for (HolonObject hl : sN.getObjects()) { if (type.equals("prod")) { if (hl.getCurrentEnergyAtTimeStep(x) > 0) { energy = energy + hl.getCurrentEnergyAtTimeStep(x); hl.setState(3); } } if (type.equals("cons")) { if (hl.getCurrentEnergyAtTimeStep(x) < 0) { energy = energy + hl.getCurrentEnergyAtTimeStep(x); hl.setState(1); } } if (hl.getCurrentEnergyAtTimeStep(x) == 0) { hl.setState(0); } } return energy; } public float calculateMinimumEnergy(SubNet sN, int x) { float min = 0; float minElement = 0; for (HolonObject hl : sN.getObjects()) { if (hl.getElements().size() > 0 && hl.getElements().get(0).getTotalEnergyAtTimeStep(x) < 0) { minElement = hl.getElements().get(0).getTotalEnergyAtTimeStep(x); } for (HolonElement he : hl.getElements()) { if (minElement < he.getTotalEnergyAtTimeStep(x) && he.getTotalEnergyAtTimeStep(x) < 0) { minElement = he.getTotalEnergyAtTimeStep(x); } } min = min + minElement; } return min; } /** * generates all subNets from all objectsToHandle */ public void searchForSubNets() { subNets = new ArrayList(); boolean end = false; int i = 0; AbstractCpsObject cps; if (objectsToHandle.size() > 0) { while (!end) { cps = objectsToHandle.get(i); SubNet singleSubNet = new SubNet(new ArrayList(), new ArrayList(), new ArrayList()); singleSubNet = buildSubNet(cps, new ArrayList(), singleSubNet); if (singleSubNet.getObjects().size() != 0) { subNets.add(singleSubNet); } if (0 == objectsToHandle.size()) { end = true; } } } } /** * recursivly generates a subnet of all objects, that one specific object is * connected to * * @param cps * @param visited * @param sN * @return */ public SubNet buildSubNet(AbstractCpsObject cps, ArrayList visited, SubNet sN) { visited.add(cps.getID()); if (cps instanceof HolonObject) { sN.getObjects().add((HolonObject) cps); } if (cps instanceof HolonSwitch) { sN.getSwitches().add((HolonSwitch) cps); } removeFromToHandle(cps.getID()); AbstractCpsObject A; AbstractCpsObject B; for (CpsEdge edge : cps.getConnections()) { A = edge.getA(); B = edge.getB(); if (!(cps instanceof HolonSwitch)) { if (!(sN.getEdges().contains(edge))) { sN.getEdges().add(edge); } } if (!visited.contains(A.getID()) && legitState(A, cps)) { sN = buildSubNet(A, visited, sN); } if (!visited.contains(B.getID()) && legitState(B, cps)) { sN = buildSubNet(B, visited, sN); } } return sN; } public boolean legitState(AbstractCpsObject neighbor, AbstractCpsObject current) { if (current instanceof HolonSwitch) { if (((HolonSwitch) current).getState(timeStep)) { if (neighbor instanceof HolonSwitch) { if (((HolonSwitch) neighbor).getState(timeStep)) { return true; } else { return false; } } } else { return false; } } return true; } /** * removes an Object that already has been handled with * * @param id */ public void removeFromToHandle(int id) { for (int i = 0; i < objectsToHandle.size(); i++) { if (objectsToHandle.get(i).getID() == id) { objectsToHandle.remove(i); } } } /** * ensures that objectsToHandle only contains HolonObjects */ public void cleanObjectsToHandle() { for (int i = 0; i < objectsToHandle.size(); i++) { if (!(objectsToHandle.get(i) instanceof HolonObject)) { objectsToHandle.remove(i); } } } /** * copies the data of an array of Objects * * @param toCopy */ public void copyObjects(ArrayList toCopy) { objectsToHandle = new ArrayList(); for (AbstractCpsObject cps : toCopy) { objectsToHandle.add(cps); } } /** * Prints the Components auf all subnets */ public void printNet() { for (int i = 0; i < subNets.size(); i++) { System.out.println("SUBNET NR:" + i); System.out.println(" Objects:"); for (int j = 0; j < subNets.get(i).getObjects().size(); j++) { HolonObject hl = subNets.get(i).getObjects().get(j); System.out.println(" " + hl.getName() + " " + hl.getID()); } System.out.println(" Edges:"); for (int j = 0; j < subNets.get(i).getEdges().size(); j++) { CpsEdge edge = subNets.get(i).getEdges().get(j); System.out.println(" " + edge.getA().getName() + " connected To " + edge.getB().getName()); } System.out.println(" Switches:"); for (int j = 0; j < subNets.get(i).getSwitches().size(); j++) { HolonSwitch sw = subNets.get(i).getSwitches().get(j); System.out.println(" " + sw.getName() + " " + sw.getID() + " State:" + sw.getActiveAt()[timeStep]); } } } public void setCanvas(MyCanvas can) { canvas = can; } public void reset() { copyObjects(model.getObjectsOnCanvas()); } public ArrayList getSubNets() { return subNets; } }