Files
2026-06-12 01:31:31 +09:00

4.2 KiB

Step 4: dof-manager

읽어야 할 파일

먼저 아래 파일들을 읽고 프로젝트의 아키텍처와 이전 step 산출물을 파악하라:

  • /AGENTS.md
  • /docs/PRD.md
  • /docs/ARCHITECTURE.md
  • /docs/ADR.md
  • /src/fesa/model/boundary_condition.hpp
  • /src/fesa/analysis/analysis_model.hpp
  • /tests/unit/analysis_model_view_test.cpp

이전 step에서 만들어진 model object와 AnalysisModel을 꼼꼼히 읽고, equation numbering이 Node/Element로 새지 않도록 유지하라.

작업

node별 DOF 정의, constrained/free mapping, equation numbering, sparse pattern ownership의 최소 골격을 /src/fesa/fem/에 구현한다.

필수 파일:

  • /src/fesa/fem/dof_key.hpp
  • /src/fesa/fem/dof_manager.hpp
  • /tests/unit/dof_manager_numbering_test.cpp

필수 interface:

namespace fesa::fem {

struct DofKey {
    core::NodeId node_id;
    model::DofComponent component;
};

bool operator==(const DofKey& lhs, const DofKey& rhs);

class DofManager {
public:
    void define_node_dofs(core::NodeId node_id, std::vector<model::DofComponent> components);
    void apply_boundary_condition(const model::BoundaryCondition& bc);
    void number_equations();

    int total_dof_count() const;
    int free_dof_count() const;
    int constrained_dof_count() const;

    bool is_constrained(DofKey key) const;
    int equation_id(DofKey key) const;
    std::optional<int> free_equation_id(DofKey key) const;

    std::vector<double> expand_free_vector(const std::vector<double>& free_values) const;
    const std::vector<std::pair<int, int>>& sparse_pattern() const;
};

} // namespace fesa::fem

구현 규칙:

  • Equation id는 DofManager 내부에만 저장한다.
  • equation_id는 전체 DOF ordering의 dense id를 반환한다.
  • free_equation_id는 constrained DOF면 std::nullopt를 반환한다.
  • number_equations()는 deterministic ordering을 보장한다:
    • node id value 오름차순
    • component enum 순서 오름차순
  • expand_free_vector는 constrained DOF 값을 0.0으로 채우고 free DOF 값만 배치한다.
  • sparse_pattern()은 skeleton 단계에서 free equation ids의 dense full matrix pattern을 deterministic pair list로 보유해도 된다.
  • missing DOF 조회는 std::invalid_argument를 던진다.

Tests To Write First

  • /tests/unit/dof_manager_numbering_test.cpp
    • 두 node에 ux, uy를 정의하고 deterministic equation id ordering을 확인한다.
    • boundary condition 적용 후 constrained/free count가 맞는지 확인한다.
    • constrained key의 free_equation_idstd::nullopt임을 확인한다.
    • free vector가 full vector로 재구성될 때 constrained DOF가 0.0으로 채워지는지 확인한다.
    • sparse pattern pair list가 free equation id 기반 deterministic dense pattern을 가진다.
    • model::Node나 model::Element를 수정하지 않고도 equation numbering이 가능함을 확인한다.

RED 확인:

  1. 테스트 파일을 먼저 작성한다.
  2. targeted CTest를 실행해 missing dof_manager.hpp로 실패함을 확인한다.
  3. 그 뒤 production headers를 작성한다.

Acceptance Criteria

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 dof_manager_numbering_test

검증 절차

  1. 위 AC 커맨드를 실행한다.
  2. 아키텍처 체크리스트를 확인한다:
    • DofManager가 equation numbering을 전담하는가?
    • Node/Element public interface가 equation id로 오염되지 않았는가?
    • sparse pattern ownership이 DofManager 내부에 있는가?
  3. 결과에 따라 phases/solver-core-skeleton/index.json의 step 4를 업데이트한다:
    • 성공: "status": "completed", "summary": "DofManager deterministic numbering and constrained/free mapping added"
    • 3회 수정 시도 후 실패: "status": "error", "error_message": "구체적 에러 내용"
    • 사용자 개입 필요: "status": "blocked", "blocked_reason": "구체적 사유" 후 중단

금지사항

  • Solver backend, assembly matrix, MKL adapter를 구현하지 마라.
  • Node 또는 Element에 equation id field를 추가하지 마라.
  • JavaScript/TypeScript/npm fallback을 추가하지 마라.