3030 configureAdjuster , route_around_anchors )
3131
3232
33+ t2N = 9806.7 # conversion factor from t to N
34+
3335def incrementer (text ):
3436 '''
3537 Increments the last integer found in a string.
@@ -267,7 +269,7 @@ def printNotSupported(st):
267269 except :
268270 pass
269271
270- req ['bollard_pull' ]['max_force_t ' ] = 0.01 * mass / 1e4 # <<< can add a better calculation for towing force required
272+ req ['bollard_pull' ]['max_force ' ] = 0.0001 * mass * t2N # <<< can add a better calculation for towing force required
271273
272274
273275 elif reqname == 'chain_storage' : # Storage specifically for chain
@@ -283,8 +285,8 @@ def printNotSupported(st):
283285 chain_vol += sec ['L' ] * np .pi * (sec ['type' ]['d_nom' ] / 2 ) ** 2 * (2 ) # volume [m^3]
284286 chain_L += sec ['L' ] # length [m]
285287
286- req ['chain_locker' ]['volume_m3 ' ] += chain_vol # <<< replace with proper estimate
287- req ['deck_space' ]['area_m2 ' ] += chain_L * 0.205 # m^2
288+ req ['chain_locker' ]['volume ' ] += chain_vol # <<< replace with proper estimate
289+ req ['deck_space' ]['area ' ] += chain_L * 0.205 # m^2
288290
289291
290292 elif reqname == 'rope_storage' : # Storage specifically for chain
@@ -300,8 +302,8 @@ def printNotSupported(st):
300302 rope_vol += sec ['L' ] * np .pi * (sec ['type' ]['d_nom' ] / 2 ) ** 2 # volume [m^3]
301303 rope_L += sec ['L' ] # length [m]
302304
303- req ['line_reel' ]['volume_m3 ' ] += rope_vol
304- req ['deck_space' ]['area_m2 ' ] += np .ceil ((0.0184 * rope_L )/ 13.5 )* 13.5 # m^2
305+ req ['line_reel' ]['volume ' ] += rope_vol
306+ req ['deck_space' ]['area ' ] += np .ceil ((0.0184 * rope_L )/ 13.5 )* 13.5 # m^2
305307
306308
307309 elif reqname == 'storage' : # Generic storage, such as for anchors
@@ -315,32 +317,32 @@ def printNotSupported(st):
315317 # if the suction piles are to be standing up # <<<<<< how to implement this? Depends on the asset assignment
316318 # A = (obj.dd['design']['D']+(10/3.28084))**2
317319
318- req ['deck_space' ]['area_m2 ' ] += A
320+ req ['deck_space' ]['area ' ] += A
319321
320322 elif reqname == 'anchor_overboarding' or reqname == 'anchor_lowering' :
321323 for obj in self .objectList :
322324 if isinstance (obj , Anchor ):
323325
324326 if obj .mass :
325- mass = obj .mass / 1e3 # tonnes
327+ mass = obj .mass # [kg]
326328 else : # rough estimate based on size
327329 wall_thickness = (6.35 + obj .dd ['design' ]['D' ]* 20 )/ 1e3 # Suction pile wall thickness (m), API RP2A-WSD. It changes for different anchor concepts
328- mass = (np .pi * ((obj .dd ['design' ]['D' ]/ 2 )** 2 - (obj .dd ['design' ]['D' ]/ 2 - wall_thickness )** 2 ) * obj .dd ['design' ]['L' ] * 7850 ) / 1e3 # rough mass estimate [tonne ]
329- req ['crane' ]['capacity_t ' ] = mass * 1.2 # <<< replace with proper estimate
330- req ['crane' ]['hook_height_m ' ] = obj .dd ['design' ]['L' ] * 1.2 # <<< replace with proper estimate
330+ mass = (np .pi * ((obj .dd ['design' ]['D' ]/ 2 )** 2 - (obj .dd ['design' ]['D' ]/ 2 - wall_thickness )** 2 ) * obj .dd ['design' ]['L' ] * 7850 ) # rough mass estimate [kg ]
331+ req ['crane' ]['capacity ' ] = mass * 1.2 # <<< replace with proper estimate
332+ req ['crane' ]['hook_height ' ] = obj .dd ['design' ]['L' ] * 1.2 # <<< replace with proper estimate
331333 if reqname == 'anchor_overboarding' :
332- req ['stern_roller' ]['width_m ' ] = obj .dd ['design' ]['D' ] * 1.2 # <<< replace with proper estimate
334+ req ['stern_roller' ]['width ' ] = obj .dd ['design' ]['D' ] * 1.2 # <<< replace with proper estimate
333335 else : # anchor lowering
334- req ['winch' ]['max_line_pull_t ' ] = mass * 1.2 # <<< replace with proper estimate
335- req ['winch' ]['speed_mpm ' ] = 18 # meters per minute
336+ req ['winch' ]['max_line_pull ' ] = mass * 1.2 # <<< replace with proper estimate
337+ req ['winch' ]['speed ' ] = 0.3 # [m/s]
336338
337339 elif reqname == 'anchor_orienting' :
338340 for obj in self .objectList :
339341 if isinstance (obj , Anchor ):
340342
341343 # req['winch']['max_line_pull_t'] =
342- req ['rov' ]['depth_rating_m ' ] = abs (obj .r [- 1 ]) * 1.2 # <<< replace with proper estimate
343- req ['divers' ]['max_depth_m ' ] = abs (obj .r [- 1 ]) * 1.2 # <<< replace with proper estimate / basically, if anchor is too deep, divers might not be an option
344+ req ['rov' ]['depth_rating ' ] = abs (obj .r [- 1 ]) * 1.2 # <<< replace with proper estimate
345+ req ['divers' ]['max_depth ' ] = abs (obj .r [- 1 ]) * 1.2 # <<< replace with proper estimate / basically, if anchor is too deep, divers might not be an option
344346
345347 elif reqname == 'anchor_embedding' :
346348
@@ -349,18 +351,18 @@ def printNotSupported(st):
349351
350352 if obj .dd ['type' ] == 'DEA' :
351353
352- req ['bollard_pull' ]['max_force_t ' ] = 270 # <<< replace with proper estimate
354+ req ['bollard_pull' ]['max_force ' ] = 270 * t2N # <<< replace with proper estimate
353355
354356 elif obj .dd ['type' ] == 'suction' :
355357
356- req ['pump_subsea' ]['pressure_bar ' ] = 12 # <<< replace with proper estimate
358+ req ['pump_subsea' ]['pressure ' ] = 1.2e5 # <<< replace with proper estimate
357359
358360 else :
359361 printNotSupported (f"Anchor type { obj .dd ['type' ]} " )
360362
361363 elif reqname == 'line_handling' :
362- req ['winch' ]['max_line_pull_t ' ] = 1
363- req ['crane' ]['capacity_t ' ] = 27 # should set to mooring weight <<<
364+ req ['winch' ]['max_line_pull ' ] = 1 * t2N
365+ req ['crane' ]['capacity ' ] = 27 * t2N # should set to mooring weight <<<
364366 #req['']['']
365367
366368 elif reqname == 'subsea_connection' :
@@ -369,9 +371,9 @@ def printNotSupported(st):
369371 if isinstance (obj , Mooring ):
370372
371373 depth = abs (obj .rA [2 ]) # depth assumed needed for the connect/disconnect work
372- req ['rov' ]['depth_rating_m ' ] = depth
374+ req ['rov' ]['depth_rating ' ] = depth
373375 if depth < 200 : # don't consider divers if deeper than this
374- req ['divers' ]['max_depth_m ' ] = depth #
376+ req ['divers' ]['max_depth ' ] = depth #
375377
376378 else :
377379 printNotSupported (f"Requirement { reqname } " )
@@ -1035,9 +1037,9 @@ def checkAssets(self, assets):
10351037 # Sum up the asset capabilities and their specs (not sure this is useful/valid)
10361038
10371039 # Here's a list of specs we might want to take the max of instead of sum: Add more as needed
1038- specs_to_max = ['hook_height_m ' , 'depth_rating_m ' ,
1039- 'max_depth_m ' , 'accuracy_m ' ,
1040- 'speed_mpm ' , 'capacity_t ' ] # capacity_t is here because it doesn't make sense to have two cranes to lift a single anchor.
1040+ specs_to_max = ['hook_height ' , 'depth_rating ' ,
1041+ 'max_depth ' , 'accuracy ' ,
1042+ 'speed ' , 'capacity ' ] # capacity_t is here because it doesn't make sense to have two cranes to lift a single anchor.
10411043 asset_caps = {}
10421044 for asset in assets :
10431045 for cap , specs in asset ['capabilities' ].items ():
@@ -1193,7 +1195,11 @@ def checkAsset(self, asset):
11931195
11941196 def calcDurationAndCost (self ):
11951197 '''
1196- Calculates duration and cost for the action. The structure here is dependent on `actions.yaml`.
1198+ Calculates duration and cost for the action, based on the time for
1199+ each requirement to be performed based on the selected capability
1200+ and the assigned asset(s) that meeting that capability.
1201+ The durations of each requirement are assumed to add (i.e. each is
1202+ done in series rather than parallel). <<< MH: is this okay? <<<
11971203 TODO: finish description
11981204
11991205 Inputs
@@ -1277,7 +1283,7 @@ def calcDurationAndCost(self):
12771283
12781284 distance = 2500 # <<< need to eventually compute distances based on positions
12791285
1280- speed = req ['assigned_assets' ][0 ]['capabilities' ]['bollard_pull' ]['site_speed_mps ' ]
1286+ speed = req ['assigned_assets' ][0 ]['capabilities' ]['bollard_pull' ]['site_speed ' ]
12811287
12821288 self .durations ['tow' ] = distance / speed / 60 / 60 # duration [hr]
12831289
@@ -1439,7 +1445,7 @@ def calcDurationAndCost(self):
14391445
14401446 # onsite speed from capabilities.engine (SI)
14411447 cap_eng = vessel .get ('capabilities' , {}).get ('engine' , {})
1442- speed_mps = float (cap_eng ['site_speed_mps ' ])
1448+ speed_mps = float (cap_eng ['site_speed ' ])
14431449
14441450 self .duration += dist_m / speed_mps / 3600.0
14451451
@@ -1546,7 +1552,7 @@ def calcDurationAndCost(self):
15461552 raise ValueError ('transit_onsite_tug: operator (barge) missing.' )
15471553
15481554 cap_eng = operator .get ('capabilities' , {}).get ('bollard_pull' , {})
1549- speed_mps = float (cap_eng ['site_speed_mps ' ])
1555+ speed_mps = float (cap_eng ['site_speed ' ])
15501556
15511557 self .duration += dist_m / speed_mps / 3600.0
15521558
@@ -1586,7 +1592,7 @@ def calcDurationAndCost(self):
15861592
15871593 if 'winch' in req ['selected_capability' ]: # using a winch to load
15881594
1589- speed = req ['assigned_assets' ][0 ]['capabilities' ]['winch' ]['speed_mpm' ]
1595+ speed = req ['assigned_assets' ][0 ]['capabilities' ]['winch' ]['speed' ] * 60 # [m/min ]
15901596
15911597 L = sum ([mooring ['length' ] for mooring in moorings ])
15921598
@@ -1625,9 +1631,9 @@ def calcDurationAndCost(self):
16251631
16261632 v_mpm = None
16271633 if 'winch' in req ['selected_capability' ]: # using a winch to lower
1628- v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['winch' ]['speed_mpm' ]
1634+ v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['winch' ]['speed' ] * 60 # [m/min ]
16291635 elif 'crane' in req ['selected_capability' ]: # using a crane to lower
1630- v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['crane' ]['speed_mpm' ]
1636+ v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['crane' ]['speed' ] * 60 # [m/min ]
16311637
16321638 if v_mpm : # there is only a lowering time if a winch or crane is involved
16331639 self .durations ['anchor lowering' ] = depth_m / v_mpm / 60 # [h]
@@ -1637,7 +1643,7 @@ def calcDurationAndCost(self):
16371643 req = self .requirements ['anchor_embedding' ]
16381644 if 'pump_subsea' in req ['selected_capability' ]: # using a winch to lower
16391645 specs = req ['assigned_assets' ][0 ]['capabilities' ]['pump_subsea' ] # pump specs
1640- embed_speed = 0.1 * specs ['power_kW ' ]/ (np .pi / 4 * anchor .dd ['design' ]['D' ]** 2 ) # <<< example of more specific calculation
1646+ embed_speed = 1E-4 * specs ['power ' ]/ (np .pi / 4 * anchor .dd ['design' ]['D' ]** 2 ) # <<< example of more specific calculation
16411647 else :
16421648 embed_speed = 0.07 # embedment rate [m/min]
16431649 self .durations ['anchor embedding' ] = L * embed_speed / 60
@@ -1663,9 +1669,9 @@ def calcDurationAndCost(self):
16631669 # note: some of this code is repeated and could be put in a function
16641670 v_mpm = None
16651671 if 'winch' in req ['selected_capability' ]: # using a winch to lower
1666- v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['winch' ]['speed_mpm' ]
1672+ v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['winch' ]['speed' ] * 60 # [m/min ]
16671673 elif 'crane' in req ['selected_capability' ]: # using a crane to lower
1668- v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['crane' ]['speed_mpm' ]
1674+ v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['crane' ]['speed' ] * 60 # [m/min ]
16691675
16701676 if v_mpm : # there is only a lowering time if a winch or crane is involved
16711677 self .durations ['mooring line lowering' ] = depth / v_mpm / 60 # [h]
@@ -1694,9 +1700,9 @@ def calcDurationAndCost(self):
16941700 # note: some of this code is repeated and could be put in a function
16951701 v_mpm = None
16961702 if 'winch' in req ['selected_capability' ]: # using a winch to lower
1697- v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['winch' ]['speed_mpm' ]
1703+ v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['winch' ]['speed' ] * 60 # [m/min ]
16981704 elif 'crane' in req ['selected_capability' ]: # using a crane to lower
1699- v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['crane' ]['speed_mpm' ]
1705+ v_mpm = req ['assigned_assets' ][0 ]['capabilities' ]['crane' ]['speed' ] * 60 # [m/min ]
17001706
17011707 if v_mpm : # there is only a lowering time if a winch or crane is involved
17021708 self .durations ['mooring line retrieval' ] = depth / v_mpm / 60 # [h]
0 commit comments