OpenTNSim

Contents

OpenTNSim#

This page lists all functions and classes available in the OpenTNSim.model and OpenTNSim.core modules. For examples on how to use these submodules please check out the Examples page, information on installing OpenTNim 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.

opentnsim.model module#

Vessel generator.

class opentnsim.model.Simulation(graph, simulation_start=datetime.datetime(2025, 11, 5, 9, 35, 16, 404223), simulation_duration=None, simulation_stop=None, hydrodynamic_start_time=datetime.datetime(2025, 11, 5, 9, 35, 16, 404228), hydrodynamic_data_path=None, vessel_speed_data_path=None, scenario=None)#

Bases: Identifiable

A class to generate vessels from a database

Parameters#

simulation_start: datetime

The start time of the simulation.

graph: networkx graph

The graph that is used for the simulation.

scenario:

scenario with vessels - should be coupled to the database

add_vessels(origin=None, destination=None, vessel=None, vessel_generator: VesselGenerator = None, fleet_distribution=None, arrival_distribution=1, arrival_process='Markovian')#

Make arrival process in the environment. Add one vessel on one input vessel, or with the vessel generator

Parameters#

vessel_generator: VesselGenerator

The vessel generator that is used to generate vessels. Optional. If not specified, the vessel should be specified. If specified, the vessel should be None, but origin, destination, arrival_distribution and arrival_process should be specified.

origin: str

The origin of the vessel. Must be specified if vessel_generator is specified.

destination: str

The destination of the vessel. Must be specified if vessel_generator is specified.

arrival_distribution: int or list

The amount of vessels that enter the simulation per hour. Must be specified if vessel_generator is specified. If int, it is the average number of vessels per hour over the entire day. If list, it is the average number of vessels per hour for each hour of the day. List must have length of 24 (one entry for each hour).

arrival_process: str

The process of arrivals. Must be specified if vessel_generator is specified. Choose between “Markovian” or “Uniform”.

vessel: Vessel

A vessel object with a route between origin and destination. Optional. If specified, the vessel_generator should be None, and origin, destination, arrival_distribution and arrival_process are ignored.

run(duration=86400)#

Run the simulation

duration: float

specify the duration of the simulation in seconds

class opentnsim.model.VesselGenerator(vessel_type, vessel_database, loaded=None, random_seed=3)#

Bases: object

A class to generate vessels from a database

Parameters#

vessel_type: class of mixins.

The type of vessel to be generated.

vessel_database: ??

The database from which the vessel is generated. Make sure all needed attributes for vessel_type are available in the database.

loaded: optional

whether or not the vessel is loaded. If True, the vessel is loaded. If “Random”, the vessel is randomly loaded or not (50% chance fully loaded, 50% chance empty). If not specified, the vessel is empty.

random_seed: int, optional

The random seed for generating vessels. The default is 3.

arrival_process(environment, origin, destination, arrival_distribution, scenario, arrival_process, fleet_distribution)#

Make arrival process in the simulation environment. Vessels with a route and between origin and destination are generated according to the arrival distribution. The route is calculated using the dijkstra algorithm.

Parameters#

environment: simpy environment

The environment in which the vessel is generated.

origin: str

The origin of the vessel.

destination: str

The destination of the vessel.

arrival_distribution: int or list

The amount of vessels that enter the simulation per hour. If int, it is the average number of vessels per hour over the entire day. If list, it is the average number of vessels per hour for each hour of the day. List must have length of 24 (one entry for each hour).

scenario: str

The scenario that is assigned to the generated vessel.

arrival_process: str

process of arrivals. choose between “Markovian” or “Uniform”.

generate(environment, vessel_name: str, fleet_distribution=None, scenario=None)#

Get a random vessel from self.database

Parameters#

environment: simpy environment

The environment in which the vessel is generated.

vessel_name: str

The name that is assigned to the generated vessel.

scenario: str, optional

The scenario of the generated vessel. If given, the vessel with this scenario is selected from the database.

opentnsim.core module#

class opentnsim.core.ContainerDependentMovable(compute_v, *args, **kwargs)#

Bases: Movable, HasContainer

Mixin class: ContainerDependentMovable class Used for objects that move with a speed dependent on the container level

Parameters#

compute_v: function

a function, given the fraction the container is filled (in [0,1]), returns the current speed

v: float

passed to Movable, speed of the object (in m/s)

geometry: shapely.geometry.Point

passed to Movable. point used to track its current location

node: str, optional

passed to Movable,

route: list, optional

passed to Movable,

complete_path: list, optional

passed to Movable,

Capacity: float

passed to HasContainer, the capacity of the container, which may either be continuous (like water) or discrete (like apples)

level: int, default=0

passed to HasContainer, level of the container at the beginning of the simulation

total_requested: int, default=0

passed to HasContainer, total amount that has been requested at the beginning of the simulation

Attributes#

compute_v: function

a function, given the fraction the container is filled (in [0,1]), returns the current speed

current_speed: float

the current speed of the vessel (in m/s), based on the filling degree of the container

property current_speed#

return the current speed of the vessel, based on the filling degree of the container

class opentnsim.core.ExtraMetadata(*args, **kwargs)#

Bases: object

Mixin class: store all leftover keyword arguments as metadata property (use as last mixin)

class opentnsim.core.HasContainer(capacity: float, level: float = 0, total_requested: float = 0, *args, **kwargs)#

Bases: SimpyObject

Mixin class: Something with a container, modelled as a storage capacity

Parameters#

capacity: float

the capacity of the container, which may either be continuous (like water) or discrete (like apples)

level: int, default=0

level of the container at the beginning of the simulation

total_requested: int, default=0

total amount that has been requested at the beginning of the simulation

args, kwargs:

passed to SimpyObject. Must at least contain parameter env: simpy.Environment.

Attributes#

container: simpy.Container

the container that is used to limit the amount that can be requested.

total_requested: int

total amount that has been requested.

property filling_degree#

return the filling degree of the container

property is_loaded#

Return if the container is loaded

property max_load#

return the maximum cargo to load

class opentnsim.core.HasLength(length: float, remaining_length: float = 0, *args, **kwargs)#

Bases: SimpyObject

Mixin class: Something with a length. The length is modelled as a storage capacity

Parameters#

length: float

length that can be requested

remaining_length: float, default=0

length that is still available at the beginning of the simulation.

args, kwargs:

passed to SimpyObject. Must at least contain parameter env: simpy.Environment.

Attributes#

length: simpy.Container

the container that is used to limit the length that can be requested.

pos_length: simpy.Container

the container that is used to limit the length that can be requested.

class opentnsim.core.HasLoad(H_e, H_f, T_e, T_f, filling_degree=0, *args, **kwargs)#

Bases: object

Mixin class with load dependent height (H) and draught (T). The filling degree (filling_degree: fraction) will interpolate between empty and full height and draught.

Parameters#

H_e: float

height of the vessel when empty

H_f: float

height of the vessel when full

T_e: float

draught of the vessel when empty

T_f: float

draught of the vessel when full

filling_degree: float, default=0

fraction of the vessel that is filled upon creation

property H#

Calculate current height based on filling degree

property T#

Calculate current draught based on filling degree

class opentnsim.core.HasResource(nr_resources: int = 1, priority: bool = False, *args, **kwargs)#

Bases: SimpyObject

Mixin class: Something that has a resource limitation, a resource request must be granted before the object can be used.

Parameters#

nr_resources: int, default=1

nr of requests that can be handled simultaneously, optional, default=1

priority: bool, default=False

if True, prioritized resources can be handled. optional, default=False.

args, kwargs:

passed to SimpyObject. Must at least contain parameter env: simpy.Environment.

Attributes#

resource: simpy.Resource or simpy.PriorityResource

the resource that is used to limit the nr of requests that can be handled simultaneously.

env: simpy.Environment

the simpy environment that is used to run the simulation.

class opentnsim.core.Identifiable(name: str, id: str | None = None, *args, **kwargs)#

Bases: object

OpenCLSim Identifiable with tags and a description.

Parameters#

name

a human readable name to be used in logs and charts

idUUID

a unique id generated with uuid

description

Text that can be used to describe a simulation object. Note that this field does not influence the simulation.

tags

List of tags that can be used to identify objects. Note that this field does not influence the simulation.

class opentnsim.core.Locatable(geometry: BaseGeometry, node: str | None = None, *args, **kwargs)#

Bases: object

Something with a geometry (geojson format). Can be a point as well as a polygon. The object can also be located on a graph (with a node). That requires the extra and optional node attribute. Make sure to also update the geometry when sailing over graphs.

Parameters#

geometry : Shapely Geometry that determines the position of an object. Coordinates are expected to be in wgs84 lon, lat. node: Optional string that locates an object on a graph.

get_state()#
is_at(locatable, tolerance=100)#
class opentnsim.core.Log(*args, **kwargs)#

Bases: SimpyObject

Log class to log the object activities.

get_state()#

empty instance of the get state function.

Add an empty instance of the get state function so that it is always available.

property log#

Return the log in log format (compatible with old log attribute).

The log can contain the following columns:

Timestamp: datetime ActivityID: str ActivityState: dict ObjectState: dict ActivityLabel: dict

log_entry(*args, **kwargs)#

Backward compatible log_entry. Calls the opentnsim variant.

log_entry_v0(log: str, t: float, value, geometry_log: Geometry)#

Log an entry (opentnsim version)

log_entry_v1(t: float, activity_id: str | int | None = None, activity_state: LogState = LogState.UNKNOWN, additional_state: dict | None = None, activity_label: dict | None = None)#

Log an entry (openclsim version).

Parameters#

tfloat

Timestamp in seconds since 1970 in utc.

activity_idUnion[str, int, None], optional

Identifier of the activity, by default None

