Example #1
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 #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
Example #3
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 #4
0
def main():
    """
    Make the flowsheet object, fix some variables, and solve the problem
    """
    # Create a Concrete Model as the top level object
    m = ConcreteModel()

    # Add a flowsheet object to the model
    m.fs = FlowsheetBlock(default={"dynamic": False})

    # Add property packages to flowsheet library
    m.fs.thermo_params = thermo_props.SaponificationParameterBlock()
    m.fs.reaction_params = reaction_props.SaponificationReactionParameterBlock(
        default={"property_package": m.fs.thermo_params})

    # Create unit models
    m.fs.Tank1 = CSTR(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params,
            "has_equilibrium_reactions": False,
            "has_heat_of_reaction": True,
            "has_heat_transfer": True,
            "has_pressure_change": False
        })
    m.fs.Tank2 = CSTR(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params,
            "has_equilibrium_reactions": False,
            "has_heat_of_reaction": True,
            "has_heat_transfer": True,
            "has_pressure_change": False
        })

    # Make Streams to connect units
    m.fs.stream = Arc(source=m.fs.Tank1.outlet, destination=m.fs.Tank2.inlet)

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

    # Set inlet and operating conditions, and some initial conditions.
    m.fs.Tank1.inlet.flow_vol[0].fix(1.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "H2O"].fix(55388.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "NaOH"].fix(100.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "EthylAcetate"].fix(100.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "SodiumAcetate"].fix(0.0)
    m.fs.Tank1.inlet.conc_mol_comp[0, "Ethanol"].fix(0.0)

    m.fs.Tank1.inlet.temperature[0].fix(303.15)
    m.fs.Tank1.inlet.pressure[0].fix(101325.0)

    m.fs.Tank1.volume.fix(1.0)
    m.fs.Tank1.heat_duty.fix(0.0)

    m.fs.Tank2.volume.fix(1.0)
    m.fs.Tank2.heat_duty.fix(0.0)

    # Initialize Units
    m.fs.Tank1.initialize()
    m.fs.Tank2.initialize(
        state_args={
            "flow_vol": 1.0,
            "conc_mol_comp": {
                "H2O": 55388.0,
                "NaOH": 100.0,
                "EthylAcetate": 100.0,
                "SodiumAcetate": 0.0,
                "Ethanol": 0.0
            },
            "temperature": 303.15,
            "pressure": 101325.0
        })

    # =========================================================================
    # Adding Optimization
    m.fs.obj = Objective(expr=m.fs.Tank2.outlet.conc_mol_comp[0,
                                                              "SodiumAcetate"],
                         sense=maximize)

    # Add additional constraint
    m.fs.volume_constraint = Constraint(expr=m.fs.Tank1.volume[0] +
                                        m.fs.Tank2.volume[0] == 3.0)

    # Set bounds for variables
    m.fs.Tank1.volume[0].setlb(0.5)
    m.fs.Tank1.volume[0].setub(5.0)
    m.fs.Tank2.volume[0].setlb(0.5)
    m.fs.Tank2.volume[0].setub(5.0)

    # Unfix heat inputs
    m.fs.Tank1.volume.unfix()
    m.fs.Tank2.volume.unfix()
    # =========================================================================

    # Create a solver
    solver = SolverFactory('ipopt')
    results = solver.solve(m, tee=True)

    # Print results
    print(results)
    print()
    print("Results")
    print()
    print("Tank 1 Volume")
    m.fs.Tank1.volume.display()
    print()
    print("Tank 2 Volume")
    m.fs.Tank2.volume.display()
    print()
    print("Tank 1 Outlet")
    m.fs.Tank1.outlet.display()
    print()
    print("Tank 2 Outlet")
    m.fs.Tank2.outlet.display()

    # For testing purposes
    return (m, results)
