docs: add shell pressure feature workflow
This commit is contained in:
@@ -0,0 +1,216 @@
|
||||
# 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.md`
|
||||
- `docs/PRD.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/ADR.md`
|
||||
- `docs/CODINGSTYLE.md`
|
||||
- `docs/HARNESS.md`
|
||||
- `docs/HARNESS_WORKFLOW.md`
|
||||
- `.codex/hooks.json`
|
||||
- `docs/shell-surface-pressure-load/requirements.md`
|
||||
- `docs/shell-surface-pressure-load/research.md`
|
||||
- `docs/shell-surface-pressure-load/formulation.md`
|
||||
- `docs/shell-surface-pressure-load/numerical-review.md`
|
||||
- `docs/shell-surface-pressure-load/reference-model.md`
|
||||
- `docs/shell-surface-pressure-load/io.md`
|
||||
- `docs/shell-surface-pressure-load/implementation-plan.md`
|
||||
- `include/fesa/io/abaqus/input_syntax.h`
|
||||
- `include/fesa/io/abaqus/input_reader.h`
|
||||
- `src/fesa/io/abaqus/input_reader.cpp`
|
||||
- `src/fesa/io/abaqus/domain_mapping_context.h`
|
||||
- `src/fesa/io/abaqus/domain_mapping_context.cpp`
|
||||
- `src/fesa/io/abaqus/topology_mapper.h`
|
||||
- `src/fesa/io/abaqus/topology_mapper.cpp`
|
||||
- `src/fesa/io/abaqus/step_definition_mapper.h`
|
||||
- `src/fesa/io/abaqus/step_definition_mapper.cpp`
|
||||
- `src/fesa/io/abaqus/domain_builder.h`
|
||||
- `src/fesa/io/abaqus/domain_builder.cpp`
|
||||
- `src/fesa/io/abaqus/domain_mapper.cpp`
|
||||
- `include/fesa/model/model_types.h`
|
||||
- `include/fesa/model/domain.h`
|
||||
- `src/fesa/model/domain.cpp`
|
||||
- `include/fesa/analysis/analysis_model.h`
|
||||
- `src/fesa/analysis/analysis_model.cpp`
|
||||
- `tests/unit/io/abaqus/input_reader_test.cpp`
|
||||
- `tests/unit/io/abaqus/input_syntax_test.cpp`
|
||||
- `tests/unit/io/abaqus/domain_mapper_test.cpp`
|
||||
- `tests/unit/io/abaqus/domain_mapping_components_test.cpp`
|
||||
- `src/fesa/CMakeLists.txt`
|
||||
- `tests/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에 조정 이유를 기록한다.
|
||||
|
||||
```cpp
|
||||
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:
|
||||
|
||||
```cpp
|
||||
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.AcceptsAsciiKeywordContinuationAndPreservesPhysicalSourceLines`
|
||||
- `ShellSurfacePressureInput.MapsDirectInstanceFacetsForS4AndS4rCaseInsensitively`
|
||||
- `ShellSurfacePressureInput.MapsExplicitInstanceElsetAndResultNeutralInternalParameter`
|
||||
- `ShellSurfacePressureInput.MapsMixedDirectAndElsetMembersAcrossTwoExplicitInstancesWithStableDataMemberAndElsetOrder`
|
||||
- `ShellSurfacePressureInput.PreservesSposSnegMagnitudeTextLocationsAndSourceOrder`
|
||||
- `ShellSurfacePressureDomain.OwnsCanonicalFacetsAndStepOwnedAdditivePressureRecords`
|
||||
- `ShellSurfacePressureDomain.AnalysisModelBorrowsActivePressureWithoutCopyingDomain`
|
||||
- `ShellSurfacePressureInput.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:
|
||||
|
||||
```powershell
|
||||
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=ELEMENT` and `NAME`; DSLOAD data is exactly `<surface>,P,<finite C-locale scalar>`.
|
||||
- Run `SurfaceDefinitionMapper` after topology finalization and before Step binding. Resolve direct `<instance>.<positive label>` and flat assembly ELSETs with explicit `INSTANCE=` 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_index` plus part/instance raw+canonical identity, source label/raw token, exact `S4|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 `StaticStepDefinition` constructors 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:
|
||||
|
||||
```powershell
|
||||
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.
|
||||
|
||||
Reference in New Issue
Block a user