mirror of
https://github.com/CoolProp/CoolProp.git
synced 2026-01-10 14:38:11 -05:00
172 lines
4.6 KiB
Python
172 lines
4.6 KiB
Python
from CoolProp import CoolProp as CP
|
|
from PDSim.misc.datatypes import Collector
|
|
import numpy as np
|
|
import matplotlib.pyplot as plt
|
|
from scipy.odr import *
|
|
import textwrap
|
|
|
|
#
|
|
#fluid = 'Propane'
|
|
#Rfluid = 'REFPROP-propane'
|
|
#e_k = 263.88
|
|
#sigma = 0.49748
|
|
#
|
|
fluid = 'DimethylEther'
|
|
Rfluid = 'REFPROP-DME'
|
|
e_k = 329.72
|
|
sigma = 0.5529
|
|
molemass = CP.Props(fluid, 'molemass')
|
|
|
|
Ttriple = CP.Props(fluid, 'Ttriple')
|
|
Tcrit = CP.Props(fluid, 'Tcrit')
|
|
rhocrit = CP.Props(fluid, 'rhocrit')
|
|
n = 6
|
|
m = 3
|
|
NP = 1
|
|
Nb = 0
|
|
N = (n - 1) * (m + 1) + 3 + Nb
|
|
|
|
mu, mu_dilute, RHO, TTT = Collector(), Collector(), Collector(), Collector()
|
|
|
|
rhomax = CP.Props('D', 'T', Ttriple, 'Q', 0, fluid)
|
|
# Build a database of "experimental" data
|
|
for T in np.linspace(Ttriple, Tcrit + 30, 400):
|
|
for rho in np.linspace(1e-10, rhomax, 400):
|
|
muval = CP.Props('V', 'T', T, 'D', rho, Rfluid)
|
|
mudilute = CP.viscosity_dilute(fluid, T, rho, e_k, sigma)
|
|
|
|
# Want positive value, and single-phase
|
|
if (muval > 0 and T > Tcrit or rho > CP.rhosatL_anc(fluid, T) or rho < CP.rhosatV_anc(fluid, T)):
|
|
mu << muval
|
|
mu_dilute << mudilute
|
|
TTT << T
|
|
RHO << rho
|
|
|
|
from CoolProp.Plots.Plots import Trho
|
|
Trho(fluid)
|
|
plt.plot(RHO.vec, TTT.vec, '.')
|
|
plt.show()
|
|
|
|
#tau = np.array(TTT.vec)/Tcrit
|
|
tau = np.array(TTT.vec) / Tcrit
|
|
delta = np.array(RHO.vec) / rhocrit
|
|
Tstar = np.array(TTT.vec) / e_k
|
|
|
|
# Define the objective function
|
|
|
|
|
|
def OBJECTIVE_fit(c, x):
|
|
tau = x[0, :]
|
|
delta = x[1, :]
|
|
# Unpack the inputs into e matrix and f vector
|
|
e = np.zeros((n + 1, m + 1))
|
|
|
|
sum = 0
|
|
k = 0
|
|
for i in range(2, n + 1):
|
|
for j in range(0, m + 1):
|
|
e[i][j] = c[k]
|
|
sum += e[i][j] * delta**i / tau**j
|
|
k += 1
|
|
|
|
for o in range(0, NP):
|
|
f1 = c[k + o * 3]
|
|
g1 = c[k + 1 + o * 3]
|
|
g2 = c[k + 2 + o * 3]
|
|
|
|
delta_0 = g1 * (1 + g2 * tau**0.5)
|
|
sum += f1 * (delta / (delta_0 - delta) - delta / delta_0)
|
|
return sum + np.array(mu_dilute.vec)
|
|
|
|
|
|
print('starting fit')
|
|
XXX = np.r_[np.array(tau, ndmin=2), np.array(delta, ndmin=2)]
|
|
mod = Model(OBJECTIVE_fit)
|
|
mydata = Data(XXX.copy(), np.array(mu.vec))
|
|
beta0 = [1 for _ in range(N)]
|
|
myodr = ODR(mydata, mod, beta0=beta0)
|
|
myoutput = myodr.run()
|
|
myoutput.pprint()
|
|
print(myoutput.sum_square)
|
|
YFIT = OBJECTIVE_fit(myoutput.beta, XXX)
|
|
plt.plot(np.array(mu.vec), YFIT / np.array(mu.vec), 'o')
|
|
plt.show()
|
|
|
|
rel_error = (YFIT) / np.array(mu.vec) - 1
|
|
MAE = np.mean(np.abs(rel_error)) * 100
|
|
SSE = np.sum(np.power(YFIT - np.array(mu.vec), 2))
|
|
print(SSE)
|
|
|
|
|
|
def write_output(c):
|
|
e = np.zeros((n + 1, m + 1))
|
|
k = 0
|
|
edata = ''
|
|
for i in range(2, n + 1):
|
|
erow = ''
|
|
for j in range(0, m + 1):
|
|
e[i][j] = c[k]
|
|
erow += 'e[{i:d}][{j:d}] = {val:0.16g}; '.format(val=e[i][j], i=i, j=j)
|
|
k += 1
|
|
edata += erow + '\n'
|
|
f1 = c[k]
|
|
g1 = c[k + 1]
|
|
g2 = c[k + 2]
|
|
|
|
template = textwrap.dedent(
|
|
"""
|
|
double {name:s}Class::viscosity_Trho(double T, double rho)
|
|
{{
|
|
// This function was generated by fitting REFPROP ECS data
|
|
// to the functional form of Vogel, 1998 (propane viscosity)
|
|
// The script entitled dev/fit_avoid_ECS.py was used to make this
|
|
// function. The mean absolute error of the fit is equal to
|
|
// {MAE:g} %
|
|
|
|
double delta_0, sum, DELTA_H_eta, e_k, sigma, tau, delta;
|
|
double e[{n:d}+1][{m:d}+1];
|
|
|
|
tau = T/reduce.T; //[Opposite to normal definition]
|
|
delta = rho/reduce.rho;
|
|
|
|
// Load the coefficients
|
|
double f1 = {f1:0.16g}, g1 = {g1:0.16g}, g2 = {g2:0.16g};
|
|
for (int i=0;i<={n:d};i++){{ for(int j=0;j<={m:d};j++){{ e[i][j]=0.0; }} }}
|
|
{edata:s}
|
|
delta_0=g1*(1+g2*sqrt(tau)); //[no units]
|
|
sum=0;
|
|
for (int i=2;i<={n:d};i++){{
|
|
for (int j=0;j<={m:d};j++){{
|
|
sum += e[i][j]*pow(delta,i)/pow(tau,j);
|
|
}}
|
|
}}
|
|
DELTA_H_eta = sum + f1*(delta/(delta_0-delta)-delta/delta_0); //[Pa-s]
|
|
|
|
try{{
|
|
// Get the ECS params for the fluid if it has them
|
|
ECSParams(&e_k,&sigma);
|
|
}}
|
|
catch(NotImplementedError)
|
|
{{
|
|
throw ValueError(format("Your fluid does not implement ECSParams"));
|
|
}}
|
|
|
|
return viscosity_dilute(T,e_k,sigma) + DELTA_H_eta;
|
|
}}
|
|
"""
|
|
)
|
|
|
|
values = dict(f1=f1,
|
|
g1=g1,
|
|
g2=g2,
|
|
n=n,
|
|
m=m,
|
|
name=fluid,
|
|
edata=edata,
|
|
MAE=MAE)
|
|
|
|
print(template.format(**values))
|
|
|
|
|
|
write_output(myoutput.beta)
|