SimulationManager.java 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068
  1. package ui.controller;
  2. import classes.*;
  3. import classes.comparator.EnergyMinToMaxComparator;
  4. import classes.comparator.MinEnergyComparator;
  5. import classes.comparator.TotalEnergyComparator;
  6. import classes.comparator.WeakestBattery;
  7. import ui.model.Model;
  8. import ui.view.FlexiblePane;
  9. import ui.view.MyCanvas;
  10. import java.util.ArrayList;
  11. import java.util.Collections;
  12. import java.util.HashMap;
  13. import com.sun.xml.internal.ws.util.xml.XMLReaderComposite.State;
  14. /**
  15. * Controller for Simulation.
  16. *
  17. * @author Gruppe14
  18. */
  19. public class SimulationManager {
  20. int global = 0;
  21. private Model model;
  22. private ArrayList<AbstractCpsObject> objectsToHandle;
  23. // private ArrayList<CpsEdge> allConnections;
  24. private ArrayList<SubNet> subNets;
  25. private ArrayList<CpsEdge> brokenEdges;
  26. private MyCanvas canvas;
  27. private int timeStep;
  28. private HashMap<Integer, Float> tagTable = new HashMap<>();
  29. private FlexiblePane flexPane;
  30. private HashMap<HolonElement, Float> flexDevicesTurnedOnThisTurn = new HashMap<>();
  31. /**
  32. * One Element of each HolonObject will be powered first, starting with the
  33. * smallest Demand. If ale HolonObjects have an active Element, the
  34. * simulation will try to fully supply as many HolonObjects as possible.
  35. */
  36. public static final short fairnessMininumDemandFirst = 0;
  37. /**
  38. * All HolonObjects will receive the same amount of energy.
  39. */
  40. public static final short fairnessAllEqual = 1;
  41. /**
  42. * Constructor.
  43. *
  44. * @param m
  45. * Model
  46. */
  47. SimulationManager(Model m) {
  48. canvas = null;
  49. model = m;
  50. subNets = new ArrayList<>();
  51. brokenEdges = new ArrayList<>();
  52. }
  53. /**
  54. * calculates the flow of the edges and the supply for objects.
  55. *
  56. * @param x
  57. * current Iteration
  58. */
  59. void calculateStateForTimeStep(int x) {
  60. reset();
  61. timeStep = x;
  62. searchForSubNets();
  63. for (SubNet singleSubNet : subNets) {
  64. resetConnections(singleSubNet.getObjects().get(0),
  65. new ArrayList<>(), new ArrayList<>());
  66. }
  67. for (SubNet singleSubNet : subNets) {
  68. float production = calculateEnergyWithoutFlexDevices("prod",
  69. singleSubNet, timeStep);
  70. float consumption = calculateEnergyWithoutFlexDevices("cons",
  71. singleSubNet, timeStep);
  72. // surplus of energy is computed by sum, since consumption is a
  73. // negative value
  74. float energySurplus = production + consumption;
  75. //float minConsumption = calculateMinimumEnergy(singleSubNet, timeStep);
  76. // --------------- use flexible devices ---------------
  77. if (energySurplus != 0 && model.useFlexibleDevices()) {
  78. turnOnFlexibleDevices(singleSubNet, energySurplus, x);
  79. // if (!flexDevicesTurnedOnThisTurn.isEmpty()) {
  80. // System.out.println("The following devices were turned on in this turn: ");
  81. // System.out.println(flexDevicesTurnedOnThisTurn.toString());
  82. // }
  83. // recompute after having examined/turned on all flexible
  84. // devices
  85. production = calculateEnergyWithFlexDevices("prod",
  86. singleSubNet, timeStep);
  87. consumption = calculateEnergyWithFlexDevices("cons",
  88. singleSubNet, timeStep);
  89. energySurplus = production + consumption;
  90. }
  91. // --------------- set flow simulation ---------------
  92. setFlowSimulation(singleSubNet);
  93. // --------------- visualise graph ---------------
  94. /**
  95. * production of subnets, that might be partially turned on/off
  96. */
  97. float currentProduction = production;
  98. /**
  99. * HolonObjects that can be partially Supplied but might be fully
  100. * Supplied
  101. */
  102. ArrayList<HolonObject> partiallySuppliedList = new ArrayList<HolonObject>();
  103. /**
  104. * HolonObjects that can get the spare energy
  105. */
  106. ArrayList<HolonObject> notSuppliedList = new ArrayList<HolonObject>();
  107. /**
  108. * Number of HolonObjects that need to be supplied
  109. */
  110. long numberOfConsumers = singleSubNet.getObjects().stream()
  111. .filter(hl -> (hl.getState() != HolonObject.NO_ENERGY
  112. && hl.getState() != HolonObject.PRODUCER && hl
  113. .getConnectedTo().stream()
  114. .filter(e -> (e.getFlow() > 0)).count() > 0))
  115. .count();
  116. /**
  117. * energy each HolonObject receives in AlleEqualModus
  118. */
  119. float energyPerHolonObject = 0;
  120. if(energySurplus >= 0)
  121. {
  122. //Supply all consumer
  123. for(HolonObject hO : singleSubNet.getObjects())
  124. {
  125. float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
  126. if(neededEnergy < 0)
  127. {
  128. hO.setCurrentSupply(-neededEnergy);
  129. currentProduction -= -neededEnergy; //Subtract the Energy from the Production
  130. }
  131. }
  132. //Supply all Batterys with the left currentProduction
  133. System.out.println("production: "+production + " consumption: "+ consumption);
  134. singleSubNet.getBatteries().sort(new WeakestBattery());//Sort all batteries by the Value of ther StateOfCharge/Capasity
  135. for(HolonBattery hB : singleSubNet.getBatteries())
  136. {
  137. float energyToCollect = hB.getInAtTimeStep(x);
  138. if(currentProduction >= energyToCollect)
  139. {
  140. //TODO: change StateofCharge soc = soc + energyToCollect
  141. hB.setNewStateOfCharge(hB.getStateOfCharge() + energyToCollect);
  142. hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) + energyToCollect, x);
  143. currentProduction -= energyToCollect;
  144. }else
  145. {
  146. //TODO: change StateofCharge soc = soc + currentProduction
  147. hB.setNewStateOfCharge(hB.getStateOfCharge() + currentProduction);
  148. hB.setStateOfChargeAtTimeStep(hB.getStateOfChargeAtTimeStep(x-1) + currentProduction, x);
  149. currentProduction = 0;
  150. //no break must be calculatet for all break; //because no more energy
  151. }
  152. System.out.println(hB.toString() + " currentProduction: "+ currentProduction);
  153. }
  154. //Over_Supply all consumer equal
  155. long nOConsumer = singleSubNet.getObjects().stream().filter(hl -> (hl.getCurrentEnergyAtTimeStep(x) < 0)).count();
  156. if(nOConsumer != 0)
  157. {
  158. //energy to seperated equal
  159. float EnergyOverSupplyPerHolonObject = currentProduction / nOConsumer;
  160. for(HolonObject hO : singleSubNet.getObjects())
  161. {
  162. float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
  163. if(neededEnergy < 0)
  164. {
  165. hO.setCurrentSupply(hO.getCurrentSupply() + EnergyOverSupplyPerHolonObject);
  166. }
  167. }
  168. currentProduction = 0;
  169. }
  170. }
  171. else
  172. {
  173. //Check all Battries what they can provide
  174. if(energySurplus + GetOutAllBatteries(singleSubNet.getBatteries(), x) >= 0)
  175. {
  176. singleSubNet.getBatteries().sort(new WeakestBattery());//.reverse();
  177. Collections.reverse(singleSubNet.getBatteries()); //most supplyed first
  178. //Get the NEEDED energy
  179. for(HolonBattery hB : singleSubNet.getBatteries())
  180. {
  181. float neededEnergyFromBattery = currentProduction + consumption; //Energy is negativ
  182. float maxEnergyAvailable = hB.getOutAtTimeStep(x); //energy is positiv
  183. if(maxEnergyAvailable >= -neededEnergyFromBattery)
  184. {
  185. //TODO: change StateofCharge soc = soc - -neededEnergyFromBattery
  186. hB.setNewStateOfCharge(hB.getStateOfCharge() - -neededEnergyFromBattery);
  187. currentProduction += -neededEnergyFromBattery;
  188. //no break must be calculatet for all beabreak; //When a energy can supply the last needed energy break;
  189. }
  190. else
  191. {
  192. //TODO: change StateofCharge soc = soc - maxEnergyAvailable
  193. hB.setNewStateOfCharge(hB.getStateOfCharge() - maxEnergyAvailable);
  194. currentProduction += maxEnergyAvailable;
  195. }
  196. }
  197. //Supply all consumer all ar in state Supplied no one is oversupplied because
  198. // just the energy that is needed is gained from the batteries
  199. for(HolonObject hO : singleSubNet.getObjects())
  200. {
  201. float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
  202. if(neededEnergy < 0)
  203. {
  204. hO.setCurrentSupply(-neededEnergy);
  205. currentProduction -= -neededEnergy; //Subtract the Energy from the Production
  206. }
  207. }
  208. }
  209. else //Objects have to be partially supplied
  210. {
  211. //Get all Energy out of battries as possible
  212. for(HolonBattery hB : singleSubNet.getBatteries())
  213. {
  214. float maxEnergyAvailable = hB.getOutAtTimeStep(x); //energy is positiv
  215. //TODO: change StateofCharge soc = soc - maxEnergyAvailable
  216. hB.setNewStateOfCharge(hB.getStateOfCharge() - maxEnergyAvailable);
  217. currentProduction += maxEnergyAvailable;
  218. }
  219. calculation(x, singleSubNet, production, consumption, energySurplus, currentProduction,
  220. partiallySuppliedList, notSuppliedList, energyPerHolonObject);
  221. }
  222. }
  223. //Visualize the Color
  224. for(HolonObject hO : singleSubNet.getObjects())
  225. {
  226. float neededEnergy = hO.getCurrentEnergyAtTimeStep(x);
  227. if(neededEnergy > 0)
  228. {
  229. hO.setState(HolonObject.PRODUCER);
  230. }
  231. else if(neededEnergy < 0)
  232. {
  233. float currentSupply = hO.getCurrentSupply();
  234. if(currentSupply > -neededEnergy)
  235. {
  236. hO.setState(HolonObject.OVER_SUPPLIED);
  237. }else if (currentSupply == -neededEnergy)
  238. {
  239. hO.setState(HolonObject.SUPPLIED);
  240. }else if (currentSupply < -neededEnergy)
  241. {
  242. if(currentSupply >= hO.getMinEnergy(x))
  243. {
  244. hO.setState(HolonObject.PARTIALLY_SUPPLIED);
  245. }else
  246. {
  247. hO.setState(HolonObject.NOT_SUPPLIED);
  248. }
  249. }
  250. }
  251. else if(neededEnergy == 0)
  252. {
  253. hO.setState(HolonObject.NO_ENERGY);
  254. }
  255. }
  256. //Old Calculation
  257. // calculation(x, singleSubNet, production, consumption, energySurplus, currentProduction,
  258. // partiallySuppliedList, notSuppliedList, energyPerHolonObject);
  259. }
  260. canvas.repaint();
  261. flexPane.recalculate();
  262. }
  263. private void calculation(int x, SubNet singleSubNet, float production, float consumption, float energySurplus,
  264. float currentProduction, ArrayList<HolonObject> partiallySuppliedList,
  265. ArrayList<HolonObject> notSuppliedList, float energyPerHolonObject) {
  266. long numberOfConsumers;
  267. if (model.getFairnessModel() == fairnessMininumDemandFirst) {
  268. /**
  269. * supply Buildings with minimal Energy first, if conflicts
  270. * happen
  271. */
  272. singleSubNet.getObjects().sort(new MinEnergyComparator(x));
  273. } else if (model.getFairnessModel() == fairnessAllEqual) {
  274. /*
  275. * give every building (just consumer) the same energy
  276. */
  277. numberOfConsumers = singleSubNet
  278. .getObjects()
  279. .stream()
  280. .filter(hl -> (hl.getState() != HolonObject.NO_ENERGY
  281. && hl.getState() != HolonObject.PRODUCER && hl
  282. .getConnectedTo().stream()
  283. .filter(e -> (e.getFlow() > 0)).count() > 0))
  284. .count();
  285. if (numberOfConsumers != 0)
  286. energyPerHolonObject = currentProduction / numberOfConsumers;
  287. }
  288. for (HolonObject hl : singleSubNet.getObjects()) {
  289. hl.setCurrentSupply(0);
  290. if (hl.getState() != HolonObject.NO_ENERGY
  291. && hl.getState() != HolonObject.PRODUCER) {
  292. for (int i = 0; i < hl.getConnections().size(); i++) {
  293. CpsEdge edge = hl.getConnectedTo().get(i);
  294. if (edge.isWorking()
  295. && edge.getFlow() > 0
  296. || edge.getCapacity() == CpsEdge.CAPACITY_INFINITE) {
  297. if (model.getFairnessModel() == fairnessAllEqual) {
  298. /* fairness: everyone receives the Same Energy */
  299. float neededEnergy = hl
  300. .getCurrentEnergyAtTimeStep(x);
  301. if (neededEnergy > 0) {
  302. hl.setState(HolonObject.PRODUCER);
  303. } else if (energyPerHolonObject > -neededEnergy) {
  304. hl.setState(HolonObject.OVER_SUPPLIED);
  305. } else if (energyPerHolonObject == -neededEnergy) {
  306. hl.setState(HolonObject.SUPPLIED);
  307. } else if (energyPerHolonObject >= -hl
  308. .getMinEnergy(x)) {
  309. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  310. } else {
  311. hl.setState(HolonObject.NOT_SUPPLIED);
  312. }
  313. hl.setCurrentSupply(energyPerHolonObject);
  314. } else if (model.getFairnessModel() == fairnessMininumDemandFirst) {
  315. /* fairness: minimum demand gets Energy first */
  316. if ((production + consumption) >= 0) {
  317. if (energySurplus > 0) {
  318. hl.setState(HolonObject.OVER_SUPPLIED);
  319. hl.setCurrentSupply((-energySurplus
  320. / consumption + 1)
  321. * hl.getCurrentEnergyAtTimeStep(x));
  322. } else {
  323. hl.setState(HolonObject.SUPPLIED);
  324. hl.setCurrentSupply(-hl
  325. .getCurrentEnergyAtTimeStep(x));
  326. }
  327. } else {
  328. float minEnergy = hl.getMinEnergy(x);
  329. if (hl.checkIfPartiallySupplied(timeStep)) {
  330. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  331. currentProduction += minEnergy;
  332. hl.setCurrentSupply(-minEnergy);
  333. partiallySuppliedList.add(hl);
  334. } else {
  335. /**
  336. * Case that only some HolonObjects can
  337. * be supplied
  338. */
  339. if (-hl.getCurrentEnergyAtTimeStep(x) <= currentProduction) {
  340. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  341. currentProduction += minEnergy;
  342. hl.setCurrentSupply(-minEnergy);
  343. partiallySuppliedList.add(hl);
  344. } else if (-hl.getMinEnergy(x) <= currentProduction) {
  345. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  346. currentProduction += minEnergy;
  347. hl.setCurrentSupply(-minEnergy);
  348. partiallySuppliedList.add(hl);
  349. } else {
  350. hl.setState(HolonObject.NOT_SUPPLIED);
  351. hl.setCurrentSupply(0.0f);
  352. notSuppliedList.add(hl);
  353. // currentProduction +=
  354. // hl.getCurrentEnergyAtTimeStep(x);
  355. }
  356. }
  357. }
  358. }
  359. hl.getCurrentEnergyAtTimeStep(x);
  360. break;
  361. }
  362. }
  363. /**
  364. * check if some object cn self supply itself
  365. */
  366. if (hl.checkIfPartiallySupplied(timeStep)
  367. && hl.getState() != HolonObject.SUPPLIED
  368. && hl.getState() != HolonObject.OVER_SUPPLIED) {
  369. hl.setState(HolonObject.PARTIALLY_SUPPLIED);
  370. }
  371. }
  372. }
  373. if (model.getFairnessModel() == fairnessMininumDemandFirst) {
  374. /**
  375. * check if some partially supplied building might be fully
  376. * supplied.
  377. */
  378. partiallySuppliedList.sort(new EnergyMinToMaxComparator(x));
  379. for (HolonObject hl : partiallySuppliedList) {
  380. float minEnergy = hl.getMinEnergy(x);
  381. currentProduction -= minEnergy;
  382. /*
  383. * if possible, supply fully
  384. */
  385. float currentEnergyAtTimeStep = hl
  386. .getCurrentEnergyAtTimeStep(x);
  387. if (-currentEnergyAtTimeStep <= currentProduction) {
  388. hl.setState(HolonObject.SUPPLIED);
  389. currentProduction += currentEnergyAtTimeStep;
  390. hl.setCurrentSupply(-currentEnergyAtTimeStep);
  391. hl.getCurrentEnergyAtTimeStep(x);
  392. } else {
  393. currentProduction += minEnergy;
  394. notSuppliedList.add(hl);
  395. }
  396. }
  397. if (!notSuppliedList.isEmpty() && currentProduction > 0) {
  398. float energyPerHolon = currentProduction
  399. / notSuppliedList.size();
  400. for (HolonObject hl : notSuppliedList) {
  401. hl.setCurrentSupply(hl.getCurrentSupply()
  402. + energyPerHolon);
  403. hl.getCurrentEnergyAtTimeStep(x);
  404. }
  405. }
  406. }
  407. }
  408. /**
  409. * add all battries.getOut() from a list of battries and return them
  410. * @param aL a List of HolonBattries likely from subnet.getBatteries()
  411. * @param x TODO
  412. * @return
  413. *
  414. */
  415. private float GetOutAllBatteries(ArrayList<HolonBattery> aL, int x)
  416. {
  417. float OutEnergy = 0;
  418. for(HolonBattery hB : aL)
  419. {
  420. OutEnergy += hB.getOutAtTimeStep(x);
  421. }
  422. return OutEnergy;
  423. }
  424. /**
  425. * search for all flexible devices in the network and turn them on, until
  426. * energy surplus = 0 or all devices have been examined.
  427. *
  428. * This code could be compressed (cases inside over- and underproduction are
  429. * the same), but we decided that it is better readable this way
  430. *
  431. * @param subNet
  432. * the subnet
  433. * @param energySurplus
  434. * the current surplus of energy
  435. */
  436. private void turnOnFlexibleDevices(SubNet subNet, float energySurplus,
  437. int timestep) {
  438. for (HolonObject holonOb : subNet.getObjects()) {
  439. for (HolonElement holonEl : holonOb.getElements()) {
  440. // if this element is flexible and active (can be considered for
  441. // calculations)
  442. if (holonEl.isFlexible() && holonEl.isActive()) {
  443. float energyAvailableSingle = holonEl
  444. .getAvailableEnergyAt(timestep);
  445. float energyAvailableMultiple = energyAvailableSingle
  446. * holonEl.getAmount();
  447. // ------------- flexible consumer / OVERPRODUCTION
  448. // -------------
  449. if (energyAvailableMultiple < 0 && energySurplus > 0) {
  450. // if there is more wasted energy than energy that this
  451. // device can give, give all energy available
  452. if (Math.abs(energyAvailableMultiple) <= Math
  453. .abs(energySurplus)) {
  454. energySurplus += energyAvailableMultiple;
  455. // set the new energy consumption to the maximum
  456. holonEl.setEnergyPerElement(energyAvailableSingle);
  457. flexDevicesTurnedOnThisTurn.put(holonEl,
  458. energyAvailableMultiple);
  459. }
  460. // else: we just need to turn on part of the flexible
  461. // energy available
  462. else {
  463. float energyNeeded = -energySurplus;
  464. energySurplus += energyNeeded; // should give 0, but
  465. // was kept this was
  466. // for consistency
  467. // the energy needed divided through the amount of
  468. // elements
  469. holonEl.setEnergyPerElement(energyNeeded
  470. / holonEl.getAmount());
  471. flexDevicesTurnedOnThisTurn.put(holonEl,
  472. energyNeeded);
  473. }
  474. }
  475. // ------------- flexible producer / UNDERPRODUCTION
  476. // -------------
  477. else if (energyAvailableMultiple > 0 && energySurplus < 0) {
  478. // if there is more energy needed than this device can
  479. // give, give all the energy available
  480. if (Math.abs(energyAvailableMultiple) <= Math
  481. .abs(energySurplus)) {
  482. energySurplus += energyAvailableMultiple;
  483. // set the new energy consumption to the maximum
  484. holonEl.setEnergyPerElement(energyAvailableSingle);
  485. flexDevicesTurnedOnThisTurn.put(holonEl,
  486. energyAvailableMultiple);
  487. }
  488. // else: we just need to turn on part of the flexible
  489. // energy available
  490. else {
  491. float energyNeeded = -energySurplus;
  492. int i = 0;
  493. energySurplus += energyNeeded; // should give 0, but
  494. // was kept this was
  495. // for consistency
  496. // the energy needed divided through the amount of
  497. // elements
  498. holonEl.setEnergyPerElement(energyNeeded
  499. / holonEl.getAmount());
  500. flexDevicesTurnedOnThisTurn.put(holonEl,
  501. energyNeeded);
  502. }
  503. }
  504. }
  505. if (energySurplus == 0) {
  506. break;
  507. }
  508. }
  509. if (energySurplus == 0) {
  510. break;
  511. }
  512. }
  513. }
  514. /**
  515. * Set Flow Simulation.
  516. *
  517. * @param sN
  518. * Subnet
  519. */
  520. private void setFlowSimulation(SubNet sN) {
  521. ArrayList<AbstractCpsObject> producers = new ArrayList<>();
  522. AbstractCpsObject tmp = null;
  523. tagTable = new HashMap<>();
  524. // traverse all objects in this subnet
  525. for (HolonObject hl : sN.getObjects()) {
  526. float energy = hl.getCurrentEnergyAtTimeStep(timeStep);
  527. // if their production is higher than their consumption
  528. if (energy > 0) {
  529. tagTable.put(hl.getId(), energy);
  530. hl.addTag(hl.getId());
  531. for (CpsEdge edge : hl.getConnections()) {
  532. if (edge.isWorking()) {
  533. // set other end of edge as tmp-object
  534. // and add this end to the other end's tag-list
  535. AbstractCpsObject a = edge.getA();
  536. AbstractCpsObject b = edge.getB();
  537. if (a.getId() == hl.getId()) {
  538. b.addTag(hl.getId());
  539. tmp = b;
  540. }
  541. if (b.getId() == hl.getId()) {
  542. a.addTag(hl.getId());
  543. tmp = a;
  544. }
  545. edge.setFlow(edge.getFlow() + energy);
  546. edge.calculateState();
  547. edge.addTag(hl.getId());
  548. if (edge.isWorking() && !producers.contains(tmp)) {
  549. if (tmp instanceof HolonSwitch) {
  550. if (((HolonSwitch) tmp).getState(timeStep)) {
  551. producers.add(tmp);
  552. }
  553. } else if (!(tmp instanceof CpsUpperNode)) {
  554. producers.add(tmp);
  555. }
  556. }
  557. }
  558. }
  559. }
  560. }
  561. setFlowSimRec(producers, 0);
  562. }
  563. /**
  564. * Set Flow Simulation Rec.
  565. *
  566. * @param nodes
  567. * the nodes
  568. * @param iter
  569. * the Iteration
  570. */
  571. private void setFlowSimRec(ArrayList<AbstractCpsObject> nodes, int iter) {
  572. ArrayList<AbstractCpsObject> newNodes = new ArrayList<>();
  573. ArrayList<CpsEdge> changedEdges = new ArrayList<>();
  574. AbstractCpsObject tmp;
  575. if (nodes.size() != 0) {
  576. for (AbstractCpsObject cps : nodes) {
  577. // check whether the cps is in a legit state if it is a switch
  578. if (legitState(cps)) {
  579. for (CpsEdge edge : cps.getConnections()) {
  580. // is edge working
  581. // and does the edge's tag-list not (yet) contain all
  582. // tags of the cps
  583. if (edge.isWorking()
  584. && (!(edge.containsTags(edge.getTags(),
  585. cps.getTag())))) {
  586. if (edge.getA().getId() == cps.getId()) {
  587. tmp = edge.getB();
  588. } else {
  589. tmp = edge.getA();
  590. }
  591. for (Integer tag : cps.getTag()) {
  592. if (!(edge.getTags().contains(tag))
  593. && !(edge.getPseudoTags().contains(tag))) {
  594. edge.setFlow(edge.getFlow()
  595. + tagTable.get(tag));
  596. edge.addTag(tag);
  597. }
  598. }
  599. // uppernodes do not spread energy
  600. if (!(tmp instanceof CpsUpperNode)) {
  601. for (Integer tag : tmp.getTag()) {
  602. if (!(edge.getTags().contains(tag))
  603. && tagTable.get(tag) != null
  604. && !(edge.getPseudoTags()
  605. .contains(tag))) {
  606. edge.setFlow(edge.getFlow()
  607. + tagTable.get(tag));
  608. edge.addPseudoTag(tag);
  609. changedEdges.add(edge);
  610. }
  611. }
  612. }
  613. edge.calculateState();
  614. if (edge.isWorking()
  615. && !(tmp instanceof CpsUpperNode)) {
  616. tmp.addAllPseudoTags(cps.getTag());
  617. if (!newNodes.contains(tmp)) {
  618. newNodes.add(tmp);
  619. }
  620. }
  621. }
  622. }
  623. }
  624. }
  625. setPseudoTags(newNodes, changedEdges);
  626. setFlowSimRec(newNodes, iter + 1);
  627. }
  628. }
  629. /**
  630. * Set the Pseudo Tags.
  631. *
  632. * @param nodes
  633. * Array of AbstractCpsObjects
  634. */
  635. private void setPseudoTags(ArrayList<AbstractCpsObject> nodes,
  636. ArrayList<CpsEdge> edges) {
  637. for (AbstractCpsObject node : nodes) {
  638. node.recalculateTags();
  639. node.setPseudoTags(new ArrayList<>());
  640. }
  641. for (CpsEdge edge : edges) {
  642. edge.recalculateTags();
  643. edge.setPseudoTag(new ArrayList<>());
  644. }
  645. }
  646. /**
  647. * Reset the Connection.
  648. *
  649. * @param cps
  650. * CpsObject
  651. * @param visitedObj
  652. * the visited Objects
  653. * @param visitedEdges
  654. * the visited Edges
  655. */
  656. private void resetConnections(AbstractCpsObject cps,
  657. ArrayList<Integer> visitedObj, ArrayList<CpsEdge> visitedEdges) {
  658. visitedObj.add(cps.getId());
  659. cps.resetTags();
  660. for (CpsEdge e : cps.getConnections()) {
  661. if (!(visitedEdges.contains(e))) {
  662. e.setFlow(0);
  663. e.calculateState();
  664. e.setTags(new ArrayList<>());
  665. visitedEdges.add(e);
  666. if (!(visitedObj.contains(e.getA().getId()))) {
  667. resetConnections(e.getA(), visitedObj, visitedEdges);
  668. e.getA().resetTags();
  669. }
  670. if (!(visitedObj.contains(e.getB().getId()))) {
  671. resetConnections(e.getB(), visitedObj, visitedEdges);
  672. e.getB().resetTags();
  673. }
  674. }
  675. }
  676. }
  677. /**
  678. * calculates the energy of either all producers or consumers. Flexible
  679. * devices are filtered out
  680. *
  681. * @param type
  682. * Type
  683. * @param sN
  684. * Subnet
  685. * @param x
  686. * Integer
  687. * @return The Energy
  688. */
  689. private float calculateEnergyWithoutFlexDevices(String type, SubNet sN,
  690. int x) {
  691. float energy = 0;
  692. for (HolonObject hl : sN.getObjects()) {
  693. float currentEnergyWithoutFlexibles = hl
  694. .getCurrentEnergyAtTimeStepWithoutFlexiblesAndResetFlexibles(x);
  695. if (type.equals("prod")) {
  696. if (currentEnergyWithoutFlexibles > 0) {
  697. energy += currentEnergyWithoutFlexibles;
  698. hl.setState(HolonObject.PRODUCER);
  699. }
  700. }
  701. if (type.equals("cons")) {
  702. if (currentEnergyWithoutFlexibles < 0) {
  703. energy += currentEnergyWithoutFlexibles;
  704. hl.setState(HolonObject.NOT_SUPPLIED);
  705. }
  706. }
  707. if (currentEnergyWithoutFlexibles == 0) {
  708. hl.setState(HolonObject.NO_ENERGY);
  709. }
  710. }
  711. return energy;
  712. }
  713. /**
  714. * calculates the energy of either all producers or consumers. Flexible
  715. * devices are filtered out
  716. *
  717. * @param type
  718. * Type
  719. * @param sN
  720. * Subnet
  721. * @param x
  722. * Integer
  723. * @return The Energy
  724. */
  725. private float calculateEnergyWithFlexDevices(String type, SubNet sN, int x) {
  726. float energy = 0;
  727. for (HolonObject hl : sN.getObjects()) {
  728. float currentEnergy = hl.getCurrentEnergyAtTimeStep(x);
  729. if (type.equals("prod")) {
  730. if (currentEnergy > 0) {
  731. energy += currentEnergy;
  732. hl.setState(HolonObject.PRODUCER);
  733. }
  734. }
  735. if (type.equals("cons")) {
  736. if (currentEnergy < 0) {
  737. energy = energy + currentEnergy;
  738. hl.setState(HolonObject.NOT_SUPPLIED);
  739. }
  740. }
  741. if (currentEnergy == 0) {
  742. hl.setState(HolonObject.NO_ENERGY);
  743. }
  744. }
  745. return energy;
  746. }
  747. /**
  748. * Calculate the Minimum Energy of a Subnet.
  749. *
  750. * @param sN
  751. * Subnet
  752. * @param x
  753. * Integer
  754. * @return the Calculated minimum Energy of a Subnet
  755. */
  756. private float calculateMinimumEnergy(SubNet sN, int x) {
  757. float minimummConsumptionSubnet = 0;
  758. for (HolonObject hl : sN.getObjects()) {
  759. float minElement = 0;
  760. // Search for a activ element
  761. for (HolonElement he : hl.getElements()) {
  762. if (he.isActive()) {
  763. float overallEnergy = he.getOverallEnergyAtTimeStep(x);
  764. if (overallEnergy < 0) {
  765. // Is a consumer
  766. minElement = overallEnergy;
  767. }
  768. }
  769. }
  770. for (HolonElement he : hl.getElements()) {
  771. if (he.isActive()) {
  772. float overallEnergy = he.getOverallEnergyAtTimeStep(x);
  773. if (minElement < overallEnergy && overallEnergy < 0) {
  774. // is a smaller consumer
  775. minElement = overallEnergy;
  776. }
  777. }
  778. }
  779. minimummConsumptionSubnet += minElement;
  780. }
  781. System.out.println("MinimumEnergy = "+ minimummConsumptionSubnet);
  782. return minimummConsumptionSubnet;
  783. }
  784. /**
  785. * generates all subNets from all objectsToHandle.
  786. */
  787. private void searchForSubNets() {
  788. subNets = new ArrayList<>();
  789. brokenEdges.clear();
  790. boolean end = false;
  791. int i = 0;
  792. AbstractCpsObject cps;
  793. if (objectsToHandle.size() > 0) {
  794. while (!end) {
  795. cps = objectsToHandle.get(i);
  796. SubNet singleSubNet = new SubNet(new ArrayList<>(),
  797. new ArrayList<>(), new ArrayList<>(), new ArrayList<>());
  798. singleSubNet = buildSubNet(cps, new ArrayList<>(), singleSubNet);
  799. if (singleSubNet.getObjects().size() != 0) {
  800. subNets.add(singleSubNet);
  801. }
  802. if (0 == objectsToHandle.size()) {
  803. end = true;
  804. }
  805. }
  806. }
  807. }
  808. /**
  809. * recursivly generates a subnet of all objects, that one specific object is
  810. * connected to.
  811. *
  812. * @param cps
  813. * AbstractCpsObject
  814. * @param visited
  815. * visited Array of Integer
  816. * @param sN
  817. * Subnets
  818. * @return Subnet
  819. */
  820. private SubNet buildSubNet(AbstractCpsObject cps,
  821. ArrayList<Integer> visited, SubNet sN) {
  822. visited.add(cps.getId());
  823. if (cps instanceof HolonObject) {
  824. sN.getObjects().add((HolonObject) cps);
  825. }
  826. if (cps instanceof HolonSwitch) {
  827. sN.getSwitches().add((HolonSwitch) cps);
  828. }
  829. if (cps instanceof HolonBattery) {
  830. sN.getBatteries().add((HolonBattery) cps);
  831. }
  832. removeFromToHandle(cps.getId());
  833. AbstractCpsObject a;
  834. AbstractCpsObject b;
  835. for (CpsEdge edge : cps.getConnections()) {
  836. if (edge.isWorking()) {
  837. a = edge.getA();
  838. b = edge.getB();
  839. if (!(cps instanceof HolonSwitch)) {
  840. if (!(sN.getEdges().contains(edge))) {
  841. sN.getEdges().add(edge);
  842. }
  843. }
  844. if (cps instanceof HolonSwitch
  845. && ((HolonSwitch) cps).getState(timeStep)) {
  846. if (!(sN.getEdges().contains(edge))) {
  847. sN.getEdges().add(edge);
  848. }
  849. }
  850. if (!visited.contains(a.getId()) && legitState(cps)
  851. && !(a instanceof CpsUpperNode)) {
  852. sN = buildSubNet(a, visited, sN);
  853. }
  854. if (!visited.contains(b.getId()) && legitState(cps)
  855. && !(b instanceof CpsUpperNode)) {
  856. sN = buildSubNet(b, visited, sN);
  857. }
  858. if (a instanceof CpsUpperNode && a.getId() != cps.getId()) {
  859. edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
  860. checkForConnectedStates(b, (CpsUpperNode) a, edge);
  861. }
  862. if (b instanceof CpsUpperNode && b.getId() != cps.getId()) {
  863. edge.setConnected(CpsEdge.CON_UPPER_NODE_NOT_INSIDE);
  864. checkForConnectedStates(a, (CpsUpperNode) b, edge);
  865. }
  866. } else {
  867. brokenEdges.add(edge);
  868. }
  869. }
  870. return sN;
  871. }
  872. /**
  873. * is the Switch in a legitimate State.
  874. *
  875. * @param current
  876. * AbstractCpsObject
  877. * @return boolean
  878. */
  879. private boolean legitState(AbstractCpsObject current) {
  880. return !(current instanceof HolonSwitch)
  881. || ((HolonSwitch) current).getState(timeStep);
  882. }
  883. // /**
  884. // * ensures that objectsToHandle only contains HolonObjects.
  885. // */
  886. // public void cleanObjectsToHandle() {
  887. // for (int i = 0; i < objectsToHandle.size(); i++) {
  888. // if (!(objectsToHandle.get(i) instanceof HolonObject)) {
  889. // objectsToHandle.remove(i);
  890. // }
  891. // }
  892. // }
  893. /**
  894. * removes an Object that already has been handled.
  895. *
  896. * @param id
  897. * the Object ID
  898. */
  899. private void removeFromToHandle(int id) {
  900. for (int i = 0; i < objectsToHandle.size(); i++) {
  901. if (objectsToHandle.get(i).getId() == id) {
  902. objectsToHandle.remove(i);
  903. }
  904. }
  905. }
  906. /**
  907. * copies the data of an array of Objects.
  908. *
  909. * @param toCopy
  910. * the ArrayList of CpsObjects co Copy
  911. */
  912. private void copyObjects(ArrayList<AbstractCpsObject> toCopy) {
  913. for (AbstractCpsObject cps : toCopy) {
  914. if (cps instanceof CpsUpperNode) {
  915. copyObjects(((CpsUpperNode) cps).getNodes());
  916. } else {
  917. objectsToHandle.add(cps);
  918. }
  919. }
  920. }
  921. /**
  922. * Prints the Components auf all subnets.
  923. */
  924. private void printNetsToConsole() {
  925. for (int i = 0; i < subNets.size(); i++) {
  926. SubNet subNet = subNets.get(i);
  927. System.out.println("SUBNET NR:" + i);
  928. subNet.toString(timeStep);
  929. }
  930. }
  931. /**
  932. * Set the Canvas.
  933. *
  934. * @param can
  935. * the Canvas
  936. */
  937. public void setCanvas(MyCanvas can) {
  938. canvas = can;
  939. }
  940. /**
  941. * Reset all Data to the current state of the Model.
  942. */
  943. public void reset() {
  944. objectsToHandle = new ArrayList<>();
  945. copyObjects(model.getObjectsOnCanvas());
  946. flexDevicesTurnedOnThisTurn = new HashMap<>();
  947. }
  948. /**
  949. * Resets the State of all Edges
  950. */
  951. private void resetEdges() {
  952. for (CpsEdge e : brokenEdges) {
  953. e.setWorkingState(true);
  954. }
  955. }
  956. /**
  957. * Resets the State for the whole Simulation Model
  958. */
  959. void resetSimulation() {
  960. reset();
  961. resetEdges();
  962. }
  963. /**
  964. * Get all Subnets.
  965. *
  966. * @return all Subnets
  967. */
  968. public ArrayList<SubNet> getSubNets() {
  969. return subNets;
  970. }
  971. /**
  972. * Get broken Edges
  973. */
  974. // public ArrayList<CpsEdge> getBrokenEdges() {
  975. // return brokenEdges;
  976. // }
  977. /**
  978. * checks whether a given object is connected to an object inside the
  979. * upperNode. if yes, the state for the edge is changed in "connected" or
  980. * "not connected"
  981. */
  982. private void checkForConnectedStates(AbstractCpsObject cps,
  983. CpsUpperNode cUNode, CpsEdge theEdge) {
  984. AbstractCpsObject tmp;
  985. for (CpsEdge edge : cps.getConnections()) {
  986. if (edge.getA().getId() == cps.getId()) {
  987. tmp = edge.getB();
  988. } else {
  989. tmp = edge.getA();
  990. }
  991. if (cUNode.getNodes().contains(tmp)) {
  992. if (tmp instanceof CpsUpperNode) {
  993. checkForConnectedStates(cps, (CpsUpperNode) tmp, theEdge);
  994. } else {
  995. theEdge.setConnected(CpsEdge.CON_UPPER_NODE_AND_INSIDE);
  996. break;
  997. }
  998. }
  999. }
  1000. }
  1001. public FlexiblePane getFlexiblePane() {
  1002. return flexPane;
  1003. }
  1004. void setFlexiblePane(FlexiblePane fp) {
  1005. flexPane = fp;
  1006. }
  1007. }