Skip to content

Commit fb63f3f

Browse files
committed
lineProps yaml specification, marine growth description conformity, unload/fairleads bug fix
-- yaml specification option for lineProps, where the yaml name will be read in and applied when developing mooring properties (when calling moorpy.helpers.loadLineProps) - property saved as lineProps -- marine growth description altered to conform to general table format (now a list of dicts, -{'thickness':x,'lowerRange':y,'upperRange':z,'density':w}) -- marine growth on buoys moved to its own project property, marine_growth_buoys, same setup as before (list of thicknesses corresponding to different buoyancy sections irrespective of depth) -- bug fix in unload for fairleads stuff -- bug fix helpers.compareDicts to fix issue with recursion -- bug fix in platform.setPosition to reset mooring end point attached to fairleads even if set_moorings is False
1 parent 114b99c commit fb63f3f

File tree

5 files changed

+136
-123
lines changed

5 files changed

+136
-123
lines changed

famodel/cables/dynamic_cable.py

Lines changed: 44 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -616,28 +616,29 @@ def createSubsystem(self, case=0,pristine=True,dd=None):
616616
self.ss_mod = ss
617617
return(self.ss_mod)
618618

619-
def addMarineGrowth(self, mgDict,updateDepths=False,tol=2):
619+
def addMarineGrowth(self, mgDict, buoy_mg, updateDepths=False,tol=2):
620620
'''Creates a new design dictionary (does not overwrite old one) to account for marine
621621
growth on the subystem, then calls createSubsystem() to recreate the cable
622622
623623
Parameters
624624
----------
625-
mgDict : dictionary
625+
mgDict : list, optional
626626
Provides marine growth thicknesses and the associated depth ranges
627-
{
628-
th : list with 3 values in each entry - thickness, range lower z-cutoff, range higher z-cutoff [m]
629-
*In order from sea floor to surface*
630-
example, if depth is 200 m: - [0.00,-200,-100]
631-
- [0.05,-100,-80]
632-
- [0.10,-80,-40]
633-
- [0.20,-40,0]
634-
buoy_th : list of thicknesses associated with buoyancy sections. This is used to simplify the marine growth modeling on buoys.
635-
* In order of sections from end A to end B (also the order of sections listed in buoyancy_sections list in the dd)
636-
example, if 3 buoyancy sections: - 0.1
637-
- 0.05
638-
- 0.1
639-
rho : list of densities for each thickness, or one density for all thicknesses, [kg/m^3] (optional - default is 1325 kg/m^3)
640-
}
627+
Default is None, which triggers the use of the marine growth dictionary saved in the project class
628+
'density' entry is optional. If no 'density' entry is created in the dictionary, addMarineGrowth defaults to 1325 kg/m^3
629+
*In order from sea floor to surface*
630+
example, if depth is 200 m: - {'thickness':0.00,'lowerRange':-200,'upperRange':-100, 'density':1320}
631+
- {'thickness':0.05,'lowerRange':-100,'upperRange':-80, 'density':1325}
632+
- {'thickness':0.1,'lowerRange':-80,'upperRange':0, 'density':1325}
633+
634+
buoy_mg: list, optional
635+
Provides marine growth thicknesses for buoyancy sections of cables, irrespective of depth.
636+
This is used to simplify the marine growth modeling on buoys.
637+
* In order of sections from end A to end B (also the order of sections listed in buoyancy_sections list in the dd)
638+
example, if 3 buoyancy sections: - 0.1
639+
- 0.05
640+
- 0.1
641+
641642
Returns
642643
-------
643644
changePoints : list
@@ -646,7 +647,7 @@ def addMarineGrowth(self, mgDict,updateDepths=False,tol=2):
646647
List of cutoff depths the changePoints should be located at
647648
648649
'''
649-
def getMG(mgDict):
650+
def getMG(mgDict, buoy_mg):
650651
# create a reference subsystem if it doesn't already exist
651652
if not self.ss:
652653
self.createSubsystem(pristine=1)
@@ -699,31 +700,31 @@ def getMG(mgDict):
699700
high = ssLine.rB
700701
flip = 0
701702

