123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125 |
- 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.getMinEnergy(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 neededEnergy = -hO.getCurrentEnergyAtTimeStep(x);
- if(neededEnergy < 0)continue; //Producer
- if(neededEnergy <= currentProduction)
- {
- hO.setCurrentSupply(neededEnergy+hO.getCurrentSupply());
- currentProduction -= neededEnergy;
- }else
- {
- hO.setCurrentSupply(currentProduction+hO.getCurrentSupply());
- 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.getMinEnergy(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
- .getMinEnergy(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.getMinEnergy(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.getMinEnergy(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.getMinEnergy(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
- */
- private 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
- */
- private 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;
- }
- }
|