View Javadoc
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-2019 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 }