usnistgov / REFPROP-wrappers

Wrappers around NIST REFPROP for languages such as Python, MATLAB, etc.
193 stars 127 forks source link

Dew point flash error #598

Closed JamesYatesHowden closed 6 months ago

JamesYatesHowden commented 6 months ago

Description

I am running a dew point temperature flash using the refprop dll in python.

The answer I get via the dll is VERY different to the answer I get using the same version of refprop via the GUI.

If I were to take a partial pressure approach, the GUI version is in the range I'd expect the dew point to be.

Steps to Reproduce

Capture

from ctREFPROP.ctREFPROP import REFPROPFunctionLibrary, REFPROPInstance  # type: ignore
from os import getcwd

pressure = 145138.42

mix = [
    ('HYDROGEN.FLD',          0.346829),
    ('NITROGEN.FLD',          0.002203),
    ('CO.FLD',                0.103263),
    ('CO2.FLD',               0.318607),
    ('METHANE.FLD',           0.030366),
    ('ETHANE.FLD',            0.018206),
    ('PROPANE.FLD',           0.159881),
    ('ISOBUTAN.FLD',          0.006154),
    ('BUTANE.FLD',            0.002821),
    ('IPENTANE.FLD',          0.001154),
    ('PENTANE.FLD',           0.000641),
    ('22DIMETHYLBUTANE.FLD',  0.001282),
    ('WATER.FLD',             0.007821),
    ('HCL.FLD',               0.000003),
    ('H2S.FLD',               0.000769),
]

fluid_str = ';'.join([f'{fluid}' for fluid, _ in mix])
z = [x for _, x in mix]

dll: REFPROPInstance = REFPROPFunctionLibrary(f"{getcwd()}//calcs//refprop")
dll.SETPATHdll(f"{getcwd()}//calcs//refprop")
iUnits: int = dll.GETENUMdll(0, 'MASS BASE SI')[0]
iFlag: int = 1

setup_ierr = dll.SETFLUIDSdll(fluid_str)
if setup_ierr not in [0, 117, -117]:
    raise Exception(f'Failed to set fluid mixture! {setup_ierr}')        

r = dll.REFPROP2dll("", 'PQ', 'T', iUnits, iFlag, pressure, 1.0, z)
t_dew = r.Output[0]
if r.ierr != 0:
    raise Exception(f'Failed to calculate dew point temperature! {r.herr}')

print()
print(setup_ierr)
print()
print(r)
print()
print(t_dew - 273.15)
print()
117

REFPROP2dlloutput(z=array('d', [0.346829, 0.002203, 0.103263, 0.318607, 0.030366, 0.018206, 0.159881, 0.006154, 0.002821, 0.001154, 0.000641, 0.001282, 0.007821, 3e-06, 0.000769, 0.0, 0.0, 0.0, 0.0, 0.0]), Output=array('d', [221.60094737069616, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0]), q=1.0, ierr=0, herr='K')

-51.549052629303816

Expected behavior: GUI value: 8.73C

Actual behavior: dll value: -51.55C

Versions

REFPROP Version: 10.0 Operating System and Version: Windows 10 Access Method: Python

ianhbell commented 6 months ago

Error code 117 should be a fatal error (-117 on the other hand would be ok). So by rights you should not get any results if the setup does not work. I guess that the presence of HCl is the problematic component since interaction parameters with other components are probably impossible.

Recommend to call ERRMSGdll after the failed setup

P.S. Very(!) nice issue report. Clearly you've done this sort of thing before.

Here is my code:

from ctREFPROP.ctREFPROP import REFPROPFunctionLibrary, REFPROPInstance  # type: ignore
from os import getcwd

pressure = 145138.42

mix = [
    ('HYDROGEN.FLD',          0.346829),
    ('NITROGEN.FLD',          0.002203),
    ('CO.FLD',                0.103263),
    ('CO2.FLD',               0.318607),
    ('METHANE.FLD',           0.030366),
    ('ETHANE.FLD',            0.018206),
    ('PROPANE.FLD',           0.159881),
    ('ISOBUTAN.FLD',          0.006154),
    ('BUTANE.FLD',            0.002821),
    ('IPENTANE.FLD',          0.001154),
    ('PENTANE.FLD',           0.000641),
    ('22DIMETHYLBUTANE.FLD',  0.001282),
    ('WATER.FLD',             0.007821),
    ('HCL.FLD',               0.000003),
    ('H2S.FLD',               0.000769),
]

fluid_str = ';'.join([f'{fluid}' for fluid, _ in mix])
z = [x for _, x in mix]

import os 
root = os.getenv('HOME') + '/REFPROP10'
dll: REFPROPInstance = REFPROPFunctionLibrary(root)
dll.SETPATHdll(root)
iUnits: int = dll.GETENUMdll(0, 'MASS BASE SI')[0]
iFlag: int = 1

setup_ierr = dll.SETFLUIDSdll(fluid_str)
if setup_ierr not in [0, -117]:
    msg = dll.ERRMSGdll(setup_ierr)
    raise Exception(f'Failed to set fluid mixture! {setup_ierr} w/ message "{msg}"')

r = dll.REFPROP2dll("", 'PQ', 'T', iUnits, iFlag, pressure, 1.0, z)
t_dew = r.Output[0]
if r.ierr != 0:
    raise Exception(f'Failed to calculate dew point temperature! {r.herr}')

