OpenSees 강막은 왜 기둥을 네 배 무르게 남기는가: 비틀림·결합 모드·leaning column·두 성분 가진

강막은 병진과 연직축 회전을 묶을 뿐 기둥 상단 회전에는 아무것도 하지 않으며 그것이 강성 4배·주기 2배 차이다. 질량 편심은 한 병진 방향만 비틀림과 결합하고 다른 방향은 정확히 그대로 둔다. 결합 모드를 식별하는 것은 모드 번호가 아니라 유효질량비다. 유연측 가장자리는 대칭 대비 32% 더, 강성측

OpenSees 강막은 왜 기둥을 네 배 무르게 남기는가: 비틀림·결합 모드·leaning column·두 성분 가진

편심 있는 건물을 한 방향으로만 흔들면 전혀 비틀리지 않을 수 있다. 아래 1층 모델은 8 m 평면에서 질량이 2 m 편심되어 있다. X 방향으로 가진하면 강막 회전이 정확히 0이다. 직교 성분을 더하면 최악 모서리가 36% 커진다. 둘 다 모델링 오류가 아니다. 강성행렬의 결합항이 실제로 그렇게 말하고 있고, 단방향 해석에는 그것을 드러낼 방법이 없다.

이 글은 내진기준·우발편심·하중조합·허용치를 제시하지 않는다. 시리즈를 3차원으로 옮기면서, 모든 편심에서 OpenSees와 10⁻¹⁵로 일치하는 닫힌 형태의 3자유도 해로 각 단계를 검증한다. 강막이 무엇을 구속하고 무엇을 구속하지 않는지, 편심이 병진과 비틀림을 어떻게 결합하는지, 주기로는 알 수 없는 것을 유효질량비가 어떻게 말해주는지, leaning column이 변위를 왜 최대 44% 바꾸는지, 그리고 직교 두 성분이 왜 한 성분을 두 번 거는 것과 다른지를 다룬다. 이 글은 8부이며 1~7부를 전제한다.

1. 차원이 하나 늘면 무엇이 바뀌는가

선언은 한 줄이고, 그것이 절점당 숫자를 셋에서 여섯으로 확정한다.

ops.model('basic', '-ndm', 3, '-ndf', 6) # ux uy uz rx ry rz

곧바로 따라 나오는 결과가 넷이고, 각각이 잘 돌던 2D 스크립트가 조용히 깨지는 지점이다.

모든 fix()·load()·mass()가 이제 값 여섯 개를 받는다. 다섯 개면 stderr 경고와 함께 거부되고 아무것도 생성되지 않는다. 1부에서 본 그대로다.

모든 보–기둥이 vecxz 벡터를 가진 geomTransf를 요구한다. 2부에서 잘못된 벡터의 대가를 측정했다. 같은 단면, 같은 하중, 그런데 답은 Iy 대 Iz 비만큼 다르다. 부재 방향마다 태그 하나다.

질량에 회전 성분이 생긴다. 비틀림에 저항하는 바닥은 병진질량만이 아니라 연직축에 대한 질량관성모멘트가 필요하다.

바닥에는 강막이 필요하고, 강막은 대부분이 생각하는 것보다 적게 한다. 다음 절의 주제다.

이 글의 예제는 손으로 풀 수 있을 만큼 작게 잡았다. 1층, 평면 8 × 6 m, 높이 3.5 m, 모서리에 동일한 기둥 4개, 60 t을 지지하는 강성 바닥. 전부 탄성이므로 닫힌해가 정확하고, 차이가 나면 그것은 근사가 아니라 모델링 오류다.

2. 강막은 기둥 상단의 회전을 구속하지 않는다

3D 모델링에서 가장 흔한 오해이고, 그 값은 강성 400%다.

ops.rigidDiaphragm(3, master_node, *floor_nodes) # ^ 수직 방향: 3 은 바닥이 1-2 평면에 있다는 뜻

