# Step 18: Load Hierarchy ## 담당 역할과 필수 스킬 - 담당 역할: `implementation-agent` - 필수 스킬: `harness`, `fesa-cpp-msvc-tdd` - 이 Step만 `RED -> observed failure -> minimal GREEN -> focused/full VERIFY`로 수행한다. ## 읽어야 할 파일 - `/AGENTS.md` - `/docs/CODINGSTYLE.md` - `/docs/ARCHITECTURE.md` - `/docs/ADR.md` - `/docs/cpp-object-oriented-modular-refactoring/implementation-plan.md` - Step 11 source-target resolver files - Step 13 Domain/AnalysisModel files - Step 15 DofManager files - `/include/fesa/assembly/load_assembler.h`, `/src/fesa/assembly/load_assembler.cpp` - `/tests/unit/assembly/load_assembler_test.cpp` - `/tests/unit/analysis/analysis_model_test.cpp` - `/src/fesa/io/abaqus/domain_mapper.cpp` - `/src/fesa/CMakeLists.txt`, `/tests/CMakeLists.txt` - `/phases/cpp-object-oriented-modular-refactoring/index.json` - `/phases/cpp-object-oriented-modular-refactoring/step18.md` ## 작업 Requirement `R-LOAD-001`을 구현한다. 1. `/tests/unit/loads/load_test.cpp`와 LoadAssembler generic test를 먼저 추가한다. `C-LOAD-001` uses a fake Load to emit ordered contributions, verifies signed duplicate target accumulation and rejects nonfinite/index errors before global mutation. 2. Missing Load base/contribution API or concrete-vector-only assembler gives RED. 3. Create `/include/fesa/loads/load.h`, `/include/fesa/loads/concentrated_nodal_load.h`, and `/src/fesa/loads/concentrated_nodal_load.cpp`; register the source and load test in CMake. 4. Candidate interfaces: ```cpp struct LoadContribution { std::size_t source_order; std::size_t full_dof_index; double value; }; struct LoadContext { const Domain& domain; const DofManager& dof_manager; const SourceTargetResolver& target_resolver; }; class Load { public: virtual ~Load() = default; virtual Result> ComputeContributions( const LoadContext& context) const = 0; }; class ConcentratedNodalLoad final : public Load { public: ConcentratedNodalLoad(SourceTargetQuery target, std::array global_components, std::size_t source_order); Result> ComputeContributions( const LoadContext& context) const override; private: SourceTargetQuery target_; std::array global_components_; std::size_t source_order_; }; ``` 5. Domain StepDefinition owns loads through `unique_ptr` and exposes const active order. 6. `LoadAssembler` requests contributions in active source order, validates them, then accumulates into a candidate full vector in the existing deterministic order. 7. Current drilling-moment validation, exact-zero aggregate handling, nonzero prescribed effective RHS behavior and diagnostics remain unchanged. ## Acceptance Criteria ```powershell cmake --build .harness/build --config Debug --target fesa_unit_tests ctest --test-dir .harness/build -C Debug ` -R "Load|LoadAssembly|AnalysisModel|InpDomainMapping" --output-on-failure & "C:/Program Files/LLVM/bin/clang-format.exe" --dry-run --Werror ` (rg --files include/fesa/loads -g "*.h") ` (rg --files src/fesa/loads -g "*.cpp") ` include/fesa/assembly/load_assembler.h src/fesa/assembly/load_assembler.cpp ` tests/unit/loads/load_test.cpp tests/unit/assembly/load_assembler_test.cpp cmake --build .harness/build --config Debug ctest --test-dir .harness/build -C Debug --show-only=json-v1 ctest --test-dir .harness/build -C Debug --output-on-failure ``` ## 검증 및 상태 갱신 - RED fake load, ordered/validation focused tests and full CTest를 summary에 기록한다. - Reduction/order/diagnostic regression is `error`. - 성공 시 현재 Step만 `completed`로 갱신한다. - timestamp, retry, commit, advancement는 Executor 소유다. ## 금지사항 - Load object가 global Vector를 직접 mutate하게 하지 마라. - Distributed load, body force or new keyword를 구현하지 마라. - Parallel accumulation or order optimization을 추가하지 마라. - 직접 commit하거나 hook script를 수동 실행하지 마라.