\section{Teaching pair: an R1234yf swimming-pool heat pump}
\label{sec:tutorial-r1234yf-heat-pump}

This tutorial constructs a student worksheet and a model solution for a
swimming-pool heat pump. The heat pump operates cyclically between
outside air and pool water.  R1234yf flows steadily through an evaporator,
compressor, condenser, and expansion valve at
\(
  \dot m=5.0\,\mathrm{kg\,s^{-1}}.
\)

Every background curve, process path, state coordinate, and numerical value
is computed through the external CoolProp library; neither diagram depends on
an imported chart.

\begin{LCPNote}[What you will build]
The two standalone drivers share one graphical source.  The worksheet contains
only the dense PH chart needed for graphical construction.  The solution adds
the four directed processes, states $A$ through $D$, construction guides,
thermodynamic readings, and the condenser power.  The operating pressures are
themselves calculated from the two specified saturation temperatures; they are
not transcribed from a printed graph.
\end{LCPNote}

\subsection{Translate the statement into four idealized devices}

Begin by separating saturation temperatures from inlet and outlet
temperatures.  The evaporator operates at $-10\,{}^\circ\mathrm C$ and its
outlet receives $10\,\mathrm K$ of superheating, so
\[
  p_e=p_{\mathrm{sat}}(-10\,{}^\circ\mathrm C),
  \qquad T_B=0\,{}^\circ\mathrm C.
\]
The condenser operates at $50\,{}^\circ\mathrm C$ and its outlet receives
$10\,\mathrm K$ of subcooling, so
\[
  p_c=p_{\mathrm{sat}}(50\,{}^\circ\mathrm C),
  \qquad T_D=40\,{}^\circ\mathrm C.
\]

The four paths can then be expressed without reference to their expected
shape:
\begin{center}
\begin{tabularx}{\textwidth}{@{}c l X@{}}
\toprule
Path & Device model & Thermodynamic constraint \\
\midrule
$A\to B$ & Evaporator, no moving part & Isobar at $p_e$; evaporation followed
  by superheating to $T_B=0\,{}^\circ\mathrm C$.\\
$B\to C$ & Adiabatic reversible compressor & Isentrope from $p_e$ to $p_c$,
  hence $s_C=s_B$.\\
$C\to D$ & Condenser, no moving part & Isobar at $p_c$; desuperheating,
  condensation at $50\,{}^\circ\mathrm C$, then subcooling to
  $40\,{}^\circ\mathrm C$.\\
$D\to A$ & Insulated expansion valve, no moving part & Isenthalpic throttle,
  hence $h_A=h_D$.\\
\bottomrule
\end{tabularx}
\end{center}

This translation determines the cycle uniquely.  In particular, state $A$
should not be guessed on a quality line: its quality is a result of throttling
the subcooled state $D$ to $p_e$.

\subsection{Establish the steady-flow first law}

For a one-inlet, one-outlet control volume in steady operation, with heat and
non-flow mechanical powers counted positive when received by the refrigerant,
the industrial first law is
\[
  \dot Q+\dot W
  =\dot m\left[
      h_{\mathrm{out}}-h_{\mathrm{in}}
      +\frac{c_{\mathrm{out}}^2-c_{\mathrm{in}}^2}{2}
      +g(z_{\mathrm{out}}-z_{\mathrm{in}})
    \right].
\]
Neglecting kinetic- and potential-energy changes gives
\[
  \dot Q+\dot W=\dot m(h_{\mathrm{out}}-h_{\mathrm{in}}).
\]
The sign convention must be stated before interpreting the answer.  For the
condenser, \(\dot W=0\), and the thermal power received by the fluid is
\[
  \mathcal P_1=\dot m(h_D-h_C).
\]
A heat pump is expected to reject heat from the refrigerant to the pool in this
device, so \(\mathcal P_1\) should be negative under the stated convention.

The same equation explains the graphical invariants used later.  In the
adiabatic valve, both \(\dot Q\) and \(\dot W\) vanish, giving $h_A=h_D$.
In the evaporator and condenser, absence of moving parts makes the enthalpy
difference directly proportional to heat received by the fluid.

\subsection{Use one source and two thin drivers}

The generated pair uses these files:
\begin{center}
\begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash\ttfamily}p{.46\textwidth}>{\raggedright\arraybackslash}X@{}}
\toprule
File & Responsibility \\
\midrule
tutorial/r1234yf-heat-pump-worksheet.tex & Selects the blank chart.\\
tutorial/r1234yf-heat-pump-solution.tex & Enables the solution overlay.\\
tutorial/source/r1234yf-heat-pump-diagram.tex & Owns the axis, background
families, operating-pressure helpers, process paths, intersections, and
numerical calculations.\\
\bottomrule
\end{tabularx}
\end{center}

