Skip to content
cfd-lab:~/es/posts/2026-08-13-metacentric-h…online
NOTE #130DAY THU 유체역학DATE 2026.08.13READ 8 min read#Metacenter#Buoyancy#Free-Surface#Fluid-Mechanics#FSI

El peso va arriba y aun así se endereza — altura metacéntrica GM y efecto de superficie libre

GM es el margen que gana la inercia del plano de flotación. Una sola superficie libre en un tanque puede llevarse ese margen entero.

El centro de gravedad de un portacontenedores queda varios metros por encima del centroide de su volumen sumergido. Lo pesado está arriba y el buque se endereza solo. En cambio, una barcaza con el centro de gravedad por debajo del centro de carena puede volcar. La relación arriba-abajo no decide nada. Este artículo trata de la magnitud que sí decide el caso — la altura metacéntrica GMGM —, de dónde sale y por qué el líquido de un tanque puede borrarla por completo.

El centro de gravedad está por encima del de carena#

Primero los símbolos. KK es la quilla, GG el centro de gravedad y BB el centro de carena, es decir, el centroide del volumen sumergido. Arquímedes fijó solo la magnitud: el empuje vale lo que pesa el agua desplazada y su línea de acción pasa por el centroide de ese volumen.

En posición adrizada, GG y BB comparten la misma vertical. Peso y empuje son iguales y opuestos, de modo que el momento es cero. En ese estado da lo mismo que GG esté alto o bajo. La estabilidad no se define por el estado en reposo, sino por lo que aparece al inclinar el cuerpo un poco.

Al escorar cambia todo. BB es el centroide de la forma sumergida, así que si esa forma cambia, BB se desplaza con ella. GG gira con el buque, pero dentro de él no se mueve. Al separarse las dos verticales surge un brazo de momento. Ese brazo es el brazo adrizante GZGZ, y el momento adrizante vale M=ΔGZM = \Delta \cdot GZ para un desplazamiento Δ\Delta.

Al escorar cambia la forma sumergida#

Conviene inclinarla a mano en la simulación de abajo. Se cambian manga, calado y altura del centro de gravedad, se pulsa release at 15 deg y se observa si vuelve.

phi = 15.0 deg
Raise KG past 7.33 m and the barge no longer comes back — it rolls out to an angle of loll and stays there. Hold the heel and drag it past 27 deg: the deck edge goes under, the waterplane stops widening, and the green GZ curve peels away from the dashed straight line GM sin phi. That gap is why a single number cannot certify a hull.

BB (verde) es arrastrado hacia la banda baja, y la separación que se abre respecto de la vertical por GG (amarillo) es GZGZ. El punto morado MM es donde la línea de empuje corta la crujía del buque. Al subir el deslizador KG por encima de 7.33 m, MM cae por debajo de GG: en lugar de volver, la barcaza queda tumbada a un ángulo fijo.

BM=I/BM = I/\nabla — todo está en la inercia del plano de flotación#

Con una escora pequeña ϕ\phi, el cambio de la forma sumergida se reduce a dos cuñas: una que emerge en la banda alta y otra que se sumerge en la banda baja. Sus volúmenes son iguales, porque el desplazamiento no puede cambiar, y están separadas transversalmente. Ese trasvase de volumen es lo que mueve BB.

Sea una franja dAdA del plano de flotación (la sección con la que la superficie del agua corta el casco) a una distancia xx de la crujía. Aporta un cambio de volumen xϕdAx\phi\,dA y un momento x2ϕdAx^2\phi\,dA. Al sumar sobre todo el plano aparece un momento de inercia de área.

