| name | hydrodynamic-analysis-5-hydrostatic-stiffness |
| description | Sub-skill of hydrodynamic-analysis: 5. Hydrostatic Stiffness (+1). |
| version | 1.0.0 |
| category | engineering |
| type | reference |
| scripts_exempt | true |
5. Hydrostatic Stiffness (+1)
5. Hydrostatic Stiffness
Stiffness Matrix:
def calculate_hydrostatic_stiffness(
waterplane_area: float,
center_of_buoyancy: np.ndarray,
metacentric_height_long: float,
metacentric_height_trans: float,
displacement: float,
rho: float = 1025
) -> np.ndarray:
"""
Calculate 6x6 hydrostatic stiffness matrix.
Args:
waterplane_area: Waterplane area (m²)
center_of_buoyancy: [x, y, z] position (m)
metacentric_height_long: Longitudinal GM (m)
metacentric_height_trans: Transverse GM (m)
displacement: Vessel displacement (tonnes)
rho: Water density (kg/m³)
Returns:
6x6 hydrostatic stiffness matrix
"""
g = 9.81
mass = displacement * 1000
K = np.zeros((6, 6))
K[2, 2] = rho * g * waterplane_area
K[3, 3] = mass * g * metacentric_height_trans
K[4, 4] = mass * g * metacentric_height_long
K[2, 4] = -rho * g * waterplane_area * center_of_buoyancy[0]
K[4, 2] = K[2, 4]
K[2, 3] = -rho * g * waterplane_area * center_of_buoyancy[1]
K[3, 2] = K[2, 3]
return K
K_hydro = calculate_hydrostatic_stiffness(
waterplane_area=15000,
center_of_buoyancy=np.array([160, 0, -10]),
metacentric_height_long=5.0,
metacentric_height_trans=3.0,
displacement=150000
)
print("Hydrostatic Stiffness Matrix:")
print(K_hydro)
6. Wave Spectra and Irregular Seas
JONSWAP Spectrum:
def jonswap_spectrum(
frequencies: np.ndarray,
Hs: float,
Tp: float,
gamma: float = 3.3
) -> np.ndarray:
"""
Calculate JONSWAP wave spectrum.
S(f) = α g² (2π)^-4 f^-5 exp[-5/4(f/fp)^-4] γ^exp[-(f-fp)²/(2σ²fp²)]
Args:
frequencies: Frequency array (Hz)
Hs: Significant wave height (m)
Tp: Peak period (s)
gamma: Peak enhancement factor (default 3.3)
Returns:
Spectral density S(f) (m²/Hz)
"""
g = 9.81
fp = 1 / Tp
alpha = 5.0 / 16.0 * Hs**2 * fp**4 / g**2
sigma = np.where(frequencies <= fp, 0.07, 0.09)
S_PM = alpha * g**2 * (2*np.pi)**(-4) * frequencies**(-5) * \
np.exp(-5/4 * (frequencies / fp)**(-4))
gamma_factor = gamma ** np.exp(-(frequencies - fp)**2 / (2 * sigma**2 * fp**2))
S_JONSWAP = S_PM * gamma_factor
return S_JONSWAP
freq = np.linspace(0.01, 0.5, 500)
S = jonswap_spectrum(freq, Hs=8.5, Tp=12.0, gamma=3.3)
m0 = np.trapz(S, freq)
Hs_calculated = * np.sqrt(m0)
()
()
Response Spectrum:
def calculate_response_spectrum(
wave_spectrum: np.ndarray,
rao_amplitude: np.ndarray,
frequencies: np.ndarray
) -> tuple[np.ndarray, dict]:
"""
Calculate response spectrum from wave spectrum and RAO.
S_response(ω) = |RAO(ω)|² * S_wave(ω)
Args:
wave_spectrum: Wave spectral density
rao_amplitude: RAO amplitude (m/m)
frequencies: Frequency array
Returns:
(response_spectrum, statistics)
"""
S_response = rao_amplitude**2 * wave_spectrum
m0 = np.trapz(S_response, frequencies)
m2 = np.trapz(S_response * frequencies**2, frequencies)
stats = {
'variance': m0,
'std_dev': np.sqrt(m0),
'significant_amplitude': 2 * np.sqrt(m0),
'zero_crossing_period': 2 * np.pi * np.sqrt(m0 / m2)
}
return S_response, stats
freq = np.linspace(0.01, 0.5, 500)
S_wave = jonswap_spectrum(freq, Hs=8.5, Tp=12.0)
rao_heave = 1.2 / np.sqrt((1 - (2*np.pi*freq / 0.6)**2)**2 + (0.1 * 2*np.pi*freq / 0.6)**2)
S_heave, stats_heave = calculate_response_spectrum(S_wave, rao_heave, freq)
print(f"Significant heave amplitude: {stats_heave[]:f} m")
()