12 KiB
Step 1: map-pressure-input-contract
실행 범위와 상태 소유권
이 Step의 단일 책임은 valid assembly-level *SURFACE, TYPE=ELEMENT와 sole static Step의 *DSLOAD P를 immutable Domain/Step semantic objects와 non-owning AnalysisModel view로 mapping하는 것이다. 이 Step 안에서 RED -> observed expected failure -> minimal GREEN -> focused VERIFY -> full/Stop VERIFY를 끝내고 green 상태로 종료한다.
Implementation Agent는 Executor가 선택한 이 Step만 수행한다. 성공 시 phases/shell-surface-pressure-load/index.json의 Step 1 status와 한 줄 summary만, 오류/차단 시 각각 error_message 또는 blocked_reason만 기록할 수 있다. branch, retry, timestamps, commits, 다음 Step 선택, top-level phase status와 step1-output.json은 Harness Executor 소유다.
읽어야 할 파일
먼저 전부 읽는다.
AGENTS.mddocs/PRD.mddocs/ARCHITECTURE.mddocs/ADR.mddocs/CODINGSTYLE.mddocs/HARNESS.mddocs/HARNESS_WORKFLOW.md.codex/hooks.jsondocs/shell-surface-pressure-load/requirements.mddocs/shell-surface-pressure-load/research.mddocs/shell-surface-pressure-load/formulation.mddocs/shell-surface-pressure-load/numerical-review.mddocs/shell-surface-pressure-load/reference-model.mddocs/shell-surface-pressure-load/io.mddocs/shell-surface-pressure-load/implementation-plan.mdinclude/fesa/io/abaqus/input_syntax.hinclude/fesa/io/abaqus/input_reader.hsrc/fesa/io/abaqus/input_reader.cppsrc/fesa/io/abaqus/domain_mapping_context.hsrc/fesa/io/abaqus/domain_mapping_context.cppsrc/fesa/io/abaqus/topology_mapper.hsrc/fesa/io/abaqus/topology_mapper.cppsrc/fesa/io/abaqus/step_definition_mapper.hsrc/fesa/io/abaqus/step_definition_mapper.cppsrc/fesa/io/abaqus/domain_builder.hsrc/fesa/io/abaqus/domain_builder.cppsrc/fesa/io/abaqus/domain_mapper.cppinclude/fesa/model/model_types.hinclude/fesa/model/domain.hsrc/fesa/model/domain.cppinclude/fesa/analysis/analysis_model.hsrc/fesa/analysis/analysis_model.cpptests/unit/io/abaqus/input_reader_test.cpptests/unit/io/abaqus/input_syntax_test.cpptests/unit/io/abaqus/domain_mapper_test.cpptests/unit/io/abaqus/domain_mapping_components_test.cppsrc/fesa/CMakeLists.txttests/CMakeLists.txt
이 Step에는 이전 Step 산출물이 없다. Existing parser/domain behavior를 먼저 이해하고 legacy beam/shell inputs를 보존한다.
소유 파일
먼저 test files를 생성/수정한 뒤 production files를 변경한다.
- Modify:
include/fesa/io/abaqus/input_syntax.h - Modify:
src/fesa/io/abaqus/input_reader.cpp - Modify:
src/fesa/io/abaqus/domain_mapping_context.h - Modify:
src/fesa/io/abaqus/domain_mapping_context.cpp - Create:
src/fesa/io/abaqus/surface_definition_mapper.h - Create:
src/fesa/io/abaqus/surface_definition_mapper.cpp - Modify:
src/fesa/io/abaqus/domain_mapper.cpp - Modify:
src/fesa/io/abaqus/step_definition_mapper.cpp - Modify:
src/fesa/io/abaqus/domain_builder.cpp - Modify:
include/fesa/model/model_types.h - Modify:
include/fesa/model/domain.h - Modify:
src/fesa/model/domain.cpp - Modify:
include/fesa/analysis/analysis_model.h - Modify:
src/fesa/analysis/analysis_model.cpp - Modify/Test:
tests/unit/io/abaqus/input_reader_test.cpp - Create/Test:
tests/unit/io/abaqus/shell_surface_pressure_domain_test.cpp - Modify:
src/fesa/CMakeLists.txt - Modify:
tests/CMakeLists.txt
domain_mapper_test.cpp와 domain_mapping_components_test.cpp는 focused regression 대상으로 우선 읽는다. 이 Step의 valid mapping에 직접 필요한 assertion이 새 feature test로 표현되지 않는 경우에만 최소 수정한다.
인터페이스와 semantic contract
include/fesa/model/model_types.h에 다음 의미의 candidate value types를 구현한다. Existing style상 이름을 최소 조정해야 하면 upstream semantic fields와 아래 accessors를 빠짐없이 보존하고 summary에 조정 이유를 기록한다.
enum class ShellSurfaceSide { kSpos, kSneg };
enum class SurfaceMemberKind { kDirect, kElset };
struct ElementSurfaceFacetDefinition {
EntityIndex element_index;
std::size_t facet_ordinal;
std::string part_name_raw;
std::string part_name_canonical;
std::string instance_name_raw;
std::string instance_name_canonical;
std::int64_t source_element_label;
std::string source_element_label_raw;
std::string source_element_type;
ShellSurfaceSide side;
SourceLocation first_member_location;
std::size_t first_member_ordinal;
SurfaceMemberKind member_kind;
std::string elset_name_raw;
std::string elset_name_canonical;
};
struct ElementSurfaceDefinition {
std::string surface_name_raw;
std::string surface_name_canonical;
std::vector<ElementSurfaceFacetDefinition> facets;
SourceLocation declaration_location;
std::size_t declaration_ordinal;
};
struct SurfacePressureLoadDefinition {
std::string step_name_raw;
std::string step_name_canonical;
EntityIndex surface_index;
std::string surface_name_raw;
std::string surface_name_canonical;
std::string load_type;
double magnitude;
std::string magnitude_raw;
SourceLocation keyword_location;
SourceLocation data_location;
std::size_t data_ordinal;
std::size_t load_ordinal;
};
Required queries:
const std::vector<ElementSurfaceDefinition>&
Domain::ElementSurfaces() const noexcept;
const std::vector<SurfacePressureLoadDefinition>&
StepDefinition::SurfacePressureLoads() const noexcept;
bool StepDefinition::UsesNonlinearGeometry() const noexcept;
const std::vector<SurfacePressureLoadDefinition>&
AnalysisModel::ActiveSurfacePressureLoads() const noexcept;
ModelDefinition owns element_surfaces; StaticStepDefinition owns surface_pressure_loads; committed Domain/StepDefinition remain immutable. AnalysisModel returns non-owning references and never copies/reorders the surface inventory; Domain must outlive it. Pressure records do not enter the existing configuration-independent nodal Load::ComputeContributions interface.
RED
Write and register these tests before production implementation:
InpSyntax.AcceptsAsciiKeywordContinuationAndPreservesPhysicalSourceLinesShellSurfacePressureInput.MapsDirectInstanceFacetsForS4AndS4rCaseInsensitivelyShellSurfacePressureInput.MapsExplicitInstanceElsetAndResultNeutralInternalParameterShellSurfacePressureInput.MapsMixedDirectAndElsetMembersAcrossTwoExplicitInstancesWithStableDataMemberAndElsetOrderShellSurfacePressureInput.PreservesSposSnegMagnitudeTextLocationsAndSourceOrderShellSurfacePressureDomain.OwnsCanonicalFacetsAndStepOwnedAdditivePressureRecordsShellSurfacePressureDomain.AnalysisModelBorrowsActivePressureWithoutCopyingDomainShellSurfacePressureInput.AcceptsWhitespaceSignedZeroAndFiniteScientificNotation
The mixed-instance fixture declares Instance-A and Instance-B in distinct declaration order, interleaves differently cased direct members and flat assembly ELSET members bound by explicit INSTANCE=, and uses the same numeric element label in both instances. It must compare case-insensitive resolution, raw data/member ordinals, flat ELSET provenance, canonical facet order, distinct part/instance/source label/source type/side identities and first-member provenance exactly. It must not accept implicit-instance syntax.
After test edits and CMake test registration, run:
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
"-DFESA_GTEST_SOURCE_DIR=C:/git/googletest" `
"-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" `
"-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" `
"-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(InpSyntax|ShellSurfacePressureInput|ShellSurfacePressureDomain)\."
Expected RED: missing mapper/header/semantic accessors produces compile/link failure, or current unsupported SURFACE/DSLOAD behavior fails assertions. The mixed-instance fixture must fail because the two explicit instances/mixed direct+ELSET are not resolved or committed identity/provenance is absent. Record command, exit code, duration and meaningful output tail. An unrelated existing failure is regression; an unexpected pass is an evidence-gap. Stop before production changes until the expected RED is observed.
Minimal GREEN
- Support physical-line ASCII/256-byte policy, comma/cardinality, physical locations and keyword-parameter-only continuation exactly as
io.md§3 defines. Do not invent inline comments or data continuation. - Parse assembly-only element surfaces and parameterless step-level DSLOAD. Surface parameters are exactly
TYPE=ELEMENTandNAME; DSLOAD data is exactly<surface>,P,<finite C-locale scalar>. - Run
SurfaceDefinitionMapperafter topology finalization and before Step binding. Resolve direct<instance>.<positive label>and flat assembly ELSETs with explicitINSTANCE=case-insensitively. - One surface may mix direct/ELSET members and multiple explicit instances. Preserve raw data/member order and ELSET expansion provenance, then sort unique committed facets by
(instance declaration ordinal, numeric element label, SPOS before SNEG). - Preserve each facet's internal
element_indexplus part/instance raw+canonical identity, source label/raw token, exactS4|S4R, side, facet ordinal and first-member provenance. - Preserve each Step pressure record's step/surface raw+canonical identity,
load_type="P", signed magnitude/raw token, keyword/data locations, data ordinal and total Step load ordinal. Records remain distinct/additive. - Bind pressure surface references only after every candidate target validates. DomainBuilder commits once. Legacy
StaticStepDefinitionconstructors delegate with an empty pressure vector.
VERIFY and Acceptance Criteria
If .harness/config.json exists at execution time, its complete configure/build/test selection takes precedence and the exact resolved commands must be recorded. Otherwise execute:
cmake --build .harness/build --config Debug --target fesa_unit_tests
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(InpSyntax|ShellSurfacePressureInput|ShellSurfacePressureDomain)\."
ctest --test-dir .harness/build -C Debug --output-on-failure -R "^(InpDomainMapping|DomainMappingComponents|InpSyntax)\."
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
Acceptance requires exit 0, nonzero discovered tests, all named tests present/pass, no new MSVC /W4 /WX warnings, and all legacy tests green. The automatic Stop hook performs another whole-project MSVC validation; do not call hook scripts manually.
불변식, 실패 처리와 증거
- Supported: mixed direct/ELSET and multiple explicit instances in one surface. Unsupported: implicit-instance ELSET, one ELSET mixing instances, part-scope fallback.
- Same numeric label in different instances is never merged. Source identity is not replaced by internal/equation index.
- Parse/map failure returns no Domain and exposes no partial surface/load. Do not update AnalysisState or HDF5.
- Evidence must record RED/GREEN/VERIFY commands, exits, durations/tails, mapped facet/load inventory, source identity/order, warnings and changed files.
- Failure classification:
configure | compile | link | test | harness | environment | upstream-contract | regression | evidence-gap.
Trace: FESA-REQ-SHELL-PRESSURE-001–004, 010, 013; io.md §§2–6; formulation.md §3.
금지사항
- Do not implement pressure force/tangent or procedure assembly. 이유: Steps 3–5 ownership이다.
- Do not support
*DLOAD, implicit-instance ELSET, part surface, generalized distributed loads or additional element types. 이유: approved subset 밖이다. - Do not change HDF5 schema, CLI output contract, upstream docs, tolerance or reference artifacts.
- Do not run Abaqus/reference solvers, create output JSON, invoke
scripts/execute.py, select Step 2, commit or push.