🔬
Solver Purpose & Physical Scope
Computes hydrostatic pressure profiles in single or multi-layer liquid systems, resultant gauge and absolute forces and centers of pressure on submerged shapes (rectangular, circular, triangular, and trapezoidal), and multi-fluid U-tube manometer pressure differentials.
📂 Discipline: Fluid
⚡ Precision: IEEE-754 64-bit Real(`real(8)`)
📥 Total Downloads: 469 times
📄 Source File:
fluid_statics.f90
📁 calcul/FluidMechanics /
fluid_statics.f90
program fluid_statics
implicit none
! Gravitational acceleration [m/s2]
double precision, parameter :: g = 9.80665d0
integer :: mode
! Mode A variables (Layered Fluids)
double precision :: P0, z_interest, P_final
integer :: N_layers
double precision, allocatable :: rho_layer(:), h_layer(:), p_interface(:)
double precision :: current_depth, accum_pressure
integer :: i, k
! Mode B variables (Submerged Surfaces)
integer :: shape
double precision :: dim1, dim2, dim3, dim4, dim5
double precision :: theta, hc, rho_fluid, P_atm
double precision :: theta_rad, area, Ixx_c, yc, ycp, hcp, FR_gauge, FR_abs
double precision :: shape_centroid_dist
! Mode C variables (Manometers)
integer :: N_left, N_right
double precision, allocatable :: rho_L(:), h_L(:)
double precision, allocatable :: rho_R(:), h_R(:)
double precision :: rho_m, dh, sum_L, sum_R, delta_P
! Read mode
read(*,*,iostat=i) mode
if (i /= 0) then
print *, "ERROR: Invalid calculation mode."
stop
end if
select case(mode)
case(1)
! ==========================================
! MODE 1: HYDROSTATIC PRESSURE (LAYERED)
! ==========================================
read(*,*,iostat=i) P0
if (i /= 0) then
print *, "ERROR: Failed to read surface pressure P0."
stop
end if
read(*,*,iostat=i) N_layers
if (i /= 0 .or. N_layers <= 0 .or. N_layers > 20) then
print *, "ERROR: Invalid number of layers."
stop
end if
allocate(rho_layer(N_layers))
allocate(h_layer(N_layers))
allocate(p_interface(0:N_layers))
do i = 1, N_layers
read(*,*,iostat=k) rho_layer(i), h_layer(i)
if (k /= 0 .or. rho_layer(i) < 0.0d0 .or. h_layer(i) <= 0.0d0) then
print *, "ERROR: Invalid layer data for layer", i
stop
end if
end do
read(*,*,iostat=i) z_interest
if (i /= 0 .or. z_interest < 0.0d0) then
print *, "ERROR: Invalid depth of interest."
stop
end if
! Compute interface pressures
p_interface(0) = P0
accum_pressure = P0
do i = 1, N_layers
accum_pressure = accum_pressure + (rho_layer(i) * g * h_layer(i)) / 1000.0d0 ! in kPa
p_interface(i) = accum_pressure
end do
! Compute pressure at z_interest
P_final = P0
current_depth = 0.0d0
do i = 1, N_layers
if (z_interest <= current_depth + h_layer(i)) then
! Target lies in current layer
P_final = p_interface(i-1) + (rho_layer(i) * g * (z_interest - current_depth)) / 1000.0d0
exit
else
current_depth = current_depth + h_layer(i)
if (i == N_layers) then
! Depth is beyond all layers, extrapolate with bottom layer density
P_final = p_interface(N_layers) + (rho_layer(N_layers) * g * (z_interest - current_depth)) / 1000.0d0
end if
end if
end do
! Print results
print *, "--- RESULTS MODE A ---"
print '(A,F12.4,A)', "Surface Pressure (P0) = ", P0, " kPa"
print '(A,F12.4,A)', "Target Depth = ", z_interest, " m"
print '(A,F12.4,A)', "Pressure at Target Depth = ", P_final, " kPa"
print *
print *, "--- INTERFACE PRESSURE DISTRIBUTION ---"
print '(A12, A15, A18)', "Boundary", "Depth [m]", "Pressure [kPa]"
current_depth = 0.0d0
print '(I12, F15.3, F18.4)', 0, current_depth, p_interface(0)
do i = 1, N_layers
current_depth = current_depth + h_layer(i)
print '(I12, F15.3, F18.4)', i, current_depth, p_interface(i)
end do
case(2)
! ==========================================
! MODE 2: SUBMERGED PLANE SURFACES
! ==========================================
read(*,*,iostat=i) shape
if (i /= 0 .or. shape < 1 .or. shape > 4) then
print *, "ERROR: Invalid shape code (1=Rect, 2=Circ, 3=Tri, 4=Trap)."
stop
end if
read(*,*,iostat=i) dim1, dim2, dim3, dim4, dim5
if (i /= 0) then
print *, "ERROR: Failed to read dimensions."
stop
end if
read(*,*,iostat=i) theta
if (i /= 0 .or. theta < 0.0d0 .or. theta > 90.0d0) then
print *, "ERROR: Inclination angle must be in [0, 90] degrees."
stop
end if
read(*,*,iostat=i) hc
if (i /= 0 .or. hc < 0.0d0) then
print *, "ERROR: Centroid depth must be non-negative."
stop
end if
read(*,*,iostat=i) rho_fluid
if (i /= 0 .or. rho_fluid <= 0.0d0) then
print *, "ERROR: Fluid density must be positive."
stop
end if
read(*,*,iostat=i) P_atm
if (i /= 0 .or. P_atm < 0.0d0) then
P_atm = 101.325d0 ! Default standard atm in kPa
end if
! Calculate shape properties
select case(shape)
case(1)
! Rectangle: dim1 = width b, dim2 = height h
if (dim1 <= 0.0d0 .or. dim2 <= 0.0d0) then
print *, "ERROR: Rectangle dimensions must be positive."
stop
end if
area = dim1 * dim2
Ixx_c = (dim1 * dim2**3) / 12.0d0
case(2)
! Circle: dim1 = Radius R
if (dim1 <= 0.0d0) then
print *, "ERROR: Circle radius must be positive."
stop
end if
area = 3.141592653589793d0 * dim1**2
Ixx_c = (3.141592653589793d0 * dim1**4) / 4.0d0
case(3)
! Triangle: dim1 = base b, dim2 = height h
if (dim1 <= 0.0d0 .or. dim2 <= 0.0d0) then
print *, "ERROR: Triangle dimensions must be positive."
stop
end if
area = 0.5d0 * dim1 * dim2
Ixx_c = (dim1 * dim2**3) / 36.0d0
case(4)
! Trapezoid: dim1 = top base a, dim2 = bottom base b, dim3 = height h
if (dim1 <= 0.0d0 .or. dim2 <= 0.0d0 .or. dim3 <= 0.0d0) then
print *, "ERROR: Trapezoid dimensions must be positive."
stop
end if
area = 0.5d0 * (dim1 + dim2) * dim3
Ixx_c = (dim3**3 * (dim1**2 + 4.0d0 * dim1 * dim2 + dim2**2)) / (36.0d0 * (dim1 + dim2))
end select
theta_rad = theta * 3.141592653589793d0 / 180.0d0
! Resultant Forces
! Force = pressure at centroid * Area
FR_gauge = (rho_fluid * g * hc * area) / 1000.0d0 ! in kN
FR_abs = ((rho_fluid * g * hc + P_atm * 1000.0d0) * area) / 1000.0d0 ! in kN
! Center of Pressure
if (theta < 0.001d0) then
! Horizontal surface
yc = hc
ycp = yc
hcp = hc
else
yc = hc / sin(theta_rad)
ycp = yc + Ixx_c / (yc * area)
hcp = ycp * sin(theta_rad)
end if
! Print results
print *, "--- RESULTS MODE B ---"
print '(A,I2)', "Shape Code = ", shape
print '(A,F12.4,A)', "Surface Area (A) = ", area, " m2"
print '(A,E14.6,A)', "Moment of Inertia (Ixx,c) = ", Ixx_c, " m4"
print '(A,F12.4,A)', "Inclination Angle (theta) = ", theta, " deg"
print '(A,F12.4,A)', "Centroid Depth (hc) = ", hc, " m"
print '(A,F12.4,A)', "Centroid distance (yc) = ", yc, " m"
print '(A,F12.4,A)', "Resultant Force (Gauge) = ", FR_gauge, " kN"
print '(A,F12.4,A)', "Resultant Force (Absolute) = ", FR_abs, " kN"
print '(A,F12.4,A)', "Center of Pressure (ycp) = ", ycp, " m"
print '(A,F12.4,A)', "Center of Pressure depth(h)= ", hcp, " m"
case(3)
! ==========================================
! MODE 3: MANOMETER DIFFERENTIAL PRESSURE
! ==========================================
read(*,*,iostat=i) N_left
if (i /= 0 .or. N_left < 0 .or. N_left > 10) then
print *, "ERROR: Invalid number of fluids in left leg."
stop
end if
allocate(rho_L(N_left))
allocate(h_L(N_left))
do i = 1, N_left
read(*,*,iostat=k) rho_L(i), h_L(i)
if (k /= 0 .or. rho_L(i) < 0.0d0 .or. h_L(i) < 0.0d0) then
print *, "ERROR: Invalid left leg fluid data at index", i
stop
end if
end do
read(*,*,iostat=i) N_right
if (i /= 0 .or. N_right < 0 .or. N_right > 10) then
print *, "ERROR: Invalid number of fluids in right leg."
stop
end if
allocate(rho_R(N_right))
allocate(h_R(N_right))
do i = 1, N_right
read(*,*,iostat=k) rho_R(i), h_R(i)
if (k /= 0 .or. rho_R(i) < 0.0d0 .or. h_R(i) < 0.0d0) then
print *, "ERROR: Invalid right leg fluid data at index", i
stop
end if
end do
read(*,*,iostat=i) rho_m, dh
if (i /= 0 .or. rho_m <= 0.0d0) then
print *, "ERROR: Invalid manometer fluid density."
stop
end if
! Calculate stages
sum_L = 0.0d0
do i = 1, N_left
sum_L = sum_L + (rho_L(i) * g * h_L(i)) / 1000.0d0 ! in kPa
end do
sum_R = 0.0d0
do i = 1, N_right
sum_R = sum_R + (rho_R(i) * g * h_R(i)) / 1000.0d0 ! in kPa
end do
! Delta P = P_left - P_right
! P_left + sum_L = P_right + sum_R + rho_m*g*dh
! Delta P = sum_R + (rho_m*g*dh)/1000 - sum_L
delta_P = sum_R + (rho_m * g * dh) / 1000.0d0 - sum_L
! Print results
print *, "--- RESULTS MODE C ---"
print '(A,F12.4,A)', "Left Leg Fluids head = ", sum_L, " kPa"
print '(A,F12.4,A)', "Right Leg Fluids head = ", sum_R, " kPa"
print '(A,F12.4,A)', "Manometer deflection head = ", (rho_m * g * dh) / 1000.0d0, " kPa"
print '(A,F12.4,A)', "Pressure Difference (DP) = ", delta_P, " kPa"
print '(A,F12.4,A)', "Pressure Difference (mH2O) = ", delta_P / (9.80665d0), " mH2O"
case default
print *, "ERROR: Calculator mode not recognized."
end select
end program fluid_statics
💻 How to Compile & Run Locally
1. Compilation (GNU Fortran / Intel oneAPI):
gfortran -O3 fluid_statics.f90 -o fluid_statics_calc
2. Execution with input.txt redirection:
fluid_statics_calc < input.txt
📄 Sample input.txt File Structure
Sample Data:
1 101.325 2 800.0 2.0 1000.0 3.0 2.5
Parameter Description:
Calculation mode (1=Layered, 2=Surfaces, 3=Manometer) Surface pressure [kPa] Number of fluid layers Density and thickness of layers Depth of interest [m]