Files
FESADev/docs/linear-static-3d-euler-beam/lessons.md
T
2026-10-04 03:32:59 +09:00

339 lines
25 KiB
Markdown

# Beam 수정·실패와 재발 방지
당시 독립 검토의 실제 결함·RED/GREEN·수정 확인을 보존한다. 현재 ownership과 실행은 공통 문서를 따른다.
<a id="implementation-report"></a>
<a id="implementation-report--review-fix-round-1--matrix-storage-size-overflow"></a>
#### Review Fix Round 1 — matrix-storage-size-overflow
- regression_test: `tests/unit/math/matrix_test.cpp` now constructs
`Matrix{SIZE_MAX / 2 + 1, 2}` and requires `std::length_error`.
- RED: `cmake --build .harness/build --config Debug --target fesa_tests` exited 0;
`ctest --test-dir .harness/build -C Debug -R DenseMath --output-on-failure`
exited 8 with 1/2 failures because the wraparound constructor threw nothing.
- fix: `Matrix` computes its storage size through a checked helper before vector
construction and rejects exactly `columns != 0 && rows > SIZE_MAX / columns`.
- GREEN: the same targeted build and DenseMath CTest commands exited 0; 2/2 passed.
- VERIFY: approved MSVC x64 configure and full Debug build exited 0; targeted
DenseMath passed 2/2, discovery found 7 tests, and the full suite passed 7/7.
The public-header MKL scan had zero matches, `git diff --check` exited 0, and
`git diff --exit-code -- reference/` exited 0.
- scope: the deferred empty-dot review minor was not changed, reference artifacts
remain untouched, and phase Step 9 status/timestamps were not modified.
<a id="implementation-report--step-12-review-corrections"></a>
#### Step 12 Review Corrections
- A duplicate-`*ELASTIC` regression test first failed because a second
consecutive elasticity record lost the owning-material state. Preserving the
immediate material eligibility produced the exact `duplicate-entity`
diagnostic and restored targeted 5/5.
- Ten monotonic-order regressions first failed at the accepted late-`*PART`
case. Explicit phase state now rejects late model data, assembly sets before
or followed by instances, element-before-node, incomplete block closure, and
pre-`*STATIC` or out-of-order history data with
`invalid-keyword-location`.
- Review edge tests then failed for valid `1e308` geometry and for nonfinite
elasticity being classified as input. Context-specific model parsing,
overflow-safe scaled geometry comparisons, active beam-section context,
exact GENERATE landing, direct/ambiguous target resolution, and exact
threshold cases were added. The corrected focused suite passes 5/5 and the
full accumulated suite passes 19/19.
- Focused re-review returned Critical 0 and Important 0. Its sole remaining
minor requested an explicit negative transverse-shear context assertion;
that table case was added and passes without a production change.
<a id="implementation-report--step-12-root-review-fix-round-1--same-token-target-ambiguity"></a>
#### Step 12 Root Review Fix Round 1 — same-token target ambiguity
- finding: `resolveNodeTarget` returned one matching node set before computing
the direct numeric source-label candidates. A token such as `1` therefore
silently selected `NSET=1` even when node source label `1` was also a valid
interpretation.
- regression_scope: `RejectsUnsupportedAndInvalidPortfolio` now constructs an
`NSET` named `1` containing node `2` while node label `1` also exists, and
exercises the same token independently through both `*BOUNDARY` and
`*CLOAD`. It requires input-category `unresolved-reference` with exact
keyword, entity identity `1`, and original data-row file/line location.
- RED-build: `cmake --build .harness/build --config Debug --target fesa_tests`
exited 0 after registering the two regression paths.
- RED-test: `ctest --test-dir .harness/build -C Debug -R "InpDomainMapping.RejectsUnsupportedAndInvalidPortfolio" --output-on-failure`
exited 8. The test failed at `same-token-boundary`
because `result.hasValue()` was true instead of the required structured
failure.
- fix: target resolution computes both name-matched node sets and numeric
direct-node candidates before returning either. Multiple candidates within
an interpretation or one valid candidate from each interpretation use the
existing input/`unresolved-reference` ambiguity contract; unique set-only
and direct-only paths remain unchanged.
- GREEN: the targeted build exited 0 and `ctest --test-dir .harness/build -C Debug -R InpDomainMapping --output-on-failure`
exited 0 with 5/5 passed.
- VERIFY: approved explicit-dependency MSVC x64 configure and full Debug build
exited 0; discovery found 19 tests including all five mapper names; full
CTest passed 19/19. Backend/upward/core-upward/distributed-load/unapproved
`nu` scans were 0, exactly five mapper tests remained, `git diff --check`
exited 0, and reference diff/status were clean.
- deferred_scope: the separate known-but-misplaced keyword diagnostic Minor was
deliberately not changed in this fix round. No phase-index change and no
commit were made.
<a id="implementation-report--root-numerical-review--fix-round-1"></a>
#### Root numerical review — Fix Round 1
- scope: all three `Important` findings addressed in
`src/fesa/elements/euler_beam_3d.cpp` and the existing exact T16 tests; the
two `Minor` findings were intentionally not changed in this round.
- defect_RED: after adding finite-positive derived-overflow,
derived-underflow, and length-scaled-underflow fixtures to existing
`T16-BEAM-007`,
`ctest --test-dir .harness/build -C Debug -R EulerBeam3D.RejectsInvalidGeometryAndProperties --output-on-failure`
exited 8. All three invalid fixtures were accepted; the diagnostic path
observed respectively a nonfinite stiffness with maximum `inf`, an all-zero
stiffness, and a stiffness with a required bending coefficient underflowed
to zero.
- defect_GREEN: `cmake --build .harness/build --config Debug --target fesa_tests`
exited 0 and the same focused CTest exited 0 with 1/1 passed. `create()` now
requires derived `EA`, `GJ`, `EIy`, `EIz` and all ten distinct positive
length-scaled axial/torsion/bending block magnitudes to be finite and
strictly positive. This rejects arithmetic overflow/underflow as
`invalid-beam-property` without a conditioning threshold.
- invariant_hardening: production `normalizedMatrixError` now returns infinite
error for any nonfinite operand, difference, scale, or quotient, so the
two-point/closed-form `1e-12` invariant fails closed.
- analytical_hardening: every nonzero reference in existing `T16-BEAM-006`
now checks `abs(actual-reference)/abs(reference) <= 1e-9`; only the explicitly
zero free-end resultants retain an absolute check. This evidence-only change
was expected to remain GREEN and its focused test passed without a production
correction.
- convergence_hardening: existing `T16-BEAM-005` directly assembles aligned
1/2/4-element `[v,rz]` cantilever systems from public `localStiffness()` and
`localEquivalentLoad()` only. It checks each exact signed constant transverse
element load, solves a test-only dense reduced system, and uses independent
five-point integration of interior cubic-Hermite displacement error against
the quartic uniform-load solution. Both refinements are monotone and each
observed order is 4 within `1e-8`. No `DLOAD`, parser, Domain, or production
assembly support was introduced. This evidence-only change was expected to
remain GREEN and the T16-005/T16-006 focused run passed 2/2.
| stage | exact command | exit_code | observed_result |
| --- | --- | ---: | --- |
| FIX1-RED | `ctest --test-dir .harness/build -C Debug -R EulerBeam3D.RejectsInvalidGeometryAndProperties --output-on-failure` | 8 | 0/1 passed; unexpected acceptance exposed nonfinite and zero stiffness outcomes |
| FIX1-GREEN-build | `cmake --build .harness/build --config Debug --target fesa_tests` | 0 | corrected source and unchanged ten test names compiled under `/W4 /WX` without a warning |
| FIX1-GREEN-defect | `ctest --test-dir .harness/build -C Debug -R EulerBeam3D.RejectsInvalidGeometryAndProperties --output-on-failure` | 0 | 1/1 passed |
| FIX1-GREEN-evidence | `ctest --test-dir .harness/build -C Debug -R 'EulerBeam3D.(ConstantLineLoadMatchesAllSignedComponents|AnalyticalAxialTorsionAndTwoPlaneBendingRecover)' --output-on-failure` | 0 | 2/2 analytical/convergence hardening tests passed without another production change |
| FIX1-VERIFY-configure | `cmake -S . -B .harness/build -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"` | 0 | exact MSVC x64 Debug tree configured and generated |
| FIX1-VERIFY-build | `cmake --build .harness/build --config Debug` | 0 | full Debug build completed without a new warning |
| FIX1-VERIFY-targeted | `ctest --test-dir .harness/build -C Debug -R EulerBeam3D --output-on-failure` | 0 | exact 10/10 passed |
| FIX1-VERIFY-discovery | `ctest --test-dir .harness/build -C Debug --show-only=json-v1` | 0 | 39 total tests discovered, including the same ten EulerBeam3D names |
| FIX1-VERIFY-full | `ctest --test-dir .harness/build -C Debug --output-on-failure` | 0 | 39/39 passed |
| FIX1-VERIFY-scans | fail-on-match numerical invariant, dependency, scope, exact-test-count, reference, phase-index, and diff/whitespace scans | 0 | derived rigidity/coefficient and fail-closed checks present; tests 10; leaks 0; reference and phase index unchanged; diff clean |
<a id="implementation-report--step-17-review-fix-round-1--atomic-test-evidence"></a>
#### Step 17 Review Fix Round 1 — atomic test evidence
- classification: test-evidence reliability hardening; no production defect
was observed or corrected.
- baseline_GREEN: before changing the test,
`ctest --test-dir .harness/build -C Debug -R ParallelFor --output-on-failure`
exited 0 with the existing production adapter passing 3/3. Because the
review changes only how a test observes duplicate callbacks, no
implementation-owned RED was expected or manufactured.
- reliability_issue: the prior `std::vector` scalar writes were race-free only
if the exact-once contract was already true. A duplicate concurrent callback
for one index could write the same non-atomic scalar concurrently, making the
negative case undefined instead of a deterministic test failure.
- correction: T17-PFOR-001 now uses an explicitly initialized atomic zero-count
counter and explicitly initialized per-index atomic visit counters.
T17-PFOR-002 uses explicitly initialized atomic serial/TBB output slots plus
per-index atomic visit counters. All callback increments use
`fetch_add(1, memory_order_relaxed)` and post-execution assertions require
every count to equal one, so duplicate same-index callbacks are observed
without a data race. Output stores/loads are relaxed atomics because only
per-slot observation is required after the blocking adapter returns.
- scope: only `tests/unit/assembly/parallel_for_test.cpp`, this cumulative
Step 17 section, and the ignored `task-17-report.md` changed. Production,
CMake, the phase index, upstream contracts, and reference artifacts were not
modified in this review round; the exact three test names remain unchanged.
| stage | exact command | exit_code | observed_result |
| --- | --- | ---: | --- |
| REVIEW1-baseline-GREEN | `ctest --test-dir .harness/build -C Debug -R ParallelFor --output-on-failure` | 0 | existing correct production passed 3/3 before test hardening; no implementation RED expected |
| REVIEW1-VERIFY-build | `cmake --build .harness/build --config Debug` | 0 | C++17 atomic test evidence compiled and linked under MSVC `/W4 /WX` without a warning |
| REVIEW1-VERIFY-targeted | `ctest --test-dir .harness/build -C Debug -R ParallelFor --output-on-failure` | 0 | hardened exact three ParallelFor tests passed 3/3 |
| REVIEW1-VERIFY-discovery | `ctest --test-dir .harness/build -C Debug --show-only=json-v1` | 0 | 42 tests discovered, including the unchanged three exact ParallelFor names |
| REVIEW1-VERIFY-full | `ctest --test-dir .harness/build -C Debug --output-on-failure` | 0 | full accumulated suite passed 42/42 |
| REVIEW1-VERIFY-scans | public TBB leak, production scope, atomic reliability, reference, and diff/whitespace scans | 0 | public leaks 0; forbidden production scope 0; atomic vectors 5; relaxed duplicate counters 4; legacy non-atomic visit/output paths 0; reference unchanged; diff clean |
<a id="implementation-report--step-18-review-fix-round-1--evidence-artifact-scope"></a>
#### Step 18 Review Fix Round 1 — evidence artifact scope
- classification: evidence/artifact-integrity correction only. Production,
public headers, tests, CMake, upstream contracts, and phase-index content
were not changed by this review fix.
- reproduced_finding: before correction,
`git diff --check 59da6c6..HEAD` exited 2 with
191 findings (382 output lines), all for trailing whitespace in tracked file
`.harness/step18-discovery.json`. The cumulative `changed_files` list omitted
that tracked file while listing ignored scratch file
`.superpowers/sdd/linear-static-3d-euler-beam/task-18-report.md` as though it
were tracked.
- correction: deleted the generated discovery JSON with `apply_patch` and
reconciled `changed_files` to the exact 10-file combined tracked scope. The
ignored scratch report remains supplementary evidence and is not listed as
a tracked Step 18 file.
- phase_index_guard: `git hash-object
phases/linear-static-3d-euler-beam/index.json` was
`6808d3a8101f656e978b7e00df6cf1a4ad5f1711` before and after correction.
| stage | exact command | exit_code | observed_result |
| --- | --- | ---: | --- |
| REVIEW1-reproduce | `git diff --check 59da6c6..HEAD` | 2 | 191 findings (382 output lines), all for trailing whitespace, were isolated to the accidental tracked discovery JSON |
| REVIEW1-scope | `git diff --name-status 59da6c6` | 0 | Combined base-to-worktree scope contains exactly 10 tracked Step 18 files; discovery JSON and ignored scratch report are absent |
| REVIEW1-diff | `git diff --check 59da6c6` | 0 | Combined committed plus worktree Step 18 range is whitespace-clean after artifact deletion |
| REVIEW1-configure | `cmake -S . -B .harness/build -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"` | 0 | Exact MSVC x64 dependency-resolved configuration completed |
| REVIEW1-build | `cmake --build .harness/build --config Debug` | 0 | Full Debug build completed under `/W4 /WX` without a new warning |
| REVIEW1-targeted | `ctest --test-dir .harness/build -C Debug -R SparseAssembly --output-on-failure` | 0 | Exact SparseAssembly suite passed 5/5 |
| REVIEW1-full | `ctest --test-dir .harness/build -C Debug --output-on-failure` | 0 | Full accumulated suite passed 47/47 |
| REVIEW1-reference | `git diff --exit-code 59da6c6 -- reference/`; `git status --short -- reference/` | 0 | Approved reference artifacts remain unchanged and reference status is empty |
<a id="implementation-report--step-20-review-fix-round-1--fully-constrained-lifecycle-and-normalized-validation"></a>
#### Step 20 Review Fix Round 1 — fully constrained lifecycle and normalized validation
- review_classification: Important integration/correctness fixes. Step 19
intentionally produces a valid `0x0 Kff` for an all-constrained model, so
rejecting that matrix contradicted the accumulated solver workflow.
- test_scope: the existing six `MklPardisoSolver` test names were retained.
The invalid-state test now covers trivial factorize/solve followed by a
nonempty refactor, unchanged caller output on failed solves, and a
small-scale asymmetric matrix. Numerical helpers now divide by the actual
nonzero RHS/expected norm and fail closed for zero or nonfinite norms.
| stage | exact command | exit_code | observed_result |
| --- | --- | ---: | --- |
| RED-zero-equation | `cmake --build .harness/build --config Debug; ctest --test-dir .harness/build -C Debug --output-on-failure -R MklPardisoSolver` | 1 | Build passed; 5/6 tests passed and `RejectsInvalidCsrStateAndDimensions` failed because valid `0x0 Kff` factorization returned failure |
| TEST-hardening | same targeted command after replacing unit-floor norm helpers | 1 | The same zero-equation production defect remained the only failure; no artificial RED was claimed for already-correct numerical results |
| GREEN-zero-equation | same targeted command after the minimum production change | 0 | 6/6 passed; empty factorize/solve avoids PARDISO and a following nonempty refactor solves correctly |
| RED-scaled-symmetry | `cmake --build .harness/build --config Debug; ctest --test-dir .harness/build -C Debug --output-on-failure -R MklPardisoSolver` | 1 | Build passed; 5/6 tests passed and the existing invalid-state test showed that a scaled asymmetric matrix was incorrectly accepted |
| GREEN-scaled-symmetry | same targeted command after the minimum production change | 0 | 6/6 passed with symmetry normalized by the matrix's actual maximum absolute entry and no unit-size floor |
| VERIFY-configure | `cmake -S . -B .harness/build -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"` | 0 | Explicit MSVC x64 dependencies configured and generated successfully |
| VERIFY-build/targeted | `cmake --build .harness/build --config Debug; ctest --test-dir .harness/build -C Debug --output-on-failure -R MklPardisoSolver` | 0 | Debug build completed without a new warning; exact Step 20 suite passed 6/6 |
| VERIFY-discovery/full | `ctest --test-dir .harness/build -C Debug --show-only=json-v1; ctest --test-dir .harness/build -C Debug --output-on-failure` | 0 | 57 tests discovered and 57/57 passed |
| VERIFY-contract | backend API leak scan, exact-test count, forbidden fallback/regularization scan, `git diff --check`, and reference diff/status | 0 | backend API leaks 0; exact tests 6; forbidden implementation matches 0; whitespace clean; `reference/` unchanged |
- production_fix: a successful zero-equation factorization is represented as
trivial private state without allocating or calling PARDISO; empty solve
succeeds only after that observable factorization. The ordinary `release()`
path safely clears this state before later refactorization or destruction.
- production_fix: symmetry requires every reverse structural pair and compares
`abs(aij-aji)` to `1e-12 * max(abs(A))`. An exactly zero matrix uses an exact
zero difference check; SparseMatrix validation remains responsible for
rejecting nonfinite values.
- failure_atomicity: solve-before-factorize, dimension mismatch, and nonfinite
RHS failures are asserted to leave the caller's solution values unchanged;
successful backend output is still copied from a private candidate only
after phase 33 and finite-result validation.
- evidence_hygiene: two intermediate symmetry RED attempts were discarded
because a concurrent clean build locked MSBuild files. The uncontended RED
above reproduced the production defect deterministically and is the recorded
evidence.
- phase_index: intentionally unchanged during this review fix; hash
`2cfb6ee5e0c49fbf6b06d27cb33ec9ac2c34dbc4`.
- supersession: this review section supersedes the original Step 20 statements
that the factorized CSR must be nonempty or that empty input is rejected.
- concerns: none; the transient build contention was resolved before recorded
RED/GREEN/VERIFY runs and no critical or upstream blocker remains.
<a id="implementation-report--step-22-review-fix-round-1--full-space-free-residual-visibility"></a>
#### Step 22 Review Fix Round 1 — full-space free-residual visibility
- review_trigger: the approved I/O contract requires Reaction at every node
and component, including the accepted free-DOF residual; the AnalysisState
storage comment likewise makes reaction a full-index residual view.
- RED-test: `cmake --build .harness/build --config Debug --target fesa_tests;
ctest --test-dir .harness/build -C Debug -R
'^ResultRecovery.EnforcesNormalizedFreeResidual$' --output-on-failure`
built successfully and exited 1 in CTest. The accepted below-tolerance free
residual was `-1.000000082740371e-09`, while its reaction entry was `0`.
- production_fix: the private reaction candidate is now a full copy of
`residual=K*d-F`. Constrained entries remain the physical reactions, free
entries retain residual evidence, and element end actions are still never
summed into reaction.
- GREEN-focused: the same focused build/test command exited 0 and passed 1/1
after the minimum production change.
- VERIFY-build: `cmake --build .harness/build --config Debug` exited 0 under
MSVC x64 Debug with no new FESA warning.
- VERIFY-targeted: `ctest --test-dir .harness/build -C Debug -R
ResultRecovery --output-on-failure` exited 0 and passed the unchanged exact
six names 6/6.
- VERIFY-discovery-full: `ctest --test-dir .harness/build -C Debug
--show-only=json-v1` discovered 68 tests, exactly six ResultRecovery tests;
full `ctest --test-dir .harness/build -C Debug --output-on-failure` exited 0
and passed 68/68.
- failure_atomicity: the existing tolerance-failure branch in
`ResultRecovery.EnforcesNormalizedFreeResidual` still proves prior internal,
residual, reaction, and endpoint state remains unchanged on failure.
- supersession: this review section records the historical pre-fix finding
that implementation and report originally kept only constrained residual
entries. The final Step 22 contract above now states that reaction is the
full residual dataset; only constrained entries are physical reactions.
- phase_index: the review-fix worker intentionally left phase metadata
unchanged. After independent root verification, finalization preserved exact
`started_at=2026-08-09T20:42:15+0900`, added
`completed_at=2026-08-09T21:14:47+0900`, and updated the summary to state
the corrected full-residual reaction contract.
- evidence_hygiene: an initial parallel VERIFY/audit wrapper terminated before
product commands because its PowerShell count expression was malformed. It
is excluded from TDD and product VERIFY evidence; the recorded evidence is
the subsequent uncontended serial build, targeted, discovery, full sequence
followed by a separate successful audit command.
- concerns: none; no upstream-contract conflict or critical blocker remains.
<a id="implementation-report--step-24-review-fix-round-1--option-token-output-rejection"></a>
#### Step 24 Review Fix Round 1 — option-token output rejection
- review_trigger: the approved CLI contract classifies repeated `--output`
and every unknown option as usage error exit 2. The original three-argument
parser treated the value position as an arbitrary nonempty path, so an
option token could advance into input analysis instead.
- RED-repeated-option: after adding
`{missingInput,"--output","--output"}` to the existing exact
`LinearStaticCli.ReturnsEveryExactExitCodeAndOrderedDiagnostic` test,
`cmake --build .harness/build --config Debug --target
fesa_integration_tests` exited 0 and the focused CTest exited 1. Actual exit
was 3 and stderr contained no `cli-usage`, rather than expected exit 2.
- GREEN-repeated-option: rejecting the literal repeated token made the same
focused test pass 1/1.
- RED-unknown-option: the reviewer then identified the general unknown-option
case. Adding `{missingInput,"--output","--bogus"}` before broadening the
production condition again produced build exit 0 and focused CTest exit 1;
actual exit was 3 with no `cli-usage`.
- production_fix: explicit output form now requires a nonempty third argument
that does not begin with `-`. Both a repeated known option and an unknown
option token are rejected before any input or output access, while ordinary
output paths retain the approved behavior.
- GREEN-focused: rebuilding `fesa_integration_tests` exited 0 under `/W4 /WX`;
the unchanged exact focused test passed 1/1 with both option cases pinned.
- independent_review: Critical 0, unresolved Important 0. The reviewer reran
exact Step 24 10/10, discovery 83, full 83/83, comparison 176 rows/16
metrics passed, and reference diff/status clean.
- remaining_minor: the test-only comparator independently pins float64 result
file types but relies on the Step 23 writer self-check/full-suite schema test
for exact uint64 endianness and every compound member file dtype/UTF-8. This
is defense-in-depth negative coverage, not a reproducible approved-pipeline
false pass.
- remaining_minor: the inherited diagnostic sorter is not a literal
implementation of future multi-source declaration/internal-ID ordering, but
no V0 single-input CLI misordering is reproducible.
- remaining_minor: the Step 23 `libmmd.dll` guard remains unconditional across
alternate HDF5 targets; it is correct for the approved shared-HDF5
environment and is an external portability limitation.