702-
th = mgDict['th'] # set location for ease of coding
703+
th = mgDict # set location for ease of coding
703704
# look up what thickness this line section starts at (if lowest point is not on the sea floor, first segment will have a thickness other than the sea floor thickness)
704705
rAth = 0 # exit while loop when we find thickness at low
705706
count1 = 0 # counter
706707
while rAth==0: # and count1 < len(th):
707708
if flip:
708-
if high[2] <= th[count1][2]:
709-
LThick.append(th[count1][0])
709+
if high[2] <= th[count1]['upperRange']:
710+
LThick.append(th[count1]['thickness'])
710711
rAth = 1 # exit while loop
711712
else:
712-
if low[2] <= th[count1][2]:
713-
LThick.append(th[count1][0])
713+
if low[2] <= th[count1]['upperRange']:
714+
LThick.append(th[count1]['thickness'])
714715
rAth = 1 # exit while loop
715716
count1 = count1 + 1 # iterate counter
716717

717718
# determine if this line section will be split
718719
for j in range(0,len(th)): # go through all changeDepths
719720
if flip:
720-
rs = 2
721+
rs = 'upperRange'
721722
else:
722-
rs = 1
723+
rs = 'lowerRange'
723724
if th[j][rs]>low[2] and th[j][rs]<high[2]:
724725
# line section will be split - add line type, mg thickness, and material to list
725726
LTypes.append(ssLine.type['name'])
726-
slthick.append(th[j][0])
727+
slthick.append(th[j]['thickness'])
727728
# Mats.append(ssLine.type['material'])
728729
# add an empty connector object to list for split location
729730
sCount += 1
@@ -771,12 +772,12 @@ def getMG(mgDict):
771772

772773
else:
773774
# this is a buoy section, add the prescribed buoy marine growth thickness
774-
if isinstance(mgDict['buoy_th'],list):
775+
if isinstance(buoy_mg,list):
775776
# add the buoy thickness for this specific buoyancy section
776-
LThick.append(mgDict['buoy_th'][buoyCount])
777+
LThick.append(buoy_mg[buoyCount])
777778
else:
778779
# add the single buoy thickness
779-
LThick.append(mgDict['buoy_th'])
780+
LThick.append(buoy_mg)
780781

781782
if slthick: # add the length of the top line (from last split to upper end of section) if there was a split in the line
782783
slength.append(float(ssLine.L-ln_raw[-1]))
@@ -811,17 +812,13 @@ def getMG(mgDict):
811812
mu_mg = np.zeros((len(LTypes)))
812813
rho_mg = np.ones((len(LTypes)))*1325
813814
# adjust rho value if alternative provided
814-
if 'rho' in mgDict:
815-
if not type(mgDict['rho']) is list:
816-
# just one density given for all marine growth on the line
817-
rho_mg = rho_mg*mgDict['rho']/1325
818-
else: # density given for each thickness of marine growth
819-
for i in range(0,len(rho_mg)):
820-
# look up what thickness number this rho is related to
821-
for j in range(0,len(LThick)):
822-
thind = np.where(th[:][0]==LThick[j])
823-
# assign rho_mg based on the rho_mg of the thickness
824-
rho_mg[i] = mgDict['rho'][thind]
815+
if 'density' in mgDict[0]:
816+
for i in range(0,len(mgDict)):
817+
# look up what thickness number this rho is related to
818+
for j in range(0,len(LThick)):
819+
thind = np.where([th[ii]['thickness']==LThick[j] for ii in range(len(th))])
820+
# assign rho_mg based on the rho_mg of the thickness
821+
rho_mg[i] = mgDict[thind[0][0]]['density']
825822

826823

827824
nd = [] # list of dictionaries for new design dictionary sections part
@@ -955,29 +952,29 @@ def getMG(mgDict):
955952
cEq = tol + 1
956953
ct = 0
957954
while(cEq>tol):
958-
changeDepths,changePoints = getMG(mgDict1)
955+
changeDepths,changePoints = getMG(mgDict1, buoy_mg)
959956
D = []
960957
for d in range(0,len(changeDepths)):
961-
diff = mgDict['th'][changeDepths[d][0]][changeDepths[d][1]] - self.ss_mod.pointList[changePoints[d]].r[2]
958+
diff = mgDict[changeDepths[d][0]][changeDepths[d][1]] - self.ss_mod.pointList[changePoints[d]].r[2]
962959
D.append(diff)
963960
cEq = np.mean(D)
964961
# adjust depth to change based on difference between actual and desired change depth
965962
if cEq>tol:
966-
mgDict1['th'][0][2] = mgDict1['th'][0][2] + cEq
967-
for j in range(1,len(mgDict['th'])):
968-
for k in range(1,3):
963+
mgDict1[0]['upperRange'] = mgDict1[0]['upperRange'] + cEq
964+
for j in range(1,len(mgDict)):
965+
for k in ['lowerRange','upperRange']:
969966
if ct < 4 and abs(cEq)<12:
970-
mgDict1['th'][j][k] = mgDict1['th'][j][k] + cEq
967+
mgDict1[j][k] = mgDict1[j][k] + cEq
971968
elif (ct >= 4 and ct < 9) or abs(cEq)>=12:
972969
# could be ping-ponging between two different things, try adding half
973-
mgDict1['th'][j][k] = mgDict1['th'][j][k] + 0.5*cEq
970+
mgDict1[j][k] = mgDict1[j][k] + 0.5*cEq
974971
print('average difference between expected and actual change depth is: ',cEq)
975972
if ct > 10:
976973
print('Could not meet tolerance in 10 attempts. Exiting loop')
977974
break
978975
ct += 1
979976
else:
980-
changeDepths,changePoints = getMG(mgDict)
977+
changeDepths,changePoints = getMG(mgDict, buoy_mg)
981978
return(changeDepths,changePoints)
982979