The drivers differ in one Boolean value:

\begin{LCPExample}{Worksheet and solution switches}
% In r1234yf-heat-pump-worksheet.tex:
\newif\ifRHeatPumpSolution
\RHeatPumpSolutionfalse

% In r1234yf-heat-pump-solution.tex:
\newif\ifRHeatPumpSolution
\RHeatPumpSolutiontrue
\end{LCPExample}

This arrangement prevents an edited background from making the problem sheet
and model solution geometrically inconsistent.

\subsection{Step 1: reproduce the blank PH chart}

The worksheet uses SI coordinates, so the tutorial overrides the usual
LuaCoolProp scales: $h$ remains in $\mathrm{J\,kg^{-1}}$ and $p$ in pascals.
Pressure is logarithmic and enthalpy linear.

\begin{LCPExample}{Worksheet axis}
\LCPSetup{fluid=R1234yf}
\begin{tikzpicture}
\begin{axis}[
  lcp fluid=R1234yf,
  width=24cm,height=15cm,
  xmin=100000,xmax=620000,
  ymin=100000,ymax=8000000,ymode=log,
  xlabel={Specific enthalpy $h$ (\si{\joule\per\kilogram})},
  ylabel={Pressure $p$ (\si{\pascal})},
  grid=both,clip mode=individual,
  auto node placement,
  auto node algorithm=greedy,
  auto node candidates=21,
  auto node bbox mode=oriented,
  auto node failure mode=hide-low-priority
]
  % The three isoline families go here.
\end{axis}
\end{tikzpicture}
\end{LCPExample}

The background combines vapour qualities, isotherms in kelvin, and
isentropes in SI units:

\begin{LCPExample}{The three PH families}
\LCPAddPHQuality[
  fluid=R1234yf,
  pressure min=100000,pressure max=8000000,
  enthalpy scale=1,pressure scale=1,
  quality values={0,0.1,0.2,0.3,0.4,0.5,
    0.6,0.7,0.8,0.9,1},
  quality color=red,quality boundary color=red,
  labels=true,quality label sloped=true]

\LCPAddPHIsotherms[
  fluid=R1234yf,
  pressure min=100000,pressure max=8000000,
  enthalpy scale=1,pressure scale=1,
  temperature unit=K,
  temperature values={253,263,273,283,293,303,313,
    323,333,343,353,363,373},
  isotherm color=blue,
  labels=true,isotherm label sloped=true]

\LCPAddPHIsentropes[
  fluid=R1234yf,
  pressure min=100000,pressure max=8000000,
  enthalpy scale=1,pressure scale=1,
  entropy unit=SI,
  entropy values={1500,1550,1600,1650,1700,
    1750,1800,1850,1900,1950,2000},
  isentrope color=green!50!black,
  labels=true,isentrope label sloped=true]
\end{LCPExample}

The complete implementation also tightens adaptive sampling for print-quality
curves.  Automatic label placement remains delegated to
\pkg{pgfplots-autonode}; the tutorial does not contain a competing placement
algorithm.

\IfFileExists{tutorial/r1234yf-heat-pump-worksheet.pdf}{%
  \begin{center}
    \includegraphics[width=\textwidth]
      {tutorial/r1234yf-heat-pump-worksheet.pdf}
  \end{center}
}{\begin{LCPWarning}[R1234yf worksheet not built]
Run \texttt{scripts/build-examples.sh} before compiling the manual.
\end{LCPWarning}}

\subsection{Step 2: derive both operating pressures}

Only temperatures are supplied for the two heat exchangers.  Two short,
invisible quality paths query the saturation pressure and export it to TeX.
The low-pressure helper starts at saturated vapour at
$-10\,{}^\circ\mathrm C$; the high-pressure helper starts at saturated liquid
at $50\,{}^\circ\mathrm C$.

\begin{LCPExample}{Saturation pressures exported as TeX macros}
\LCPAddPHProcess[
  fluid=R1234yf,type=quality,quality=1,
  from={temperature=-10C},to={temperature=-9C},
  name=r1234yf-low-saturation-helper,
  style={draw=none},
  export coordinates=RHeatPumpLowSaturation]

\LCPAddPHProcess[
  fluid=R1234yf,type=quality,quality=0,
  from={temperature=50C},to={temperature=49C},
  name=r1234yf-high-saturation-helper,
  style={draw=none},
  export coordinates=RHeatPumpHighSaturation]
