# Step 8: global-transform-recovery ## Read These Files First Read the following files before editing: - `/AGENTS.md` - `/docs/ARCHITECTURE.md` - `/docs/ADR.md` - `/docs/formulations/euler-beam-3d-formulation.md` - `/docs/numerical-reviews/euler-beam-3d-review.md` - `/docs/implementation-plans/euler-beam-3d-implementation-plan.md` - `/src/fesa/elements/euler_beam_3d.hpp` - `/src/fesa/elements/euler_beam_3d.cpp` - `/tests/unit/euler_beam_3d_local_stiffness_test.cpp` ## Task Use TDD to add local/global transformation and global end-force recovery to the 3D Euler-Bernoulli beam kernel. Extend the API in `/src/fesa/elements/euler_beam_3d.hpp`: ```cpp using Vector3 = std::array; struct EulerBeam3DGeometry { Vector3 node1; Vector3 node2; Vector3 orientation; }; Matrix12 euler_beam_3d_global_stiffness(const EulerBeam3DGeometry& geometry, const EulerBeam3DSection& section); Vector12 euler_beam_3d_global_end_forces(const EulerBeam3DGeometry& geometry, const EulerBeam3DSection& section, const Vector12& global_displacements); ``` Implementation rules: - local `x` is normalized `node2 - node1` - local `y` is the normalized projection of `orientation` onto the plane normal to local `x` - local `z = x cross y` - use the same 3x3 rotation block for translational and rotational DOFs - compute `K_global = T^T K_local T` - compute global end forces by transforming global displacements to local, recovering local forces, then transforming forces back to global - throw `std::invalid_argument` for zero-length element, zero orientation vector, or orientation parallel to the beam axis ## Tests To Write First Create `/tests/unit/euler_beam_3d_transform_recovery_test.cpp` before production code. Test behavior: - Axis-aligned beam from `(0,0,0)` to `(2,0,0)` with orientation `(0,1,0)` gives global stiffness equal to local stiffness. - A rotated beam preserves stiffness symmetry. - A rigid global translation vector produces near-zero global end forces. - A simple global axial extension on the axis-aligned beam produces equal and opposite axial end forces. - Parallel orientation vector throws `std::invalid_argument`. RED command: ```powershell ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R euler_beam_3d_transform_recovery_test ``` Expected RED: test executable missing or compile failure because the transform API does not exist. Then implement the minimal API. GREEN command: ```powershell ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R euler_beam_3d_transform_recovery_test ``` ## Acceptance Criteria ```powershell ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R "euler_beam_3d_(local_stiffness|transform_recovery)_test" python -m unittest discover -s scripts -p "test_*.py" python scripts/validate_workspace.py ``` ## Verification Notes 1. Confirm RED failed before production code was added. 2. Confirm local stiffness tests still pass. 3. Update `phases/euler-beam-3d/index.json` step 8: - success: `"status": "completed"`, `"summary": "global transform and global end-force recovery added for 3D Euler beam"` - failure after retries: `"status": "error"`, `"error_message": ""` - blocked: `"status": "blocked"`, `"blocked_reason": ""` ## Forbidden - Do not add assembly or solver integration in this step. - Do not modify reference artifacts.