mirror of
https://github.com/CoolProp/CoolProp.git
synced 2026-01-10 14:38:11 -05:00
* Expansions are fully wrapped, looking good. Next step is the set of expansions that is the 1D approximation * Get 1D approx working via cython * Count solutions * SuperAncillary class is working >1000x speedup for water Time for C++! * Superancillaries are working! In C++, speedup is more than 2000x. In Python, more like 150x because of Python <-> C++ overhead * Add pmax check for PQ superancillary calls * Update tests * Allow T limits to be obtained * Implement get_fluid_parameter_double for getting superanc value * Add tests for getting parameters from superanc * Script for testing superancillaries for sphinx * Microoptimizations; don't help speed The limiting factor remains the clear function, which takes about 30 ns * Add R125 superancillary * Use the release from fastchebpure for the files * Drop a .gitignore in the unzipped folder * Update superancillary injection script * Turn on superancillaries by default * Missing header * Many int conversions in superancillary * Another int cast * More annoying solution for boost iter max * Fix warnings * One more warning * Clear up the calculation of rho * Update docs_docker-build.yml Use arm64 since the containers were built on mac * Superfluous ; * Update backend.py * Get the critical points working for superancillaries * Fix wrapping changes of xmin&xmax methods * squelch warnings * Version 0 of jupyter notebook for docs * Try to add the notebook to the docs * Add jupyter notebook for superancillary * Lots of updates to superancillary notebook * More updates to docs * Skip pseudo-pure for superancillary docs * Fix output of superancillary figures * Add superancillary plots to docs for the page for each fluid * Make a placeholder figure for fluids without superancillary * Add superancillary plots to task list * Bump to release fixing m-xylene * Relax the location of the REFPROP stuff * Change default name for R-1336mzz(E) * No need for figures to be so large * Don't need REFPROP setting * Bump to fastchebpure release with methanol * Benchmark caching options * Benchmark more granularly * Add the fast methods to public API for HEOS class * Back to memset - can memset with 0 but no other value * Fix how caching is managed in Helmholtz class * Close to final implementation Perhaps a tiny bit more optimization possible? * Update function name * Make message more accurate * Fix init order * Expose update_QT_pure_superanc to Python * Fix when _reducing is set for pures * Fix the post_update * Indent * Notebook * Notebook * Make ln(p) construction lazy Only really matters for debug builds * Also make reference non-const * Inject superancillary for methanol * Make the superancillary loading entirely lazy in debug * Fix PH bug for Nitrogen Closes #2470 * Force the clear to be called on SatL and SatV To invalidate them at start * Default is non-lazy superancillary loading * Add CMake option to have lazy-loading superancillaries [skip ci] Not a good idea unless doing very narrow testing
160 lines
5.1 KiB
Python
160 lines
5.1 KiB
Python
from __future__ import print_function
|
|
import os.path
|
|
import CoolProp
|
|
import urllib.request
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
from zipfile import ZipFile
|
|
|
|
web_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
root_dir = os.path.abspath(os.path.join(web_dir, '..'))
|
|
fluids_path = os.path.join(web_dir, 'fluid_properties', 'fluids')
|
|
plots_path = os.path.join(web_dir, 'fluid_properties', 'fluids', 'Superancillaryplots')
|
|
|
|
outputversion = '2025.04.27'
|
|
if not Path(f'{outputversion}.zip').exists():
|
|
print('Downloading the chebyshev output file to ', Path('.').absolute())
|
|
urllib.request.urlretrieve(f'https://github.com/CoolProp/fastchebpure/archive/refs/tags/{outputversion}.zip', f'{outputversion}.zip')
|
|
|
|
with ZipFile(f'{outputversion}.zip') as z:
|
|
z.extractall('.')
|
|
|
|
with (Path('.') / f'fastchebpure-{outputversion}' / '.gitignore').open('w') as fp:
|
|
fp.write("*")
|
|
|
|
outputcheck = (Path('.') / f'fastchebpure-{outputversion}' / 'outputcheck').absolute()
|
|
|
|
|
|
template = r"""
|
|
import matplotlib
|
|
matplotlib.use('Agg') # Force mpl to use a non-GUI backend
|
|
import matplotlib.pyplot as plt
|
|
import json
|
|
import numpy as np
|
|
import pandas as pd
|
|
import CoolProp.CoolProp as CP
|
|
|
|
CP.set_config_bool(CP.ENABLE_SUPERANCILLARIES, False)
|
|
|
|
AS = CP.AbstractState('HEOS', "{fluid}")
|
|
|
|
# Skip pseudo-pure fluids, pure fluids only; pseudo-pure do not have superancillaries
|
|
if AS.fluid_param_string("pure") != "true":
|
|
quit()
|
|
|
|
jEOS = json.loads(CP.get_fluid_param_string("{fluid}", "JSON"))[0]['EOS'][0]
|
|
if 'SUPERANCILLARY' not in jEOS:
|
|
fig = plt.figure()
|
|
fig.text(0.5, 0.5, 'Superancillary not available')
|
|
plt.savefig('{fluid:s}.png', dpi = 300)
|
|
plt.savefig('{fluid:s}.pdf')
|
|
plt.close()
|
|
quit()
|
|
else:
|
|
jSuper = jEOS['SUPERANCILLARY']
|
|
|
|
superanc = CP.SuperAncillary(json.dumps(jSuper))
|
|
RPname = AS.fluid_param_string("REFPROP_name")
|
|
|
|
# Load extended precision calcs from the release on github
|
|
chk = json.load(open('{outputcheck}/{fluid}_check.json'))
|
|
df = pd.DataFrame(chk['data'])
|
|
# df.info() # uncomment to see what fields are available
|
|
|
|
Tcrit_num = AS.get_fluid_parameter_double(0, "SUPERANC::Tcrit_num")
|
|
T = df['T / K'].to_numpy()
|
|
Theta = (Tcrit_num-T)/Tcrit_num
|
|
|
|
fig, axes = plt.subplots(3, 1, sharex=True, figsize=(3.5,7))
|
|
|
|
|
|
plt.sca(axes[0])
|
|
rhoL_anc = np.zeros_like(T)
|
|
superanc.eval_sat_many(T, 'D', 0, rhoL_anc)
|
|
err = np.abs(df["rho'(mp) / mol/m^3"]/rhoL_anc-1)
|
|
plt.plot(Theta, err, 'o', label=r'$\Upsilon$:SA')
|
|
|
|
errCP = np.abs(df["rho'(mp) / mol/m^3"]/CP.PropsSI('Dmolar', 'T', T, 'Q', 0, f'HEOS::{fluid}')-1)
|
|
plt.plot(Theta, errCP, '^', label=r'$\Upsilon$:HEOS')
|
|
|
|
try:
|
|
errRP = np.abs(df["rho'(mp) / mol/m^3"]/CP.PropsSI('Dmolar', 'T', T, 'Q', 0, f'REFPROP::{{RPname}}')-1)
|
|
plt.plot(Theta, errRP, 'x', label=r'$\Upsilon$:REFPROP')
|
|
except BaseException as BE:
|
|
print(BE)
|
|
|
|
plt.legend(loc='best')
|
|
plt.ylabel(r"$|\rho_{{\rm \Upsilon}}'/\rho_{{\rm ep}}'-1|$")
|
|
plt.yscale('log')
|
|
|
|
|
|
|
|
plt.sca(axes[1])
|
|
rhoV_anc = np.zeros_like(T)
|
|
superanc.eval_sat_many(T, 'D', 1, rhoV_anc)
|
|
err = np.abs(df["rho''(mp) / mol/m^3"]/rhoV_anc-1)
|
|
plt.plot(Theta, err, 'o', label=r'$\Upsilon$:SA')
|
|
|
|
errCP = np.abs(df["rho''(mp) / mol/m^3"]/CP.PropsSI('Dmolar', 'T', T, 'Q', 1, f'HEOS::{fluid}')-1)
|
|
plt.plot(Theta, errCP, '^', label=r'$\Upsilon$:HEOS')
|
|
|
|
try:
|
|
errRP = np.abs(df["rho''(mp) / mol/m^3"]/CP.PropsSI('Dmolar', 'T', T, 'Q', 1, f'REFPROP::{{RPname}}')-1)
|
|
plt.plot(Theta, errRP, 'x', label=r'$\Upsilon$:REFPROP')
|
|
except BaseException as BE:
|
|
print(BE)
|
|
|
|
plt.legend(loc='best')
|
|
plt.ylabel(r"$|\rho_{{\rm \Upsilon}}''/\rho_{{\rm ep}}''-1|$")
|
|
plt.yscale('log')
|
|
|
|
|
|
|
|
plt.sca(axes[2])
|
|
p_anc = np.zeros_like(T)
|
|
superanc.eval_sat_many(T, 'P', 1, p_anc)
|
|
err = np.abs(df["p(mp) / Pa"]/p_anc-1)
|
|
plt.plot(Theta, err, 'o', label=r'$\Upsilon$:SA')
|
|
|
|
errCP = np.abs(df["p(mp) / Pa"]/CP.PropsSI('P', 'T', T, 'Q', 1, f'HEOS::{fluid}')-1)
|
|
plt.plot(Theta, errCP, '^', label=r'$\Upsilon$:HEOS')
|
|
|
|
try:
|
|
errRP = np.abs(df["p(mp) / Pa"]/CP.PropsSI('P', 'T', T, 'Q', 1, f'REFPROP::{{RPname}}')-1)
|
|
plt.plot(Theta, errRP, 'x', label=r'$\Upsilon$:REFPROP')
|
|
except BaseException as BE:
|
|
print(BE)
|
|
plt.legend(loc='best')
|
|
|
|
# print(CP.PropsSI('gas_constant', 'T', T[0], 'Q', 1, f'HEOS::{fluid}'))
|
|
# print(CP.PropsSI('gas_constant', 'T', T[0], 'Q', 1, f'REFPROP::{fluid}'))
|
|
|
|
plt.ylabel(r"$|p_{{\rm \Upsilon}}/p_{{\rm ep}}-1|$")
|
|
plt.yscale('log')
|
|
|
|
plt.sca(axes[2])
|
|
plt.xlabel(r'$\Theta=(T_{{\rm crit,num}}-T)/T_{{\rm crit,num}}$')
|
|
plt.xscale('log')
|
|
|
|
plt.suptitle('Superancillary v. Extended Precision')
|
|
plt.tight_layout(pad=0.2, rect=(0,0,1,0.95))
|
|
plt.savefig('{fluid:s}.png', dpi = 300)
|
|
plt.savefig('{fluid:s}.pdf')
|
|
plt.close()
|
|
"""
|
|
if not os.path.exists(plots_path):
|
|
os.makedirs(plots_path)
|
|
|
|
from pathlib import Path
|
|
|
|
for fluid in CoolProp.__fluids__:
|
|
print('fluid:', fluid)
|
|
file_string = template.format(fluid=fluid, outputcheck=outputcheck)
|
|
file_path = os.path.join(plots_path, fluid + '.py')
|
|
print('Writing to', file_path)
|
|
with open(file_path, 'w') as fp:
|
|
fp.write(file_string)
|
|
print('calling:', 'python "' + fluid + '.py"', 'in', plots_path)
|
|
subprocess.check_call('python -u "' + fluid + '.py"', cwd=plots_path, stdout=sys.stdout, stderr=sys.stderr, shell=True)
|