98 lines
3.8 KiB
Markdown
98 lines
3.8 KiB
Markdown
# Step 3: analysis-model-view
|
|
|
|
## 읽어야 할 파일
|
|
|
|
먼저 아래 파일들을 읽고 프로젝트의 아키텍처와 이전 step 산출물을 파악하라:
|
|
|
|
- `/AGENTS.md`
|
|
- `/docs/PRD.md`
|
|
- `/docs/ARCHITECTURE.md`
|
|
- `/docs/ADR.md`
|
|
- `/src/fesa/model/domain.hpp`
|
|
- `/src/fesa/model/analysis_step.hpp`
|
|
- `/tests/unit/model_domain_test.cpp`
|
|
|
|
이전 step에서 만들어진 Domain과 AnalysisStep을 꼼꼼히 읽고, Domain 복사 없는 step view를 유지하라.
|
|
|
|
## 작업
|
|
|
|
현재 step에서 활성화되는 해석 객체 view를 제공하는 `AnalysisModel`을 `/src/fesa/analysis/`에 구현한다.
|
|
|
|
필수 파일:
|
|
|
|
- `/src/fesa/analysis/analysis_model.hpp`
|
|
- `/tests/unit/analysis_model_view_test.cpp`
|
|
|
|
필수 interface:
|
|
|
|
```cpp
|
|
namespace fesa::analysis {
|
|
|
|
class AnalysisModel {
|
|
public:
|
|
AnalysisModel(const model::Domain& domain, core::StepId step_id);
|
|
|
|
const model::Domain& domain() const;
|
|
const model::AnalysisStep& step() const;
|
|
const std::vector<const model::Element*>& active_elements() const;
|
|
const std::vector<const model::BoundaryCondition*>& active_boundary_conditions() const;
|
|
const std::vector<const model::Load*>& active_loads() const;
|
|
|
|
const model::Property* property_for(const model::Element& element) const;
|
|
const model::Material* material_for(const model::Property& property) const;
|
|
};
|
|
|
|
} // namespace fesa::analysis
|
|
```
|
|
|
|
구현 규칙:
|
|
|
|
- `AnalysisModel`은 `Domain`을 복사하지 않고 const reference 또는 pointer view만 보유한다.
|
|
- Phase skeleton에서는 모든 Domain elements가 active라고 간주한다.
|
|
- Boundary condition과 load는 선택된 `AnalysisStep`에서 가져온다.
|
|
- `property_for`와 `material_for`는 Domain lookup을 사용한다.
|
|
- 없는 step id는 구조화된 exception 대신 `std::invalid_argument`로 실패해도 된다. 이 skeleton 단계에서는 별도 error hierarchy를 만들지 않는다.
|
|
- `AnalysisModel`은 displacement, residual, equation number를 소유하지 않는다.
|
|
|
|
## Tests To Write First
|
|
|
|
- `/tests/unit/analysis_model_view_test.cpp`
|
|
- Domain에 node/element/material/property/step을 만든다.
|
|
- `AnalysisModel(domain, step_id)`가 원본 Domain reference를 유지함을 pointer identity로 확인한다.
|
|
- 모든 Domain element가 `active_elements()`에 const pointer로 나타난다.
|
|
- step의 boundary condition과 load가 active view에 const pointer로 나타난다.
|
|
- `property_for(element)`와 `material_for(property)`가 Domain 소유 객체를 반환한다.
|
|
- 없는 step id는 `std::invalid_argument`를 던진다.
|
|
|
|
RED 확인:
|
|
|
|
1. 테스트 파일을 먼저 작성한다.
|
|
2. targeted CTest를 실행해 missing `analysis_model.hpp`로 실패함을 확인한다.
|
|
3. 그 뒤 production header를 작성한다.
|
|
|
|
## Acceptance Criteria
|
|
|
|
```powershell
|
|
python -m unittest discover -s scripts -p "test_*.py"
|
|
python scripts/validate_workspace.py
|
|
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R analysis_model_view_test
|
|
```
|
|
|
|
## 검증 절차
|
|
|
|
1. 위 AC 커맨드를 실행한다.
|
|
2. 아키텍처 체크리스트를 확인한다:
|
|
- AnalysisModel이 Domain을 복사하지 않는가?
|
|
- AnalysisModel이 현재 step view만 제공하고 mutable state를 소유하지 않는가?
|
|
- active BC/load가 AnalysisStep에서 온 것임이 테스트되는가?
|
|
3. 결과에 따라 `phases/solver-core-skeleton/index.json`의 step 3을 업데이트한다:
|
|
- 성공: `"status": "completed"`, `"summary": "AnalysisModel step view added without Domain copies"`
|
|
- 3회 수정 시도 후 실패: `"status": "error"`, `"error_message": "구체적 에러 내용"`
|
|
- 사용자 개입 필요: `"status": "blocked"`, `"blocked_reason": "구체적 사유"` 후 중단
|
|
|
|
## 금지사항
|
|
|
|
- DofManager나 equation numbering을 이 step에서 구현하지 마라.
|
|
- AnalysisState를 이 step에서 구현하지 마라.
|
|
- JavaScript/TypeScript/npm fallback을 추가하지 마라.
|