Skip to content

Commit 4b1b96b

Browse files
committed
updates to mooring adjustments
-- bug fixes and updates to mooring adjustment helpers and mooring.reposition -- add display option in mooring adjustment helper func -- calculate unit vec from span and heading (since rA isn't updated from new position yet) -- calculate slope from fairlead depth to water depth -- updateAnchor location bug fix -- small bug fix in anchor.py getCost function
1 parent 79e74c6 commit 4b1b96b

File tree

4 files changed

+62
-31
lines changed

4 files changed

+62
-31
lines changed

famodel/anchors/anchor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -711,7 +711,7 @@ def getCost(self,costDict='default'):
711711
keyFail = True
712712
# check if mass info is available
713713
if not self.mass:
714-
if 'soil_properties' in self.dd:
714+
if self.soilProps:
715715
# need mass - call capacity functions
716716
self.getAnchorCapacity(plot=False)
717717
else:

famodel/helpers.py

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -923,15 +923,21 @@ def configureAdjuster(mooring, adjuster=None, method='horizontal',
923923
targetdd = deepcopy(mooring.dd)
924924
if project == None:
925925
raise Exception('Project class instance needs to be provided to determine target')
926-
targetdd['zAnchor'] = project.depth
927-
mooring.createSubsystem()
926+
targetdd['zAnchor'] = -project.depth
927+
if not mooring.shared:
928+
mooring.rA[2] = -project.depth
929+
mooring.createSubsystem(dd=targetdd)
928930

929931
if method == 'horizontal':
930932
mooring.target = np.linalg.norm(mooring.ss.fB_L[:2])
931933
elif method =='pretension':
932934
mooring.target = np.linalg.norm(mooring.ss.fB_L)
933935
else:
934936
raise Exception('Invalid adjustment method. Must be pretension or horizontal')
937+
# return mooring depth to accurate val
938+
if not mooring.shared:
939+
depth = project.getDepthAtLocation(mooring.rA[0], mooring.rA[1])
940+
mooring.rA[2] = -depth
935941
else:
936942
mooring.target = target
937943

@@ -941,26 +947,25 @@ def configureAdjuster(mooring, adjuster=None, method='horizontal',
941947

942948
# check if method is 'pretension' then save slope
943949
if method == 'pretension':
944-
945950
if project == None:
946951
raise Exception('Project class instance needs to be provided to determine slope')
947952

948953
if mooring.dd:
949954

950955
#calculate mooring slope using base depth
951956
#**** this assumes that the mooring system is designed for the base depth*****
952-
mooring.slope = project.depth / mooring.dd['span']
957+
mooring.slope = (project.depth+mooring.rB[2]) / mooring.dd['span']
953958

954959
else:
955960
if span:
956-
mooring.slope = project.depth / span
961+
mooring.slope = (project.depth+mooring.rB[2]) / span
957962
else:
958963
raise Exception('Span required to perform adjustment')
959964

960965
return(mooring)
961966

962967
def adjustMooring(mooring, method = 'horizontal', r=[0,0,0], project=None, target=1e6,
963-
i_line = 0, slope = 0.58 ):
968+
i_line = 0, slope = 0.58, display=False ):
964969
'''Custom function to adjust a mooring, called by
965970
Mooring.adjust. Fairlead point should have already
966971
been adjusted.
@@ -992,11 +997,12 @@ def adjustMooring(mooring, method = 'horizontal', r=[0,0,0], project=None, targe
992997
fairlead_rad = mooring.rad_fair
993998
fairlead_z = mooring.z_fair
994999

995-
fairlead = ss.rB # fairlead point
1000+
fairlead = ss.rB # fairlead point (already updated)
9961001

9971002
#unit direction vector towards ORIGNAL anchor in x,y plane, and inputted slope as the z component
998-
xydist = np.linalg.norm([ss.rA[0] - ss.rB[0],ss.rA[1] - ss.rB[1]])
999-
direction = np.array([(ss.rA[0] - ss.rB[0])/xydist, (ss.rA[1] - ss.rB[1])/xydist, -slope])
1003+
xydist = mooring.span # np.linalg.norm([ss.rA[0] - ss.rB[0],ss.rA[1] - ss.rB[1]])
1004+
phi = np.pi/2 - np.radians(mooring.heading)
1005+
direction = np.array([np.cos(phi), np.sin(phi), -slope]) # np.array([(ss.rA[0] - ss.rB[0])/xydist, (ss.rA[1] - ss.rB[1])/xydist, -slope])
10001006

10011007
#use project class to find new anchor interesection point, maintaining original line heading
10021008
if project:
@@ -1005,10 +1011,11 @@ def adjustMooring(mooring, method = 'horizontal', r=[0,0,0], project=None, targe
10051011
print('Project must be inputted for the pretension method')
10061012
return
10071013
#update mooring properties
1008-
print('R_anch new ', r_anch)
1014+
if display:
1015+
print('R_anch new ', r_anch)
10091016
mooring.dd['zAnchor'] = r_anch[2]
10101017
mooring.z_anch = mooring.dd['zAnchor']
1011-
mooring.rad_anch = np.linalg.norm(r_anch-r)
1018+
mooring.rad_anch = np.linalg.norm(r_anch[:2]-r[:2])
10121019
span = mooring.rad_anch - fairlead_rad
10131020
mooring.setEndPosition(r_anch, 'a') # set the anchor position
10141021

@@ -1017,12 +1024,17 @@ def adjustMooring(mooring, method = 'horizontal', r=[0,0,0], project=None, targe
10171024
iend = mooring.rA if i == 0 else mooring.rB
10181025
if type(att).__name__ in 'Anchor':
10191026
# this is an anchor, move anchor location
1020-
att.r = iend
1027+
if project:
1028+
project.updateAnchor(att)
1029+
else:
1030+
att.r = iend
10211031
if att.mpAnchor:
10221032
att.mpAnchor.r = att.r
10231033

1024-
# Estimate the correct line length to start with
1025-
ss.lineList[i_line].setL(np.linalg.norm(mooring.rB - mooring.rA))
1034+
# Estimate the correct line length to start with based on % of total length
1035+
L_tot = sum([line.L for line in ss.lineList])
1036+
initial_L_ratio = ss.lineList[i_line].L/L_tot
1037+
ss.lineList[i_line].setL(np.linalg.norm(mooring.rB - mooring.rA)*initial_L_ratio)
10261038

10271039
# Next we could adjust the line length/tension (if there's a subsystem)
10281040

@@ -1034,9 +1046,14 @@ def eval_func(X, args):
10341046

10351047
# run dsolve2 solver to solve for the line length that matches the initial tension
10361048
X0 = [ss.lineList[i_line].L] # start with the current section length
1037-
L_final, T_final, _ = dsolve2(eval_func, X0, Ytarget=[target],
1038-
Xmin=[1], Xmax=[1.1*np.linalg.norm(ss.rB-ss.rA)],
1039-
dX_last=[1], tol=[0.01], maxIter=50, stepfac=4)
1049+
if display:
1050+
L_final, T_final, _ = dsolve2(eval_func, X0, Ytarget=[target],
1051+
Xmin=[1], Xmax=[1.1*np.linalg.norm(ss.rB-ss.rA)],
1052+
dX_last=[1], tol=[0.01], maxIter=50, stepfac=4, display=5)
1053+
else:
1054+
L_final, T_final, _ = dsolve2(eval_func, X0, Ytarget=[target],
1055+
Xmin=[1], Xmax=[1.1*np.linalg.norm(ss.rB-ss.rA)],
1056+
dX_last=[1], tol=[0.01], maxIter=50, stepfac=4)
10401057
ss.lineList[i_line].L = L_final[0]
10411058
mooring.dd['sections'][i_line]['L'] = L_final[0]
10421059
mooring.dd['span'] = span
@@ -1055,7 +1072,16 @@ def func_TH_L(X, args):
10551072
return np.array([Fx - target]), dict(status=1) , False
10561073

10571074
X0 = [ss.lineList[i_line].L]
1058-
x, y, info = dsolve2(func_TH_L, X0, tol=[0.01], args=dict(direction='horizontal'), Xmin=[10], Xmax=[2000], dX_last=[10], maxIter=50, stepfac=4, display = 5)
1075+
if display:
1076+
x, y, info = dsolve2(func_TH_L, X0, tol=[0.01],
1077+
args=dict(direction='horizontal'),
1078+
Xmin=[10], Xmax=[2000], dX_last=[10],
1079+
maxIter=50, stepfac=4, display = 5)
1080+
else:
1081+
x, y, info = dsolve2(func_TH_L, X0, tol=[0.01],
1082+
args=dict(direction='horizontal'),
1083+
Xmin=[10], Xmax=[2000], dX_last=[10],
1084+
maxIter=50, stepfac=4)
10591085

10601086
else:
10611087
print('Invalid method. Must be either pretension or horizontal')

famodel/mooring/mooring.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ def setSectionType(self, lineType, i):
190190

191191

192192
def reposition(self, r_center=None, heading=None, project=None,
193-
degrees=False, rad_fair=[], z_fair=[], **kwargs):
193+
degrees=False, rad_fair=[], z_fair=[], adjust=True, **kwargs):
194194
'''Adjusts mooring position based on changed platform location or
195195
heading. It can call a custom "adjuster" function if one is
196196
provided. Otherwise it will just update the end positions.
@@ -251,7 +251,7 @@ def reposition(self, r_center=None, heading=None, project=None,
251251

252252
# Run custom function to update the mooring design (and anchor position)
253253
# this would also szie the anchor maybe?
254-
if self.adjuster:
254+
if self.adjuster and adjust:
255255

256256
#if i_line is not defined, assumed segment 0 will be adjusted
257257
if not hasattr(self,'i_line'):
@@ -293,8 +293,11 @@ def reposition(self, r_center=None, heading=None, project=None,
293293
for i,att in enumerate(self.attached_to):
294294
iend = self.rA if i == 0 else self.rB
295295
if type(att).__name__ in 'Anchor':
296-
# this is an anchor, move anchor location
297-
att.r = iend
296+
# this is an anchor, move anchor location & get soil (if possible)
297+
if project:
298+
project.updateAnchor(att)
299+
else:
300+
att.r = iend
298301
if att.mpAnchor:
299302
att.mpAnchor.r = att.r
300303

famodel/project.py

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -867,15 +867,15 @@ def loadSite(self, site):
867867
for i in range(len(xy)):
868868
self.boundary[i,0] = float(xy[i][0])
869869
self.boundary[i,1] = float(xy[i][1])
870-
870+
871871
if 'seabed' in site and site['seabed']:
872872
# if there's a file listed in the seabed dictionary
873873
if 'file' in site['seabed'] and site['seabed']['file']:
874874
# without reading the file to tell whether it has soil property information listed, check to see if soil property information is given
875875
if 'soil_types' in site['seabed'] and site['seabed']['soil_types']: # if the yaml does have soil property information
876-
self.loadSoil(filename=site['seabed']['file'], yaml=site['seabed'])
876+
self.loadSoil(filename=str(site['seabed']['file']), yaml=site['seabed'])
877877
else: # if the yaml doesn't have soil property information, read in just the filename to get all the information out of that
878-
self.loadSoil(filename=site['seabed']['file'])
878+
self.loadSoil(filename=str(site['seabed']['file']))
879879
# if there's no file listed in the seabed dictionary, load in just the yaml information (assuming the ['x', 'y', and 'type_array'] information are there)
880880
else:
881881
self.loadSoil(yaml=site['seabed'])
@@ -1225,6 +1225,7 @@ def getSoilAtLocation(self, x, y):
12251225

12261226
# # ----- Anchor
12271227
def updateAnchor(self,anch='all',update_loc=True):
1228+
#breakpoint()
12281229
if anch == 'all':
12291230
anchList = [anch for anch in self.anchorList.values()]
12301231
elif isinstance(anch, Anchor):
@@ -1234,11 +1235,11 @@ def updateAnchor(self,anch='all',update_loc=True):
12341235
if update_loc:
12351236
att = next(iter(anchor.attachments.values()), None)
12361237
if att['end'] in ['a', 'A', 0]:
1237-
x,y = att['obj'].rA[:2]
1238+
anchor.r = att['obj'].rA
12381239
else:
1239-
x,y = att['obj'].rB[:2]
1240-
else:
1241-
x,y = anchor.r[:2]
1240+
anchor.r = att['obj'].rB
1241+
1242+
x,y = anchor.r[:2]
12421243

12431244
anchor.r[2] = -self.getDepthAtLocation(x,y) # update depth
12441245
for att in anchor.attachments.values():
@@ -1594,7 +1595,8 @@ def addMooring(self, id=None, endA=None, endB=None, heading=0, dd={},
15941595
if len(r_center)>0:
15951596
if len(r_center)==1:
15961597
r_center = r_center[0]
1597-
mooring.reposition(r_center=r_center, heading=heading, project=self)
1598+
mooring.reposition(r_center=r_center, heading=heading,
1599+
adjust=False, project=self)
15981600
# adjust anchor z location and rA based on location of anchor
15991601
zAnew, nAngle = self.getDepthAtLocation(mooring.rA[0],
16001602
mooring.rA[1],

0 commit comments

Comments
 (0)