Skip to content

Commit

Permalink
Minor catenary bug fixes and bath plot tweak:
Browse files Browse the repository at this point in the history
- Catenary: adjustment to avoid error with never-ending recursive loop
  when solving profile of U shaped lines (by removing Tol from seabed contact).
- Catenary: fixed irregularity on node outputs of U shaped profiles. Now the
  nodes are evently distributed as expected.
- System plotting: editing optional bathymetry plotting arguments to now have
  "args_bath", a dictionary of optional arguments that go straight to the 3d
  surface plotting function to allow greater control. cmap_bath and alpha are
  now removed as separate options.
  • Loading branch information
mattEhall committed Sep 19, 2023
1 parent 0317e46 commit 2270ade
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 11 deletions.
22 changes: 14 additions & 8 deletions moorpy/Catenary.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def catenary(XF, ZF, L, EA, W, CB=0, alpha=0, HF0=0, VF0=0, Tol=0.000001, nNodes
flipFlag = False

# reverse line in the solver if end A is above end B
if ZF < 0 and hA > Tol: # and if end A isn't on the seabed
if ZF < 0 and hA > 0: # and if end A isn't on the seabed
#CB = -max(0, -CB) - ZF + XF*np.tan(np.radians(alpha))
hA, hB = hB, hA
ZF = -ZF
Expand Down Expand Up @@ -648,18 +648,19 @@ def step_func_U(X, args, Y, info, Ytarget, err, tols, iter, maxIter):
X, Y, infoU = dsolve2(eval_func_U, [X1_0], step_func=step_func_U, ytol=0.25*Tol, stepfac=1, maxIter=20, a_max=1.2, display=0)
X1 = X[0]
X2 = XF-X1
nNodes1 = int(L1/L*nNodes + 0.5) # set number of nodes in the first line proportionally to its length, rounded.
nNodes1 = int(L1/L*(nNodes-1) + 0.5) + 1 # set number of nodes in the first line by trying to keep original segment length

# call one more time to get final values
(fAH1, fAV1, fBH1, fBV1, info1) = catenary(X1, Z1, L1, EA, W, CB=Z1, alpha=0, Tol=0.5*Tol, MaxIter=MaxIter, plots=plots, nNodes=nNodes1)
(fAH2, fAV2, fBH2, fBV2, info2) = catenary(X2, Z2, L2, EA, W, CB=0, alpha=0, Tol=0.5*Tol, MaxIter=MaxIter, plots=plots, nNodes=nNodes-nNodes1)
(fAH2, fAV2, fBH2, fBV2, info2) = catenary(X2, Z2, L2, EA, W, CB=0, alpha=0, Tol=0.5*Tol, MaxIter=MaxIter, plots=plots, nNodes=nNodes-nNodes1+1)

if plots > 0 or (info1['error'] and info2['error']):

s = np.hstack([ info1["s" ] , info2["s" ]+L1 ])
Xs = np.hstack([ info1["X" ] , info2["X" ]+X1 ])
Zs = np.hstack([ info1["Z" ] , info2["Z" ]+Z1 ])
Te = np.hstack([ info1["Te"] , info2["Te"] ])
# concatenate nodal values (removing duplicate at the end nodes where they connect)
s = np.hstack([ info1["s" ] , info2["s" ][1:]+L1 ])
Xs = np.hstack([ info1["X" ] , info2["X" ][1:]+X1 ])
Zs = np.hstack([ info1["Z" ] , info2["Z" ][1:]+Z1 ])
Te = np.hstack([ info1["Te"] , info2["Te"][1:] ])

# re-reverse line distributed data back to normal if applicable
'''
Expand Down Expand Up @@ -1314,10 +1315,15 @@ def step_func_cat(X, args, Y, info, Ytarget, err, tols, iter, maxIter):
print('')
printMat(info1['stiffnessB'])
"""
(fAH1, fAV1, fBH1, fBV1, info1) = catenary(147.0, -25.8, 160.0, 8540000000.0, 6523.0,
'''
# sloped case
(fAH1, fAV1, fBH1, fBV1, info1) = catenary(147.0, -25.8, 160.0, 854e7, 6523.0,
CB=0.0, alpha=-27.73, HF0=725968.57, VF0=667765.24,
Tol=0.0001, MaxIter=100, plots=1)
'''
# simple U case (fAH1, fAV1, fBH1, fBV1, info1) = catenary(200, 30, 260.0, 8e9, 6500, CB=-50, nNodes=21, plots=1)
plt.plot(info1['X'], info1['Z'] )
plt.plot(info1['s'], info1['X'] )
plt.axis('equal')


Expand Down
7 changes: 5 additions & 2 deletions moorpy/line.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ def getTimestep(self, Time):



def getLineCoords(self, Time, n=0): # formerly UpdateLine
def getLineCoords(self, Time, n=0, segmentTensions=False):
'''Gets the updated line coordinates for drawing and plotting purposes.'''

if n==0: n = self.nNodes
Expand Down Expand Up @@ -377,7 +377,10 @@ def getLineCoords(self, Time, n=0): # formerly UpdateLine

# handle whether or not there is tension data
try: # use average to go from segment tension to node tensions <<< can skip this once MD is updated to output node tensions
Te = 0.5*(np.append(self.Te[ts,0], self.Te[ts,:]) +np.append(self.Te[ts,:], self.Te[ts,-1]))
if segmentTensions:
Te = self.Te[ts,:] # return tensions of segments rather than averaging to get tensions of nodes
else:
Te = 0.5*(np.append(self.Te[ts,0], self.Te[ts,:]) +np.append(self.Te[ts,:], self.Te[ts,-1]))
except: # otherwise return zeros to avoid an error (might want a warning in some cases?)
Te = np.zeros(self.nNodes)

Expand Down
5 changes: 4 additions & 1 deletion moorpy/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -3065,8 +3065,11 @@ def plot(self, ax=None, bounds='default', rbound=0, color=None, **kwargs):
draw_clumps = kwargs.get('draw_clumps' , False ) # toggle to draw clump weights and float of the mooring system
draw_anchors = kwargs.get('draw_anchors' , False ) # toggle to draw the anchors of the mooring system or not
bathymetry = kwargs.get("bathymetry" , False ) # toggle (and string) to include bathymetry or not. Can do full map based on text file, or simple squares
args_bath = kwargs.get("args_bath" , {} ) # dictionary of optional plot_surface arguments
'''
cmap_bath = kwargs.get("cmap" , 'ocean' ) # matplotlib colormap specification
alpha = kwargs.get("opacity" , 1.0 ) # the transparency of the bathymetry plot_surface
'''
rang = kwargs.get('rang' , 'hold' ) # colorbar range: if range not used, set it as a placeholder, it will get adjusted later
cbar_bath = kwargs.get('cbar_bath' , False ) # toggle to include a colorbar for a plot or not
colortension = kwargs.get("colortension" , False ) # toggle to draw the mooring lines in colors based on node tensions
Expand Down Expand Up @@ -3249,7 +3252,7 @@ def plot(self, ax=None, bounds='default', rbound=0, color=None, **kwargs):
# Second method: plot a 3D surface, plot_surface
X, Y = np.meshgrid(bathGrid_Xs, bathGrid_Ys)

bath = ax.plot_surface(X,Y,-bathGrid, cmap=cmap_bath, vmin=rang[0], vmax=rang[1], alpha=alpha)
bath = ax.plot_surface(X,Y,-bathGrid, vmin=rang[0], vmax=rang[1], **args_bath)

if cbar_bath_size!=1.0: # make sure the colorbar is turned on just in case it isn't when the other colorbar inputs are used
cbar_bath=True
Expand Down

0 comments on commit 2270ade

Please sign in to comment.