add uncommitted files
This commit is contained in:
+277
@@ -0,0 +1,277 @@
|
||||
# FESA Architecture Decision Records
|
||||
|
||||
이 문서는 FESA의 주요 기술 선택과 포기한 대안을 기록한다. 현재 상태가 `Accepted`인
|
||||
결정은 Phase 1 계획과 구현에 적용한다. 결정을 변경할 때는 기존 기록을 지우지 않고
|
||||
새 ADR에서 대체 관계를 명시한다.
|
||||
|
||||
## ADR-001: C++20, MSVC v143, x64와 CMake Presets
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 첫 배포는 Windows 개발팀 내부 검증용이며 Intel oneAPI와 HDF5를 일관되게
|
||||
연동하고 Harness에서 자동 검증해야 한다.
|
||||
|
||||
**결정:** C++20, Visual Studio 2022 MSVC v143, Windows x64, CMake, CMake Presets,
|
||||
CTest 및 GoogleTest/GoogleMock을 사용한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- `std::span` 등 C++20 기능으로 비소유 수치 view를 명시할 수 있다.
|
||||
- CMake target 경계와 preset을 빌드 계약으로 사용할 수 있다.
|
||||
- 다른 컴파일러, 운영체제 및 32비트 플랫폼은 Phase 1 보장 대상이 아니다.
|
||||
|
||||
## ADR-002: 외부 의존성은 개발 환경에 사전 설치
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** oneMKL, oneTBB, HDF5와 GoogleTest의 공급 방식을 하나로 정해야 한다.
|
||||
|
||||
**결정:** 모든 외부 라이브러리는 개발·빌드 PC에 사전 설치하고 CMake가 설치 위치를
|
||||
탐색한다. vcpkg나 Conan manifest는 Phase 1에 도입하지 않는다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 사내 표준 설치 환경을 그대로 사용할 수 있다.
|
||||
- dependency bootstrap을 구현하지 않는다.
|
||||
- 구성 단계는 누락, architecture 불일치 및 지원하지 않는 설치를 명시적으로
|
||||
진단해야 한다.
|
||||
- 재현성은 설치 버전 기록과 build environment 문서에 의존한다.
|
||||
|
||||
## ADR-003: 위험 우선 수직 파이프라인
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 첫 배포는 요소 종류보다 입력부터 결과까지의 코드 구조 검증에 초점을 둔다.
|
||||
|
||||
**결정:** 가장 작은 Beam 모델로 `.inp` 파싱, semantic model, DOF, 조립, constraint,
|
||||
PARDISO, 결과 회복 및 HDF5 출력을 먼저 연결한다. 이후 합의된 입력 기능을 완성하고
|
||||
마지막으로 요소 정확도 자격 검증을 수행한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 모듈 계약과 데이터 누락을 일찍 발견한다.
|
||||
- 임시 가짜 강성행렬은 사용하지 않고 실제 Timoshenko kernel의 최소 구현을 사용한다.
|
||||
- 파이프라인 연결 완료는 수치적으로 검증된 배포를 뜻하지 않는다.
|
||||
- Abaqus tolerance와 physics sanity를 통과해야 Phase 1 배포가 완료된다.
|
||||
|
||||
## ADR-004: Abaqus syntax와 solver semantic model 분리
|
||||
|
||||
**상태:** Superseded by ADR-013
|
||||
|
||||
**상황:** Abaqus `.inp` 부분집합을 지원하지만 내부 모델이 Abaqus 문법과 결합되면
|
||||
해석 코드와 향후 입력 adapter가 오염된다.
|
||||
|
||||
**결정:** `io/abaqus`가 syntax를 파싱하고 검증된 `Domain` semantic model로
|
||||
변환한다. 해석 계층에는 keyword 문자열, line layout 및 parser 임시 객체를 전달하지
|
||||
않는다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 입력 adapter와 FEM 코어를 독립적으로 시험할 수 있다.
|
||||
- syntax 오류와 semantic 오류를 분리할 수 있다.
|
||||
- 이 결정의 syntax/semantic 분리 원칙은 유지되며 입력 조직 범위는 ADR-013이
|
||||
대체한다.
|
||||
|
||||
## ADR-005: 2절점 3D Isoparametric Timoshenko Beam
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 첫 요소는 절점당 6자유도의 3D Beam이며 짧고 두꺼운 보의 전단변형을
|
||||
표현해야 한다.
|
||||
|
||||
**결정:**
|
||||
|
||||
- 2절점 직선 Isoparametric Timoshenko Beam을 사용한다.
|
||||
- 축·굽힘·비틀림 항은 2점, 전단 항은 1점 Gauss 적분한다.
|
||||
- 일반 단면 \(A,I_y,I_z,J,A_{sy},A_{sz}\)와 등방성 선형 탄성을 사용한다.
|
||||
- 도심·주축 단면, \(I_{yz}=0\), 단면 오프셋과 워핑 없음으로 제한한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 전단변형을 표현하고 세장 보의 shear locking을 완화한다.
|
||||
- reduced shear integration과 좌표변환을 별도로 검증해야 한다.
|
||||
- 점별 전단·비틀림 응력은 단면 형상 정보가 없어 출력하지 않는다.
|
||||
- 미래 Beam이나 shell formulation을 위한 범용 kernel framework를 미리 만들지 않는다.
|
||||
|
||||
## ADR-006: Essential BC 소거와 MKL PARDISO
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 최대 약 10만 자유도의 선형 정적 문제를 안정적으로 풀고 비영 지정값과
|
||||
반력을 지원해야 한다.
|
||||
|
||||
**결정:** essential DOF를 소거해 reduced symmetric CSR system을 구성하고 MKL
|
||||
PARDISO 대칭 양정치 직접해법으로 푼다. full solution을 복원한 뒤 원래 평형식에서
|
||||
반력을 계산한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 초기 구현과 singularity 진단이 반복해법보다 단순하고 안정적이다.
|
||||
- PARDISO API와 handle은 `solvers/linear` adapter에 격리한다.
|
||||
- MPC, penalty, Lagrange multiplier 및 iterative backend는 Phase 1에서 제외한다.
|
||||
- 구속이 부족한 모델은 명시적 numerical failure로 처리한다.
|
||||
|
||||
## ADR-007: 결정적 oneTBB 요소 계산과 조립
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 요소 계산을 병렬화하면서 reference 회귀검증에 필요한 수치 재현성을
|
||||
유지해야 한다.
|
||||
|
||||
**결정:** oneTBB로 요소별 contribution을 병렬 계산하고 thread-local 결과를 안정된
|
||||
key로 정렬한 뒤 고정 순서로 합산해 CSR을 생성한다. PARDISO 실행 중에는 외부 TBB
|
||||
작업을 중첩하지 않는다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- thread scheduling 변화에 의한 비결정적 합산을 줄인다.
|
||||
- 공유 CSR에 대한 원자적 무질서 누적을 피한다.
|
||||
- 최대 throughput보다 재현성과 디버깅 가능성을 우선한다.
|
||||
- 병렬화 이득이 작은 모델에는 scheduling overhead가 생길 수 있다.
|
||||
|
||||
## ADR-008: 자기완결형, 버전 지정 HDF5 결과
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 결과 파일만으로 모델과 해석 조건을 추적하고 reference comparison을
|
||||
수행해야 한다.
|
||||
|
||||
**결정:** 모델, ID mapping, step, solver 설정, 절점·요소 결과와 diagnostic을 하나의
|
||||
HDF5 파일에 저장하고 root에 schema version을 기록한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 원본 `.inp` 없이도 결과 entity와 해석 조건을 추적할 수 있다.
|
||||
- schema 변경을 명시적으로 versioning할 수 있다.
|
||||
- 모델을 중복 저장하므로 결과 파일이 커진다.
|
||||
- HDF5 writer/reader와 resource 수명 관리가 별도 adapter 책임이 된다.
|
||||
|
||||
## ADR-009: Abaqus 2024 오프라인 골든 검증
|
||||
|
||||
**상태:** Superseded by ADR-014 and ADR-015
|
||||
|
||||
**상황:** 상용 reference solver는 개발·CI 환경에서 자동 실행할 수 없지만 변위,
|
||||
반력, 요소 내력 및 응력 비교가 필요하다.
|
||||
|
||||
**결정:** Abaqus/Standard 2024가 생성한 입력과 CSV 결과를 versioned golden data로
|
||||
관리한다. 구체적인 CSV 선택과 전단 기본값 계약은 ADR-014와 ADR-015가 대체한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- CI에서 Abaqus 설치와 license가 필요하지 않다.
|
||||
- 골든 데이터 갱신은 별도 Abaqus 환경과 수동 승인 절차가 필요하다.
|
||||
- per-model metadata 요구사항은 ADR-015에서 제거한다.
|
||||
|
||||
## ADR-010: 검증 계층별 허용오차
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 모든 물리량에 하나의 상대오차를 적용하면 영에 가까운 값이나 서로 다른
|
||||
규모의 결과를 올바르게 판정할 수 없다.
|
||||
|
||||
**결정:** 단위·정식화 테스트와 Abaqus 비교를 분리하고, reference 비교에는 기본
|
||||
상대오차 \(10^{-5}\)와 물리량별 characteristic scale 기반 절대오차를 함께 사용한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 영에 가까운 값과 큰 값 모두 의미 있게 비교할 수 있다.
|
||||
- 모델별 예외 tolerance에는 문서화된 수치 근거가 필요하다.
|
||||
- 단일 tolerance보다 comparison request와 helper가 복잡해진다.
|
||||
|
||||
## ADR-011: 일관 단위계와 결과 좌표계
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** Abaqus와 같은 입력 호환성과 명확한 Beam 결과 부호를 유지해야 한다.
|
||||
|
||||
**결정:** FESA는 단위를 변환하지 않고 사용자가 일관 단위계를 제공한다. 절점
|
||||
변위·회전과 반력은 전역좌표계로, 단면력·단면변형률과 회복응력은 요소
|
||||
국부좌표계로 출력한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 입력이 단순하고 Abaqus 모델과 공유하기 쉽다.
|
||||
- 단위 일관성은 입력 작성자의 책임이다.
|
||||
- HDF5에 요소별 국부 기저와 좌표계 metadata를 저장해야 한다.
|
||||
|
||||
## ADR-012: Phase 1 최소 실체화와 기존 Harness 유지
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 장기 아키텍처는 여러 요소와 해석 절차를 예상하지만, 첫 배포는 Beam
|
||||
선형 정적 파이프라인에 한정된다. 저장소에는 이미 phase executor와 MSVC validation
|
||||
hook이 있다.
|
||||
|
||||
**결정:**
|
||||
|
||||
- 필요한 모듈과 클래스만 해당 phase에서 만든다.
|
||||
- 미래 taxonomy는 `docs/ARCHITECTURE.md`에 기록하되 빈 구현을 생성하지 않는다.
|
||||
- 현재 `scripts/execute.py`, `docs/HARNESS.md` 및
|
||||
`.agents/skills/harness/SKILL.md`의 실행 계약을 변경하지 않는다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 선행 abstraction과 사용되지 않는 상태를 줄인다.
|
||||
- 두 번째 실제 요소나 analysis가 추가될 때 factory, registry 또는 state 계약을
|
||||
확장한다.
|
||||
- Harness phase는 현재의 `feat-{phase-name}` 브랜치, 재시도, guardrail 및
|
||||
코드/metadata 분리 commit 동작을 따른다.
|
||||
|
||||
## ADR-013: 단일 Instance를 Domain으로 정규화
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 제공된 Abaqus 검증 모델은 Part/Assembly/Instance 구조를 사용하지만
|
||||
해석 코어 전체에 Abaqus scope를 노출하면 Phase 1 복잡도가 크게 증가한다.
|
||||
|
||||
**결정:** flat/orphan mesh를 계속 지원하면서 여러 Part와 단일 Assembly·단일
|
||||
무변환 Instance를 파싱한다. semantic mapper는 Instance가 참조하는 Part만 활성화해
|
||||
flat `Domain`으로 정규화한다. 외부 entity는 `(instance name, part-local label)`로
|
||||
식별하고 dense solver index와 분리한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 제공된 계층형 입력을 해석하면서 FEM·assembly·solver 경계를 유지한다.
|
||||
- 사용되지 않는 Part는 파싱하되 해석 객체를 생성하지 않는다.
|
||||
- Part와 Assembly 집합 scope를 별도로 해석해야 한다.
|
||||
- 여러 Assembly/Instance, Instance 좌표변환 및 instance-local mesh 수정은 Phase 1
|
||||
미지원 diagnostic이다.
|
||||
|
||||
## ADR-014: 생략된 Beam 전단강성의 Phase 1 기본값
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 일반 Beam 단면 입력과 제공된 검증 샘플에 명시적
|
||||
`*TRANSVERSE SHEAR STIFFNESS`가 없지만 Timoshenko kernel에는 유효 전단면적이
|
||||
필요하다.
|
||||
|
||||
**결정:** 전단강성이 생략되면 \(A_{sy}=A_{sz}=5A/6\)과 `SCF=0`을 적용한다.
|
||||
지원되는 명시값은 기본값을 덮어쓰고 nonzero `SCF`는 거부한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 현재 정사각형 캔틸레버 샘플의 전단 응답을 일관되게 표현할 수 있다.
|
||||
- 이 값은 임의 일반 단면에 대한 보편적 Abaqus 기본값이 아니라 FESA Phase 1
|
||||
가정이다.
|
||||
- HDF5 결과에 전단 값과 입력/기본값 출처를 기록해야 한다.
|
||||
|
||||
## ADR-015: 명시적 물리량 선택 기반 CSV 검증
|
||||
|
||||
**상태:** Accepted
|
||||
|
||||
**상황:** 현재 캔틸레버 reference에는 변위와 반력만 있고 per-model metadata는
|
||||
요구하지 않는다. 요소 내력과 응력 비교 기능은 해당 CSV가 추가되기 전에 구현해야
|
||||
한다.
|
||||
|
||||
**결정:** comparison request가 물리량, CSV 경로, 상대 tolerance와 절대 scale을
|
||||
명시한다. 현재 캔틸레버는 변위와 반력만 선택한다. 요소 내력은
|
||||
`SF1..SF3/SM1..SM3`을 \(N,V_y,V_z,T,M_y,M_z\)로, 응력 `Sxx`는 요소 절점의
|
||||
단면 도심 \(N/A\)로 비교한다. 요소 내력·응력 adapter는 synthetic CSV로 우선
|
||||
검증한다.
|
||||
|
||||
**결과와 트레이드오프:**
|
||||
|
||||
- 누락된 비요청 CSV 때문에 현재 reference 검증이 차단되지 않는다.
|
||||
- 요청한 파일이 없으면 실패하며 비요청 물리량을 통과로 오인하지 않는다.
|
||||
- 단일 Instance에서는 Instance 열을 생략할 수 있다.
|
||||
- tolerance와 검증 출처는 test registration과 `docs/VALIDATION.md`에서 관리한다.
|
||||
@@ -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 아키텍처의
|
||||
요구사항으로 간주하지 않는다.
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
# Harness 운영 가이드
|
||||
|
||||
## Requirements
|
||||
|
||||
Windows, Python 3.10 이상, Codex CLI가 필요하다. CMake 프로젝트에는 Visual Studio의
|
||||
Desktop development with C++ 워크로드와 MSBuild, CMake/CTest를 설치한다.
|
||||
|
||||
## 프로젝트 자동 감지
|
||||
|
||||
프로젝트 형식은 다음 순서로 결정한다: `.harness/config.json`의 명시적 type, 루트의
|
||||
CMake metadata, 하나의 `.sln`, 하나의 `.vcxproj` 순서다. C/C++가 아닌 저장소는
|
||||
건너뛰며, C/C++ 파일은 있지만 CMake/solution metadata가 없는 orphan-C++ 저장소는
|
||||
오류로 처리한다.
|
||||
|
||||
설정을 시작하려면 다음을 실행한다.
|
||||
|
||||
```powershell
|
||||
Copy-Item .harness/config.example.json .harness/config.json
|
||||
python scripts/execute.py <phase-name>
|
||||
python scripts/execute.py <phase-name> --push
|
||||
```
|
||||
|
||||
## Harness Python 검증
|
||||
|
||||
이 저장소의 테스트와 최종 acceptance 검증은 pytest를 시스템 Python에 설치하지 않고
|
||||
다음 명령으로 실행한다.
|
||||
|
||||
```powershell
|
||||
uv run --with pytest python -m pytest -v -rs
|
||||
```
|
||||
|
||||
## CMake preset 설정
|
||||
|
||||
`projectType`을 `cmake`로 지정하거나 자동 감지를 사용한다. `cmake.sourceDir`,
|
||||
`binaryDir`, `configurePreset`, `buildPreset`, `testPreset`은 preset을 사용할 때 함께
|
||||
지정해야 한다. 빌드 산출물은 저장소의 `.harness/build/`처럼 격리된 경로에 둔다.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"projectType": "cmake",
|
||||
"cmake": {
|
||||
"sourceDir": ".",
|
||||
"binaryDir": "out/build/windows-debug",
|
||||
"configurePreset": "windows-debug",
|
||||
"buildPreset": "windows-debug",
|
||||
"testPreset": "windows-debug"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```powershell
|
||||
cmake --preset windows-debug
|
||||
cmake --build --preset windows-debug
|
||||
ctest --preset windows-debug --output-on-failure
|
||||
```
|
||||
|
||||
Preset을 쓰지 않는 경우에는 같은 격리된 build directory를 명시한다.
|
||||
|
||||
```powershell
|
||||
cmake -S . -B .harness/build -A x64
|
||||
cmake --build .harness/build --config Debug
|
||||
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||
```
|
||||
|
||||
## 직접 MSBuild 설정
|
||||
|
||||
`projectType`을 `msbuild`로 설정하면 `msbuild.solution`, `configuration`, `platform`을
|
||||
지정한다. 직접 MSBuild 프로젝트에서는 `msbuild.testCommand`가 필수이며, 테스트 실행
|
||||
파일과 인수를 JSON 배열로 적는다.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"projectType": "msbuild",
|
||||
"msbuild": {
|
||||
"solution": "MyProject.sln",
|
||||
"configuration": "Debug",
|
||||
"platform": "x64",
|
||||
"testCommand": ["build/tests/Debug/MyProjectTests.exe"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```powershell
|
||||
MSBuild.exe MyProject.sln /m /p:Configuration=Debug /p:Platform=x64
|
||||
.\build\tests\Debug\MyProjectTests.exe
|
||||
```
|
||||
|
||||
## TDD 확장
|
||||
|
||||
`tdd.testRoots`와 `tdd.testPatterns`로 테스트 위치와 이름을 확장한다. 패턴마다
|
||||
`{stem}`이 필요하다. `main`, 테스트, 외부 의존성, 생성 파일, build directory 같은
|
||||
기본 제외 항목은 Harness가 관리하며, `tdd.exclude`의 사용자 제외 항목은 이를
|
||||
대체하지 않고 추가한다.
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"tdd": {
|
||||
"testRoots": ["tests", "integration-tests"],
|
||||
"testPatterns": ["{stem}_test.cpp", "test_{stem}.cpp"],
|
||||
"exclude": ["legacy/generated/**"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 실패 복구
|
||||
|
||||
- Visual Studio C++ workload가 없으면 Installer에서 Desktop development with C++를 설치한 뒤 다시 실행한다.
|
||||
- solution 또는 project가 여러 개라서 모호하면 `projectType`과 `msbuild.solution`을 명시한다.
|
||||
- MSVC가 아닌 컴파일러가 감지되면 MSVC Developer Command Prompt에서 실행하거나 toolchain을 MSVC로 전환한다.
|
||||
- CTest가 0개 테스트를 보고하면 `enable_testing()`과 테스트 등록을 확인한다.
|
||||
- 직접 MSBuild 구성에 test command가 없으면 `msbuild.testCommand` 배열을 추가한다.
|
||||
- timeout 또는 명령 실패 시 Stop 응답의 stage, 안전한 argv 배열, 작업 디렉터리,
|
||||
종료 코드와 출력 tail을 확인하고 해당 명령을 단독으로 다시 실행한다. Harness는
|
||||
별도의 로그 파일을 만들지 않는다.
|
||||
+240
@@ -0,0 +1,240 @@
|
||||
# PRD: FESA
|
||||
|
||||
## 1. 제품 목표
|
||||
|
||||
FESA는 Abaqus `.inp` 제한 부분집합으로 정의된 유한요소 모델을 읽고 선형 정적
|
||||
구조해석을 수행한 뒤, 모델과 절점·요소 결과를 자기완결형 HDF5 파일로 저장하는
|
||||
C++20/MSVC 기반 내부 검증용 솔버다.
|
||||
|
||||
첫 배포는 Abaqus나 Nastran의 기능 범위를 재현하는 것이 아니라 다음 기반을 검증하는
|
||||
데 목적이 있다.
|
||||
|
||||
- 입력에서 결과까지 이어지는 전체 해석 파이프라인
|
||||
- FEM 정식화를 추적할 수 있는 모듈 구조
|
||||
- 명시적인 입력·내부 모델·출력 계약
|
||||
- MKL, TBB 및 HDF5를 격리하는 backend 경계
|
||||
- 해석해, physics sanity 및 reference 비교가 가능한 TDD 구조
|
||||
|
||||
## 2. 대상 사용자와 배포 형태
|
||||
|
||||
- 주 사용자: FESA를 개발하고 검증하는 1인 개발자
|
||||
- 배포 대상: 개발팀 내부 검증 환경
|
||||
- 산출물: 정적 해석 코어 라이브러리, CLI, 예제 입력, HDF5 schema 문서,
|
||||
reference 데이터 및 검증 보고서
|
||||
- 일정: 고정 기한보다 단계별 완료 조건과 품질 게이트를 우선한다.
|
||||
|
||||
## 3. Phase 1 기능 범위
|
||||
|
||||
### 3.1 해석
|
||||
|
||||
- 소변형 선형 정적 해석
|
||||
- 단일 `*STEP`과 단일 `*STATIC` 하중 케이스
|
||||
- 약 10만 자유도 이하
|
||||
- 비영 지정 변위·회전을 포함한 essential boundary condition
|
||||
- 일관 단위계 사용; FESA 내부 단위 변환 없음
|
||||
|
||||
### 3.2 요소와 정식화
|
||||
|
||||
- 2절점 직선 3D Isoparametric Timoshenko Beam
|
||||
- 절점당 자유도:
|
||||
\(u_x,u_y,u_z,\theta_x,\theta_y,\theta_z\)
|
||||
- 선형 형상함수와 자연좌표 \(\xi\in[-1,1]\)
|
||||
- 선택적 감차적분:
|
||||
- 축·굽힘·비틀림 항: 2점 Gauss 적분
|
||||
- 전단 항: 1점 Gauss 적분
|
||||
- 등방성 선형 탄성:
|
||||
- 입력: \(E,\nu\)
|
||||
- 계산: \(G=E/[2(1+\nu)]\)
|
||||
- 일반 단면 semantic property:
|
||||
\(A,I_y,I_z,J,A_{sy},A_{sz}\)
|
||||
- 도심과 전단중심이 일치하는 주축 단면
|
||||
- \(I_{yz}=0\), 단면 오프셋과 워핑 없음
|
||||
- 요소축과 평행하지 않은 국부 단면 기준 방향 벡터 필수
|
||||
- 여러 재료와 여러 단면을 `ELSET`별로 할당
|
||||
|
||||
### 3.3 Abaqus 입력 부분집합
|
||||
|
||||
입력은 다음 두 조직 중 하나를 사용한다.
|
||||
|
||||
- 전역 절점·요소로 구성된 flat/orphan mesh
|
||||
- 여러 Part 정의와 좌표변환이 없는 단일 Assembly·단일 Instance
|
||||
|
||||
계층형 입력에서는 Assembly의 Instance가 참조하는 Part만 해석에 사용한다. 사용되지
|
||||
않는 Part는 파싱하지만 해석 `Domain`에 포함하지 않는다. 외부 entity는
|
||||
`(instance name, part-local label)`로 식별하고 내부 dense index와 분리한다.
|
||||
|
||||
필수 지원 대상:
|
||||
|
||||
- `*NODE`
|
||||
- `*ELEMENT, TYPE=B31`
|
||||
- `*PART`, `*END PART`
|
||||
- `*ASSEMBLY`, `*END ASSEMBLY`
|
||||
- `*INSTANCE`, `*END INSTANCE`
|
||||
- `*NSET`, `*ELSET`
|
||||
- 명시적 ID 목록
|
||||
- `GENERATE`
|
||||
- 기존 집합을 참조하는 중첩 집합
|
||||
- `*MATERIAL`, `*ELASTIC`
|
||||
- `*BEAM GENERAL SECTION, SECTION=GENERAL`
|
||||
- `*TRANSVERSE SHEAR STIFFNESS`(선택)
|
||||
- `*BOUNDARY`
|
||||
- `*CLOAD`
|
||||
- `*STEP`, `*STATIC`, `*END STEP`
|
||||
|
||||
계층형 입력은 좌표변환이 없는 단일 Instance만 허용한다. 여러 Assembly/Instance,
|
||||
Instance 평행이동·회전, instance-local mesh 수정 및 flat/계층 mesh 혼합은 파일
|
||||
위치와 원인을 포함한 diagnostic으로 거부한다. Part 집합과 Assembly 집합은 scope를
|
||||
구분하며, Assembly의 `INSTANCE=` 집합을 활성 Part의 로컬 ID에 연결한다.
|
||||
|
||||
파서는 Abaqus syntax를 semantic model로 변환한다. `*HEADING`, `*PREPRINT`,
|
||||
`*RESTART`, `*OUTPUT`은 명시적으로 지원하는 no-op directive로 처리한다. 그 밖의
|
||||
지원하지 않는 keyword나 option을 묵시적으로 무시하지 않는다.
|
||||
|
||||
명시적 전단강성이 있으면 FESA의 \(A_{sy},A_{sz}\)를 재료의 \(G\)와 일관되게
|
||||
구성한다. 생략되면 \(A_{sy}=A_{sz}=5A/6\)과 `SCF=0`을 Phase 1 기본값으로
|
||||
적용한다. 명시된 `SCF`가 0이 아니면 미지원 입력으로 거부한다.
|
||||
|
||||
### 3.4 하중과 경계조건
|
||||
|
||||
- `*BOUNDARY`: 6개 절점 자유도의 0 또는 비영 지정값
|
||||
- `*CLOAD`: 절점 집중력과 집중모멘트
|
||||
- 지정값이 중복되거나 충돌하면 semantic validation 오류
|
||||
- 분포하중, 중력, 압력 및 follower load는 제외
|
||||
|
||||
### 3.5 결과
|
||||
|
||||
절점 결과는 전역좌표계로 출력한다.
|
||||
|
||||
- 변위와 회전
|
||||
- 반력과 반력모멘트
|
||||
|
||||
요소 결과는 요소 국부좌표계로 출력한다.
|
||||
|
||||
- 단면력 \(N,V_y,V_z,T,M_y,M_z\)
|
||||
- 대응 단면변형률
|
||||
- 사용자 지정 단면 회복점 \((y,z)\)에서 축력과 이축 굽힘에 의한
|
||||
\(\sigma_{xx}\)
|
||||
- 요소별 국부 기저 벡터
|
||||
- 계층형 입력의 Part/Instance 이름과 part-local ID
|
||||
|
||||
점별 전단응력과 비틀림응력은 단면 형상 정보 없이는 유일하게 복원할 수 없으므로
|
||||
Phase 1에서 출력하지 않는다.
|
||||
|
||||
HDF5 결과는 다음 정보를 함께 갖는 자기완결형 파일이어야 한다.
|
||||
|
||||
- schema와 FESA 버전
|
||||
- 원본 입력 식별 정보
|
||||
- 절점, 요소, 집합, 재료 및 단면
|
||||
- 외부 ID와 내부 dense index mapping
|
||||
- step과 solver 설정
|
||||
- 적용된 전단강성과 입력값/기본값 출처
|
||||
- 절점·요소 결과
|
||||
- 수렴·평형·solver diagnostic
|
||||
|
||||
## 4. 수치해법과 병렬화 요구사항
|
||||
|
||||
- 지정 자유도 소거 후 reduced equation system을 구성한다.
|
||||
- 소거 전 평형식 \(r=Ku-f\)를 이용해 반력을 복원한다.
|
||||
- 전역 강성행렬은 대칭 CSR로 저장한다.
|
||||
- MKL PARDISO 대칭 양정치 직접해법을 기본 backend로 사용한다.
|
||||
- oneTBB는 요소 강성·하중·결과 계산과 조립 전처리에 사용한다.
|
||||
- 선형해법 실행 중에는 외부 TBB 작업을 중첩하지 않고 MKL 내부 병렬화를 사용한다.
|
||||
- 부동소수점 contribution의 병합 순서를 고정해 같은 설정에서 재현 가능한 결과를 낸다.
|
||||
|
||||
## 5. 검증 요구사항
|
||||
|
||||
### 5.1 검증 계층
|
||||
|
||||
1. 단위 테스트
|
||||
- 형상함수 partition of unity
|
||||
- Jacobian과 Gauss 적분
|
||||
- 국부 기저 직교성
|
||||
- 좌표변환
|
||||
- 요소 강성 대칭성
|
||||
2. 정식화 테스트
|
||||
- 강체운동에서 무변형
|
||||
- 축력, 비틀림, 단축 및 이축 굽힘
|
||||
- 전단 지배 문제
|
||||
- 세장비 변화와 shear locking
|
||||
3. 통합 테스트
|
||||
- 입력 파싱부터 HDF5 출력까지 전체 파이프라인
|
||||
- 평형 \(Ku-f-r\)
|
||||
- 비영 지정 변위
|
||||
- 여러 재료·단면과 중첩 집합
|
||||
4. Reference 테스트
|
||||
- Abaqus/Standard 2024 B31 결과
|
||||
- 현재 캔틸레버의 변위와 반력
|
||||
- 요소 내력 및 요소 절점 단면 도심 응력 비교 계약의 synthetic CSV 검증
|
||||
|
||||
### 5.2 골든 데이터
|
||||
|
||||
Abaqus는 CI나 Harness에서 자동 실행하지 않는다. 별도 Abaqus 2024 환경에서 수동으로
|
||||
생성한 입력과 CSV 결과를 `reference/<model-id>/`에 보관하며 per-model metadata
|
||||
파일은 요구하지 않는다.
|
||||
|
||||
비교 실행은 물리량과 해당 CSV 경로를 명시한다. 요청한 파일이 없으면 실패하고,
|
||||
요청하지 않은 물리량은 통과로 보고하지 않는다. 현재 `reference/cantilever beam`
|
||||
샘플은 변위와 반력만 비교한다. 요소 내력과 응력 CSV가 추가되기 전까지 해당
|
||||
reader와 비교 kernel은 synthetic CSV로 검증한다.
|
||||
|
||||
CSV 식별 및 값 열:
|
||||
|
||||
- 변위: `Part Instance Name`, `Node Label`, `U-U1..U-U3`, `UR-UR1..UR-UR3`
|
||||
- 반력: `Part Instance Name`, `Node Label`, `RF-RF1..RF-RF3`, `RM-RM1..RM-RM3`
|
||||
- 요소 내력: `Part Instance Name`, `Element Label`, `Node Label`,
|
||||
`SF-SF1..SF-SF3`, `SM-SM1..SM-SM3`
|
||||
- 요소 응력: `Part Instance Name`, `Element Label`, `Node Label`, `Sxx`
|
||||
|
||||
단일 Instance에서는 `Part Instance Name` 열을 생략할 수 있다. 내력은
|
||||
`SF1,SF2,SF3,SM1,SM2,SM3`을 각각 \(N,V_y,V_z,T,M_y,M_z\)로 비교한다.
|
||||
응력은 요소 절점의 단면 도심값 \(\sigma_{xx}=N/A\)를 비교한다.
|
||||
|
||||
### 5.3 허용오차
|
||||
|
||||
- 단위·정식화 테스트는 정규화된 엄격한 tolerance를 사용한다.
|
||||
- Abaqus 비교 기본 상대오차는 \(10^{-5}\)로 한다.
|
||||
- 영에 가까운 결과는 특성 길이, 하중 및 응력에 기반한 절대오차를 함께 사용한다.
|
||||
- formulation 또는 output 위치 차이로 별도 tolerance가 필요하면 comparison
|
||||
test 설정과 `docs/VALIDATION.md`에 근거를 기록한다.
|
||||
|
||||
## 6. 개발 워크플로우
|
||||
|
||||
각 기능은 다음 게이트를 순서대로 통과한다.
|
||||
|
||||
1. 요구조건과 완료 기준 정의
|
||||
2. 책, 논문 및 공식 문서 조사
|
||||
3. FEM 정식화, 가정, 좌표계, 부호 및 적분 규칙 작성
|
||||
4. 입력·semantic model·HDF5 데이터 계약 정의
|
||||
5. 실패하는 테스트와 개발 솔버/Abaqus 모델 작성
|
||||
6. 테스트를 통과하는 최소 코드 구현
|
||||
7. 현재 Abaqus 변위·반력 비교와 요소 내력·응력 비교 루틴 검증
|
||||
8. tolerance 및 physics sanity 통과
|
||||
9. 내부 배포
|
||||
|
||||
파이프라인 수직 슬라이스를 먼저 완성하지만, 이는 수치적으로 자격이 검증된 배포를
|
||||
의미하지 않는다. 요소 정확도와 Abaqus 비교 게이트까지 통과해야 Phase 1이 완료된다.
|
||||
|
||||
## 7. 제외 범위
|
||||
|
||||
- Truss, bar, plane, solid, shell 및 다른 Beam 요소
|
||||
- 여러 step과 하중 이력
|
||||
- 여러 Assembly/Instance, Instance 평행이동·회전 및 instance-local mesh 수정
|
||||
- 분포하중, 압력, 중력 및 체적력
|
||||
- MPC, RBE2, RBE3, penalty 및 Lagrange multiplier constraint
|
||||
- 기하·재료 비선형, 접촉, 좌굴, 모달, 동적 및 열전달
|
||||
- 소성, 직교이방성 및 사용자 재료
|
||||
- 단면 오프셋, 곱관성모멘트, 전단중심 편심 및 워핑
|
||||
- 점별 전단·비틀림 응력
|
||||
- 단위 변환
|
||||
- 외부 고객용 installer와 API 호환성 보장
|
||||
|
||||
## 8. 내부 배포 수용 조건
|
||||
|
||||
- MSVC Debug와 Release 구성에서 새 경고 없이 빌드
|
||||
- 모든 GoogleTest/CTest와 Harness 검증 통과
|
||||
- 테스트 0개 수집이 아님을 확인
|
||||
- 전체 입력-해석-출력 통합 테스트 통과
|
||||
- physics sanity와 평형 잔차 기준 통과
|
||||
- 현재 Abaqus 2024 변위·반력 골든 결과의 tolerance 통과
|
||||
- 요소 내력·도심 응력 CSV adapter와 비교 kernel의 synthetic 검증 통과
|
||||
- HDF5 schema, 입력 부분집합, 정식화 및 검증 보고서 제공
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,312 @@
|
||||
# FESA Phase 1 Abaqus Assembly and Reference Comparison Design
|
||||
|
||||
## 1. Status and purpose
|
||||
|
||||
This document records the approved Phase 1 design changes for:
|
||||
|
||||
- parsing both flat/orphan-mesh and Part/Assembly/Instance Abaqus inputs;
|
||||
- activating only the Part referenced by one untransformed Instance;
|
||||
- applying Phase 1 transverse-shear defaults when the input omits them; and
|
||||
- validating displacement, reaction, element internal force, and centroidal
|
||||
element stress without per-model metadata files.
|
||||
|
||||
It refines the existing Phase 1 product and architecture documents. It does not
|
||||
authorize solver implementation.
|
||||
|
||||
## 2. Phase 1 input scope
|
||||
|
||||
FESA supports two mutually exclusive input organizations.
|
||||
|
||||
### 2.1 Flat/orphan mesh
|
||||
|
||||
Nodes, elements, sets, sections, boundary conditions, and loads are defined in
|
||||
the global input scope. These records map directly to the solver `Domain`.
|
||||
|
||||
### 2.2 Part/Assembly/Instance
|
||||
|
||||
The parser preserves the following syntax scopes:
|
||||
|
||||
```text
|
||||
ParsedDeck
|
||||
├── PartDefinition[]
|
||||
├── AssemblyDefinition
|
||||
│ └── InstanceDefinition[1]
|
||||
├── MaterialDefinition[]
|
||||
└── StepDefinition
|
||||
```
|
||||
|
||||
Phase 1 accepts exactly one Assembly containing exactly one Instance. The
|
||||
Instance must:
|
||||
|
||||
- reference one defined Part;
|
||||
- contain no translation or rotation data; and
|
||||
- contain no instance-local mesh modifications.
|
||||
|
||||
Multiple Part definitions may be parsed, but only the Part referenced by the
|
||||
accepted Instance is expanded into the analysis `Domain`. Unreferenced Parts
|
||||
remain syntax/semantic input records and do not contribute nodes, elements,
|
||||
properties, loads, degrees of freedom, or results.
|
||||
|
||||
Multiple Instances, multiple Assemblies, mixed flat and hierarchical meshes,
|
||||
missing Part references, and Instance transformation data are semantic errors.
|
||||
Diagnostics identify the keyword and source location that caused the failure.
|
||||
|
||||
The following non-analysis directives found in the supplied Abaqus sample are
|
||||
explicitly recognized no-op records rather than silently ignored unknown
|
||||
keywords:
|
||||
|
||||
- `*HEADING`
|
||||
- `*PREPRINT`
|
||||
- `*RESTART`
|
||||
- `*OUTPUT`
|
||||
|
||||
Comments and output-request data owned by these directives do not affect the
|
||||
analysis `Domain`. Any other unsupported keyword or option remains an error.
|
||||
|
||||
## 3. Scope and identity resolution
|
||||
|
||||
Part-local node and element labels may be reused by future Instances. The
|
||||
semantic layer therefore identifies instantiated entities by:
|
||||
|
||||
```text
|
||||
(instance_name, part_local_label)
|
||||
```
|
||||
|
||||
The Phase 1 single-Instance restriction means this composite key is not needed
|
||||
to disambiguate the current equation system, but it is retained as explicit
|
||||
input and result provenance. Dense internal indices remain separate from
|
||||
external Abaqus labels.
|
||||
|
||||
For a hierarchical input:
|
||||
|
||||
- Part `NSET` and `ELSET` definitions resolve in Part scope.
|
||||
- Material and section references are resolved after the complete deck has
|
||||
been parsed, so their textual declaration order does not control validity.
|
||||
- Section assignments made to a Part `ELSET` are applied to the active
|
||||
Instance.
|
||||
- Assembly `NSET` and `ELSET` definitions with `INSTANCE=` lift local labels
|
||||
from the active Part into Assembly scope.
|
||||
- Nested set references resolve within their declared scope with cycle
|
||||
detection and deterministic sorted-unique membership.
|
||||
- Step-level `*BOUNDARY` and `*CLOAD` references resolve through Assembly sets.
|
||||
|
||||
For a flat input, the same semantic contracts use a reserved global scope and
|
||||
do not require an Instance name.
|
||||
|
||||
The normalized `Domain` contains analysis entities and their provenance, but it
|
||||
does not expose Abaqus keyword records to FEM, element, assembly, constraint, or
|
||||
solver modules.
|
||||
|
||||
## 4. Normalization flow
|
||||
|
||||
```text
|
||||
Abaqus input
|
||||
-> scoped syntax records
|
||||
-> complete-deck name and reference resolution
|
||||
-> organization validation
|
||||
-> active Part/Instance selection or flat-scope selection
|
||||
-> set, material, section, load, and boundary resolution
|
||||
-> normalized immutable Domain
|
||||
-> existing analysis pipeline
|
||||
```
|
||||
|
||||
The normalization stage is the only production layer that understands both
|
||||
Abaqus scopes and the flat solver `Domain`. The analysis pipeline is not made
|
||||
hierarchy-aware in Phase 1.
|
||||
|
||||
## 5. Transverse-shear default
|
||||
|
||||
If `*TRANSVERSE SHEAR STIFFNESS` is absent, the Phase 1 semantic mapper applies:
|
||||
|
||||
\[
|
||||
A_{sy}=A_{sz}=\frac{5}{6}A
|
||||
\]
|
||||
|
||||
and uses `SCF=0`.
|
||||
|
||||
If explicit transverse-shear stiffness is present, its supported values
|
||||
override the effective shear-area default. An explicitly specified nonzero
|
||||
`SCF` is unsupported in Phase 1 and produces an input diagnostic.
|
||||
|
||||
The result database records whether the effective shear properties came from
|
||||
the input or the Phase 1 default. This rule is a documented FESA Phase 1
|
||||
assumption; it is not presented as a general default for arbitrary Abaqus
|
||||
sections.
|
||||
|
||||
## 6. Reference comparison contract
|
||||
|
||||
No `metadata.json` file is required. A comparison request explicitly supplies:
|
||||
|
||||
- the result quantities to compare;
|
||||
- the path of each requested reference CSV;
|
||||
- relative tolerance; and
|
||||
- quantity-specific absolute scale.
|
||||
|
||||
The default relative tolerance is \(10^{-5}\). Absolute scales are defined by
|
||||
the PRD and test registration rather than by per-model metadata.
|
||||
|
||||
The comparison supports four quantities:
|
||||
|
||||
1. nodal displacement and rotation;
|
||||
2. nodal reaction force and moment;
|
||||
3. element-node section force and moment; and
|
||||
4. element-node centroidal axial stress.
|
||||
|
||||
A requested missing file is an error. A quantity not selected by the comparison
|
||||
request is not required and is not silently reported as passed.
|
||||
|
||||
The supplied `reference/cantilever beam` test initially requests only
|
||||
displacement and reaction. The element-force and stress readers and comparison
|
||||
kernels are still implemented and tested with synthetic reference tables.
|
||||
When the corresponding Abaqus CSV files are added, the same reference test can
|
||||
select all four quantities without changing the comparison kernel.
|
||||
|
||||
## 7. Reference CSV schemas
|
||||
|
||||
CSV readers trim surrounding whitespace from headers and values. A UTF-8 byte
|
||||
order mark on the first header is tolerated. Entity rows must be unique for the
|
||||
key required by their result type.
|
||||
|
||||
### 7.1 Displacement
|
||||
|
||||
The existing Abaqus field-report columns are accepted:
|
||||
|
||||
```text
|
||||
Part Instance Name, Node Label,
|
||||
U-U1, U-U2, U-U3, UR-UR1, UR-UR2, UR-UR3
|
||||
```
|
||||
|
||||
For a single Instance, `Part Instance Name` may be omitted.
|
||||
|
||||
### 7.2 Reaction
|
||||
|
||||
The existing Abaqus field-report columns are accepted:
|
||||
|
||||
```text
|
||||
Part Instance Name, Node Label,
|
||||
RF-RF1, RF-RF2, RF-RF3, RM-RM1, RM-RM2, RM-RM3
|
||||
```
|
||||
|
||||
For a single Instance, `Part Instance Name` may be omitted.
|
||||
|
||||
### 7.3 Element internal force
|
||||
|
||||
```text
|
||||
Part Instance Name, Element Label, Node Label,
|
||||
SF-SF1, SF-SF2, SF-SF3, SM-SM1, SM-SM2, SM-SM3
|
||||
```
|
||||
|
||||
The canonical component mapping is:
|
||||
|
||||
```text
|
||||
SF1 -> N
|
||||
SF2 -> Vy
|
||||
SF3 -> Vz
|
||||
SM1 -> T
|
||||
SM2 -> My
|
||||
SM3 -> Mz
|
||||
```
|
||||
|
||||
The element label and element-end node label together identify the result
|
||||
position. For a single Instance, `Part Instance Name` may be omitted.
|
||||
|
||||
### 7.4 Element stress
|
||||
|
||||
```text
|
||||
Part Instance Name, Element Label, Node Label, Sxx
|
||||
```
|
||||
|
||||
`Sxx` is compared with the FESA element-end stress at the section centroid:
|
||||
|
||||
\[
|
||||
\sigma_{xx,\mathrm{centroid}}=\frac{N}{A}
|
||||
\]
|
||||
|
||||
The reference comparison does not use bending stress at an unspecified
|
||||
recovery point. FESA may still store explicitly identified non-centroid
|
||||
recovery-point stresses in its HDF5 result contract. For a single Instance,
|
||||
`Part Instance Name` may be omitted.
|
||||
|
||||
## 8. Comparison behavior
|
||||
|
||||
Each scalar component uses the normalized error:
|
||||
|
||||
\[
|
||||
e_n=\frac{|a-r|}{a_\mathrm{scale}+r_\mathrm{tol}|r|}
|
||||
\]
|
||||
|
||||
and passes when \(e_n\leq1\).
|
||||
|
||||
Before evaluation, the comparison layer rejects:
|
||||
|
||||
- nonfinite actual or reference values;
|
||||
- duplicate entity/result-position rows;
|
||||
- unknown Instance, node, or element labels;
|
||||
- an element-node pair that is not part of the referenced element;
|
||||
- missing requested components; and
|
||||
- reference rows that cannot be matched to one FESA result.
|
||||
|
||||
The comparison report identifies the quantity, entity key, component,
|
||||
reference value, actual value, tolerance, and normalized error for every
|
||||
failure.
|
||||
|
||||
## 9. Required tests
|
||||
|
||||
### 9.1 Parser and semantic normalization
|
||||
|
||||
- A flat deck still produces a valid `Domain`.
|
||||
- The supplied hierarchical cantilever deck produces an active Domain from its
|
||||
single referenced Part.
|
||||
- Unreferenced Parts do not contribute analysis entities.
|
||||
- Part and Assembly sets resolve in the correct scope.
|
||||
- Material definitions declared after the Part resolve correctly.
|
||||
- Multiple Instances and multiple Assemblies are rejected.
|
||||
- Translation and rotation data are rejected.
|
||||
- Missing Part references and wrong Instance names are rejected.
|
||||
- Unsupported keywords are not silently ignored.
|
||||
- Omitted transverse-shear data yields \(A_{sy}=A_{sz}=5A/6\) and `SCF=0`.
|
||||
|
||||
### 9.2 Reference adapters and comparison
|
||||
|
||||
- Existing displacement and reaction CSV files parse after whitespace
|
||||
normalization.
|
||||
- Optional single-Instance columns are handled without weakening multi-scope
|
||||
identity checks.
|
||||
- Synthetic internal-force rows verify all six component mappings.
|
||||
- Synthetic stress rows verify centroidal \(N/A\) comparison.
|
||||
- Requested missing files, duplicates, invalid IDs, invalid element-node pairs,
|
||||
missing columns, and nonfinite values fail.
|
||||
- Relative and absolute tolerance behavior is tested near zero and at
|
||||
representative scales.
|
||||
- The current cantilever integration test selects displacement and reaction
|
||||
only.
|
||||
|
||||
## 10. Phase-plan impact
|
||||
|
||||
The existing ten Harness phases remain. Four phases receive revised steps:
|
||||
|
||||
- `domain-and-input-skeleton`: add scoped Part/Assembly/single-Instance syntax
|
||||
records and minimal normalization.
|
||||
- `abaqus-subset-completion`: complete scoped set resolution, active-Part
|
||||
expansion, no-op directive handling, and transverse-shear defaults.
|
||||
- `result-contract-completion`: recover and expose element-end internal force
|
||||
and centroidal `Sxx` alongside the complete result contract.
|
||||
- `beam-reference-qualification`: replace metadata-driven discovery with
|
||||
explicit comparison requests and use the supplied cantilever displacement
|
||||
and reaction files as the initial real reference.
|
||||
|
||||
Phase step files must keep parser syntax handling, semantic normalization,
|
||||
result recovery, CSV adaptation, and numeric comparison in separate
|
||||
module-bounded steps.
|
||||
|
||||
## 11. Completion criteria for this design change
|
||||
|
||||
Planning is consistent when:
|
||||
|
||||
- PRD, architecture, ADR, detailed implementation plan, and Harness step draft
|
||||
describe the same single-Instance scope;
|
||||
- no planning artifact requires reference metadata;
|
||||
- the current cantilever reference requires only displacement and reaction;
|
||||
- element internal-force and centroidal-stress comparison remain mandatory
|
||||
implementation work; and
|
||||
- no document claims support for multiple or transformed Instances in Phase 1.
|
||||
Reference in New Issue
Block a user