jjgomera / iapws

python libray for IAPWS standard calculation of water and steam properties
GNU General Public License v3.0
170 stars 64 forks source link

Validity range for enthalpy of vaporization? #38

Closed cfcohen closed 5 years ago

cfcohen commented 5 years ago

Hello again. Hopefully these reports are helpful and not just annoying. As I mentioned previously, I'm trying to use IAPWS because I'm not terribly knowledgeable about the subject matter. I suspect that these results are also unintended:

$ python3 -c "import iapws; print(iapws.IAPWS95(T=647.0959, x=0.5).Hvap)"
-4.444518708623946e-08
$ python3 -c "import iapws; print(iapws.IAPWS95(T=647.0958, x=0.5).Hvap)"
/home/cory/.local/lib/python3.6/site-packages/scipy/optimize/minpack.py:163: RuntimeWarning: The iteration is not making good progress, as measured by the 
  improvement from the last ten iterations.
  warnings.warn(msg, RuntimeWarning)
1.0171681899464602
$ python3 -c "import iapws; print(iapws.IAPWS95(T=647.097, x=0.5).Hvap)"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/usr/lib/python3/dist-packages/iapws/iapws95.py", line 396, in __init__
    self.__call__(**kwargs)
  File "/usr/lib/python3/dist-packages/iapws/iapws95.py", line 420, in __call__
    raise(err)
  File "/usr/lib/python3/dist-packages/iapws/iapws95.py", line 415, in __call__
    self.calculo()
  File "/usr/lib/python3/dist-packages/iapws/iapws95.py", line 1358, in calculo
    raise NotImplementedError("Incoming out of bound")
NotImplementedError: Incoming out of bound
$ python3 -c "import iapws; print(iapws.IAPWS95(T=647.096, x=0.5).Hvap)"
/usr/lib/python3/dist-packages/iapws/iapws95.py:172: RuntimeWarning: divide by zero encountered in double_scalars
  DeltaBd = b*Delta**(b-1)*Deltad
/usr/lib/python3/dist-packages/iapws/iapws95.py:172: RuntimeWarning: invalid value encountered in double_scalars
  DeltaBd = b*Delta**(b-1)*Deltad
/home/cory/.local/lib/python3.6/site-packages/scipy/optimize/minpack.py:163: RuntimeWarning: The iteration is not making good progress, as measured by the 
  improvement from the last ten iterations.
  warnings.warn(msg, RuntimeWarning)
/usr/lib/python3/dist-packages/iapws/iapws95.py:1867: RuntimeWarning: divide by zero encountered in double_scalars
  DeltaBd = b*Delta**(b-1)*Deltad
/usr/lib/python3/dist-packages/iapws/iapws95.py:1867: RuntimeWarning: invalid value encountered in double_scalars
  ...

The lower bound for validity was zero Celsius, which makes sense, but apparently there's an upper limit as well (100C?, Hvap <0?), but it's not properly enforced.

Since the value of x doesn't change the Hvap result at all, why does the system require that parameter to be passed, instead of just populating Hvap from T when given T & P?

Is there a reason why returning None is superior to returning the value that's evaluated at the minimum or maximum? I ask because in some contexts it's easier for the function to return the same data type. Say for example a graph from 0K to 500K... If you explicitly want to signal that value was outside the validity range by returning None, I understand that as well.

jjgomera commented 5 years ago

Hi, Hvap is not really a state property, simply it's the difference between the enthalpy in liquid and vapor phase in equilibrium. So only has sense in two phases region.

Since the value of x doesn't change the Hvap result at all, why does the system require that parameter to be passed, instead of just populating Hvap from T when given T & P?

IAPWS It is not thought as a direct calculator of properties but rather as a state calculator, there are no direct functions to calculate some property, for example Hvap (T) but st (T, P) with that state containing all the properties calculable by iapws. All point with same temperature give same saturated liquid and vapor so vapor quality no change its value. The validity range for Hvap is from triple point (273.16K) and the critical point(647.096K) T, P input pair can't define a point in saturation state (where hvap is defined. I could add support calculate in any state with T between Tt and Tc but thats slow the code only for that use, when you can get Hvap value defining a state in two phases region.

$ python3 -c "import iapws; print(iapws.IAPWS95(T=647.0959, x=0.5).Hvap)" -4.444518708623946e-08

Normal result, near the critical point the value must be almost zero

$ python3 -c "import iapws; print(iapws.IAPWS95(T=647.0958, x=0.5).Hvap)" /home/cory/.local/lib/python3.6/site-packages/scipy/optimize/minpack.py:163: RuntimeWarning: The iteration is not making good progress, as measured by the improvement from the last ten iterations. warnings.warn(msg, RuntimeWarning) 1.0171681899464602

Ummmm, iteration fail, the values calculated dont are real. Working in fix this case

$ python3 -c "import iapws; print(iapws.IAPWS95(T=647.097, x=0.5).Hvap)" Traceback (most recent call last): File "", line 1, in File "/usr/lib/python3/dist-packages/iapws/iapws95.py", line 396, in init self.call(**kwargs) File "/usr/lib/python3/dist-packages/iapws/iapws95.py", line 420, in call raise(err) File "/usr/lib/python3/dist-packages/iapws/iapws95.py", line 415, in call self.calculo() File "/usr/lib/python3/dist-packages/iapws/iapws95.py", line 1358, in calculo raise NotImplementedError("Incoming out of bound") NotImplementedError: Incoming out of bound

See the message of error, the point is upper to critical point so is not supported

$ python3 -c "import iapws; print(iapws.IAPWS95(T=647.096, x=0.5).Hvap)" /usr/lib/python3/dist-packages/iapws/iapws95.py:172: RuntimeWarning: divide by zero encountered in double_scalars DeltaBd = b*Delta(b-1)Deltad /usr/lib/python3/dist-packages/iapws/iapws95.py:172: RuntimeWarning: invalid value encountered in double_scalars DeltaBd = bDelta(b-1)Deltad /home/cory/.local/lib/python3.6/site-packages/scipy/optimize/minpack.py:163: RuntimeWarning: The iteration is not making good progress, as measured by the improvement from the last ten iterations. warnings.warn(msg, RuntimeWarning) /usr/lib/python3/dist-packages/iapws/iapws95.py:1867: RuntimeWarning: divide by zero encountered in double_scalars DeltaBd = bDelta*(b-1)Deltad /usr/lib/python3/dist-packages/iapws/iapws95.py:1867: RuntimeWarning: invalid value encountered in double_scalars ...

This is the critical point exactly, I must work in avoid this error.

Here you have a simple code to plot Hvap in his validity range:

` from matplotlib.pyplot import plot, show, xlabel, ylabel from scipy import arange from iapws import IAPWS95 from iapws._iapws import Tt, Tc

xlabel("T, K") ylabel("$H_{vap}$, kJ/kg") T = arange(Tt, Tc, 1) hvap = [IAPWS95(T=t, x=0.5).Hvap for t in T]

plot(T, hvap) show() Hvap

cfcohen commented 5 years ago

Thank you. Your explanation has made the situation more clear for me. I had already obtained a plot like the one you provided. I had figured out that the validity range was probably 273.16-647.096K, and knew that the lower bound was the triple point but not that 647.096 was the critical point. My only other comment is to note that -4.444518708623946e-08 is negative, so it seems to be related to the iteration problem. You feedback is appreciated and you can close this ticket whenever you want.