mirror of
https://github.com/CoolProp/CoolProp.git
synced 2026-04-23 03:00:17 -04:00
Fixed temperature data sets, now everything is local in the incompressible object, fixed equation selection, exponential fit works, some polynomials have too high orders...
This commit is contained in:
@@ -13,70 +13,131 @@ class IncompressibleData(object):
|
||||
Implements both data structures and fitting
|
||||
procedures.
|
||||
"""
|
||||
def __init__(self):
|
||||
self.INCOMPRESSIBLE_NOT_SET = 'notdefined'
|
||||
self.INCOMPRESSIBLE_POLYNOMIAL = 'polynomial'
|
||||
self.INCOMPRESSIBLE_EXPPOLYNOMIAL = 'exppolynomial'
|
||||
self.INCOMPRESSIBLE_EXPONENTIAL = 'exponential'
|
||||
self.INCOMPRESSIBLE_POLYOFFSET = 'polyoffset'
|
||||
self.INCOMPRESSIBLE_CHEBYSHEV = 'chebyshev'
|
||||
|
||||
self.SOURCE_DATA = 'data'
|
||||
self.SOURCE_EQUATION = 'equation'
|
||||
self.SOURCE_COEFFS = 'coefficients'
|
||||
self.SOURCE_NOT_SET = 'notdefined'
|
||||
|
||||
INCOMPRESSIBLE_NOT_SET = 'notdefined'
|
||||
INCOMPRESSIBLE_POLYNOMIAL = 'polynomial'
|
||||
INCOMPRESSIBLE_EXPPOLYNOMIAL = 'exppolynomial'
|
||||
INCOMPRESSIBLE_EXPONENTIAL = 'exponential'
|
||||
INCOMPRESSIBLE_POLYOFFSET = 'polyoffset'
|
||||
INCOMPRESSIBLE_CHEBYSHEV = 'chebyshev'
|
||||
|
||||
SOURCE_DATA = 'data'
|
||||
SOURCE_EQUATION = 'equation'
|
||||
SOURCE_COEFFS = 'coefficients'
|
||||
SOURCE_NOT_SET = 'notdefined'
|
||||
|
||||
maxLog = np.log(np.finfo(np.float64).max-1)
|
||||
minLog = -maxLog
|
||||
|
||||
def __init__(self):
|
||||
self.source = self.SOURCE_NOT_SET
|
||||
self.type = self.INCOMPRESSIBLE_NOT_SET
|
||||
self.coeffs = None #np.zeros((4,4))
|
||||
self.data = None # None #np.zeros((10,10))
|
||||
|
||||
self.maxLog = np.log(np.finfo(np.float64).max-1)
|
||||
self.minLog = -self.maxLog
|
||||
|
||||
self.xData = None # In case you need a customised first data set (temperature?)
|
||||
self.yData = None # In case you need a customised second data set (concentration?)
|
||||
self.DEBUG = False
|
||||
|
||||
@staticmethod
|
||||
def baseFunc(x, y=0.0, xbase=0.0, ybase=0.0, eqnType=None, c=None):
|
||||
|
||||
### Base functions that handle the custom data type, just a place holder to show the structure.
|
||||
def baseFunction(self, x, y=0.0, xbase=0.0, ybase=0.0, c=None):
|
||||
if c==None:
|
||||
c = self.coeffs
|
||||
|
||||
if self.type==self.INCOMPRESSIBLE_POLYNOMIAL:
|
||||
if eqnType==None: raise ValueError("You did not provide data for eqnType.")
|
||||
if c==None: raise ValueError("You did not provide data for the coefficients.")
|
||||
|
||||
if eqnType==IncompressibleData.INCOMPRESSIBLE_POLYNOMIAL:
|
||||
return np.polynomial.polynomial.polyval2d(x-xbase, y-ybase, c)
|
||||
|
||||
elif self.type==self.INCOMPRESSIBLE_POLYOFFSET:
|
||||
elif eqnType==IncompressibleData.INCOMPRESSIBLE_POLYOFFSET:
|
||||
#if y!=0.0: raise ValueError("This is 1D only, use x not y.")
|
||||
return self.basePolyOffset(c, x) # offset included in coeffs
|
||||
return IncompressibleData.basePolyOffset(c, x) # offset included in coeffs
|
||||
|
||||
elif self.type==self.INCOMPRESSIBLE_EXPONENTIAL:
|
||||
elif eqnType==IncompressibleData.INCOMPRESSIBLE_EXPONENTIAL:
|
||||
#if y!=0.0: raise ValueError("This is 1D only, use x not y.")
|
||||
return self.baseExponential(c, x)
|
||||
return IncompressibleData.baseExponential(c, x)
|
||||
|
||||
elif self.type==self.INCOMPRESSIBLE_EXPPOLYNOMIAL:
|
||||
elif eqnType==IncompressibleData.INCOMPRESSIBLE_EXPPOLYNOMIAL:
|
||||
return np.exp(np.polynomial.polynomial.polyval2d(x-xbase, y-ybase, c))
|
||||
|
||||
else:
|
||||
raise ValueError("Unknown function: {0}.".format(self.type))
|
||||
|
||||
|
||||
def baseExponential(self, co, x):
|
||||
r,c,coeffs = self.shapeArray(co)
|
||||
raise ValueError("Unknown function: {0}.".format(eqnType))
|
||||
|
||||
@staticmethod
|
||||
def baseExponential(co, x):
|
||||
r,c,coeffs = IncompressibleFitter.shapeArray(co)
|
||||
if not ( (r==3 and c==1) or (r==1 and c==3) ):
|
||||
raise ValueError("You have to provide a 3,1 matrix of coefficients, not ({0},{1}).".format(r,c))
|
||||
coeffs_tmp = np.array(coeffs.flat)
|
||||
return np.exp(np.clip( (coeffs_tmp[0]/ ( x+coeffs_tmp[1] ) - coeffs_tmp[2]),self.minLog,self.maxLog))
|
||||
return np.exp(np.clip( (coeffs_tmp[0]/ ( x+coeffs_tmp[1] ) - coeffs_tmp[2]),IncompressibleData.minLog,IncompressibleData.maxLog))
|
||||
|
||||
|
||||
def basePolyOffset(self, co, x):
|
||||
r,c,coeffs = self.shapeArray(co)
|
||||
@staticmethod
|
||||
def basePolyOffset(co, x):
|
||||
r,c,coeffs = IncompressibleFitter.shapeArray(co)
|
||||
if not ( c==1 or r==1 ):
|
||||
raise ValueError("You have to provide a 1D vector of coefficients, not ({0},{1}).".format(r,c))
|
||||
offset = coeffs[0][0]
|
||||
coeffs = np.array(coeffs.flat)[1:]
|
||||
return np.polynomial.polynomial.polyval(x-offset, coeffs)
|
||||
|
||||
|
||||
### Base functions that handle the custom data type, just a place holder to show the structure.
|
||||
def baseFunction(self, x, y=0.0, xbase=0.0, ybase=0.0, c=None):
|
||||
if c==None: c = self.coeffs
|
||||
return self.baseFunc(x, y, xbase, ybase, self.type, c)
|
||||
|
||||
def fitCoeffs(self, xbase, ybase, x=None, y=None):
|
||||
|
||||
if (x!=None and self.xData!=None and not np.allclose(x, self.xData)) \
|
||||
or (x==None and self.xData==None): raise ValueError("I do not know which x-value you would like to use. Define either x or self.xData.")
|
||||
if (y!=None and self.yData!=None and not np.allclose(y, self.yData)) \
|
||||
or (y==None and self.yData==None): raise ValueError("I do not know which y-value you would like to use. Define either y or self.yData.")
|
||||
|
||||
if x==None and self.xData!=None: x=self.xData
|
||||
if y==None and self.yData!=None: y=self.yData
|
||||
|
||||
res = IncompressibleFitter.fitter(x=x, y=y, z=self.data, \
|
||||
xbase=xbase, ybase=ybase, \
|
||||
eqnType=self.type, \
|
||||
coeffs=self.coeffs, DEBUG=self.DEBUG)
|
||||
|
||||
if res==None:
|
||||
raise ValueError("There was a fitting error.")
|
||||
elif np.allclose(res, self.coeffs):
|
||||
if self.DEBUG: print("Coefficients did not change.")
|
||||
else:
|
||||
self.coeffs = res
|
||||
|
||||
|
||||
def setxData(self, xData):
|
||||
if self.xData==None:
|
||||
self.xData = xData
|
||||
else:
|
||||
if self.DEBUG: print("Cannot update xData, value is set already.")
|
||||
|
||||
|
||||
def setyData(self, yData):
|
||||
if self.yData==None:
|
||||
self.yData = yData
|
||||
else:
|
||||
if self.DEBUG: print("Cannot update yData, value is set already.")
|
||||
|
||||
def setxyData(self, xData, yData):
|
||||
self.setxData(xData)
|
||||
self.setyData(yData)
|
||||
|
||||
|
||||
def toJSON(self):
|
||||
j = {}
|
||||
try:
|
||||
j['coeffs'] = self.coeffs.tolist()
|
||||
except:
|
||||
j['coeffs'] = 'null'
|
||||
|
||||
j['type'] = self.type
|
||||
return j
|
||||
|
||||
|
||||
|
||||
class IncompressibleFitter(object):
|
||||
|
||||
@staticmethod
|
||||
def shapeArray(array, axs=0):
|
||||
"""
|
||||
@@ -107,86 +168,110 @@ class IncompressibleData(object):
|
||||
raise ValueError("You have to provide a 1D-vector or a 2D-matrix.")
|
||||
return (r,c,np.reshape(array,(r,c)))
|
||||
|
||||
@staticmethod
|
||||
def fitter(x=None, y=None, z=None, \
|
||||
xbase=0.0, ybase=0.0, \
|
||||
eqnType=None, \
|
||||
coeffs=None, DEBUG=False):
|
||||
""" The entry point to the fitting routines
|
||||
|
||||
:param x : a 1D array in x direction or 2D with one column, most likely temperature
|
||||
:param y : a 1D array in y direction or 2D with one row, most likely cocentration
|
||||
:param z : a 2D array of data, rows = len(x[:,0]) and cols = len(y[0])
|
||||
:param xbase : a value to be subtracted from x, might not be used
|
||||
:param ybase : a value to be subtracted from y, might not be used
|
||||
:param eqnType : an instance of IncompressibleData.INCOMPRESSIBLE_ ...
|
||||
:param coeffs : the initial guess and shape (!) for the desired coefficients, can be zeros
|
||||
:param DEBUG : message to display
|
||||
|
||||
:returns : None if failed or coeffs filled with the right values
|
||||
|
||||
|
||||
def fitCoeffs(self, x=0.0, y=0.0, xbase=0.0, ybase=0.0):
|
||||
"""
|
||||
A function that selects the correct equations and
|
||||
fits coefficients. Some functions require a start
|
||||
guess for the coefficients to work properly.
|
||||
"""
|
||||
dr,dc,_ = self.shapeArray(self.data)
|
||||
xr,xc,x = self.shapeArray(x)
|
||||
yr,yc,y = self.shapeArray(y, axs=1)
|
||||
"""
|
||||
|
||||
if self.DEBUG: print("Data : ({0},{1})".format(dr,dc))
|
||||
if self.DEBUG: print("x-axis : ({0},{1})".format(xr,xc))
|
||||
if self.DEBUG: print("y-axis : ({0},{1})".format(yr,yc))
|
||||
if x==None: raise ValueError("You did not provide data for the x-values.")
|
||||
if y==None: raise ValueError("You did not provide data for the y-values.")
|
||||
if z==None: raise ValueError("You did not provide data for the z-values.")
|
||||
if xbase==None: raise ValueError("You did not provide data for xbase.")
|
||||
if ybase==None: raise ValueError("You did not provide data for ybase.")
|
||||
if eqnType==None: raise ValueError("You did not provide data for eqnType.")
|
||||
if coeffs==None: raise ValueError("You did not provide data for the coefficients.")
|
||||
if DEBUG==None: raise ValueError("You did not provide data for DEBUG.")
|
||||
|
||||
if dr==1 and dc==1: #
|
||||
if self.DEBUG: print("Data no set, we cannot fit the coefficients")
|
||||
self.coeffs = None
|
||||
self.type = self.INCOMPRESSIBLE_NOT_SET
|
||||
return
|
||||
zr,zc,_ = IncompressibleFitter.shapeArray(z)
|
||||
xr,xc,x = IncompressibleFitter.shapeArray(x)
|
||||
yr,yc,y = IncompressibleFitter.shapeArray(y, axs=1)
|
||||
|
||||
if DEBUG: print("Data : ({0},{1})".format(zr,zc))
|
||||
if DEBUG: print("x-axis : ({0},{1})".format(xr,xc))
|
||||
if DEBUG: print("y-axis : ({0},{1})".format(yr,yc))
|
||||
|
||||
if zr==1 and zc==1: #
|
||||
if DEBUG: print("Data no set, we cannot fit the coefficients")
|
||||
return None
|
||||
|
||||
if (xc!=1): raise ValueError("The first input has to be a 2D array with one column.")
|
||||
if (yr!=1): raise ValueError("The second input has to be a 2D array with one row.")
|
||||
if (xr!=dr): raise ValueError("First independent vector and result vector have to have the same number of rows, {0} is not {1}.".format(xr,dr))
|
||||
if (yc!=dc): raise ValueError("Second independent vector and result vector have to have the same number of columns, {0} is not {1}.".format(yc,dc))
|
||||
if (xr!=zr): raise ValueError("First independent vector and result vector have to have the same number of rows, {0} is not {1}.".format(xr,zr))
|
||||
if (yc!=zc): raise ValueError("Second independent vector and result vector have to have the same number of columns, {0} is not {1}.".format(yc,zc))
|
||||
|
||||
if self.DEBUG: print("Coefficients before fitting: \n{0}".format(self.coeffs))
|
||||
if DEBUG: print("Coefficients before fitting: \n{0}".format(coeffs))
|
||||
|
||||
# Polynomial fitting works for both 1D and 2D functions
|
||||
if self.type==self.INCOMPRESSIBLE_POLYNOMIAL or self.type==self.INCOMPRESSIBLE_EXPPOLYNOMIAL:
|
||||
if eqnType==IncompressibleData.INCOMPRESSIBLE_POLYNOMIAL or eqnType==IncompressibleData.INCOMPRESSIBLE_EXPPOLYNOMIAL:
|
||||
|
||||
cr,cc,_ = self.shapeArray(self.coeffs)
|
||||
if self.DEBUG: print("Coefficients: ({0},{1})".format(cr,cc))
|
||||
cr,cc,_ = IncompressibleFitter.shapeArray(coeffs)
|
||||
if DEBUG: print("Coefficients: ({0},{1})".format(cr,cc))
|
||||
if (xr==1 and xc==1 and cr>1):
|
||||
if self.DEBUG: print("Discarding coefficient rows, {0} -> {1}".format(cr,xr))
|
||||
self.coeffs = self.coeffs[0]
|
||||
self.coeffs = self.coeffs.reshape((1,cc))
|
||||
if DEBUG: print("Discarding coefficient rows, {0} -> {1}".format(cr,xr))
|
||||
coeffs = coeffs[0]
|
||||
coeffs = coeffs.reshape((1,cc))
|
||||
if (yr==1 and yc==1 and cc>1):
|
||||
if self.DEBUG: print("Discarding coefficient columns, {0} -> {1}".format(cc,yc))
|
||||
self.coeffs = self.coeffs.T[0]
|
||||
self.coeffs = self.coeffs.reshape((cr,1))
|
||||
cr,cc,_ = self.shapeArray(self.coeffs)
|
||||
if DEBUG: print("Discarding coefficient columns, {0} -> {1}".format(cc,yc))
|
||||
coeffs = coeffs.T[0]
|
||||
coeffs = coeffs.reshape((cr,1))
|
||||
cr,cc,_ = IncompressibleFitter.shapeArray(coeffs)
|
||||
|
||||
if self.DEBUG: print("polynomial detected, fitting {0}".format(self.type))
|
||||
if DEBUG: print("polynomial detected, fitting {0}".format(eqnType))
|
||||
if cr==1 and cc==1:
|
||||
if self.DEBUG: print("No coefficients left to fit, aborting procedure.")
|
||||
self.coeffs = np.array([[0.0]])
|
||||
if DEBUG: print("No coefficients left to fit, aborting procedure.")
|
||||
coeffs = np.array([[0.0]])
|
||||
return
|
||||
if (xr<cr):
|
||||
if self.DEBUG: print("Less data points than coefficients in first dimension ({0} < {1}), reducing coefficient matrix.".format(xr,cr))
|
||||
self.coeffs = self.coeffs[:xr,:]
|
||||
if DEBUG: print("Less data points than coefficients in first dimension ({0} < {1}), reducing coefficient matrix.".format(xr,cr))
|
||||
coeffs = coeffs[:xr,:]
|
||||
if (yc<cc):
|
||||
if self.DEBUG: print("Less data points than coefficients in second dimension ({0} < {1}), reducing coefficient matrix.".format(yc,cc))
|
||||
self.coeffs = self.coeffs[:,:yc]
|
||||
cr,cc,_ = self.shapeArray(self.coeffs)
|
||||
if DEBUG: print("Less data points than coefficients in second dimension ({0} < {1}), reducing coefficient matrix.".format(yc,cc))
|
||||
coeffs = coeffs[:,:yc]
|
||||
cr,cc,_ = IncompressibleFitter.shapeArray(coeffs)
|
||||
x_input = np.array(x.flat)-xbase
|
||||
y_input = np.array(y.flat)-ybase
|
||||
z_input = np.copy(self.data)
|
||||
if self.type==self.INCOMPRESSIBLE_EXPPOLYNOMIAL:
|
||||
z_input = np.copy(z)
|
||||
if eqnType==IncompressibleData.INCOMPRESSIBLE_EXPPOLYNOMIAL:
|
||||
z_input = np.log(z_input)
|
||||
self.coeffs = self.getCoeffs2d(x_input, y_input, z_input, cr-1, cc-1)
|
||||
if self.DEBUG: print("Coefficients after fitting: \n{0}".format(self.coeffs))
|
||||
return
|
||||
coeffs = IncompressibleFitter.getCoeffs2d(x_input, y_input, z_input, cr-1, cc-1, DEBUG=DEBUG)
|
||||
if DEBUG: print("Coefficients after fitting: \n{0}".format(coeffs))
|
||||
return coeffs
|
||||
|
||||
|
||||
# Select if 1D or 2D fitting
|
||||
if yc==1 or xr==1: # 1D fitting, only one input
|
||||
if self.DEBUG: print("1D function detected.")
|
||||
if DEBUG: print("1D function detected.")
|
||||
if yc==1:
|
||||
if self.DEBUG: print("Fitting {0} in x-direction.".format(self.type))
|
||||
self.coeffs = self.getCoeffsIterative1D(x, coeffs_start=None)
|
||||
if DEBUG: print("Fitting {0} in x-direction.".format(eqnType))
|
||||
coeffs = IncompressibleFitter.getCoeffsIterative1D(x, z, eqnType=eqnType, coeffs=coeffs, DEBUG=DEBUG)
|
||||
elif xr==1:
|
||||
if self.DEBUG: print("Fitting {0} in y-direction.".format(self.type))
|
||||
self.coeffs = self.getCoeffsIterative1D(y, coeffs_start=None)
|
||||
if DEBUG: print("Fitting {0} in y-direction.".format(eqnType))
|
||||
coeffs = IncompressibleFitter.getCoeffsIterative1D(y, z, eqnType=eqnType, coeffs=coeffs, DEBUG=DEBUG)
|
||||
else: raise ValueError("Unknown error in matrix shapes.")
|
||||
if self.DEBUG: print("Coefficients after fitting: \n{0}".format(self.coeffs))
|
||||
return
|
||||
if DEBUG: print("Coefficients after fitting: \n{0}".format(coeffs))
|
||||
return coeffs
|
||||
|
||||
elif yc>1: # 2D fitting
|
||||
raise ValueError("There are no other 2D fitting functions than polynomials, cannot use {0}.".format(self.type))
|
||||
raise ValueError("There are no other 2D fitting functions than polynomials, cannot use {0}.".format(eqnType))
|
||||
|
||||
else:
|
||||
raise ValueError("Unknown function.")
|
||||
@@ -202,8 +287,16 @@ class IncompressibleData(object):
|
||||
# coeffs, resids, rank, singulars = np.linalg.lstsq(A, z)
|
||||
# return np.reshape(coeffs, (len(x),1))
|
||||
|
||||
|
||||
def getCoeffs2d(self, x_in, y_in, z_in, x_order, y_order):
|
||||
@staticmethod
|
||||
def getCoeffs2d(x_in, y_in, z_in, x_order, y_order, DEBUG=False):
|
||||
|
||||
if x_in==None: raise ValueError("You did not provide data for the x-values.")
|
||||
if y_in==None: raise ValueError("You did not provide data for the y-values.")
|
||||
if z_in==None: raise ValueError("You did not provide data for the z-values.")
|
||||
if x_order==None: raise ValueError("You did not provide data for x_order.")
|
||||
if y_order==None: raise ValueError("You did not provide data for y_order.")
|
||||
if DEBUG==None: raise ValueError("You did not provide data for DEBUG.")
|
||||
|
||||
x_order += 1
|
||||
y_order += 1
|
||||
#To avoid overfitting, we only use the upper left triangle of the coefficient matrix
|
||||
@@ -250,11 +343,11 @@ class IncompressibleData(object):
|
||||
raise ValueError("Your matrix has only {0} valid rows and you try to fit {1} coefficients, please reduce the order.".format(len(A),cols))
|
||||
|
||||
coeffs, resids, rank, singulars = np.linalg.lstsq(A, zz)
|
||||
if self.DEBUG: print("Linear algebra solver returned:")
|
||||
if self.DEBUG: print(coeffs)
|
||||
if self.DEBUG: print(resids)
|
||||
if self.DEBUG: print(rank)
|
||||
if self.DEBUG: print(singulars)
|
||||
if DEBUG: print("Linear algebra solver returned:")
|
||||
if DEBUG: print(coeffs)
|
||||
if DEBUG: print(resids)
|
||||
if DEBUG: print(rank)
|
||||
if DEBUG: print(singulars)
|
||||
|
||||
#Rearrange coefficients to a matrix shape
|
||||
C = np.zeros((x_order,y_order))
|
||||
@@ -263,37 +356,38 @@ class IncompressibleData(object):
|
||||
|
||||
return C
|
||||
|
||||
|
||||
def getCoeffsIterative1D(self, xData, coeffs_start=None):
|
||||
@staticmethod
|
||||
def getCoeffsIterative1D(x_in, z_in, eqnType, coeffs, DEBUG=False):
|
||||
|
||||
if x_in==None: raise ValueError("You did not provide data for the x-values.")
|
||||
if z_in==None: raise ValueError("You did not provide data for the z-values.")
|
||||
if eqnType==None: raise ValueError("You did not provide data for eqnType.")
|
||||
if coeffs==None: raise ValueError("You did not provide data for the coefficients.")
|
||||
if DEBUG==None: raise ValueError("You did not provide data for DEBUG.")
|
||||
|
||||
#fit = "Powell" # use Powell's algorithm
|
||||
#fit = "BFGS" # use Broyden-Fletcher-Goldfarb-Shanno
|
||||
#fit = "LMA" # use the Levenberg-Marquardt algorithm from curve_fit
|
||||
fit = ["LMA","Powell","BFGS"] # First try LMA, use others as fall-back
|
||||
|
||||
if coeffs_start==None and \
|
||||
self.coeffs!=None:
|
||||
coeffs_start = self.coeffs
|
||||
|
||||
|
||||
# make sure that we use other routines for polynomials
|
||||
if (self.type==self.INCOMPRESSIBLE_POLYNOMIAL) or \
|
||||
(self.type==self.INCOMPRESSIBLE_EXPPOLYNOMIAL) :
|
||||
if (eqnType==IncompressibleData.INCOMPRESSIBLE_POLYNOMIAL) or \
|
||||
(eqnType==IncompressibleData.INCOMPRESSIBLE_EXPPOLYNOMIAL) :
|
||||
raise ValueError("Please use the specific polynomial functions, they are much better.")
|
||||
|
||||
expLog = False
|
||||
# Preprocess the exponential data
|
||||
if (self.type==self.INCOMPRESSIBLE_EXPONENTIAL):
|
||||
# Fitting the logarithm of z_in?
|
||||
if (eqnType==IncompressibleData.INCOMPRESSIBLE_EXPONENTIAL):
|
||||
expLog = True
|
||||
|
||||
xData = np.array(xData.flat)
|
||||
if expLog:
|
||||
yData = np.log(self.data.flat)
|
||||
else:
|
||||
yData = np.array(self.data.flat)
|
||||
xData = np.array(x_in.flat)
|
||||
if expLog: zData = np.log(z_in.flat)
|
||||
else: zData = np.array(z_in.flat)
|
||||
|
||||
# Remove np.nan elements
|
||||
mask = np.isfinite(yData)
|
||||
mask = np.isfinite(zData)
|
||||
xData = xData[mask]
|
||||
yData = yData[mask]
|
||||
zData = zData[mask]
|
||||
|
||||
# The residual function
|
||||
def fun(coefficients,xArray,yArray):
|
||||
@@ -304,7 +398,7 @@ class IncompressibleData(object):
|
||||
equal to None
|
||||
"""
|
||||
# No offset and no Tbase etc for 1D functions!
|
||||
calculated = self.baseFunction(xArray, 0.0, 0.0, 0.0, coefficients)
|
||||
calculated = IncompressibleData.baseFunc(xArray, y=0.0, xbase=0.0, ybase=0.0, eqnType=eqnType, c=coefficients)
|
||||
if expLog: calculated = np.log(calculated)
|
||||
if yArray==None: return calculated
|
||||
data = yArray
|
||||
@@ -327,15 +421,15 @@ class IncompressibleData(object):
|
||||
try:
|
||||
#print func(xData, coeffs_start)
|
||||
# Do the actual fitting
|
||||
popt, pcov = curve_fit(func, xData, yData, p0=coeffs_start, ftol=tolerance)
|
||||
if np.any(popt!=coeffs_start):
|
||||
popt, pcov = curve_fit(func, xData, zData, p0=coeffs, ftol=tolerance)
|
||||
if np.any(popt!=coeffs):
|
||||
success = True
|
||||
if self.DEBUG: print("Fit succeeded with: {0}".format(algorithm))
|
||||
if DEBUG: print("Fit succeeded with: {0}".format(algorithm))
|
||||
# print "Fit succeeded for "+fit[counter]+": "
|
||||
# print "data: {0}, func: {1}".format(yData[ 2],func(xData[ 2], popt))
|
||||
# print "data: {0}, func: {1}".format(yData[ 6],func(xData[ 6], popt))
|
||||
# print "data: {0}, func: {1}".format(yData[-1],func(xData[-1], popt))
|
||||
if self.DEBUG: print("Estimated covariance of parameters: ".format(pcov))
|
||||
if DEBUG: print("Estimated covariance of parameters: ".format(pcov))
|
||||
return popt
|
||||
else:
|
||||
print("Fit failed for {0}.".format(algorithm))
|
||||
@@ -350,14 +444,14 @@ class IncompressibleData(object):
|
||||
#fit = "MIN" # use a home-made minimisation with Powell and Broyden-Fletcher-Goldfarb-Shanno
|
||||
elif algorithm=="Powell" or algorithm=="BFGS":
|
||||
|
||||
arguments = (xData,yData)
|
||||
arguments = (xData,zData)
|
||||
#options = {'maxiter': 1e2, 'maxfev': 1e5}
|
||||
|
||||
try:
|
||||
res = minimize(fun, coeffs_start, method=algorithm, args=arguments, tol=tolerance)
|
||||
res = minimize(fun, coeffs, method=algorithm, args=arguments, tol=tolerance)
|
||||
if res.success:
|
||||
success = True
|
||||
if self.DEBUG: print("Fit succeeded with: {0}".format(algorithm))
|
||||
if DEBUG: print("Fit succeeded with: {0}".format(algorithm))
|
||||
return res.x
|
||||
else:
|
||||
print("Fit failed for {0}.".format(algorithm))
|
||||
@@ -376,7 +470,7 @@ class IncompressibleData(object):
|
||||
#print("Fit did not succeed with {0}, reducing tolerance to {1}.".format(algorithm,tol))
|
||||
success = False
|
||||
counter += 1
|
||||
elif tolerance<1e-6:
|
||||
elif tolerance<1e-8:
|
||||
tolerance *= 1e2
|
||||
print("Fit did not succeed, reducing tolerance to {0}.".format(tolerance))
|
||||
success = False
|
||||
@@ -385,22 +479,9 @@ class IncompressibleData(object):
|
||||
print("--------------------------------------------------------------")
|
||||
print("Fit failed for {0}. ".format(fit))
|
||||
print("--------------------------------------------------------------")
|
||||
return False
|
||||
return None
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def toJSON(self):
|
||||
j = {}
|
||||
try:
|
||||
j['coeffs'] = self.coeffs.tolist()
|
||||
except:
|
||||
j['coeffs'] = 'null'
|
||||
|
||||
j['type'] = self.type
|
||||
return j
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ class NitrateSalt(PureData,CoefficientData):
|
||||
Heat transfer fluid based on 60% NaNO3 and 40% KNO3
|
||||
"""
|
||||
def __init__(self):
|
||||
PureData.__init__(self)
|
||||
CoefficientData.__init__(self)
|
||||
CoefficientData.__init__(self)
|
||||
PureData.__init__(self)
|
||||
self.name = "NaK"
|
||||
self.description = "NitrateSalt"
|
||||
self.reference = "Solar Power Tower Design Basis Document, Alexis B. Zavoico, Sandia Labs, USA"
|
||||
|
||||
@@ -3,6 +3,7 @@ import numpy as np
|
||||
import os, math
|
||||
from BaseObjects import IncompressibleData
|
||||
from abc import ABCMeta
|
||||
from CPIncomp.BaseObjects import IncompressibleFitter
|
||||
|
||||
class SolutionData(object):
|
||||
"""
|
||||
@@ -11,13 +12,15 @@ class SolutionData(object):
|
||||
put in your data and add some documentation for where the
|
||||
information came from.
|
||||
"""
|
||||
ifrac_mass = "mass"
|
||||
ifrac_mole = "mole"
|
||||
ifrac_volume = "volume"
|
||||
ifrac_undefined = "not defined"
|
||||
ifrac_pure = "pure"
|
||||
|
||||
__metaclass__ = ABCMeta
|
||||
def __init__(self):
|
||||
self.ifrac_mass = "mass"
|
||||
self.ifrac_mole = "mole"
|
||||
self.ifrac_volume = "volume"
|
||||
self.ifrac_undefined = "not defined"
|
||||
self.ifrac_pure = "pure"
|
||||
|
||||
|
||||
self.significantDigits = 6
|
||||
|
||||
@@ -77,10 +80,10 @@ class SolutionData(object):
|
||||
|
||||
def roundSingle(self,x):
|
||||
if x==0.0: return 0.0
|
||||
return round(x, self.significantDigits-int(math.floor(math.log10(abs(x))))-1)
|
||||
return round(x, self.significantDigits-int(math.floor(math.log10(abs(x))))-1)
|
||||
|
||||
def round(self, x):
|
||||
r,c,res = IncompressibleData.shapeArray(x)
|
||||
r,c,res = IncompressibleFitter.shapeArray(x)
|
||||
#digits = -1*np.floor(np.log10(res))+self.significantDigits-1
|
||||
for i in range(r):
|
||||
for j in range(c):
|
||||
@@ -243,7 +246,7 @@ class DigitalData(SolutionData):
|
||||
|
||||
def getFromFile(self, data):
|
||||
fullPath = self.getFile(data)
|
||||
_,_,res = IncompressibleData.shapeArray(np.loadtxt(fullPath))
|
||||
_,_,res = IncompressibleFitter.shapeArray(np.loadtxt(fullPath))
|
||||
return res
|
||||
|
||||
def writeToFile(self, data, array):
|
||||
@@ -258,91 +261,90 @@ class DigitalData(SolutionData):
|
||||
return np.array([0.0])
|
||||
|
||||
def getxrange(self):
|
||||
if self.xmin<self.xmax:
|
||||
if self.xmin<self.xmax and self.xid!=self.ifrac_pure:
|
||||
return np.linspace(self.xmin, self.xmax, 20)
|
||||
else:
|
||||
return np.array([0.0])
|
||||
|
||||
def getArray(self, func=None, data=None):
|
||||
"""
|
||||
func is a callable object that takes T,x as inputs
|
||||
and data is the file name for the data.
|
||||
We try to read the file and if unsuccessful, we
|
||||
generate the data and write it.
|
||||
def getArray(self, dataID=None, func=None, x_in=None, y_in=None, DEBUG=False):
|
||||
""" Tries to read a data file, overwrites it if x or y do not match
|
||||
|
||||
:param dataID : ID to contruct the path to the data file
|
||||
:param func : Callable object that can take x_in and y_in
|
||||
:param x_in : a 1D array in x direction or 2D with one column, most likely temperature
|
||||
:param y_in : a 1D array in y direction or 2D with one row, most likely cocentration
|
||||
:param DEBUG : a boolean that controls verbosity
|
||||
|
||||
:returns : Returns a tuple with three entries: x(1D),y(1D),data(2D)
|
||||
"""
|
||||
|
||||
forceUpdate = False
|
||||
readFromFile = False
|
||||
fileArray = None
|
||||
x = None
|
||||
y = None
|
||||
z = None
|
||||
|
||||
# First we try to read the file
|
||||
if (dataID!=None and os.path.isfile(self.getFile(dataID))): # File found
|
||||
fileArray = self.getFromFile(dataID)
|
||||
x = np.copy(fileArray[1:,0 ])
|
||||
y = np.copy(fileArray[0 ,1:])
|
||||
z = np.copy(fileArray[1:,1:])
|
||||
else:
|
||||
if DEBUG: print("No readable file found for {0}: {1}".format(dataID,self.getFile(dataID)))
|
||||
|
||||
if self.temperature.data==None or self.concentration.data==None: # no data set, try to get it from file
|
||||
if self.temperature.data!=None: raise ValueError("Temperature is not None, but concentration is.")
|
||||
if self.concentration.data!=None: raise ValueError("Concentration is not None, but temperature is.")
|
||||
if (data!=None and os.path.isfile(self.getFile(data))): # File found
|
||||
fileArray = self.getFromFile(data)
|
||||
self.temperature.data = np.copy(fileArray[1:,0])
|
||||
self.concentration.data = np.copy(fileArray[0,1:])
|
||||
readFromFile = True
|
||||
else:
|
||||
raise ValueError("No temperature and concentration data given and no readable file found for {0}".format(data))
|
||||
|
||||
tData = self.round(self.temperature.data)[:,0]
|
||||
xData = self.round(self.concentration.data)[:,0]
|
||||
updateFile = DEBUG
|
||||
|
||||
baseArray = np.zeros( (len(tData)+1,len(xData)+1) )
|
||||
if x_in!=None: # Might need update
|
||||
if x!=None: # Both given, check if different
|
||||
mask = np.isfinite(x)
|
||||
if np.allclose(x[mask], x_in[mask]):
|
||||
if DEBUG: print("Both x-arrays are the same, no action required.")
|
||||
updateFile = (updateFile or False) # Do not change a True value to False
|
||||
else:
|
||||
updateFile = True
|
||||
if DEBUG: print("x-arrays do not match. {0} contains \n {1} \n and will be updated with \n {2}".format(self.getFile(dataID),x,x_in))
|
||||
else: updateFile = True
|
||||
elif x==None: raise ValueError("Could not load x from file and no x_in provided, aborting.")
|
||||
else: updateFile = (updateFile or False) # Do not change a True value to False
|
||||
|
||||
if (data!=None and os.path.isfile(self.getFile(data)) and not forceUpdate): # File found and no update wanted
|
||||
if fileArray==None: fileArray = self.getFromFile(data)
|
||||
if y_in!=None: # Might need update
|
||||
if y!=None: # Both given, check if different
|
||||
mask = np.isfinite(y)
|
||||
if np.allclose(y[mask], y_in[mask]):
|
||||
if DEBUG: print("Both y-arrays are the same, no action required.")
|
||||
updateFile = (updateFile or False) # Do not change a True value to False
|
||||
else:
|
||||
updateFile = True
|
||||
if DEBUG: print("y-arrays do not match. {0} contains \n {1} \n and will be updated with \n {2}".format(self.getFile(dataID),y,y_in))
|
||||
else: updateFile = True
|
||||
elif y==None: raise ValueError("Could not load y from file and no y_in provided, aborting.")
|
||||
else: updateFile = (updateFile or False) # Do not change a True value to False
|
||||
|
||||
# tFile = fileArray[1:,0]
|
||||
# xFile = fileArray[0,1:]
|
||||
# curDataLim = np.array([np.min(tData),np.max(tData),np.min(xData),np.max(xData)])
|
||||
# curFileLim = np.array([np.min(tFile),np.max(tFile),np.min(xFile),np.max(xFile)])
|
||||
# if np.allclose(curDataLim, curFileLim, rtol=1e-2) and fileArray.shape!=baseArray.shape: # We might have to interpolate
|
||||
# if len(tData)<len(tFile) or len(xData)<len(xFile): # OK, we can interpolate
|
||||
# data = fileArray[1:,1:]
|
||||
# if len(tFile)==1: # 1d in concentration
|
||||
# f = interpolate.interp1d(xFile, data.flat)#, kind='cubic')
|
||||
# dataNew = f(xData).reshape((1,len(xData)))
|
||||
# elif len(xFile)==1: # 1d in temperature
|
||||
# f = interpolate.interp1d(tFile, data.flat)#, kind='cubic')
|
||||
# dataNew = f(tData).reshape((len(tData),1))
|
||||
# else: # 2d
|
||||
# f = interpolate.interp2d(xFile, tFile, data)#, kind='cubic')
|
||||
# dataNew = f(xData,tData)
|
||||
# fileArray = np.copy(baseArray)
|
||||
# fileArray[1:,1:] = dataNew
|
||||
# fileArray[1:,0] = tData
|
||||
# fileArray[0,1:] = xData
|
||||
# else:
|
||||
# raise ValueError("Less points in file, not enough data for interpolation.")
|
||||
# elif fileArray.shape==baseArray.shape:
|
||||
# pass
|
||||
# else:
|
||||
# raise ValueError("The array shapes do not match. Check {0}".format(self.getFile(data)))
|
||||
|
||||
if readFromFile or fileArray.shape==baseArray.shape: # Shapes match
|
||||
if readFromFile or np.allclose(tData, fileArray[1:,0]): # Temperature data matches
|
||||
if readFromFile or np.allclose(xData, fileArray[0,1:]): # Concentration data matches
|
||||
baseArray = fileArray
|
||||
else:
|
||||
raise ValueError("Concentration arrays do not match. Check {0} \n and have a look at \n {1} \n vs \n {2} \n yielding \n {3}".format(self.getFile(data),xData,fileArray[0,1:],(xData==fileArray[0,1:])))
|
||||
else:
|
||||
raise ValueError("Temperature arrays do not match. Check {0} \n and have a look at \n {1} \n vs \n {2} \n yielding \n {3}".format(self.getFile(data),tData,fileArray[1:,0],(tData==fileArray[1:,0])))
|
||||
else:
|
||||
raise ValueError("The array shapes do not match. Check {0}".format(self.getFile(data)))
|
||||
else: # file not found or update forced
|
||||
if func==None and forceUpdate:
|
||||
raise ValueError("Need a function to update the data file.")
|
||||
for cT,T in enumerate(self.temperature.data):
|
||||
for cx,x in enumerate(self.concentration.data):
|
||||
baseArray[cT+1][cx+1] = func(T,x)
|
||||
baseArray[0,0] = np.NaN
|
||||
baseArray[1:,0] = np.copy(self.temperature.data)
|
||||
baseArray[0,1:] = np.copy(self.concentration.data)
|
||||
if data!=None: self.writeToFile(data, baseArray)
|
||||
|
||||
return np.copy(baseArray.T[1:].T[1:]) # Remove the first column and row and return
|
||||
if DEBUG: print("Updating data file {0}".format(updateFile))
|
||||
|
||||
if not updateFile: return x,y,z # Done, data read from file
|
||||
|
||||
# Overwrite inputs
|
||||
x = x_in
|
||||
y = y_in
|
||||
z = np.zeros( (len(x)+1,len(y)+1) )
|
||||
r,c = z.shape
|
||||
|
||||
if func==None: raise ValueError("Need a function to update the data file.")
|
||||
|
||||
for i in range(r-1):
|
||||
for j in range(c-1):
|
||||
z[i+1,j+1] = func(x[i],y[j])
|
||||
z[0,0 ] = np.NaN
|
||||
z[1:,0] = x
|
||||
z[0,1:] = y
|
||||
|
||||
if dataID!=None:
|
||||
self.writeToFile(dataID, z)
|
||||
else:
|
||||
if DEBUG: print("Not updating data file, dataID is missing.")
|
||||
|
||||
return x,y,z[1:,1:]
|
||||
|
||||
|
||||
|
||||
class CoefficientData(SolutionData):
|
||||
@@ -512,6 +514,7 @@ class CoefficientData(SolutionData):
|
||||
self.T_freeze.type = self.T_freeze.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.T_freeze.coeffs = self.convertMelinderArray(coeffs[0])
|
||||
self.T_freeze.coeffs[0,0] += 273.15
|
||||
self.T_freeze.coeffs = np.array([self.T_freeze.coeffs[0]])
|
||||
#print(self.T_freeze.coeffs)
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
@@ -528,7 +531,7 @@ class CoefficientData(SolutionData):
|
||||
|
||||
self.viscosity.source = self.viscosity.SOURCE_COEFFS
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.viscosity.coeffs = self.convertMelinderArray(coeffs[4])
|
||||
self.viscosity.coeffs = self.convertMelinderArray(coeffs[4])/1e3
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -48,18 +48,18 @@ class LiBrData(DigitalData):
|
||||
key = 'D'
|
||||
def funcD(T,x):
|
||||
return CP.PropsSI(key,'T',T,'P',1e8,self.name+"-{0:.4f}%".format(x*100.0))
|
||||
self.density.data = self.getArray(funcD,key)
|
||||
self.density.xData,self.density.yData,self.density.data = self.getArray(dataID=key, func=funcD, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.density.DEBUG)
|
||||
self.density.source = self.density.SOURCE_EQUATION
|
||||
|
||||
key = 'C'
|
||||
def funcC(T,x):
|
||||
return CP.PropsSI(key,'T',T,'P',1e8,self.name+"-{0:.4f}%".format(x*100.0))
|
||||
self.specific_heat.data = self.getArray(funcC,key)
|
||||
self.specific_heat.xData,self.specific_heat.yData,self.specific_heat.data = self.getArray(dataID=key, func=funcC, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.specific_heat.DEBUG)
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_EQUATION
|
||||
|
||||
key = 'Psat'
|
||||
def funcP(T,x):
|
||||
return CP.PropsSI(key,'T',T,'P',1e8,self.name+"-{0:.4f}%".format(x*100.0))
|
||||
self.saturation_pressure.data = self.getArray(funcP,key)
|
||||
self.saturation_pressure.xData,self.saturation_pressure.yData,self.saturation_pressure.data = self.getArray(dataID=key, func=funcP, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.saturation_pressure.DEBUG)
|
||||
self.saturation_pressure.source = self.saturation_pressure.SOURCE_EQUATION
|
||||
|
||||
|
||||
@@ -81,15 +81,63 @@ class DigitalExample(DigitalData):
|
||||
|
||||
def funcRho(T,x):
|
||||
return T + x*100.0 + T*(x+0.5)
|
||||
self.density.data = self.getArray(funcRho,"rho")
|
||||
self.density.xData,self.density.yData,self.density.data = self.getArray(dataID="D", func=funcRho, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.density.DEBUG)
|
||||
self.density.source = self.density.SOURCE_EQUATION
|
||||
|
||||
def funcCp(T,x):
|
||||
return T + x*50.0 + T*(x+0.6)
|
||||
self.specific_heat.data = self.getArray(funcCp,"cp")
|
||||
|
||||
self.density.source = self.density.SOURCE_EQUATION
|
||||
self.specific_heat.xData,self.specific_heat.yData,self.specific_heat.data = self.getArray(dataID="C", func=funcCp, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.specific_heat.DEBUG)
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_EQUATION
|
||||
|
||||
class DigitalExamplePure(PureData,DigitalData):
|
||||
def __init__(self):
|
||||
DigitalData.__init__(self)
|
||||
PureData.__init__(self)
|
||||
|
||||
self.name = "ExampleDigitalPure"
|
||||
self.description = "water"
|
||||
self.reference = "none"
|
||||
|
||||
self.Tmin = 280.00;
|
||||
self.Tmax = 500.00;
|
||||
|
||||
self.TminPsat = self.Tmin;
|
||||
|
||||
self.temperature.data = self.getTrange()
|
||||
self.concentration.data = self.getxrange()
|
||||
|
||||
import CoolProp.CoolProp as CP
|
||||
|
||||
def funcD(T,x):
|
||||
return CP.PropsSI('D','T',T,'P',1e7,'water')
|
||||
def funcC(T,x):
|
||||
return CP.PropsSI('C','T',T,'P',1e7,'water')
|
||||
def funcL(T,x):
|
||||
return CP.PropsSI('L','T',T,'P',1e7,'water')
|
||||
def funcV(T,x):
|
||||
return CP.PropsSI('V','T',T,'P',1e7,'water')
|
||||
def funcP(T,x):
|
||||
return CP.PropsSI('P','T',T,'Q',0.0,'water')
|
||||
|
||||
self.density.xData,self.density.yData,self.density.data = self.getArray(dataID="D", func=funcD, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.density.DEBUG)
|
||||
self.density.source = self.density.SOURCE_EQUATION
|
||||
|
||||
self.specific_heat.xData,self.specific_heat.yData,self.specific_heat.data = self.getArray(dataID="C", func=funcC, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.specific_heat.DEBUG)
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_EQUATION
|
||||
|
||||
self.conductivity.xData,self.conductivity.yData,self.conductivity.data = self.getArray(dataID="L", func=funcL, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.conductivity.DEBUG)
|
||||
self.conductivity.source = self.conductivity.SOURCE_EQUATION
|
||||
|
||||
self.viscosity.xData,self.viscosity.yData,self.viscosity.data = self.getArray(dataID="V", func=funcV, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.viscosity.DEBUG)
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
|
||||
self.saturation_pressure.xData,self.saturation_pressure.yData,self.saturation_pressure.data = self.getArray(dataID="P", func=funcP, x_in=self.temperature.data, y_in=self.concentration.data,DEBUG=self.saturation_pressure.DEBUG)
|
||||
self.saturation_pressure.source = self.saturation_pressure.SOURCE_EQUATION
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class SecCoolExample(CoefficientData):
|
||||
"""
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from __future__ import division, print_function
|
||||
import numpy as np
|
||||
from CPIncomp.DataObjects import PureData,CoefficientData
|
||||
from CPIncomp.BaseObjects import IncompressibleFitter
|
||||
|
||||
|
||||
class DEBLiquidClass(CoefficientData,PureData):
|
||||
@@ -19,16 +20,16 @@ class DEBLiquidClass(CoefficientData,PureData):
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.density.coeffs = self.density.shapeArray(np.array([1076.5,-0.731182]))
|
||||
_,_,self.density.coeffs = IncompressibleFitter.shapeArray(np.array([1076.5,-0.731182]))
|
||||
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.specific_heat.coeffs = self.specific_heat.shapeArray(np.array([999.729,2.87576]))
|
||||
_,_,self.specific_heat.coeffs = IncompressibleFitter.shapeArray(np.array([999.729,2.87576]))
|
||||
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
_,_,self.viscosity.coeffs = self.viscosity.shapeArray(np.array([3.5503,-0.0566396,7.03331e-05]))
|
||||
_,_,self.viscosity.coeffs = IncompressibleFitter.shapeArray(np.array([3.5503,-0.0566396,7.03331e-05]))
|
||||
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.conductivity.coeffs = self.conductivity.shapeArray(np.array([0.000189132,-2.06364e-07]))
|
||||
_,_,self.conductivity.coeffs = IncompressibleFitter.shapeArray(np.array([0.000189132,-2.06364e-07]))
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_COEFFS
|
||||
@@ -52,16 +53,16 @@ class HCMLiquidClass(CoefficientData,PureData):
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.density.coeffs = self.density.shapeArray(np.array([971.725,-0.718788]))
|
||||
_,_,self.density.coeffs = IncompressibleFitter.shapeArray(np.array([971.725,-0.718788]))
|
||||
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.specific_heat.coeffs = self.specific_heat.shapeArray(np.array([844.023,4.31212]))
|
||||
_,_,self.specific_heat.coeffs = IncompressibleFitter.shapeArray(np.array([844.023,4.31212]))
|
||||
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
_,_,self.viscosity.coeffs = self.viscosity.shapeArray(np.array([18.3237,-0.14706,0.000209096]))
|
||||
_,_,self.viscosity.coeffs = IncompressibleFitter.shapeArray(np.array([18.3237,-0.14706,0.000209096]))
|
||||
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.conductivity.coeffs = self.conductivity.shapeArray(np.array([0.000153716,-1.51212e-07]))
|
||||
_,_,self.conductivity.coeffs = IncompressibleFitter.shapeArray(np.array([0.000153716,-1.51212e-07]))
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_COEFFS
|
||||
@@ -85,16 +86,16 @@ class HFELiquidClass(CoefficientData,PureData):
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.density.coeffs = self.density.shapeArray(np.array([1822.37,-0.918485]))
|
||||
_,_,self.density.coeffs = IncompressibleFitter.shapeArray(np.array([1822.37,-0.918485]))
|
||||
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.specific_heat.coeffs = self.specific_heat.shapeArray(np.array([871.834,858788]))
|
||||
_,_,self.specific_heat.coeffs = IncompressibleFitter.shapeArray(np.array([871.834,858788]))
|
||||
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
_,_,self.viscosity.coeffs = self.viscosity.shapeArray(np.array([-4.22878,-0.0114765,7.39823e-06]))
|
||||
_,_,self.viscosity.coeffs = IncompressibleFitter.shapeArray(np.array([-4.22878,-0.0114765,7.39823e-06]))
|
||||
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.conductivity.coeffs = self.conductivity.shapeArray(np.array([9.92958e-05,-8.33333e-08]))
|
||||
_,_,self.conductivity.coeffs = IncompressibleFitter.shapeArray(np.array([9.92958e-05,-8.33333e-08]))
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_COEFFS
|
||||
@@ -118,16 +119,16 @@ class PMS1LiquidClass(CoefficientData,PureData):
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.density.coeffs = self.density.shapeArray(np.array([1172.35,-0.9025]))
|
||||
_,_,self.density.coeffs = IncompressibleFitter.shapeArray(np.array([1172.35,-0.9025]))
|
||||
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.specific_heat.coeffs = self.specific_heat.shapeArray(np.array([1223.69,1.48417]))
|
||||
_,_,self.specific_heat.coeffs = IncompressibleFitter.shapeArray(np.array([1223.69,1.48417]))
|
||||
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
_,_,self.viscosity.coeffs = self.viscosity.shapeArray(np.array([6.36183,-0.0636352,7.51428e-05]))
|
||||
_,_,self.viscosity.coeffs = IncompressibleFitter.shapeArray(np.array([6.36183,-0.0636352,7.51428e-05]))
|
||||
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.conductivity.coeffs = self.conductivity.shapeArray(np.array([0.000207526,-2.84167e-07]))
|
||||
_,_,self.conductivity.coeffs = IncompressibleFitter.shapeArray(np.array([0.000207526,-2.84167e-07]))
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_COEFFS
|
||||
@@ -151,16 +152,16 @@ class PMS2LiquidClass(CoefficientData,PureData):
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.density.coeffs = self.density.shapeArray(np.array([1155.94,-1.02576]))
|
||||
_,_,self.density.coeffs = IncompressibleFitter.shapeArray(np.array([1155.94,-1.02576]))
|
||||
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.specific_heat.coeffs = self.specific_heat.shapeArray(np.array([1153.55,2.10788]))
|
||||
_,_,self.specific_heat.coeffs = IncompressibleFitter.shapeArray(np.array([1153.55,2.10788]))
|
||||
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
_,_,self.viscosity.coeffs = self.viscosity.shapeArray(np.array([5.66926,-0.065582,8.09988e-05]))
|
||||
_,_,self.viscosity.coeffs = IncompressibleFitter.shapeArray(np.array([5.66926,-0.065582,8.09988e-05]))
|
||||
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.conductivity.coeffs = self.conductivity.shapeArray(np.array([0.000172305,-2.11212e-07]))
|
||||
_,_,self.conductivity.coeffs = IncompressibleFitter.shapeArray(np.array([0.000172305,-2.11212e-07]))
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_COEFFS
|
||||
@@ -184,16 +185,16 @@ class SABLiquidClass(CoefficientData,PureData):
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.density.coeffs = self.density.shapeArray(np.array([1102.34,-0.801667]))
|
||||
_,_,self.density.coeffs = IncompressibleFitter.shapeArray(np.array([1102.34,-0.801667]))
|
||||
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.specific_heat.coeffs = self.specific_heat.shapeArray(np.array([1360.94,1.51667]))
|
||||
_,_,self.specific_heat.coeffs = IncompressibleFitter.shapeArray(np.array([1360.94,1.51667]))
|
||||
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
_,_,self.viscosity.coeffs = self.viscosity.shapeArray(np.array([5.21288,-0.0665792,8.5066e-05]))
|
||||
_,_,self.viscosity.coeffs = IncompressibleFitter.shapeArray(np.array([5.21288,-0.0665792,8.5066e-05]))
|
||||
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.conductivity.coeffs = self.conductivity.shapeArray(np.array([0.000208374,-2.61667e-07]))
|
||||
_,_,self.conductivity.coeffs = IncompressibleFitter.shapeArray(np.array([0.000208374,-2.61667e-07]))
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_COEFFS
|
||||
@@ -217,16 +218,16 @@ class HCBLiquidClass(CoefficientData,PureData):
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.density.coeffs = self.density.shapeArray(np.array([1071.78,-0.772024]))
|
||||
_,_,self.density.coeffs = IncompressibleFitter.shapeArray(np.array([1071.78,-0.772024]))
|
||||
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.specific_heat.coeffs = self.specific_heat.shapeArray(np.array([761.393,3.52976]))
|
||||
_,_,self.specific_heat.coeffs = IncompressibleFitter.shapeArray(np.array([761.393,3.52976]))
|
||||
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
_,_,self.viscosity.coeffs = self.viscosity.shapeArray(np.array([7.16819,-0.0863212,0.000130604]))
|
||||
_,_,self.viscosity.coeffs = IncompressibleFitter.shapeArray(np.array([7.16819,-0.0863212,0.000130604]))
|
||||
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.conductivity.coeffs = self.conductivity.shapeArray(np.array([0.000203186,-2.3869e-07]))
|
||||
_,_,self.conductivity.coeffs = IncompressibleFitter.shapeArray(np.array([0.000203186,-2.3869e-07]))
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_COEFFS
|
||||
@@ -250,16 +251,16 @@ class TCOLiquidClass(CoefficientData,PureData):
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.density.coeffs = self.density.shapeArray(np.array([1071.02,-0.778166]))
|
||||
_,_,self.density.coeffs = IncompressibleFitter.shapeArray(np.array([1071.02,-0.778166]))
|
||||
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.specific_heat.coeffs = self.specific_heat.shapeArray(np.array([223.775,5.2159]))
|
||||
_,_,self.specific_heat.coeffs = IncompressibleFitter.shapeArray(np.array([223.775,5.2159]))
|
||||
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
_,_,self.viscosity.coeffs = self.viscosity.shapeArray(np.array([-3.47971,-0.0107031,1.14086e-06]))
|
||||
_,_,self.viscosity.coeffs = IncompressibleFitter.shapeArray(np.array([-3.47971,-0.0107031,1.14086e-06]))
|
||||
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
_,_,self.conductivity.coeffs = self.conductivity.shapeArray(np.array([0.000174156,-1.85052e-07]))
|
||||
_,_,self.conductivity.coeffs = IncompressibleFitter.shapeArray(np.array([0.000174156,-1.85052e-07]))
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_COEFFS
|
||||
|
||||
@@ -4,6 +4,7 @@ from BaseObjects import IncompressibleData
|
||||
from DataObjects import DigitalData, PureData
|
||||
import os, sys
|
||||
from scipy import interpolate
|
||||
from CPIncomp.BaseObjects import IncompressibleFitter
|
||||
|
||||
class SecCoolSolutionData(DigitalData):
|
||||
"""
|
||||
@@ -27,7 +28,7 @@ class SecCoolSolutionData(DigitalData):
|
||||
self.description = desc
|
||||
self.reference = ref
|
||||
|
||||
self.density.data = self.getArray(data='Rho')
|
||||
self.temperature.data,self.concentration.data,self.density.data = self.getArray(dataID='Rho')
|
||||
|
||||
self.Tmax = np.max(self.temperature.data)
|
||||
self.Tmin = np.min(self.temperature.data)
|
||||
@@ -43,9 +44,6 @@ class SecCoolSolutionData(DigitalData):
|
||||
raise ValueError("Unknown folder type specified.")
|
||||
self.TminPsat = self.Tmax
|
||||
|
||||
self.Tbase = (self.Tmin + self.Tmax) / 2.0
|
||||
self.xbase = (self.xmin + self.xmax) / 2.0
|
||||
|
||||
|
||||
# def interp(self, tOld, xOld, dataNew):
|
||||
# tCur = self.temperature.data
|
||||
@@ -63,164 +61,139 @@ class SecCoolSolutionData(DigitalData):
|
||||
# data = f(xOld,tOld)
|
||||
# return data
|
||||
|
||||
def interp(self, tOld, xOld, dataNew):
|
||||
tCur = self.temperature.data
|
||||
xCur = self.concentration.data
|
||||
|
||||
data = None
|
||||
if len(tCur)==1: # 1d in concentration
|
||||
f = interpolate.InterpolatedUnivariateSpline(xCur, dataNew.flat, k=1)
|
||||
data = f(xOld).reshape((1,len(xOld)))
|
||||
elif len(xCur)==1: # 1d in temperature
|
||||
f = interpolate.InterpolatedUnivariateSpline(tCur, dataNew.flat, k=1)
|
||||
data = f(tOld).reshape((len(tOld),1))
|
||||
else: # 2d
|
||||
#f = interpolate.SmoothBivariateSpline(xCur, tCur, dataNew, kx=1, ky=1)
|
||||
f = interpolate.interp2d(xCur, tCur, dataNew)#, kind='cubic')
|
||||
data = f(xOld,tOld)
|
||||
return data
|
||||
|
||||
|
||||
|
||||
# def interp(self, tOld, xOld, dataNew):
|
||||
# tCur = self.temperature.data
|
||||
# xCur = self.concentration.data
|
||||
#
|
||||
# data = None
|
||||
# if len(tCur)==1: # 1d in concentration
|
||||
# f = interpolate.InterpolatedUnivariateSpline(xCur, dataNew.flat, k=1)
|
||||
# data = f(xOld).reshape((1,len(xOld)))
|
||||
# elif len(xCur)==1: # 1d in temperature
|
||||
# f = interpolate.InterpolatedUnivariateSpline(tCur, dataNew.flat, k=1)
|
||||
# data = f(tOld).reshape((len(tOld),1))
|
||||
# else: # 2d
|
||||
# #f = interpolate.SmoothBivariateSpline(xCur, tCur, dataNew, kx=1, ky=1)
|
||||
# f = interpolate.interp2d(xCur, tCur, dataNew)#, kind='cubic')
|
||||
# data = f(xOld,tOld)
|
||||
# return data
|
||||
|
||||
#def extrap(self, x, xp, yp):
|
||||
# """np.interp function with linear extrapolation"""
|
||||
# y = np.interp(x, xp, yp)
|
||||
# y[x < xp[0]] = yp[0] + (x[x<xp[0]]-xp[0]) * (yp[0]-yp[1]) / (xp[0]-xp[1])
|
||||
# y[x > xp[-1]]= yp[-1] + (x[x>xp[-1]]-xp[-1])*(yp[-1]-yp[-2])/(xp[-1]-xp[-2])
|
||||
# return y
|
||||
|
||||
|
||||
|
||||
|
||||
def fitFluid(self):
|
||||
|
||||
if self.Tbase==None:
|
||||
self.Tbase = (self.Tmin + self.Tmax) / 2.0
|
||||
if self.xbase==None:
|
||||
self.xbase = (self.xmin + self.xmax) / 2.0
|
||||
|
||||
std_coeffs = np.zeros((4,6))
|
||||
errList = (ValueError, AttributeError, TypeError, RuntimeError)
|
||||
|
||||
tempData = np.copy(self.temperature.data)
|
||||
concData = np.copy(self.concentration.data)
|
||||
|
||||
|
||||
try:
|
||||
self.temperature.data = None
|
||||
self.concentration.data = None
|
||||
self.density.data = self.getArray(data='Rho')
|
||||
self.density.xData,self.density.yData,self.density.data = self.getArray(dataID="Rho")
|
||||
self.density.coeffs = np.copy(std_coeffs)
|
||||
self.density.source = self.density.SOURCE_DATA
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.density.fitCoeffs(tempData,concData,self.Tbase,self.xbase)
|
||||
self.density.data = self.interp(tempData, concData, self.density.data)
|
||||
self.density.fitCoeffs(self.Tbase,self.xbase)
|
||||
except errList as ve:
|
||||
if self.density.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'density',ve))
|
||||
pass
|
||||
|
||||
try:
|
||||
self.temperature.data = None
|
||||
self.concentration.data = None
|
||||
self.specific_heat.data = self.getArray(data='Cp')
|
||||
self.specific_heat.xData,self.specific_heat.yData,self.specific_heat.data = self.getArray(dataID='Cp')
|
||||
while np.max(self.specific_heat.data[np.isfinite(self.specific_heat.data)])<500: # Expect values around 1e3
|
||||
self.specific_heat.data *= 1e3
|
||||
self.specific_heat.coeffs = np.copy(std_coeffs)
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_DATA
|
||||
self.specific_heat.type = self.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.specific_heat.fitCoeffs(tempData,concData,self.Tbase,self.xbase)
|
||||
self.specific_heat.data = self.interp(tempData, concData, self.specific_heat.data)
|
||||
self.specific_heat.fitCoeffs(self.Tbase,self.xbase)
|
||||
except errList as ve:
|
||||
if self.specific_heat.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'specific heat',ve))
|
||||
pass
|
||||
|
||||
try:
|
||||
self.temperature.data = None
|
||||
self.concentration.data = None
|
||||
self.conductivity.data = self.getArray(data='Cond')
|
||||
self.conductivity.xData,self.conductivity.yData,self.conductivity.data = self.getArray(data='Cond')
|
||||
while np.max(self.conductivity.data[np.isfinite(self.conductivity.data)])>10: # Expect value below 1
|
||||
self.conductivity.data *= 1e-3
|
||||
self.conductivity.coeffs = np.copy(std_coeffs)
|
||||
self.conductivity.source = self.conductivity.SOURCE_DATA
|
||||
self.conductivity.type = self.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.conductivity.fitCoeffs(tempData,concData,self.Tbase,self.xbase)
|
||||
self.conductivity.data = self.interp(tempData, concData, self.conductivity.data)
|
||||
self.conductivity.fitCoeffs(self.Tbase,self.xbase)
|
||||
except errList as ve:
|
||||
if self.conductivity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'conductivity',ve))
|
||||
pass
|
||||
|
||||
try:
|
||||
self.temperature.data = None
|
||||
self.concentration.data = None
|
||||
self.viscosity.data = self.getArray(data='Mu')
|
||||
self.viscosity.xData,self.viscosity.yData,self.viscosity.data = self.getArray(data='Mu')
|
||||
while np.max(self.viscosity.data[np.isfinite(self.viscosity.data)])>100: # Expect value below 10
|
||||
self.viscosity.data *= 1e-3
|
||||
self.viscosity.coeffs = np.copy(std_coeffs)
|
||||
self.viscosity.source = self.viscosity.SOURCE_DATA
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.fitCoeffs(tempData,concData,self.Tbase,self.xbase)
|
||||
self.viscosity.data = self.interp(tempData, concData, self.viscosity.data)
|
||||
self.viscosity.fitCoeffs(self.Tbase,self.xbase)
|
||||
except errList as ve:
|
||||
if self.viscosity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'viscosity',ve))
|
||||
pass
|
||||
|
||||
# reset data for getArray and read special files
|
||||
if self.xid!=self.ifrac_pure and self.xid!=self.ifrac_undefined:
|
||||
self.temperature.data = None
|
||||
self.concentration.data = None
|
||||
allowNegativeData_org = self.allowNegativeData
|
||||
self.allowNegativeData = True
|
||||
Tfreeze_T = self.getArray(data='TFreeze')
|
||||
if np.min(Tfreeze_T)<150: Tfreeze_T += 273.15
|
||||
Tfreeze_x = (self.temperature.data - 273.15) / 100.0
|
||||
self.T_freeze.data = Tfreeze_T.T
|
||||
self.temperature.data = [0.0]
|
||||
self.concentration.data = Tfreeze_x
|
||||
|
||||
x,_,z = self.getArray(dataID='TFreeze')
|
||||
self.T_freeze.yData = (x - 273.15) / 100.0
|
||||
self.T_freeze.xData = [0.0]
|
||||
if np.min(z)<150: z += 273.15
|
||||
self.T_freeze.data = z.T
|
||||
|
||||
try:
|
||||
self.T_freeze.source = self.T_freeze.SOURCE_DATA
|
||||
if np.isfinite(self.T_freeze.data).sum()<0:
|
||||
if np.isfinite(self.T_freeze.data).sum()<2:
|
||||
self.T_freeze.coeffs = np.array([+7e+6, +6e+4, +1e+1])
|
||||
self.T_freeze.type = self.T_freeze.INCOMPRESSIBLE_EXPONENTIAL
|
||||
else:
|
||||
self.T_freeze.coeffs = np.zeros(np.round(np.array(std_coeffs.shape) * 2))
|
||||
self.T_freeze.type = self.T_freeze.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.T_freeze.fitCoeffs([0.0],Tfreeze_x,0.0,self.xbase)
|
||||
self.T_freeze.data = self.interp([0.0], concData, self.T_freeze.data)
|
||||
self.T_freeze.fitCoeffs(self.Tbase,self.xbase)
|
||||
except errList as ve:
|
||||
if self.T_freeze.DEBUG: print("{0}: Could not fit {1} coefficients: {2}".format(self.name,"T_freeze",ve))
|
||||
pass
|
||||
|
||||
# reset data for getArray again
|
||||
self.temperature.data = None
|
||||
self.concentration.data = None
|
||||
self.allowNegativeData = allowNegativeData_org
|
||||
massData = self.getArray(data='Vol2Mass')[:,0]/100.0
|
||||
volData = (self.temperature.data - 273.15) /100.0
|
||||
x,_,z = self.getArray(dataID='Vol2Mass')
|
||||
massData = z[:,0] /100.0
|
||||
volData = (x - 273.15) /100.0
|
||||
if self.xid==self.ifrac_volume:
|
||||
_,_,self.mass2input.data = IncompressibleData.shapeArray(volData,axs=1)
|
||||
#_,_,massData = IncompressibleData.shapeArray(massData,axs=1)
|
||||
_,_,self.mass2input.data = IncompressibleFitter.shapeArray(volData,axs=1)
|
||||
self.mass2input.xData = [0.0]
|
||||
self.mass2input.yData = massData
|
||||
try:
|
||||
self.mass2input.coeffs = np.copy(std_coeffs)
|
||||
self.mass2input.source = self.mass2input.SOURCE_DATA
|
||||
self.mass2input.type = self.mass2input.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.mass2input.fitCoeffs([self.Tbase],massData,self.Tbase,self.xbase)
|
||||
self.mass2input.fitCoeffs(self.Tbase,self.xbase)
|
||||
except errList as ve:
|
||||
if self.mass2input.DEBUG: print("{0}: Could not fit {1} coefficients: {2}".format(self.name,"mass2input",ve))
|
||||
pass
|
||||
elif self.xid==self.ifrac_mass:
|
||||
_,_,self.volume2input.data = IncompressibleData.shapeArray(massData,axs=1)
|
||||
#_,_,volData = IncompressibleData.shapeArray(volData,axs=1)
|
||||
_,_,self.volume2input.data = IncompressibleFitter.shapeArray(massData,axs=1)
|
||||
self.volume2input.xData = [0.0]
|
||||
self.volume2input.yData = volData
|
||||
try:
|
||||
self.volume2input.coeffs = np.copy(std_coeffs)
|
||||
self.volume2input.source = self.volume2input.SOURCE_DATA
|
||||
self.volume2input.type = self.volume2input.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.volume2input.fitCoeffs([self.Tbase],volData,self.Tbase,self.xbase)
|
||||
self.volume2input.fitCoeffs(self.Tbase,self.xbase)
|
||||
except errList as ve:
|
||||
if self.volume2input.DEBUG: print("{0}: Could not fit {1} coefficients: {2}".format(self.name,"volume2input",ve))
|
||||
pass
|
||||
else:
|
||||
raise ValueError("Unknown xid specified.")
|
||||
|
||||
# reset temperature and concentration to real values
|
||||
self.temperature.data = tempData
|
||||
self.concentration.data = concData
|
||||
#self.Tbase = -4.48 + 273.15
|
||||
#self.xbase = 31.57 / 100.0
|
||||
|
||||
|
||||
# Redefine some functions to avoid data loss
|
||||
def getFile(self, data):
|
||||
@@ -229,7 +202,7 @@ class SecCoolSolutionData(DigitalData):
|
||||
|
||||
def getFromFile(self, data):
|
||||
fullPath = self.getFile(data)
|
||||
r,c,res = IncompressibleData.shapeArray(np.loadtxt(fullPath,dtype=type('string')))
|
||||
r,c,res = IncompressibleFitter.shapeArray(np.loadtxt(fullPath,dtype=type('string')))
|
||||
# numbers = res.astype(np.float)
|
||||
numbers = np.zeros((r,c))
|
||||
for i in range(r):
|
||||
@@ -384,9 +357,9 @@ class ThermogenVP1869(PureData,DigitalData):
|
||||
"""
|
||||
Source: SecCool Software
|
||||
"""
|
||||
def __init__(self):
|
||||
PureData.__init__(self)
|
||||
DigitalData.__init__(self)
|
||||
def __init__(self):
|
||||
DigitalData.__init__(self)
|
||||
PureData.__init__(self)
|
||||
self.name = "TVP1869"
|
||||
self.description = "Thermogen VP 1869"
|
||||
self.reference = "Hoechst, SecCool software"
|
||||
@@ -420,10 +393,11 @@ class ThermogenVP1869(PureData,DigitalData):
|
||||
return (341.3688975+T*(-0.713408301+0.017723992*T))/ \
|
||||
(1+T*(0.034502393+T*(0.000401319+1.57288E-06*T)))*1e-2
|
||||
|
||||
self.viscosity.data = self.getArray(funcMu,key)
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.xData,self.viscosity.yData,self.viscosity.data = self.getArray(dataID=key,func=funcMu,x_in=self.temperature.data,y_in=self.concentration.data)
|
||||
|
||||
try:
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.coeffs = np.zeros((4,6))
|
||||
self.viscosity.fitCoeffs(self.temperature.data,self.concentration.data,self.Tbase,self.xbase)
|
||||
except (ValueError, AttributeError, TypeError, RuntimeError) as e:
|
||||
@@ -469,12 +443,13 @@ class Freezium(DigitalData):
|
||||
T = (T-self.Tbase)/100.0
|
||||
return (4.15*np.exp(-0.9*x)+0.63*T*x)*1000.0
|
||||
|
||||
self.specific_heat.data = self.getArray(funcCp,key)
|
||||
self.specific_heat.source = self.specific_heat.SOURCE_EQUATION
|
||||
self.specific_heat.type = self.viscosity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.specific_heat.xData,self.specific_heat.yData,self.specific_heat.data = self.getArray(dataID=key,func=funcCp,x_in=self.temperature.data,y_in=self.concentration.data,DEBUG=self.specific_heat.DEBUG)
|
||||
|
||||
try:
|
||||
self.specific_heat.source = IncompressibleData.SOURCE_EQUATION
|
||||
self.specific_heat.type = IncompressibleData.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.specific_heat.coeffs = np.zeros((4,6))
|
||||
self.specific_heat.fitCoeffs(self.temperature.data,self.concentration.data,self.Tbase,self.xbase)
|
||||
self.specific_heat.fitCoeffs(self.Tbase,self.xbase)
|
||||
except (ValueError, AttributeError, TypeError, RuntimeError) as e:
|
||||
if self.specific_heat.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'specific heat',e))
|
||||
pass
|
||||
@@ -487,12 +462,13 @@ class Freezium(DigitalData):
|
||||
result = 0.32+x*(-0.70+x*2.26)+Tr*(-1.26+Tr*(1.12-Tr*0.894))
|
||||
return self.rho(T, 1e6, x)*np.power(10,result)*1E-3;
|
||||
|
||||
self.viscosity.data = self.getArray(funcMu,key)
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.xData,self.viscosity.yData,self.viscosity.data = self.getArray(dataID=key,func=funcMu,x_in=self.temperature.data,y_in=self.concentration.data,DEBUG=self.viscosity.DEBUG)
|
||||
|
||||
try:
|
||||
self.viscosity.source = IncompressibleData.SOURCE_EQUATION
|
||||
self.viscosity.type = IncompressibleData.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.coeffs = np.zeros((4,6))
|
||||
self.viscosity.fitCoeffs(self.temperature.data,self.concentration.data,self.Tbase,self.xbase)
|
||||
self.viscosity.fitCoeffs(self.Tbase,self.xbase)
|
||||
except (ValueError, AttributeError, TypeError, RuntimeError) as e:
|
||||
if self.viscosity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'viscosity',e))
|
||||
pass
|
||||
@@ -501,7 +477,7 @@ class Freezium(DigitalData):
|
||||
|
||||
# Changed the coefficient order for TFreeze
|
||||
key = 'Tfreeze'
|
||||
def funcTf(x,T):
|
||||
def funcTf(T,x):
|
||||
x = x * 100.0
|
||||
a = 0.03422039835160944
|
||||
b = -0.05425629002714395
|
||||
@@ -515,14 +491,12 @@ class Freezium(DigitalData):
|
||||
j = 4.314861246570078E-11
|
||||
return ((a+x*(c+x*(e+x*(g+i*x))))/(1+x*(b+x*(d+x*(f+x*(h+j*x)))))*100)+273.15
|
||||
|
||||
# Change the coefficients for TFreeze
|
||||
self.T_freeze.data = self.getArray(funcTf,key)
|
||||
self.T_freeze.xData,self.T_freeze.yData,self.T_freeze.data = self.getArray(dataID=key,func=funcTf,x_in=np.array([0.0]),y_in=self.concentration.data,DEBUG=self.T_freeze.DEBUG)
|
||||
try:
|
||||
self.T_freeze.coeffs = np.zeros((4,6))
|
||||
self.T_freeze.source = self.T_freeze.SOURCE_EQUATION
|
||||
self.T_freeze.type = self.T_freeze.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.T_freeze.fitCoeffs(0.0,self.concentration.data,0.0,self.xbase)
|
||||
self.T_freeze.data = self.interp([0.0], self.concentration.data, self.T_freeze.data)
|
||||
self.T_freeze.source = IncompressibleData.SOURCE_EQUATION
|
||||
self.T_freeze.type = IncompressibleData.INCOMPRESSIBLE_POLYNOMIAL
|
||||
self.T_freeze.fitCoeffs(self.Tbase,self.xbase)
|
||||
except (ValueError, AttributeError, TypeError, RuntimeError) as e:
|
||||
if self.T_freeze.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'T freeze',e))
|
||||
pass
|
||||
@@ -533,8 +507,8 @@ class Freezium(DigitalData):
|
||||
|
||||
class AS10(PureData,DigitalData):
|
||||
def __init__(self):
|
||||
PureData.__init__(self)
|
||||
DigitalData.__init__(self)
|
||||
PureData.__init__(self)
|
||||
self.name = "AS10"
|
||||
self.description = "Aspen Temper -10, Potassium acetate/formate"
|
||||
self.reference = "Aspen Petroleum AB, SecCool software"
|
||||
@@ -544,8 +518,6 @@ class AS10(PureData,DigitalData):
|
||||
self.TminPsat = self.Tmax
|
||||
self.Tbase = 0.00 + 273.15
|
||||
self.temperature.data = self.getTrange()
|
||||
self.concentration.data = np.array([0]) # mass fraction
|
||||
self.xid = self.ifrac_pure
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
@@ -571,8 +543,8 @@ class AS10(PureData,DigitalData):
|
||||
|
||||
class AS20(PureData,DigitalData):
|
||||
def __init__(self):
|
||||
PureData.__init__(self)
|
||||
DigitalData.__init__(self)
|
||||
PureData.__init__(self)
|
||||
self.name = "AS20"
|
||||
self.description = "Aspen Temper -20, Potassium acetate/formate"
|
||||
self.reference = "Aspen Petroleum AB, SecCool software"
|
||||
@@ -582,8 +554,6 @@ class AS20(PureData,DigitalData):
|
||||
self.TminPsat = self.Tmax
|
||||
self.Tbase = 0.00 + 273.15
|
||||
self.temperature.data = self.getTrange()
|
||||
self.concentration.data = np.array([0]) # mass fraction
|
||||
self.xid = self.ifrac_pure
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
@@ -604,12 +574,13 @@ class AS20(PureData,DigitalData):
|
||||
T = (T-self.Tbase)
|
||||
return 2.43708721027941*np.exp(-0.0537593944541809*T) + 0.97244
|
||||
|
||||
self.viscosity.data = self.getArray(funcMu,key)
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.xData,self.viscosity.yData,self.viscosity.data = self.getArray(dataID=key,func=funcMu,x_in=self.temperature.data,y_in=self.concentration.data,DEBUG=self.viscosity.DEBUG)
|
||||
|
||||
try:
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.coeffs = np.zeros((4,6))
|
||||
self.viscosity.fitCoeffs(self.temperature.data,self.concentration.data,self.Tbase,self.xbase)
|
||||
self.viscosity.fitCoeffs(self.Tbase,self.xbase)
|
||||
except (ValueError, AttributeError, TypeError, RuntimeError) as e:
|
||||
if self.viscosity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'viscosity',e))
|
||||
pass
|
||||
@@ -620,8 +591,8 @@ class AS20(PureData,DigitalData):
|
||||
|
||||
class AS30(PureData,DigitalData):
|
||||
def __init__(self):
|
||||
PureData.__init__(self)
|
||||
DigitalData.__init__(self)
|
||||
PureData.__init__(self)
|
||||
self.name = "AS30"
|
||||
self.description = "Aspen Temper -30, Potassium acetate/formate"
|
||||
self.reference = "Aspen Petroleum AB, SecCool software"
|
||||
@@ -631,8 +602,6 @@ class AS30(PureData,DigitalData):
|
||||
self.TminPsat = self.Tmax
|
||||
self.Tbase = 0.00 + 273.15
|
||||
self.temperature.data = self.getTrange()
|
||||
self.concentration.data = np.array([0]) # mass fraction
|
||||
self.xid = self.ifrac_pure
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
@@ -653,12 +622,13 @@ class AS30(PureData,DigitalData):
|
||||
T = (T-self.Tbase)
|
||||
return 2.65653950695888*np.exp(-0.0598806339442954*T) + 1.30143
|
||||
|
||||
self.viscosity.data = self.getArray(funcMu,key)
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.xData,self.viscosity.yData,self.viscosity.data = self.getArray(dataID=key,func=funcMu,x_in=self.temperature.data,y_in=self.concentration.data,DEBUG=self.viscosity.DEBUG)
|
||||
|
||||
try:
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.coeffs = np.zeros((4,6))
|
||||
self.viscosity.fitCoeffs(self.temperature.data,self.concentration.data,self.Tbase,self.xbase)
|
||||
self.viscosity.fitCoeffs(self.Tbase,self.xbase)
|
||||
except (ValueError, AttributeError, TypeError, RuntimeError) as e:
|
||||
if self.viscosity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'viscosity',e))
|
||||
pass
|
||||
@@ -669,8 +639,8 @@ class AS30(PureData,DigitalData):
|
||||
|
||||
class AS40(PureData,DigitalData):
|
||||
def __init__(self):
|
||||
PureData.__init__(self)
|
||||
DigitalData.__init__(self)
|
||||
PureData.__init__(self)
|
||||
self.name = "AS40"
|
||||
self.description = "Aspen Temper -40, Potassium acetate/formate"
|
||||
self.reference = "Aspen Petroleum AB, SecCool software"
|
||||
@@ -680,8 +650,6 @@ class AS40(PureData,DigitalData):
|
||||
self.TminPsat = self.Tmax
|
||||
self.Tbase = 0.00 + 273.15
|
||||
self.temperature.data = self.getTrange()
|
||||
self.concentration.data = np.array([0]) # mass fraction
|
||||
self.xid = self.ifrac_pure
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
@@ -701,12 +669,13 @@ class AS40(PureData,DigitalData):
|
||||
T = (T-self.Tbase)
|
||||
return 0.714976365635003*np.exp(-0.100050525515385*T) + 4.38768154440393*np.exp(-0.0260039000649317*T)
|
||||
|
||||
self.viscosity.data = self.getArray(funcMu,key)
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.xData,self.viscosity.yData,self.viscosity.data = self.getArray(dataID=key,func=funcMu,x_in=self.temperature.data,y_in=self.concentration.data,DEBUG=self.viscosity.DEBUG)
|
||||
|
||||
try:
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.coeffs = np.zeros((4,6))
|
||||
self.viscosity.fitCoeffs(self.temperature.data,self.concentration.data,self.Tbase,self.xbase)
|
||||
self.viscosity.fitCoeffs(self.Tbase,self.xbase)
|
||||
except (ValueError, AttributeError, TypeError, RuntimeError) as e:
|
||||
if self.viscosity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'viscosity',e))
|
||||
pass
|
||||
@@ -717,8 +686,8 @@ class AS40(PureData,DigitalData):
|
||||
|
||||
class AS55(PureData,DigitalData):
|
||||
def __init__(self):
|
||||
PureData.__init__(self)
|
||||
DigitalData.__init__(self)
|
||||
PureData.__init__(self)
|
||||
self.name = "AS55"
|
||||
self.description = "Aspen Temper -55, Potassium acetate/formate"
|
||||
self.reference = "Aspen Petroleum AB, SecCool software"
|
||||
@@ -728,8 +697,6 @@ class AS55(PureData,DigitalData):
|
||||
self.TminPsat = self.Tmax
|
||||
self.Tbase = 0.00 + 273.15
|
||||
self.temperature.data = self.getTrange()
|
||||
self.concentration.data = np.array([0]) # mass fraction
|
||||
self.xid = self.ifrac_pure
|
||||
|
||||
self.density.source = self.density.SOURCE_COEFFS
|
||||
self.density.type = self.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
@@ -750,12 +717,13 @@ class AS55(PureData,DigitalData):
|
||||
T = (T-self.Tbase)
|
||||
return 0.159583223482554*np.exp(-0.138097704125669*T) + 6.3176967296442*np.exp(-0.0380509974688477*T)
|
||||
|
||||
self.viscosity.data = self.getArray(funcMu,key)
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.xData,self.viscosity.yData,self.viscosity.data = self.getArray(dataID=key,func=funcMu,x_in=self.temperature.data,y_in=self.concentration.data,DEBUG=self.viscosity.DEBUG)
|
||||
|
||||
try:
|
||||
self.viscosity.source = self.viscosity.SOURCE_EQUATION
|
||||
self.viscosity.type = self.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
self.viscosity.coeffs = np.zeros((4,6))
|
||||
self.viscosity.fitCoeffs(self.temperature.data,self.concentration.data,self.Tbase,self.xbase)
|
||||
self.viscosity.fitCoeffs(self.Tbase,self.xbase)
|
||||
except (ValueError, AttributeError, TypeError, RuntimeError) as e:
|
||||
if self.viscosity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(self.name,'viscosity',e))
|
||||
pass
|
||||
|
||||
@@ -18,15 +18,20 @@ class SolutionDataWriter(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def fitAll(self, fluidObject):
|
||||
def fitAll(self, fluidObject=SolutionData()):
|
||||
|
||||
tempData = fluidObject.temperature.data
|
||||
concData = fluidObject.concentration.data
|
||||
|
||||
if fluidObject.Tbase==0.0 or fluidObject.Tbase==None:
|
||||
fluidObject.Tbase = (np.min(tempData) + np.max(tempData)) / 2.0
|
||||
if fluidObject.xbase==0.0 or fluidObject.xbase==None:
|
||||
fluidObject.xbase = (np.min(concData) + np.max(concData)) / 2.0
|
||||
|
||||
if fluidObject.Tbase==None:
|
||||
fluidObject.Tbase = (fluidObject.Tmin + fluidObject.Tmax) / 2.0
|
||||
|
||||
if fluidObject.xbase==None:
|
||||
fluidObject.xbase = (fluidObject.xmin + fluidObject.xmax) / 2.0
|
||||
|
||||
tData = fluidObject.temperature.data
|
||||
xData = fluidObject.concentration.data
|
||||
tBase = fluidObject.Tbase
|
||||
xBase = fluidObject.xbase
|
||||
|
||||
# Set the standard order for polynomials
|
||||
std_xorder = 3+1
|
||||
@@ -36,65 +41,73 @@ class SolutionDataWriter(object):
|
||||
errList = (ValueError, AttributeError, TypeError, RuntimeError)
|
||||
|
||||
try:
|
||||
fluidObject.density.setxyData(tData,xData)
|
||||
fluidObject.density.coeffs = np.copy(std_coeffs)
|
||||
fluidObject.density.type = fluidObject.density.INCOMPRESSIBLE_POLYNOMIAL
|
||||
fluidObject.density.fitCoeffs(tempData,concData,fluidObject.Tbase,fluidObject.xbase)
|
||||
fluidObject.density.type = IncompressibleData.INCOMPRESSIBLE_POLYNOMIAL
|
||||
fluidObject.density.fitCoeffs(tBase,xBase)
|
||||
except errList as ve:
|
||||
if fluidObject.density.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(fluidObject.name,'density',ve))
|
||||
pass
|
||||
|
||||
try:
|
||||
fluidObject.specific_heat.setxyData(tData,xData)
|
||||
fluidObject.specific_heat.coeffs = np.copy(std_coeffs)
|
||||
fluidObject.specific_heat.type = fluidObject.specific_heat.INCOMPRESSIBLE_POLYNOMIAL
|
||||
fluidObject.specific_heat.fitCoeffs(tempData,concData,fluidObject.Tbase,fluidObject.xbase)
|
||||
fluidObject.specific_heat.type = IncompressibleData.INCOMPRESSIBLE_POLYNOMIAL
|
||||
fluidObject.specific_heat.fitCoeffs(tBase,xBase)
|
||||
except errList as ve:
|
||||
if fluidObject.specific_heat.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(fluidObject.name,'specific heat',ve))
|
||||
pass
|
||||
|
||||
try:
|
||||
fluidObject.conductivity.setxyData(tData,xData)
|
||||
fluidObject.conductivity.coeffs = np.copy(std_coeffs)
|
||||
fluidObject.conductivity.type = fluidObject.conductivity.INCOMPRESSIBLE_POLYNOMIAL
|
||||
fluidObject.conductivity.fitCoeffs(tempData,concData,fluidObject.Tbase,fluidObject.xbase)
|
||||
fluidObject.conductivity.type = IncompressibleData.INCOMPRESSIBLE_POLYNOMIAL
|
||||
fluidObject.conductivity.fitCoeffs(tBase,xBase)
|
||||
except errList as ve:
|
||||
if fluidObject.conductivity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(fluidObject.name,'conductivity',ve))
|
||||
pass
|
||||
|
||||
try:
|
||||
if len(concData)==1 and np.isfinite(fluidObject.viscosity.data).sum()<10:
|
||||
fluidObject.viscosity.setxyData(tData,xData)
|
||||
tried = False
|
||||
if len(fluidObject.viscosity.yData)==1:# and np.isfinite(fluidObject.viscosity.data).sum()<10:
|
||||
fluidObject.viscosity.coeffs = np.array([+7e+2, -6e+1, +1e+1])
|
||||
fluidObject.viscosity.type = fluidObject.viscosity.INCOMPRESSIBLE_EXPONENTIAL
|
||||
else:
|
||||
fluidObject.viscosity.coeffs = np.zeros(np.round(np.array(std_coeffs.shape) * 2))
|
||||
fluidObject.viscosity.type = fluidObject.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
#fluidObject.viscosity.coeffs = np.copy(std_coeffs)
|
||||
#fluidObject.viscosity.type = fluidObject.viscosity.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
fluidObject.viscosity.fitCoeffs(tempData,concData,fluidObject.Tbase,fluidObject.xbase)
|
||||
fluidObject.viscosity.type = IncompressibleData.INCOMPRESSIBLE_EXPONENTIAL
|
||||
fluidObject.viscosity.fitCoeffs(tBase,xBase)
|
||||
if fluidObject.viscosity.coeffs==None or np.allclose(fluidObject.viscosity.coeffs, np.array([+7e+2, -6e+1, +1e+1])): # Fit failed
|
||||
tried = True
|
||||
if len(fluidObject.viscosity.yData)>1 or tried:
|
||||
fluidObject.viscosity.coeffs = np.zeros(np.round(np.array(std_coeffs.shape) * 1.5))
|
||||
fluidObject.viscosity.type = IncompressibleData.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
fluidObject.viscosity.fitCoeffs(tBase,xBase)
|
||||
except errList as ve:
|
||||
if fluidObject.viscosity.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(fluidObject.name,'viscosity',ve))
|
||||
pass
|
||||
|
||||
try:
|
||||
if len(concData)==1 and np.isfinite(fluidObject.saturation_pressure.data).sum()<10:
|
||||
fluidObject.saturation_pressure.setxyData(tData,xData)
|
||||
if len(fluidObject.saturation_pressure.yData)==1:# and np.isfinite(fluidObject.saturation_pressure.data).sum()<10:
|
||||
fluidObject.saturation_pressure.coeffs = np.array([-5e+3, +6e+1, -1e+1])
|
||||
fluidObject.saturation_pressure.type = fluidObject.saturation_pressure.INCOMPRESSIBLE_EXPONENTIAL
|
||||
fluidObject.saturation_pressure.type = IncompressibleData.INCOMPRESSIBLE_EXPONENTIAL
|
||||
else:
|
||||
fluidObject.saturation_pressure.coeffs = np.zeros(np.round(np.array(std_coeffs.shape) * 2))
|
||||
fluidObject.saturation_pressure.type = fluidObject.saturation_pressure.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
fluidObject.saturation_pressure.fitCoeffs(tempData,concData,fluidObject.Tbase,fluidObject.xbase)
|
||||
fluidObject.saturation_pressure.coeffs = np.zeros(np.round(np.array(std_coeffs.shape) * 1.5))
|
||||
fluidObject.saturation_pressure.type = IncompressibleData.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
fluidObject.saturation_pressure.fitCoeffs(tBase,xBase)
|
||||
except errList as ve:
|
||||
if fluidObject.saturation_pressure.DEBUG: print("{0}: Could not fit polynomial {1} coefficients: {2}".format(fluidObject.name,'saturation pressure',ve))
|
||||
pass
|
||||
|
||||
# reset data for getArray and read special files
|
||||
if fluidObject.xid!=fluidObject.ifrac_pure and fluidObject.xid!=fluidObject.ifrac_undefined:
|
||||
fluidObject.T_freeze.setxyData([0.0],xData)
|
||||
try:
|
||||
if np.isfinite(fluidObject.T_freeze.data).sum()<0:
|
||||
if len(fluidObject.T_freeze.xData)==1 and np.isfinite(fluidObject.T_freeze.data).sum()<2:
|
||||
fluidObject.T_freeze.coeffs = np.array([+7e+2, -6e+1, +1e+1])
|
||||
fluidObject.T_freeze.type = fluidObject.T_freeze.INCOMPRESSIBLE_EXPONENTIAL
|
||||
fluidObject.T_freeze.type = IncompressibleData.INCOMPRESSIBLE_EXPONENTIAL
|
||||
else:
|
||||
fluidObject.T_freeze.coeffs = np.zeros(np.round(np.array(std_coeffs.shape) * 2))
|
||||
fluidObject.T_freeze.type = fluidObject.T_freeze.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
fluidObject.T_freeze.fitCoeffs(0.0,concData,0.0,fluidObject.xbase)
|
||||
fluidObject.T_freeze.coeffs = np.zeros(np.round(np.array(std_coeffs.shape) * 1))
|
||||
fluidObject.T_freeze.type = IncompressibleData.INCOMPRESSIBLE_EXPPOLYNOMIAL
|
||||
fluidObject.T_freeze.fitCoeffs(tBase,xBase)
|
||||
except errList as ve:
|
||||
if fluidObject.T_freeze.DEBUG: print("{0}: Could not fit {1} coefficients: {2}".format(fluidObject.name,"T_freeze",ve))
|
||||
pass
|
||||
@@ -240,7 +253,7 @@ class SolutionDataWriter(object):
|
||||
print("An error occurred for fluid: {0}".format(obj.name))
|
||||
print(obj)
|
||||
print(e)
|
||||
pass
|
||||
pass
|
||||
print(" ... done")
|
||||
return
|
||||
|
||||
@@ -370,6 +383,7 @@ class SolutionDataWriter(object):
|
||||
if np.all(solObj.T_freeze.coeffs==dataObj.coeffs):
|
||||
xFunction = True
|
||||
except AttributeError as ae:
|
||||
if False: print(ae)
|
||||
pass
|
||||
|
||||
points = 30
|
||||
@@ -386,8 +400,11 @@ class SolutionDataWriter(object):
|
||||
dataFormatter['marker'] = 'o'
|
||||
dataFormatter['ls'] = 'none'
|
||||
|
||||
tData = solObj.temperature.data
|
||||
xData = solObj.concentration.data
|
||||
|
||||
dataObj.setxyData(solObj.temperature.data,solObj.concentration.data)
|
||||
|
||||
tData = dataObj.xData
|
||||
xData = dataObj.yData
|
||||
pData = 1e7 # 100 bar
|
||||
zData = dataObj.data
|
||||
|
||||
@@ -398,7 +415,7 @@ class SolutionDataWriter(object):
|
||||
for j in range(c):
|
||||
zError[i,j]= func(tData[i],pData,xData[j])
|
||||
|
||||
zError = self.relError(zData, zError, PCT=True)
|
||||
zError = self.relError(zData, zError) * 1e2
|
||||
|
||||
if xFunction: axis = 1
|
||||
else: axis = 0
|
||||
@@ -487,8 +504,8 @@ class SolutionDataWriter(object):
|
||||
pData = xData
|
||||
pFunc = xFunc
|
||||
else:
|
||||
pData = tData
|
||||
pFunc = tFunc
|
||||
pData = tData - 273.15
|
||||
pFunc = tFunc - 273.15
|
||||
|
||||
if zData!=None and axVal!=None:
|
||||
axVal.plot(pData, zData, label='data', **dataFormatter)
|
||||
@@ -499,7 +516,7 @@ class SolutionDataWriter(object):
|
||||
if zError!=None and axErr!=None:
|
||||
axErr.plot(pData, zError, label='error' , **errorFormatter)
|
||||
if solObj.xid!=solObj.ifrac_pure and not xFunction:
|
||||
axErr.set_title("largest error at x={0}".format(xData[0]))
|
||||
axErr.set_title("showing x={0:3.2f}".format(xData[0]))
|
||||
else:
|
||||
axErr.set_title(" ")
|
||||
elif axErr!=None:
|
||||
@@ -508,6 +525,8 @@ class SolutionDataWriter(object):
|
||||
#axErr.xaxis.set_visible(False)
|
||||
#axErr.yaxis.set_visible(False)
|
||||
#axErr.plot(pData, zFunc, label='function' , **fitFormatter)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -626,7 +645,7 @@ class SolutionDataWriter(object):
|
||||
|
||||
# First we determine some basic settings
|
||||
|
||||
gs = gridspec.GridSpec(4, 2, height_ratios=[2,3,3,3])
|
||||
gs = gridspec.GridSpec(4, 2, wspace=None, hspace=None, height_ratios=[2.5,3,3,3])
|
||||
#gs.update(top=0.75, hspace=0.05)
|
||||
div = 22
|
||||
fig = plt.figure(figsize=(210/div,297/div))
|
||||
@@ -635,66 +654,113 @@ class SolutionDataWriter(object):
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# Info text settings
|
||||
infoText = {}
|
||||
infoText['ha'] = 'center'
|
||||
infoText['va'] = 'baseline'
|
||||
infoText['fontsize'] = 'smaller'
|
||||
infoText['xycoords'] =('axes fraction', 'axes fraction')
|
||||
|
||||
# Setting the labels
|
||||
errLabel = r'$\mathdefault{rel.\/Error\/[\%]}$'
|
||||
#errLabel = ur'$\mathdefault{rel.\/Error\/[\u2030]}$'
|
||||
errLabel = r'$\mathdefault{rel.\/Error\/[\%]}$'
|
||||
tempLabel = ur'$\mathdefault{Temperature\/(\u00B0C)}$'
|
||||
|
||||
if solObj.density.source!=solObj.density.SOURCE_NOT_SET:
|
||||
density_axis = plt.subplot(gs[1,0])
|
||||
density_error = density_axis.twinx()
|
||||
density_axis.set_ylabel(r'Density [$\mathdefault{kg/m^3\!}$]')
|
||||
density_error.set_ylabel(errLabel)
|
||||
density_axis = plt.subplot(gs[1,0])
|
||||
density_error = density_axis.twinx()
|
||||
density_axis.set_ylabel(r'Density [$\mathdefault{kg/m^3\!}$]')
|
||||
density_axis.set_xlabel(tempLabel)
|
||||
density_error.set_ylabel(errLabel)
|
||||
if solObj.density.source!=solObj.density.SOURCE_NOT_SET:
|
||||
self.plotValues(density_axis,density_error,solObj=solObj,dataObj=solObj.density,func=solObj.rho)
|
||||
else:
|
||||
raise ValueError("Density data has to be provided!")
|
||||
|
||||
|
||||
capacity_axis = plt.subplot(gs[1,1])
|
||||
capacity_error = capacity_axis.twinx()
|
||||
capacity_axis.set_ylabel(r'Heat Capacity [$\mathdefault{J/kg/K}$]')
|
||||
capacity_axis.set_xlabel(tempLabel)
|
||||
capacity_error.set_ylabel(errLabel)
|
||||
if solObj.specific_heat.source!=solObj.specific_heat.SOURCE_NOT_SET:
|
||||
capacity_axis = plt.subplot(gs[1,1])
|
||||
capacity_error = capacity_axis.twinx()
|
||||
capacity_axis.set_ylabel(r'Heat Capacity [$\mathdefault{J/kg/K}$]')
|
||||
capacity_error.set_ylabel(errLabel)
|
||||
self.plotValues(capacity_axis,capacity_error,solObj=solObj,dataObj=solObj.specific_heat,func=solObj.c)
|
||||
else:
|
||||
raise ValueError("Specific heat data has to be provided!")
|
||||
|
||||
# Optional plots, might not all be shown
|
||||
conductivity_axis = plt.subplot(gs[2,0])#, sharex=density_axis)
|
||||
conductivity_error = conductivity_axis.twinx()
|
||||
conductivity_axis.set_ylabel(r'Thermal Conductivity [$\mathdefault{W/m/K}$]')
|
||||
conductivity_axis.set_xlabel(tempLabel)
|
||||
conductivity_error.set_ylabel(errLabel)
|
||||
if solObj.conductivity.source!=solObj.conductivity.SOURCE_NOT_SET:
|
||||
conductivity_axis = plt.subplot(gs[2,0])#, sharex=density_axis)
|
||||
conductivity_error = conductivity_axis.twinx()
|
||||
conductivity_axis.set_ylabel(r'Thermal Conductivity [$\mathdefault{W/m/K}$]')
|
||||
conductivity_error.set_ylabel(errLabel)
|
||||
self.plotValues(conductivity_axis,conductivity_error,solObj=solObj,dataObj=solObj.conductivity,func=solObj.cond)
|
||||
else:
|
||||
#conductivity_axis.xaxis.set_visible(False)
|
||||
#conductivity_axis.yaxis.set_visible(False)
|
||||
#conductivity_error.xaxis.set_visible(False)
|
||||
#conductivity_error.yaxis.set_visible(False)
|
||||
conductivity_axis.annotate("No conductivity information",xy=(0.5,0.5),**infoText)
|
||||
|
||||
viscosity_axis = plt.subplot(gs[2,1])#, sharex=capacity_axis)
|
||||
viscosity_error = viscosity_axis.twinx()
|
||||
viscosity_axis.set_yscale('log')
|
||||
viscosity_axis.set_ylabel(r'Dynamic Viscosity [$\mathdefault{Pa\/s}$]')
|
||||
viscosity_axis.set_xlabel(tempLabel)
|
||||
viscosity_error.set_ylabel(errLabel)
|
||||
if solObj.viscosity.source!=solObj.viscosity.SOURCE_NOT_SET:
|
||||
viscosity_axis = plt.subplot(gs[2,1])#, sharex=capacity_axis)
|
||||
viscosity_error = viscosity_axis.twinx()
|
||||
viscosity_axis.set_yscale('log')
|
||||
viscosity_axis.set_ylabel(r'Dynamic Viscosity [$\mathdefault{Pa\/s}$]')
|
||||
viscosity_error.set_ylabel(errLabel)
|
||||
self.plotValues(viscosity_axis,viscosity_error,solObj=solObj,dataObj=solObj.viscosity,func=solObj.visc)
|
||||
|
||||
self.plotValues(viscosity_axis,viscosity_error,solObj=solObj,dataObj=solObj.viscosity,func=solObj.visc)
|
||||
else:
|
||||
#viscosity_axis.xaxis.set_visible(False)
|
||||
#viscosity_axis.yaxis.set_visible(False)
|
||||
#viscosity_error.xaxis.set_visible(False)
|
||||
#viscosity_error.yaxis.set_visible(False)
|
||||
viscosity_axis.annotate("No viscosity information",xy=(0.5,0.5),**infoText)
|
||||
|
||||
saturation_axis = plt.subplot(gs[3,0])#, sharex=density_axis)
|
||||
saturation_error = saturation_axis.twinx()
|
||||
saturation_axis.set_yscale('log')
|
||||
saturation_axis.set_ylabel(r'Saturation Pressure [$\mathdefault{Pa}$]')
|
||||
saturation_axis.set_xlabel(tempLabel)
|
||||
saturation_error.set_ylabel(errLabel)
|
||||
if solObj.saturation_pressure.source != solObj.saturation_pressure.SOURCE_NOT_SET: # exists
|
||||
saturation_axis = plt.subplot(gs[3,0])#, sharex=density_axis)
|
||||
saturation_error = saturation_axis.twinx()
|
||||
saturation_axis.set_yscale('log')
|
||||
saturation_axis.set_ylabel(r'Saturation Pressure [$\mathdefault{Pa}$]')
|
||||
saturation_error.set_ylabel(errLabel)
|
||||
self.plotValues(saturation_axis,saturation_error,solObj=solObj,dataObj=solObj.saturation_pressure,func=solObj.psat)
|
||||
else:
|
||||
#saturation_axis.xaxis.set_visible(False)
|
||||
#saturation_axis.yaxis.set_visible(False)
|
||||
#saturation_error.xaxis.set_visible(False)
|
||||
#saturation_error.yaxis.set_visible(False)
|
||||
saturation_axis.annotate("No saturation state information",xy=(0.5,0.5),**infoText)
|
||||
|
||||
Tfreeze_axis = plt.subplot(gs[3,1])#, sharex=capacity_axis)
|
||||
Tfreeze_error = Tfreeze_axis.twinx()
|
||||
Tfreeze_axis.set_ylabel(r'Freezing Temperature [$\mathdefault{K}$]')
|
||||
Tfreeze_axis.set_xlabel("{0} fraction".format(solObj.xid.title()))
|
||||
Tfreeze_error.set_ylabel(errLabel)
|
||||
if solObj.T_freeze.source != solObj.T_freeze.SOURCE_NOT_SET: # exists
|
||||
Tfreeze_axis = plt.subplot(gs[3,1])#, sharex=capacity_axis)
|
||||
Tfreeze_error = Tfreeze_axis.twinx()
|
||||
Tfreeze_axis.set_ylabel(r'Freezing Temperature [$\mathdefault{K}$]')
|
||||
Tfreeze_error.set_ylabel(errLabel)
|
||||
self.plotValues(Tfreeze_axis,Tfreeze_error,solObj=solObj,dataObj=solObj.T_freeze,func=solObj.Tfreeze)
|
||||
else:
|
||||
#Tfreeze_axis.xaxis.set_visible(False)
|
||||
#Tfreeze_axis.yaxis.set_visible(False)
|
||||
#Tfreeze_error.xaxis.set_visible(False)
|
||||
#Tfreeze_error.yaxis.set_visible(False)
|
||||
Tfreeze_axis.annotate("No freezing point information",xy=(0.5,0.5),**infoText)
|
||||
Tfreeze_axis.set_xlabel("Fraction")
|
||||
|
||||
#saturation_axis = plt.subplot2grid((3,2), (2,0))
|
||||
#Tfreeze_axis = plt.subplot2grid((3,2), (2,0))
|
||||
#mass2input_axis = plt.subplot2grid((3,2), (2,0))
|
||||
#volume2input_axis = plt.subplot2grid((3,2), (2,0))
|
||||
|
||||
# Set a minimum error level
|
||||
minAbsErrorScale = 0.05 # in per cent
|
||||
for a in fig.axes:
|
||||
if a.get_ylabel()==errLabel:
|
||||
mi,ma = a.get_ylim()
|
||||
if mi>-minAbsErrorScale: a.set_ylim(bottom=-minAbsErrorScale)
|
||||
if ma< minAbsErrorScale: a.set_ylim( top= minAbsErrorScale)
|
||||
|
||||
|
||||
|
||||
# print headlines etc.
|
||||
self.printFluidInfo(table_axis, solObj)
|
||||
# Prepare the legend
|
||||
|
||||
@@ -10,21 +10,25 @@ if __name__ == '__main__':
|
||||
writer = SolutionDataWriter()
|
||||
doneObjs = []
|
||||
|
||||
# To debug single fluids
|
||||
from CPIncomp.SecCoolFluids import Freezium
|
||||
#solObjs = [SecCoolSolutionData(sFile='Melinder, Ammonia' ,sFolder='xMass',name='MAM2',desc='Melinder, Ammonia' ,ref='Melinder-BOOK-2010, SecCool software')]
|
||||
solObjs = [Freezium()]
|
||||
solObjs[0].T_freeze.DEBUG = True
|
||||
writer.fitSecCoolList(solObjs)
|
||||
#
|
||||
##from CPIncomp.ExampleObjects import SecCoolExample
|
||||
##solObjs = [SecCoolExample()]
|
||||
writer.writeFluidList(solObjs)
|
||||
writer.writeReportList(solObjs)
|
||||
sys.exit(0)
|
||||
# # To debug single fluids
|
||||
# from CPIncomp.SecCoolFluids import Freezium
|
||||
# #solObjs = [SecCoolSolutionData(sFile='Melinder, Ammonia' ,sFolder='xMass',name='MAM2',desc='Melinder, Ammonia' ,ref='Melinder-BOOK-2010, SecCool software')]
|
||||
# solObjs = [Freezium()]
|
||||
# #solObjs[0].density.DEBUG = True
|
||||
# #solObjs[0].specific_heat.DEBUG = True
|
||||
# #solObjs[0].conductivity.DEBUG = True
|
||||
# #solObjs[0].viscosity.DEBUG = True
|
||||
# solObjs[0].T_freeze.DEBUG = True
|
||||
# writer.fitSecCoolList(solObjs)
|
||||
# #
|
||||
# ##from CPIncomp.ExampleObjects import SecCoolExample
|
||||
# ##solObjs = [SecCoolExample()]
|
||||
# writer.writeFluidList(solObjs)
|
||||
# writer.writeReportList(solObjs)
|
||||
# sys.exit(0)
|
||||
|
||||
fluidObjs = getExampleNames(obj=True)
|
||||
examplesToFit = ["ExamplePure","ExampleSolution","ExampleDigital"]
|
||||
examplesToFit = ["ExamplePure","ExampleSolution","ExampleDigital","ExampleDigitalPure"]
|
||||
for obj in fluidObjs:
|
||||
if obj.name in examplesToFit:
|
||||
writer.fitAll(obj)
|
||||
@@ -32,6 +36,9 @@ if __name__ == '__main__':
|
||||
|
||||
print("\nProcessing example fluids")
|
||||
writer.writeFluidList(doneObjs)
|
||||
|
||||
writer.writeReportList(doneObjs)
|
||||
#sys.exit(0)
|
||||
|
||||
# If the examples did not cause any errors,
|
||||
# we can proceed to the real data.
|
||||
|
||||
Reference in New Issue
Block a user