docs: define consistent-mass HHT dynamics contracts
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
# HHT dynamic reference 비교 계약
|
||||
|
||||
- Feature: `hht-implicit-dynamics`; 정적 inventory·초안 작성: 메인 assistant; 수치 비교 검토: numerical-review-agent.
|
||||
- 상태: `numerical-contract-reviewed; io-binding-and-solver-execution-pending`.
|
||||
- 기준: [요구사항](requirements.md), [정식화](formulation.md), [수치 검토](numerical-review.md), [공통 TOLERANCE](../TOLERANCE.md).
|
||||
|
||||
## 1. 원본과 모델 의미
|
||||
|
||||
입력은 [shellNL-dyn-meshfine.inp](../../reference/shellNL-dyn-meshfine/shellNL-dyn-meshfine.inp), 외부 결과는 같은 폴더의 [shellNL-dyn-meshfine displacements.csv](<../../reference/shellNL-dyn-meshfine/shellNL-dyn-meshfine displacements.csv>)다. 원본 이름·내용을 보존한다. 공식 FESA 출력은 입력의 lexical sibling `shellNL-dyn-meshfine_results.h5`이며 dataset path와 schema는 후속 I/O 소유다. [HHT-ADR-007](ADR.md)의 **consistent kinetic mass**와 시간적분 계약을 결과 identity에 연결해야 하며 비교 결과에 따라 variant를 바꾸지 않는다.
|
||||
|
||||
CSV에는 step column이 없다. 원본 INP의 **유일한 dynamic step `Step-1`**과의 연결이 step authority다. 다른 step이나 reference를 파일명으로 추정하지 않는다.
|
||||
|
||||
| 직접 확인한 항목 | 값·의미 |
|
||||
| --- | --- |
|
||||
| 모델 | 729 nodes, 676 S4, global x/y 범위 `[-5,5]`, z=0, 중심 node 2는 `(0,0,0)` |
|
||||
| section/material | 두께 `0.5`, E=`2.1e11`, nu=`0.3`, rho=`2700`; 일관된 입력 단위계이며 SI 선언으로 간주하지 않음 |
|
||||
| 경계 | 외곽 `Set-2`의 104 nodes에서 DOF 1–6 고정; 자유 node 625개 |
|
||||
| 하중 | 중심 `Set-1`/node 2의 global 1–3 각각 `-100000`, amplitude·follower·물리 damping 입력 없음 |
|
||||
| 절차 | `NLGEOM=YES`, `INC=1000`, `*Dynamic,direct`, 데이터 `0.1,10.` |
|
||||
| 시간·결과 | increment 0–100, time 0–10, 101 frames, frame당 9 nodes, U/UR 6성분 |
|
||||
| DOF 수 | full 4374, constrained 624, free 3750 |
|
||||
| 질량의 해석적 예상 | 이 평면·고정경계에서 positive mass dimension 3125와 drilling null dimension 625. 실제 조립 행렬의 rank를 측정한 결과는 아님 |
|
||||
|
||||
## 2. Quantity와 stable row identity
|
||||
|
||||
CSV의 필수 column은 `Frame`, `Part Instance Name`, `Node Label`, `U-U1`, `U-U2`, `U-U3`, `UR-UR1`, `UR-UR2`, `UR-UR3`다. Header/field의 외곽 공백 처리는 구문 처리이며 reference 수치를 수정하지 않는다. Header가 중복되거나 필수 column이 없으면 실패한다.
|
||||
|
||||
`Frame`은 `Increment <n>: Step Time = <decimal>` 구조로 읽는다. 이 원본에서는 `n=0..100`이며 decimal time이 정확히 `n/10`이다. 단일 step 연결과 함께 logical scalar key를 다음으로 고정한다.
|
||||
|
||||
`(case, source step=Step-1, source increment=n, instance=PART-1-1, node label, quantity, component)`
|
||||
|
||||
비교 대상 label은 오름차순 `2,21,22,69,70,165,309,442,586`다. 이들은 중심과 `x/y=0, ±0.384615391`의 주변 3×3 절점군이다. CSV의 행 위치, internal node index, equation index 또는 변위의 크기는 identity가 아니다. 행 재정렬은 허용하되 동일 key의 두 행을 합치거나 평균하지 않는다.
|
||||
|
||||
| Quantity | 원본 column | FESA logical quantity·좌표 | 차원 | 판정 영향 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| U-global | `U-U1/U-U2/U-U3` | global translation U1/U2/U3 | length | blocking |
|
||||
| UR-global | `UR-UR1/UR-UR2/UR-UR3` | fixed-initial global total rotation-vector components | rad | warning-only |
|
||||
|
||||
양쪽 회전의 내부 업데이트 알고리즘이 같다는 주장은 하지 않는다. 비교는 지정된 observable component의 수치 대조다. 이 warning-only 분류는 FESA 내부 회전 운동학의 correctness 면제가 아니다.
|
||||
|
||||
## 3. Time 및 projection 사전검사
|
||||
|
||||
먼저 reference의 frame 101개, 매 frame의 동일 instance/node inventory와 decimal time을 검증한다. 공식 결과의 완료된 한 dynamic step에서 초기 frame 및 increment 1–100을 요구한다. Newton iteration이나 rejected trial은 frame으로 대응시키지 않는다.
|
||||
|
||||
정식화의 `t_n=n h`에 따라 FESA의 source increment와 scheduled time을 함께 검사한다. 이 고정 reference에서 binary64 결과 시간은 `double(n)*double(h)`로 생성한 schedule과 일치하도록 I/O 계약에 연결한다. CSV의 표시 decimal을 먼저 binary64로 변환한 값과 직접 bit 비교하지 않는다. 최근접 시간 선택, 서로 다른 시간의 보간, 시간 순서 재배치 또는 임의 absolute time tolerance를 쓰지 않는다. 최종 timestamp 표현·field binding은 I/O owner가 이 의미를 보존하여 확정한다.
|
||||
|
||||
공식 HDF5가 전체 729 nodes를 포함하는 것은 정상이다. 전체 결과의 고유 identity와 필수 finite 값 검사를 먼저 수행하고, **고정된 9-node subset**으로 projection한 양쪽 scalar row inventory를 비교한다. Reference에 추가 node나 frame이 있으면 subset으로 조용히 버리지 않는다. Projected FESA에 필요한 행이 없거나 중복·추가가 생기면 실패한다. 다른 물리 quantity의 정상 존재는 U/UR 행의 추가로 분류하지 않는다.
|
||||
|
||||
다음은 tolerance 이전의 blocking 오류다.
|
||||
|
||||
- 필수 파일·step·dataset·component 누락, wrong procedure/mass identity, 잘못된 frame/time.
|
||||
- 필수 row의 missing/extra/duplicate, instance/node/component identity 불일치.
|
||||
- 필수 U/UR의 NaN/Inf, malformed label/number 또는 비교할 수 없는 회전 의미.
|
||||
- 공식 결과에 failed/trial frame이 accepted frame으로 노출됨.
|
||||
|
||||
UR가 warning-only여도 schema·identity·finite 오류는 전체 비교를 실패시킨다. 결과가 없는 상태를 zero 응답으로 채우지 않는다.
|
||||
|
||||
## 4. Comparison family와 수치 판정
|
||||
|
||||
각 frame에 `U-global:Step-1:increment-n`과 `UR-global:Step-1:increment-n` 두 family를 둔다. 각 family는 9 nodes × 3 components = 27 scalars다. 전체 202 families이며 U 2727 scalars, UR 2727 scalars를 모두 검사한다. 서로 다른 시간의 값을 한 family로 합치지 않는다.
|
||||
|
||||
[TOLERANCE](../TOLERANCE.md)의 `S=max|reference|`, near-zero band `0.01S`, 일반 행 relative limit `0.05`, family relative RMS limit `0.01`을 그대로 적용한다. `S=0`은 FESA도 exact zero여야 한다. Eigen 전용 RMS 5% 예외를 사용하지 않는다.
|
||||
|
||||
초기 frame의 두 family는 모두 exact zero다. 비초기 frame에서 직접 집계한 S의 범위는 U `[7.04349895e-6,4.91895989e-5]`, UR `[9.65224785e-7,6.88441514e-6]`다. 이 범위는 원본 audit 결과이지 fixed absolute tolerance가 아니다. 매 frame의 실제 reference 값으로 S를 다시 계산한다.
|
||||
|
||||
보고 순서는 step, increment, quantity(U→UR), instance, node label, component 1→3으로 결정적이다. 모든 행의 원값·오차·near-zero/relative 분류·행 판정, family scale/RMS/판정, warning 및 최종 blocking verdict를 기록한다. 최종 frame 또는 peak 값만의 보고로 전체 이력을 대신하지 않는다.
|
||||
|
||||
## 5. Coverage와 실행 상태
|
||||
|
||||
원본 INP/CSV를 Python 표준 라이브러리로 읽어 inventory, decimal time, 909 unique rows, finite 성분, 202 families와 초기 zero를 검증했다. Source mesh/BC를 대조했고 원본 bytes가 조사 전후 동일함을 확인했다. 이것은 **reference 준비 상태의 정적 확인**이다. FESA dynamic 해석·HDF5 비교·Abaqus 실행은 미실행이다.
|
||||
|
||||
현재 reference는 중심 주변 변위·회전만 제공한다. 전판 응답, 경계 반력, V/A, 운동량·에너지, 큰 회전 관성과 hidden constraint에는 별도 [검증 사례](verification-cases.md)가 필요하다. `dt/T1≈7.4567`인 성긴 시간간격 때문에 이 CSV의 일치만으로 transient phase 정확도나 시간 수렴을 주장하지 않는다.
|
||||
Reference in New Issue
Block a user