이 구속은 바닥 절점들의 면내 병진과 연직축 회전을 마스터 절점에 묶는다. 수평축에 대한 회전에 대해서는 아무 말도 하지 않는다. 따라서 강막에만 연결된 기둥은 상단 회전이 자유다. 양단고정 부재가 아니라 캔틸레버다.

모델기둥 횡강성T1

강막만3EI/H³ = 2798.8 kN/m0.45998 s

상단 회전까지 구속12EI/H³ = 11195.3 kN/m0.22999 s

비율4.00002.0000

두 경우 모두 손계산과 10⁻¹⁶로 일치하므로 어느 쪽이 어느 쪽인지 의심할 여지가 없다. 실무적 요점은 이렇다. 실제 건물에서 기둥 상단 회전을 구속하는 것은 슬래브가 아니라 거기 붙는 보다. 보를 모델링하면 구속이 생긴다. 기둥과 강막만 모델링하면 — 1차 검토에서 흔한 단순화다 — 의도한 것보다 네 배 무른 구조물과 두 배 긴 주기를 얻는다.

3. 편심은 병진과 비틀림을 결합하되 한 방향만 결합한다

질량이 강성중심에서 벗어나면 바닥의 세 자유도가 더 이상 분리되지 않는다. 질량중심에 대해 쓴 강성행렬은 이렇다.

Kxx = Σ kx,i Kyy = Σ ky,i Kxθ = −Σ kx,i · y_i Kyθ = +Σ ky,i · x_i Kθθ = Σ (kx,i y_i² + ky,i x_i²) + n · GJ/H

마지막 항은 놓치기 쉽고 확인하기도 쉽다. 각 기둥은 팔 길이를 가진 횡강성만이 아니라 자기 비틀림 강성으로도 강막의 회전에 저항한다. 여기서 이 항을 빼면 비틀림 진동수가 0.16% 달라진다. 작지만, "가깝다"와 "정확하다"의 차이이고, 이것을 찾아내는 것이 행렬의 나머지가 맞다는 것을 아는 방법이다.

편심1모드2모드3모드

0.0 m0.459980.459980.26515

0.8 m0.468530.459980.26031

1.6 m0.491960.459980.24792

2.0 m0.507910.459980.24013

가운데 열을 보자. 전혀 변하지 않는다. x 방향 편심은 Kyθ를 0이 아니게 만들고 Kxθ는 0으로 남긴다. 그래서 X 모드는 대칭 건물에서와 정확히 같고 Y 모드와 비틀림 모드가 섞인다. 편심 하나가 한 방향을 결합한다. 같은 건물이 한 축으로는 완벽히 얌전하고 다른 축으로는 심하게 비틀리는 이유가 이것이다.

이동 방향도 보아 두자. 결합된 병진 주기는 길어지고(0.460 → 0.508 s, 10.4%), 비틀림 주기는 짧아진다(0.265 → 0.240 s). 결합은 둘을 벌린다. 병진 주기와 비틀림 주기가 가까운 건물이 가장 크게 고생하는데, 바로 그 경우에 이 분리가 가장 적게 일어난다.

4. 유효질량비는 주기가 못 하는 말을 한다

위 세 모드 중 둘은 병진 모드도 비틀림 모드도 아니다. 주기만으로는 어느 쪽인지 알 수 없다. modalProperties는 알 수 있다.

ops.eigen('-fullGenLapack', 3) mp = ops.modalProperties('-return') print(mp['partiMassRatiosMX']) # -> [0.0, 100.0, 0.0] print(mp['partiMassRatiosMY']) # -> [96.72, 0.0, 3.28] print(mp['partiMassRatiosRMZ']) # -> [3.28, 0.0, 96.72]

