Claude Code Plugins

Community-maintained marketplace

Feedback

hydrodynamic-analysis

@vamseeachanta/workspace-hub
0
0

Hydrodynamic analysis using BEM, RAOs, added mass, damping, and wave loads for offshore structures

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name hydrodynamic-analysis
version 1.0.0
description Hydrodynamic analysis using BEM, RAOs, added mass, damping, and wave loads for offshore structures
author workspace-hub
category subject-matter-expert
tags hydrodynamics, bem, rao, added-mass, damping, wave-loads, wamit, aqwa, orcawave
platforms engineering

Hydrodynamic Analysis SME Skill

Comprehensive hydrodynamic analysis expertise for offshore floating structures including BEM theory, RAO calculations, added mass/damping, and integration with industry-standard software.

When to Use This Skill

Use hydrodynamic analysis knowledge when:

  • RAO calculation - Response Amplitude Operators for vessel motions
  • Added mass & damping - Frequency-dependent hydrodynamic coefficients
  • Wave loading - Diffraction, Froude-Krylov, radiation forces
  • BEM analysis - Boundary Element Method for potential flow
  • Software integration - WAMIT, AQWA, OrcaWave workflows
  • Frequency domain - Linear wave theory analysis
  • Time domain - Convolution for time-domain simulations

Core Knowledge Areas

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

# Radiation Problem:
# - Forced oscillation in calm water
# - Calculates added mass and damping
# - 6 DOFs → 6 radiation potentials

# Diffraction Problem:
# - Fixed body in waves
# - Calculates wave excitation forces
# - Different wave headings analyzed

Panel Mesh Quality:

mesh_requirements:
  panel_size:
    general: "< λ/6"  # Lambda = wavelength
    critical_areas: "< λ/10"  # Bow, stern, sharp edges

  aspect_ratio:
    maximum: 3.0
    preferred: 1.5

  panel_count:
    minimum: 2000  # Small vessels
    typical: 5000-10000  # FPSOs
    large: 20000+  # Complex geometries

  symmetry:
    use_if_possible: true  # Reduces computational cost by 50%
    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)
    """
    # Dynamic stiffness matrix (complex)
    K_dynamic = (
        -omega**2 * (mass_matrix + added_mass) +
        1j * omega * damping +
        stiffness
    )

    # Solve for RAO
    rao_complex = np.linalg.solve(K_dynamic, wave_excitation)

    return rao_complex

# Example: Calculate heave RAO
omega = 2 * np.pi / 10  # T = 10s
M = np.diag([150000, 150000, 150000, 1e7, 1e7, 5e6])  # Mass matrix
A = np.diag([15000, 15000, 50000, 1e6, 1e6, 5e5])     # Added mass
B = np.diag([50000, 50000, 100000, 5e5, 5e5, 2e5])    # Damping
K = np.diag([0, 0, 3000, 0, 0, 0])                    # Hydrostatic stiffness

# Wave excitation (heave dominant)
F_wave = np.array([100000, 0, 500000, 0, 1e6, 0]) + 0j

rao = calculate_rao_from_hydrodynamic_coefficients(omega, M, A, B, K, F_wave)

# Heave RAO amplitude
heave_rao_amplitude = np.abs(rao[2])
heave_rao_phase = np.angle(rao[2], deg=True)

print(f"Heave RAO: {heave_rao_amplitude:.3f} m/m at {heave_rao_phase:.1f}°")

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
    """
    # Find peak
    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  # Typical threshold
    }

# Example
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")

3. Added Mass and Damping

Frequency-Dependent Coefficients:

def interpolate_hydrodynamic_coefficients(
    omega_target: float,
    omega_data: np.ndarray,
    coefficient_data: np.ndarray
) -> np.ndarray:
    """
    Interpolate added mass or damping at target frequency.

    Args:
        omega_target: Target frequency (rad/s)
        omega_data: Frequency data from BEM
        coefficient_data: Coefficient matrix (n_freq x 6 x 6)

    Returns:
        Interpolated 6x6 coefficient matrix
    """
    from scipy.interpolate import interp1d

    # Interpolate each element
    coefficient_interp = np.zeros((6, 6))

    for i in range(6):
        for j in range(6):
            # Extract time series for this coefficient
            coef_series = coefficient_data[:, i, j]

            # Create interpolator
            interpolator = interp1d(
                omega_data,
                coef_series,
                kind='cubic',
                fill_value='extrapolate'
            )

            # Interpolate
            coefficient_interp[i, j] = interpolator(omega_target)

    return coefficient_interp