activity_stateLogState, optional

State of the activity, by default LogState.UNKNOWN

additional_stateOptional[dict], optional

Additional state of the activity, by default None

activity_labelOptional[dict], optional

Label of the activity, by default None

class opentnsim.core.Movable(v: float, *args, **kwargs)#

Bases: Locatable, Routable, Log

Mixin class: Something can move.

Used for object that can move with a fixed speed

Parameters#

v: float

speed of the object (in m/s)

geometry: shapely.geometry.Point

passed to Locatable. point used to track its current location

node: str, optional

passed to Locatable,

route: list, optional

passed to Routable,

complete_path: list, optional

passed to Routable,

Attributes#

v: float

speed of the object (in m/s)

on_pass_edge_functions: list

list of functions to call when passing an edge

on_pass_node_functions: list

list of functions to call when passing a node

wsg84: pyproj.Geod

used for distance computation

req: simpy.Resource request

resource request for passing nodes and edges. saved for using resources over various nodes and edges.

resource: simpy.Resource

resource used for passing nodes and edges. saved for using resources over various nodes and edges.

Notes#

This class can handle a basic graph in env.graph. This will result in a simple simulation.

The class can also handle more complex simulations. For this, extra information is needed in the graph, such as: - Resources on nodes and edges, which can be requested and released.

  • Resources on nodes are saved in env.graph.nodes[node][“Resources”]

  • Resources on edges are saved in env.graph.edges[origin, destination][“Resources”].

  • Several edges and nodes can have the same resource, which is usefull when a segment can only be used by one vessel at a time.

  • When using a digraph, make sure to assign the same resource to both directions of the edge.

  • Current on edges, which can be used to compute the speed of the vessel.
    • Current on edges is saved in env.graph.edges[origin, destination][“Info”][“Current”].

    • Current can only be used in a directed graph (DiGraph).

    • Current is positive in the direction of the edge, and negative in the opposite direction.

    • Make sure to assign current to both directions of the edge in a digraph. (the negative and positive current)

  • Power information, which can be used to compute the speed of the vessel.
    • self must be a mixin of ConsumesEnergy.

    • self must have the attribute P_tot_given and must not be None.

    • general depth of fairway is saved in env.graph.edges[origin, destination][“Info”][“GeneralDepth”].

    • width of fairway is saved in env.graph.edges[origin, destination][“Info”][“Width”]. If not given, we use 150 m.

complete_pass_edge(destination)#
property current_node: str | None#

Return the current node on the route based on self.position_on_route.

property current_speed#

return the current speed of the vessel

determine_route_to_target_node(target_node: str)#

Determine the route to the target node. Parameters ———- target_node: str

The target node to determine the route to.

Returns#

list

The route to the target node.

look_ahead_to_node(destination)#
move()#

Moves vessel over the path defined by self.route.

Assumption is that self.path is in the right order - vessel moves from route[0] to route[-1].

Yields#

time it takes to travel the distance to the destination.

property next_edge#

Return the next edge on the route. based on self.position_on_route.

Returns#

tuple(str, str) or None

(origin, destination) of the next edge on the route.

property next_node: str | None#

Return the next node on the route based on self.position_on_route.

pass_edge(origin, destination)#

pass an edge and call all on_pass_edge_functions.

Parameters#

origin: str

the origin node of the edge

destination: str

the destination node of the edge

Yields#

The time it takes to pass the edge.

pass_node(node)#

pass a node and call all on_pass_node_functions

Parameters#

node: str

the node to pass

Yields#

The time it takes to pass the node.

property route_ahead#

Return the remaining route ahead of the current position.

update_position(position_on_route: int)#

Update the position on the route.

Parameters#

position_on_route: int

index of position on the route

class opentnsim.core.Neighbours#

Bases: object

Mixin class: Can be added to a locatable object (list)

Parameters#

travel_to: list

list of locatables to which can be travelled

args, kwargs:

passed to SimpyObject. Must at least contain parameter env: simpy.Environment.

Attributes#

neighbours: list

list of locatables to which can be travelled.

class opentnsim.core.Routable(route, complete_path=None, *args, **kwargs)#

Bases: SimpyObject

Mixin class: Something with a route (networkx format)

Parameters#

route: list

list of node-IDs

complete_path: list, optional

???

args, kwargs:

passed to SimpyObject. Must at least contain parameter env: simpy.Environment.

Attributes#

route: list

list of node-IDs

complete_path: list, optional

???

position_on_route: int

index of position on the route

check_attributes()#

Check if all required attributes are set.

property graph#

Return the graph of the underlying environment.

If it’s multigraph cast to corresponding type If you want the multidigraph use the HasMultiGraph mixin

class opentnsim.core.Routeable(*args, **kwargs)#

Bases: Routable

Old name for Mixin class: renamed to Routable.

class opentnsim.core.SimpyObject(env, *args, **kwargs)#

Bases: object

General object which can be extended by any class requiring a simpy environment.

Parameters#

env

A simpy Environment

class opentnsim.core.VesselProperties(type, B, L, h_min=None, T=None, safety_margin=None, h_squat=None, payload=None, vessel_type=None, renewable_fuel_mass=None, renewable_fuel_volume=None, renewable_fuel_required_space=None, *args, **kwargs)#

Bases: object

Mixin class: Something that has vessel properties This mixin is updated to better accommodate the ConsumesEnergy mixin

Parameters#

type: str

can contain info on vessel type (avv class, cemt_class or other)

B: float

vessel width

L: float

vessel length

h_min: float, optional

vessel minimum water depth. The wather-depth can also be extracted from the network edges if they have the property [‘Info’][‘GeneralDepth’]

T: float, optional

actual draught. If not given, it will be calculated based on the filling degree (use mixin HasLoad) or based on the payload and vessel type

safety_margin: float, optional

the water area above the waterway bed reserved to prevent ship grounding due to ship squatting during sailing the value of safety margin depends on waterway bed material and ship types. For tanker vessel with rocky bed the safety margin is recommended as 0.3 m based on Van Dorsser et al. The value setting for safety margin depends on the risk attitude of the ship captain and shipping companies.

h_squat: boolean, optional

the water depth considering ship squatting while the ship moving (if False, squat is disabled, if True, squat is calculated)

payload: float, optional

