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:
jowr
2014-07-31 00:01:18 +02:00
parent 8ff8332e77
commit e8f0e2d11b
9 changed files with 651 additions and 477 deletions

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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):
"""

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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.