OpenSees 커뮤니티가 말하는 것, 측정해보면: 반복되는 조언 아홉 개와 각각의 판정

"반복 한도를 올려라"는 인터넷에서 가장 많이 반복되는 OpenSees 조언인데, 9부의 실패 스텝에서는 아무것도 바꾸지 못한다. 30·100·500·2000회 모두 실패하고 언제나 정확히 5회 만에 멈춘다. 적분점을 늘려도 여기서는 수렴이 전혀 나빠지지 않았고, 반복 8% 더 쓰는 대가로 내력이 94.

OpenSees 커뮤니티가 말하는 것, 측정해보면: 반복되는 조언 아홉 개와 각각의 판정

"최대 반복 횟수를 늘려라"는 인터넷에서 가장 많이 반복되는 OpenSees 조언입니다. 9부에서 골조를 멈춰 세운 그 스텝에서, 그것은 아무 일도 하지 않습니다. 30회, 100회, 500회, 2000회 — 매번 실패하고, 매번 정확히 5회 만에 멈춥니다. 한도에 닿은 적이 없으므로 한도를 올리는 것이 영향을 줄 수 없습니다.

OpenSees 커뮤니티는 포럼과 블로그와 ResearchGate 스레드에 20년치 조언을 쌓아왔고, 대부분은 좋은 조언입니다. 일부는 전승입니다. 이 글은 가장 자주 반복되는 주장 아홉 개를 골라 출처를 밝히고 하나씩 측정합니다. 전부 OpenSeesPy 3.8.0에서, 이 시리즈가 이미 공개한 모델 위에서 돌렸으므로 판정을 직접 검증할 수 있습니다.

1. "반복 한도를 올려라" — 뒷받침 안 됨

거의 모든 수렴 스레드의 첫 번째 제안이고, 보통 "최대 반복을 500 이상으로 늘려라"는 형태입니다. 9부의 실패 스텝에 test() 한도를 네 가지로 줘봅니다.

반복 한도사용한 횟수회복

305아니오

1005아니오

5005아니오

2,0005아니오

9부가 실패를 네 종류로 나눴는데 이것은 두 번째 종류입니다. 요소 자신의 상태 결정이 실패해서 전역 반복이 소진된 게 아니라 중단된 것입니다. 반복 한도는 첫 번째 종류에만 의미가 있습니다. testIter()가 여러분이 설정한 한도보다 한참 아래로 돌아온다면 한도는 문제가 아닙니다 — 그리고 그건 한 줄이면 확인됩니다.

2. "적분점을 늘리면 수렴이 나빠진다" — 조건부, 대체로는 아님

포럼에는 "적분 단면 수를 늘리는 것은 수렴 속도를 높이지 않는다. 정확도를 높이고 수렴은 오히려 나빠지게 한다"로 적혀 있습니다. Steel01 파이버 단면 캔틸레버, 경화 2%, 변위 120스텝으로 확인합니다.

적분점M / Mp반복실패 스텝

30.94121270

50.98551300

70.99151330

100.99091370

3점에서 10점으로 가면서 반복이 8% 늘었고 실패는 하나도 없었으며, 모멘트 내력은 소성모멘트의 94.1%에서 99.1%로 개선됐습니다. 이 모델에서 이 조언은 그냥 틀렸습니다.

어디서나 틀린 것은 아닙니다. 3부가 진짜 사례를 찾았습니다. 완전소성 단면의 forceBeamColumn에서 7점 이상이면 요소의 내부 루프가 수렴하지 못하고 보고된 단부 모멘트가 Mp를 447 kN·m 초과했습니다. 경화 2%를 주면 해결됐습니다. 그러니 정직한 형태는 좁습니다. 단면에 경화가 전혀 없을 때, 적분점을 늘리면 힘기반 요소의 내부 루프가 깨질 수 있다. 경화가 조금이라도 있으면 적분점 추가는 몇 퍼센트의 비용으로 정확도를 삽니다.

놓치기 쉬운 하드 리밋 하나: LobattoBeamIntegration -- max # integration points is 10.

3. "EnergyIncr가 더 강건하다" — 확인, 다만 중요한 단서와 함께

커뮤니티 수렴 도구 SmartAnalyze가 기본값으로 NormDispIncr가 아니라 EnergyIncr를 쓰는데, 이는 숙고된 한 표입니다. 9부의 실패 스텝에서:

판정허용오차시행결과

NormDispIncr1e-65실패

EnergyIncr1e-84회복

NormUnbalance1e-65실패

RelativeNormDispIncr1e-65실패

NormDispIncr1e-32회복

EnergyIncr는 다른 판정 셋이 못 넘은 스텝을 정말로 넘었습니다. 그런데 어떻게 넘었는지 보십시오. 다른 것들이 5개를 쓸 때 4개를 썼습니다. 요소를 깨뜨린 그 시행상태를 푼 것이 아니라, 그것을 제안하기 전에 스텝을 받아들인 것입니다. 느슨한 NormDispIncr는 같은 일을 더 거칠게, 2개로 했습니다.

이것이 9부의 서술 하나를 정정합니다. 그 글은 허용오차를 푸는 것이 "아무것도 달라지게 하지 않았을 것이다. 애초에 허용오차가 문제가 아니었으니까"라고 했습니다. 너무 강한 말이었고, 위 측정이 이유를 보여줍니다. 수렴 판정은 알고리즘이 언제 제안을 멈출지를 정하고, 더 일찍 멈추면 요소가 풀 수 없는 시행상태를 피해갈 수 있습니다. 9부를 수정했습니다. 근본 경고는 그대로이고 이제 더 잘 뒷받침됩니다. 더 멀리 가는 것과 옳은 것은 다릅니다. Tabas × 2.0으로 전체 기록을 돌리면 가장 느슨한 설정이 14초 창의 끝까지 가고 조인 것들은 11.455초에서 멈춥니다. 차이는 정확도가 아니라 해석이 얼마나 알아채기를 거부하느냐입니다.

4. "감쇠를 넣으면 수렴한다" — 뒷받침 안 됨

레일리 감쇠가 수렴 보조 수단으로 자주 제안됩니다. 같은 골조, 같은 강도, 다섯 구성:

감쇠실패까지 도달

5% 질량+강성11.455 s

5% 질량만11.295 s

2% 질량+강성11.255 s

감쇠 없음11.230 s

5% 강성만11.195 s

편차는 11.3초 중 0.26초, 약 2%이고, 감쇠를 완전히 없앤 경우가 최악도 아니었습니다. 감쇠는 응답을 바꾸고, 응답이 바뀌면 문제가 있는 자리가 조금 옮겨갑니다. 문제를 없애지는 않습니다. 모델에 감쇠가 있다면 그것은 모델링하려는 물리 때문에 있어야지, 예전에 어떤 해석을 끝나게 해준 적이 있어서 있으면 안 됩니다.

5. "탄성으로 남을 때까지 기록을 줄여라" — 콘크리트에서는 뒷받침 안 됨

본능은 진짜 좋습니다. 포럼에는 "먼저 선형 물성으로 모델을 돌려 비선형 응답에서 오는 문제를 배제하라"로, 그리고 흔히 "지진을 90% 줄여 구조물이 대체로 탄성으로 남게 하라"로 적혀 있습니다. 두 번째 형태는 파이버 콘크리트 모델에서 통하지 않고, 16부가 그것을 증명할 계기를 줍니다. 반복 횟수입니다.

배율시행 > 2 스텝최대 (m)최대/배율

0.022,800 중 3240.001230.06140

0.101,6180.007270.07274

0.402,0830.030770.07693

0.802,1860.066590.08324

기록의 2%, 즉 최대지반가속도 약 0.018 g에서 이미 324스텝이 시행상태를 둘 넘게 필요로 하고, 최대 응답은 40배 강도 범위에서 35.6% 비비례입니다. 축소해서 도달할 탄성 영역이 없습니다.

