# Thermodynamics

Physical strokes inherit the surrounding native TikZ line width. No custom
line thickness is required; `>=latex` is the common arrow default.

Load everything with `\usepackage{tikzphysics}`, or load only this library after
TikZ with `\usetikzlibrary{tikzphysics.thermodynamics}`. The single-file Overleaf
runtime includes the same implementation. All physical geometry defaults to
black outlines, no fill, and black hatching where insulation is indicated.
Use ordinary TikZ `draw`, `fill`, `pattern color`, and style overrides for color.

## Apparatus and energy flow

Use `thermal reservoir` (`hot reservoir` / `cold reservoir` aliases), `gas chamber`,
`thermal wall`, `conducting wall`, `insulated wall`, `heat engine`, and
`refrigerator` (`heat pump` alias) as ordinary named nodes. The `heat pump diagram` pic is an
alias of `refrigerator diagram` and accepts the same options. Gas chambers represent
closed schematic boundaries; the shared `piston cylinder` and
`piston cylinder diagram` provide a movable closed-system boundary. No material properties or equilibrium states are inferred.

Rectangular boundaries have `bottom-0..100` left to right, `right-0..100` bottom
to top, `top-0..100` right to left, and `left-0..100` top to bottom. Reservoirs,
chambers and walls expose `heat-left`, `heat-right`, `heat-top`, `heat-bottom`.
The engine's `rim-0..100` runs counterclockwise from the rightmost point. Its
diagonal compass anchors and automatic path connections lie on the circle.
Rectangular devices use rectangular borders.
Devices expose `hot` above, `cold` below and `work` on the right. For engines,
`heat-in` is above and `heat-out` below; refrigerators reverse these heat ports.

```tex
\begin{tikzpicture}[>=latex]
  \pic (E) {heat engine diagram};
  \pic (R) at (7,0) {refrigerator diagram};
\end{tikzpicture}
```

These pics supply reservoirs, device, labels and energy arrows. The engine receives
heat from the hot reservoir, rejects heat to the cold reservoir and delivers work.
The refrigerator receives work and heat from the cold reservoir and rejects heat
to the hot reservoir. Heat/work labels denote positive magnitudes; arrow direction
defines input/output. Neither pic calculates heat, work, efficiency or COP.

A named pic `(E)` exports child nodes `E-hot`, `E-cold`, `E-device` and coordinates
`E-origin`, `E-work`. Ordinary child anchors such as `(E-hot.bottom-30)` work.
Use distinct names for multiple pics. Three coordinate families accept every
integer percentage from 0 to 100, measured along the arrow from tail to head:

| Pic coordinate | Engine direction | Refrigerator / heat pump direction |
|---|---|---|
| `(E-heat-hot-0)` ... `(E-heat-hot-100)` | hot reservoir to device | device to hot reservoir |
| `(E-heat-cold-0)` ... `(E-heat-cold-100)` | device to cold reservoir | cold reservoir to device |
| `(E-work-0)` ... `(E-work-100)` | device to work port | work port to device |

For example, `(E-heat-hot-50)` is the hot heat-flow midpoint and
`(E-work-25)` lies a quarter of the way along the work arrow. These are named
pic coordinates, accessed with a hyphen after the pic name; native node anchors
use a dot, for example `(E-device.rim-25)`. Rotations and scaling transform both
kinds of coordinates. The `heat pump diagram` alias uses the same families.
`\physicshelp{heat pump diagram}` and the apparatus aliases resolve to their
canonical reference cards.

Pass pic keys in braces:

```tex
\pic (E) {heat engine diagram={
  thermo diagram separation=2.5cm,
  thermo hot label={$600\,\mathrm K$},
  thermo cold label={$300\,\mathrm K$}}};
```

| Pic key | Default / meaning |
|---|---|
| `thermo diagram separation` | `2cm`, center-to-center device/reservoir distance |
| `thermo diagram work length` | `1.5cm`, from device edge to external work port |
| `thermo hot label`, `thermo cold label` | `$T_H$`, `$T_C$` |
| `thermo engine label`, `thermo refrigerator label` | `$E$`, `$R$` |
| `thermo hot heat label`, `thermo cold heat label`, `thermo work label` | `$Q_H$`, `$Q_C$`, `$W$` |
| `every thermo flow` | `>=latex` black arrows; customize using `/.append style` |
| `every thermo label` | inherits the picture/document font; customize using `/.append style` |

