def test_get_method_invalid_name(self, frame): with pytest.raises( AttributeError, match="ScalarBlock Generic Property Package called for " "invalid configuration option foo. Please contact the " "developer of the property package."): get_method(frame, "foo")
def energy_internal_mol_ls_comp_pure(b, j): # Method for calculating pure component U from H for liquids & solids units = b.params.get_metadata().derived_units R = pyunits.convert(const.gas_constant, to_units=units["heat_capacity_mole"]) if cobj(b, j).parent_block().config.include_enthalpy_of_formation: # First, need to determine correction between U_form and H_form # U_form = H_form - delta_n*R*T ele_comp = cobj(b, j).config.elemental_composition if ele_comp is None: raise ConfigurationError( "{} calculation of internal energy requires elemental " "composition of all species. Please set this using the " "elemental_composition argument in the component " "declaration ({}).".format(b.name, j)) delta_n = 0 for e, s in ele_comp.items(): # Check for any element which is vapor at standard state if e in ["He", "Ne", "Ar", "Kr", "Xe", "Ra"]: delta_n += -s elif e in ["F", "Cl", "H", "N", "O"]: delta_n += -s / 2 # These are diatomic at standard state dU_form = delta_n * R * b.params.temperature_ref # For ideal (incompressible) liquids and solids, U = H + dU_form return (get_method(b, "enth_mol_liq_comp", j)(b, cobj( b, j), b.temperature) + dU_form) else: # If not including heat of formation, U = H return get_method(b, "enth_mol_liq_comp", j)(b, cobj(b, j), b.temperature)
def rule_mole_frac_dew_temp(b, p1, p2, j): (l_phase, v_phase, vl_comps, henry_comps, l_only_comps, v_only_comps) = _valid_VL_component_list(b, (p1, p2)) if l_phase is None or v_phase is None: # Not a VLE pair return Constraint.Skip elif l_only_comps != []: # Non-vaporisables present, no dew point return Constraint.Skip if j in vl_comps: return (b._mole_frac_tdew[p1, p2, j] * get_method(b, "pressure_sat_comp", j)( b, cobj(b, j), b.temperature_dew[p1, p2]) == b.mole_frac_comp[j] * b.pressure) elif j in henry_comps: return (b._mole_frac_tdew[p1, p2, j] * get_method(b, "henry_component", j, l_phase)( b, l_phase, j, b.temperature_dew[p1, p2]) == b.mole_frac_comp[j] * b.pressure) else: return b._mole_frac_tdew[p1, p2, j] == 0
def test_get_method_not_callable(self, frame): frame.params.config.test_arg = "foo" with pytest.raises( ConfigurationError, match="ScalarBlock Generic Property Package received " "invalid value for argument test_arg. Value must be a " "method, a class with a method named expression or a " "module containing one of the previous."): get_method(frame, "test_arg")
def test_get_method_none(self, frame): with pytest.raises( GenericPropertyPackageError, match="Generic Property Package instance ScalarBlock " "called for test_arg, but was not provided with a " "method for this property. Please add a method for " "this property in the property parameter " "configuration."): get_method(frame, "test_arg")
def cv_mol_ls_comp_pure(b, p, j): # Method for calculating pure component liquid and solid cv from cp # For ideal (incompressible) liquids and solids, cv = cp pobj = b.params.get_phase(p) if pobj.is_liquid_phase(): return get_method(b, "cp_mol_liq_comp", j)( b, cobj(b, j), b.temperature) elif pobj.is_solid_phase(): return get_method(b, "cp_mol_sol_comp", j)( b, cobj(b, j), b.temperature)
def enth_mol_phase_comp(b, p, j): pobj = b.params.get_phase(p) if pobj.is_vapor_phase(): return get_method(b, "enth_mol_ig_comp", j)( b, cobj(b, j), b.temperature) elif pobj.is_liquid_phase(): return get_method(b, "enth_mol_liq_comp", j)( b, cobj(b, j), b.temperature) else: raise PropertyNotSupportedError(_invalid_phase_msg(b.name, p))
def rule_vol_mol_solvent(b): # Eqn 77 if len(b.params.solvent_set) == 1: s = b.params.solvent_set.first() return 1/get_method(b, "dens_mol_liq_comp", s)( b, cobj(b, s), b.temperature) else: return (sum(b.mole_frac_phase_comp_true[pname, s] / get_method(b, "dens_mol_liq_comp", s)( b, cobj(b, s), b.temperature) for s in b.params.solvent_set) / sum(b.mole_frac_phase_comp_true[pname, s] for s in b.params.solvent_set))
def entr_mol_phase_comp(b, p, j): pobj = b.params.get_phase(p) if pobj.is_vapor_phase(): return (get_method(b, "entr_mol_ig_comp", j)(b, cobj( b, j), b.temperature) - Ideal.gas_constant(b) * log(b.mole_frac_phase_comp[p, j] * b.pressure / b.params.pressure_ref)) elif pobj.is_liquid_phase(): # Assume no pressure/volume dependecy of entropy for ideal liquids return (get_method(b, "entr_mol_liq_comp", j)(b, cobj(b, j), b.temperature)) else: raise PropertyNotSupportedError(_invalid_phase_msg(b.name, p))
def rule_eps_solvent(b): # Eqn 78 if len(b.params.solvent_set) == 1: s = b.params.solvent_set.first() return get_method(b, "relative_permittivity_liq_comp", s)(b, cobj(b, s), b.temperature) else: return (sum(b.mole_frac_phase_comp_true[pname, s] * get_method(b, "relative_permittivity_liq_comp", s) (b, cobj(b, s), b.temperature) * b.params.get_component(s).mw for s in b.params.solvent_set) / sum(b.mole_frac_phase_comp_true[pname, s] * b.params.get_component(s).mw for s in b.params.solvent_set))
def entr_mol_phase(blk, p): pobj = blk.params.get_phase(p) cname = pobj._cubic_type.name bm = getattr(blk, cname + "_bm")[p] B = getattr(blk, cname + "_B")[p] dam_dT = getattr(blk, cname + "_dam_dT")[p] Z = blk.compress_fact_phase[p] EoS_u = EoS_param[pobj._cubic_type]['u'] EoS_w = EoS_param[pobj._cubic_type]['w'] EoS_p = sqrt(EoS_u**2 - 4 * EoS_w) R = Cubic.gas_constant(blk) entr_ideal_gas = -R * safe_log(blk.pressure / blk.params.pressure_ref, eps=eps_SL) for j in blk.components_in_phase(p): entr_j = get_method(blk, "entr_mol_ig_comp", j)(blk, cobj(blk, j), blk.temperature) xj = blk.mole_frac_phase_comp[p, j] log_xj = blk.log_mole_frac_phase_comp[p, j] entr_ideal_gas += xj * (entr_j - R * log_xj) # See pg. 102 in Properties of Gases and Liquids # or pg. 208 of Sandler, 4th Ed. entr_departure = (R * safe_log( (Z - B), eps=eps_SL) + dam_dT / (bm * EoS_p) * safe_log( (2 * Z + B * (EoS_u + EoS_p)) / (2 * Z + B * (EoS_u - EoS_p)), eps=eps_SL)) return entr_ideal_gas + entr_departure
def enth_mol_phase(blk, p): pobj = blk.params.get_phase(p) cname = pobj._cubic_type.name am = getattr(blk, cname + "_am")[p] bm = getattr(blk, cname + "_bm")[p] B = getattr(blk, cname + "_B")[p] dam_dT = getattr(blk, cname + "_dam_dT")[p] Z = blk.compress_fact_phase[p] R = Cubic.gas_constant(blk) T = blk.temperature EoS_u = EoS_param[pobj._cubic_type]['u'] EoS_w = EoS_param[pobj._cubic_type]['w'] EoS_p = sqrt(EoS_u**2 - 4 * EoS_w) enth_ideal = sum(blk.mole_frac_phase_comp[p, j] * get_method(blk, "enth_mol_ig_comp", j) (blk, cobj(blk, j), blk.temperature) for j in blk.components_in_phase(p)) # Derived from equation on pg. 120 in Properties of Gases and Liquids enth_departure = (R * T * (Z - 1) + (T * dam_dT - am) / (bm * EoS_p) * safe_log( (2 * Z + B * (EoS_u + EoS_p)) / (2 * Z + B * (EoS_u - EoS_p)), eps=eps_SL)) return enth_ideal + enth_departure
def rule_vol_mol_solvent(b): # Eqn 77 return (sum(b.mole_frac_phase_comp_true[pname, s] / get_method(b, "dens_mol_liq_comp", s) (b, cobj(b, s), b.temperature) for s in molecular_set) / sum(b.mole_frac_phase_comp_true[pname, s] for s in molecular_set))
def entr_mol_phase_comp(blk, p, j): pobj = blk.params.get_phase(p) if not (pobj.is_vapor_phase() or pobj.is_liquid_phase()): raise PropertyNotSupportedError(_invalid_phase_msg(blk.name, p)) cname = pobj._cubic_type.name bm = getattr(blk, cname + "_bm")[p] B = getattr(blk, cname + "_B")[p] dadT = getattr(blk, cname + "_dadT")[p] Z = blk.compress_fact_phase[p] EoS_u = EoS_param[pobj._cubic_type]['u'] EoS_w = EoS_param[pobj._cubic_type]['w'] EoS_p = sqrt(EoS_u**2 - 4 * EoS_w) # See pg. 102 in Properties of Gases and Liquids return (((Cubic.gas_constant(blk) * safe_log( (Z - B) / Z, eps=1e-6) * bm * EoS_p + Cubic.gas_constant(blk) * safe_log(Z * blk.params.pressure_ref / (blk.mole_frac_phase_comp[p, j] * blk.pressure), eps=1e-6) * bm * EoS_p + dadT * safe_log( (2 * Z + B * (EoS_u + EoS_p)) / (2 * Z + B * (EoS_u - EoS_p)), eps=1e-6)) / (bm * EoS_p)) + get_method(blk, "entr_mol_ig_comp", j)(blk, cobj(blk, j), blk.temperature))
def enth_mol_phase(blk, p): pobj = blk.params.get_phase(p) if not (pobj.is_vapor_phase() or pobj.is_liquid_phase()): raise PropertyNotSupportedError(_invalid_phase_msg(blk.name, p)) cname = pobj._cubic_type.name am = getattr(blk, cname + "_am")[p] bm = getattr(blk, cname + "_bm")[p] B = getattr(blk, cname + "_B")[p] dadT = getattr(blk, cname + "_dadT")[p] Z = blk.compress_fact_phase[p] EoS_u = EoS_param[pobj._cubic_type]['u'] EoS_w = EoS_param[pobj._cubic_type]['w'] EoS_p = sqrt(EoS_u**2 - 4 * EoS_w) # Derived from equation on pg. 120 in Properties of Gases and Liquids return (((blk.temperature * dadT - am) * safe_log( (2 * Z + B * (EoS_u + EoS_p)) / (2 * Z + B * (EoS_u - EoS_p)), eps=1e-6) + Cubic.gas_constant(blk) * blk.temperature * (Z - 1) * bm * EoS_p) / (bm * EoS_p) + sum(blk.mole_frac_phase_comp[p, j] * get_method(blk, "enth_mol_ig_comp", j) (blk, cobj(blk, j), blk.temperature) for j in blk.components_in_phase(p)))
def log_fug_phase_comp_Tdew(b, p, j, pp): pobj = b.params.get_phase(p) cobj = b.params.get_component(j) if pobj.is_vapor_phase(): return log(b.mole_frac_comp[j]) + log(b.pressure) elif pobj.is_liquid_phase(): if (cobj.config.henry_component is not None and p in cobj.config.henry_component): return (log(b._mole_frac_tdew[pp[0], pp[1], j]) + log(get_method(b, "henry_component", j, p)( b, p, j, b.temperature_dew[pp]))) else: return (log(b._mole_frac_tdew[pp[0], pp[1], j]) + log(get_method(b, "pressure_sat_comp", j)( b, cobj, b.temperature_dew[pp]))) else: raise PropertyNotSupportedError(_invalid_phase_msg(b.name, p))
def test_get_method_comp(self, frame): def test_arg(): return "bar" frame.params.comp.config.test_arg_2 = test_arg mthd = get_method(frame, "test_arg_2", comp="comp") assert mthd() == "bar"
def cv_mol_ig_comp_pure(b, j): # Method for calculating pure component ideal gas cv from cp # For ideal gases, cv = cp - R units = b.params.get_metadata().derived_units R = pyunits.convert(const.gas_constant, to_units=units["heat_capacity_mole"]) return (get_method(b, "cp_mol_ig_comp", j)( b, cobj(b, j), b.temperature) - R)
def test_get_method_phase(self, frame): def test_arg(): return "bar" frame.params.config.test_arg = {"test_phase": test_arg} mthd = get_method(frame, "test_arg", phase="test_phase") assert mthd() == "bar"
def rule_eps_solvent(b): # Eqn 78 return (sum( b.mole_frac_phase_comp_true[pname, s] * get_method(b, "relative_permittivity_liq_comp", s) (b, cobj(b, s), b.temperature) * b.params.get_component(s).mw for s in molecular_set) / sum(b.mole_frac_phase_comp_true[pname, s] * b.params.get_component(s).mw for s in molecular_set))
def test_get_method_simple(self, frame): def test_arg(): return "bar" frame.params.config.test_arg = test_arg mthd = get_method(frame, "test_arg") assert mthd() == "bar"
def test_get_method_phase_comp(self, frame): def test_arg(): return "bar" frame.params.comp.config.test_arg_2 = {"test_phase": test_arg} mthd = get_method(frame, "test_arg_2", comp="comp", phase="test_phase") assert mthd() == "bar"
def test_get_method_class_w_return_expression(self, frame): class TestClass(): def return_expression(*args, **kwargs): return "bar" frame.params.config.test_arg = TestClass mthd = get_method(frame, "test_arg") assert mthd() == "bar"
def test_get_method_class_w_method(self, frame): class TestClass(): def test_arg(): return "bar" frame.params.config.test_arg = TestClass mthd = get_method(frame, "test_arg") assert mthd() == "bar"
def _fug_phase_comp(b, p, j, T): pobj = b.params.get_phase(p) if pobj.is_vapor_phase(): return b.mole_frac_phase_comp[p, j] * b.pressure elif pobj.is_liquid_phase(): return (b.mole_frac_phase_comp[p, j] * get_method(b, "pressure_sat_comp", j)(b, cobj(b, j), T)) else: raise PropertyNotSupportedError(_invalid_phase_msg(b.name, p))
def log_fug_phase_comp_eq(b, p, j, pp): pobj = b.params.get_phase(p) if pobj.is_vapor_phase(): return log(b.mole_frac_phase_comp[p, j]) + log(b.pressure) elif pobj.is_liquid_phase(): return (log(b.mole_frac_phase_comp[p, j]) + log(get_method(b, "pressure_sat_comp", j)( b, cobj(b, j), b.temperature))) else: raise PropertyNotSupportedError(_invalid_phase_msg(b.name, p))
def enth_mol_phase(b, p): pobj = b.params.get_phase(p) if pobj.is_vapor_phase(): return sum(b.get_mole_frac()[p, j]*b.enth_mol_phase_comp[p, j] for j in b.components_in_phase(p)) elif pobj.is_liquid_phase(): return (sum(b.get_mole_frac()[p, j] * get_method(b, "enth_mol_liq_comp", j)( b, cobj(b, j), b.temperature) for j in b.components_in_phase(p)) + (b.pressure-b.params.pressure_ref)/b.dens_mol_phase[p]) elif pobj.is_solid_phase(): return (sum(b.get_mole_frac()[p, j] * get_method(b, "enth_mol_sol_comp", j)( b, cobj(b, j), b.temperature) for j in b.components_in_phase(p)) + (b.pressure-b.params.pressure_ref)/b.dens_mol_phase[p]) else: raise PropertyNotSupportedError(_invalid_phase_msg(b.name, p))
def get_vol_mol_pure(b, phase, comp, temperature): try: vol_mol = get_method(b, "vol_mol_"+phase+"_comp", comp)( b, cobj(b, comp), temperature) except (AttributeError, ConfigurationError): # vol_mol not defined, try for dens_mol instead try: vol_mol = 1/get_method(b, "dens_mol_"+phase+"_comp", comp)( b, cobj(b, comp), temperature) except (AttributeError, ConfigurationError): # Does not have either vol_mol or dens_mol suffix = "_"+phase+"_comp" raise ConfigurationError( f"{b.name} does not have a method defined to use " f"when calculating molar volume and density for " f"component {comp} in phase {phase}. Each component " f"must define a method for either vol_mol{suffix} or " f"dens_mol{suffix}.") return vol_mol
def rule_bubble_temp(b, p1, p2): (l_phase, v_phase, vl_comps, henry_comps, l_only_comps, v_only_comps) = _valid_VL_component_list(b, (p1, p2)) if l_phase is None or v_phase is None: # Not a VLE pair return Constraint.Skip elif v_only_comps != []: # Non-condensables present, no bubble point return Constraint.Skip return (sum( b.mole_frac_comp[j] * get_method(b, "pressure_sat_comp", j) (b, cobj(b, j), b.temperature_bubble[p1, p2]) for j in vl_comps) + sum(b.mole_frac_comp[j] * get_method(b, "henry_component", j, l_phase) (b, l_phase, j, b.temperature_bubble[p1, p2]) for j in henry_comps) - b.pressure) == 0
def dens_mol_phase(b, p): pobj = b.params.get_phase(p) if pobj.is_vapor_phase(): return b.pressure/(Ideal.gas_constant(b)*b.temperature) elif pobj.is_liquid_phase(): return sum(b.mole_frac_phase_comp[p, j] * get_method(b, "dens_mol_liq_comp", j)( b, cobj(b, j), b.temperature) for j in b.components_in_phase(p)) else: raise PropertyNotSupportedError(_invalid_phase_msg(b.name, p))