cargo load [ton], the actual draught can be determined by knowing payload based on van Dorsser et al’s method. (https://www.researchgate.net/publication/344340126_The_effect_of_low_water_on_loading_capacity_of_inland_ships)

vessel_type: str, optional

vessel_type: vessel type can be selected from “Container”,”Dry_SH”,”Dry_DH”,”Barge”,”Tanker”. (“Dry_SH” means dry bulk single hull, “Dry_DH” means dry bulk double hull), based on van Dorsser et al’s paper. (https://www.researchgate.net/publication/344340126_The_effect_of_low_water_on_loading_capacity_of_inland_ships)

renewable_fuel_mass: float, optional

renewable fuel mass on board [kg]

renewable_fuel_volume: float, optional

renewable fuel volume on board [m3]

renewable_fuel_required_space: float, optional

renewable fuel required storage space (consider packaging factor) on board [m3]

property T#

Compute the actual draught. This will default to using the draught passed by the constructor. If it is None it will try to find one in the super class.

get_route(origin, destination, graph=None, minWidth=None, minHeight=None, minDepth=None, randomSeed=4)#

Calculate a path based on vessel restrictions restrictions are only applied if the graph has the attributes [‘Width’, ‘Height’, ‘Depth’]

Parameters#

origin: str

ID of the starting node

destination: str

ID of the destination node

graph: networkx.Graph, default = self.graph

The graph to use for the pathfinding

minWidth: float, default = 1.1 * self.B

Minimum width of the path

minHeight: float, default = 1.1 * self.H

Minimum height of the path

minDepth: float, default = 1.1 * self.T

Minimum depth of the path

randomSeed: int, default = 4

Seed for the random number generator

property h_min#

get the minimum water depth. if not given, h_min is the minimal water depth of the graph..

opentnsim.energy module#

class opentnsim.energy.ConsumesEnergy(P_installed, L_w, C_year=None, current_year=None, bulbous_bow=False, karpov_correction=False, P_hotel_perc=0.05, P_hotel=None, P_tot_given=None, nu=1e-06, rho=1000, g=9.81, x=2, D_s=1.4, eta_o=0.4, eta_r=1.0, eta_t=0.98, eta_g=0.96, c_stern=0, C_BB=0.2, C_B=0.85, one_k2=2.5, *args, **kwargs)#

Bases: object

Mixin class: Something that consumes energy.

Parameters#

P_installedfloat

Installed engine power in kilowatts (kW).

P_tot_givenfloat

Total power set by captain (includes hotel power). When P_tot_given > P_installed; P_tot_given=P_installed.

karpov_correctionbool, optional

If True, apply Karpovs correction for velocity under the vessel, if False, use the speed to water.

bulbous_bowbool, optional

Indicates if the ship has a bulbous bow. Inland ships generally do not have a bulbous bow, hence the default is False. If a ship has a bulbous bow, set to True.

L_wint

Weight class of the ship depending on carrying capacity. Classes: L1 (=1), L2 (=2), L3 (=3).

current_yearint

The current year.

nufloat

Kinematic viscosity in square meters per second (m^2/s).

rhofloat

Density of the surrounding water in kilograms per cubic meter (kg/m^3).

gfloat

Gravitational acceleration in meters per second squared (m/s^2).

xint

Number of propellers.

eta_ofloat

Open water efficiency of the propeller.

eta_rfloat

Relative rotative efficiency.

eta_tfloat

Transmission efficiency.

eta_gfloat

Gearing efficiency.

c_sternfloat

Determines the shape of the afterbody.

C_BBfloat

Breadth coefficient of the bulbous bow, set to 0.2 according to the paper of Kracht (1970), https://doi.org/10.5957/jsr.1970.14.1.1.

C_Bfloat, optional

Block coefficient (‘fullness’), default to 0.85.

one_k2float

Appendage resistance factor (1+k2).

C_yearint

Construction year of the engine.

SFC_general()#

Specific Fuel Consumption (SFC) is calculated by energy density and energy conversion efficiency. The SFC calculation equation, SFC = 1 / (energy density * energy conversion efficiency), can be found in the paper of Kim et al (2020)(A Preliminary Study on an Alternative Ship Propulsion System Fueled by Ammonia: Environmental and Economic Assessments, https://doi.org/10.3390/jmse8030183).

for diesel SFC, there are 3 kinds of general diesel SFC - SFC_diesel_ICE_mass, calculated by net diesel gravimetric density and ICE energy-power system efficiency, without considering engine performence variation due to engine ages - SFC_diesel_ICE_vol, calculated by net diesel volumetric density and ICE energy-power system efficiency, without considering engine performence variation due to engine ages - SFC_diesel_C_year, a group of SFC considering ICE engine performence variation due to engine ages (C_year), based on TNO (2019)

Please note: later on a correction factor has to be applied to get the total SFC

calculate_SFC_final(v, h_0)#

The final SFC is computed by multiplying the general SFC by the partial engine load correction factor.

The calculation of final SFC below includes - the final SFC of LH2, eLNG, eMethanol, eNH3 in mass and volume while using Fuel Cell Engine (PEMFC, SOFC) - the final SFC of eLNG, eMethanol, eNH3 in mass and volume while using Internal Combustion Engine - the final SFC of diesel in mass and volume while using Internal Combustion Engine - the final SFC of battery in mass and volume while use battery-electric power system

calculate_appendage_resistance(v)#

Appendage resistance

  • 3rd resistance component defined by Holtrop and Mennen (1982)

  • Appendages (like a rudder, shafts, skeg) result in additional frictional resistance

calculate_diesel_use_g_m(v)#

Total diesel fuel use in g/m:

  • The total fuel use in g/m can be computed by total fuel use in g (P_tot * delta_t * self.total_factor_) divided by the sailing distance (v * delt_t)

calculate_diesel_use_g_s()#

Total diesel fuel use in g/s:

  • The total fuel use in g/s can be computed by total emission in g (P_tot * delta_t * self.total_factor_) diveded by the sailing duration (delt_t)

calculate_emission_factors_total(v, h_0)#

Total emission factors:

  • The total emission factors can be computed by multiplying the general emission factor by the correction factor

calculate_emission_rates_g_m(v)#

CO2, PM10, NOX emission rates in g/m:

  • The CO2, PM10, NOX emission rates in g/m can be computed by total fuel use in g (P_tot * delta_t * self.total_factor_) diveded by the sailing distance (v * delt_t)

calculate_emission_rates_g_s()#

CO2, PM10, NOX emission rates in g/s:

  • The CO2, PM10, NOX emission rates in g/s can be computed by total fuel use in g (P_tot * delta_t * self.total_factor_) diveded by the sailing duration (delt_t)

calculate_engine_age()#

Calculate the age of the engine based on the weight class of the ship (L_w).

The age is drawn randomly from a Weibull distribution with parameters k and lmb, which depend on the weight class of the ship. The year of construction is computed from the current year of the simulation and the age of the engine.

Notes#

Uses self.L_w and self.year to compute the age and construction year of the engine. This method sets attributes self.age and self.C_year.

calculate_frictional_resistance(v, h_0)#

Frictional resistance

  • 1st resistance component defined by Holtrop and Mennen (1982)

  • A modification to the original friction line is applied, based on literature of Zeng (2018), to account for shallow water effects

calculate_h_squat(v, h_0, width=150)#

Calculate the water depth in case h_squat is set to True

The amount of water under the keel is calculated h_0 - T. When h_squat is set to True, we estimate a max_sinkage that is subtracted from h_0. This values is returned as h_squat for further calculation.

calculate_max_sinkage(v, h_0, width=150)#

Calculate the maximum sinkage of a moving ship

the calculation equation is described in Barrass, B. & Derrett, R.’s book (2006), Ship Stability for Masters and Mates, chapter 42. https://doi.org/10.1016/B978-0-08-097093-6.00042-6

some explanation for the variables in the equation: - h_0: water depth - v: ship velocity relative to the water - width: river width, default to 150

calculate_properties()#

Calculate a number of basic vessel properties

calculate_residual_resistance(V_2, h_0)#

Residual resistance terms

  • Holtrop and Mennen (1982) defined three residual resistance terms:

    1. Resistance due to immersed transom (R_TR), Karpov corrected velocity V2 is used

    1. Resistance due to model-ship correlation (R_A), Karpov corrected velocity V2 is used

    1. Resistance due to the bulbous bow (R_B), Karpov corrected velocity V2 is used

calculate_total_power_required(v, h_0)#

Total required power:

  • The total required power is the sum of the power for systems on board (P_hotel) + power required for propulsion

  • The power required for propulsion depends on the calculated resistance

Output: - P_propulsion: required power for propulsion, equals to P_d (Delivered Horse Power) - P_tot: required power for propulsion and hotelling - P_given: the power given by the engine to the ship (for propulsion and hotelling), which is the actual power

the ship uses

Note: In this version, we define the propulsion power as P_d (Delivered Horse Power) rather than P_b (Brake Horse Power). The reason we choose P_d as propulsion power is to prevent double use of the same power efficiencies. The details are 1) The P_b calculation involves gearing efficiency and transmission efficiency already while P_d not. 2) P_d is the power delivered to propellers. 3) To estimate the renewable fuel use, we will involve “energy conversion efficiencies” later in the

calculation.

The ‘energy conversion efficiencies’ for renewable fuel powered vessels are commonly measured/given as a whole covering the engine power systems, includes different engine (such as fuel cell engine, battery engine, internal combustion engine, hybrid engine) efficiencies, and corresponding gearbox efficiencies, AC/DC converter efficiencies, excludes the efficiency items of propellers. Therefore, to align with the later use of “energy conversion efficiencies” for fuel use estimation and prevent double use of some power efficiencies such as gearing efficiency, here we choose P_d as propulsion power.

calculate_total_resistance(v, h_0)#

Total resistance:

The total resistance is the sum of all resistance components (Holtrop and Mennen, 1982)

calculate_viscous_resistance()#

Viscous resistance

  • 2nd resistance component defined by Holtrop and Mennen (1982)

  • Form factor (1 + k1) has to be multiplied by the frictional resistance R_f, to account for the effect of viscosity

calculate_wave_resistance(V_2, h_0)#

Wave resistance

  • 4th resistance component defined by Holtrop and Mennen (1982)

  • When the speed or the vessel size increases, the wave making resistance increases

  • In shallow water, the wave resistance shows an asymptotical behaviour by reaching the critical speed

correction_factors(v, h_0)#

