簡體   English   中英

使用 Python 中 C DLL 中的函數時出現奇怪的情況

[英]Strange Occurance when using functions from C DLL in Python

我有一個奇怪的問題,我正在使用 DLL 函數返回或多或少相同的浮點值(即它們的殘差小於 1e-08),但我不知何故看到了不同的行為。

這是我在 Python 中編寫 function 原型的一般方式; 這應該足以讓您了解我是如何做這部分的。

class OWTP:

    def __init__(self):
        self._lib = CDLL("../Include/OWTP.dll")
        protoTwoParams = CFUNCTYPE(c_double, c_double, c_double)
        ptApi = (1, "P"), (1, "T")

        #properties as functions of pressure and temperature
        self.v_PT = protoTwoParams(("v_P_T", self._lib), ptApi)
        self.u_PT = protoTwoParams(("u_P_T", self._lib), ptApi)
        self.s_PT = protoTwoParams(("s_P_T", self._lib), ptApi)
        self.h_PT = protoTwoParams(("h_P_T", self._lib), ptApi)
        self.cp_PT = protoTwoParams(("cp_P_T", self._lib), ptApi)
        self.cv_PT = protoTwoParams(("cv_P_T", self._lib), ptApi)
        #much more past this point, but it's generally more of the same

接下來,我正在編寫幾個類,它們基本上是為了進行一堆計算並保存一堆屬性數據。

根class

class ThermoProperties(ABC):

    def __init__(self):
        self._P = float('nan')
        self._T = float('nan')
        self._h = float('nan')
        self._s = float('nan')
        self._u = float('nan')
        self._v = float('nan')
        self._cp = float('nan')
        self._cv = float('nan')

混凝土 class

class OrdinaryWaterThermoProperties(ThermoProperties):

    _owtp = OWTP()

    def __init__(self):
        super(ThermoProperties, self).__init__()
        self._x = float('nan')

現在對於在OrdinaryWaterThermoProperties上有問題的 function

def Set_Tx(self, T, x):
    P = self._owtp.PSat_T(T)
    self._P = P
    self._T = T
    self._v = self._owtp.v_Tx(T,x)
    self._u = self._owtp.u_Tx(T,x)
    self._s = self._owtp.s_Tx(T,x)
    self._h = self._owtp.h_Tx(T,x)
    self._x = x

    #at this point, linearly interpolate between the cps
    #and cvs @ 0 and 1 vapor quality

    if (x <= 1e-08):
        cpLow = self._owtp.cp_Ps(P, self._s)
        cvLow = self._owtp.cv_Ps(P, self._s)
    else:
        s = self._owtp.s_Tx(T,0)
        cpLow = self._owtp.cp_Ps(P, s)
        cvLow = self._owtp.cv_Ps(P, s)

    if (1.0 - x <= 1e-08):
        cpHigh = self._owtp.cp_Ps(P, self._s)
        cvHigh = self._owtp.cv_Ps(P, self._s)
    else:
        s = self._owtp.s_Tx(T,1)
        cpHigh = self._owtp.cp_Ps(P, s)
        cvHigh = self._owtp.cv_Ps(P, s)

    self._cp = cpLow + x * (cpHigh - cpLow)
    self._cv = cvLow + x * (cvHigh - cvLow)

問題是最后兩行評估為一些荒謬的數字。 起初,我顯然認為這只是我編寫的庫的問題,但是當我嘗試更多的東西時,我現在不太確定了。

如果我用這個self._s = self._owtp.s_Px(P,x)替換這條線self._s = self._owtp.s_Tx(T,x) x) ,但是一旦我進行替換,最后兩行將評估為我擁有的參考值。

是我做錯了什么還是 Python 做了什么我不知道的事情?

我只是想知道為什么會發生這種情況。

如果需要更多信息,請告訴我。

編輯:

使用這些命令:

from properties import *
p = OrdinaryWaterThermoProperties()
p.Set_Tx(507.008845,1)

#a function that does the same thing as p.Set_Tx(), but uses a different input.
p.Set_Px(3.000021637933144,1)

我生成了這些輸出:

使用p.Set_Tx(507.008845,1)后:

cpLow = 4.713721716228506
cvLow = 3.1991548400342227
cpHigh = -892771.9785675189
cvHigh = -892771.9785675189
self._s = 6.185784988287523
self._cp = -892771.9785675189
self._cv = -892771.9785675189
P = 3.000021637933144
T = 507.008845

使用p.Set_Px(3.000021637933144,1)后:

cpLow = 4.713721716228509
cvLow = 3.1991548400342205
cpHigh = 3.612225802173107
cvHigh = 2.328260186952078
self._s = 6.185784988287527
self._cp = 3.612225802173107
self._cv = 2.328260186952078
P = 3.000021637933144
T = 507.0088450000006

請注意, p.Set_Px(3.000021637933144,1)會產生self._cpself._cv的所需輸出。

經過進一步調查,似乎在self._s DLL 中 self._s 存在一個非常小的浮點誤差帶(小於 1e-10)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM