Example #1
0
    def _make_feed_arcs(self):

        self.feed_liq_in = Arc(
            source=self.rectification_section[
                self.config.feed_tray_location - 1].liq_out,
            destination=self.feed_tray.liq_in
        )

        self.feed_liq_out = Arc(
            source=self.feed_tray.liq_out,
            destination=self.stripping_section[
                self.config.feed_tray_location + 1].liq_in
        )

        self.feed_vap_in = Arc(
            source=self.stripping_section[
                self.config.feed_tray_location + 1].vap_out,
            destination=self.feed_tray.vap_in
        )

        self.feed_vap_out = Arc(
            source=self.feed_tray.vap_out,
            destination=self.rectification_section[
                self.config.feed_tray_location - 1].vap_in
        )
Example #2
0
def HX1D_array_model():
    # An example of maximum perversity. Dynamics, 1D control volumes, and 
    # an indexed unit
    unit_set = range(3)
    time_set = [0,5]
    time_units=pyunits.s
    fs_cfg = {
        "dynamic": True, "time_set": time_set, "time_units": time_units}
    
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default=fs_cfg)

    m.fs.properties = thermo_props.SaponificationParameterBlock()

    m.fs.unit_array = HX1D(unit_set,default={
            "shell_side": {"property_package": m.fs.properties},
            "tube_side": {"property_package": m.fs.properties}})

    def tube_stream_array_rule(b, i):
        return {'source':b.unit_array[i].tube_outlet, 
                'destination':b.unit_array[i+1].tube_inlet}
    m.fs.tube_stream_array = Arc(range(2), rule=tube_stream_array_rule)
    
    def shell_stream_array_rule(b, i):
        return {'source':b.unit_array[i+1].shell_outlet, 
                'destination':b.unit_array[i].shell_inlet}
    m.fs.shell_stream_array = Arc(range(1,-1,-1), rule=shell_stream_array_rule)

    TransformationFactory("network.expand_arcs").apply_to(m)
    return m
def test_build_flowsheet():
    model = run_chlorination_block_example(fix_free_chlorine=True)
    property_models.build_prop(model, base="TDS")
    build_translator_from_RO_to_chlorination_block(model)
    # Here, we set 'has_feed' to True because RO is our first block in the flowsheet
    kwargs_desal = {
        "has_desal_feed": True,
        "is_twostage": False,
        "has_ERD": False,
        "RO_type": "0D",
        "RO_base": "TDS",
        "RO_level": "detailed",
    }
    desal_port = desalination.build_desalination(model, **kwargs_desal)
    desalination.scale_desalination(model, **kwargs_desal)
    desalination.initialize_desalination(model, **kwargs_desal)

    # Add the connecting arcs
    model.fs.S1 = Arc(source=desal_port["out"],
                      destination=model.fs.RO_to_Chlor.inlet)
    model.fs.S2 = Arc(
        source=model.fs.RO_to_Chlor.outlet,
        destination=model.fs.ideal_naocl_mixer_unit.inlet_stream,
    )
    TransformationFactory("network.expand_arcs").apply_to(model)

    # Unfix inlet stream for mixer
    unfix_ideal_naocl_mixer_inlet_stream(model)
    check_dof(model)
Example #4
0
def m():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.thermo_params = thermo_props.SaponificationParameterBlock()
    m.fs.reaction_params = rxn_props.SaponificationReactionParameterBlock(
        default={"property_package": m.fs.thermo_params})

    m.fs.tank1 = CSTR(default={"property_package": m.fs.thermo_params,
                               "reaction_package": m.fs.reaction_params})
    m.fs.tank2 = CSTR(default={"property_package": m.fs.thermo_params,
                               "reaction_package": m.fs.reaction_params})
    m.fs.tank_array = CSTR(
        range(3),
        default={"property_package": m.fs.thermo_params,
                 "reaction_package": m.fs.reaction_params})

    m.fs.stream = Arc(source=m.fs.tank1.outlet,
                      destination=m.fs.tank2.inlet)

    def stream_array_rule(b, i):
        return (b.tank_array[i].outlet, b.tank_array[i+1].inlet)
    m.fs.stream_array = Arc(range(2), rule=stream_array_rule)

    TransformationFactory("network.expand_arcs").apply_to(m)

    return m
Example #5
0
def build_turbine_for_run_test():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95_ph.Iapws95ParameterBlock()
    # roughly based on NETL baseline studies
    m.fs.turb = TurbineMultistage(
        default={
            "property_package": m.fs.properties,
            "num_hp": 7,
            "num_ip": 14,
            "num_lp": 11,
            "hp_split_locations": [4, 7],
            "ip_split_locations": [5, 14],
            "lp_split_locations": [4, 7, 9, 11],
            "hp_disconnect": [7],
            "ip_split_num_outlets": {
                14: 3
            }
        })

    # Add reheater
    m.fs.reheat = Heater(default={"property_package": m.fs.properties})
    m.fs.hp_to_reheat = Arc(source=m.fs.turb.hp_split[7].outlet_1,
                            destination=m.fs.reheat.inlet)
    m.fs.reheat_to_ip = Arc(source=m.fs.reheat.outlet,
                            destination=m.fs.turb.ip_stages[1].inlet)

    return m
