Original Source Code (V1)"

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

Below is the original Visual Basic source code for the V1 class-based EQUIL-2 module (clsEquil2), the basis of the equil2_v1() function in this package. It is included to allow users to inspect the fidelity of the code translation.

This program is intended for research use, only. The code within is translated from Visual Basic code based on Werness, et al 1985 to R. The Visual Basic code was kindly provided by Dr. John Lieske of the Mayo Clinic and shared on the equil2 issue tracker by Lea Lerose (issue #2).

Reference

Werness PG, Brown CM, Smith LH, Finlayson B. Equil2: A Basic Computer Program for the Calculation of Urinary Saturation. Journal of Urology. 1985;134(6):1242-1244. doi:10.1016/S0022-5347(17)47703-2

How V1 differs from V5

The V5 form-based BASIC source (in vignette("original-source")) is a stripped-down version of V1. V1 adds several pathways that V5 omits:

V1 and V5 share the same stability constants for the core CaOx / Brushite / HAP / Uric Acid / Sodium-urate / Ammonium-urate pathways. The constants that differ are concentrated in the CO2 / PP / HU pathways that V5 doesn't use anyway (e.g. P7 for CO2 dissociation is 0.00229 in V1 vs 0.00123 in V5; the HU formation constant is 7.943e10 in V1 vs 2.78e5 in V5).

V1 reports activity products (APCaOx, APBr, APStru, APUA, APNaU) and relative saturation ratios (RSR = AP / Ksp) for Calcium Oxalate, Brushite, Struvite, and Uric Acid only. V5 additionally reports SS values for Hydroxyapatite, Sodium Urate, and Ammonium Urate, plus a negative ΔGibbs energy for each. For those V5-only outputs use the equil2() function.

V1's iteration loop is capped at 500 iterations (vs 50 in V5) and raises a warning on non-convergence.

Quirks preserved by the R port

Three quirks of the V1 source are preserved verbatim in equil2_v1() for fidelity:

  1. Pyrophosphate is disabled. After reading the input, V1 unconditionally sets TPP = 0 and PP = 0, which short-circuits the entire pyrophosphate pathway. The R port keeps this; users who want PP chemistry can edit the two TPP <- 0 / PP_var <- 0 lines in R/equil2_v1.R.
  2. NH4PO4 is uninitialized. V1 declares Dim NH4PO4 As Double but never assigns it, so it is always zero (VBA default). In the R port we make this explicit with NH4PO4 <- 0.
  3. Urate-cation complexes (NaU, KU, NH4U) are not in the cation mass balance. V1 computes them and uses them for ionic strength and for the chloride electroneutrality auto-fill, but STNa / STK / STNH4 do not include them. Effectively V1 treats them as trace species that don't deplete free Na, K, or NH4. The R port matches this.

Numerical verification against the V1 VBA module

The R port has been cross-validated against the original VBA module by running clsEquil2.bas in LibreOffice 26.2.4 with Option VBASupport 1 and Option ClassModule, using LibreOffice's Python UNO bridge to drive the Calc method. On the LabCorp inputs in the package examples, ionic strength agrees to <1 ppm and the four reported activity products / relative saturation ratios agree to ~10 ppm. The residual differences are floating-point reordering noise from how mass-balance sums are grouped in R vs the original BASIC.

EQUIL-2 V1 source

The code below is the basis of the equil2_v1() function.

src_path <- system.file("clsEquil2.bas.txt", package = "equil2")
if (!nzchar(src_path)) {
  # Fall back to the inst/ source if not yet installed
  # (e.g. devtools::build_vignettes() before install).
  src_path <- file.path("..", "inst", "clsEquil2.bas.txt")
}
cat("```vb\n")
cat(readLines(src_path), sep = "\n")
cat("\n```\n")


Try the equil2 package in your browser

Any scripts or data that you put into this service are public.

equil2 documentation built on June 11, 2026, 5:08 p.m.