| name | hydrodynamic-analysis-1-boundary-element-method-bem |
| description | Sub-skill of hydrodynamic-analysis: 1. Boundary Element Method (BEM) (+1). |
| version | 1.0.0 |
| category | engineering |
| type | reference |
| scripts_exempt | true |
1. Boundary Element Method (BEM) (+1)
1. Boundary Element Method (BEM)
Potential Flow Theory:
Governing Equation: ∇²φ = 0 (Laplace equation)
Where:
- φ = velocity potential
- Pressure: p = -ρ ∂φ/∂t - ρgz (Bernoulli)
- Velocity: v = ∇φ
BEM Principles:
def bem_panel_method_concept():
"""
Conceptual explanation of BEM panel method.
Key Steps:
1. Discretize wetted surface into panels
2. Apply Green's function (source/dipole distribution)
3. Satisfy boundary conditions on each panel
4. Solve linear system for unknown potentials
5. Calculate forces from pressure integration
"""
pass
Panel Mesh Quality:
mesh_requirements:
panel_size:
general: "< λ/6"
critical_areas: "< λ/10"
aspect_ratio:
maximum: 3.0
preferred: 1.5
panel_count:
minimum: 2000
typical: 5000-10000
large: 20000+
symmetry:
use_if_possible: true
check: "Ensure port-starboard symmetry"
2. Response Amplitude Operators (RAOs)
RAO Definition:
RAO(ω) = Response Amplitude / Wave Amplitude
Units:
- Translation (surge, sway, heave): m/m
- Rotation (roll, pitch, yaw): rad/m or deg/m
RAO Calculation:
import numpy as np
def calculate_rao_from_hydrodynamic_coefficients(
omega: float,
mass_matrix: np.ndarray,
added_mass: np.ndarray,
damping: np.ndarray,
stiffness: np.ndarray,
wave_excitation: np.ndarray
) -> np.ndarray:
"""
Calculate RAO at frequency omega.
Equation of motion (frequency domain):
[-ω²(M + A(ω)) + iω·B(ω) + K]·RAO = F_wave
Args:
omega: Wave frequency (rad/s)
mass_matrix: 6x6 mass matrix
added_mass: 6x6 added mass matrix at omega
damping: 6x6 damping matrix at omega
stiffness: 6x6 hydrostatic stiffness
wave_excitation: 6x1 complex wave excitation force
Returns:
6x1 complex RAO (amplitude and phase)
"""
K_dynamic = (
-omega**2 * (mass_matrix + added_mass) +
1j * omega * damping +
stiffness
)
rao_complex = np.linalg.solve(K_dynamic, wave_excitation)
return rao_complex
omega = 2 * np.pi / 10
M = np.diag([150000, 150000, 150000, 1e7, 1e7, 5e6])
A = np.diag([15000, 15000, 50000, 1e6, 1e6, 5e5])
B = np.diag([50000, 50000, 100000, 5e5, 5e5, 2e5])
K = np.diag([0, 0, 3000, , , ])
F_wave = np.array([, , , , , ]) +
rao = calculate_rao_from_hydrodynamic_coefficients(omega, M, A, B, K, F_wave)
heave_rao_amplitude = np.(rao[])
heave_rao_phase = np.angle(rao[], deg=)
()
RAO Peak Period:
def find_rao_peak_period(
frequencies: np.ndarray,
rao_amplitude: np.ndarray
) -> dict:
"""
Find peak RAO period and resonance characteristics.
Args:
frequencies: Frequency array (rad/s)
rao_amplitude: RAO amplitude array
Returns:
Peak information
"""
peak_idx = np.argmax(rao_amplitude)
peak_omega = frequencies[peak_idx]
peak_period = 2 * np.pi / peak_omega
peak_rao = rao_amplitude[peak_idx]
return {
'peak_frequency_rad_s': peak_omega,
'peak_period_s': peak_period,
'peak_rao': peak_rao,
'resonance_detected': peak_rao > 2.0
}
frequencies = np.linspace(0.1, 2.0, 100)
rao_amplitudes = 1.5 / np.sqrt((1 - (frequencies/0.5)**2)**2 + (0.1*frequencies/0.5)**2)
peak_info = find_rao_peak_period(frequencies, rao_amplitudes)
print(f"Natural period: {peak_info['peak_period_s']:.2f} s")
print(f"Peak RAO: {peak_info['peak_rao']:.2f} m/m")