Example #6
0
    def _make_condenser_arcs(self):

        self.condenser_vap_in = Arc(
            source=self.rectification_section[1].vap_out,
            destination=self.condenser.inlet)

        self.condenser_reflux_out = Arc(
            source=self.condenser.reflux,
            destination=self.rectification_section[1].liq_in)
Example #7
0
    def _make_reboiler_arcs(self):

        self.reboiler_liq_in = Arc(
            source=self.stripping_section[self.config.number_of_trays].liq_out,
            destination=self.reboiler.inlet)

        self.reboiler_vap_out = Arc(source=self.reboiler.vapor_reboil,
                                    destination=self.stripping_section[
                                        self.config.number_of_trays].vap_in)
Example #8
0
def define_heatx_streams(m, h):
    """
    Declare all steams in the heat exchanger network
    via the SOFC model built before.
    Optional keyword arguments:
    ---------------------------
    :param m: SOFC model
    :param h: the heat exchanger network
    :return: heat exchanger network after declaring all steams
    """
    h.fs.Split2.inlet.flow_mol.fix(m.fs.Burner.outlet.flow_mol[0].value)
    h.fs.HX1a.tube_inlet.flow_mol.fix(m.fs.Mix1.outlet.flow_mol[0].value)
    h.fs.HX2a.tube_inlet.flow_mol.fix(m.fs.Split1.outlet_1.flow_mol[0].value)
    h.fs.HX2b.tube_inlet.flow_mol.fix(m.fs.Split1.outlet_2.flow_mol[0].value)

    material = ["CH4", "CO", "CO2", "H2", "H2O", "N2", "NH3", "O2"]
    for i in material:
        h.fs.Split2.inlet.mole_frac_comp[0, i].\
            fix(m.fs.Burner.outlet.mole_frac_comp[0, i].value)
        h.fs.HX1a.tube_inlet.mole_frac_comp[0, i].\
            fix(m.fs.Mix1.outlet.mole_frac_comp[0, i].value)
        h.fs.HX2a.tube_inlet.mole_frac_comp[0, i].\
            fix(m.fs.Split1.outlet_1.mole_frac_comp[0, i].value)
        h.fs.HX2b.tube_inlet.mole_frac_comp[0, i].\
            fix(m.fs.Split1.outlet_2.mole_frac_comp[0, i].value)

    h.fs.Split2.inlet.temperature.fix(m.fs.Burner.outlet.temperature[0].value)
    h.fs.Split2.inlet.pressure.fix(m.fs.Burner.outlet.pressure[0].value)

    h.fs.HX1a.tube_inlet.temperature.fix(m.fs.Mix1.outlet.temperature[0].value)
    h.fs.HX1a.tube_inlet.pressure.fix(m.fs.Mix1.outlet.pressure[0].value)

    h.fs.HX2a.tube_inlet.temperature.\
        fix(m.fs.Split1.outlet_1.temperature[0].value)
    h.fs.HX2a.tube_inlet.pressure.fix(m.fs.Split1.outlet_1.pressure[0].value)

    h.fs.HX2b.tube_inlet.temperature.\
        fix(m.fs.Split1.outlet_2.temperature[0].value)
    h.fs.HX2b.tube_inlet.pressure.fix(m.fs.Split1.outlet_2.pressure[0].value)

    # Declare all Streams
    h.fs.stream0 = Arc(source=h.fs.Split2.outlet_1,
                       destination=h.fs.HX1a.shell_inlet)
    h.fs.stream1 = Arc(source=h.fs.Split2.outlet_2,
                       destination=h.fs.HX2a.shell_inlet)
    h.fs.stream2 = Arc(source=h.fs.Split2.outlet_3,
                       destination=h.fs.HX2b.shell_inlet)
    h.fs.stream3 = Arc(source=h.fs.HX1a.shell_outlet,
                       destination=h.fs.HX1b.inlet)

    TransformationFactory("network.expand_arcs").apply_to(h)

    return h
Example #9
0
    def test_arc_lists(self):
        m = ConcreteModel()
        m.x = Var()
        m.p1 = Port()
        m.p2 = Port()
        m.p3 = Port()
        m.p4 = Port()
        m.p5 = Port()
        m.p1.add(m.x)
        m.p2.add(m.x)
        m.p3.add(m.x)
        m.p4.add(m.x)
        m.p5.add(m.x)
        m.a1 = Arc(source=m.p1, destination=m.p2)
        m.a2 = Arc(source=m.p1, destination=m.p3)
        m.a3 = Arc(source=m.p4, destination=m.p1)
        m.a4 = Arc(source=m.p5, destination=m.p1)

        self.assertEqual(len(m.p1.dests()), 2)
        self.assertEqual(len(m.p1.sources()), 2)
        self.assertEqual(len(m.p1.arcs()), 4)
        self.assertEqual(len(m.p2.dests()), 0)
        self.assertEqual(len(m.p2.sources()), 1)
        self.assertEqual(len(m.p2.arcs()), 1)
        self.assertIn(m.a1, m.p1.dests())
        self.assertIn(m.a1, m.p2.sources())
        self.assertNotIn(m.a1, m.p1.sources())
        self.assertNotIn(m.a1, m.p2.dests())

        self.assertEqual(len(m.p1.dests(active=True)), 2)
        self.assertEqual(len(m.p1.sources(active=True)), 2)
        self.assertEqual(len(m.p1.arcs(active=True)), 4)
        self.assertEqual(len(m.p2.dests(active=True)), 0)
        self.assertEqual(len(m.p2.sources(active=True)), 1)
        self.assertEqual(len(m.p2.arcs(active=True)), 1)
        self.assertIn(m.a1, m.p1.dests(active=True))
        self.assertIn(m.a1, m.p2.sources(active=True))
        self.assertNotIn(m.a1, m.p1.sources(active=True))
        self.assertNotIn(m.a1, m.p2.dests(active=True))

        m.a2.deactivate()

        self.assertNotIn(m.a2, m.p1.dests(active=True))
        self.assertNotIn(m.a2, m.p3.sources(active=True))
        self.assertIn(m.a2, m.p1.dests(active=False))
        self.assertIn(m.a2, m.p3.sources(active=False))
        self.assertIn(m.a2, m.p1.arcs(active=False))
        self.assertIn(m.a2, m.p3.arcs(active=False))
        self.assertIn(m.a2, m.p1.dests())
        self.assertIn(m.a2, m.p3.sources())
        self.assertIn(m.a2, m.p1.arcs())
        self.assertIn(m.a2, m.p3.arcs())
