| name | ship-dynamics-6dof-3-natural-frequencies-and-periods |
| description | Sub-skill of ship-dynamics-6dof: 3. Natural Frequencies and Periods (+1). |
| version | 1.0.0 |
| category | engineering |
| type | reference |
| scripts_exempt | true |
3. Natural Frequencies and Periods (+1)
3. Natural Frequencies and Periods
Uncoupled Natural Frequency:
def calculate_natural_frequency_uncoupled(
mass: float,
stiffness: float
) -> dict:
"""
Calculate natural frequency for single DOF.
ω_n = sqrt(K / M)
T_n = 2π / ω_n
Args:
mass: Mass or moment of inertia
stiffness: Stiffness or restoring coefficient
Returns:
Natural frequency and period
"""
omega_n = np.sqrt(stiffness / mass)
period_n = 2 * np.pi / omega_n
frequency_hz = omega_n / (2 * np.pi)
return {
'omega_rad_s': omega_n,
'frequency_hz': frequency_hz,
'period_s': period_n
}
m = 150000 * 1000
A33 = 50000 * 1000
K33 = 1025 * 9.81 * 15000
heave_freq = calculate_natural_frequency_uncoupled(
mass=m + A33,
stiffness=K33
)
print(f"Heave natural period: {heave_freq['period_s']:.2f} seconds")
Coupled Natural Frequencies:
def calculate_coupled_natural_frequencies(
mass_matrix: np.ndarray,
stiffness_matrix: np.ndarray
) -> dict:
"""
Calculate coupled natural frequencies from eigenvalue problem.
det([K] - ω²[M]) = 0
Args:
mass_matrix: 6x6 mass matrix (including added mass)
stiffness_matrix: 6x6 stiffness matrix
Returns:
Natural frequencies for all modes
"""
eigenvalues, eigenvectors = np.linalg.eig(
np.linalg.solve(mass_matrix, stiffness_matrix)
)
omega_n = np.sqrt(eigenvalues.real)
periods = 2 * np.pi / omega_n
sort_idx = np.argsort(periods)
periods = periods[sort_idx]
omega_n = omega_n[sort_idx]
eigenvectors = eigenvectors[:, sort_idx]
dof_names = ['Surge', 'Sway', 'Heave', 'Roll', 'Pitch', 'Yaw']
return {
'periods_s': periods,
'frequencies_rad_s': omega_n,
'frequencies_hz': omega_n / (2*np.pi),
'mode_shapes': eigenvectors,
'dof_names': dof_names
}
M_total = M_fpso + np.diag([15000e3, 15000e3, 50000e3, 1e9, 1e9, 5e8])
K = np.diag([0, 0, 150e6, 5e9, 8e9, 0])
natural_freq = calculate_coupled_natural_frequencies(M_total, K)
print("Natural Periods:")
i, (dof, T) ((natural_freq[], natural_freq[])):
()
4. Hydrostatic Restoring
Complete Stiffness Matrix:
def calculate_complete_hydrostatic_stiffness(
rho: float,
g: float,
displacement: float,
waterplane_area: float,
waterplane_inertia: dict,
center_of_buoyancy: np.ndarray,
center_of_gravity: np.ndarray,
metacentric_height: dict
) -> np.ndarray:
"""
Calculate complete 6x6 hydrostatic stiffness matrix.
Args:
rho: Water density (kg/m³)
g: Gravity (m/s²)
displacement: Volume displacement (m³)
waterplane_area: Waterplane area (m²)
waterplane_inertia: {'Ixx': Ixx, 'Iyy': Iyy} second moments (m⁴)
center_of_buoyancy: [xb, yb, zb] (m)
center_of_gravity: [xg, yg, zg] (m)
metacentric_height: {'GMT': transverse, 'GML': longitudinal} (m)
Returns:
6x6 hydrostatic stiffness matrix
"""
xb, yb, zb = center_of_buoyancy
xg, yg, zg = center_of_gravity
C = np.zeros((6, 6))
C[2, 2] = rho * g * waterplane_area
C[3, 3] = rho * g * displacement * metacentric_height['GMT']
C[4, 4] = rho * g * displacement * metacentric_height['GML']
C[2, 4] = -rho * g * waterplane_area * xb
C[4, 2] = C[2, 4]
C[2, 3] = -rho * g * waterplane_area * yb
C[3, 2] = C[2, 3]
C[, ] = -rho * g * displacement * (zg - zb)
C[, ] = C[, ]
C
C_hydro = calculate_complete_hydrostatic_stiffness(
rho=,
g=,
displacement=,
waterplane_area=,
waterplane_inertia={: , : },
center_of_buoyancy=np.array([, , -]),
center_of_gravity=np.array([, , ]),
metacentric_height={: , : }
)
()
(np.diag(C_hydro))