print()
print(setup_ierr)
print()
print(r)
print()
print(t_dew - 273.15)
print()

yielding

Exception: Failed to set fluid mixture! 117 w/ message "[SETUP error 117] Estimation of mixing parameters is not possible for most mixtures containing water, helium, hydrogen, neon, carbon monoxide, fluorine, methanol, or ethanol."

which clarifies why things didn't work. I expect you would have gotten the same error message in the GUI but continued on anyhow?

JamesYatesHowden commented 6 months ago

Hi Iain,

Thanks for the quick response! You'd be correct, that I got that message in the GUI and continued anyway.

How would you advise I continue that same behaviour when using the dll?

I'd like to continue, and then I'll just include a print out with the above error message so I'm aware I'm doing something 'non-standard'.

ianhbell commented 6 months ago

Simply put: you can't(shouldn't!) do it. You need to remove components that cause nonsense binary interaction parameters to be put in the model. Otherwise the model could give you totally wrong results.

JamesYatesHowden commented 6 months ago

Thanks for clarifying that, I'll make some changes to catch those cases with nonsense interaction parameters.

I assumed by continuing in the GUI that I was acknowledging that there would be no interaction modelled for those pairings.

Could you explain a little bit more what the Refprop GUI is doing? Presumably it started with the same parameters, but is somehow producing a more believable result.

ianhbell commented 6 months ago

I can't explain why the results would be different. My only idea is that perhaps the saturation spline was enabled in the GUI and not in the DLL? It is unlikely, but it could be a bitness issue since the GUI uses the 32-bit DLL and your code uses the 64-bit one. And if the saturation spline is enabled in one case but not the other that could explain what you see.

JamesYatesHowden commented 6 months ago

I decided to run my python code with the SATSPLN routine disabled and this produced the same dew point temperature as the GUI. So it looks like that SATSPLN routine must have been disabled in the GUI somehow.

Could you clarify what actually happens when I continue on with my calculations despite getting error code 117 on setup? Is it that there is no modelling of the interaction between certain pairs and that's what results in potentially wrong results? Or are there wider implications to doing that, and if so what might they be?


from ctREFPROP.ctREFPROP import REFPROPFunctionLibrary, REFPROPInstance  # type: ignore
from os import getcwd

pressure = 145138.42

mix = [
    ('HYDROGEN.FLD',          0.346829),
    ('NITROGEN.FLD',          0.002203),
    ('CO.FLD',                0.103263),
    ('CO2.FLD',               0.318607),
    ('METHANE.FLD',           0.030366),
    ('ETHANE.FLD',            0.018206),
    ('PROPANE.FLD',           0.159881),
    ('ISOBUTAN.FLD',          0.006154),
    ('BUTANE.FLD',            0.002821),
    ('IPENTANE.FLD',          0.001154),
    ('PENTANE.FLD',           0.000641),
    ('22DIMETHYLBUTANE.FLD',  0.001282),
    ('WATER.FLD',             0.007821),
    ('HCL.FLD',               0.000003),
    ('H2S.FLD',               0.000769),
]

fluid_str = ';'.join([f'{fluid}' for fluid, _ in mix])
z = [x for _, x in mix]

dll: REFPROPInstance = REFPROPFunctionLibrary(f"{getcwd()}//calcs//refprop")
dll.SETPATHdll(f"{getcwd()}//calcs//refprop")
iUnits: int = dll.GETENUMdll(0, 'MASS BASE SI')[0]
iFlag: int = 0

setup_ierr = dll.SETFLUIDSdll(fluid_str)
if setup_ierr not in [0, 117, -117]:
    raise Exception(f'Failed to set fluid mixture! {setup_ierr}')        

r = dll.REFPROP2dll("", 'PQ', 'T', iUnits, iFlag, pressure, 1.0, z)
t_dew = r.Output[0]
if r.ierr != 0:
    raise Exception(f'Failed to calculate dew point temperature! {r.herr}')

print()
print(setup_ierr)
print()
print(r)
print()
print(t_dew - 273.15)
print()
117

REFPROP2dlloutput(z=array('d', [0.346829, 0.002203, 0.103263, 0.318607, 0.030366, 0.018206, 0.159881, 0.006154, 0.002821, 0.001154, 0.000641, 0.001282, 0.007821, 3e-06, 0.000769, 0.0, 0.0, 0.0, 0.0, 0.0]), Output=array('d', [281.8869052444022, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0, -9999990.0]), q=1.0, ierr=0, herr='K')

8.736905244402237
nist-aharvey commented 6 months ago

You should also note that asking REFPROP for a dewpoint of a system like this is dangerous, because it contains water and organics. Depending on composition, the first liquid phase to drop out might be a water-rich phase or an organic phase. @ianhbell might know more about this, but I think that because REFPROP does not currently handle systems with two liquid phases, a dew-point calculation where two liquids are competing to see which forms first could be unreliable.

ianhbell commented 6 months ago

@nist-aharvey is right - there is a warning message about the non-handling of liquid-liquid and vapor-liquid-liquid equilibria in the REFPROP GUI, and you should give thought to whether additional phase splits are likely/possible.

ianhbell commented 6 months ago

I'm closing this issue because calculations are not meaningful after setup of the mixture has failed and we do not recommend proceeding until you have a mixture that does not yield a 117 error code. I think HCl is the problem here.