initial commit FESurrogateModelTutorial

This commit is contained in:
김경종
2026-05-21 17:03:51 +09:00
parent 93665d9ee6
commit 43b86669fa
122 changed files with 7929 additions and 0 deletions
@@ -0,0 +1,18 @@
{
"project": "FEMSurrogateTutorial",
"phase": "0-project-foundation",
"steps": [
{
"step": 0,
"name": "python-project-skeleton",
"status": "completed",
"summary": "Created uv/pyproject foundation, src package skeleton, artifact directories, and ruff configuration."
},
{
"step": 1,
"name": "import-smoke-test",
"status": "completed",
"summary": "Added package import smoke tests and exposed femsurrogate.__version__."
}
]
}
@@ -0,0 +1,40 @@
# Step 0: python-project-skeleton
## 읽어야 할 파일
- `/AGENTS.md`
- `/PROGRESS.md`
- `/WORKNOTES.md`
- `/docs/PRD.md`
- `/docs/ARCHITECTURE.md`
- `/docs/ADR.md`
## 작업
Python tutorial project의 최소 기반을 만든다.
- `/pyproject.toml` 생성: Python `>=3.12,<3.15`, setuptools src layout, pytest `pythonpath = ["src"]`, ruff target `py312`.
- runtime dependencies: `numpy`, `scipy`, `pandas`, `scikit-learn`, `matplotlib`, `joblib`.
- dev dependencies: `pytest`, `ruff`, `jupyterlab`, `ipykernel`, `nbconvert`.
- Python package directories: `/src/femsurrogate/`, `/src/femsurrogate/fea/`, `/src/femsurrogate/data/`, `/src/femsurrogate/surrogates/`, `/src/femsurrogate/plotting/`.
- artifact directories: `/tests/`, `/data/reference/`, `/data/processed/`, `/reports/results/`, `/reports/predictions/`, `/reports/figures/`, `/notebooks/`.
- 빈 artifact directory에는 `.gitkeep`을 둔다.
- Python cache, virtualenv, notebook checkpoint를 `.gitignore`에 추가한다.
- `/PROGRESS.md`에 phase 0 시작 상태를 기록한다.
## Acceptance Criteria
```powershell
uv sync
uv run python -c "import femsurrogate; print(femsurrogate.__name__)"
uv run ruff check .
```
## 검증 절차
AC 커맨드를 실행하고 성공하면 `phases/0-project-foundation/index.json`의 step 0을 `completed`로 갱신한다.
## 금지사항
- Beam solver, parser, dataset, surrogate 모델 구현을 이 step에서 만들지 마라.
- Notebook 내용을 만들지 마라.
@@ -0,0 +1,36 @@
# Step 1: import-smoke-test
## 읽어야 할 파일
- `/AGENTS.md`
- `/PROGRESS.md`
- `/WORKNOTES.md`
- `/docs/ARCHITECTURE.md`
- `/pyproject.toml`
- `/src/femsurrogate/__init__.py`
## 작업
TDD로 package import smoke test를 추가한다.
- 먼저 `/tests/test_project_structure.py`를 작성한다.
- 테스트는 `femsurrogate.__version__`이 문자열인지 확인한다.
- 테스트는 `femsurrogate.fea`, `femsurrogate.data`, `femsurrogate.surrogates`, `femsurrogate.plotting` import 가능성을 확인한다.
- 테스트 실패를 먼저 확인한 뒤 최소 구현으로 통과시킨다.
- `/PROGRESS.md`에 검증 결과를 기록한다.
## Acceptance Criteria
```powershell
uv run pytest tests/test_project_structure.py -q
uv run ruff check .
```
## 검증 절차
테스트가 먼저 실패한 기록을 확인하고, 구현 후 AC가 통과하면 `phases/0-project-foundation/index.json`의 step 1을 `completed`로 갱신한다.
## 금지사항
- solver API를 만들지 마라.
- 테스트를 구현 후에만 작성하지 마라.
@@ -0,0 +1,30 @@
{
"project": "FEMSurrogateTutorial",
"phase": "1-beam2d-solver",
"steps": [
{
"step": 0,
"name": "beamexamples-parser",
"status": "completed",
"summary": "Added BeamExamples parser dataclasses and tests for cantilever input and displacement fixtures."
},
{
"step": 1,
"name": "frame-element",
"status": "completed",
"summary": "Added 2D Euler-Bernoulli frame local stiffness and transformation matrix tests and implementation."
},
{
"step": 2,
"name": "assembly-and-solver",
"status": "completed",
"summary": "Added sparse global stiffness assembly, load vector assembly, constrained DOF handling, and linear static solve."
},
{
"step": 3,
"name": "fixture-regression",
"status": "completed",
"summary": "Added BeamExamples displacement regression, analytical cantilever tip check, and clockwise-positive Rz convention alignment."
}
]
}
@@ -0,0 +1,32 @@
# Step 0: beamexamples-parser
## 읽어야 할 파일
- `/AGENTS.md`
- `/PROGRESS.md`
- `/WORKNOTES.md`
- `/docs/ARCHITECTURE.md`
- `/BeamExamples/CantileverBeam.txt`
- `/BeamExamples/CantileverBeam_Displacements.txt`
## 작업
TDD로 `BeamExamples` parser를 구현한다.
- `/tests/test_beamexamples_io.py`를 먼저 작성한다.
- `read_beam_example()`은 metadata, 6 nodes, 5 beams, fixed node 1, node 6 load를 읽는다.
- `read_expected_displacements()`는 node별 `Ux`, `Uy`, `Rz` 기준값을 읽는다.
- parser는 comment, blank line, trailing comma, `Poisson'sRatio` label을 처리한다.
- 구현 파일: `/src/femsurrogate/fea/model.py`, `/src/femsurrogate/fea/io.py`.
## Acceptance Criteria
```powershell
uv run pytest tests/test_beamexamples_io.py -q
uv run ruff check .
```
## 금지사항
- solver 구현을 이 step에 넣지 마라.
- fixture 파일을 수정하지 마라.
@@ -0,0 +1,28 @@
# Step 1: frame-element
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/src/femsurrogate/fea/model.py`
- `/src/femsurrogate/fea/io.py`
## 작업
TDD로 2-node 2D Euler-Bernoulli frame element 행렬을 구현한다.
- `/tests/test_frame_element.py`를 먼저 작성한다.
- `local_frame_stiffness(E, A, I, L)`의 shape, symmetry, axial/bending 계수를 검증한다.
- `transformation_matrix(x1, y1, x2, y2)`의 shape와 orthogonality를 검증한다.
- 구현 파일: `/src/femsurrogate/fea/element.py`.
## Acceptance Criteria
```powershell
uv run pytest tests/test_frame_element.py tests/test_beamexamples_io.py -q
uv run ruff check .
```
## 금지사항
- Timoshenko beam, 3D beam DOF를 추가하지 마라.
@@ -0,0 +1,31 @@
# Step 2: assembly-and-solver
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/src/femsurrogate/fea/model.py`
- `/src/femsurrogate/fea/io.py`
- `/src/femsurrogate/fea/element.py`
## 작업
TDD로 global assembly와 constrained linear static solver를 구현한다.
- `/tests/test_beam_solver.py`를 먼저 작성한다.
- BeamExamples model의 global stiffness shape `(18, 18)`을 검증한다.
- fixed node 1의 3 DOF가 constrained 처리되는지 검증한다.
- `solve_linear_static(model)`이 모든 node displacement를 finite 값으로 반환하는지 검증한다.
- 구현 파일: `/src/femsurrogate/fea/assembly.py`, `/src/femsurrogate/fea/solver.py`.
- solver는 `scipy.sparse``scipy.sparse.linalg.spsolve`를 사용한다.
## Acceptance Criteria
```powershell
uv run pytest tests/test_beam_solver.py tests/test_frame_element.py tests/test_beamexamples_io.py -q
uv run ruff check .
```
## 금지사항
- expected displacement 값을 solver에 hard-code하지 마라.
@@ -0,0 +1,30 @@
# Step 3: fixture-regression
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/PRD.md`
- `/docs/ARCHITECTURE.md`
- `/BeamExamples/CantileverBeam.txt`
- `/BeamExamples/CantileverBeam_Displacements.txt`
- `/src/femsurrogate/fea/`
## 작업
TDD로 BeamExamples displacement regression을 완성한다.
- `/tests/test_cantilever_fixture_regression.py`를 먼저 작성한다.
- solver 결과의 모든 node별 `Ux`, `Uy`, `Rz`를 기준 displacement file과 `atol=5e-7`, `rtol=1e-6`으로 비교한다.
- tip displacement 부호와 해석해 `P L^3 / (3 E I)` 대비 크기를 검증한다.
- 필요한 helper는 `/src/femsurrogate/fea/benchmark.py`, `/src/femsurrogate/fea/responses.py`에 둔다.
## Acceptance Criteria
```powershell
uv run pytest tests/test_cantilever_fixture_regression.py tests/test_beam_solver.py tests/test_frame_element.py tests/test_beamexamples_io.py -q
uv run ruff check .
```
## 금지사항
- 허용오차를 문서 기준보다 느슨하게 키우지 마라.
@@ -0,0 +1,30 @@
{
"project": "FEMSurrogateTutorial",
"phase": "2-dataset-and-surrogates",
"steps": [
{
"step": 0,
"name": "sampling-and-dataset",
"status": "completed",
"summary": "Added reproducible LHS sampling, BeamParameters/AnalysisResult schema, and Beam2D dataset builder using the in-repository solver."
},
{
"step": 1,
"name": "surrogate-common",
"status": "completed",
"summary": "Added reproducible dataset split helper, evaluation result dataclasses, regression metrics, fit/predict timing, and prediction table generation."
},
{
"step": 2,
"name": "surrogate-models",
"status": "completed",
"summary": "Added scikit-learn builders and registry for RSM, GPR, Random Forest, Gradient Boosting, and MLP models."
},
{
"step": 3,
"name": "plotting-and-results",
"status": "completed",
"summary": "Added parity and residual diagnostic plots, metrics table creation, and metric comparison plot helpers returning matplotlib figures."
}
]
}
@@ -0,0 +1,28 @@
# Step 0: sampling-and-dataset
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/docs/theory/01_doe_sampling_validation.md`
- `/src/femsurrogate/fea/`
## 작업
TDD로 LHS sampling과 Beam2D dataset builder를 구현한다.
- 테스트: `/tests/test_sampling.py`, `/tests/test_dataset_builder.py`.
- 구현: `/src/femsurrogate/data/bounds.py`, `schema.py`, `sampling.py`, `dataset.py`.
- 기본 seed는 `20260521`.
- dataset schema는 문서의 SI 단위 컬럼을 따른다.
## Acceptance Criteria
```powershell
uv run pytest tests/test_sampling.py tests/test_dataset_builder.py -q
uv run ruff check .
```
## 금지사항
- surrogate 학습을 이 step에 넣지 마라.
@@ -0,0 +1,26 @@
# Step 1: surrogate-common
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/src/femsurrogate/data/`
## 작업
TDD로 surrogate 공통 split/evaluate/result helper를 구현한다.
- 테스트: `/tests/test_surrogate_common.py`.
- 구현: `/src/femsurrogate/surrogates/common.py`.
- metrics는 `rmse`, `mae`, `r2`, `fit_time_s`, `predict_time_s`를 포함한다.
## Acceptance Criteria
```powershell
uv run pytest tests/test_surrogate_common.py -q
uv run ruff check .
```
## 금지사항
- 개별 모델 builder를 이 step에 섞지 마라.
@@ -0,0 +1,30 @@
# Step 2: surrogate-models
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/theory/02_response_surface_methodology.md`
- `/docs/theory/03_gaussian_process_kriging.md`
- `/docs/theory/04_random_forest.md`
- `/docs/theory/05_gradient_boosting.md`
- `/docs/theory/06_mlp_neural_network.md`
- `/src/femsurrogate/surrogates/common.py`
## 작업
TDD로 모델별 scikit-learn pipeline builder와 registry를 구현한다.
- 테스트: `/tests/test_surrogate_models.py`.
- 구현: `rsm.py`, `gpr.py`, `random_forest.py`, `boosting.py`, `mlp.py`, `registry.py`.
- 모델명: `rsm`, `gpr`, `random_forest`, `gradient_boosting`, `mlp`.
## Acceptance Criteria
```powershell
uv run pytest tests/test_surrogate_models.py -q
uv run ruff check .
```
## 금지사항
- PyTorch/TensorFlow, AutoML, MLflow를 추가하지 마라.
@@ -0,0 +1,26 @@
# Step 3: plotting-and-results
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/ARCHITECTURE.md`
- `/src/femsurrogate/surrogates/`
## 작업
TDD로 diagnostics plotting과 result comparison helper를 구현한다.
- 테스트: `/tests/test_plotting_and_results.py`.
- 구현: `/src/femsurrogate/plotting/diagnostics.py`, `/src/femsurrogate/plotting/comparison.py`.
- plotting 함수는 matplotlib Figure를 반환한다.
## Acceptance Criteria
```powershell
uv run pytest tests/test_plotting_and_results.py -q
uv run ruff check .
```
## 금지사항
- browser dashboard를 만들지 마라.
@@ -0,0 +1,30 @@
{
"project": "FEMSurrogateTutorial",
"phase": "3-notebooks-and-final-verification",
"steps": [
{
"step": 0,
"name": "dataset-notebook",
"status": "completed",
"summary": "Added and executed dataset notebook that validates BeamExamples, generates LHS samples, builds FEM dataset, and writes reference CSV/metadata."
},
{
"step": 1,
"name": "model-notebooks",
"status": "completed",
"summary": "Added and executed five model notebooks sharing the same dataset, target, and split seed while saving metrics, predictions, and diagnostic figures."
},
{
"step": 2,
"name": "comparison-notebook",
"status": "completed",
"summary": "Added and executed comparison notebook that reads saved metrics and writes model comparison CSV and figures without retraining."
},
{
"step": 3,
"name": "final-verification",
"status": "completed",
"summary": "Ran full pytest, ruff, all seven nbconvert executions, and verified comparison outputs exist."
}
]
}
@@ -0,0 +1,23 @@
# Step 0: dataset-notebook
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/PRD.md`
- `/docs/ARCHITECTURE.md`
- `/src/femsurrogate/`
## 작업
`notebooks/00_beam2d_fea_dataset.ipynb`를 만든다. Notebook은 BeamExamples regression 검증, LHS sampling, FEM batch run, dataset 저장을 설명하고 실행한다.
## Acceptance Criteria
```powershell
uv run jupyter nbconvert --to notebook --execute notebooks/00_beam2d_fea_dataset.ipynb
uv run ruff check .
```
## 금지사항
- 핵심 solver 구현을 notebook cell에 넣지 마라.
@@ -0,0 +1,39 @@
# Step 1: model-notebooks
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/theory/02_response_surface_methodology.md`
- `/docs/theory/03_gaussian_process_kriging.md`
- `/docs/theory/04_random_forest.md`
- `/docs/theory/05_gradient_boosting.md`
- `/docs/theory/06_mlp_neural_network.md`
- `/src/femsurrogate/surrogates/`
- `/src/femsurrogate/plotting/`
## 작업
모델별 notebook 5개를 만든다.
- `notebooks/01_response_surface_surrogate.ipynb`
- `notebooks/02_gaussian_process_kriging_surrogate.ipynb`
- `notebooks/03_random_forest_surrogate.ipynb`
- `notebooks/04_gradient_boosting_surrogate.ipynb`
- `notebooks/05_mlp_surrogate.ipynb`
각 notebook은 같은 dataset, target, split seed를 쓰고 metric JSON과 prediction CSV를 저장한다.
## Acceptance Criteria
```powershell
uv run jupyter nbconvert --to notebook --execute notebooks/01_response_surface_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/02_gaussian_process_kriging_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/03_random_forest_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/04_gradient_boosting_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/05_mlp_surrogate.ipynb
uv run ruff check .
```
## 금지사항
- 모델별로 다른 split을 쓰지 마라.
@@ -0,0 +1,24 @@
# Step 2: comparison-notebook
## 읽어야 할 파일
- `/AGENTS.md`
- `/docs/PRD.md`
- `/reports/results/`
- `/reports/predictions/`
- `/src/femsurrogate/plotting/comparison.py`
## 작업
`notebooks/06_compare_surrogate_models.ipynb`를 만든다. 이전 notebook 결과물을 읽어 RMSE, MAE, R2, 학습 시간, 예측 시간을 비교하고 모델 선택 가이드를 정리한다.
## Acceptance Criteria
```powershell
uv run jupyter nbconvert --to notebook --execute notebooks/06_compare_surrogate_models.ipynb
uv run ruff check .
```
## 금지사항
- 비교 notebook에서 모델을 다시 학습하지 마라.
@@ -0,0 +1,37 @@
# Step 3: final-verification
## 읽어야 할 파일
- `/AGENTS.md`
- `/PROGRESS.md`
- `/WORKNOTES.md`
- `/docs/PRD.md`
- `/docs/ARCHITECTURE.md`
## 작업
전체 검증과 handoff 문서 정리를 수행한다.
- `uv run pytest`
- `uv run ruff check .`
- 모든 notebook 순차 `nbconvert --execute`
- `/PROGRESS.md` 최종 업데이트
- `/WORKNOTES.md`에 남은 주의점 기록
## Acceptance Criteria
```powershell
uv run pytest
uv run ruff check .
uv run jupyter nbconvert --to notebook --execute notebooks/00_beam2d_fea_dataset.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/01_response_surface_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/02_gaussian_process_kriging_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/03_random_forest_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/04_gradient_boosting_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/05_mlp_surrogate.ipynb
uv run jupyter nbconvert --to notebook --execute notebooks/06_compare_surrogate_models.ipynb
```
## 금지사항
- 실패한 검증을 성공으로 기록하지 마라.
@@ -0,0 +1,20 @@
{
"phases": [
{
"dir": "0-project-foundation",
"status": "completed"
},
{
"dir": "1-beam2d-solver",
"status": "completed"
},
{
"dir": "2-dataset-and-surrogates",
"status": "completed"
},
{
"dir": "3-notebooks-and-final-verification",
"status": "completed"
}
]
}