Partial engine load correction factors (C_partial_load):

  • The correction factors have to be multiplied by the general emission factors (or general SFC), to get the total emission factors (or final SFC)

  • The correction factor takes into account the effect of the partial engine load

  • When the partial engine load is low, the correction factors for ICE engine are higher (ICE engine is less efficient at lower enegine load)

  • the correction factors for emissions and diesel fuel in ICE engine are based on literature TNO (2019)

  • For fuel cell enegines(PEMFC & SOFC), the correction factors are lower when the partial engine load is low (fuel cell enegine is more efficient at lower enegine load)

  • the correction factors for renewable fuels used in fuel cell engine are based on literature Kim et al (2020) (A Preliminary Study on an Alternative Ship Propulsion System Fueled by Ammonia: Environmental and Economic Assessments, https://doi.org/10.3390/jmse8030183)

emission_factors_general()#

General emission factors:

This function computes general emission factors, based on construction year of the engine. - Based on literature TNO (2019)

Please note: later on a correction factor has to be applied to get the total emission factor

energy_conversion_efficiency()#

energy efficiencies for combinations of different energy source and energy-power conversion systems, including engine and power plant, excluding propellers. This will be used for calculating SFC later.

  • Eeff_FuelCell: the efficiency of the fuel cell energy conversion system on board, includes fuel cells, AC/DC converter, electric motor and gearbox. Generally this value is between 40% - 60%, here we use 45%.

  • Eeff_ICE: the efficiency of the Internal Combustion Engine (ICE) energy conversion system on board, includes ICE and gearbox. This value is approximately 35%.

  • Eeff_Battery: the efficiency of the battery energy conversion system on board. Batteries use 80% capacity to prolong life cycle, and lose efficiency in AC/DC converter, electric motor. Generally this value is between 70% - 95%, here we use 80 %.

data source: Marin report 2019, Energietransitie emissieloze binnenvaart, vooronderzoek ontwerpaspecten, systeem configuraties.(Energy transition zero-emission inland shipping, preliminary research on design aspects, system configurations) add other ref

energy_density()#

net energy density of diesel and renewable energy sources. This will be used for calculating SFC later.

  • Edens_xx_mass: net gravimetric energy density, which is the amount of energy stored in a given energy source in mass [kWh/kg].

  • Edens_xx_vol: net volumetric energy density, which is the amount of energy stored in a given energy source in volume [kWh/m3].

Data source: Table 3-2 from Marin report 2019, Energietransitie emissieloze binnenvaart, vooronderzoek ontwerpaspecten, systeem configuraties.(Energy transition zero-emission inland shipping, preliminary research on design aspects, system configurations

Note: net energy density can be used for calculate fuel consumption in mass and volume, but for required energy source storage space determination, the packaging factors of different energy sources also need to be considered.

karpov(v, h_0)#

Intermediate calculation: Karpov

  • The Karpov method computes a velocity correction that accounts for limited water depth (corrected velocity V2, expressed as “Vs + delta_V” in the paper), but it also can be used for deeper water depth (h_0 / T >= 9.5).

  • V2 has to be implemented in the wave resistance (R_W) and the residual resistance terms (R_res: R_TR, R_A, R_B)

class opentnsim.energy.EnergyCalculation(graph, vessel, *args, **kwargs)#

Bases: object

Add information on energy use and effects on energy use.

calculate_energy_consumption()#

Calculation of energy consumption based on total time in system and properties

opentnsim.energy.karpov_smooth_curves()#

read correction factor from package directory

opentnsim.energy.load_partial_engine_load_correction_factors()#

read correction factor from package directory

opentnsim.lock module#

class opentnsim.lock.HasLockPlanning(*args, **kwargs)#

Bases: object

This class keeps track of the lock-planning of a lock-master.

add_vessel_to_new_lock_operation(vessel, operation_index, direction)#

Adds a vessel to a newly to be planned lock operation

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

add_vessel_to_planned_lock_operation(vessel, operation_index, direction)#

Add vessel to a planned lock operation

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

the index of the already planned lock operation to which the vessel is added to

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Returns#

operation_planningpd.DataFrame

the lock complex master’s new planning of lock operations

assign_vessel_to_lock_operation(vessel, direction)#

Function that adds a vessel to the lock operation planning

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Returns#

operation_indexint

index of the lock operation to which the vessel can be added (can either be an existing or a new lock operation)

add_operationbool

determines if a new lock operation should be added (True) or not (False)

available_operationspd.DataFrame

the available lock operations to which the vessel can be assigned including their information

get_vessel_from_planned_operation(operation_index)#

Gets the vessels that are assigned to a certain lock operation in the operation planning of the lock master

Parameters#

operation_indexint

index of the lock operation

Returns#

vesselslist of vessel type objects

the vessels that have been assigned to the specified lock operation (a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput)

update_operation_planning(vessel, direction, operation_index, add_operation)#

Updates the lock master’s lock operation planning

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

operation_indexint

index of the lock operation

add_operationbool

expresses whether the vessel should be added to a new lock operation planning: yes [True] or no [False]

Yields#

Adds vessel to new or planned lock operation

class opentnsim.lock.IsLockChamber(start_node, end_node, lock_length, lock_width, lock_depth, lock_master=None, k=0, distance_from_start_node_to_lock_doors_A=0.0, distance_from_end_node_to_lock_doors_B=0.0, registration_nodes=[], doors_opening_time=300.0, doors_closing_time=300.0, disch_coeff=0.4, opening_area=12.0, opening_depth=None, speed_reduction_factor_lock_chamber=0.3, start_sailing_out_time_after_doors_have_been_opened=0.0, sailing_time_before_opening_lock_doors=600.0, sailing_time_before_closing_lock_doors=120.0, minimum_time_between_operations_for_intermediate_door_closure=0.0, sailing_distance_to_crossing_point=500.0, passage_time_door=300.0, sailing_in_time_gap_through_doors=180.0, sailing_out_time_gap_through_doors=180.0, sailing_in_time_gap_after_berthing_previous_vessel=0.0, sailing_out_time_gap_after_berthing_previous_vessel=0.0, sailing_in_speed_A=1.028888888, sailing_out_speed_A=1.028888888, sailing_in_speed_B=1.028888888, sailing_out_speed_B=1.028888888, minimum_manoeuvrability_speed=1.028888888, levelling_time=600.0, time_step=10.0, gate_opening_time=60.0, node_open=None, conditions=None, priority_rules=None, used_as_one_way_traffic_regulation=False, seed_nr=None, *args, **kwargs)#

Bases: IsLockChamberOperator, HasResource, HasLength, Identifiable, Log, HasOutput, HasMultiDiGraph, ExtraMetadata

Mixin class: lock complex has a lock chamber:

creates a lock chamber with a resource which is requested when a vessels wants to enter the area with limited capacity

Attributes#

vessel_sailing_speed_in_lock :

calculates the average speed in the lock when entering

vessel_sailing_speed_out_lock :

calculates the average speed in the lock when leaving

vessel_sailing_in_speed :

Calculates the average speed when sailing towards the lock chamber

vessel_sailing_out_speed :

Calculates the average speed when sailing away from the lock chamber

determine_levelling_time :

calculates the levelling time of a lock operation

vessel_sailing_in_speed(vessel, direction)#

Calculates the average speed when sailing towards the lock chamber

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

x_location_lockfloat

logintudinal coordinate in the lock to which the vessel is assigned [m]

P_usedfloat

the breaking power used by the vessel to gradually decelerate [kW]

Returns#

speedfloat

the average speed in the lock from the lock doors to the location of berthing

vessel_sailing_out_speed(vessel, direction, P_used=None, h0=17, until_crossing_point=False)#

Calculates the average speed when sailing away from the lock chamber

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

P_usedfloat

the breaking power used by the vessel to gradually decelerate [kW]

until_crossing_point : bool

Returns#

speedfloat

the average speed in the lock from the lock doors to the location of berthing

vessel_sailing_speed_in_lock(vessel)#

Calculates the average speed in the lock when entering

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

x_location_lockfloat

logintudinal coordinate in the lock to which the vessel is assigned [m]

P_usedfloat

the breaking power used by the vessel to gradually decelerate [kW]

Returns#

speedfloat

the average speed in the lock from the lock doors to the location of berthing

vessel_sailing_speed_out_lock(vessel)#

Calculates the average speed to in the lock when leaving

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

x_location_lockfloat

logintudinal coordinate in the lock to which the vessel is assigned [m]

P_usedfloat

the breaking power used by the vessel to gradually decelerate [kW]

Returns#

speedfloat

the average speed in the lock from the lock doors to the location of berthing

class opentnsim.lock.IsLockChamberOperator(lock_master, *args, **kwargs)#

Bases: object

The lock chamber operator operates one chamber of the lock.

The operator communicates with the lock master through self.lock_master to coordinate vessel operations and lock state changes.

allow_vessel_to_sail_into_lock(origin, destination, vessel=None, k=0)#

Allows the vessel to sail into the lock chamber

Parameters#

originstr

node name (that has to be in the graph) on which the vessel is currently sailing, to navigate an edge should form an edge with the origin)

destinationstr

node name (that has to be in the graph) on which the vessel is currently sailing to, to navigate an edge (should form an edge with the origin)

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

kint

identifier of the edge between two nodes in a multidigraph network

allow_vessel_to_sail_out_of_lock(origin, destination, vessel=None, k=0)#

Allows the vessel to sail out of the lock chamber

Parameters#

originstr

node name (that has to be in the graph) on which the vessel is currently sailing, to navigate an edge should form an edge with the origin)

destinationstr

node name (that has to be in the graph) on which the vessel is currently sailing to, to navigate an edge (should form an edge with the origin)

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

kint

identifier of the edge between two nodes in a multidigraph network

Yields#

Vessel to sail to the end of the edge at which the lock chamber is located, and initiates new processes: i.e. closing doors or empty lock operation

calculate_sailing_time_to_waiting_area(vessel, direction, current_node=None, prognosis=False, overwrite=True)#

Calculate sailing time to waiting area through lock master.

Parameters#

vesseltype

a type including the following mixins: PassesLockComplex,Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (A -> B) or 1 (B -> A)

current_nodestr

node name (that has to be in the graph) on which the vessel is currently sailing, to navigate an edge should form an edge with the origin)

prognosisbool

if the sailing time is calculated for prognosis purposes (True) or for actual sailing (False)

overwritebool

if existing sailing time in the vessel planning should be overwritten (True) or not (False)

calculate_vessel_departure_start_delay(vessel, operation_index, direction, prognosis=False)#

Calculate vessel departure start delay through lock master.

Parameters#

vesseltype

a type including the following mixins: PassesLockComplex,Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the vessel: 0 (A -> B) or 1 (B -> A)

prognosisbool

if the delay is calculated for prognosis purposes (True) or for actual sailing (False)

overwritebool

if existing delay in the vessel planning should be overwritten (True) or not (False)

close_door(delay=0.0)#

Lock operator closes the lock doors TODO: attribute for lock operator

Parameters#

delayfloat

a delay before door opening [s]

Yields#

The closing of the door

close_doors_before_vessel_is_laying_still(operation_index)#

Get policy on closing doors before vessel is laying still through lock master.

Parameters#

operation_indexint

index of the lock operation

property closing_doors_in_between_arrivals#

Get policy on closing doors in between arrivals through lock master.

property closing_doors_in_between_operations#

Get policy on closing doors in between operations through lock master.

convert_chamber(new_level, direction, operation_index=None, vessel=None, close_doors=True, delay=0.0)#

Converts the lock chamber and logs this event. TODO: attribute for lock operator

Parameters#

new_levelstr

node that represents the side at which the lock is currently levelled

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

close_doorsbool

if the doors have to be closed: yes (True) or no (False)

delayfloat

a delay before lock conversion [s]

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Yields#

The conversion of the lock chamber

determine_if_door_can_be_closed(vessel, direction, operation_index, between_arrivals=False)#

Determines if the doors can be closed in between operations or vessel arrivals

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

between_arrivalsbool

if the function is run to determine if the doors can be closed in between vessel arrivals (True) or not (False)

Returns#

doors_can_be_closedbool

doors can be closed (True) or not (False)

determine_if_door_is_closed(vessel, operation_index, direction, first_in_lock=False, between_arrivals=False)#

Determines if the doors are closed

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

first_in_lockbool

if the function is run for the first vessel assigned to the lock operation (True) or not (False)

between_arrivalsbool