Reservoir, device, heat, work and piston-gas labels inherit the surrounding
`font` by default. The short flow/label hooks delegate to
`every physics thermo flow` and `every physics thermo label`, respectively.
Append styles to either spelling; use the prefixed hooks if another package
uses the short names. See `examples/native-style-review.tex` for font sizes
and explicit dashed-arrow/annotation overrides.

Reservoir and device dimension keys also apply inside pics. Separation must exceed
half the sum of reservoir height and device size; work length must be positive.

## Piston-cylinder closed systems

`piston cylinder` is available when loading thermodynamics alone, fluids alone,
or the whole package. Both modules load the shared `tikzphysics.piston` library;
its native shape is declared once, in either loading order. The standalone
Overleaf runtime contains this same implementation. Existing fluids diagrams
keep their geometry and original anchors.

```tex
\usepackage{tikz}
\usetikzlibrary{tikzphysics.thermodynamics}
% In the document:
\begin{tikzpicture}[>=latex]
  \pic (P) {piston cylinder diagram={
    piston position=.6,
    piston gas label={$P,V,T$},
    piston heat direction=in,
    piston work direction=out}};
  \draw[<->] ($(P-cylinder.south)+(1.3,0)$)
    --($(P-cylinder.piston)+(1.3,0)$) node[midway,right] {$h_g$};
\end{tikzpicture}
```

The cylinder is closed at the bottom and open above its piston. Gas occupies
only the region below the **lower piston face**. `piston position` is a unitless
fraction of full cylinder height, strictly between `.1` and `.9`. Width and
height must be positive and accept TeX lengths or bare centimetres. Defaults
are `1.8cm`, `3cm` and `.65`. The drawn piston thickness is `.04` times cylinder
height; the rod joins its upper face to the mouth level.

For width `w`, height `h`, position `f` and node centred at `(0,0)`, the bottom
is `y=-h/2`, the gas-contact face is `y=(-.5+f)h`, gas height is `fh`, and gas
centre is `(0,(-.5+f/2)h)`. Position changes gas height and piston/rod geometry.
These equations describe geometry; they do not calculate pressure or temperature.

| Native node anchor / family | Meaning / direction |
|---|---|
| `gas-center` | centre of the trapped gas, independent of the full node centre |
| `piston`, `piston-0..100` | lower contact face; left to right |
| `piston-top`, `piston-top-0..100` | upper face; left to right |
| `rod-start`, `rod-end`, `rod-0..100` | upper piston face to rod tip |
| `gas-axis-0..100` | bottom centre to lower piston centre |
| `gas-left-0..100`, `gas-right-0..100` | each gas-side wall; bottom to lower face |
| `heat-left`, `heat-right` | side-wall ports at half the gas height |
| `heat-bottom` | bottom centre |
| `work` | rod tip, identical to `rod-end` |
| `axis-0..100`, `wall-left-0..100`, `wall-right-0..100` | full cylinder height, bottom to mouth |
| `bottom-0..100`, `right-0..100`, `top-0..100`, `left-0..100` | counterclockwise rectangle boundary; top is a virtual guide across the open mouth |

Every family supports each integer from `0` through `100`. For example,
`(P-cylinder.gas-axis-50)` equals `(P-cylinder.gas-center)`. A plain native
node uses `(C.gas-center)`. Its ordinary `center` and text anchor retain their
original full-cylinder-centre meaning; place gas text explicitly at `gas-center`,
or use the pic, which does this automatically.

The **`piston cylinder diagram` pic** combines this native cylinder, a gas label,
and optional heat/work arrows. It accepts the native cylinder keys plus:

