Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic tensions on mooring lines #29

Merged
merged 18 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
45d2827
Add: Line dynamcis + new CompositeLine class
serag-abdulmotaleb Jan 3, 2024
14fc51d
New dymamic functions from Serag now working with Subsystem:
mattEhall Feb 7, 2024
374785f
Merge remote-tracking branch 'origin/dev' into dynamics
lucas-carmo May 20, 2024
8126b99
Merge branch 'dev' into dynamics
lucas-carmo May 22, 2024
663b66d
Moved dynamic tension and compositeLine functions to existing files
lucas-carmo May 22, 2024
c2b2454
Functions to get system dynamic matrices
lucas-carmo May 23, 2024
dbacf6d
Fix double counting of an effect + deal with matrices w/ null rows/cols
lucas-carmo May 24, 2024
4bddb15
Functions to lump matrices at line ends and body + code reorganization
lucas-carmo Jun 2, 2024
016b119
RAFT needs tension amplitude at nodes + removed nodes on the seabed
lucas-carmo Jun 26, 2024
21de5af
Merge branch 'dev' into dynamics
lucas-carmo Jul 2, 2024
c9ed16b
Bug fix to remove nodes on the sea bed
lucas-carmo Jul 11, 2024
b286b7f
Added nSegs in makeGeneric + initialize subsystem in system.initalize
lucas-carmo Jul 11, 2024
26e1c0a
Merge branch 'dev' into dynamics
lucas-carmo Jul 15, 2024
7ee3fe4
Cleaned parts of the code + removed *args and **kwargs
lucas-carmo Jul 16, 2024
acae461
Reformulation to compute dynamic matrices of lines separately
lucas-carmo Jul 17, 2024
e4e3386
Changed amplitudes to be complex and have a factor of two
lucas-carmo Aug 2, 2024
75e6d39
Default values for kbot and cbot
lucas-carmo Aug 2, 2024
27d8659
Example to show how to use the lumped mass approach
lucas-carmo Aug 2, 2024
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
Binary file added examples/RAO_fl.pkl
Binary file not shown.
129 changes: 129 additions & 0 deletions examples/dynamic.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Hasty example with a Subsystem and the new dynamic features

import numpy as np
import matplotlib.pyplot as plt
import moorpy as mp


# ===== Create a MoorPy system to test with =====

# ----- choose some system geometry parameters -----

depth = 200 # water depth [m]
angles = np.radians([60, 300]) # line headings list [rad]
rAnchor = 600 # anchor radius/spacing [m]
zFair = -21 # fairlead z elevation [m]
rFair = 20 # fairlead radius [m]
lineLength= 650 # line unstretched length [m]
typeName = "chain1" # identifier string for the line type


# ----- Now a Subsystem in a larger System with a floating body -----

# Create new MoorPy System and set its depth
ms = mp.System(depth=depth)

# add a line type
ms.setLineType(dnommm=120, material='chain', name=typeName, Cd=1.4, Ca=1, CdAx=0.4, CaAx=0) # this would be 120 mm chain

# Add a free, body at [0,0,0] to the system (including some properties to make it hydrostatically stiff)
ms.addBody(0, np.zeros(6), m=1e6, v=1e3, rM=100, AWP=1e3)

# For each line heading, set the anchor point, the fairlead point, and the line itself
for i, angle in enumerate(angles):

# create end Points for the line
ms.addPoint(1, [rAnchor*np.cos(angle), rAnchor*np.sin(angle), -depth]) # create anchor point (type 0, fixed)
ms.addPoint(1, [ rFair*np.cos(angle), rFair*np.sin(angle), zFair]) # create fairlead point (type 0, fixed)

# attach the fairlead Point to the Body (so it's fixed to the Body rather than the ground)
ms.bodyList[0].attachPoint(2*i+2, [rFair*np.cos(angle), rFair*np.sin(angle), zFair])

# add a Line going between the anchor and fairlead Points
ms.addLine(lineLength, typeName, pointA=2*i+1, pointB=2*i+2)

