% Shared worksheet/solution source for methane liquefaction by the Linde
% process. All curves, states, paths, mass-flow rates, and powers are generated.

\usepackage{luacoolprop}
\usetikzlibrary{arrows.meta,calc}
\pgfplotsset{compat=1.18}

\definecolor{MLQuality}{RGB}{50,105,225}
\definecolor{MLTemperature}{RGB}{220,55,40}
\definecolor{MLEntropy}{RGB}{235,135,15}
\definecolor{MLVolume}{RGB}{30,145,75}
\definecolor{MLCompression}{RGB}{190,55,35}
\definecolor{MLCooling}{RGB}{30,105,185}
\definecolor{MLRegenerator}{RGB}{130,60,160}
\definecolor{MLSeparation}{RGB}{15,125,110}
\definecolor{MLGuide}{RGB}{75,82,95}

\tikzset{
  methane linde state/.style={
    circle,draw=black,fill=white,very thick,inner sep=1.4pt,
    font=\sffamily\bfseries\scriptsize
  },
  methane linde note/.style={
    fill=white,fill opacity=.94,text opacity=1,rounded corners=1pt,
    inner sep=2.5pt,font=\sffamily\scriptsize,align=left
  }
}

% Four colour-coded curve families are computed independently by CoolProp.
\newcommand{\MethaneLindeDenseBackground}{%
  \LCPAddPHQuality[
    fluid=Methane,pressure min=20000,pressure max=20000000,
    quality values={0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1},
    quality symbol=x,quality color=MLQuality,
    quality boundary color=MLQuality,
    interior style={line width=.36pt},boundary style={line width=.85pt},
    labels=true,quality label every=1,quality label pos=.13,
    quality label sloped=true,
    initial intervals=24,max depth=9,tolerance=.12
  ]%
  \LCPAddPHIsotherms[
    fluid=Methane,pressure min=20000,pressure max=20000000,
    temperature unit=K,
    temperature values={103,113,123,133,143,153,163,173,183,193,
      203,213,223,233,243,253,263,273,283,293,303,313,323,333,
      343,353,363,373},
    temperature symbol=T,isotherm color=MLTemperature,
    isotherm style={line width=.38pt},labels=true,
    % Retain the complete 10 K grid but label alternate curves.  This keeps
    % interpolation accurate without crowding entropy and volume labels.
    isotherm label every=2,isotherm label pos=.68,
    isotherm label sloped=true,
    initial intervals=24,max depth=9,tolerance=.12
  ]%
  \LCPAddPHIsentropes[
    fluid=Methane,pressure min=20000,pressure max=20000000,
    entropy unit=kjkgk,
    entropy values={1,1.5,2,2.5,3,3.5,4,4.5,5,5.5,6,6.5},
    entropy symbol=s,isentrope color=MLEntropy,
    isentrope style={line width=.42pt},labels=true,
    isentrope label every=2,isentrope label pos=.79,
    isentrope label sloped=true,
    initial intervals=22,max depth=8,tolerance=.14
  ]%
  \LCPAddPHIsochores[
    fluid=Methane,pressure min=20000,pressure max=20000000,
    specific volume unit=m3kg,
    specific volume values={0.005,0.01,0.02,0.05,0.1,0.2,0.5,1,2,5},
    specific volume symbol=v,isochore color=MLVolume,
    isochore style={line width=.42pt},labels=true,
    isochore label every=2,isochore label pos=.38,
    isochore label sloped=true,
    isochore initial intervals=22,isochore max depth=8,
    isochore tolerance=.14
  ]%
}

% Intermediate solution pages retain the phase envelope and quality grid, but
% avoid repeating the sixty-one-curve reference network on every page.
\newcommand{\MethaneLindeSparseBackground}{%
  \LCPAddPHQuality[
    fluid=Methane,pressure min=20000,pressure max=20000000,
    quality values={0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1},
    quality color=MLQuality,quality boundary color=MLQuality,
    interior style={line width=.3pt},boundary style={line width=.8pt},
    labels=false,initial intervals=20,max depth=8,tolerance=.14
  ]%
}

