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 super();
91 this.simulator = simulator;
92 this.terminalFrom = terminalFrom;
93 this.terminalLastStacked = terminalFrom;
94 this.terminalTo = terminalTo;
95 this.empty = empty;
96 this.shippingLine = shippingLine;
97 this.creationTime = this.simulator.getSimulatorTime();
98 for (int i = 0; i < ContainerTransportCostBreakdownEnum.values().length; i++)
99 {
100 this.transportCosts[i] = 0.0f;
101 }
102 for (int i = 0; i < ContainerTransportFeeBreakdownEnum.values().length; i++)
103 {
104 this.transportFee[i] = 0.0f;
105 }
106 for (int i = 0; i < ContainerTransportCO2BreakdownEnum.values().length; i++)
107 {
108 this.transportKgCO2[i] = 0.0f;
109 }
110 for (int i = 0; i < ContainerTransportTimeBreakdownEnum.values().length; i++)
111 {
112 this.transportTime[i] = 0.0f;
113 }
114 }
115
116 /**
117 * @param costEnum ContainerTransportCostBreakdownEnum; cost category
118 * @param cost double; cost to add
119 */
120 public final void addTransportCost(final ContainerTransportCostBreakdownEnum costEnum, final double cost)
121 {
122 this.transportCosts[costEnum.ordinal()] += cost;
123 }
124
125 /**
126 * @param feeEnum ContainerTransportFeeBreakdownEnum; cost category
127 * @param fee double; the fee to add
128 */
129 public final void addTransportFee(final ContainerTransportFeeBreakdownEnum feeEnum, final double fee)
130 {
131 this.transportFee[feeEnum.ordinal()] += fee;
132 }
133
134 /**
135 * @param co2Enum ContainerTransportCO2BreakdownEnum; CO2 category
136 * @param kgCO2 double; the amount of CO2 to add
137 */
138 public final void addTransportKgCO2(final ContainerTransportCO2BreakdownEnum co2Enum, final double kgCO2)
139 {
140 this.transportKgCO2[co2Enum.ordinal()] += kgCO2;
141 }
142
143 /**
144 * @param timeEnum ContainerTransportTimeBreakdownEnum; time category
145 * @param time double; the time in hours to add
146 */
147 public final void addTransportTime(final ContainerTransportTimeBreakdownEnum timeEnum, final double time)
148 {
149 this.transportTime[timeEnum.ordinal()] += time;
150 }
151
152 /**
153 * @param costEnum ContainerTransportCostBreakdownEnum; cost category
154 * @return costs of this cost breakdown category until now
155 */
156 public final double getTransportCost(final ContainerTransportCostBreakdownEnum costEnum)
157 {
158 return this.transportCosts[costEnum.ordinal()];
159 }
160
161 /**
162 * @param feeEnum ContainerTransportFeeBreakdownEnum; cost category
163 * @return fee until now of this cost breakdown category until now
164 */
165 public final double getTransportFee(final ContainerTransportFeeBreakdownEnum feeEnum)
166 {
167 return this.transportFee[feeEnum.ordinal()];
168 }
169
170 /**
171 * @param co2Enum ContainerTransportCO2BreakdownEnum; CO2 category
172 * @return kg CO2 of this CO2 breakdown category until now
173 */
174 public final double getTransportKgCO2(final ContainerTransportCO2BreakdownEnum co2Enum)
175 {
176 return this.transportKgCO2[co2Enum.ordinal()];
177 }
178
179 /**
180 * @param timeEnum ContainerTransportTimeBreakdownEnum; time category
181 * @return the time in hours
182 */
183 public final double getTransportTime(final ContainerTransportTimeBreakdownEnum timeEnum)
184 {
185 return this.transportTime[timeEnum.ordinal()];
186 }
187
188 /**
189 * @return summed total costs
190 */
191 public final double getSumTransportCost()
192 {
193 double sum = 0.0;
194 for (int i = 0; i < ContainerTransportCostBreakdownEnum.values().length; i++)
195 {
196 sum += this.transportCosts[i];
197 }
198 return sum;
199 }
200
201 /**
202 * @return summed total fee
203 */
204 public final double getSumTransportFee()
205 {
206 double sum = 0.0;
207 for (int i = 0; i < ContainerTransportFeeBreakdownEnum.values().length; i++)
208 {
209 sum += this.transportFee[i];
210 }
211 return sum;
212 }
213
214 /**
215 * @return summed total kg CO2
216 */
217 public final double getSumTransportKgCO2()
218 {
219 double sum = 0.0;
220 for (int i = 0; i < ContainerTransportCO2BreakdownEnum.values().length; i++)
221 {
222 sum += this.transportKgCO2[i];
223 }
224 return sum;
225 }
226
227 /**
228 * @return summed total time
229 */
230 public final double getSumTransportTime()
231 {
232 double sum = 0.0;
233 for (int i = 0; i < ContainerTransportTimeBreakdownEnum.values().length; i++)
234 {
235 sum += this.transportTime[i];
236 }
237 return sum;
238 }
239
240 /**
241 * Collect the final statistics when the container arrived at its destination.
242 */
243 @SuppressWarnings("checkstyle:needbraces")
244 public final void collectTerminalStatisticsAtContainerDestination()
245 {
246 // Terminal terminal = this.terminalTo.isRtmTerminal() ? this.terminalFrom : this.terminalTo;
247 // TODO: add at terminal: totalCosts += terminal.getAnnualFixedCostsTerminalPerTEU();
248 // TerminalStatistics stats = terminal.getTerminalStatistics();
249 //
250 // stats.costPerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportCost());
251 // stats.feePerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportFee());
252 // stats.kgCO2PerTEU.get(DirectionEnum.TOTAL).tally(getSumTransportKgCO2());
253 // stats.transportTime.get(DirectionEnum.TOTAL).tally(getSumTransportTime());
254 // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
255 // stats.addBreakdownCost(DirectionEnum.TOTAL, ctcb, this.getTransportCost(ctcb));
256 // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
257 // stats.addBreakdownFee(DirectionEnum.TOTAL, ctfb, this.getTransportFee(ctfb));
258 // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
259 // stats.addBreakdownCO2(DirectionEnum.TOTAL, ctcb, this.getTransportKgCO2(ctcb));
260 // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
261 // stats.addBreakdownTime(DirectionEnum.TOTAL, cttb, this.getTransportTime(cttb));
262 //
263 // if (this.terminalTo.isRtmTerminal())
264 // {
265 // stats.costPerTEU.get(DirectionEnum.TORTM).tally(getSumTransportCost());
266 // stats.feePerTEU.get(DirectionEnum.TORTM).tally(getSumTransportFee());
267 // stats.kgCO2PerTEU.get(DirectionEnum.TORTM).tally(getSumTransportKgCO2());
268 // stats.transportTime.get(DirectionEnum.TORTM).tally(getSumTransportTime());
269 // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
270 // stats.addBreakdownCost(DirectionEnum.TORTM, ctcb, this.getTransportCost(ctcb));
271 // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
272 // stats.addBreakdownFee(DirectionEnum.TORTM, ctfb, this.getTransportFee(ctfb));
273 // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
274 // stats.addBreakdownCO2(DirectionEnum.TORTM, ctcb, this.getTransportKgCO2(ctcb));
275 // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
276 // stats.addBreakdownTime(DirectionEnum.TORTM, cttb, this.getTransportTime(cttb));
277 // }
278 //
279 // else
280 //
281 // {
282 // stats.costPerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportCost());
283 // stats.feePerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportFee());
284 // stats.kgCO2PerTEU.get(DirectionEnum.FROMRTM).tally(getSumTransportKgCO2());
285 // stats.transportTime.get(DirectionEnum.FROMRTM).tally(getSumTransportTime());
286 // for (ContainerTransportCostBreakdownEnum ctcb : ContainerTransportCostBreakdownEnum.values())
287 // stats.addBreakdownCost(DirectionEnum.FROMRTM, ctcb, this.getTransportCost(ctcb));
288 // for (ContainerTransportFeeBreakdownEnum ctfb : ContainerTransportFeeBreakdownEnum.values())
289 // stats.addBreakdownFee(DirectionEnum.FROMRTM, ctfb, this.getTransportFee(ctfb));
290 // for (ContainerTransportCO2BreakdownEnum ctcb : ContainerTransportCO2BreakdownEnum.values())
291 // stats.addBreakdownCO2(DirectionEnum.FROMRTM, ctcb, this.getTransportKgCO2(ctcb));
292 // for (ContainerTransportTimeBreakdownEnum cttb : ContainerTransportTimeBreakdownEnum.values())
293 // stats.addBreakdownTime(DirectionEnum.FROMRTM, cttb, this.getTransportTime(cttb));
294 // }
295 }
296
297 /**
298 * @return the terminalFrom
299 */
300 public final Terminal getTerminalFrom()
301 {
302 return this.terminalFrom;
303 }
304
305 /**
306 * @return the terminalTo
307 */
308 public final Terminal getTerminalTo()
309 {
310 return this.terminalTo;
311 }
312
313 /**
314 * @return the terminalCurrent
315 */
316 public final Terminal getTerminalLastStacked()
317 {
318 return this.terminalLastStacked;
319 }
320
321 /**
322 * @param terminalFrom Terminal; the terminalFrom to set
323 */
324 public final void setTerminalFrom(final Terminal terminalFrom)
325 {
326 this.terminalFrom = terminalFrom;
327 }
328
329 /**
330 * @param terminalTo Terminal; the terminalTo to set
331 */
332 public final void setTerminalTo(final Terminal terminalTo)
333 {
334 this.terminalTo = terminalTo;
335 }
336
337 /**
338 * @param terminalLastStacked Terminal; the terminalCurrent to set
339 */
340 public final void setTerminalLastStacked(final Terminal terminalLastStacked)
341 {
342 this.terminalLastStacked = terminalLastStacked;
343 }
344
345 /**
346 * @return the empty
347 */
348 public final boolean isEmpty()
349 {
350 return this.empty;
351 }
352
353 /**
354 * @return full or empty
355 */
356 public final FullEmptyEnum fullEmpty()
357 {
358 if (this.empty)
359 {
360 return FullEmptyEnum.EMPTY;
361 }
362 return FullEmptyEnum.FULL;
363 }
364
365 /**
366 * @return the owner
367 */
368 public final Company getOwner()
369 {
370 return this.shippingLine;
371 }
372
373 /**
374 * @return the shippingLine
375 */
376 public final ShippingLine getShippingLine()
377 {
378 return this.shippingLine;
379 }
380
381 /** {@inheritDoc} */
382 @Override
383 public final String toString()
384 {
385 String full = this.empty ? "[EMPTY]" : "[FULL]";
386 return "Container from " + this.terminalFrom.getName() + " to " + this.terminalTo.getName() + " at "
387 + this.terminalLastStacked.getName() + " (owner " + this.shippingLine.getCode() + ") " + full;
388 }
389
390 /**
391 * @return short info
392 */
393 public final String toShortString()
394 {
395 String full = this.empty ? "[E]" : "[F]";
396 return this.terminalFrom.getName() + "->" + this.terminalTo.getName() + "@" + this.terminalLastStacked.getName() + full;
397 }
398
399 /**
400 * @return the arrivalTime
401 */
402 public final Time getStackArrivalTime()
403 {
404 return this.stackArrivalTime;
405 }
406
407 /**
408 * set the arrivalTime.
409 */
410 public final void setStackArrivalTime()
411 {
412 this.stackArrivalTime = this.simulator.getSimulatorTime();
413 }
414
415 /**
416 * @return the creationTime
417 */
418 public final Time getCreationTime()
419 {
420 return this.creationTime;
421 }
422
423 /**
424 * @return the onShipTime
425 */
426 public final Time getOnShipTime()
427 {
428 return this.onShipTime;
429 }
430
431 /**
432 * set onShipTime.
433 */
434 public final void setOnShipTime()
435 {
436 this.onShipTime = this.simulator.getSimulatorTime();
437 }
438
439 }