Files
FESADev/AGENTS.md
T
2026-08-12 02:22:01 +09:00

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 .inp keyword 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>_*.csv canonical 이름을 사용한다.
  • 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에 분할하고, Kff factorization을 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.pyfeat-<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, *STATICTYPE=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를 순서대로 통과해야 한다.
    1. 요구조건 분석
    2. 연구자료 조사
    3. 유한요소 정식화
    4. 수치 검토
    5. I/O 계약 정의
    6. reference model 계약 준비
    7. C++ 구현
    8. build/test 검증
    9. reference comparison
    10. physics sanity
    11. 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를 기준으로 한다.