Source code for sandlersteam.satd

# Author: Cameron F Abrams <cfa22@drexel.edu>

import numpy as np
import pandas as pd
from scipy.interpolate import interp1d
from importlib.resources import files

[docs] def merge_high_low_P_tables(lowP_df, highP_df): """ Merge two dataframes of steam table data at low and high pressures """ lowP_df['P'] = lowP_df['P'] / 1000.0 # convert kPa to MPa merged_df = pd.concat([lowP_df, highP_df], axis=0) icolumn = merged_df.columns[0] merged_df.sort_values(by=icolumn, inplace=True) return merged_df
[docs] class svi: # wrap the interp1d function so that it returns a scalar def __init__(self, f): self.f = f def __call__(self, x): return self.f(x).item()
[docs] class SaturatedSteamTables: """ Saturated steam tables based on Sandler's Steam Tables Data from: Sandler, S. I. (2017). Chemical, biochemical, and engineering thermodynamics 5th ed. John Wiley & Sons. """ data_path = files('sandlersteam') / 'resources' / 'data' tablesP = [data_path / 'SandlerSatdSteamTableP1.txt', data_path / 'SandlerSatdSteamTableP2.txt'] tablesT = [data_path / 'SandlerSatdSteamTableT1.txt', data_path / 'SandlerSatdSteamTableT2.txt'] # _sp = ['T', 'P', 'vL', 'vV', 'uL', 'uV', 'hL', 'hV', 'sL', 'sV'] # _su = ['C','MPa','m3/kg','m3/kg','kJ/kg','kJ/kg','kJ/kg','kJ/kg','kJ/kg-K','kJ/kg-K'] # _sfs = ['{: .1f}','{: .2f}','{: .6g}','{: .6g}','{: .6g}','{: .6g}','{: .6g}','{: .6g}','{: .6g}','{: .6g}'] colorder = ['P', 'T', 'vL', 'vV', 'uL', 'Du', 'uV', 'hL', 'Dh', 'hV', 'sL', 'Ds', 'sV'] def __init__(self): self.DF = {'P': merge_high_low_P_tables( pd.read_csv(self.tablesP[0], sep=r'\s+', header=0, index_col=None), pd.read_csv(self.tablesP[1], sep=r'\s+', header=0, index_col=None))[self.colorder], 'T': merge_high_low_P_tables( pd.read_csv(self.tablesT[0], sep=r'\s+', header=0, index_col=None), pd.read_csv(self.tablesT[1], sep=r'\s+', header=0, index_col=None))[self.colorder]} self.lim = {'P':[self.DF['P']['P'].min(),self.DF['P']['P'].max()], 'T':[self.DF['T']['T'].min(),self.DF['T']['T'].max()]} for p in ['vL', 'vV', 'uL', 'uV', 'hL', 'hV', 'sL', 'sV']: self.lim[p] = [min(self.DF['P'][p].min(), self.DF['T'][p].min()), max(self.DF['P'][p].max(), self.DF['T'][p].max())] self.interpolators = {} for bp, cp in zip(['P', 'T'], ['T', 'P']): self.interpolators[bp] = {} X = np.array(self.DF[bp][bp].to_list()) for p in [cp, 'vL', 'vV', 'uL', 'uV', 'hL', 'hV', 'sL', 'sV']: Y = np.array(self.DF[bp][p].to_list()) self.interpolators[bp][p] = svi(interp1d(X, Y, kind='linear'))