Skip to content

Commit

Permalink
Subsystem bathymetry functionality
Browse files Browse the repository at this point in the history
- Included a function in subsystem.py to pull from the global bathymetry and produce a 2D bathymetry directly underneath the subsystem
- - The bathGrid variable now becomes a 1D array of depths along the subsystem
- - bathGrid_Ys become 0, and the xs are set as the nodes along each line in the subsystem
- - This way, the alpha (slope) is calculated for each line in the subsystem's line list properly
- This function is called every time subsystem.staticSolve is called, with updated bathymetry based on any new rA/rB positions
- Additional work to do
- - Make sure the global bathymetry is tracked properly (currently needs self.sys != None)
- - Ensure the seabedMod parameter is set up properly
  • Loading branch information
shousner committed Dec 26, 2024
1 parent 8973cfc commit f55b264
Showing 1 changed file with 64 additions and 2 deletions.
66 changes: 64 additions & 2 deletions moorpy/subsystem.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,21 @@ def __init__(self, mooringSys=None, num=0, depth=0, rho=1025, g=9.81,
self.xSlope = getFromDict(kwargs, 'xSlope', default=0)
self.ySlope = getFromDict(kwargs, 'ySlope', default=0)

#if 'bathymetry' in kwargs:
#self.seabedMod = 2
#self.bathGrid_Xs, self.bathGrid_Ys, self.bathGrid = self.readBathymetryFile(kwargs['bathymetry'])
'''
if 'bathymetry' in kwargs:
self.seabedMod = 2
self.bathGrid_Xs, self.bathGrid_Ys, self.bathGrid = self.readBathymetryFile(kwargs['bathymetry'])
if isinstance(kwargs['bathymetry'],str):
self.bathGrid_Xs, self.bathGrid_Ys, self.bathGrid = readBathymetryFile(kwargs['bathymetry'])
elif isinstance(kwargs['bathymetry'],dict):
bath_dictionary = kwargs['bathymetry']
# grid sent in, just assign to properties
self.bathGrid_Xs = bath_dictionary['x']
self.bathGrid_Ys = bath_dictionary['y']
self.bathGrid = bath_dictionary['depth']
'''
# Note, System and Subsystem bathymetry can be set after creation
# by setBathymetry, which uses link to existing data, for efficiency.

Expand All @@ -124,6 +136,53 @@ def __init__(self, mooringSys=None, num=0, depth=0, rho=1025, g=9.81,

self.MDoptions = {} # dictionary that can hold any MoorDyn options read in from an input file, so they can be saved in a new MD file if need be
self.qs = 1 # flag that it's a MoorPy analysis, so System methods don't complain. One day should replace this <<<

def setSSBathymetry(self):
'''Provides global bathymetry data, but creates a 2D line corresponding to what's underneath the subsystem
- not naming it 'setBathymetry' since that is already a function name in the System class, but maybe I could name it the same?
- should theoretically be called every iteration / every call to a new position, to get the most update bathymetry plane
- need to make sure that any bathymetric operation in subsystem uses this new bathymetry information, and not the System.getDepthFromBathymetry
- - the fact that the bathGrid_Xs and Ys and grid arrays are new, should solve this issue
- could set up something for seabedMod = 0, 1, 2
Parameters
----------
x : list or array
X coordinates of a global, rectangular bathymetry grid [m].
y : list or array
Y coordinates of a global, rectangular bathymetry grid [m].
depth : 2D array
Matrix of depths at x and y locations [m]. Positive depths.
Shape should be [len(x), len(y)]
'''

# get the depth at the anchor point of the subsystem
depthA, nvecA = self.sys.getDepthFromBathymetry(self.rA[0], self.rA[1])
# get the depth under the fairlead point of the subsystem
depthB, nvecB = self.sys.getDepthFromBathymetry(self.rB[0], self.rB[1])

# collection information to create a new list of x coordinates to use for bathymetry for the subsystem (subsystems don't have y coordinates)
nNodes = [line.nNodes for line in self.lineList] # collecting the number of nodes in all the line sections
nx = np.sum(nNodes) - len(self.lineList) + 1 # adding all those nodes, subtracting the top nodes from each line (to avoid duplicates) and adding the fairlead node
xs = np.linspace(-self.span, 0, nx) # assuming that the subsystem rB will always be at 0,0

# calculate the bathymetric depths directly underneath the subsystem
depths = np.zeros(len(xs))
for i in range(len(xs)):
x = self.rA[0] + (xs[i]+self.span)*self.cos_th # take the global x position of the anchor and add the cosine of the node x (while setting it relative to 0,0)
y = self.rA[1] + (xs[i]+self.span)*self.sin_th # take the global y position of the anchor and add the sine of the node x (while setting it relative to 0,0)
depths[i], _ = self.sys.getDepthFromBathymetry(x, y) # calculate the depth at this individual point for one row of depths

# save all these variables to use later (overwrites any previous 'System' bathymetry arrays, and now getDepthFromBathymetry can use this data)
self.bathGrid_Xs = np.array(xs)
self.bathGrid_Ys = np.array([0])
self.bathGrid = np.array([depths])

self.seabedMod = 2


def initialize(self, daf_dict={}):
Expand Down Expand Up @@ -284,7 +343,7 @@ def setEndPosition(self, r, endB, sink=False):
raise LineError("setEndPosition: endB value has to be either 1 or 0")


def staticSolve(self, tol=0, profiles=0, maxIter = 500):
def staticSolve(self, tol=0, profiles=0, maxIter=500):
'''Solve internal equilibrium of the Subsystem and saves the forces
and stiffnesses at the ends in the global reference frame. All the
This method mimics the behavior of the Line.staticSolve method and
Expand All @@ -308,6 +367,9 @@ def staticSolve(self, tol=0, profiles=0, maxIter = 500):
else:
self.pointList[ 0].setPosition([ -self.span , 0, self.rA[2]])
self.pointList[-1].setPosition([ -self.span+LH, 0, self.rB[2]])

# update the bathymetry based on any new positions
#self.setSSBathymetry()

# get equilibrium
self.solveEquilibrium(tol=tol, maxIter = maxIter)
Expand Down

0 comments on commit f55b264

Please sign in to comment.