336 lines
15 KiB
Markdown
336 lines
15 KiB
Markdown
# FESA Session Handoff
|
|
|
|
## 1. 문서 목적
|
|
|
|
이 문서는 `fem-and-beam-kernel` 완료 후 새 세션에서
|
|
`equation-and-linear-solve` Phase를 바로 시작하기 위한 인수인계 기록이다.
|
|
요구사항과 설계의 기준은 이 문서가 아니라 다음 파일이다.
|
|
|
|
- `/AGENTS.md`
|
|
- `/docs/PRD.md`
|
|
- `/docs/ARCHITECTURE.md`
|
|
- `/docs/ADR.md`
|
|
- `/docs/HARNESS.md`
|
|
- `/docs/formulation/timoshenko-beam-3d.md`
|
|
- `/docs/superpowers/plans/2026-07-29-fesa-phase-1.md`
|
|
- `/phases/equation-and-linear-solve/index.json`
|
|
- `/phases/equation-and-linear-solve/step0.md`부터 `step2.md`
|
|
|
|
내용이 충돌하면 위 기준 문서와 `phases/`의 현재 상태를 우선한다.
|
|
|
|
## 2. 현재 저장소 상태
|
|
|
|
2026-07-31 확인 기준:
|
|
|
|
- 현재 브랜치: `dev`
|
|
- 현재 `dev` HEAD:
|
|
`fa48a4d9d717224ed84ec41f06c43fbc33d42780`
|
|
- `origin/dev`, `origin/HEAD`:
|
|
`4ee3895915accf69c3f988bf14119fab7c318ed5`
|
|
- 로컬 `dev`는 `origin/dev`보다 10 commit 앞서고 0 commit 뒤처져 있다.
|
|
- 완료 Phase:
|
|
- `solver-bootstrap`
|
|
- `domain-and-input-skeleton`
|
|
- `fem-and-beam-kernel`
|
|
- 다음 Phase: `equation-and-linear-solve`
|
|
- 다음 Step: `0 - symmetric-csr-assembly`
|
|
- `equation-and-linear-solve`의 Step 0~2는 모두 `pending`이다.
|
|
- `fem-and-beam-kernel`은 `dev`에 fast-forward 병합되었고 로컬
|
|
`feat-fem-and-beam-kernel` 브랜치는 삭제되었다.
|
|
- 원격 push는 수행하지 않았다.
|
|
|
|
이 문서를 갱신하기 직전 작업 트리는 clean이었다. 이 문서 변경은 사용자가 별도로
|
|
요청하지 않는 한 커밋하지 않는다. 새 세션에서 Harness를 실행하기 전에
|
|
`docs/HANDOFF.md` 변경을 먼저 커밋하거나 별도로 정리해야 한다. 그렇지 않으면
|
|
executor의 feature branch와 step commit에 인수인계 문서가 섞일 수 있다.
|
|
|
|
## 3. 완료된 `fem-and-beam-kernel`
|
|
|
|
Phase metadata는 `/phases/fem-and-beam-kernel/index.json`에 기록되어 있으며 Step
|
|
0~3이 모두 `completed`다.
|
|
|
|
### FEM primitives
|
|
|
|
- `/include/fesa/fem/gauss_rule.hpp`
|
|
- `/include/fesa/fem/line2_shape.hpp`
|
|
- 1점/2점 1D Gauss rule
|
|
- 2절점 선형 shape function, 자연좌표 derivative와 \(J=L/2\)
|
|
- partition of unity, endpoint interpolation, 적분 정확도와 invalid-input 테스트
|
|
|
|
### `DofManager`
|
|
|
|
- `/include/fesa/fem/dof_manager.hpp`
|
|
- internal `NodeId` 정렬에 기반한 deterministic full DOF numbering
|
|
- 절점당 순서:
|
|
\(u_x,u_y,u_z,r_x,r_y,r_z\)
|
|
- free equation mapping, prescribed value, 12-DOF Beam mapping과 full-vector 복원
|
|
- equation ID는 `Node`나 `BeamElement`에 저장하지 않는다.
|
|
|
|
현재 `DofManager::build(const Domain&)`는 `Domain::step().prescribed_dofs`를 읽어
|
|
구속 자유도와 prescribed 값을 이미 내부에 반영한다. 다음 Phase에서 이 상태를
|
|
중복 소유하지 않도록 주의한다.
|
|
|
|
### Beam frame와 transformation
|
|
|
|
- `/include/fesa/fem/beam_frame.hpp`
|
|
- scale-aware normalization과 Gram-Schmidt
|
|
- 오른손 기저 \(e_z=e_x\times e_y\)
|
|
- 요소축과 orientation의 평행 판정에 scale-aware tolerance 적용
|
|
- 12x12 global-to-local transformation과 회전/에너지 invariant 테스트
|
|
|
|
### Timoshenko stiffness kernel
|
|
|
|
- `/include/fesa/elements/beam/beam3d2.hpp`
|
|
- `/docs/formulation/timoshenko-beam-3d.md`
|
|
- local DOF 순서:
|
|
`[u,v,w,theta_x,theta_y,theta_z]` per node
|
|
- strain component 순서:
|
|
\([\epsilon,\gamma_y,\gamma_z,\kappa_x,\kappa_y,\kappa_z]\)
|
|
- \(\gamma_y=v'-\theta_z\), \(\gamma_z=w'+\theta_y\)
|
|
- constitutive diagonal:
|
|
\([EA,GA_{sy},GA_{sz},GJ,EI_y,EI_z]\)
|
|
- 축·비틀림·굽힘은 2점, 전단은 1점 Gauss 적분
|
|
- global stiffness는 \(T^\mathsf{T}K_\mathrm{local}T\)
|
|
- 대칭성, 여섯 강체모드, 축, 비틀림, 양 축 굽힘과 전단, 세장비 sweep,
|
|
좌표 회전 invariant 테스트
|
|
|
|
통합 설명은 구현처럼 upper triangle을 적분한 뒤 대칭 위치로 복사한다고
|
|
`fa48a4d`에서 정정했다.
|
|
|
|
## 4. 검증된 baseline과 개발환경
|
|
|
|
새 PowerShell 세션에서 configure 또는 Harness 실행 전에 다음 환경 변수를 설정한다.
|
|
절대경로를 tracked CMake 파일이나 Preset에 넣지 않는다.
|
|
|
|
```powershell
|
|
$env:MKL_DIR = "C:\Program Files (x86)\Intel\oneAPI\2026.1\lib\cmake\mkl"
|
|
$env:TBB_DIR = "C:\Program Files (x86)\Intel\oneAPI\2026.1\lib\cmake\tbb"
|
|
$env:HDF5_DIR = "C:\Program Files\HDF_Group\HDF5\2.1.1\cmake"
|
|
$env:GTest_DIR = "C:\Users\baram\AppData\Local\FESA\dependencies\googletest-1.17.0-v145-x64-crt\lib\cmake\GTest"
|
|
|
|
Test-Path "$env:MKL_DIR\MKLConfig.cmake"
|
|
Test-Path "$env:TBB_DIR\TBBConfig.cmake"
|
|
Test-Path "$env:HDF5_DIR\hdf5-config.cmake"
|
|
Test-Path "$env:GTest_DIR\GTestConfig.cmake"
|
|
```
|
|
|
|
2026-07-31 현재 네 package 경로가 모두 존재한다. 현재 `dev` HEAD에서 다음 baseline을
|
|
새로 검증했다.
|
|
|
|
- MSBuild 18.8.2, MSVC v145 Debug build 성공
|
|
- build 출력에 새 warning 없음
|
|
- CTest 22개 중 22개 성공
|
|
- Harness pytest 20개 중 20개 성공
|
|
- pytest가 실제로 20개를 수집했으므로 0-test 성공이 아님
|
|
|
|
검증 명령:
|
|
|
|
```powershell
|
|
cmake --build --preset windows-debug
|
|
ctest --preset windows-debug --output-on-failure
|
|
uv run --with pytest python -m pytest -v -rs
|
|
```
|
|
|
|
CMake cache가 없거나 package 경로가 바뀐 경우에만 같은 환경 변수 세션에서 먼저
|
|
다음을 실행한다.
|
|
|
|
```powershell
|
|
cmake --fresh --preset windows-debug
|
|
```
|
|
|
|
## 5. 다음 Phase 목표와 Step 순서
|
|
|
|
`equation-and-linear-solve`의 독립 deliverable은 Beam contribution과 nodal load를
|
|
full symmetric system으로 조립하고, essential BC를 소거한 뒤 MKL PARDISO로
|
|
reduced SPD system을 푸는 것이다. 세 Step을 순서대로 실행한다.
|
|
|
|
### Step 0 — `symmetric-csr-assembly`
|
|
|
|
- `/include/fesa/assembly/`와 `/src/fesa/assembly/`에 필요한 최소 계약을 만든다.
|
|
- `SymmetricCsr {order,row_offsets,column_indices,values}`와
|
|
`EquationSystem {stiffness,force}`를 구현한다.
|
|
- `Domain`의 Beam, material, section, node와 `DofManager::element_full_dofs()`를
|
|
사용해 `compute_beam3d2()`의 global contribution을 조립한다.
|
|
- sparsity pattern 생성과 numeric merge를 분리한다.
|
|
- `(row,column,element-origin,local-order)`의 안정된 순서로 합산한다.
|
|
- hand-calculated 2-element system, duplicate contribution, external ID 순서 변화와
|
|
CSR invariant를 실패 테스트로 먼저 고정한다.
|
|
- 이 Step의 serial assembler는 후속 병렬 조립의 oracle이다. TBB 병렬화는
|
|
`deterministic-parallel-assembly` Phase까지 미룬다.
|
|
|
|
### Step 1 — `essential-bc-elimination`
|
|
|
|
- `/include/fesa/constraints/`와 `/src/fesa/constraints/`에 essential-BC elimination을
|
|
구현한다.
|
|
- 원래 full `EquationSystem`은 변경하지 않고 reduced symmetric system을 만든다.
|
|
- 0과 비영 prescribed value의 RHS shift를 모두 처리한다.
|
|
- free solution과 prescribed 값을 full vector로 복원한다.
|
|
- 반력은 reduced matrix가 아니라 원래 시스템의 \(r=Ku-f\)에서 계산한다.
|
|
- hand calculation으로 0/비영 지정값, all-constrained, 충돌 조건과 반력을 먼저
|
|
테스트한다.
|
|
|
|
### Step 2 — `pardiso-linear-solver`
|
|
|
|
- `/include/fesa/solvers/linear/`와 `/src/fesa/solvers/linear/`에 backend 경계를
|
|
구현한다.
|
|
- public `LinearSolver` 계약에는 MKL 타입을 노출하지 않는다.
|
|
- `PardisoLinearSolver`가 analysis, factorization, solve, release 수명을 RAII로
|
|
관리한다.
|
|
- `mtype=2`, LP64 index, `iparm[34]=1`, matrix checker를 사용한다.
|
|
- 3x3 SPD, repeated solve, invalid CSR, dimension mismatch와 singular matrix를
|
|
실패 테스트로 먼저 고정한다.
|
|
- 해와 상대잔차를 adapter 외부의 독립 계산으로 확인한다.
|
|
|
|
## 6. 다음 Phase의 핵심 계약과 확인할 설계점
|
|
|
|
### 아키텍처 경계
|
|
|
|
- `assembly`는 sparse pattern, local-to-global mapping, contribution 정렬·병합과
|
|
CSR 변환만 담당한다. Beam formulation이나 PARDISO handle을 소유하지 않는다.
|
|
- `constraints`는 essential BC와 full/reduced vector 변환만 담당한다.
|
|
- `solvers/linear`만 MKL PARDISO API에 의존한다.
|
|
- `core`, `model`, `fem`, `elements`에 MKL 또는 TBB API를 유입하지 않는다.
|
|
- penalty, MPC, Lagrange multiplier, iterative solver, 병렬 조립과 analysis
|
|
pipeline은 이번 Phase 범위가 아니다.
|
|
|
|
### 구현 전에 명시적으로 정렬할 점
|
|
|
|
1. `SymmetricCsr`의 upper/lower triangle 저장 계약이 Step 파일에 아직 하나로
|
|
고정되어 있지 않다. Step 0에서 테스트와 주석으로 하나를 명시하고 Step 1~2와
|
|
일관되게 사용한다.
|
|
2. `DofManager`는 이미 free equation mapping과 prescribed 값을 내부 소유한다.
|
|
Step 1 초안의 별도 `prescribed` 인수와 `ReducedSystem` 상태를 그대로 중복하지
|
|
말고, 기존 계약을 읽은 뒤 필요한 최소 query만 추가한다.
|
|
3. `Domain`은 material/section span을 제공하지만 현재 ID lookup public accessor는
|
|
없다. 조립을 위해 mutable `Domain`이나 범용 registry를 만들지 말고, Phase 1에
|
|
필요한 deterministic lookup을 최소 범위로 구현한다.
|
|
4. `BeamKernelResult`는 contribution 또는 diagnostic을 반환한다. 조립 계층이
|
|
실패를 무시하거나 zero matrix로 대체하지 않도록 오류 전달 계약을 테스트한다.
|
|
5. all-constrained 문제는 reduced order가 0일 수 있다. constraint 계층에서 유효한
|
|
결과로 다루되, 빈 system을 PARDISO에 넘기는 정책과 혼동하지 않는다.
|
|
|
|
위 항목은 범위를 넓히라는 의미가 아니다. 기존 코드와 Step 초안 사이의 중복 또는
|
|
미정 계약을 구현 전에 드러내고 가장 단순한 일관된 계약을 선택하기 위한 확인
|
|
목록이다.
|
|
|
|
## 7. Child sandbox의 MSBuild 실행 조건
|
|
|
|
`fem-and-beam-kernel` 실행 전 child sandbox를 실제로 조사한 결과:
|
|
|
|
- 앱 설치 경로의 `codex-cli 0.146.0`은 matching `codex-resources`를 찾지 못했다.
|
|
- 완전한 standalone 배포는 다음 위치에 있다.
|
|
`C:\Users\baram\.codex\packages\standalone\releases\0.146.0-x86_64-pc-windows-msvc`
|
|
- child에서 WindowsApps 경유 PowerShell은 실패했고 Windows PowerShell 5.1은
|
|
정상 동작했다.
|
|
- `[windows] sandbox = "elevated"`에서는 MSBuild FileTracker가 access denied로
|
|
실패했다.
|
|
- 완전한 standalone Codex, 정리된 PATH와
|
|
`[windows] sandbox = "unelevated"` 조합에서는 child MSBuild가 성공했다.
|
|
|
|
현재 `C:\Users\baram\.codex\config.toml`은 원래 값인
|
|
`[windows] sandbox = "elevated"`로 복원되어 있다. 다음 Harness 실행에서도 같은
|
|
문제가 재현되면 사용자가 이미 선택한 1번 방식에 따라 다음 순서를 사용한다.
|
|
|
|
1. 다른 Codex 작업에 미칠 영향을 확인하고 global config 원래 값을 기록한다.
|
|
2. Harness 실행 동안만 `[windows] sandbox = "unelevated"`로 바꾼다.
|
|
3. 현재 PowerShell 세션의 PATH 앞에 standalone `bin`과 Windows PowerShell 5.1을
|
|
둔다. `Get-Command codex`와 `Get-Command powershell`로 실제 경로를 확인한다.
|
|
|
|
```powershell
|
|
$codexReleaseBin = "C:\Users\baram\.codex\packages\standalone\releases\0.146.0-x86_64-pc-windows-msvc\bin"
|
|
$windowsPowerShell = "$env:SystemRoot\System32\WindowsPowerShell\v1.0"
|
|
$filteredPath = $env:PATH -split ";" | Where-Object {
|
|
$_ -and
|
|
$_ -ne $codexReleaseBin -and
|
|
$_ -ne $windowsPowerShell -and
|
|
$_ -notmatch "\\Microsoft\\WindowsApps$" -and
|
|
$_ -notmatch "\\OpenAI\\Codex\\bin$"
|
|
}
|
|
$env:PATH = (@($codexReleaseBin, $windowsPowerShell) + $filteredPath) -join ";"
|
|
|
|
(Get-Command codex).Source
|
|
(Get-Command powershell).Source
|
|
```
|
|
|
|
4. 같은 세션에서 package 환경 변수와 baseline을 확인한 뒤 Harness를 실행한다.
|
|
5. 성공·실패와 무관하게 global config를 즉시
|
|
`[windows] sandbox = "elevated"`로 복원하고 실제 값을 다시 읽어 확인한다.
|
|
|
|
사용자 profile 전체나 드라이브 루트를 `--codex-add-dir`로 허용하지 않는다. 설치
|
|
버전이나 경로가 달라졌다면 위 절대경로를 맹목적으로 사용하지 말고 실제 standalone
|
|
release와 `codex-resources` 존재를 먼저 확인한다.
|
|
|
|
이전 Harness는 모든 Step과 phase commit을 완료한 뒤 stderr reader의 CP949/UTF-8
|
|
decode 예외를 한 번 출력했다. Phase metadata와 Git commit에는 영향이 없었고 root
|
|
검증은 모두 통과했다. 같은 메시지가 반복되면 제품 실패로 단정하지 말고 executor
|
|
종료 시점, phase status와 Git 이력을 함께 확인한다.
|
|
|
|
## 8. 새 세션 시작 절차
|
|
|
|
먼저 이 문서와 다음 Phase 파일을 모두 읽는다.
|
|
|
|
```text
|
|
/phases/equation-and-linear-solve/index.json
|
|
/phases/equation-and-linear-solve/step0.md
|
|
/phases/equation-and-linear-solve/step1.md
|
|
/phases/equation-and-linear-solve/step2.md
|
|
```
|
|
|
|
그 다음 저장소 상태를 재검증한다.
|
|
|
|
```powershell
|
|
git switch dev
|
|
git status --short --branch
|
|
git rev-parse HEAD
|
|
git rev-parse origin/dev
|
|
```
|
|
|
|
로컬 `dev`의 미push 10 commit을 보존한다. `origin/dev`에 맞추기 위한 reset, checkout
|
|
또는 rebase를 수행하지 않는다. `docs/HANDOFF.md` 변경이 남아 있으면 먼저 사용자의
|
|
의도대로 커밋하거나 정리한다.
|
|
|
|
4절의 package 환경 변수를 설정하고 baseline을 실행한다. Child MSBuild 문제가
|
|
재현될 가능성이 있으므로 7절 조건을 적용한 뒤 다음을 실행한다.
|
|
|
|
```powershell
|
|
python scripts/execute.py equation-and-linear-solve
|
|
```
|
|
|
|
executor는 `feat-equation-and-linear-solve` 브랜치를 생성하거나 checkout하고 Step
|
|
상태와 output metadata를 기록한다. 사용자가 명시적으로 요청하지 않은 한 `--push`를
|
|
사용하지 않는다.
|
|
|
|
각 Step은 다음 순서를 지킨다.
|
|
|
|
1. Step 파일의 필수 문서와 선행 구현을 모두 읽는다.
|
|
2. 성공 기준과 CSR/constraint/backend invariant를 명시한다.
|
|
3. 실패 테스트를 먼저 작성하고 예상한 이유로 실패함을 확인한다.
|
|
4. 테스트를 통과시키는 최소 production code만 구현한다.
|
|
5. focused test, 전체 CTest, Harness pytest를 실행한다.
|
|
6. Step summary와 output metadata가 실제 결과와 일치하는지 확인한다.
|
|
7. Phase 종료 전 전체 diff를 아키텍처·수치 계약·resource lifetime 기준으로
|
|
review한다.
|
|
|
|
## 9. 다음 Phase 완료 조건
|
|
|
|
- `/phases/equation-and-linear-solve/index.json`의 Step 0~2가 모두 `completed`
|
|
- `/phases/index.json`에서 `equation-and-linear-solve`가 `completed`
|
|
- deterministic serial symmetric CSR의 구조·값·stable merge 테스트 통과
|
|
- full load vector와 Beam global contribution의 hand calculation 일치
|
|
- 0/비영 essential BC의 RHS shift와 full-vector 복원 검증 통과
|
|
- 반력이 원래 \(r=Ku-f\)에서 정확히 복원됨
|
|
- PARDISO SPD solve, repeated solve, invalid input와 singular diagnostic 검증 통과
|
|
- focused test와 전체 CTest 통과
|
|
- Harness pytest가 0개가 아닌 상태로 전체 통과
|
|
- 새 MSVC warning 없음
|
|
- MKL 타입과 handle이 `solvers/linear` adapter 밖으로 노출되지 않음
|
|
- TBB 병렬 조립, analysis pipeline 또는 범위 밖 solver 기능을 선행 구현하지 않음
|
|
- review의 Critical/Important 항목 해결
|
|
- 사용자 선택 전 원격 push나 `dev` 병합을 수행하지 않음
|
|
|
|
새 세션의 권장 첫 요청:
|
|
|
|
> `docs/HANDOFF.md`와 `phases/equation-and-linear-solve/step0.md`부터 `step2.md`를
|
|
> 읽고 현재 baseline과 child sandbox의 MSBuild 실행 조건을 확인한 뒤
|
|
> `equation-and-linear-solve` Phase를 시작해주세요.
|