# ----- Now add a SubSystem line! -----
ss = mp.Subsystem(mooringSys=ms, depth=depth, spacing=rAnchor, rBfair=[10,0,-20])

# set up the line types
ms.setLineType(180, 'chain', name='one', Cd=1.4, Ca=1, CdAx=0.4, CaAx=0)
ms.setLineType( 50, 'chain', name='two', Cd=1.4, Ca=1, CdAx=0.4, CaAx=0)


# set up the lines and points and stuff
ls = [350, 300]
ts = ['one', 'two']
ss.makeGeneric(lengths=ls, types=ts)
ss.lineList[1].nNodes = 10 # reduce nodes on rope line for easier viewing
ss.initialize() # update things after changing node number

# add points that the subSystem will attach to...
ms.addPoint(1, [-rAnchor, 100, -depth]) # Point 5 - create anchor point (type 0, fixed)
ms.addPoint(1, [ -rFair , 0, zFair]) # Point 6 - create fairlead point (type 0, fixed)
ms.bodyList[0].attachPoint(6, [-rFair, 0, zFair]) # attach the fairlead Point to the Body

# string the Subsystem between the two points!
ms.lineList.append(ss) # add the SubSystem to the System's lineList
ss.number = 3
ms.pointList[4].attachLine(3, 0) # attach it to the respective points
ms.pointList[5].attachLine(3, 1) # attach it to the respective points


# ----- run the model to check that the Subsystem is working -----

ms.initialize() # make sure everything's connected

ms.solveEquilibrium() # equilibrate
fig, ax = ms.plot() # plot the system in original configuration

ms.bodyList[0].f6Ext = np.array([3e6, 0, 0, 0, 0, 0]) # apply an external force on the body
ms.solveEquilibrium() # equilibrate
fig, ax = ms.plot(ax=ax, color='red') # plot the system in displaced configuration (on the same plot, in red)

print(f"Body offset position is {ms.bodyList[0].r6}")



# ===== Now try out Serag's dynamic tension functions with it =====

# dynamic solve of some lines
kbot = 3E+06
cbot = 3E+05

moorpy_freqs = []
moorpy_fairten_psds = []
moorpy_ten_stds = []

omegas = np.array([ 0.02, 0.04, 0.06, 0.08 ])
S_zeta = np.array([ 10.0 , 10.0 , 10.0 , 10.0 ])
RAO_fl = np.array([[ 2.0 , 0.0 , 0.0 ],
[ 2.0 , 0.0 , 0.0 ],
[ 2.0 , 0.0 , 0.0 ],
[ 2.0 , 0.0 , 0.0 ]])

T_nodes_psd_fd,T_nodes_std_fd,s,r_static,r_dynamic,r_total,X = ms.lineList[1].dynamicSolve(
omegas,S_zeta,RAO_A=0,RAO_B=RAO_fl,depth=-ms.depth,
kbot=kbot,cbot=cbot, seabed_tol=1e-4, tol=0.01, iters=100, w=0.8)

fig2,ax2 = plt.subplots(1,1)

plt.plot(T_nodes_std_fd,'-r',label = 'MoorPy (FD)')
plt.xlabel('Node number (anchor to fairlead)')
plt.ylabel('Fairlead tension std. dev [$N$]')

# now try a Subsystem
T_nodes_psd_fd,T_nodes_std_fd,s,r_static,r_dynamic,r_total,X = ms.lineList[2].dynamicSolve(
omegas,S_zeta,RAO_A=0,RAO_B=RAO_fl,depth=-ms.depth,
kbot=kbot,cbot=cbot, seabed_tol=1e-4, tol=0.01, iters=100, w=0.8)

fig2,ax2 = plt.subplots(1,1)
plt.plot(T_nodes_std_fd,'-r',label = 'MoorPy (FD)')
plt.xlabel('Node number (anchor to fairlead)')
plt.ylabel('Fairlead tension std. dev [$N$]')


