EMlab-generation Documentation  1.0
Documentation of the EMLab-Generation model.
ElectricityProducerFactory.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.domain.factory;
17 
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21 
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.springframework.beans.factory.InitializingBean;
25 import org.springframework.transaction.annotation.Transactional;
26 
35 
36 public class ElectricityProducerFactory implements InitializingBean {
37 
38  private double capacityMargin;
39 
40  private Map<PowerGeneratingTechnology, Double> portfolioShares = null;
41 
42  private Set<PowerGridNode> nodes;
43 
44  private ElectricitySpotMarket market;
45 
46  private List<EnergyProducer> producers;
47 
48  static final Logger logger = LoggerFactory.getLogger(ElectricityProducerFactory.class);
49 
50  @Override
51  public void afterPropertiesSet() throws Exception {
52  createPowerPlantsForMarket(market);
53  }
54 
55  @Transactional
56  private PowerPlant createPowerPlant(PowerGeneratingTechnology technology, EnergyProducer energyProducer, PowerGridNode location) {
57  PowerPlant plant = new PowerPlant().persist();
58  String label = energyProducer.getName() + " - " + technology.getName();
59  plant.setName(label);
60  plant.setTechnology(technology);
61  plant.setOwner(energyProducer);
62  plant.setLocation(location);
63  plant.setConstructionStartTime(-(technology.getExpectedLeadtime() + technology.getExpectedPermittime() + Math.round((Math.random() * technology
64  .getExpectedLifetime()))) + 2); // TODO: Why include expected lead
65  // time and permit time? Wouldn't it
66  // be realistic to have some PP in
67  // the pipeline at the start?
68  plant.setActualLeadtime(plant.getTechnology().getExpectedLeadtime());
69  plant.setActualPermittime(plant.getTechnology().getExpectedPermittime());
70  plant.setExpectedEndOfLife(plant.getConstructionStartTime() + plant.getActualPermittime() + plant.getActualLeadtime()
71  + plant.getTechnology().getExpectedLifetime());
72  plant.setActualNominalCapacity(technology.getCapacity() * location.getCapacityMultiplicationFactor());
73  plant.calculateAndSetActualInvestedCapital(plant.getConstructionStartTime());
74  plant.calculateAndSetActualEfficiency(plant.getConstructionStartTime());
75  plant.calculateAndSetActualFixedOperatingCosts(plant.getConstructionStartTime());
76  plant.setDismantleTime(1000);
77  Loan loan = new Loan().persist();
78  loan.setFrom(energyProducer);
79  loan.setTo(null);
80  double amountPerPayment = determineLoanAnnuities(plant.getActualInvestedCapital() * energyProducer.getDebtRatioOfInvestments(),
81  plant.getTechnology().getDepreciationTime(), energyProducer.getLoanInterestRate());
82  loan.setAmountPerPayment(amountPerPayment);
83  loan.setTotalNumberOfPayments(plant.getTechnology().getDepreciationTime());
84  loan.setLoanStartTime(plant.getConstructionStartTime());
85  loan.setNumberOfPaymentsDone(-plant.getConstructionStartTime());// Some
86  // payments
87  // are
88  // already
89  // made
90  plant.setLoan(loan);
91  return plant;
92  }
93 
94  private void createPowerPlantsForMarket(ElectricitySpotMarket market) {
95 
96  double maxLoad = Double.MIN_NORMAL;
97  // get max load
98  for (SegmentLoad segmentLoad : market.getLoadDurationCurve()) {
99 
100  if (maxLoad < segmentLoad.getBaseLoad()) {
101  maxLoad = segmentLoad.getBaseLoad();
102  }
103  }
104  double requiredCapacity = maxLoad * (1 + capacityMargin);
105  logger.info("required capacity for market {} is {}", market, requiredCapacity);
106  for (PowerGeneratingTechnology technology : portfolioShares.keySet()) {
107  double pctValue = portfolioShares.get(technology);
108  double requiredCapacityForTechnology = pctValue * requiredCapacity;
109  logger.info("required capacity within this market for technology {} is {}", technology, requiredCapacityForTechnology);
110  // logger.info("required capacity: {} for technology {} before creating",
111  // requiredCapacityForTechnology, technology);
112  while (requiredCapacityForTechnology > 0) {
113  EnergyProducer energyProducer = getRandomProducer(producers);
114  PowerPlant plant = createPowerPlant(technology, energyProducer, getNodeForZone(market.getZone()));
115  requiredCapacityForTechnology -= plant.getAvailableCapacity(0);
116  }
117  // logger.info("required capacity: {} for technology {} after creating",
118  // requiredCapacityForTechnology, technology);
119  }
120 
121  }
122 
123  private EnergyProducer getRandomProducer(List<EnergyProducer> producers) {
124  if (producers.size() > 0) {
125  int size = producers.size();
126  int index = getRandomIndexFromList(size);
127  return producers.get(index);
128  }
129  return null;
130  }
131 
132  private int getRandomIndexFromList(int size) {
133  return (int) Math.min(Math.floor(Math.random() * size), size - 1);
134  }
135 
136  private PowerGridNode getNodeForZone(Zone zone) {
137  for (PowerGridNode node : nodes) {
138  if (node.getZone().equals(zone)) {
139  return node;
140  }
141  }
142  return null;
143  }
144 
145  public double getCapacityMargin() {
146  return capacityMargin;
147  }
148 
149  public void setCapacityMargin(double capacityMargin) {
150  this.capacityMargin = capacityMargin;
151  }
152 
153  public Map<PowerGeneratingTechnology, Double> getPortfolioShares() {
154  return portfolioShares;
155  }
156 
157  public void setPortfolioShares(Map<PowerGeneratingTechnology, Double> portfolioShares) {
158  this.portfolioShares = portfolioShares;
159  }
160 
161  public Set<PowerGridNode> getNodes() {
162  return nodes;
163  }
164 
165  public void setNodes(Set<PowerGridNode> nodes) {
166  this.nodes = nodes;
167  }
168 
169  public ElectricitySpotMarket getMarket() {
170  return market;
171  }
172 
173  public void setMarket(ElectricitySpotMarket market) {
174  logger.info("setting market {}", market);
175  this.market = market;
176  }
177 
178  public List<EnergyProducer> getProducers() {
179  return producers;
180  }
181 
182  public void setProducers(List<EnergyProducer> producers) {
183  this.producers = producers;
184  }
185 
186  public double determineLoanAnnuities(double totalLoan, double payBackTime, double interestRate) {
187 
188  double q = 1 + interestRate;
189  double annuity = totalLoan * (Math.pow(q, payBackTime) * (q - 1)) / (Math.pow(q, payBackTime) - 1);
190 
191  return annuity;
192  }
193 
194 }