| Pic key | Default / meaning |
|---|---|
| `piston gas label` | `$P,V,T$`; ordinary text at the gas centre |
| `piston heat label`, `piston work label` | `$Q$`, `$W$` |
| `piston heat length`, `piston work length` | `1.2cm`, `1cm`; positive external flow lengths |
| `piston heat direction` | `in`; `in`, `out` or `none` |
| `piston work direction` | `out`; `in`, `out` or `none` |
| `every piston cylinder` | native apparatus style hook |
| `every piston cylinder diagram` | pic style hook |
| `every thermo flow`, `every thermo label` | shared thermodynamics flow/label styles |

A named pic `(P)` exports the nodes `P-cylinder`, `P-gas`, the coordinates
`P-origin`, `P-heat`, `P-work`, and families `P-heat-0..100`, `P-work-0..100`.
`P-heat` and `P-work` always identify the external endpoints. Flow percentages
run **tail to head**, reversing for input versus output. Heat attaches to
`P-cylinder.heat-left`; work attaches to `P-cylinder.rod-end`.
For `none`, the arrow and its label disappear while all coordinates remain,
ordered from the apparatus to the external endpoint. Flow lengths must remain
positive even when hidden. Directions apply locally to each pic.

```tex
\pic (C) {piston cylinder diagram={
  piston position=.4,piston heat direction=none,piston work direction=in,
  piston gas label={gas},piston work label={$W_{\rm in}$}}};
% An adiabatic compression illustration with no heat arrow.
```

Default flows are black `>=latex` arrows and inherit the surrounding native
TikZ stroke width. Append styles to `every thermo flow` to change arrows and
colors; use `every piston cylinder` to change the apparatus. Rotation and
scaling follow ordinary TikZ rules; add `transform shape` when transforming
child-node bodies and text along with a pic. Oversized labels remain the
author's responsibility. Distinct pic names keep instance anchors separate.

A piston position is a geometric state, not an equation of state or a process
solver. Heat and work directions are chosen independently. For a constant
cross-sectional area `A`, gas volume is `V=A h_g`. Quasistatic boundary work by
the gas is the integral of `P dV`; arrows label energy transfers rather than
numerically scaled displacement or force. An omitted heat arrow represents
an author-assumed adiabatic process; it does not add insulation automatically.
External pressure/load arrows can be attached to `piston-top` or `rod-end` using
ordinary TikZ. The two-page `thermodynamics-piston.pdf` gallery covers expansion,
compression, adiabatic compression, percentage samples, rotation and styling.

## Pressure-volume curves

All PV nodes include two axes, but leave text, ticks and arrows to the author.
Pressure and volume keys accept numbers in consistent author-chosen units, not
TeX dimensions. For example, choose litres and kilopascals and label the axes
accordingly. `pv width` and `pv height` set the physical drawing dimensions.
The plot maps `(V,P)` to `(-width/2 + width*V/Vmax,
-height/2 + height*P/Pmax)` relative to its node center. The physical zero point
is `origin`; it is not the node center.

| Process | Relation |
|---|---|
| `isothermal process` | `P = Pstart * Vstart / V` (ideal gas, constant temperature) |
| `isobaric process` | `P = Pstart` |
| `isochoric process` | `V = Vstart`, pressure interpolated to `pv end pressure` |
| `adiabatic process` | `P = Pstart * (Vstart/V)^gamma`, reversible ideal gas |
| `polytropic process` | `P = Pstart * (Vstart/V)^n`, `n = pv exponent` |

`process-0..100` advances linearly in volume, except for isochoric curves where it
advances linearly in pressure. It is not arc length or elapsed time. `start` and
`end` coincide with process endpoints; `start-volume` and `end-volume` project
these onto the horizontal axis. `start-pressure` and `end-pressure` project
onto the vertical axis. `volume-axis-0..100` runs right from `origin`;
`pressure-axis-0..100` runs up from `origin`. Endpoints are also named
`volume-end` and `pressure-end`. Compression is supported by a smaller end volume.
For an isochoric process `pv end volume` is ignored; set `pv end pressure` instead.

```tex
\begin{tikzpicture}[>=latex]
  \node[isothermal process,pv width=5cm] (P) {};
  \node[right] at (P.volume-end) {$V$};
  \node[above] at (P.pressure-end) {$P$};
  \draw[->] (P.process-45)--(P.process-55);
  \fill (P.start) circle (1.5pt);
\end{tikzpicture}
```

## Cycles

