111 lines
3.6 KiB
Markdown
111 lines
3.6 KiB
Markdown
# Step 7: local-stiffness-kernel
|
|
|
|
## 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`
|
|
|
|
Also read any files created by previous steps in this phase.
|
|
|
|
## Task
|
|
|
|
Use TDD to create the local 12x12 stiffness kernel for the 3D Euler-Bernoulli beam.
|
|
|
|
Create:
|
|
|
|
- `/src/fesa/elements/euler_beam_3d.hpp`
|
|
- `/src/fesa/elements/euler_beam_3d.cpp`
|
|
- `/tests/unit/euler_beam_3d_local_stiffness_test.cpp`
|
|
|
|
Required API:
|
|
|
|
```cpp
|
|
namespace fesa::elements {
|
|
|
|
using Vector12 = std::array<double, 12>;
|
|
using Matrix12 = std::array<double, 144>;
|
|
|
|
struct EulerBeam3DSection {
|
|
double young_modulus;
|
|
double shear_modulus;
|
|
double area;
|
|
double torsion_constant;
|
|
double second_moment_y;
|
|
double second_moment_z;
|
|
};
|
|
|
|
Matrix12 euler_beam_3d_local_stiffness(double length, const EulerBeam3DSection& section);
|
|
Vector12 euler_beam_3d_local_end_forces(double length,
|
|
const EulerBeam3DSection& section,
|
|
const Vector12& local_displacements);
|
|
|
|
} // namespace fesa::elements
|
|
```
|
|
|
|
Implementation rules:
|
|
|
|
- Matrix storage is row-major: index `(row, col)` is `row * 12 + col`.
|
|
- Validate `length > 0` and all section constants are positive; throw `std::invalid_argument` otherwise.
|
|
- Use only C++17 standard library.
|
|
- Do not introduce an external linear algebra dependency.
|
|
- Do not edit CMake files; source and test globs should pick up new files.
|
|
|
|
## Tests To Write First
|
|
|
|
Create `/tests/unit/euler_beam_3d_local_stiffness_test.cpp` before production code.
|
|
|
|
Test behavior:
|
|
|
|
- For `L = 2.0`, `E = 210.0`, `G = 80.0`, `A = 3.0`, `J = 4.0`, `Iy = 5.0`, `Iz = 6.0`, verify representative matrix entries:
|
|
- axial: `K(0,0) = EA/L`, `K(0,6) = -EA/L`, `K(6,6) = EA/L`
|
|
- torsion: `K(3,3) = GJ/L`, `K(3,9) = -GJ/L`, `K(9,9) = GJ/L`
|
|
- local `x-y` bending uses `EIz`: `K(1,1) = 12*E*Iz/L^3`, `K(1,5) = 6*E*Iz/L^2`, `K(5,5) = 4*E*Iz/L`
|
|
- local `x-z` bending uses `EIy`: `K(2,2) = 12*E*Iy/L^3`, `K(2,4) = -6*E*Iy/L^2`, `K(4,4) = 4*E*Iy/L`
|
|
- Verify all entries are symmetric within `1.0e-10`.
|
|
- Verify `euler_beam_3d_local_end_forces` returns `K * u` for a displacement vector with at least three nonzero components.
|
|
- Verify invalid length and nonpositive section constants throw `std::invalid_argument`.
|
|
|
|
RED command:
|
|
|
|
```powershell
|
|
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R euler_beam_3d_local_stiffness_test
|
|
```
|
|
|
|
Expected RED: test executable missing or compile failure because the header/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_local_stiffness_test
|
|
```
|
|
|
|
## Acceptance Criteria
|
|
|
|
```powershell
|
|
ctest --test-dir build/msvc-debug --output-on-failure -C Debug -R euler_beam_3d_local_stiffness_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 no parser, assembly, or results writer code was changed.
|
|
3. Update `phases/euler-beam-3d/index.json` step 7:
|
|
- success: `"status": "completed"`, `"summary": "local 3D Euler beam stiffness and local end-force kernel added"`
|
|
- failure after retries: `"status": "error"`, `"error_message": "<specific error>"`
|
|
- blocked: `"status": "blocked"`, `"blocked_reason": "<specific reason>"`
|
|
|
|
## Forbidden
|
|
|
|
- Do not add shear deformation or Timoshenko terms.
|
|
- Do not modify reference artifacts.
|