Example #10
0
def test_create_stream_table_dataframe_from_StateBlock_time():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False, "time_set": [3]})
    m.fs.thermo_params = thermo_props.SaponificationParameterBlock()
    m.fs.reaction_params = rxn_props.SaponificationReactionParameterBlock(
        default={"property_package": m.fs.thermo_params})

    m.fs.tank1 = CSTR(default={"property_package": m.fs.thermo_params,
                               "reaction_package": m.fs.reaction_params})
    m.fs.tank2 = CSTR(default={"property_package": m.fs.thermo_params,
                               "reaction_package": m.fs.reaction_params})

    m.fs.stream = Arc(source=m.fs.tank1.outlet,
                      destination=m.fs.tank2.inlet)
    TransformationFactory("network.expand_arcs").apply_to(m)

    df = create_stream_table_dataframe({
            "state": m.fs.tank1.control_volume.properties_out},
            time_point=3)

    assert df.loc["Pressure"]["state"] == 101325
    assert df.loc["Temperature"]["state"] == 298.15
    assert df.loc["Volumetric Flowrate"]["state"] == 1.0
    assert df.loc["Molar Concentration H2O"]["state"] == 100.0
    assert df.loc["Molar Concentration NaOH"]["state"] == 100.0
    assert df.loc["Molar Concentration EthylAcetate"]["state"] == 100.0
    assert df.loc["Molar Concentration SodiumAcetate"]["state"] == 100.0
    assert df.loc["Molar Concentration Ethanol"]["state"] == 100.0
Example #11
0
def build_components(m, has_bypass=True):
    # build flowsheet
    property_models.build_prop(m, base='ion')
    pretrt_port = pretreatment_NF.build_pretreatment_NF(m,
                                                        NF_type='ZO',
                                                        NF_base='ion',
                                                        has_bypass=has_bypass)

    property_models.build_prop(m, base='TDS')
    translator_block.build_tb(m,
                              base_inlet='ion',
                              base_outlet='TDS',
                              name_str='tb_pretrt_to_desal')

    # Arc to translator block
    m.fs.s_pretrt_tb = Arc(source=pretrt_port['out'],
                           destination=m.fs.tb_pretrt_to_desal.inlet)

    property_models.build_prop(m, base='eNRTL')
    gypsum_saturation_index.build(m, section='pretreatment')

    m.fs.NF.area.fix(175)
    if has_bypass:
        m.fs.splitter.split_fraction[0, 'bypass'].fix(0.50)

        m.fs.removal_Ca = Expression(
            expr=(
                m.fs.feed.properties[0].flow_mass_phase_comp['Liq', 'Ca'] -
                m.fs.mixer.mixed_state[0].flow_mass_phase_comp['Liq', 'Ca']) /
            m.fs.feed.properties[0].flow_mass_phase_comp['Liq', 'Ca'])
        m.fs.removal_Mg = Expression(
            expr=(
                m.fs.feed.properties[0].flow_mass_phase_comp['Liq', 'Mg'] -
                m.fs.mixer.mixed_state[0].flow_mass_phase_comp['Liq', 'Mg']) /
            m.fs.feed.properties[0].flow_mass_phase_comp['Liq', 'Mg'])
Example #12
0
def model():
    m = pyo.ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.prop_water = iapws95.Iapws95ParameterBlock()
    n_waterwalls = 10
    m.fs.ww_zones = pyo.RangeSet(n_waterwalls)
    m.fs.Waterwalls = WaterwallSection(
        m.fs.ww_zones,
        default={
            "dynamic": False,
            "has_holdup": False,
            "property_package": m.fs.prop_water,
            "has_heat_transfer": True,
            "has_pressure_change": True,
        },
    )

    def arc_rule(b, i):
        return {
            "source": m.fs.Waterwalls[i].outlet,
            "destination": m.fs.Waterwalls[i + 1].inlet
        }

    m.arc = Arc(pyo.RangeSet(n_waterwalls - 1), rule=arc_rule)

    # Pyomo expands arcs writing constraints outlet unit 1 = inlet unit 2
    pyo.TransformationFactory("network.expand_arcs").apply_to(m)

    return m
