220 lines
18 KiB
Markdown
220 lines
18 KiB
Markdown
# MITC4 eigen authoritative HDF5 schema
|
||
|
||
- Feature ID: `mitc4-shell-feast-eigen`
|
||
- Owner: `io-definition-agent`
|
||
- Input contract revision: `r2`
|
||
- 기본 보고서: [io.md](io.md)
|
||
- 수학: [E1~E8](formulation-eigen.md), [V1~V6](formulation-verification.md)
|
||
- Numerical authority: [C1~C6](numerical-review-controls.md)
|
||
|
||
## O1. Container, version과 공통 규칙
|
||
|
||
공식 결과는 input lexical sibling `<stem>_results.h5`다. 기존 linear schema0와 nonlinear
|
||
schema1은 각각의 [현행 static 계약](../shell-surface-pressure-load/io.md#71-version-and-filename-decision)을
|
||
유지한다. Eigen은 기존 shell model container에 새 procedure를 추가하며 discriminant는
|
||
`(schema_version=0, feature_id=mitc4-shell-feast-eigen, analysis_procedure=linear-frequency,
|
||
eigen_schema_version=1)`이다. `eigen_schema_version`은 새 procedure 전용 revision이다.
|
||
Static reader가 schema_version만 보고 eigen을 static으로 해석해서는 안 된다.
|
||
기존 static 파일에 새 eigen mandatory fields를 요구하거나 재작성/migration하지 않는다.
|
||
앞으로 unknown additive optional field는 무시할 수 있지만 known field의 type/의미 변경,
|
||
unknown procedure 또는 eigen_schema_version은 reader의 명시적 unsupported schema 실패다.
|
||
|
||
Float는 `H5T_IEEE_F64LE`, unsigned/signed integer는 명시된 `H5T_STD_U{8,64}LE`/
|
||
`H5T_STD_I64LE`, string은 variable-length UTF-8이다. Compound field의 byte offset/padding은
|
||
private이며 field name/type/array extent가 authoritative다. Shape의 `nn,ne,nmat`는 model
|
||
node/element/material 수, `N`은 입력 요청, `c`는 최종 solve의 전체 검증 column 수,
|
||
`Lcalls`는 모든 actual FEAST calls 수다. 모든 shape/capacity는 checked integer다.
|
||
|
||
새 numeric dataset의 required attrs는 `schema_version=0`, `eigen_schema_version=1`,
|
||
`component_names`, `component_unit_dimensions`, `coordinate_system`, `location`이다.
|
||
Compound에서 component attrs는 수치 quantity fields만 table의 명시 순서로 나열하고
|
||
identity/flag/counter는 schema 정의를 따른다. 새 modal result에는 추가로
|
||
`step_name=Step-1`, `source_step_name=<raw source>`, `domain=mode`를 기록한다.
|
||
Tokenized dimension은 아래 `mass`, `length`, `time`를 사용하며 SI label을 붙이지 않는다.
|
||
모든 mandatory physical/검증 real 값은 finite다. Optional backend diagnostic의
|
||
unavailable는 O4의 명시적 validity flag만 사용한다. NaN payload를 공개하지 않는다.
|
||
|
||
## O2. Metadata, 모델과 source 요청
|
||
|
||
`/metadata`의 아래 attributes는 mandatory다.
|
||
|
||
| Attribute | Type / 값 |
|
||
| --- | --- |
|
||
| `schema_version`, `eigen_schema_version` | uint64 `0`, `1` |
|
||
| `feature_id`, `analysis_procedure` | UTF-8 `mitc4-shell-feast-eigen`, `linear-frequency` |
|
||
| `solver_version` | 실제 실행 binary의 기존 version string |
|
||
| `source_input_identity` | 기존 `path=<absolute lexical generic path>;content_identity=fnv1a64:<16 lower hex>`; parser가 실제 읽은 원본 bytes 기준 |
|
||
| `unit_system_label` | `user-consistent-unspecified` |
|
||
| `coordinate_convention` | `global-cartesian; shell-local=initial-reference; positive-thickness=+zeta` |
|
||
| `internal_formulation` | `FESA-MITC4` |
|
||
| `integration_rule`, `mass_integration_rule` | `2x2x2-gauss; mitc4-edge-midpoint-shear`, `3x3x3-gauss` |
|
||
| `stabilization_rule` | `initial-physical-rotary-trace-mean-r2` |
|
||
| `step_name`, `source_step_name`, `frame_indexing` | `Step-1`, raw input name(현재 Step-2), `mode-rank-one-based` |
|
||
| `mass_variant`, `mass_origin`, `normalization` | `derived-lumped`, `consistent-moment-row-sum`, `mass` |
|
||
| `eigensolver_backend`, `eigensolver_routine` | `MKL FEAST`, `dfeast_scsrgv` |
|
||
| `backend_problem` | `scaled-whitened-lumped-with-identity-mass` |
|
||
| `numerical_contract` | `mitc4-shell-feast-eigen:r2` |
|
||
|
||
Source identity는 [현재 writer primitive](../../src/fesa/io/hdf5/hdf5_primitives.cpp)의 byte
|
||
identity와 동일하다. SHA-256 reference audit와 FNV source identity는 다른 목적이다.
|
||
Filename만으로 동일 input이라고 간주하지 않는다. Comparator는 실제 지정 input bytes의
|
||
content identity와 lexical input path를 metadata에 대조한다.
|
||
|
||
| Dataset | Shape/type와 fields | Identity·단위·ordering |
|
||
| --- | --- | --- |
|
||
| `/model/nodes` | `[nn]` 기존 compound: `internal_node_id:u64,instance_name:utf8,source_label:utf8,coordinates:f64[3]` | Internal ID 0..nn-1, 기존 instance expansion/declaration order; coordinates length, global-cartesian |
|
||
| `/model/elements` | `[ne]` 기존 shell compound: `internal_element_id:u64,instance_name:utf8,source_label:utf8,source_element_type:utf8,internal_formulation:utf8,node_internal_ids:u64[4],shell_section_internal_id:u64,material_internal_id:u64` | Internal ID order; source S4/S4R 구별; formulation FESA-MITC4 |
|
||
| `/model/shell/materials` | `[nmat]` 기존 compound: `internal_material_id:u64,name:utf8,E:f64,nu:f64` | Declaration order; E force/length^2, nu1. 기존 field에 rho를 끼워 넣지 않음 |
|
||
| `/model/shell/sections` | 기존 compound: `internal_section_id:u64,source_file:utf8,source_line:u64,source_elset:utf8,material_internal_id:u64,thickness:f64` | Declaration order, thickness length, centered-single-layer |
|
||
| `/model/shell/nodal_director`, `/model/shell/nodal_frame` | `[nn,3]`, `[nn,3,3]` f64 | 기존 source node rows; D components, frame axes A/B/D×global X/Y/Z, dimension1 |
|
||
| `/model/nodal_constraint_mask` | `[nn,6]` u8 | Existing DOF order UX,UY,UZ,URX,URY,URZ; free0/constrained1 |
|
||
| `/model/prescribed_displacement` | `[nn,6]` f64 | 같은 DOF order, 모든 값 exact0; units length×3,radian×3 |
|
||
| `/model/shell/densities` | `[density_count]` 새 compound: `material_internal_id:u64,rho:f64,source_file:utf8,source_line:u64` | Material ID ascending, rho mass/length^3, location model-material; declared density별 한 row, 활성 material 모두 존재 |
|
||
| `/model/eigen/source_records` | `[record_count]` compound: `ordinal:u64,source_line:u64,keyword:utf8,physical_text:utf8` | 아래 source provenance 대상의 실제 physical line 순서, ordinal0부터 |
|
||
| `/diagnostics` | `[diagnostic_count]` 기존 compound: `severity:utf8,code:utf8,file:utf8,line:u64,keyword:utf8,entity_identity:utf8,message:utf8` | 기존 SortDiagnostics 순서. 성공 파일에는 warning만 존재 |
|
||
|
||
공통 model dataset의 기존 attrs는 [linear model schema](../linear-static-mitc4-shell/io.md)와
|
||
[현재 writer](../../src/fesa/io/hdf5/hdf5_model_writer.cpp)를 따른다. Eigen-specific attrs는
|
||
새 dataset에만 필수이며 기존 static dataset type/attrs를 바꾸지 않는다.
|
||
기존 model-only midsurface_locations/section_positions를 공유 writer가 추가 저장해도 허용하나
|
||
eigen result/acceptance quantity는 아니며 eigen의 mandatory replay dataset이 아니다.
|
||
|
||
`source_records` 대상은 STEP, FREQUENCY(그 count data 포함), DENSITY(data 포함), I5
|
||
no-op keyword와 그 parameter-continuation physical lines다. Comments는 포함하지 않는다.
|
||
`keyword`는 canonical parent keyword이고 `physical_text`는 CR/LF를 제거한 원문이다.
|
||
Frequency 선언 유무·blank slot 수·raw values를 여기서 보존한다. 물리 domain의 기준은
|
||
validated semantic fields이며 output consumer가 raw text를 다시 실행하지 않는다.
|
||
|
||
`/steps/Step-1` group attrs는 아래와 같다. Canonical group명과 source name을 구분한다.
|
||
|
||
| Attribute | Type / 의미 |
|
||
| --- | --- |
|
||
| `source_step_name`, `source_step_name_canonical` | utf8 raw name / ASCII uppercase key |
|
||
| `step_source_line`, `frequency_source_line`, `frequency_data_line` | u64 실제 source1-based line |
|
||
| `source_nlgeom`, `source_perturbation_present` | u8 effective NO=0 / explicit flag 유무0 또는1 |
|
||
| `source_eigensolver`, `source_sim`, `source_acoustic_coupling`, `source_normalization` | utf8 effective `LANCZOS,YES,ON,MASS`; explicit/omitted는 source_records에서 구분 |
|
||
| `requested_mode_count`, `returned_mode_count` | u64 N,N; table row수로 입력 N을 덮어쓰지 않음 |
|
||
| `full_dof_count`, `free_dof_count`, `mass_null_dimension`, `finite_dimension` | u64 6nn,nf,nz,n, nf=n+nz |
|
||
| `validated_eigenpair_count` | u64 c, N<=c<=n; publicly returned mode 수와 구별 |
|
||
|
||
## O3. 고유치와 modal vectors
|
||
|
||
Path prefix는 `/steps/Step-1/eigen`이다. `modes`만 공개 eigenvalue row authority다.
|
||
|
||
| Relative dataset | Shape/type/fields | 의미·attrs |
|
||
| --- | --- | --- |
|
||
| `modes` | `[N]` compound `mode_id:u64,eigenvalue:f64,classification:u8,cluster_id:u64` | Row k는 mode_id=k+1; quantity=eigenvalue, component_names=Value, component_unit_dimensions=time^-2, coordinate_system=scalar, location=modal-frame |
|
||
| `frequencies` | `[Nv]` compound `mode_id:u64,frequency:f64` | 정확히 lambda>=0인 modes의 ID subset, mode ID ascending. quantity=cycle-frequency, component_names=Freq, dimension=time^-1, scalar/modal-frame; mandatory dataset이며 Nv=0도 유효 |
|
||
| `vectors` | `[N,nn,6]` f64 | mode axis는 modes와 동일, node axis는 model/nodes, component_names=UX,UY,UZ,URX,URY,URZ; global-cartesian, location=nodal-modal-vector |
|
||
|
||
`vectors.component_unit_dimensions`는 `mass^-1/2` 세 개와 `mass^-1/2*length^-1` 세 개다.
|
||
추가 attrs `normalization=mass`, `amplitude_unit_dimension=mass^1/2*length`,
|
||
`mass_variant=derived-lumped`, `interpretation=normalized-mode-not-response-displacement`를 둔다.
|
||
각 node의 세 회전 성분은 initial global infinitesimal rotation coordinates다. Constrained
|
||
component는 exact0이며 source node label을 internal/equation index로 바꾸지 않는다.
|
||
기존 `/nodal/displacement`, reaction, stress, nonlinear accepted_frames를 modal 결과로 생성하지 않는다.
|
||
Full matrices/consistent matrix/modal stress를 영속 mandatory output으로 추가하지 않는다.
|
||
|
||
Raw lambda의 오름차순 stable paired sort와 exact tie의 original FEAST column 순서를 따른다.
|
||
Sign은 [C4](numerical-review-controls.md#c4-repeated-subspace와-결정론)대로 largest absolute
|
||
scaled global component(translation/ell,rotation)의 양수, tie는 source DOF 순서다.
|
||
여기서 source DOF 순서는 model/nodes의 stable row order×정해진 component order다.
|
||
Cluster는 전체 c sorted columns에서 C4의 connected rule로 1부터 매기고 첫 N개에 같은 ID를
|
||
투영한다. Cluster ID는 진단용이며 값을 평균하거나 결과 multiplicity를 줄이지 않는다.
|
||
|
||
`operator_scale=s`는 O4에 저장한다. `mu=lambda/s`에서 `mu<-1e-9`는 성공 파일을 만들 수
|
||
없는 negative spectrum failure다. `abs(mu)<=1e-9`이면 classification=0(`near-zero`),
|
||
그 외는 classification=1(`positive`)이다. Raw lambda와 부호를 그대로 기록하며 ±boundary는
|
||
near-zero다. Frequency는 classification이 아닌 raw lambda 부호로 결정한다:
|
||
lambda>0이면 sqrt(lambda)/(2pi), lambda==0이면 exact0, lambda<0이면 row가 없다.
|
||
따라서 small positive near-zero에도 real frequency가 있고 small negative에는 없다.
|
||
Negative row의 부재 이유는 `frequencies@unavailable_rule=negative-raw-eigenvalue`로 명시한다.
|
||
Frequency overflow/양수의 underflow-to-zero도 파생 결과 실패로 처리한다. Mandatory lambda
|
||
및 mu→lambda conversion은 C3의 finite/underflow 조건을 그대로 따른다.
|
||
|
||
## O4. Backend와 검증 evidence
|
||
|
||
Prefix `/steps/Step-1/eigen/verification`의 attrs:
|
||
|
||
| Attribute | Type / 의미 |
|
||
| --- | --- |
|
||
| `characteristic_length`, `operator_scale` | positive finite f64 ell[length], s[time^-2] |
|
||
| `eta_gram`, `max_eta_orth` | finite f64, 전체 c의 V3 Gram와 pairwise 최대 metric; c=1이면 max_eta_orth=0 |
|
||
| `eta_mz`, `eta_kz`, `eta_pz`, `null_checks_applicable` | f64×3 및 u8; nz=0이면 applicable0와 storage값0, N/A이지 수행 통과로 보고하지 않음 |
|
||
| `validation_scope`, `numerical_contract` | utf8 `all-computed-c-columns`, `mitc4-shell-feast-eigen:r2` |
|
||
|
||
| Dataset | Fields / shape | 의미 |
|
||
| --- | --- | --- |
|
||
| `verification/nodal_reduction` | `[nn]` compound `free_count:u8,null_count:u8,positive_count:u8,rcond_available:u8,rcond_inf:f64` | Source node row 대응; E2 analytic counts. Nonempty positive block에 rcond_available1, C2 cutoff 통과; 빈 block은0/0 storage. nf/nz/n과 합 일치 |
|
||
| `verification/eigenpair_checks` | `[c]` compound `sorted_rank:u64,solver_column:u64,eigenvalue:f64,modal_mass:f64,rayleigh_quotient:f64,eta_r:f64,eta_w:f64,rho_b:f64,eta_norm:f64,eta_energy:f64,backend_res_available:u8,backend_res:f64` | sorted_rank1..c, solver_column은 원 FEAST column0-based unique; 실제 ML의 V3/V4/C3 metrics. 첫 N ranks의 lambda는 modes와 exact equal |
|
||
|
||
Nodal reduction의 quantity component는 `rcond_inf`, dimension1, coordinates=scalar,
|
||
location=nodal-mass-reduction이다. Eigenpair checks의 component_names는 표의 f64 fields
|
||
순서이고 dimensions는 eigenvalue와 rayleigh_quotient만 time^-2, 나머지는1이다.
|
||
Coordinates=scalar, location=eigenpair-verification이며 mandatory finite 검증량과
|
||
optional backend_res의 validity를 구분한다.
|
||
|
||
`eigenpair_checks`는 내부 count/검증 evidence다. c>N 진단행은 추가 공개 modal frame이
|
||
아니며 comparator는 여기서 Value를 추출하지 않는다. c개 vector 전부는 검사 동안 유지하고
|
||
accepted state에는 공개 N개 vector와 전체 c의 check evidence를 보존한다. 전체 c Gram의
|
||
runtime/독립 검증은 C17/18 evidence로 확인하며 N개 persistent vectors만으로 full-c Gram를
|
||
재검산했다고 주장하지 않는다. N개 원 residual/normalization은 model 데이터에서 K/ML를
|
||
독립 재구성하여 재현할 수 있다. Consistent/lumped 독립 oracle는 NR cases의 내부 테스트다.
|
||
|
||
Backend `res`가 0-eigenvalue의 상대분모 때문에 unavailable인 경우만
|
||
backend_res_available0, backend_res storage0을 사용하고 dataset attr
|
||
`unavailable_reason=zero-eigenvalue-relative-residual`를 둔다. Available 값은 finite이고,
|
||
nonzero eigenvalue의 nonfinite backend diagnostic은 failure다. Storage0을 residual evidence0으로
|
||
해석하지 않는다. mandatory eta_*는 모든 경우 자체 zero branch와 함께 finite다.
|
||
|
||
Prefix `/steps/Step-1/eigen/backend` attrs는 `runtime_version:utf8`(실제 MKL query),
|
||
`integer_abi:utf8`(`LP64|ILP64` 실제 linked ABI), `thread_count:u64=1`,
|
||
`seed:u64=0x4D495443344D4645`, `count_calls:u64`, `solve_calls:u64`,
|
||
`final_count:u64=c`, `final_solve_ordinal:u64`, `selected_ranks:utf8=1..N`,
|
||
`enclosure_lower:f64`, `enclosure_upper:f64`, `solve_lower:f64`, `solve_upper:f64`다.
|
||
Bounds는 모두 dimensionless B-space이며 physical frequency bound가 아니다.
|
||
|
||
| Relative dataset | Shape / fields | 의미 |
|
||
| --- | --- | --- |
|
||
| `calls` | `[Lcalls]` compound `ordinal:u64,kind:utf8,purpose:utf8,lower:f64,upper:f64,allocated_m0:u64,info:i64,count_available:u8,count:u64,loop_available:u8,loop:u64,epsout_available:u8,epsout:f64` | ordinal0-based 실제 call 순서; kind=count/solve, strict bounds, 실제 allocated capacity. Count의 overwritten m0와 solve의 m을 count로 구분 저장 |
|
||
| `fpm` | `[Lcalls,128]` i64 | 각 call 직전 feastinit 이후의 exact parameter snapshot; vendor type을 public core에 노출하지 않음 |
|
||
|
||
`purpose`는 `total-enclosure`, `upper-prefix`, `lower-prefix`, `endpoint-guard`,
|
||
`final-prefix`, `final-interval`, `solve` 중 하나이며 실제 C5 단계에 대응한다.
|
||
Calls의 component_names는 `lower,upper,epsout`, dimensions는 `1,1,1`,
|
||
coordinates=scalar, location=backend-call이다. Fpm은 component_names=fpm,
|
||
dimension1, coordinates=none, location=backend-parameter이며 128개 C-index 순서다.
|
||
Calls의 unavailable output은 flag0+storage0이고 원인을 info로 해석한다. Undefined vendor
|
||
output을 읽거나 garbage를 저장하지 않는다. `info=0`이면 count_available1; 성공 solve는
|
||
loop/epsout도 available1이고 epsout finite. 내부 허용 재시도의 실패 call도 삭제하지 않는다.
|
||
최종 성공과 C5 guard/prefix/total count 관계는 chronological calls/bounds로 재구성 가능해야 한다.
|
||
Allocated_m0와 input N은 독립이다. Effective fpm와 seed/budget은 C5/C6와 일치해야 한다.
|
||
Count-only res/epsout을 fabricated physical result로 사용하지 않는다.
|
||
|
||
## O5. Self-check와 compatibility tests
|
||
|
||
Writer는 candidate를 flush/close한 뒤 read-only reopen하여 type/field/shape/required attrs,
|
||
finite required values, enum/validity domains 및 다음 관계를 확인하고 검사용 handle도 닫는다.
|
||
|
||
1. Source identity·input semantic snapshot이 writer 입력과 일치한다. Node/element/material IDs,
|
||
connectivity/section/material/density links가 unique/in-range이고 모든 활성 material rho>0이다.
|
||
2. Source step은 한 개이고 canonical Step-1과 raw name의 관계가 유일하다. Input N,
|
||
requested N, returned N, modes/vector row수가 같다. mode IDs는 정확히1..N이다.
|
||
3. Modes가 raw 오름차순이며 classification/cluster는 C3/C4 규칙과 맞는다. Frequencies의
|
||
ID set은 lambda>=0 set과 exact equal이며 각 값은 candidate 파생값과 같고 finite다.
|
||
4. Vectors는 finite, source constraint component exact0, scalar/vector pair는 candidate와
|
||
일치한다. Selected vectors의 ML normalization/원 residual은 serializer 전 C3 gate에서
|
||
검증되었고 해당 metrics 및 read-back values를 대조한다. Serializer 자기복사를 독립 physics로 부르지 않는다.
|
||
5. `nf=n+nz`, node별 counts 합, N<=c<=n, 전체 c check rows와 solver-column uniqueness,
|
||
첫 N lambda exact equality, modal_mass>0, 모든 적용 C2/C3 metric 한계가 맞는다.
|
||
6. Calls/fpm row수·ordinals·strict endpoints·finite available diagnostics, fpm controls,
|
||
counts/budgets(<=512 count, <=3 solve), final solve info0/returned m=c와 selected1..N이 맞는다.
|
||
증거 없는 성공 bool 하나로 대체하지 않는다.
|
||
7. `/diagnostics`는 기존 compound `severity,code,file,line,keyword,entity_identity,message`를
|
||
유지하며 source order warnings를 저장한다. 성공 파일에 fatal error diagnostic은 없다.
|
||
|
||
이 mandatory inventory는 reader version dispatch, round-trip, 누락/extra mode/duplicate ID,
|
||
nonfinite/wrong dimension/type/mass/backend/source, close/reopen/self-check failure tests의 기준이다.
|
||
Optional unknown dataset의 존재를 extra-mode로 오인하지 않는다. Static 파일은 기존 schema
|
||
inventory로 계속 검증하고, eigen reader는 static 또는 unknown eigen revision을 명시적으로 거부한다.
|