\end{LCPExample}

The two reusable values are exposed separately:
\begin{itemize}
  \item \macro{\RHeatPumpLowSaturationFromPressureSI} stores $p_e$;
  \item \macro{\RHeatPumpHighSaturationFromPressureSI} stores $p_c$.
\end{itemize}
They give
\[
  p_e=2.21785\,\mathrm{bar},
  \qquad p_c=13.0235\,\mathrm{bar}.
\]
Changing either saturation temperature regenerates the pressure, the four
states, the cycle, and the power result in one build.

\subsection{Step 3: compute the cycle in dependency order}

Although the physical cycle is narrated from $A$, the most convenient
calculation begins at $B$, whose pressure and temperature are known.  First
draw the isentropic compressor path and export state $C$:

\begin{LCPExample}{Adiabatic reversible compression B to C}
\LCPAddPHProcess[
  fluid=R1234yf,type=isentrope,
  from={pressure=\RHeatPumpLowSaturationFromPressureSI Pa,
    temperature=0C},
  to={pressure=\RHeatPumpHighSaturationFromPressureSI Pa},
  enthalpy scale=1,pressure scale=1,
  name=r1234yf-bc,
  export coordinates=RHeatPumpBC,
  color=orange,style={very thick,-Latex}]
\end{LCPExample}

State $C$ is now the high-pressure state with entropy
\macro{\RHeatPumpBCToEntropySI}.  Use it to start the complete isobaric
condenser path and finish at the specified $40\,{}^\circ\mathrm C$ outlet:

\begin{LCPExample}{Desuperheating, condensation, and subcooling C to D}
\LCPAddPHProcess[
  fluid=R1234yf,type=isobar,
  pressure=\RHeatPumpHighSaturationFromPressureSI Pa,
  from={entropy=\RHeatPumpBCToEntropySI JkgK},
  to={temperature=40C},
  enthalpy scale=1,pressure scale=1,
  name=r1234yf-cd,
  export coordinates=RHeatPumpCD,
  color=orange,style={very thick,-Latex}]
\end{LCPExample}

The expansion valve fixes $A$ by conserving the enthalpy of $D$ while reducing
pressure to $p_e$:

\begin{LCPExample}{Adiabatic throttling D to A}
\LCPAddPHProcess[
  fluid=R1234yf,type=isenthalp,
  from={pressure=\RHeatPumpHighSaturationFromPressureSI Pa,
    temperature=40C},
  to={pressure=\RHeatPumpLowSaturationFromPressureSI Pa},
  enthalpy scale=1,pressure scale=1,
  name=r1234yf-da,
  export coordinates=RHeatPumpDA,
  color=orange,style={very thick,-Latex}]
\end{LCPExample}

Finally, state $A$ is known and the evaporator closes the cycle at $B$:

\begin{LCPExample}{Evaporation and superheating A to B}
\LCPAddPHProcess[
  fluid=R1234yf,type=isobar,
  pressure=\RHeatPumpLowSaturationFromPressureSI Pa,
  from={enthalpy=\RHeatPumpDAToEnthalpySI Jkg},
  to={temperature=0C},
  enthalpy scale=1,pressure scale=1,
  name=r1234yf-ab,
  export coordinates=RHeatPumpAB,
  color=orange,style={very thick,-Latex}]
\end{LCPExample}

This chain demonstrates why process exports are numerical API values rather
than presentation-only strings.  Exported macros are expanded inside later
\key{from} and \key{to} state specifications, allowing one thermodynamic
calculation to feed the next without duplicating rounded numbers.

\subsection{Step 4: place states by intersections, not copied coordinates}

Each state is the common endpoint of two named physical paths.  Ask TikZ to
resolve the four intersections:

\begin{LCPExample}{Four topology-derived state positions}
\path[name intersections={of=r1234yf-da and r1234yf-ab,
  by=RHeatPumpA}];
\path[name intersections={of=r1234yf-ab and r1234yf-bc,
  by=RHeatPumpB}];
\path[name intersections={of=r1234yf-bc and r1234yf-cd,
  by=RHeatPumpC}];
\path[name intersections={of=r1234yf-cd and r1234yf-da,
  by=RHeatPumpD}];

\node at (RHeatPumpA) {$A$};
\node at (RHeatPumpB) {$B$};
\node at (RHeatPumpC) {$C$};
\node at (RHeatPumpD) {$D$};
\end{LCPExample}