Example #13
0
def build_components(m, has_bypass=True):
    # build flowsheet
    property_models.build_prop(m, base="ion")
    pretrt_port = pretreatment_NF.build_pretreatment_NF(m,
                                                        NF_type="ZO",
                                                        NF_base="ion",
                                                        has_bypass=has_bypass)

    property_models.build_prop(m, base="TDS")
    translator_block.build_tb(m,
                              base_inlet="ion",
                              base_outlet="TDS",
                              name_str="tb_pretrt_to_desal")

    # Arc to translator block
    m.fs.s_pretrt_tb = Arc(source=pretrt_port["out"],
                           destination=m.fs.tb_pretrt_to_desal.inlet)

    property_models.build_prop(m, base="eNRTL")
    gypsum_saturation_index.build(m, section="pretreatment")

    m.fs.NF.area.fix(175)
    if has_bypass:
        m.fs.splitter.split_fraction[0, "bypass"].fix(0.50)

        m.fs.removal_Ca = Expression(
            expr=(
                m.fs.feed.properties[0].flow_mass_phase_comp["Liq", "Ca"] -
                m.fs.mixer.mixed_state[0].flow_mass_phase_comp["Liq", "Ca"]) /
            m.fs.feed.properties[0].flow_mass_phase_comp["Liq", "Ca"])
        m.fs.removal_Mg = Expression(
            expr=(
                m.fs.feed.properties[0].flow_mass_phase_comp["Liq", "Mg"] -
                m.fs.mixer.mixed_state[0].flow_mass_phase_comp["Liq", "Mg"]) /
            m.fs.feed.properties[0].flow_mass_phase_comp["Liq", "Mg"])
Example #14
0
    def _make_rectification_arcs(self):
        self._rectification_stream_index = RangeSet(
            1, self.config.feed_tray_location - 2)

        def rule_liq_stream(self, i):
            return {"source": self.rectification_section[i].liq_out,
                    "destination": self.rectification_section[i + 1].liq_in}

        def rule_vap_stream(self, i):
            return {"source": self.rectification_section[i + 1].vap_out,
                    "destination": self.rectification_section[i].vap_in}

        self.rectification_liq_stream = Arc(
            self._rectification_stream_index, rule=rule_liq_stream)
        self.rectification_vap_stream = Arc(
            self._rectification_stream_index, rule=rule_vap_stream)
Example #15
0
def test_flowsheet_report_with_arcs():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.thermo_params = thermo_props.SaponificationParameterBlock()
    m.fs.reaction_params = rxn_props.SaponificationReactionParameterBlock(
        default={"property_package": m.fs.thermo_params})

    m.fs.tank1 = CSTR(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params
        })
    m.fs.tank2 = CSTR(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params
        })

    m.fs.stream = Arc(source=m.fs.tank1.outlet, destination=m.fs.tank2.inlet)
    TransformationFactory("network.expand_arcs").apply_to(m)

    df = m.fs._get_stream_table_contents()

    assert df.loc["Pressure"]["stream"] == 101325
    assert df.loc["Temperature"]["stream"] == 298.15
    assert df.loc["Volumetric Flowrate"]["stream"] == 1.0
    assert df.loc["Molar Concentration H2O"]["stream"] == 100.0
    assert df.loc["Molar Concentration NaOH"]["stream"] == 100.0
    assert df.loc["Molar Concentration EthylAcetate"]["stream"] == 100.0
    assert df.loc["Molar Concentration SodiumAcetate"]["stream"] == 100.0
    assert df.loc["Molar Concentration Ethanol"]["stream"] == 100.0
Example #16
0
def demo_flowsheet():
    """Semi-complicated demonstration flowsheet.
    """
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.BT_props = BTXParameterBlock()
    m.fs.M01 = Mixer(default={"property_package": m.fs.BT_props})
    m.fs.H02 = Heater(default={"property_package": m.fs.BT_props})
    m.fs.F03 = Flash(default={"property_package": m.fs.BT_props})
    m.fs.s01 = Arc(source=m.fs.M01.outlet, destination=m.fs.H02.inlet)
    m.fs.s02 = Arc(source=m.fs.H02.outlet, destination=m.fs.F03.inlet)
    TransformationFactory("network.expand_arcs").apply_to(m.fs)

    m.fs.properties = SWCO2ParameterBlock()
    m.fs.main_compressor = PressureChanger(
      default={'dynamic': False,
               'property_package': m.fs.properties,
               'compressor': True,
               'thermodynamic_assumption': ThermodynamicAssumption.isentropic})

    m.fs.bypass_compressor = PressureChanger(
        default={'dynamic': False,
                 'property_package': m.fs.properties,
                 'compressor': True,
                 'thermodynamic_assumption': ThermodynamicAssumption.isentropic})

    m.fs.turbine = PressureChanger(
      default={'dynamic': False,
               'property_package': m.fs.properties,
               'compressor': False,
               'thermodynamic_assumption': ThermodynamicAssumption.isentropic})
    m.fs.boiler = Heater(default={'dynamic': False,
                                  'property_package': m.fs.properties,
                                  'has_pressure_change': True})
    m.fs.FG_cooler = Heater(default={'dynamic': False,
                                     'property_package': m.fs.properties,
                                     'has_pressure_change': True})
    m.fs.pre_boiler = Heater(default={'dynamic': False,
                                      'property_package': m.fs.properties,
                                      'has_pressure_change': False})
    m.fs.HTR_pseudo_tube = Heater(default={'dynamic': False,
                                       'property_package': m.fs.properties,
                                       'has_pressure_change': True})
    m.fs.LTR_pseudo_tube = Heater(default={'dynamic': False,
                                       'property_package': m.fs.properties,
                                       'has_pressure_change': True})
    return m.fs
