Skip to content

Commit 74851c7

Browse files
authored
Merge pull request #15 from Yuksel-Rudy/main
Adding Resetting Array Origin to Mid-Platform:
2 parents fd4e8e7 + 405118b commit 74851c7

File tree

3 files changed

+76
-24
lines changed

3 files changed

+76
-24
lines changed

famodel/mooring/mooring.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ def reposition(self, r_center=None, heading=None, project=None,
198198
r_center : list or nested list
199199
The x, y, z coordinates of the platform(s) (undisplaced) [m]. If shared mooring, must be a list of lists, with the
200200
coordinates for each platform connection. In this case, end A platform connection is the first entry and end B
201-
platform connection is the second entry.
201+
platform connection is the second entry. If not given, r_center will be populated from what self is attached to.
202202
heading : float
203203
The absolute heading compass direction of the mooring line from end B
204204
[deg or rad] depending on degrees parameter (True or False). Must account for the platform heading as well.
@@ -227,11 +227,15 @@ def reposition(self, r_center=None, heading=None, project=None,
227227
# heading 2D unit vector
228228
u = np.array([np.cos(phi), np.sin(phi)])
229229

230-
if self.shared == 1:
231-
r_centerB = np.array(r_center)[1]
232-
r_centerA = np.array(r_center)[0]
230+
if np.any(r_center):
231+
if self.shared == 1:
232+
r_centerA = np.array(r_center)[0]
233+
r_centerB = np.array(r_center)[1]
234+
else:
235+
r_centerB = np.array(r_center)
233236
else:
234-
r_centerB = np.array(r_center)
237+
r_centerA = self.attached_to[0].r
238+
r_centerB = self.attached_to[1].r
235239

236240
# create fairlead radius list for end A and end B if needed
237241
if not rad_fair:

famodel/platform/platform.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ def __init__(self, id, r=[0,0,0], heading=0, mooring_headings=[60,180,300],rFair
6464
def setPosition(self, r, heading=None, degrees=False,project=None):
6565
'''
6666
Set the position/orientation of the platform as well as the associated
67-
anchor points.
67+
anchor points.
6868
69+
"Note: must only be used for a platform that's only attached with anchored lines"
70+
6971
Parameters
7072
----------
7173
r : list

famodel/project.py

Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ def __init__(self, lon=0, lat=0, file=None, depth=202,raft=1):
117117
# MoorPy system associated with the project
118118
self.ms = None
119119

120-
120+
# RAFTDict associated with the project
121+
self.RAFTDict = None
121122

122123
# ----- if an input file has been passed, load it -----
123124
if file:
@@ -788,15 +789,17 @@ def loadDesign(self, d, raft=1):
788789
# create a name for the raft model
789790
RAFTDict['name'] = 'Project_Array'
790791
RAFTDict['type'] = 'input file for RAFT'
791-
792+
793+
self.RAFTDict = deepcopy(RAFTDict)
794+
792795
# create RAFT model if necessary components exist
793796
if 'platforms' in RAFTDict or 'platform' in RAFTDict:
794797

795798
self.getRAFT(RAFTDict,pristine=1)
796-
799+
800+
797801

798802

799-
800803

801804

802805
# ----- Site conditions processing functions -----
@@ -4114,20 +4117,21 @@ def extractFarmInfo(self, cmax=5, fmax=10/6, Cmeander=1.9):
41144117
i = 0
41154118
yaw_init = np.zeros((1, len(self.platformList.items())))
41164119
for _, pf in self.platformList.items():
4117-
x, y, z = pf.body.r6[0], pf.body.r6[1], pf.body.r6[2]
4118-
phi_deg = np.degrees(pf.phi) # float((90 - np.degrees(pf.phi)) % 360) # Converting FAD's rotational convention (0deg N, +ve CW) into FF's rotational convention (0deg E, +ve CCW)
4119-
phi_deg = (phi_deg + 180) % 360 - 180 # Shift range to -180 to 180
4120-
for att in pf.attachments.values():
4121-
if isinstance(att['obj'],Turbine):
4122-
D = 240 # att['obj'].D (assuming 15MW)
4123-
zhub = att['obj'].dd['hHub']
4120+
if pf.entity=='FOWT':
4121+
x, y, z = pf.body.r6[0], pf.body.r6[1], pf.body.r6[2]
4122+
phi_deg = np.degrees(pf.phi) # float((90 - np.degrees(pf.phi)) % 360) # Converting FAD's rotational convention (0deg N, +ve CW) into FF's rotational convention (0deg E, +ve CCW)
4123+
phi_deg = (phi_deg + 180) % 360 - 180 # Shift range to -180 to 180
4124+
for att in pf.attachments.values():
4125+
if isinstance(att['obj'],Turbine):
4126+
D = 240 # att['obj'].D (assuming 15MW)
4127+
zhub = att['obj'].dd['hHub']
41244128

4125-
wts[i] = {
4126-
'x': x, 'y': y, 'z': z, 'phi_deg': phi_deg, 'D': D, 'zhub': zhub,
4127-
'cmax': cmax, 'fmax': fmax, 'Cmeander': Cmeander
4128-
}
4129-
yaw_init[0, i] = -phi_deg
4130-
i += 1
4129+
wts[i] = {
4130+
'x': x, 'y': y, 'z': z, 'phi_deg': phi_deg, 'D': D, 'zhub': zhub,
4131+
'cmax': cmax, 'fmax': fmax, 'Cmeander': Cmeander
4132+
}
4133+
yaw_init[0, i] = -phi_deg
4134+
i += 1
41314135

41324136
# store farm-level wind turbine information
41334137
self.wts = wts
@@ -4206,6 +4210,48 @@ def FFarmCompatibleMDOutput(self, filename, unrotateTurbines=True, renameBody=Tr
42064210
with open(filename, 'w') as f:
42074211
f.writelines(newLines)
42084212

4213+
def resetArrayCenter(self, FOWTOnly=True):
4214+
'''
4215+
Function to reset array center such that the farm origin is the mid-point between all FOWT platforms:
4216+
4217+
Parameters
4218+
----------
4219+
FOWTOnly : bool
4220+
find the center between only FOWT-entity platforms if True.
4221+
'''
4222+
xCenter = np.mean([p.r[0] for p in self.platformList.values() if p.entity=='FOWT' or not FOWTOnly])
4223+
yCenter = np.mean([p.r[1] for p in self.platformList.values() if p.entity=='FOWT' or not FOWTOnly])
4224+
delta = np.array([xCenter, yCenter])
4225+
4226+
# Change boundaries
4227+
self.boundary -= delta
4228+
4229+
# Change bathymetry
4230+
self.grid_x -= delta[0]
4231+
self.grid_y -= delta[1]
4232+
4233+
# Change all platform locations and associated anchors/moorings/cables
4234+
for pf in self.platformList.values():
4235+
pf.r[:2]-=delta
4236+
for i, att in enumerate(pf.attachments.values()):
4237+
obj = att['obj']
4238+
if isinstance(obj, Mooring):
4239+
obj.reposition(project=self)
4240+
4241+
if isinstance(obj, Cable):
4242+
obj.reposiiton(project=self)
4243+
4244+
# Change RAFTDict if available.
4245+
if self.RAFTDict:
4246+
x_idx = self.RAFTDict['array']['keys'].index('x_location')
4247+
y_idx = self.RAFTDict['array']['keys'].index('y_location')
4248+
for i in range(len(self.platformList.values())):
4249+
self.RAFTDict['array']['data'][i][x_idx] -= delta[0]
4250+
self.RAFTDict['array']['data'][i][y_idx] -= delta[1]
4251+
4252+
if 'platforms' in self.RAFTDict or 'platform' in self.RAFTDict:
4253+
self.getRAFT(self.RAFTDict,pristine=1)
4254+
42094255

42104256
def updateFailureProbability(self):
42114257
'''
@@ -4219,7 +4265,7 @@ def updateFailureProbability(self):
42194265
None.
42204266
42214267
'''
4222-
4268+
pass
42234269

42244270

42254271

0 commit comments

Comments
 (0)