if the function is run to determine if the doors can be closed in between vessel arrivals (True) or not (False)

Returns#

doors_are_closedbool

doors are closed (True) or not (False)

doors_required_to_be_openpd.Timestamp

moment in time when the doors need to be opened

operation_timepd.Timedelta

the time duration required to perform the lock operation

determine_levelling_time(t_start, direction, wlev_init=None, operation_index=0, prediction=False)#

Calculates the levelling time of a lock operation

Parameters#

t_start :

the start time of the levelling process

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

wlev_initfloat

initial water level in the lock chamber

same_directionbool

states if the levelling process is predicted in the same direction as the last lock operation (True) or not (False)

predictionbool

states if the levelling process is only predicted (True) or executed (False)

Returns#

levelling_timefloat

the time duration of the levelling process

tlist of float

the time series of the levelling process

zlist of float

the water level difference series over the time of the levelling process

determine_time_to_open_door(operation_index, direction, doors_required_to_be_open)#

Determines the time to finish the levelling process and the door opening process

Parameters#

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

doors_required_to_be_openpd.Timestamp

the moment in time that the doors are required to be opened

Returns#

operation_timepd.Timedelta

the time to finish the levelling process and the door opening process

determine_water_levels_before_and_after_levelling(levelling_start, levelling_stop, direction)#

Determines the water level at both sides of the lock

Parameters#

levelling_startpd.Timestamp

the start time of the levelling process

levelling_stoppd.Timestamp

the stop time of the levelling process

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Returns#

wlev_A :

the water level at side A [m] before or after the levelling process (depending on the direction of the operation)

wlev_B :

the actual water level at side B [m] before or after the levelling process (depending on the direction of the operation)

initiate_levelling(origin, destination, vessel=None, k=0)#

Initiates levelling process as function that can be added to a vessel TODO: preferably you don’t want to add this process to the vessel but let the lock master / operator handle this

Parameters#

originstr

node name (that has to be in the graph) on which the vessel is currently sailing, to navigate an edge should form an edge with the origin)

destinationstr

node name (that has to be in the graph) on which the vessel is currently sailing to, to navigate an edge (should form an edge with the origin)

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

kint

identifier of the edge between two nodes in a multidigraph network

level_lock(new_level, direction, operation_index=None, vessel=None)#

Lock operator levels the water level of the lock chamber to the harbour side of the direction of the lock operation TODO: attribute for lock operator

new_levelstr

node of the edge of lock complex to which the lock chamber is levelling

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

same_direction : bool

Yields#

Levelling of the lock chamber

minimum_advance_to_open_doors()#

Determines the minimum time in advance that a lock door should be opened

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Returns#

minimum_advance_to_open_doorspd.Timedelta

the minimum time in advance that a lock door should be opened [s]

minimum_delay_to_close_doors()#

Calculates the time delay (in seconds) between when the last vessel has entered the lock and when the lock doors can be closed

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

Returns#

minimum_delay_to_close_doorspd.Timedelta

the minimum time delay that the lock doors can be closed after a vessel has entered the lock

open_door(to_level=None, vessel=None, delay=0.0)#

Lock operator opens the lock doors TODO: attribute for lock operator

Parameters#

to_levelstr

node of the edge of lock complex to which the lock chamber opens

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

delayfloat

a delay before door opening

Yields#

The opening of the door

property operation_planning#

Get operation planning through lock master.

prepare_next_lock_operation(lock, operation_index, direction, vessel)#

Lock operator checks and (if required) initiates an empty lock operation or closes the doors if there is sufficient time with respect to the next operation’s start time

Parameters#

lockobject

the lock chamber object generated with IsLockChamber

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (A -> B) or 1 (B -> A)

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

register_vessel(vessel)#

Register vessel through lock master.

Parameters#

vesseltype

a type including the following mixins: PassesLockComplex,Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

property vessel_planning#

Get vessel planning through lock master.

property waiting_area_A#

Get waiting area A through lock master.

property waiting_area_B#

Get waiting area B through lock master.

class opentnsim.lock.IsLockComplex(node_A, node_B, edge_waiting_area_A=None, edge_waiting_area_B=None, distance_lock_doors_A_to_waiting_area_A=0.0, distance_lock_doors_B_to_waiting_area_B=0.0, lineup_area_A_length=None, lineup_area_B_length=None, distance_lock_doors_A_to_lineup_area_A=None, distance_lock_doors_B_to_lineup_area_B=None, effective_lineup_area_A_length=None, effective_lineup_area_B_length=None, passing_allowed_in_lineup_area_A=False, passing_allowed_in_lineup_area_B=False, speed_reduction_factor_lineup_area_A=0.75, speed_reduction_factor_lineup_area_B=0.75, P_used_to_break_before_lock=None, P_used_to_break_in_lock=None, P_used_to_accelerate_in_lock=None, P_used_to_accelerate_after_lock=None, k=0, *args, **kwargs)#

Bases: IsLockMaster

Mixin-class: a lock complex object

TODO: I would like the lock complex to be decoupled from its infrastructure, so that you can add multiple lock chambers, line-up areas and waiting areas

Attributes:#

_verify_node_AB :

.

create_time_distance_plot :

.

create_time_distance_plot(vessels, xlimmin=None, xlimmax=None, ylimmin=None, ylimmax=None, method='Matplotlib')#

Create a time-distance plot of vessels passing a lock complex

Parameters#

vessels: list of vessel type objects

the vessels that have been simulated (a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput)

xlimminfloat

minimum x coordinate as distance front the lock complex (should be negative) [m]

xlimmaxfloat

maximum x coordinate as distance front the lock complex (should be positive) [m]

ylimminpd.Timestamp

minimum time (should be equal or greater that the simulation start time)

ylimmaxpd.Timestamp

maximum time (should be equal or smaller that the simulation stop time)

Returns#

nothing, but creates a plot

determine_levelling_time(t_start, direction, wlev_init=None, operation_index=0, prediction=False)#

Determine levelling time through lock chamber.

property distance_from_end_node_to_lock_doors_B#

Get distance from end node to lock doors B through lock chamber.

property distance_from_start_node_to_lock_doors_A#

Get distance from start node to lock doors A through lock chamber.

property doors_closing_time#

Get doors closing time through lock chamber.

property doors_opening_time#

Get doors opening time through lock chamber.

property location_lock_doors_A#

Get location of lock doors A through lock chamber.

property location_lock_doors_B#

Get location of lock doors B through lock chamber.

property lock_length#

Get length of the lock chamber.

property lock_width#

Get width of the lock chamber.

property name#

Get name of the lock chamber.

property node_open#

Get node open status through lock chamber.

property registration_nodes#

Get registration nodes of the lock chamber.

property sailing_distance_to_crossing_point#

Get sailing distance to crossing point through lock chamber.

property sailing_in_time_gap_after_berthing_previous_vessel#

Get sailing in time gap after berthing previous vessel through lock chamber.

property sailing_in_time_gap_through_doors#

Get sailing in time gap through doors.

property sailing_out_time_gap_after_berthing_previous_vessel#

Get sailing out time gap after berthing previous vessel through lock chamber.

property sailing_out_time_gap_through_doors#

Get sailing out time gap through doors.

property start_sailing_out_time_after_doors_have_been_opened#

Get start sailing out time after doors have been opened through lock chamber.

vessel_sailing_in_speed(vessel, direction)#

Get vessel sailing in speed through lock chamber.

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

vessel_sailing_out_speed(vessel, direction, P_used=None, h0=17, until_crossing_point=False)#

Get vessel sailing out speed through lock chamber.

vessel_sailing_speed_in_lock(vessel)#

Get vessel sailing speed in lock through lock chamber.

vessel_sailing_speed_out_lock(vessel)#

Get vessel sailing speed out of lock through lock chamber.

class opentnsim.lock.IsLockMaster(lock_complex, min_vessels_in_operation=0, max_vessels_in_operation=100, clustering_time=1800.0, water_level_difference_limit_to_open_doors=0.05, minimize_door_open_times=False, closing_doors_in_between_operations=False, closing_doors_in_between_arrivals=False, close_doors_before_vessel_is_laying_still=False, operational_hour_start_times=None, operational_hour_stop_times=None, *args, **kwargs)#

Bases: SimpyObject, HasLockPlanning

Mixin class: lock complex has a lock master:

Creates a lock master that schedules the vessels into lock operations

Attributes#

create_operational_hours :

creates an DataFrame with the operational hours of the lock complex

register_vessel :

registers a vessel to the lock operation and vessel planning

calculate_sailing_information_on_route_to_lock_complex :

calculates the sailing information (i.e., duration, distance, and speed) of the vessel per edge of its route between its current location and the lock doors

overrule_vessel_speed :

overrules the speed of an vessel based on the additional waiting time

initiate_levelling :

allow_vessel_to_sail_out_of_lock :

allow_vessel_to_sail_into_lock :

add_vessel_to_vessel_planning :

adds vessel to the vessel planning of the lock complex upon request

add_empty_lock_operation_to_planning :

adds an empty lock operation to the operation planning

determine_route_to_waiting_area_from_node :

calculate_sailing_time_to_waiting_area :

calculates the sailing time of a vessel from its location to the waiting area

calculate_sailing_time_to_lineup_area :

calculates the sailing time of a vessel from its location to the line-up area

calculate_sailing_time_to_approach_point :

calculates the sailing time of a vessel from its location to the approach point

calculate_sailing_time_to_lock_door :

calculates the sailing time of a vessel from its location to the first lock doors that it will encounter

calculate_sailing_time_in_lock :

calculates the time duration that a vessel needs to enter the lock until laying still

calculate_sailing_in_time_delay :

calculates the minimum required time gap between two entering vessels for safety, resulting in a delay

calculate_vessel_entry_duration :

