OpenTISim

This page lists all functions and classes available in the OpenTISim.model and OpenTISim.core modules. For examples on how to use these submodules please check out the Examples page, information on installing OpenTISim can be found on the Installation page.

Submodules

The main components are the Model module and the Core module. All of their components are listed below.

opentisim.agribulk_defaults module

Defaults for following objects:

    1. Quay_wall
    1. Berth
    1. Cyclic_Unloader
    • Gantry crane
    • Harbour crane
    • Mobile crane

    Continuous_Unloader

    • Continuous screw
    1. Conveyor
    • Hinterland conveyor
    • Quay conveyor
    1. Storage
    • Silo
    • Warehouse
    1. Unloading_station
    • Hinterland station
    1. Commodity
    • Maize
    • Soybean
    • Wheat
    1. Vessel
    • Handysize
    • Handymax
    • Panamax
    1. Labour

Default values are based on Claes 2018; Corbeau 2018; Daas 2018; Juha 2018; Kranendonk 2018; Schutz 2018; Schuurmans 2018 and Verstegen 2018

opentisim.agribulk_mixins module

Basic properties mixins:

  • identifiable_properties_mixin
  • history_properties_mixin
  • hascapex_properties_mixin
  • hasopex_properties_mixin
  • hasrevenue_properties_mixin
  • hastriggers_properties_mixin
  • quay_wall_properties_mixin
  • berth_properties_mixin
  • cyclic_properties_mixin
  • continuous_properties_mixin
  • conveyor_properties_mixin
  • storage_properties_mixin
  • unloading_station_properties_mixin
  • commodity_properties_mixin
  • vessel_properties_mixin
  • labour_properties_mixin
  • hasscenario_properties_mixin
