docs: design linear static 3D Euler beam pipeline
This commit is contained in:
@@ -0,0 +1,527 @@
|
|||||||
|
# Linear Static 3D Euler Beam End-to-End Design
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
- feature_id: `linear-static-3d-euler-beam`
|
||||||
|
- phase_name: `linear-static-3d-euler-beam`
|
||||||
|
- status: `approved`
|
||||||
|
- approved_by: user
|
||||||
|
- approved_on: `2026-08-08`
|
||||||
|
- source_formulation: `docs/formulations/3d-isoparametric-euler-beam-formulation.md`
|
||||||
|
- implementation_environment: C++17, MSVC, CMake, CTest, GoogleTest, Intel oneMKL, Intel oneTBB, HDF5
|
||||||
|
|
||||||
|
## 1. 목적
|
||||||
|
|
||||||
|
이 설계는 Abaqus `.inp` keyword subset을 읽어 2절점 3차원
|
||||||
|
Euler–Bernoulli beam의 단일 선형 정적 step을 해석하고, 변위·반력·요소 내력·축응력을
|
||||||
|
authoritative HDF5 파일 `results.h5`에 기록하는 FESA V0 파이프라인을 정의한다.
|
||||||
|
|
||||||
|
런타임 순서는 다음과 같이 고정한다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
.inp 입력
|
||||||
|
-> Domain 생성
|
||||||
|
-> 현재 step의 AnalysisModel 생성
|
||||||
|
-> DofManager 및 sparse pattern 생성
|
||||||
|
-> 요소강성 계산과 전역강성 조립
|
||||||
|
-> free/constrained partition
|
||||||
|
-> MKL PARDISO factorization
|
||||||
|
-> 전체 하중벡터 조립과 effective RHS 생성
|
||||||
|
-> PARDISO substitution
|
||||||
|
-> 전체 변위벡터 복구
|
||||||
|
-> 반력·요소 내력·요소 축응력 복구
|
||||||
|
-> results.h5 기록
|
||||||
|
-> 정상 종료
|
||||||
|
```
|
||||||
|
|
||||||
|
## 2. 범위
|
||||||
|
|
||||||
|
### 2.1 포함 범위
|
||||||
|
|
||||||
|
- 입력 파일당 하나의 `*STEP, *STATIC`
|
||||||
|
- small displacement, small rotation, 선형 탄성 해석
|
||||||
|
- 2절점 직선 3D Euler–Bernoulli beam
|
||||||
|
- 절점당 자유도 `[UX, UY, UZ, URX, URY, URZ]`
|
||||||
|
- 축, 두 방향 굽힘, Saint-Venant 비틀림
|
||||||
|
- nodal concentrated load와 prescribed displacement
|
||||||
|
- nonzero prescribed displacement를 포함한 자유/구속 partition
|
||||||
|
- deterministic COO-to-CSR sparse assembly
|
||||||
|
- MKL PARDISO factorization과 substitution의 분리
|
||||||
|
- oneTBB 기반 element-local 계산
|
||||||
|
- 변위, 반력, equilibrium end action, section resultant, axial `S11` 출력
|
||||||
|
- Abaqus B33 변위·반력·section resultant reference comparison
|
||||||
|
|
||||||
|
### 2.2 제외 범위
|
||||||
|
|
||||||
|
- Abaqus full compatibility
|
||||||
|
- Abaqus B31/Timoshenko beam
|
||||||
|
- 다중 analysis step과 step 간 load/BC propagation
|
||||||
|
- instance translation/rotation, nested assembly, dependent/independent mesh 차이
|
||||||
|
- `I12 != 0`, taper, offset, release, curved beam, warping
|
||||||
|
- distributed load용 Abaqus `*DLOAD` 입력
|
||||||
|
- 기하·재료비선형, dynamics, contact, thermal effects
|
||||||
|
- transverse shear stress와 torsional shear stress recovery
|
||||||
|
- beam stress에 대한 Abaqus reference comparison
|
||||||
|
- reference artifact의 자동 생성, 수정 또는 Abaqus 실행
|
||||||
|
|
||||||
|
## 3. Phase 구성
|
||||||
|
|
||||||
|
단일 Harness task `linear-static-3d-euler-beam`은 다음 29개 step으로 구성한다.
|
||||||
|
각 step은 하나의 gate 또는 하나의 C++ 모듈만 소유한다.
|
||||||
|
|
||||||
|
### 3.1 문서 및 계약 gate
|
||||||
|
|
||||||
|
| Step | Name | Primary output |
|
||||||
|
| ---: | --- | --- |
|
||||||
|
| 0 | `requirements-baseline` | `docs/requirements/linear-static-3d-euler-beam.md` |
|
||||||
|
| 1 | `research-evidence` | `docs/research/linear-static-3d-euler-beam-research.md` |
|
||||||
|
| 2 | `formulation-alignment` | 승인 범위와 정렬된 기존 beam formulation |
|
||||||
|
| 3 | `numerical-review` | `docs/numerical-reviews/linear-static-3d-euler-beam-review.md` |
|
||||||
|
| 4 | `io-contract` | `docs/io-definitions/linear-static-3d-euler-beam-io.md` |
|
||||||
|
| 5 | `reference-model-contract` | `docs/reference-models/linear-static-3d-euler-beam-reference-models.md` |
|
||||||
|
| 6 | `implementation-plan` | `docs/implementation-plans/linear-static-3d-euler-beam.md` |
|
||||||
|
|
||||||
|
### 3.2 C++ TDD 구현
|
||||||
|
|
||||||
|
| Step | Name | Module responsibility |
|
||||||
|
| ---: | --- | --- |
|
||||||
|
| 7 | `cmake-test-foundation` | CMake, GoogleTest, CTest, dependency discovery |
|
||||||
|
| 8 | `core-diagnostics` | IDs, source locations, diagnostics, status |
|
||||||
|
| 9 | `dense-math-adapters` | MKL BLAS `Matrix` and `Vector` |
|
||||||
|
| 10 | `domain-model` | Immutable model definitions and source identities |
|
||||||
|
| 11 | `inp-syntax-parser` | Keyword/data/comment lexical and syntax parsing |
|
||||||
|
| 12 | `inp-domain-mapping` | Part/Assembly/Instance semantic mapping |
|
||||||
|
| 13 | `analysis-model` | Active single-step views into Domain |
|
||||||
|
| 14 | `dof-manager` | DOFs, constraints, numbering, sparse pattern |
|
||||||
|
| 15 | `analysis-state` | Displacement, forces, residual, step/frame state |
|
||||||
|
| 16 | `euler-beam-element` | B33 element stiffness, transformation, load/recovery kernels |
|
||||||
|
| 17 | `parallel-for-tbb` | oneTBB adapter for deterministic element-local work |
|
||||||
|
| 18 | `sparse-assembly` | COO contribution collection and CSR finalization |
|
||||||
|
| 19 | `essential-constraints` | Matrix partition and full/reduced vector mapping |
|
||||||
|
| 20 | `mkl-pardiso-solver` | PARDISO adapter, factorization, substitution, diagnostics |
|
||||||
|
| 21 | `load-assembly` | Nodal load vector and prescribed-displacement RHS |
|
||||||
|
| 22 | `result-recovery` | Reactions, end actions, resultants, axial stress |
|
||||||
|
| 23 | `hdf5-results-writer` | Versioned HDF5 schema and atomic finalization |
|
||||||
|
| 24 | `linear-static-cli` | Analysis orchestration and `fesa.exe` entry point |
|
||||||
|
|
||||||
|
### 3.3 최종 gate
|
||||||
|
|
||||||
|
| Step | Name | Primary output |
|
||||||
|
| ---: | --- | --- |
|
||||||
|
| 25 | `build-test-verification` | `docs/build-test-reports/linear-static-3d-euler-beam.md` |
|
||||||
|
| 26 | `reference-verification` | `docs/reference-verifications/linear-static-3d-euler-beam-reference-verification.md` |
|
||||||
|
| 27 | `physics-sanity` | `docs/physics-evaluations/linear-static-3d-euler-beam-physics-evaluation.md` |
|
||||||
|
| 28 | `release-readiness` | `docs/releases/linear-static-3d-euler-beam-release.md` |
|
||||||
|
|
||||||
|
## 4. 아키텍처와 소유권
|
||||||
|
|
||||||
|
### 4.1 Domain 계층
|
||||||
|
|
||||||
|
`Domain`은 parser가 만든 전체 모델을 소유하며 parsing 이후 가능한 한 불변으로
|
||||||
|
취급한다. 최소 semantic object는 다음과 같다.
|
||||||
|
|
||||||
|
- `Node`
|
||||||
|
- `EulerBeam3DDefinition`
|
||||||
|
- `LinearElasticMaterial`
|
||||||
|
- `GeneralBeamSection`
|
||||||
|
- `NodeSet`, `ElementSet`
|
||||||
|
- `BoundaryCondition`, `NodalLoad`
|
||||||
|
- `StaticStepDefinition`
|
||||||
|
|
||||||
|
Part 내부 source label은 변경하지 않는다. 외부 identity는
|
||||||
|
`SourceEntityId { instance_name, source_label }`로 유지하고, Domain은 별도의 stable
|
||||||
|
internal index를 부여한다. 같은 part의 여러 identity instance는 허용하지만 instance
|
||||||
|
transform data가 있으면 입력 오류로 처리한다.
|
||||||
|
|
||||||
|
### 4.2 AnalysisModel
|
||||||
|
|
||||||
|
`AnalysisModel`은 단일 static step에 활성화된 element, load, boundary condition,
|
||||||
|
material, section의 ID/reference view를 제공한다. Domain 객체를 복사하거나 수정하지
|
||||||
|
않는다. 두 번째 `*STEP`은 V0 unsupported diagnostic을 발생시킨다.
|
||||||
|
|
||||||
|
### 4.3 DofManager
|
||||||
|
|
||||||
|
`DofManager`만 다음 정보를 소유한다.
|
||||||
|
|
||||||
|
- node별 6개 DOF 정의
|
||||||
|
- full DOF index
|
||||||
|
- constrained/free mapping
|
||||||
|
- free equation numbering
|
||||||
|
- element scatter map
|
||||||
|
- sparse matrix pattern
|
||||||
|
- full/reduced vector reconstruction
|
||||||
|
|
||||||
|
Node와 Element에는 equation ID를 저장하지 않는다.
|
||||||
|
|
||||||
|
### 4.4 AnalysisState
|
||||||
|
|
||||||
|
`AnalysisState`는 다음 해석 중 상태를 소유한다.
|
||||||
|
|
||||||
|
- full displacement
|
||||||
|
- external force
|
||||||
|
- internal force
|
||||||
|
- residual
|
||||||
|
- constrained reaction
|
||||||
|
- current step/frame identity
|
||||||
|
- element recovery rows
|
||||||
|
|
||||||
|
V0에서는 velocity, acceleration, temperature, iteration history를 할당하지 않는다.
|
||||||
|
|
||||||
|
### 4.5 요소 계약
|
||||||
|
|
||||||
|
`EulerBeam3D`는
|
||||||
|
`docs/formulations/3d-isoparametric-euler-beam-formulation.md`의 부호, DOF 순서,
|
||||||
|
2점 Gauss rule, transformation을 따른다. 구현 API는 다음 책임을 분리한다.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Matrix localStiffness() const;
|
||||||
|
Matrix globalStiffness() const;
|
||||||
|
Vector localEquivalentLoad() const;
|
||||||
|
BeamRecovery recover(const Vector& globalElementDisplacement) const;
|
||||||
|
```
|
||||||
|
|
||||||
|
요소는 equation ID를 소유하지 않는다. `BeamRecovery`는 endpoint equilibrium end
|
||||||
|
action, endpoint section resultant, Gauss-point generalized strain/resultant, section-point
|
||||||
|
`S11`을 구분한다.
|
||||||
|
|
||||||
|
### 4.6 LinearSolver 계약
|
||||||
|
|
||||||
|
Solver core에는 MKL 타입을 노출하지 않는다.
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
class LinearSolver {
|
||||||
|
public:
|
||||||
|
virtual ~LinearSolver() = default;
|
||||||
|
virtual Status factorize(const SparseMatrix& matrix) = 0;
|
||||||
|
virtual Status solve(const Vector& rhs, Vector& solution) const = 0;
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
`MklPardisoSolver`는 factorization 상태를 소유하고 같은 matrix에 여러 RHS
|
||||||
|
substitution을 수행할 수 있다. singularity와 invalid CSR은 구조화된 diagnostic으로
|
||||||
|
반환한다.
|
||||||
|
|
||||||
|
## 5. Matrix, Vector 및 SparseMatrix
|
||||||
|
|
||||||
|
### 5.1 Vector
|
||||||
|
|
||||||
|
`Vector`는 연속된 `double` 데이터와 크기를 소유한다. copy/move semantics와
|
||||||
|
bounds-checked access를 제공한다. 다음 연산은 MKL CBLAS를 사용한다.
|
||||||
|
|
||||||
|
- copy
|
||||||
|
- `dot`
|
||||||
|
- Euclidean norm
|
||||||
|
- `scale`
|
||||||
|
- `axpy`
|
||||||
|
|
||||||
|
### 5.2 Matrix
|
||||||
|
|
||||||
|
`Matrix`는 연속된 row-major `double` 데이터, row count, column count를 소유한다.
|
||||||
|
copy/move semantics와 bounds-checked access를 제공한다. matrix-vector와
|
||||||
|
matrix-matrix 연산은 `CBLAS_ROW_MAJOR`의 MKL CBLAS를 사용한다. beam의 3x3, 4x12,
|
||||||
|
12x12 dense 연산도 이 타입을 사용한다.
|
||||||
|
|
||||||
|
MKL header와 MKL-specific type은 `.cpp` adapter 경계 밖으로 노출하지 않는다.
|
||||||
|
|
||||||
|
### 5.3 SparseMatrix
|
||||||
|
|
||||||
|
`SparseMatrix`는 CSR 전용 별도 타입이며 `Matrix`를 상속하지 않는다. CSR row pointer,
|
||||||
|
column index, values를 소유하고 0-based indexing을 사용한다. PARDISO adapter가
|
||||||
|
필요한 indexing과 descriptor 변환은 adapter 내부에서 수행한다.
|
||||||
|
|
||||||
|
## 6. 입력 계약
|
||||||
|
|
||||||
|
### 6.1 지원 keyword
|
||||||
|
|
||||||
|
- `*HEADING`
|
||||||
|
- `*PART`, `*END PART`
|
||||||
|
- `*NODE`
|
||||||
|
- `*ELEMENT, TYPE=B33`
|
||||||
|
- `*NSET`, `*ELSET`, including `GENERATE`
|
||||||
|
- `*MATERIAL`, `*ELASTIC`
|
||||||
|
- `*BEAM GENERAL SECTION, SECTION=GENERAL`
|
||||||
|
- `*SECTION POINTS`
|
||||||
|
- `*ASSEMBLY`, `*END ASSEMBLY`
|
||||||
|
- `*INSTANCE`, `*END INSTANCE`
|
||||||
|
- `*BOUNDARY`
|
||||||
|
- `*CLOAD`
|
||||||
|
- `*STEP`, `*STATIC`, `*END STEP`
|
||||||
|
|
||||||
|
Keyword와 parameter는 case-insensitive이고 label identity는 원문 값을 보존한다.
|
||||||
|
Comment line은 `**`로 시작한다.
|
||||||
|
|
||||||
|
### 6.2 General beam section mapping
|
||||||
|
|
||||||
|
`*BEAM GENERAL SECTION, SECTION=GENERAL`의 data는
|
||||||
|
`A, I11, I12, I22, J` 순서로 읽는다.
|
||||||
|
|
||||||
|
- `I12`는 0이어야 한다.
|
||||||
|
- Abaqus first beam section axis `n1`을 FESA local `y`로 둔다.
|
||||||
|
- `t x n1`을 FESA local `z`로 둔다.
|
||||||
|
- `Iy = I11`, `Iz = I22`로 매핑한다.
|
||||||
|
- `E`와 Poisson ratio `nu`로 `G = E / (2(1 + nu))`를 계산한다.
|
||||||
|
- `E`, `G`, `A`, `Iy`, `Iz`, `J`는 양수여야 한다.
|
||||||
|
- beam length와 projected guide-vector norm은 승인된 tolerance보다 커야 한다.
|
||||||
|
|
||||||
|
이 축 계약은 Abaqus의 right-handed `(t, n1, n2)` section system 및 현재 formulation의
|
||||||
|
`(x, y, z)` system과 일치한다.
|
||||||
|
|
||||||
|
### 6.3 B33 의미 보존
|
||||||
|
|
||||||
|
Abaqus B31은 transverse shear deformation을 포함하는 Timoshenko beam이고 B33은
|
||||||
|
2절점 cubic Euler–Bernoulli beam이다. FESA V0는 `TYPE=B33`만 Euler 요소로 매핑한다.
|
||||||
|
`TYPE=B31`은 `unsupported-element-formulation` 오류로 거부한다. 기존 B31 reference
|
||||||
|
결과를 tolerance 확대로 Euler reference인 것처럼 사용하지 않는다.
|
||||||
|
|
||||||
|
이 결정은 [[Abaqus Structural Element Families]], [[Beam and Frame Finite Elements]],
|
||||||
|
[[Abaqus-Analysis-User-s-Guide-Volume-IV|Abaqus Analysis User's Guide Volume IV]]의
|
||||||
|
beam-family 구분을 따른다.
|
||||||
|
|
||||||
|
### 6.4 Instance 제한
|
||||||
|
|
||||||
|
- 같은 part의 여러 identity instance를 허용한다.
|
||||||
|
- instance name과 source node/element/set label을 보존한다.
|
||||||
|
- source identity를 stable Domain index로 deterministic하게 매핑한다.
|
||||||
|
- translation 또는 rotation data가 있으면 `unsupported-instance-transform` 오류를 낸다.
|
||||||
|
- nested assembly와 dependent/independent mesh semantics는 지원하지 않는다.
|
||||||
|
|
||||||
|
### 6.5 No-op allowlist
|
||||||
|
|
||||||
|
다음 keyword와 관련 data line은 구조화된 warning을 기록하고 해석에서는 사용하지
|
||||||
|
않는다.
|
||||||
|
|
||||||
|
- `*PREPRINT`
|
||||||
|
- `*RESTART`
|
||||||
|
- `*TRANSVERSE SHEAR STIFFNESS`
|
||||||
|
- `*OUTPUT, FIELD`
|
||||||
|
- `*OUTPUT, HISTORY`
|
||||||
|
- `*NODE OUTPUT`
|
||||||
|
- `*ELEMENT OUTPUT`
|
||||||
|
- `*CONTACT OUTPUT`
|
||||||
|
- 위 output request에 속한 미지원 variable data
|
||||||
|
|
||||||
|
이 allowlist 밖의 미지원 keyword는 오류다. FESA의 기본 출력은 Abaqus output request와
|
||||||
|
무관하게 항상 생성된다.
|
||||||
|
|
||||||
|
## 7. 선형 정적 알고리즘
|
||||||
|
|
||||||
|
1. `AbaqusInputReader`가 syntax model과 source location을 만든다.
|
||||||
|
2. semantic mapper가 immutable `Domain`을 만든다.
|
||||||
|
3. `AnalysisModel`이 단일 static step의 active view를 만든다.
|
||||||
|
4. `DofManager`가 DOF, constraints, scatter map, sparse pattern을 만든다.
|
||||||
|
5. `ParallelFor`가 element-local global stiffness를 계산한다.
|
||||||
|
6. element internal index 순서로 COO contribution을 deterministic하게 reduce하고 CSR로
|
||||||
|
finalize한다.
|
||||||
|
7. free/constrained partition으로 `Kff`, `Kfc`, `Kcf`, `Kcc`를 만든다.
|
||||||
|
8. `MklPardisoSolver::factorize(Kff)`를 호출한다.
|
||||||
|
9. nodal load를 full `F`에 조립한다.
|
||||||
|
10. `rhs = Ff - Kfc * dc`를 만든다.
|
||||||
|
11. `solve(rhs, df)`로 substitution하고 full `d`를 복구한다.
|
||||||
|
12. `Rc = Kcf * df + Kcc * dc - Fc`로 reaction을 복구한다.
|
||||||
|
13. element displacement를 gather하여 end action, section resultant, strain, `S11`을
|
||||||
|
복구한다.
|
||||||
|
14. `ResultsWriter`가 임시 HDF5 파일을 완성한 뒤 최종 `results.h5`로 교체한다.
|
||||||
|
|
||||||
|
반력은 요소 끝력의 별도 합산 경로가 아니라 전체 조립 residual `K*d-F`에서 구한다.
|
||||||
|
|
||||||
|
## 8. 결과 복구
|
||||||
|
|
||||||
|
### 8.1 변위와 반력
|
||||||
|
|
||||||
|
모든 node에 전역 성분 `[UX, UY, UZ, URX, URY, URZ]`를 기록한다. 반력은 동일한
|
||||||
|
6성분 순서로 기록하고 free DOF의 값은 수치 residual 검사에 사용한다.
|
||||||
|
|
||||||
|
### 8.2 요소 내력
|
||||||
|
|
||||||
|
다음 데이터를 서로 다른 dataset으로 유지한다.
|
||||||
|
|
||||||
|
- equilibrium end action: `Kl*dl-fl_dist`, local `[FX,FY,FZ,MX,MY,MZ]`
|
||||||
|
- section resultant: endpoint `xi=-1,+1`의 `[N,T,My,Mz]`
|
||||||
|
- generalized strain/resultant: 두 Gauss point의 formulation 값
|
||||||
|
|
||||||
|
Abaqus internal-force CSV는 equilibrium end action이 아니라 section resultant와
|
||||||
|
비교한다. component mapping은 다음과 같다.
|
||||||
|
|
||||||
|
| Abaqus | FESA local component |
|
||||||
|
| --- | --- |
|
||||||
|
| `SF1` | `FX` / `N` |
|
||||||
|
| `SF3` | `FY` |
|
||||||
|
| `SF2` | `FZ` |
|
||||||
|
| `SM3` | `MX` / `T` |
|
||||||
|
| `SM1` | `MY` |
|
||||||
|
| `SM2` | `MZ` |
|
||||||
|
|
||||||
|
### 8.3 Axial stress
|
||||||
|
|
||||||
|
General beam section은 section point에서 axial stress만 복구한다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
S11 = E * (epsilon0 + x2*kappa1 - x1*kappa2)
|
||||||
|
```
|
||||||
|
|
||||||
|
FESA 좌표로는 `x1=y`, `x2=z`, `kappa1=kappa_y`, `kappa2=kappa_z`다.
|
||||||
|
`*SECTION POINTS`가 있으면 지정 순서대로 출력한다. 없으면 FESA-specific centroid
|
||||||
|
point `(0,0)`을 만들고 `source=fesa-default`로 기록한다. Stress는 두 Gauss point에서
|
||||||
|
평가한다. Transverse shear stress와 torsional shear stress는 출력하지 않는다.
|
||||||
|
|
||||||
|
이 계약은 [[Abaqus Beam and Shell Section Definitions]]과
|
||||||
|
[[Abaqus-Analysis-User-s-Guide-Volume-IV|Abaqus Analysis User's Guide Volume IV]]의
|
||||||
|
general beam section output 제한을 따른다.
|
||||||
|
|
||||||
|
## 9. HDF5 schema v0
|
||||||
|
|
||||||
|
Authoritative output은 `results.h5` 하나다. 최소 schema는 다음과 같다.
|
||||||
|
|
||||||
|
```text
|
||||||
|
/metadata
|
||||||
|
/model/nodes
|
||||||
|
/model/elements
|
||||||
|
/steps/<step-name>/frames/0/nodal/displacement
|
||||||
|
/steps/<step-name>/frames/0/nodal/reaction
|
||||||
|
/steps/<step-name>/frames/0/element/end_force_local
|
||||||
|
/steps/<step-name>/frames/0/element/section_resultant
|
||||||
|
/steps/<step-name>/frames/0/element/generalized_strain
|
||||||
|
/steps/<step-name>/frames/0/element/stress_s11
|
||||||
|
/diagnostics
|
||||||
|
```
|
||||||
|
|
||||||
|
`/metadata`에는 schema version, solver version, source input identity, unit-system label,
|
||||||
|
coordinate convention, element formulation을 기록한다. Node/element group은 stable internal
|
||||||
|
ID와 instance/source label mapping을 함께 저장한다.
|
||||||
|
|
||||||
|
- displacement: `[node_count, 6]`
|
||||||
|
- reaction: `[node_count, 6]`
|
||||||
|
- end force: `[element_count, 2, 6]`
|
||||||
|
- section resultant: `[element_count, 2, 4]`, `xi={-1,+1}`
|
||||||
|
- generalized strain: `[element_count, 2, 4]`, two Gauss points
|
||||||
|
- stress: flat row identity with element, Gauss point, section point, `(x1,x2)`, `S11`
|
||||||
|
|
||||||
|
HDF5 API는 `Hdf5ResultsWriter` implementation 밖으로 노출하지 않는다. Writer failure 시
|
||||||
|
불완전한 최종 `results.h5`를 남기지 않는다.
|
||||||
|
|
||||||
|
## 10. CLI와 diagnostics
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
fesa.exe <model.inp> --output <results.h5>
|
||||||
|
```
|
||||||
|
|
||||||
|
`--output`을 생략하면 현재 작업 디렉터리에 `results.h5`를 생성한다.
|
||||||
|
|
||||||
|
| Exit code | Meaning |
|
||||||
|
| ---: | --- |
|
||||||
|
| 0 | success |
|
||||||
|
| 2 | CLI usage error |
|
||||||
|
| 3 | input syntax or semantic mapping error |
|
||||||
|
| 4 | model validation error |
|
||||||
|
| 5 | factorization or substitution error |
|
||||||
|
| 6 | HDF5 output error |
|
||||||
|
|
||||||
|
각 diagnostic은 `severity`, `code`, `file`, `line`, `keyword`, `entity_identity`,
|
||||||
|
`message`를 가진다. CLI는 오류 diagnostic을 stderr에 deterministic한 순서로 출력한다.
|
||||||
|
|
||||||
|
## 11. TDD와 검증
|
||||||
|
|
||||||
|
### 11.1 C++ step 규칙
|
||||||
|
|
||||||
|
각 production C++ step은 다음 순서를 같은 step 안에서 증명한다.
|
||||||
|
|
||||||
|
1. GoogleTest 작성
|
||||||
|
2. 관련 test target 실행과 요구사항을 재현하는 RED 실패 확인
|
||||||
|
3. 최소 production 구현
|
||||||
|
4. 관련 CTest GREEN 확인
|
||||||
|
5. 전체 MSVC x64 Debug build와 CTest VERIFY
|
||||||
|
|
||||||
|
새 경고를 허용하지 않으며 FESA target에만 MSVC `/W4 /WX`를 적용한다. Third-party
|
||||||
|
GoogleTest target에는 FESA warning policy를 강제하지 않는다.
|
||||||
|
|
||||||
|
### 11.2 테스트 포트폴리오
|
||||||
|
|
||||||
|
- Matrix/Vector ownership, bounds, dimension mismatch, BLAS result checks
|
||||||
|
- parser case-insensitivity, comments, set generation, wrapper nesting, allowlist diagnostics
|
||||||
|
- B31 rejection, B33 acceptance, instance transform rejection, unknown keyword rejection
|
||||||
|
- Domain duplicate label와 dangling reference validation
|
||||||
|
- AnalysisModel active view와 Domain non-copy/non-mutation 검사
|
||||||
|
- DofManager numbering, constraints, scatter map, full/reduced reconstruction
|
||||||
|
- Hermite interpolation, B matrix, 2-point Gauss vs closed-form stiffness
|
||||||
|
- symmetry, rank 6, six rigid modes, positive deformation energy
|
||||||
|
- local/global transform orthogonality와 energy invariance
|
||||||
|
- deterministic parallel COO reduction과 CSR structure
|
||||||
|
- nonzero prescribed displacement와 reaction recovery
|
||||||
|
- PARDISO factorization/substitution 분리, repeated RHS, singular diagnostic
|
||||||
|
- axial, torsion, y/z bending cantilever analytical cases
|
||||||
|
- HDF5 schema, identity, component, metadata, atomic finalization
|
||||||
|
- CLI `.inp -> results.h5` integration
|
||||||
|
|
||||||
|
### 11.3 수치 tolerance
|
||||||
|
|
||||||
|
| Check | Criterion |
|
||||||
|
| --- | --- |
|
||||||
|
| matrix symmetry and Gauss/closed-form comparison | normalized `1e-12` |
|
||||||
|
| rigid-mode and linear-system residual | normalized `1e-10` |
|
||||||
|
| analytical solution tests | relative `1e-9` |
|
||||||
|
| Abaqus B33 reference comparison | relative `1e-6` |
|
||||||
|
| SI displacement and rotation absolute floor | `1e-9` |
|
||||||
|
| SI force and moment absolute floor | `1e-3` |
|
||||||
|
|
||||||
|
Reference row 판정은 `abs_error <= abs_tol OR rel_error <= rel_tol`을 사용한다.
|
||||||
|
Reference metadata가 SI가 아니면 quantity별 absolute tolerance를 동일 차원으로 변환해야
|
||||||
|
하며 변환 근거를 verification report에 기록한다.
|
||||||
|
|
||||||
|
### 11.4 공통 build/test command
|
||||||
|
|
||||||
|
GoogleTest checkout은 `C:/git/googletest`에 있고 승인 당시 revision은
|
||||||
|
`04ee1b4f2aefdffb0135d7cf2a2c519fe50dabe4`다. 절대경로를 production CMake에
|
||||||
|
하드코딩하지 않고 cache variable로 전달한다.
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
cmake -S . -B .harness/build -A x64 `
|
||||||
|
-DFESA_GTEST_SOURCE_DIR=C:/git/googletest `
|
||||||
|
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
|
||||||
|
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
|
||||||
|
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
|
||||||
|
|
||||||
|
cmake --build .harness/build --config Debug
|
||||||
|
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||||
|
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||||
|
```
|
||||||
|
|
||||||
|
CTest discovery 결과는 한 개 이상의 test를 포함해야 한다.
|
||||||
|
|
||||||
|
## 12. Reference 및 release gate
|
||||||
|
|
||||||
|
기존 `reference/cantilever beam/` bundle은 Abaqus B31 결과이므로 수정하지 않고 V0
|
||||||
|
Euler verification에 사용하지 않는다. Reference Model Contract는 사람이 Abaqus에서
|
||||||
|
생성할 B33 bundle의 다음 artifact를 요구한다.
|
||||||
|
|
||||||
|
- `model.inp` using `TYPE=B33`
|
||||||
|
- `metadata.json` with Abaqus version, units, coordinate system, provenance, tolerances
|
||||||
|
- `<model-id>_displacements.csv`
|
||||||
|
- `<model-id>_reactions.csv`
|
||||||
|
- `<model-id>_internalforces.csv`
|
||||||
|
- `README.md`
|
||||||
|
- stress CSV: explicitly `not-applicable` for this feature
|
||||||
|
|
||||||
|
Agent와 Harness는 Abaqus를 실행하거나 reference artifact를 생성·수정하지 않는다.
|
||||||
|
B33 artifact가 없으면 reference-verification step은 `blocked`로 끝나며 사용자가 bundle을
|
||||||
|
준비한 후 해당 step을 `pending`으로 되돌려 재개한다.
|
||||||
|
|
||||||
|
Reference comparison이 pass한 뒤에만 physics sanity를 수행한다. Physics sanity는
|
||||||
|
global force/moment equilibrium, reaction sign, displacement direction, symmetry, element
|
||||||
|
section-force consistency, normalized residual을 검사한다. Release readiness는 모든 이전
|
||||||
|
gate evidence와 known limitations를 확인한다.
|
||||||
|
|
||||||
|
## 13. 완료 조건
|
||||||
|
|
||||||
|
다음 조건을 모두 만족해야 phase를 완료할 수 있다.
|
||||||
|
|
||||||
|
1. 요구조건, 연구, 정식화, 수치 검토, I/O, reference model, 구현 계획 문서가 승인
|
||||||
|
상태다.
|
||||||
|
2. 모든 production C++ 변경에 대응 테스트와 RED/GREEN/VERIFY evidence가 있다.
|
||||||
|
3. MSVC x64 Debug configure, build, CTest discovery, 전체 CTest가 성공한다.
|
||||||
|
4. `fesa.exe`가 승인된 B33 single-step input에서 `results.h5`를 생성한다.
|
||||||
|
5. HDF5 변위·반력·내력 rows가 Abaqus B33 reference CSV와 tolerance 안에서 일치한다.
|
||||||
|
6. Beam stress reference comparison은 명시적 N/A이고 stress output schema/test는
|
||||||
|
통과한다.
|
||||||
|
7. Physics sanity가 pass한다.
|
||||||
|
8. Release report에 지원 subset과 모든 V0 제한사항이 기록된다.
|
||||||
|
|
||||||
Reference in New Issue
Block a user