def test_option_has_pressure_change(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = props.PropParameterBlock() m.fs.unit = NanofiltrationZO(default={ "property_package": m.fs.properties, "has_pressure_change": True }) assert isinstance(m.fs.unit.feed_side.deltaP, Var) assert isinstance(m.fs.unit.deltaP, Var)
def test_config(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = props.PropParameterBlock() m.fs.unit = NanofiltrationZO(default={"property_package": m.fs.properties}) assert len(m.fs.unit.config) == 8 assert not m.fs.unit.config.dynamic assert not m.fs.unit.config.has_holdup assert m.fs.unit.config.material_balance_type == MaterialBalanceType.useDefault assert m.fs.unit.config.energy_balance_type == EnergyBalanceType.useDefault assert m.fs.unit.config.momentum_balance_type == MomentumBalanceType.pressureTotal assert not m.fs.unit.config.has_pressure_change assert m.fs.unit.config.property_package is m.fs.properties
def unit_frame(self): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = props.PropParameterBlock() m.fs.unit = NanofiltrationZO( default={"property_package": m.fs.properties}) # fully specify system feed_flow_mass = 1 feed_mass_frac = { "Na": 11122e-6, "Ca": 382e-6, "Mg": 1394e-6, "SO4": 2136e-6, "Cl": 20316.88e-6, } m.fs.unit.feed_side.properties_in[0].flow_mass_phase_comp[ "Liq", "H2O"].fix(feed_flow_mass * (1 - sum(x for x in feed_mass_frac.values()))) for j in feed_mass_frac: m.fs.unit.feed_side.properties_in[0].flow_mass_phase_comp[ "Liq", j].fix(feed_flow_mass * feed_mass_frac[j]) m.fs.unit.feed_side.properties_in[0].pressure.fix(101325) m.fs.unit.feed_side.properties_in[0].temperature.fix(298.15) m.fs.unit.flux_vol_solvent.fix(1.67e-6) m.fs.unit.area.fix(500) m.fs.unit.properties_permeate[0].pressure.fix(101325) m.fs.unit.rejection_phase_comp[0, "Liq", "Na"].fix(0.01) m.fs.unit.rejection_phase_comp[0, "Liq", "Ca"].fix(0.79) m.fs.unit.rejection_phase_comp[0, "Liq", "Mg"].fix(0.94) m.fs.unit.rejection_phase_comp[0, "Liq", "SO4"].fix(0.87) m.fs.unit.rejection_phase_comp[ 0, "Liq", "Cl"] = 0.15 # guess, but electroneutrality enforced below charge_comp = {"Na": 1, "Ca": 2, "Mg": 2, "SO4": -2, "Cl": -1} m.fs.unit.eq_electroneutrality = Constraint(expr=0 == sum( charge_comp[j] * m.fs.unit.feed_side.properties_out[0].conc_mol_phase_comp["Liq", j] for j in charge_comp)) constraint_scaling_transform(m.fs.unit.eq_electroneutrality, 1) return m
def build_prop(m, base="TDS"): """ Builds a property package for the specified base. Includes default scaling. Bases include: 'TDS', 'ion', 'salt'. """ if base == "TDS": m.fs.prop_TDS = seawater_prop_pack.SeawaterParameterBlock() m.fs.prop_TDS.set_default_scaling("flow_mass_phase_comp", 1, index=("Liq", "H2O")) m.fs.prop_TDS.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "TDS")) elif base == "ion": m.fs.prop_ion = seawater_ion_prop_pack.PropParameterBlock() m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp", 1, index=("Liq", "H2O")) m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "Na")) m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp", 1e4, index=("Liq", "Ca")) m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp", 1e3, index=("Liq", "Mg")) m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp", 1e3, index=("Liq", "SO4")) m.fs.prop_ion.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "Cl")) elif base == "salt": m.fs.prop_salt = seawater_salt_prop_pack.PropParameterBlock() m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp", 1, index=("Liq", "H2O")) m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "NaCl")) m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp", 1e3, index=("Liq", "CaSO4")) m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp", 1e3, index=("Liq", "MgSO4")) m.fs.prop_salt.set_default_scaling("flow_mass_phase_comp", 1e3, index=("Liq", "MgCl2")) elif base == "eNRTL": m.fs.prop_eNRTL = GenericParameterBlock( default=entrl_config_FpcTP.configuration) # default scaling in config file else: raise ValueError( "Unexpected property base {base} provided to build_prop" "".format(base=base))
def test_property_seawater_ions(): m = ConcreteModel() m.fs = FlowsheetBlock(default={"dynamic": False}) m.fs.properties = property_seawater_ions.PropParameterBlock() m.fs.stream = m.fs.properties.build_state_block([0], default={}) # specify feed_flow_mass = 1 feed_mass_frac = { "Na": 11122e-6, "Ca": 382e-6, "Mg": 1394e-6, "SO4": 2136e-6, "Cl": 20300e-6, } m.fs.stream[0].flow_mass_phase_comp["Liq", "H2O"].fix( feed_flow_mass * (1 - sum(x for x in feed_mass_frac.values()))) for s in feed_mass_frac: m.fs.stream[0].flow_mass_phase_comp["Liq", s].fix(feed_flow_mass * feed_mass_frac[s]) m.fs.stream[0].temperature.fix(273.15 + 25) m.fs.stream[0].pressure.fix(101325) m.fs.stream[0].mass_frac_phase_comp m.fs.stream[0].flow_mol_phase_comp # scaling m.fs.properties.set_default_scaling("flow_mass_phase_comp", 1, index=("Liq", "H2O")) m.fs.properties.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "Na")) m.fs.properties.set_default_scaling("flow_mass_phase_comp", 1e4, index=("Liq", "Ca")) m.fs.properties.set_default_scaling("flow_mass_phase_comp", 1e3, index=("Liq", "Mg")) m.fs.properties.set_default_scaling("flow_mass_phase_comp", 1e3, index=("Liq", "SO4")) m.fs.properties.set_default_scaling("flow_mass_phase_comp", 1e2, index=("Liq", "Cl")) iscale.calculate_scaling_factors(m.fs) # checking state block assert_units_consistent(m) check_dof(m) # initialize m.fs.stream.initialize(optarg={"nlp_scaling_method": "user-scaling"}) # solve solve_block(m) # check values assert value(m.fs.stream[0].mass_frac_phase_comp["Liq", "H2O"]) == pytest.approx( 0.9647, rel=1e-3) assert value(m.fs.stream[0].flow_mol_phase_comp["Liq", "Na"]) == pytest.approx( 0.4838, rel=1e-3) assert value(m.fs.stream[0].flow_mol_phase_comp["Liq", "Ca"]) == pytest.approx( 9.531e-3, rel=1e-3)
def build_prop(m, base='TDS'): """ Builds a property package for the specified base. Includes default scaling. Bases include: 'TDS', 'ion', 'salt'. """ if base == 'TDS': m.fs.prop_TDS = seawater_prop_pack.SeawaterParameterBlock() m.fs.prop_TDS.set_default_scaling('flow_mass_phase_comp', 1, index=('Liq', 'H2O')) m.fs.prop_TDS.set_default_scaling('flow_mass_phase_comp', 1e2, index=('Liq', 'TDS')) elif base == 'ion': m.fs.prop_ion = seawater_ion_prop_pack.PropParameterBlock() m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp', 1, index=('Liq', 'H2O')) m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp', 1e2, index=('Liq', 'Na')) m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp', 1e4, index=('Liq', 'Ca')) m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp', 1e3, index=('Liq', 'Mg')) m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp', 1e3, index=('Liq', 'SO4')) m.fs.prop_ion.set_default_scaling('flow_mass_phase_comp', 1e2, index=('Liq', 'Cl')) elif base == 'salt': m.fs.prop_salt = seawater_salt_prop_pack.PropParameterBlock() m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp', 1, index=('Liq', 'H2O')) m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp', 1e2, index=('Liq', 'NaCl')) m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp', 1e3, index=('Liq', 'CaSO4')) m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp', 1e3, index=('Liq', 'MgSO4')) m.fs.prop_salt.set_default_scaling('flow_mass_phase_comp', 1e3, index=('Liq', 'MgCl2')) elif base == 'eNRTL': m.fs.prop_eNRTL = GenericParameterBlock( default=entrl_config_FpcTP.configuration) # default scaling in config file else: raise ValueError( 'Unexpected property base {base} provided to build_prop' ''.format(base=base))