# Some mode shape plots
ms.lineList[1].getModes(plot_modes=7, amp_factor=1000) # with a Line
ms.lineList[2].getModes(plot_modes=7, amp_factor=1000) # with a Subsystem

plt.show()
74 changes: 74 additions & 0 deletions examples/lumped_mass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import moorpy as mp
import os
import numpy as np
from moorpy.helpers import lines2subsystem, lines2ss
try:
import pickle5 as pickle
except:
import pickle
import matplotlib.pyplot as plt

def JONSWAP(ws, Hs, Tp, Gamma=None):
'''JONSWAP function copied from RAFT
'''
# If peak shape parameter gamma is not specified, use the recommendation
# from IEC 61400-3 as a function of Hs and Tp. For PM spectrum, use 1.
if not Gamma:
TpOvrSqrtHs = Tp/np.sqrt(Hs)
if TpOvrSqrtHs <= 3.6:
Gamma = 5.0
elif TpOvrSqrtHs >= 5.0:
Gamma = 1.0
else:
Gamma = np.exp( 5.75 - 1.15*TpOvrSqrtHs )

# handle both scalar and array inputs
if isinstance(ws, (list, tuple, np.ndarray)):
ws = np.array(ws)
else:
ws = np.array([ws])

# initialize output array
S = np.zeros(len(ws))


# the calculations
f = 0.5/np.pi * ws # wave frequencies in Hz
fpOvrf4 = pow((Tp*f), -4.0) # a common term, (fp/f)^4 = (Tp*f)^(-4)
C = 1.0 - ( 0.287*np.log(Gamma) ) # normalizing factor
Sigma = 0.07*(f <= 1.0/Tp) + 0.09*(f > 1.0/Tp) # scaling factor

Alpha = np.exp( -0.5*((f*Tp - 1.0)/Sigma)**2 )

return 0.5/np.pi *C* 0.3125*Hs*Hs*fpOvrf4/f *np.exp( -1.25*fpOvrf4 )* Gamma**Alpha



current_dir = os.path.dirname(os.path.abspath(__file__))
ms = mp.System(os.path.join(current_dir, 'volturn_chain.dat'))
ms.initialize()
ms.solveEquilibrium()
# ms = lines2ss(ms) # For cases with multisegment lines, need to convert each of them to a subsystem

# Updates the dynamic matrices of all the lines in the system.
# This function can only properly update the inertia, added mass, and stiffness matrices of each line.
# Though it updates the damping matrix, this is done considering unitary amplitude motions of the nodes and
# no fluid kinematics, so it is not correct.
ms.updateSystemDynamicMatrices()
M, A, B, K_dyn = ms.getCoupledDynamicMatrices() # Get the dynamic matrices of the system
K_qsA = ms.getCoupledStiffnessA(lines_only=True) # We can also compute the stiffness matrix without the lumped mass model. K_dyn should be similar to K_qsa


# Get the dynamic tension along the line
line = ms.lineList[0] # Get the line object
RAO_data = pickle.load(open(os.path.join(current_dir, 'RAO_fl.pkl'), 'rb')) # Read the nFreq x 3 RAO matrix (nFreq x 4 complex numpy array, first column are the frequencies in rad/s)
RAO_fl = RAO_data[:, 1:] # Motion RAOs of the fairlead
w = RAO_data[:, 0] # Frequencies of the RAO data
Sw = JONSWAP(ws = w, Hs = 6, Tp = 8) # Arbitrary wave spectrum
T_nodes_amp, T_nodes_psd,T_nodes_std,s,r_static,r_dynamic,r_total,X = line.dynamicSolve(w, Sw, RAO_A=0,RAO_B=RAO_fl, depth=np.abs(line.rA[2]))

fig, ax = plt.subplots(1, 1)
ax.plot(w, T_nodes_psd[:,-1], '-k')
ax.set_xlabel('Frequency (rad/s)')
ax.set_ylabel('PSD fairlead tension (N^2.s/rad)')
plt.show()
Loading
Loading