# Example usage
omega_data = np.array([0.1, 0.5, 1.0, 1.5, 2.0])  # rad/s
added_mass_data = np.random.rand(5, 6, 6) * 10000  # Sample data

# Interpolate at T = 8s (omega = 0.785 rad/s)
A_interp = interpolate_hydrodynamic_coefficients(
    omega_target=2*np.pi/8,
    omega_data=omega_data,
    coefficient_data=added_mass_data
)

print(f"Added mass at T=8s:")
print(A_interp)

Infinite Frequency Added Mass:

def calculate_infinite_frequency_added_mass(
    omega_data: np.ndarray,
    added_mass_data: np.ndarray
) -> np.ndarray:
    """
    Estimate infinite frequency added mass (A_inf).

    A_inf = lim(ω→∞) A(ω)

    Args:
        omega_data: Frequency array
        added_mass_data: Added mass array (n_freq x 6 x 6)

    Returns:
        6x6 infinite frequency added mass
    """
    # Use highest frequency values and extrapolate
    # Typically: fit A(ω) = A_inf + C/ω²

    A_inf = np.zeros((6, 6))

    for i in range(6):
        for j in range(6):
            # Take average of highest 3 frequencies
            A_inf[i, j] = np.mean(added_mass_data[-3:, i, j])

    return A_inf

4. Wave Forces

Froude-Krylov Force:

def calculate_froude_krylov_force(
    wave_amplitude: float,
    omega: float,
    waterplane_area: float,
    center_of_buoyancy_depth: float,
    rho: float = 1025
) -> float:
    """
    Calculate Froude-Krylov force (undisturbed wave pressure).

    F_FK = ρ g ζ_a A_wp e^(k z_b)

    Args:
        wave_amplitude: Wave amplitude (m)
        omega: Wave frequency (rad/s)
        waterplane_area: Waterplane area (m²)
        center_of_buoyancy_depth: Depth of center of buoyancy (m)
        rho: Water density (kg/m³)

    Returns:
        Froude-Krylov force amplitude (N)
    """
    g = 9.81

    # Wave number (deep water approximation)
    k = omega**2 / g

    # Froude-Krylov force
    F_FK = rho * g * wave_amplitude * waterplane_area * np.exp(k * center_of_buoyancy_depth)

    return F_FK

# Example
F_FK = calculate_froude_krylov_force(
    wave_amplitude=2.0,  # 2m amplitude (Hs = 4m)
    omega=2*np.pi/10,    # 10s period
    waterplane_area=15000,  # m²
    center_of_buoyancy_depth=-10  # 10m below waterline
)

print(f"Froude-Krylov force: {F_FK/1e6:.2f} MN")

Diffraction Force:

def calculate_diffraction_coefficient(
    diameter: float,
    wavelength: float
) -> float:
    """
    Estimate diffraction coefficient.

    Diffraction important when D/λ > 0.2 (MacCamy-Fuchs)

    Args:
        diameter: Characteristic diameter
        wavelength: Wave length

    Returns:
        Diffraction importance factor
    """
    D_over_lambda = diameter / wavelength

    if D_over_lambda < 0.1:
        regime = "Morison (small body)"
    elif D_over_lambda < 0.2:
        regime = "Transition"
    else:
        regime = "Diffraction (large body)"

    print(f"D/λ = {D_over_lambda:.3f} → {regime}")

    return D_over_lambda

# Example: FPSO hull
D = 58  # Beam = 58m
T = 10  # Wave period
wavelength = 9.81 * T**2 / (2 * np.pi)  # Deep water

