# Dispensing nozzle

This package compares three nominal nozzles with an axisymmetric creeping-flow finite-element model. It contains the solver, CAD generator, STEP/STL solids, calculated fields, CSV results and an offline HTML report. Inputs are an explicit reference case, not measurements from a client or physical pump.

## Run

Use Python 3.12 in a virtual environment. CadQuery requires a supported 64-bit desktop platform.

```sh
python -m venv .venv
# Activate .venv using your platform's activation command.
python -m pip install -r requirements.txt
python run.py
python test_flow.py
# Re-run only the additional virtual bench:
python virtual_bench.py
```

The run includes the original comparison and the additional virtual bench. Runtime depends on CAD export and sparse factorization. It overwrites generated files under `outputs/`, `report.html`, `verification.json` and `delivery.json`. Open `report.html` in a browser. No server or internet connection is required after installing dependencies.

## Inputs and units

Edit `inputs.json`. Geometry and velocity use mm and mm/s; flow uses mm3/s, pressure uses Pa, viscosity uses Pa s, and density uses kg/m3. The Reynolds conversion therefore includes 1e-6. The model is linear in flow and viscosity; the operating sweep scales the solved reference system. A regression test independently solves two operating points.

`flow.py` uses Taylor-Hood P2/P1 elements on the meridian. The cylindrical weak form includes hoop strain and radial divergence. Equal developed velocity profiles prescribe flow at both ends. Pressure is pinned once to remove its arbitrary constant. Reported pressure drop is area-averaged static pressure at the ends, with no external fittings or free-jet contribution. Sectional flux checks sample the solved velocity and include quadrature/interpolation error.

## Files

- `model.py`: editable CadQuery source; nozzle solids and fluid passages.
- `outputs/cad/`: three nozzle STEP/STL models and three fluid STEP volumes.
- `outputs/*-field.csv`: nodal coordinates, velocity and pressure.
- `outputs/*-solution.npz`: full mesh and solution DOFs for further postprocessing. Pressure in NPZ retains the arbitrary solver gauge; CSV pressure is relative to mean outlet pressure.
- `outputs/mesh-study.csv`: three mesh levels per candidate.
- `outputs/operating-sweep.csv`: declared flow/viscosity combinations and Reynolds numbers.
- `outputs/section.svg`: selected nominal bore section; not a released production drawing.
- `verification.json`: executed checks and thresholds.
- `virtual_bench.py` and `virtual-bench-inputs.json`: completed synthetic pressure, tolerance and dosing bench.
- `completion.json`: 14 expected-outcome verification checks, source hashes and evidence type.
- `outputs/virtual-bench/report.html`: methods, acceptance decisions and linked raw data.
- `bench-test.md`: physical procedure paired with the completed virtual run-through.

The selected reference bore passes the numerical pressure and volume limits. Suitability for a real liquid, pump, material or cleaning process still needs physical validation. All dimensions are nominal; sealing, threads, tolerances and material selection are deliberately outside this fluid study.

## Completed virtual bench

`python run.py` now also runs `virtual_bench.py`. The supplemental report contains three new FEM tolerance-corner solves, 243 geometry/property/flow combinations, 30 synthetic pressure/flow observations, and four pressure-pulse/shutoff cases. All observations are explicitly generated from declared inputs. They do not represent bench measurements.

The additional upstream tube and bounded meniscus head expose a real scope difference from the nozzle-only result. The upper combined case reaches 7,323.08 Pa, above the unchanged 6,500 Pa budget. The computed conservative flow bound is 26.4 mm3/s across the declared tolerance and viscosity range. This is an operating-envelope result, not a new pump rating.

The de-aired fixed-pressure pulse delivers within the 100 +/- 1 mm3 reference target. A 250 mm3 trapped-air compliance case produces 7.540 mm3 of calculated tail in two seconds. Raising viscosity from 0.75 to 1 Pa s at the same pressure and pulse gives about 75 mm3, so a fixed pulse cannot guarantee dose across that range. These adverse outcomes are retained in `acceptance-matrix.csv`; verification passes when the model detects the expected failure, not when every design case meets its target.

The report derives the resistance/compliance equations, explains the synthetic instrument fit, checks conservation and limiting cases, and records all input values. The physical protocol remains available for a later comparison; this delivered package completes the computational run-through without implying fabricated hardware validation.

### Selected operating decision

The selected geometry remains `outputs/cad/wide-inlet.step`. No CAD revision is implied by the new study. For the combined system envelope, command no more than 26.4 mm3/s at 0.5 to 1.0 Pa s with the declared dimensional, feed-tube and meniscus bounds. Worst calculated pressure at that flow is 6,478.60 Pa. The earlier 30 mm3/s endpoint is rejected once those added system effects are included. The separate fixed-pressure 100 mm3 pulse is qualified only for its stated nominal de-aired case; a changed viscosity or gas compliance needs a recalculated regulator setting or pulse duration. The machine-readable decision is `outputs/virtual-bench/selected-operating-envelope.json`.