def main():
    """
    Make the flowsheet object, fix some variables, and solve the problem
    """
    # Create a Concrete Model as the top level object
    m = ConcreteModel()

    # Add a flowsheet object to the model
    # time_set has points at 0 and 20 as the start and end of the domain,
    # and a point at t=1 to allow for a step-change at this time
    m.fs = FlowsheetBlock(default={"dynamic": True, "time_set": [0, 1, 20]})

    # Add property packages to flowsheet library
    m.fs.thermo_params = thermo_props.SaponificationParameterBlock()
    m.fs.reaction_params = reaction_props.SaponificationReactionParameterBlock(
        default={"property_package": m.fs.thermo_params})

    # Create unit models
    m.fs.mix = Mixer(default={
        "dynamic": False,
        "property_package": m.fs.thermo_params
    })
    m.fs.Tank1 = CSTR(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params,
            "has_holdup": True,
            "has_equilibrium_reactions": False,
            "has_heat_of_reaction": True,
            "has_heat_transfer": True,
            "has_pressure_change": False
        })
    m.fs.Tank2 = CSTR(
        default={
            "property_package": m.fs.thermo_params,
            "reaction_package": m.fs.reaction_params,
            "has_holdup": True,
            "has_equilibrium_reactions": False,
            "has_heat_of_reaction": True,
            "has_heat_transfer": True,
            "has_pressure_change": False
        })

    # Add pressure-flow constraints to Tank 1
    m.fs.Tank1.height = Var(m.fs.time,
                            initialize=1.0,
                            doc="Depth of fluid in tank [m]")
    m.fs.Tank1.area = Var(initialize=1.0,
                          doc="Cross-sectional area of tank [m^2]")
    m.fs.Tank1.flow_coeff = Var(m.fs.time,
                                initialize=5e-5,
                                doc="Tank outlet flow coefficient")

    def geometry(b, t):
        return b.volume[t] == b.area * b.height[t]

    m.fs.Tank1.geometry = Constraint(m.fs.time, rule=geometry)

    def outlet_flowrate(b, t):
        return b.control_volume.properties_out[t].flow_vol == \
                    b.flow_coeff[t]*b.height[t]**0.5

    m.fs.Tank1.outlet_flowrate = Constraint(m.fs.time, rule=outlet_flowrate)

    # Add pressure-flow constraints to tank 2
    m.fs.Tank2.height = Var(m.fs.time,
                            initialize=1.0,
                            doc="Depth of fluid in tank [m]")
    m.fs.Tank2.area = Var(initialize=1.0,
                          doc="Cross-sectional area of tank [m^2]")
    m.fs.Tank2.flow_coeff = Var(m.fs.time,
                                initialize=5e-5,
                                doc="Tank outlet flow coefficient")

    m.fs.Tank2.geometry = Constraint(m.fs.time, rule=geometry)
    m.fs.Tank2.outlet_flowrate = Constraint(m.fs.time, rule=outlet_flowrate)

    # Make Streams to connect units
    m.fs.stream1 = Arc(source=m.fs.mix.outlet, destination=m.fs.Tank1.inlet)

    m.fs.stream2 = Arc(source=m.fs.Tank1.outlet, destination=m.fs.Tank2.inlet)

    # Discretize time domain
    m.discretizer = TransformationFactory('dae.finite_difference')
    m.discretizer.apply_to(m, nfe=50, wrt=m.fs.time, scheme="BACKWARD")

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

    # Set inlet and operating conditions, and some initial conditions.
    m.fs.mix.inlet_1.flow_vol.fix(0.5)
    m.fs.mix.inlet_1.conc_mol_comp[:, "H2O"].fix(55388.0)
    m.fs.mix.inlet_1.conc_mol_comp[:, "NaOH"].fix(100.0)
    m.fs.mix.inlet_1.conc_mol_comp[:, "EthylAcetate"].fix(0.0)
    m.fs.mix.inlet_1.conc_mol_comp[:, "SodiumAcetate"].fix(0.0)
    m.fs.mix.inlet_1.conc_mol_comp[:, "Ethanol"].fix(0.0)
    m.fs.mix.inlet_1.temperature.fix(303.15)
    m.fs.mix.inlet_1.pressure.fix(101325.0)

    m.fs.mix.inlet_2.flow_vol.fix(0.5)
    m.fs.mix.inlet_2.conc_mol_comp[:, "H2O"].fix(55388.0)
    m.fs.mix.inlet_2.conc_mol_comp[:, "NaOH"].fix(0.0)
    m.fs.mix.inlet_2.conc_mol_comp[:, "EthylAcetate"].fix(100.0)
    m.fs.mix.inlet_2.conc_mol_comp[:, "SodiumAcetate"].fix(0.0)
    m.fs.mix.inlet_2.conc_mol_comp[:, "Ethanol"].fix(0.0)
    m.fs.mix.inlet_2.temperature.fix(303.15)
    m.fs.mix.inlet_2.pressure.fix(101325.0)

    m.fs.Tank1.area.fix(1.0)
    m.fs.Tank1.flow_coeff.fix(0.5)
    m.fs.Tank1.heat_duty.fix(0.0)

    m.fs.Tank2.area.fix(1.0)
    m.fs.Tank2.flow_coeff.fix(0.5)
    m.fs.Tank2.heat_duty.fix(0.0)

    # Set initial conditions - accumulation = 0 at time = 0
    m.fs.fix_initial_conditions(state="steady-state")

    # Initialize Units
    m.fs.mix.initialize()

    m.fs.Tank1.initialize(
        state_args={
            "flow_vol": 1.0,
            "conc_mol_comp": {
                "H2O": 55388.0,
                "NaOH": 100.0,
                "EthylAcetate": 100.0,
                "SodiumAcetate": 0.0,
                "Ethanol": 0.0
            },
            "temperature": 303.15,
            "pressure": 101325.0
        })

    m.fs.Tank2.initialize(
        state_args={
            "flow_vol": 1.0,
            "conc_mol_comp": {
                "H2O": 55388.0,
                "NaOH": 100.0,
                "EthylAcetate": 100.0,
                "SodiumAcetate": 0.0,
                "Ethanol": 0.0
            },
            "temperature": 303.15,
            "pressure": 101325.0
        })

    # Create a solver
    solver = SolverFactory('ipopt')
    results = solver.solve(m.fs)

    # Make a step disturbance in feed and solve again
    for t in m.fs.time:
        if t >= 1.0:
            m.fs.mix.inlet_2.conc_mol_comp[t, "EthylAcetate"].fix(90.0)
    results = solver.solve(m.fs)

    # Print results
    print(results)

    # For testing purposes
    return (m, results)