diffraction_coef = calculate_diffraction_coefficient(D, wavelength)

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  # kg

    K = np.zeros((6, 6))

    # Heave stiffness: K_33 = ρ g A_wp
    K[2, 2] = rho * g * waterplane_area

    # Roll stiffness: K_44 = ρ g ∇ GM_T
    K[3, 3] = mass * g * metacentric_height_trans

    # Pitch stiffness: K_55 = ρ g ∇ GM_L
    K[4, 4] = mass * g * metacentric_height_long

    # Heave-pitch coupling
    K[2, 4] = -rho * g * waterplane_area * center_of_buoyancy[0]
    K[4, 2] = K[2, 4]

    # Heave-roll coupling
    K[2, 3] = -rho * g * waterplane_area * center_of_buoyancy[1]
    K[3, 2] = K[2, 3]

    return K

# Example: FPSO hydrostatic stiffness
K_hydro = calculate_hydrostatic_stiffness(
    waterplane_area=15000,  # m²
    center_of_buoyancy=np.array([160, 0, -10]),  # m
    metacentric_height_long=5.0,  # m
    metacentric_height_trans=3.0,  # m
    displacement=150000  # tonnes
)

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  # Peak frequency

    # Phillips constant
    alpha = 5.0 / 16.0 * Hs**2 * fp**4 / g**2

    # Spectral width parameter
    sigma = np.where(frequencies <= fp, 0.07, 0.09)

    # JONSWAP spectrum
    S_PM = alpha * g**2 * (2*np.pi)**(-4) * frequencies**(-5) * \
           np.exp(-5/4 * (frequencies / fp)**(-4))

    # Peak enhancement
    gamma_factor = gamma ** np.exp(-(frequencies - fp)**2 / (2 * sigma**2 * fp**2))

    S_JONSWAP = S_PM * gamma_factor

    return S_JONSWAP

# Example: Generate JONSWAP spectrum
freq = np.linspace(0.01, 0.5, 500)  # Hz
S = jonswap_spectrum(freq, Hs=8.5, Tp=12.0, gamma=3.3)

# Check Hs from spectrum
m0 = np.trapz(S, freq)  # Zero-order moment
Hs_calculated = 4 * np.sqrt(m0)