calculates the moment in time that a vessel starts entering the lock

calculate_vessel_passing_start_time :

calculates the start time that a vessel can start its manoeuvre of entering the lock

calculate_lock_operation_start_time :

calculates the new earliest possible start time of a lock operation

calculate_lock_door_opening_time :

.

calculate_lock_entry_start_time :

.

calculate_vessel_entry_stop_time :

calculates the moment in time that a vessel finished its lock entry process

calculate_lock_entry_stop_time :

calculates the moment in time that a lock operation entry process of all the assigned vessels is finished (all vessels are in lock chamber)

calculate_lock_operation_times :

calculates the moments in time of the start and stop of the operation steps of the lock: (1) door closing, (2) levelling, (3) door opening

calculate_vessel_departure_start_time :

.

calculate_lock_departure_start_time :

.

calculate_vessel_sailing_time_out_of_lock :

.

calculate_vessel_departure_stop_time :

.

calculate_lock_departure_stop_time :

.

calculate_vessel_passing_stop_time :

.

calculate_lock_operation_stop_time :

.

minimum_delay_to_close_doors :

calculates the time delay between when the last vessel has entered the lock and when the lock doors can be closed

minimum_advance_to_open_doors :

determines the minimum time in advance that a lock door should be opened

calculate_lock_door_closing_time :

determine_first_vessel_of_lock_operation :

determines the first vessel that was assigned to the lock operation

determine_last_vessel_of_lock_operation:

determines the last vessel that was assigned to the lock operation

calculate_delay_to_open_doors :

.

determine_if_door_can_be_closed :

.

determine_if_door_is_closed :

.

determine_time_to_open_door :

.

determine_water_levels_before_and_after_levelling :

determines the water level at both sides of the lock

get_vessel_from_planned_operation :

gets the vessels that are assigned to a certain lock operation in the operation planning of the lock master

update_operation_planning :

updates the lock master’s lock operation planning

add_vessel_to_new_lock_operation :

adds a vessel to a newly to be planned lock operation

add_vessel_to_planned_lock_operation :

add vessel to a planned lock operation

assign_vessel_to_lock_operation :

adds a vessel to the lock operation planning

convert_chamber :

converts the lock chamber and logs this event

close_door :

.

level_lock :

.

open_door :

.

add_empty_lock_operation_to_planning(operation_index, direction)#

Adds an empty lock operation to the operation planning

Parameters#

operation_indexint

index of the lock operation to which the vessel can be added (can either be an existing or a new lock operation)

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

add_vessel_to_vessel_planning(vessel, direction, time_of_registration=None)#

Adds vessel to the vessel planning of the lock complex upon request

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

time_of_registrationpd.Timestamp

the time that the vessel registers to the lock master

calculate_lock_departure_start_time(vessel, operation_index, direction, operation_stop_time, prognosis=False)#

Calculates the moment in time the departure can start of a lock operation

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

operation_stop_timepd.Timestamp

the time that the lock operation has stopped (i.e., doors have been opened again)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

departure_start_timepd.Timestamp

the time that a lock operation’s departure process can start

calculate_lock_departure_stop_time(vessel, operation_index, direction, operation_stop_time, prognosis=False)#

Calculates the moment in time the departure process of a lock operation stops

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

operation_stop_timepd.Timestamp

the time that the lock operation has stopped (i.e., doors have been opened again)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

time_departure_stoppd.Timestamp

the moment in time that a lock operation’s departure process stops

calculate_lock_door_closing_time(vessel, operation_index, direction, operation_stop_time, prognosis=False)#

Calculates the moment in time a new lock operation can start

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

operation_stop_timepd.Timestamp

the time that the lock operation has stopped (i.e., doors have been opened again)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

time_operation_stoppd.Timestamp

the moment in time a new lock operation can start

calculate_lock_door_opening_time(vessel, operation_index, direction, operation_start_time)#

Calculates the time at which the lock doors can open before an vessel arrival

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

the index of the lock operation in the operation planning of the lock complex master

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Returns#

lock_entry_start_timepd.Timestamp

the time at which the lock doors can open before an vessel arrival

calculate_lock_entry_start_time(vessel, operation_index, direction, operation_start_time)#

Calculates the time at which the vessel can start sailing into to lock

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

the index of the lock operation in the operation planning of the lock complex master

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Returns#

lock_entry_start_timepd.Timestamp

the time at which the vessel can start sailing into to lock

calculate_lock_entry_stop_time(vessel, operation_index, direction, lock_entry_start_time, prognosis=False)#

Calculates the moment in time that a lock operation entry process of a lock operation is finished (all vessels are in lock chamber)

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

lock_entry_stop_timepd.Timestamp

the time that a lock operation entry process is finished

calculate_lock_operation_start_time(vessel, operation_index, direction, prognosis=False, overwrite=True)#

Calculates the new earliest possible start time of a lock operation

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

the index of the lock operation in the operation planning of the lock complex master

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

overwritebool

overwrites the vessel planning: True (yes) or False (no)

Returns#

lock_operation_start_timepd.Timestamp

the moment in time of the start of the lock operation

calculate_lock_operation_stop_time(vessel, operation_index, direction, operation_stop_time, prognosis=False)#

Calculates the moment in time a new lock operation can start

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

operation_stop_timepd.Timestamp

the time that the lock operation has stopped (i.e., doors have been opened again)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

time_operation_stoppd.Timestamp

the moment in time a new lock operation can start

calculate_lock_operation_times(operation_index, last_entering_time, start_time, vessel=None, direction=None)#

Calculates the moments in time of the start and stop of the operation steps of the lock: (1) door closing, (2) levelling, (3) door opening

Parameters#

operation_indexint

the index of the lock operation in the operation planning of the lock complex master

last_entering_timepd.Timestamp

the time that the last vessel entered the lock

start_timepd.Timestamp

the start time of the lock operation (i.e., for the doors to close)

vesseltype [optional]

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint [optional]

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Returns#

levelling_informationdict
including:
time_door_closing_startpd.Timestamp

the time that the lock doors are planned to start closing

time_door_closing_stoppd.Timestamp

the time that the lock doors are planned to stop closing

time_levelling_startpd.Timestamp

the time that the lock chamber is planned to start levelling

time_levelling_stoppd.Timestamp

the time that the lock chamber is planned to stop levelling

time_door_opening_startpd.Timestamp

the time that the lock doors are planned to start opening

time_door_opening_stoppd.Timestamp

the time that the lock doors are planned to stop opening

calculate_sailing_in_time_delay(vessel, operation_index, direction, minimum_difference_with_previous_vessel=False, prognosis=False, overwrite=True)#

Calculates the minimum required time gap between two entering vessels for safety, resulting in a delay

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

the index of the lock operation in the operation planning dataframe

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

minimum_difference_with_previous_vesselbool

.

prognosisbool

.

overwritebool

.

Returns#

sailing_in_time_delaypd.Timedelta

time delay because of waiting for the vessel to sail entering the lock [s]

calculate_sailing_information_on_route_to_lock_complex(vessel, lock_end_node)#

Calculates the sailing information (i.e., duration, distance, and speed) of the vessel per edge of its route between its current location and the lock doors

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

lock_end_nodestr

the node name that forms the end node of the lock complex given the direction of the vessel

Returns#

sailing_timepd.DataFrame

sailing information (i.e., duration, distance, and speed) per edge of the route of the vessel between its current location and the lock doors

calculate_sailing_time_in_lock(vessel, operation_index, prognosis=False)#

Calculates the time duration that a vessel needs to enter the lock until laying still

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

prognosisbool

.

Returns#

sailing_time_into_lockpd.Timedelta

the time duration of the process of sail in the lock [s]

calculate_sailing_time_to_approach_point(vessel, direction, from_waiting_area=False, operation_index=None, prognosis=False, overwrite=True)#

Calculates the sailing time of a vessel from its location to the approach point

The approach point is the closest location in front of the lock doors where the outdirection vessel(s) can pass the indirection vessel waiting to enter the lock. The point is located in between the line-up area and the lock doors.

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

current_nodestr

the node name (which has to be in the graph) at which the vessel is currently sailing

prognosis :

.

overwrite :

.

Returns#

sailing_to_lineup_area_timepd.Timedelta

sailing time to the lock chambers’s line-up area in [s]

calculate_sailing_time_to_lineup_area(vessel, direction, current_node=None, prognosis=False, overwrite=True)#

Calculates the sailing time of a vessel from its location to the line-up area

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

current_nodestr

the node name (which has to be in the graph) at which the vessel is currently sailing

prognosis :

.

overwrite :

.

Returns#

sailing_to_lineup_area_timepd.Timedelta

sailing time to the lock chambers’s line-up area in [s]

calculate_sailing_time_to_lock_door(vessel, direction, prognosis=False, overwrite=True)#

Calculates the sailing time of a vessel from its location to the first lock doors that it will encounter

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

current_nodestr

the node name (which has to be in the graph) at which the vessel is currently sailing

prognosis :

.

overwrite :

.

Returns#

sailing_to_lineup_area_timepd.Timedelta

sailing time to the lock chambers’s line-up area in [s]

calculate_sailing_time_to_waiting_area(vessel, direction, current_node=None, prognosis=False, overwrite=True)#

TODO: note that this function looks a lot like other ‘calculate_sailing_time_to’-functions below, so maybe we can investigate to combine the functions Calculates the sailing time of a vessel from its location to the waiting area

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

current_nodestr

the node name (which has to be in the graph) at which the vessel is currently sailing

prognosis: bool

.

overwrite: bool

.

Returns#

sailing_to_waiting_area_time: pd.Timedelta

sailing time to the waiting area in [s]

sailing_distance: float

sailing distance to the waiting area in [m]

average_sailing_speed: float