2번 모드는 100% X이고 나머지는 0이다. 비결합 방향이다. 1번과 3번 모드는 Y 질량과 회전질량을 96.7 / 3.28, 3.28 / 96.7로 나눠 가진다. 1번을 "병진 모드", 3번을 "비틀림 모드"라 부르는 것은 약칭이고, 그 약칭이 얼마나 좋은지를 숫자가 말해준다. 편심이 커지면 비율이 50/50 쪽으로 가고 약칭은 아예 쓸모없어진다.

이것은 4부에서 평범한 캔틸레버의 세 번째 고유치가 1차 축방향 모드였던 교훈의 3차원 판이다. 모드 번호는 정렬이지 분류가 아니다. 실제 건물의 목록에는 연직 모드와 국부 바닥 모드도 들어 있고, 중요한 것을 찾아내는 값싼 방법은 유효질량비뿐이다.

5. 지배하는 것은 유연측 가장자리다

질량중심에 Y 방향 정적 100 kN을 걸고 네 모서리를 읽는다. 아래 모든 값이 닫힌 형태의 3자유도 해와 10⁻¹⁵로 일치한다.

편심중심 (mm)회전 (mrad)유연측 / 중심강성측 / 중심

0.0 m8.9320.0001.0001.000

0.8 m9.1600.2851.0990.851

1.6 m9.8440.5701.1390.676

2.0 m10.3570.7121.1380.587

유용한 순서로 세 가지를 읽는다.

중심이 16% 더 움직였다. 결합은 질량중심에서조차 구조물을 무르게 만든다. 작용한 힘의 일부가 바닥을 병진시키는 대신 회전시키는 데 쓰이기 때문이다.

유연측 가장자리는 대칭 건물보다 32% 더 움직였다. 10.357 × 1.138 / 8.932이다. 질량중심 변위를 보고했다면 지배 요구를 4분의 1만큼 낮게 말한 셈이다.

강성측 가장자리는 41% 덜 움직였다. 좋은 소식이 아니다. 그쪽 부재는 같은 변위에 더 큰 힘을 끌어당기므로, 강성측의 변위 기준 검토는 편안해 보이는데 그곳 부재는 변위가 시사하는 것보다 더 열심히 일하고 있다.

6. 한 성분만으로는 비틀림을 통째로 놓칠 수 있다

이제 같은 편심 모델을 실제 기록으로 구동한다. 7부의 Tabas 단층 직교 성분을 X에, 단층 평행 성분을 Y에 걸고 한 성분과 두 성분을 비교한다.

편심X만, 최악 모서리X와 Y, 최악 모서리비율X만일 때 회전

0.0 m28.434 mm33.382 mm1.1740.000 mrad

1.2 m28.573 mm38.238 mm1.3380.000 mrad

2.0 m28.811 mm39.180 mm1.3600.000 mrad

마지막 열이 발견이다. X 가진에서는 편심과 무관하게 회전이 정확히 0이다. 3절에서 보았듯 x 편심은 Kxθ를 0으로 남기기 때문이다. 이 건물의 단방향 해석은 비틀림 응답이 전혀 없다고, 모서리 요구가 대칭 경우의 1.3% 이내라고 보고할 것이다. 두 성분을 함께 걸면 최악 모서리에서 36% 더 나온다.

증가분의 일부는 단순한 벡터 합이다. 대칭 모델조차 17% 커지는데, 두 성분의 최대가 서로 다른 시각에 오기 때문이다. 편심 모델은 그보다 더 커지고, 1.174와 1.360의 차이가 비틀림 기여분이다.

실무 규칙은 이렇다. 한 방향으로만 가진한 3차원 모델은 자유도가 많아진 2차원 모델이다. 3D로 만든 이유가 비틀림이었다면 해석은 수평 두 성분을 모두 포함해야 한다.

7. Leaning column: 그리지 않은 중력의 P-델타

횡력저항 라멘은 보통 건물 중력하중의 일부만 받는다. 나머지는 횡력저항계에 속하지 않고 흔히 모델링되지도 않는 기둥 위에 있다. 그 무게는 여전히 바닥을 통해 라멘에 기댄다.