이유는 명령 하나로 보입니다. Concrete01을 손으로 인장 쪽으로 몰면 양의 변형률 전부에서 응력 0.0000, 접선 0.0을 보고합니다. 인장을 처음 보는 파이버 하나가 단면 강성을 바꾸고, 실제 기록에서는 그것이 즉시 일어납니다. 조언 자체는 여전히 따를 값어치가 있습니다. 다만 따르는 방법은 콘크리트 모델을 줄여놓고 바라는 게 아니라, section('Elastic', ...)로 진짜 탄성 대조 모델을 만드는 것입니다.

6. "파이썬 프로파일러가 시간이 어디로 가는지 보여준다" — 뒷받침 안 됨

OpenSees 개발자 Michael Scott이 블로그에서 지적합니다. 파이썬 프로파일러는 "ops.analyze()가 호출됐다는 것만 알려주지 그 안에서 무슨 일이 일어나는지는 알려주지 않는다." 해석 60스텝에 cProfile을 걸면 정확히 그렇습니다. 해석 전체가 한 줄로 나옵니다.

60 0.002 0.000 0.002 0.000 {built-in method openseespylinux.opensees.analyze}

60번 호출, 항목 하나, 구조 없음. 중요한 모든 것 — 조립, 상태 결정, 선형 풀이 — 이 프로파일러가 들어갈 수 없는 컴파일된 코드 안에서 일어납니다. Scott의 답은 리눅스 perf이고, 쓸모 있는 부분은 그의 두 사례입니다. 파이버 10만 개에서는 시간이 "파이버 단면 상태 결정과 재료 응력-변형률 응답"으로 갔고, 요소 100개에 조밀 솔버에서는 "LAPACK 서브루틴, 특히 dgemm"으로 갔습니다. 답은 그 둘뿐이고, 처방이 서로 다릅니다. 파이버를 줄이거나, 희소 솔버를 쓰거나.

7. "스크립트 언어가 속도를 좌우한다" — 뒷받침 안 됨

Scott이 Is OpenSees Pythonic?에서 다시 말합니다. OpenSeesPy가 컴파일된 비선형 알고리즘을 감싸고 있으므로 스크립트 실행 속도는 솔버 성능 옆에서 무시할 만하다고. 10부가 그 양쪽을 다 측정했습니다. 동일한 200만 회 루프가 Tcl에서 835 ms, 파이썬에서 203 ms — 실제로 4.12배 언어 차이 — 인데, 그 글의 240스텝 비선형 푸시오버에서 스크립트 언어가 차지한 실행시간은 1퍼센트의 몇 분의 일이었습니다.

같은 글은 Scott이 정당하다고 인정하는 유일한 비판 때문에도 읽을 값어치가 있습니다. OpenSeesPy에는 키워드 인자가 없어서 ops.uniaxialMaterial('Steel01', 8, 60, 29000, 0.01)이 위치 기반이고 순서에 민감합니다. 그는 이것을 파이썬과 Tcl 명령 집합을 동일하게 유지하기 위한 대가로 옹호하는데, 10부가 그 동일성을 240스텝 소성 경로에서 3.7 × 10⁻¹⁰ 일치로 측정했습니다. 그 거래는 값어치가 있었던 것으로 보입니다.

8. "OpenSees에는 단위가 없다" — 확인, 그리고 가장 먼저 적어야 할 것

커뮤니티의 가장 일관된 경고이고, Eurasian OpenSees basics에 분명히 적혀 있습니다. "OpenSees에는 단위가 없다. 일관된 입력 단위를 쓰라." 프레임워크의 어떤 것도 검사하지 않고 경고하지 않으며, 이 시리즈의 모든 글이 모든 스크립트 맨 위에 단위 줄을 다는 이유가 그것입니다. 11부가 단위 실수 하나의 대가를 측정했습니다. 단위중량 자리에 중력가속도를 넣자 연직응력이 ρ배 작게, 조용히 나왔습니다.