class opentisim.agribulk_mixins.berth_properties_mixin(crane_type, max_cranes, delivery_time, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.commodity_properties_mixin(handling_fee, handysize_perc, handymax_perc, panamax_perc, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.continuous_properties_mixin(ownership, delivery_time, lifespan, unit_rate, mobilisation_perc, maintenance_perc, consumption, insurance_perc, crew, crane_type, peak_capacity, eff_fact, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.conveyor_properties_mixin(type, length, ownership, delivery_time, lifespan, unit_rate_factor, mobilisation, maintenance_perc, insurance_perc, consumption_constant, consumption_coefficient, crew, utilisation, capacity_steps, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.cyclic_properties_mixin(ownership, delivery_time, lifespan, unit_rate, mobilisation_perc, maintenance_perc, consumption, insurance_perc, crew, crane_type, lifting_capacity, hourly_cycles, eff_fact, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.energy_properties_mixin(price, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.hascapex_properties_mixin(capex=[], *args, **kwargs)[source]

Bases: object

Something has CAPEX

capex: list with cost to be applied from investment year

class opentisim.agribulk_mixins.hasopex_properties_mixin(labour=[], maintenance=[], energy=[], insurance=[], lease=[], demurrage=[], residual=[], *args, **kwargs)[source]

Bases: object

Something has OPEX

opex: list with cost to be applied from investment year

class opentisim.agribulk_mixins.hasrevenue_properties_mixin(renevue=[], *args, **kwargs)[source]

Bases: object

Something has Revenue

revenue: list with revenues to be applied from investment year

class opentisim.agribulk_mixins.hasscenario_properties_mixin(historic_data=[], scenario_data=[], *args, **kwargs)[source]

Bases: object

Something has a scenario

historic_data: observed demand scenario_data: generated estimates of future demand

plot_demand(width=0.1, alpha=0.6, fontsize=20)[source]

generate a histogram of the demand data

scenario_random(startyear=2019, lifecycle=20, rate=1.02, mu=0.01, sigma=0.065)[source]

trend generated from random growth rate increments

class opentisim.agribulk_mixins.hastriggers_properties_mixin(triggers=[], *args, **kwargs)[source]

Bases: object

Something has InvestmentTriggers

triggers: list with revenues to be applied from investment year

class opentisim.agribulk_mixins.history_properties_mixin(year_purchase=[], year_online=[], *args, **kwargs)[source]

Bases: object

Something that has a purchase history

purchase_date: year in which the decision was made to add another element online_date: year by which the elements starts to perform

class opentisim.agribulk_mixins.identifiable_properties_mixin(name=[], id=None, *args, **kwargs)[source]

Bases: object

Something that has a name and id

name: a name id: a unique id generated with uuid

class opentisim.agribulk_mixins.labour_properties_mixin(international_salary, international_staff, local_salary, local_staff, operational_salary, shift_length, annual_shifts, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.quay_wall_properties_mixin(ownership, delivery_time, lifespan, mobilisation_min, mobilisation_perc, maintenance_perc, insurance_perc, freeboard, Gijt_constant_2, Gijt_constant, Gijt_coefficient, max_sinkage, wave_motion, safety_margin, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.storage_properties_mixin(type, ownership, delivery_time, lifespan, unit_rate, mobilisation_min, mobilisation_perc, maintenance_perc, crew, insurance_perc, storage_type, consumption, capacity, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.train_properties_mixin(wagon_payload, number_of_wagons, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.unloading_station_properties_mixin(ownership, delivery_time, lifespan, unit_rate, mobilisation, maintenance_perc, insurance_perc, consumption, crew, production, wagon_payload, number_of_wagons, prep_time, *args, **kwargs)[source]

Bases: object

class opentisim.agribulk_mixins.vessel_properties_mixin(type, call_size, LOA, draft, beam, max_cranes, all_turn_time, mooring_time, demurrage_rate, *args, **kwargs)[source]

Bases: object

opentisim.agribulk_objects module

Main generic object classes:

    1. Quay_wall
    1. Berth
    1. Cyclic_Unloader
    • Gantry crane
    • Harbour crane
    • Mobile crane

    Continuous_Unloader

    • Continuous screw
    1. Conveyor
    • Hinterland conveyor
    • Quay conveyor
    1. Storage
    • Silo
    • Warehouse
    1. Unloading_station
    • Hinterland station
    1. Commodity
    • Maize
    • Soybean
    • Wheat
    1. Vessel
    • Handysize
    • Handymax
    • Panamax
    1. Labour
class opentisim.agribulk_objects.Berth(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.history_properties_mixin, opentisim.agribulk_mixins.berth_properties_mixin, opentisim.agribulk_mixins.hascapex_properties_mixin, opentisim.agribulk_mixins.hasopex_properties_mixin, opentisim.agribulk_mixins.hasrevenue_properties_mixin, opentisim.agribulk_mixins.hastriggers_properties_mixin

class opentisim.agribulk_objects.Commodity(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.commodity_properties_mixin, opentisim.agribulk_mixins.hasscenario_properties_mixin

class opentisim.agribulk_objects.Continuous_Unloader(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.history_properties_mixin, opentisim.agribulk_mixins.continuous_properties_mixin, opentisim.agribulk_mixins.hascapex_properties_mixin, opentisim.agribulk_mixins.hasopex_properties_mixin, opentisim.agribulk_mixins.hasrevenue_properties_mixin, opentisim.agribulk_mixins.hastriggers_properties_mixin

class opentisim.agribulk_objects.Conveyor_Hinter(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.history_properties_mixin, opentisim.agribulk_mixins.conveyor_properties_mixin, opentisim.agribulk_mixins.hascapex_properties_mixin, opentisim.agribulk_mixins.hasopex_properties_mixin, opentisim.agribulk_mixins.hasrevenue_properties_mixin, opentisim.agribulk_mixins.hastriggers_properties_mixin

class opentisim.agribulk_objects.Conveyor_Quay(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.history_properties_mixin, opentisim.agribulk_mixins.conveyor_properties_mixin, opentisim.agribulk_mixins.hascapex_properties_mixin, opentisim.agribulk_mixins.hasopex_properties_mixin, opentisim.agribulk_mixins.hasrevenue_properties_mixin, opentisim.agribulk_mixins.hastriggers_properties_mixin

class opentisim.agribulk_objects.Cyclic_Unloader(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.history_properties_mixin, opentisim.agribulk_mixins.cyclic_properties_mixin, opentisim.agribulk_mixins.hascapex_properties_mixin, opentisim.agribulk_mixins.hasopex_properties_mixin, opentisim.agribulk_mixins.hasrevenue_properties_mixin, opentisim.agribulk_mixins.hastriggers_properties_mixin

class opentisim.agribulk_objects.Energy(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.energy_properties_mixin

class opentisim.agribulk_objects.Labour(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.labour_properties_mixin

class opentisim.agribulk_objects.Quay_wall(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.quay_wall_properties_mixin, opentisim.agribulk_mixins.history_properties_mixin, opentisim.agribulk_mixins.hascapex_properties_mixin, opentisim.agribulk_mixins.hasopex_properties_mixin, opentisim.agribulk_mixins.hasrevenue_properties_mixin, opentisim.agribulk_mixins.hastriggers_properties_mixin

class opentisim.agribulk_objects.Storage(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.history_properties_mixin, opentisim.agribulk_mixins.storage_properties_mixin, opentisim.agribulk_mixins.hascapex_properties_mixin, opentisim.agribulk_mixins.hasopex_properties_mixin, opentisim.agribulk_mixins.hasrevenue_properties_mixin, opentisim.agribulk_mixins.hastriggers_properties_mixin

class opentisim.agribulk_objects.Train(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.train_properties_mixin

class opentisim.agribulk_objects.Unloading_station(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.unloading_station_properties_mixin

class opentisim.agribulk_objects.Vessel(name=[], id=None, *args, **kwargs)

Bases: opentisim.agribulk_mixins.identifiable_properties_mixin, opentisim.agribulk_mixins.vessel_properties_mixin

opentisim.agribulk_system module

class opentisim.agribulk_system.System(startyear=2019, lifecycle=20, operational_hours=5840, debug=False, elements=[], crane_type_defaults={'consumption': 485, 'crane_type': 'Mobile crane', 'crew': 3, 'delivery_time': 1, 'eff_fact': 0.35, 'hourly_cycles': 25, 'insurance_perc': 0.01, 'lifespan': 40, 'lifting_capacity': 30, 'maintenance_perc': 0.02, 'mobilisation_perc': 0.15, 'name': 'Mobile_crane_01', 'ownership': 'Terminal operator', 'unit_rate': 3325000}, storage_type_defaults={'capacity': 6000, 'consumption': 0.002, 'crew': 1, 'delivery_time': 1, 'insurance_perc': 0.01, 'lifespan': 30, 'maintenance_perc': 0.02, 'mobilisation_min': 200000, 'mobilisation_perc': 0.003, 'name': 'Silo_01', 'ownership': 'Terminal operator', 'storage_type': 'Silos', 'type': 'silo', 'unit_rate': 60}, allowable_waiting_service_time_ratio_berth=0.3, allowable_berth_occupancy=0.4, allowable_dwelltime=0.049315068493150684, allowable_waiting_service_time_ratio_station=0.5, allowable_station_occupancy=0.4)[source]

Bases: object

This class implements the ‘complete supply chain’ concept (Van Koningsveld et al, 2020) for agribulk terminals.

The module allows variation of the type of quay crane used and the type of storage used.

Terminal development is governed by the following triggers: - the allowable waiting time as a factor of service time at the berth - the allowable dwell time of cargo in the storage area, and - the allowable waiting time as a factor of service time at the station.

berth_invest(year, handysize, handymax, panamax)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the berth investments.

Decision recipe Berth:

QSC: berth_occupancy & allowable_waiting_service_time_ratio Benchmarking procedure: there is a problem if the estimated berth_occupancy triggers a waiting time over service time ratio that is larger than the allowed waiting time over service time ratio

  • allowable_waiting_service_time_ratio = .30 # 30% (see PIANC (2014))
  • a berth needs:
    • a quay, and
    • cranes (min:1 and max: max_cranes)
  • berth occupancy depends on:
    • total_calls, total_vol and time needed for mooring, unmooring
    • total_service_capacity as delivered by the cranes
  • berth occupancy in combination with nr of berths is used to lookup the waiting over service time ratio
Intervention procedure: invest enough to make the planned waiting service time ratio < allowable waiting

service time ratio - adding berths, quays and cranes decreases berth_occupancy_rate (and increases the number of servers)

which will yield a smaller waiting time over service time ratio
calculate_berth_occupancy(year, handysize_calls, handymax_calls, panamax_calls)[source]
  • Find all cranes and sum their effective_capacity to get service_capacity
  • Divide callsize_per_vessel by service_capacity and add mooring time to get total time at berth
  • Occupancy is total_time_at_berth divided by operational hours
calculate_demurrage_cost(year)[source]

Find the demurrage cost per type of vessel and sum all demurrage cost

calculate_energy_cost(year)[source]
  1. calculate the value of the total demand in year (demand * handling fee)

2. calculate the maximum amount that can be handled (service capacity * operational hours) Terminal.revenues is the minimum of 1. and 2.

calculate_revenue(year)[source]
  1. calculate the value of the total demand in year (demand * handling fee)

2. calculate the maximum amount that can be handled (service capacity * operational hours) Terminal.revenues is the minimum of 1. and 2.

calculate_station_occupancy(year)[source]

The station occupancy is calculated based on the service rate for the throughput of the online quay unloaders (effective capacity * occupancy). The unloading station should at least be able to handle the throughput by the online quay unloaders at a level that the station occupancy planned remains below the target occupancy level.

calculate_vessel_calls(year=2019)[source]

Calculate volumes to be transported and the number of vessel calls (both per vessel type and in total)

check_crane_slot_available()[source]
conveyor_hinter_invest(year, agribulk_defaults_hinterland_conveyor_data)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the hinter conveyor investments.

Operational objective: maintain a hinter conveyor capacity that at least matches the station unloading capacity (so basically the hinter conveyors follow what happens on the station)

Decision recipe quay conveyor:

QSC: hinter_conveyor_capacity planned Benchmarking procedure: there is a problem when the hinter_conveyor_capacity_planned is smaller than the station_service_rate_planned

For the hinter conveyor investments the strategy is to at least match the unloading station capacity
Intervention procedure: the intervention strategy is to add hinter conveyors until the trigger is achieved
  • find out how much hinter_conveyor_capacity is planned
  • find out how much station_service_rate_planned is planned
  • add hinter_conveyor_capacity until it matches station_service_rate_planned
conveyor_quay_invest(year, agribulk_defaults_quay_conveyor_data)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the quay conveyor investments.

Operational objective: maintain a quay conveyor capacity that at least matches the quay crane capacity (so basically the quay conveyors follow what happens on the berth)

Decision recipe quay conveyor:

QSC: quay_conveyor_capacity planned Benchmarking procedure: there is a problem when the quay_conveyor_capacity_planned is smaller than the quay_crane_service_rate_planned

For the quay conveyor investments the strategy is to at least match the quay crane processing capacity
Intervention procedure: the intervention strategy is to add quay conveyors until the trigger is achieved
  • find out how much quay_conveyor_capacity is planned
  • find out how much quay_crane_service_rate is planned
  • add quay_conveyor_capacity until it matches quay_crane_service_rate
crane_invest(year)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the crane investments.

Decision recipe Crane:
QSC: planned waiting over service time ratio Benchmarking procedure (triggered in self.berth_invest): there is a problem when the planned planned waiting over service time ratio is larger than the max allowable waiting over service time ratio Intervention procedure: invest until planned waiting over service time ratio is below the max allowable waiting over service time ratio
quay_invest(year, length, depth)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the quay investments.

Decision recipe Quay:

QSC: quay_per_berth Benchmarking procedure (triggered in self.berth_invest): there is a problem when

the number of berths > the number of quays, but also while the planned waiting over service time ratio is too large

Intervention procedure: invest enough to make sure that each quay has a berth and the planned waiting over service time ratio is below the max allowable waiting over service time ratio

  • adding quay will increase quay_per_berth
  • quay_wall.length must be long enough to accommodate largest expected vessel
  • quay_wall.depth must be deep enough to accommodate largest expected vessel
  • quay_wall.freeboard must be high enough to accommodate largest expected vessel
simulate()[source]

The ‘simulate’ method implements the terminal investment strategy for this terminal class.

This method automatically generates investment decisions, parametrically derived from overall demand trends and a number of investment triggers.

Generic approaches based on: - PIANC. 2014. Master plans for the development of existing ports. MarCom - Report 158, PIANC - Van Koningsveld, M. (Ed.), Verheij, H., Taneja, P. and De Vriend, H.J. (in preparation). Ports and Waterways.

Navigating the changing world. TU Delft, Delft, The Netherlands.
  • Van Koningsveld, M. and J. P. M. Mulder. 2004. Sustainable Coastal Policy Developments in the Netherlands. A Systematic Approach Revealed. Journal of Coastal Research 20(2), pp. 375-385

Specific application based on (modifications have been applied where deemed an improvement): - Ijzermans, W., 2019. Terminal design optimization. Adaptive agribulk terminal planning

in light of an uncertain future. Master’s thesis. Delft University of Technology, Netherlands. URL: http://resolver.tudelft.nl/uuid:7ad9be30-7d0a-4ece-a7dc-eb861ae5df24.

The simulate method applies Frame of Reference style decisions while stepping through each year of the terminal lifecycle and checks if investments are needed (in light of strategic objective, operational objective, QSC, decision recipe and intervention method):

  1. for each year estimate the anticipated vessel arrivals based on the expected demand
  2. for each year evaluate which investments are needed given the strategic and operational objectives
  3. for each year calculate the energy costs (requires insight in realized demands)
  4. for each year calculate the demurrage costs (requires insight in realized demands)
  5. for each year calculate terminal revenues (requires insight in realized demands)
  6. collect all cash flows (capex, opex, revenues)
  7. calculate PV’s and aggregate to NPV
storage_invest(year, agribulk_defaults_storage_data)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the storage investments.

Operational objective: maintain a storage capacity that is large enough to at least contain one time the largest vessel call size or that is large enough to accommodate a maximum allowable dwell time plus 10 percent.

Decision recipe storage:

QSC: storage_capacity Benchmarking procedure: there is a problem when the storage_capacity is too small to store one time the largest call size or when it is too small to allow for a predetermined max allowable dwell time

The max allowable dwell time is here determined as 5% of the annual demand, increased by 10% (PIANC, 2014)

Intervention procedure: the intervention strategy is to add storage until the benchmarking trigger is achieved. The trigger is the max of one call size, or the volume derived from the dwell time requirement.

terminal_capacity_plot(width=0.25, alpha=0.6, fontsize=20)[source]

Gather data from Terminal and plot which elements come online when

terminal_elements_plot(width=0.1, alpha=0.6, fontsize=20, demand_step=100000)[source]

Gather data from Terminal and plot which elements come online when

train_call(year)[source]

Calculation of the train calls per year, this is calculated from: - find out how much throughput there is - find out how much cargo the train can transport - calculate the numbers of train calls

unloading_station_invest(year)[source]

The operational objective for the investment strategy for unloading stations is to have sufficient planned unloading stations to keep the station occupancy below a given threshold for the quay crane capacity planned.

current strategy is to add unloading stations as soon as a service trigger is achieved - find out how much service capacity is online - find out how much service capacity is planned - find out how much service capacity is needed - add service capacity until service_trigger is no longer exceeded

opentisim.container_defaults module

Main generic object classes: - 1. Quay_wall - 2. Berth - 3. Cyclic_Unloader

  • STS crane
    1. Horizontal transport
    • Tractor trailer
    1. Commodity
    • TEU
    1. Containers
    • Laden
    • Reefer
    • Empty
    • OOG
    1. Laden and reefer stack
    1. Stack equipment
    1. Empty stack
    1. OOG stack
    1. Gates
    1. Empty handler
    1. Vessel
    1. Labour
    1. Energy
    1. General
    1. Indirect Costs

opentisim.container_mixins module

Basic properties mixins:

  • identifiable_properties_mixin
  • history_properties_mixin
  • hascapex_properties_mixin
  • hasopex_properties_mixin
  • hasrevenue_properties_mixin
  • hastriggers_properties_mixin
  • quay_wall_properties_mixin
  • berth_properties_mixin
  • cyclic_properties_mixin
  • transport_properties_mixin
  • container_properties_mixin
  • laden_stack_properties_mixin
  • empty_stack_properties_mixin
  • oog_stack_properties_mixin
  • stack_equipment_properties_mixin
  • gate_properties_mixin
  • empty_handler_properties_mixin
  • commodity_properties_mixin
  • vessel_properties_mixin
  • labour_properties_mixin
  • hasscenario_properties_mixin
class opentisim.container_mixins.berth_properties_mixin(crane_type, max_cranes, delivery_time, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.commodity_properties_mixin(handling_fee, fully_cellular_perc, panamax_perc, panamax_max_perc, post_panamax_I_perc, post_panamax_II_perc, new_panamax_perc, VLCS_perc, ULCS_perc, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.container_properties_mixin(type, teu_factor, dwell_time, peak_factor, stack_occupancy, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.cyclic_properties_mixin(ownership, delivery_time, lifespan, unit_rate, mobilisation_perc, maintenance_perc, consumption, insurance_perc, crew, crane_type, lifting_capacity, hourly_cycles, eff_fact, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.empty_handler_properties_mixin(type, ownership, delivery_time, lifespan, unit_rate, mobilisation, maintenance_perc, crew, salary, fuel_consumption, required, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.empty_stack_properties_mixin(ownership, delivery_time, lifespan, mobilisation, maintenance_perc, width, height, length, capacity, gross_tgs, area_factor, pavement, drainage, household, digout, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.energy_properties_mixin(price, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.gate_properties_mixin(type, ownership, delivery_time, lifespan, unit_rate, mobilisation, maintenance_perc, crew, salary, canopy_costs, area, staff_gates, service_gates, design_capacity, exit_inspection_time, entry_inspection_time, peak_hour, peak_day, peak_factor, truck_moves, operating_days, capacity, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.general_services_mixin(type, office, office_cost, workshop, workshop_cost, fuel_station_cost, scanning_inspection_area, scanning_inspection_area_cost, lighting_mast_required, lighting_mast_cost, firefight_cost, maintenance_tools_cost, terminal_operating_software_cost, electrical_station_cost, repair_building, repair_building_cost, ceo, secretary, administration, hr, commercial, operations, engineering, security, general_maintenance, crew_required, delivery_time, lighting_consumption, general_consumption, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.hascapex_properties_mixin(capex=[], *args, **kwargs)[source]

Bases: object

Something has CAPEX

capex: list with cost to be applied from investment year

class opentisim.container_mixins.hasland_properties_mixin(land_use=[], *args, **kwargs)[source]

Bases: object

Something has land use [m^2]

land_use: list with land use to be applied from investment year

class opentisim.container_mixins.hasopex_properties_mixin(labour=[], maintenance=[], energy=[], insurance=[], lease=[], demurrage=[], residual=[], fuel=[], *args, **kwargs)[source]

Bases: object

Something has OPEX

opex: list with cost to be applied from investment year

class opentisim.container_mixins.hasrevenue_properties_mixin(renevue=[], *args, **kwargs)[source]

Bases: object

Something has Revenue

revenue: list with revenues to be applied from investment year

class opentisim.container_mixins.hasscenario_properties_mixin(historic_data=[], scenario_data=[], *args, **kwargs)[source]

Bases: object

Something has a scenario

historic_data: observed demand scenario_data: generated estimates of future demand

plot_demand(width=0.1, alpha=0.6, fontsize=20)[source]

generate a histogram of the demand data

scenario_random(startyear=2019, lifecycle=20, rate=1.02, mu=0.01, sigma=0.065)[source]

trend generated from random growth rate increments

class opentisim.container_mixins.hastriggers_properties_mixin(triggers=[], *args, **kwargs)[source]

Bases: object

Something has InvestmentTriggers

triggers: list with revenues to be applied from investment year

class opentisim.container_mixins.history_properties_mixin(year_purchase=[], year_online=[], *args, **kwargs)[source]

Bases: object

Something that has a purchase history

purchase_date: year in which the decision was made to add another element online_date: year by which the elements starts to perform

class opentisim.container_mixins.identifiable_properties_mixin(name=[], id=None, *args, **kwargs)[source]

Bases: object

Something that has a name and id

name: a name id: a unique id generated with uuid

class opentisim.container_mixins.indirect_costs_mixin(preliminaries, engineering, miscellaneous, electrical_works_fuel_terminal, electrical_works_power_terminal, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.labour_properties_mixin(international_salary, international_staff, local_salary, local_staff, operational_salary, shift_length, annual_shifts, daily_shifts, blue_collar_salary, white_collar_salary, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.laden_stack_properties_mixin(ownership, delivery_time, lifespan, mobilisation, maintenance_perc, width, height, length, capacity, gross_tgs, area_factor, pavement, drainage, household, digout_margin, reefer_factor, consumption, reefer_rack, reefers_present, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.land_price_mixin(price, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.oog_stack_properties_mixin(ownership, delivery_time, lifespan, mobilisation, maintenance_perc, width, height, length, capacity, gross_tgs, area_factor, pavement, drainage, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.quay_wall_properties_mixin(ownership, delivery_time, lifespan, mobilisation_min, mobilisation_perc, maintenance_perc, insurance_perc, berthing_gap, freeboard, Gijt_constant, Gijt_coefficient, max_sinkage, wave_motion, safety_margin, apron_width, apron_pavement, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.stack_equipment_properties_mixin(type, ownership, delivery_time, lifespan, unit_rate, mobilisation, maintenance_perc, insurance_perc, crew, salary, required, fuel_consumption, power_consumption, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.transport_properties_mixin(type, ownership, delivery_time, lifespan, unit_rate, mobilisation, maintenance_perc, insurance_perc, crew, salary, utilisation, fuel_consumption, productivity, required, non_essential_moves, *args, **kwargs)[source]

Bases: object

class opentisim.container_mixins.vessel_properties_mixin(type, delivery_time, call_size, LOA, draught, beam, max_cranes, all_turn_time, mooring_time, demurrage_rate, transport_costs, all_in_transport_costs, *args, **kwargs)[source]

Bases: object

opentisim.container_objects module

Main generic object classes:

    1. Quay_wall
    1. Berth
    1. Cyclic_Unloader
    • STS crane
    1. Horizontal transport
    • Tractor trailer
    1. Commodity
    • TEU
    1. Containers
    • Laden
    • Reefer
    • Empty
    • OOG
    1. Laden and reefer stack
    • RTG stack
    • RMG stack
    • SC stack
    • RS stack
    1. Stack equipment
    • RTG
    • RMG
    • SC
    • RS
    1. Empty stack
    1. OOG stack
    1. Gates
    1. Empty handler
    1. Vessel
    1. Labour
    1. Energy
    1. General
    1. Indirect Costs
class opentisim.container_objects.Berth(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.berth_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hasrevenue_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin

class opentisim.container_objects.Commodity(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.commodity_properties_mixin, opentisim.container_mixins.hasscenario_properties_mixin

class opentisim.container_objects.Container(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.container_properties_mixin

class opentisim.container_objects.Cyclic_Unloader(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.cyclic_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hasrevenue_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin

class opentisim.container_objects.Empty_Handler(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.empty_handler_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin

class opentisim.container_objects.Empty_Stack(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.empty_stack_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin, opentisim.container_mixins.hasland_properties_mixin

class opentisim.container_objects.Energy(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.energy_properties_mixin

class opentisim.container_objects.Gate(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.gate_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin, opentisim.container_mixins.hasland_properties_mixin

class opentisim.container_objects.General_Services(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.hasland_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.general_services_mixin, opentisim.container_mixins.history_properties_mixin

class opentisim.container_objects.Horizontal_Transport(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.transport_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin

opentisim.container_objects.Indirect_Costs

alias of opentisim.container_objects.Indirect Costs

class opentisim.container_objects.Labour(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.labour_properties_mixin

class opentisim.container_objects.Laden_Stack(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.laden_stack_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin, opentisim.container_mixins.hasland_properties_mixin

opentisim.container_objects.Land_Price

alias of opentisim.container_objects.Land Price

class opentisim.container_objects.OOG_Stack(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.oog_stack_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin, opentisim.container_mixins.hasland_properties_mixin

class opentisim.container_objects.Quay_wall(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.quay_wall_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hasrevenue_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin, opentisim.container_mixins.hasland_properties_mixin

class opentisim.container_objects.Stack_Equipment(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.history_properties_mixin, opentisim.container_mixins.stack_equipment_properties_mixin, opentisim.container_mixins.hascapex_properties_mixin, opentisim.container_mixins.hasopex_properties_mixin, opentisim.container_mixins.hastriggers_properties_mixin

class opentisim.container_objects.Vessel(name=[], id=None, *args, **kwargs)

Bases: opentisim.container_mixins.identifiable_properties_mixin, opentisim.container_mixins.vessel_properties_mixin

opentisim.container_system module

class opentisim.container_system.System(terminal_name='Terminal', startyear=2019, lifecycle=20, operational_hours=7500, debug=False, elements=[], crane_type_defaults={'consumption': 8, 'crane_type': 'STS crane', 'crew': 5.5, 'delivery_time': 1, 'eff_fact': 0.75, 'hourly_cycles': 25, 'insurance_perc': 0.01, 'lifespan': 40, 'lifting_capacity': 2.13, 'maintenance_perc': 0.02, 'mobilisation_perc': 0.15, 'name': 'STS_crane', 'ownership': 'Terminal operator', 'unit_rate': 10000000}, stack_equipment='rs', laden_stack='rs', allowable_waiting_service_time_ratio_berth=0.1, allowable_berth_occupancy=0.6, laden_perc=0.8, reefer_perc=0.1, empty_perc=0.05, oog_perc=0.05, transhipment_ratio=0.69, energy_price=0.17, fuel_price=1, land_price=0)[source]

Bases: object

This class implements the ‘complete supply chain’ concept (Van Koningsveld et al, 2020) for container terminals.

The module allows variation of the type of quay crane used and the type of quay crane used and the type of stack equipment used.

Terminal development is governed by the following triggers: - the allowable waiting time as a factor of service time at the berth, and - the distribution ratios (adding up to 1) for:

  • ladens
  • empties
  • reefers
  • out of gauges
  • the transhipment ratio
berth_invest(year, fully_cellular, panamax, panamax_max, post_panamax_I, post_panamax_II, new_panamax, VLCS, ULCS)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the berth investments.

Decision recipe Berth:

QSC: berth_occupancy & allowable_waiting_service_time_ratio Benchmarking procedure: there is a problem if the estimated berth_occupancy triggers a waiting time over service time ratio that is larger than the allowed waiting time over service time ratio

  • allowable_waiting_service_time_ratio = .10 # 10% (see PIANC (2014, 2014b))
  • a berth needs:
    • a quay
    • cranes (min:1 and max: max_cranes)
  • berth occupancy depends on:
    • total_calls, total_vol and time needed for mooring, unmooring
    • total_service_capacity as delivered by the cranes
  • berth occupancy in combination with nr of berths is used to lookup the waiting over service time ratio
Intervention procedure: invest enough to make the planned waiting service time ratio < allowable waiting

service time ratio - adding berths, quays and cranes decreases berth_occupancy_rate (and increases the number of servers)

which will yield a smaller waiting time over service time ratio
box_moves(year)[source]

Calculate the box moves as input for the power and fuel consumption

calculate_berth_occupancy(year, fully_cellular_calls, panamax_calls, panamax_max_calls, post_panamax_I_calls, post_panamax_II_calls, new_panamax_calls, VLCS_calls, ULCS_calls)[source]
  • Find all cranes and sum their effective_capacity to get service_capacity
  • Divide callsize_per_vessel by service_capacity and add mooring time to get total time at berth
  • Occupancy is total_time_at_berth divided by operational hours
calculate_demurrage_cost(year)[source]

Find the demurrage cost per type of vessel and sum all demurrage cost

calculate_energy_cost(year)[source]

# todo voeg energy toe voor nieuwe elementen

calculate_fuel_cost(year)[source]

Fuel cost

calculate_gate_minutes(year)[source]
  • Find all gates and sum their effective_capacity to get service_capacity
  • Calculate average entry and exit time to get total time at gate
  • Occupancy is total_minutes_at_gate per hour divided by 1 hour
calculate_general_labour_cost(year)[source]

General labour

calculate_indirect_costs()[source]

Indirect costs are a function of overall CAPEX.

calculate_land_use(year)[source]

Calculate total land use by summing all land_use values of the physical terminal elements

calculate_throughput(year)[source]

Find throughput (minimum of crane capacity and demand)

calculate_vessel_calls(year)[source]

Calculate volumes to be transported and the number of vessel calls (both per vessel type and in total)

check_crane_slot_available()[source]
crane_invest(year)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the crane investments.

Decision recipe Crane:
QSC: planned waiting over service time ratio Benchmarking procedure (triggered in self.berth_invest): there is a problem when the planned planned waiting over service time ratio is larger than the max allowable waiting over service time ratio Intervention procedure: invest until planned waiting over service time ratio is below the max allowable waiting over service time ratio
empty_handler_invest(year)[source]

current strategy is to add empty hanlders as soon as a service trigger is achieved - find out how many empty handlers are online - find out how many empty handlers areplanned - find out how many empty handlers are needed - add empty handlers until service_trigger is no longer exceeded

empty_stack_capacity(year)[source]

Calculate the stack capacity for empty containers

empty_stack_invest(year)[source]

current strategy is to add stacks as soon as trigger is achieved - find out how much stack capacity is online - find out how much stack capacity is planned - find out how much stack capacity is needed - add stack capacity until service_trigger is no longer exceeded

gate_invest(year)[source]

current strategy is to add gates as soon as trigger is achieved - find out how much gate capacity is online - find out how much gate capacity is planned - find out how much gate capacity is needed - add gate capacity until service_trigger is no longer exceeded

general_services_invest(year)[source]
horizontal_transport_invest(year)[source]

current strategy is to add horizontal transport (tractors) as soon as a service trigger is achieved - find out how many cranes are online and planned - find out how many tractors trailers are online and planned (each STS needs a pre-set number of tractors trailers) - add tractor trailers until the required amount (given by the cranes) is achieved

laden_reefer_stack_capacity(year)[source]

Calculate the stack capacity for laden and reefer containers

laden_reefer_stack_invest(year)[source]
current strategy is to add stacks as soon as trigger is achieved
  • find out how much stack capacity is planned
  • find out how much stack capacity is required
  • add stack capacity until service_trigger is no longer exceeded

The laden stack has a number of positions for laden containers and a number of positions for reefer containers

laden_stack_area_plot(width=0.25, alpha=0.6)[source]

Gather data from laden stack area and plot it against demand

land_use_plot(width=0.25, alpha=0.6, fontsize=20)[source]

Gather data from Terminal and plot which elements come online when

oog_stack_capacity(year)[source]

Calculate the stack capacity for OOG containers

oog_stack_invest(year)[source]

Current strategy is to add stacks as soon as trigger is achieved - find out how much stack capacity is planned - find out how much stack capacity is needed - add stack capacity until service_trigger is no longer exceeded

opex_plot(cash_flows)[source]

Gather data from Terminal elements and combine into a cash flow plot

quay_invest(year, length, depth)[source]

Given the overall objectives for the terminal apply the following decision recipe (Van Koningsveld and Mulder, 2004) for the quay investments.

Decision recipe Quay:

QSC: quay_per_berth Benchmarking procedure (triggered in self.berth_invest): there is a problem when

the number of berths > the number of quays, but also while the planned waiting over service time ratio is too large

Intervention procedure: invest enough to make sure that each quay has a berth and the planned waiting over service time ratio is below the max allowable waiting over service time ratio

  • adding quay will increase quay_per_berth
  • quay_wall.length must be long enough to accommodate largest expected vessel
  • quay_wall.depth must be deep enough to accommodate largest expected vessel
  • quay_wall.freeboard must be high enough to accommodate largest expected vessel
simulate()[source]

The ‘simulate’ method implements the terminal investment strategy for this terminal class.

This method automatically generates investment decisions, parametrically derived from overall demand trends and a number of investment triggers.

Generic approaches based on: - Quist, P. and Wijdeven, B., 2014. Ports & Terminals Hand-out. Chapter 7 Container terminals. CIE4330/CIE5306 - PIANC. 2014. Master plans for the development of existing ports. MarCom - Report 158, PIANC - PIANC. 2014b. Design principles for small and medium marine containter terminals. MarCom - Report 135, PIANC - Van Koningsveld, M. (Ed.), Verheij, H., Taneja, P. and De Vriend, H.J. (2020). Ports and Waterways.

Navigating the changing world. TU Delft, Delft, The Netherlands.
  • Van Koningsveld, M. and J. P. M. Mulder. 2004. Sustainable Coastal Policy Developments in the Netherlands. A Systematic Approach Revealed. Journal of Coastal Research 20(2), pp. 375-385

Specific application based on (modifications have been applied where deemed an improvement): - Koster, P.H.F., 2019. Concept level container terminal design. Investigating the consequences of accelerating

the concept design phase by modelling the automatable tasks. Master’s thesis. Delft University of Technology, Netherlands. URL: http://resolver.tudelft.nl/uuid:131133bf-9021-4d67-afcb-233bd8302ce0.
  • Stam, H.W.B., 2020. Offshore-Onshore Port Systems. A framework for the financial evaluation of offshore container terminals. Master’s thesis. Delft University of Technology, Netherlands.

The simulate method applies frame of reference style decisions while stepping through each year of the terminal lifecycle and check if investment is needed (in light of strategic objective, operational objective, QSC, decision recipe, intervention method):

  1. for each year estimate the anticipated vessel arrivals based on the expected demand
  2. for each year evaluate which investment are needed given the strategic and operational objectives
  3. for each year calculate the energy costs (requires insight in realized demands)
  4. for each year calculate the demurrage costs (requires insight in realized demands)
  5. for each year calculate terminal revenues (requires insight in realized demands)
  6. collect all cash flows (capex, opex, [revenues])
  7. calculate PV’s and aggregate to NPV
stack_equipment_invest(year)[source]

current strategy is to add stack equipment as soon as a service trigger is achieved - find out how much stack equipment is online - find out how much stack equipment is planned - find out how much stack equipment is needed - add equipment until service_trigger is no longer exceeded

terminal_capacity_plot(width=0.25, alpha=0.6)[source]

Gather data from Terminal and plot which elements come online when

terminal_elements_plot(width=0.08, alpha=0.6, fontsize=20, demand_step=50000)[source]

Gather data from Terminal and plot which elements come online when

throughput_box(year)[source]
  • Find the total TEU/year for every throughput type (types: ladens, empties, reefers, oogs)
  • Translate the total TEU/year to number of boxes for every throughput type
throughput_characteristics(year)[source]
  • Find commodity volume
  • Find the on terminal modal split (types: ladens, empties, reefers, oogs)
  • Return the total TEU/year for every throughput type

opentisim.hydrogen_defaults module

Defaults for following objects:

    1. Jetty
    1. Berth
    1. Unloader
    • Liquid hydrogen
    • Ammonia
    • MCH
    1. Pipelines
    • jetty
    • hinterland
    1. Storage
    • Liquid hydrogen
    • Ammonia
    • MCH
    1. H2 retrieval
    • Ammonia
    • MCH
    1. Commodity
    • Liquid hydrogen
    • Ammonia
    • MCH
    1. Vessel
    • smallhydrogen
    • largehydrogen
    • smallammonia
    • largeammonia
    • Handysize
    • Panamax
    • VLCC
    1. Labour

Default values are based on Claes 2018; Corbeau 2018; Daas 2018; Juha 2018; Kranendonk 2018; Schutz 2018; Schuurmans 2018 and Verstegen 2018

opentisim.hydrogen_defaults.commodity_MCH_data = {'handling_fee': 1000, 'handysize_perc': 30, 'historic_data': year volume 0 2014 1000000 1 2015 1100000 2 2016 1250000 3 2017 1400000 4 2018 1500000, 'largeammonia_perc': 0, 'largehydrogen_perc': 0, 'name': 'MCH', 'panamax_perc': 40, 'smallammonia_perc': 0, 'smallhydrogen_perc': 0, 'type': 'MCH', 'vlcc_perc': 30}

Liquid hydrogen:

opentisim.hydrogen_defaults.h2retrieval_lh2_data = {'capacity': 171, 'consumption': 600, 'crew_for5': 1, 'crew_min': 3, 'delivery_time': 2, 'h2retrieval_type': 'tank', 'insurance_perc': 0.01, 'lifespan': 10, 'maintenance_perc': 0.015, 'mobilisation_min': 200000, 'mobilisation_perc': 0.003, 'name': 'H2retrieval_LH2_01', 'ownership': 'Terminal operator', 'type': 'HydrogenTank', 'unit_rate': 18000000}

Ammonia

opentisim.hydrogen_defaults.h2retrieval_nh3_data = {'capacity': 55, 'consumption': 5889, 'crew_for5': 1, 'crew_min': 3, 'delivery_time': 2, 'h2retrieval_type': 'tank', 'insurance_perc': 0.01, 'lifespan': 20, 'maintenance_perc': 0.015, 'mobilisation_min': 200000, 'mobilisation_perc': 0.003, 'name': 'H2retrieval_NH3_01', 'ownership': 'Terminal operator', 'type': 'AmmoniaTank', 'unit_rate': 100000000}

MCH

opentisim.hydrogen_defaults.hinterland_pipeline_data = {'capacity': 4000, 'consumption_coefficient': 80, 'crew': 1, 'delivery_time': 1, 'insurance_perc': 0.01, 'length': 400, 'lifespan': 26, 'maintenance_perc': 0.01, 'mobilisation': 30000, 'name': 'hinterland_pipeline_01', 'ownership': 'Terminal operator', 'type': 'hinterland_pipeline', 'unit_rate_factor': 193000, 'utilisation': 0.8}

Liquid hydrogen

opentisim.hydrogen_defaults.largeammonia_data = {'LOA': 230, 'all_turn_time': 24, 'beam': 40, 'call_size': 55000, 'demurrage_rate': 750, 'draft': 11, 'max_cranes': 2, 'mooring_time': 3, 'name': 'largeammonia_1', 'pump_capacity': 5500, 'type': 'Largeammonia'}

MCH:

opentisim.hydrogen_defaults.largehydrogen_data = {'LOA': 300, 'all_turn_time': 30, 'beam': 43, 'call_size': 30000, 'demurrage_rate': 700, 'draft': 12, 'max_cranes': 3, 'mooring_time': 3, 'name': 'largehydrogen_1', 'pump_capacity': 3000, 'type': 'Largehydrogen'}

Ammonia:

opentisim.hydrogen_defaults.storage_MCH_data = {'capacity': 38500, 'consumption': 10, 'crew_for5': 1, 'crew_min': 3, 'delivery_time': 1, 'insurance_perc': 0.01, 'lifespan': 50, 'maintenance_perc': 0.01, 'mobilisation_min': 200000, 'mobilisation_perc': 0.003, 'name': 'MCHTank_01', 'ownership': 'Terminal operator', 'storage_type': 'tank', 'type': 'MCHTank', 'unit_rate': 35000000}

Liquid hydrogen

opentisim.hydrogen_defaults.storage_lh2_data = {'capacity': 3540, 'consumption': 610, 'crew_for5': 1, 'crew_min': 3, 'delivery_time': 1, 'insurance_perc': 0.01, 'lifespan': 30, 'maintenance_perc': 0.01, 'mobilisation_min': 200000, 'mobilisation_perc': 0.003, 'name': 'HTank_01', 'ownership': 'Terminal operator', 'storage_type': 'tank', 'type': 'HydrogenTank', 'unit_rate': 200000000}

Ammonia

opentisim.hydrogen_defaults.storage_nh3_data = {'capacity': 34130, 'consumption': 100, 'crew_for5': 1, 'crew_min': 3, 'delivery_time': 1, 'insurance_perc': 0.01, 'lifespan': 30, 'maintenance_perc': 0.01, 'mobilisation_min': 200000, 'mobilisation_perc': 0.003, 'name': 'ATank_01', 'ownership': 'Terminal operator', 'storage_type': 'tank', 'type': 'AmmoniaTank', 'unit_rate': 60000000}

MCH

opentisim.hydrogen_mixins module

Basic properties mixins:

  • identifiable_properties_mixin
  • history_properties_mixin
  • hascapex_properties_mixin
  • hasopex_properties_mixin
  • hasrevenue_properties_mixin
  • hastriggers_properties_mixin
  • jetty_properties_mixin
  • berth_properties_mixin
  • cyclic_properties_mixin
  • continuous_properties_mixin
  • pipeline_properties_mixin
  • storage_properties_mixin
  • commodity_properties_mixin
  • vessel_properties_mixin
  • labour_properties_mixin
  • hasscenario_properties_mixin
class opentisim.hydrogen_mixins.berth_properties_mixin(crane_type, delivery_time, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.commodity_properties_mixin(type, handling_fee, smallhydrogen_perc, largehydrogen_perc, smallammonia_perc, largeammonia_perc, handysize_perc, panamax_perc, vlcc_perc, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.energy_properties_mixin(price, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.h2retrieval_properties_mixin(type, ownership, delivery_time, lifespan, unit_rate, mobilisation_min, mobilisation_perc, maintenance_perc, crew_min, crew_for5, insurance_perc, h2retrieval_type, consumption, capacity, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.hascapex_properties_mixin(capex=[], *args, **kwargs)[source]

Bases: object

Something has CAPEX

capex: list with cost to be applied from investment year

class opentisim.hydrogen_mixins.hasopex_properties_mixin(labour=[], maintenance=[], energy=[], insurance=[], lease=[], demurrage=[], *args, **kwargs)[source]

Bases: object

Something has OPEX

opex: list with cost to be applied from investment year

class opentisim.hydrogen_mixins.hasrevenue_properties_mixin(renevue=[], residual=[], *args, **kwargs)[source]

Bases: object

Something has Revenue

revenue: list with revenues to be applied from investment year

class opentisim.hydrogen_mixins.hasscenario_properties_mixin(historic_data=[], scenario_data=[], *args, **kwargs)[source]

Bases: object

Something has a scenario

historic_data: observed demand scenario_data: generated estimates of future demand

plot_demand(width=0.1, alpha=0.6, fontsize=20)[source]

generate a histogram of the demand data

scenario_random(startyear=2019, lifecycle=20, rate=1.02, mu=0.01, sigma=0.065)[source]

trend generated from random growth rate increments

class opentisim.hydrogen_mixins.hastriggers_properties_mixin(triggers=[], *args, **kwargs)[source]

Bases: object

Something has InvestmentTriggers

triggers: list with revenues to be applied from investment year

class opentisim.hydrogen_mixins.history_properties_mixin(year_purchase=[], year_online=[], *args, **kwargs)[source]

Bases: object

Something that has a purchase history

purchase_date: year in which the decision was made to add another element online_date: year by which the elements starts to perform

class opentisim.hydrogen_mixins.identifiable_properties_mixin(name=[], id=None, *args, **kwargs)[source]

Bases: object

Something that has a name and id

name: a name id: a unique id generated with uuid

class opentisim.hydrogen_mixins.jetty_properties_mixin(ownership, delivery_time, lifespan, mobilisation_min, mobilisation_perc, maintenance_perc, insurance_perc, Gijt_constant_jetty, jettywidth, jettylength, mooring_dolphins, catwalkwidth, catwalklength, Catwalk_rate, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.labour_properties_mixin(international_salary, international_staff, local_salary, local_staff, operational_salary, shift_length, annual_shifts, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.pipeline_properties_mixin(type, length, ownership, delivery_time, lifespan, unit_rate_factor, mobilisation, maintenance_perc, insurance_perc, consumption_coefficient, crew, utilisation, capacity, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.storage_properties_mixin(type, ownership, delivery_time, lifespan, unit_rate, mobilisation_min, mobilisation_perc, maintenance_perc, crew_min, crew_for5, insurance_perc, storage_type, consumption, capacity, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.train_properties_mixin(wagon_payload, number_of_wagons, *args, **kwargs)[source]

Bases: object

class opentisim.hydrogen_mixins.vessel_properties_mixin(type, call_size, LOA, draft, beam, max_cranes, all_turn_time, pump_capacity, mooring_time, demurrage_rate, *args, **kwargs)[source]

Bases: object

opentisim.hydrogen_objects module

Main generic object classes:

Defaults for following objects: - 1. Jetty - 2. Berth - 3. Unloader

  • Liquid hydrogen
  • Ammonia
  • MCH
    1. Pipelines
    • jetty
    • hinterland
    1. Storage
    • Liquid hydrogen
    • Ammonia
    • MCH
    1. H2 retrieval
    • Ammonia
    • MCH
    1. Commodity
    • Liquid hydrogen
    • Ammonia
    • MCH
    1. Vessel
    • smallhydrogen
    • largehydrogen
    • smallammonia
    • largeammonia
    • Handysize
    • Panamax
    • VLCC
    1. Labour
class opentisim.hydrogen_objects.Berth(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.history_properties_mixin, opentisim.hydrogen_mixins.berth_properties_mixin, opentisim.hydrogen_mixins.hascapex_properties_mixin, opentisim.hydrogen_mixins.hasopex_properties_mixin, opentisim.hydrogen_mixins.hasrevenue_properties_mixin, opentisim.hydrogen_mixins.hastriggers_properties_mixin

class opentisim.hydrogen_objects.Commodity(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.commodity_properties_mixin, opentisim.hydrogen_mixins.hasscenario_properties_mixin

class opentisim.hydrogen_objects.Energy(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.energy_properties_mixin

class opentisim.hydrogen_objects.H2retrieval(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.history_properties_mixin, opentisim.hydrogen_mixins.h2retrieval_properties_mixin, opentisim.hydrogen_mixins.hascapex_properties_mixin, opentisim.hydrogen_mixins.hasopex_properties_mixin, opentisim.hydrogen_mixins.hasrevenue_properties_mixin, opentisim.hydrogen_mixins.hastriggers_properties_mixin

class opentisim.hydrogen_objects.Jetty(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.jetty_properties_mixin, opentisim.hydrogen_mixins.history_properties_mixin, opentisim.hydrogen_mixins.hascapex_properties_mixin, opentisim.hydrogen_mixins.hasopex_properties_mixin, opentisim.hydrogen_mixins.hasrevenue_properties_mixin, opentisim.hydrogen_mixins.hastriggers_properties_mixin

class opentisim.hydrogen_objects.Labour(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.labour_properties_mixin

class opentisim.hydrogen_objects.Pipeline_Hinter(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.history_properties_mixin, opentisim.hydrogen_mixins.pipeline_properties_mixin, opentisim.hydrogen_mixins.hascapex_properties_mixin, opentisim.hydrogen_mixins.hasopex_properties_mixin, opentisim.hydrogen_mixins.hasrevenue_properties_mixin, opentisim.hydrogen_mixins.hastriggers_properties_mixin

class opentisim.hydrogen_objects.Pipeline_Jetty(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.history_properties_mixin, opentisim.hydrogen_mixins.pipeline_properties_mixin, opentisim.hydrogen_mixins.hascapex_properties_mixin, opentisim.hydrogen_mixins.hasopex_properties_mixin, opentisim.hydrogen_mixins.hasrevenue_properties_mixin, opentisim.hydrogen_mixins.hastriggers_properties_mixin

class opentisim.hydrogen_objects.Storage(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.history_properties_mixin, opentisim.hydrogen_mixins.storage_properties_mixin, opentisim.hydrogen_mixins.hascapex_properties_mixin, opentisim.hydrogen_mixins.hasopex_properties_mixin, opentisim.hydrogen_mixins.hasrevenue_properties_mixin, opentisim.hydrogen_mixins.hastriggers_properties_mixin

class opentisim.hydrogen_objects.Train(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.train_properties_mixin

class opentisim.hydrogen_objects.Vessel(name=[], id=None, *args, **kwargs)

Bases: opentisim.hydrogen_mixins.identifiable_properties_mixin, opentisim.hydrogen_mixins.vessel_properties_mixin

opentisim.hydrogen_system module

class opentisim.hydrogen_system.System(startyear=2019, lifecycle=20, operational_hours=5840, debug=False, elements=[], commodity_type_defaults={'handling_fee': 150, 'handysize_perc': 0, 'historic_data': year volume 0 2014 1000000 1 2015 1100000 2 2016 1250000 3 2017 1400000 4 2018 1500000, 'largeammonia_perc': 60, 'largehydrogen_perc': 0, 'name': 'Ammonia', 'panamax_perc': 0, 'smallammonia_perc': 40, 'smallhydrogen_perc': 0, 'type': 'Ammonia', 'vlcc_perc': 0}, storage_type_defaults={'capacity': 34130, 'consumption': 100, 'crew_for5': 1, 'crew_min': 3, 'delivery_time': 1, 'insurance_perc': 0.01, 'lifespan': 30, 'maintenance_perc': 0.01, 'mobilisation_min': 200000, 'mobilisation_perc': 0.003, 'name': 'ATank_01', 'ownership': 'Terminal operator', 'storage_type': 'tank', 'type': 'AmmoniaTank', 'unit_rate': 60000000}, h2retrieval_type_defaults={'capacity': 55, 'consumption': 5889, 'crew_for5': 1, 'crew_min': 3, 'delivery_time': 2, 'h2retrieval_type': 'tank', 'insurance_perc': 0.01, 'lifespan': 20, 'maintenance_perc': 0.015, 'mobilisation_min': 200000, 'mobilisation_perc': 0.003, 'name': 'H2retrieval_NH3_01', 'ownership': 'Terminal operator', 'type': 'AmmoniaTank', 'unit_rate': 100000000}, allowable_berth_occupancy=0.5, allowable_dwelltime=0.038356164383561646, h2retrieval_trigger=1)[source]

Bases: object

This class implements the ‘complete supply chain’ concept (Van Koningsveld et al, 2020) for hydrogen terminals. The module allows variation of the commodity type, the storage type and the h2retrieval type. Terminal development is governed by three triggers: the allowable berth occupancy, the allowable dwell time and an h2retrieval trigger.

H2retrieval_capacity_plot(width=0.25, alpha=0.6)[source]

Gather data from Terminal and plot which elements come online when

Jetty_capacity_plot(width=0.3, alpha=0.6)[source]

Gather data from Terminal and plot which elements come online when

Pipeline1_capacity_plot(width=0.2, alpha=0.6)[source]

Gather data from Terminal and plot which elements come online when

Pipeline2_capacity_plot(width=0.2, alpha=0.6)[source]

Gather data from Terminal and plot which elements come online when

Storage_capacity_plot(width=0.25, alpha=0.6)[source]

Gather data from Terminal and plot which elements come online when

berth_invest(year)[source]

Given the overall objectives of the terminal

Decision recipe Berth: QSC: berth_occupancy Problem evaluation: there is a problem if the berth_occupancy > allowable_berth_occupancy

  • allowable_berth_occupancy = .50 # 50%
  • a berth needs:
    • a jetty
  • berth occupancy depends on:
    • total_calls and total_vol
    • total_service_capacity as delivered by the vessels
Investment decisions: invest enough to make the berth_occupancy < allowable_berth_occupancy
  • adding jettys decreases berth_occupancy_rate
calculate_berth_occupancy(year, smallhydrogen_calls, largehydrogen_calls, smallammonia_calls, largeammonia_calls, handysize_calls, panamax_calls, vlcc_calls, smallhydrogen_calls_planned, largehydrogen_calls_planned, smallammonia_calls_planned, largeammonia_calls_planned, handysize_calls_planned, panamax_calls_planned, vlcc_calls_planned)[source]
  • Find all cranes and sum their effective_capacity to get service_capacity
  • Divide callsize_per_vessel by service_capacity and add mooring time to get total time at berth
  • Occupancy is total_time_at_berth divided by operational hours
calculate_demurrage_cost(year)[source]

Find the demurrage cost per type of vessel and sum all demurrage cost

calculate_energy_cost(year)[source]

The energy cost of all different element are calculated. 1. At first find the consumption, capacity and working hours per element 2. Find the total energy price to multiply the consumption with the energy price

calculate_h2retrieval_occupancy(year, hydrogen_defaults_h2retrieval_data)[source]
  • Divide the throughput by the service rate to get the total hours in a year
  • Occupancy is total_time_at_h2retrieval divided by operational hours
calculate_revenue(year, hydrogen_defaults_commodity_data)[source]
  1. calculate the value of the total throughput in year (throughput * handling fee)
calculate_vessel_calls(year=2019)[source]

Calculate volumes to be transported and the number of vessel calls (both per vessel type and in total)

check_throughput_available(year)[source]
demand_terminal_plot(width=0.1, alpha=0.6)[source]
h2retrieval_invest(year, hydrogen_defaults_h2retrieval_data)[source]

current strategy is to add h2 retrieval as long as target h2 retrieval is not yet achieved - find out how much h2 retrieval is online - find out how much h2 retrieval is planned - find out how much h2 retrieval is needed - add h2 retrieval until target is reached

jetty_invest(year, nrofdolphins)[source]

* Decision recipe jetty: * QSC: jetty_per_berth problem evaluation: there is a problem if the jetty_per_berth < 1 investment decisions: invest enough to make the jetty_per_berth = 1

  • adding jetty will increase jetty_per_berth
  • jetty_wall.length must be long enough to accommodate largest expected vessel
  • jetty_wall.depth must be deep enough to accommodate largest expected vessel
  • jetty_wall.freeboard must be high enough to accommodate largest expected vessel
pipeline_hinter_invest(year)[source]

current strategy is to add pipeline as soon as a service trigger is achieved - find out how much service capacity is online - find out how much service capacity is planned - find out how much service capacity is needed - add service capacity until service_trigger is no longer exceeded

pipeline_jetty_invest(year)[source]

current strategy is to add pipeline as soon as a service trigger is achieved - find out how much service capacity is online - find out how much service capacity is planned - find out how much service capacity is needed - add service capacity until service_trigger is no longer exceeded

plant_occupancy_plot(width=0.3, alpha=0.6)[source]

Gather data from Terminal and plot which elements come online when

simulate()[source]

The ‘simulate’ method implements the terminal investment strategy for this terminal class.

This method automatically generates investment decisions, parametrically derived from overall demand trends and a number of investment triggers.

Generic approaches based on: - Van Koningsveld, M. (Ed.), Verheij, H., Taneja, P. and De Vriend, H.J. (2020). Ports and Waterways.

Navigating the changing world. TU Delft, Delft, The Netherlands.
  • Van Koningsveld, M. and J. P. M. Mulder. 2004. Sustainable Coastal Policy Developments in the Netherlands. A Systematic Approach Revealed. Journal of Coastal Research 20(2), pp. 375-385

Specific application based on: - Ijzermans, W., 2019. Terminal design optimization. Adaptive agribulk terminal planning

in light of an uncertain future. Master’s thesis. Delft University of Technology, Netherlands. URL: http://resolver.tudelft.nl/uuid:7ad9be30-7d0a-4ece-a7dc-eb861ae5df24.

The simulate method applies frame of reference style decisions while stepping through each year of the terminal lifecycle and check if investment is needed (in light of strategic objective, operational objective, QSC, decision recipe, intervention method):

  1. for each year estimate the anticipated vessel arrivals based on the expected demand
  2. for each year evaluate which investment are needed given the strategic and operational objectives
  3. for each year calculate the energy costs (requires insight in realized demands)
  4. for each year calculate the demurrage costs (requires insight in realized demands)
  5. for each year calculate terminal revenues (requires insight in realized demands)
  6. for each year calculate the throughput (requires insight in realized demands) 6. for each year calculate terminal throughputequires insight in realized demands)
  7. collect all cash flows (capex, opex, revenues)
  8. calculate PV’s and aggregate to NPV
storage_invest(year, hydrogen_defaults_storage_data)[source]

current strategy is to add storage as long as target storage is not yet achieved - find out how much storage is online - find out how much storage is planned - find out how much storage is needed - add storage until target is reached

terminal_elements_plot(width=0.1, alpha=0.6, fontsize=20)[source]

Gather data from Terminal and plot which elements come online when

terminal_occupancy_plot(width=0.3, alpha=0.6)[source]

Gather data from Terminal and plot which elements come online when

throughput_elements(year)[source]
  • Find which elements are important and needs to be included
  • Find from each element the online capacity
  • Find where the lowest value is present, in the capacity or in the demand

Module contents

Top-level package for OpenTISim.