% Resolve the primitive states supplied by the exercise, then close the two
% coupled balances before calculating the three compression stages.  Helper
% paths are invisible; their globally exported SI values are the numerical API
% used by both the drawing and the correction.
\newcommand{\MethaneLindeCompute}{%
  \LCPAddPHProcess[
    fluid=Methane,type=isobar,pressure=1bar,
    from={temperature=7C},to={quality=1},
    name=ml-helper-feed-vapour,style={draw=none},
    export coordinates=MethaneLindeFeedVapour,coord digits=12
  ]%
  \LCPAddPHProcess[
    fluid=Methane,type=isobar,pressure=1bar,
    from={quality=0},to={quality=1},
    name=ml-helper-saturation,style={draw=none},
    export coordinates=MethaneLindeSaturation,coord digits=12
  ]%
  \LCPAddPHProcess[
    fluid=Methane,type=isobar,pressure=100bar,
    from={temperature=-63C},to={temperature=-82C},
    name=ml-helper-high-regenerator,style={draw=none},
    export coordinates=MethaneLindeHighRegenerator,coord digits=12
  ]%
  \LCPAddPHProcess[
    fluid=Methane,type=isenthalp,
    from={pressure=100bar,temperature=-82C},to={pressure=1bar},
    name=ml-helper-throttle,style={draw=none},
    export coordinates=MethaneLindeThrottle,coord digits=12,
    log coordinates=true
  ]%

  \edef\MethaneLindeQualityEight{\fpeval{
    \MethaneLindeThrottleToQuality}}%
  \edef\MethaneLindeMassFlowOne{\fpeval{
    1/(1-\MethaneLindeQualityEight)}}%
  \edef\MethaneLindeMassFlowOneBis{\fpeval{
    \MethaneLindeQualityEight*\MethaneLindeMassFlowOne}}%
  \edef\MethaneLindeEnthalpyOneBisSI{\fpeval{
    \MethaneLindeSaturationToEnthalpySI
    -(\MethaneLindeMassFlowOne/\MethaneLindeMassFlowOneBis)
    *(\MethaneLindeHighRegeneratorToEnthalpySI
      -\MethaneLindeHighRegeneratorFromEnthalpySI)}}%
  \edef\MethaneLindeEnthalpyOneSI{\fpeval{
    (\MethaneLindeFeedVapourFromEnthalpySI
      +\MethaneLindeMassFlowOneBis*\MethaneLindeEnthalpyOneBisSI)
    /\MethaneLindeMassFlowOne}}%

  \LCPAddPHProcess[
    fluid=Methane,type=isentrope,
    from={pressure=1bar,enthalpy=\MethaneLindeEnthalpyOneSI Jkg},
    to={pressure=5bar},name=ml-helper-c-one,
    style={draw=none},export coordinates=MethaneLindeCOne,
    coord digits=12,log coordinates=true
  ]%
  \LCPAddPHProcess[
    fluid=Methane,type=isobar,pressure=5bar,
    from={entropy=\MethaneLindeCOneToEntropySI JkgK},
    to={enthalpy=866kJkg},name=ml-helper-e-one,
    style={draw=none},export coordinates=MethaneLindeEOne,
    coord digits=12
  ]%
  \LCPAddPHProcess[
    fluid=Methane,type=isentrope,
    from={pressure=5bar,enthalpy=866kJkg},to={pressure=25bar},
    name=ml-helper-c-two,style={draw=none},
    export coordinates=MethaneLindeCTwo,coord digits=12,
    log coordinates=true
  ]%
  \LCPAddPHProcess[
    fluid=Methane,type=isobar,pressure=25bar,
    from={entropy=\MethaneLindeCTwoToEntropySI JkgK},
    to={enthalpy=840kJkg},name=ml-helper-e-two,
    style={draw=none},export coordinates=MethaneLindeETwo,
    coord digits=12
  ]%
  \LCPAddPHProcess[
    fluid=Methane,type=isentrope,
    from={pressure=25bar,enthalpy=840kJkg},to={pressure=100bar},
    name=ml-helper-c-three,style={draw=none},
    export coordinates=MethaneLindeCThree,coord digits=12,
    log coordinates=true
  ]%
  \LCPAddPHProcess[
    fluid=Methane,type=isobar,pressure=100bar,
    from={entropy=\MethaneLindeCThreeToEntropySI JkgK},
    to={temperature=-63C},name=ml-helper-e-three,
    style={draw=none},export coordinates=MethaneLindeEThree,
    coord digits=12
  ]%

  \edef\MethaneLindeThermalPowerOneKW{\fpeval{
    \MethaneLindeMassFlowOne*(866000-\MethaneLindeCOneToEnthalpySI)/1000}}%
  \edef\MethaneLindeThermalPowerTwoKW{\fpeval{
    \MethaneLindeMassFlowOne*(840000-\MethaneLindeCTwoToEnthalpySI)/1000}}%
  \edef\MethaneLindeThermalPowerThreeKW{\fpeval{
    \MethaneLindeMassFlowOne*(\MethaneLindeEThreeToEnthalpySI
      -\MethaneLindeCThreeToEnthalpySI)/1000}}%
  \edef\MethaneLindeCompressorOnePowerKW{\fpeval{
    \MethaneLindeMassFlowOne*(\MethaneLindeCOneToEnthalpySI
      -\MethaneLindeEnthalpyOneSI)/1000}}%
  \edef\MethaneLindeCompressorTwoPowerKW{\fpeval{
    \MethaneLindeMassFlowOne*(\MethaneLindeCTwoToEnthalpySI-866000)/1000}}%
  \edef\MethaneLindeCompressorThreePowerKW{\fpeval{
    \MethaneLindeMassFlowOne*(\MethaneLindeCThreeToEnthalpySI-840000)/1000}}%
  \edef\MethaneLindeIdealCompressionPowerKW{\fpeval{
    \MethaneLindeCompressorOnePowerKW
    +\MethaneLindeCompressorTwoPowerKW
    +\MethaneLindeCompressorThreePowerKW}}%
  \edef\MethaneLindeCoolingEffectiveness{\fpeval{
    -(\MethaneLindeThermalPowerOneKW
      +\MethaneLindeThermalPowerTwoKW
      +\MethaneLindeThermalPowerThreeKW)/1800}}%
}

