\section{A teaching pair for a real-fluid refrigeration machine}
\label{sec:tutorial-r717-machine}

This tutorial is written for an instructor preparing both a problem sheet and
its model solution.  It follows the progressive style of the TikZ and PGFPlots
tutorials: we first decide what the picture must communicate, then construct a
clean student diagram, and finally add the thermodynamic cycle, state names,
process arrows, and reading aids for the teacher version.

The case study is a single-stage R717 (ammonia) refrigeration machine operating
between $3\,\mathrm{bar}$ and $10\,\mathrm{bar}$. All thermodynamic curves
and cycle segments are generated from the external CoolProp shared library.

\begin{LCPNote}[What you will build]
The student receives a dense but unannotated PH chart suitable for graphical
readings.  The instructor uses the same source with one Boolean switch enabled;
the second PDF adds the five-state cycle, direction arrows, process names,
projection lines, and numerical enthalpy readings.  Keeping one graphical
source prevents the problem sheet and model solution from drifting apart.
\end{LCPNote}

\subsection{The exercise behind the diagram}

The refrigerant follows this idealized sequence:
\begin{enumerate}
  \item state $A$ is dry saturated vapor at $3\,\mathrm{bar}$;
  \item $A\to B$ is reversible adiabatic compression to
        $10\,\mathrm{bar}$, hence an isentrope;
  \item $B\to C$ is isobaric desuperheating at $10\,\mathrm{bar}$ until
        saturated vapor is reached;
  \item $C\to D$ is complete isobaric condensation at
        $10\,\mathrm{bar}$;
  \item $D\to E$ is throttling to $3\,\mathrm{bar}$, hence an
        isenthalpic process; and
  \item $E\to A$ is complete isobaric evaporation at
        $3\,\mathrm{bar}$.
\end{enumerate}

A PH chart is particularly effective here.  Both heat-exchanger processes are
horizontal because they are isobaric, while the throttle is vertical because
specific enthalpy is conserved.  The compressor follows a constant-entropy
curve.  The geometry therefore carries physical meaning before any number is
read.

The exercise can ask learners to locate the states, complete a state table,
identify whether the vapor behaves as an ideal gas during compression, and
calculate compressor work, evaporator heat, coefficient of performance, mass
flow, compressor power, and latent enthalpy of vaporization.

\subsection{One shared source and two thin drivers}

The example uses three files:
\begin{center}
\begin{tabularx}{\textwidth}{@{}>{\raggedright\arraybackslash\ttfamily}p{.38\textwidth}>{\raggedright\arraybackslash}X@{}}
\toprule
File & Responsibility \\
\midrule
tutorial/r717-worksheet.tex & Disables the solution overlay.\\
tutorial/r717-solution.tex & Enables the solution overlay.\\
tutorial/source/r717-machine-diagram.tex & Owns the axis, isolines, and
conditional solution overlay.\\
\bottomrule
\end{tabularx}
\end{center}

The student driver is deliberately small:

\begin{LCPExample}{Student driver}
\documentclass[tikz,border=5mm]{standalone}
\newif\ifRSevenSolution
\RSevenSolutionfalse
\input{tutorial/source/r717-machine-diagram.tex}
\end{LCPExample}

The teacher driver changes only the Boolean value:

\begin{LCPExample}{Teacher driver}
\documentclass[tikz,border=5mm]{standalone}
\newif\ifRSevenSolution
\RSevenSolutiontrue
\input{tutorial/source/r717-machine-diagram.tex}
\end{LCPExample}

This pattern scales well to a course containing many statement/correction
pairs.  Shared data, colors, axis limits, and thermodynamic grids are edited
once.  Only pedagogical information belongs inside
\texttt{\string\ifRSevenSolution}.

