def propPhase(self): phases = [] for i in self.medium: phase1 = PhaseSI('T', self.t1, 'P', self.p * i[1], i[0]) if phase1 == 'supercritical_gas': phase1 = 'gas' elif phase1 == 'supercritical_liquid': phase1 = 'liquid' phase2 = PhaseSI('T', self.t2, 'P', self.p * i[1], i[0]) if phase2 == 'supercritical_gas': phase2 = 'gas' elif phase2 == 'supercritical_liquid': phase2 = 'liquid' if phase1 == phase2: phases.append(phase1) else: return 'twophase' for phase in phases: if phase != phases[0]: return 'twophase' return phases[0]
def bottom_up(fluid, z_bot, z_top, dz, mflow, P, T_celsius, d, k, g=9.81): # # bottom-up simulation z = z_bot h = PropsSI('H', 'T', T_celsius + 273.15, 'P', P, fluid) rho = PropsSI('D', 'T', T_celsius + 273.15, 'P', P, fluid) A = np.pi * d**2 / 4. V = mflow / rho / A #negative massflow is injection phase = PhaseSI('T', T_celsius + 273.15, 'P', P, fluid) results_vals = [[z, P, h, rho, V, T_celsius, phase]] for i in np.arange(z_bot, z_top, dz): # print z, z_top if z + dz > z_top: z2, h2, P2 = wellbore_step(fluid, z, z_top - z, h, V, P, rho, d, k, g) else: z2, h2, P2 = wellbore_step(fluid, z, dz, h, V, P, rho, d, k, g) if P2 < 5E3: break h = h2 P = P2 z = z2 #update rho try: rho = PropsSI('D', 'H', h, 'P', P, fluid) phase = PhaseSI('H', h, 'P', P, fluid) except ValueError: print 'Warning: Error in z={}'.format(z) continue #update V V = mflow / rho / A #velocity updated with density #check Temp T_celsius = PropsSI('T', 'H', h, 'P', P, fluid) - 273.15 results_vals += [[z, P, h, rho, V, T_celsius, phase]] # print 'Debug: ', z, P, h, rho, V results_df = pd.DataFrame( results_vals, columns=['z', 'P', 'h', 'rho', 'V', 'T', 'phase']) return results_df
def get_heat_extraction_rate(work_dir, fluid, inj_temp=30): pres_df, temp_df, mass_df = get_data(fluid, work_dir) times = mass_df.time.unique().tolist() columns = temp_df.columns.tolist() wnames = get_well_names(work_dir) wname_map = {k: wnames[i] for i, k in enumerate(columns)} h_df = pd.DataFrame(columns=columns, index=times) state_df = pd.DataFrame(columns=columns, index=times) for t in times: print "DEBUG: time is " + str(t) for col in columns: if fluid == 'Water': mf = mass_df[(mass_df['Node'] == col) & (mass_df['time'] == t)]['mf_water'].values[0] elif fluid == 'CO2': mf = mass_df[(mass_df['Node'] == col) & (mass_df['time'] == t)]['mf_co2'].values[0] if mf > 0.0: T = temp_df.loc[t, col] + 273.15 elif mf < 0.0: T = inj_temp + 273.15 inj_well = col P = pres_df.loc[t, col] * 1E6 h_df.loc[t, col] = PropsSI('H', 'T', T, 'P', P, fluid) / 1E3 state_df.loc[t, col] = PhaseSI('T', T, 'P', P, fluid) prod_wells = [col for col in columns if col != inj_well] q_df = pd.DataFrame(columns=prod_wells, index=times) for t in times: print "DEBUG: time is " + str(t) for col in prod_wells: if fluid == 'Water': mf = mass_df[(mass_df['Node'] == col) & (mass_df['time'] == t)]['mf_water'].values[0] elif fluid == 'CO2': mf = mass_df[(mass_df['Node'] == col) & (mass_df['time'] == t)]['mf_co2'].values[0] q_df.loc[t, col] = mf * (h_df.loc[t, col] - h_df.loc[t, inj_well]) q_df['Total'] = q_df.sum(axis=1) q_df.rename(columns=wname_map, inplace=True) h_df.rename(columns=wname_map, inplace=True) state_df.rename(columns=wname_map, inplace=True) return q_df, h_df, state_df
def get_phase(self, fluid: str, fp: str, fpv: float, sp: str, spv: float, n: int = 4): """ get fluid's phase """ try: result = PhaseSI(fp, fpv, sp, spv, fluid) except: result = 'phase does not work' return result
def get_phase(T,p): """Returns the phase of water through CoolProp library Arguments: T {K} -- Temperature P {Pa} -- Pressure Returns: Returns phase according to CoolProp ('liquid'/'gas'/'supercritical_gas'/'supercritical'/'supercritical_liquid') """ return PhaseSI('T',T,'P',p,"HEOS::Water")
def CoolProp_T_dependent_property(T, CASRN, prop, phase): r'''Calculates a property of a chemical in either the liquid or gas phase as a function of temperature only. This means that the property is either at 1 atm or along the saturation curve. Parameters ---------- T : float Temperature of the fluid [K] CASRN : str CAS number of the fluid prop : str CoolProp string shortcut for desired property phase : str Either 'l' or 'g' for liquid or gas properties respectively Returns ------- prop : float Desired chemical property, [units] Notes ----- For liquids above their boiling point, the liquid property is found on the saturation line (at higher pressures). Under their boiling point, the property is calculated at 1 atm. No liquid calculations are permitted above the critical temperature. For gases under the chemical's boiling point, the gas property is found on the saturation line (at sub-atmospheric pressures). Above the boiling point, the property is calculated at 1 atm. An exception is raised if the desired CAS is not supported, or if CoolProp is not available. The list of strings acceptable as an input for property types is: http://www.coolprop.org/coolprop/HighLevelAPI.html#table-of-string-inputs-to-propssi-function Examples -------- Water at STP according to IAPWS-95 >>> CoolProp_T_dependent_property(298.15, '7732-18-5', 'D', 'l') 997.047636760347 References ---------- .. [1] Bell, Ian H., Jorrit Wronski, Sylvain Quoilin, and Vincent Lemort. "Pure and Pseudo-Pure Fluid Thermophysical Property Evaluation and the Open-Source Thermophysical Property Library CoolProp." Industrial & Engineering Chemistry Research 53, no. 6 (February 12, 2014): 2498-2508. doi:10.1021/ie4033999. http://www.coolprop.org/ ''' if not has_CoolProp: # pragma: no cover raise Exception('CoolProp library is not installed') if CASRN not in coolprop_dict: raise Exception('CASRN not in list of supported fluids') Tc = coolprop_fluids[CASRN].Tc T = float(T) # Do not allow custom objects here if phase == 'l': if T > Tc: raise Exception( 'For liquid properties, must be under the critical temperature.' ) if PhaseSI('T', T, 'P', 101325, CASRN) in [u'liquid', u'supercritical_liquid']: return PropsSI(prop, 'T', T, 'P', 101325, CASRN) else: return PropsSI(prop, 'T', T, 'Q', 0, CASRN) elif phase == 'g': if PhaseSI('T', T, 'P', 101325, CASRN) == 'gas': return PropsSI(prop, 'T', T, 'P', 101325, CASRN) else: if T < Tc: return PropsSI(prop, 'T', T, 'Q', 1, CASRN) else: # catch supercritical_gas and friends return PropsSI(prop, 'T', T, 'P', 101325, CASRN) else: raise Exception('Error in CoolProp property function')
def PropertyLookup( desired, T=None, p=None, v=None, u=None, h=None, s=None, x=None, d=None, rho=None, u_molar=None, h_molar=None, s_molar=None, d_molar=None, fluid=None, unit_system=None, verbose=False, **kwargs, ): """ Each of the follow properties/parameters is expected to be a quantity with units :param desired: Dependent from two of the following independent properties :param T: Temperature (Default value = None) :param p: pressure (Default value = None) :param v: mass specific volume (Default value = None) :param u: mass specific internal energy (Default value = None) :param h: mass specific enthalpy (Default value = None) :param s: mass specific entropy (Default value = None) :param x: mass quality (Default value = None) :param d: mass density (Default value = None) :param rho: mass density (Default value = None) :param u_molar: molar specific internal energy (Default value = None) :param h_molar: molar specific enthalpy (Default value = None) :param s_molar: molar specific entropy (Default value = None) :param d_molar: molar density (Default value = None) :param fluid: fluid name (Default value = None) :param unit_system: unit system for return value - one of 'SI_C', 'SI_K', 'English_F', 'English_R' (Default value = ) :param verbose: show debug information (Default value = False) :param **kwargs: """ # Translate common variable names into CoolProp syntax, i.e. quality CP_symb_trans = {"x": "Q", "rho": "D"} # flag to determine whether the result from CoolProps should be inverted, i.e. density to specific volume invert_result = False if desired in CP_symb_trans.keys(): # CoolProp expects all parameters to be capitalized CP_desired = CP_symb_trans[desired].upper() elif desired.upper() in ["V"]: # Use CoolProp library to return specific volume by inverting the density invert_result = True CP_desired = "D" elif desired in ["vmolar"]: # Use CoolProp library to return specific volume by inverting the density invert_result = True CP_desired = "DMOLAR" else: CP_desired = (desired.upper() ) # CoolProp expects all parameters to be capitalized if "phase" in desired.lower(): PropsSI_args = ( [] ) # don't add a desired parameter for the call to CoolProp.PhaseSI else: # add the desired parameter as the first argument to pass to CoolProp.PropsSI PropsSI_args = [CP_desired] def process_indep_arg(arg, CPSymb, exponent=1, AltSymb=None): """ Add a property symbol and its value to the CoolProp.PropSI argument string :param arg: value of independent parameter :param CPSymb: CoolProp symbol :param exponent: exponent used to invert the value (Default value = 1) :param AltSymb: symbol to use for inverted values (Default value = None) """ if arg is not None: if AltSymb: PropsSI_args.append(AltSymb) else: # Add independent parameter symbol to argument list PropsSI_args.append(CPSymb) if CP_symbUpper_to_units[CPSymb] is not None: # Add independent parameter value to argument list with appropriate magnitude and units stripped (invert specific volume to get density if needed) if not isinstance(arg, Quantity): arg_type = CP_symb_to_type[PropsSI_args[-1]] arg_units = preferred_units_from_type( arg_type, unit_system) arg = Quantity(arg, arg_units) value = (arg.to( CP_symbUpper_to_units[CPSymb]).magnitude)**exponent else: value = arg # Add independent paramter value directly to argument list if it has no units that need to be adjusted PropsSI_args.append(value) # Process all the possible independent arguments process_indep_arg(T, "T") process_indep_arg(p, "P") process_indep_arg(v, "V", exponent=-1, AltSymb="D") process_indep_arg(u, "U") process_indep_arg(h, "H") process_indep_arg(s, "S") process_indep_arg(x, "Q") process_indep_arg(d, "D") process_indep_arg(rho, "D") process_indep_arg(u_molar, "UMOLAR") process_indep_arg(h_molar, "HMOLAR") process_indep_arg(s_molar, "SMOLAR") process_indep_arg(d_molar, "DMOLAR") # Add the fluid name as the last parameter to the argument list PropsSI_args.append(fluid) if verbose: print("Calling: CoolProps.CoolProps.PropsSI({})".format(",".join( [str(i) for i in PropsSI_args]))) # Make call to PropsSI or PhaseSI if "phase" in desired.lower(): result = PhaseSI(*PropsSI_args) return result else: result = PropsSI(*PropsSI_args) # Determine the units of the value as returned from CoolProp CP_return_units = CP_symbUpper_to_units[CP_desired] CP_return_type = CP_symb_to_type[desired] # Determine the preferred units for the value if unit_system is None: result_units = preferred_units_from_type(CP_return_type, units.preferred_units) else: result_units = preferred_units_from_type(CP_return_type, unit_system) # Convert the returned value to the preferred units if result_units is not None: if invert_result: result = Quantity(result, CP_return_units)**-1 result = result.to(result_units) else: result = Quantity(result, CP_return_units).to(result_units) return result
def phase_byPressTemp(self, flt_P_Pascal, flt_Temp_K): if self.isError(): return return PhaseSI("P", flt_P_Pascal, "T", flt_Temp_K, self.m_fluid)