average sailing speed to the lock chambers’s waiting area in [m/s]

calculate_vessel_departure_start_delay(vessel, operation_index, direction, prognosis=False)#

Calculates the delay for a vessel to start leaving the lock

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

delay_to_departurepd.Timestamp

the delay of a vessel to start its departure process out of the lock

calculate_vessel_departure_start_time(vessel, operation_index, direction, operation_stop_time, prognosis=False)#

Calculates the moment in time that a vessel can start leaving the lock

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

operation_stop_timepd.Timestamp

the time that the lock operation has stopped (i.e., doors have been opened again)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

departure_start_timepd.Timestamp

the time that a vessel’s departure process out of the lock can start

calculate_vessel_departure_stop_time(vessel, operation_index, direction, operation_stop_time, prognosis=False)#

Calculates the moment in time the departure process of a vessel stops

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

operation_stop_timepd.Timestamp

the time that the lock operation has stopped (i.e., doors have been opened again)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

time_departure_stoppd.Timestamp

the moment in time that a vessel’s departure process stops

calculate_vessel_entry_duration(vessel, direction)#

Calculates the time duration required for a vessel starts entering the lock (from approach point to first encountered lock doors)

Parameters#

vesseltype [optional]

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

Returns#

sailing_time_entrypd.Timedelta

the time duration required for a vessel starts entering the lock [s]

calculate_vessel_entry_stop_time(vessel, operation_index, direction, prognosis=False)#

Calculates the moment in time that a vessel finished its lock entry process

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

vessel_entry_stop_timepd.Timestamp

the moment in time that the vessel stops entering the lock

calculate_vessel_passing_start_time(vessel, operation_index, direction, prognosis=False, overwrite=True)#

Calculates the start time that a vessel can start its manoeuvre of entering the lock

Parameters#

vesseltype [optional]

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

the index of the lock operation in the operation planning of the lock complex master

directionint

the direction of the vessel: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

overwritebool

overwrites the vessel planning: True (yes) or False (no)

Returns#

vessel_passing_start_timestamppd.Timestamp

the moment in time that a vessel starts entering the lock from the approach point

calculate_vessel_passing_stop_time(vessel, operation_index, direction, operation_stop_time, prognosis=False)#

Calculates the moment in time the vessel has reached the approach point at the other side of the lock (while sailing away from the lock)

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

directionint

the direction of the lock operation: 0 (direction from node_A to node_B) or 1 (direction from node_B to node_A)

operation_stop_timepd.Timestamp

the time that the lock operation has stopped (i.e., doors have been opened again)

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

time_departure_stoppd.Timestamp

the moment in time the vessel has reached the approach point at the other side of the lock

calculate_vessel_sailing_time_out_of_lock(vessel, operation_index, prognosis=False)#

Calculates the sailing time for a vessel to sail from its position in the lock to the lock doors that have to be passed to sail out of the lock

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

departure_start_timepd.Timestamp

the time that a lock operation’s departure process can start

create_operational_hours(start_times, stop_times)#

Creates an DataFrame with the operational hours of the lock complex

Parameters#

start_times: list of pd.Timestamp

the time at which the operation of the lock starts

stop_times: list of pd.Timestamp

the time at which the operation of the lock stops (after the start times)

Returns#

operational_hourspd.DataFrame

a dataframe with the windows of operation for the lock complex

determine_first_vessel_of_lock_operation(vessel, operation_index)#

Determines the first vessel that was assigned to the lock operation

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

the index of the lock operation in the operation planning of the lock complex master

determine_last_vessel_of_lock_operation(vessel, operation_index, prognosis=False)#

Determines the last vessel that was assigned to the lock operation

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

operation_indexint

index of the lock operation

prognosisbool

is for planning purposes or for actual events: True (yes) or False (no)

Returns#

last_vesseltype

the last assigned vessel of the lock operation (the one that will enter and leave the lock chamber last)

overrule_vessel_speed(vessel, lock_end_node, waiting_time=0.0)#

Overrules the speed of an vessel based on the additional waiting time

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

lock_end_nodestr

the node name that forms the end node of the lock complex given the direction of the vessel

waiting_timefloat

waiting duration in seconds

register_vessel(vessel)#

Registers a vessel to the lock operation and vessel planning

Parameters#

vesseltype

a type including the following parent-classes: PassesLockComplex, Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

class opentnsim.lock.IsLockWaitingArea(edge, lock, distance_from_edge_start, *args, **kwargs)#

Bases: HasResource, Identifiable, Log, HasOutput, HasMultiDiGraph

Mixin class: lock complex has waiting area object:

creates a waiting area with a waiting_area resource which is requested when a vessels wants to enter the area with limited capacity

Attributes#

waiting_areasimpy.PriorityResource

the waiting area resource with a certain capacity

locationLocation

the location of the waiting area on the edge

class opentnsim.lock.PassesLockComplex(*args, **kwargs)#

Bases: Movable, HasMultiDiGraph

Mixin class: Something that passes a lock complex (i.e., can be added to a vessel-object)

Pre-requisites#

arrival_time:

the vessel should have an arrival_time in its metadata

Attributes#

register_to_lock_master: generator

vessel requests registration of itself to the lock master of the lock complex (for short-term planning)

sail_to_waiting_area: generator

the event of sailing towards the vessel’s first to be encountered waiting area of the lock complex

register_to_lock_master(origin)#

Request lock master to register when vessel reaches a registration node of a lock complex object

Parameters#

originstr

node name (that has to be in the graph) on which the vessel is currently starting to navigate an edge

Yields#

Request to the lock complex master to register the vessel

sail_to_waiting_area(origin, destination)#

Vessel sails to the waiting area

Parameters#

originstr

node name (that has to be in the graph) on which the vessel is currently sailing, to navigate an edge

destinationstr

node name (that has to be in the graph) on which the vessel is currently sailing to, to navigate an edge (should form an edge with the origin)

Yields#

wait_in_waiting_area(waiting_area)#

Let the vessel wait in the waiting area

Parameters#

waiting_areaclass

the waiting area of the lock chamber (IsLockWaitingArea-class)

Yields#

waiting time in the waiting area: (1) for another vessel and (2) for the start of the assigned lock operation

opentnsim.lock.calculate_cycle_looptimes(leveling_cycles: list, vessels: list) DataFrame#

Calculates the looptime for each locking cycle.

Looptime is defined as the time between: - the last vessel exiting the lock in the previous cycle (‘Sailing to lock complex exit start’) - the first vessel entering the lock in the current cycle (‘Sailing to first lock doors stop’)

Parameters: - leveling_cycles: List of dicts from get_vessels_during_leveling, each with ‘vessels_present’. - vessels: List of vessel objects, each with a .logbook attribute and optional .name.

Returns: - DataFrame with columns: ‘cycle’, ‘looptime_seconds’

opentnsim.lock.calculate_detailed_cycle_time(lock, vessels, leveling_cycles)#

Calculates detailed timing metrics for full lock cycles (up + down) using logbook data.

Each full cycle consists of two consecutive leveling events: one upward and one downward. The function computes: - Looptimes before each phase (t_l_up, t_l_down) - Entry and exit durations for vessels based on first and last movement timestamps - Lock operation durations (door opening/closing, water level adjustment) per cycle - Total cycle time (Tc) - Locking system intensity (I_s = 2 * n_max / (Tc / 3600))

Parameters#

lockobject

Lock object with a .logbook attribute containing a list of dicts with ‘Message’ and ‘Timestamp’.

vesselslist

List of vessel objects, each with a .logbook attribute and optional .name.

leveling_cycleslist

Output from get_vessels_during_leveling, containing dicts with ‘leveling_start’, ‘leveling_stop’, and ‘vessels_present’.

Returns#

pd.DataFrame

A DataFrame with one row per full lock cycle and the following columns: - t_l_up: Looptime before upcycle - sum_t_i_up: Time between first vessel’s entry start and last vessel’s entry stop (upcycle) - T_close_up, T_waterlevel_up, T_open_up: Lock operation durations (upcycle) - sum_t_u_up: Time between first vessel’s exit start and last vessel’s exit stop (upcycle)

  • t_l_down: Looptime before downcycle

  • sum_t_i_down: Time between first vessel’s entry start and last vessel’s entry stop (downcycle)

  • T_close_down, T_waterlevel_down, T_open_down: Lock operation durations (downcycle)

  • sum_t_u_down: Time between first vessel’s exit start and last vessel’s exit stop (downcycle)

  • Tc_seconds: Total time for the full cycle (up + down)

  • up_vessels: List of vessels in upcycle

  • down_vessels: List of vessels in downcycle

  • I_s: Locking system intensity (vessels per hour)

Notes#

  • Lock operation durations are extracted per cycle from the lock’s logbook using start/stop message pairs.

  • Vessel entry and exit durations are calculated using the earliest and latest timestamps of relevant movement messages.

  • The function assumes leveling_cycles are chronologically ordered and alternate between up and down phases.

opentnsim.lock.get_vessels_during_leveling(lock, vessels: list) list#

Identifies which vessels were present during each lock leveling event.

Parameters: - lock: An object with a .logbook attribute (list of dicts with ‘Message’ and ‘Timestamp’). - vessels: List of vessel objects, each with a .logbook attribute and optional .name.

Returns: - List of dicts with keys: ‘leveling_start’, ‘leveling_stop’, ‘vessels_present’

opentnsim.lock.levelling_time_equation(t, z, lock_length, lock_width, disch_coeff, gate_opening_time, opening_area, t_start, dt, direction, water_level_difference_limit_to_open_doors, prediction, H_A, H_B)#