9. "순서가 중요하고 태그는 덮어쓰인다" — 절반만 맞음

문서는 "앞서 정의된 객체는 이미 Domain에 추가되어 있어야 한다"고 명시하고, 16부가 앞선 참조는 나중에 터지는 게 아니라 명확한 메시지로 거부된다는 것을 측정했습니다. 이 절반은 참입니다.

나머지 절반 — 태그를 재사용하면 앞선 객체가 조용히 덮어쓰인다는 것 — 은 거짓입니다. 16부는 반대를 측정했습니다. 두 번째 정의가 거부되고 첫 번째가 살아남습니다. 조용히 존재하지 않게 되는 쪽은 여러분의 새 정의입니다.

10. 좋은 조언이 사는 곳

어떤 팁 목록보다 값어치 있는 커뮤니티 자원이 셋 있습니다.

OpenSees Digital(구 Portwood Digital)은 OpenSees 개발자가 쓰며, 프레임워크 설계의 이유가 적혀 있는 유일한 곳입니다. 어떤 거동이 임의로 보인다면 대개 거기 설명이 있습니다. 도메인이 이전했으니 옛 portwooddigital.com 링크는 리다이렉트됩니다.

Hanlin Dong의 SmartAnalyze와 그 후손인 opstool은 9부가 손으로 만든 회복 캐스케이드를 패키지로 만들어둔 것입니다. 반복 허용을 늘리고, 알고리즘을 바꾸고, 스텝을 나누는 그 순서입니다. 그 루프를 직접 쓰고 있다면 먼저 그쪽을 읽으십시오.

OpenSees Community 포럼은 20년치 아카이브이고, 여러분과 정확히 같은 경고 메시지를 만난 사람을 찾기에 여전히 가장 좋은 곳입니다. 메시지 텍스트를 그대로 검색하십시오.

11. 조언을 다루는 법

처방을 적용하기 전에 testIter()를 읽으십시오. 한도보다 아래면 한도에 관한 조언은 전부 해당 없습니다.

어떤 변경이 해석을 "되게" 만들면, 그것이 무엇을 알아채지 못하게 만들었는지 물으십시오.

규칙이 딸려오는 조언보다 돌려볼 수 있는 모델이 딸려오는 조언을 택하십시오.

"수렴했다"를 가장 약한 증거로 취급하십시오. 남의 작업에서도, 자기 작업에서도.

팁이 측정과 어긋나면 측정이 이깁니다. 그 측정이 제 것일 때도 마찬가지입니다.

마지막 줄은 수사가 아닙니다. 이 글을 쓰면서 9부가 바뀌었습니다. 허용오차에 관한 너무 강한 서술을 정정했는데, 제가 배제했던 방식으로 커뮤니티의 주장이 옳았기 때문입니다.

전체 스크립트

2절의 적분점 주장을, 여러분의 단면에 대고 직접 돌려볼 수 있는 스크립트로.