Example #17
0
    def model(self):
        m = ConcreteModel()
        m.db = Database()

        m.fs = FlowsheetBlock(default={"dynamic": False})
        m.fs.params = WaterParameterBlock(default={"solute_list": ["cod"]})

        m.fs.unit = CofermentationZO(default={
            "property_package": m.fs.params,
            "database": m.db
        })
        m.fs.feed1 = FeedZO(default={
            "property_package": m.fs.params,
        })
        m.fs.feed2 = FeedZO(default={
            "property_package": m.fs.params,
        })

        m.fs.feed1.flow_vol[0].fix(
            value(
                pyunits.convert(32.1 * pyunits.L / pyunits.day,
                                to_units=pyunits.m**3 / pyunits.s)))
        m.fs.feed1.conc_mass_comp[0, "cod"].fix(
            value(
                pyunits.convert(
                    69781.93146 * pyunits.mg / pyunits.L,
                    to_units=pyunits.kg / pyunits.m**3,
                )))

        m.fs.feed2.flow_vol[0].fix(
            value(
                pyunits.convert(3.21 * pyunits.L / pyunits.day,
                                to_units=pyunits.m**3 / pyunits.s)))
        m.fs.feed2.conc_mass_comp[0, "cod"].fix(
            value(
                pyunits.convert(1e4 * pyunits.mg / pyunits.L,
                                to_units=pyunits.kg / pyunits.m**3)))

        m.fs.feed1_to_coferm = Arc(source=m.fs.feed1.outlet,
                                   destination=m.fs.unit.inlet1)
        m.fs.feed2_to_coferm = Arc(source=m.fs.feed2.outlet,
                                   destination=m.fs.unit.inlet2)

        TransformationFactory("network.expand_arcs").apply_to(m)

        return m
Example #18
0
def create_model(m):
    """Create unit models"""

    m.fs.ww_zones = pyo.RangeSet(10)

    m.fs.drum = Drum(
        default={
            "property_package": m.fs.prop_water,
            "has_holdup": False,
            "has_heat_transfer": True,
            "has_pressure_change": True,
        })
    m.fs.downcomer = Downcomer(
        default={
            "property_package": m.fs.prop_water,
            "has_holdup": False,
            "has_heat_transfer": True,
        })
    m.fs.Waterwalls = WaterwallSection(
        m.fs.ww_zones,
        default={
            "dynamic": False,
            "has_holdup": False,
            "property_package": m.fs.prop_water,
            "has_heat_transfer": True,
            "has_pressure_change": True,
        },
    )

    m.fs.stream_drum_out = Arc(source=m.fs.drum.liquid_outlet,
                               destination=m.fs.downcomer.inlet)
    m.fs.stream_dcmr_out = Arc(source=m.fs.downcomer.outlet,
                               destination=m.fs.Waterwalls[1].inlet)

    def arc_rule(b, i):
        return {
            "source": m.fs.Waterwalls[i].outlet,
            "destination": m.fs.Waterwalls[i + 1].inlet
        }

    m.arc = Arc(pyo.RangeSet(9), rule=arc_rule)

    m.fs.stream_ww14 = Arc(source=m.fs.Waterwalls[10].outlet,
                           destination=m.fs.drum.water_steam_inlet)
    # pyomo arcs expand constraints for inlet = outlet ports
    pyo.TransformationFactory("network.expand_arcs").apply_to(m)
Example #19
0
def test_propagate_state_indexed_fixed():
    m = ConcreteModel()

    def block_rule(b):
        b.s = Set(initialize=[1, 2])
        b.v1 = Var()
        b.v2 = Var(b.s)

        b.p = Port(b.s)
        b.p[1].add(b.v1, "V1")
        b.p[2].add(b.v2, "V2")
        return

    m.b1 = Block(rule=block_rule)
    m.b2 = Block(rule=block_rule)

    def arc_rule(m, i):
        return {'source': m.b1.p[i], 'destination': m.b2.p[i]}

    m.s1 = Arc([1, 2], rule=arc_rule)

    # Set values on first block
    m.b1.v1.value = 10
    m.b1.v2[1].value = 20
    m.b1.v2[2].value = 30

    # Make sure vars in block 2 haven't been changed accidentally
    assert m.b2.v1.value is None
    assert m.b2.v2[1].value is None
    assert m.b2.v2[2].value is None

    # Fix v1 in block 2
    m.b2.v1.fix(500)

    propagate_state(m.s1[1])

    # Check that values were propagated correctly
    assert m.b2.v1.value == 500
    assert m.b1.v1.fixed is False
    assert m.b2.v1.fixed is True

    propagate_state(m.s1[1], overwrite_fixed=True)

    # Check that values were propagated correctly
    assert m.b2.v1.value == 10
    assert m.b1.v1.fixed is False
    assert m.b2.v1.fixed is True

    propagate_state(m.s1[2])

    # Check that values were propagated correctly
    assert m.b2.v2[1].value == m.b1.v2[1].value
    assert m.b2.v2[2].value == m.b1.v2[2].value
    assert m.b1.v2[1].fixed is False
    assert m.b1.v2[2].fixed is False
    assert m.b2.v2[1].fixed is False
    assert m.b2.v2[2].fixed is False
