Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions famodel/mooring/mooring.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ def setSectionType(self, lineType, i):


def reposition(self, r_center=None, heading=None, project=None,
degrees=False, rad_fair=[], **kwargs):
degrees=False, rad_fair=[], z_fair=[], **kwargs):
'''Adjusts mooring position based on changed platform location or
heading. It can call a custom "adjuster" function if one is
provided. Otherwise it will just update the end positions.
Expand All @@ -208,6 +208,10 @@ def reposition(self, r_center=None, heading=None, project=None,
fairlead radius of node connected on each end of the mooring line (list should be length 2)
If not provided, the fairlead radius will be determined from the attached nodes' listed
fairlead radius (or, if it's an anchor, 0)
z_fair : list, optional
fairlead depth of node connected on each end of the mooring line (list should be length 2)
If not provided, the fairlead depth will be determined from the attached nodes' listed
fairlead depths (or, if it's an anchor, 0)
**kwargs : dict
Additional arguments passed through to the designer function.
'''
Expand All @@ -232,17 +236,18 @@ def reposition(self, r_center=None, heading=None, project=None,
# create fairlead radius list for end A and end B if needed
if not rad_fair:
rad_fair = [self.attached_to[x].rFair if (hasattr(self.attached_to[x],'rFair') and self.attached_to[x].rFair) else 0 for x in range(2)]

if not z_fair:
z_fair = [self.attached_to[x].zFair if (hasattr(self.attached_to[x],'zFair') and self.attached_to[x].zFair) else 0 for x in range(2)]
# Set the updated end B location
self.setEndPosition(np.hstack([r_centerB + rad_fair[1]*u, self.z_fair]), 'b')
self.setEndPosition(np.hstack([r_centerB + rad_fair[1]*u, z_fair[1]]), 'b')

# Run custom function to update the mooring design (and anchor position)
# this would also szie the anchor maybe?
if self.adjuster:
self.adjuster(self, r_centerB, u, project=project, **kwargs)

elif self.shared == 1: # set position of end A at platform end A
self.setEndPosition(np.hstack([r_centerA - rad_fair[0]*u, self.z_fair]),'a')
self.setEndPosition(np.hstack([r_centerA - rad_fair[0]*u, z_fair[0]]),'a')

else: # otherwise just set the anchor position based on a set spacing (NEED TO UPDATE THE ANCHOR DEPTH AFTER!)
xy_loc = r_centerB + self.rad_anch*u
Expand Down
32 changes: 23 additions & 9 deletions famodel/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,6 +600,8 @@ def getAnchors(lineAnch, mc=None,aNum=0):
# attach turbine to platform
self.platformList[arrayInfo[i]['ID']].attach(self.turbineList[turb_name])
self.platformList[arrayInfo[i]['ID']].entity = 'FOWT'
elif arrayInfo[i]['turbineID'] < 0: # (buoy)
self.platformList[arrayInfo[i]['ID']].entity = 'buoy'
else:
# for now, assume it's an OSS (To be changed!!)
self.platformList[arrayInfo[i]['ID']].entity = 'OSS'
Expand Down Expand Up @@ -745,8 +747,9 @@ def getAnchors(lineAnch, mc=None,aNum=0):
# set line anchor type and get dictionary of anchor information
lineAnch = arrayAnchor[k]['type']
ad = getAnchors(lineAnch,aNum=aNum) # call method to create dictionary
#mc.z_anch = -zAnew
# create anchor object
zAnew = self.getDepthAtLocation(aloc[0], aloc[1])
mc.z_anch = -zAnew
self.anchorList[arrayAnchor[aNum]['ID']] = Anchor(dd=ad, r=[aloc[0],aloc[1],-zAnew], aNum=aNum,id=arrayAnchor[aNum]['ID'])
# attach mooring object to anchor
mc.attachTo(self.anchorList[(arrayAnchor[aNum]['ID'])],end='A')
Expand Down Expand Up @@ -2560,11 +2563,18 @@ def getMoorPyArray(self,bodyInfo=None,plt=0, pristineLines=True,cables=0):
wflag = 0 # warning flag has not yet been printed (prevent multiple printings of same hydrostatics warning)
for i,body in enumerate(self.platformList): # make all the bodies up front - i is index in dictionary, body is key (name of platform)
PF = self.platformList[body]
dd = getattr(PF, 'dd', None) # Check if there is a design dictionary for this body
# add a moorpy body at the correct location
r6 = [PF.r[0],PF.r[1],0,0,0,0]
# use bodyInfo dictionary to create moorpy body if given
if bodyInfo:
self.ms.addBody(-1,r6,m=bodyInfo[body]['m'],v=bodyInfo[body]['v'],rCG=np.array(bodyInfo[body]['rCG']),rM=np.array(bodyInfo[body]['rM']),AWP=bodyInfo[body]['AWP'])
if not PF.entity=="FOWT":
r6[2] = bodyInfo[body]['rCG'][-1]
self.ms.addBody(-1,r6,m=bodyInfo[body]['m'],v=bodyInfo[body]['v'],rCG=np.array(bodyInfo[body]['rCG']),rM=np.array(bodyInfo[body]['rM']),AWP=bodyInfo[body]['AWP'])
else:
self.ms.addBody(-1,r6,m=bodyInfo[body]['m'],v=bodyInfo[body]['v'],rCG=np.array(bodyInfo[body]['rCG']),rM=np.array(bodyInfo[body]['rM']),AWP=bodyInfo[body]['AWP'])
elif 'm' in dd and 'v' in dd:
self.ms.addBody(-1, r6,m=PF.dd['m'],v=PF.dd['v'])
elif not bodyInfo and wflag == 0: # default to UMaine VolturnUS-S design hydrostatics info
print('No hydrostatics information given, so default body hydrostatics from UMaine VolturnUS-S will be used.')
wflag = 1
Expand Down Expand Up @@ -3706,19 +3716,23 @@ def arrayWatchCircle(self,plot=False, ang_spacing=45, RNAheight=150,

if not self.ms:
self.getMoorPyArray()



# apply thrust force to platforms at specified angle intervals
for i,ang in enumerate(angs):
print('Analyzing platform offsets at angle ',ang)
fx = thrust*np.cos(np.radians(ang))
fy = thrust*np.sin(np.radians(ang))

# add thrust force and moment to the body
for body in self.ms.bodyList:
body.f6Ext = np.array([fx, fy, 0, fy*RNAheight, fx*RNAheight, 0]) # apply an external force on the body [N]
for pf in self.platformList.values():
if pf.entity.upper() == 'FOWT':
pf.body.f6Ext = np.array([fx, fy, 0, fy*RNAheight, fx*RNAheight, 0]) # apply an external force on the body [N]

# solve equilibrium
self.ms.solveEquilibrium3(DOFtype='both')

self.ms.plot(draw_seabed=False)
plt.show()
# save info if requested
if SFs:
# get loads on anchors (may be shared)
Expand Down Expand Up @@ -4094,7 +4108,7 @@ def gothroughlist(dat):
# this is not an empty connector
if not 'type' in conf['connectors'][i]:
# make a new connector type
connTypes[str(int(len(connTypes)))] = dict(conf['connectors'][i])
connTypes[str(int(len(connTypes))+1)] = dict(conf['connectors'][i])
ctn = str(int(len(connTypes))) # connector type name
else:
ctn = str(conf['connectors'][i]['type'])
Expand Down Expand Up @@ -4123,7 +4137,7 @@ def gothroughlist(dat):
if not 'type' in conf['connectors'][i+1]:
# make a new connector type
#conf['connectors'][i+1] = cleanDataTypes(conf['connectors'][i+1])
connTypes[str(len(connTypes))] = conf['connectors'][i+1]
connTypes[str(len(connTypes))] = dict(conf['connectors'][i+1])
ctn = str(int(len(connTypes)))
else:
ctn = conf['connectors'][i+1]['type']
Expand Down