# luacoolprop 1.1.0

`luacoolprop` is a format-generic LuaTeX interface to the CoolProp shared library. It computes thermodynamic states in Lua and emits PGFPlots code for PH (pressure-enthalpy), log-log PV (pressure-specific-volume), linear TS (temperature-entropy), linear HS (enthalpy-entropy), and PT (pressure-temperature, logarithmic in pressure) diagrams of pure fluids. It requires PGFPlots 1.18 or later but never changes the document's selected PGFPlots compatibility level.

The package supports saturation curves, quality lines, diagram-specific
background families, thermodynamic process paths, stable curve names,
per-curve overrides, and automatic label placement delegated to
`pgfplots-autonode`.

The autonomous `pgfplots-autonode` library is included with the package. It
can also label ordinary PGFPlots curves independently of LuaCoolProp.

![Methane Linde-process solution with a fully constructed PH cycle](docs/images/methane-linde-cycle.png)

*The final stage of the [methane Linde-process tutorial](tutorial/methane-linde-solution.tex): a computed PH diagram, coupled flows, state readings, and energy balances.*

![Butane pressure-specific-volume diagram with ideal-gas comparison](docs/images/butane-pv-ideal-gas.png)

*An [intermediate butane PV tutorial stage](tutorial/butane-pv.tex), comparing a real-fluid isotherm with its dilute-gas approximation.*

Both images are rasterized from PDFs built by the package's TeX sources. Run
`scripts/build-examples.sh` followed by `scripts/build-readme-images.sh` to
regenerate them; no external exercise artwork is bundled.

> [!WARNING]
> This package has been **vibe-coded with ChatGPT**. Substantial parts of its
> design, code, documentation, and tests were generated or revised with AI
> assistance. AI output can be plausible and still be wrong. CTAN publication
> is not a safety certification: inspect the source and independently validate
> all thermodynamic results before industrial, regulated, safety-critical, or
> other high-consequence use.

