diff --git a/.gitignore b/.gitignore index 8c0e18b..698a91f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ __pycache__/ phases/**/phase*-output.json phases/**/step*-output.json /CMakeUserPresets.json + +# local document backups and initialization state +.dryforge/ diff --git a/AGENTS.md b/AGENTS.md index 4b02d44..7b3b97a 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,195 +1,132 @@ -# Project: FESA Structural Solver +# FESA Structural Solver -## 기술 스택 +FESA는 개인 연구를 위해 개발하는 유한요소 구조해석 솔버이며 외부 사용자 배포를 장기 +목표로 한다. C++17 이상·Windows MSVC·CMake/CTest를 사용하고 승인된 Abaqus 입력 +subset에서 재현 가능한 해석과 HDF5 결과를 제공한다. 코드 존재와 기능 검증 완료는 다르다. -- 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 `_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 폴더나 빈 보고서를 만들지 않는다. -- 일반 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//`와 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--###`이다. -- 커밋 메시지는 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 +```text +. +├── AGENTS.md → 작업 진입점과 핵심 규칙 +├── CLAUDE.md → 같은 내용의 작업 진입점 +├── docs/ +│ ├── ARCHITECTURE.md → 구성·데이터 흐름·소유권 +│ ├── business-rules.md → 물리 의미와 제품 범위 +│ ├── security.md → 실행 권한과 데이터 취급 +│ ├── standards.md → 개발·검증·변경의 공통 규칙 +│ ├── engineering-notes.md → 수치·실행에서 혼동하기 쉬운 점 +│ ├── operations.md → 환경 준비·빌드·검사·실행 +│ ├── contracts.md → CLI·입력·결과·비교 계약 +│ ├── PRD.md → 기존 공통 요구사항과 승인 ID +│ ├── ADR.md → 기존 결정·승인·대체 이력 +│ ├── TOLERANCE.md → 승인된 외부 비교 기준의 상세 원본 +│ ├── CODINGSTYLE.md → 기존 C++ 규약의 상세 원본 +│ ├── FEATURE_DOCUMENTATION.md → 기능별 기록의 소유권 +│ ├── SOLVER_AGENT_DESIGN.md → 전문 역할과 사용자 결정 경계 +│ ├── SOLVER_SKILL_DESIGN.md → 전문 skill의 적용 범위 +│ ├── HARNESS.md → 기존 검증 실행기 상세 사용법 +│ ├── HARNESS_WORKFLOW.md → 검증 실행기의 책임과 실패 처리 +│ ├── / → 해당 기능의 요구·결정·수식·I/O·evidence +│ └── tracking/ +│ ├── status.md → 구현·검증 상태와 남은 범위 +│ ├── findings.md → 미해결 문제와 영향 +│ └── decisions/ +│ ├── index.md → 유지하는 선택 목록 +│ ├── 0001-independent-solver.md → 외부 subset과 내부 독립성 +│ ├── 0002-build-and-backends.md → 검증 환경과 vendor 격리 +│ ├── 0003-model-and-equations.md → 모델·view·equation 소유권 +│ ├── 0004-ordered-assembly.md → local 계산과 결정적 누적 +│ ├── 0005-state-and-output.md → candidate와 최종 결과 보존 +│ ├── 0006-procedure-lifecycle.md → 절차별 상태와 full residual +│ ├── 0007-reference-evidence.md → 원본과 수치 비교 정책 +│ ├── 0008-layered-verification.md → 독립 수치·물리 검증 +│ ├── 0009-explicit-development.md → 필요한 전문 작업과 명시 실행 +│ ├── 0010-feature-contract-ownership.md → 기능별 계약 소유권 +│ ├── 0011-eigen-first-implementation.md → 고유치 첫 구현의 경계 +│ ├── 0012-hht-kinetic-mass.md → 동역학 질량 선택 +│ └── 0013-thermal-staged-scope.md → 초기 열해석 범위 +├── include/fesa/ +│ └── AGENTS.md → 공개 API와 수명·의존성 +├── src/fesa/ +│ ├── AGENTS.md → production target과 구현 경계 +│ ├── app/AGENTS.md → 경로·lease·실행 조합 +│ ├── core/AGENTS.md → source identity·진단 +│ ├── model/AGENTS.md → Domain·target·geometry +│ ├── properties/AGENTS.md → section·material 연결 +│ ├── materials/AGENTS.md → 물성 capability와 구성 관계 +│ ├── elements/AGENTS.md → local 수식·회전·관성 +│ ├── loads/AGENTS.md → 하중 의미와 contribution +│ ├── fem/AGENTS.md → DOF·equation·pattern +│ ├── constraints/AGENTS.md → 지정값·partition +│ ├── assembly/AGENTS.md → deterministic reduction +│ ├── analysis/AGENTS.md → procedure·trial·commit +│ ├── math/AGENTS.md → storage·private 수치 adapter +│ ├── solvers/ +│ │ ├── linear/AGENTS.md → factorization·solve +│ │ └── eigen/AGENTS.md → FEAST·count·검증 경계 +│ ├── results/AGENTS.md → 복구량·identity·candidate +│ └── io/ +│ ├── abaqus/AGENTS.md → 문법·의미 mapping +│ └── hdf5/AGENTS.md → schema·readback·finalize +├── scripts/ +│ ├── AGENTS.md → 명시 실행 진입점 +│ ├── msvc_harness/AGENTS.md → config·toolchain·명령 실행 +│ └── verification/AGENTS.md → 원본 reference 비교 +├── tests/ +│ └── AGENTS.md → 계층별 검사·실패·비교 evidence +└── cmake/ + └── AGENTS.md → dependency·runtime 연결 ``` -이 Python suite는 Harness 구현을 검증한다. 현재 CMake/CTest 구성은 이를 실행하지 않으므로 -`python scripts/execute.py`의 성공을 Python 회귀 검사 통과로 보고하지 않는다. +## 핵심 규칙 -### 구성된 전체 build/test +1. 승인된 물리·입력·결과·수치 기준을 구현 편의로 바꾸지 않는다. 모호한 의미를 silent + default·clamp·평균으로 숨기지 않는다. +2. Source identity와 내부 index를 구분하고 병렬 실행에서도 구조·누적·결과·진단 순서를 + 결정적으로 유지한다. +3. 모델 정의·equation·state·local 계산·adapter의 소유권을 지킨다. Vendor 타입을 public + core에 노출하지 않고 실패한 candidate가 유효한 state나 최종 HDF5를 오염시키지 않게 한다. +4. Reference 원본과 관련 없는 사용자 변경을 보존한다. 생성·수정·복원, 외부 solver·비용, + 원격·파괴·release 작업은 명시적으로 승인된 범위에 한정한다. +5. 실행 성공을 correctness로 대체하지 않는다. 수식 변경에는 독립 검토와 필요한 물리 + 검증을 수행하고 실패·미실행·과거 evidence를 현재 통과로 보고하지 않는다. -```powershell -python scripts/execute.py -``` +## 작업 전 확인 -Phase 인자나 `--push`·`--approve-danger-full-access`를 추가하지 않는다. 이 인자들은 -usage error로 거부된다. Exit 의미·설정·이전 방식 변경 안내는 [HARNESS](docs/HARNESS.md)를 -따른다. 필요한 수치/reference 검증을 runner 성공만으로 대체하지 않는다. +기본적으로 [개발 규칙](docs/standards.md), [주의점](docs/engineering-notes.md)과 +변경할 영역의 AGENTS.md를 확인한다. 같은 문맥에서 읽고 바뀌지 않은 자료는 다시 읽지 않는다. +Public header 변경은 대응하는 src 영역의 책임과 consumer까지 확인한다. -### CMake/CTest 프로젝트 +- 범위·physics·절차 변경: [제품 요구](docs/PRD.md), [구조](docs/ARCHITECTURE.md), + [기존 결정](docs/ADR.md)과 해당 Feature의 PRD·ADR·정식화·독립 검토. +- 입력·결과·비교 변경: [외부 계약](docs/contracts.md), [수치 기준](docs/TOLERANCE.md), + 해당 Feature의 I/O·reference mapping. 공통 요약이 승인된 상세 계약을 덮어쓰지 않는다. +- C++ 구현: [코딩 규약](docs/CODINGSTYLE.md), 해당 영역 지침과 행동을 검증할 검사. +- 실행기·빌드 변경: [실행 방법](docs/operations.md), 실제 config·preset·target graph. + Config와 명령의 side effect는 실행 전에 확인한다. +- 기능 재개: [전체 현황](docs/tracking/status.md)과 Feature PRD의 실제 checklist. + 폐기된 phase·hook·고정 stage 순회를 복원하지 않는다. -현재 [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) +[기능 기록](docs/FEATURE_DOCUMENTATION.md)의 FEATURED_AGENTS·PRD·ADR과 기존 +요구사항 ID·승인 이력은 보존한다. 공통 지침을 바꾸는 별도 요청 없이 일반 Feature 작업에서 +프로젝트 PRD·ADR·지침을 수정하지 않는다. 현재 checklist는 Feature PRD 한 곳에 둔다. -```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 -``` +메인이 필요한 전문 작업만 배정한다. 역할은 [전문 작업 운영](docs/SOLVER_AGENT_DESIGN.md), +적용 범위는 [Skill 사용](docs/SOLVER_SKILL_DESIGN.md)을 따른다. 구현 계획·수정에는 +fem-implementation-tdd, 명시 build/test에는 [harness](.agents/skills/harness/SKILL.md), +요청 diff 검토에는 [review](.agents/skills/review/SKILL.md)를 사용한다. Release-readiness는 +별도 명시 요청에만 수행한다. 승인된 일반 작업에 반복 승인 gate를 추가하지 않는다. -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 파일을 따른다. +## 문제 처리 + +승인된 physics·acceptance·영속 schema를 바꿔야 하는 경우, 필수 reference와 계약이 +충돌한 경우, 기존 최종 결과 손상·원본 reference 변경이 발견된 경우에는 즉시 사용자에게 +근거와 영향을 알린다. 자동으로 tolerance를 완화하거나 데이터를 복구·보정하지 않는다. + +나머지 문제는 현재 owner가 관련 범위에서 해결한다. 지금 해결할 수 없는 문제는 재현 조건, +영향, 해결하지 못하는 이유와 다음 접근을 [미해결 문제](docs/tracking/findings.md)에 기록한다. +새 근거나 변경 없이 같은 명령·agent 호출을 반복하지 않는다. + +문서만 변경하면 정적 검토를 하고 build/test를 실행하지 않는다. 동작 변경은 관련 검사부터, +솔버 기능 완료 시에는 구성된 전체 MSVC x64 Debug build/CTest와 필수 reference 비교를 수행한다. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..7b3b97a --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,132 @@ +# FESA Structural Solver + +FESA는 개인 연구를 위해 개발하는 유한요소 구조해석 솔버이며 외부 사용자 배포를 장기 +목표로 한다. C++17 이상·Windows MSVC·CMake/CTest를 사용하고 승인된 Abaqus 입력 +subset에서 재현 가능한 해석과 HDF5 결과를 제공한다. 코드 존재와 기능 검증 완료는 다르다. + +## 프로젝트 문서와 영역 + +```text +. +├── AGENTS.md → 작업 진입점과 핵심 규칙 +├── CLAUDE.md → 같은 내용의 작업 진입점 +├── docs/ +│ ├── ARCHITECTURE.md → 구성·데이터 흐름·소유권 +│ ├── business-rules.md → 물리 의미와 제품 범위 +│ ├── security.md → 실행 권한과 데이터 취급 +│ ├── standards.md → 개발·검증·변경의 공통 규칙 +│ ├── engineering-notes.md → 수치·실행에서 혼동하기 쉬운 점 +│ ├── operations.md → 환경 준비·빌드·검사·실행 +│ ├── contracts.md → CLI·입력·결과·비교 계약 +│ ├── PRD.md → 기존 공통 요구사항과 승인 ID +│ ├── ADR.md → 기존 결정·승인·대체 이력 +│ ├── TOLERANCE.md → 승인된 외부 비교 기준의 상세 원본 +│ ├── CODINGSTYLE.md → 기존 C++ 규약의 상세 원본 +│ ├── FEATURE_DOCUMENTATION.md → 기능별 기록의 소유권 +│ ├── SOLVER_AGENT_DESIGN.md → 전문 역할과 사용자 결정 경계 +│ ├── SOLVER_SKILL_DESIGN.md → 전문 skill의 적용 범위 +│ ├── HARNESS.md → 기존 검증 실행기 상세 사용법 +│ ├── HARNESS_WORKFLOW.md → 검증 실행기의 책임과 실패 처리 +│ ├── / → 해당 기능의 요구·결정·수식·I/O·evidence +│ └── tracking/ +│ ├── status.md → 구현·검증 상태와 남은 범위 +│ ├── findings.md → 미해결 문제와 영향 +│ └── decisions/ +│ ├── index.md → 유지하는 선택 목록 +│ ├── 0001-independent-solver.md → 외부 subset과 내부 독립성 +│ ├── 0002-build-and-backends.md → 검증 환경과 vendor 격리 +│ ├── 0003-model-and-equations.md → 모델·view·equation 소유권 +│ ├── 0004-ordered-assembly.md → local 계산과 결정적 누적 +│ ├── 0005-state-and-output.md → candidate와 최종 결과 보존 +│ ├── 0006-procedure-lifecycle.md → 절차별 상태와 full residual +│ ├── 0007-reference-evidence.md → 원본과 수치 비교 정책 +│ ├── 0008-layered-verification.md → 독립 수치·물리 검증 +│ ├── 0009-explicit-development.md → 필요한 전문 작업과 명시 실행 +│ ├── 0010-feature-contract-ownership.md → 기능별 계약 소유권 +│ ├── 0011-eigen-first-implementation.md → 고유치 첫 구현의 경계 +│ ├── 0012-hht-kinetic-mass.md → 동역학 질량 선택 +│ └── 0013-thermal-staged-scope.md → 초기 열해석 범위 +├── include/fesa/ +│ └── AGENTS.md → 공개 API와 수명·의존성 +├── src/fesa/ +│ ├── AGENTS.md → production target과 구현 경계 +│ ├── app/AGENTS.md → 경로·lease·실행 조합 +│ ├── core/AGENTS.md → source identity·진단 +│ ├── model/AGENTS.md → Domain·target·geometry +│ ├── properties/AGENTS.md → section·material 연결 +│ ├── materials/AGENTS.md → 물성 capability와 구성 관계 +│ ├── elements/AGENTS.md → local 수식·회전·관성 +│ ├── loads/AGENTS.md → 하중 의미와 contribution +│ ├── fem/AGENTS.md → DOF·equation·pattern +│ ├── constraints/AGENTS.md → 지정값·partition +│ ├── assembly/AGENTS.md → deterministic reduction +│ ├── analysis/AGENTS.md → procedure·trial·commit +│ ├── math/AGENTS.md → storage·private 수치 adapter +│ ├── solvers/ +│ │ ├── linear/AGENTS.md → factorization·solve +│ │ └── eigen/AGENTS.md → FEAST·count·검증 경계 +│ ├── results/AGENTS.md → 복구량·identity·candidate +│ └── io/ +│ ├── abaqus/AGENTS.md → 문법·의미 mapping +│ └── hdf5/AGENTS.md → schema·readback·finalize +├── scripts/ +│ ├── AGENTS.md → 명시 실행 진입점 +│ ├── msvc_harness/AGENTS.md → config·toolchain·명령 실행 +│ └── verification/AGENTS.md → 원본 reference 비교 +├── tests/ +│ └── AGENTS.md → 계층별 검사·실패·비교 evidence +└── cmake/ + └── AGENTS.md → dependency·runtime 연결 +``` + +## 핵심 규칙 + +1. 승인된 물리·입력·결과·수치 기준을 구현 편의로 바꾸지 않는다. 모호한 의미를 silent + default·clamp·평균으로 숨기지 않는다. +2. Source identity와 내부 index를 구분하고 병렬 실행에서도 구조·누적·결과·진단 순서를 + 결정적으로 유지한다. +3. 모델 정의·equation·state·local 계산·adapter의 소유권을 지킨다. Vendor 타입을 public + core에 노출하지 않고 실패한 candidate가 유효한 state나 최종 HDF5를 오염시키지 않게 한다. +4. Reference 원본과 관련 없는 사용자 변경을 보존한다. 생성·수정·복원, 외부 solver·비용, + 원격·파괴·release 작업은 명시적으로 승인된 범위에 한정한다. +5. 실행 성공을 correctness로 대체하지 않는다. 수식 변경에는 독립 검토와 필요한 물리 + 검증을 수행하고 실패·미실행·과거 evidence를 현재 통과로 보고하지 않는다. + +## 작업 전 확인 + +기본적으로 [개발 규칙](docs/standards.md), [주의점](docs/engineering-notes.md)과 +변경할 영역의 AGENTS.md를 확인한다. 같은 문맥에서 읽고 바뀌지 않은 자료는 다시 읽지 않는다. +Public header 변경은 대응하는 src 영역의 책임과 consumer까지 확인한다. + +- 범위·physics·절차 변경: [제품 요구](docs/PRD.md), [구조](docs/ARCHITECTURE.md), + [기존 결정](docs/ADR.md)과 해당 Feature의 PRD·ADR·정식화·독립 검토. +- 입력·결과·비교 변경: [외부 계약](docs/contracts.md), [수치 기준](docs/TOLERANCE.md), + 해당 Feature의 I/O·reference mapping. 공통 요약이 승인된 상세 계약을 덮어쓰지 않는다. +- C++ 구현: [코딩 규약](docs/CODINGSTYLE.md), 해당 영역 지침과 행동을 검증할 검사. +- 실행기·빌드 변경: [실행 방법](docs/operations.md), 실제 config·preset·target graph. + Config와 명령의 side effect는 실행 전에 확인한다. +- 기능 재개: [전체 현황](docs/tracking/status.md)과 Feature PRD의 실제 checklist. + 폐기된 phase·hook·고정 stage 순회를 복원하지 않는다. + +[기능 기록](docs/FEATURE_DOCUMENTATION.md)의 FEATURED_AGENTS·PRD·ADR과 기존 +요구사항 ID·승인 이력은 보존한다. 공통 지침을 바꾸는 별도 요청 없이 일반 Feature 작업에서 +프로젝트 PRD·ADR·지침을 수정하지 않는다. 현재 checklist는 Feature PRD 한 곳에 둔다. + +메인이 필요한 전문 작업만 배정한다. 역할은 [전문 작업 운영](docs/SOLVER_AGENT_DESIGN.md), +적용 범위는 [Skill 사용](docs/SOLVER_SKILL_DESIGN.md)을 따른다. 구현 계획·수정에는 +fem-implementation-tdd, 명시 build/test에는 [harness](.agents/skills/harness/SKILL.md), +요청 diff 검토에는 [review](.agents/skills/review/SKILL.md)를 사용한다. Release-readiness는 +별도 명시 요청에만 수행한다. 승인된 일반 작업에 반복 승인 gate를 추가하지 않는다. + +## 문제 처리 + +승인된 physics·acceptance·영속 schema를 바꿔야 하는 경우, 필수 reference와 계약이 +충돌한 경우, 기존 최종 결과 손상·원본 reference 변경이 발견된 경우에는 즉시 사용자에게 +근거와 영향을 알린다. 자동으로 tolerance를 완화하거나 데이터를 복구·보정하지 않는다. + +나머지 문제는 현재 owner가 관련 범위에서 해결한다. 지금 해결할 수 없는 문제는 재현 조건, +영향, 해결하지 못하는 이유와 다음 접근을 [미해결 문제](docs/tracking/findings.md)에 기록한다. +새 근거나 변경 없이 같은 명령·agent 호출을 반복하지 않는다. + +문서만 변경하면 정적 검토를 하고 build/test를 실행하지 않는다. 동작 변경은 관련 검사부터, +솔버 기능 완료 시에는 구성된 전체 MSVC x64 Debug build/CTest와 필수 reference 비교를 수행한다. diff --git a/cmake/AGENTS.md b/cmake/AGENTS.md new file mode 100644 index 0000000..ddd3169 --- /dev/null +++ b/cmake/AGENTS.md @@ -0,0 +1,13 @@ +# Dependency와 빌드 경계 + +이 영역은 package 탐색·project-owned dependency target과 실행 환경 연결을 소유한다. +설치된 개인 경로를 source contract로 고정하거나 자동 download를 추가하지 않는다. + +- GoogleTest는 승인된 local source checkout을 사용한다. MSVC runtime을 FESA와 맞추되 + 외부 source tree 자체를 변경하지 않는다. +- MKL·TBB·HDF5의 vendor target 차이는 Fesa-owned target 뒤에 둔다. Vendor 타입이나 + include requirement가 public solver core로 역류하지 않게 한다. +- Windows DLL·OpenMP·Intel runtime staging은 link와 별도 검증 대상이다. 개발자 PATH의 + 우연한 dependency로 성공한 것을 독립 배포 검증으로 간주하지 않는다. +- Target graph·preset을 바꾸면 configure·MSVC compiler·실제 CTest discovery와 runtime + loading을 검증한다. Solution-only 성공으로 CMake 제품 검증을 대체하지 않는다. diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 564d362..9323ed0 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,260 +1,131 @@ -# FESA 구조해석 솔버 아키텍처 +# FESA 시스템 구조 -## 목적과 적용 범위 +## 구성과 의존성 -FESA는 유한요소법 기반 구조해석 솔버를 단계적으로 구축한다. 이 문서는 -[PRD](PRD.md)의 제품 목표를 공통 책임, 의존성, 데이터와 수명 경계로 연결한다. -특정 요소·재료·하중의 정식화, 해석 알고리즘, 코드 목록 또는 구현 완료 현황은 다루지 않는다. - -구체적인 API, 수식, 실행 순서와 결과 schema는 `docs//`의 승인된 -정식화·I/O·구현 계약에서 정의한다. 아래의 책임 모델은 아직 없는 클래스, 공통 base, -state field 또는 디렉토리를 미리 만들라는 지시가 아니다. 기존 구현의 승인된 의미를 -일반적인 설명에 맞추어 변경하지 않는다. - -설계 결정과 변경 근거는 [ADR](ADR.md), 코드 규약은 [CODINGSTYLE](CODINGSTYLE.md)을 -따른다. 현재 프로젝트의 기술 선택은 [AGENTS.md](../AGENTS.md)와 실행 가능한 -build/configuration에서 확인한다. - -## 아키텍처 원칙 - -- 물리·수치 의미는 외부 파일 형식과 vendor API보다 독립적인 계약으로 유지한다. -- 모델 정의, 현재 실행 view, equation 구성, mutable state와 결과의 소유권을 구분한다. -- Local physics 계산과 global topology, assembly, constraint, solve 책임을 분리한다. -- Identity, units, coordinates, ordering과 failure 의미를 경계마다 명시한다. -- Candidate를 완성·검증한 뒤 계약된 state나 authoritative output에 반영한다. -- 병렬화와 최적화에서도 결정적인 ordering과 failure preservation을 유지한다. -- 실제 승인된 사용 사례에 필요한 최소 확장만 도입한다. - -## Solver runtime과 개발 운영 영역 +FESA는 로컬 모델 파일을 읽어 해석하고 HDF5 결과를 저장하는 C++ 솔버다. 현재 공개 +실행 경로는 하나의 CLI이며, 내부 정적 library와 테스트 target이 같은 core를 사용한다. +개발용 Python 실행기는 솔버 runtime의 의존성이 아니다. ```text -Solver runtime -입력 adapter → semantic model → analysis procedure → recovery/results → 출력 adapter - │ - ├─ DOF / equation / sparse pattern - ├─ element / material / load contribution - ├─ assembly / constraint policy - └─ numerical backend - -개발 운영 영역 -사용자 요구 → 메인 assistant → 필요한 전문 작업·구현 → 검증·결과 확인 - │ - └─ 명시적 Harness / 코드·테스트·문서 변경 +fesa_cli + └─ app: 경로·출력 쓰기 소유권·실행 조합 + ├─ io/abaqus: 입력 읽기 → syntax → semantic mapping + │ └─ model: Domain·source identity·재료/단면/step 정의 + └─ analysis: 준비된 모델 → procedure별 실행 → 완료 candidate + ├─ AnalysisModel: Domain의 non-owning view + ├─ fem / constraints: DOF·equation·partition + ├─ elements / materials / properties / loads: local 계산 + ├─ assembly: 결정적인 global 누적 + ├─ math / solvers: storage·PARDISO·FEAST + └─ results: 물리 결과 복구·state 반영 + └─ io/hdf5: candidate 파일 → self-check·close → 최종 교체 ``` -첫 흐름은 해석 데이터의 전달을, 두 번째는 개발 작업과 검증의 흐름을 나타낸다. -Agent, skill과 Harness는 solver runtime API나 물리 모델의 일부가 아니다. -개발 운영 영역은 저장소의 변경과 검증을 통제하며 solver가 실행 중 이를 호출하지 않는다. +Consumer는 backend-neutral contract를 통해 값을 주고받는다. MKL·TBB·HDF5·Win32 +header와 handle은 private implementation에 머문다. 새 물리나 backend를 추가할 때 +core가 외부 adapter를 참조하는 방향으로 의존성을 뒤집지 않는다. -## 공통 책임과 의존성 +## 모듈 경계 -아래 명칭은 책임 경계이며 반드시 각각 하나의 클래스나 독립 library를 뜻하지 않는다. -실제 타입과 파일 배치는 승인된 Feature와 현재 코드 구조에서 결정한다. - -| 경계 | 소유하는 책임 | 소유하지 않는 책임 | +| 영역 | 소유하는 책임 | 경계 밖의 책임 | | --- | --- | --- | -| Core identity/diagnostic | Source identity, 공통 상태와 진단의 의미 | 파일 문법, 물리 정식화, vendor resource | -| Input adapter | 외부 syntax와 지원 semantics의 검증·mapping | 해석 알고리즘과 acceptance 변경 | -| Model definition | Topology, 재료·property·하중·제약·step 정의와 stable identity | Equation 번호, 해석 중 mutable solution | -| Active model view | 현재 procedure/step에 필요한 모델의 non-owning 참조 | 원본 모델 복사나 수명 소유 | -| Element/material | 승인된 local ordering의 물리 응답과 recovery 계약 | Global equation numbering, 직접 sparse write, 파일 저장 | -| Load definition/evaluation | Target·magnitude·configuration 의미와 ordered contribution | Global vector의 공유 누적 | -| DOF/equation | 활성 DOF, full/free/constrained mapping, numbering, scatter와 sparse pattern | 요소 정식화, 수치 factorization | -| Assembly | Local contribution을 지정된 global structure에 결정적으로 누적 | Physics 재해석, equation 번호의 분산 생성 | -| Constraint policy | 승인된 제약의 equation 적용과 해 복구 의미 | Input syntax나 별도 물리 모델의 임의 도입 | -| Analysis procedure | 필요한 state·해법·반복/종료·commit·recovery lifecycle | Vendor handle이나 concrete storage API의 공개 | -| Numerical backend | 행렬·벡터 연산, 해법 resource와 backend failure translation | Source label의 물리 의미, 입력 모델 해석 | -| Results/recovery | 계산 결과의 물리량·위치·identity와 state 반영 | 저장 파일 layout이나 reference 데이터 보정 | -| Output adapter | 승인 schema로의 serialization, self-check와 finalization | 물리량 정의와 acceptance 판정 변경 | +| `include/fesa` | 공개 선언, 값·실패·수명 계약 | Vendor handle, 실행별 equation 저장 | +| `app` | CLI 경로, output lease, 객체 조합과 외부 종료 | 요소 정식화, 수렴 기준 결정 | +| `core` | Source identity, ASCII 처리, Status·Diagnostic | 입력 procedure 허용 범위 | +| `io/abaqus` | 문법·scope·semantic mapping, Domain 생성 | 해법, 결과 복구 | +| `model` | 전체 정의, target 해석, 초기 shell geometry | Mutable solution, global equation 번호 | +| `properties` | 재료 연결과 beam/shell 단면 정의 | 물성 평가식, state 수명 | +| `materials` | 구성 관계와 필요한 물성 capability | Element topology, analysis state | +| `elements` | Local 행렬·힘·관성·회복에 필요한 응답 | Global CSR 갱신, 파일 접근 | +| `loads` | 하중 의미·configuration·local contribution | Global 공유 누적, 입력 target 이름 해석 | +| `fem` | DOF, scatter, full/free/constrained mapping, pattern | 선형계 factorization | +| `constraints` | 지정값 적용, partition·대입 정책 | 물리 결과 재해석 | +| `assembly` | Sparse·하중·압력 contribution의 ordered reduction | Equation 번호 발급, 수렴 판정 | +| `analysis` | Procedure별 초기화·증분·반복·종료·state lifecycle | Concrete 저장 형식, vendor resource 공개 | +| `math` | Vector·Matrix·SparseMatrix, private BLAS adapter | 모델 의미, source target lookup | +| `solvers/linear` | PARDISO factorization·solve, resource와 실패 변환 | 경계조건 변경, 모델 수정 | +| `solvers/eigen` | FEAST 실행과 수치 제어의 backend 경계 | Source EIGENSOLVER의 재해석, 외부 비교 판정 | +| `results` | Location·부호·좌표가 명확한 복구와 candidate commit | HDF5 layout, reference 보정 | +| `io/hdf5` | Schema serialization·readback·최종 파일 교체 | 물리량 정의, acceptance 완화 | -의존성은 consumer가 명시된 contract를 사용하는 방향으로 둔다. Input/output과 vendor -adapter가 core 계약에 의존하며, public core가 concrete adapter나 vendor/OS 타입에 -의존하지 않는다. Interface와 implementation의 의존성 방향을 역전하지 않는다. +같은 module의 public 선언은 `include/fesa/`, implementation은 +`src/fesa/`에 나뉜다. 이 물리적 분리가 interface와 implementation의 소유권을 +둘로 나누지는 않는다. Parser가 concrete numerical storage를 생성·조작하는 대신 +semantic 정의와 검증된 생성 경계로 연결한다. -Numerical consumer가 요소 종류별 concrete storage를 직접 분기하지 않도록 승인된 -evaluation/contribution contract를 사용한다. Definition과 runtime object의 호환성은 -지정된 생성 경계에서 검사한다. 이를 위해 speculative registry, 공유 소유권 또는 -사용하지 않는 polymorphic capability를 추가하지 않는다. +## 대표 실행 흐름 -## 데이터 계약 +1. App이 단일 입력 경로에서 lexical sibling 결과·로그 경로를 만들고 output lease를 + 획득한다. Lease를 얻기 전에 공개 파일을 truncate하지 않는다. +2. 입력을 한 번 읽고 source 위치·raw 표기와 함께 syntax를 해석한다. Mapper가 target, + element/section/material 및 procedure 조합을 검증해 Domain을 만든다. +3. 준비 단계가 static, nonlinear static, frequency 또는 HHT executor로 분기한다. + Domain을 복사해 별도 모델을 만들지 않는다. +4. 선택된 procedure가 active view, equation과 workspace를 구성하고 local 계산, + ordered assembly, constraint, solve 및 필요한 반복을 수행한다. +5. 해와 recovery를 검증해 procedure 전용 state에 반영한다. 비선형·동적 trial은 + 이전 committed state/history와 독립적이며 실패한 trial은 공개하지 않는다. +6. 완료 outcome을 얻은 뒤 로그 close를 확인하고 해당 writer를 호출한다. Writer는 + 임시 파일에 기록·검사·close를 마친 뒤 최종 HDF5를 교체한다. -### Identity +State commit과 파일 교체는 별개의 실패 경계다. 일부 frame을 내부에서 accept했더라도 +전체 해석이 실패했다면 미완성 이력을 새로운 정상 결과 파일로 공개하지 않는다. +반면 실행 로그는 실패를 설명하기 위해 남을 수 있어 최종 결과와 보존 범위가 다르다. -다음 개념을 같은 정수나 row 위치라는 이유로 서로 대체하지 않는다. +## 해석 모델과 수명 -- Source identity: 외부 입력에서 의미가 있는 label과 instance/scope -- Internal identity/index: 검증된 모델 내부의 안정된 식별 또는 위치 -- DOF identity: Entity의 물리 자유도와 component -- Equation index: 특정 procedure의 equation ordering -- Result identity: Entity, quantity, location, component, step/frame과 coordinate 의미 +Domain이 모델 정의를 소유한다. AnalysisModel, DOF 구성에 사용되는 참조와 실행 객체가 +Domain보다 오래 살아서는 안 된다. DofManager는 topology에서 물리 DOF와 equation +순서를 구성하며 node/element 내부에 equation 번호를 배포하지 않는다. -Renumbering, filtering, 병렬 scheduling과 serialization 뒤에도 필요한 대응 관계를 -보존한다. Reference matching은 row 순서가 아니라 계약된 source identity와 component를 -사용한다. 특정 typed wrapper나 result-key 클래스를 이 문서만으로 새로 만들지 않는다. +현재 procedure마다 static, nonlinear, eigen, dynamic state를 구별한다. 공통된다는 +이유로 사용하지 않는 가속도·plastic state·thermal field를 일괄 추가하지 않는다. +새 procedure는 필요한 lifecycle을 정의한 뒤 준비 단계에서 연결한다. 기존 static +반복문에 조건문으로 물리를 누적하지 않는다. -### Units, coordinates와 result meaning +Source identity, internal entity index, DOF component, equation index와 결과 위치는 +서로 다른 경계의 식별자다. Assembly와 serialization 사이에서 row 순서를 바꾸더라도 +source와 결과의 대응은 명시적으로 유지한다. -입력 값의 단위계를 임의로 추론하거나 결과에 맞춰 변환하지 않는다. 필요한 dimension, -좌표계, component 순서, 변환과 부호는 정식화 및 I/O 계약으로 고정한다. -서로 다른 위치나 정의의 recovery quantity를 같은 결과로 취급하지 않는다. -Averaging, extrapolation 또는 station 변환은 별도 승인된 의미가 있을 때만 수행한다. +## 계산과 병렬화 -### 모델, view와 state의 수명 +Element/local load 계산은 index-owned buffer에 기록한다. TBB 작업을 join한 뒤 +stable COO ordering과 고정된 reduction으로 sparse matrix와 global vector를 만든다. +Global storage를 여러 worker가 직접 수정하지 않으므로 thread scheduling이 합산 순서를 +정하지 않는다. 진단 선택과 결과 row의 순서도 같은 원칙으로 관리한다. -- `Domain`은 전체 모델 정의를 소유하며 검증 이후 가능한 한 불변으로 취급한다. -- `AnalysisModel`은 Domain을 복사하지 않는 non-owning 실행 view다. Domain은 모든 - view와 그에 의존하는 계산보다 오래 살아야 한다. -- `DofManager`는 DOF/equation mapping과 sparse pattern을 전담한다. Node나 Element에 - equation 번호를 분산 저장하지 않는다. -- Analysis owner는 해당 procedure가 실제로 사용하는 mutable state와 workspace만 소유한다. - 재사용·재시도·해제 시 dependent object를 남기지 않는다. -- Trial/committed 구분이 필요한 procedure는 update 실패와 commit 시점을 별도 계약으로 - 정의한다. 모든 procedure나 material에 이 state를 일괄 추가하지 않는다. -- Recovery와 output은 유효한 candidate를 검증한 뒤 반영한다. 기존 state와 최종 파일의 - 보존 범위는 성공 경로뿐 아니라 실패 경로에서도 검증한다. - -## 해석 실행 흐름 - -공통적으로 외부 입력의 의미를 검증하고 실행 모델을 구성한 뒤, 선택된 procedure가 -equation과 state를 관리하여 결과를 복구·저장한다. 이것은 책임 수준의 설명이며 모든 -procedure에 동일한 반복문이나 고정된 단계 목록을 강제하는 Template Method가 아니다. - -각 procedure 계약은 다음을 명시한다. - -1. 입력 준비와 procedure 선택의 경계, 원본 모델의 owner와 lifetime -2. 필요한 DOF, state, equation, workspace와 초기화 조건 -3. Contribution, constraint, factorization/solve와 update의 순서 -4. 해당하는 경우 increment, iteration, convergence와 종료 조건 -5. 성공 candidate의 commit, recovery와 결과 frame의 의미 -6. 실패 category, rollback·재사용 조건과 final output의 보존 범위 - -정적·동적, 선형·비선형, eigen 또는 contact 계열은 실제 요구와 승인된 계약으로 -정의한다. 이 구분을 명시하는 것은 해당 기능이 이미 지원된다는 뜻이 아니다. -기존 절차에 조건문으로 새 physics를 끼워 넣거나, 간결한 공통 그림을 근거로 승인된 -연산 순서·reaction·residual·commit 의미를 바꾸지 않는다. - -현재 개별 procedure의 구체적인 실행 계약은 해당 Feature의 formulation·I/O·구현 문서를 -확인한다. 기존 프로젝트 문서의 실행 순서와 객체 배치는 -[개정 전 아키텍처](archive/pre-generalization/ARCHITECTURE.md)에 이력으로 보존한다. - -## Local 계산, assembly와 constraint - -Local kernel은 승인된 geometry, material/property, DOF/state와 요청된 계산 범위를 받아 -local ordering이 명시된 contribution 또는 recovery 값을 만든다. Global numbering, -공유 matrix 갱신, 파일 lookup, 전체 convergence 판정이나 최종 저장을 수행하지 않는다. - -DOF owner가 지정한 pattern과 scatter를 assembly가 사용한다. Contribution 생성과 -누적 순서를 명시하고 병렬 worker는 소유한 buffer에만 기록한다. Join 이후 reduction과 -diagnostic 선택은 결정적으로 수행한다. Hash iteration이나 실행 scheduling을 -authoritative ordering으로 사용하지 않는다. - -Constraint 방식, full/reduced space, prescribed value, residual과 reaction의 정의는 -선택된 procedure의 수학 계약에 포함한다. 서로 다른 enforcement 방식의 결과 의미를 -같다고 가정하지 않는다. 특수 차원·빈 시스템·singularity의 처리는 계약에 따라 검증하며 -임의의 regularization, zero clamp 또는 fallback으로 실패를 숨기지 않는다. - -## Numerical backend와 실행 환경 - -Math storage, index convention, matrix capability, resource lifetime과 오류 변환은 -backend-neutral 계약으로 노출한다. Vendor header, handle과 OS 타입은 private adapter에 -격리한다. Dense와 sparse의 의미가 다르면 하나의 storage hierarchy로 억지로 합치지 않는다. - -Build dependency는 프로젝트가 소유한 target 경계에서 정규화하고, 새로운 dynamic -dependency는 link뿐 아니라 실제 실행에 필요한 runtime closure까지 확인한다. -개인 설치 절대 경로를 소스 계약으로 고정하지 않는다. Thread와 workspace 정책은 -실제 workload와 재현성 evidence에 근거하여 관리한다. - -현재 target graph와 dependency 선택은 [CMakeLists.txt](../CMakeLists.txt), -[dependency 설정](../cmake/FesaDependencies.cmake), -[solver target](../src/fesa/CMakeLists.txt), [test target](../tests/CMakeLists.txt)과 -[CMakePresets.json](../CMakePresets.json)을 확인한다. 이 참조는 다른 toolchain이나 -backend를 자동 승인하지 않으며 FESA의 현재 검증 baseline은 프로젝트 지침을 따른다. +MKL은 private dense 연산과 PARDISO·FEAST backend에서 사용한다. Linear solver와 +tangent solver의 matrix 성질을 구별하고, eigen finite-space reduction은 해석 모델의 +책임으로 유지한다. Backend 선택이 물성·경계조건·질량을 바꾸는 fallback이 되지 않는다. ## 입력, 결과와 진단 -Input adapter는 지원되는 외부 syntax, scope, default와 model/history 의미를 -검증된 semantic model로 mapping한다. 의미상 무해하다고 계약된 항목만 warning/no-op으로 -처리할 수 있으며 나머지 미지원 semantics는 fail-closed로 진단한다. +입력 adapter는 syntax뿐 아니라 procedure별 허용 의미까지 검사한다. Source 이름· +label·raw spelling은 보존하고 내부 정렬과 결과 schema의 고정 storage 이름을 분리한다. +무시 가능한 출력 요청은 허용된 조합에만 적용한다. -Results/recovery가 물리량의 의미를, output adapter가 저장 layout을 소유한다. -Authoritative output과 diagnostic log, debug view, reference artifact를 구분한다. -공식 형식, 파일명, schema version, mandatory dataset과 backward compatibility는 -현재 프로젝트·Feature I/O 계약을 따른다. 일반화 때문에 기존의 필수 결과를 optional로 -바꾸거나 다른 파일 형식으로 대체하지 않는다. +Recovery는 물리량의 위치·좌표·단위·부호를 결정하고 writer는 이를 저장한다. +Final output은 입력의 lexical sibling인 `_results.h5`다. Log와 debug CSV는 +다른 역할이며 공식 HDF5를 대신하지 않는다. HDF5 self-check와 solver의 물리 검증은 +서로 다른 책임이다. -Output은 계약된 임시 candidate에 기록하고 검증·close를 완료한 뒤 최종 결과로 반영한다. -실패 frame이나 불완전한 파일을 정상 결과처럼 공개하지 않는다. 내부 state의 commit과 -외부 파일의 finalization은 서로 다른 경계이므로 각각의 failure contract를 정의한다. +Expected failure는 Status/Result로 이동하며 source location과 entity를 포함한 +Diagnostic으로 변환한다. App이 공개 오류 출력과 종료값을 결정한다. Vendor 코드가 +public exit code나 사용자 입력의 의미를 직접 결정하지 않는다. -Diagnostic은 실패 단계, 안정된 code와 메시지, 가능한 source location/entity를 제공한다. -정확한 category, field와 CLI exit code는 I/O 계약을 따른다. Backend 오류를 그대로 -누출하거나 내부 failure classification을 새 public exit code로 임의 승격하지 않는다. +## 빌드와 개발 실행 영역 -## 검증과 reference 경계 +CMake는 `fesa_solver` static library, `fesa_cli` 실행 파일과 C++ 테스트를 구성한다. +Project-owned dependency target이 MKL·TBB·HDF5의 package target 차이를 감싼다. +GoogleTest는 승인된 로컬 source checkout을 사용한다. Windows 실행 target 옆에 +필요한 MKL·OpenMP·TBB·HDF5 및 관련 runtime을 준비하며 link 성공만으로 실행 환경이 +완성되었다고 판단하지 않는다. -검증 coverage와 비교량의 논리적 정의는 Numerical Review, 물리량의 저장·외부 대응은 -I/O, 실행 evidence는 구현 담당자, 독립 물리 판단은 Physics Evaluation의 전문 책임이다. -메인은 작업에 필요한 전문 판단만 배정하며 고정 stage 순회를 요구하지 않는다. 수식·요소· -재료·적분·상태 갱신 변경에는 독립 수치 검토와 해당 analytical/invariant 검증을 수행한다. -각 담당자는 상위 계약을 결과에 맞춰 수정하지 않는다. +Python 실행 경로는 `execute.py → config/discovery/toolchain → adapter → process`다. +Adapter는 CMake/CTest 또는 MSBuild 명령 계획을 만들고 process는 argv·cwd·timeout과 +결과 검사를 수행한다. FESA 제품의 검증 baseline은 CMake/MSVC x64 Debug/CTest다. +Python 실행기 회귀는 별도 suite이며 CTest가 이를 자동 실행하지 않는다. -- Source identity, location과 component 일치 여부를 수치 tolerance보다 먼저 확인한다. -- Missing, extra, duplicate와 nonfinite required value를 숨기지 않는다. -- 외부 reference 판정은 [TOLERANCE](TOLERANCE.md)의 공통 정책을 적용한다. 물리 평형, - 정식화와 수렴의 검증 기준은 각자의 계약을 따른다. -- Reference artifact의 naming이나 보조 metadata를 맞추기 위해 파일을 변경하지 않는다. -- 공개 입력 의미나 관찰 가능한 결과 비교를 외부 solver의 내부 동작 동등성으로 해석하지 않는다. - -구현 존재, 특정 revision의 검증 통과와 현재 release readiness는 별도로 확인한다. -Architecture 문서의 그림이나 모듈명이 기능의 완료 증거를 대신하지 않는다. - -## 개발 운영 인프라 - -현행 운영은 [ADR-028](ADR.md#adr-028), 역할·인계는 -[SOLVER_AGENT_DESIGN](SOLVER_AGENT_DESIGN.md), skill 적용은 -[SOLVER_SKILL_DESIGN](SOLVER_SKILL_DESIGN.md)을 따른다. 실행 동작은 -[Harness skill](../.agents/skills/harness/SKILL.md)과 현재 source·config에 대조한다. - -| Owner | 책임 | -| --- | --- | -| 메인 assistant | 범위·작업 분해, 필요한 전문 작업 배정, 직접 계획·구현·수정, Feature context와 완료 evidence 확인 | -| Specialist | 할당된 전문 판단·파일과 간결한 결과; 상위 계약 문제를 owner와 메인에 전달 | -| 구현 담당자 | 메인 또는 implementation-agent로서 코드·테스트·관련 검증과 필요한 reference evidence 작성 | -| Harness runner | 명시 호출 시 config·project·toolchain 선택, adapter 계획 실행과 결과 반환 | -| Backend adapter/process | CMake/CTest 또는 MSBuild 명령 구성, argv/cwd·timeout·실패·결과 검사 | - -구성된 solver build/test와 Harness 구현의 Python 회귀 검증은 별도 범위다. -현재 CMake adapter와 CTest 등록은 Harness Python suite를 실행하지 않는다. -Harness 동작 변경의 Python 검사는 구현 담당자가 변경 영향에 맞게 별도로 수행하며, -Runner 성공을 미실행한 Python 검사나 reference 비교의 통과로 확장하지 않는다. - -Runner는 내부 LLM, phase 상태기계, 자동 Git·retry, 파일명 TDD gate나 대화 종료 hook을 -사용하지 않는다. 과거 phase/coordination 기록은 이력으로 보존한다. 일반 실패는 현재 -구현 owner가 수정하며 새 근거나 변경 없이 같은 명령·agent 호출을 반복하지 않는다. - -Project config·preset·command는 검토해야 할 실행 입력이다. Repository 경로 검사, -`shell=False`와 timeout이 실행 파일의 side effect를 모두 격리하는 sandbox는 아니다. -사용자 변경을 보존하고 실제 도구 권한과 외부 solver·원격·파괴 작업의 명시적 승인을 따른다. -승인된 일반 작업에 반복 승인을 추가하지 않으며 계획 요청만으로 실행을 시작하지 않는다. - -변경 중에는 관련 검사를, 솔버 기능 완료 시에는 구성된 전체 build/test와 계약상 필수 -reference 비교를 한 번 수행한다. 요청이나 넓은 영향으로 전체 검증이 필요한 경우에도 -실행하고 이후 변경·실패가 없으면 반복하지 않는다. 문서 작업은 정적 검토로 확인한다. -명령·exit code·판정값과 미실행 항목을 필요한 보고서에 기록하며 Harness 성공만으로 -물리·수치 correctness나 외부 release readiness를 선언하지 않는다. - -## 문서와 아키텍처의 변경 - -프로젝트 공통 원칙의 변경은 공통 ADR로, 구현 항목별 선택은 해당 Feature ADR로 -기록한다. Feature PRD는 범위·작은 요구사항·acceptance와 현재 checklist의 원본이다. -복잡한 requirements·formulation·I/O는 필요한 경우에만 전문 문서로 분리하고 PRD에서 -참조하여 원본을 중복하지 않는다. 메인이 관리하는 핵심 문서 3개와 선택적 상세 산출물은 -[FEATURE_DOCUMENTATION](FEATURE_DOCUMENTATION.md)의 소유권과 링크 규칙을 따른다. - -Public dependency, identity, 수명, result meaning이나 lifecycle 변경은 영향받는 -계약과 evidence를 함께 검토한다. 상위 계약 변경으로 영향받는 evidence는 stale 처리하며, -문서 정리만으로 기존 기능의 재검증이나 release 승인을 완료한 것으로 표시하지 않는다. - -개정 전 구현 설명은 [보존본](archive/pre-generalization/ARCHITECTURE.md)에 남긴다. -해당 설명을 Feature 문서로 이관할 때 원래 범위와 승인 revision을 확인한다. -현재 문서는 과거 구현 상세를 삭제하여 계약을 없애거나 미래 API를 선결정하지 않는다. +개발 작업을 조정하는 메인과 전문 agent는 파일·검증 evidence를 다루지만 솔버가 이들을 +호출하지 않는다. 실행기는 내부 LLM·phase 상태기계·자동 Git·자동 retry·대화 종료 hook을 +소유하지 않는다. 과거 운영 기록은 실행 가능한 현재 pipeline으로 해석하지 않는다. diff --git a/docs/business-rules.md b/docs/business-rules.md new file mode 100644 index 0000000..bbadaef --- /dev/null +++ b/docs/business-rules.md @@ -0,0 +1,93 @@ +# FESA 해석의 의미와 제품 범위 + +## 목적과 사용자 + +FESA의 현재 목적은 개인 연구를 위한 유한요소 솔버 개발이다. 사용자는 요소·해법을 +구현하는 개발자이면서 결과를 검증하는 해석자다. 외부 사용자 배포는 장기 목표이며, +배포 계획이 현재 지원 범위나 정확성 보장을 확대하지는 않는다. + +제품 가치는 승인된 모델에서 물리적으로 설명 가능하고 재현 가능한 결과를 얻는 데 있다. +외부 입력을 읽었다는 사실이나 요소 행렬 하나를 계산했다는 사실만으로 기능을 완성했다고 +판정하지 않는다. 입력 의미, 방정식, 해법, 결과와 독립 검증이 연결되어야 한다. + +## 모델과 물리량 + +- Source label은 instance와 함께 입력의 대상을 식별한다. 내부 배열 위치나 equation + 번호가 같다는 이유로 다른 instance의 같은 label을 합치지 않는다. +- 입력 단위는 사용자가 일관되게 선택한다. 좌표나 물성의 크기로 SI 단위를 추정하거나 + 자동 변환하지 않는다. 힘·길이·시간을 기본으로 쓰면 질량은 `force*time^2/length`다. +- 절점 변위, 회전, 단면력, 응력은 위치와 좌표계를 포함한 물리량이다. 요소 끝 작용력과 + 양의 local-x 단면력, 적분점 응력과 절점 평균 응력은 서로 대체할 수 없다. +- 유효한 재료·단면·연결 관계가 유일하게 결정되어야 해석한다. 누락된 재료를 다른 + 영역의 평균값으로 채우거나 잘못된 요소를 조용히 제거하지 않는다. +- 미지원 의미는 명확한 실패다. 출력만 제어하는 무해한 요청의 무시도 해당 해석 절차에서 + 허용한 조합에 한정한다. 한 절차의 예외를 다른 절차로 확대하지 않는다. + +## 외부 솔버와의 관계 + +Abaqus `.inp`의 승인된 일부 문법을 입력으로 사용한다. `S4`와 `S4R`라는 source 표기를 +보존하지만 FESA의 MITC4 정식화에 연결한다. Abaqus의 요소 내부 적분, 안정화, 상태 또는 +결과 생성 알고리즘이 같다는 뜻이 아니다. 공개 결과의 수치적 일치는 허용되지만 내부 +동등성을 증명하지 않는다. + +기존 reference는 같은 `.inp` 모델로 생성한 외부 결과다. 비교 대상에는 CSV 외에 +고유치 TXT도 있으며, 실제 필요한 원본 경로를 사용한다. Naming 규칙이나 추가 metadata를 +맞추기 위해 기준 데이터를 변경하지 않는다. + +## 정적 해석 + +선형 정적 해석에서 free/constrained 분할은 다음 관계를 보존한다. + +\[ +K_{ff}d_f=F_f-K_{fc}d_c,\qquad r=Kd-F. +\] + +지정 변위는 해 복구 뒤에도 정확히 유지된다. `r`의 constrained 성분은 반력, +free 성분은 평형 잔차다. 모든 자유도가 지정된 유효한 모델은 빈 free 방정식을 +갖는 해석이지 singular 모델이 아니다. 반력을 외력의 부호 반전만으로 계산하지 않는다. + +비선형 정적 해석은 증가분마다 trial과 accepted 상태를 구분한다. 회전벡터에 대한 +일반화 모멘트와 공간상의 물리 모멘트를 같은 성분으로 취급하지 않는다. 수렴한 변위만 +있고 recovery나 상태 검증이 실패했다면 해당 증가분을 정상 결과로 공개하지 않는다. + +물리 변형에너지와 수치 drilling 안정화 에너지는 구별한다. 안정화가 선형계를 풀 수 있게 +했다는 사실을 물리 강성·에너지의 정확성 증거로 사용하지 않는다. + +## 고유치와 동해석 + +현재 MITC4 고유치 해석은 원형상·무응력 선형 섭동의 고유쌍을 구한다. Consistent +질량에서 유도한 lumped 질량으로 해석·정규화·검증을 일관되게 수행한다. Source의 +`EIGENSOLVER=LANCZOS`는 실제 FEAST 계산과 구별한다. 질량 영공간에 임의 질량을 더해 +유한 모드로 바꾸지 않는다. + +HHT 동해석은 consistent kinetic mass를 사용한다. 고유치 해석의 lumped 선택을 그대로 +가져오지 않는다. 물리적 endpoint 가속도, 회전벡터의 시간 미분, 공간 각가속도, +알고리즘 보조 가속도를 구별한다. 어느 하나의 reference 일치로 다른 양의 시간수렴을 +통과했다고 판정하지 않는다. 현재 shell 시간수렴에는 미해결 문제가 있다. + +## 열해석의 합의된 향후 범위 + +가까운 목표는 shell의 단일 step uncoupled transient heat transfer다. 두께가 균질한 +단면에 온도점 5개를 두고 면내 및 두께 방향 열전달을 다룬다. 상수 등방 전도도·밀도·비열, +영역별 재료·두께, 고정 시간 증분과 시간에 따라 일정한 입력이 합의된 범위다. + +초기 온도는 절점마다 지정하되 그 절점의 두께 온도점에는 같은 값을 준다. 지정 온도와 +절점 열률은 아랫면·윗면에 적용하고, edge 열입력은 두께에 걸쳐 균일하게 적용한다. +온도·heat flux·반력 열률의 저장을 요구한다. 5개 온도점에서 source DOF 11은 아랫면, +13은 중앙면, 15는 윗면이다. + +Q4 면내 보간과 두 구간의 이차 두께 보간, consistent 열용량, Backward Euler와 flux +복구 위치는 아직 제안이다. Geometry 근사, 초기 경계 jump, edge 문법·단위와 영속 결과 +schema를 확정한 뒤 구현한다. 장기 목표인 양방향 열-구조 연성은 현재 열해석의 완료 +조건에 포함하지 않는다. + +## 수용과 실패 + +결과가 finite이고 방정식이 풀렸다는 것만으로 correctness를 인정하지 않는다. 해당 +물리에 필요한 평형·반력·에너지·영모드·수렴·대칭성과 독립 비교를 확인한다. 외부 +reference 오차 기준은 내부 잔차나 시간수렴 기준을 대신하지 않는다. + +기준 데이터의 row 누락·추가·중복, 좌표·위치 불일치, nonfinite는 수치 오차 판정 이전의 +실패다. 불일치를 평균하거나 임의의 `max(1, scale)` 및 zero clamp로 숨기지 않는다. +실패한 trial과 미완성 출력은 정상 결과가 아니며, 계약된 범위에서 기존 유효 상태와 +최종 결과 파일을 보존한다. diff --git a/docs/contracts.md b/docs/contracts.md new file mode 100644 index 0000000..1dfafdb --- /dev/null +++ b/docs/contracts.md @@ -0,0 +1,174 @@ +# 실행·입력·결과의 외부 계약 + +## 호출과 파일 수명 + +```text +fesa.exe +``` + +인자는 비어 있지 않은 입력 경로 하나다. 상대 경로는 호출 시 작업 디렉터리 기준으로 +lexical normalization한다. 확장자 `.inp`는 대소문자를 구별하지 않는다. 옵션 형태 인자와 +`--output`은 지원하지 않는다. Symlink·junction·short name을 resolve해 결과 위치를 바꾸지 않는다. + +| 산출물 | 경로와 의미 | +| --- | --- | +| 공식 결과 | 입력의 lexical sibling `_results.h5` | +| 실행 로그 | 같은 위치의 `_log.txt`; 실패 진단을 포함할 수 있음 | +| 쓰기 lease | 결과 경로에 `.fesa.lock`을 붙인 임시 소유권 파일; 정상 handle 종료 시 삭제 | + +같은 output pair를 다른 실행이 점유하면 `output-busy`로 실패한다. Lease 생성 실패도 +같은 output failure로 분류되므로 충돌 외에 OS 권한·디렉터리 상태도 확인해야 한다. +최종 HDF5는 완료 candidate의 기록·self-check·close 후 교체한다. 실패 시 이전 최종 +HDF5를 보존하는 계약과 로그가 갱신될 수 있는 계약을 구별한다. 기존 파일의 존재가 +새 실행 성공을 의미하지 않는다. + +| CLI exit | 의미 | +| ---: | --- | +| 0 | 선택된 해석과 최종 결과 저장 성공 | +| 2 | 잘못된 인자·입력 확장자 등 usage 오류 | +| 3 | 파일 읽기·문법·미지원 입력 오류 | +| 4 | 모델 의미·구성·유효성 오류 | +| 5 | 해법 실패 | +| 6 | Output lease·로그·HDF5 저장 실패 | + +진단은 stderr에 결정적인 순서로 출력된다. 한 줄은 탭으로 구분된 +`severity=... code=... file=... line=... keyword=... entity_identity=... message=...` +필드를 갖고 빈 source 필드도 유지한다. Backend 원래 오류 번호를 새 CLI exit로 그대로 +반환하지 않는다. 경고가 있는 성공도 가능하며 성공 HDF5의 진단은 warning이다. + +## 공통 입력 규칙 + +현재 입력은 하나의 physical `.inp` 파일이다. LF·CRLF, 빈 줄, `**` comment와 +keyword parameter continuation을 처리한다. Physical line은 종결자 제외 256 ASCII +bytes 이내이며 printable ASCII와 tab을 사용한다. Keyword·parameter·enum·이름 lookup은 +ASCII case-insensitive이고 원문 표기와 줄 번호는 보존한다. 같은 값의 중복 parameter도 +실패다. Comma의 빈 field를 없애거나 data continuation으로 연결하지 않는다. + +모델은 part의 node·element·set·section, identity instance를 둔 assembly, named material, +모델 경계조건과 하나의 해석 step으로 구성한다. Instance transform, `*INCLUDE`, 일반 +contact·MPC·비탄성·혼합 beam/shell model은 현재 공개 subset이 아니다. + +| 입력 | 소비자가 지켜야 할 의미 | +| --- | --- | +| `*NODE` | Part 안의 `label,x,y,z`; label은 양의 정수, 좌표는 finite | +| `*ELEMENT, TYPE=B33|S4|S4R, ELSET=...` | B33은 2개, shell은 서로 다른 4개 node label; source type과 내부 정식화 구별 | +| `*NSET`·`*ELSET` | 허용 scope의 label 나열 또는 `GENERATE`; assembly set은 명시 instance에 결속 | +| `*INSTANCE, NAME=..., PART=...` | 기존 part의 identity instance; transform data 미지원 | +| `*ELASTIC` | 상수 등방 `E,nu`; `E>0`, `-1/` | +| Frequency | schema 0에 `feature_id=mitc4-shell-feast-eigen2`, `analysis_procedure=linear-frequency`, `eigen_schema_version=1` 추가 | +| HHT | `feature_id=hht-implicit-dynamics`, `analysis_procedure=hht-implicit-dynamics`, schema 1, 전체 accepted frame과 `/steps/Step-1/frames//` | + +`Step-1`은 storage slot이다. Frequency는 `/steps/Step-1`의 `source_step_name`, HHT는 +`/metadata`의 `source_step_name`에서 원래 이름을 읽는다. 기존 선형·비선형 static은 +canonical `step_name=Step-1`만 저장하므로 원래 source 이름이 HDF5에 별도로 있다고 +가정하지 않는다. Float64와 fixed-width integer는 little-endian, +문자열은 UTF-8다. Compound는 field name/type/extent로 읽고 C++ struct padding에 의존하지 않는다. +Source 입력 identity는 실제 읽은 byte의 identity를 포함한다. + +`/model/nodes`와 `/model/elements`의 source instance/label과 internal ID를 사용해 +결과 row를 연결한다. Internal row 번호를 원본 label로 취급하지 않는다. Nodal +displacement와 constraint mask의 6성분 순서는 `[UX,UY,UZ,URX,URY,URZ]`다. Reaction, +가속도 등 다른 dataset에는 각각의 component 이름이 있으므로 이 이름을 재사용하지 않고 +단위·좌표·location·component attribute를 함께 읽는다. `/model/nodal_constraint_mask`의 +free=0/constrained=1이 반력 해석의 기준이다. + +Static nodal `displacement`는 `[node_count,6]`이다. Linear nodal `reaction`의 constrained +성분은 반력, free 성분은 잔차 evidence다. Shell 결과의 기본 location 축은 면내 4점, +응력의 section 축은 bottom/middle/top 3점이다. Section resultant의 8성분은 +`[N11,N22,N12,M11,M22,M12,Q13,Q23]`, 응력의 3성분은 `[S11,S22,S12]`다. +두 값의 단위와 위치를 서로 바꾸지 않는다. Beam 결과는 element endpoint와 단면 위치를 +유지하며 node 평균 결과로 읽지 않는다. + +Frequency의 `/steps/Step-1/eigen/modes`는 N개 `mode_id,eigenvalue,classification,cluster_id` +record이며 mode_id는 1부터다. `frequencies`는 raw eigenvalue가 비음수인 mode의 +ID subset, `vectors`는 `[N,node_count,6]`의 mass-normalized mandatory projection이다. +이 벡터는 응답 변위가 아니다. 작은 음수 고유치를 abs/zero clamp하지 않으며 frequency +존재 여부를 eigenvalue와 구별한다. Static reaction·stress를 modal 결과에 요구하지 않는다. + +HHT frame은 0부터 N까지이고 `time=double(n)*h`다. `is_initial`은 n=0에만 참이다. +Nodal `acceleration`과 `algorithmic_acceleration`, `angular_acceleration`, +`generalized_reaction`과 공간 `reaction`은 구별된 dataset이다. Accepted frame과 source +identity로 접근하고 failed trial이나 time 기반 nearest-neighbor matching을 사용하지 않는다. + +## 외부 비교 + +Comparison은 필요한 instance·entity·location·component·step/frame을 일대일 대응한다. +Missing·extra·duplicate·nonfinite는 tolerance 전에 실패한다. 같은 case/step/frame/ +quantity/단위/좌표/판정 영향의 값만 한 family에 넣는다. + +Reference 값만으로 `S=max(abs(r_i))`, `B=0.01*S`를 정한다. `abs(r_i)<=B`이면 +`abs(f_i-r_i)<=B`, 나머지는 상대오차 `<=0.05`를 요구한다. Family 전체의 +`sqrt(mean((f_i-r_i)^2))/S<=0.01`도 만족해야 한다. S=0이면 모든 FESA 값도 exact 0이어야 +하며 nonzero 오류는 `zero-reference-scale-nonzero-error`로 보고한다. 임의 floor는 없다. + +MITC4 eigen 첫 구현의 named policy `mitc4-eigen-first-implementation`에 한해 mode별 +singleton Value family의 상대오차와 RMS를 모두 5%로 판정한다. 다른 family의 RMS 1%나 +내부 eigen 검증 기준을 바꾸지 않는다. MITC4 U는 blocking, UR는 warning-only이며 warning도 +결정적 순서로 남긴다. 사전검사 실패는 warning-only family에서도 전체 실패다. + +CSV view는 비교 보조 산출물이다. FESA 공식 output으로 대체하거나 reference 값을 +보정하는 중간 형식으로 사용하지 않는다. diff --git a/docs/engineering-notes.md b/docs/engineering-notes.md new file mode 100644 index 0000000..2eee34e --- /dev/null +++ b/docs/engineering-notes.md @@ -0,0 +1,72 @@ +# 수치 구현과 검증에서 주의할 점 + +## 실행 성공과 기능 완료의 차이 + +HHT 원본 모델의 변위 비교는 통과 기록이 있지만 실제 shell의 두 시간수렴 사례는 +미해결이다. 따라서 외부 변위가 맞는다는 이유로 가속도 복구·시간수렴·physics 완료를 +추론하면 안 된다. 변경 후에는 동일한 dt refinement에서 변위·속도·물리 가속도의 차수를 +각각 확인해야 하며 auxiliary acceleration의 결과를 물리 가속도로 대신하지 않는다. + +과거 I/O 문서의 `implementation-pending` 같은 문구는 그 문서가 작성된 시점의 상태일 수 +있다. 현재 코드는 dynamic/eigen state와 writer를 포함한다. 코드 존재, 작성 당시 계획, +후속 실행 보고서를 구분하고 날짜가 오래된 머리말 하나로 전체 기능 상태를 결정하지 않는다. + +## 단면력과 회전 + +Shell 굽힘 모멘트 복구에는 두께의 세제곱 계수 `M=t^3 C kappa/12`가 들어간다. +막력과 같은 두께 계수로 처리하면 displacement가 맞아도 section resultant가 틀릴 수 있다. +복구식을 바꿀 때 두께를 독립적으로 바꾸는 사례와 HDF5 readback을 함께 대조한다. + +비선형 shell의 rotation-vector generalized moment는 spatial moment와 다르다. Chart에 +대한 일의 짝을 유지해야 하므로 성분 이름만 바꿔 공개 reaction으로 내보내지 않는다. +자세 변화가 큰 사례와 원점 이동 시 moment balance를 확인한다. + +Beam section resultant는 요소 endpoint identity로 대응한다. 같은 절점에 모인 여러 +endpoint 값을 node 평균으로 줄이면 end action 부호 또는 station 불일치를 숨긴다. +Instance·element·endpoint node·component를 함께 비교해야 한다. + +## 질량·영공간과 source 옵션 + +고유치의 derived lumped mass와 HHT의 consistent kinetic mass는 승인 목적이 다르다. +두 절차가 같은 shell을 쓴다는 이유로 질량 구현을 한 가지로 치환하지 않는다. 질량 +영공간이 있으면 analytic null과 free 공간의 교집합을 확인하고 임의 drilling inertia를 +더하지 않는다. 부분 회전 구속을 full clamp로 바꾸는 것도 같은 모델이 아니다. + +Source `S4R`나 shell section의 integration-point 필드는 FESA의 적분법 선택 스위치가 +아니다. Source 보존·허용 문법과 실제 numerical integration을 별도로 검증한다. + +## 열해석 계획에서 혼동하기 쉬운 위치 + +온도점 5개의 DOF 11은 아랫면이며 중앙면은 DOF 13이다. 열해석 제안의 54개 직접 +적분점과 24개 flux trace는 서로 다른 목적의 위치다. 두 구간 이차 보간의 중앙면에서는 +두께 미분의 양쪽 trace가 다를 수 있어 평균하지 않는다. 이 수치 방법은 아직 채택 대기다. + +열전달 반력에는 열용량에 의한 저장률이 포함된다. 전도 flux만으로 반력 열률을 정의하면 +transient 에너지 수지가 달라진다. 첫 증분에서 지정 온도가 변하는 경우에는 이전 constrained +온도의 용량 결합 항도 필요하므로 초기값을 조용히 projection하지 않는다. + +열 reference의 NT11에는 음수가 있다. 모든 음수를 roundoff라고 가정하거나 clamp하지 +않고 원본 identity와 승인된 비교 기준으로 다룬다. 현재 CSV의 한 시점 온도만으로 flux, +반력, 다른 두께 온도점 또는 전체 시간수렴을 검증했다고 주장하지 않는다. + +## 실행 환경과 결과 파일 + +Preset 파일이 존재해도 Python 실행기가 자동 선택하지 않는다. 개인 설정에서 +`configurePreset`, `buildPreset`, `testPreset`, `binaryDir`를 함께 맞춰야 다른 build tree의 +테스트를 읽는 실수를 피할 수 있다. CTest discovery 결과가 비거나 다른 compiler가 +선택되면 실행 실패로 다룬다. + +MSVC link 성공 뒤 실행 시 DLL을 못 찾는다면 dependency runtime staging을 확인한다. +개발자 PATH에 우연히 있던 DLL로 성공한 것을 배포 환경 검증으로 보고하지 않는다. +Python suite는 CTest와 별개이므로 runner의 성공에 포함시켜 보고하지 않는다. + +CLI 결과 경로는 입력의 lexical parent다. Symlink나 junction을 canonical 경로로 +치환하면 사용자가 지정한 output 위치 의미가 바뀐다. Output lease와 atomic replace의 +검증에서는 기존 final HDF5뿐 아니라 로그·임시 파일의 서로 다른 실패 수명을 확인한다. + +## 과거 개발 절차와 검사 + +일부 Python 검사는 삭제된 coordinator·planning·correction profile과 고정 단계 표를 +기대한다. 현재 agent inventory 및 인자 없는 실행기와 맞지 않는 정적 근거가 있다. +이전 검사를 만족시키기 위해 폐기된 profile·phase·hook을 복원하지 않는다. 현행 절차를 +확인한 뒤 별도 테스트 변경 작업으로 정리하고 실제 실행 결과를 기록한다. diff --git a/docs/operations.md b/docs/operations.md new file mode 100644 index 0000000..9f3cd0e --- /dev/null +++ b/docs/operations.md @@ -0,0 +1,117 @@ +# 개발 환경과 실행 방법 + +## 최초 준비 + +Windows에서 Visual Studio의 Desktop development with C++ 워크로드, CMake 3.25 이상, +Ninja, Intel oneAPI MKL·TBB, HDF5 C package와 승인된 GoogleTest 로컬 checkout을 준비한다. +Runner는 Python 3.10 이상, `tomllib`을 사용하는 Python 검사에는 3.11 이상이 필요하다. +자동 dependency download나 특정 개인 설치 경로를 전제하지 않는다. + +저장소 루트를 작업 디렉터리로 하는 **MSVC x64 Developer PowerShell**을 연다. +일반 PowerShell에서 아래 configure를 먼저 실행하면 compiler와 runtime 환경이 빠질 수 있다. +설치 경로가 환경변수에 없다면 아래 질문에 실제 로컬 경로를 입력한다. + +```powershell +$env:FESA_GTEST_SOURCE_DIR = Read-Host 'GoogleTest source checkout 경로' +$env:MKL_DIR = Read-Host 'MKLConfig.cmake가 있는 디렉터리' +$env:TBB_DIR = Read-Host 'TBBConfig.cmake가 있는 디렉터리' +$env:HDF5_DIR = Read-Host 'hdf5-config.cmake 또는 HDF5Config.cmake가 있는 디렉터리' +Get-Command cl, cmake, ctest, ninja, python +Test-Path -LiteralPath (Join-Path $env:FESA_GTEST_SOURCE_DIR 'CMakeLists.txt') +``` + +`FESA_GTEST_SOURCE_DIR`는 source root, 나머지 세 변수는 CMake package config directory다. +네 값은 현재 프로세스·개인 설정에 두며 저장소의 절대 경로로 고정하지 않는다. +`Test-Path`가 false이거나 명령이 없으면 먼저 준비 환경을 수정한다. + +## C++ 구성·빌드·검사 + +다음 순서로 실행한다. Configure 전에 dependency 경로와 x64 compiler가 준비되어야 하며, +build 전에 configure가 성공해야 한다. 각 명령이 실패하면 다음 단계로 진행하지 않는다. + +```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 +``` + +Build tree는 `.harness/build-ninja-msvc-debug`다. CTest discovery는 실제 등록된 검사를 +확인하며 0개 검사는 검증 성공이 아니다. 관련 검사만 실행할 때는 같은 preset에 `-R`로 +실제 CTest 이름을 지정한다. 솔버 기능 완료 시 전체 검사와 필수 수치/reference 비교를 +수행하고, 문서만 수정할 때는 실행하지 않는다. + +## 설정된 실행기로 검증 + +개인 `.harness/config.json`이 이미 있으면 보존하고 실제 선택된 backend를 확인한다. +동일 preset을 사용하려면 다음 설정을 사용한다. 기존 설정을 무조건 덮어쓰지 않는다. + +```json +{ + "version": 1, + "projectType": "cmake", + "cmake": { + "sourceDir": ".", + "binaryDir": ".harness/build-ninja-msvc-debug", + "configurePreset": "windows-msvc-ninja-debug", + "buildPreset": "windows-msvc-ninja-debug", + "testPreset": "windows-msvc-ninja-debug" + } +} +``` + +```powershell +python scripts/execute.py +``` + +실행기는 명령을 한 번 구성·실행하고 compiler metadata와 CTest discovery를 확인한다. +전체 deadline은 CLI 시작부터 1,800초이며 각 명령 제한과 남은 시간 중 짧은 값을 적용한다. +Phase 인자·`--push`·`--approve-danger-full-access`를 받지 않는다. 자동 Git·retry·외부 +solver 실행이나 필요한 추가 reference 비교의 추론은 하지 않는다. + +성공은 exit 0, config/toolchain/backend/timeout 실패는 exit 1이다. 잘못된 CLI 인자나 +자동 감지에서 project metadata가 없는 경우는 exit 2다. 원래 backend exit와 runner exit를 +구분해 기록하고 출력 tail에 포함된 stage·argv·cwd에서 실패 경계를 찾는다. + +## Python 검사와 비교 도구 + +Runner 또는 Python 비교기를 변경하면 관련 Python 검사를 별도로 실행한다. +전체 Python 검사 명령은 다음과 같으며 CTest 실행에 포함되지 않는다. + +```powershell +uv run --with pytest python -B -m pytest -v -rs +``` + +HHT 비교 도구에는 Python 3.11 이상과 `numpy`·`h5py`가 필요하다. 현재 도구는 지정된 +`shellNL-dyn-meshfine`의 729개 절점 중 선택한 9개 절점, 101 frames의 U/UR 비교용이다. +다음 명령은 **이미 생성된** HDF5와 원본 변위 CSV를 비교하며 솔버나 Abaqus를 실행하지 않는다. +다른 모델의 범용 비교기로 사용하지 않는다. Report의 상위 디렉터리는 도구가 생성한다. + +```powershell +$inputPath = Read-Host '비교할 원본 .inp 경로' +$referencePath = Read-Host '원본 변위 CSV 경로' +$resultPath = Read-Host 'FESA HDF5 경로' +$reportPath = Read-Host '비교 보고서 JSON 경로' +uv run --with numpy --with h5py python scripts/verification/compare_hht_dynamic.py --input $inputPath --reference $referencePath --results $resultPath --report $reportPath +``` + +Reference 원본을 생성·복원하거나 다른 곳으로 옮기는 명령은 검증 절차에 포함하지 않는다. +원본이 없으면 필요한 경로와 미실행 이유를 보고한다. 외부 solver와 라이선스 사용은 +별도 명시된 권한 아래 수행한다. + +## 모델 실행과 배포 상태 + +성공한 Debug build 뒤 생성된 CLI를 실행한다. 모델 경로는 실제 승인된 입력을 지정한다. + +```powershell +$modelPath = Read-Host '해석할 .inp 경로' +& ./.harness/build-ninja-msvc-debug/src/fesa/fesa.exe $modelPath +``` + +입력 옆에 `_results.h5`와 `_log.txt`를 생성하므로 해당 디렉터리에 쓸 수 +있어야 한다. 실행 실패 때 이전 HDF5가 남아 있을 수 있으므로 파일 존재만으로 이번 실행의 +성공을 판단하지 않는다. Exit와 진단, 실제 저장된 source identity를 함께 확인한다. + +현재 별도의 데이터베이스 초기화·계정 생성·서비스 배포 명령은 없다. 외부 사용자 배포의 +형식, 설치 방식, dependency 재배포 조건과 지원 범위는 아직 정하지 않았다. 로컬 실행 +성공을 설치·배포 검증으로 간주하지 않는다. diff --git a/docs/security.md b/docs/security.md new file mode 100644 index 0000000..112f3c2 --- /dev/null +++ b/docs/security.md @@ -0,0 +1,49 @@ +# 실행 권한과 데이터 취급 + +## 현재 사용 환경 + +FESA는 개인 연구용으로 로컬 입력 파일을 읽고 로컬 결과를 저장하는 솔버다. 사용자에게 +별도의 데이터 분류·보안 정책은 없다. 고객 기밀이 없다고 단정하거나 모델의 외부 전송이 +허용되었다고 해석하지 않는다. 외부 배포는 계획이며, 공개 서비스 인증·계정·권한 관리가 +현재 구현된 것으로 설명하지 않는다. + +현재 CLI에는 별도 로그인·토큰·비밀번호 수명주기가 없다. 실행 파일과 입력·결과에 +대한 접근 권한은 운영체제의 실행 계정과 파일 권한에 따른다. 잘못된 자격증명·만료·계정 +잠금에 대한 솔버 응답은 적용 대상이 아니다. 이후 서버나 계정 기능이 추가되면 새 정책과 +실패 경로를 정의해야 하며 로컬 실행 권한을 그대로 서버 권한 모델로 사용하지 않는다. + +## 보호 대상과 허용 범위 + +| 주체 | 동작 | 조건과 경계 | +| --- | --- | --- | +| 로컬 해석 사용자 | 입력을 읽고 결과·로그 생성 | 실행 계정이 경로에 접근할 수 있어야 한다. OS 접근 거부를 우회하지 않는다. | +| 솔버 프로세스 | 같은 입력의 결과·로그 쓰기 | Output write lease 획득 후 수행한다. Lease 충돌 시 새 쓰기를 시작하지 않는다. | +| 개발 담당자 | 요청한 소스·문서·테스트 수정 | 요청 범위의 일반 작업은 진행하고 관련 없는 사용자 변경은 보존한다. | +| 개발 담당자 | Reference 생성·변경·복원 | 해당 작업이 명시적으로 요청되어야 한다. 구현의 실패를 없애기 위한 데이터 보정은 허용하지 않는다. | +| 개발 담당자 | 외부 solver·라이선스·자격증명·비용 사용 | 기존 승인 범위가 없으면 사용자 결정이 필요하다. 파일의 존재가 실행 허가를 뜻하지 않는다. | +| 개발 담당자 | Commit·push·tag·publish·release | 각각 요청된 범위에 한정한다. 검증 실행기가 이 권한을 부여하지 않는다. | + +## 입력과 실행의 신뢰 경계 + +`.inp`는 모델 데이터다. 지원하지 않는 keyword를 외부 명령이나 파일 포함으로 실행하지 +않는다. 문법·참조·물성 검사는 해석 의미를 보호하지만, 악의적인 입력에 대한 자원 제한이나 +프로세스 격리가 입증되었다는 뜻은 아니다. 외부에서 받은 임의 모델을 안전하게 실행하는 +서비스라는 보장은 현재 없다. + +빌드 설정, CMake preset, 실행할 프로그램과 스크립트는 코드 실행 권한을 가진 입력이다. +작업 디렉터리 검사·`shell=False`·timeout은 실행 파일의 모든 부작용을 차단하지 못한다. +신뢰하지 않는 설정을 단순 데이터로 보고 자동 실행하지 않는다. + +Output lease는 동시 쓰기 충돌 방지 장치다. 파일 ACL이나 사용자 인증을 대신하지 않는다. +결과 경로의 lexical 의미와 OS가 해석하는 symlink·junction의 실제 위치도 구별한다. + +## 기록과 배포 시 남은 결정 + +솔버 진단에는 source 파일 경로, 줄 번호, keyword, entity identity와 오류 설명이 들어갈 +수 있다. 모델·결과·진단을 외부 공유할 때 경로와 모델 정보가 포함될 수 있음을 확인한다. +현재 별도의 암호화·자동 마스킹·보존기간·사용자 접근 감사 정책은 정해져 있지 않다. +수치 실행 로그를 보안 감사 로그로 간주하지 않는다. + +개인 dependency 경로와 자격증명을 공용 문서나 버전 관리에 넣지 않는다. 향후 외부 배포 +전에 배포 방식, dependency 재배포 권리, 입력 신뢰 범위와 데이터 취급 방침을 결정해야 한다. +이는 현재 기능 완료의 새 조건이나 배포 승인 기록이 아니다. diff --git a/docs/standards.md b/docs/standards.md new file mode 100644 index 0000000..83f5490 --- /dev/null +++ b/docs/standards.md @@ -0,0 +1,133 @@ +# FESA 개발 규칙 + +## 계약과 변경 범위 + +요구조건, 정식화, 부호, 단위, 좌표계, source identity와 수치 기준을 구현 전에 고정한다. +구현 편의나 실패한 결과를 이유로 승인된 의미를 조용히 변경하지 않는다. Physics·지원 +범위·공개 호환성·acceptance·영속 schema 변경과 해결되지 않은 필수 reference 충돌은 +사용자 결정 사항이다. 이미 승인된 일반 수정과 인계에는 반복 승인 절차를 추가하지 않는다. + +요청 범위에 필요한 최소 변경만 한다. 미래 기능을 위한 state·base class·registry를 +선할당하지 않는다. 다른 작업자의 변경을 되돌리거나 주변 코드를 함께 정리하지 않는다. +계획 요청만으로 solver 구현이나 외부 실행을 시작하지 않는다. + +## 의존성과 소유권 + +- Public core는 concrete I/O adapter나 MKL·TBB·HDF5·Win32 타입에 의존하지 않는다. + Backend 교체는 interface 경계 뒤에서 처리하고 vendor 오류는 공개 실패 형식으로 변환한다. +- Domain은 전체 모델 정의를 소유하고 파싱 이후 가능한 한 불변이다. AnalysisModel은 + 복사본이 아닌 non-owning view이며 Domain이 view보다 오래 살아야 한다. +- DofManager가 자유도 정의·free/constrained mapping·equation 번호·sparse pattern을 + 전담한다. Node와 Element에 equation 번호를 저장하지 않는다. +- Element/material은 local response, assembly는 global reduction, procedure는 해법과 + 상태 수명, recovery는 물리량, writer는 serialization을 소유한다. 책임을 역전하지 않는다. +- Procedure가 실제 사용하는 mutable state만 할당한다. Trial을 검증한 뒤 commit하고 + 실패한 candidate가 기존 state나 최종 HDF5를 부분적으로 오염시키지 않게 한다. + +## 수치 코드 + +Element-local contribution을 stable ordering으로 생성하고 고정된 순서로 합산한다. +병렬 worker는 자기 index의 buffer만 갱신하며 global CSR이나 결과 row를 공유 누적하지 +않는다. Hash 순서나 thread scheduling이 sparse structure·결과·진단 순서를 결정하면 안 된다. + +선형 정적 해석은 full K를 stable free/constrained 순서로 분할하고 `Kff` factorization을 +load assembly보다 먼저 수행한다. 유효한 all-constrained의 빈 free system을 singular로 +바꾸지 않는다. 반력과 free 평형은 같은 full residual에서 복구한다. + +서로 다른 결과 위치·단위·부호·source identity를 평균으로 합치지 않는다. 식이나 +reduction 순서를 바꾸는 최적화도 수치 변경이다. 임의 absolute floor, zero clamp, +missing-row 무시, 실패 시 다른 물성·질량·solver로의 silent fallback을 추가하지 않는다. + +## C++ 규약 + +현재 검증 기준은 C++17 이상, Windows MSVC x64 Debug, CMake target과 CTest다. +다른 backend를 지원하는 실행 스크립트가 FESA의 다른 platform 검증을 뜻하지 않는다. +새 compiler warning을 추가하지 않는다. Vendor target에 FESA warning 정책을 강제하지 않는다. + +| 대상 | 규칙 | +| --- | --- | +| 파일·namespace | 소문자 snake_case, source `.cpp`, header `.h` | +| 타입·함수·accessor | PascalCase; constructor·destructor·operator는 언어 규칙 | +| 변수·parameter | snake_case | +| Class 멤버 | snake_case 뒤 `_`; struct record는 trailing `_` 없음 | +| 상수·enumerator | `kPascalCase` | +| Header | Self-contained include와 repository 경로 기반 include guard; `#pragma once`로 대체하지 않음 | +| Formatting | Google 기반 `.clang-format`, space 2개, 통상 80자, namespace 본문 들여쓰기 없음 | + +Include는 대응 header, C, C++ standard, third-party, FESA 순서로 그룹화하고 그룹 내부는 +알파벳순이다. Transitive include에 의존하지 않는다. 한 statement에 한 declaration을 +두고 변수를 가능한 좁은 범위에서 초기화한다. 의미 없는 type modifier를 장식으로 붙이지 않는다. + +RAII와 단독 ownership의 `unique_ptr`를 우선한다. 실제 공유 수명이 없는 `shared_ptr`, +미래용 virtual method, static 함수 묶음용 class를 만들지 않는다. Polymorphic base는 +public virtual destructor를 갖고, non-owning 수명은 API 계약에 적는다. + +Expected failure는 `Status` 또는 `Result`다. Backend exception을 그대로 외부로 +노출하지 않는다. 같은 물리·단위·좌표·실패·소유권 의미일 때만 공통화하며, 코드 모양만 +비슷한 다른 정식화를 합치지 않는다. + +Production의 public/protected 선언과 private/internal 함수에는 필요한 목적·수명·단위· +부호·실패·결정적 순서를 기록한다. Public API Doxygen는 영어를 기본으로 하고 테스트에 +형식적인 Doxygen를 요구하지 않는다. 코드 동작의 번역보다 비자명한 이유를 설명한다. +Formatting-only 변경은 동작 변경과 같은 commit에 섞지 않는다. + +## 검증 조건 + +1. 동작·interface 변경은 해당 의미를 확인하는 테스트로 검증한다. 버그는 가능한 경우 + 실패를 먼저 재현하고 최소 수정한다. Coverage가 충분한 rename이나 문서 작업에는 + 구현을 반복하는 형식적 테스트를 추가하지 않는다. +2. 수식·요소·재료·적분·상태 갱신 변경에는 독립 numerical review와 해당 analytical/ + invariant 검사를 수행한다. 필요한 물리·reference 검증도 유지한다. +3. 개발 중에는 관련 검사를 실행한다. 솔버 기능 완료 시 구성된 전체 build/test와 필수 + reference 비교를 한 번 수행한다. 이후 변경·실패·미해결 우려가 없으면 반복하지 않는다. +4. 외부 비교는 row identity·component·finite 검사를 먼저 통과해야 한다. 수치 기준이나 + reference 경로·값을 구현 결과에 맞춰 바꾸지 않는다. 기존 비교 기준 변경은 승인·결정 + 기록·경계값 테스트·영향받는 비교의 재실행을 요구한다. +5. 문서만 수정하면 링크·source 대조·diff 정적 검토를 하고 build/test는 실행하지 않는다. + 미실행·실패·과거 revision의 결과를 현재 통과로 표시하지 않는다. +6. Runner, CTest, Python 회귀, 독립 물리 검토의 성공 범위는 각각 다르다. 실행기 exit 0만으로 + 모든 검증이나 외부 배포 준비가 완료됐다고 보고하지 않는다. + +## 작업 배정과 실패 처리 + +메인이 필요한 전문 작업만 선택한다. 작은 작업은 직접 수행하며 고정 stage 순회, +별도 coordinator, 자동 retry 예산을 도입하지 않는다. 일반 실패는 현재 구현 owner가 +수정하고 새 근거·변경 없이 같은 명령이나 agent 호출을 반복하지 않는다. + +| 작업 | 담당과 적용 조건 | +| --- | --- | +| 요구사항 | `requirement-agent`: 복잡하거나 상충하는 범위·acceptance | +| 근거 조사 | `research-agent`: 부족한 이론·benchmark·reference 근거 | +| 정식화 | `formulation-agent`: 새 수식·요소·해석 알고리즘 | +| 독립 수치 검토 | `numerical-review-agent`: 정식화·수치 변경·불일치 | +| 입력·결과 | `io-definition-agent`: syntax·진단·schema·비교 mapping | +| 구현 | 메인 또는 `implementation-agent`: 위임 이점이 있는 코드 묶음 | +| 물리 평가 | `physics-evaluation-agent`: 평형·타당성·coverage | + +일반 역할은 medium, 정식화·수치·물리 역할은 high 추론 강도를 기본으로 한다. 실제 profile과 +사용 가능한 도구를 확인한다. 인계는 작업·관련 경로/절·수정 파일·검증 기준, 반환은 결과· +변경 파일·검사·미해결 항목으로 충분하다. Specialist는 peer에게 재위임하거나 상위 계약을 +자기 결과에 맞춰 수정하지 않는다. 독립 검토를 자기 승인으로 대체하지 않는다. + +Release-readiness 감사는 별도 명시 요청에만 수행한다. 감사 결과는 release 권한이 아니다. +실행기는 내부 LLM·phase 상태기계·자동 Git·대화 종료 hook을 사용하지 않는다. + +## 기능 기록과 Git + +지속할 계약이 필요한 기능에는 stable kebab-case ID와 `docs//`를 정한다. +메인이 `FEATURED_AGENTS.md`, `PRD.md`, `ADR.md`를 관리한다. 기능 PRD 한 곳에서 현재 +checklist를 관리하며 복잡한 수식·schema만 별도 전문 문서로 분리한다. `FEATURED_AGENTS.md`는 +자동 로드되는 코드 영역의 `AGENTS.md`가 아니다. + +기능 문서는 한국어로 작성하고 identifier·field·명령은 원래 표기를 유지한다. 새 요구사항 +이름은 기존 `FEM-REQ--###` 형식을 유지한다. 기존 ID·승인 근거·전문 계약을 +번호 정리 때문에 변경하지 않는다. 의미 변화 없는 편집마다 hash·인계·gate 기록을 만들지 않는다. + +기존 프로젝트 PRD·ADR·수치 기준과 기능별 계약은 승인된 상세 의미를 보존한다. 공통 +규칙의 재정리는 그 의미를 변경하지 않는다. 일반 기능 작업은 공통 문서를 읽기 전용으로 +취급하며 공통 기준 변경은 별도 요청으로 다룬다. 과거 phase·coordination 기록을 재작성하거나 +현재 실행 입력으로 복원하지 않는다. 전체 진행 현황은 요약이며 기능 checklist를 복제하지 않는다. + +Commit 요청 시 작업 경로만 stage하고 Conventional Commits를 사용한다. Push·tag·publish· +파괴적 작업은 명시 범위에 한정한다. 개인 설정·machine 절대 경로·generated build 결과를 +공용 계약으로 commit하지 않는다. diff --git a/docs/tracking/decisions/0001-independent-solver.md b/docs/tracking/decisions/0001-independent-solver.md new file mode 100644 index 0000000..61cb2f5 --- /dev/null +++ b/docs/tracking/decisions/0001-independent-solver.md @@ -0,0 +1,24 @@ +# 외부 입력 subset과 독립 솔버 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +기존 모델을 읽고 외부 결과로 검증해야 하지만, 공개 입력 형식과 외부 솔버의 내부 알고리즘은 +같은 계약이 아니다. 파서 호환성을 제품 목표로 삼으면 검증 가능한 물리 의미보다 문법 수용이 앞설 수 있다. + +## 결정 + +승인된 Abaqus keyword subset의 의미만 지원한다. S4/S4R 등 source 표기는 보존하고 +FESA 정식화로 연결한다. 외부 solver의 내부 적분·안정화·상태·결과 생성 동등성은 주장하지 않는다. + +## 대안과 선택 이유 + +Full compatibility는 비공개 내부 동작까지 추정해야 하므로 채택하지 않는다. +자체 입력 형식만 쓰는 방식은 기존 .inp와 외부 reference를 직접 활용하는 현재 작업 흐름과 맞지 않는다. + +## 영향 + +입력과 kernel의 연결·차이를 명시해야 한다. Exact 수치 일치는 가능하지만 내부 동등성의 +증거가 아니다. Unknown model-affecting 입력은 silent approximation 대신 실패한다. diff --git a/docs/tracking/decisions/0002-build-and-backends.md b/docs/tracking/decisions/0002-build-and-backends.md new file mode 100644 index 0000000..3323267 --- /dev/null +++ b/docs/tracking/decisions/0002-build-and-backends.md @@ -0,0 +1,24 @@ +# 검증 환경과 private backend + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +수치 library의 package target·integer·resource와 Windows runtime이 core로 퍼지면 +물리 코드와 설치 환경을 독립적으로 검증하기 어렵다. + +## 결정 + +현재 CMake/MSVC x64 Debug/CTest와 C++17 이상을 검증 기준으로 유지한다. MKL·TBB· +HDF5·Win32는 backend-neutral 경계 뒤에 두고 project-owned dependency target과 runtime staging을 사용한다. + +## 대안과 선택 이유 + +Vendor 타입을 public에 노출하면 adapter 교체가 core와 consumer 변경으로 전파된다. +다른 toolchain의 즉시 지원 선언은 해당 환경의 numerical/runtime evidence 없이 할 수 없다. + +## 영향 + +Dependency 추가마다 build뿐 아니라 실제 runtime closure를 확인한다. 개인 설치 경로를 +제품 계약으로 고정하지 않으며 실행기 MSBuild 지원을 FESA의 별도 제품 검증으로 취급하지 않는다. diff --git a/docs/tracking/decisions/0003-model-and-equations.md b/docs/tracking/decisions/0003-model-and-equations.md new file mode 100644 index 0000000..b3c01ab --- /dev/null +++ b/docs/tracking/decisions/0003-model-and-equations.md @@ -0,0 +1,24 @@ +# 모델 정의와 equation 소유권 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +Source label, 모델 배열과 equation 번호는 서로 다른 수명과 의미를 가진다. 실행별 +제약이나 procedure가 바뀌어도 원본 모델과 결과 identity는 보존되어야 한다. + +## 결정 + +Domain이 전체 정의를 소유하고 AnalysisModel은 non-owning view로 둔다. +DofManager가 DOF·partition·equation·sparse pattern을 전담한다. Semantic definition과 numerical object는 검증된 생성 경계로 연결한다. + +## 대안과 선택 이유 + +Node/Element에 equation 번호를 저장하면 여러 실행 상태가 원본 정의에 섞인다. +모델 복사는 별도 수명·동기화 비용을 만들고 source identity가 다른 복사본처럼 취급될 수 있다. + +## 영향 + +Domain 수명을 view보다 길게 유지해야 한다. Parser나 consumer가 모든 concrete storage를 +알아야 하는 구조를 피하되 speculative clone·registry·사용하지 않는 capability는 추가하지 않는다. diff --git a/docs/tracking/decisions/0004-ordered-assembly.md b/docs/tracking/decisions/0004-ordered-assembly.md new file mode 100644 index 0000000..342948a --- /dev/null +++ b/docs/tracking/decisions/0004-ordered-assembly.md @@ -0,0 +1,24 @@ +# Local contribution과 결정적인 조립 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +병렬 계산의 속도를 얻으면서 같은 입력의 sparse 구조·합산·진단·결과 순서를 +재현해야 한다. Floating-point 누적 순서는 수치 결과에 영향을 준다. + +## 결정 + +Local contribution은 index-owned buffer에 계산하고 join 뒤 stable COO와 고정된 +reduction으로 global matrix/vector에 반영한다. Global pattern은 DOF owner가 정의한다. + +## 대안과 선택 이유 + +Worker의 직접 global CSR 갱신은 race 또는 lock 순서 의존을 만든다. +Hash iteration에 의존한 누적도 stable source ordering을 보장하지 않는다. + +## 영향 + +Contribution buffer와 정렬 비용을 부담한다. Optimization은 같은 순서·물리 의미·실패 +선택을 보존해야 하며 더 빠르다는 이유로 결정론을 선택 기능으로 만들 수 없다. diff --git a/docs/tracking/decisions/0005-state-and-output.md b/docs/tracking/decisions/0005-state-and-output.md new file mode 100644 index 0000000..ee72783 --- /dev/null +++ b/docs/tracking/decisions/0005-state-and-output.md @@ -0,0 +1,24 @@ +# Candidate 검증과 공식 HDF5 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +반복 중 일부 값 또는 저장 중 일부 dataset만 성공한 결과를 정상 해석으로 읽으면 +실패 뒤 기존 유효 결과까지 신뢰할 수 없게 된다. + +## 결정 + +State와 recovery는 완성·검증된 candidate만 반영한다. 공식 결과는 입력 lexical sibling의 +HDF5이며 임시 파일의 self-check·close 후 최종 교체한다. Output lease로 동일 output pair의 동시 쓰기를 막는다. + +## 대안과 선택 이유 + +실패 중간 state나 final 파일에 직접 누적하면 rollback 범위를 명확히 하기 어렵다. +CSV를 공식 결과로 두면 계층적 위치·단위·identity 계약을 현재 방식으로 유지할 수 없다. + +## 영향 + +Candidate와 readback 비용을 부담한다. State commit과 file finalize, final HDF5와 +진단 로그의 수명은 구분하며 실패 시 로그까지 동일하게 보존된다고 약속하지 않는다. diff --git a/docs/tracking/decisions/0006-procedure-lifecycle.md b/docs/tracking/decisions/0006-procedure-lifecycle.md new file mode 100644 index 0000000..b750612 --- /dev/null +++ b/docs/tracking/decisions/0006-procedure-lifecycle.md @@ -0,0 +1,24 @@ +# Procedure별 lifecycle과 full residual + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +정적·비선형·고유치·동적 해석은 초기화·해법·종료·결과 의미가 다르다. +반력과 free 잔차는 같은 수치 vector에 있어도 다른 물리적 역할을 가진다. + +## 결정 + +각 procedure가 필요한 state와 solver lifecycle을 소유한다. 기존 선형 정적 해석은 +elimination의 coupling을 유지하고 full residual Kd-F에서 constrained 반력과 free 평형을 구한다. + +## 대안과 선택 이유 + +Static lifecycle에 계속 분기를 누적하면 다른 procedure의 state·종료 의미가 섞인다. +Constrained 외력만 부호 반전한 반력은 지정 변위와 stiffness coupling을 반영하지 못한다. + +## 영향 + +새 procedure는 입력부터 output까지 연결해야 한다. 빈 free system은 유효한 경우 +지원하며 arbitrary penalty·regularization을 failure의 우회로로 사용하지 않는다. diff --git a/docs/tracking/decisions/0007-reference-evidence.md b/docs/tracking/decisions/0007-reference-evidence.md new file mode 100644 index 0000000..7be35d7 --- /dev/null +++ b/docs/tracking/decisions/0007-reference-evidence.md @@ -0,0 +1,24 @@ +# 원본 reference와 승인된 비교 정책 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +구현에 맞춰 기준 데이터를 고치거나 family마다 scale을 달리 정하면 수치 검증이 +구현과 기준의 순환적 자기 정당화가 된다. + +## 결정 + +기존 reference의 경로·값을 보존하고 source identity·component를 먼저 일대일 +대응한다. Approved family/scale/near-zero/row/RMS/zero-scale 정책과 판정 영향을 유지한다. + +## 대안과 선택 이유 + +Canonical naming·보조 metadata를 필수로 추가하는 방식은 실제 비교에 필요하지 않은 +정리 작업을 gate로 만든다. Missing row 무시·평균·floor·clamp는 다른 모델을 통과시킬 수 있다. + +## 영향 + +필수 원본이 없으면 비교 미실행으로 남긴다. 정책 변경은 사용자 승인과 영향 검증을 +요구하며 새 evidence를 생성할 수 있지만 과거 실패 보고와 원본을 소급 수정하지 않는다. diff --git a/docs/tracking/decisions/0008-layered-verification.md b/docs/tracking/decisions/0008-layered-verification.md new file mode 100644 index 0000000..6a2aca3 --- /dev/null +++ b/docs/tracking/decisions/0008-layered-verification.md @@ -0,0 +1,24 @@ +# 수치·물리·외부 비교의 분리 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +유한한 해, 선형계 성공 또는 외부 변위 일치만으로 정식화·회복·에너지·시간 정확성을 +모두 확인할 수 없다. HHT의 reference 통과와 temporal 실패도 별개 증거다. + +## 결정 + +동작 검사, analytical/invariant, 필요한 reference와 독립 numerical/physics 판단을 +구분한다. 수식·요소·재료·적분·상태 갱신 변경은 독립 검토를 받는다. + +## 대안과 선택 이유 + +모든 기능에 같은 고정 benchmark 목록을 강제하면 의미 없는 검사를 늘린다. +반대로 test count나 runner exit만으로 완료를 판정하면 검증되지 않은 물리를 통과로 오인한다. + +## 영향 + +기능별 필수 evidence와 미실행·실패·제외를 명시해야 한다. Release-readiness 감사는 +별도 요청이며 독립 검토·감사 결과가 배포 권한을 부여하지 않는다. diff --git a/docs/tracking/decisions/0009-explicit-development.md b/docs/tracking/decisions/0009-explicit-development.md new file mode 100644 index 0000000..3f3c1cc --- /dev/null +++ b/docs/tracking/decisions/0009-explicit-development.md @@ -0,0 +1,24 @@ +# 필요한 전문 작업과 명시적 검증 실행 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +고정 stage·반복 인계·자동 Git·종료 hook 중심 운영은 실질적인 공학 판단보다 +형식적인 상태 유지와 중복 실행을 늘렸다. + +## 결정 + +메인이 범위를 파악해 필요한 전문 작업만 배정한다. 실행기는 config·toolchain· +backend 명령을 명시 호출 시 한 번 실행한다. 일반 실패는 현재 owner가 수정한다. + +## 대안과 선택 이유 + +전용 coordinator·planning/correction profile·고정 상태기계·retry 예산을 유지하는 +방식은 폐기한다. 검증 script에 commit/push 권한을 묶는 방식도 채택하지 않는다. + +## 영향 + +메인이 작업 범위와 evidence를 확인해야 한다. 반복 승인 없이 승인된 일반 작업을 +이어가되 원격·파괴·외부 비용·상위 계약 변경의 사용자 결정 경계는 유지한다. diff --git a/docs/tracking/decisions/0010-feature-contract-ownership.md b/docs/tracking/decisions/0010-feature-contract-ownership.md new file mode 100644 index 0000000..f2c235e --- /dev/null +++ b/docs/tracking/decisions/0010-feature-contract-ownership.md @@ -0,0 +1,24 @@ +# 공통 기준과 기능별 상세 계약 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +공통 기준에 모든 기능 진행상태를 누적하거나 같은 checklist를 여러 파일에 두면 +어느 기록이 현재 요구와 상태인지 모호해진다. + +## 결정 + +공통 제품·수치 기준과 기능별 요구·정식화·I/O·결정을 구별한다. Feature의 +FEATURED_AGENTS·PRD·ADR을 유지하고 현재 checklist는 Feature PRD 한 곳에 둔다. + +## 대안과 선택 이유 + +모든 기능에 빈 보고서·requirements·matrix를 일괄 만드는 방식은 중복을 늘린다. +기존 계약을 새 파일명 규칙에 맞춰 자동 이동·재번호화하면 승인·evidence의 추적성을 잃는다. + +## 영향 + +복잡한 상세 내용만 분리한다. 기존 ID·승인 근거·reference와 과거 운영 이력을 보존한다. +전체 상태 요약이 기능별 필수 검사를 대체하지 않으며 공통 기준 변경은 별도 요청으로 다룬다. diff --git a/docs/tracking/decisions/0011-eigen-first-implementation.md b/docs/tracking/decisions/0011-eigen-first-implementation.md new file mode 100644 index 0000000..41a9271 --- /dev/null +++ b/docs/tracking/decisions/0011-eigen-first-implementation.md @@ -0,0 +1,24 @@ +# MITC4 고유치 첫 구현의 경계 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +MITC4 고유치의 첫 구현에서 외부 값 차이와 추가 정확도 개선을 분리해 진행할 +필요가 있었고, 사용자가 모드별 5% 범위의 첫 구현을 승인했다. + +## 결정 + +실제 FEAST와 consistent에서 유도한 lumped mass를 사용한다. 외부 Value는 mode별 +singleton family의 상대오차·RMS 모두 5%로 판정하는 named policy를 적용한다. + +## 대안과 선택 이유 + +공통 RMS 1%를 이 첫 구현에 그대로 요구하는 선택 대신 범위를 명시한 예외를 +채택했다. 다른 모드의 scale로 차이를 흡수하거나 reference를 보정하는 방식은 허용하지 않는다. + +## 영향 + +다른 해석의 RMS 1%와 내부 eigen 잔차·정규화·직교성 기준은 유지한다. +정확도 개선·보류한 검증은 해결된 것으로 취급하지 않고 과거 1% 실패 기록도 보존한다. diff --git a/docs/tracking/decisions/0012-hht-kinetic-mass.md b/docs/tracking/decisions/0012-hht-kinetic-mass.md new file mode 100644 index 0000000..b24d842 --- /dev/null +++ b/docs/tracking/decisions/0012-hht-kinetic-mass.md @@ -0,0 +1,24 @@ +# HHT의 consistent kinetic mass + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +유한회전 shell 동역학에서는 회전관성과 configuration에 따른 kinetic kinematics를 +다뤄야 한다. 고유치 계산의 질량 선택을 그대로 옮기면 다른 물리를 해석할 수 있다. + +## 결정 + +HHT에는 사용자 선택인 consistent kinetic mass를 사용하고 analytic null· +부분구속·회전 관성·convective 항을 보존한다. 물리 가속도와 알고리즘 보조 가속도를 구분한다. + +## 대안과 선택 이유 + +Lumped mass는 비교 연구로 남겼으며 현 HHT 지원의 fallback으로 채택하지 않았다. +임의 drilling inertia나 부분구속의 full-clamp 치환은 원래 모델을 바꾼다. + +## 영향 + +비대칭 접선·moving null·regularity와 실제 shell temporal 검증 부담이 있다. +현재 시간수렴 실패를 유지하며 가속도 복구 후보는 독립 검증·채택 전 승인된 해법으로 간주하지 않는다. diff --git a/docs/tracking/decisions/0013-thermal-staged-scope.md b/docs/tracking/decisions/0013-thermal-staged-scope.md new file mode 100644 index 0000000..ec605b9 --- /dev/null +++ b/docs/tracking/decisions/0013-thermal-staged-scope.md @@ -0,0 +1,24 @@ +# Uncoupled shell 열해석부터 구현 + +- 상태: 기존 승인·인터뷰 합의의 의미 유지 +- 결정 주체: 사용자와 기존 승인 계약의 담당자 + +## 배경 + +최종 목표는 양방향 열-구조 연성이지만, 현재는 온도장 자체의 transient 해석과 +검증 범위를 먼저 확정해야 한다. + +## 결정 + +첫 범위는 단일 step uncoupled shell 열해석, 균질 단면의 온도점 5개와 상수 물성, +고정 증분이다. 초기에 검토한 두께 방향 등온 범위는 5점 온도장으로 대체한다. + +## 대안과 선택 이유 + +즉시 양방향 연성을 구현하는 방식은 현재 요구 범위를 넘는다. 두께 등온 모델은 +아랫면·윗면의 독립 지정 온도와 두께 방향 열전달 요구를 충족하지 못한다. + +## 영향 + +열행렬·flux·반력·에너지·시간수렴을 별도로 검증해야 한다. 두 구간 이차 보간, +Backward Euler, geometry 근사와 결과 schema는 제안 상태이며 이 범위 결정만으로 채택되지 않는다. diff --git a/docs/tracking/decisions/index.md b/docs/tracking/decisions/index.md new file mode 100644 index 0000000..d36ac19 --- /dev/null +++ b/docs/tracking/decisions/index.md @@ -0,0 +1,20 @@ +# 프로젝트 결정 목록 + +현재 유지하는 선택과 그 비용을 구분한다. 과거 승인 이력과 수치 기준은 그대로 보존하며, +아래 기록은 새로운 physics·acceptance 승인이 아니다. 열해석의 제안 방법은 채택 목록에 넣지 않는다. + +| 파일 | 유지하는 선택 | +| --- | --- | +| `0001-independent-solver.md` | 외부 입력 subset과 독립 솔버 | +| `0002-build-and-backends.md` | 검증 환경과 private backend | +| `0003-model-and-equations.md` | 모델 정의와 equation 소유권 | +| `0004-ordered-assembly.md` | Local contribution과 결정적인 조립 | +| `0005-state-and-output.md` | Candidate 검증과 공식 HDF5 | +| `0006-procedure-lifecycle.md` | Procedure별 lifecycle과 full residual | +| `0007-reference-evidence.md` | 원본 reference와 승인된 비교 정책 | +| `0008-layered-verification.md` | 수치·물리·외부 비교의 분리 | +| `0009-explicit-development.md` | 필요한 전문 작업과 명시적 검증 실행 | +| `0010-feature-contract-ownership.md` | 공통 기준과 기능별 상세 계약 | +| `0011-eigen-first-implementation.md` | MITC4 고유치 첫 구현의 경계 | +| `0012-hht-kinetic-mass.md` | HHT의 consistent kinetic mass | +| `0013-thermal-staged-scope.md` | Uncoupled shell 열해석부터 구현 | diff --git a/docs/tracking/findings.md b/docs/tracking/findings.md new file mode 100644 index 0000000..662528c --- /dev/null +++ b/docs/tracking/findings.md @@ -0,0 +1,47 @@ +# 미해결 문제 + +## HHT shell의 시간수렴 + +- 조건·현상: 실제 shell의 두 시간수렴 사례에서 요구한 수렴 성능을 만족하지 못한 + 재현 기록이 남아 있다. 원본 변위 reference 통과와 함께 존재하는 실패다. +- 영향: 변위 일치만으로 동적 가속도·관성·에너지·전체 시간 정확성을 보장할 수 없다. + HHT 전체 기능 완료를 선언할 수 없다. +- 현재 해결하지 않는 이유: 문서 재구성 범위를 벗어나는 수치 알고리즘 변경이며, + 가속도 복구 후보의 정식화·독립 검증·채택 판단이 선행되어야 한다. +- 후속 방향: 기존 물리 질량·허용 오차를 유지한 재현에서 dt refinement별 q/v/물리 a와 + hidden constraint 차수를 분리하고 후보 변경의 영향을 검증한다. + +## Python 운영 계약 검사의 기대값 불일치 + +- 조건·현상: `tests/test_agent_skill_workflow_contract.py`의 inventory 검사는 11개 + profile을 기대하지만 현재 `.codex/agents`에는 7개가 있다. 같은 파일은 루트 지침의 + 고정 단계 표를 parsing하고, 과거 phase 실행 예제를 검사한다. 현재 명시 실행기와 + 필요한 전문 작업만 호출하는 운영 원칙에 맞지 않는다. +- 영향: 이 검사를 현행 운영의 통과 증거로 쓰거나 통과시키기 위해 삭제된 절차를 + 복원하면 잘못된 개발 흐름을 다시 도입한다. 루트 문서 재구성 이후에는 옛 표 위치에 + 의존하는 검사도 조정 대상이다. +- 현재 해결하지 않는 이유: 기존 불일치는 source 정적 대조로 확인했지만 이번 요청은 + 문서 변경이다. Python 검사를 실행하거나 테스트 코드를 수정하지 않았다. +- 후속 방향: 유효한 동작·권한·검증 범위를 검사하도록 기대값을 정리하고 Python suite를 + 별도로 실행한다. 현재 CTest의 성공으로 대체하지 않는다. + +## 열 reference의 작업 사본 내 부재 + +- 조건·현상: 열해석 계획은 기존 `shell-thermal.inp`와 `shell-thermal NodalTemperature.csv`를 + 지정하지만 이 작업 사본의 `reference/shell-thermal`에는 해당 파일이 없다. 앞선 계획 + 작업에서는 별도 기존 저장소의 원본을 읽기 전용으로 확인했다. +- 영향: 이 작업 사본만으로 열 reference 비교를 재현할 수 없다. CSV는 t=37의 NT11 + 한 frame만 포함하므로 원본 확보 뒤에도 flux·반력·두께 온도 분포의 검증을 대신하지 않는다. +- 현재 해결하지 않는 이유: Reference 생성·복원·복사는 현재 요청에 포함되지 않는다. + 명명 규칙 때문에 새 artifact나 보조 metadata를 만들지 않는다. +- 후속 방향: 실제 비교 작업 시 사용할 기존 원본 경로를 명시하고 허용된 접근으로 + 읽는다. 보존된 원본의 행·identity·값을 수정하지 않는다. + +## 외부 배포 결정의 공백 + +- 조건·현상: 외부 사용자 배포는 장기 목표지만 배포 형태·지원 환경·dependency 재배포 + 조건과 외부 입력의 신뢰 범위는 정해져 있지 않다. 사용자가 별도 보안 정책은 없다고 확인했다. +- 영향: 현재 로컬 실행·개인 연구 범위를 외부 서비스의 보안·설치·지원 보장으로 설명할 수 없다. +- 현재 해결하지 않는 이유: 제품 배포 범위와 권리 검토는 아직 요청되지 않았으며 코드만으로 + 사용자의 배포 방식을 정할 수 없다. +- 후속 방향: 배포를 실제 추진할 때 형식·대상·설치·검증·데이터 취급 조건을 구체화한다. diff --git a/docs/tracking/status.md b/docs/tracking/status.md new file mode 100644 index 0000000..0380cde --- /dev/null +++ b/docs/tracking/status.md @@ -0,0 +1,40 @@ +# 개발 현황 + +기준일은 2026-09-28이다. 현재 주목적은 개인 연구용 솔버 개발이며 외부 사용자 배포는 +장기 목표다. 아래 검증 상태는 기존 실행 기록의 범위이며 이번 문서 작업에서 solver나 +검증 suite를 새로 실행한 결과가 아니다. + +## 구현과 검증 상태 + +| 영역 | 구현 상태 | 확인된 evidence와 한계 | +| --- | --- | --- | +| Abaqus 입력·Domain·source identity | 구현됨 | Reader/mapper/invalid input 테스트가 존재. 최신 전체 suite 통과를 새로 주장하지 않음 | +| B33·MITC4 선형 정적 | 구현됨 | Local·integration·reference 검사가 존재. 과거 readiness는 이후 기준 변경으로 재검증 대기 표시가 있으므로 현재 release 통과로 승계하지 않음 | +| MITC4 비선형 정적·표면 압력 | 구현됨 | Newton·pressure tangent·result/reference 관련 검사와 실행 기록이 있음. 현 checkout 전체 재검증 없음 | +| MITC4 frequency | 승인된 첫 구현 완료 기록 | 당시 전체 417개 검사와 모드별 외부 Value 5% 비교·독립 검토 통과. 추가 검증 S3와 정확도 향상은 보류 | +| HHT 동해석 | 입력부터 HDF5까지 구현, 기능 검증 미완료 | 101-frame U 비교 PASS 기록, UR 경고 200건. Shell 시간수렴 두 사례 실패와 잔여 physics coverage 유지 | +| HHT 굽힘 단면력 복구 | 두께 계수 수정됨 | 관련 Debug 14 tests와 원본 HDF5 재생성·독립 식 대조 완료 기록. 전체 동해석 완료와 별개 | +| HHT 관련 전체 CTest | 일부 실패·미실행 범위 존재 | 최근 기록은 두 시간수렴 검사를 제외한 475 PASS/1 SKIP. 제외한 검사를 통과로 계산하지 않음 | +| Shell transient heat transfer | 요구사항·상세 수치 계획 작성, solver 미구현 | 5개 온도점·uncoupled 범위 합의. 수식 검산은 제한된 algebra evidence이며 solver/reference 통과 아님 | +| Python 검증 실행기 | 구현됨 | 명시 build/test runner와 별도 Python suite가 존재. 일부 운영 계약 검사는 현행 절차와 맞지 않는 기대값을 유지 | +| 외부 사용자 배포 | 계획 | 배포 방식·설치·지원 정책과 dependency 재배포 검토가 아직 정해지지 않음 | + +## 남은 작업과 의존성 + +1. Shell 열해석은 geometry·두께 station 접속·시간 종료 규칙·초기 온도 jump·edge 입력· + 결과 schema를 확정한다. 채택된 정식화의 독립 검토 이후 semantic mapping, DOF, + 행렬·시간 적분·recovery·HDF5와 검증을 연결한다. 단일 시점 NT11 비교 외 물리 검증을 + 별도로 마련해야 한다. 현재 진행 요청에 가장 가까운 구현 준비 작업이다. +2. HHT는 기존 시간수렴 실패를 유지한 상태에서 물리 가속도 복구 후보의 정식화·독립 + 검증·채택 여부를 결정한다. 강체 병진 전체 이력, Newton 경계·실패 보존, 반복 결정론, + partition·좌표변환 coverage를 완료하고 필수 전체 검사를 다시 수행해야 한다. +3. Python 운영 계약 검사는 폐기된 profile·고정 단계·phase 인자 기대값을 현행 명시 + 실행 절차에 맞게 정리하는 별도 작업이 필요하다. 현재 문서 수정에 테스트 코드 변경을 + 포함하지 않는다. +4. Eigen 첫 구현 이후 정확도 개선과 보류한 검증을 별도 범위로 정한다. 현재 승인된 + 5% 기준을 다른 해석으로 확대하거나 과거 실패 기록을 수정하지 않는다. +5. 이후 양방향 열-구조 연성과 외부 사용자 배포의 구체적인 요구·지원 범위를 정한다. + 두 장기 목표 간 순서나 일정은 정해지지 않았다. + +각 기능의 세부 checklist와 승인 이력은 기존 기능 단위로 유지한다. 전체 요약의 상태가 +상세 계약·필수 검사·실패 기록을 대체하지 않는다. diff --git a/include/fesa/AGENTS.md b/include/fesa/AGENTS.md new file mode 100644 index 0000000..3eb3600 --- /dev/null +++ b/include/fesa/AGENTS.md @@ -0,0 +1,15 @@ +# 공개 C++ interface + +이 영역은 외부 consumer와 solver 내부 계층이 공유하는 선언·값·실패·수명 계약을 소유한다. +구현 파일의 세부 구조나 vendor handle은 공개 API에 포함하지 않는다. + +- Header는 단독 include로 사용할 수 있어야 한다. Repository 경로 기반 include guard와 + 직접 필요한 include를 사용하고 src의 private header를 역으로 include하지 않는다. +- MKL·TBB·HDF5·Win32 타입은 공개하지 않는다. Concrete adapter class 선언이 있더라도 + resource는 private implementation에 격리한다. +- Source identity, entity index와 equation index를 구분한다. 반환한 record의 단위·좌표· + location과 non-owning 인자의 수명을 production Doxygen에 기록한다. +- Status/Result로 표현하는 expected failure와 exception 경계를 보존한다. Future용 + optional state·virtual method를 공통 base에 추가하지 않는다. +- Interface 변경은 consumer compile, 소유권·수명, invalid combination과 현재 결과의 + 보존을 검증한다. 선언만 추가하고 parser나 CLI 지원까지 완료됐다고 보고하지 않는다. diff --git a/scripts/AGENTS.md b/scripts/AGENTS.md new file mode 100644 index 0000000..3c7c2dc --- /dev/null +++ b/scripts/AGENTS.md @@ -0,0 +1,13 @@ +# 개발 실행 진입점 + +이 영역은 명시적으로 요청된 검증 실행과 비교 도구를 제공한다. 솔버의 제품 runtime이나 +자동 작업 승인·commit·push·release 절차를 소유하지 않는다. + +- execute.py는 인자 없는 build/test 진입점이다. 과거 phase 인자, 자동 retry·내부 LLM· + 파일명 TDD gate·대화 종료 hook을 복원하지 않는다. +- 명령 성공의 범위를 실제 실행한 검사로 제한한다. C++ 실행기가 Python 회귀나 별도 + reference 비교까지 자동 수행한다고 보고하지 않는다. +- Config·preset·실행 명령은 신뢰가 필요한 실행 입력이다. shell=False나 timeout을 + sandbox라고 설명하지 않는다. +- 변경 동작은 해당 Python 검사로 검증하고 문서만 수정하면 실행하지 않는다. + 기능별 source/reference를 실행기 편의를 위해 rename·rewrite하지 않는다. diff --git a/scripts/msvc_harness/AGENTS.md b/scripts/msvc_harness/AGENTS.md new file mode 100644 index 0000000..9a9465c --- /dev/null +++ b/scripts/msvc_harness/AGENTS.md @@ -0,0 +1,15 @@ +# Build와 test 실행기 + +이 package는 config·project 감지·toolchain 선택, adapter 명령 계획과 process 실행을 소유한다. +수치 acceptance나 Feature 상태, Git와 agent 인계는 소유하지 않는다. + +- Explicit config와 metadata에 따라 CMake/MSBuild를 선택한다. 모호한 project 감지를 + 첫 번째 파일로 해결하거나 C++ source 존재만으로 별도 gate를 만들지 않는다. +- CMake 경로는 configure 이후 MSVC metadata와 CTest의 비어 있지 않은 JSON discovery를 + 검사한다. Preset 네 필드와 실제 binaryDir의 일치를 보존한다. +- Argv list와 shell=False를 사용하고 cwd를 검증한다. CLI의 전체 deadline과 step timeout + 중 남은 범위를 적용한다. Backend side effect 전체를 격리한다고 주장하지 않는다. +- Nonzero·timeout·결과 검사 실패는 stage/argv/cwd와 출력 tail을 포함해 반환한다. + 자동 retry·commit·push·phase 결과 파일 생성을 추가하지 않는다. +- Config precedence, ambiguous metadata, non-MSVC, empty discovery, timeout 경계, + backend exit와 runner exit 구분을 process seam으로 검증한다. diff --git a/scripts/verification/AGENTS.md b/scripts/verification/AGENTS.md new file mode 100644 index 0000000..8d23d13 --- /dev/null +++ b/scripts/verification/AGENTS.md @@ -0,0 +1,14 @@ +# 외부 결과 비교 도구 + +이 영역은 승인된 reference와 FESA HDF5의 deterministic comparison을 소유한다. +솔버 실행, reference 생성·수정과 물리식 채택을 소유하지 않는다. + +- 비교 전 필요한 source instance·label·component·step/frame을 일대일 대응한다. + 누락·추가·중복·nonfinite와 schema 오류를 tolerance로 무시하지 않는다. +- Reference 값만으로 family scale을 만들고 approved near-zero·row·RMS·zero-scale 규칙을 + 적용한다. 임의 absolute floor·값 보정·nearest-time matching을 추가하지 않는다. +- 현재 HHT 비교기는 지정된 729-node 모델과 101 frames의 선택 절점 U/UR용이다. + 다른 모델을 인자로 받는다는 이유로 범용 comparator라 설명하지 않는다. +- U blocking과 UR warning-only를 유지하고 warning도 결정적인 순서로 보고한다. +- Identity 변형·frame 누락·비유한 값·tolerance 경계·zero scale·report 재현성을 검증한다. + 변위 비교 성공을 가속도·에너지·시간수렴 검증으로 확대하지 않는다. diff --git a/src/fesa/AGENTS.md b/src/fesa/AGENTS.md new file mode 100644 index 0000000..9ec337b --- /dev/null +++ b/src/fesa/AGENTS.md @@ -0,0 +1,14 @@ +# Solver 구현과 target 조합 + +이 영역은 fesa_solver와 fesa_cli의 production 구현을 소유한다. Public interface와 vendor +resource 사이의 구현 책임을 유지하며 테스트 실행기나 문서 workflow를 solver에 연결하지 않는다. + +- CMake target에 새 source와 필요한 private dependency를 명시한다. Link 성공뿐 아니라 + Windows runtime staging의 영향을 확인한다. +- Public consumer가 implementation header를 include하도록 경로를 공개하지 않는다. + MKL·TBB·HDF5·Win32는 private adapter 뒤에 둔다. +- Core 기능 추가는 input 의미 → model → equation → solve → recovery → output의 + 실제 연결과 필요한 검증 범위를 함께 고려한다. Kernel 존재만으로 공개 지원을 선언하지 않는다. +- /W4와 /WX가 적용되는 MSVC x64 Debug 기준을 유지하고 새 warning을 추가하지 않는다. +- 하위 영역 간 소유권을 바꾸는 수정은 기존 수식·source identity·상태 수명에 대한 + 영향을 먼저 검토한다. 무관한 모듈을 함께 refactor하지 않는다. diff --git a/src/fesa/analysis/AGENTS.md b/src/fesa/analysis/AGENTS.md new file mode 100644 index 0000000..b5b225a --- /dev/null +++ b/src/fesa/analysis/AGENTS.md @@ -0,0 +1,16 @@ +# Procedure와 상태 수명 + +Analysis는 준비된 Domain을 procedure별로 실행하고 equation·backend·trial·commit·recovery를 +조정한다. Concrete HDF5 layout이나 vendor handle을 공개 state에 저장하지 않는다. + +- AnalysisModel은 Domain의 non-owning view다. State에는 해당 procedure가 실제 사용하는 + mutable 해와 recovery만 둔다. 새 procedure를 static lifecycle의 조건문으로 누적하지 않는다. +- Linear static은 Kff factorization 뒤 load assembly, effective RHS, full 해와 residual 복구를 + 수행한다. Empty free를 singular로 오인하지 않는다. +- Nonlinear/HHT는 trial을 committed state/history와 분리한다. 수렴·finite·recovery 검증을 + 모두 마친 candidate만 반영하고 실패한 trial의 일부 값이 history에 남지 않게 한다. +- HHT physical a, auxiliary A, 공간 angular acceleration을 구분하고 consistent kinetic + mass·analytic null·부분구속 의미를 유지한다. 시간수렴 실패를 기준 완화로 숨기지 않는다. +- Frequency reduction은 null/finite 공간과 공개 mode 수·내부 검증 수를 구분한다. +- 초기화, nonzero BC, all-constrained, 증분·반복 종료 경계, 실패 보존, temporal convergence, + 반복 결정론과 backend failure를 검증한다. 한 reference의 U 일치로 모든 physics를 통과시키지 않는다. diff --git a/src/fesa/app/AGENTS.md b/src/fesa/app/AGENTS.md new file mode 100644 index 0000000..facd78d --- /dev/null +++ b/src/fesa/app/AGENTS.md @@ -0,0 +1,15 @@ +# CLI와 실행 조합 + +App은 입력 인자·결과 경로·output lease·실행 객체 조합·진단과 exit 변환을 소유한다. +해석식·수렴 기준·HDF5 dataset 정의를 이 영역에서 결정하지 않는다. + +- 단일 .inp 경로에서 결과와 로그의 lexical sibling을 만든다. Canonical 경로로 바꾸거나 + --output을 우회 수용하지 않는다. +- Lease 획득 전 공개 파일을 truncate하지 않는다. 같은 output pair의 충돌과 실패 시 + 기존 final HDF5 보존을 유지한다. +- 준비된 입력은 한 번 mapping한 Domain으로 실행한다. Procedure마다 다시 파싱하거나 + concrete state를 static 결과로 위장하지 않는다. +- 성공 outcome과 로그 close를 확인한 뒤 해당 결과 writer를 호출한다. 로그 오류를 + 무시하고 정상 결과 저장으로 진행하지 않는다. +- Usage·input·model·solver·output 오류의 외부 분류를 보존한다. Argument 개수, 잘못된 + 확장자, 상대 경로, busy output, 기존 결과가 있는 실패와 성공 finalize를 검증한다. diff --git a/src/fesa/assembly/AGENTS.md b/src/fesa/assembly/AGENTS.md new file mode 100644 index 0000000..7028a88 --- /dev/null +++ b/src/fesa/assembly/AGENTS.md @@ -0,0 +1,13 @@ +# 결정적인 sparse·하중 조립 + +Assembly는 element/load의 local contribution을 global matrix/vector로 누적한다. +Equation 번호와 pattern의 owner는 DofManager이며 worker가 pattern을 변경하지 않는다. + +- Worker는 element/index-owned buffer만 쓰고 join 뒤 stable COO ordering과 고정된 + reduction으로 합산한다. Global CSR에 직접 병렬 더하기를 하지 않는다. +- Full-space stiffness·내력·외력·pressure tangent의 scatter와 부호를 유지한다. + Free 성분만 조립해 constrained reaction의 근거를 잃지 않는다. +- 여러 element가 같은 DOF에 기여하는 순서는 thread scheduling에 의존하지 않는다. + Failure diagnostic도 발견 시각이 아니라 지정된 순서로 선택한다. +- Serial/parallel 일치, shared node 누적, 중복 COO, invalid contribution, empty partition, + pressure 합력·모멘트와 tangent를 검증한다. diff --git a/src/fesa/constraints/AGENTS.md b/src/fesa/constraints/AGENTS.md new file mode 100644 index 0000000..aa4aec9 --- /dev/null +++ b/src/fesa/constraints/AGENTS.md @@ -0,0 +1,12 @@ +# 지정값과 partition 정책 + +Constraints는 prescribed displacement와 equation에 적용하는 essential constraint 정책을 +소유한다. 새 물리 DOF·source target 범위·reaction 의미를 단독으로 변경하지 않는다. + +- Elimination은 full matrix의 free/constrained coupling을 유지한다. Nonzero prescribed + 값의 기여를 RHS에서 빠뜨리거나 constrained load를 버리지 않는다. +- 해 복구 후 full vector에서 지정값을 유지한다. Physical reaction과 free residual은 + 같은 조립 방정식의 서로 다른 성분이며 서로 대체하지 않는다. +- 빈 free system은 별도로 유효하게 처리하고 artificial penalty로 풀지 않는다. +- Homogeneous·nonzero BC, 충돌한 지정값, all-constrained, free/constrained permutation과 + full residual 복구를 검증한다. 새 enforcement 방식은 공개 결과 영향까지 정의한다. diff --git a/src/fesa/core/AGENTS.md b/src/fesa/core/AGENTS.md new file mode 100644 index 0000000..7cb79ce --- /dev/null +++ b/src/fesa/core/AGENTS.md @@ -0,0 +1,13 @@ +# 공통 identity와 진단 + +Core는 source identity·ASCII token 처리와 Status/Diagnostic의 공통 의미를 소유한다. +Procedure별 keyword 허용 여부나 물리식을 이 영역의 공통 default로 넣지 않는다. + +- Raw source spelling과 canonical lookup 값을 구분한다. ASCII case 처리를 locale + 의존 변환으로 바꾸지 않는다. +- Source 위치·instance·label과 내부 index를 혼용하지 않는다. Diagnostic sorting은 + 실행 thread나 hash iteration 순서와 독립적이어야 한다. +- Expected failure를 성공·빈 결과로 치환하지 않는다. Backend 예외를 통과시키는 새 경로를 + 만들 때 공개 실패 범위와 분류를 먼저 검토한다. +- Label 경계·invalid token·대소문자·빈 source 필드·동일 진단의 반복 정렬을 검증한다. + 의미가 다른 사용자 오류를 메시지 하나로 합쳐 identity를 잃지 않는다. diff --git a/src/fesa/elements/AGENTS.md b/src/fesa/elements/AGENTS.md new file mode 100644 index 0000000..5a824b1 --- /dev/null +++ b/src/fesa/elements/AGENTS.md @@ -0,0 +1,16 @@ +# 요소 local 계산 + +Elements는 Euler beam·MITC4 shell의 local 강성·내력·관성·복구용 응답을 소유한다. +Global equation 번호, 공유 sparse write와 파일 저장은 소유하지 않는다. + +- Local node/DOF 순서, 축·회전 chart·director와 부호를 정식화와 일치시킨다. + Source S4/S4R 이름이 FESA 적분·stabilization 선택을 바꾸지 않는다. +- Physical 에너지와 drilling 안정화 항을 분리한다. 질량 영공간에 임의 회전관성을 + 추가하거나 고유치와 HHT의 질량 계약을 통합하지 않는다. +- Trial response는 실패 시 기존 유효 상태를 보존한다. 비선형 접선·관성·convective 항은 + 동일 kinematics에서 유도하고 대칭이라고 가정해 항을 버리지 않는다. +- 새 수식·적분·상태 갱신은 독립 numerical review와 analytical/invariant 검사 대상이다. + Rigid motion, patch, tangent 대조, 에너지, 두께 scaling, 질량 영모드·양성 및 좌표변환을 + 변경에 맞게 검증한다. +- End action·단면력·응력의 location과 부호가 다르면 같은 recovery 함수로 강제하지 않는다. + Local kernel 완료를 Abaqus 입력이나 CLI 노출 완료로 확대하지 않는다. diff --git a/src/fesa/fem/AGENTS.md b/src/fesa/fem/AGENTS.md new file mode 100644 index 0000000..6d9247a --- /dev/null +++ b/src/fesa/fem/AGENTS.md @@ -0,0 +1,13 @@ +# DOF와 equation 구성 + +DofManager가 물리 DOF, full/free/constrained mapping, equation 번호, scatter와 sparse +pattern을 소유한다. 이 정보를 Node·Element·개별 solver에 분산 저장하지 않는다. + +- Source node identity와 equation index를 구분하고 numbering·row ordering을 결정적으로 만든다. +- Partition은 전체 DOF를 중복·누락 없이 덮어야 한다. Prescribed 값과 free 해 복구가 같은 + mapping을 사용해야 하며 partial rotation constraint를 full clamp로 바꾸지 않는다. +- 모든 DOF가 constrained인 유효한 모델의 0차원 free system을 허용한다. Empty free와 + 잘못된 topology·singular free matrix는 다른 경우다. +- Validation은 임의 fallback으로 잘못된 scatter를 건너뛰지 않는다. +- Renumbering, shared nodes, mixed free/constrained, all-constrained, invalid scatter와 + serial/parallel 경로의 동일 sparse structure를 검증한다. diff --git a/src/fesa/io/abaqus/AGENTS.md b/src/fesa/io/abaqus/AGENTS.md new file mode 100644 index 0000000..8e1eee0 --- /dev/null +++ b/src/fesa/io/abaqus/AGENTS.md @@ -0,0 +1,17 @@ +# Abaqus 입력 adapter + +이 영역은 physical source·syntax·scope·default를 검증된 Domain 정의로 mapping한다. +Abaqus 전체 호환성이나 내부 요소·해법 동등성을 목표로 하지 않는다. + +- Raw text/빈 field/source line과 canonical lookup을 구별한다. ASCII case 처리, + keyword continuation, physical line 제한과 duplicate parameter 거부를 유지한다. +- 지원 여부는 procedure별 allowlist로 판단한다. 무해한 출력 요청의 no-op 예외를 + model-affecting keyword로 확대하지 않는다. INCLUDE를 자동으로 열지 않는다. +- Instance·label·set·section/material target은 결정적으로 해소한다. 모호한 이름을 + 첫 일치값으로 선택하거나 missing 물성을 default로 채우지 않는다. +- S4/S4R source 표기를 보존하되 FESA 내부 적분 선택값으로 사용하지 않는다. + Source step 이름과 canonical result storage 이름도 구분한다. +- Procedure 선택 후 density·BC·하중·출력 요청의 조합을 검사한다. Static의 관대한 no-op을 + HHT/eigen에 복사하지 않는다. +- Valid minimal 입력과 각 keyword의 위치·arity·range·unknown parameter·중복·nonfinite· + cross-instance·여러 step 실패를 검증한다. Parser 수용만으로 새 기능 완료를 선언하지 않는다. diff --git a/src/fesa/io/hdf5/AGENTS.md b/src/fesa/io/hdf5/AGENTS.md new file mode 100644 index 0000000..26fb572 --- /dev/null +++ b/src/fesa/io/hdf5/AGENTS.md @@ -0,0 +1,15 @@ +# HDF5 출력 adapter + +이 영역은 검증된 state를 영속 schema로 기록하고 readback·close·최종 교체를 수행한다. +새 물리량의 정의와 acceptance 기준을 writer 편의로 바꾸지 않는다. + +- Procedure와 version을 함께 식별한다. Eigen의 additive discriminator와 static/dynamic + frame 의미를 구분하고 기존 필수 dataset을 optional로 바꾸지 않는다. +- Fixed-width little-endian 수치, UTF-8 문자열, compound field 이름·shape·component·unit· + coordinate/location과 source identity를 보존한다. C++ padding을 file contract로 쓰지 않는다. +- 임시 candidate에 기록·self-check·close한 뒤 final을 교체한다. 실패한 frame·write·close가 + 기존 final HDF5를 손상시키지 않아야 한다. State commit과 file finalize는 별개다. +- Source step 이름을 path로 직접 넣거나 node row를 source label로 해석하지 않는다. + Auxiliary acceleration·generalized force를 physical 결과 이름으로 바꾸지 않는다. +- Mandatory field/attribute·shape·dtype·ordering·nonfinite·version 거부, readback과 각 + failure boundary를 검증한다. Reference artifact를 writer 결과에 맞춰 수정하지 않는다. diff --git a/src/fesa/loads/AGENTS.md b/src/fesa/loads/AGENTS.md new file mode 100644 index 0000000..570862a --- /dev/null +++ b/src/fesa/loads/AGENTS.md @@ -0,0 +1,12 @@ +# 하중 의미와 local contribution + +Loads는 concentrated nodal load와 shell surface pressure의 의미·configuration·local +contribution을 소유한다. Source 이름의 해석은 mapping 경계에서, global 누적은 assembly에서 한다. + +- Global dead load와 현재 geometry를 따르는 압력을 구분한다. SPOS/SNEG와 압력 부호를 + element normal 관례에 맞추며 실패한 geometry를 normal 뒤집기로 숨기지 않는다. +- Full-space 외력과 비선형 load tangent의 부호·미분 대상을 유지한다. Constrained DOF의 + 하중을 미리 제거하면 반력 의미가 달라지므로 free RHS만 반환하지 않는다. +- 동일 target 하중은 안정된 source 순서로 합산하며 서로 다른 facet를 node 평균으로 합치지 않는다. +- 면적·법선·합력·모멘트와 tangent를 독립 대조하고 회전·반전 side·여러 facet·중복 입력을 + 검증한다. 정적 pressure 지원을 dynamic·thermal 입력까지 확대하지 않는다. diff --git a/src/fesa/materials/AGENTS.md b/src/fesa/materials/AGENTS.md new file mode 100644 index 0000000..863e364 --- /dev/null +++ b/src/fesa/materials/AGENTS.md @@ -0,0 +1,13 @@ +# 재료 구성 관계 + +Materials는 현재 승인된 물성 capability와 구성 응답을 소유한다. Topology, DOF, +element state와 전체 해석 수렴은 이 영역의 책임이 아니다. + +- Isotropic elastic parameter의 finite·range와 units를 생성 경계에서 유지한다. + 잘못된 값에 epsilon을 더하거나 clamp하지 않는다. +- Density·thermal·비탄성 등 서로 다른 의미를 기존 base의 미사용 field로 누적하지 않는다. + 실제 사용되는 capability와 승인된 procedure만 연결한다. +- Material은 analysis state를 임의 소유하지 않는다. 향후 history-dependent 재료는 + trial/commit과 실패 보존을 별도로 정의한다. +- Constitutive 응답·대칭성·경계값·invalid 조합을 독립적인 식과 대조한다. Parser에서 + 읽을 수 있다는 이유로 모든 procedure가 해당 물성을 지원한다고 판단하지 않는다. diff --git a/src/fesa/math/AGENTS.md b/src/fesa/math/AGENTS.md new file mode 100644 index 0000000..382b80a --- /dev/null +++ b/src/fesa/math/AGENTS.md @@ -0,0 +1,12 @@ +# 수치 값과 storage + +Math는 backend-neutral Vector·Matrix·SparseMatrix와 private dense-BLAS 연산을 소유한다. +Source identity나 모델의 물리·constraint 의미는 저장하지 않는다. + +- Public 타입에 MKL pointer·integer·handle을 노출하지 않는다. Size 변환과 allocation + overflow는 adapter 경계에서 검증하고 잘못된 차원을 truncate하지 않는다. +- Dense와 sparse storage의 의미를 하나의 상속 구조로 억지로 합치지 않는다. +- Copy·alias·lifetime와 operation/reduction 순서는 결과 계약이다. Refactoring으로 + 비결정적인 합산이나 silent zero clamp를 도입하지 않는다. +- 0차원 연산, shape mismatch, sparse 중복/정렬, copy/move, 비유한 입력과 backend 경계의 + 크기 조건을 검증한다. 물리 잔차 tolerance를 이 영역에서 새로 선택하지 않는다. diff --git a/src/fesa/model/AGENTS.md b/src/fesa/model/AGENTS.md new file mode 100644 index 0000000..bfcbd9a --- /dev/null +++ b/src/fesa/model/AGENTS.md @@ -0,0 +1,14 @@ +# 모델 정의와 source target + +Model은 Domain의 전체 정의, source target resolution과 초기 shell geometry를 소유한다. +Mutable 해·equation 번호·factorization resource를 node나 element 정의에 저장하지 않는다. + +- Domain은 view보다 오래 살아야 한다. Mapping 이후의 정의를 실행 편의를 위해 복사·변형해 + 서로 다른 원본처럼 유지하지 않는다. +- SourceTargetResolver의 instance/set 범위를 보존한다. 같은 숫자 label을 다른 instance와 + 합치거나 모호한 이름을 첫 번째 항목으로 선택하지 않는다. +- Section과 material의 연결은 유일하게 검증한다. Missing property를 기본 물성으로 채우지 않는다. +- Shell director/frame은 승인된 geometry 의미를 따른다. 잘못된 연결·방향·degenerate + geometry를 clamp 또는 averaging으로 숨기지 않는다. +- Declaration order, 재배열된 label, 여러 instance, 중복/모호한 set, invalid geometry와 + non-owning view의 수명 경계를 검증한다. diff --git a/src/fesa/properties/AGENTS.md b/src/fesa/properties/AGENTS.md new file mode 100644 index 0000000..2809857 --- /dev/null +++ b/src/fesa/properties/AGENTS.md @@ -0,0 +1,12 @@ +# 요소 단면과 property + +이 영역은 beam general section과 shell section의 물리적 데이터 및 재료 연결을 소유한다. +Material 구성식이나 global assembly, 실행 중 solution state는 소유하지 않는다. + +- 면적·두께·단면 관성·축의 units와 유효 조건을 보존한다. 값이 없거나 다른 element와 + 호환되지 않으면 structured failure로 처리하고 비슷한 section으로 대체하지 않는다. +- Centered homogeneous shell과 beam의 단면 위치 의미를 구분한다. Source optional + integration-point 필드를 내부 적분법 선택값으로 재해석하지 않는다. +- Property identity는 source/element 연결과 recovery까지 추적 가능해야 한다. +- 생성·invalid finite/range·element/material compatibility와 두께 변화의 결과 차원을 + 검증한다. 새로운 section 의미는 kernel만 추가하지 말고 입력과 결과까지 계약한다. diff --git a/src/fesa/results/AGENTS.md b/src/fesa/results/AGENTS.md new file mode 100644 index 0000000..5b298d2 --- /dev/null +++ b/src/fesa/results/AGENTS.md @@ -0,0 +1,14 @@ +# 물리 결과 복구와 candidate commit + +Results는 backend-neutral 결과 record와 위치·좌표·부호가 명확한 recovery를 소유한다. +HDF5 layout이나 reference 데이터를 맞추기 위한 보정은 하지 않는다. + +- Beam end action과 positive-local-x section resultant, shell generalized result와 stress를 + 구별한다. 다른 endpoint·Gauss·section 위치를 평균해 identity를 없애지 않는다. +- Reaction은 해당 procedure의 full residual에서 얻는다. Free 성분은 residual evidence이며 + constrained reaction과 같은 외부 비교로 섞지 않는다. +- Physical strain energy와 drilling energy, generalized moment와 spatial moment를 구분한다. + Shell bending resultant의 두께 세제곱 계수를 막력의 두께 계수로 치환하지 않는다. +- 전체 recovery candidate의 finite·identity·balance 검증 뒤 state에 반영한다. +- Analytical recovery, thickness scaling, 원점·좌표변환, force/moment balance, failure + preservation와 row ordering을 검증한다. Displacement 일치만으로 recovery를 승인하지 않는다. diff --git a/src/fesa/solvers/eigen/AGENTS.md b/src/fesa/solvers/eigen/AGENTS.md new file mode 100644 index 0000000..7d2cf97 --- /dev/null +++ b/src/fesa/solvers/eigen/AGENTS.md @@ -0,0 +1,13 @@ +# 고유치 backend + +이 영역은 실제 MKL FEAST 호출, interval/count/solve 제어와 backend evidence를 소유한다. +Input의 LANCZOS 표기를 실제 내부 알고리즘 동등성으로 해석하지 않는다. + +- 승인된 count·solve 제한과 spectral enclosure를 보존한다. 실패를 임의 range 확대나 + 다른 eigen solver로 조용히 대체하지 않는다. +- Mass null을 artificial inertia로 제거하지 않는다. Finite-space 구성과 공개 N개 모드, + 전체 c개 내부 검증의 의미를 유지한다. +- Vendor workspace·integer 변환·resource는 private다. 작은 음수 eigenvalue를 abs 또는 + clamp로 숨기지 않고 raw 분류와 frequency 생성의 차이를 유지한다. +- 독립 residual·정규화·직교성, repeated/cluster modes, count 경계·실패, deterministic + ordering과 source modal identity를 검증한다. 외부 mode shape 비교가 자동 필수는 아니다. diff --git a/src/fesa/solvers/linear/AGENTS.md b/src/fesa/solvers/linear/AGENTS.md new file mode 100644 index 0000000..3f16801 --- /dev/null +++ b/src/fesa/solvers/linear/AGENTS.md @@ -0,0 +1,13 @@ +# 선형계 backend + +이 영역은 PARDISO 기반 factorization·solve와 tangent solver resource를 소유한다. +Model 수정, constraint 추가와 물성 변경은 solver 실패의 대안이 아니다. + +- Positive-definite와 tangent matrix의 성질·index 형식을 구별한다. Backend 편의를 위해 + 비대칭 항을 버리거나 singular matrix에 임의 diagonal을 더하지 않는다. +- Factorization 수명, 다중 RHS·반복 solve와 해제 경로를 adapter 내부에 격리한다. + Vendor exception·상태를 public Status/Result로 변환한다. +- 실패 뒤 이전 factorization을 잘못 재사용하거나 출력 vector를 부분적으로 성공 상태로 + 남기지 않는다. Empty free 처리의 caller/backend 계약을 유지한다. +- 알려진 해, residual, 잘못된 matrix, failure/reuse, size 변환과 resource 정리를 검증한다. + 해가 finite인 것만으로 FEM 평형을 통과했다고 보고하지 않는다. diff --git a/tests/AGENTS.md b/tests/AGENTS.md new file mode 100644 index 0000000..ca97f12 --- /dev/null +++ b/tests/AGENTS.md @@ -0,0 +1,17 @@ +# 검증과 reference evidence + +Tests는 solver 동작·수학적 일관성·외부 비교 및 개발 실행기의 검증을 소유한다. +테스트를 통과시키기 위해 제품 계약이나 reference 원본을 변경하지 않는다. + +- C++ unit·integration·reference와 Python suite는 서로 다른 범위다. CTest 성공을 + Python 통과로 보고하지 않는다. CMake/MSVC x64 Debug 기준과 실제 실행 결과를 기록한다. +- 수치 변화는 analytical/invariant와 독립 review를 결합한다. Finite/solve 성공만 검사하거나 + implementation 식을 그대로 복사한 oracle로 correctness를 주장하지 않는다. +- 비교 전에 source identity·location·component·finite를 검증한다. Missing/extra/duplicate를 + 허용하지 않고 node averaging으로 beam endpoint를 collapse하지 않는다. +- MITC4 U blocking·UR warning-only와 승인된 eigen first-implementation 예외를 유지한다. + 기준 경계·zero scale·family 분리와 결정적 보고를 테스트한다. +- Reference의 경로·값·naming·metadata를 임의 수정하지 않는다. 검증용 algebra fixture의 + 입력 자유도를 공개 CLI 지원으로 승격하지 않는다. +- 과거 profile·phase를 요구하는 테스트가 현행 절차와 다르면 별도 정리 대상으로 보고한다. + 미실행·skip·제외·실패를 PASS로 계산하거나 폐기된 workflow를 복원하지 않는다.