12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127 |
- package ui.controller;
- import classes.*;
- import classes.comparator.EnergyMinToMaxComparator;
- import classes.comparator.MinEnergyComparator;
- import classes.comparator.WeakestBattery;
- import ui.model.Model;
- import ui.view.FlexiblePane;
- import ui.view.MyCanvas;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.HashMap;
- /**
- * Controller for Simulation.
- *
- * @author Gruppe14
- */
- public class SimulationManager {
- int global = 0;
- private Model model;
- private ArrayList<AbstractCpsObject> objectsToHandle;
- // private ArrayList<CpsEdge> allConnections;
- private ArrayList<SubNet> subNets;
- private ArrayList<CpsEdge> brokenEdges;
- private MyCanvas canvas;
- private int timeStep;
- private HashMap<Integer, Float> tagTable = new HashMap<>();
- private FlexiblePane flexPane;
- private HashMap<HolonElement, Float> flexDevicesTurnedOnThisTurn = new HashMap<>();
- /**
- * One Element of each HolonObject will be powered first, starting with the
- * smallest Demand. If ale HolonObjects have an active Element, the
- * simulation will try to fully supply as many HolonObjects as possible.
- */
- public static final short fairnessMininumDemandFirst = 0;
- /**
- * All HolonObjects will receive the same amount of energy.
- */
- public static final short fairnessAllEqual = 1;
- /**
- * Constructor.
- *
- * @param m
- * Model
- */
- SimulationManager(Model m) {
- canvas = null;
- model = m;
- subNets = new ArrayList<>();
- brokenEdges = new ArrayList<>();
- }
- /**
- * calculates the flow of the edges and the supply for objects.
- *
- * @param x
- * current Iteration
- */
- void calculateStateForTimeStep(int x) {
- reset();
- timeStep = x;
- searchForSubNets();
- for (SubNet singleSubNet : subNets) {
- if(singleSubNet.getObjects().size() == 0)
- {
- resetConnections(singleSubNet.getBatteries().get(0),
- new ArrayList<>(), new ArrayList<>());
- }else
- {
- resetConnections(singleSubNet.getObjects().get(0),
- new ArrayList<>(), new ArrayList<>());
- }
-
- }
- for (SubNet singleSubNet : subNets) {
- float production = calculateEnergyWithoutFlexDevices("prod",
- singleSubNet, timeStep);
- float consumption = calculateEnergyWithoutFlexDevices("cons",
- singleSubNet, timeStep);
- // surplus of energy is computed by sum, since consumption is a
- // negative value
- float energySurplus = production + consumption;
-
-
- //float minConsumption = calculateMinimumEnergy(singleSubNet, timeStep);
- // --------------- use flexible devices ---------------
- if (energySurplus != 0 && model.useFlexibleDevices()) {
- turnOnFlexibleDevices(singleSubNet, energySurplus, x);
- // if (!flexDevicesTurnedOnThisTurn.isEmpty()) {
- // System.out.println("The following devices were turned on in this turn: ");
- // System.out.println(flexDevicesTurnedOnThisTurn.toString());
- // }
- // recompute after having examined/turned on all flexible
- // devices
- production = calculateEnergyWithFlexDevices("prod",
- singleSubNet, timeStep);
- consumption = calculateEnergyWithFlexDevices("cons",
- singleSubNet, timeStep);
- energySurplus = production + consumption;
- }
- // --------------- set flow simulation ---------------
- setFlowSimulation(singleSubNet);
- // --------------- visualise graph ---------------
- /**
- * production of subnets, that might be partially turned on/off
- */
- float currentProduction = production;
- /**
- * HolonObjects that can be partially Supplied but might be fully
- * Supplied
- */
- /*
- ArrayList<HolonObject> partiallySuppliedList = new ArrayList<HolonObject>();
- /**
- * HolonObjects that can get the spare energy
- */
- //
- // ArrayList<HolonObject> notSuppliedList = new ArrayList<HolonObject>();
- /**
- * Number of HolonObjects that need to be supplied
- */
- // long numberOfConsumers = singleSubNet.getObjects().stream()
- // .filter(hl -> (hl.getState() != HolonObject.NO_ENERGY
- // && hl.getState() != HolonObject.PRODUCER && hl
- // .getConnectedTo().stream()
- // .filter(e -> (e.getFlow() > 0)).count() > 0))
- // .count();
- /**
- * energy each HolonObject receives in AlleEqualModus
- */
-
- if(energySurplus >= 0)
- {
- //Supply all consumer
- for(HolonObject hO : singleSubNet.getObjects())
- {
- float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
- if(neededEnergy < 0)
- {
- hO.setCurrentSupply(-neededEnergy);
- currentProduction -= -neededEnergy; //Subtract the Energy from the Production
- }
- }
- //Supply all Batterys with the left currentProduction
- singleSubNet.getBatteries().sort(new WeakestBattery(x));//Sort all batteries by the Value of ther StateOfCharge/Capasity
- for(HolonBattery hB : singleSubNet.getBatteries())
- {
- float energyToCollect = hB.getInAtTimeStep(x-1);
- if(currentProduction >= energyToCollect)
- {
- //change StateofCharge soc = soc + energyToCollect
- hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) + energyToCollect, x);
- currentProduction -= energyToCollect;
- }else
- {
- //change StateofCharge soc = soc + currentProduction
- hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) + currentProduction, x);
- currentProduction = 0;
- //no break must be calculatet for all break; //because no more energy
- }
- }
- //Over_Supply all consumer equal
- long nOConsumer = singleSubNet.getObjects().stream().filter(hl -> (hl.getCurrentEnergyAtTimeStep(x) < 0)).count();
- if(nOConsumer != 0)
- {
- //energy to seperated equal
- float EnergyOverSupplyPerHolonObject = currentProduction / nOConsumer;
- for(HolonObject hO : singleSubNet.getObjects())
- {
- float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
- if(neededEnergy < 0)
- {
- hO.setCurrentSupply(hO.getCurrentSupply() + EnergyOverSupplyPerHolonObject);
- }
- }
- currentProduction = 0;
- }
- }
- else
- {
- //Check all Battries what they can provide
- if(energySurplus + GetOutAllBatteries(singleSubNet.getBatteries(), x) >= 0)
- {
- singleSubNet.getBatteries().sort(new WeakestBattery(x));//.reverse();
- Collections.reverse(singleSubNet.getBatteries()); //most supplyed first
- //Get the NEEDED energy
- for(HolonBattery hB : singleSubNet.getBatteries())
- {
- float neededEnergyFromBattery = currentProduction + consumption; //Energy is negativ
- float maxEnergyAvailable = hB.getOutAtTimeStep(x-1); //energy is positiv
- if(maxEnergyAvailable >= -neededEnergyFromBattery)
- {
- //change StateofCharge soc = soc - -neededEnergyFromBattery
- hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) - -neededEnergyFromBattery, x);
- currentProduction += -neededEnergyFromBattery;
- //no break must be calculatet for all beabreak; //When a energy can supply the last needed energy break;
- }
- else
- {
- //change StateofCharge soc = soc - maxEnergyAvailable
- hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) - maxEnergyAvailable, x);
- currentProduction += maxEnergyAvailable;
- }
- }
- //Supply all consumer all ar in state Supplied no one is oversupplied because
- // just the energy that is needed is gained from the batteries
- for(HolonObject hO : singleSubNet.getObjects())
- {
- float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
- if(neededEnergy < 0)
- {
- hO.setCurrentSupply(-neededEnergy);
- currentProduction -= -neededEnergy; //Subtract the Energy from the Production
- }
- }
- }
- else //Objects have to be partially supplied
- {
- //Get all Energy out of battries as possible
- for(HolonBattery hB : singleSubNet.getBatteries())
- {
- float maxEnergyAvailable = hB.getOutAtTimeStep(x-1); //energy is positiv
- //change StateofCharge soc = soc - maxEnergyAvailable
- hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) - maxEnergyAvailable, x);
- currentProduction += maxEnergyAvailable;
- }
- //Calc
- singleSubNet.getObjects().stream().forEach(hl -> hl.setCurrentSupply(0));
- if(model.getFairnessModel() == fairnessAllEqual)
- {
- long nOConsumer = singleSubNet.getObjects().stream().filter(hl -> (hl.getCurrentEnergyAtTimeStep(x) < 0)).count();
- float energyPerHolonObject = 0;
- if (nOConsumer != 0)
- energyPerHolonObject = currentProduction / nOConsumer;
- for(HolonObject hO : singleSubNet.getObjects())
- {
- if(hO.getCurrentEnergyAtTimeStep(x) < 0) //Just Consumer need Energy
- {
- hO.setCurrentSupply(energyPerHolonObject);
- currentProduction -= energyPerHolonObject; //Subtract the Energy from the Production
- }
- }
- }
- else //(model.getFairnessModel() == fairnessMininumDemandFirst)
- {
- singleSubNet.getObjects().sort(new MinEnergyComparator(x));
- //SupplyAllMinimumEnergy
- for(HolonObject hO : singleSubNet.getObjects())
- {
- if(hO.checkIfPartiallySupplied(x))continue;
- if(hO.getCurrentEnergyAtTimeStep(x) > 0)continue;
- float minEnergy = -hO.getMinEnergyNecessaryAtTimestep(x); //Energy from getMinEnergy is negative -> convert to positive
- if(minEnergy <= currentProduction)
- {
- hO.setCurrentSupply(minEnergy);
- currentProduction -= minEnergy;
- }else
- {
- hO.setCurrentSupply(currentProduction);
- currentProduction = 0;
- break;
- }
- }
- singleSubNet.getObjects().sort(new EnergyMinToMaxComparator(x));
- //supplyFullytillEnd ... because its cant be fully supplied
- for(HolonObject hO : singleSubNet.getObjects())
- {
-
- float actualSupplyEnergy = hO.getCurrentSupply();
- float neededEnergy = -hO.getCurrentEnergyAtTimeStep(x) - actualSupplyEnergy;
- if(neededEnergy <= 0)continue; //Producer or No EnergyNeeded
- if(neededEnergy <= currentProduction)
- {
- hO.setCurrentSupply(neededEnergy+actualSupplyEnergy);
- currentProduction -= neededEnergy;
- }else
- {
- hO.setCurrentSupply(currentProduction+actualSupplyEnergy);
- currentProduction = 0;
- break;
- }
- }
-
-
- }
- }
-
- }
- //Visualize the Color
- for(HolonObject hO : singleSubNet.getObjects())
- {
- float neededEnergy = -hO.getCurrentEnergyAtTimeStep(x); // convert negative energy in positive for calculations
- if(neededEnergy < 0)
- {
- hO.setState(HolonObject.PRODUCER);
- }
- else if(neededEnergy > 0)
- {
- float currentSupply = hO.getCurrentSupply() ;
- if(currentSupply > neededEnergy)
- {
- hO.setState(HolonObject.OVER_SUPPLIED);
- }else if (currentSupply == neededEnergy)
- {
- hO.setState(HolonObject.SUPPLIED);
- }else if (currentSupply < neededEnergy)
- {
- float minEnergy = -hO.getMinEnergyNecessaryAtTimestep(x);
- if(currentSupply >= minEnergy || hO.getSelfMadeEnergy(x) >= minEnergy )
- {
- hO.setState(HolonObject.PARTIALLY_SUPPLIED);
- }else
- {
- hO.setState(HolonObject.NOT_SUPPLIED);
- }
- }
- }
- else if(neededEnergy == 0)
- {
- hO.setState(HolonObject.NO_ENERGY);
- }
- }
- }
- canvas.repaint();
- flexPane.recalculate();
- }
- private void calculation(int x, SubNet singleSubNet, float production, float consumption, float energySurplus,
- float currentProduction, ArrayList<HolonObject> partiallySuppliedList,
- ArrayList<HolonObject> notSuppliedList, float energyPerHolonObject) {
- long numberOfConsumers;
- if (model.getFairnessModel() == fairnessMininumDemandFirst) {
- /**
- * supply Buildings with minimal Energy first, if conflicts
- * happen
- */
- singleSubNet.getObjects().sort(new MinEnergyComparator(x));
- } else if (model.getFairnessModel() == fairnessAllEqual) {
- /*
- * give every building (just consumer) the same energy
- */
- numberOfConsumers = singleSubNet
- .getObjects()
- .stream()
- .filter(hl -> (hl.getState() != HolonObject.NO_ENERGY
- && hl.getState() != HolonObject.PRODUCER && hl
- .getConnectedTo().stream()
- .filter(e -> (e.getFlow() > 0)).count() > 0))
- .count();
- if (numberOfConsumers != 0)
- energyPerHolonObject = currentProduction / numberOfConsumers;
- }
- for (HolonObject hl : singleSubNet.getObjects()) {
- hl.setCurrentSupply(0);
- if (hl.getState() != HolonObject.NO_ENERGY
- && hl.getState() != HolonObject.PRODUCER) {
- for (int i = 0; i < hl.getConnections().size(); i++) {
- CpsEdge edge = hl.getConnectedTo().get(i);
- if (edge.isWorking()
- && edge.getFlow() > 0
- || edge.getCapacity() == CpsEdge.CAPACITY_INFINITE) {
- if (model.getFairnessModel() == fairnessAllEqual) {
- /* fairness: everyone receives the Same Energy */
- float neededEnergy = hl
- .getCurrentEnergyAtTimeStep(x);
- if (neededEnergy > 0) {
- hl.setState(HolonObject.PRODUCER);
- } else if (energyPerHolonObject > -neededEnergy) {
- hl.setState(HolonObject.OVER_SUPPLIED);
- } else if (energyPerHolonObject == -neededEnergy) {
- hl.setState(HolonObject.SUPPLIED);
- } else if (energyPerHolonObject >= -hl
- .getMinEnergyNecessaryAtTimestep(x)) {
- hl.setState(HolonObject.PARTIALLY_SUPPLIED);
- } else {
- hl.setState(HolonObject.NOT_SUPPLIED);
- }
- hl.setCurrentSupply(energyPerHolonObject);
- } else if (model.getFairnessModel() == fairnessMininumDemandFirst) {
- /* fairness: minimum demand gets Energy first */
- if ((production + consumption) >= 0) {
- if (energySurplus > 0) {
- hl.setState(HolonObject.OVER_SUPPLIED);
- hl.setCurrentSupply((-energySurplus
- / consumption + 1)
- * hl.getCurrentEnergyAtTimeStep(x));
- } else {
- hl.setState(HolonObject.SUPPLIED);
- hl.setCurrentSupply(-hl
- .getCurrentEnergyAtTimeStep(x));
- }
- } else {
- float minEnergy = hl.getMinEnergyNecessaryAtTimestep(x);
- if (hl.checkIfPartiallySupplied(timeStep)) {
- hl.setState(HolonObject.PARTIALLY_SUPPLIED);
- currentProduction += minEnergy;
- hl.setCurrentSupply(-minEnergy);
- partiallySuppliedList.add(hl);
- } else {
- /**
- * Case that only some HolonObjects can
- * be supplied
- */
- if (-hl.getCurrentEnergyAtTimeStep(x) <= currentProduction) {
- hl.setState(HolonObject.PARTIALLY_SUPPLIED);
- currentProduction += minEnergy;
- hl.setCurrentSupply(-minEnergy);
- partiallySuppliedList.add(hl);
- } else if (-hl.getMinEnergyNecessaryAtTimestep(x) <= currentProduction) {
- hl.setState(HolonObject.PARTIALLY_SUPPLIED);
- currentProduction += minEnergy;
- hl.setCurrentSupply(-minEnergy);
- partiallySuppliedList.add(hl);
- } else {
- hl.setState(HolonObject.NOT_SUPPLIED);
- hl.setCurrentSupply(0.0f);
- notSuppliedList.add(hl);
- // currentProduction +=
- // hl.getCurrentEnergyAtTimeStep(x);
- }
- }
- }
- }
- hl.getCurrentEnergyAtTimeStep(x);
- break;
- }
- }
- /**
- * check if some object cn self supply itself
- */
- if (hl.checkIfPartiallySupplied(timeStep)
- && hl.getState() != HolonObject.SUPPLIED
- && hl.getState() != HolonObject.OVER_SUPPLIED) {
- hl.setState(HolonObject.PARTIALLY_SUPPLIED);
- }
- }
- }
- if (model.getFairnessModel() == fairnessMininumDemandFirst) {
- /**
- * check if some partially supplied building might be fully
- * supplied.
- */
- partiallySuppliedList.sort(new EnergyMinToMaxComparator(x));
- for (HolonObject hl : partiallySuppliedList) {
- float minEnergy = hl.getMinEnergyNecessaryAtTimestep(x);
- currentProduction -= minEnergy;
- /*
- * if possible, supply fully
- */
- float currentEnergyAtTimeStep = hl
- .getCurrentEnergyAtTimeStep(x);
- if (-currentEnergyAtTimeStep <= currentProduction) {
- hl.setState(HolonObject.SUPPLIED);
- currentProduction += currentEnergyAtTimeStep;
- hl.setCurrentSupply(-currentEnergyAtTimeStep);
- hl.getCurrentEnergyAtTimeStep(x);
- } else {
- currentProduction += minEnergy;
- notSuppliedList.add(hl);
- }
- }
- if (!notSuppliedList.isEmpty() && currentProduction > 0) {
- float energyPerHolon = currentProduction
- / notSuppliedList.size();
- for (HolonObject hl : notSuppliedList) {
- hl.setCurrentSupply(hl.getCurrentSupply()
- + energyPerHolon);
- hl.getCurrentEnergyAtTimeStep(x);
- }
- }
- }
- }
- /**
- * add all battries.getOut() from a list of battries and return them
- * @param aL a List of HolonBattries likely from subnet.getBatteries()
- * @param x TimeStep
- * @return
- *
- */
- private float GetOutAllBatteries(ArrayList<HolonBattery> aL, int x)
- {
- float OutEnergy = 0;
- for(HolonBattery hB : aL)
- {
- //System.out.println("Iteration: "+ x +"OutBattery: "+ hB.getOutAtTimeStep(x-1));
- OutEnergy += hB.getOutAtTimeStep(x-1);
- }
- //System.out.println("Iteration: "+ x +"GetOutAllBatteries: "+ OutEnergy);
- return OutEnergy;
- }
- /**
- * search for all flexible devices in the network and turn them on, until
- * energy surplus = 0 or all devices have been examined.
- *
- * This code could be compressed (cases inside over- and underproduction are
- * the same), but we decided that it is better readable this way
- *
- * @param subNet
- * the subnet
- * @param energySurplus
- * the current surplus of energy
- */
- private void turnOnFlexibleDevices(SubNet subNet, float energySurplus,
- int timestep) {
- for (HolonObject holonOb : subNet.getObjects()) {
- for (HolonElement holonEl : holonOb.getElements()) {
- // if this element is flexible and active (can be considered for
- // calculations)
- if (holonEl.isFlexible() && holonEl.isActive()) {
- float energyAvailableSingle = holonEl
- .getAvailableEnergyAt(timestep);
- float energyAvailableMultiple = energyAvailableSingle
- * holonEl.getAmount();
- // ------------- flexible consumer / OVERPRODUCTION
- // -------------
- if (energyAvailableMultiple < 0 && energySurplus > 0) {
- // if there is more wasted energy than energy that this
- // device can give, give all energy available
- if (Math.abs(energyAvailableMultiple) <= Math
- .abs(energySurplus)) {
- energySurplus += energyAvailableMultiple;
- // set the new energy consumption to the maximum
- holonEl.setEnergyPerElement(energyAvailableSingle);
- flexDevicesTurnedOnThisTurn.put(holonEl,
- energyAvailableMultiple);
- }
- // else: we just need to turn on part of the flexible
- // energy available
- else {
- float energyNeeded = -energySurplus;
- energySurplus += energyNeeded; // should give 0, but
- // was kept this was
- // for consistency
- // the energy needed divided through the amount of
- // elements
- holonEl.setEnergyPerElement(energyNeeded
- / holonEl.getAmount());
- flexDevicesTurnedOnThisTurn.put(holonEl,
- energyNeeded);
- }
- }
- // ------------- flexible producer / UNDERPRODUCTION
- // -------------
- else if (energyAvailableMultiple > 0 && energySurplus < 0) {
- // if there is more energy needed than this device can
- // give, give all the energy available
- if (Math.abs(energyAvailableMultiple) <= Math
- .abs(energySurplus)) {
- energySurplus += energyAvailableMultiple;
- // set the new energy consumption to the maximum
- holonEl.setEnergyPerElement(energyAvailableSingle);
- flexDevicesTurnedOnThisTurn.put(holonEl,
- energyAvailableMultiple);
- }
- // else: we just need to turn on part of the flexible
- // energy available
- else {
- float energyNeeded = -energySurplus;
- int i = 0;
- energySurplus += energyNeeded; // should give 0, but
- // was kept this was
- // for consistency
- // the energy needed divided through the amount of
- // elements
- holonEl.setEnergyPerElement(energyNeeded
- / holonEl.getAmount());
- flexDevicesTurnedOnThisTurn.put(holonEl,
- energyNeeded);
- }
- }
- }
- if (energySurplus == 0) {
- break;
- }
- }
- if (energySurplus == 0) {
- break;
- }
- }
- }
- /**
- * Set Flow Simulation.
- *
- * @param sN
- * Subnet
- */
- private void setFlowSimulation(SubNet sN) {
- ArrayList<AbstractCpsObject> producers = new ArrayList<>();
- AbstractCpsObject tmp = null;
- tagTable = new HashMap<>();
- // traverse all objects in this subnet
- for (HolonObject hl : sN.getObjects()) {
- float energy = hl.getCurrentEnergyAtTimeStep(timeStep);
- // if their production is higher than their consumption
- if (energy > 0) {
- tagTable.put(hl.getId(), energy);
- hl.addTag(hl.getId());
- for (CpsEdge edge : hl.getConnections()) {
- if (edge.isWorking()) {
- // set other end of edge as tmp-object
- // and add this end to the other end's tag-list
- AbstractCpsObject a = edge.getA();
- AbstractCpsObject b = edge.getB();
- if (a.getId() == hl.getId()) {
- b.addTag(hl.getId());
- tmp = b;
- }
- if (b.getId() == hl.getId()) {
- a.addTag(hl.getId());
- tmp = a;
- }
- edge.setFlow(edge.getFlow() + energy);
- edge.calculateState();
- edge.addTag(hl.getId());
- if (edge.isWorking() && !producers.contains(tmp)) {
- if (tmp instanceof HolonSwitch) {
- if (((HolonSwitch) tmp).getState(timeStep)) {
- producers.add(tmp);
- }
- } else if (!(tmp instanceof CpsUpperNode)) {
- producers.add(tmp);
- }
- }
- }
- }
- }
- }
- setFlowSimRec(producers, 0);
- }
- /**
- * Set Flow Simulation Rec.
- *
- * @param nodes
- * the nodes
- * @param iter
- * the Iteration
- */
- private void setFlowSimRec(ArrayList<AbstractCpsObject> nodes, int iter) {
- ArrayList<AbstractCpsObject> newNodes = new ArrayList<>();
- ArrayList<CpsEdge> changedEdges = new ArrayList<>();
- AbstractCpsObject tmp;
- if (nodes.size() != 0) {
- for (AbstractCpsObject cps : nodes) {
- // check whether the cps is in a legit state if it is a switch
- if (legitState(cps)) {
- for (CpsEdge edge : cps.getConnections()) {
- // is edge working
- // and does the edge's tag-list not (yet) contain all
- // tags of the cps
- if (edge.isWorking()
- && (!(edge.containsTags(edge.getTags(),
- cps.getTag())))) {
- if (edge.getA().getId() == cps.getId()) {
- tmp = edge.getB();
- } else {
- tmp = edge.getA();
- }
- for (Integer tag : cps.getTag()) {
- if (!(edge.getTags().contains(tag))
- && !(edge.getPseudoTags().contains(tag))) {
- edge.setFlow(edge.getFlow()
- + tagTable.get(tag));
- edge.addTag(tag);
- }
- }
- // uppernodes do not spread energy
- if (!(tmp instanceof CpsUpperNode)) {
- for (Integer tag : tmp.getTag()) {
- if (!(edge.getTags().contains(tag))
- && tagTable.get(tag) != null
- && !(edge.getPseudoTags()
- .contains(tag))) {
- edge.setFlow(edge.getFlow()
- + tagTable.get(tag));
- edge.addPseudoTag(tag);
- changedEdges.add(edge);
- }
- }
- }
- edge.calculateState();
- if (edge.isWorking()
- && !(tmp instanceof CpsUpperNode)) {
- tmp.addAllPseudoTags(cps.getTag());
- if (!newNodes.contains(tmp)) {
- newNodes.add(tmp);
- }
- }
- }
- }
- }
- }
- setPseudoTags(newNodes, changedEdges);
- setFlowSimRec(newNodes, iter + 1);
- }
- }
- /**
- * Set the Pseudo Tags.
- *
- * @param nodes
- * Array of AbstractCpsObjects
- */
- private void setPseudoTags(ArrayList<AbstractCpsObject> nodes,
- ArrayList<CpsEdge> edges) {
- for (AbstractCpsObject node : nodes) {
- node.recalculateTags();
- node.setPseudoTags(new ArrayList<>());
- }
- for (CpsEdge edge : edges) {
- edge.recalculateTags();
- edge.setPseudoTag(new ArrayList<>());
- }
- }
- /**
- * Reset the Connection.
- *
- * @param cps
- * CpsObject
- * @param visitedObj
- * the visited Objects
- * @param visitedEdges
- * the visited Edges
- */
- private void resetConnections(AbstractCpsObject cps,
- ArrayList<Integer> visitedObj, ArrayList<CpsEdge> visitedEdges) {
- visitedObj.add(cps.getId());
- cps.resetTags();
- for (CpsEdge e : cps.getConnections()) {
- if (!(visitedEdges.contains(e))) {
- e.setFlow(0);
- e.calculateState();
- 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. Flexible
- * devices are filtered out
- *
- * @param type
- * Type
- * @param sN
- * Subnet
- * @param x
- * Integer
- * @return The Energy
- */
- public float calculateEnergyWithoutFlexDevices(String type, SubNet sN,
- int x) {
- float energy = 0;
- for (HolonObject hl : sN.getObjects()) {
- float currentEnergyWithoutFlexibles = hl
- .getCurrentEnergyAtTimeStepWithoutFlexiblesAndResetFlexibles(x);
- if (type.equals("prod")) {
- if (currentEnergyWithoutFlexibles > 0) {
- energy += currentEnergyWithoutFlexibles;
- hl.setState(HolonObject.PRODUCER);
- }
- }
- if (type.equals("cons")) {
- if (currentEnergyWithoutFlexibles < 0) {
- energy += currentEnergyWithoutFlexibles;
- hl.setState(HolonObject.NOT_SUPPLIED);
- }
- }
- if (currentEnergyWithoutFlexibles == 0) {
- hl.setState(HolonObject.NO_ENERGY);
- }
- }
- return energy;
- }
- /**
- * calculates the energy of either all producers or consumers. Flexible
- * devices are filtered out
- *
- * @param type
- * Type
- * @param sN
- * Subnet
- * @param x
- * Integer
- * @return The Energy
- */
- public float calculateEnergyWithFlexDevices(String type, SubNet sN, int x) {
- float energy = 0;
- for (HolonObject hl : sN.getObjects()) {
- float currentEnergy = hl.getCurrentEnergyAtTimeStep(x);
- if (type.equals("prod")) {
- if (currentEnergy > 0) {
- energy += currentEnergy;
- hl.setState(HolonObject.PRODUCER);
- }
- }
- if (type.equals("cons")) {
- if (currentEnergy < 0) {
- energy = energy + currentEnergy;
- hl.setState(HolonObject.NOT_SUPPLIED);
- }
- }
- if (currentEnergy == 0) {
- hl.setState(HolonObject.NO_ENERGY);
- }
- }
- return energy;
- }
- /**
- * Calculate the Minimum Energy of a Subnet.
- *
- * @param sN
- * Subnet
- * @param x
- * Integer
- * @return the Calculated minimum Energy of a Subnet
- */
- private float calculateMinimumEnergy(SubNet sN, int x) {
- float minimummConsumptionSubnet = 0;
- for (HolonObject hl : sN.getObjects()) {
- float minElement = 0;
- // Search for a activ element
- for (HolonElement he : hl.getElements()) {
- if (he.isActive()) {
- float overallEnergy = he.getOverallEnergyAtTimeStep(x);
- if (overallEnergy < 0) {
- // Is a consumer
- minElement = overallEnergy;
- }
- }
- }
- for (HolonElement he : hl.getElements()) {
- if (he.isActive()) {
- float overallEnergy = he.getOverallEnergyAtTimeStep(x);
- if (minElement < overallEnergy && overallEnergy < 0) {
- // is a smaller consumer
- minElement = overallEnergy;
- }
- }
- }
- minimummConsumptionSubnet += minElement;
- }
- System.out.println("MinimumEnergy = "+ minimummConsumptionSubnet);
- return minimummConsumptionSubnet;
- }
- /**
- * generates all subNets from all objectsToHandle.
- */
- private void searchForSubNets() {
- subNets = new ArrayList<>();
- brokenEdges.clear();
- 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<>(), new ArrayList<>());
- singleSubNet = buildSubNet(cps, new ArrayList<>(), singleSubNet);
- if (singleSubNet.getObjects().size() + singleSubNet.getBatteries().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
- * AbstractCpsObject
- * @param visited
- * visited Array of Integer
- * @param sN
- * Subnets
- * @return Subnet
- */
- private SubNet buildSubNet(AbstractCpsObject cps,
- ArrayList<Integer> 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);
- }
- if (cps instanceof HolonBattery) {
- sN.getBatteries().add((HolonBattery) cps);
- }
- removeFromToHandle(cps.getId());
- AbstractCpsObject a;
- AbstractCpsObject b;
- for (CpsEdge edge : cps.getConnections()) {
- if (edge.isWorking()) {
- a = edge.getA();
- b = edge.getB();
- if (!(cps instanceof HolonSwitch)) {
- if (!(sN.getEdges().contains(edge))) {
- sN.getEdges().add(edge);
- }
- }
- if (cps instanceof HolonSwitch
- && ((HolonSwitch) cps).getState(timeStep)) {
- if (!(sN.getEdges().contains(edge))) {
- sN.getEdges().add(edge);
- }
- }
- if (!visited.contains(a.getId()) && legitState(cps)
- && !(a instanceof CpsUpperNode)) {
- sN = buildSubNet(a, visited, sN);
- }
- if (!visited.contains(b.getId()) && legitState(cps)
- && !(b instanceof CpsUpperNode)) {
- sN = buildSubNet(b, visited, sN);
- }
- if (a instanceof CpsUpperNode && a.getId() != cps.getId()) {
- edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
- checkForConnectedStates(b, (CpsUpperNode) a, edge);
- }
- if (b instanceof CpsUpperNode && b.getId() != cps.getId()) {
- edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
- checkForConnectedStates(a, (CpsUpperNode) b, edge);
- }
- } else {
- brokenEdges.add(edge);
- }
- }
- return sN;
- }
- /**
- * is the Switch in a legitimate State.
- *
- * @param current
- * AbstractCpsObject
- * @return boolean
- */
- private boolean legitState(AbstractCpsObject current) {
- return !(current instanceof HolonSwitch)
- || ((HolonSwitch) current).getState(timeStep);
- }
- // /**
- // * 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);
- // }
- // }
- // }
- /**
- * removes an Object that already has been handled.
- *
- * @param id
- * the Object ID
- */
- private void removeFromToHandle(int id) {
- for (int i = 0; i < objectsToHandle.size(); i++) {
- if (objectsToHandle.get(i).getId() == id) {
- objectsToHandle.remove(i);
- }
- }
- }
- /**
- * copies the data of an array of Objects.
- *
- * @param toCopy
- * the ArrayList of CpsObjects co Copy
- */
- private void copyObjects(ArrayList<AbstractCpsObject> toCopy) {
- for (AbstractCpsObject cps : toCopy) {
- if (cps instanceof CpsUpperNode) {
- copyObjects(((CpsUpperNode) cps).getNodes());
- } else {
- objectsToHandle.add(cps);
- }
- }
- }
- /**
- * Prints the Components auf all subnets.
- */
- private void printNetsToConsole() {
- for (int i = 0; i < subNets.size(); i++) {
- SubNet subNet = subNets.get(i);
- System.out.println("SUBNET NR:" + i);
- subNet.toString(timeStep);
- }
- }
- /**
- * Set the Canvas.
- *
- * @param can
- * the Canvas
- */
- public void setCanvas(MyCanvas can) {
- canvas = can;
- }
- /**
- * Reset all Data to the current state of the Model.
- */
- public void reset() {
- objectsToHandle = new ArrayList<>();
- copyObjects(model.getObjectsOnCanvas());
- flexDevicesTurnedOnThisTurn = new HashMap<>();
- }
- /**
- * Resets the State of all Edges
- */
- private void resetEdges() {
- for (CpsEdge e : brokenEdges) {
- e.setWorkingState(true);
- }
- }
- /**
- * Resets the State for the whole Simulation Model
- */
- void resetSimulation() {
- reset();
- resetEdges();
- }
- /**
- * Get all Subnets.
- *
- * @return all Subnets
- */
- public ArrayList<SubNet> getSubNets() {
- return subNets;
- }
- /**
- * Get broken Edges
- */
- // public ArrayList<CpsEdge> getBrokenEdges() {
- // return brokenEdges;
- // }
- /**
- * checks whether a given object is connected to an object inside the
- * upperNode. if yes, the state for the edge is changed in "connected" or
- * "not connected"
- */
- private void checkForConnectedStates(AbstractCpsObject cps,
- CpsUpperNode cUNode, CpsEdge theEdge) {
- AbstractCpsObject tmp;
- for (CpsEdge edge : cps.getConnections()) {
- if (edge.getA().getId() == cps.getId()) {
- tmp = edge.getB();
- } else {
- tmp = edge.getA();
- }
- if (cUNode.getNodes().contains(tmp)) {
- if (tmp instanceof CpsUpperNode) {
- checkForConnectedStates(cps, (CpsUpperNode) tmp, theEdge);
- } else {
- theEdge.setConnected(CpsEdge.CON_UPPER_NODE_AND_INSIDE);
- break;
- }
- }
- }
- }
- public FlexiblePane getFlexiblePane() {
- return flexPane;
- }
- void setFlexiblePane(FlexiblePane fp) {
- flexPane = fp;
- }
- }
|