983980

famodel/helpers.py

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ def CableProps(cabType, cable_types, rho_water, g, checkType=1, A=None):
767767

768768
return(deepcopy(dd))
769769

770-
def MooringProps(mCon, lineTypes, rho_water, g, checkType=1):
770+
def MooringProps(mCon, lineTypes, rho_water, g, lineProps, checkType=1):
771771
'''
772772
Parameters
773773
----------
@@ -805,8 +805,8 @@ def MooringProps(mCon, lineTypes, rho_water, g, checkType=1):
805805
from moorpy.helpers import loadLineProps, getLineProps
806806
if not 'd_nom' in mCon:
807807
raise Exception('To use MoorProps yaml, you must specify a nominal diameter in mm for the mooring line family')
808-
lineprops = loadLineProps(None)
809-
mProps = getLineProps(mCon['d_nom']*1000,mCon['mooringFamily'],lineProps=lineprops)
808+
809+
mProps = getLineProps(mCon['d_nom']*1000,mCon['mooringFamily'],lineProps=lineProps)
810810
dd = mProps
811811
dd['name'] = mCon['mooringFamily']
812812
dd['d_nom'] = mCon['d_nom']
@@ -816,7 +816,7 @@ def MooringProps(mCon, lineTypes, rho_water, g, checkType=1):
816816

817817
return(deepcopy(dd))
818818

819-
def getMoorings(lcID, lineConfigs, connectorTypes, pfID, proj):
819+
def getMoorings(lcID, lineConfigs, connectorTypes, pfID, proj, lineProps):
820820
'''
821821
822822
Parameters
@@ -858,7 +858,8 @@ def getMoorings(lcID, lineConfigs, connectorTypes, pfID, proj):
858858
config.append({})
859859
c_config.append({})
860860
# set line information
861-
lt = MooringProps(lc, proj.lineTypes, proj.rho_water, proj.g)
861+
lt = MooringProps(lc, proj.lineTypes, proj.rho_water, proj.g,
862+
lineProps)
862863
# lt = self.lineTypes[lc['type']] # set location for code clarity and brevity later
863864
# set up sub-dictionaries that will contain info on the line type
864865
config.append({'type':lt})# {'name':str(ct)+'_'+lc['type'],'d_nom':lt['d_nom'],'material':lt['material'],'d_vol':lt['d_vol'],'m':lt['m'],'EA':float(lt['EA'])}})
@@ -929,7 +930,7 @@ def getMoorings(lcID, lineConfigs, connectorTypes, pfID, proj):
929930
if sublineLast[ii]:
930931
# add empty connector
931932
config[-1][-1].append({})
932-
lt = MooringProps(subsub,proj.lineTypes, proj.rho_water, proj.g)
933+
lt = MooringProps(subsub,proj.lineTypes, proj.rho_water, proj.g, lineProps)
933934
config[-1][-1].append({'type':lt,
934935
'L': subsub['length']})
935936
# make EA a float not a string
@@ -1415,13 +1416,17 @@ def compareDicts(d1, d2):
14151416
for key in d1:
14161417
if key in d2:
14171418
if type(d1[key]) is dict:
1418-
compareDicts(d1[key],d2[key])
1419+
x = compareDicts(d1[key],d2[key])
1420+
if x==False:
1421+
return(False)
14191422
elif isinstance(d1[key],(list, np.ndarray)):
14201423
if len(d1[key])!=len(d2[key]):
14211424
return(False)
14221425
for i,ix in enumerate(d1[key]):
14231426
if type(d1[key][i]) is dict:
1424-
compareDicts(ix,d2[key][i])
1427+
x = compareDicts(ix,d2[key][i])
1428+
if x==False:
1429+
return(False)
14251430
elif isinstance(ix,(list, np.ndarray)):
14261431
for j,jx in ix:
14271432
if jx != d2[key][i][j]:

