# Verification Record

Date: 2026-09-26. Application version: 2.0.0.

## Evidence and precedence

Primary evidence is the user-supplied 21-page `Penstock Anchor Block 3D.pdf`, visually inspected alongside extracted text. Its corresponding official source is [JICA 11259108_03.pdf](https://openjicareport.jica.go.jp/pdf/11259108_03.pdf).

The written component equations govern the force calculation. Published worked loads are used separately to test the stability calculation. This distinction is essential: matching a table containing a sign inconsistency is not proof of following its equations.

All page numbers below refer to the PDF page index starting at 1, not the handwritten/printed report page labels.

## Formula Map

| Quantity                                    | Implementation                                        | Source                                |
| ------------------------------------------- | ----------------------------------------------------- | ------------------------------------- |
| Pipe area, water and thin-wall steel weight | `A = pi D^2/4`, `w = A`, `s = pi D t rs`              | p.4                                   |
| W, W'                                       | `(w+s) l cos(delta)/2` and tabulated x/y/z components | p.4                                   |
| P1, P1'                                     | `s L sin(delta)` and tabulated components             | pp.4-5                                |
| P2, P2'                                     | `2 f Q^2 L/(g pi D^3)` and tabulated components       | p.5                                   |
| Pv, Ph                                      | `2 v^2 A sin(angle/2)/g` and tabulated components     | p.5                                   |
| P3, P3'                                     | `He pi D t` and tabulated components                  | p.5                                   |
| Prv, Prh                                    | `2 H A sin(angle/2)` and tabulated components         | pp.5-6                                |
| F1, F1'                                     | `c (w+s) (L-l/2) cos(delta)`                          | p.6                                   |
| F2, F2'                                     | `fe pi (D+2t)`                                        | p.6                                   |
| F, F'                                       | F1+F2 with source component signs                     | p.6                                   |
| WA, FWA, Fp                                 | `wc V`, `Kh WA`, `Kh ((w+s)l/2+(w+s')l'/2)`           | p.6                                   |
| Thermal signs / seismic directions          | 4 combinations, X-Z/Y-Z, +/- earthquake               | pp.8-9                                |
| Moments                                     | `sum(V arm) - sum(H height)`                          | pp.14-21                              |
| Eccentricity                                | `abs(B/2 - sumM/sumV) < B/6`                          | p.8                                   |
| Sliding                                     | `N lambda/abs(sumH) > 2`, provided `N = -sumV > 0`    | p.8, compression domain made explicit |
| Bearing                                     | `N/A (1 +/- 6e/B) < qa`, full contact only            | p.8                                   |

The force scalar can be signed for a signed slope/vertical bend. The resultant magnitude uses `hypot(x,y,z)`, never a sum of unrelated scalar magnitudes. Upward z is positive. Separate source-plane horizontal reactions are used, not a combined horizontal norm.

## Adopted Geometry

The old application treated the plan footprint in Figure 2.1.3 as an X-Z profile. It also replaced contact area with the product of the two effective base lengths. Those are different quantities in this example.

The presets explicitly adopt the values used by the source's calculation sheets:

| Property                 |                   Value |
| ------------------------ | ----------------------: |
| Concrete weight WA       |              227.302 tf |
| Net volume V at wc = 2.3 |        227.302 / 2.3 m3 |
| Foundation area          |               23.221 m2 |
| Effective Bx / By        |         5.901 / 4.719 m |
| Concrete x / y / z arms  | 2.680 / 2.275 / 2.500 m |
| Pipe x / y / z arms      | 3.000 / 2.000 / 3.000 m |
| Block height             |                 5.000 m |

Independent evaluation of the p.9 volume expression gives WA = 227.3019341820891 tf, consistent with the adopted rounded weight. The coordinate worksheet footprint has area 23.2211375 m2 and centroid x = 2.6800119501 m. Its displayed y coordinate uses the entered coordinate origin; it is **not** a substitute for the source's adopted transverse moment arm. No automatic solid reconstruction or pipe-void centroid correction is claimed.

For a different block, adopted properties must come from a geometry calculation appropriate to that block. A schematic cuboid envelope does not establish volume or physical pipe containment along the full alignment. The input validation checks finite values, prescribed ranges, the friction-length domain, arm bounds, and vertical outside-diameter fit at the bend; it cannot establish physical feasibility of an arbitrary solid.

## Source Discrepancies

1. **Downstream P2' y sign, block 2-3.** PDF p.5 specifies `-P2' cos(delta') sin(theta)`. Table 2.1.1 on p.10 displays `+0.042 tf`. The engine computes `-0.0415398961 tf`. Its constant Py is `29.0685746595 tf`, versus the printed `29.153 tf`. The difference is dominated by the sign, with a small momentum/rounding difference. Full-engine block 2-3 Y-Z results intentionally do not exactly match the printed table.
2. **Gravity and intermediate precision.** The app explicitly uses g = 9.81 m/s2. Its Ph is 1.5718435753 tf; the table prints 1.573 tf, consistent with g near 9.8. The exact source arithmetic convention is not specified here. No attempt is made to tune g or round intermediates to force table agreement.
3. **Scalar totals.** Source scalar totals such as 41.327 are not the Euclidean magnitude of P's three components. The app labels signed scalar force values separately and reports actual resultant magnitudes.
4. **Generic seismic illustration.** The p.9 example uses shell weight and lengths different from Table 2.1.1's two blocks. The engine uses actual case inputs, giving Fp = 1.9329428859 tf for 1-3 and 4.8651645369 tf for 2-3, consistent with the subsequent case sheets.
5. **Displayed rounding.** The printed Bx/6 limit of 0.984 differs from the app's nearest display of the exact 5.901/6 = 0.9835, depending on rounding convention. Acceptance uses the exact value. Printed force sums/moments also contain last-place differences; tests use declared absolute tolerances.

OCR alone initially misread some numerals. Visual inspection and direct arithmetic were used to avoid treating those OCR errors as source errors.

## Regression Coverage

`npm test` currently runs 25 test groups. Important coverage:

- **32 published stability cases:** manually transcribed loads and expected e, Fs, qmax from PDF pp.10 and 13-21. This isolates the equilibrium/stability engine from source force-table inconsistencies. Absolute tolerances: e <= 0.0006 m; Fs <= 0.012; qmax <= 0.012 tf/m2.
- **16 block 1-3 end-to-end cases:** calculated forces, adopted geometry, and stability results compared with the printed table using the same declared tolerances.
- **All block 1-3 force components:** absolute tolerance 0.002 tf, covering the g/intermediate-rounding difference.
- **Block 2-3 negative P2' y:** checks the written sign and records the deliberate divergence from the printed Py total.
- Signed vertical bends, Q-squared scaling, linear head scaling, zero hydraulic loads, all thermal signs, and true vector magnitudes.
- Independent volume/area changes, zero horizontal demand, zero/negative compression, strict threshold equality, partial contact, resultant outside the base, seismic symmetry, nonfinite and overflow inputs.
- Winding/translation invariant polygon centroids, concave boundaries, self-intersection rejection, versioned import validation, and blocked legacy automatic geometry.

`npm run test:browser` checks offline `file://` startup, all six views at 1440/768/390/320 px, nonblank canvas pixel colors and orbit interaction, invalid inputs, failure states, geometry acknowledgment, polygon errors, local save/reload, escaped project names, JSON roundtrip, malformed and legacy imports, filtering, CSV and 16 detailed report worksheets. Screenshots and the printed report are generated under ignored `test-results/` for visual review.

These checks provide specific evidence; they do not establish universal numerical correctness, applicability to every penstock configuration, or independent professional approval.

## Deliberate Domain Handling

- Positive normal compression is mandatory. Absolute value is not used to turn uplift into frictional capacity.
- With zero horizontal demand and positive normal force, Fs is represented as Infinity and displayed as `Unlimited`, not an arbitrary 999.
- At or beyond the strict acceptance boundaries, the relevant check fails.
- For e > B/6, bearing is unavailable. No unreferenced triangular-contact formula is introduced for the irregular/effective-area model.
- No independent overturning moment-ratio requirement is attributed to JICA; its source criterion is eccentricity.
- Full contact in one plane does not establish full biaxial contact. This implementation intentionally preserves the source's separate-plane method and reports that limitation.

## Not Checked

Simultaneous biaxial bearing, combined horizontal sliding, torsion, transient hydraulic modeling, vertical earthquake, reinforcement, crack/shear resistance, shell/anchor-ring design, groundwater uplift, overburden, passive pressure, and additional operational/empty/test load combinations are outside this implementation. Arbitrary bend geometry and transformations require independent engineering assessment.

## Reproducibility and Maintenance

Engine results feed tables, worksheets, CSV and print output. JSON stores inputs and provenance, never trusted calculated results. Third-party viewer/icon versions are pinned in `package-lock.json`; the generated viewer bundle is included for static deployment. CI runs numeric tests, verifies the generated bundle, and runs browser checks. The historical implementation is available at commit `d8e20e3`.
