EMlab-generation Documentation  1.0
Documentation of the EMLab-Generation model.
DecarbonizationModelRole.java
1 /*******************************************************************************
2  * Copyright 2012 the original author or authors.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 package emlab.gen.role;
17 
18 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.data.neo4j.support.Neo4jTemplate;
20 import org.springframework.transaction.annotation.Transactional;
21 
22 import agentspring.role.AbstractRole;
23 import agentspring.role.Role;
24 import agentspring.role.ScriptComponent;
25 import cern.colt.Timer;
41 import emlab.gen.role.investment.GenericInvestmentRole;
60 
67 @ScriptComponent
68 public class DecarbonizationModelRole extends AbstractRole<DecarbonizationModel> implements Role<DecarbonizationModel> {
69 
70  @Autowired
71  private PayCO2TaxRole payCO2TaxRole;
72  @Autowired
73  private PayCO2AuctionRole payCO2AuctionRole;
74  @Autowired
75  private GenericInvestmentRole<EnergyProducer> genericInvestmentRole;
76  @Autowired
77  private SubmitOffersToElectricitySpotMarketRole submitOffersToElectricitySpotMarketRole;
78  @Autowired
79  private ClearCommodityMarketRole clearCommodityMarketRole;
80  @Autowired
81  private SubmitBidsToCommodityMarketRole submitBidsToCommodityMarketRole;
82  @Autowired
83  private SubmitOffersToCommodityMarketRole submitOffersToCommodityMarketRole;
84  @Autowired
85  private SubmitLongTermElectricityContractsRole submitLongTermElectricityContractsRole;
86  @Autowired
87  private SelectLongTermElectricityContractsRole selectLongTermElectricityContractsRole;
88  @Autowired
89  private DismantlePowerPlantPastTechnicalLifetimeRole dismantlePowerPlantRole;
90  @Autowired
91  private ReassignPowerPlantsToLongTermElectricityContractsRole reassignPowerPlantsToLongTermElectricityContractsRole;
92  @Autowired
93  private ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole clearIterativeCO2AndElectricitySpotMarketTwoCountryRole;
94  @Autowired
95  private DetermineFuelMixRole determineFuelMixRole;
96  @Autowired
97  private ReceiveLongTermContractPowerRevenuesRole receiveLongTermContractPowerRevenuesRole;
98  @Autowired
99  private ProcessAcceptedPowerPlantDispatchRole processAcceptedPowerPlantDispatchRole;
100  @Autowired
101  private ProcessAcceptedBidsRole processAcceptedBidsRole;
102  @Autowired
103  private PayForLoansRole payForLoansRole;
104  @Autowired
105  private PayOperatingAndMaintainanceCostsRole payOperatingAndMaintainanceCostsRole;
106  @Autowired
107  private StrategicReserveOperatorRole strategicReserveOperatorRole;
108  @Autowired
109  private ProcessAcceptedPowerPlantDispatchRoleinSR acceptedPowerPlantDispatchRoleinSR;
110  @Autowired
111  private RenewableAdaptiveCO2CapRole renewableAdaptiveCO2CapRole;
112  @Autowired
113  MarketStabilityReserveRole marketStabilityReserveRole;
114  @Autowired
115  private DetermineResidualLoadCurvesForTwoCountriesRole determineResidualLoadCurve;
116  @Autowired
117  private CreatingFinancialReports creatingFinancialReports;
118 
119  @Autowired
120  Reps reps;
121 
122  @Autowired
123  Neo4jTemplate template;
124 
128  @Override
129  public void act(DecarbonizationModel model) {
130 
131  if (getCurrentTick() > model.getSimulationLength() && model.isExitSimulationAfterSimulationLength()) {
132  logger.warn("Simulation is terminating!!!");
133  // agentspring.simulation.Schedule.getSchedule().stop();
134  System.exit(0);
135  }
136 
137  if (getCurrentTick() >= model.getSimulationLength()) {
138  agentspring.simulation.Schedule.getSchedule().stop();
139  }
140 
141  logger.warn("***** STARTING TICK {} *****", getCurrentTick());
142  Timer timer = new Timer();
143  timer.start();
144 
145  logger.warn(" 0a. Determing load duration curves.");
146  if (model.isRealRenewableDataImplemented())
147  determineResidualLoadCurve.act(model);
148 
149  logger.warn(" 0. Dismantling & paying loans");
150  for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
151  dismantlePowerPlantRole.act(producer);
152  payForLoansRole.act(producer);
153  // producer.act(dismantlePowerPlantRole);
154  // producer.act(payForLoansRole);
155  }
156 
157  /*
158  * Determine fuel mix of power plants
159  */
160  Timer timerMarket = new Timer();
161  timerMarket.start();
162  logger.warn(" 1. Determining fuel mix");
163  for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
164  determineFuelMixRole.act(producer);
165  // producer.act(determineFuelMixRole);
166  }
167  timerMarket.stop();
168  logger.warn(" took: {} seconds.", timerMarket.seconds());
169 
170  /*
171  * Submit and select long-term electricity contracts
172  */
173 
174  if (model.isLongTermContractsImplemented()) {
175  timerMarket.reset();
176  timerMarket.start();
177  logger.warn(" 2. Submit and select long-term electricity contracts");
178  for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
179  submitLongTermElectricityContractsRole.act(producer);
180  // producer.act(submitLongTermElectricityContractsRole);
181  }
182 
183  for (EnergyConsumer consumer : reps.genericRepository.findAllAtRandom(EnergyConsumer.class)) {
184  selectLongTermElectricityContractsRole.act(consumer);
185  // consumer.act(selectLongTermElectricityContractsRole);
186  }
187  timerMarket.stop();
188  logger.warn(" took: {} seconds.", timerMarket.seconds());
189  }
190 
191  /*
192  * Clear electricity spot and CO2 markets and determine also the commitment of powerplants.
193  */
194  timerMarket.reset();
195  timerMarket.start();
196  logger.warn(" 3. Submitting offers to market");
197  for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
198  submitOffersToElectricitySpotMarketRole.act(producer);
199  // producer.act(submitOffersToElectricitySpotMarketRole);
200  }
201  timerMarket.stop();
202  logger.warn(" took: {} seconds.", timerMarket.seconds());
203 
204  /*
205  * Contract strategic reserve volume and set strategic reserve dispatch
206  * price
207  */
208  for (StrategicReserveOperator strategicReserveOperator : reps.strategicReserveOperatorRepository.findAll()) {
209  logger.warn(" 3a. Contracting Strategic Reserve in " + strategicReserveOperator.getZone().getName());
210  strategicReserveOperatorRole.act(strategicReserveOperator);
211  }
212 
213  Government government = template.findAll(Government.class).iterator().next();
214  if (getCurrentTick() > 0 && government.getCo2CapTrend() != null && government.isActivelyAdjustingTheCO2Cap()) {
215  logger.warn("Lowering cap according to RES installations");
216  renewableAdaptiveCO2CapRole.act(government);
217  }
218 
219  if (model.isStabilityReserveIsActive() && getCurrentTick() == 0) {
220  government.getStabilityReserveAddingMinimumTrend().getValue(0);
221  government.getStabilityReserveAddingPercentageTrend().getValue(0);
222  government.getStabilityReserveLowerTriggerTrend().getValue(0);
223  government.getStabilityReserveReleaseQuantityTrend().getValue(0);
224  government.getStabilityReserveUpperTriggerTrend().getValue(0);
225  }
226  if (getCurrentTick() >= model.getStabilityReserveFirstYearOfOperation() && model.isStabilityReserveIsActive()) {
227  logger.warn("3b. CO2 Market Stability Reserve");
228  marketStabilityReserveRole.act(government);
229  }
230 
231  timerMarket.reset();
232  timerMarket.start();
233  logger.warn(" 4. Clearing electricity spot and CO2 markets");
234  clearIterativeCO2AndElectricitySpotMarketTwoCountryRole.act(model);
235  // model.act(clearIterativeCO2AndElectricitySpotMarketTwoCountryRole);
236  timerMarket.stop();
237  logger.warn(" took: {} seconds.", timerMarket.seconds());
238 
239  timerMarket.reset();
240  timerMarket.start();
241  for (EnergyProducer producer : reps.genericRepository.findAll(EnergyProducer.class)) {
242  receiveLongTermContractPowerRevenuesRole.act(producer);
243  // producer.act(receiveLongTermContractPowerRevenuesRole);
244  }
245  for (ElectricitySpotMarket electricitySpotMarket : reps.marketRepository.findAllElectricitySpotMarkets()) {
246  processAcceptedPowerPlantDispatchRole.act(electricitySpotMarket);
247  // electricitySpotMarket.act(processAcceptedPowerPlantDispatchRole);
248  }
249  for (StrategicReserveOperator strategicReserveOperator : reps.strategicReserveOperatorRepository.findAll()) {
250  acceptedPowerPlantDispatchRoleinSR.act(strategicReserveOperator);
251  }
252  // logger.warn(" 4. Processing Strategic Reserve Payment ");
253  timerMarket.stop();
254  logger.warn(" paying took: {} seconds.", timerMarket.seconds());
255  /*
256  * Maintenance and CO2
257  */
258  logger.warn(" 5. Paying for maintenance & co2");
259  timerMarket.reset();
260  timerMarket.start();
261  for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
262  // do accounting
263  payOperatingAndMaintainanceCostsRole.act(producer);
264  // producer.act(payOperatingAndMaintainanceCostsRole);
265  // pay tax
266  payCO2TaxRole.act(producer);
267  // producer.act(payCO2TaxRole);
268  // pay for CO2 auction only if CO2 trading
269  if (model.isCo2TradingImplemented()) {
270  payCO2AuctionRole.act(producer);
271  // producer.act(payCO2AuctionRole);
272  }
273  }
274  timerMarket.stop();
275  logger.warn(" took: {} seconds.", timerMarket.seconds());
276 
277  /*
278  * COMMODITY MARKETS
279  */
280  logger.warn(" 6. Purchasing commodities");
281  timerMarket.reset();
282  timerMarket.start();
283 
284  // SUPPLIER (supply for commodity markets)
285  for (CommoditySupplier supplier : reps.genericRepository.findAllAtRandom(CommoditySupplier.class)) {
286  // 1) first submit the offers
287  submitOffersToCommodityMarketRole.act(supplier);
288  // supplier.act(submitOffersToCommodityMarketRole);
289  }
290 
291  // PRODUCER (demand for commodity markets)
292  for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
293  // 2) submit bids
294  submitBidsToCommodityMarketRole.act(producer);
295  // producer.act(submitBidsToCommodityMarketRole);
296  }
297 
298  for (CommodityMarket market : reps.genericRepository.findAllAtRandom(CommodityMarket.class)) {
299  clearCommodityMarketRole.act(market);
300  processAcceptedBidsRole.act(market);
301  // market.act(clearCommodityMarketRole);
302  // market.act(processAcceptedBidsRole);
303  }
304  timerMarket.stop();
305  logger.warn(" took: {} seconds.", timerMarket.seconds());
306 
307  logger.warn(" 6.b) Creating power plant financial reports.");
308  Timer financialReports = new Timer();
309  financialReports.start();
310 
311  creatingFinancialReports.act(model);
312 
313  financialReports.stop();
314  logger.warn(" took: {} seconds.", financialReports.seconds());
315 
316  logger.warn(" 7. Investing");
317  Timer timerInvest = new Timer();
318  timerInvest.start();
319 
320  logger.warn("\t Private investment");
321  if (getCurrentTick() > 1) {
322  boolean someOneStillWillingToInvest = true;
323  while (someOneStillWillingToInvest) {
324  someOneStillWillingToInvest = false;
325  for (EnergyProducer producer : reps.energyProducerRepository
326  .findAllEnergyProducersExceptForRenewableTargetInvestorsAtRandom()) {
327  // invest in new plants
328  if (producer.isWillingToInvest()) {
329  genericInvestmentRole.act(producer);
330  // producer.act(investInPowerGenerationTechnologiesRole);
331  someOneStillWillingToInvest = true;
332  }
333  }
334  }
335  resetWillingnessToInvest();
336  }
337  logger.warn("\t subsidized investment.");
338  for (TargetInvestor targetInvestor : template.findAll(TargetInvestor.class)) {
339  genericInvestmentRole.act(targetInvestor);
340  }
341  timerInvest.stop();
342  logger.warn(" took: {} seconds.", timerInvest.seconds());
343 
344  if (model.isLongTermContractsImplemented()) { // if (getCurrentTick() >=
345  // model.getSimulationLength())
346  // {
347  // agentspring.simulation.Schedule.getSchedule().stop();
348  // }
349 
350  logger.warn(" 7. Reassign LTCs");
351  timerMarket.reset();
352  timerMarket.start();
353  for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
354  reassignPowerPlantsToLongTermElectricityContractsRole.act(producer);
355  // producer.act(reassignPowerPlantsToLongTermElectricityContractsRole);
356  }
357  timerMarket.stop();
358  logger.warn(" took: {} seconds.", timerMarket.seconds());
359  }
360 
361  /*
362  * Deletion of old nodes
363  */
364 
365  if (model.isDeletionOldPPDPBidsAndCashFlowsEnabled() && (getCurrentTick() - model.getDeletionAge() >= 0)) {
366  timerMarket.reset();
367  timerMarket.start();
368  logger.warn(" 8. Delete old nodes in year {}.", (getCurrentTick() - model.getDeletionAge()));
369  reps.bidRepository.delete(reps.bidRepository.findAllBidsForForTime(getCurrentTick()
370  - model.getDeletionAge()));
371  reps.cashFlowRepository.delete(reps.cashFlowRepository.findAllCashFlowsForForTime(getCurrentTick()
372  - model.getDeletionAge()));
373  reps.powerPlantRepository.delete(reps.powerPlantRepository
374  .findAllPowerPlantsDismantledBeforeTick(getCurrentTick() - 1 - model.getDeletionAge()));
375  reps.powerPlantDispatchPlanRepository.delete(reps.powerPlantDispatchPlanRepository
376  .findAllPowerPlantDispatchPlansForTime(getCurrentTick() + model.getCentralForecastingYear() - 1,
377  true));
378  timerMarket.stop();
379  logger.warn(" took: {} seconds.", timerMarket.seconds());
380  }
381 
382  timer.stop();
383  logger.warn("Tick {} took {} seconds.", getCurrentTick(), timer.seconds());
384  }
385 
386  @Transactional
387  private void resetWillingnessToInvest() {
388  for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
389  producer.setWillingToInvest(true);
390  }
391  }
392 }
Iterable< ElectricitySpotMarket > findAllElectricitySpotMarkets()