\newcommand{\MethaneLindeCoordinates}{%
  \coordinate (MLZero) at
    (axis cs:\MethaneLindeFeedVapourFromX,\MethaneLindeFeedVapourFromY);%
  \coordinate (MLOne) at
    (axis cs:\fpeval{\MethaneLindeEnthalpyOneSI/1000},1);%
  \coordinate (MLOneBis) at
    (axis cs:\fpeval{\MethaneLindeEnthalpyOneBisSI/1000},1);%
  \coordinate (MLTwo) at
    (axis cs:\MethaneLindeCOneToX,\MethaneLindeCOneToY);%
  \coordinate (MLThree) at
    (axis cs:\MethaneLindeEOneToX,\MethaneLindeEOneToY);%
  \coordinate (MLFour) at
    (axis cs:\MethaneLindeCTwoToX,\MethaneLindeCTwoToY);%
  \coordinate (MLFive) at
    (axis cs:\MethaneLindeETwoToX,\MethaneLindeETwoToY);%
  \coordinate (MLSix) at
    (axis cs:\MethaneLindeCThreeToX,\MethaneLindeCThreeToY);%
  \coordinate (MLSeven) at
    (axis cs:\MethaneLindeHighRegeneratorFromX,
      \MethaneLindeHighRegeneratorFromY);%
  \coordinate (MLSevenBis) at
    (axis cs:\MethaneLindeHighRegeneratorToX,
      \MethaneLindeHighRegeneratorToY);%
  \coordinate (MLEight) at
    (axis cs:\MethaneLindeThrottleToX,\MethaneLindeThrottleToY);%
  \coordinate (MLNine) at
    (axis cs:\MethaneLindeSaturationToX,\MethaneLindeSaturationToY);%
  \coordinate (MLTen) at
    (axis cs:\MethaneLindeSaturationFromX,\MethaneLindeSaturationFromY);%
}

