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

무게중심이 위에 있는데도 안 뒤집힌다 — 메타센터 GM과 자유표면 효과

GM은 수선면 관성모멘트가 벌어 주는 여유다. 탱크에 담긴 물의 자유표면 하나가 그 여유를 통째로 가져갈 수 있다.

컨테이너선의 무게중심은 물에 잠긴 부분의 중심보다 몇 미터 위에 있다. 무거운 쪽이 위에 얹혀 있는데도 배는 스스로 일어선다. 반대로 무게중심이 부력중심보다 아래인데 뒤집히는 부선(barge)도 있다. 위아래 관계만으로는 아무것도 결정되지 않는다는 뜻이다. 판정을 내리는 양은 메타센터 높이 GMGM이고, 탱크에 담긴 물이 그 값을 통째로 지우는 자리까지 적어 둔다.

무게중심이 부력중심보다 위에 있다#

기호부터 맞추자. KK는 용골(keel, 배 바닥 중심), GG는 무게중심, BB는 부력중심이다. 부력중심은 물에 잠긴 부피의 도심(centroid)이다. 아르키메데스가 말한 것은 크기뿐이다. 부력의 크기는 밀어낸 물의 무게와 같고, 작용선은 잠긴 부피의 도심을 지난다.

똑바로 떠 있을 때 GG와 BB는 같은 연직선 위에 있다. 무게와 부력은 크기가 같고 방향이 반대라 모멘트가 0이다. 이 상태에서는 GG가 위든 아래든 아무 일도 일어나지 않는다. 안정성은 정지 상태가 아니라 살짝 기울였을 때 무엇이 생기는가로 정의된다.

기울이면 사정이 달라진다. BB는 잠긴 모양의 도심이므로 잠긴 모양이 바뀌면 함께 옮겨 간다. GG는 배와 함께 회전할 뿐 배 안에서는 제자리다. 두 연직선이 어긋나면서 모멘트 팔이 생긴다. 이것을 복원정(righting arm) GZGZ라 부르고, 복원 모멘트는 배수량 Δ\Delta에 대해 M=Δ⋅GZM = \Delta \cdot GZ다.

기울면 잠긴 모양이 바뀐다#

아래 시뮬레이션에서 직접 기울여보자. 폭·흘수·무게중심을 바꾸고 release at 15 deg를 눌러 돌아오는지 보면 된다.

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(초록)가 기울인 쪽으로 끌려가고, GG(노랑)를 지나는 연직선과 벌어지는 간격이 GZGZ다. 보라색 MM은 부력 작용선이 배 중심선과 만나는 점이다. KG 슬라이더를 7.33 m 위로 올리면 MM이 GG 아래로 내려가고, 배는 돌아오는 대신 한쪽으로 누워 멈춘다.

BM=I/∇BM = I/\nabla — 수선면의 관성모멘트가 전부다#

작은 각도 ϕ\phi에서 잠긴 모양의 변화는 쐐기 두 개로 정리된다. 한쪽 현측에서 물 밖으로 나온 쐐기와 반대쪽에서 새로 잠긴 쐐기다. 두 쐐기의 부피는 같고(배수량이 그대로여야 하므로) 좌우로 떨어져 있다. 이 부피 이동이 BB를 옮긴다.

수선면(waterplane, 수면이 배를 자른 단면)의 미소 띠 dAdA가 중심선에서 xx만큼 떨어져 있으면, 그 띠가 만드는 부피 변화는 xϕ dAx\phi\,dA이고 모멘트는 x2ϕ dAx^2\phi\,dA다. 전부 더하면 관성모멘트가 나온다.

