14 KiB
14 KiB
Project: FESA Structural Solver
기술 스택
- C++17 이상
- MSVC on Windows
- CMake + CTest
- Python 3 Harness scripts
- Intel oneAPI MKL, Intel oneAPI TBB
- HDF5 result storage
- Abaqus
.inpkeyword subset input
프로젝트 정체성
- FESA는 유한요소법 기반 구조해석 솔버를 단계적으로 구축하고 검증하는 프로젝트이다. 목표는 Abaqus를 흉내 내는 parser를 만드는 것이 아니라, 승인된 입력 범위에서 물리적으로 설명 가능하고 재현 가능한 해석 결과를 만드는 것이다.
- 새 기능은 입력 keyword만 인식하거나 element kernel만 존재한다고 완성된 것이 아니다. Semantic model, equation system, 해법, 결과 복구, HDF5 외부 계약과 독립 검증 evidence가 하나의 추적 가능한 기능을 이뤄야 한다.
- 프로젝트의 배경, 목적, 사용자, 범위는
docs/PRD.md에서 확인한다. - 전체 아키텍처와 모듈별 책임은
docs/ARCHITECTURE.md에서 확인한다. - 주요 아키텍처 결정과 그 이유 및 트레이드오프는
docs/ADR.md에서 확인한다. - AI 에이전트는 설계나 구현 결정을 내리기 전에 PRD에서 제품 범위를, ARCHITECTURE에서 소유권과 데이터 흐름을, ADR에서 이미 결정된 트레이드오프를 먼저 확인한다. 기능별 의미는
docs/requirements/,docs/formulations/,docs/io-definitions/,docs/reference-models/의 승인 문서를 source of truth로 삼는다. - Harness는 솔버 자체가 아니라 요구조건, TDD, phase 실행, 검증을 통제하는 개발 운영 인프라이다. 전체 실행 흐름은
docs/HARNESS_WORKFLOW.md, 설치와 설정은docs/HARNESS.md를 따른다. - 문서와 구현은 full Abaqus compatibility를 주장하지 않는다. 기능별로 승인된 Abaqus keyword subset만 지원한다.
- 공식 solver output은 HDF5
results.h5이다. - reference 결과는 FESA와 같은 Abaqus
.inp모델을 Abaqus로 해석해 생성한 CSV 파일이다. - reference artifact의 정확한 경로와 파일명은 기능별 reference model contract를 따른다. 신규 모델은
reference/<model-id>/<model-id>_*.csvcanonical 이름을 사용한다. metadata.json은 선택 reference artifact다. 파일이 없어도 bundle을 불완전하다고 판정하지 않으며, 필수 provenance, units, coordinate system, step/frame, schema, tolerance 정보는 승인된 기능별 reference model contract에 기록한다. 파일이 존재하면 read-only 보조 자료로 inventory하고 계약과 일치하는지 확인한다.- 승인된 B33 baseline은 예외적으로
reference/cantilever beam/의 기존 space-containing 파일명을 read-only legacy alias로 사용한다. - CSV는 FESA 공식 output이 아니며, FESA HDF5에서 추출한 deterministic CSV view는 비교 디버깅/검토용 보조 artifact로만 둔다.
FESA 개발의 핵심 원칙
물리와 수치 계약
- CRITICAL: 구현보다 요구조건, 정식화, 부호, 단위, 좌표계, row identity와 tolerance 계약을 먼저 고정한다. 구현 편의를 위해 승인된 의미를 조용히 바꾸지 않는다.
- CRITICAL: 해석 결과가 유한하고 선형계가 풀렸다는 사실만으로 correctness를 주장하지 않는다. Equilibrium, reaction, rigid-body mode, energy, symmetry와 reference identity를 기능에 맞게 검증한다.
- Source label/instance identity와 internal index/equation index를 구분한다. Stable source identity는 진단, 결과, reference mapping 전 구간에서 보존한다.
- 병렬 실행 여부와 관계없이 같은 입력은 같은 sparse structure, reduction order, result row order와 diagnostic order를 만들어야 한다.
- Scale-aware validation은 formulation과 I/O 계약의 기준을 사용한다. 임의의
max(1, ...), zero clamp, 누락 row 무시 또는 불일치 평균으로 오류를 숨기지 않는다.
소유권과 의존성
- CRITICAL: C++ 빌드는 CMake/MSVC/x64/Debug 기준으로 검증한다.
- CRITICAL: 새 기능 또는 동작 변경은 테스트를 먼저 작성하고 실패를 확인한 뒤 구현한다.
- CRITICAL: C++ production file을 바꿀 때는 관련 C++ test file이 있어야 한다.
- CRITICAL: Abaqus reference artifact 생성, 수정, 복원은 명시적으로 요청된 phase에서만 수행한다.
- CRITICAL: public header와 implementation 의존성 방향을 역전하지 않는다.
- CRITICAL: 사람이 계약과 수치식을 대조할 수 있는 단순한 코드를 작성한다. 주석은 코드가 이미 말하는 동작보다 부호, 수명, 순서, backend 제약처럼 비자명한 이유를 설명한다.
- Domain은 입력 파일에서 생성된 전체 모델 정의를 소유하고, 파싱 이후 가능한 한 불변으로 취급한다.
- AnalysisModel은 현재 step에서 활성화된 elements, loads, boundary conditions, properties/materials의 non-owning view를 제공하며 Domain을 복사하지 않는다. 따라서 Domain은 AnalysisModel보다 오래 살아야 한다.
- DofManager는 node별 자유도 정의, constrained/free mapping, equation numbering, sparse pattern ownership을 전담한다. Node 또는 Element 내부에 equation id를 분산 저장하지 않는다.
- AnalysisState는 해당 procedure가 실제로 사용하는 mutable solution과 recovery row만 소유한다. V0는 full displacement/external/internal force/residual/reaction과 step/frame 및 beam recovery rows만 보관하며 미래 state를 미리 할당하지 않는다.
- MKL, TBB, HDF5, Win32 API와 vendor type은 public solver core에 노출하지 않는다.
LinearSolver,ParallelFor,ResultsWriter,Vector,Matrix,SparseMatrix경계 뒤에 둔다. - 해석 단계는 실패할 수 있는 candidate를 완성하고 검증한 뒤 소유 state/output에 반영한다. 실패 시 기존 state와 기존 최종 HDF5를 가능한 계약 범위에서 보존한다.
선형 정적 해석 불변식
Analysis::run()의 실제 단계와 객체별 책임은docs/ARCHITECTURE.md의 해석 실행 흐름을 따른다.- Full stiffness를 stable free/constrained 순서로
Kff/Kfc/Kcf/Kcc에 분할하고,Kfffactorization을 load assembly보다 먼저 수행한다. - Effective RHS는
Ff - Kfc * dc이며 substitution 뒤 full displacement를 복구한다. 모든 DOF가 constrained인 유효한 모델의0 x 0 Kff를 singular error로 바꾸지 않는다. - Reaction과 free-equilibrium evidence는 조립된 full residual
K*d - F에서 구한다. Constrained 성분은 physical reaction이고 free 성분은 residual evidence다. - Sparse assembly는 element-local contribution과 stable COO ordering, 고정된 reduction을 사용한다. 병렬 worker가 global CSR storage를 직접 갱신하지 않는다.
- Element end action, positive-local-x section resultant, Gauss generalized result와 section-point stress는 서로 다른 identity와 부호 계약을 가진다. Station mismatch를 평균으로 합치지 않는다.
개발 운영 인프라
- Codex custom agent의
model_reasoning_effort기본값은extra high로 둔다. - Harness runner는
scripts/execute.py에 둔다. scripts/execute.py는feat-<phase-name>branch prefix를 사용한다.- runner는
git add -A로 변경사항을 stage하므로 실행 전 clean worktree 또는 별도 Git worktree를 사용한다. - Hook 연결은
.codex/hooks.json, 구현은scripts/hooks/와scripts/msvc_harness/에 둔다. - PreToolUse는 위험 명령과 C++ production file의 대응 테스트 존재 여부를 검사하는 guardrail이며 RED 실행을 증명하지 않는다.
- Stop은
.harness/config.json또는 자동 감지 결과에 따라 MSVC build와 test를 모두 검증한다. - Generated phase execution outputs remain ignored under
phases/**/step*-output.json.
현재 승인된 V0 기능 계약
linear-static-3d-euler-beam의 source of truth는docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md이다. 관련 문서를 변경하거나 구현할 때 이 계약의 의미를 임의로 넓히지 않는다.- 입력 파일당 하나의
*STEP, *STATIC과TYPE=B33만 지원한다. B31을 Euler 요소로 매핑하지 않고unsupported-element-formulation으로 거부한다. *PART/*ASSEMBLY/*INSTANCE는 identity instance와 stable source identity만 지원한다. instance transform과 nested assembly는 거부한다.- 선형 정적 실행 순서는 stiffness assembly와 constrained partition 뒤
Kff를 factorize하고, 그 다음 load vector와 effective RHS를 조립해 substitution하는 순서를 유지한다. - FESA는 output request와 무관하게 displacement, reaction, equilibrium end action, section resultant, generalized strain/resultant, axial
S11을 HDF5에 기록한다. Beam stress의 Abaqus reference comparison은 N/A다. - B33 reference row는 component별 Abaqus scale로
absolute_floor + 1e-6 * reference_scale을 적용한다. Reference 값을 zero-clamp하거나 누락 row를 무시하지 않는다. reference/cantilever beam/artifact는 rename, rewrite 또는 보정하지 않는다.
기능을 추가할 때의 판단 기준
- 새 element는 요구조건과 formulation을 승인한 뒤 semantic mapping, property/material 연결, DOF/scatter, local kernel, deterministic assembly, recovery, HDF5 row identity, reference/physics evidence를 함께 설계한다.
- 새 load 또는 constraint는 parser 인식만 추가하지 않는다. Source target resolution, stable application order, full-space assembly, partition/effective RHS, diagnostic과 결과 의미까지 연결한다.
- 새 analysis procedure는 기존 선형 정적 lifecycle에 조건문을 누적하지 않는다. 필요한 state, equation, solver lifecycle과 recovery contract를 별도 요구조건·ADR·formulation으로 정의한다.
- 새 backend는 기존 public interface를 유지하고 vendor lifecycle, integer/index conversion, runtime dependency와 failure translation을 adapter 내부에 격리한다.
- 새 output quantity는 계산식뿐 아니라 units, coordinate system, source/internal identity, HDF5 schema, mandatory 여부, reference projection과 tolerance를 동시에 정의한다.
- Element API에 kernel이 존재하는 것과 Abaqus keyword/CLI에서 그 기능을 노출하는 것은 별도 계약이다. 예를 들어 V0의 line-load kernel은
*DLOAD지원을 뜻하지 않는다.
개발 프로세스
- TDD를 기본으로 한다. 구현은
RED -> GREEN -> VERIFY순서를 따른다. - CRITICAL: 빌드 경고를 새로 추가하지 말 것.
- 기능 개발은 다음 gate를 순서대로 통과해야 한다.
- 요구조건 분석
- 연구자료 조사
- 유한요소 정식화
- 수치 검토
- I/O 계약 정의
- reference model 계약 준비
- C++ 구현
- build/test 검증
- reference comparison
- physics sanity
- release readiness
- 커밋 메시지는 conventional commits 형식을 따른다:
feat:,fix:,docs:,refactor:,test:,chore:.
Agent/Skill Workflow
AI 에이전트는 유한요소 구조해석 지식이 필요할 때 FEM wiki를 참조하기 위해 .codex/skills/fem-theory-query 스킬을 사용할 수 있다.
| 개발 과정 | Agent | Skill | 산출물 |
|---|---|---|---|
| 요구조건 분석 | requirement-agent |
fesa-requirements-baseline |
docs/requirements/<feature-id>.md |
| 연구자료 조사 | research-agent |
fesa-research-evidence, fem-theory-query |
docs/research/<feature-id>-research.md |
| 유한요소 정식화 | formulation-agent |
fesa-formulation-spec |
docs/formulations/<feature-id>-formulation.md |
| 수치 검토 | numerical-review-agent |
fesa-numerical-review |
docs/numerical-reviews/<feature-id>-review.md |
| I/O 정의 | io-definition-agent |
fesa-io-contract |
docs/io-definitions/<feature-id>-io.md |
| reference model | reference-model-agent |
fesa-reference-models |
docs/reference-models/<feature-id>-reference-models.md |
| 구현 계획/구현 | implementation-planning-agent, implementation-agent |
fesa-cpp-msvc-tdd |
tests, source, implementation report |
| build/test | build-test-executor-agent |
fesa-cpp-msvc-tdd |
docs/build-test-reports/<feature-id>.md |
| correction | correction-agent |
fesa-cpp-msvc-tdd |
docs/corrections/<feature-id>.md |
| reference 비교 | reference-verification-agent |
fesa-reference-comparison |
docs/reference-verifications/<feature-id>-reference-verification.md |
| 물리 검토 | physics-evaluation-agent |
fesa-physics-sanity |
docs/physics-evaluations/<feature-id>-physics-evaluation.md |
| 배포 준비 | release-agent |
fesa-release-readiness |
docs/releases/<feature-id>-release.md |
최소 검증 진입점
세부 target graph, dependency normalization과 Windows runtime staging은 docs/ARCHITECTURE.md와 실제 CMake 파일을 따른다. .harness/config.json이 존재하면 그 설정을 우선한다.
Harness Python 검증
uv run --with pytest python -m pytest -v -rs
Phase 실행
python scripts/execute.py <phase-name>
python scripts/execute.py <phase-name> --push
CMake/CTest 프로젝트
$gtestSource = "C:/path/to/googletest"
$mklDir = "C:/path/to/oneAPI/mkl/lib/cmake/mkl"
$tbbDir = "C:/path/to/oneAPI/tbb/lib/cmake/tbb"
$hdf5Dir = "C:/path/to/HDF5/cmake"
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
"-DMKL_DIR=$mklDir" `
"-DTBB_DIR=$tbbDir" `
"-DHDF5_DIR=$hdf5Dir"
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
FESA_GTEST_SOURCE_DIR는 approved local GoogleTest source checkout을 반드시 가리켜야 한다. MKL/TBB/HDF5가 기본 package search에서 발견되지 않는 환경에서는 나머지 세 config directory도 명시한다. FESA 제품 검증은 solution-only MSBuild가 아니라 CMake target과 CTest를 기준으로 한다.