Author and Current Maintainer: Christophe Jorssen
<christophe.jorssen@gmail.com>. Version 1.1.0 is dated 2026-09-18; version
1.0.0 was distributed to a small group on 2026-09-05. The work is
maintained and distributed under the LaTeX Project Public License 1.3c or
later. The public project repository is
[github.com/cjorssen/luacoolprop](https://github.com/cjorssen/luacoolprop).

## Citing CoolProp

If you publish work based on thermodynamic results produced with LuaCoolProp,
please cite the underlying CoolProp project as its authors request:
Ian H. Bell, Jorrit Wronski, Sylvain Quoilin, and Vincent Lemort,
“Pure and Pseudo-pure Fluid Thermophysical Property Evaluation and the
Open-Source Thermophysical Property Library CoolProp,” *Industrial &
Engineering Chemistry Research* **53**(6), 2498–2508 (2014),
[doi:10.1021/ie4033999](https://doi.org/10.1021/ie4033999), and
[coolprop.org](https://coolprop.org/). The [official citation page](https://coolprop.org/citation.html)
also provides BibTeX. Record the CoolProp version used for reproducibility.

## Files

- `luacoolprop.tex`: generic TeX interface based on `pgfkeys`.
- `luacoolprop.lua`: FFI declarations, CoolProp wrappers, thermodynamic calculations, curve generation, process validation, and PGFPlots serialization.
- `luacoolprop.sty`: LaTeX wrapper.
- `t-luacoolprop.tex`: ConTeXt wrapper.
- `p-luacoolprop.tex`: plain TeX wrapper.
- `luacoolprop-manual.tex`: English user manual, exhaustive TeX reference,
  command/key indexes, and developer reference.
- `docs/luacoolprop-tex-reference.tex`: command-by-command and key-by-key TeX
  reference with executable source/result examples.
- `docs/pgfplots-autonode-reference.tex`: complete reference for the bundled
  autonomous PGFPlots library.
- `docs/r717-teaching-tutorial.tex`: instructor-oriented tutorial producing a
  blank R717 worksheet diagram and its annotated model-solution diagram.
- `docs/r134a-air-conditioner-tutorial.tex`: advanced six-stage R134a tutorial
  progressing from phase regions to a fully quantified air-conditioning cycle.
- `docs/butane-pv-tutorial.tex`: five-stage butane PV tutorial covering phase
  regions, the ideal-gas limit, intersection-defined states, a rigid-tank
  isochore, and numerical process exports.
- `docs/r1234yf-heat-pump-tutorial.tex`: worksheet/model-solution tutorial for
  an R1234yf swimming-pool heat pump, including saturation-derived pressures,
  a four-device PH cycle, and automated condenser-power calculation.
- `docs/methane-linde-tutorial.tex`: expert worksheet/progressive-solution
  tutorial for methane liquefaction by the Linde process, including coupled
  separator, regenerator, mixer, three-stage compression, and live power
  balances.
- `docs/luacoolprop-lua-api.md`: detailed Lua API, ownership, units, error,
  extension, and contribution reference.
- `examples/`: compilable LaTeX, plain TeX, ConTeXt, and Lua API examples with
  reproducible compilation logs.
- `pgflibrarypgfplots.autonode.code.tex`: autonomous PGFPlots library for
  automatic label placement.
- `pgfplots-autonode.lua`: numerical backend of the `autonode` library.
- `pgfplots-autonode.sty` and `pgfplots-autonode.code.tex`: alternate loaders.

## Quick start: automatic PH diagram

The LaTeX wrapper uses `siunitx` for generated numbers and units. If `siunitx`
was loaded first, LuaCoolProp preserves its package options and `\sisetup`
configuration. Otherwise the wrapper loads it with the standard defaults.
Plain TeX and ConTeXt do not acquire this LaTeX dependency.

Numeric input is locale independent: always use `.` as the decimal separator,
even if `siunitx` displays decimal commas. Decimal scientific notation and an
attached recognized process unit are accepted, for example `1.2E5Pa`.
Malformed numbers, units, booleans, lists, modes, presets, and bounds stop the
build instead of silently selecting a fallback.

```tex
\documentclass[border=3mm]{standalone}
\usepackage{luacoolprop}
\pgfplotsset{compat=1.18}

\begin{document}
\LCPPHDiagram[
  fluid=R134a,
  quality step=0.2,
  isotherm=true,
  temperature values={-20,0,20,40,60},
  labels=true
]
\end{document}
```

Compile with `lualatex --shell-escape` after selecting the external CoolProp
shared library as described below. The source is also available as
[`examples/ph-readme-automatic.tex`](examples/ph-readme-automatic.tex).

## Quick start: choose the curves in a PGFPlots axis

Use a normal PGFPlots `axis` when you want to choose each family and control
the axes yourself. `auto node placement` enables the bundled autonomous label
solver; it does not take control of unrelated axes.

```tex
\documentclass[border=3mm]{standalone}
\usepackage{luacoolprop}
\pgfplotsset{compat=1.18}

\begin{document}
\begin{tikzpicture}
\begin{axis}[
  lcp fluid=R134a,
  width=12cm,height=8cm,
  ymode=log,grid=both,
  xlabel={$h/(\mathrm{kJ\,kg^{-1}})$},
  ylabel={$p/\mathrm{bar}$},
  auto node placement
]
  \LCPAddPHQuality[quality values={0,0.5,1},labels=true]
  \LCPAddPHIsotherms[temperature values={-20,0,20,40,60},labels=true]
\end{axis}
\end{tikzpicture}
\end{document}
```

This exact source is [`examples/ph-readme-selected.tex`](examples/ph-readme-selected.tex).

## Pressure-specific-volume diagrams

PV is a registered diagram type with a log-log default axis. Quality curves,
isotherms, and isentropes use the shared option vocabulary; the abscissa is
mass-specific volume in m³/kg by default.

```tex
\LCPPVDiagram[
  fluid=R134a,
  isotherm=true,
  isentrope=true,
  quality values={0,0.25,0.5,0.75,1},
  temperature values={-20,0,20,40,60},
  entropy values={1.6,1.8,2.0},
  labels=true
]
```

The low-level commands `\LCPAddPVQuality`, `\LCPAddPVIsotherms`,
`\LCPAddPVIsentropes`, `\LCPAddPVPlots`, and `\LCPAddPVProcess` work inside an
existing `loglogaxis`. PV process coordinate exports use scaled specific volume
for X while retaining raw SI volume in the `...SpecificVolumeSI` macros.

## Temperature-entropy diagrams

TS is a registered diagram type with linear axes. Mass-specific entropy is
shown in kJ/(kg K) and absolute temperature in K by default. Quality curves and
constant mass-specific enthalpy curves use the shared selection, styling,
label, and autonode vocabulary.

```tex
\LCPTSDiagram[
  fluid=R134a,
  isenthalp=true,
  quality values={0,0.25,0.5,0.75,1},
  enthalpy values={200,250,300,350,400,450},
  labels=true
]
```

The low-level commands `\LCPAddTSQuality`, `\LCPAddTSIsenthalps`,
`\LCPAddTSPlots`, and `\LCPAddTSProcess` work inside an existing linear
`axis`. TS process coordinate exports use scaled entropy for X and the selected
scaled/offset temperature coordinate for Y while retaining absolute
temperature and every other resolved property in SI.

## Enthalpy-entropy diagrams

HS is a registered linear diagram type with mass-specific entropy on the
horizontal axis and mass-specific enthalpy on the vertical axis. It supports
qualities, isochores, isotherms, and isobars, including a common critical-limit
endpoint
and continuous two-phase isotherm/isobar segments.

```tex
\LCPHSDiagram[
  fluid=Water,
  quality step=0.2,
  isochore=true,
  specific volume values={0.01,0.1,1},
  isotherm=true,
  temperature values={100,200,300,400},
  isobar=true,
  isobar values={0.1,1,10,100},
  labels=true
]
```

The low-level commands `\LCPAddHSQuality`, `\LCPAddHSIsochores`,
`\LCPAddHSIsotherms`, `\LCPAddHSIsobars`, `\LCPAddHSPlots`, and
`\LCPAddHSProcess` work inside an existing linear `axis`. HS process exports
use scaled entropy for X and scaled enthalpy for Y, with all resolved
thermodynamic properties retained in SI.

## Pressure-temperature diagrams

PT uses temperature on the horizontal axis and a logarithmic pressure axis.
Its default background is the single liquid-vapour coexistence curve from the
triple point to the critical point. Saturated liquid and saturated vapour have
the same `(T,p)` coordinates, so this locus is intentionally not represented
as separate `Q=0` and `Q=1` curves. Isentropes, isenthalps, and isochores are
optional.

```tex
\LCPPTDiagram[
  fluid=R134a,
  temperature axis unit=celsius,
  pressure axis unit=bar,
  isentrope=true, entropy values={1.4,1.7,2.0},
  isenthalp=true, enthalpy values={200,300,400},
  isochore=true, specific volume values={0.001,0.01,0.1}
]
```

The low-level commands are `\LCPAddPTPhaseEnvelope` (also
`\LCPAddPTSaturation`), `\LCPAddPTIsentropes`, `\LCPAddPTIsenthalps`,
`\LCPAddPTIsochores`, `\LCPAddPTPlots`, and `\LCPAddPTProcess`.

## Scientific and coordinate contracts

PH, PV, TS, HS, and PT are peers in one registry. Their background capabilities
are validated: PH provides quality/isotherm/isentrope/isochore, PV provides
quality/isotherm/isentrope, TS provides quality/isenthalp, and HS provides
quality/isochore/isotherm/isobar, while PT provides one phase envelope plus
isentrope/isenthalp/isochore. An unsupported family switch is an error;
all six conserved-property process types remain projectable in every diagram.

Diagram construction accepts only CoolProp fluids reported as pure. Mixtures
and predefined blends are rejected because this release does not implement
mixture phase envelopes. The low-level Lua wrappers remain mixture-capable.

At the critical state, vapor quality is undefined. When a quality curve reaches
the critical pressure, its final graphical record is a quality-independent
limiting endpoint, not a state carrying the curve's subcritical quality value.

Use semantic coordinate keys such as `pressure axis unit=mpa`,
`enthalpy axis unit=jkg`, `specific volume axis unit=lkg`,
`entropy axis unit=jkgk`, and `temperature axis unit=celsius`. Each changes the
numeric coordinate and generated label together. Raw scale keys are retained
for advanced use and produce an explicit scaled-SI label.

Enthalpy and entropy reference origins are selected at initialization with
`\LCPSetReferenceState{DEF|IIR|ASHRAE|NBP}` or `reference state=...`. The first
diagram calculation locks the convention for that fluid. Use the same
convention for every compared state and use enthalpy differences in energy
balances.

Adaptive curves retain disconnected valid components instead of drawing
across rejected CoolProp states. `domain policy=ignore|warning|error` controls
the diagnostic; PGFPlots serialization always uses explicit jumps.

## Process path example

```tex
\LCPAddPHProcess[
  fluid=R134a,
  type=isentrope,
  from={pressure=1bar,quality=1},
  to={pressure=10bar},
  style={very thick,-Latex},
  label={$1\to2$},
  mark endpoints=true
]
```

## Diagram API

Diagram identifiers are uppercase coordinate pairs. `\LCPPHDiagram[<options>]`,
`\LCPPVDiagram[<options>]`, `\LCPTSDiagram[<options>]`, and
`\LCPHSDiagram[<options>]`, and `\LCPPTDiagram[<options>]` are the convenience spellings;
`\LCPDiagram{PH}[<options>]`, `\LCPDiagram{PV}[<options>]`, and
`\LCPDiagram{TS}[<options>]`, `\LCPDiagram{HS}[<options>]`, and
`\LCPDiagram{PT}[<options>]` are their generic
equivalents. The same dispatch API is available for plots, families, and
processes:

```tex
\LCPAddDiagramPlots{PH}[<options>]
\LCPAddDiagramFamily{PH}{isotherm}[<options>]
\LCPAddDiagramProcess{PH}[<options>]
```

Additional implementations can register further identifiers behind the same
interface. Mixed-case commands and abbreviated keys are accepted aliases;
the canonical interface uses uppercase diagram codes and
full property names such as `quality`, `temperature`, and `pressure`.

The developer-facing Lua API is documented in
[`docs/luacoolprop-lua-api.md`](docs/luacoolprop-lua-api.md). It covers the
CoolProp FFI wrappers, deterministic `AbstractState` cleanup, SI-unit contracts,
PH, PV, TS, HS, and PT point/process records, renderer options, error handling, and the
stable registration shape for custom diagram implementations.

## Autonomous PGFPlots library

`pgfplots-autonode` is part of this work as a regular PGFPlots
library. LuaCoolProp loads it automatically. It can also be used independently
after loading the PGFPlots frontend for the current format:

```tex
\usepgfplotslibrary{autonode}
```

The frontend is `\usepackage{pgfplots}` in LaTeX, `\input pgfplots.tex` in
plain TeX, and `\usemodule[t][pgfplots]` in ConTeXt. A labelled plot uses
`\pgfplotsautonode` as a trailing path command:

```tex
\begin{axis}[auto node placement,auto node algorithm=repair]
  \addplot[domain=0:4] {x}
    \pgfplotsautonode[preferred pos=0.65,sloped=true]{$y=x$};
\end{axis}
```

`auto node placement` is the lifecycle switch which runs the joint solver at
the end of the axis. It is mandatory for standalone use and for LuaCoolProp
family commands inside a manually written axis; omitting it produces a clear
warning. High-level commands such as `\LCPPHDiagram` install it on the axis
they create without changing unrelated PGFPlots axes.

The standalone examples `autonode-latex-basic.tex`,
`plain-autonode-basic.tex`, and `context-autonode-basic.tex` exercise the same
library implementation in all three formats. The `pgfplots-autonode` LaTeX
package and direct code loader are alternate entry points.

## CoolProp installation and runtime

CoolProp is an external native dependency. It is never included in the
LuaCoolProp package or its CTAN archive. Obtain a binary from the [official
shared-library page](https://coolprop.org/coolprop/wrappers/SharedLibrary/) or
build a reviewed revision from the [official CoolProp
repository](https://github.com/CoolProp/CoolProp). The library is normally
named `libCoolProp.dylib` on macOS, `libCoolProp.so` on Linux, and
`CoolProp.dll` on Windows.

The CoolProp library and the TeX engine process must have matching
architectures. Use an absolute `LUACOOLPROP_LIB` path, and record the CoolProp
tag or commit used to produce reproducible documents. Loading a shared library
executes native code, so use only an official binary or one built from source
you trust.

### Security warning: `--shell-escape`

> [!CAUTION]
> LuaCoolProp requires full `--shell-escape` because TeX Live exposes the
> LuaTeX FFI module only in a shell-escape-enabled typesetting process. This
> option lets the document and every loaded class, package, module, and input
> file run external programs with your user permissions. Compile only trusted
> sources, preferably in a sandbox or isolated account without secrets or
> elevated privileges. Never run the TeX engine as `root` or Administrator.
> Restricted shell escape is not sufficient for this FFI mechanism.

LuaCoolProp uses FFI to load the CoolProp C API. It does not download or compile
CoolProp and does not issue shell commands while typesetting, but that does not
reduce the authority granted to the rest of the document by
`--shell-escape`.

### Install the TeX package

Once the package is available through a TeX distribution, install it with that
distribution's package manager (`tlmgr install luacoolprop` for TeX Live, or
the MiKTeX Console on MiKTeX). CoolProp must still be installed separately.

For a manual TDS installation, unpack `luacoolprop.tds.zip` at the root of a
personal TEXMF tree. On TeX Live this is normally:

```sh
texmf_home=$(kpsewhich -var-value=TEXMFHOME)
mkdir -p "$texmf_home"
unzip luacoolprop.tds.zip -d "$texmf_home"
mktexlsr "$texmf_home"
```

Do not unpack the browsing archive `luacoolprop.zip` directly into a TEXMF
tree: it contains documentation and source files in CTAN's browsing layout.

### Reproducible source checkout

Building from source requires Git, CMake, Ninja, Python, a C++ compiler, and
CoolProp's submodule prerequisites. Keep the checkout beside, never inside,
this repository. This example pins the `v8.0.0` tag; replace it deliberately
when adopting another reviewed release.

```sh
git clone https://github.com/CoolProp/CoolProp.git ../coolprop-src
git -C ../coolprop-src fetch --tags
git -C ../coolprop-src checkout --detach v8.0.0
git -C ../coolprop-src submodule update --init --recursive
```

### macOS

Install Apple's command-line developer tools plus Git, CMake, and Ninja. For a
reproducible build, perform the pinned common checkout above first. The bundled
helper then reuses `../coolprop-src`, updates submodules, and puts the build in
a sibling directory. If no checkout exists, it can clone the current default
branch for exploratory use:

```sh
./scripts/build-coolprop-macos.sh
```

It defaults to `arm64` on Apple Silicon and prints the final absolute library
path. Match an Intel TeX engine or request a universal binary with:

```sh
COOLPROP_MACOS_ARCH=x86_64 ./scripts/build-coolprop-macos.sh
COOLPROP_MACOS_ARCH='arm64;x86_64' ./scripts/build-coolprop-macos.sh
```

The separate `./scripts/update-coolprop.sh v8.0.0` command is a maintainer
workflow for intentionally adopting another CoolProp API. It also regenerates
the marked FFI declaration block in `luacoolprop.lua`, so end users should not
run it as a routine installation step. It accepts `8.0.0` and resolves the
leading `v`. The equivalent build-only CMake commands are:

```sh
cmake -S ../coolprop-src -B ../coolprop-build-macos-arm64 -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DCMAKE_OSX_ARCHITECTURES=arm64 \
  -DCOOLPROP_SHARED_LIBRARY=ON \
  -DCOOLPROP_STATIC_LIBRARY=OFF \
  -DCOOLPROP_OBJECT_LIBRARY=OFF
cmake --build ../coolprop-build-macos-arm64 --target CoolProp
export LUACOOLPROP_LIB="$PWD/../coolprop-build-macos-arm64/libCoolProp.dylib"
```

### Linux

Install Git, CMake, Ninja, Python, a C++ toolchain, and 7-Zip with the system
package manager. For Debian or Ubuntu, the usual package names are `git`,
`cmake`, `ninja-build`, `build-essential`, `python3`, and `p7zip-full`. After
the pinned checkout above:

```sh
cmake -S ../coolprop-src -B ../coolprop-build-linux -G Ninja \
  -DCMAKE_BUILD_TYPE=Release \
  -DCOOLPROP_SHARED_LIBRARY=ON \
  -DCOOLPROP_STATIC_LIBRARY=OFF \
  -DCOOLPROP_OBJECT_LIBRARY=OFF
cmake --build ../coolprop-build-linux --target CoolProp
export LUACOOLPROP_LIB="$PWD/../coolprop-build-linux/libCoolProp.so"
```

A system-wide install and `sudo` are not required. Keeping the versioned build
outside the package and selecting it with an absolute path is easier to audit.

### Windows

The simplest setup is to extract an official precompiled x64 DLL to a stable
directory outside the LuaCoolProp tree. For a source build, install Git, CMake,
Python, and either Ninja with a compatible C++ compiler or Visual Studio. In
PowerShell, a Ninja build is:

```powershell
git clone https://github.com/CoolProp/CoolProp.git ..\coolprop-src
git -C ..\coolprop-src fetch --tags
git -C ..\coolprop-src checkout --detach v8.0.0
git -C ..\coolprop-src submodule update --init --recursive
cmake -S ..\coolprop-src -B ..\coolprop-build-windows -G Ninja `
  -DCMAKE_BUILD_TYPE=Release `
  -DCOOLPROP_SHARED_LIBRARY=ON `
  -DCOOLPROP_STATIC_LIBRARY=OFF `
  -DCOOLPROP_OBJECT_LIBRARY=OFF
cmake --build ..\coolprop-build-windows --target CoolProp
$env:LUACOOLPROP_LIB =
  (Resolve-Path ..\coolprop-build-windows\CoolProp.dll).Path
```

With Visual Studio 2022, use the matching x64 multi-configuration build:

```powershell
cmake -S ..\coolprop-src -B ..\coolprop-build-vs `
  -G "Visual Studio 17 2022" -A x64 `
  -DCOOLPROP_SHARED_LIBRARY=ON `
  -DCOOLPROP_STATIC_LIBRARY=OFF `
  -DCOOLPROP_OBJECT_LIBRARY=OFF
cmake --build ..\coolprop-build-vs --config Release --target CoolProp
$env:LUACOOLPROP_LIB =
  (Resolve-Path ..\coolprop-build-vs\Release\CoolProp.dll).Path
```

Some CMake versions place the DLL in a different configuration subdirectory;
locate the newly built `CoolProp.dll` under the selected build directory if
needed. In `cmd.exe`, use `set "LUACOOLPROP_LIB=C:\absolute\path\CoolProp.dll"`.

### Compile a document

Set `LUACOOLPROP_LIB` in the terminal that launches TeX, then use the engine
belonging to the document format.

LaTeX:

```sh
export LUACOOLPROP_LIB=/absolute/path/to/libCoolProp.dylib
lualatex --shell-escape myfile.tex
```

Plain TeX documents load `p-luacoolprop.tex` and use LuaTeX:

```tex
\input p-luacoolprop.tex
\pgfplotsset{compat=1.18}
\LCPPHDiagram[fluid=R134a]
\bye
```

```sh
luatex --shell-escape myfile.tex
```

ConTeXt documents select the `t-` module explicitly, because this repository
also contains the plain-TeX `p-` wrapper:

```tex
\usemodule[t][luacoolprop]
\pgfplotsset{compat=1.18}
\starttext
\LCPPHDiagram[fluid=R134a]
\stoptext
```

```sh
context --luatex --shell-escape myfile.tex
```

The `--luatex` switch selects ConTeXt MkIV. It is required because LuaCoolProp
uses the LuaTeX FFI module, which is not available in LuaMetaTeX/LMTX. Full
installation, loader diagnostics, and security guidance are in
`luacoolprop-manual.pdf`.

## Reproducible document build

The repository build exercises all three wrappers. Files named `plain-*.tex`
are built with `luatex`, files named `context-*.tex` with ConTeXt MkIV, and all
other examples plus the manual with `lualatex`. The manual build also regenerates
its separate command and key/value indexes with `makeindex`:

```sh
LUACOOLPROP_LIB=/path/to/libCoolProp.dylib ./scripts/build-examples.sh
```

Console logs are stored in `examples/logs/` and `build-logs/`; PDFs are placed
next to their sources. Sandboxed builds may set `LUACOOLPROP_TEX_CACHE` to a
writable directory for the LaTeX and plain-TeX font cache.

The same build also compiles every teaching driver in `tutorial/` before the
manual. Their logs are stored in `tutorial/logs/`; shared implementations in
`tutorial/source/` keep the generated diagrams synchronized with the manual.
This includes the R717 and R1234yf worksheet/solution pairs, the six-page
advanced R134a air-conditioner construction, the five-page butane PV
construction, and the six-page expert methane Linde-process correction.

## Complete validation

The main test entry point checks POSIX shell syntax, verifies that every public
TeX command and key remains represented in the exhaustive reference, exercises
the numerical LuaCoolProp and autonomous label-placement APIs, and finally
rebuilds every LaTeX, plain TeX, and ConTeXt example plus the indexed manual:

```sh
LUACOOLPROP_LIB=/path/to/libCoolProp.dylib ./scripts/test.sh
```

The numerical tests compare independent CoolProp entry points and physical
invariants instead of freezing values from one CoolProp release. Test logs are
written to `build-logs/`; document logs retain their established locations in
`build-logs/` and `examples/logs/`.

After a successful local test, create and installation-test both CTAN archives
listed by `MANIFEST.txt` with:

```sh
./scripts/package-release.sh
```

The command writes `luacoolprop.zip` and `luacoolprop.tds.zip`. The browsing
archive contains the exact top-level directory `luacoolprop/` and embeds the
TDS archive as requested by CTAN. Both archives use `SOURCE_DATE_EPOCH` when
set, otherwise the canonical release epoch recorded in `VERSION`; file modes,
timestamps, and member order are normalized. The installed-tree test resolves no runtime file from
the repository and covers LuaLaTeX, plain LuaTeX, ConTeXt MkIV, and standalone
pgfplots-autonode.

Copyright (C) 2026 Christophe Jorssen. LuaCoolProp, including
pgfplots-autonode, is distributed under LPPL 1.3c or later with maintenance
status `maintained`. CoolProp is a separate MIT-licensed dependency and is not
included.