Example #20
0
    def _make_stripping_arcs(self):

        self._stripping_stream_index = RangeSet(
            self.config.feed_tray_location + 1,
            self.config.number_of_trays - 1)

        def rule_liq_stream(self, i):
            return {"source": self.stripping_section[i].liq_out,
                    "destination": self.stripping_section[i + 1].liq_in}

        def rule_vap_stream(self, i):
            return {"source": self.stripping_section[i + 1].vap_out,
                    "destination": self.stripping_section[i].vap_in}

        self.stripping_liq_stream = Arc(
            self._stripping_stream_index, rule=rule_liq_stream)
        self.stripping_vap_stream = Arc(
            self._stripping_stream_index, rule=rule_vap_stream)
def build_components(m, pretrt_type="NF", **kwargs):
    kwargs_desalination = {
        k: kwargs[k]
        for k in (
            "has_desal_feed",
            "is_twostage",
            "has_ERD",
            "RO_type",
            "RO_base",
            "RO_level",
        )
    }

    desal_port = desalination.build_desalination(m, **kwargs_desalination)
    m.fs.s_tb_desal = Arc(source=m.fs.tb_pretrt_to_desal.outlet,
                          destination=desal_port["in"])

    if pretrt_type == "softening":
        property_models.build_prop(m, base="eNRTL")
    gypsum_saturation_index.build(m,
                                  section="desalination",
                                  pretrt_type=pretrt_type,
                                  **kwargs)

    m.fs.RO.area.fix(80)
    m.fs.pump_RO.control_volume.properties_out[0].pressure.fix(60e5)

    if kwargs["is_twostage"]:
        m.fs.RO2.area.fix(20)
        m.fs.pump_RO2.control_volume.properties_out[0].pressure.fix(90e5)

    # touch some properties used in optimization
    if kwargs["is_twostage"]:
        product_water_sb = m.fs.mixer_permeate.mixed_state[0]
    else:
        product_water_sb = m.fs.RO.mixed_permeate[0]

    feed_flow_vol = 0.0009769808  # value of feed flowrate using the seawater property package with 1 kg/s mass flowrate
    m.fs.system_recovery = Expression(expr=product_water_sb.flow_vol /
                                      feed_flow_vol)

    # RO recovery
    m.fs.RO_recovery = Var(
        initialize=0.5,
        bounds=(0.01, 0.99),
        doc="Total volumetric water recovery for RO",
    )
    m.fs.eq_RO_recovery = Constraint(
        expr=m.fs.RO_recovery == product_water_sb.flow_vol /
        m.fs.tb_pretrt_to_desal.properties_out[0].flow_vol)

    # annual water production
    m.fs.treated_flow_vol = Expression(expr=product_water_sb.flow_vol)
    costing.build_costing(m, **kwargs)

    return desal_port
def build_flowsheet():
    m = ConcreteModel()

    m.fs = FlowsheetBlock(default={"dynamic": False})

    m.fs.BT_props = BTXParameterBlock()

    m.fs.M01 = Mixer(default={"property_package": m.fs.BT_props})

    m.fs.H02 = Heater(default={"property_package": m.fs.BT_props})

    m.fs.F03 = Flash(default={"property_package": m.fs.BT_props})

    m.fs.s01 = Arc(source=m.fs.M01.outlet, destination=m.fs.H02.inlet)
    m.fs.s02 = Arc(source=m.fs.H02.outlet, destination=m.fs.F03.inlet)

    TransformationFactory("network.expand_arcs").apply_to(m.fs)

    return m
Example #23
0
def build():
    # flowsheet set up
    m = ConcreteModel()
    m.db = Database()

    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.prop = prop_ZO.WaterParameterBlock(
        default={"solute_list": ["cod", "hydrogen", "methane"]})

    # unit models
    m.fs.feed = FeedZO(default={"property_package": m.fs.prop})
    m.fs.metab_hydrogen = MetabZO(default={
        "property_package": m.fs.prop,
        "database": m.db,
        "process_subtype": "hydrogen",
    }, )
    m.fs.metab_methane = MetabZO(default={
        "property_package": m.fs.prop,
        "database": m.db,
        "process_subtype": "methane",
    }, )
    m.fs.product_hydrogen = Product(default={"property_package": m.fs.prop})
    m.fs.product_methane = Product(default={"property_package": m.fs.prop})
    m.fs.product_H2O = Product(default={"property_package": m.fs.prop})

    # connections
    m.fs.s01 = Arc(source=m.fs.feed.outlet,
                   destination=m.fs.metab_hydrogen.inlet)
    m.fs.s02 = Arc(source=m.fs.metab_hydrogen.treated,
                   destination=m.fs.metab_methane.inlet)
    m.fs.s03 = Arc(source=m.fs.metab_hydrogen.byproduct,
                   destination=m.fs.product_hydrogen.inlet)
    m.fs.s04 = Arc(source=m.fs.metab_methane.byproduct,
                   destination=m.fs.product_methane.inlet)
    m.fs.s05 = Arc(source=m.fs.metab_methane.treated,
                   destination=m.fs.product_H2O.inlet)
    TransformationFactory("network.expand_arcs").apply_to(m)

    # scaling
    iscale.calculate_scaling_factors(m)

    return m