\def\MethaneLindeProcess[#1]{%
  \LCPAddPHProcess[#1,fluid=Methane,coord digits=10,
    style={line width=1.55pt,-{Latex[length=2.4mm]}}]}

\newcommand{\MethaneLindeDrawSeparation}{%
  \MethaneLindeProcess[type=isobar,pressure=100bar,
    from={temperature=-63C},to={temperature=-82C},
    name=ml-seven-sevenbis,color=MLRegenerator]%
  \MethaneLindeProcess[type=isenthalp,
    from={pressure=100bar,temperature=-82C},to={pressure=1bar},
    name=ml-sevenbis-eight,color=MLRegenerator,
    log coordinates=true]%
  \MethaneLindeProcess[type=isobar,pressure=1bar,
    from={enthalpy=\MethaneLindeThrottleToEnthalpySI Jkg},to={quality=1},
    name=ml-eight-nine,color=MLSeparation]%
  \MethaneLindeProcess[type=isobar,pressure=1bar,
    from={enthalpy=\MethaneLindeThrottleToEnthalpySI Jkg},to={quality=0},
    name=ml-eight-ten,color=MLSeparation]%
  \MethaneLindeProcess[type=isobar,pressure=1bar,
    from={quality=1},to={enthalpy=\MethaneLindeEnthalpyOneBisSI Jkg},
    name=ml-nine-onebis,color=MLRegenerator]%
}

\newcommand{\MethaneLindeDrawMixer}{%
  \MethaneLindeProcess[type=isobar,pressure=1bar,
    from={temperature=7C},to={enthalpy=\MethaneLindeEnthalpyOneSI Jkg},
    name=ml-zero-one,color=MLSeparation]%
  \MethaneLindeProcess[type=isobar,pressure=1bar,
    from={enthalpy=\MethaneLindeEnthalpyOneBisSI Jkg},
    to={enthalpy=\MethaneLindeEnthalpyOneSI Jkg},
    name=ml-onebis-one,color=MLSeparation]%
}

\newcommand{\MethaneLindeDrawStageOne}{%
  \MethaneLindeProcess[type=isentrope,
    from={pressure=1bar,enthalpy=\MethaneLindeEnthalpyOneSI Jkg},
    to={pressure=5bar},name=ml-one-two,color=MLCompression,
    log coordinates=true]%
  \MethaneLindeProcess[type=isobar,pressure=5bar,
    from={entropy=\MethaneLindeCOneToEntropySI JkgK},
    to={enthalpy=866kJkg},name=ml-two-three,color=MLCooling]%
}

\newcommand{\MethaneLindeDrawStageTwo}{%
  \MethaneLindeProcess[type=isentrope,
    from={pressure=5bar,enthalpy=866kJkg},to={pressure=25bar},
    name=ml-three-four,color=MLCompression,log coordinates=true]%
  \MethaneLindeProcess[type=isobar,pressure=25bar,
    from={entropy=\MethaneLindeCTwoToEntropySI JkgK},
    to={enthalpy=840kJkg},name=ml-four-five,color=MLCooling]%
}

\newcommand{\MethaneLindeDrawStageThree}{%
  \MethaneLindeProcess[type=isentrope,
    from={pressure=25bar,enthalpy=840kJkg},to={pressure=100bar},
    name=ml-five-six,color=MLCompression,log coordinates=true]%
  \MethaneLindeProcess[type=isobar,pressure=100bar,
    from={entropy=\MethaneLindeCThreeToEntropySI JkgK},
    to={temperature=-63C},name=ml-six-seven,color=MLCooling]%
}