famodel/mooring/mooring.py

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -904,15 +904,10 @@ def addMarineGrowth(self, mgDict):
904904
----------
905905
mgDict : dictionary
906906
Provides marine growth thicknesses and the associated depth ranges
907-
{
908-
th : list with 3 values in each entry - thickness, range lower z-cutoff, range higher z-cutoff [m]
909-
*In order from sea floor to surface*
910-
example, if depth is 200 m: - [0.00,-200,-100]
911-
- [0.05,-100,-80]
912-
- [0.10,-80,-40]
913-
- [0.20,-40,0]
914-
rho : list of densities for each thickness, or one density for all thicknesses, [kg/m^3] (optional - default is 1325 kg/m^3)
915-
}
907+
*In order from sea floor to surface*
908+
example, if depth is 200 m: - {'thickness':0.00,'lowerRange':-200,'upperRange':-100, 'density':1320}
909+
- {'thickness':0.05,'lowerRange':-100,'upperRange':-80, 'density':1325}
910+
- {'thickness':0.1,'lowerRange':-80,'upperRange':0, 'density':1325}
916911
917912
Returns
918913
-------
@@ -967,31 +962,31 @@ def addMarineGrowth(self, mgDict):
967962
high = ssLine.rB
968963
flip = 0
969964

970-
th = mgDict['th'] # set location for ease of coding
965+
th = mgDict # set location for ease of coding
971966
# look up what thickness this line section starts at (if lowest point is not on the sea floor, first segment will have a thickness other than the sea floor thickness)
972967
rAth = 0 # exit while loop when we find thickness at low
973968
count1 = 0 # counter
974969
while rAth==0 and count1 <= len(th):
975970
if flip:
976-
if high[2] <= th[count1][2]:
977-
LThick.append(th[count1][0])
971+
if high[2] <= th[count1]['upperRange']:
972+
LThick.append(th[count1]['thickness'])
978973
rAth = 1 # exit while loop
979974
else:
980-
if low[2] <= th[count1][2]:
981-
LThick.append(th[count1][0])
975+
if low[2] <= th[count1]['upperRange']:
976+
LThick.append(th[count1]['thickness'])
982977
rAth = 1 # exit while loop
983978
count1 = count1 + 1 # iterate counter
984979

985980
# determine if this line section will be split
986981
for j in range(0,len(th)): # go through all changeDepths
987982
if flip:
988-
rs = 2
983+
rs = 'upperRange'
989984
else:
990-
rs = 1
985+
rs = 'lowerRange'
991986
if th[j][rs]>low[2] and th[j][rs]<high[2]:
992987
# line section will be split - add line type, mg thickness, and material to list
993988
LTypes.append(ssLine.type['name'])
994-
slthick.append(th[j][0])
989+
slthick.append(th[j]['thickness'])
995990
Mats.append(ssLine.type['material'])
996991
# add an empty connector object to list for split location
997992
connList.append(Connector(str(len(connList))+'_empty'))
@@ -1075,7 +1070,7 @@ def addMarineGrowth(self, mgDict):
10751070
# look up what thickness number this rho is related to
10761071
for j in range(0,len(th)):
10771072
# compare thickness to th list
1078-
if LThick == th[j][0]:
1073+
if LThick == th[j]['thickness']:
10791074
# assign rho_mg based on the rho_mg of the thickness
10801075
rho_mg[i] = mgDict['rho'][j]
10811076

famodel/platform/platform.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,6 @@ def setPosition(self, r, heading=None, degrees=False,project=None, update_moorin
9797
if update_moorings:
9898
for i, att in enumerate(self.attachments):
9999
if isinstance(self.attachments[att]['obj'], Mooring):
100-
self.updateMooringPoints()
101100
# Heading of the mooring line
102101
heading_i = self.mooring_headings[count] + self.phi
103102
# Reposition the whole Mooring if it is an anchored line
@@ -116,7 +115,8 @@ def setPosition(self, r, heading=None, degrees=False,project=None, update_moorin
116115

117116
# reposition the cable
118117
cab.reposition(project=project)
119-
118+
119+
self.updateMooringPoints()
120120

121121
def mooringSystem(self,rotateBool=0,mList=None,bodyInfo=None, project=None):
122122
'''

0 commit comments

Comments
 (0)