# 라멘이 받지 않는 중력을 지고 라멘에 묶인 핀 기둥 ops.node(3, 5.0, 0.0); ops.node(4, 5.0, H) ops.fix(3, 1, 1, 0) # 핀 기초, 회전 자유 ops.geomTransf('PDelta', 1) ops.element('elasticBeamColumn', 2, 3, 4, A, E, 1.0e-9, 1) # I 는 무시할 만큼 작게 ops.equalDOF(2, 4, 1) # 같은 횡변위 ops.load(4, 0.0, -P_gravity, 0.0) # 지고 있는 중력

중력계 θleaning column 포함중력계 무시과소평가

0.01.11111.11110%

0.11.25001.111111.1%

0.21.42861.111122.2%

0.31.66671.111133.3%

0.42.00001.111144.4%

leaning column을 넣은 증폭은 모든 점에서 1/(1 − θ_전체)와 다섯 자리까지 일치한다. 여기서 θ는 바닥이 지고 있는 전부에 대해 합산한 안정지수 P/(kH)다. 중력계를 무시하면 라멘 자신의 θ = 0.1만 남고, 건물이 실제로 얼마나 무겁든 증폭은 1.111에 고정된다.

가져갈 세부가 둘이다. leaning column의 휨강성은 무시할 만큼 작아야 한다. 실제 I를 주면 그것이 횡력저항계의 일부가 되어 의도와 정반대가 된다. 그리고 PDelta나 Corotational 변환이 필요하다. 2부에서 측정했듯 Linear에서는 축하중이 횡강성에 영향을 줄 메커니즘 자체가 없어 이 장치가 아무 일도 하지 않는다.

8. 3차원에서만 존재하는 여섯 가지 결정

목록에 들어가야 하지만 대응하는 명령이 없는 일곱 번째가 있다. 우발편심이다. 기준은 계산된 편심 너머의 설계 편심을 요구한다. 도면에 없던 질량과 강성을 덮기 위해서다. OpenSees에서는 마스터 절점을 옮기거나 토크를 걸고 다시 돌린다는 뜻이며, 자동으로 되는 것은 아무것도 없다.

9. 3차원 모델에 특유한 오류

증상유력한 원인확인

아무것도 생성되지 않고 stderr 가 인수 개수를 경고ndf 6인데 fix/load/mass에 값 다섯 개인수를 센다. 여섯 개여야 한다

주기가 예상의 약 두 배보 없이 강막만 있어 기둥 상단 회전이 자유2절, 3EI/H³과 대조

비틀림 주기가 터무니없거나 없음마스터 절점에 회전질량 미배정Z 축 질량관성모멘트를 배정

부재가 엉뚱한 축으로 휨여러 방향에 geomTransf 태그 하나 재사용2부 4절

편심 건물인데 회전이 정확히 0비결합 방향으로만 가진6절, 두 번째 성분을 추가

손계산보다 변위가 작음중력계가 표현되지 않음7절, leaning column 추가

강막을 넣은 뒤 matrix singular마스터 절점의 면외 자유도가 비구속·무질량마스터 절점의 uz·rx·ry 구속

강막에서 구속 경고constraints('Plain')은 다점구속을 처리하지 못함constraints('Transformation') 사용

10. 같은 논리를 다섯 단계 깊이로

입문자는 ndf 6, 방향마다 변환 하나, 모든 바닥에 강막을 맞춘다. 초급 실무자는 회전질량을 배정하고 기본주기를 손 추정치와 대조하며, 강막이 기둥 상단을 고정하지 않는다는 것을 안다. 실무 해석자는 모드 번호가 아니라 유효질량비를 읽고, 중심이 아니라 유연측 요구를 보고하며, 수평 두 성분을 모두 가진한다. 선임 엔지니어는 중력계를 leaning column으로 표현하고, 우발편심을 의도적으로 적용하며, 어느 모드가 결합했는지 명시한다. 전문가는 강막 가정 자체가 무너지는 경우 — 길고 좁거나 개구부가 많은 바닥 — 를 알고, 가정해 없애는 대신 슬래브 면내 유연성을 모델링한다.

