# Sampling chamber

This package compares three straight annular sampling chambers around a fixed cylindrical probe. It runs an axisymmetric Stokes flow model and a conservative two-dimensional passive-tracer transport model. The files include source, inputs, executed checks, raw time series, a tracer animation, and nominal STEP/STL CAD.

## Run

Use Python 3.12 in a virtual environment on a 64-bit platform supported by CadQuery.

```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_transport.py
# Re-run only the additional virtual bench:
python virtual_bench.py
```

Open `report.html` after the run. The run includes the original comparison and the additional virtual bench; runtime depends on sparse factorization and CAD export. It overwrites generated files in `outputs/`, `report.html`, `verification.json` and `delivery.json`. The report and animation work offline; no service or account is required.

## Reference inputs

- Probe radius 2 mm, length 20 mm. The probe occupies the complete chamber length.
- Outer liquid radii 2.5, 3 and 4 mm; the nominal CAD adds a 2 mm wall.
- Flow 5 mm3/s; density 1000 kg/m3; dynamic viscosity 0.01 Pa s.
- Molecular tracer diffusivity 0.0005 mm2/s.
- Initial old-sample concentration 1; incoming fluid concentration 0.
- Minimum reference radial clearance 0.5 mm; reference pressure budget 10 Pa.

These are declared numerical inputs. They do not describe an existing commercial sensor or a physically tested fluid.

## Methods

`flow.py` assembles a Taylor-Hood P2/P1 axisymmetric Stokes problem with axial, radial and circumferential strain. Developed annular profiles prescribe inlet and outlet flow; both cylinder walls are no-slip. An exact annular pressure solution provides an independent benchmark.

`transport.py` integrates the computed axial velocity into ring face fluxes. A recorded normalization makes their sum exactly the requested flow; the verification limits this correction. It solves mass-form finite volumes with first-order upwind axial advection, centered axial/radial diffusion, and backward Euler. Both walls and both end planes have zero diffusive tracer flux. The inlet supplies only clean advective flow. This avoids silently including unmeasured diffusive tracer loss through an inlet reservoir.

The two spatial dimensions are axial and radial; there is no angular variation. The model is specifically a uniform annulus, not a chamber with an expansion, bypass or recirculation pocket.

## Results and metrics

- Whole-chamber concentration is volume-weighted.
- Probe concentration averages z=8 to 12 mm and r=2 to 2.2 mm. Partial-cell volume weights preserve the declared measurement region across grids.
- Outlet concentration is weighted by outgoing ring flow.
- Each t99 is the first linearly interpolated crossing below an old-sample fraction of 0.01.
- The solver accounts for tracer mass remaining plus integrated outflow at every time step.

Three spatial grids (40x12, 80x24 and 160x48) are compared at 0.25 s. The finest grid is then rerun at 0.125 s. First-order transport still introduces numerical smearing; the recorded changes show sensitivity for this input set, not a proof of exactness for other geometries.

## Files

- `inputs.json`: editable dimensions, fluid properties and numerical settings.
- `flow.py`, `transport.py`: independent flow and transport solvers.
- `model.py`: CadQuery body, probe and fluid-volume exports.
- `outputs/cad/`: all three assemblies, body STEP/STL models, fluid STEP volumes and probe STEP.
- `outputs/*-trace.csv`: every timestep's three concentrations, outflow and mass balance.
- `outputs/*-fields.npz`: spatial coordinates, ring flow and concentration snapshots.
- `outputs/refinement.csv`: spatial and timestep sensitivity.
- `outputs/flow-benchmarks.csv`: FEM pressure versus exact annular solution.
- `outputs/tracer-washout.gif`: animation of calculated concentration.
- `outputs/section.svg`: nominal geometry and probe-region definition.
- `verification.json`: executed checks and thresholds.
- `virtual_bench.py` and `virtual-bench-inputs.json`: completed coupled wall/inlet/sensor and tolerance studies.
- `completion.json`: 29 expected-outcome verification checks and source hashes.
- `outputs/virtual-bench/report.html`: synthetic flushing results, acceptance matrix and methods.
- `flush-test.md`: physical comparison protocol paired with the executed virtual bench.

The CAD omits seals, mounts, ports, tolerances and material selection. The original fluid model excludes asymmetric fittings, trapped gas, adsorption and sensor chemistry. The supplemental virtual bench adds a declared linear wall-retention model, inlet mixing and first-order sensor lag. A real sensor's response can therefore differ from these fluid-replacement results.

## Completed virtual flushing bench

`python run.py` now also runs `virtual_bench.py`. The supplement executes 162 dimensional/flow/viscosity cases, six coupled transport/measurement cases, three slow-wall refinement runs and 20 synthetic pressure readings. `completion.json` separates successful verification from cases that fail a design criterion.

A 0.5 mm nominal radial gap cannot retain a 0.5 mm minimum after independent +/-0.015 mm chamber-radius and +/-0.010 mm probe-radius tolerances. The virtual dimensional study therefore supplies an additional 2.525 mm nominal chamber-radius CAD assembly. Its worst declared gap is 0.500 mm and worst hydraulic pressure is 8.174 Pa, below the original 10 Pa budget. The original three comparison geometries and results remain intact. The revised assembly is a reference tolerance allowance, not a manufactured or released part.

The response cases retain the original 2.5 mm chamber radius to isolate sensor and wall effects. A 30 s sensor time constant gives an indicated t99 of 156.31 s. Adding the declared slow wall capacity and 20 mm3 mixed inlet volume gives 345.88 s. Both fail the explicit 90 s virtual-bench response criterion, although the passive-fluid result is much faster. Fluid plus wall tracer inventory and inlet/outlet transfers balance in every run. The slow-wall case is also re-run at finer grid and time step.

Wall capacity and transfer time are hypothetical sensitivity parameters, not measurements or material-specific adsorption coefficients. The report derives the coupling, distinguishes sensor signal from fluid replacement, and includes independent limiting-case and exchange benchmarks. The physical protocol remains useful for future comparison, but every computational case described above has been executed and its raw traces are included.

### Selected design and operating decision

The final reference geometry is the tolerance-allowance assembly at `outputs/cad/radius-2.525mm-assembly.step`, with a 4 mm nominal probe diameter and the declared independent radial tolerances. The original 2.5 mm model remains as a baseline comparison.

For the explicit slow-retention virtual fixture, the selected operating wait is 600 s at 4.5 mm3/s. Four geometry-tolerance corners and a finer worst-corner run verify old-sample fractions below 0.01 in the fluid, outlet, sensor indication and total fluid-plus-wall inventory at that time. The qualification uses 0.1 mm wall capacity length, 120 s wall exchange, a 20 mm3 mixed inlet volume, 30 s sensor lag and 0.0005 mm2/s diffusivity. These are declared values, not inferred material or sensor properties. `outputs/virtual-bench/selected-operating-envelope.json` records the exact selection and measured-from-simulation residual fraction.

The earlier 90 s response objective is rejected for this slow-retention condition. The chosen 600 s wait is the documented operating decision; it is not presented as meeting a 90 s specification.
