Source code for berhoel.holtrop.test.test_holtrop

"""Testing Holtrop."""

import math

import numpy as np
import pytest
import matplotlib.pyplot as plt
from astropy import units as u  # type: ignore
from astropy.units import imperial as ui  # type: ignore
from astropy.units.quantity import Quantity  # type: ignore

from berhoel.holtrop import Holtrop, ship, hydro

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


u.imperial.enable()


[docs] class TestHoltrop: """example from [4], page 275"""
[docs] @pytest.fixture() def probe(self): return Holtrop( L=Quantity(50.00, "m"), B=Quantity(12.00, "m"), T_F=Quantity(3.10, "m"), T_A=Quantity(3.30, "m"), h_b=Quantity(0.0, "m"), Nab=Quantity(900.0, "m3"), S_app=[Quantity(50.0, "m2")], S=Quantity(584.9, "m2"), k_2=[3.0], # 1 + k_2 C_Stern=0.0, A_BT=Quantity(0.0, "m2"), i_E=Quantity(25.0, "deg"), C_M=0.78, lcb=-4.5, # L aft of 1/2 L A_T=Quantity(10.0, "m2"), C_WP=0.80, # Related coefficients C_P=0.60096, C_B=0.46875, )
[docs] def test_C_P(self, probe): assert ( probe.Nab / (probe.L * probe.B * probe.T * probe.C_M) ).value == pytest.approx(0.60096, 1e-5)
[docs] def test_C_B(self, probe): assert (probe.Nab / (probe.L * probe.B * probe.T)).value == pytest.approx( 0.46875, 1e-5, )
[docs] def test_L_R(self, probe): assert probe.L_R.value == pytest.approx(14.1728, 1e-5) assert probe.L_R.unit == u.m
[docs] def test_S_calc(self, probe): assert probe.S.value == pytest.approx(584.9, 1e-5) assert probe.S.unit == u.m**2
[docs] def test_k_1(self, probe): assert probe.k_1 == pytest.approx(1.297, 1e-5) # 1 + k_1
[docs] def test_C_A(self, probe): assert pytest.approx(0.00064, 1e-1) == probe.C_A
[docs] def test_c_17(self, probe): assert probe.c_17 == pytest.approx(1.4133, 1e-5)
[docs] def test_m_3(self, probe): assert probe.m_3 == pytest.approx(-2.0298, 1e-5)
[docs] def test_rest(self, probe): assert probe.c_2 == pytest.approx(1.0, 1e-5)
[docs] def test_c_5(self, probe): assert probe.c_5 == pytest.approx(0.7329, 1e-5)
[docs] def test_lambda(self, probe): assert probe.λ == pytest.approx(0.7440, 1e-4)
[docs] def test_C_15(self, probe): assert probe.c_15 == pytest.approx(-1.69385, 1e-5)
[docs] def test_i_E(self, probe): assert probe.calc_i_E.value == pytest.approx(26.3978, 1e-5) ref = { 25: [0.3279, -3.31, 475, 21, 25, 662], 27: [0.182, -3.0883, 512, 24, 16, 715], 29: [0.0409, -2.8962, 539, 28, 2, 756], 31: [-0.0834, -2.7274, 564, 31, 0, 807], 33: [-0.1876, -2.578, 590, 35, 0, 864], 35: [-0.273, -2.4453, 618, 39, 0, 925], } f_string = "{:3.0f} {:7.4f} {:7.4f} {:7.4f} {:5.0f} {:5.0f} {:5.0f} {:5.0f}" for speed in range(25, 36, 2): print(" V F_n m_4 m_3 R_W R_app R_TR R") V = (speed * ui.knot).si print( f_string.format( speed, hydro.F_n(V, probe.L), ref[speed][0], ref[speed][1], ref[speed][2], ref[speed][3], ref[speed][4], ref[speed][5], ), ) print( f_string.format( speed, hydro.F_n(V, probe.L), probe.m_4(V) * math.cos(probe.λ * math.pow(hydro.F_n(V, probe.L), -2.0)), probe.m_3 * math.pow(hydro.F_n(V, probe.L), probe.d), probe.R_W(V).to(u.N).value / 1000.0, probe.R_app(V).to(u.N).value / 1000.0, probe.R_TR(V).to(u.N).value / 1000.0, probe.R(V).to(u.N).value / 1000.0, ), )
[docs] def plot(): example = ship.Ship( # Main particulars L=Quantity(50.00, "m"), B=Quantity(12.00, "m"), T_F=Quantity(3.10, "m"), T_A=Quantity(3.30, "m"), h_b=Quantity(0.0, "m"), Nab=Quantity(900.0, "m3"), S_app=[Quantity(50.0, "m2")], k_2=[3.0], # 1 + k_2 C_Stern=0.0, A_BT=Quantity(0.1, "m2"), i_E=Quantity(25.0, "deg"), C_M=0.78, lcb=-4.5, # %L aft of 1/2 L A_T=Quantity(10.0, "m2"), C_WP=0.80, # Related coefficients C_P=0.60096, C_B=0.46875, ) data = np.array( [ (speed.value, example.R(speed).to(u.N).value / 1000.0) for speed in (np.arange(0.1, 35.0, 0.5) * u.m / u.s) ], ) plt.plot(data[:, 0], data[:, 1]) plt.show()
[docs] def prau(): S_app = 0.01 * u.m**2 k_2 = 0.01 # 1 + k_2 Prau = ship.Ship( # Main particulars L=Quantity(30.564, "m"), B=Quantity(12.65, "m"), T=Quantity(4.50, "m"), h_b=Quantity(0.0, "m"), Nab=Quantity(741.0, "m3"), App=[(S_app, k_2)], C_Stern=0.0, A_BT=Quantity(0.01, "m2"), i_E=Quantity(25.0, "deg"), C_M=0.744, lcb=50 - 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, ) data = np.array( [ (V, Prau.R(V * u.m / u.s, Prau).to(u.N).value / 1000.0) for V in np.arange(2.0, 7.0, 0.1) ], ) plt.plot(data[:, 0], data[:, 1]) plt.show()
[docs] def prop(): _ = ship.Ship( # Main particulars L=50.00 * u.m, B=12.00 * u.m, T_F=3.10 * u.m, T_A=3.30 * u.m, h_b=0.0 * u.m, Nab=900.0 * u.m**3, S_app=[50.0 * u.m**2], k_2=[3.0], # 1 + k_2 C_Stern=0.0, A_BT=0.1 * u.m**2, i_E=25.0 * u.deg, C_M=0.78, lcb=-4.5, # %L aft of 1/2 L A_T=10.0 * u.m**2, C_WP=0.80, # Related coefficients C_P=0.60096, C_B=0.46875, # propeller related coefficents: t=0.054, w=0.039, eta_R=0.980, D=3.231 * u.m, # c_P_D == P/D c_P_D=1.136, # A_E_0 = A_E / A_0 A_E_0=0.763, eta_0=0.705, ) # (30 knots)
[docs] def Poehls_Soeding(): probe = ship.Ship( # Main particulars L=214.00 * u.m, B=28.50 * u.m, T_F=10.50 * u.m, T_A=10.50 * u.m, h_b=8.25 * u.m, # Nab = 900. * u.m**3, S_app=[89.88 * u.m**2], k_2=[1.3], # 1 + k_2 C_Stern=0.0, A_BT=0.1 * u.m**2, # i_E = 25. , 'deg'), # C_M = .78, lcb=1.5, # %L aft of 1/2 L A_T=10.0 * u.m**2, C_WP=0.875, # # Related coefficients # C_P = .60096, C_B=0.813, C_M=0.995, # # propeller related coefficents: # t = .054, # w = .039, # eta_R = .980, # D = 3.231, 'u.m'), # # c_P_D == P/D # c_P_D = 1.136, # # A_E_0 = A_E / A_0 # A_E_0 = .763, # eta_0 = .705 ) from numpy import arange f_string = "{:3.0f} {:7.4f} {:7.4f} {:7.2f} {:7.2f} {:5.0f} {:5.0f} {:5.0f} {:5.0f}" for speed in arange(5.716, 10, 1): print(" V V[kn] F_n m_4 m_3 R_W R_app R_TR R") V = speed * u.m / u.s print( f_string.format( speed, V.to(ui.knot).value, hydro.F_n(V, probe.L), probe.m_4(V, probe) * math.cos(probe.λ * math.pow(hydro.F_n(V, probe.L), -2.0)), probe.m_3 * math.pow(hydro.F_n(V, probe.L), probe.d()), (probe.R_W(V) / 1000.0).value, (probe.R_app(V) / 1000.0).value, (probe.R_TR(V) / 1000.0).value, (probe.R(V) / 1000.0).value, ), )