196 lines
20 KiB
Markdown
196 lines
20 KiB
Markdown
# 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가 하나의 추적 가능한 기능을 이뤄야 한다.
|
|
- 설계·구현 전에 [PRD](docs/PRD.md), [ARCHITECTURE](docs/ARCHITECTURE.md), [ADR](docs/ADR.md)에서 현재 작업에 관련된 제품 범위·소유권·데이터 흐름·결정을 확인한다. C++ naming, formatting, Doxygen와 변경 검증은 [CODINGSTYLE](docs/CODINGSTYLE.md)을 따른다. 같은 문맥에서 읽은 변경 없는 자료를 다시 읽지 않는다.
|
|
- 재사용 가능한 agent, skill과 Harness는 개발 운영 인프라다. 이를 일반화해도 이 저장소가 선택한 MSVC, Abaqus 입력 subset, HDF5 출력과 승인된 수치 계약은 바뀌지 않는다.
|
|
- FESA는 Abaqus와 독립적인 솔버다. 문서와 구현은 full Abaqus compatibility뿐 아니라
|
|
Abaqus 요소 정식화, 적분, stabilization, 내부 상태 또는 결과 생성 절차의 동등성을
|
|
주장하거나 목표로 삼지 않는다. 수치 결과의 exact equality는 허용되지만 내부 동작
|
|
동등성의 evidence가 아니다.
|
|
- 기능별로 승인된 Abaqus keyword subset만 입력 형식으로 지원한다. Abaqus 결과는 승인된
|
|
비교량의 외부 수치 reference일 뿐 FESA 내부 알고리즘 계약이 아니다.
|
|
- 공식 solver output은 입력 경로의 lexical sibling인 HDF5 `<stem>_results.h5`이다. 파일명과 저장 계약은 PRD와 ARCHITECTURE를 따른다.
|
|
- reference 결과는 FESA와 같은 Abaqus `.inp` 모델을 Abaqus로 해석해 생성한 CSV 파일이다.
|
|
- reference case는 기능 문서가 지정한 기존 `.inp`와 실제 비교에 필요한 Abaqus CSV 경로를
|
|
그대로 사용한다. canonical 이름, legacy-alias 승인, bundle `README.md`, `metadata.json`,
|
|
Abaqus version/provenance 또는 중복 unit/coordinate/step-frame/schema 기록은 readiness
|
|
조건이 아니다.
|
|
- 비교기는 필요한 source row identity와 component를 결정적으로 대응시키고 누락, 추가,
|
|
중복, nonfinite 값을 tolerance 전에 거부한다. Reference artifact는 rename, rewrite 또는
|
|
보정하지 않는다.
|
|
- 모든 외부 reference comparison의 scale, near-zero/relative/RMS 판정, zero-scale 처리와 보고서는 [TOLERANCE](docs/TOLERANCE.md)의 승인된 공통 정책을 따른다. Numerical Review는 이 정책 안에서 기능별 비교량, identity/component와 blocking/diagnostic 구분을 정의하며 고정된 수치 기준을 임의로 선택·완화하지 않는다. 정책 변경은 해당 문서의 사용자 승인과 ADR 절차를 따른다.
|
|
- B33 section-resultant reference는 `(instance, element label, endpoint node label,
|
|
component)`로 HDF5 element endpoint와 직접 대응한다. Node-station collapse 또는 평균을
|
|
사용하지 않는다. MITC4 `U1/U2/U3`는 blocking, `UR1/UR2/UR3`는 warning-only 분류를
|
|
유지하면서 같은 공통 수치 정책을 사용한다.
|
|
- CSV는 FESA 공식 output이 아니며, FESA HDF5에서 추출한 deterministic CSV view는 비교 디버깅/검토용 보조 artifact로만 둔다.
|
|
|
|
## 문서 기준과 Feature 관리
|
|
|
|
- 현행 운영 결정은 [ADR-028](docs/ADR.md#adr-028), 역할·인계·실패 처리는 [SOLVER_AGENT_DESIGN](docs/SOLVER_AGENT_DESIGN.md), skill 적용은 [SOLVER_SKILL_DESIGN](docs/SOLVER_SKILL_DESIGN.md), 문서 배치·소유권은 [FEATURE_DOCUMENTATION](docs/FEATURE_DOCUMENTATION.md)을 따른다. 실제 절차는 필요한 `SKILL.md`와 관련 reference만 읽는다.
|
|
- [HARNESS](docs/HARNESS.md)는 설치·설정·CLI, [HARNESS_WORKFLOW](docs/HARNESS_WORKFLOW.md)는 개발·검증 흐름을 설명한다. 실행 동작은 선택된 설정과 현재 `scripts/`에 대조하며 구현이 승인된 제품·수치 계약을 바꿀 권한은 없다.
|
|
- 지속할 계약·evidence가 필요한 Feature는 메인이 안정적인 kebab-case ID와 `docs/<feature-id>/`를 정한다. 작은 수정에는 새 Feature 폴더나 빈 보고서를 만들지 않는다.
|
|
- 일반 Feature 작업에서 프로젝트 `AGENTS.md`, `docs/PRD.md`, `docs/ADR.md`는 읽기 전용 기준이다. 현재 작업의 진행 링크를 누적하지 않으며 공통 지침 수정은 별도 사용자 요청 범위에서 수행한다.
|
|
- 새 Feature를 초기화하면 아래 핵심 문서 3개를 실제 요구사항으로 작성한다. 각 문서는 프로젝트 AGENTS·PRD·ADR를 상대 Markdown 링크로 참조한다.
|
|
|
|
| 메인 소유 문서 | 내용과 경계 |
|
|
| --- | --- |
|
|
| `FEATURED_AGENTS.md` | Feature ID·목적·지역 지침, 할당 owner와 문서 목록. 현재 checklist는 PRD로 연결 |
|
|
| `PRD.md` | 사용자 요구·범위·제외·acceptance와 현재 checklist. 작은 요구사항의 원본이며 복잡한 상세 계약은 필요한 경우만 분리하여 연결 |
|
|
| `ADR.md` | Feature 결정 ID·상태·결정·이유·영향과 owner·승인 근거 |
|
|
|
|
- 현재 checklist는 PRD 한 곳에 둔다. `requirements.md`·검증 matrix는 분리가 필요할 때만 작성하고 PRD에는 요약·링크만 유지한다. Specialist는 할당된 전문 문서만 수정한다.
|
|
- `FEATURED_AGENTS.md`는 자동 로드되는 `AGENTS.md`가 아니다. 메인은 필요한 Feature context와 관련 경로·절만 인계하며 모든 문서를 매번 재독하도록 요구하지 않는다.
|
|
- 기존 `coordination.md`, `docs/features/<feature-id>/`와 phase 자료는 이력으로 보존하고 필요한 경로·계약 revision을 참조한다. 자동 이동·복제하거나 신규 coordination 상태 파일을 만들지 않는다.
|
|
- 기존 Feature 재개 시 운영 절차와 승인된 요구사항을 구분하여 [ADR-028](docs/ADR.md#adr-028)을 적용한다. 현재 할 일과 근거 링크만 Feature PRD의 checklist에 정리한다.
|
|
- 보고서는 결정·결과, 적용 계약, evidence와 미해결 항목을 간결하게 기록한다. 간단한 구현·build/test·reference 결과는 한 보고서로 모으고 긴 유도·schema는 같은 폴더의 상세 문서로 분리해 연결한다.
|
|
- 실제 계약 변경은 관련 evidence의 유효성을 다시 확인한다. 의미 변화 없는 문서 편집마다 고정 handoff·hash·gate 기록을 만들지 않는다. 미실행 검사는 이유를 남기며 승인·통과로 표시하지 않는다.
|
|
- 소스·테스트·기계 생성 로그/결과·read-only reference 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 기준으로 검증한다.
|
|
- 동작 추가·수정은 해당 동작을 확인하는 테스트로 검증한다. 버그는 가능한 경우 실패를 재현한 뒤 최소 수정한다.
|
|
- 기존 coverage가 충분한 rename·refactor나 문서 수정에는 형식적인 새 테스트를 요구하지 않는다.
|
|
- CRITICAL: Abaqus reference artifact 생성, 수정, 복원은 명시적으로 요청된 작업 범위에서만 수행한다. 문서 또는 agent가 artifact naming이나 보조 metadata를 맞추기 위해 파일 변경을 요구하지 않는다.
|
|
- 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만 소유한다. 구체적인 state는 승인된 procedure 계약과 ARCHITECTURE를 따르며 미래 state를 미리 할당하지 않는다.
|
|
- MKL, TBB, HDF5, Win32 API와 vendor type은 public solver core에 노출하지 않는다. `LinearSolver`, `ParallelFor`, `ResultsWriter`, `Vector`, `Matrix`, `SparseMatrix` 경계 뒤에 둔다.
|
|
- 해석 단계는 실패할 수 있는 candidate를 완성하고 검증한 뒤 소유 state/output에 반영한다. 실패 시 기존 state와 기존 최종 HDF5를 가능한 계약 범위에서 보존한다.
|
|
|
|
### 선형 정적 해석 불변식
|
|
|
|
- 해석 실행의 공통 책임은 `docs/ARCHITECTURE.md`를 따른다. `LinearStaticAnalysis::Run()`의 구체적인 단계와 객체별 책임은 해당 기능의 승인된 계약과 구현을 대조한다.
|
|
- 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를 평균으로 합치지 않는다.
|
|
|
|
### 개발 운영 인프라
|
|
|
|
- 일반 specialist의 기본 추론 강도는 `medium`, 정식화·수치·물리 검토는 `high`다. 모델과 역할별 설정은 [.codex/agents](.codex/agents)의 현재 profile을 따르고 난해한 작업에만 필요한 범위에서 높인다.
|
|
- [scripts/execute.py](scripts/execute.py)는 명시적 build/test 실행기다. 내부 LLM·phase 상태기계·자동 Git·재시도·파일명 TDD gate·대화 종료 hook을 사용하지 않는다.
|
|
- 설정·preset·명령은 검토할 실행 입력이다. `shell=False`·경로 검사·timeout이 모든 side effect를 격리하는 sandbox는 아니며 실제 도구 권한과 외부 실행 승인은 별도로 따른다.
|
|
- 관련 없는 사용자 변경은 보존한다. Commit을 요청받으면 작업 경로만 stage하고 push·tag·publish 등 원격 작업은 명시적으로 승인된 범위에서 수행한다. Runner는 이 권한을 부여하거나 Git 상태를 변경하지 않는다.
|
|
- 기존 phase·hook 생성 기록은 이력으로 보존하며 ignored 상태를 유지한다. 현재 검증을 위해 기록을 조작하거나 삭제된 hook을 수동 실행하지 않는다.
|
|
|
|
## 기능을 추가할 때의 판단 기준
|
|
|
|
- 새 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` 지원을 뜻하지 않는다.
|
|
|
|
## 개발 프로세스
|
|
|
|
- 동작 변경을 검증하는 테스트와 가능한 버그 재현을 기본으로 하며 최소 수정 후 관련 검사를 수행한다.
|
|
- CRITICAL: 빌드 경고를 새로 추가하지 말 것.
|
|
- 수식·요소·재료·적분·상태 갱신 변경은 독립 numerical review와 해당 analytical/invariant 검증을 수행한다. 필요한 물리·reference 검증도 유지한다.
|
|
- 변경 중에는 관련 검사를, 솔버 기능 완료 시에는 구성된 전체 build/test와 필수 reference 비교를 한 번 수행한다. 사용자 요청이나 넓은 변경 영향으로 전체 검증이 필요한 경우에도 실행하며 이후 변경·실패가 없으면 반복하지 않는다.
|
|
- 문서만 수정하는 작업은 링크·소스 대조·diff 정적 검토로 확인하고 build/test를 실행하지 않는다. 미실행을 통과로 보고하지 않는다.
|
|
- 기능 문서는 기본적으로 한국어 Markdown으로 작성하되 agent/skill ID, field, requirement ID, 경로와 명령은 English를 유지한다. 새 requirement ID 기본 형식은 `FEM-REQ-<FEATURE>-###`이다.
|
|
- 커밋 메시지는 conventional commits 형식을 따른다: `feat:`, `fix:`, `docs:`, `refactor:`, `test:`, `chore:`.
|
|
|
|
## Agent/Skill Workflow
|
|
|
|
메인 assistant가 범위를 파악하고 필요한 전문 작업만 위임하며 계획·구현·검증·결과 확인을
|
|
조정한다. 작은 작업은 직접 수행하고 고정된 stage 순회나 별도 coordinator를 호출하지 않는다.
|
|
|
|
| Gate | Specialist | 호출 조건 | Skill |
|
|
| --- | --- | --- | --- |
|
|
| requirement | `requirement-agent` | 복잡하거나 상충하는 scope·acceptance 정리 | `fem-requirements-baseline` |
|
|
| research | `research-agent` | 부족한 이론·benchmark·reference 근거 조사 | `fem-research-evidence` |
|
|
| formulation | `formulation-agent` | 새 수식·요소·재료·해석 알고리즘 정식화 | `fem-formulation-spec` |
|
|
| numerical review | `numerical-review-agent` | 정식화·주요 수치 변경·수치 불일치의 독립 검토 | `fem-numerical-review` |
|
|
| io definition | `io-definition-agent` | 입력 의미·진단·결과 schema·비교 mapping 정의 | `fem-io-contract` |
|
|
| implementation | `implementation-agent` | 위임할 이점이 있는 구현 묶음 | `fem-implementation-tdd` |
|
|
| physics evaluation | `physics-evaluation-agent` | 평형·물리 타당성·coverage 평가 | `fem-physics-review` |
|
|
|
|
- 메인도 `fem-implementation-tdd`로 계획·구현·일반 실패 수정을 수행할 수 있다. 전용 planning/correction profile이나 phase 파일을 요구하지 않는다.
|
|
- `fem-release-readiness`는 사용자가 별도 감사를 명시 요청할 때만 사용한다. Readiness 권고는 외부 release 권한이 아니다.
|
|
- [harness](.agents/skills/harness/SKILL.md)는 구성된 build/test의 명시 실행, [review](.agents/skills/review/SKILL.md)는 요청 diff의 읽기 전용 검토, [fem-theory-query](.codex/skills/fem-theory-query/SKILL.md)는 configured FEM wiki 근거·coverage gap 조회에 사용한다. Workstation vault 절대 경로를 commit하지 않는다.
|
|
- Dispatch는 작업·관련 경로/절·수정 파일·검증 기준, return은 결과·변경 파일·검사 결과·미해결 항목으로 충분하다. 지원되는 도구에서는 `fork_turns="none"`으로 필요한 문맥만 전달하고 연속 수정은 같은 owner에게 보낸다.
|
|
- Specialist는 할당 범위를 지키고 peer를 재위임하거나 상위 계약을 결과에 맞춰 수정하지 않는다. 계약 문제는 owner·경로·근거와 함께 메인에 전달한다. 독립 검토를 자기 승인으로 대체하지 않는다.
|
|
- 일반 실패는 현재 구현 owner가 수정한다. 새 근거·변경 없이 같은 명령·agent 호출을 반복하지 않으며 고정 correction/transport 예산을 두지 않는다.
|
|
- 승인된 범위의 일반 작업과 인계에 반복 승인 gate를 추가하지 않는다. 계획 요청만으로 실행 권한을 추정하지 않는다.
|
|
- Physics·지원 범위·공개 호환성·acceptance·영속 schema 변경, 해결되지 않은 필수 계약/reference 충돌, 외부 solver 라이선스·자격증명·비용, 중대한 보안·법률 위험, destructive/remote/release 작업은 [SOLVER_AGENT_DESIGN](docs/SOLVER_AGENT_DESIGN.md)의 사용자 결정 경계를 따른다.
|
|
|
|
## 최소 검증 진입점
|
|
|
|
아래 명령은 해당 구현·검증 작업에만 사용한다. 현재 작업, `.harness/config.json`,
|
|
preset·project metadata와 프로젝트 기준을 대조하여 선택한다. 문서 수정에는 실행하지 않는다.
|
|
|
|
### Harness Python 검증
|
|
|
|
Harness 구현 변경에 필요한 검사는 관련 범위부터 실행하며 전체 검사가 필요할 때는 다음을 사용한다.
|
|
|
|
```powershell
|
|
uv run --with pytest python -B -m pytest -v -rs
|
|
```
|
|
|
|
이 Python suite는 Harness 구현을 검증한다. 현재 CMake/CTest 구성은 이를 실행하지 않으므로
|
|
`python scripts/execute.py`의 성공을 Python 회귀 검사 통과로 보고하지 않는다.
|
|
|
|
### 구성된 전체 build/test
|
|
|
|
```powershell
|
|
python scripts/execute.py
|
|
```
|
|
|
|
Phase 인자나 `--push`·`--approve-danger-full-access`를 추가하지 않는다. 이 인자들은
|
|
usage error로 거부된다. Exit 의미·설정·이전 방식 변경 안내는 [HARNESS](docs/HARNESS.md)를
|
|
따른다. 필요한 수치/reference 검증을 runner 성공만으로 대체하지 않는다.
|
|
|
|
### CMake/CTest 프로젝트
|
|
|
|
현재 [CMakePresets.json](CMakePresets.json)의 MSVC x64 Debug preset 사용 예시다.
|
|
MSVC x64 developer 환경에서 `FESA_GTEST_SOURCE_DIR`, `MKL_DIR`, `TBB_DIR`, `HDF5_DIR`
|
|
환경변수를 설치된 dependency 경로로 설정한다. `FESA_GTEST_SOURCE_DIR`는 승인된 local
|
|
GoogleTest source checkout, 나머지는 각 package의 CMake config directory를 가리킨다.
|
|
(FESA_GTEST_SOURCE_DIR 예시: C:\git\googletest)
|
|
|
|
```powershell
|
|
cmake --preset windows-msvc-ninja-debug
|
|
cmake --build --preset windows-msvc-ninja-debug
|
|
ctest --preset windows-msvc-ninja-debug --show-only=json-v1
|
|
ctest --preset windows-msvc-ninja-debug --output-on-failure
|
|
```
|
|
|
|
Runner에도 이 preset을 적용하려면 [HARNESS](docs/HARNESS.md)의 예시에 따라 개인
|
|
`.harness/config.json`의 `binaryDir`, `configurePreset`, `buildPreset`, `testPreset`을
|
|
함께 맞춘다. 현재 [.harness/config.example.json](.harness/config.example.json)은 최소
|
|
CMake 설정이며 preset 필드가 없다. Preset 파일이 있다는 사실만으로 runner가 이를
|
|
선택하지 않는다. FESA 제품 검증은 solution-only MSBuild가 아니라 CMake target과 CTest를
|
|
기준으로 한다. Target graph·dependency·Windows runtime staging은 ARCHITECTURE와 실제
|
|
CMake 파일을 따른다.
|