Tanks Module
The Tanks module provides functionality for modeling fluid tanks in vessels, including volume calculations, fill level management, and free surface effects.
Tank Class
Bases:
objectRepresents a tank (reservoir, cuve) with fluid management capabilities.
A tank is defined by a 3D geometry (STL or VTK file), a fluid density, and a fill level. The class calculates fluid mass, center of gravity, and free surface effects based on the current fill state.
The VTK polydata representing the tank mesh.
- Type:
vtk.vtkPolyData
Path to the original geometry file.
- Type:
Density of the fluid in kg/m³.
- Type:
Optional name for the tank.
- Type:
Examples
>>> tank = Tank("fuel_tank.stl", fluid_density=850.0) >>> tank.set_fill_level(50, unit='percent') >>> print(f"Fluid mass: {tank.fluid_mass:.2f} kg") >>> print(f"Free surface moment: {tank.free_surface_moment_t:.4f} m⁴")
Initialize a Tank by loading geometry from an STL or VTK file.
- Parameters:
file_path (str) – Path to the STL or VTK file defining the tank geometry.
fluid_density (float, optional) – Density of the fluid in kg/m³. Default is 1025.0 (seawater).
fill_level (float, optional) – Initial fill level as a fraction (0.0 to 1.0). Default is 0.0.
name (str, optional) – Name for the tank. If None, uses the filename stem.
- Raises:
FileNotFoundError – If the geometry file does not exist.
ValueError – If the file format is not supported or geometry is empty.
Create a Tank from parallelepiped (box) dimensions.
This is an alternative constructor for when no STL/VTK file is available. Creates a box-shaped tank from min/max coordinates.
- Parameters:
x_min (float) – Minimum X coordinate (longitudinal, aft) in meters.
x_max (float) – Maximum X coordinate (longitudinal, forward) in meters.
y_min (float) – Minimum Y coordinate (transverse, port) in meters.
y_max (float) – Maximum Y coordinate (transverse, starboard) in meters.
z_min (float) – Minimum Z coordinate (vertical, bottom) in meters.
z_max (float) – Maximum Z coordinate (vertical, top) in meters.
fluid_density (float, optional) – Density of the fluid in kg/m³. Default is 1025.0 (seawater).
fill_level (float, optional) – Initial fill level as a fraction (0.0 to 1.0). Default is 0.0.
name (str, optional) – Name for the tank. Default is “BoxTank”.
- Returns:
A new Tank instance with box geometry.
- Return type:
- Raises:
ValueError – If min values are greater than or equal to max values.
Examples
>>> tank = Tank.from_box( ... x_min=10.0, x_max=15.0, ... y_min=-2.0, y_max=2.0, ... z_min=0.0, z_max=3.0, ... fluid_density=850.0, ... name="FuelTank1" ... ) >>> tank.set_fill_level(50, unit='percent') >>> print(f"Volume: {tank.total_volume:.2f} m³") # 5×4×3 = 60 m³
Create a Tank as the intersection of a box with a hull geometry.
This allows creating tanks that follow the shape of the hull, for example a bottom tank that follows the hull’s curved bottom.
- Parameters:
hull (Hull) – The hull geometry to intersect with. Can be a Hull object or any object with a polydata attribute.
x_min (float) – Minimum X coordinate (longitudinal) in meters.
x_max (float) – Maximum X coordinate (longitudinal) in meters.
y_min (float) – Minimum Y coordinate (transverse) in meters.
y_max (float) – Maximum Y coordinate (transverse) in meters.
z_min (float) – Minimum Z coordinate (vertical) in meters.
z_max (float) – Maximum Z coordinate (vertical) in meters.
fluid_density (float, optional) – Density of the fluid in kg/m³. Default is 1025.0 (seawater).
fill_level (float, optional) – Initial fill level as a fraction (0.0 to 1.0). Default is 0.0.
name (str, optional) – Name for the tank. Default is “HullTank”.
- Returns:
A new Tank instance with geometry that is the intersection of the box and hull.
- Return type:
- Raises:
ValueError – If dimensions are invalid or intersection results in empty geometry.
Examples
>>> from pynavaltoolbox import Hull >>> from pynavaltoolbox.tanks import Tank >>> hull = Hull("ship.stl") >>> # Create a double-bottom tank that follows the hull shape >>> tank = Tank.from_box_hull_intersection( ... hull, ... x_min=20.0, x_max=40.0, # 20m section of hull ... y_min=-10.0, y_max=10.0, # Full beam ... z_min=0.0, z_max=2.0, # 2m from keel ... fluid_density=1025.0, ... name="DoubleBottom1" ... )
Total capacity of the tank in m³.
Current fill level as a fraction (0.0 to 1.0).
Current fill level as a percentage (0 to 100).
Current filled volume in m³.
Mass of fluid in the tank in kg.
Center of gravity of the fluid [x, y, z] in meters.
Returns zeros if tank is empty.
Transverse free surface moment (I_t) in m⁴.
This is the second moment of area of the free surface about its centroidal axis parallel to the longitudinal axis. Returns 0 if tank is empty or full (no free surface).
Longitudinal free surface moment (I_l) in m⁴.
This is the second moment of area of the free surface about its centroidal axis parallel to the transverse axis. Returns 0 if tank is empty or full (no free surface).
Transverse free surface correction in m⁴.
This is I_t × (ρ_fluid / ρ_water), used in the formula: GG’ = FSC / Δ (where Δ is vessel displacement mass).
Longitudinal free surface correction in m⁴.
This is I_l × (ρ_fluid / ρ_water), used in the formula: GG’ = FSC / Δ (where Δ is vessel displacement mass).
Set the fill level of the tank.
- Parameters:
- Raises:
ValueError – If the unit is not recognized or value is out of bounds.
Return the bounding box of the tank geometry.
- Returns:
(xmin, xmax, ymin, ymax, zmin, zmax)
- Return type:
Get the current state of the tank.
- Returns:
Dataclass containing all tank state information.
- Return type:
String representation of the tank.
TankState Dataclass
Stores the current state of a tank.
Fill level as a percentage (0-100).
- Type:
Volume of fluid in the tank in m³.
- Type:
Mass of fluid in the tank in kg.
- Type:
Center of gravity of the fluid [x, y, z] in meters.
- Type:
np.ndarray
Transverse free surface moment in m⁴. This is the second moment of area (I_t) of the free surface.
- Type:
Longitudinal free surface moment in m⁴. This is the second moment of area (I_l) of the free surface.
- Type:
Transverse free surface correction in m⁴. This is I_t × (ρ_fluid / ρ_water) for use in GG’ = FSC / Δ.
- Type:
Longitudinal free surface correction in m⁴. This is I_l × (ρ_fluid / ρ_water) for use in GG’ = FSC / Δ.
- Type:
Creating Tanks
There are three ways to create a Tank:
From STL/VTK File
from pynavaltoolbox.tanks import Tank
# Load tank geometry from a file
tank = Tank(
"tank_geometry.stl",
fluid_density=850.0, # Fuel oil density
fill_level=0.5, # 50% filled
name="FuelTank1"
)
From Box Dimensions
from pynavaltoolbox.tanks import Tank
# Create a rectangular tank from dimensions
tank = Tank.from_box(
x_min=10.0, x_max=20.0, # 10m long
y_min=-3.0, y_max=3.0, # 6m wide
z_min=0.0, z_max=4.0, # 4m tall
fluid_density=1025.0, # Seawater ballast
fill_level=0.75, # 75% filled
name="BallastTank1"
)
From Hull Intersection
Create tanks that follow the shape of the hull (e.g., double-bottom tanks):
from pynavaltoolbox import Hull
from pynavaltoolbox.tanks import Tank
hull = Hull("ship.stl")
# Create a double-bottom tank that follows the hull shape
tank = Tank.from_box_hull_intersection(
hull,
x_min=20.0, x_max=40.0, # Section of hull
y_min=-10.0, y_max=10.0, # Full beam
z_min=0.0, z_max=1.5, # 1.5m from keel
fluid_density=1025.0,
name="DoubleFond1"
)
Managing Fill Level
# Set fill level in different units
tank.set_fill_level(75, unit='percent') # 75%
tank.set_fill_level(0.5, unit='fraction') # 50%
tank.set_fill_level(100.0, unit='m³') # 100 cubic meters
# Get current fill state
print(f"Fill: {tank.fill_percent:.1f}%")
print(f"Volume: {tank.fill_volume:.2f} m³")
print(f"Mass: {tank.fluid_mass:.0f} kg")
Free Surface Effects
Tanks with free surfaces cause a virtual rise in the center of gravity, reducing stability. The module calculates free surface moments (FSM) and free surface corrections (FSC):
# Get free surface properties
I_t = tank.free_surface_moment_t # Transverse moment (m⁴)
I_l = tank.free_surface_moment_l # Longitudinal moment (m⁴)
fsc_t = tank.free_surface_correction_t # GG' correction (m⁴)
fsc_l = tank.free_surface_correction_l # GG' correction (m⁴)
# Get complete tank state
state = tank.get_state()
print(f"CoG: {state.center_of_gravity}")
print(f"FSC transverse: {state.free_surface_correction_t:.2f} m⁴")
Integration with Vessel
Tanks can be added to a Vessel for combined calculations:
from pynavaltoolbox import Vessel, Hull
from pynavaltoolbox.tanks import Tank
hull = Hull("ship.stl")
# Create tanks
fuel = Tank.from_box(
x_min=30.0, x_max=40.0,
y_min=-5.0, y_max=5.0,
z_min=2.0, z_max=6.0,
fluid_density=850.0,
name="Fuel"
)
fuel.set_fill_level(60, unit='percent')
ballast = Tank.from_box(
x_min=10.0, x_max=30.0,
y_min=-8.0, y_max=8.0,
z_min=0.0, z_max=2.0,
fluid_density=1025.0,
name="Ballast"
)
ballast.set_fill_level(50, unit='percent')
# Create vessel with tanks
vessel = Vessel(hull, tanks=[fuel, ballast])
# Get combined tank properties
total_mass = vessel.get_total_tanks_mass()
combined_cog = vessel.get_tanks_center_of_gravity()
fsm_t, fsm_l = vessel.get_total_free_surface_moment()
fsc_t, fsc_l = vessel.get_total_free_surface_correction()