Example #24
0
def build():
    # flowsheet set up
    m = ConcreteModel()
    m.db = Database()

    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.prop = prop_ZO.WaterParameterBlock(
        default={
            "solute_list":
            ["bod", "tss", "ammonium_as_nitrogen", "nitrate", "nitrogen"]
        })

    # unit models
    m.fs.feed = FeedZO(default={"property_package": m.fs.prop})
    m.fs.mabr = MABRZO(default={
        "property_package": m.fs.prop,
        "database": m.db,
    }, )
    m.fs.dmbr = DMBRZO(default={
        "property_package": m.fs.prop,
        "database": m.db,
    }, )
    m.fs.pump = PumpElectricityZO(default={
        "property_package": m.fs.prop,
        "database": m.db,
    }, )

    m.fs.product_H2O = Product(default={"property_package": m.fs.prop})

    # connections
    m.fs.s01 = Arc(source=m.fs.feed.outlet, destination=m.fs.pump.inlet)
    m.fs.s02 = Arc(source=m.fs.pump.outlet, destination=m.fs.mabr.inlet)
    m.fs.s03 = Arc(source=m.fs.mabr.treated, destination=m.fs.dmbr.inlet)
    m.fs.s04 = Arc(source=m.fs.dmbr.treated,
                   destination=m.fs.product_H2O.inlet)
    TransformationFactory("network.expand_arcs").apply_to(m)

    # scaling
    iscale.calculate_scaling_factors(m)

    return m
Example #25
0
    def _make_arcs(self):
        # make arcs
        self.liq_stream_index = RangeSet(0, self.config.number_of_trays)
        self.vap_stream_index = RangeSet(1, self.config.number_of_trays + 1)

        def rule_liq_stream(self, i):
            if i == 0:
                return {
                    "source": self.condenser.reflux,
                    "destination": self.tray[i + 1].liq_in
                }
            elif i == self.config.number_of_trays:
                return {
                    "source": self.tray[i].liq_out,
                    "destination": self.reboiler.inlet
                }
            else:
                return {
                    "source": self.tray[i].liq_out,
                    "destination": self.tray[i + 1].liq_in
                }

        def rule_vap_stream(self, i):
            if i == 1:
                return {
                    "source": self.tray[i].vap_out,
                    "destination": self.condenser.inlet
                }
            elif i == self.config.number_of_trays + 1:
                return {
                    "source": self.reboiler.vapor_reboil,
                    "destination": self.tray[i - 1].vap_in
                }
            else:
                return {
                    "source": self.tray[i].vap_out,
                    "destination": self.tray[i - 1].vap_in
                }

        self.liq_stream = Arc(self.liq_stream_index, rule=rule_liq_stream)
        self.vap_stream = Arc(self.vap_stream_index, rule=rule_vap_stream)
Example #26
0
def build(m):
    # Properties
    m.fs.properties_feed = props_sw.SeawaterParameterBlock()
    m.fs.properties_vapor = props_w.WaterParameterBlock()

    # Evaporator
    m.fs.evaporator = Evaporator(
        default={
            "property_package_feed": m.fs.properties_feed,
            "property_package_vapor": m.fs.properties_vapor,
        })
    # Compressor
    m.fs.compressor = Compressor(
        default={"property_package": m.fs.properties_vapor})

    # Connections
    m.fs.s01 = Arc(source=m.fs.evaporator.outlet_vapor,
                   destination=m.fs.compressor.inlet)
    m.fs.s02 = Arc(source=m.fs.compressor.outlet,
                   destination=m.fs.evaporator.inlet_condenser)
    TransformationFactory("network.expand_arcs").apply_to(m)
    def build(self):
        super().build()
        config = self.config  # sorter ref to config for less line splitting

        # All feedwater heaters have a condensing section
        _set_prop_pack(config.condense, config)
        self.condense = FWHCondensing0D(default=config.condense)

        # Add a mixer to add the drain stream from another feedwater heater
        if config.has_drain_mixer:
            mix_cfg = {
                "dynamic": False,
                "inlet_list": ["steam", "drain"],
                "property_package": config.property_package,
                "momentum_mixing_type": MomentumMixingType.none,
            }
            self.drain_mix = Mixer(default=mix_cfg)

            @self.drain_mix.Constraint(self.drain_mix.flowsheet().config.time)
            def mixer_pressure_constraint(b, t):
                """
                Constraint to set the drain mixer pressure to the pressure of
                the steam extracted from the turbine. The drain inlet should
                always be a higher pressure than the steam inlet.
                """
                return b.steam_state[t].pressure == b.mixed_state[t].pressure

            # Connect the mixer to the condensing section inlet
            self.SMX = Arc(source=self.drain_mix.outlet,
                           destination=self.condense.inlet_1)

        # Add a desuperheat section before the condensing section
        if config.has_desuperheat:
            _set_prop_pack(config.desuperheat, config)
            self.desuperheat = HeatExchanger(default=config.desuperheat)
            # set default area less than condensing section area, this will
            # almost always be overridden by the user fixing an area later
            self.desuperheat.area.value = 10
            if config.has_drain_mixer:
                self.SDS = Arc(source=self.desuperheat.outlet_1,
                               destination=self.drain_mix.steam)
            else:
                self.SDS = Arc(source=self.desuperheat.outlet_1,
                               destination=self.condense.inlet_1)
            self.FW2 = Arc(source=self.condense.outlet_2,
                           destination=self.desuperheat.inlet_2)

        # Add a drain cooling section after the condensing section
        if config.has_drain_cooling:
            _set_prop_pack(config.cooling, config)
            self.cooling = HeatExchanger(default=config.cooling)
            # set default area less than condensing section area, this will
            # almost always be overridden by the user fixing an area later
            self.cooling.area.value = 10
            self.FW1 = Arc(source=self.cooling.outlet_2,
                           destination=self.condense.inlet_2)
            self.SC = Arc(source=self.condense.outlet_1,
                          destination=self.cooling.inlet_1)

        TransformationFactory("network.expand_arcs").apply_to(self)