`rectangular cycle` runs clockwise: A=(low volume,low pressure), B=(low volume,
high pressure), C=(high volume,high pressure), D=(high volume,low pressure).
`AB-0..100`, `BC-0..100`, `CD-0..100`, `DA-0..100` advance along each branch.

`carnot cycle` constructs a reversible ideal-gas cycle from `V_A`, hot constant
`K_H = P_A V_A`, absolute-temperature ratio `r = T_C/T_H`, expansion ratio
`e = V_B/V_A`, and `gamma`. It derives `f = (1/r)^(1/(gamma-1))`,
`V_B=e V_A`, `V_D=f V_A`, `V_C=f V_B`, and `K_C=r K_H`.
Thus the hot and cold isotherms and the two adiabats meet at shared states.
Use Kelvin (or another absolute scale) for the temperature ratio, never Celsius.
The `pv start pressure` key does not apply to Carnot cycles; use the hot constant.

| Family | Direction / equation |
|---|---|
| `hot-0..100` | A to B, `P=K_H/V` |
| `expansion-0..100` | B to C, reversible adiabatic expansion |
| `cold-0..100` | C to D, `P=K_C/V` |
| `compression-0..100` | D to A, reversible adiabatic compression |

Both cycle nodes expose `state-A` through `state-D`, plus the same axis anchors
as process nodes. Every state has `state-A-volume` / `state-A-pressure`
projections, with the same spelling for B, C and D. Each Carnot branch percentage interpolates volume. Direction
arrows are optional author additions; reverse them to illustrate the reversed cycle.

## Overlaying processes on a shared frame

Use `pv diagram` for an empty axes frame. Set `pv show axes=false` on process
or cycle nodes to draw only their physical curve. All compass, zero, axis,
percentage and projection anchors remain available even when axes are hidden.
The option defaults to `true` on all PV nodes and is stored with each instance.

Keep `pv width`, `pv height`, `pv max volume` and `pv max pressure` identical
for every overlaid node, and place each at the frame's center. Use solid, dashed
or dotted styles to compare processes without color. Ordinary TikZ `draw=...`
after the process style changes its color when explicitly requested.

```tex
\begin{tikzpicture}[>=latex,pv width=6cm,pv height=4cm]
  \node[pv diagram] (F) {};
  \node[isothermal process,pv show axes=false] (I) at (F.center) {};
  \node[adiabatic process,pv show axes=false,dashed] (A) at (F.center) {};
  \node[above] at (F.pressure-end) {$P$};
  \node[right] at (F.volume-end) {$V$};
  \draw[densely dotted] (I.start-pressure)--(I.start)--(I.start-volume);
\end{tikzpicture}
```

Projection coordinates remain in the node's local frame under rotation, scaling
and translation. For a complete pic whose child shapes and labels should rotate
and scale, use `\pic[rotate=90,scale=.8,transform shape] ...`. Without
`transform shape`, standard TikZ keeps node shapes and text upright while it
transforms positions; explicit native node `rotate` and `scale` options transform
that node's geometry.

The physical sizes are explicit: text, `minimum width`, `minimum height` and
padding do not enlarge these native diagrams. Increase the module dimension
keys to fit longer labels. Flow and label style hooks work as normal TikZ styles:

```tex
\tikzset{
  every thermal reservoir/.append style={draw=black,thick},
  every thermo flow/.append style={dashed},
  every thermo label/.append style={font=\footnotesize}
}
```

## Parameter reference

Lengths accept explicit TeX units; bare geometric lengths are centimetres.
Saved geometry belongs to each instance, so later key changes do not move anchors.
Rotation, scaling and translation transform the geometry and anchors together.

All process and cycle nodes also accept `pv show axes=true` (default) or
`false`.

### pv diagram

| Key | Default |
|---|---|
| `pv width` | `4cm` |
| `pv height` | `3cm` |
| `pv max volume` | `4` |
| `pv max pressure` | `4` |
| `pv show axes` | `true` |

### thermal reservoir

| Key | Default |
|---|---|
| `reservoir width` | `3cm` |
| `reservoir height` | `.8cm` |

### gas chamber

