Source code for berhoel.holtrop.test.test_ship

"""Testing module holtrop.ship."""

from typing import NamedTuple

import pytest
from astropy import units as u  # type: ignore
from astropy.units.quantity import Quantity  # type: ignore

from berhoel.holtrop import hydro
from berhoel.holtrop.ship import (
    Ship as Ship_,
    C_WP_Schneekluth_U,
    C_WP_Schneekluth_V,
    BlockCoefficientMethod,
    C_WP_Schneekluth_medium,
    C_WP_Schneekluth_V_alt_1,
    C_WP_Schneekluth_V_alt_2,
    WaterlineCoefficientMethod,
    WettedSurfaceEstimationMethod,
)

__date__ = "2024/08/01 21:31:56 hoel"
__author__ = "Berthold Höllmann"
__copyright__ = "Copyright © 2019 by Berthold Höllmann"
__credits__ = ["Berthold Höllmann"]
__maintainer__ = "Berthold Höllmann"
__email__ = "berhoel@gmail.com"

u.imperial.enable()


[docs] class Ship(Ship_):
[docs] def R(self, speed: Quantity) -> Quantity: return 0 * u.m
[docs] class TestPrau:
[docs] @pytest.fixture(scope="function") def probe(self): return Ship( L=30.564 * u.m, B=12.65 * u.m, T=4.50 * u.m, h_b=0.0 * u.m, Nab=741.0 * u.m**3, S_app=[], # m^2 k_2=[], # 1 + k_2 # App = [(S_app, k_2)], C_Stern=0.0, A_BT=0.01 * u.m**2, i_E=25.0 * u.deg, C_M=0.744, lcb=50.0 - 49.881, # %L aft of 1/2 L A_T=0.01 * u.m**2, A_WP=271.597 * u.m**2, #: Waterplane area L_WP=30.564 * u.m, #: Waterline length B_WP=12.430 * u.m, #: Waterlien beam # Related coefficients C_P=0.583, C_B=0.434, )
[docs] def test_L(self, probe): assert 30.564 * u.m == probe.L
[docs] def test_T(self, probe): assert Quantity(4.5, "m") == probe.T
[docs] def test_B(self, probe): assert Quantity(12.65, "m") == probe.B
[docs] def test_C_B(self, probe): assert probe.C_B == 0.434
[docs] def test_C_M(self, probe): assert probe.C_M == 0.744
[docs] def test_C_WP(self, probe): assert probe.C_WP == pytest.approx(0.7148972868663915)
[docs] def test_A_BT(self, probe): assert Quantity(0.01, "m2") == probe.A_BT
[docs] def test_S(self, probe): assert probe.S.value == pytest.approx(391.93508) assert probe.S.unit == "m2"
[docs] def test_S_calc_Schenzle(self, probe): probe.set_S_Method(WettedSurfaceEstimationMethod.Schenzle) assert probe.S.value == pytest.approx(416.80066) assert probe.S.unit == "m2"
[docs] def test_App(self, probe): assert probe.App == []
[docs] class TestGenerated:
[docs] @pytest.fixture(scope="function") def probe(self): return Ship( L=30.564 * u.m, B=12.65 * u.m, T=4.50 * u.m, h_b=0.0 * u.m, Nab=741.0 * u.m**3, S_app=[], # m^2 k_2=[], # 1 + k_2 # App = [(S_app, k_2)], C_Stern=0.0, A_BT=0.01 * u.m**2, i_E=25.0 * u.deg, C_M=0.744, lcb=50.0 - 49.881, # %L aft of 1/2 L A_T=0.01 * u.m**2, # A_WP=271.597 * u.m**2, #: Waterplane area L_WP=30.564 * u.m, #: Waterline length B_WP=12.430 * u.m, #: Waterlien beam # Related coefficients C_P=0.583, C_B=0.434, )
[docs] def test_C_WP_calc_schneekluth_U(self, probe): probe.set_C_WP_Method(WaterlineCoefficientMethod.Schneekluth_U) assert probe.C_WP == pytest.approx(0.68086, 1e-5)
[docs] def test_C_WP_calc_schneekluth_medium(self, probe): probe.set_C_WP_Method(WaterlineCoefficientMethod.Schneekluth_medium) assert probe.C_WP == pytest.approx(0.62267, 1e-5)
[docs] def test_C_WP_calc_schneekluth_V(self, probe): probe.set_C_WP_Method(WaterlineCoefficientMethod.Schneekluth_V) assert probe.C_WP == pytest.approx(0.63379, 1e-5)
[docs] def test_C_WP_calc_schneekluth_V_alt_1(self, probe): probe.set_C_WP_Method(WaterlineCoefficientMethod.Schneekluth_V_alt_1) assert probe.C_WP == pytest.approx(0.69788, 1e-5)
[docs] def test_C_WP_calc_schneekluth_V_alt_2(self, probe): probe.set_C_WP_Method(WaterlineCoefficientMethod.Schneekluth_V_alt_2) assert probe.C_WP == pytest.approx(0.66877, 1e-5)
[docs] class TestGenerated_C_B:
[docs] @pytest.fixture(scope="function") def probe(self): return Ship( L=60.0 * u.m, B=10.0 * u.m, T=4.50 * u.m, h_b=0.0 * u.m, Nab=741.0 * u.m**3, S_app=[], # m^2 k_2=[], # 1 + k_2 # App = [(S_app, k_2)], C_Stern=0.0, A_BT=0.01 * u.m**2, i_E=25.0 * u.deg, C_M=0.744, lcb=50.0 - 49.881, # %L aft of 1/2 L A_T=0.01 * u.m**2, # A_WP=271.597 * u.m**2, #: Waterplane area L_WP=30.564 * u.m, #: Waterline length B_WP=12.430 * u.m, #: Waterlien beam # Related coefficients C_P=0.583, )
[docs] class C_B_References(NamedTuple): F_n: float C_B_Ayre_1_06: float C_B_Ayre_1_08: float C_B_Ayre_1_09: float C_B_Schneekluth_1: float C_B_Schneekluth_2: float
[docs] @pytest.fixture( params=( C_B_References(0.14, 0.82, 0.85, 0.85, 0.85, 0.85), C_B_References(0.17, 0.77, 0.79, 0.80, 0.82, 0.75), C_B_References(0.20, 0.72, 0.74, 0.75, 0.70, 0.67), C_B_References(0.25, 0.64, 0.66, 0.67, 0.56, 0.58), C_B_References(0.30, 0.55, 0.57, 0.58, 0.48, 0.51), C_B_References(0.32, 0.52, 0.54, 0.55, 0.48, 0.51), ) ) def C_B_reference(self, probe, request): param = request.param v = param.F_n * pow(probe.L * hydro.g, 0.5) return param, v
[docs] def test_C_B(self, probe, C_B_reference: tuple[C_B_References, Quantity]): probe.set_default_speed(C_B_reference[1]) assert probe.C_B == pytest.approx(C_B_reference[0].C_B_Ayre_1_06, 1e-2)
[docs] def test_C_B_calc_Ayre_1_06( self, probe, C_B_reference: tuple[C_B_References, Quantity] ): probe.set_default_speed(C_B_reference[1]) probe.set_C_B_method(BlockCoefficientMethod.Ayre_1_06) assert probe.C_B == pytest.approx(C_B_reference[0].C_B_Ayre_1_06, 1e-2)
[docs] def test_C_B_calc_Ayre_1_08( self, probe, C_B_reference: tuple[C_B_References, Quantity] ): probe.set_default_speed(C_B_reference[1]) probe.set_C_B_method(BlockCoefficientMethod.Ayre_1_08) assert probe.C_B == pytest.approx(C_B_reference[0].C_B_Ayre_1_08, 1e-2)
[docs] def test_C_B_calc_Ayre_1_09( self, probe, C_B_reference: tuple[C_B_References, Quantity] ): probe.set_default_speed(C_B_reference[1]) probe.set_C_B_method(BlockCoefficientMethod.Ayre_1_09) assert probe.C_B == pytest.approx(C_B_reference[0].C_B_Ayre_1_09, 1e-2)
[docs] def test_C_B_calc_Schneekluth_1( self, probe, C_B_reference: tuple[C_B_References, Quantity] ): probe.set_default_speed(C_B_reference[1]) probe.set_C_B_method(BlockCoefficientMethod.Schneekluth_1) _C_B = probe.C_B assert _C_B == pytest.approx(C_B_reference[0].C_B_Schneekluth_1, 1e-2)
[docs] def test_C_B_calc_Schneekluth_2( self, probe, C_B_reference: tuple[C_B_References, Quantity] ): probe.set_default_speed(C_B_reference[1]) probe.set_C_B_method(BlockCoefficientMethod.Schneekluth_2) _C_B = probe.C_B assert _C_B == pytest.approx(C_B_reference[0].C_B_Schneekluth_2, 1e-2)
[docs] class C_WP_References(NamedTuple): C_B: float C_M: float C_WP_U: float C_WP_medium: float C_WP_V: float C_WP_V_alt_1: float C_WP_V_alt_2: float
# Schneekluth, Entwerfen, S. 145
[docs] @pytest.fixture( params=( C_WP_References(0.50, 0.78, 0.667, 0.730, 0.743, 0.682, 0.711), C_WP_References(0.50, 0.94, 0.667, 0.637, 0.656, 0.682, 0.677), C_WP_References(0.60, 0.98, 0.733, 0.706, 0.721, 0.749, 0.737), C_WP_References(0.70, 0.99, 0.800, 0.785, 0.793, 0.812, 0.802), C_WP_References(0.80, 0.99, 0.866, 0.866, 0.868, 0.869, 0.870), ) ) def C_WP_reference(request): return request.param
[docs] @pytest.mark.skip( reason="reference values in literature do not match calculated values" ) def test_calc_C_WP_Schneekluth_U(C_WP_reference): C_P = C_WP_reference.C_B / C_WP_reference.C_M assert C_WP_Schneekluth_U(C_P) == pytest.approx(C_WP_reference.C_WP_U, 1e-2)
[docs] @pytest.mark.skip( reason="reference values in literature do not match calculated values" ) def test_calc_C_WP_Schneekluth_medium(C_WP_reference): assert C_WP_Schneekluth_medium(C_WP_reference.C_B) == pytest.approx( C_WP_reference.C_WP_medium, 1e-2 )
[docs] @pytest.mark.skip( reason="reference values in literature do not match calculated values" ) def test_calc_C_WP_Schneekluth_V(C_WP_reference): assert C_WP_Schneekluth_V(C_WP_reference.C_B) == pytest.approx( C_WP_reference.C_WP_V, 1e-2 )
[docs] @pytest.mark.skip( reason="reference values in literature do not match calculated values" ) def test_calc_C_WP_Schneekluth_V_alt_1(C_WP_reference): C_P = C_WP_reference.C_B / C_WP_reference.C_M assert C_WP_Schneekluth_V_alt_1(C_P) == pytest.approx( C_WP_reference.C_WP_V_alt_1, 1e-3 )
[docs] def test_calc_C_WP_Schneekluth_V_alt_2(C_WP_reference): assert C_WP_Schneekluth_V_alt_2( C_WP_reference.C_B, C_WP_reference.C_M ) == pytest.approx(C_WP_reference.C_WP_V_alt_2, 1e-3)