The diagram source also projects $C$ and $D$ vertically toward the enthalpy
axis.  Those are the two readings needed for the requested condenser power.

\IfFileExists{tutorial/r1234yf-heat-pump-solution.pdf}{%
  \begin{center}
    \includegraphics[width=\textwidth]
      {tutorial/r1234yf-heat-pump-solution.pdf}
  \end{center}
}{\begin{LCPWarning}[R1234yf solution not built]
Run \texttt{scripts/build-examples.sh} before compiling the manual.
\end{LCPWarning}}

The four exact states generated by CoolProp are:
\begin{center}
\small
\begin{tabular}{@{}c r r r r r@{}}
\toprule
State & $p/\mathrm{bar}$ & $T/{}^\circ\mathrm C$ & $x$ &
$h/\mathrm{kJ\,kg^{-1}}$ & $s/\mathrm{kJ\,kg^{-1}\,K^{-1}}$ \\
\midrule
$A$ & 2.21785 & $-10.000$ & 0.39960 & 254.959 & 1.21006 \\
$B$ & 2.21785 & 0.000 & --- & 365.744 & 1.63042 \\
$C$ & 13.0235 & 55.318 & --- & 398.878 & 1.63042 \\
$D$ & 13.0235 & 40.000 & --- & 254.959 & 1.18450 \\
\bottomrule
\end{tabular}
\end{center}

Quality is undefined for the single-phase superheated states $B$ and $C$ and
the subcooled-liquid state $D$.  State $A$ is genuinely two-phase.  Graphical
answers should be rounded according to the printed grid; the table contains
extra digits only to audit the generated construction.

\subsection{Step 5: calculate and interpret the condenser power}

The condenser process export provides both required SI enthalpies:
\macro{\RHeatPumpCDFromEnthalpySI} is $h_C$ and
\macro{\RHeatPumpCDToEnthalpySI} is $h_D$.  In LaTeX, the expandable
floating-point evaluator can calculate with the full SI values without TeX's
fixed-point dimension limit:

\begin{LCPExample}{Power calculated from the plotted process}
\edef\RHeatPumpCondenserPowerKW{\fpeval{
  5*(\RHeatPumpCDToEnthalpySI
    -\RHeatPumpCDFromEnthalpySI)/1000}}

\typeout{Condenser power received by R1234yf (kW):
  \RHeatPumpCondenserPowerKW}

$\mathcal P_1=
  \qty{\RHeatPumpCondenserPowerKW}{\kilo\watt}$.
\end{LCPExample}

With $h_C=398.878$ and $h_D=254.959\,\mathrm{kJ\,kg^{-1}}$,
\[
  \mathcal P_1
  =5.0(254.959-398.878)
  =-719.6\,\mathrm{kW}.
\]
The negative sign is physically necessary: the refrigerant does not receive
heat in the condenser; it transfers approximately $720\,\mathrm{kW}$ to the
pool-water side.  If the requested quantity were instead the heating power
received by the pool, and external losses were neglected, its value would be
$+719.6\,\mathrm{kW}$.

The other two non-zero energy transfers provide an independent closure check:
\[
  \dot Q_{AB}=+553.9\,\mathrm{kW},
  \qquad
  \dot W_{BC}=+165.7\,\mathrm{kW},
  \qquad
  \dot Q_{CD}=-719.6\,\mathrm{kW}.
\]
Their sum is zero to rounding, as required for a cyclic refrigerant with no net
energy accumulation.  This check is more informative than accepting the sign
of one graphical subtraction in isolation.

\subsection{Rebuild and adapt the teaching pair}

Build the complete documentation set with the same external library used for
the other examples:

\begin{LCPExample}{Reproducible repository build}
export LUACOOLPROP_LIB=/path/to/libCoolProp.dylib
./scripts/build-examples.sh
\end{LCPExample}

The two generated PDFs remain next to their drivers, while their transcripts
are stored in \path{tutorial/logs}.  The solution log records both saturation
pressures, $h_C$, $h_D$, and the signed condenser power.

To adapt the construction to another heat pump:
\begin{enumerate}
  \item replace the fluid and the two saturation temperatures;
  \item distinguish superheating and subcooling from those saturation values;
  \item derive operating pressures through CoolProp rather than a copied axis
        reading;
  \item encode every device by its conserved property;
  \item export each path before using its endpoint in the next path;
  \item derive state markers from named-path intersections;
  \item calculate powers from the exported SI enthalpies; and
  \item state the sign convention and verify the cycle energy balance.
\end{enumerate}

The worksheet, graphical correction, and numerical correction then remain
three synchronized views of the same model.