\subsection{Step 1: choose the worksheet's reading domain}

Start from the physical operating region, not from the full validity range of
the fluid model.  The cycle lies between $3$ and $10\,\mathrm{bar}$, but
learners need enough context to recognize the saturation dome and extrapolate
nearby families.  The example therefore shows $0.07$ to
$140\,\mathrm{bar}$, and $100$ to
$2200\,\mathrm{kJ\,kg^{-1}}$.

\begin{LCPExample}{Axis prepared for graphical reading}
\LCPSetup{fluid=R717}
\begin{tikzpicture}
\begin{axis}[
  lcp fluid=R717,
  width=24cm,height=15cm,
  xmin=100,xmax=2200,
  ymin=0.07,ymax=140,ymode=log,
  xlabel={Specific enthalpy $h$ ($\mathrm{kJ\,kg^{-1}}$)},
  ylabel={Pressure $p$ (bar)},
  title={R717 pressure--enthalpy diagram},
  grid=both,
  clip mode=individual,
  auto node placement,
  auto node algorithm=repair,
  auto node bbox mode=oriented,
  auto node failure mode=hide-low-priority
]
  % Isoline families and, conditionally, the solution go here.
\end{axis}
\end{tikzpicture}
\end{LCPExample}

The logarithmic pressure scale is essential: equal vertical distances represent
equal pressure ratios.  This is also why projected horizontal readings must be
drawn with axis coordinates rather than with page coordinates.

\subsection{Step 2: select purposeful isoline families}

An instructional chart should contain enough curves to support interpolation,
but not so many that the cycle disappears.  Explicit value lists make the
worksheet stable and auditable.  They are preferable here to a preset because
the list itself documents what learners are expected to read.

\begin{center}
\begin{tabularx}{\textwidth}{@{}l l X@{}}
\toprule
Family & Values used & Teaching role \\
\midrule
quality & $0,0.1,\ldots,1$ & Locate wet-vapor states and estimate
  $Q_E$.\\
isotherm & $-60,-40,\ldots,240\,{}^\circ\mathrm C$ & Read state
  temperatures and inspect superheated-vapor behavior.\\
isentrope & $1,2,\ldots,8\,\mathrm{kJ\,kg^{-1}\,K^{-1}}$ & Construct
  the ideal compressor path and read entropy.\\
isochore & $0.01,0.02,\ldots,20\,\mathrm{m^3\,kg^{-1}}$ & Estimate
  specific volume and test the incompressible-flow assumption.\\
\bottomrule
\end{tabularx}
\end{center}

The quality family draws the saturation boundaries as well as the interior
quality lines:

\begin{LCPExample}{Saturation dome and quality lines}
\LCPAddPHQuality[
  pressure min=7000,pressure max=14000000,
  quality values={0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1},
  quality color=black,quality boundary color=black,
  interior style={line width=.32pt},
  boundary style={line width=.9pt},
  labels=true,quality label every=1,
  quality label pos=.18,quality label sloped=true
]
\end{LCPExample}

Add the three remaining families with visually distinct encodings.  Color is
helpful on screen, but dash pattern and line weight still distinguish the
families after grayscale photocopying.

\begin{LCPExample}{Temperature, entropy, and volume grids}
\LCPAddPHIsotherms[
  temperature values={-60,-40,-20,0,20,40,60,80,
    100,120,140,160,180,200,220,240},
  isotherm color=RSevenTemperature,
  isotherm style={line width=.34pt,densely dotted},
  labels=true,isotherm label every=1,isotherm label sloped=true
]
\LCPAddPHIsentropes[
  entropy values={1,2,3,4,5,6,7,8},
  isentrope color=black,isentrope style={line width=.32pt},
  labels=true,isentrope label every=1,isentrope label sloped=true
]
\LCPAddPHIsochores[
  specific volume values={0.01,0.02,0.05,0.1,0.2,0.5,1,2,10,20},
  isochore color=RSevenVolume,
  isochore style={line width=.36pt,dashed},
  labels=true,isochore label every=1,isochore label sloped=true
]
\end{LCPExample}

All automatic labels still belong to \pkg{pgfplots-autonode}.  The tutorial
does not calculate label boxes or collision positions.  The
\key{hide-low-priority} failure policy is appropriate for a dense background
grid: losing one redundant isoline label is preferable to obscuring the cycle.

\subsection{Result: the student worksheet diagram}

The first generated PDF is the diagram supplied with the exercise.  It contains
no answer-specific marks, so it can be printed, embedded in a statement, or
used as a digital annotation background.

\IfFileExists{tutorial/r717-worksheet.pdf}{%
  \begin{center}
    \includegraphics[width=\textwidth]{tutorial/r717-worksheet.pdf}
  \end{center}
}{%
  \begin{LCPWarning}[Tutorial PDF not built]
  Run \texttt{scripts/build-examples.sh} to generate the tutorial diagrams.
  \end{LCPWarning}
}

Compile the standalone file with the same external library used by the package:

\begin{LCPExample}{Build only the student diagram}
export LUACOOLPROP_LIB=/path/to/libCoolProp.dylib
lualatex --shell-escape --output-directory=tutorial \
  tutorial/r717-worksheet.tex
\end{LCPExample}

The repository build places the PDF next to its source and the transcript in
\texttt{tutorial/logs}.  Building through the script is recommended because it
also checks the log and uses the same policy as the manual.

\subsection{Step 3: establish the five thermodynamic states}

Before drawing arrows, write each state as two independent properties or as one
property plus the conserved property of the process.  This makes the solution
reviewable: every segment states its own physical hypothesis.

The following table was calculated with CoolProp 8.0.0.  It is intentionally
more precise than a student can read from a printed chart.

\begin{center}
\small
\begin{tabular}{@{}c r r c r r r@{}}
\toprule
State & $p/\mathrm{bar}$ & $T/{}^\circ\mathrm C$ & $Q$ &
 $v/\mathrm{m^3\,kg^{-1}}$ & $h/\mathrm{kJ\,kg^{-1}}$ &
 $s/\mathrm{kJ\,kg^{-1}\,K^{-1}}$ \\
\midrule
$A$ & 3 & $-9.22$ & 1 & 0.40597 & 1596.90 & 6.22769 \\
$B$ & 10 & 74.39 & --- & 0.15947 & 1765.42 & 6.22769 \\
$C$ & 10 & 24.91 & 1 & 0.12853 & 1628.94 & 5.80290 \\
$D$ & 10 & 24.91 & 0 & 0.001658 & 462.76 & 1.89037 \\
$E$ & 3 & $-9.22$ & 0.1233 & 0.051386 & 462.76 & 1.93059 \\
\bottomrule
\end{tabular}
\end{center}

\begin{LCPWarning}[Quality outside the saturation dome]
Vapor quality is a two-phase property.  State $B$ is superheated vapor, so
CoolProp reports quality as undefined there; writing $Q_B=1$ may be an
informal way to say ``all vapor'', but it is not a valid equilibrium quality.
The distinction is worth making explicit in a model solution.
\end{LCPWarning}

Graphical values should be reported with graphical precision.  Depending on
print size and interpolation, reasonable readings from the generated diagram
are $h_A\simeq1580$, $h_B\simeq1760$, $h_C\simeq1610$, and
$h_D=h_E\simeq460\,\mathrm{kJ\,kg^{-1}}$.  The difference from the table
is not an error: the table evaluates the equation of state directly, whereas
the exercise assesses chart reading.  CoolProp versions and enthalpy reference
states should always be recorded when exact absolute enthalpies are published.

\subsection{Step 4: draw each process from its invariant}

The five calls below are inside \texttt{\string\ifRSevenSolution}.  Notice how
the option \key{type} names the invariant rather than merely describing the
appearance of the line.

\paragraph{Compression $A\to B$.}
State $A$ is fixed by pressure and saturated-vapor quality.  The target
pressure fixes $B$, because the process supplies constant entropy.

\begin{LCPExample}{Reversible adiabatic compression}
\LCPAddPHProcess[
  type=isentrope,
  from={pressure=3bar,quality=1},
  to={pressure=10bar},
  color=RSevenCycle,
  style={line width=1.35pt,-{Latex[length=2.2mm]}},
  name=r717-ab,
  export coordinates=RSevenAB,
  log coordinates=true
]
\end{LCPExample}

\paragraph{Desuperheating $B\to C$.}
The high-side pressure is conserved.  The entropy copied from state $A$
identifies $B$; \key{quality=1} identifies saturated vapor at $C$.

\begin{LCPExample}{High-pressure desuperheating}
\LCPAddPHProcess[
  type=isobar,pressure=10bar,
  from={entropy=6.2276889kJkgK},
  to={quality=1},
  color=RSevenCycle,
  style={line width=1.35pt,-{Latex[length=2.2mm]}},
  name=r717-bc,
  export coordinates=RSevenBC
]
\end{LCPExample}

\paragraph{Condensation $C\to D$.}
Both endpoints are saturation states on the same isobar.

\begin{LCPExample}{Complete condensation}
\LCPAddPHProcess[
  type=isobar,pressure=10bar,
  from={quality=1},to={quality=0},
  color=RSevenCycle,
  style={line width=1.35pt,-{Latex[length=2.2mm]}},
  name=r717-cd,
  export coordinates=RSevenCD
]
\end{LCPExample}

\paragraph{Throttle $D\to E$.}
The inlet is saturated liquid at $10\,\mathrm{bar}$.  The outlet pressure is
enough to resolve $E$, because throttling conserves specific enthalpy.

\begin{LCPExample}{Isenthalpic expansion}
\LCPAddPHProcess[
  type=isenthalp,
  from={pressure=10bar,quality=0},
  to={pressure=3bar},
  color=RSevenCycle,
  style={line width=1.35pt,-{Latex[length=2.2mm]}},
  name=r717-de,
  export coordinates=RSevenDE
]
\end{LCPExample}

\paragraph{Evaporation $E\to A$.}
The inlet enthalpy equals $h_D$; the outlet is dry saturated vapor.  Supplying
the high-precision inlet value makes the independently generated segment meet
the throttle exactly.

\begin{LCPExample}{Low-pressure evaporation}
\LCPAddPHProcess[
  type=isobar,pressure=3bar,
  from={enthalpy=462.75654kJkg},
  to={quality=1},
  color=RSevenCycle,
  style={line width=1.35pt,-{Latex[length=2.2mm]}},
  name=r717-ea,
  export coordinates=RSevenEA
]
\end{LCPExample}

The repeated style is kept visible in the tutorial so every call can be copied
independently.  In a larger course project, factor it into a TikZ style such as
\texttt{r717 cycle/.style=\{line width=1.35pt,-Latex\}}.  The five \key{name}
values become TikZ path names.  The five \key{export coordinates} values are
bare control-sequence prefixes, without a leading backslash.  For example,
the first call globally defines \macro{\RSevenABFromX},
\macro{\RSevenABFromY}, \macro{\RSevenABToX}, and
\macro{\RSevenABToY}.  Enabling \key{log coordinates} on
that call also records the two plotted coordinate pairs in the terminal and
log file.

\subsection{Step 5: add state names and reading aids}

The process commands calculate and name the thermodynamic paths.  Load TikZ's
\texttt{intersections} library, then define each state as the meeting point of
its incoming and outgoing process.  No enthalpy--pressure pair is copied from
a calculation table, so the annotations follow the paths automatically when
the fluid or operating conditions change.

\begin{LCPExample}{States obtained from named-path intersections}
\usetikzlibrary{intersections}
\path[name intersections={of=r717-ea and r717-ab,by=RSevenA}];
\path[name intersections={of=r717-ab and r717-bc,by=RSevenB}];
\path[name intersections={of=r717-bc and r717-cd,by=RSevenC}];
\path[name intersections={of=r717-cd and r717-de,by=RSevenD}];
\path[name intersections={of=r717-de and r717-ea,by=RSevenE}];

\filldraw[draw=RSevenCycle,fill=white,line width=1pt]
  (RSevenA) circle[radius=2pt];
\filldraw[draw=RSevenCycle,fill=white,line width=1pt]
  (RSevenB) circle[radius=2pt];
\filldraw[draw=RSevenCycle,fill=white,line width=1pt]
  (RSevenC) circle[radius=2pt];
\filldraw[draw=RSevenCycle,fill=white,line width=1pt]
  (RSevenD) circle[radius=2pt];
\filldraw[draw=RSevenCycle,fill=white,line width=1pt]
  (RSevenE) circle[radius=2pt];
\node[r717 state,anchor=south east] at (RSevenA) {A};
\node[r717 state,anchor=south west] at (RSevenB) {B};
\node[r717 state,anchor=south east] at (RSevenC) {C};
\node[r717 state,anchor=south east] at (RSevenD) {D};
\node[r717 state,anchor=north east] at (RSevenE) {E};
\end{LCPExample}

For reading aids, combine the intersection with a coordinate on the axis edge.
The TikZ operators \texttt{|-} and \texttt{-|} copy one canvas component from
each coordinate.  This remains correct when the axis is resized and when the
pressure axis is logarithmic.

\begin{LCPExample}{Projecting an enthalpy reading}
\coordinate (RSevenAxisBottom) at (axis cs:100,.07);
\coordinate (RSevenLabelBottom) at (axis cs:100,.075);
\path (RSevenA |- RSevenAxisBottom) coordinate (RSevenABottom);
\path (RSevenA |- RSevenLabelBottom) coordinate (RSevenALabel);
\draw[RSevenGuide,densely dashed,line width=.55pt]
  (RSevenABottom) -- (RSevenA);
\node[font=\sffamily\scriptsize,anchor=west,rotate=90,
  text=RSevenGuide]
  at (RSevenALabel)
  {$h_A=\pgfmathprintnumber[fixed,precision=0]{\RSevenABFromX}$};
\end{LCPExample}

Here \macro{\RSevenABFromX} is the numeric horizontal plot coordinate
exported by the process command.  With the tutorial's enthalpy scale it is expressed in
$\mathrm{kJ\,kg^{-1}}$; \macro{\RSevenABFromY} is the corresponding
pressure in bar.  The suffixes \texttt{ToX} and \texttt{ToY} provide the other
endpoint.  The complete source uses the same technique for the four projected
enthalpies, enough to reproduce a model reading without covering the property
grid.  Process-name nodes are placed manually because their instructional
composition is deliberate.  Automatic isoline labels remain the responsibility
of \pkg{pgfplots-autonode}.

\subsection{Result: the model-solution diagram}

\IfFileExists{tutorial/r717-solution.pdf}{%
  \begin{center}
    \includegraphics[width=\textwidth]{tutorial/r717-solution.pdf}
  \end{center}
}{%
  \begin{LCPWarning}[Tutorial PDF not built]
  Run \texttt{scripts/build-examples.sh} to generate the tutorial diagrams.
  \end{LCPWarning}
}

The result is suitable as a model solution: the thermodynamic grid remains
available for checking interpolations, while the orange cycle has a clear
direction and each process is named.

\subsection{Step 6: turn readings into an energy balance}

The chart is an intermediate model, not the end of the solution.  Retain units
at every step and avoid using more significant figures than the diagram
supports.

Using the direct CoolProp values, the specific compressor work is
\[
  w_{A\to B}=h_B-h_A
  =1765.42-1596.90
  =168.52\,\mathrm{kJ\,kg^{-1}}.
\]
The heat received by the fluid in the evaporator is
\[
  q_{E\to A}=h_A-h_E
  =1596.90-462.76
  =1134.14\,\mathrm{kJ\,kg^{-1}},
\]
and the ideal coefficient of performance is therefore
\[
  \mathrm{COP}=\frac{q_{E\to A}}{w_{A\to B}}\simeq6.73.
\]

Coarser hand readings from the generated diagram give approximately
$w_{A\to B}=180\,\mathrm{kJ\,kg^{-1}}$,
$q_{E\to A}=1120\,\mathrm{kJ\,kg^{-1}}$, and
\(\mathrm{COP}\simeq6.2\).  Both sets are defensible when their origin and
precision are stated.

For an evaporator load of $9.0\times10^4\,\mathrm{kJ\,h^{-1}}$, first
convert the rate:
\[
  \dot Q_{E\to A}
  =\frac{9.0\times10^4}{3600}\,\mathrm{kJ\,s^{-1}}
  =25\,\mathrm{kW}.
\]
Then
\[
  \dot m=\frac{\dot Q_{E\to A}}{q_{E\to A}}
  \simeq\frac{25\,\mathrm{kJ\,s^{-1}}}
                  {1134.14\,\mathrm{kJ\,kg^{-1}}}
  =2.20\times10^{-2}\,\mathrm{kg\,s^{-1}},
\]
and
\[
  \dot W_{A\to B}=\dot m\,w_{A\to B}\simeq3.71\,\mathrm{kW}.
\]

\begin{LCPWarning}[A useful dimensional check]
A result of $22\,\mathrm{kg\,s^{-1}}$ is three orders of magnitude too
large for a $25\,\mathrm{kW}$ evaporator in this example.  The intended
value is about $22\,\mathrm{g\,s^{-1}}$, or
$2.2\times10^{-2}\,\mathrm{kg\,s^{-1}}$.  Keeping both the power and the
specific enthalpy in kilojoule-based units exposes the conversion immediately.
\end{LCPWarning}

At state $A$, the latent enthalpy of vaporization is the horizontal distance
between the saturated-liquid and saturated-vapor boundaries at the low-side
pressure.  A chart reading gives roughly
$1.3\times10^3\,\mathrm{kJ\,kg^{-1}}$.

\subsection{Embedding the two PDFs in course material}

The standalone output can be reused without recompiling the thermodynamic
network inside every handout.  For example:

\begin{LCPExample}{Problem-sheet inclusion}
\begin{figure}[htbp]
  \centering
  \includegraphics[width=\linewidth]{tutorial/r717-worksheet.pdf}
  \caption{R717 PH diagram for graphical readings.}
\end{figure}
\end{LCPExample}

The model solution changes only the file name:

\begin{LCPExample}{Model-solution inclusion}
\begin{figure}[htbp]
  \centering
  \includegraphics[width=\linewidth]{tutorial/r717-solution.pdf}
  \caption{R717 refrigeration cycle and model readings.}
\end{figure}
\end{LCPExample}

Compile the diagram PDFs before the statement and correction.  The repository
script already enforces that order before compiling this manual.

\subsection{Adapting the tutorial safely}

For a different exercise, proceed in this order:
\begin{enumerate}
  \item change the fluid and operating pressures;
  \item recalculate every state from two independent properties;
  \item choose axis bounds around the new cycle;
  \item select explicit isolines appropriate to the questions;
  \item update process constraints before moving any annotation;
  \item compile the blank version and check that no answer is visible;
  \item compile the model solution and verify every arrow, state, and projected
        reading; and
  \item redo the energy balance with units carried through every equation.
\end{enumerate}

Do not obtain a new fluid merely by replacing \texttt{R717} in the finished
graphic.  State coordinates, saturation temperatures, entropy values, volume
grids, axis limits, and annotations all depend on the fluid.

If the background becomes crowded, first reduce the number of labelled curves
with the family-specific \key{... label every} keys.  Then adjust preferred
positions or use a per-curve override.  Do not add a separate label-placement
algorithm to the tutorial: collision avoidance belongs to the bundled
\pkg{pgfplots-autonode} library.

\subsection{Instructor's final checklist}

Before distributing the exercise, verify the following:
\begin{itemize}
  \item the student PDF contains the property network but no cycle or numerical
        answer;
  \item the model solution follows the stated process order and every arrow points
        from the inlet to the outlet;
  \item $A\to B$ follows an isentrope, $D\to E$ is vertical in PH
        coordinates, and both heat exchangers are horizontal;
  \item quality is only reported inside or on the saturation dome;
  \item graphical readings have realistic precision;
  \item exact values identify the CoolProp version when reproducibility matters;
  \item power, specific energy, and mass-flow units are mutually consistent;
        and
  \item both PDFs can be regenerated with \texttt{scripts/test.sh}.
\end{itemize}

The complete executable source is
\texttt{tutorial/source/r717-machine-diagram.tex}.  It is intentionally kept
beside its two drivers so instructors can copy the three-file pattern directly
into their own teaching repository.