11. 3차원 모델 최소 점검표

모든 fix()·load()·mass()가 값 여섯 개를 가지는가?

부재 방향마다 geomTransf 태그가 하나씩 있고 각 vecxz를 설명할 수 있는가?

모든 바닥 마스터 절점이 연직축 회전질량을 가지는가?

각 마스터 절점의 면외 자유도가 구속되어 있는가?

다점구속이 요구하는 대로 constraints('Transformation')을 쓰고 있는가?

기둥 상단 회전이 보로 구속되어 있는가, 아니면 모델이 네 배 무른가?

"1번 모드"가 의미를 가지도록 유효질량비를 읽었는가?

보고하는 변위가 질량중심이 아니라 유연측 가장자리인가?

중력계가 PDelta 변환의 leaning column으로 표현되어 있는가?

수평 두 성분을 모두 걸었고, 우발편심을 검토했는가?

다음 글은 이 글이 계속 마주친 어려움에 머문다. 해석이 수렴하지 않을 때 무엇을 할 것인가. 7부에서 쓴 캐스케이드를 알고리즘 하나씩 해체하고, 각각을 나머지가 실패하는 모델 위에서 측정한다.

전체 스크립트

이 글의 1층 강막 모델과, 그 옆에 닫힌 형태 3자유도 해를 함께 적었습니다.

# Part 8 - a rigid diaphragm, against a closed-form three-degree-of-freedom solution # units: kN, m, Mg import math import numpy as np import openseespy.opensees as ops BX, BY, HS = 8.0, 6.0, 3.5 E, IZ, IY, A, G, J = 2.0e8, 1.6e-4, 1.6e-4, 0.16, 8.0e7, 2.7e-4 M, EX = 60.0, 0.0 # storey mass, mass eccentricity COL = [(0.0, 0.0), (BX, 0.0), (BX, BY), (0.0, BY)] ops.wipe(); ops.model('basic', '-ndm', 3, '-ndf', 6) for i, (x, y) in enumerate(COL): ops.node(i + 1, x, y, 0.0); ops.fix(i + 1, 1, 1, 1, 1, 1, 1) ops.node(i + 5, x, y, HS) ops.node(9, BX / 2 + EX, BY / 2, HS) # the master node ops.fix(9, 0, 0, 1, 1, 1, 0) # a planar diaphragm: ux, uy, rz ops.rigidDiaphragm(3, 9, 5, 6, 7, 8) ops.mass(9, M, M, 0.0, 0.0, 0.0, M * (BX**2 + BY**2) / 12.0) ops.geomTransf('Linear', 1, 1.0, 0.0, 0.0) for i in range(4): ops.element('elasticBeamColumn', i + 1, i + 1, i + 5, A, E, G, J, IY, IZ, 1) w2 = ops.eigen('-fullGenLapack', 3) T_model = sorted(2 * math.pi / math.sqrt(w) for w in w2) # closed form: a diaphragm ties translation and rotation but NOT the column # top rotation, so each column is a propped cantilever, 3EI/H^3, not 12EI/H^3 k = 3.0 * E * IZ / HS**3 Kx = Ky = 4 * k Kt = sum(k * ((x - (BX/2 + EX))**2 + (y - BY/2)**2) for x, y in COL) \ + 4 * G * J / HS Mm = np.diag([M, M, M * (BX**2 + BY**2) / 12.0]) Kk = np.diag([Kx, Ky, Kt]) T_exact = sorted(2 * math.pi / math.sqrt(v) for v in np.linalg.eigvals(np.linalg.solve(Mm, Kk)).real) print(f'per-column lateral stiffness 3EI/H^3 = {k:10.3f} kN/m') print(f' 12EI/H^3 = {4*k:10.3f} kN/m (would be 4x)') print(f"\n{'mode':>5s}{'OpenSees (s)':>15s}{'closed form (s)':>17s}{'rel diff':>12s}") worst = 0.0 for i, (a, b) in enumerate(zip(T_model, T_exact), 1): d = abs(a - b) / b; worst = max(worst, d) print(f'{i:5d}{a:15.8f}{b:17.8f}{d:12.2e}') assert worst < 1e-9, f'the model and the closed form disagree by {worst:.2e}' print(f'\nOK all three periods match to {worst:.1e}')

