The function to be plotted reads as

enter image description here

In it, these constrains hold true:

enter image description here

If plotted it looks like

enter image description here

Please excuse the different symbols, I will explain: p/p_0 is equivalent to \Pi and \gamma is equivalent to \kappa.

The plot was generated using data from Matlab, fed into LaTeX/PGF via a CSV-file. This works fine, but of course the data cannot be modified anymore, so I wanted to have it all in Latex naturally. Plus, doing stuff in Latex is fun.

I defined a function using the math library of Tikz/PGF such that

function prcrit(\x) {%
    return (2/(\x+1))^(\x/(\x-1));
function psimax(\x) {%
    return (sqrt(\x/(\x+1))) * (2/(\x+1))^(1/(\x-1));   
function psi(\x,\y) {%
    \psimax = psimax(\x);%maximum psi only dependent on kappa / k
    \prcrit = prcrit(\x);%critical pressure ratio only dependent on kappa / k
        if \y<\prcrit then {\efflux = \psimax;} else {\efflux = sqrt(\x/(\x-1))*(\y)^(1/\x)*sqrt(1-\y^((\x-1)/\x));};
    return \efflux;

in which prcrit (pressure ratio Pi) stands for $\Pi_{mathrm{crit}}$ from the above image, and psimax for the maximum value for \Psi (see first of the two cases of the initial equation). Thus, the function \Psi is set to its respective maximum \Psi_{\mathrm{max}} for any pressure ratio below critical.

The issue with this is that the boundaries that define the piecewise 3D function are themselves functions of one of the two input variables, namely \kappa, see the second equation.

Therefore, this thread and this one did not help me. This answer seems quite close to what my attempt is, but it does not seem to work with two variables. It also does not make use of the axis environment and merely draws a regular tikz picture. This is also the approach I found in the package's documentation.

Ideally, the end result could look similar to this:

         \addplot3[domain=1.3:1.7,y domain=0:1,surf] {psi(\x,\y)};

but that I could not get to work. The issue is essentially marrying the thus far functional function declaration in the preamble and a regular surf plot using the axis environment. I could not find such a solution yet.

The function also needs to be contained in quite narrow boundaries for \Pi and \kappa, namely 0 to 1 and roughly 1.3 to 1.7 respectively. This is what I would try to achieve by assigning corresponding domain boundaries. Towards 0 and 1 for \Pi, the function also has an infinite gradient (can be seen quite clearly in the function plot above), so that pgfplots also had some hiccups there in the past; but that is not so bad.


1 Answer 1


With declare function it is arguably easier this way (since you cannot use tikzmath easily with fpu). The value y=0 is a bit tricky, but since the true dependence on y is not too strong, I'd like to argue that it is good enough to start plotting at y=0.01 or so.

\begin{tikzpicture}[declare function={%
psimax(\x)=(sqrt(\x/(\x+1))) * (2/(\x+1))^(1/(\x-1));
point meta min=-1]
  \addplot3[opacity=0.6,colormap/viridis,domain=1.3:1.7,y domain=0.01:1,surf] {psi(\x,\y)};

enter image description here

  • 1
    Absolutely on point and super quick, thank you very much. Turns out I wasn't far off, but that doesn't count.
    – Alex Povel
    Oct 31, 2018 at 14:51
  • 1
    @HansLollo No, you were not at all off, it's just unfortunate that tikzmath doesn't like to cooperate with fpu. (You can switch off fpu, but then you are more restricted.)
    – user121799
    Oct 31, 2018 at 14:52

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .