add uncommitted files
This commit is contained in:
@@ -0,0 +1,470 @@
|
||||
# FESA Architecture
|
||||
|
||||
## 1. 목표
|
||||
|
||||
FESA의 아키텍처 목표는 Abaqus `.inp` 부분집합을 내부 semantic model로 변환하고,
|
||||
유한요소 equation system을 구성해 구조해석 결과를 HDF5로 저장하며, reference
|
||||
comparison과 physics sanity가 가능한 C++20/MSVC 솔버 구조를 제공하는 것이다.
|
||||
|
||||
핵심 품질 속성:
|
||||
|
||||
- FEM formulation traceability
|
||||
- explicit I/O contracts
|
||||
- sparse linear algebra backend isolation
|
||||
- deterministic verification
|
||||
- incremental feature addition
|
||||
- Harness 기반 TDD와 workspace validation
|
||||
|
||||
## 2. 디렉터리 구조
|
||||
|
||||
public header와 implementation은 같은 모듈 구조를 사용한다.
|
||||
|
||||
```text
|
||||
include/
|
||||
fesa/
|
||||
core/
|
||||
io/
|
||||
abaqus/
|
||||
hdf5/
|
||||
model/
|
||||
fem/
|
||||
elements/
|
||||
materials/
|
||||
assembly/
|
||||
constraints/
|
||||
solvers/
|
||||
linear/
|
||||
nonlinear/
|
||||
analysis/
|
||||
results/
|
||||
validation/
|
||||
src/
|
||||
fesa/
|
||||
core/
|
||||
io/
|
||||
abaqus/
|
||||
hdf5/
|
||||
model/
|
||||
fem/
|
||||
elements/
|
||||
materials/
|
||||
assembly/
|
||||
constraints/
|
||||
solvers/
|
||||
linear/
|
||||
nonlinear/
|
||||
analysis/
|
||||
results/
|
||||
validation/
|
||||
tests/
|
||||
unit/
|
||||
integration/
|
||||
reference/
|
||||
reference/
|
||||
<model-id>/
|
||||
model.inp
|
||||
<model-id>_displacements.csv
|
||||
<model-id>_reactions.csv
|
||||
<model-id>_internalforces.csv
|
||||
<model-id>_stresses.csv
|
||||
.agents/
|
||||
skills/
|
||||
harness/
|
||||
review/
|
||||
.codex/
|
||||
hooks.json
|
||||
.harness/
|
||||
config.example.json
|
||||
config.json
|
||||
docs/
|
||||
scripts/
|
||||
execute.py
|
||||
hooks/
|
||||
msvc_harness/
|
||||
phases/
|
||||
```
|
||||
|
||||
목표 구조는 장기적인 namespace와 책임 분류다. 실제 소스 디렉터리와 클래스는 해당
|
||||
기능을 구현하는 phase에서만 만든다.
|
||||
|
||||
Phase 1에서 실체화하는 범위:
|
||||
|
||||
- `elements/beam`: 2절점 3D Timoshenko Beam
|
||||
- `materials/elastic`: 등방성 선형 탄성
|
||||
- `constraints`: essential BC elimination
|
||||
- `solvers/linear`: MKL PARDISO
|
||||
- `analysis`: `LinearStaticAnalysis`
|
||||
- `results`: 단일 step/frame의 field와 diagnostic output
|
||||
|
||||
Truss, plane, solid, shell, plasticity, MPC, nonlinear, dynamic, frequency 및 heat
|
||||
transfer는 목표 taxonomy로만 유지하고 빈 구현을 미리 만들지 않는다.
|
||||
|
||||
## 3. 모듈 경계
|
||||
|
||||
### `core`
|
||||
|
||||
ID, status, diagnostic, source location 및 작은 값 타입을 제공한다. 외부 라이브러리에
|
||||
의존하지 않는다. 단위 변환 엔진은 두지 않고 일관 단위계 규약만 표현한다.
|
||||
|
||||
### `io/abaqus`
|
||||
|
||||
`.inp` lexer/parser, flat 또는 Part/Assembly/Instance scope record 및
|
||||
syntax-to-semantic mapping을 담당한다. 해석 알고리즘과 equation numbering을 알지
|
||||
않는다. parser의 임시 syntax 객체는 `model`에 노출하지 않는다. `*HEADING`,
|
||||
`*PREPRINT`, `*RESTART`, `*OUTPUT`은 명시적인 no-op record로 처리하고 일반적인
|
||||
unknown-keyword ignore 경로를 만들지 않는다.
|
||||
|
||||
### `io/hdf5`
|
||||
|
||||
HDF5 결과 writer/reader, schema versioning 및 HDF5 resource 수명을 담당한다.
|
||||
HDF5 handle은 RAII wrapper 밖으로 노출하지 않는다.
|
||||
|
||||
### `model`
|
||||
|
||||
활성 Instance에서 정규화된 절점, 요소, 집합, 재료, 단면, step, 하중 및
|
||||
경계조건의 solver semantic model을 소유한다. Part/Assembly keyword record나 MKL
|
||||
자료구조를 저장하지 않는다.
|
||||
|
||||
### `fem`
|
||||
|
||||
DOF 정의, equation numbering 계약, quadrature, shape function, Jacobian 및
|
||||
local/global mapping을 제공한다. 특정 analysis procedure에 종속되지 않는다.
|
||||
|
||||
### `elements`와 `materials`
|
||||
|
||||
요소의 local contribution과 결과 회복 계약을 제공한다. Phase 1 요소는 선형 문제에
|
||||
필요한 local stiffness, equivalent load 및 section response만 계산한다.
|
||||
|
||||
### `assembly`
|
||||
|
||||
local-to-global mapping, sparse pattern 생성, contribution 정렬·병합 및 COO/CSR
|
||||
변환을 담당한다. 요소 formulation이나 PARDISO handle을 소유하지 않는다.
|
||||
|
||||
### `constraints`
|
||||
|
||||
essential BC와 full/reduced vector 변환 정책을 담당한다. Phase 1에는 elimination만
|
||||
구현하고 MPC, penalty 및 Lagrange multiplier는 추가하지 않는다.
|
||||
|
||||
### `solvers`
|
||||
|
||||
희소 선형계 backend 경계를 제공한다. Phase 1의 `solvers/linear`는 MKL PARDISO를
|
||||
adapter로 감싸며 symbolic analysis, factorization, solve 및 release 수명을 관리한다.
|
||||
|
||||
### `analysis`
|
||||
|
||||
step data를 실행 가능한 `AnalysisModel`로 변환하고 DOF, assembly, constraint,
|
||||
solver 및 result writer를 조율한다. 구체 수치 kernel이나 외부 API를 직접 구현하지
|
||||
않는다.
|
||||
|
||||
### `results`
|
||||
|
||||
nodal, element, integration-point, field, history 및 diagnostic output의 semantic
|
||||
표현을 담당한다. Phase 1에는 nodal/element field와 diagnostic만 실체화한다.
|
||||
|
||||
### `validation`
|
||||
|
||||
reference mapping, 비교 metric, tolerance와 physics sanity helper를 제공한다.
|
||||
production parser와 solver 내부 상태를 우회하는 별도 해석 경로를 만들지 않는다.
|
||||
|
||||
## 4. 핵심 객체 모델
|
||||
|
||||
```text
|
||||
ParsedDeck (io/abaqus 전용)
|
||||
├── PartDefinition[]
|
||||
├── AssemblyDefinition
|
||||
│ └── InstanceDefinition[1]
|
||||
├── MaterialDefinition[]
|
||||
└── StepDefinition
|
||||
|
||||
Domain
|
||||
├── Node
|
||||
├── Element
|
||||
├── Material
|
||||
├── Property
|
||||
├── NodeSet
|
||||
├── ElementSet
|
||||
├── BoundaryCondition
|
||||
├── Load
|
||||
└── StepDefinition
|
||||
|
||||
AnalysisModel
|
||||
├── active elements
|
||||
├── active loads
|
||||
├── active boundary conditions
|
||||
├── active properties/materials
|
||||
└── equation system view
|
||||
|
||||
AnalysisState
|
||||
├── displacement U
|
||||
├── external force Fext
|
||||
├── internal force Fint
|
||||
├── residual R
|
||||
├── reaction
|
||||
└── element/integration-point response
|
||||
|
||||
DofManager
|
||||
├── node dof definitions
|
||||
├── constrained/free dof mapping
|
||||
├── equation numbering
|
||||
├── element equation adjacency view
|
||||
└── full/reduced vector reconstruction
|
||||
|
||||
Results
|
||||
└── ResultStep
|
||||
└── ResultFrame
|
||||
├── FieldOutput
|
||||
├── HistoryOutput
|
||||
└── DiagnosticOutput
|
||||
```
|
||||
|
||||
장기 목표인 `AnalysisState`의 velocity, acceleration, temperature, increment,
|
||||
iteration 및 material state는 해당 해석 기능을 구현할 때 추가한다. Phase 1 객체에
|
||||
사용되지 않는 상태를 미리 할당하지 않는다.
|
||||
|
||||
## 5. 상태 관리
|
||||
|
||||
- `Domain`은 입력에서 만들어진 전체 모델 정의를 소유한다.
|
||||
- syntax-to-semantic mapping과 validation이 끝난 `Domain`은 가능한 한 불변으로
|
||||
취급한다.
|
||||
- 계층형 입력의 외부 ID는 `(instance name, part-local label)`로 표현하고 내부
|
||||
dense index와 구분한다. flat 입력은 예약된 global scope를 사용한다.
|
||||
- 여러 Part를 파싱할 수 있지만 단일 Assembly의 단일 무변환 Instance가 참조하는
|
||||
Part만 `Domain`에 포함한다.
|
||||
- `AnalysisModel`은 현재 step에서 활성화되는 객체의 ID/참조 기반 view다. `Domain`을
|
||||
복제하지 않는다.
|
||||
- `DofManager`는 DOF와 equation numbering을 전담한다. `Node`와 `Element`에
|
||||
equation ID를 저장하지 않는다.
|
||||
- `AnalysisState`는 해석 중 변하는 물리량만 소유한다.
|
||||
- 결과는 `ResultStep -> ResultFrame -> FieldOutput/HistoryOutput` 구조로 관리한다.
|
||||
|
||||
## 6. 데이터 흐름
|
||||
|
||||
```text
|
||||
Abaqus input file
|
||||
-> lexer/parser
|
||||
-> scoped syntax records
|
||||
-> complete-deck reference resolution
|
||||
-> flat scope 또는 단일 active Part/Instance 선택
|
||||
-> set/material/section/load/BC 정규화와 validation
|
||||
-> immutable Domain
|
||||
-> StepDefinition
|
||||
-> AnalysisModel
|
||||
-> DofManager
|
||||
-> sparse pattern
|
||||
-> element contributions
|
||||
-> deterministic Assembler
|
||||
-> essential BC elimination
|
||||
-> MKL PARDISO
|
||||
-> full state/reaction reconstruction
|
||||
-> element result recovery
|
||||
-> Results
|
||||
-> HDF5 writer
|
||||
```
|
||||
|
||||
파싱, semantic validation, equation construction, solve 및 output 단계는 서로 다른
|
||||
diagnostic context를 유지한다.
|
||||
|
||||
## 7. 해석 실행 흐름
|
||||
|
||||
`Analysis::run()`은 다음 생명주기를 고정한다.
|
||||
|
||||
```text
|
||||
initialize
|
||||
buildAnalysisModel
|
||||
buildDofMap
|
||||
buildSparsePattern
|
||||
executeProcedure
|
||||
finalizeResults
|
||||
```
|
||||
|
||||
Phase 1의 `LinearStaticAnalysis::executeProcedure()`는 다음을 수행한다.
|
||||
|
||||
```text
|
||||
assemble
|
||||
applyBoundaryConditions
|
||||
solve
|
||||
reconstructFullState
|
||||
recoverReactions
|
||||
recoverElementResults
|
||||
writeResults
|
||||
```
|
||||
|
||||
미래의 비선형·동적 해석은 `executeProcedure` 내부에 각각 Newton 또는 time-step
|
||||
loop를 소유한다. base class가 모든 해석 종류의 반복 변수를 미리 소유하지 않는다.
|
||||
|
||||
## 8. Timoshenko Beam kernel
|
||||
|
||||
Phase 1 kernel은 다음 입력만 받는다.
|
||||
|
||||
- 두 절점 좌표
|
||||
- 12개 local/global DOF mapping
|
||||
- \(E,\nu\)
|
||||
- \(A,I_y,I_z,J,A_{sy},A_{sz}\)
|
||||
- 국부 단면축 기준 방향
|
||||
- 필요한 평가 위치와 회복점
|
||||
|
||||
kernel 책임:
|
||||
|
||||
- 강건한 국부 직교 기저 생성
|
||||
- 자연좌표 shape function과 Jacobian 평가
|
||||
- 축·굽힘·비틀림 2점 Gauss 적분
|
||||
- 전단 1점 Gauss 적분
|
||||
- local stiffness와 global transformation
|
||||
- section strain/resultant와 \(\sigma_{xx}\) 회복
|
||||
|
||||
kernel은 Abaqus의 slenderness compensation을 구현하지 않는다. 명시적 전단강성이
|
||||
없으면 semantic mapper가 \(A_{sy}=A_{sz}=5A/6\)과 `SCF=0`을 적용한다. 명시적
|
||||
전단강성은 이 기본값을 덮어쓰며 nonzero `SCF`는 거부한다.
|
||||
|
||||
## 9. 희소 조립과 병렬성
|
||||
|
||||
1. `assembly`의 sparse pattern builder가 요소 connectivity와 `DofManager`의
|
||||
equation mapping으로 sparsity pattern을 생성한다.
|
||||
2. oneTBB가 요소별 local contribution을 독립적으로 계산한다.
|
||||
3. worker는 공유 CSR 값 배열에 무질서하게 누적하지 않고 thread-local contribution을
|
||||
생성한다.
|
||||
4. contribution을 전역 row, column 및 안정된 tie-break key로 정렬한다.
|
||||
5. 고정된 순서로 합산해 대칭 CSR을 생성한다.
|
||||
6. essential BC를 소거해 reduced symmetric system을 만든다.
|
||||
7. TBB 작업이 끝난 뒤 MKL PARDISO를 호출한다.
|
||||
|
||||
성능보다 같은 입력·설정에서의 수치 재현성을 우선한다. 병렬·직렬 결과 비교와 thread
|
||||
count 변화 테스트를 reference suite에 포함한다.
|
||||
|
||||
## 10. 선형해법 backend
|
||||
|
||||
`LinearSolver` 경계는 matrix structure, numeric values, RHS를 입력받고 solution과
|
||||
진단을 반환한다. Phase 1의 유일한 구현은 `PardisoLinearSolver`다.
|
||||
|
||||
PARDISO adapter 책임:
|
||||
|
||||
- 0-based 대칭 CSR 계약 검증
|
||||
- analysis, factorization, solve 및 release phase 관리
|
||||
- MKL error code를 FESA diagnostic으로 변환
|
||||
- matrix checker와 residual diagnostic 제공
|
||||
- handle과 workspace의 RAII 수명 관리
|
||||
|
||||
반력은 reduced solve 결과를 full vector로 복원한 뒤 원래 시스템의
|
||||
\(r=Ku-f\)에서 계산한다.
|
||||
|
||||
## 11. HDF5 schema
|
||||
|
||||
최상위 구조:
|
||||
|
||||
```text
|
||||
/
|
||||
├── metadata
|
||||
├── model
|
||||
│ ├── nodes
|
||||
│ ├── elements
|
||||
│ ├── sets
|
||||
│ ├── materials
|
||||
│ ├── properties
|
||||
│ └── id_maps
|
||||
├── analysis
|
||||
│ ├── steps
|
||||
│ ├── boundary_conditions
|
||||
│ ├── loads
|
||||
│ └── solver_settings
|
||||
├── results
|
||||
│ └── steps/<step-id>/frames/<frame-id>
|
||||
│ ├── nodal
|
||||
│ ├── element
|
||||
│ └── history
|
||||
└── diagnostics
|
||||
```
|
||||
|
||||
작은 schema 정보와 설명은 attribute로, 수치 배열과 가변 크기 데이터는 dataset으로
|
||||
저장한다. root metadata에는 schema version, FESA version, 입력 fingerprint,
|
||||
좌표계 및 단위 정책을 기록한다. 계층형 입력은 Part/Instance 이름, part-local ID와
|
||||
전단강성 값의 입력/기본값 출처를 함께 저장한다.
|
||||
|
||||
## 12. 오류 처리
|
||||
|
||||
진단은 최소한 다음 분류를 가진다.
|
||||
|
||||
- I/O 및 encoding 오류
|
||||
- lexical/syntax 오류
|
||||
- 미지원 keyword/option
|
||||
- semantic reference 오류
|
||||
- model validity 오류
|
||||
- equation system 오류
|
||||
- numerical solver 오류
|
||||
- result recovery 또는 HDF5 오류
|
||||
|
||||
각 진단은 가능한 경우 source file, line, keyword, entity ID, analysis stage 및 원인을
|
||||
포함한다.
|
||||
|
||||
다음 조건은 묵시적으로 보정하지 않고 실패시킨다.
|
||||
|
||||
- 길이가 0인 요소
|
||||
- 요소축과 평행하거나 길이가 0인 단면 방향 벡터
|
||||
- 존재하지 않는 절점·집합·재료·단면 참조
|
||||
- 중첩 집합 순환
|
||||
- 여러 Assembly/Instance 또는 Instance 평행이동·회전
|
||||
- Instance가 참조하지 않는 Part entity를 Assembly 집합이 참조하는 경우
|
||||
- 재료나 단면이 없거나 중복 할당된 요소
|
||||
- 상충하는 경계조건
|
||||
- 강체모드가 남은 singular equation system
|
||||
- NaN 또는 무한대 입력·결과
|
||||
|
||||
## 13. 설계 패턴
|
||||
|
||||
- Adapter: Abaqus, MKL, TBB 및 HDF5 경계
|
||||
- RAII: PARDISO handle, HDF5 object와 temporary workspace
|
||||
- Strategy: 실제 교체 가능성이 있는 solver와 writer 경계
|
||||
- Template Method: `Analysis::run()`의 공통 생명주기
|
||||
- Factory: Phase 1에는 B31을 생성하는 명시적 factory
|
||||
- Registry: 두 번째 실제 요소나 material type이 추가되는 phase에서만 도입
|
||||
- Runtime polymorphism: assembly가 구체 요소 내부 상태를 알지 않게 하는 최소 계약
|
||||
|
||||
대규모 모델에서 virtual dispatch가 병목이라는 측정 결과가 있을 때만 타입별 batch
|
||||
kernel을 추가한다.
|
||||
|
||||
## 14. 검증 구조
|
||||
|
||||
- `tests/unit`: 값 타입, parser 단위, shape function, quadrature, transformation,
|
||||
element matrix
|
||||
- `tests/integration`: `.inp`에서 HDF5까지 전체 경로
|
||||
- `tests/reference`: CSV 골든 결과와 FESA HDF5 결과 비교
|
||||
- `reference/<model-id>`: Abaqus 입력과 현재 사용할 수 있는 결과 CSV
|
||||
|
||||
reference comparison request가 비교할 물리량과 CSV 경로, 상대 tolerance 및
|
||||
물리량별 절대 scale을 명시한다. 요청한 CSV가 없으면 실패하며 요청하지 않은 결과를
|
||||
통과로 표시하지 않는다. 현재 캔틸레버는 변위와 반력만 요청하고, 요소 내력과
|
||||
단면 도심 응력 adapter는 synthetic CSV로 검증한다.
|
||||
|
||||
요소 내력 CSV의 `(Instance, Element Label, Node Label)` 위치에서
|
||||
`SF1,SF2,SF3,SM1,SM2,SM3`을 \(N,V_y,V_z,T,M_y,M_z\)로 매핑한다. 응력 CSV의
|
||||
같은 위치에 있는 `Sxx`는 단면 도심값 \(N/A\)와 비교한다. 단일 Instance에서는
|
||||
Instance 열 생략을 허용하되 comparison request가 제공한 Instance 이름으로
|
||||
보완한다.
|
||||
|
||||
reference helper는 반드시 public parser와 analysis 경로로 FESA 결과를 생성한다.
|
||||
테스트 전용 경로로 Domain이나 matrix를 직접 주입해 전체 파이프라인 결함을 숨기지
|
||||
않는다.
|
||||
|
||||
## 15. Harness 실행 계층
|
||||
|
||||
현재 저장소의 `scripts/execute.py`, `docs/HARNESS.md` 및
|
||||
`.agents/skills/harness/SKILL.md`를 실행 계약으로 사용한다.
|
||||
|
||||
Executor 동작:
|
||||
|
||||
- `feat-{phase-name}` 브랜치 생성 또는 checkout
|
||||
- `AGENTS.md`와 `docs/*.md` guardrail 주입
|
||||
- 완료된 step의 `summary`를 다음 prompt에 전달
|
||||
- 실패 시 이전 오류를 포함해 최대 3회 재시도
|
||||
- 코드 변경과 phase metadata를 분리해 commit
|
||||
- step/phase timestamp 기록
|
||||
- `--push` 사용 시에만 원격 push
|
||||
|
||||
Codex hook 동작:
|
||||
|
||||
- PreToolUse hook은 위험한 명령 패턴을 검사한다.
|
||||
- Stop hook은 감지된 C/C++ 프로젝트를 MSVC로 빌드하고 테스트한다.
|
||||
- `.harness/config.json`이 있으면 해당 설정과 preset을 우선한다.
|
||||
|
||||
현재 executor에 없는 `allowed_paths`, `validate_workspace.py`,
|
||||
`codex/<phase-name>` 브랜치 및 명시적 clean-worktree 정책은 FESA 아키텍처의
|
||||
요구사항으로 간주하지 않는다.
|
||||
Reference in New Issue
Block a user