실행하면 이렇게 나옵니다.

per-column lateral stiffness 3EI/H^3 = 2239.067 kN/m 12EI/H^3 = 8956.268 kN/m (would be 4x) mode OpenSees (s) closed form (s) rel diff 1 0.28178698 0.28178698 3.94e-16 2 0.51427090 0.51427090 0.00e+00 3 0.51427090 0.51427090 8.64e-16 OK all three periods match to 8.6e-16

OpenSees 시리즈 전체

각 편은 닫힌해·독립적인 풀이·OpenSees 소스 중 하나와 대조해 검증했다. 순서대로 읽도록 썼지만 각 편이 자기 전제를 스스로 밝힌다.

1부 — 도메인 모델과 해석 조립

2부 — 단면·기하변환·분포하중

3부 — 파이버 단면·모멘트–곡률·푸시오버

4부 — 질량·감쇠·시간적분

5부 — 라이브러리 읽기와 재현 가능한 워크플로

6부 — 철근콘크리트 파이버 단면과 구속

7부 — 실제 지진기록·층간변위·증분동적해석

8부 — 3차원: 강막·비틀림·leaning column — 지금 보는 글

9부 — 수렴하지 않을 때: 실패·알고리즘·한계점

10부 — Tcl 읽기와 공개 스크립트 이식

11부 — 쉘·솔리드·지반: 락킹·메시·부지응답

12부 — 후처리: recorder·질의, 그리고 그림이 증명하는 것

13부 — 좌굴과 한계점: 분기점·스냅백·호장법

14부 — Windows: 설치·파일 형식·조용한 실패

15부 — 검증된 정답이 딸린 연습문제와 한영 용어집

16부 — 어떻게 동작하는가: 시행상태·확정상태·해석 루프

17부 — 커뮤니티가 말하는 것, 측정해보면

18부 — 절점 변위에서 파이버 응력까지

19부 — 면진과 감쇠: 속도 의존 요소와 베어링

참고 자료

OpenSeesPy, rigidDiaphragm, rigidLink, equalDOF — 여기 쓴 세 가지 다점구속.

OpenSeesPy, Transformation 구속 처리기 — 다점구속이 생기면 필요하다.

OpenSeesPy, modalProperties — 유효질량비와 총질량.

OpenSeesPy, geomTransf, PDelta 변환 — 3차원 방향과 leaning column.

OpenSeesPy, 3층 철골 건물 예제 — 같은 명령 체계로 된 공식 3D 모델.

Chopra, A. K., Dynamics of Structures, 병진–비틀림 결합 시스템 장 — 3절과 5절에서 대조한 닫힌 형태 3자유도 모델.

Scott, M. H., OpenSees Digital — 구속·강막·모드해석을 다루는 OpenSees 개발자 블로그.

Pacific Earthquake Engineering Research Center, OpenSees Wiki.

자료 확인 2026-08-31. 모든 수치는 OpenSeesPy 3.8.0에서 생성되었으며 위 스크립트로 재현할 수 있다. 닫힌해 비교는 탄성 3자유도 강막 모델을 쓰므로 인용한 일치도는 근사가 아니라 모델에 대한 검사다. 프레임워크의 동작을 보여주는 것이지 프로젝트별 해석이나 기준 적합성 검토를 대신하지 않는다.