print(f"Input Hs: 8.5 m")
print(f"Calculated Hs from spectrum: {Hs_calculated:.2f} m")

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)
    """
    # Response spectrum
    S_response = rao_amplitude**2 * wave_spectrum

    # Calculate statistics
    m0 = np.trapz(S_response, frequencies)  # Variance
    m2 = np.trapz(S_response * frequencies**2, frequencies)

    # Response statistics
    stats = {
        'variance': m0,
        'std_dev': np.sqrt(m0),
        'significant_amplitude': 2 * np.sqrt(m0),  # ≈ H_1/3 for motions
        'zero_crossing_period': 2 * np.pi * np.sqrt(m0 / m2)
    }

    return S_response, stats

# Example
freq = np.linspace(0.01, 0.5, 500)
S_wave = jonswap_spectrum(freq, Hs=8.5, Tp=12.0)

# Sample heave RAO
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['significant_amplitude']:.2f} m")
print(f"Heave zero-crossing period: {stats_heave['zero_crossing_period']:.2f} s")

Practical Applications

Application 1: Complete RAO Analysis

def complete_rao_analysis(
    bem_results_file: str,
    wave_headings: np.ndarray = None,
    output_dir: str = 'reports/rao_analysis'
) -> dict:
    """
    Complete RAO analysis from BEM results.

    Args:
        bem_results_file: Path to BEM results (WAMIT .out or AQWA .lis)
        wave_headings: Wave heading array (degrees)
        output_dir: Output directory

    Returns:
        RAO results dictionary
    """
    import pandas as pd
    from pathlib import Path

    output_path = Path(output_dir)
    output_path.mkdir(parents=True, exist_ok=True)

    if wave_headings is None:
        wave_headings = np.arange(0, 360, 30)

    # Load BEM results (example format)
    # In reality, parse WAMIT .out or AQWA results
    frequencies = np.linspace(0.1, 2.0, 50)  # rad/s
    periods = 2 * np.pi / frequencies

    # Sample RAO data (6 DOFs x n_frequencies x n_headings)
    raos = {}
    dof_names = ['Surge', 'Sway', 'Heave', 'Roll', 'Pitch', 'Yaw']

    for heading in wave_headings:
        for i, dof in enumerate(dof_names):
            # Simplified RAO calculation
            # In practice, read from BEM output
            if heading == 0:  # Head seas
                if dof == 'Surge':
                    rao = 0.8 * np.ones_like(frequencies)
                elif dof == 'Heave':
                    rao = 1.2 / np.sqrt((1 - (frequencies/0.6)**2)**2 + (0.1*frequencies/0.6)**2)
                elif dof == 'Pitch':
                    rao = 0.05 * frequencies / (1 + (frequencies/0.6)**2)
                else:
                    rao = np.zeros_like(frequencies)
            else:
                # Simplified for other headings
                rao = np.random.rand(len(frequencies)) * 0.5

            raos[(heading, dof)] = rao

    # Export RAOs to CSV
    for dof in dof_names:
        df_rao = pd.DataFrame({
            'Period_s': periods,
            **{f'Heading_{h}deg': raos[(h, dof)] for h in wave_headings}
        })

        df_rao.to_csv(output_path / f'RAO_{dof}.csv', index=False)

    # Create polar plot
    import plotly.graph_objects as go

    fig = go.Figure()

    for dof in ['Surge', 'Heave', 'Pitch']:
        rao_at_peak = [raos[(h, dof)][25] for h in wave_headings]  # At T=10s

        fig.add_trace(go.Scatterpolar(
            r=rao_at_peak,
            theta=wave_headings,
            name=dof,
            mode='lines+markers'
        ))

    fig.update_layout(
        title='RAO Polar Plot (T = 10s)',
        polar=dict(radialaxis=dict(visible=True))
    )

    fig.write_html(output_path / 'RAO_polar.html')

    print(f"✓ RAO analysis complete")
    print(f"  Output: {output_dir}")

    return raos

# Usage
rao_results = complete_rao_analysis(
    bem_results_file='data/processed/wamit_results.out',
    wave_headings=np.array([0, 45, 90, 135, 180])
)

Application 2: Motion Prediction in Irregular Seas

def predict_vessel_motions_irregular_seas(
    Hs: float,
    Tp: float,
    heading: float,
    rao_data: dict,
    duration: float = 3600
) -> dict:
    """
    Predict vessel motions in irregular seas.

    Args:
        Hs: Significant wave height (m)
        Tp: Peak period (s)
        heading: Wave heading (degrees)
        rao_data: RAO dictionary from BEM analysis
        duration: Simulation duration (s)

    Returns:
        Motion statistics
    """
    # Frequency array
    freq_hz = np.linspace(0.01, 0.5, 500)
    omega = 2 * np.pi * freq_hz

    # Wave spectrum
    S_wave = jonswap_spectrum(freq_hz, Hs, Tp)

    # Calculate response spectra
    dof_names = ['Surge', 'Sway', 'Heave', 'Roll', 'Pitch', 'Yaw']
    motion_stats = {}

    for dof in dof_names:
        # Get RAO for this heading and DOF
        # Simplified: use constant RAO
        rao_amplitude = np.interp(
            omega,
            np.linspace(0.1, 2.0, 50),
            rao_data.get((heading, dof), np.zeros(50))
        )

        # Response spectrum
        S_response, stats = calculate_response_spectrum(S_wave, rao_amplitude, freq_hz)

        motion_stats[dof] = {
            'std_dev': stats['std_dev'],
            'significant_amplitude': stats['significant_amplitude'],
            'max_expected': stats['significant_amplitude'] * 1.86  # Rayleigh distribution
        }

    return motion_stats

# Example
motion_predictions = predict_vessel_motions_irregular_seas(
    Hs=8.5,
    Tp=12.0,
    heading=0,  # Head seas
    rao_data=rao_results,
    duration=10800  # 3 hours
)

print("Predicted Motion Statistics:")
for dof, stats in motion_predictions.items():
    print(f"{dof}:")
    print(f"  Significant amplitude: {stats['significant_amplitude']:.2f}")
    print(f"  Max expected (3hr): {stats['max_expected']:.2f}")

Application 3: Added Mass Convergence Check

def check_added_mass_convergence(
    panel_counts: list,
    added_mass_results: list
) -> dict:
    """
    Check convergence of added mass with panel count.

    Args:
        panel_counts: List of panel counts
        added_mass_results: List of 6x6 added mass matrices

    Returns:
        Convergence assessment
    """
    import plotly.graph_objects as go

    # Check heave added mass convergence
    A33_values = [A[2, 2] for A in added_mass_results]

    # Calculate relative change
    relative_changes = [
        abs(A33_values[i] - A33_values[i-1]) / A33_values[i-1] * 100
        for i in range(1, len(A33_values))
    ]

    # Plot convergence
    fig = go.Figure()

    fig.add_trace(go.Scatter(
        x=panel_counts,
        y=A33_values,
        name='A33 (Heave Added Mass)',
        mode='lines+markers'
    ))

    fig.update_layout(
        title='Added Mass Convergence Study',
        xaxis_title='Panel Count',
        yaxis_title='A33 (tonnes)',
        hovermode='x unified'
    ))

    fig.write_html('reports/added_mass_convergence.html')

    # Convergence criteria: < 1% change
    converged = relative_changes[-1] < 1.0 if relative_changes else False

    return {
        'converged': converged,
        'final_value': A33_values[-1],
        'relative_change_percent': relative_changes[-1] if relative_changes else 0,
        'recommended_panels': panel_counts[-1] if converged else 'Increase further'
    }

# Example
panel_counts = [1000, 2000, 5000, 10000, 15000]
A_results = [
    np.diag([15000, 15000, 45000, 1e6, 1e6, 5e5]),
    np.diag([15000, 15000, 48000, 1e6, 1e6, 5e5]),
    np.diag([15000, 15000, 49500, 1e6, 1e6, 5e5]),
    np.diag([15000, 15000, 50000, 1e6, 1e6, 5e5]),
    np.diag([15000, 15000, 50100, 1e6, 1e6, 5e5])
]

convergence = check_added_mass_convergence(panel_counts, A_results)
print(f"Converged: {convergence['converged']}")
print(f"Recommended panels: {convergence['recommended_panels']}")

Integration with Software

WAMIT Workflow

wamit_workflow:
  step_1_geometry:
    tool: "Rhino, GHS, or MultiSurf"
    output: "geometry.gdf"
    requirements:
      - "Waterline at z=0"
      - "Wetted surface only"
      - "Right-hand coordinate system"

  step_2_panel_mesh:
    tool: "WAMIT-PGEN or Multisurf"
    output: "vessel.gdf"
    quality_checks:
      - "Panel aspect ratio < 3:1"
      - "Panel size < λ/6"
      - "Use symmetry if applicable"

  step_3_run_wamit:
    input_files:
      - "vessel.frc"  # Force control
      - "vessel.pot"  # Potential control
      - "vessel.gdf"  # Geometry
    output_files:
      - "vessel.out"  # Main output
      - "vessel.1"    # Added mass/damping
      - "vessel.3"    # Wave excitation

  step_4_post_processing:
    tools:
      - "WAMIT-VIEW"
      - "Python (read .1, .3 files)"
      - "OrcaFlex (import RAOs)"

AQWA Workflow

aqwa_workflow:
  step_1_geometry:
    tool: "ANSYS DesignModeler or SpaceClaim"
    output: "geometry.scdoc"

  step_2_mesh:
    tool: "AQWA-GS (meshing)"
    output: "vessel.anl"
    settings:
      element_size: "Auto or manual"
      symmetry: "Use if applicable"

  step_3_analysis:
    solver: "AQWA-NAUT or AQWA-LINE"
    analysis_types:
      - "Hydrodynamic diffraction"
      - "Response calculation"

  step_4_results:
    output: "vessel.LIS"
    exports:
      - "RAOs → CSV"
      - "Added mass/damping → CSV"
      - "OrcaFlex YML"

Resources

  • WAMIT User Manual: https://www.wamit.com/
  • AQWA Documentation: ANSYS Help System
  • OrcaWave Manual: Orcina documentation
  • DNV-RP-C205: Environmental Conditions and Environmental Loads
  • DNV-RP-H103: Modelling and Analysis of Marine Operations
  • Lloyd's Register: Guidance on wave loading

Use this skill for all hydrodynamic analysis in DigitalModel!