|
1 | 1 | import math |
2 | | -from typing import Optional |
3 | 2 | import copy |
4 | | -from warnings import warn |
5 | 3 | import numpy as np |
6 | | -from scipy.integrate import solve_ivp |
7 | 4 | import matplotlib.pyplot as plt |
8 | 5 | import mmgdynamics.crossflow as cf |
9 | | -from typing import Any, List |
| 6 | + |
| 7 | +from typing import Optional, Any, List, Dict |
| 8 | +from scipy.integrate import solve_ivp |
| 9 | +from warnings import warn |
10 | 10 |
|
11 | 11 | """ |
12 | 12 | Set up the System of ODEs for vessel maneuvering prediction after |
@@ -446,6 +446,134 @@ def C_6c(psi: float, p: dict) -> float: |
446 | 446 |
|
447 | 447 | return val1 - val2 - val3 |
448 | 448 |
|
| 449 | +# In here all the important hydrodynamic derivatives are calculated via empirical |
| 450 | +# formulas from Suras and Sakir Bal (2019) |
| 451 | +def calibrate(v: Dict[str,float], rho: float) -> Dict[str,float]: |
| 452 | + """Calculate relevant hydrodynamic derivatives based on a minimal |
| 453 | + dict and a given water density |
| 454 | +
|
| 455 | + Sources: |
| 456 | + Suras and Sakir Bal (2019) |
| 457 | +
|
| 458 | + Args: |
| 459 | + v (dict): Minimal dict of vessel parameters |
| 460 | + rho (float): water density |
| 461 | +
|
| 462 | + Raises: |
| 463 | + KeyError: If your dict is incomplete, calculations will be aborted |
| 464 | +
|
| 465 | + Returns: |
| 466 | + dict: Dict with all relevant information to be used as input in the step() function |
| 467 | + """ |
| 468 | + |
| 469 | + # Length, Breadth, draft, Block coef, mass, Rudder area |
| 470 | + mininfo = ["B","Lpp","d","C_b","m","A_R"] |
| 471 | + |
| 472 | + if not all (k in v for k in mininfo): |
| 473 | + raise KeyError(f"Mandatory keys not found. Need at least ['B','Lpp','d','C_b','A_R']") |
| 474 | + |
| 475 | + # Unpack initial dict |
| 476 | + L, B, d, Cb, m = v["Lpp"], v["B"], v["d"], v["C_b"], v["m"] |
| 477 | + |
| 478 | + # X-Coordinate of the center of gravity (m) |
| 479 | + if "x_G" not in v: |
| 480 | + v["x_G"] = float(0) |
| 481 | + |
| 482 | + # X-Coordinate of the propeller (assumed as -0.5*Lpp) |
| 483 | + v["x_P"] = -0.5*L |
| 484 | + |
| 485 | + # Add current water density to dict |
| 486 | + v["rho"]= rho |
| 487 | + |
| 488 | + # Masses and Moment of Intertia |
| 489 | + nondim_M = 0.5 * v["rho"] * L**2 * d |
| 490 | + nondim_N = 0.5 * v["rho"] * L**4 * d |
| 491 | + v["m"] = m * v["rho"] # Displacement * water density |
| 492 | + v["I_zG"] = v["m"] * (0.25*L)**2 |
| 493 | + v["m_x_dash"] = 0.05*v["m"] / nondim_M |
| 494 | + v["m_y_dash"] = (0.882-0.54*Cb*(1-1.6*d/B)-0.156*(1-0.673*Cb)*L/B+\ |
| 495 | + 0.826*((d*L)/(B**2))*(1-0.678*d/B)-0.638*Cb*((d*L)/(B**2))*(1-0.669*d/B))*v["m"] / nondim_M |
| 496 | + v["J_z_dash"] = ((0.01*(33-76.85*Cb*(1-0.784*Cb)+3.43*L/B*(1-0.63*Cb)))**2)*v["m"] / nondim_N |
| 497 | + |
| 498 | + # Hydrodynamic derivatives |
| 499 | + # Surge |
| 500 | + v["X_vv_dash"] = 1.15*(Cb/(L/B)) - 0.18 # Yoshimura and Masumoto (2012) |
| 501 | + v["X_vvvv_dash"]= -6.68*(Cb/(L/B)) + 1.1 # Yoshimura and Masumoto (2012) |
| 502 | + v["X_rr_dash"] = (-0.0027+0.0076*Cb*d/B)*L/d # Lee et al. (1998) |
| 503 | + v["X_vr_dash"] = v["m_y_dash"] - 1.91*(Cb/(L/B)) + 0.08 # Yoshimura and Masumoto (2012) |
| 504 | + |
| 505 | + # Sway |
| 506 | + v["Y_v_dash"] = -(0.5*math.pi*(2*d/L)+1.4*(Cb/(L/B))) # Yoshimura and Masumoto (2012) |
| 507 | + v["Y_vvv_dash"] = -0.185*L/B + 0.48 # Yoshimura and Masumoto (2012) |
| 508 | + v["Y_r_dash"] = v["m_x_dash"] + 0.5*Cb*B/L # Yoshimura and Masumoto (2012) |
| 509 | + v["Y_rrr_dash"] = -0.051 |
| 510 | + v["Y_vrr_dash"] = -(0.26*(1-Cb)*L/B + 0.11) |
| 511 | + v["Y_vvr_dash"] = -0.75 # TODO: Change this |
| 512 | + |
| 513 | + # Yaw |
| 514 | + v["N_v_dash"] = -2*d/L # Yoshimura and Masumoto (2012) |
| 515 | + v["N_vvv_dash"] = -(-0.69*Cb+0.66)# Yoshimura and Masumoto (2012) |
| 516 | + v["N_r_dash"] = -0.54*(2*d/L) + (2*d/L)**2 # Yoshimura and Masumoto (2012) |
| 517 | + v["N_rrr_dash"] = ((0.25*Cb)/(L/B))-0.056 # Yoshimura and Masumoto (2012) |
| 518 | + v["N_vrr_dash"] = -0.075*(1-Cb)*L/B-0.098 # Yoshimura and Masumoto (2012) |
| 519 | + v["N_vvr_dash"] = ((1.55*Cb)/(L/B))-0.76 # Yoshimura and Masumoto (2012) |
| 520 | + |
| 521 | + # Wake coefficient |
| 522 | + if "w_P0" not in v: |
| 523 | + v["w_P0"] = 0.5*Cb - 0.05 |
| 524 | + |
| 525 | + # Thrust deduction factor |
| 526 | + if "t_P" not in v: |
| 527 | + v["t_P"] = -0.27 |
| 528 | + |
| 529 | + # Rudder force incease factor |
| 530 | + v["a_H"] = 0.627*Cb-0.153 # Quadvlieg (2013) |
| 531 | + |
| 532 | + # Longituinal acting point of longitudinal force |
| 533 | + v["x_H_dash"] = -0.45 # Aoki et. al. (2006) |
| 534 | + |
| 535 | + # Steering resistance deduction factor |
| 536 | + v["t_R"] = 0.39 # Yoshimura and Masumoto (2012) |
| 537 | + |
| 538 | + # Espilon [Lee and Shin (1998)] |
| 539 | + v["epsilon"] = -2.3281+8.697*Cb-3.78*((2*d)/L)+1.19*Cb**2+292*((2*d)/L)**2-81.51*Cb*((2*d)/L) # Lee and Shin (1998) |
| 540 | + #v["epsilon"] = -156.5*(Cb*B/L)**2 + 41.6*(Cb*B/L) - 1.76 # Kijima (1990) |
| 541 | + #v["epsilon"] = 2.26*1.82*(1-v["w_P0"]) # Yoshimura and Masumoto (2012) |
| 542 | + |
| 543 | + # Kappa |
| 544 | + v["kappa"] = 0.55-0.8*Cb*B/L |
| 545 | + |
| 546 | + # Correction of flow straightening factor to yaw-rate |
| 547 | + v["l_R"] = -0.9 # Yoshimura and Masumoto (2012) |
| 548 | + |
| 549 | + # Flow straightening coefficient |
| 550 | + v["gamma_R"] = 2.06*Cb*B/L+0.14 |
| 551 | + |
| 552 | + # Additional assumptions |
| 553 | + v["J_int"] = 0.4 |
| 554 | + v["k_0"] = 0.4 |
| 555 | + v["J_slo"] = -0.5 |
| 556 | + |
| 557 | + # Rudder aspect ratio |
| 558 | + if "f_alpha" not in v: |
| 559 | + while True: |
| 560 | + asp = input("No rudder aspect ratio found. Please enter manually: ") |
| 561 | + try: |
| 562 | + asp = float(asp) |
| 563 | + break |
| 564 | + except ValueError as e: |
| 565 | + print("Wrong input type. Only float or int allowed. Err:",e) |
| 566 | + |
| 567 | + asp = float(asp) |
| 568 | + falpha =(6.13*asp)/(asp+2.25) |
| 569 | + v["f_alpha"] = falpha |
| 570 | + |
| 571 | + print(f"Aspect ration saved. Rudder lift coef calculated to be {falpha}") |
| 572 | + |
| 573 | + # Frictional resistance coefficent [ARBITRARY, no calculations so far] |
| 574 | + v["R_0_dash"] = 0.025 |
| 575 | + |
| 576 | + return v |
449 | 577 |
|
450 | 578 | def turning_maneuver(ivs: np.ndarray, vessel: dict, |
451 | 579 | time: int, dir: str = "starboard", |
|
0 commit comments