Example #28
0
    def build(self):

        # Call UnitModel.build to setup dynamics
        super(HydrogenTurbineData, self).build()

        self.compressor = Compressor(
            default={"property_package": self.config.property_package})

        self.stoic_reactor = StoichiometricReactor(
            default={"property_package": self.config.property_package,
                     "reaction_package": self.config.reaction_package,
                     "has_heat_of_reaction": True,
                     "has_heat_transfer": False,
                     "has_pressure_change": False})

        self.turbine = Turbine(
            default={"property_package": self.config.property_package})

        # Declare var for reactor conversion
        self.stoic_reactor.conversion = Var(initialize=0.75, bounds=(0, 1))

        stoic_reactor_in = self.stoic_reactor.control_volume.properties_in[0.0]
        stoic_reactor_out = self.stoic_reactor.control_volume.properties_out[0.0]

        self.stoic_reactor.conv_constraint = Constraint(
            expr=self.stoic_reactor.conversion *
            stoic_reactor_in.flow_mol_comp["hydrogen"] ==
            (stoic_reactor_in.flow_mol_comp["hydrogen"] -
             stoic_reactor_out.flow_mol_comp["hydrogen"]))

        # Connect arcs
        self.comp_to_reactor = Arc(
            source=self.compressor.outlet,
            destination=self.stoic_reactor.inlet)
        self.reactor_to_turbine = Arc(
            source=self.stoic_reactor.outlet,
            destination=self.turbine.inlet)

        TransformationFactory("network.expand_arcs").apply_to(self)
def test_scale_arcs():
    m = pyo.ConcreteModel()
    m.x = pyo.Var([1, 2, 3, 4])
    m.y = pyo.Var([1, 2, 3, 4])

    m.p1 = Port()
    m.p1.add(m.x[1], name="x")
    m.p1.add(m.y[1], name="y")

    m.p = Port([2, 3, 4])
    m.p[2].add(m.x[2], name="x")
    m.p[2].add(m.y[2], name="y")
    m.p[3].add(m.x[3], name="x")
    m.p[3].add(m.y[3], name="y")
    m.p[4].add(m.x[4], name="x")
    m.p[4].add(m.y[4], name="y")

    def arc_rule(b, i):
        if i == 1:
            return (m.p1, m.p[2])
        elif i == 2:
            return (m.p[3], m.p[4])

    m.arcs = Arc([1, 2], rule=arc_rule)

    sc.set_scaling_factor(m.x, 10)
    sc.set_scaling_factor(m.y, 20)
    sc.set_scaling_factor(m.x[1], 5)

    # make sure there is no error if the scaling is done with unexpanded arcs
    sc.scale_arc_constraints(m)

    # expand and make sure it works
    pyo.TransformationFactory('network.expand_arcs').apply_to(m)
    sc.scale_arc_constraints(m)
    m.x[1] = 1
    m.x[2] = 2
    m.x[3] = 3
    m.x[4] = 4
    m.y[1] = 11
    m.y[2] = 12
    m.y[3] = 13
    m.y[4] = 14

    # for all the arc constraints the differnce is 1 the scale factor is the
    # smallest scale factor for variables in a constraint.  Make sure the
    # constraints are scaled as expected.
    assert abs(m.arcs_expanded[1].x_equality.body()) == 5
    assert abs(m.arcs_expanded[2].x_equality.body()) == 10
    assert abs(m.arcs_expanded[1].y_equality.body()) == 20
    assert abs(m.arcs_expanded[2].y_equality.body()) == 20
Example #30
0
 def test_gams_arc_in_active_constraint(self):
     m = ConcreteModel()
     m.b1 = Block()
     m.b2 = Block()
     m.b1.x = Var()
     m.b2.x = Var()
     m.b1.c = Port()
     m.b1.c.add(m.b1.x)
     m.b2.c = Port()
     m.b2.c.add(m.b2.x)
     m.c = Arc(source=m.b1.c, destination=m.b2.c)
     m.o = Objective(expr=m.b1.x)
     outs = StringIO()
     with self.assertRaises(RuntimeError):
         m.write(outs, format="gams")