# PetroCalcHub native companion bundle 1.4.0 File-based local calculations. No account, database, listener, cloud compute or automatic upload. Installation needs internet; cases run on your own computer. Keep both the exact downloaded case file and its accepted result file. Case files must be UTF-8 JSON without a byte-order mark. Duplicate keys and nonfinite numbers are rejected by the companion. The original `petrocalc_native.py` runner and its 1.3.0 result contract are unchanged. Reactive/transient cases use the separate 1.4.0 extension runner below. This preserves the exact sources bound to the earlier steady-flow validation records; the bundle version is not a claim that old engines reran. ## Reactive carbonate and transient two-fluid extensions These models are separate local calculations, not coupled reacting CFD or an unrestricted reactive oil/water VLLS solver. Their case/result schema is `petrocalchub.native.extension.case.v1` / `.result.v1`. The same new-path, no-overwrite, exact case-byte SHA-256 rules apply. Each case has generated inputs and native logs in a new `--work` directory. No executable commands, raw PHREEQC programs or OpenFOAM dictionaries are accepted from JSON. ### Closed CO2/water/calcite at 25 C Install the trusted USGS PHREEQC 3.8.6-17100 engine separately from https://www.usgs.gov/software/phreeqc-version-3 . Its official source archive can be built on Linux/macOS with `./configure` and `make`; Windows binaries are also supplied by USGS. No engine binary is redistributed here. The pinned offline chemical-property file `data/phreeqc-3.8.6.dat` is from that release, SHA-256 `59373961d648dfbf68a40744060c1d64f57ecbec98f4f5fb89f3a1b4213ccd10`. This is a thermodynamic property dataset, not a website storage database. Its upstream redistribution notice is included in `data/USGS-NOTICE.txt`; the original unmodified distribution is available from the archive linked in `data/README.md`. No USGS endorsement is implied. ```sh python petrocalc_extensions.py examples/reactive-carbonate.json \ --output carbonate.result.json --work new-carbonate-case \ --phreeqc /path/to/trusted/phreeqc ``` Initially pure water and finite calcite contact an initially dry CO2 gas in a fixed-volume headspace. Water vapour is explicitly included at equilibrium. Only final gas/solution pressures at or below 1.001 atm absolute are accepted by this low-pressure property-screen subset; an input within the allowed bounds is not a promise that its final state passes every acceptance gate. The gas uses PHREEQC's PR coefficients, its R=0.0820597 L atm/(mol K), and the dataset's CO2/H2O binary interaction 0.19. Total gas pressure and CO2 partial pressure are distinct. The entire model is thermostatted at 25 C; no heat duty, caloric or rate prediction is provided. Pressure follows the fixed-volume gas calculation and is applied to the aqueous phase. Inputs: 0.1-10 kg water, 0.1-10 L headspace, 0.001-1 atm initial CO2 and 1e-6-0.1 mol calcite. Aqueous concentrations are mol/kg final solvent water, not mol/L. The pure-water initial ionic H/O contribution is included when checking atom inventories. H2O uses the dataset's matched atomic weights H=1.008 and O=16, hence 18.016 g/mol, not a substituted molecular-weight convention. Accepted results require carbon/calcium balances <1e-8 mol, H/O relative balances and charge/ionic-strength/pH checks <1e-7, and mass-action, calcite complementarity, both gas-solubility and PR gas checks <2e-5. PHREEQC convergence is set to 1e-14, with at most 200 iterations. The browser recomputes these checks from full species activities and amounts. Pressure-corrected log K, solvent mass and water activity are native property outputs. A 0.002 log-unit screen compares exported constants with their pinned 25 C analytic references, allowing the native sub-atmospheric pressure corrections. A separate rounded water-property activity-coefficient screen uses A=0.5100, B=0.3286 and the dataset's ion sizes/Davies/neutral rules, with 2e-4 log-unit tolerance. These screens do not independently reproduce the entire PHREEQC property package. The 60-digit allocation reconstruction holds native log K/activity coefficients/water activity fixed, and independently solves species, phase amounts, solvent mass, pressure and H/C/Ca constraints. It is algebraic verification, not measured-fluid validation or a global reactive phase-stability proof. The native engine passed its 32 upstream examples. Nine local cases cover initial CO2 pressure, complete calcite exhaustion and extensive scaling. Records are in `benchmarks/reactive-validation.json`. There is no brine, hydrocarbon liquid, arbitrary redox/mineral network, solid solution or kinetics. Other numerical/conditioning failures produce logs without accepted results. ### Transient immiscible two-fluid VOF Use the same trusted Foundation OpenFOAM 14 Linux installation as the steady runner. No OpenCFD substitution, imported script, arbitrary mesh or custom runtime-compiled code is accepted. ```sh python petrocalc_extensions.py examples/vof-dam-break.json \ --output tank.result.json --work new-tank-case --foam-root /opt/openfoam14 ``` Both generated cases have multiple cells in all three directions and no empty patch. Native incompressibleVoF advances phase fraction and momentum, with Euler time integration, MULES/interface compression, laminar transport, maxCo=maxAlphaCo=0.25, two outer PIMPLE corrections and strict inner solves. The requested deltaT is a maximum, not a promise of a fixed time step. Every inclusive output time must exist; incomplete time series are rejected. - `vof-advection.json`: 1 x 0.2 x 0.1 m axial-periodic box, slip sidewalls, uniform speed 1 m/s, initial water-marker slab x=0.25..0.5 m. Both marker fluids have rho=1000 kg/m3 and nu=1e-6 m2/s; gravity/sigma are zero. The historical native phase name `air` is an equal-property verification fluid in this case, not physical air. Transverse invariance makes this an exact transport test on a 3-D mesh, not general 3-D flow validation. - `vof-dam-break.json`: 0.6 x 0.4 x 0.1 m closed tank with an initial 0.15 x 0.2 x 0.1 m water column, stationary no-slip walls including both spanwise walls. Water/air rho=1000/1 kg/m3, nu=1e-6/1.48e-5 m2/s, g=9.81 m/s2, sigma=0.07 N/m. This is a short laminar numerical release study, not measured dam-break or turbulent impact validation. Phase-fraction walls use zero normal gradient; no calibrated wetting or dynamic contact-angle law is supplied. Fields are xyz (m), Uxyz (m/s), reduced p_rgh (Pa) and alpha.water (volume fraction). Reduced pressure is not kinematic p/rho or absolute pressure. All cells are included in the portable result; only the 3-D visual is sampled when necessary. Cartesian centroids are exact vertex averages for these boxes; legacy VTK field/coordinate precision is retained, then all audit accumulations use float64. CSVs identify pressure/velocity/time units. At most 20,000 cells, 3-11 snapshots, 100,000 total cell-snapshots and 0.05-0.3 s are accepted, keeping results within the browser's 40 MB limit. Initial interfaces must align with the mesh. Phase volume error must be <1e-6, alpha within [-1e-8,1+1e-8], local native continuity <1e-7, and native Courant numbers <=0.26 (0.25 adaptive target with log rounding margin). Initial fields, native pressure reference, finite residuals, exact time grid and complete Cartesian cells are checked independently. Advection requires L1 cell-average phase error <0.20, velocity error <1e-5 m/s and centroid error =4000 screen is not a transition criterion. The original duct requires L >= 10 max(H,W); periodic circular lengths must be between 0.2 and 5 outer diameters. Inspect final initial residuals, inlet/outlet volume balance and y+; repeat on a refined mesh and compare engineering quantities, not only colored plots. For the original developing duct, all six final initial p/U/k/omega residuals must be below 1e-6. Its inner linear solves use 0.05 relative stopping with absolute floors of 1e-9 for pressure and 1e-10 for velocity/turbulence. Circular templates use strict 1e-12 inner solves (zero relative tolerance). Their nonzero Ux/k/omega initial residuals must be below 1e-6; the native SIMPLE stop tests k/omega at 1e-8. The p and transverse-velocity normalized residuals are reported, not used as zero-field convergence tests: Foundation normalizes by field-dependent sums that become ill-conditioned for nearly zero fields. Instead, max transverse speed / bulk speed and periodic pressure span / bulk speed squared must each be <1e-5. Every U/k/omega/nut field must also change by <1e-4 of its maximum (U uses bulk speed) across two native saved checkpoints separated by at least 20 iterations. Missing checkpoints reject the result. These are separate from the strict inner linear solves and momentum balance. New results also require volume-averaged |div(phi)| / (U/Dh) <1e-6. This is derived from Foundation's native local-continuity log with generated deltaT=1 s, not inferred from cyclic inlet/outlet balance. The latter alone is insufficient. Convergence and conservation do not establish physical accuracy. High/low y+ and wall-function choices need engineering review. This steady runner is not a universal geometry, DNS, LES, transient, compressible, reacting or multiphase CFD front end. Full fields remain in the new case directory. At most 4,000 cell-center samples are exported for the browser. Pressure is kinematic gauge p/rho in m2/s2, NOT Pa. For the original duct, y+ is the native nutkWallFunction k-based diagnostic, not an independent wall-stress reconstruction. Circular cases use k=0, nutLowReWallFunction (zero wall eddy viscosity), omegaWallFunction and resolved wall grading. Their native y+ uses the wall velocity gradient; exports require its maximum <=2. This differs from the original duct's k-based diagnostic. Legacy VTK field samples have single-precision export accuracy; the native case retains its higher-precision field files. The original recorded duct example uses 1,728 / 13,824 / 46,656 cells, with pressure loss / rho 0.227182727 / 0.225231258 / 0.227365851 m2/s2. Successive relative changes are 0.87% and 0.94%, non-monotonic. This is not a grid-independence claim, an error bound or experimental validation. Complete three-mesh diagnostics are included in benchmarks/cfd-refinement.json. Recorded seconds include emulation and concurrent verification load; they are not a performance benchmark. Circular cases specify `geometry.type` as `pipe` or `annulus`, with an outer diameter. Annuli also require inner diameter and relative eccentricity, the center offset divided by radial clearance (0-0.6). Inner diameter may not exceed 90% of outer. `height` and `width` must both equal outer diameter; they are the bounding spans, not extra hydraulic dimensions. `ny` is radial cells, `nz` is cells per quarter circumference; a pipe adds an nz-by-nz central square. Hydraulic diameter is outer minus inner diameter. Both annular walls are stationary: no rotating drillstring, cuttings or non-Newtonian model is implied. The circular templates use PCG/DIC pressure solves and one nonorthogonal correction, bounded upwind convection and p/U/k/omega relaxation 0.3/0.7/0.7/0.7, with the physical zero-field and nonzero-field convergence gates above. At least 16 radial cells and fine-wall grading are required. Exact extruded-quadrilateral volumes from the parsed native VTK geometry weight axial pressure/profile diagnostics. Boundary faces approximate circles by chords; the polygon area error is reported explicitly. Total entrance pressure loss is not included. The periodic driving gradient must settle over the last 20 iterations, and its integrated forcing must agree with native wall shear drag to within 1%. The inlet/outlet flux tolerance remains 1e-5. The displayed equivalent p/rho adds the solved macroscopic gradient to periodic pressure fluctuations and sets the outlet reference to zero. Original periodic p remains in the native VTK file. The equivalent loss is gradient times periodic length, not a pressure loss through an entrance or fitting. Ten native validation cases cover three transverse resolutions for pipe, concentric and eccentric annuli, plus a separate pipe axial-resolution holdout. Final friction changes are 1.5741%, 2.4389% and 2.5659%; the axial holdout changes friction by 0.00003018%. Fine-pipe friction is 1.4429% below the original Princeton Superpipe point at Re=31,577; maximum axial velocity differs by about 4.50%. This is one measured pipe operating point, not validation across flow regimes or measured annular accuracy. Complete records are in `benchmarks/geometry-validation.json`; reference cases include `pipe.json`, `annulus.json` and `eccentric.json`. Eccentric reference/fine meshes use eight axial cells to pass native aspect-ratio checks, without relaxing mesh quality. ## Calibrated low-pressure wax solid solution `examples/wax.json` uses only n-C11/C14/C16/C18 at about 0.9 bar and 275-294 K. It is separate from the PR vapor/multiple-liquid solver. The liquid is ideal; one mixed solid uses Thermo's Wilson activity model with a fitted symmetric interaction Lambda_ij=exp[-a(Ci-Cj)^2/T]. The parameter is in K per squared carbon-number difference. This is an empirical fit, not predictive Wilson or UNIQUAC. Fusion H/Tm pairs are matched NIST rows: C11 22,179 J/mol at 247.59 K; C14 45,070 at 279.03 K; C16 53,359 at 291.34 K; C18 61,500 at 301.5 K. Cp/pressure corrections and solid-solid transitions are omitted. `wax-calibration.json` retains all 30 Table 1 measurements from Shariatrad et al. (2022), DOI 10.1021/acsomega.1c07072. Every third mixture was held out before fitting: 20 training and 10 test mixtures. a=131.69379525; training WDT AAD 0.8372 K, held-out AAD 0.7332 K, held-out maximum error 1.2272 K. The ideal-solid held-out AAD is 5.6715 K. These errors exceed the experimental expanded temperature uncertainty of 0.1 K. Printed experimental weights with 0.0001 rounding imbalance are explicitly normalized during data preparation, with raw values retained. Case mass fractions must sum to one and are not normalized. WDT and its incipient mixed-solid composition are returned, together with the solid/liquid allocation at case temperature. Analytic chemical potentials and logistic allocation refinement retain trace components without relaxing closure gates. Below-WDT solid fractions have numerical verification, not measured validation. Marginal composition bounds do not prove interpolation in the experimental convex hull. Crude oils, high pressure, multiple solid structures, energy flashes and fully solid/near-disappearing endpoints remain unsupported. WDT outputs outside the observed temperature range are temperature extrapolation, even when the case calculation temperature is within the allowed input bounds. ### Equilibrium temperature sweeps and composition support `examples/wax-sweep.json` adds optional `temperatureSweep` with `start`, `end` and an integer `points` count (3-41). All temperatures must be 275-294 K; the end must exceed the start by at least 0.01 K. The original `temperature` remains the reference-point calculation. Sweep samples use the same fixed feed and approximately 0.9 bar. Each point is solved independently with the original multistart equilibrium/stability checks. One failed point rejects the entire result; no partial curve or interpolated point is exported. Near-disappearing and all-solid conditioning limits remain in force. The separately solved WDT is a marker, not a claim that a coarse grid locates the phase boundary. The browser rechecks every grid temperature, phase amount/composition, component balance and solid/liquid chemical potential, and checks agreement where a grid point equals the reference temperature. Its chart switches between solid mole amount (mol/mol feed) and solid mass fraction (kg/kg feed), with full phase compositions and numerical diagnostics in the CSV. These equilibrium samples do not predict cooling rate, hysteresis, nucleation, deposited wax or flow restriction. Solid amounts remain numerically verified, not measured. `wax-domain.json` stores Qhull supporting planes in the first three independent mass-fraction coordinates, with the fourth fixed by their sum. Separate hulls use the 20 training mixtures and all 30 measured mixtures. Ten held-outs are never relabelled as training data. A 1e-10 signed-plane tolerance distinguishes inside, boundary and outside; it is a numerical geometry tolerance, not an experimental uncertainty or distance in the full four-component simplex. Being inside a hull is not an accuracy guarantee. The native result and browser report both hulls, including for legacy results. The calibration byte hash binds the domain file to its data. `python wax_domain.py NEW_DOMAIN.json` reproduces it without overwriting an existing file. Independent HiGHS linear-programming feasibility and high-precision sweep equations are tested in `test_wax_sweep.py`. Independent 60-digit WDT equations, library/gradient checks, phase-boundary, trace-component, data-split and geometry tests are in `test_extensions.py`. Install `requirements-test.txt` to run them. The actual engine measurement and refinement driver is `test_geometry_openfoam.py`; neither test driver is a hosted compute service. Native results are not authenticated by their case hash. `collect_geometry_report.py` rechecks all ten completed cases, their exact generated dictionaries, native fields and local-continuity logs before producing the published report and re-audited reference pairs. Incomplete sets reject without a report. JSON publication is atomic and never replaces existing work. ## Sources - https://github.com/CalebBell/thermo/blob/v0.6.0/thermo/flash/flash_vln.py - https://github.com/CalebBell/thermo/blob/v0.6.0/thermo/eos_mix.py - https://doc.cfd.direct/openfoam/user-guide-v14/transport-rheology - https://doc.cfd.direct/openfoam/user-guide-v14/fvsolution - https://ocw.mit.edu/courses/2-25-advanced-fluid-mechanics-fall-2013/7a3ff726e55b41c22037edbb3e3cd9ee_MIT2_25F13_Shapi-6.04-Prob.pdf - https://thermo.readthedocs.io/thermo.flash.html - https://thermo.readthedocs.io/thermo.eos_mix.html - https://webbook.nist.gov/cgi/cbook.cgi?ID=C593453&Mask=4 - https://webbook.nist.gov/cgi/cbook.cgi?ID=C112958&Mask=4 - https://openfoam.org/download/14-ubuntu/ - https://github.com/OpenFOAM/OpenFOAM-14 - https://tmbwg.github.io/turbmodels/sst.html - https://doi.org/10.1021/acsomega.1c07072 - https://www.ebi.ac.uk/europepmc/webservices/rest/PMC9134231/fullTextXML - https://thermo.readthedocs.io/thermo.wilson.html - https://webbook.nist.gov/cgi/cbook.cgi?ID=C1120214&Mask=4 - https://webbook.nist.gov/cgi/cbook.cgi?ID=C629594&Mask=4 - https://webbook.nist.gov/cgi/cbook.cgi?ID=C544763&Mask=4 - https://www.princeton.edu/~gasdyn/Superpipe_data/3.1577E+04.txt - https://docs.scipy.org/doc/scipy-1.17.0/reference/generated/scipy.spatial.ConvexHull.html - https://docs.scipy.org/doc/scipy-1.17.0/reference/generated/scipy.optimize.linprog.html Source and version details, benchmark comparisons and test coverage are recorded in the repository's native-companion directory and verification document.