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
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
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.stream = Arc(source=m.fs.tank1.outlet, destination=m.fs.tank2.inlet) TransformationFactory("network.expand_arcs").apply_to(m) return m
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.fix(303.15) m.fs.Tank1.inlet.pressure.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 }) # Create a solver solver = SolverFactory('ipopt') results = solver.solve(m, tee=False) # Print results print(results) print() print("Results") 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)