Calculates the levelling time of a lock operation based on Eq. 4.64 of Ports and Waterways Open Textbook (https://books.open.tudelft.nl/home/catalog/book/204) This function is called by determine_levelling_time() Returns ——- levelling_time : float

the time duration of the levelling process

tlist of float

the time series of the levelling process

zlist of float

the water level difference series over the time of the levelling process

opentnsim.graph module#

class opentnsim.graph.DiGraph(edges, weights=[1], geometries=[None], edges_info={}, crs='EPSG:4326', bidirectional=True, *args, **kwargs)#

Bases: object

class opentnsim.graph.FIS(*args, **kwargs)#

Bases: object

static import_FIS(url)#
load_fis_network()#

load the topological fairway information system network (vaarweginformatie.nl)

class opentnsim.graph.Graph(*args, **kwargs)#

Bases: object

General networkx object

Initialize a nx.Graph() element

Attributes#

graphnetworkx.Graph

The graph object

graph_infodict

The graph information

add_resources(edges, resources, environment)#

Add resources to the edges of the graph

Parameters#

edges: list

List of edges to which the resources should be added

resources: list

List of resources to be added to the edges. Should be same length as edges

environment: simpy.Environment

The simpy environment to which the resources should be added

change_projection(transform, point)#

Transform one point on the graph

Make sure to install the required package gdal (for osgeo). run pip show gdal to check if gdal is installed.

Parameters#

transform:

create_graph_new_projection(to_EPSG=4326)#

redefine self.graph with the new projection

Make sure to install the required package gdal (for osgeo). run pip show gdal to check if gdal is installed.

Parameters#

to_EPSG: int

The EPSG code to transform the graph to

from_shape(file_location, shapefile, simplify=True, strict=True)#

Generate nx.Graph() from shapefile Make sure to install the required package gdal.

run pip show gdal to check if gdal is installed.

Parameters#

file_location: Path

location on server of the shapefile

shapefile: str

name of the shapefile (including .shp)

simplify: bool

if True, the graph is simplified

strict: bool

if True, the graph is strict

plot(size=[10, 10], with_labels=False, node_size=0.5, font_size=2, width=0.2, arrowsize=3)#

Plot the graph Parameters ———- size: list

The size of the figure

with_labels: bool

If True, the labels of the nodes are shown

node_size: int

The size of the nodes, default is 0.5

font_size: int

The size of the font, default is 2

width: int

The width of the edges, default is 0.2

arrowsize: int

The size of the arrows, default is 3

transform_projection(to_EPSG)#

create a transformation object to transform the graph to a new projection Make sure to install the required package gdal.

run pip show gdal to check if gdal is installed. Parameters ———- to_EPSG: int

The EPSG code to transform the graph to

class opentnsim.graph.HasMultiDiGraph(*args, **kwargs)#

Bases: object

This locking module uses a MultiDiGraph to represent the network. This converts other graphs to a MultiDiGraph.

copy()#
property multidigraph#

opentnsim.vessel_traffic_service module#

class opentnsim.vessel_traffic_service.HydrodynamicDataManager#

Bases: object

Singleton class to manage hydrodynamic data. This class ensures that hydrodynamic data is loaded only once and can be accessed globally.

class opentnsim.vessel_traffic_service.VesselTrafficService(graph, crs_m='EPSG:4087', hydrodynamic_information_path=None, vessel_speed_information_path=None, hydrodynamic_information=None, vessel_speed_information=None, hydrodynamic_start_time=Timedelta('0 days 00:00:00'), *args, **kwargs)#

Bases: HasMultiDiGraph

Class: a collection of functions that processes requests of vessels regarding the nautical processes on ow to enter the port safely

check_if_geometry_is_aligned_with_edge(edge)#
combine_tidal_windows(tidal_window_1, tidal_window_2)#
get_closest_location_on_edge_to_point(graph, edge, point)#
get_edges_info()#
provide_distance_from_location_over_edge(edge, location, tolerance=0.0001)#
provide_distance_over_network_to_location(node_1, node_2, location, tolerance=0.0001)#
provide_edge_by_distance_from_node(env, node_1, node_2, distance)#
provide_governing_current_velocity(vessel, node, time_start_index, time_end_index)#
provide_heading(vessel, edge)#
provide_horizontal_tidal_windows(vessel, route, time_start, time_end, delay=0, plot=False)#
provide_location_over_edges(node_1, node_2, interpolation_length)#
provide_minimum_available_water_depth_along_route(vessel, route, time_start, time_end, delay=0)#
Function: calculates the minimum available water depth (predicted/modelled/measured water level minus the local maintained bed level) along the route over time,

subtracted with the difference between the gross ukc and net ukc (hence: subtracted with additional safety margins consisting of vessel-related factors and water level factors). The bottom-related factors are already accounted for in the use of the MBL instead of the actual depth.

Input:
  • vessel: an identity which is Identifiable, Movable, and Routable, and has VesselProperties

  • route: a list of strings of node names that resemble the route that the vessel is planning

to sail (can be different than vessel.route) - delay:

provide_nearest_anchorage_area(vessel, node)#
provide_sailing_distance(edge, k=None)#

Calculates sailing distance of edge

Parameters#

edgetuple

tuple resembles an edge with: a start_node [u] as str, end_node (v) as str

kint [optional]

identifier of the edge (used in networkx MultiDiGraph to distinguish between edges between the same pair of nodes)

Returns#

sailing_distancefloat

sailing distance along the edge in [m]

provide_sailing_distance_over_route(route, edges=None)#

Calculates sailing distance of a route

Parameters#

vessel :

a type including the following parent-classes: Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

edgetuple

tuple resembles an edge with: a start_node [u] as str, end_node (v) as str

Returns#

sailing_distance_over_routefloat

sailing distance along the route in [m]

provide_sailing_time(vessel, route, edges=None)#

Calculates sailing time of vessel

Parameters#

vessel :

a type including the following parent-classes: Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

routelist of str

str resemble node names that have to be in the graph

edgeslist of tuples

tuples resemble edges with: a start_node [u] as str, end_node (v) as str, and identifier (k) as int

Returns#

sailing_time_over_routepd.DataFrame

dataframe with edges as (multi)index and the following column-information: Speed, Distance, Time

provide_sailing_time_distance_on_edge_to_distance_on_another_edge(vessel, route, distance_sailed_on_first_edge=0.0, distance_sailed_on_last_edge=0.0, edges=None)#

Calculates the distance from a location along an edge A to another location along an edge B

Parameters#

vesseltype

a type including the following parent-classes: Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

routelist of str

str resemble node names that have to be in the graph

distance_sailed_on_first_edgefloat

distance that is already covered on the edge at which the vessel is currently sailing

distance_sailed_on_last_edgefloat

distance on the last edge that the vessel has to sail to reach its location of interest

edgeslist of tuples

tuples resemble edges with: a start_node [u] as str, end_node (v) as str, and identifier (k) as int

Returns#

sailing_information_dfpd.DataFrame

dataframe with edges as (multi)index and the following column-information: Speed, Distance, Time

provide_speed_over_edge(vessel, edge)#
provide_speed_over_route(vessel, route, edges=[])#

Provides the speed along a vessel’s route

Parameters#

vesseltype

a type including the following parent-classes: Identifiable, Movable, VesselProperties, ExtraMetadata, HasMultiDiGraph, HasOutput

routelist of str

str resemble node names that have to be in the graph

edgeslist of tuple

tuples resemble edges with: a start_node [u] as str, end_node (v) as str, and identifier (k) as int

Returns vessel_speed_over_route : pd.DataFrame

vessel speed per edge of the route


provide_tidal_window_restriction(vessel, route, node, delay, restriction_type='Vertical')#

Function: determines which tidal window restriction applies to the vessel at the specific node

Input:
  • vessel: an identity which is Identifiable, Movable, and Routable, and has VesselProperties

  • route: a list of strings of node names that resemble the route that the vessel is planning

to sail (can be different than vessel.route) - specifications: the specific data regarding the properties for which the restriction holds - node: a string that defines the node of the tidal window restriction

provide_tidal_windows(vessel, route, time_start, time_end, ax_left=None, ax_right=None, delay=0, plot=False)#
provide_trajectory(node_1, node_2)#
provide_ukc_clearance(vessel, node, delay=0)#

Function: calculates the sail-in-times for a specific vssel with certain properties and a pre-determined route and provides this information to the vessel

Input:
  • vessel: an identity which is Identifiable, Movable, and Routable, and has VesselProperties

  • node:

  • components_calc:

provide_vertical_tidal_windows(vessel, route, time_start, time_end, delay=0, plot=False)#
Function: calculates the windows available to sail-in and -out of the port given the

vertical tidal restrictions according to the tidal window policy.

Input:
  • vessel: an identity which is Identifiable, Movable, and Routable, and has VesselProperties

  • route: a list of strings of node names that resemble the route that the vessel is planning to sail (can be different than vessel.route)

  • sailing_time_correction: a bool that indicates whether the calculation should correct for sailing_speed (dynamic calculation) or not (static calculation)

provide_waiting_time_for_inbound_tidal_window(vessel, route, time_start=None, time_stop=None, delay=0, plot=False)#

Function: calculates the time that a vessel has to wait depending on the available tidal windows

Input:
  • vessel: an identity which is Identifiable, Movable, and Routeable, and has VesselProperties

  • route: a list of strings that resemble the route of the vessel (can be different than the vessel.route)

  • delay: a delay that can be included to calculate a future situation

  • plot: bool that specifies if a plot is requested or not

provide_waiting_time_for_outbound_tidal_window(vessel, route, delay=0, plot=False)#
provide_water_depth(vessel, node, delay=0)#
read_tidal_periods(hydrodynamic_data, tidal_period_type, station_index)#
reverse_geometry(geometry)#
transform_geometry(geometry, epsg_in='EPSG:4326', epsg_out=None)#

Module contents#