BB′‾=ϕ∫Ax2 dA∇=I ϕ∇,BM=I∇\overline{BB'} = \frac{\phi \int_A x^{2}\,dA}{\nabla} = \frac{I\,\phi}{\nabla}, \qquad BM = \frac{I}{\nabla}

II는 중심선에 대한 수선면의 2차 관성모멘트, ∇\nabla는 배수 부피다. 폭 bb인 직사각형 단면이라면 단위 길이당 I=b3/12I = b^3/12, ∇=b T\nabla = b\,T이므로

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

가 된다. 여기서 폭이 세제곱으로 들어갔다가 분모의 ∇\nabla에서 한 번 상쇄되어 제곱으로 남는다는 점이 중요하다. 폭을 20% 넓히면 BMBM은 44% 커진다. 카누가 불안정하고 뗏목이 안정한 이유가 여기 있다. 그리고 판정식은 한 줄로 끝난다.

GM=KB+BM−KGGM = KB + BM - KG

KBKB는 부력중심 높이, KGKG는 무게중심 높이다. GM>0GM > 0이면 복원, GM<0GM < 0이면 전복이다. 폭 b=16b = 16 m, 흘수 T=4T = 4 m인 부선이면 KB=2.0KB = 2.0 m, BM=5.333BM = 5.333 m이므로 KM=7.333KM = 7.333 m다. KGKG가 6.6 m라면 여유는 0.733 m뿐이다. 단위 길이로 b3/12b^3/12를 ∇=bT=64\nabla = b T = 64로 나누면 그 5.333 m가 다시 나온다. 폭을 20% 키우면 b2b^2이 1.44배가 되고, 본문의 44%가 이 제곱이다. 0.44×5.3330.44 \times 5.333 m가 GMGM에 그대로 더해진다. KG=6.6KG = 6.6 m를 고정하면 여유 0.733 m는 그 덧셈만큼 벌어진다. 얇은 선측을 쉘로 풀 때는 이 여유가 잠기기도 한다. 전단 잠김이 처짐을 죽이면, 복원 팔 GZGZ를 보기 전에 강성 행렬부터 의심해야 한다.

GMsin⁡ϕGM \sin\phi가 배신하는 각도#

GMGM은 ϕ→0\phi \to 0의 기울기다. 작은 각도에서는 GZ≈GMsin⁡ϕGZ \approx GM \sin\phi가 잘 맞는다. 문제는 이 근사가 언제 깨지는지다.

깨지는 지점은 기하학이 정한다. 수선면이 변하지 않는 동안만 II가 상수이기 때문이다. 위 부선은 건현(freeboard, 수면 위 선체 높이)이 4 m이므로 tan⁡ϕ=2×4/16\tan\phi = 2 \times 4/16, 즉 26.6°에서 갑판 끝이 물에 잠긴다. 그 순간부터 수선면은 더 넓어지지 못하고 오히려 줄어든다. BMBM이 무너지고 GZGZ 곡선은 꺾인다.

위 시뮬레이션에서 hold heel을 누르고 각도를 30° 너머로 밀어보면 초록 실선(정확값)이 보라색 점선(GMsin⁡ϕGM\sin\phi)에서 떨어져 나가는 것이 보인다. 두 곡선의 부호가 갈리는 각도가 곧 소멸각이다.

탱크 속 물이 GM을 통째로 가져간다#

이제 배 안에 액체가 담긴 탱크를 넣자. 밸러스트 탱크, 연료 탱크, 화물 탱크, 소화용수로 잠긴 자동차 갑판까지 전부 같은 문제다.

액체의 무게는 기울여도 변하지 않는다. 옮겨 갈 뿐이다. 그런데 그 이동이 GG를 아래쪽 현측으로 끌고 간다. 계산 구조는 BMBM과 똑같다. 탱크 안 자유표면도 하나의 수선면이고, 기울면 쐐기 두 개가 자리를 바꾼다.

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

ii는 탱크 자유표면의 관성모멘트, ρf\rho_f는 탱크 액체 밀도, ρ\rho는 바깥 물의 밀도다. 이 값은 배에서 실제로 빼는 것이 아니라 GG가 그만큼 위로 올라간 것처럼 취급한다(가상 상승, virtual rise). 탱크에 물이 얼마나 들어 있는지는 식에 없다. 넘칠 듯 가득 차 자유표면이 없어지거나 완전히 비지 않는 한, 20 cm가 담겼든 2 m가 담겼든 손실은 같다.

칸막이 수에 따라 손실이 1/n21/n^2로 줄어드는 이유는 아래 식이다.

칸막이 하나가 손실을 1/4로 줄인다#

폭 btb_t인 탱크를 nn개로 나누면 각 칸의 폭은 bt/nb_t/n이고 칸이 nn개다.

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

손실은 1/n1/n이 아니라 1/n21/n^2로 줄어든다. 폭의 세제곱이 개수의 1제곱을 이기기 때문이다. 위 부선에 폭 12 m 탱크가 하나 있으면 i=144i = 144 m⁴, ∇=64\nabla = 64 m³/m이므로 δGM=2.195\delta GM = 2.195 m다. GMGM 0.733 m는 이미 한참 전에 사라졌다. 중앙에 칸막이 하나만 세우면 0.549 m로 떨어지고 배는 다시 선다.

이것이 유조선 중앙에 종격벽이 서 있는 이유다. 화물량도, 무게중심 높이도 바뀌지 않는다. 자유표면의 폭만 반이 된다.

Python으로 그려본 GZ 곡선과 소멸각#

GMGM은 접선의 기울기 하나일 뿐이다. 큰 각도의 GZGZ는 잠긴 다각형을 직접 잘라서 도심을 구하는 편이 빠르다. 선체 단면을 다각형으로 놓고, 잠긴 면적이 배수 면적과 같아지는 수선 높이를 이분법으로 찾은 뒤, 그 다각형의 도심을 계산한다.

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):
    """heel phi 상태에서 지구 기준 높이가 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):
    """잠긴 면적이 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

