def test_rate_build_no_form(self, m, caplog): caplog.set_level(idaeslog.DEBUG, logger=("idaes.generic_models.properties.core." "generic.generic_reaction")) m.rxn_params = GenericReactionParameterBlock( default={ "property_package": m.params, "base_units": base_units, "rate_reactions": { "r1": { "stoichiometry": { ("p1", "c1"): -1, ("p1", "c2"): 2 }, "heat_of_reaction": "foo" } } }) assert ("rxn_params rate reaction r1 was not provided with a " "rate_form configuration argument. This is suitable for " "processes using stoichiometric reactors, but not for those " "using unit operations which rely on reaction rate." in caplog.text)
def test_missing_required_quantity(self, m): with pytest.raises( PropertyPackageError, match="Unrecognized units of measurment for quantity time " "\(None\)"): m.rxn_params = GenericReactionParameterBlock( default={ "property_package": m.params, "rate_reactions": { "r1": { "stoichiometry": { ("p1", "c1"): -1, ("p1", "c2"): 2 }, "heat_of_reaction": "foo", "rate_form": "foo" } }, "base_units": { "length": pyunits.m, "mass": pyunits.kg, "amount": pyunits.mol, "temperature": pyunits.K } })
def water_model(self): model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock( default=water_thermo_config) model.fs.rxn_params = GenericReactionParameterBlock( default={ "property_package": model.fs.thermo_params, **reaction_config }) model.fs.unit = EquilibriumReactor( default={ "property_package": model.fs.thermo_params, "reaction_package": model.fs.rxn_params, "has_rate_reactions": False, "has_equilibrium_reactions": False, "has_heat_transfer": False, "has_heat_of_reaction": False, "has_pressure_change": False, }) # NOTE: ENRTL model cannot initialize if the inlet values are 0 zero = 1e-20 model.fs.unit.inlet.mole_frac_comp[0, "H_+"].fix(zero) model.fs.unit.inlet.mole_frac_comp[0, "OH_-"].fix(zero) model.fs.unit.inlet.mole_frac_comp[0, "H2O"].fix(1.0 - 2 * zero) model.fs.unit.inlet.pressure.fix(101325.0) model.fs.unit.inlet.temperature.fix(298.0) model.fs.unit.inlet.flow_mol.fix(10) return model
def equilibrium_reactions_config(self): model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock( default=thermo_only_config) model.fs.rxn_params = GenericReactionParameterBlock( default={ "property_package": model.fs.thermo_params, **water_reaction_config }) model.fs.unit = EquilibriumReactor( default={ "property_package": model.fs.thermo_params, "reaction_package": model.fs.rxn_params, "has_rate_reactions": False, "has_equilibrium_reactions": True, "has_heat_transfer": False, "has_heat_of_reaction": False, "has_pressure_change": False }) model.fs.unit.inlet.mole_frac_comp[0, "H_+"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "OH_-"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "H2O"].fix(1.) model.fs.unit.inlet.pressure.fix(101325.0) model.fs.unit.inlet.temperature.fix(298.) model.fs.unit.inlet.flow_mol.fix(10) return model
def test_missing_required_quantity(self, m): with pytest.raises( ConfigurationError, match="rxn_params units for quantity time were not assigned. " "Please make sure to provide units for all base units " "when configuring the reaction package."): m.rxn_params = GenericReactionParameterBlock( default={ "property_package": m.params, "rate_reactions": { "r1": { "stoichiometry": { ("p1", "c1"): -1, ("p1", "c2"): 2 }, "heat_of_reaction": "foo", "rate_form": "foo" } }, "base_units": { "length": pyunits.m, "mass": pyunits.kg, "amount": pyunits.mol, "temperature": pyunits.K } })
def test_invalid_unit(self, m): with pytest.raises( ConfigurationError, match="rxn_params recieved unexpected units for quantity time:" " foo. Units must be instances of a Pyomo unit object."): m.rxn_params = GenericReactionParameterBlock( default={ "property_package": m.params, "rate_reactions": { "r1": { "stoichiometry": { ("p1", "c1"): -1, ("p1", "c2"): 2 }, "heat_of_reaction": "foo", "rate_form": "foo" } }, "base_units": { "time": "foo", "length": pyunits.m, "mass": pyunits.kg, "amount": pyunits.mol, "temperature": pyunits.K } })
def test_rate_and_equil_build(self, m): m.rxn_params = GenericReactionParameterBlock(default={ "property_package": m.params, "base_units": base_units, "rate_reactions": { "r1": {"stoichiometry": {("p1", "c1"): -1, ("p1", "c2"): 2}, "heat_of_reaction": "foo", "rate_form": "foo"}}, "equilibrium_reactions": { "e1": {"stoichiometry": {("p2", "c1"): -3, ("p2", "c2"): 4}, "heat_of_reaction": "foo", "equilibrium_form": "foo"}}}) r_rxn_config = m.rxn_params.config.rate_reactions assert isinstance(m.rxn_params.rate_reaction_idx, Set) assert len(m.rxn_params.rate_reaction_idx) == 1 assert "r1" in m.rxn_params.rate_reaction_idx assert not hasattr(self, "equilibrium_reaction_idx") assert isinstance(m.rxn_params.rate_reaction_stoichiometry, dict) assert len(m.rxn_params.rate_reaction_stoichiometry) == 4 for k, v in m.rxn_params.rate_reaction_stoichiometry.items(): if (k[1], k[2]) in r_rxn_config[k[0]].stoichiometry.keys(): assert v == r_rxn_config[k[0]].stoichiometry[k[1], k[2]] else: assert v == 0 assert not hasattr(self, "equilibrium_reaction_stoichiometry") e_rxn_config = m.rxn_params.config.equilibrium_reactions assert isinstance(m.rxn_params.equilibrium_reaction_idx, Set) assert len(m.rxn_params.equilibrium_reaction_idx) == 1 assert "e1" in m.rxn_params.equilibrium_reaction_idx assert not hasattr(self, "rate_reaction_idx") assert isinstance(m.rxn_params.equilibrium_reaction_stoichiometry, dict) assert len(m.rxn_params.equilibrium_reaction_stoichiometry) == 4 for k, v in m.rxn_params.equilibrium_reaction_stoichiometry.items(): if (k[1], k[2]) in e_rxn_config[k[0]].stoichiometry.keys(): assert v == e_rxn_config[k[0]].stoichiometry[k[1], k[2]] else: assert v == 0 assert not hasattr(self, "rate_reaction_stoichiometry") assert isinstance(m.rxn_params.reaction_idx, Set) assert m.rxn_params.reaction_idx == ( m.rxn_params.rate_reaction_idx | m.rxn_params.equilibrium_reaction_idx) assert len(m.rxn_params.reaction_idx) == 2 assert isinstance(m.rxn_params.reaction_r1, Block) assert isinstance(m.rxn_params.reaction_e1, Block)
def carbonic_acid_model(self): model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock(default=carbonic_thermo_config) model.fs.rxn_params = GenericReactionParameterBlock( default={"property_package": model.fs.thermo_params, **reaction_config}) model.fs.unit = EquilibriumReactor(default={ "property_package": model.fs.thermo_params, "reaction_package": model.fs.rxn_params, "has_rate_reactions": False, "has_equilibrium_reactions": False, "has_heat_transfer": False, "has_heat_of_reaction": False, "has_pressure_change": False}) #NOTE: ENRTL model cannot initialize if the inlet values are 0 zero = 1e-20 acid = 0.00206/(55.2+0.00206) model.fs.unit.inlet.mole_frac_comp[0, "H_+"].fix( zero ) model.fs.unit.inlet.mole_frac_comp[0, "OH_-"].fix( zero ) # Added as conjugate base form model.fs.unit.inlet.mole_frac_comp[0, "CO3_2-"].fix( zero ) model.fs.unit.inlet.mole_frac_comp[0, "HCO3_-"].fix( acid ) model.fs.unit.inlet.mole_frac_comp[0, "H2CO3"].fix( zero ) model.fs.unit.inlet.mole_frac_comp[0, "Na_+"].fix( acid ) model.fs.unit.inlet.mole_frac_comp[0, "H2O"].fix( 1.-4*zero-acid- \ value(model.fs.unit.inlet.mole_frac_comp[0, "Na_+"]) ) model.fs.unit.inlet.pressure.fix(101325.0) model.fs.unit.inlet.temperature.fix(298.) model.fs.unit.inlet.flow_mol.fix(10) return model
def model(): m = ConcreteModel() # # Add a test thermo package for validation m.pparams = PhysicalParameterTestBlock() m.thermo = m.pparams.build_state_block([1]) m.rparams = GenericReactionParameterBlock(default={ "property_package": m.pparams, "reaction_basis": MaterialFlowBasis.molar, "equilibrium_reactions": { "r1": {"stoichiometry": {("p1", "c1"): -1, ("p1", "c2"): 2}, "equilibrium_form": "foo", "concentration_form": ConcentrationForm.moleFraction}}, "base_units": {"amount": pyunits.mol, "mass": pyunits.kg, "time": pyunits.s, "length": pyunits.m, "temperature": pyunits.K}}) m.rxn = m.rparams.build_reaction_block([1], default={ "state_block": m.thermo, "has_equilibrium": False}) m.rxn[1].dh_rxn = Var(["r1"], initialize=1, units=pyunits.J/pyunits.mol) return m
def test_build_parameters(self, m): m.rxn_params = GenericReactionParameterBlock(default={ "property_package": m.params, "base_units": base_units, "rate_reactions": { "r1": {"stoichiometry": {("p1", "c1"): -1, ("p1", "c2"): 2}, "heat_of_reaction": constant_dh_rxn, "rate_form": "foo", "parameter_data": { "dh_rxn_ref": -10000}}}, "equilibrium_reactions": { "e1": {"stoichiometry": {("p2", "c1"): -3, ("p2", "c2"): 4}, "heat_of_reaction": constant_dh_rxn, "equilibrium_form": "foo", "parameter_data": { "dh_rxn_ref": -20000}}}}) assert isinstance(m.rxn_params.reaction_r1.dh_rxn_ref, Var) assert m.rxn_params.reaction_r1.dh_rxn_ref.fixed assert m.rxn_params.reaction_r1.dh_rxn_ref.value == -10000 assert isinstance(m.rxn_params.reaction_e1.dh_rxn_ref, Var) assert m.rxn_params.reaction_e1.dh_rxn_ref.fixed assert m.rxn_params.reaction_e1.dh_rxn_ref.value == -20000
def model(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) # Add a test thermo package for validation m.fs.pparams = GenericParameterBlock(default=thermo_config) m.fs.rparams = GenericReactionParameterBlock(default={ "property_package": m.fs.pparams, **rxn_config }) # Don't include energy balances, as the test doesn't have a proper # enthalpy model. Fix outlet T instead. m.fs.R101 = EquilibriumReactor( default={ "property_package": m.fs.pparams, "reaction_package": m.fs.rparams, "has_equilibrium_reactions": True, "has_rate_reactions": False, "energy_balance_type": EnergyBalanceType.none }) m.fs.R101.inlet.flow_mol_phase_comp[0, "Liq", "H2O"].fix(55.56) m.fs.R101.inlet.flow_mol_phase_comp[0, "Liq", "Na+"].fix(1e-8) m.fs.R101.inlet.flow_mol_phase_comp[0, "Liq", "Cl-"].fix(1e-8) m.fs.R101.inlet.flow_mol_phase_comp[0, "Sol", "NaCl"].fix(1e-8) m.fs.R101.inlet.temperature[0].fix(298.15) m.fs.R101.inlet.pressure[0].fix(101325) m.fs.R101.outlet.temperature[0].fix(298.15) return m
def model(self, thermo_config, variant: Variant, water_reaction_config): if variant.is_equilibrium: thermo_config = _get_without_inherent_reactions(thermo_config) model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock(default=thermo_config) print(water_reaction_config) model.fs.rxn_params = GenericReactionParameterBlock( default={ "property_package": model.fs.thermo_params, **water_reaction_config }) model.fs.unit = EquilibriumReactor( default={ "property_package": model.fs.thermo_params, "reaction_package": model.fs.rxn_params, "has_rate_reactions": False, "has_equilibrium_reactions": variant.is_equilibrium, "has_heat_transfer": False, "has_heat_of_reaction": False, "has_pressure_change": False, }) model.fs.unit.inlet.mole_frac_comp[0, "H_+"].fix(0.0) model.fs.unit.inlet.mole_frac_comp[0, "OH_-"].fix(0.0) model.fs.unit.inlet.mole_frac_comp[0, "H2O"].fix(1.0) model.fs.unit.inlet.pressure.fix(101325.0) model.fs.unit.inlet.temperature.fix(298.0) model.fs.unit.inlet.flow_mol.fix(10) return model
def test_power_law_rate_no_order(): m = ConcreteModel() # # Add a test thermo package for validation m.pparams = PhysicalParameterTestBlock() m.thermo = m.pparams.build_state_block([1]) m.rparams = GenericReactionParameterBlock( default={ "property_package": m.pparams, "base_units": { "time": pyunits.s, "mass": pyunits.kg, "amount": pyunits.mol, "length": pyunits.m, "temperature": pyunits.K }, "rate_reactions": { "r1": { "stoichiometry": { ("p1", "c1"): -1, ("p1", "c2"): 2 }, "rate_form": power_law_rate, "concentration_form": ConcentrationForm.moleFraction } } }) # Create a dummy state block m.rxn = Block([1]) add_object_reference(m.rxn[1], "params", m.rparams) add_object_reference(m.rxn[1], "state_ref", m.thermo[1]) m.rxn[1].k_rxn = Var(["r1"], initialize=1) power_law_rate.build_parameters(m.rparams.reaction_r1, m.rparams.config.rate_reactions["r1"]) # Check parameter construction assert isinstance(m.rparams.reaction_r1.reaction_order, Var) assert len(m.rparams.reaction_r1.reaction_order) == 4 for i, v in m.rparams.reaction_r1.reaction_order.items(): try: stoic = m.rparams.config.rate_reactions.r1.stoichiometry[i] except KeyError: stoic = 0 if stoic < 1: assert v.value == -stoic else: assert v.value == 0 # Check reaction form rform = power_law_rate.return_expression(m.rxn[1], m.rparams.reaction_r1, "r1", 300) assert str(rform) == str(m.rxn[1].k_rxn["r1"] * m.thermo[1].mole_frac_phase_comp["p1", "c1"]** m.rparams.reaction_r1.reaction_order["p1", "c1"])
def test_power_law_rate_with_order(): m = ConcreteModel() # # Add a test thermo package for validation m.pparams = PhysicalParameterTestBlock() m.thermo = m.pparams.build_state_block([1]) m.rparams = GenericReactionParameterBlock(default={ "property_package": m.pparams, "base_units": {"time": pyunits.s, "mass": pyunits.kg, "amount": pyunits.mol, "length": pyunits.m, "temperature": pyunits.K}, "rate_reactions": { "r1": {"stoichiometry": {("p1", "c1"): -1, ("p1", "c2"): 2}, "rate_form": power_law_rate, "concentration_form": ConcentrationForm.moleFraction, "parameter_data": { "reaction_order": {("p1", "c1"): 1, ("p1", "c2"): 2, ("p2", "c1"): 3, ("p2", "c2"): 4}}}}}) # Create a dummy state block m.rxn = Block([1]) add_object_reference( m.rxn[1], "phase_component_set", m.pparams._phase_component_set) add_object_reference(m.rxn[1], "params", m.rparams) add_object_reference(m.rxn[1], "state_ref", m.thermo[1]) m.rxn[1].k_rxn = Var(["r1"], initialize=1) power_law_rate.build_parameters( m.rparams.reaction_r1, m.rparams.config.rate_reactions["r1"]) # Check parameter construction assert isinstance(m.rparams.reaction_r1.reaction_order, Var) assert len(m.rparams.reaction_r1.reaction_order) == 4 assert m.rparams.reaction_r1.reaction_order["p1", "c1"].value == 1 assert m.rparams.reaction_r1.reaction_order["p1", "c2"].value == 2 assert m.rparams.reaction_r1.reaction_order["p2", "c1"].value == 3 assert m.rparams.reaction_r1.reaction_order["p2", "c2"].value == 4 # Check reaction form rform = power_law_rate.return_expression( m.rxn[1], m.rparams.reaction_r1, "r1", 300) assert str(rform) == str( m.rxn[1].k_rxn["r1"] * ( m.thermo[1].mole_frac_phase_comp["p1", "c1"] ** m.rparams.reaction_r1.reaction_order["p1", "c1"] * m.thermo[1].mole_frac_phase_comp["p1", "c2"] ** m.rparams.reaction_r1.reaction_order["p1", "c2"] * m.thermo[1].mole_frac_phase_comp["p2", "c1"] ** m.rparams.reaction_r1.reaction_order["p2", "c1"] * m.thermo[1].mole_frac_phase_comp["p2", "c2"] ** m.rparams.reaction_r1.reaction_order["p2", "c2"]))
def build_ideal_naocl_prop(model): model.fs.ideal_naocl_thermo_params = GenericParameterBlock( default=ideal_naocl_thermo_config) model.fs.ideal_naocl_rxn_params = GenericReactionParameterBlock( default={ "property_package": model.fs.ideal_naocl_thermo_params, **ideal_naocl_reaction_config })
def is_thermo_reaction_pair_valid(thermo_config, reaction_config): model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock(default=thermo_config) model.fs.rxn_params = GenericReactionParameterBlock( default={"property_package": model.fs.thermo_params, **reaction_config} ) return True
def chlorination_obj(self): model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock(default=thermo_config) model.fs.rxn_params = GenericReactionParameterBlock( default={ "property_package": model.fs.thermo_params, **reaction_config }) model.fs.unit = EquilibriumReactor( default={ "property_package": model.fs.thermo_params, "reaction_package": model.fs.rxn_params, "has_rate_reactions": False, "has_equilibrium_reactions": True, "has_heat_transfer": False, "has_heat_of_reaction": False, "has_pressure_change": False }) model.fs.unit.inlet.mole_frac_comp[0, "H_+"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "OH_-"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "OCl_-"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "NH4_+"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "NH2Cl"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "NHCl2"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "NCl3"].fix(0.) waste_stream_ammonia = 1 #mg/L total_molar_density = 54.8 #mol/L total_ammonia_inlet = waste_stream_ammonia / 17000 # mol/L total_molar_density += total_ammonia_inlet # Free Chlorine (mg-Cl2/L) = total_chlorine_inlet (mol/L) * 70,900 free_chlorine_added = 15 #mg/L as Cl2 total_chlorine_inlet = free_chlorine_added / 70900 # mol/L total_molar_density += total_chlorine_inlet model.fs.unit.inlet.mole_frac_comp[0, "NH3"].fix(total_ammonia_inlet / total_molar_density) model.fs.unit.inlet.mole_frac_comp[0, "HOCl"].fix( total_chlorine_inlet / total_molar_density) # Perform a summation of all non-H2O molefractions to find the H2O molefraction sum = 0 for i in model.fs.unit.inlet.mole_frac_comp: # NOTE: i will be a tuple with format (time, component) if i[1] != "H2O": sum += value(model.fs.unit.inlet.mole_frac_comp[i[0], i[1]]) model.fs.unit.inlet.mole_frac_comp[0, "H2O"].fix(1 - sum) model.fs.unit.inlet.pressure.fix(101325.0) model.fs.unit.inlet.temperature.fix(300.) model.fs.unit.inlet.flow_mol.fix(10) return model
def model(self): m = ConcreteModel() # Add a dummy thermo package for validation m.params = GenericParameterBlock(default={ "components": {"c1": {}, "c2": {}}, "phases": { "p1": {"equation_of_state": DummyEoS}, "p2": {"equation_of_state": DummyEoS}}, "state_definition": modules[__name__], "pressure_ref": 1e5, "temperature_ref": 300, "base_units": base_units}) m.sblock = m.params.build_state_block([1]) m.rxn_params = GenericReactionParameterBlock(default={ "property_package": m.params, "base_units": base_units, "rate_reactions": { "r1": {"stoichiometry": {("p1", "c1"): -1, ("p1", "c2"): 2}, "heat_of_reaction": constant_dh_rxn, "rate_constant": arrhenius, "rate_form": power_law_rate, "concentration_form": ConcentrationForm.moleFraction, "parameter_data": { "dh_rxn_ref": -10000, "arrhenius_const": 1, "energy_activation": 1000}}}, "equilibrium_reactions": { "e1": {"stoichiometry": {("p2", "c1"): -3, ("p2", "c2"): 4}, "heat_of_reaction": constant_dh_rxn, "equilibrium_constant": van_t_hoff, "equilibrium_form": power_law_equil, "concentration_form": ConcentrationForm.moleFraction, "parameter_data": { "dh_rxn_ref": -20000, "k_eq_ref": 100, "T_eq_ref": 350}}, "e2": {"stoichiometry": {("p2", "c1"): -5, ("p2", "c2"): 6}, "heat_of_reaction": constant_dh_rxn, "equilibrium_constant": van_t_hoff, "equilibrium_form": log_power_law_equil, "concentration_form": ConcentrationForm.moleFraction, "parameter_data": { "dh_rxn_ref": -20000, "k_eq_ref": 100, "T_eq_ref": 350}}}}) m.rblock = m.rxn_params.build_reaction_block( [1], default={"state_block": m.sblock, "has_equilibrium": True}) return m
def test_equil_build_no_stoichiometry(self, m): with pytest.raises(ConfigurationError, match="rxn_params equilibrium reaction e1 was not " "provided with a stoichiometry configuration " "argument."): m.rxn_params = GenericReactionParameterBlock(default={ "property_package": m.params, "base_units": base_units, "equilibrium_reactions": { "e1": {"heat_of_reaction": "foo", "equilibrium_form": "foo"}}})
def equilibrium_reactions_config(self): model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock( default=thermo_only_config) model.fs.rxn_params = GenericReactionParameterBlock( default={ "property_package": model.fs.thermo_params, **reaction_config }) model.fs.unit = EquilibriumReactor( default={ "property_package": model.fs.thermo_params, "reaction_package": model.fs.rxn_params, "has_rate_reactions": False, "has_equilibrium_reactions": True, "has_heat_transfer": False, "has_heat_of_reaction": False, "has_pressure_change": False }) model.fs.unit.inlet.mole_frac_comp[0, "H_+"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "OH_-"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "HCO3_-"].fix(0.) model.fs.unit.inlet.mole_frac_comp[0, "CO3_2-"].fix(0.) total_nacl_inlet = 0.55 # mol/L total_carbonate_inlet = 0.00206 # mol/L frac_CO3_to_NaHCO3 = 1 model.fs.unit.inlet.mole_frac_comp[0, "Na_+"].fix(total_nacl_inlet / 54.8) model.fs.unit.inlet.mole_frac_comp[0, "Cl_-"].fix(total_nacl_inlet / 54.8) model.fs.unit.inlet.mole_frac_comp[0, "NaHCO3"].fix( (total_carbonate_inlet * frac_CO3_to_NaHCO3) / 54.8) model.fs.unit.inlet.mole_frac_comp[0, "H2CO3"].fix( (total_carbonate_inlet * (1 - frac_CO3_to_NaHCO3)) / 54.8) # Perform a summation of all non-H2O molefractions to find the H2O molefraction sum = 0 for i in model.fs.unit.inlet.mole_frac_comp: # NOTE: i will be a tuple with format (time, component) if i[1] != "H2O": sum += value(model.fs.unit.inlet.mole_frac_comp[i[0], i[1]]) model.fs.unit.inlet.mole_frac_comp[0, "H2O"].fix(1 - sum) model.fs.unit.inlet.pressure.fix(101325.0) model.fs.unit.inlet.temperature.fix(298.) model.fs.unit.inlet.flow_mol.fix(10) return model
def test_log_solubility_no_solids(): m = ConcreteModel() # # Add a test thermo package for validation m.pparams = PhysicalParameterTestBlock() m.thermo = m.pparams.build_state_block([1]) # Create a dummy reaction parameter block m.rparams = GenericReactionParameterBlock( default={ "property_package": m.pparams, "base_units": { "time": pyunits.s, "mass": pyunits.kg, "amount": pyunits.mol, "length": pyunits.m, "temperature": pyunits.K }, "equilibrium_reactions": { "r1": { "stoichiometry": { ("p1", "c1"): -1, ("p1", "c2"): 2 }, "equilibrium_form": log_solubility_product, "concentration_form": ConcentrationForm.moleFraction } } }) # Create a dummy state block m.rxn = Block([1]) add_object_reference(m.rxn[1], "phase_component_set", m.pparams._phase_component_set) add_object_reference(m.rxn[1], "params", m.rparams) add_object_reference(m.rxn[1], "state_ref", m.thermo[1]) m.rxn[1].log_k_eq = Var(["r1"], initialize=1) m.thermo[1].log_mole_frac_phase_comp = Var(m.pparams._phase_component_set, initialize=1) log_solubility_product.build_parameters( m.rparams.reaction_r1, m.rparams.config.equilibrium_reactions["r1"]) # Check reaction form - should raise exception with pytest.raises(ConfigurationError, match="did not find a solid phase component for " "precipitation reaction r1. This is likely due to the " "reaction configuration."): log_solubility_product.return_expression(m.rxn[1], m.rparams.reaction_r1, "r1", 300)
def test_equil_build_invalid_component_stoichiometry(self, m): with pytest.raises(ConfigurationError, match="rxn_params stoichiometry for equilibrium " "reaction e1 included unrecognised component c7."): m.rxn_params = GenericReactionParameterBlock(default={ "property_package": m.params, "base_units": base_units, "equilibrium_reactions": { "e1": {"stoichiometry": {("p2", "c7"): -3, ("p2", "c2"): 4}, "heat_of_reaction": "foo", "equilibrium_form": "foo"}}})
def test_rate_build_invalid_phase_stoichiometry(self, m): with pytest.raises(ConfigurationError, match="rxn_params stoichiometry for rate reaction " "r1 included unrecognised phase p7."): m.rxn_params = GenericReactionParameterBlock(default={ "property_package": m.params, "base_units": base_units, "rate_reactions": { "r1": {"stoichiometry": {("p7", "c1"): -1, ("p1", "c2"): 2}, "heat_of_reaction": "foo", "rate_form": "foo"}}})
def run_the_basics_dummy_rxn_with_mockdb(db): base_obj = grab_base_thermo_config(db) (base_obj, comp_list) = get_components_and_add_to_idaes_config(db, base_obj, by_elements=True) # Add reactions to the thermo base as 'inherent' base_obj = get_reactions_return_object(db, base_obj, comp_list, is_inherent=True) # Create a reaction config react_base = grab_base_reaction_config(db) # If no reactions are in the reaction base, this will cause an error in IDAES. # However, we can add a 'dummy' reaction just to satisfy the IDAES code base. react_obj = db.get_reactions(reaction_names=["dummy"]) for r in react_obj: print("Found reaction: " + str(r.name)) react_base.add(r) # IDAES will throw an exception when we try to do this if something is wrong thermo_config = base_obj.idaes_config reaction_config = react_base.idaes_config model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock(default=thermo_config) model.fs.rxn_params = GenericReactionParameterBlock( default={ "property_package": model.fs.thermo_params, **reaction_config }) model.fs.unit = EquilibriumReactor( default={ "property_package": model.fs.thermo_params, "reaction_package": model.fs.rxn_params, "has_rate_reactions": False, "has_equilibrium_reactions": False, "has_heat_transfer": False, "has_heat_of_reaction": False, "has_pressure_change": False, }) # If all goes well, this function returns true return is_thermo_reaction_pair_valid(base_obj.idaes_config, react_base.idaes_config)
def test_rate_build(self, m): m.rxn_params = GenericReactionParameterBlock( default={ "property_package": m.params, "rate_reactions": { "r1": { "stoichiometry": { ("p1", "c1"): -1, ("p1", "c2"): 2 }, "heat_of_reaction": "foo", "rate_form": "foo" } }, "base_units": base_units }) rxn_config = m.rxn_params.config.rate_reactions assert m.rxn_params.get_metadata().default_units == { "time": pyunits.s, "length": pyunits.m, "mass": pyunits.kg, "amount": pyunits.mol, "temperature": pyunits.K, "current": None, "luminous intensity": None } assert isinstance(m.rxn_params.rate_reaction_idx, Set) assert len(m.rxn_params.rate_reaction_idx) == 1 assert "r1" in m.rxn_params.rate_reaction_idx assert not hasattr(self, "equilibrium_reaction_idx") assert isinstance(m.rxn_params.rate_reaction_stoichiometry, dict) assert len(m.rxn_params.rate_reaction_stoichiometry) == 4 for k, v in m.rxn_params.rate_reaction_stoichiometry.items(): if (k[1], k[2]) in rxn_config[k[0]].stoichiometry.keys(): assert v == rxn_config[k[0]].stoichiometry[k[1], k[2]] else: assert v == 0 assert not hasattr(self, "equilibrium_reaction_stoichiometry") assert isinstance(m.rxn_params.reaction_idx, Set) assert m.rxn_params.reaction_idx == m.rxn_params.rate_reaction_idx assert isinstance(m.rxn_params.reaction_r1, Block)
def model(self): m = ConcreteModel() # Add a test thermo package for validation m.pparams = GenericParameterBlock(default=thermo_config) m.rparams = GenericReactionParameterBlock(default={ "property_package": m.pparams, **rxn_config}) m.state = m.pparams.build_state_block( [0], default={"defined_state": False}) m.rxn = m.rparams.build_reaction_block( [0], default={"state_block": m.state, "has_equilibrium": True}) return m
def test_build(self): model = ConcreteModel() model.thermo_params = GenericParameterBlock( default=thermo_configuration) model.rxn_params = GenericReactionParameterBlock( default={ "property_package": model.thermo_params, **rxn_configuration }) rate_config = model.rxn_params.config.rate_reactions equil_config = model.rxn_params.config.equilibrium_reactions assert isinstance(model.rxn_params.rate_reaction_idx, Set) assert len(model.rxn_params.rate_reaction_idx) == 1 assert "R1" in model.rxn_params.rate_reaction_idx assert isinstance(model.rxn_params.equilibrium_reaction_idx, Set) assert len(model.rxn_params.equilibrium_reaction_idx) == 1 assert "R2" in model.rxn_params.equilibrium_reaction_idx assert isinstance(model.rxn_params.rate_reaction_stoichiometry, dict) assert len(model.rxn_params.rate_reaction_stoichiometry) == 4 for k, v in model.rxn_params.rate_reaction_stoichiometry.items(): if (k[1], k[2]) in rate_config[k[0]].stoichiometry.keys(): assert v == rate_config[k[0]].stoichiometry[k[1], k[2]] else: assert v == 0 assert isinstance(model.rxn_params.equilibrium_reaction_stoichiometry, dict) assert len(model.rxn_params.equilibrium_reaction_stoichiometry) == 4 for k, v in model.rxn_params.equilibrium_reaction_stoichiometry.items( ): if (k[1], k[2]) in equil_config[k[0]].stoichiometry.keys(): assert v == equil_config[k[0]].stoichiometry[k[1], k[2]] else: assert v == 0 assert isinstance(model.rxn_params.reaction_R1, Block) assert isinstance(model.rxn_params.reaction_R2, Block) assert_units_consistent(model)
def test_rate_build_no_form(self, m): with pytest.raises(ConfigurationError, match="rxn_params rate reaction r1 was not " "provided with a rate_form configuration " "argument."): m.rxn_params = GenericReactionParameterBlock( default={ "property_package": m.params, "base_units": base_units, "rate_reactions": { "r1": { "stoichiometry": { ("p1", "c1"): -1, ("p1", "c2"): 2 }, "heat_of_reaction": "foo" } } })
def model(self): model = ConcreteModel() model.thermo_params = GenericParameterBlock( default=thermo_configuration) model.rxn_params = GenericReactionParameterBlock( default={"property_package": model.thermo_params, **rxn_configuration}) model.props = model.thermo_params.build_state_block( [1], default={"defined_state": True}) model.rxns = model.rxn_params.build_reaction_block( [1], default={"state_block": model.props, "has_equilibrium": True}) assert_units_consistent(model) return model
def build_equilibrium_model(thermo_config, reaction_config): model = ConcreteModel() model.fs = FlowsheetBlock(default={"dynamic": False}) model.fs.thermo_params = GenericParameterBlock(default=thermo_config) model.fs.rxn_params = GenericReactionParameterBlock( default={ "property_package": model.fs.thermo_params, **reaction_config }) model.fs.unit = EquilibriumReactor( default={ "property_package": model.fs.thermo_params, "reaction_package": model.fs.rxn_params, "has_rate_reactions": False, "has_equilibrium_reactions": True, "has_heat_transfer": False, "has_heat_of_reaction": False, "has_pressure_change": False, }) return model