Skip to content

Commit c4a8536

Browse files
committed
updateState and other fixes for creep, corrosion, and stiffness bounds:
- creep function allows the input of either a percentage or a creep rate (%/year), - corrosion function allows the input of either a direct mm value to apply or a corrosion rate (mm/year), - general fixes in these functions, - updateState function in Mooring.py calls all these functions given a stateDict dictionary that describes the different inputs required.
1 parent 3f33761 commit c4a8536

File tree

2 files changed

+93
-51
lines changed

2 files changed

+93
-51
lines changed

famodel/design/LineDesign.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -608,7 +608,7 @@ def updateDesign(self, X, display=0, display2=0, normalized=True):
608608
self.dd['subcomponents'][2*i+1]['type'].update(lineType)
609609

610610
# apply corrosion to the mooring's MBL dictionary (which gets references in the getTenSF constraint in subsystem)
611-
self.addCorrosion(self.lineProps, corrosion_mm=self.corrosion_mm)
611+
self.addCorrosion(corrosion_mm=self.corrosion_mm)
612612

613613
# update the intermediate points if they have any weight or buoyancy
614614
for i in range(self.nLines-1):

famodel/mooring/mooring.py

Lines changed: 92 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,12 @@ class Mooring(Edge):
2121
def __init__(self, dd=None, subsystem=None, anchor=None,
2222
rho=1025, g=9.81, id=None, shared=0, lineProps=None):
2323
'''
24+
Initializes a Mooring object.
25+
2426
Parameters
2527
----------
26-
dd: dictionary
27-
Design dictionary that contains all information on a mooring line needed to create a MoorPy subsystem
28+
dd: dict, optional
29+
Design dictionary that contains all information on a mooring line needed to create a MoorPy subsystem.
2830
Layout: {
2931
subcomponents: # always starts and ends with connectors even if connector dict is blank
3032
{
@@ -51,6 +53,27 @@ def __init__(self, dd=None, subsystem=None, anchor=None,
5153
rad_fair
5254
}
5355
56+
subsystem: MoorPy subsystem, optional
57+
The subsystem that corresponds to the mooring line.
58+
59+
anchor: object, optional
60+
The anchor object associated with the mooring line.
61+
62+
rho: float, optional
63+
The density of the fluid (default is 1025 kg/m^3 for seawater).
64+
65+
g: float, optional
66+
The acceleration due to gravity (default is 9.81 m/s^2).
67+
68+
id: any, optional
69+
An identifier for the mooring object.
70+
71+
shared: int, optional
72+
An integer indicating if the mooring line is an anchored line (0) or a shared line (1) (default is 0).
73+
74+
lineProps: any, optional
75+
Properties related to the mooring line sizing function coefficients.
76+
5477
'''
5578
Edge.__init__(self, id) # initialize Edge base class
5679
# Design description dictionary for this Mooring
@@ -165,7 +188,7 @@ def __init__(self, dd=None, subsystem=None, anchor=None,
165188

166189
self.adjuster = None # custom function that can adjust the mooring
167190

168-
self.shared = shared # int for if the mooring line is a shared line (1) or part of a shared line (2)
191+
self.shared = shared # int for if the mooring line is an anchored line (0) or a shared line (1)
169192
self.symmetric = False # boolean for if the mooring line is a symmetric shared line
170193

171194
# relevant site info
@@ -244,7 +267,7 @@ def adjustSectionType(self, i, d_nom=None, material=None):
244267
----------
245268
d_nom : float, optional
246269
The nominal diameter to set the lineType to [mm], if provided.
247-
d_nom : string, optional
270+
material : string, optional
248271
The material type to set the lineType (must match a LineProps key),
249272
if provided.
250273
'''
@@ -834,7 +857,45 @@ def ddSave(self):
834857
835858
return self.dd
836859
"""
837-
860+
861+
def updateState(self, stateDict):
862+
'''
863+
Updates the state of the mooring system based on the provided state dictionary.
864+
865+
Parameters
866+
----------
867+
stateDict : dict
868+
Dictionary containing the state configuration. The expected keys are:
869+
- 'years': Global number of years for creep and corrosion (integer).
870+
- 'stiffnessBounds': Dictionary with 'lower' (boolean) for stiffness bounds.
871+
- 'creep': Boolean indicating whether to apply creep.
872+
- 'corrosion': Boolean indicating whether to apply corrosion.
873+
- 'marineGrowth': Dictionary for marine growth configuration (same as addMarineGrowth).
874+
'''
875+
876+
# Extract global number of years
877+
years = stateDict.get('years', 0)
878+
879+
# 1. Update stiffness bounds
880+
if 'stiffnessBounds' in stateDict:
881+
stiffness = stateDict['stiffnessBounds']
882+
suffix = stiffness.get('suffix', "")
883+
self.adjustPropertySets(suffix=suffix)
884+
885+
# 2. Apply creep if specified
886+
if stateDict.get('creep', False):
887+
self.addCreep(years)
888+
889+
# 3. Apply corrosion if specified
890+
if stateDict.get('corrosion', False):
891+
self.addCorrosion(years)
892+
893+
# 4. Apply marine growth if specified
894+
if 'marineGrowth' in stateDict:
895+
mgDict = stateDict['marineGrowth']
896+
self.addMarineGrowth(mgDict)
897+
898+
838899
def addMarineGrowth(self, mgDict):
839900
'''Re-creates sections part of design dictionary to account for marine
840901
growth on the subystem, then calls createSubsystem() to recreate the line
@@ -1127,23 +1188,19 @@ def addMarineGrowth(self, mgDict):
11271188
return(changeDepths,changePoints)
11281189

11291190

1130-
def addCorrosion(self, lineProps, years=25, corrosion_mm=None, z_lower_cutoff=None, z_upper_cutoff=None):
1191+
def addCorrosion(self, years=25, corrosion_rate=None, corrosion_mm=None):
11311192
'''
11321193
Calculates MBL of chain line with corrosion included
11331194
11341195
Parameters
11351196
----------
1136-
lineProps: dict
1137-
Dictionary of line properties from MoorProps yaml
11381197
years: float, optional
11391198
number of years to use with corrosion rate (default is 25 years)
1199+
corrosion_rate : float, optional
1200+
Corrosion rate in mm/yr.
11401201
corrosion_mm : float, optional
1141-
amount of corrosion in mm at splash zone/seabed (harsher environment).
1142-
If the value is not given, the corrosion rate from the lineProps dictionary will be used with a given design life.
1143-
z_lower_cutoff : float, optional
1144-
lower depth cutoff for lesser corrosion to be applied (default is None, meaning no cutoff)
1145-
z_upper_cutoff : float, optional
1146-
upper depth cutoff for lesser corrosion to be applied (default is None, meaning no cutoff)
1202+
Total corrosion in mm to apply directly.
1203+
If a corrosion_rate or a corrosion_mm are not given, the corrosion rate from the lineProps dictionary will be used.
11471204
'''
11481205

11491206
if self.ss:
@@ -1154,47 +1211,28 @@ def addCorrosion(self, lineProps, years=25, corrosion_mm=None, z_lower_cutoff=No
11541211
raise ValueError(f'Line material {mat} not found in lineProps dictionary.')
11551212
else:
11561213
if self.lineProps[mat].get('corrosion_rate', False):
1214+
if not corrosion_rate and not corrosion_mm:
1215+
corrosion_rate = self.lineProps[mat]['corrosion_rate'] # corrosion rate from the LineProps
11571216
if not corrosion_mm:
1158-
corrosion_mm = self.lineProps[mat]['corrosion_rate'] * years # total corrosion over design life
1159-
corrosion_m = corrosion_mm / 1000 # convert to m
1160-
1161-
if z_lower_cutoff and z_upper_cutoff:
1162-
# check where the chain lies in the water column to see if lesser corrosion should be applied
1163-
z_avg = line.Zs.mean() # average depth of the line
1164-
if z_avg >= z_lower_cutoff and z_avg <= z_upper_cutoff:
1165-
corrosion_m /= 2 # half the corrosion in the middle of the water column
1217+
corrosion_mm = corrosion_rate * years # total corrosion over design life in mm
11661218

1219+
corrosion_m = corrosion_mm / 1000 # convert to m
11671220
factor = ((line.type['d_nom'] - corrosion_m) / line.type['d_nom'])**2
1168-
# TODO: should we not also update d_nom to reflect corrosion?
1169-
# d_nom_cor = line.type['d_nom'] - corrosion_m
1170-
# lineType_cor = getLineProps(d_nom_cor*1e3, mat, lineProps) # convert to mm for getLineProps
1171-
# line.type = lineType_cor # update line type with new diameter
1172-
1173-
# OR just update MBL directly ?
11741221
line.type['MBL'] *= factor # update MBL with corrosion factored in
1175-
1176-
1177-
# Old method
1178-
# for i in self.i_sec:
1179-
# sec = self.getSubcomponent(i)
1180-
# if sec['type']['material']=='chain':
1181-
# MBL_cor = sec['type']['MBL']*( (sec['type']['d_nom']-(corrosion_mm/1000))/sec['type']['d_nom'] )**2 # corroded MBL
1182-
# else:
1183-
# MBL_cor = sec['type']['MBL']
1184-
# sec['type']['MBL'] = MBL_cor
11851222

1186-
1187-
def addCreep(self, years=25, creep_percent=None):
1223+
def addCreep(self, years=25, creep_rate=None, creep=None):
11881224
'''
11891225
Elongates the polyester lines (if exists) in the mooring by a certain creep percentage
11901226
11911227
Parameters
11921228
----------
11931229
years: float, optional
11941230
How many years worth of creep to add (default is 25 years).
1195-
creep_percent : float, optional
1196-
Percentage of creep elongation to add to polyester lines.
1197-
If not given, the creep rate from the lineProps dictionary will be used with a given design life.
1231+
creep_rate : float, optional
1232+
creep elongation rate [%]/yr to add to polyester lines.
1233+
creep : float, optional
1234+
Total creep elongation percent [%] to apply directly.
1235+
If a creep_rate and a creep are not given, the creep rate from the lineProps dictionary will be used with a given design life.
11981236
'''
11991237
if self.ss:
12001238
for i, line in enumerate(self.ss.lineList):
@@ -1204,11 +1242,15 @@ def addCreep(self, years=25, creep_percent=None):
12041242
raise ValueError(f'Line material {mat} not found in lineProps dictionary.')
12051243
else:
12061244
if self.lineProps[mat].get('creep_rate', False):
1207-
if not creep_percent:
1208-
creep_percent = lineProps[mat]['creep_rate'] * years # total creep to this point in time
1209-
L_creep = line.L * (1 + 0.01*creep_percent)
1245+
if not creep_rate:
1246+
creep_rate = self.lineProps[mat]['creep_rate']
1247+
1248+
if not creep:
1249+
creep = creep_rate * years # total creep percent over design life
1250+
1251+
L_creep = line.L * (1 + 0.01*creep)
12101252
#self.setSectionLength(L_creep, i)
1211-
line.setL(L)
1253+
line.setL(L_creep)
12121254
'''
12131255
# Change the diameter size to account for creep thinning
12141256
d_nom_creep = line.type['d_nom'] / np.sqrt(1 + creep_percent)
@@ -1236,13 +1278,13 @@ def adjustPropertySets(self, suffix):
12361278
for i, line in enumerate(self.ss.lineList):
12371279
# Get the original material as stored in the design dict
12381280
sec = self.getSubcomponent(self.i_sec[i])
1239-
mat = sec.type['material']
1281+
mat = sec['type']['material']
12401282

12411283
# Get and apply the modified properties
12421284
mat_suffix = mat + suffix # New material key to look for
1243-
if mat_suffix in lineProps:
1285+
if mat_suffix in self.lineProps:
12441286
# Update the lineType properties in the Line in the MoorPy subsystem
1245-
line.type.update(getLineProps(sec.type['d_nom']*1e3, mat_suffix, self.lineProps))
1287+
line.type.update(getLineProps(sec['type']['d_nom']*1e3, mat_suffix, self.lineProps))
12461288

12471289

12481290
def getEnvelope(self,ang_spacing=45,SFs=True):

0 commit comments

Comments
 (0)