5°에서 GZGZ는 0.0657, GMsin⁡ϕGM\sin\phi는 0.0639, 오차 −2.7%다. 25°에서는 0.5550 대 0.3099로 오차가 −44.2%까지 벌어진다. 갑판 잠김 26.6°를 지난 30°에서 실제 GZGZ는 0.7207, 선형식은 0.3667이다. 거의 절반이다. 갑판이 잠기기 전까지 수선면이 계속 넓어져 실제 복원력이 선형 예측보다 크기 때문이다. 최대 복원정 0.727 m는 31°에 있다. 45°에서 오차 부호가 +83.3%로 뒤집히고, 50°의 실제 GZGZ는 0.0001인데 선형식은 0.5618을 남긴다. 소멸각 51° 뒤의 55°와 60°에서 실제 값은 −0.3116, −0.6406이다. 선형식은 그때도 +0.6007, +0.6351이다. 소멸각을 넘긴 뒤에도 양의 복원정을 약속하는 쪽은 위험 쪽으로 기울어 있다.

자유표면 손실은 다각형을 자르지 않고도 확인할 수 있다. 갑판이 잠기기 전까지는 현측이 수직이라 복원정에 닫힌 식이 있기 때문이다. 손실은 가상 상승이므로 GMGM에서 δGM\delta GM을 빼고 넣으면 된다.

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):
    """칸막이 n개로 나뉜 폭 b 탱크의 자유표면 손실 [m]"""
    i_free = n * (b / n) ** 3 / 12
    return rho_f * i_free / (rho * nabla)
 
def wall_sided_gz(gm, bm, phi):
    """갑판이 잠기기 전, 현측이 수직인 구간의 복원정"""
    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

칸막이 수 n을 1에서 2로 올리면 빨간 손실 막대가 4분의 1로 줄고, 누워 있던 부선이 일어선다.

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.

노란색이 탱크 액체다. 액체 표면은 선체가 어떻게 기울든 수평을 유지한다. n = 1에서 놓으면 배는 돌아오지 않고 한쪽으로 누워 버틴다(각도 부동, angle of loll). 칸막이를 하나 세우는 순간 빨간 손실 막대가 1/4로 줄고 배가 일어선다.

칸막이 하나로 ii가 144에서 36으로, 정확히 1/4이 된다. ρf=1000\rho_f = 1000, ρ=1025\rho = 1025, i=144i = 144, ∇=64\nabla = 64이면 δGM=1000×144/(1025×64)=2.195\delta GM = 1000 \times 144 / (1025 \times 64) = 2.195 m다. n=4n = 4이면 i=9i = 9, δGM=0.137\delta GM = 0.137 m, 20° 복원정은 0.325 m다. 손실이 없을 때의 0.3716 m에는 아직 못 미친다. 20°에서의 복원정은 −0.379 m에서 +0.184 m로 부호가 바뀐다. 여기 쓴 닫힌 식 GZ=(GM+12BMtan⁡2ϕ)sin⁡ϕGZ = (GM + \tfrac{1}{2}BM\tan^2\phi)\sin\phi는 갑판이 잠기기 전 구간에서 다각형 계산과 일치한다. 손실이 없을 때 20°의 값 0.3716 m가 위 표와 같다.

6-DOF VOF 해석에 배를 띄우기 전에#

초기 흘수를 넣기 전에 GM=0.733GM = 0.733 m를 손으로 남겨 둔다. 자유 횡동요 주기 Tϕ=2πk/g GMT_\phi = 2\pi k/\sqrt{g\,GM}이 이 값과 어긋나면 격자나 관성 입력을 먼저 의심한다. kk는 횡동요 회전반경이다. BMBM은 수선면의 x2x^2 가중이라 현측 셀이 대부분을 만든다. 자유표면이 두세 셀로 번지면 유효 폭이 줄고, 복원 모멘트가 작게 나온다.

탱크를 채운 계산에서 칸막이 없는 δGM=2.195\delta GM = 2.195 m는 준정적 기준선이다. 그때 유효 GMGM은 −1.462-1.462 m다. 액체가 선체와 위상이 어긋나면 이 손실보다 더 기울 수도 있다. 자유수면을 음함수로 푸는 Casulli–Zanolli의 중첩 Newton이 필요한 지점이 여기다. 손계산은 정답이 아니라, 그 횡동요를 의심할 때 붙잡는 숫자다.

도움이 됐다면 공유해주세요.