BB=ϕAx2dA=Iϕ,BM=I\overline{BB'} = \frac{\phi \int_A x^{2}\,dA}{\nabla} = \frac{I\,\phi}{\nabla}, \qquad BM = \frac{I}{\nabla}

II es el momento de inercia del plano de flotación respecto de la crujía y \nabla el volumen desplazado. Para una sección rectangular de manga bb, por unidad de eslora I=b3/12I = b^3/12 y =bT\nabla = b\,T, de modo que

BM=b212TBM = \frac{b^{2}}{12\,T}

La manga entra al cubo y luego el \nabla del denominador cancela una potencia y deja un cuadrado. Ensanchar el casco un 20% aumenta BMBM un 44%. Por eso una canoa es inestable y una balsa no. Y el criterio cabe en una línea.

GM=KB+BMKGGM = KB + BM - KG

KBKB es la altura del centro de carena y KGKG la del centro de gravedad. Con GM>0GM > 0 el buque se adriza; con GM<0GM < 0 vuelca. Para una barcaza de manga b=16b = 16 m y calado T=4T = 4 m resulta KB=2.0KB = 2.0 m y BM=5.333BM = 5.333 m, es decir KM=7.333KM = 7.333 m. Si KGKG vale 6.6 m, todo el margen es de 0.733 m.

El ángulo en que GMsinϕGM \sin\phi traiciona#

GMGM es una pendiente en ϕ0\phi \to 0. A ángulos pequeños, GZGMsinϕGZ \approx GM \sin\phi funciona bien. Lo interesante es cuándo deja de funcionar.

Ese punto lo fija la geometría, porque II solo permanece constante mientras el plano de flotación no cambia. La barcaza anterior tiene 4 m de francobordo, así que el trancanil se sumerge en tanϕ=2×4/16\tan\phi = 2 \times 4/16, o sea 26.6 grados. A partir de ahí el plano de flotación deja de ensancharse y empieza a encogerse. BMBM se derrumba y la curva GZGZ se dobla.

Al pulsar hold heel en la simulación y pasar de 30 grados se ve cómo la curva verde continua (el valor exacto) se despega de la recta morada discontinua (GMsinϕGM\sin\phi). La escora en que ambas discrepan de signo es el ángulo de estabilidad nula.

El líquido de un tanque se lleva todo el GM#

Ahora se coloca un tanque con líquido dentro del casco. Tanques de lastre, de combustible, de carga, o una cubierta de vehículos inundada con agua contra incendios: el problema es el mismo.

El peso del líquido no cambia al escorar. Solo se desplaza. Y ese desplazamiento arrastra GG hacia la banda baja. La contabilidad es idéntica a la de BMBM: la superficie libre del tanque también es un plano de flotación, y al escorar se intercambian dos cuñas.

δGM=ρfiρ\delta GM = \frac{\rho_f\, i}{\rho\, \nabla}

ii es el momento de inercia de la superficie libre del tanque, ρf\rho_f la densidad del líquido interior y ρ\rho la del agua exterior. La pérdida no se resta del casco: se trata como una subida virtual de GG de esa misma magnitud. Cuánto líquido contiene el tanque no aparece en la fórmula. Salvo que esté prensado sin superficie libre o completamente vacío, 20 cm de líquido cuestan exactamente lo mismo que 2 m.

Conviene mover el deslizador de mamparos que aparece abajo.

phi = 10.0 deg
Start at n = 1 and press release: the liquid slides to the low side and the barge never comes back. Now drag the bulkhead slider. The liquid volume never changes, the centre of gravity of the ship at rest never changes — only the width of each free surface does, and at n = 2 the red loss bar has already dropped to a quarter.

El amarillo es el líquido. Su superficie se mantiene horizontal haga lo que haga el casco. Con n = 1, al soltarla no regresa: queda tumbada en un ángulo de escora permanente (angle of loll). Basta un mamparo para que la barra roja de pérdida caiga a la cuarta parte y la barcaza se levante.

Un mamparo reduce la pérdida a la cuarta parte#

Al dividir un tanque de ancho btb_t en nn compartimentos, cada uno mide bt/nb_t/n y hay nn de ellos.

i=n(bt/n)312=bt312n2i = n \cdot \frac{(b_t/n)^{3}}{12} = \frac{b_t^{3}}{12\,n^{2}}

La pérdida cae como 1/n21/n^2, no como 1/n1/n: el cubo del ancho vence a la primera potencia del número. Un solo tanque de 12 m en la barcaza anterior da i=144i = 144 m⁴ frente a =64\nabla = 64 m³/m, luego δGM=2.195\delta GM = 2.195 m. Los 0.733 m de GMGM habían desaparecido mucho antes. Un único mamparo en crujía baja la pérdida a 0.549 m y la barcaza vuelve a levantarse.

Para eso está el mamparo longitudinal en el centro de un petrolero. Ni la carga ni la altura del centro de gravedad cambian. Solo se reduce a la mitad el ancho de cada superficie libre.

La curva GZ y el ángulo de estabilidad nula, en Python#

GMGM es una única pendiente tangente. A ángulos grandes sale más rápido recortar el polígono sumergido y tomar su centroide. Se representa la sección del casco como polígono, se busca por bisección la altura de flotación que iguala el área sumergida al área desplazada y se calcula el centroide de lo que queda.

import math
 
def poly_area_centroid(poly):
    a = cx = cy = 0.0
    n = len(poly)
    for i in range(n):
        x0, y0 = poly[i]
        x1, y1 = poly[(i + 1) % n]
        cr = x0 * y1 - x1 * y0
        a += cr
        cx += (x0 + x1) * cr
        cy += (y0 + y1) * cr
    a *= 0.5
    if abs(a) < 1e-14:
        return 0.0, 0.0, 0.0
    return a, cx / (6 * a), cy / (6 * a)
 
def clip_below(poly, phi, h):
    """conserva la parte del poligono cuya altura en tierra es menor que h"""
    def f(p):
        return p[1] * math.cos(phi) - p[0] * math.sin(phi) - h
    out = []
    n = len(poly)
    for i in range(n):
        p, q = poly[i], poly[(i + 1) % n]
        fp, fq = f(p), f(q)
        if fp <= 0.0:
            out.append(p)
        if (fp < 0.0) != (fq < 0.0):
            t = fp / (fp - fq)
            out.append((p[0] + t * (q[0] - p[0]), p[1] + t * (q[1] - p[1])))
    return out
 
def waterline_offset(poly, phi, area0):
    """biseccion de la altura de flotacion que sumerge exactamente area0"""
    lo, hi = -60.0, 60.0
    for _ in range(80):
        mid = 0.5 * (lo + hi)
        a, _, _ = poly_area_centroid(clip_below(poly, phi, mid))
        if a < area0:
            lo = mid
        else:
            hi = mid
    return 0.5 * (lo + hi)
 
def righting_arm(beam, depth, draft, kg, phi):
    hull = [(-beam / 2, 0.0), (beam / 2, 0.0), (beam / 2, depth), (-beam / 2, depth)]
    h = waterline_offset(hull, phi, beam * draft)
    _, xb, yb = poly_area_centroid(clip_below(hull, phi, h))
    return xb * math.cos(phi) + (yb - kg) * math.sin(phi), xb, yb
 
def gz_curve(beam, depth, draft, kg, deg_max=70, step=1):
    return [(d, righting_arm(beam, depth, draft, kg, math.radians(d))[0])
            for d in range(0, deg_max + 1, step)]
 
BEAM, DEPTH, DRAFT = 16.0, 8.0, 4.0
KG = 6.6
KB = DRAFT / 2
BM = BEAM ** 2 / (12 * DRAFT)
GM = KB + BM - KG
print(f"KB={KB:.3f} m  BM=B^2/12T={BM:.3f} m  KM={KB+BM:.3f} m  KG={KG:.3f} m  GM={GM:.3f} m")
print(f"deck edge immerses at phi = {math.degrees(math.atan(2*(DEPTH-DRAFT)/BEAM)):.1f} deg")
print()
print(" phi[deg]   GZ[m]   GM*sin(phi)[m]   error[%]")
for d, gz in gz_curve(BEAM, DEPTH, DRAFT, KG, 60, 5):
    lin = GM * math.sin(math.radians(d))
    err = f"{100 * (lin - gz) / gz:8.1f}" if abs(gz) > 0.01 else "       -"
    print(f"  {d:5.1f}   {gz:7.4f}   {lin:11.4f}   {err}")
 
curve = gz_curve(BEAM, DEPTH, DRAFT, KG, 70, 1)
dmax, gzmax = max(curve, key=lambda t: t[1])
vanish = next((d for d, g in curve if d > 5 and g <= 0.0), None)
print()
print(f"max GZ = {gzmax:.3f} m at {dmax} deg,  vanishing stability at {vanish} deg")
KB=2.000 m  BM=B^2/12T=5.333 m  KM=7.333 m  KG=6.600 m  GM=0.733 m
deck edge immerses at phi = 26.6 deg
 
 phi[deg]   GZ[m]   GM*sin(phi)[m]   error[%]
    0.0    0.0000        0.0000          -
    5.0    0.0657        0.0639       -2.7
   10.0    0.1417        0.1273      -10.2
   15.0    0.2394        0.1898      -20.7
   20.0    0.3716        0.2508      -32.5
   25.0    0.5550        0.3099      -44.2
   30.0    0.7207        0.3667      -49.1
   35.0    0.6823        0.4206      -38.4
   40.0    0.5196        0.4714       -9.3
   45.0    0.2828        0.5185       83.3
   50.0    0.0001        0.5618          -
   55.0   -0.3116        0.6007     -292.8
   60.0   -0.6406        0.6351     -199.1
 
max GZ = 0.727 m at 31 deg,  vanishing stability at 51 deg

A 5 grados el error es del 2.7%. A 30 grados, GMsinϕGM\sin\phi entrega apenas la mitad del GZGZ real, porque el plano de flotación sigue ensanchándose hasta que la cubierta se sumerge y el brazo adrizante real supera la estimación lineal. Pasados los 45 grados el signo del error se invierte y la estimación lineal empieza a mentir del lado peligroso: a 50 grados el GZGZ real es cero mientras GMsinϕGM\sin\phi todavía promete 0.56 m.

La pérdida por superficie libre se puede comprobar sin recortar ningún polígono. Antes de que la cubierta se sumerja los costados son verticales y el brazo adrizante tiene forma cerrada. La pérdida es una subida virtual, así que se resta δGM\delta GM de GMGM y se introduce ese valor.

import math
 
BEAM, DRAFT, KG = 16.0, 4.0, 6.6
NABLA = BEAM * DRAFT
BM = BEAM ** 2 / (12 * DRAFT)
GM = DRAFT / 2 + BM - KG
 
def free_surface_loss(rho_f, rho, b, n, nabla):
    """perdida por superficie libre [m] de un tanque de ancho b con n mamparos"""
    i_free = n * (b / n) ** 3 / 12
    return rho_f * i_free / (rho * nabla)
 
def wall_sided_gz(gm, bm, phi):
    """brazo adrizante mientras los costados siguen verticales"""
    return (gm + 0.5 * bm * math.tan(phi) ** 2) * math.sin(phi)
 
print(" tanks   i[m^4]   dGM[m]   GM_eff[m]   GZ(20deg)[m]")
for n in (1, 2, 3, 4):
    d_gm = free_surface_loss(1000.0, 1025.0, 12.0, n, NABLA)
    gz20 = wall_sided_gz(GM - d_gm, BM, math.radians(20))
    print(f"  {n:4d}  {n*(12.0/n)**3/12:7.1f}  {d_gm:7.3f}   {GM-d_gm:8.3f}   {gz20:11.3f}")
 tanks   i[m^4]   dGM[m]   GM_eff[m]   GZ(20deg)[m]
     1    144.0    2.195     -1.462        -0.379
     2     36.0    0.549      0.185         0.184
     3     16.0    0.244      0.489         0.288
     4      9.0    0.137      0.596         0.325

Un mamparo lleva ii de 144 a 36, exactamente la cuarta parte. El brazo adrizante a 20 grados cambia de signo, de −0.379 m a +0.184 m. La forma cerrada empleada aquí, GZ=(GM+12BMtan2ϕ)sinϕGZ = (GM + \tfrac{1}{2}BM\tan^2\phi)\sin\phi, coincide con el cálculo por polígonos mientras la cubierta siga seca: sin pérdida alguna da 0.3716 m a 20 grados, el mismo número de la tabla anterior.

Antes de poner un casco a flotar en un cálculo 6-DOF con VOF#

En cuanto un cuerpo flotante se resuelve con CFD, cada uno de estos números se convierte en un control sobre el solver.

Primero, conviene calcular GMGM a mano antes de fijar el calado inicial. Con la superficie libre capturada por VOF (comparación de métodos de captura de interfaz) y el movimiento de sólido rígido de 6 grados de libertad acoplado (FEM de sólido rígido con cuaterniones), el casco oscila por sí solo. Si el periodo de esa oscilación libre amortiguada, Tϕ=2πk/gGMT_\phi = 2\pi k/\sqrt{g\,GM} con kk el radio de giro de balance, no coincide con el valor a mano, hay que sospechar de la malla o de la inercia introducida.

Segundo, la resolución de malla se come BMBM directamente. BMBM es una integral ponderada por x2x^2 sobre el plano de flotación, así que las celdas próximas al costado son las que más aportan. Si la superficie libre se difumina sobre dos o tres celdas, el ancho efectivo del plano de flotación se emborrona y el momento adrizante queda subestimado. Refinar localmente en torno a la línea de flotación sale barato.

Tercero, si el cálculo se hace con los tanques llenos, la pérdida por superficie libre aparece sola, y aparece junto con el sloshing. Cuando el líquido se desfasa respecto del movimiento del casco, el resultado puede ser peor o mejor que el δGM\delta GM cuasiestático. Ahí es donde los tratamientos implícitos de la superficie libre se ganan el sueldo (el Newton anidado de Casulli–Zanolli). El cálculo a mano sigue siendo válido en ese caso. Solo deja de ser la respuesta: pasa a ser la referencia con la que desconfiar del resultado.

Comparte si te resultó útil.