# Part 17 - "more integration points hurts convergence", measured # units: kN, m import openseespy.opensees as ops B, H, FY, ES = 0.20, 0.30, 400000.0, 2.0e8 MP = FY * B * H**2 / 4.0 # plastic moment of the fibre section LEN, STEPS, DU = 3.0, 120, 0.0006 def pushover(npts, b): ops.wipe(); ops.model('basic', '-ndm', 2, '-ndf', 3) ops.uniaxialMaterial('Steel01', 1, FY, ES, b) ops.section('Fiber', 1) ops.patch('rect', 1, 24, 4, -H/2, -B/2, H/2, B/2) ops.node(1, 0., 0.); ops.node(2, 0., LEN); ops.fix(1, 1, 1, 1) ops.geomTransf('Linear', 1) ops.beamIntegration('Lobatto', 1, 1, npts) ops.element('forceBeamColumn', 1, 1, 2, 1, 1) ops.timeSeries('Linear', 1); ops.pattern('Plain', 1, 1); ops.load(2, 1., 0., 0.) ops.constraints('Plain'); ops.numberer('Plain'); ops.system('BandGeneral') ops.test('NormDispIncr', 1e-8, 100); ops.algorithm('Newton') ops.integrator('DisplacementControl', 2, 1, DU); ops.analysis('Static') iters = 0; fails = 0; V = [] for _ in range(STEPS): if ops.analyze(1) != 0: fails += 1; break iters += ops.testIter(); V.append(ops.getLoadFactor(1)) return {'npts': npts, 'iters': iters, 'fails': fails, 'M_over_Mp': (max(V) * LEN / MP) if V else 0.0, 'steps': len(V)} for b, label in ((0.02, '2% hardening'), (0.0, 'perfectly plastic')): print(f'\n{label} (plastic moment {MP:.1f} kN m)') print(f"{'points':>7s}{'steps':>7s}{'fails':>7s}{'iterations':>12s}{'M / Mp':>10s}") rows = [] for n in (3, 4, 5, 6, 7, 8, 10): # Lobatto allows at most 10 r = pushover(n, b); rows.append(r) print(f"{n:7d}{r['steps']:7d}{r['fails']:7d}{r['iters']:12d}{r['M_over_Mp']:10.4f}") if b == 0.02: assert all(r['fails'] == 0 for r in rows), 'with hardening nothing should fail' assert rows[-1]['M_over_Mp'] > rows[0]['M_over_Mp'], 'accuracy should improve' cost = rows[-1]['iters'] / rows[0]['iters'] print(f' -> 3 to 10 points: no failures, {100*(cost-1):.0f}% more iterations, ' f"accuracy {rows[0]['M_over_Mp']:.4f} -> {rows[-1]['M_over_Mp']:.4f}") print('\nOK on this model the claim does not hold; Part 3 gives the case where it does')

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

2% hardening (plastic moment 1800.0 kN m) points steps fails iterations M / Mp 3 120 0 127 0.9412 4 120 0 129 0.9747 5 120 0 130 0.9855 6 120 0 131 0.9897 7 120 0 133 0.9915 8 120 0 133 0.9909 10 120 0 137 0.9909 -> 3 to 10 points: no failures, 8% more iterations, accuracy 0.9412 -> 0.9909 perfectly plastic (plastic moment 1800.0 kN m) points steps fails iterations M / Mp 3 120 0 127 0.9314 4 120 0 128 0.9588 5 120 0 129 0.9695 6 120 0 132 0.9736 7 120 0 135 0.9758 8 120 0 133 0.9767 10 120 0 139 0.9777 OK on this model the claim does not hold; Part 3 gives the case where it does

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부 — 면진과 감쇠: 속도 의존 요소와 베어링

참고 자료

Scott, M. H., Is OpenSees Pythonic?, How to Profile an OpenSeesPy Analysis.

Dong, H., SmartAnalyze, opstool — 커뮤니티 수렴 도구.

OpenSees Community 포럼 — 1·2·5절에서 인용한 수렴 스레드.

Eurasian OpenSees, Basics — 8절의 단위 경고.

OpenSees Documentation — 구축 순서.

PyPI의 opensees — 전역 상태 없는 실험적 바인딩.

출처 확인 2026-08-31. 모든 판정은 명시한 모델에 대해 OpenSeesPy 3.8.0으로 측정한 것이며 일반 결과가 아닙니다. 3층 철근콘크리트 골조에서 뒷받침되지 않은 주장이 다른 곳에서는 성립할 수 있고, 2절이 같은 주장이 다른 전제에서 참인 사례를 명시적으로 제시합니다. 포럼 스레드와 블로그 인용은 출처로 링크했습니다. 결과는 프레임워크의 거동을 보여주는 것으로, 프로젝트별 해석이나 설계기준 검토를 대체하지 않습니다.