\newcommand{\MethaneLindeMark}[3]{%
  \node[methane linde state,#3] at (#1) {#2};}

\newcommand{\MethaneLindeMarkAnchors}{%
  \MethaneLindeMark{MLZero}{0}{anchor=north west}%
  \MethaneLindeMark{MLSeven}{7}{anchor=south west}%
  \MethaneLindeMark{MLTen}{10}{anchor=north east}%
}

\newcommand{\MethaneLindeMarkSeparation}{%
  \MethaneLindeMark{MLSevenBis}{$7'$}{anchor=south}%
  \MethaneLindeMark{MLEight}{8}{anchor=north}%
  \MethaneLindeMark{MLNine}{9}{anchor=north west}%
  \MethaneLindeMark{MLOneBis}{$1'$}{anchor=north}%
}

\newcommand{\MethaneLindeMarkStageOne}{%
  \MethaneLindeMark{MLOne}{1}{anchor=north}%
  \MethaneLindeMark{MLTwo}{2}{anchor=south east}%
  \MethaneLindeMark{MLThree}{3}{anchor=north west}%
}

\newcommand{\MethaneLindeMarkStageTwo}{%
  \MethaneLindeMark{MLFour}{4}{anchor=south west}%
  \MethaneLindeMark{MLFive}{5}{anchor=north west}%
}

\newcommand{\MethaneLindeMarkStageThree}{%
  \MethaneLindeMark{MLSix}{6}{anchor=south west}%
}

\newcommand{\MethaneLindeNumericPanel}{%
  \node[methane linde note,anchor=north west]
    at (rel axis cs:.012,.985) {%
    $x_8=\num[round-mode=places,round-precision=4]
      {\MethaneLindeQualityEight}$,\quad
    $\dot m_1=\qty[round-mode=places,round-precision=3]
      {\MethaneLindeMassFlowOne}{\kilogram\per\second}$\\
    $h_{1'}=\qty[round-mode=places,round-precision=1]
      {\fpeval{\MethaneLindeEnthalpyOneBisSI/1000}}
      {\kilo\joule\per\kilogram}$,\quad
    $h_1=\qty[round-mode=places,round-precision=1]
      {\fpeval{\MethaneLindeEnthalpyOneSI/1000}}
      {\kilo\joule\per\kilogram}$\\
    $\dot Q_{E1},\dot Q_{E2},\dot Q_{E3}
      =\qty[round-mode=places,round-precision=0]
        {\MethaneLindeThermalPowerOneKW}{\kilo\watt},
       \qty[round-mode=places,round-precision=0]
        {\MethaneLindeThermalPowerTwoKW}{\kilo\watt},
       \qty[round-mode=places,round-precision=0]
        {\MethaneLindeThermalPowerThreeKW}{\kilo\watt}$\\
    $\dot W_{C1}=\qty[round-mode=places,round-precision=0]
      {\MethaneLindeCompressorOnePowerKW}{\kilo\watt}$,\quad
    $e_T=\num[round-mode=places,round-precision=3]
      {\MethaneLindeCoolingEffectiveness}$
  };%
}

\newcommand{\MethaneLindeLogResults}{%
  \typeout{Methane Linde x8: \MethaneLindeQualityEight}%
  \typeout{Methane Linde mass flow 1 (kg/s): \MethaneLindeMassFlowOne}%
  \typeout{Methane Linde mass flow 1bis (kg/s): \MethaneLindeMassFlowOneBis}%
  \typeout{Methane Linde h1bis (J/kg): \MethaneLindeEnthalpyOneBisSI}%
  \typeout{Methane Linde h1 (J/kg): \MethaneLindeEnthalpyOneSI}%
  \typeout{Methane Linde QE1 (kW): \MethaneLindeThermalPowerOneKW}%
  \typeout{Methane Linde QE2 (kW): \MethaneLindeThermalPowerTwoKW}%
  \typeout{Methane Linde QE3 (kW): \MethaneLindeThermalPowerThreeKW}%
  \typeout{Methane Linde WC1 (kW): \MethaneLindeCompressorOnePowerKW}%
  \typeout{Methane Linde ideal compressor total (kW):
    \MethaneLindeIdealCompressionPowerKW}%
  \typeout{Methane Linde cooling effectiveness:
    \MethaneLindeCoolingEffectiveness}%
}

\newcommand{\MethaneLindeStageTitle}[1]{%
  \def\MethaneLindeTitle{Blank methane PH worksheet}%
  \ifcase#1\relax
  \or\def\MethaneLindeTitle{Step 1: locate the three directly specified states}%
  \or\def\MethaneLindeTitle{Step 2: regenerator, throttle, and phase separator}%
  \or\def\MethaneLindeTitle{Step 3: close the recirculation balance and draw the first stage}%
  \or\def\MethaneLindeTitle{Step 4: add the second compression and intercooler}%
  \or\def\MethaneLindeTitle{Step 5: complete the high-pressure train}%
  \or\def\MethaneLindeTitle{Step 6: complete Linde process and live numerical audit}%
  \fi
}

\newcommand{\MethaneLindeDiagram}[1]{%
  \MethaneLindeStageTitle{#1}%
  \begin{page}
  \begin{tikzpicture}
  \begin{axis}[
    lcp fluid=Methane,width=24cm,height=15.8cm,
    xmin=-100,xmax=1200,ymin=.2,ymax=200,ymode=log,
    xlabel={Specific enthalpy $h$ (\si{\kilo\joule\per\kilogram})},
    ylabel={Pressure $p$ (bar)},title={\MethaneLindeTitle},
    grid=both,major grid style={black!28},minor grid style={black!11},
    tick label style={font=\small},label style={font=\small},
    title style={font=\sffamily\large},clip mode=individual,
    auto node placement,auto node algorithm=repair,
    auto node candidates=19,auto node bbox mode=oriented,
    auto node failure mode=hide-low-priority
  ]
    \ifnum#1=0\relax
      \MethaneLindeDenseBackground
    \else
      \ifnum#1=6\relax
        \MethaneLindeDenseBackground
      \else
        \MethaneLindeSparseBackground
      \fi
      \MethaneLindeCompute
      \MethaneLindeCoordinates

      \addplot[MLGuide,densely dashed,line width=.55pt,forget plot]
        coordinates {(-100,1) (1200,1)};
      \addplot[MLGuide,densely dashed,line width=.55pt,forget plot]
        coordinates {(-100,5) (1200,5)};
      \addplot[MLGuide,densely dashed,line width=.55pt,forget plot]
        coordinates {(-100,25) (1200,25)};
      \addplot[MLGuide,densely dashed,line width=.55pt,forget plot]
        coordinates {(-100,100) (1200,100)};

      \MethaneLindeMarkAnchors
      \ifnum#1>1\relax
        \MethaneLindeDrawSeparation
        \MethaneLindeMarkSeparation
      \fi
      \ifnum#1>2\relax
        \MethaneLindeDrawMixer
        \MethaneLindeDrawStageOne
        \MethaneLindeMarkStageOne
      \fi
      \ifnum#1>3\relax
        \MethaneLindeDrawStageTwo
        \MethaneLindeMarkStageTwo
      \fi
      \ifnum#1>4\relax
        \MethaneLindeDrawStageThree
        \MethaneLindeMarkStageThree
      \fi
      \ifnum#1=6\relax
        \MethaneLindeNumericPanel
        \MethaneLindeLogResults
      \fi
    \fi
  \end{axis}
  \end{tikzpicture}
  \end{page}%
}

\begin{document}
\LCPSetup{fluid=Methane}
\ifMethaneLindeSolution
  \MethaneLindeDiagram{1}
  \MethaneLindeDiagram{2}
  \MethaneLindeDiagram{3}
  \MethaneLindeDiagram{4}
  \MethaneLindeDiagram{5}
  \MethaneLindeDiagram{6}
\else
  \MethaneLindeDiagram{0}
\fi
\end{document}
