1 /**
2 *
3 */
4 package org.opentrafficsim.water.demand;
5
6 import java.io.Serializable;
7
8 import org.djunits.value.vdouble.scalar.Time;
9 import org.opentrafficsim.water.role.Company;
10 import org.opentrafficsim.water.role.ShippingLine;
11 import org.opentrafficsim.water.statistics.ContainerTransportCO2BreakdownEnum;
12 import org.opentrafficsim.water.statistics.ContainerTransportCostBreakdownEnum;
13 import org.opentrafficsim.water.statistics.ContainerTransportFeeBreakdownEnum;
14 import org.opentrafficsim.water.statistics.ContainerTransportTimeBreakdownEnum;
15 import org.opentrafficsim.water.statistics.FullEmptyEnum;
16 import org.opentrafficsim.water.transfer.Terminal;
17
18 import nl.tudelft.simulation.dsol.simulators.DEVSSimulatorInterface;
19
20 /**
21 * A container is exactly 1 TEU. It collects statistics along the way, which are reported to the statistics objects just before
22 * the container disappears from the model at the inland client or deep sea terminal / empty depot.
23 * <p>
24 * Copyright (c) 2013-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
25 * BSD-style license. See <a href="http://opentrafficsim.org/docs/current/license.html">OpenTrafficSim License</a>.
26 * </p>
27 * <p>
28 * Based on software from the IDVV project, which is Copyright (c) 2013 Rijkswaterstaat - Dienst Water, Verkeer en Leefomgeving
29 * and licensed without restrictions to Delft University of Technology, including the right to sub-license sources and derived
30 * products to third parties.
31 * </p>
32 * $LastChangedDate: 2015-07-24 02:58:59 +0200 (Fri, 24 Jul 2015) $, @version $Revision: 1147 $, by $Author: averbraeck $,
33 * initial version Nov 6, 2016 <br>
34 * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
35 */
36 public class Container implements Serializable
37 {
38 /** */
39 private static final long serialVersionUID = 1L;
40
41 /** the simulator. */
42 private final DEVSSimulatorInterface.TimeDoubleUnit simulator;
43
44 /** origin terminal. */
45 private Terminal terminalFrom;
46
47 /** destination terminal. */
48 private Terminal terminalTo;
49
50 /** terminal where the container was stacked last. */
51 private Terminal terminalLastStacked;
52
53 /** empty? */
54 private boolean empty;
55
56 /** shipping line. */
57 private ShippingLine shippingLine;
58
59 /** creation time of container. */
60 private Time creationTime;
61
62 /** time of arrival at last terminal in the stack (for statistics about terminal staying time). */
63 private Time stackArrivalTime;
64
65 /** time when container loaded on ship. */
66 private Time onShipTime;
67
68 /** cost breakdown (based on actual costs) of ALL handling of the container (could be multiple services). */
69 private float[] transportCosts = new float[ContainerTransportCostBreakdownEnum.values().length];
70
71 /** fee breakdown (based on fixed costs for actions) of ALL handling of the container. */
72 private float[] transportFee = new float[ContainerTransportFeeBreakdownEnum.values().length];
73
74 /** co2 breakdown (in si unit) for ALL handling of the container (could be multiple services). */
75 private float[] transportKgCO2 = new float[ContainerTransportCO2BreakdownEnum.values().length];
76
77 /** time breakdown (in si unit) for ALL handling of the container (could be multiple services). */
78 private float[] transportTime = new float[ContainerTransportTimeBreakdownEnum.values().length];
79
80 /**
81 * @param simulator DEVSSimulatorInterface.TimeDoubleUnit; the simulator
82 * @param terminalFrom Terminal; origin terminal
83 * @param terminalTo Terminal; destination terminal
84 * @param empty boolean; empty or full
85 * @param shippingLine ShippingLine; shipping line of the container
86 */
87 public Container(final DEVSSimulatorInterface.TimeDoubleUnit simulator, final Terminal terminalFrom,
88 final Terminal terminalTo, final boolean empty, final ShippingLine shippingLine)
89 {
90 this.simulator = simulator;
91 this.terminalFrom = terminalFrom;
92 this.terminalLastStacked = terminalFrom;
93 this.terminalTo = terminalTo;
94 this.empty = empty;
95 this.shippingLine = shippingLine;
96 this.creationTime = this.simulator.getSimulatorTime();
97 for (int i = 0; i < ContainerTransportCostBreakdownEnum.values().length; i++)
98 {
99 this.transportCosts[i] = 0.0f;
100 }
101 for (int i = 0; i < ContainerTransportFeeBreakdownEnum.values().length; i++)
102 {
103 this.transportFee[i] = 0.0f;
104 }
105 for (int i = 0; i < ContainerTransportCO2BreakdownEnum.values().length; i++)
106 {
107 this.transportKgCO2[i] = 0.0f;
108 }
109 for (int i = 0; i < ContainerTransportTimeBreakdownEnum.values().length; i++)
110 {
111 this.transportTime[i] = 0.0f;
112 }
113 }
114
115 /**
116 * @param costEnum ContainerTransportCostBreakdownEnum; cost category
117 * @param cost double; cost to add
118 */
119 public final void addTransportCost(final ContainerTransportCostBreakdownEnum costEnum, final double cost)
120 {
121 this.transportCosts[costEnum.ordinal()] += cost;
122 }
123
124 /**
125 * @param feeEnum ContainerTransportFeeBreakdownEnum; cost category
126 * @param fee double; the fee to add
127 */
128 public final void addTransportFee(final ContainerTransportFeeBreakdownEnum feeEnum, final double fee)
129 {
130 this.transportFee[feeEnum.ordinal()] += fee;
131 }
132
133 /**
134 * @param co2Enum ContainerTransportCO2BreakdownEnum; CO2 category
135 * @param kgCO2 double; the amount of CO2 to add
136 */
137 public final void addTransportKgCO2(final ContainerTransportCO2BreakdownEnum co2Enum, final double kgCO2)
138 {
139 this.transportKgCO2[co2Enum.ordinal()] += kgCO2;
140 }
141
142 /**
143 * @param timeEnum ContainerTransportTimeBreakdownEnum; time category
144 * @param time double; the time in hours to add
145 */
146 public final void addTransportTime(final ContainerTransportTimeBreakdownEnum timeEnum, final double time)
147 {
148 this.transportTime[timeEnum.ordinal()] += time;
149 }
150
151 /**
152 * @param costEnum ContainerTransportCostBreakdownEnum; cost category
153 * @return costs of this cost breakdown category until now
154 */
155 public final double getTransportCost(final ContainerTransportCostBreakdownEnum costEnum)
156 {
157 return this.transportCosts[costEnum.ordinal()];
158 }
159
160 /**
161 * @param feeEnum ContainerTransportFeeBreakdownEnum; cost category
162 * @return fee until now of this cost breakdown category until now
163 */
164 public final double getTransportFee(final ContainerTransportFeeBreakdownEnum feeEnum)
165 {
166 return this.transportFee[feeEnum.ordinal()];
167 }
168
169 /**
170 * @param co2Enum ContainerTransportCO2BreakdownEnum; CO2 category
171 * @return kg CO2 of this CO2 breakdown category until now
172 */
173 public final double getTransportKgCO2(final ContainerTransportCO2BreakdownEnum co2Enum)
174 {
175 return this.transportKgCO2[co2Enum.ordinal()];
176 }
177
178 /**
179 * @param timeEnum ContainerTransportTimeBreakdownEnum; time category
180 * @return the time in hours
181 */
182 public final double getTransportTime(final ContainerTransportTimeBreakdownEnum timeEnum)
183 {
184 return this.transportTime[timeEnum.ordinal()];
185 }
186
187 /**
188 * @return summed total costs
189 */
190 public final double getSumTransportCost()
191 {
192 double sum = 0.0;
193 for (int i = 0; i < ContainerTransportCostBreakdownEnum.values().length; i++)
194 {
195 sum += this.transportCosts[i];
196 }
197 return sum;
198 }
199
200 /**
201 * @return summed total fee
202 */
203 public final double getSumTransportFee()
204 {
205 double sum = 0.0;
206 for (int i = 0; i < ContainerTransportFeeBreakdownEnum.values().length; i++)
207 {
208 sum += this.transportFee[i];
209 }
210 return sum;
211 }
212
213 /**
214 * @return summed total kg CO2
215 */
216 public final double getSumTransportKgCO2()
217 {
218 double sum = 0.0;
219 for (int i = 0; i < ContainerTransportCO2BreakdownEnum.values().length; i++)
220 {
221 sum += this.transportKgCO2[i];
222 }
223 return sum;
224 }
225
226 /**
227 * @return summed total time
228 */
229 public final double getSumTransportTime()
230 {
231 double sum = 0.0;
232 for (int i = 0; i < ContainerTransportTimeBreakdownEnum.values().length; i++)
233 {
234 sum += this.transportTime[i];
235 }
236 return sum;
237 }
238
239 /**
240 * Collect the final statistics when the container arrived at its destination.
241 */
242 @SuppressWarnings("checkstyle:needbraces")
243 public final void collectTerminalStatisticsAtContainerDestination()
244 {
245 // Terminal terminal = this.terminalTo.isRtmTerminal() ? this.terminalFrom : this.terminalTo;
246 // TODO: add at terminal: totalCosts += terminal.getAnnualFixedCostsTerminalPerTEU();
247 // TerminalStatistics stats = terminal.getTerminalStatistics();
248 //
249 // stats.costPerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportCost());
250 // stats.feePerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportFee());
251 // stats.kgCO2PerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportKgCO2());
252 // stats.transportTime.get(DirectionEnum.TOTAL).tally(getSumTransportTime());
253 // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
254 // stats.addBreakdownCost(DirectionEnum.TOTAL, ctcb, this.getTransportCost(ctcb));
255 // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
256 // stats.addBreakdownFee(DirectionEnum.TOTAL, ctfb, this.getTransportFee(ctfb));
257 // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
258 // stats.addBreakdownCO2(DirectionEnum.TOTAL, ctcb, this.getTransportKgCO2(ctcb));
259 // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
260 // stats.addBreakdownTime(DirectionEnum.TOTAL, cttb, this.getTransportTime(cttb));
261 //
262 // if (this.terminalTo.isRtmTerminal())
263 // {
264 // stats.costPerTEU.get(DirectionEnum.TORTM).tally(getSumTransportCost());
265 // stats.feePerTEU.get(DirectionEnum.TORTM).tally(getSumTransportFee());
266 // stats.kgCO2PerTEU.get(DirectionEnum.TORTM).tally(getSumTransportKgCO2());
267 // stats.transportTime.get(DirectionEnum.TORTM).tally(getSumTransportTime());
268 // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
269 // stats.addBreakdownCost(DirectionEnum.TORTM, ctcb, this.getTransportCost(ctcb));
270 // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
271 // stats.addBreakdownFee(DirectionEnum.TORTM, ctfb, this.getTransportFee(ctfb));
272 // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
273 // stats.addBreakdownCO2(DirectionEnum.TORTM, ctcb, this.getTransportKgCO2(ctcb));
274 // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
275 // stats.addBreakdownTime(DirectionEnum.TORTM, cttb, this.getTransportTime(cttb));
276 // }
277 //
278 // else
279 //
280 // {
281 // stats.costPerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportCost());
282 // stats.feePerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportFee());
283 // stats.kgCO2PerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportKgCO2());
284 // stats.transportTime.get(DirectionEnum.FROMRTM).tally(getSumTransportTime());
285 // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
286 // stats.addBreakdownCost(DirectionEnum.FROMRTM, ctcb, this.getTransportCost(ctcb));
287 // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
288 // stats.addBreakdownFee(DirectionEnum.FROMRTM, ctfb, this.getTransportFee(ctfb));
289 // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
290 // stats.addBreakdownCO2(DirectionEnum.FROMRTM, ctcb, this.getTransportKgCO2(ctcb));
291 // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
292 // stats.addBreakdownTime(DirectionEnum.FROMRTM, cttb, this.getTransportTime(cttb));
293 // }
294 }
295
296 /**
297 * @return the terminalFrom
298 */
299 public final Terminal getTerminalFrom()
300 {
301 return this.terminalFrom;
302 }
303
304 /**
305 * @return the terminalTo
306 */
307 public final Terminal getTerminalTo()
308 {
309 return this.terminalTo;
310 }
311
312 /**
313 * @return the terminalCurrent
314 */
315 public final Terminal getTerminalLastStacked()
316 {
317 return this.terminalLastStacked;
318 }
319
320 /**
321 * @param terminalFrom Terminal; the terminalFrom to set
322 */
323 public final void setTerminalFrom(final Terminal terminalFrom)
324 {
325 this.terminalFrom = terminalFrom;
326 }
327
328 /**
329 * @param terminalTo Terminal; the terminalTo to set
330 */
331 public final void setTerminalTo(final Terminal terminalTo)
332 {
333 this.terminalTo = terminalTo;
334 }
335
336 /**
337 * @param terminalLastStacked Terminal; the terminalCurrent to set
338 */
339 public final void setTerminalLastStacked(final Terminal terminalLastStacked)
340 {
341 this.terminalLastStacked = terminalLastStacked;
342 }
343
344 /**
345 * @return the empty
346 */
347 public final boolean isEmpty()
348 {
349 return this.empty;
350 }
351
352 /**
353 * @return full or empty
354 */
355 public final FullEmptyEnum fullEmpty()
356 {
357 if (this.empty)
358 {
359 return FullEmptyEnum.EMPTY;
360 }
361 return FullEmptyEnum.FULL;
362 }
363
364 /**
365 * @return the owner
366 */
367 public final Company getOwner()
368 {
369 return this.shippingLine;
370 }
371
372 /**
373 * @return the shippingLine
374 */
375 public final ShippingLine getShippingLine()
376 {
377 return this.shippingLine;
378 }
379
380 /** {@inheritDoc} */
381 @Override
382 public final String toString()
383 {
384 String full = this.empty ? "[EMPTY]" : "[FULL]";
385 return "Container from " + this.terminalFrom.getName() + " to " + this.terminalTo.getName() + " at "
386 + this.terminalLastStacked.getName() + " (owner " + this.shippingLine.getCode() + ") " + full;
387 }
388
389 /**
390 * @return short info
391 */
392 public final String toShortString()
393 {
394 String full = this.empty ? "[E]" : "[F]";
395 return this.terminalFrom.getName() + "->" + this.terminalTo.getName() + "@" + this.terminalLastStacked.getName() + full;
396 }
397
398 /**
399 * @return the arrivalTime
400 */
401 public final Time getStackArrivalTime()
402 {
403 return this.stackArrivalTime;
404 }
405
406 /**
407 * set the arrivalTime.
408 */
409 public final void setStackArrivalTime()
410 {
411 this.stackArrivalTime = this.simulator.getSimulatorTime();
412 }
413
414 /**
415 * @return the creationTime
416 */
417 public final Time getCreationTime()
418 {
419 return this.creationTime;
420 }
421
422 /**
423 * @return the onShipTime
424 */
425 public final Time getOnShipTime()
426 {
427 return this.onShipTime;
428 }
429
430 /**
431 * set onShipTime.
432 */
433 public final void setOnShipTime()
434 {
435 this.onShipTime = this.simulator.getSimulatorTime();
436 }
437
438 }