| Key | Default |
|---|---|
| `chamber width` | `2.4cm` |
| `chamber height` | `1.8cm` |

### thermal wall

| Key | Default |
|---|---|
| `thermal wall width` | `.3cm` |
| `thermal wall height` | `2cm` |

### heat engine

| Key | Default |
|---|---|
| `thermal device size` | `1.2cm` |

### refrigerator

| Key | Default |
|---|---|
| `thermal device size` | `1.2cm` |

### isothermal process

| Key | Default |
|---|---|
| `pv width` | `4cm` |
| `pv height` | `3cm` |
| `pv max volume` | `4` |
| `pv max pressure` | `4` |
| `pv start volume` | `1` |
| `pv start pressure` | `3` |
| `pv end volume` | `3` |

### isobaric process

| Key | Default |
|---|---|
| `pv width` | `4cm` |
| `pv height` | `3cm` |
| `pv max volume` | `4` |
| `pv max pressure` | `4` |
| `pv start volume` | `1` |
| `pv start pressure` | `3` |
| `pv end volume` | `3` |

### isochoric process

| Key | Default |
|---|---|
| `pv width` | `4cm` |
| `pv height` | `3cm` |
| `pv max volume` | `4` |
| `pv max pressure` | `4` |
| `pv start volume` | `1` |
| `pv start pressure` | `3` |
| `pv end pressure` | `1.5` |

### adiabatic process

| Key | Default |
|---|---|
| `pv width` | `4cm` |
| `pv height` | `3cm` |
| `pv max volume` | `4` |
| `pv max pressure` | `4` |
| `pv start volume` | `1` |
| `pv start pressure` | `3` |
| `pv end volume` | `3` |
| `pv gamma` | `1.4` |

### polytropic process

| Key | Default |
|---|---|
| `pv width` | `4cm` |
| `pv height` | `3cm` |
| `pv max volume` | `4` |
| `pv max pressure` | `4` |
| `pv start volume` | `1` |
| `pv start pressure` | `3` |
| `pv end volume` | `3` |
| `pv exponent` | `1.2` |

### rectangular cycle

| Key | Default |
|---|---|
| `pv width` | `4cm` |
| `pv height` | `3cm` |
| `pv max volume` | `4` |
| `pv max pressure` | `4` |
| `pv low volume` | `1` |
| `pv high volume` | `3` |
| `pv low pressure` | `1` |
| `pv high pressure` | `3` |

### carnot cycle

| Key | Default |
|---|---|
| `pv width` | `4cm` |
| `pv height` | `3cm` |
| `pv max volume` | `4` |
| `pv max pressure` | `4` |
| `pv start volume` | `1` |
| `carnot hot constant` | `3` |
| `carnot temperature ratio` | `.75` |
| `carnot expansion ratio` | `1.5` |
| `pv gamma` | `1.4` |

## Validation and limits

Dimensions and axis maxima must be positive. Process endpoints must be positive,
distinct in the varying coordinate and within both axis limits. Adiabatic gamma
must exceed one; the polytropic exponent magnitude is limited to ten. Rectangular
cycle limits must be strictly ordered. Carnot requires positive start volume and
hot constant, gamma greater than one, expansion ratio greater than one, and a
cold/hot ratio strictly between zero and one; all states must fit the axes. Endpoint pressure and Carnot extent bounds are
checked in logarithmic form before powers are evaluated, so impossible large
expansions produce the axis-limit diagnostic rather than a PGF power overflow.

PGF uses finite-precision arithmetic: use moderately scaled pressure and volume
values and avoid extreme powers or gamma arbitrarily close to one. These nodes
are educational drawing primitives, not a numerical thermodynamic solver. They
do not integrate work, calculate entropy, model phase changes or determine real-gas
properties. Curved paths use sampled segments; named anchors evaluate the equation.

See [the three-page gallery](thermodynamics.pdf) and its editable source in
`examples/thermodynamics.tex`. The companion
[composition gallery](thermodynamics-scenes.pdf), from
`examples/thermodynamics-scenes.tex`, covers overlays, compression, automatic
circular connections, heat pumps, transformed pics and cycle projections.
The package reference cards include every new node
and both pics. The standard `show anchors` tools apply to named native nodes.
