/*******************************************************************************
* Copyright 2012 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/
package emlab.role;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import agentspring.role.AbstractRole;
import agentspring.role.Role;
import agentspring.role.ScriptComponent;
import cern.colt.Timer;
import emlab.domain.agent.CommoditySupplier;
import emlab.domain.agent.DecarbonizationModel;
import emlab.domain.agent.EnergyConsumer;
import emlab.domain.agent.EnergyProducer;
import emlab.domain.market.CommodityMarket;
import emlab.domain.market.electricity.ElectricitySpotMarket;
import emlab.repository.Reps;
import emlab.role.investment.DismantlePowerPlantPastTechnicalLifetimeRole;
import emlab.role.investment.InvestInPowerGenerationTechnologiesRole;
import emlab.role.market.ClearCommodityMarketRole;
import emlab.role.market.ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole;
import emlab.role.market.ProcessAcceptedBidsRole;
import emlab.role.market.ProcessAcceptedPowerPlantDispatchRole;
import emlab.role.market.ReassignPowerPlantsToLongTermElectricityContractsRole;
import emlab.role.market.ReceiveLongTermContractPowerRevenuesRole;
import emlab.role.market.SelectLongTermElectricityContractsRole;
import emlab.role.market.SubmitBidsToCommodityMarketRole;
import emlab.role.market.SubmitLongTermElectricityContractsRole;
import emlab.role.market.SubmitOffersToCommodityMarketRole;
import emlab.role.market.SubmitOffersToElectricitySpotMarketRole;
import emlab.role.operating.DetermineFuelMixRole;
import emlab.role.operating.PayCO2AuctionRole;
import emlab.role.operating.PayCO2TaxRole;
import emlab.role.operating.PayForLoansRole;
import emlab.role.operating.PayOperatingAndMaintainanceCostsRole;
/**
* Main model role.
*
* @author alfredas, ejlchappin, jcrichstein
*
*/
@ScriptComponent
public class DecarbonizationModelRole extends AbstractRole<DecarbonizationModel> implements Role<DecarbonizationModel> {
@Autowired
private PayCO2TaxRole payCO2TaxRole;
@Autowired
private PayCO2AuctionRole payCO2AuctionRole;
@Autowired
private InvestInPowerGenerationTechnologiesRole investInPowerGenerationTechnologiesRole;
@Autowired
private SubmitOffersToElectricitySpotMarketRole submitOffersToElectricitySpotMarketRole;
@Autowired
private ClearCommodityMarketRole clearCommodityMarketRole;
@Autowired
private SubmitBidsToCommodityMarketRole submitBidsToCommodityMarketRole;
@Autowired
private SubmitOffersToCommodityMarketRole submitOffersToCommodityMarketRole;
@Autowired
private SubmitLongTermElectricityContractsRole submitLongTermElectricityContractsRole;
@Autowired
private SelectLongTermElectricityContractsRole selectLongTermElectricityContractsRole;
@Autowired
private DismantlePowerPlantPastTechnicalLifetimeRole dismantlePowerPlantRole;
@Autowired
private ReassignPowerPlantsToLongTermElectricityContractsRole reassignPowerPlantsToLongTermElectricityContractsRole;
@Autowired
private ClearIterativeCO2AndElectricitySpotMarketTwoCountryRole clearIterativeCO2AndElectricitySpotMarketTwoCountryRole;
@Autowired
private DetermineFuelMixRole determineFuelMixRole;
@Autowired
private ReceiveLongTermContractPowerRevenuesRole receiveLongTermContractPowerRevenuesRole;
@Autowired
private ProcessAcceptedPowerPlantDispatchRole processAcceptedPowerPlantDispatchRole;
@Autowired
private ProcessAcceptedBidsRole processAcceptedBidsRole;
@Autowired
private PayForLoansRole payForLoansRole;
@Autowired
private PayOperatingAndMaintainanceCostsRole payOperatingAndMaintainanceCostsRole;
@Autowired
Reps reps;
/**
* Main model script. Executes other roles in the right sequence.
*/
public void act(DecarbonizationModel model) {
if (getCurrentTick() > model.getSimulationLength()) {
logger.warn("Simulation is terminating!!!");
agentspring.simulation.Schedule.getSchedule().stop();
//System.exit(0);
}
logger.warn("***** STARTING TICK {} *****", getCurrentTick());
Timer timer = new Timer();
timer.start();
logger.warn(" 0. Dismantling & paying loans");
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
dismantlePowerPlantRole.act(producer);
payForLoansRole.act(producer);
// producer.act(dismantlePowerPlantRole);
// producer.act(payForLoansRole);
}
/*
* Determine fuel mix of power plants
*/
Timer timerMarket = new Timer();
timerMarket.start();
logger.warn(" 1. Determining fuel mix");
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
determineFuelMixRole.act(producer);
// producer.act(determineFuelMixRole);
}
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
/*
* Submit and select long-term electricity contracts
*/
if (model.isLongTermContractsImplemented()) {
timerMarket.reset();
timerMarket.start();
logger.warn(" 2. Submit and select long-term electricity contracts");
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
submitLongTermElectricityContractsRole.act(producer);
// producer.act(submitLongTermElectricityContractsRole);
}
for (EnergyConsumer consumer : reps.genericRepository.findAllAtRandom(EnergyConsumer.class)) {
selectLongTermElectricityContractsRole.act(consumer);
// consumer.act(selectLongTermElectricityContractsRole);
}
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
}
/*
* Clear electricity spot and CO2 markets and determine also the commitment of powerplants.
*/
timerMarket.reset();
timerMarket.start();
logger.warn(" 3. Clearing electricity spot and CO2 markets");
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
submitOffersToElectricitySpotMarketRole.act(producer);
// producer.act(submitOffersToElectricitySpotMarketRole);
}
clearIterativeCO2AndElectricitySpotMarketTwoCountryRole.act(model);
// model.act(clearIterativeCO2AndElectricitySpotMarketTwoCountryRole);
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
timerMarket.reset();
timerMarket.start();
for (EnergyProducer producer : reps.genericRepository.findAll(EnergyProducer.class)) {
receiveLongTermContractPowerRevenuesRole.act(producer);
// producer.act(receiveLongTermContractPowerRevenuesRole);
}
for (ElectricitySpotMarket electricitySpotMarket : reps.marketRepository.findAllElectricitySpotMarkets()) {
processAcceptedPowerPlantDispatchRole.act(electricitySpotMarket);
// electricitySpotMarket.act(processAcceptedPowerPlantDispatchRole);
}
timerMarket.stop();
logger.warn(" paying took: {} seconds.", timerMarket.seconds());
/*
* Maintenance and CO2
*/
logger.warn(" 4. Paying for maintenance & co2");
timerMarket.reset();
timerMarket.start();
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
// do accounting
payOperatingAndMaintainanceCostsRole.act(producer);
// producer.act(payOperatingAndMaintainanceCostsRole);
// pay tax
payCO2TaxRole.act(producer);
// producer.act(payCO2TaxRole);
// pay for CO2 auction only if CO2 trading
if (model.isCo2TradingImplemented()) {
payCO2AuctionRole.act(producer);
// producer.act(payCO2AuctionRole);
}
}
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
/*
* COMMODITY MARKETS
*/
logger.warn(" 5. Purchasing commodities");
timerMarket.reset();
timerMarket.start();
// SUPPLIER (supply for commodity markets)
for (CommoditySupplier supplier : reps.genericRepository.findAllAtRandom(CommoditySupplier.class)) {
// 1) first submit the offers
submitOffersToCommodityMarketRole.act(supplier);
// supplier.act(submitOffersToCommodityMarketRole);
}
// PRODUCER (demand for commodity markets)
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
// 2) submit bids
submitBidsToCommodityMarketRole.act(producer);
// producer.act(submitBidsToCommodityMarketRole);
}
for (CommodityMarket market : reps.genericRepository.findAllAtRandom(CommodityMarket.class)) {
clearCommodityMarketRole.act(market);
processAcceptedBidsRole.act(market);
// market.act(clearCommodityMarketRole);
// market.act(processAcceptedBidsRole);
}
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
logger.warn(" 6. Investing");
Timer timerInvest = new Timer();
timerInvest.start();
if (getCurrentTick() > 1) {
boolean someOneStillWillingToInvest = true;
while (someOneStillWillingToInvest) {
someOneStillWillingToInvest = false;
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
// invest in new plants
if (producer.isWillingToInvest()) {
investInPowerGenerationTechnologiesRole.act(producer);
// producer.act(investInPowerGenerationTechnologiesRole);
someOneStillWillingToInvest = true;
}
}
}
resetWillingnessToInvest();
}
timerInvest.stop();
logger.warn(" took: {} seconds.", timerInvest.seconds());
if (model.isLongTermContractsImplemented()) {
logger.warn(" 7. Reassign LTCs");
timerMarket.reset();
timerMarket.start();
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
reassignPowerPlantsToLongTermElectricityContractsRole.act(producer);
// producer.act(reassignPowerPlantsToLongTermElectricityContractsRole);
}
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
}
/*
* Deletion of old nodes
*/
if (model.isDeletionOldPPDPBidsAndCashFlowsEnabled() && (getCurrentTick() - model.getDeletionAge() >= 0)) {
timerMarket.reset();
timerMarket.start();
logger.warn(" 8. Delete old nodes in year {}.", (getCurrentTick() - model.getDeletionAge()));
reps.bidRepository.delete(reps.bidRepository.findAllBidsForForTime(getCurrentTick() - model.getDeletionAge()));
reps.cashFlowRepository.delete(reps.cashFlowRepository.findAllCashFlowsForForTime(getCurrentTick() - model.getDeletionAge()));
reps.powerPlantRepository.delete(reps.powerPlantRepository.findAllPowerPlantsDismantledBeforeTick(getCurrentTick()
- model.getDeletionAge()));
timerMarket.stop();
logger.warn(" took: {} seconds.", timerMarket.seconds());
}
timer.stop();
logger.warn("Tick {} took {} seconds.", getCurrentTick(), timer.seconds());
// if (getCurrentTick() >= model.getSimulationLength()) {
// agentspring.simulation.Schedule.getSchedule().stop();
// }
}
@Transactional
private void resetWillingnessToInvest() {
for (EnergyProducer producer : reps.genericRepository.findAllAtRandom(EnergyProducer.class)) {
producer.setWillingToInvest(true);
}
}
}