def test02b(self): """Test with suffixes""" model = self.setup_model02b() x = model.x model.dual[model.g] = 1 model.ipopt_zL_out[x["1"]] = 0 model.ipopt_zL_out[x["2"]] = 0 model.ipopt_zU_out[x["1"]] = 0 model.ipopt_zU_out[x["2"]] = 0 to_json(model, fname=self.fname, human_read=True) model.x["1"].value = 10 model.x["2"].value = 10 model.dual[model.g] = 10 model.ipopt_zL_out[x["1"]] = 10 model.ipopt_zL_out[x["2"]] = 10 model.ipopt_zU_out[x["1"]] = 10 model.ipopt_zU_out[x["2"]] = 10 model.p["a"] = 10 model.p["b"] = 10 from_json(model, fname=self.fname) assert value(model.x["1"]) == pytest.approx(1.5) assert value(model.x["2"]) == pytest.approx(2.5) assert value(model.p["a"]) == pytest.approx(1) assert value(model.p["b"]) == pytest.approx(2) assert model.dual[model.g] == pytest.approx(1) assert model.ipopt_zL_out[x["1"]] == pytest.approx(0) assert model.ipopt_zL_out[x["2"]] == pytest.approx(0) assert model.ipopt_zU_out[x["1"]] == pytest.approx(0) assert model.ipopt_zU_out[x["2"]] == pytest.approx(0)
def test08(self): """Try just saving suffixes""" model = self.setup_model02() model.x[1].fix(1) model.dual[model.g] = 1 model.ipopt_zL_out[model.x[1]] = 1 model.ipopt_zL_out[model.x[2]] = 1 model.ipopt_zU_out[model.x[1]] = 1 model.ipopt_zU_out[model.x[2]] = 1 to_json(model, fname=self.fname, wts=StoreSpec.suffix()) model.dual[model.g] = 10 model.ipopt_zL_out[model.x[1]] = 10 model.ipopt_zL_out[model.x[2]] = 10 model.ipopt_zU_out[model.x[1]] = 10 model.ipopt_zU_out[model.x[2]] = 10 model.g.deactivate() model.x[1].setlb(-4) model.x[1].unfix() model.x[2].fix(6) from_json(model, fname=self.fname, wts=StoreSpec.suffix()) assert value(model.x[1]) == 1 assert value(model.x[2]) == 6 assert not model.x[1].fixed assert model.x[2].fixed assert not model.g.active assert model.dual[model.g] == 1 assert model.ipopt_zL_out[model.x[1]] == 1 assert model.ipopt_zL_out[model.x[2]] == 1 assert model.ipopt_zU_out[model.x[1]] == 1 assert model.ipopt_zU_out[model.x[2]] == 1 assert model.x[1].lb == -4
def test10(self): """Try just saving suffixes, and suffix filter only on write""" model = self.setup_model02() model.dual[model.g] = 1 model.ipopt_zL_out[model.x[1]] = 1 model.ipopt_zL_out[model.x[2]] = 1 model.ipopt_zU_out[model.x[1]] = 1 model.ipopt_zU_out[model.x[2]] = 1 wts = StoreSpec.suffix(suffix_filter=("dual", )) to_json(model, fname=self.fname, wts=wts) model.dual[model.g] = 10 model.ipopt_zL_out[model.x[1]] = 10 model.ipopt_zL_out[model.x[2]] = 10 model.ipopt_zU_out[model.x[1]] = 10 model.ipopt_zU_out[model.x[2]] = 10 from_json(model, fname=self.fname, wts=StoreSpec.suffix()) assert model.dual[model.g] == 1 assert model.ipopt_zL_out[model.x[1]] == 10 assert model.ipopt_zL_out[model.x[2]] == 10 assert model.ipopt_zU_out[model.x[1]] == 10 assert model.ipopt_zU_out[model.x[2]] == 10
def test08(self): """Try just saving suffixes""" model = self.setup_model02() model.x[1].fix(1) model.dual[model.g] = 1 model.ipopt_zL_out[model.x[1]] = 1 model.ipopt_zL_out[model.x[2]] = 1 model.ipopt_zU_out[model.x[1]] = 1 model.ipopt_zU_out[model.x[2]] = 1 to_json(model, fname=self.fname, wts=StoreSpec.suffix()) model.dual[model.g] = 10 model.ipopt_zL_out[model.x[1]] = 10 model.ipopt_zL_out[model.x[2]] = 10 model.ipopt_zU_out[model.x[1]] = 10 model.ipopt_zU_out[model.x[2]] = 10 model.g.deactivate() model.x[1].setlb(-4) model.x[1].unfix() model.x[2].fix(6) from_json(model, fname=self.fname, wts=StoreSpec.suffix()) assert (abs(value(model.x[1]) - 1) < 1e-5) assert (abs(value(model.x[2]) - 6) < 1e-5) assert (not model.x[1].fixed) assert (model.x[2].fixed) assert (not model.g.active) assert (abs(model.dual[model.g] - 1) < 1e-5) assert (abs(model.ipopt_zL_out[model.x[1]] - 1) < 1e-5) assert (abs(model.ipopt_zL_out[model.x[2]] - 1) < 1e-5) assert (abs(model.ipopt_zU_out[model.x[1]] - 1) < 1e-5) assert (abs(model.ipopt_zU_out[model.x[2]] - 1) < 1e-5) assert (abs(model.x[1].lb + 4) < 1e-5)
def test11(self): """Try just saving suffixes, and suffix filter only on read""" model = self.setup_model02() model.dual[model.g] = 1 model.ipopt_zL_out[model.x[1]] = 1 model.ipopt_zL_out[model.x[2]] = 1 model.ipopt_zU_out[model.x[1]] = 1 model.ipopt_zU_out[model.x[2]] = 1 to_json(model, fname=self.fname, wts=StoreSpec.suffix()) model.dual[model.g] = 10 model.ipopt_zL_out[model.x[1]] = 10 model.ipopt_zL_out[model.x[2]] = 10 model.ipopt_zU_out[model.x[1]] = 10 model.ipopt_zU_out[model.x[2]] = 10 wts = StoreSpec.suffix(suffix_filter=("dual", )) from_json(model, fname=self.fname, wts=wts) assert (abs(model.dual[model.g] - 1) < 1e-5) assert (abs(model.ipopt_zL_out[model.x[1]] - 10) < 1e-5) assert (abs(model.ipopt_zL_out[model.x[2]] - 10) < 1e-5) assert (abs(model.ipopt_zU_out[model.x[1]] - 10) < 1e-5) assert (abs(model.ipopt_zU_out[model.x[2]] - 10) < 1e-5)
def test02(self): """Test with suffixes""" model = self.setup_model02() x = model.x model.dual[model.g] = 1 model.ipopt_zL_out[x[1]] = 0 model.ipopt_zL_out[x[2]] = 0 model.ipopt_zU_out[x[1]] = 0 model.ipopt_zU_out[x[2]] = 0 to_json(model, fname=self.fname, human_read=True) model.x[1].value = 10 model.x[2].value = 10 model.dual[model.g] = 10 model.ipopt_zL_out[x[1]] = 10 model.ipopt_zL_out[x[2]] = 10 model.ipopt_zU_out[x[1]] = 10 model.ipopt_zU_out[x[2]] = 10 from_json(model, fname=self.fname) assert (abs(value(x[1]) - 1.5) < 1e-5) assert (abs(value(x[2]) - 2.5) < 1e-5) assert (abs(model.dual[model.g] - 1) < 1e-5) assert (abs(model.ipopt_zL_out[x[1]]) < 1e-5) assert (abs(model.ipopt_zL_out[x[2]]) < 1e-5) assert (abs(model.ipopt_zU_out[x[1]]) < 1e-5) assert (abs(model.ipopt_zU_out[x[2]]) < 1e-5)
def initialize( self, outlvl=idaeslog.NOTSET, solver=None, optarg={}, ): """ For simplicity this initialization requires you to set values for the efficency, inlet, and one of pressure ratio, pressure change or outlet pressure. """ init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") # Create solver slvr = get_solver(solver, optarg) # Store original specification so initialization doesn't change the model # This will only resore the values of varaibles that were originally fixed sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # Check for alternate pressure specs for t in self.flowsheet().config.time: if self.outlet.pressure[t].fixed: self.ratioP[t] = pyo.value( self.outlet.pressure[t]/self.inlet.pressure[t]) elif self.control_volume.deltaP[t].fixed: self.ratioP[t] = pyo.value( (self.control_volume.deltaP[t] + self.inlet.pressure[t])/ self.inlet.pressure[t] ) # Fix the variables we base the initializtion on and free the rest. # This requires good values to be provided for pressure, efficency, # and inlet conditions, but it is simple and reliable. self.inlet.fix() self.outlet.unfix() self.ratioP.fix() self.deltaP.unfix() self.efficiency_isentropic.fix() for t in self.flowsheet().config.time: self.outlet.pressure[t] = pyo.value( self.inlet.pressure[t]*self.ratioP[t]) self.deltaP[t] = pyo.value( self.outlet.pressure[t] - self.inlet.pressure[t]) self.outlet.enth_mol[t] = pyo.value(self.h_o[t]) self.control_volume.work[t] = pyo.value( self.inlet.flow_mol[t]*self.inlet.enth_mol[t] - self.outlet.flow_mol[t]*self.outlet.enth_mol[t] ) self.outlet.flow_mol[t] = pyo.value(self.inlet.flow_mol[t]) # Solve the model (should be already solved from above) with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = slvr.solve(self, tee=slc.tee) from_json(self, sd=istate, wts=sp)
def initialize(self, outlvl=idaeslog.NOTSET, optarg=None, solver=None): """ Initialization routine for mixer. Keyword Arguments: outlvl : sets output level of initialization routine optarg : solver options dictionary object (default=None, use default solver options) solver : str indicating which solver to use during initialization (default = None, use default solver) Returns: None """ init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") # Create solver opt = get_solver(solver, optarg) # This shouldn't require too much initializtion, just fixing inlets # and solving should always work. # sp is what to save to make sure state after init is same as the start sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) for b in self.inlet_blocks.values(): for bdat in b.values(): bdat.pressure.fix() bdat.enth_mol.fix() bdat.flow_mol.fix() for t, v in self.outlet.pressure.items(): if not v.fixed: v.value = min([ value(self.inlet_blocks[i][t].pressure) for i in self.inlet_blocks ]) self.outlet.unfix() if (hasattr(self, "pressure_equality_constraints") and self.pressure_equality_constraints.active): # If using the equal pressure constraint fix the outlet and free # the inlet pressures, this is typical for pressure driven flow for i, b in self.inlet_blocks.items(): for bdat in b.values(): bdat.pressure.unfix() self.outlet.pressure.fix() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(self, tee=slc.tee) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res))) from_json(self, sd=istate, wts=sp)
def test01_name(self): """ Simple test of load save json with differnt model names """ model = self.setup_model01("m1") model2 = self.setup_model01("m2") model2.b[1].a = 0.11 model2.b[1].b = 0.11 to_json(model, fname=self.fname, human_read=True) from_json(model2, fname=self.fname) #make sure they are right assert pytest.approx(20) == value(model2.b[1].b) assert pytest.approx(2) == value(model2.b[1].a)
def test12(self): """Test some odd set compoenents""" model = self.setup_model03() self.assertIs(model.r.ctype, Var) model.r[1, 3] = 1 model.r[2, 3] = 3 d = to_json(model, return_dict=True, human_read=True) model.r[1, 3] = 6 model.r[2, 3] = 8 assert value(model.b[1].x[3, 3]) == 6 assert value(model.b[2].x[3, 3]) == 8 from_json(model, sd=d) assert value(model.b[1].x[3, 3]) == 1 assert value(model.b[2].x[3, 3]) == 3
def initialize(self, **kwargs): # store original state sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # check for fixed outlet flows and use them to calculate fixed split # fractions for t in self.flowsheet().config.time: for o in self.outlet_list: elec_obj = getattr(self, o + "_elec") if elec_obj[t].fixed: self.split_fraction[o, t].fix( value(elec_obj[t] / self.electricity[t])) # fix or unfix split fractions so n - 1 are fixed for t in self.flowsheet().config.time: # see how many split fractions are fixed n = sum(1 for o in self.outlet_list if self.split_fraction[o, t].fixed) # if number of outlets - 1 we're good if n == len(self.outlet_list) - 1: continue # if too many are fixed, unfix the first, generally assume that is # the main flow, and is the calculated split fraction elif n == len(self.outlet_list): self.split_fraction[self.outlet_list[0], t].unfix() # if not enough fixed, start fixing from the back until there are # are enough else: for o in reversed(self.outlet_list): if not self.split_fraction[o, t].fixed: self.split_fraction[o, t].fix() n += 1 if n == len(self.outlet_list) - 1: break self.electricity.fix() for o in self.outlet_list: getattr(self, o + "_port").unfix() assert degrees_of_freedom(self) == 0 solver = "ipopt" if "solver" in kwargs: solver = kwargs["solver"] opt = SolverFactory(solver) opt.solve(self) from_json(self, sd=istate, wts=sp)
def test05b(self): """Try just saving values with fixed filter""" model = self.setup_model02() model.x[1].fix(1) wts = StoreSpec.value(only_not_fixed=True) to_json(model, fname=self.fname, human_read=True, wts=wts) model.g.deactivate() model.x[1].setlb(-4) model.x[1].value = 3 model.x[2].value = 6 from_json(model, fname=self.fname, wts=wts) assert value(model.x[1]) == 3 # should not load since is fixed assert model.x[1].lb == -4 assert value(model.x[2]) == pytest.approx(2.5) assert not model.g.active
def test05(self): """Try just saving values""" model = self.setup_model02() model.x[1].value = 1 wts = StoreSpec.value() to_json(model, fname=self.fname, human_read=True, wts=wts) model.g.deactivate() model.x[1].setlb(-4) model.x[1].value = 3 model.x[2].value = 6 from_json(model, fname=self.fname, wts=wts) assert value(model.x[1]) == 1 assert model.x[1].lb == -4 assert value(model.x[2]) == pytest.approx(2.5) assert not model.g.active
def test06(self): """Try just saving bounds""" model = self.setup_model02() model.x[1].value = 1 wts = StoreSpec.bound() to_json(model, fname=self.fname, human_read=True, wts=wts) model.g.deactivate() model.x[1].setlb(-4) model.x[1].value = 3 model.x[2].value = 6 from_json(model, fname=self.fname, wts=wts) assert value(model.x[1]) == 3 assert model.x[1].lb == -10 assert value(model.x[2]) == 6 assert not model.g.active
def test06(self): """Try just saving bounds""" model = self.setup_model02() model.x[1].value = 1 wts = StoreSpec.bound() to_json(model, fname=self.fname, human_read=True, wts=wts) model.g.deactivate() model.x[1].setlb(-4) model.x[1].value = 3 model.x[2].value = 6 from_json(model, fname=self.fname, wts=wts) assert (abs(value(model.x[1]) - 3) < 1e-5) assert (abs(model.x[1].lb + 10) < 1e-5) assert (abs(value(model.x[2]) - 6) < 1e-5) assert (not model.g.active)
def initialize(self, *args, **kwargs): """ Use the regular heat exchanger initialization, with the extraction rate constraint deactivated; then it activates the constraint and calculates a steam inlet flow rate. """ solver = kwargs.get("solver", None) optarg = kwargs.get("oparg", {}) outlvl = kwargs.get("outlvl", idaeslog.NOTSET) init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) self.area.fix() self.overall_heat_transfer_coefficient.fix() self.inlet_1.fix() self.inlet_2.fix() self.outlet_1.unfix() self.outlet_2.unfix() # Do condenser initialization self.inlet_1.flow_mol.unfix() # fix volume and pressure drop since # the condenser initialization dosen't require them self.side_1.volume.fix(10) self.side_1.deltaP.fix(0) self.shell_volume_eqn.deactivate() self.pressure_change_total_eqn.deactivate() super().initialize() self.side_1.volume.unfix() self.side_1.deltaP.unfix() self.shell_volume_eqn.activate() self.pressure_change_total_eqn.activate() # Create solver opt = get_solver(solver, optarg) with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(self, tee=slc.tee) init_log.info( "Initialization Complete (w/ steam flow calc): {}".format( idaeslog.condition(res) ) ) from_json(self, sd=istate, wts=sp)
def test07(self): """Try just saving just if fixed""" model = self.setup_model02() model.x[1].fix(1) wts = StoreSpec.isfixed() to_json(model, fname=self.fname, human_read=True, wts=wts) model.g.deactivate() model.x[1].setlb(-4) model.x[1].unfix() model.x[2].fix(6) from_json(model, fname=self.fname, wts=wts) assert (abs(value(model.x[1]) - 1) < 1e-5) assert (abs(model.x[1].lb + 4) < 1e-5) assert (abs(value(model.x[2]) - 6) < 1e-5) assert (model.x[1].fixed) assert (not model.x[2].fixed) assert (not model.g.active)
def test07(self): """Try just saving just if fixed""" model = self.setup_model02() model.x[1].fix(1) wts = StoreSpec.isfixed() to_json(model, fname=self.fname, human_read=True, wts=wts) model.g.deactivate() model.x[1].setlb(-4) model.x[1].unfix() model.x[2].fix(6) from_json(model, fname=self.fname, wts=wts) assert value(model.x[1]) == 1 assert model.x[1].lb == -4 assert value(model.x[2]) == 6 assert model.x[1].fixed assert not model.x[2].fixed assert not model.g.active
def test04(self): """ Like test03, but this StoreSpec also saves/loads active/deactivated component attribute and parameter values. """ model = self.setup_model02() x = model.x x[1].fix(1) wts = StoreSpec.value_isfixed_isactive(only_fixed=True) to_json(model, fname=self.fname, human_read=True, wts=wts) x[1].unfix() x[1].value = 2 x[2].value = 10 model.g.deactivate() from_json(model, fname=self.fname, wts=wts) assert (x[1].fixed) assert (abs(value(x[1]) - 1) < 1e-5) assert (abs(value(x[2]) - 10) < 1e-5) assert (model.g.active)
def initialize( self, outlvl=idaeslog.NOTSET, solver=None, optarg=None, ): """ For simplicity this initialization requires you to set values for the efficency, inlet, and one of pressure ratio, pressure change or outlet pressure. """ init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") # Create solver opt = get_solver(solver, optarg) # Store original specification so initialization doesn't change the model # This will only resore the values of varaibles that were originally fixed sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # Check for alternate pressure specs for t in self.flowsheet().time: if self.outlet.pressure[t].fixed: self.deltaP[t].fix( pyo.value(self.outlet.pressure[t] - self.inlet.pressure[t])) self.outlet.pressure[t].unfix() elif self.deltaP[t].fixed: # No outlet pressure specified guess a small pressure drop self.outlet.pressure[t] = pyo.value(self.inlet.pressure[t] + self.deltaP[t]) self.inlet.fix() self.outlet.unfix() for t, v in self.deltaP.items(): if v.fixed: self.inlet.flow_mol[t].unfix() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(self, tee=slc.tee) from_json(self, sd=istate, wts=sp)
def test03(self): """ This tests a StoreSpec object meant for initialization. It reloads the saved state of variable values and whether they are fixed or unfixed but it only loads values for variables that were originally fixed. It's use would be in doing initialization that changes which variables are fixed and does whatever, but when the original state is reloaded only the original values for fixed variables are reloaded. You basically end up with the same problem, just a different initial guess. """ model = self.setup_model02() x = model.x x[1].fix(1) wts = StoreSpec.value_isfixed(only_fixed=True) to_json(model, fname=self.fname, human_read=True, wts=wts) x[1].unfix() x[1].value = 2 x[2].value = 10 from_json(model, fname=self.fname, wts=wts) assert (x[1].fixed) assert (abs(value(x[1]) - 1) < 1e-5) assert (abs(value(x[2]) - 10) < 1e-5)
def initialize(self, *args, **kwargs): """ Use the regular heat exchanger initialization, with the extraction rate constraint deactivated; then it activates the constraint and calculates a steam inlet flow rate. """ solver = kwargs.get("solver", "ipopt") optarg = kwargs.get("oparg", {}) outlvl = kwargs.get("outlvl", idaeslog.NOTSET) init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) self.extraction_rate_constraint.deactivate() self.area.fix() self.overall_heat_transfer_coefficient.fix() self.inlet_1.fix() self.inlet_2.fix() self.outlet_1.unfix() self.outlet_2.unfix() # Do regular heat exchanger intialization super().initialize(*args, **kwargs) self.extraction_rate_constraint.activate() self.inlet_1.flow_mol.unfix() opt = SolverFactory(solver) opt.options = optarg with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(self, tee=slc.tee) init_log.info( "Initialization Complete (w/ extraction calc): {}".format( idaeslog.condition(res))) from_json(self, sd=istate, wts=sp)
def initialize(self, *args, **kwargs): """ Use the regular heat exchanger initilization, with the extraction rate constraint deactivated; then it activates the constraint and calculates a steam inlet flow rate. """ self.extraction_rate_constraint.deactivate() super().initialize(*args, **kwargs) self.extraction_rate_constraint.activate() solver = kwargs.get("solver", "ipopt") optarg = kwargs.get("oparg", {}) outlvl = kwargs.get("outlvl", 0) opt = SolverFactory(solver) opt.options = optarg tee = True if outlvl >= 3 else False sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) self.area.fix() self.overall_heat_transfer_coefficient.fix() self.inlet_1.fix() self.inlet_2.fix() self.outlet_1.unfix() self.outlet_2.unfix() self.inlet_1.flow_mol.unfix() results = opt.solve(self, tee=tee) if results.solver.termination_condition == TerminationCondition.optimal: if outlvl >= 2: _log.info('{} Initialization Failed.'.format(self.name)) else: _log.warning('{} Initialization Failed.'.format(self.name)) from_json(self, sd=istate, wts=sp)
def test01(self): """ Simple test of load save json """ model = self.setup_model01() a = model.b[1].a b = model.b[1].b to_json(model, fname=self.fname, human_read=True) # change variable values a.value = 0.11 b.value = 0.11 a.unfix() model.b[1].deactivate() b.setlb(2) b.setub(4) # reload values from_json(model, fname=self.fname) #make sure they are right assert (a.fixed) assert (model.b[1].active) assert (abs(value(b) - 20) < 1e-4) assert (abs(value(a) - 2) < 1e-4) assert (abs(b.lb - -100) < 1e-4) assert (abs(b.ub - 100) < 1e-4)
def test01b(self): """ Simple test of load save json """ model = self.setup_model01b() a = model.b["1"].a b = model.b["1"].b to_json(model, fname=self.fname, human_read=True) # change variable values a.value = 0.11 b.value = 0.11 a.unfix() model.b["1"].deactivate() b.setlb(2) b.setub(4) # reload values from_json(model, fname=self.fname) #make sure they are right assert a.fixed assert model.b["1"].active assert value(b) == 20 assert value(a) == 2 assert b.lb == -100 assert b.ub == 100
def initialize(self, outlvl=idaeslog.NOTSET, optarg=None, solver=None): """ Initialization routine for splitter Keyword Arguments: outlvl: sets output level of initialization routine optarg: solver options dictionary object (default=None, use default solver options) solver: str indicating which solver to use during initialization (default = None, use default solver) Returns: If hold_states is True, returns a dict containing flags for which states were fixed during initialization. """ init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") # Create solver opt = get_solver(solver, optarg) # sp is what to save to make sure state after init is same as the start sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # check for fixed outlet flows and use them to calculate fixed split # fractions for t in self.flowsheet().config.time: for o in self.outlet_list: if self.outlet_blocks[o][t].flow_mol.fixed: self.split_fraction[t, o].fix( value(self.mixed_state[t] / self.outlet_blocks[o][t].flow_mol)) # fix or unfix split fractions so n - 1 are fixed for t in self.flowsheet().config.time: # see how many split fractions are fixed n = sum(1 for o in self.outlet_list if self.split_fraction[t, o].fixed) # if number of outlets - 1 we're good if n == len(self.outlet_list) - 1: continue # if too mant are fixed un fix the first, generally assume that is # the main flow, and is the calculated split fraction if n == len(self.outlet_list): self.split_fraction[t, self.outlet_list[0]].unfix() # if not enough fixed, start fixing from the back until there are # are enough for o in reversed(self.outlet_list): if not self.split_fraction[t, o].fixed: self.split_fraction[t, o].fix() n += 1 if n == len(self.outlet_list) - 1: break # This model is really simple so it should easily solve without much # effort to initialize self.inlet.fix() for o, p in self.outlet_ports.items(): p.unfix() assert degrees_of_freedom(self) == 0 with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(self, tee=slc.tee) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res))) from_json(self, sd=istate, wts=sp)
def initialize(self, state_args={}, outlvl=0, solver='ipopt', optarg={'tol': 1e-6, 'max_iter':30}): """ Initialize the inlet turbine stage model. This deactivates the specialized constraints, then does the isentropic turbine initialization, then reactivates the constraints and solves. Args: state_args (dict): Initial state for property initialization outlvl (int): Amount of output (0 to 3) 0 is lowest solver (str): Solver to use for initialization optarg (dict): Solver arguments dictionary """ stee = True if outlvl >= 3 else False # sp is what to save to make sure state after init is same as the start # saves value, fixed, and active state, doesn't load originally free # values, this makes sure original problem spec is same but initializes # the values of free vars sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # Deactivate special constraints self.inlet_flow_constraint.deactivate() self.isentropic_enthalpy.deactivate() self.efficiency_correlation.deactivate() self.deltaP.unfix() self.ratioP.unfix() # Fix turbine parameters + eff_isen self.eff_nozzle.fix() self.blade_reaction.fix() self.flow_coeff.fix() self.blade_velocity.fix() # fix inlet and free outlet for t in self.flowsheet().config.time: for k, v in self.inlet.vars.items(): v[t].fix() for k, v in self.outlet.vars.items(): v[t].unfix() # If there isn't a good guess for efficeny or outlet pressure # provide something reasonable. eff = self.efficiency_isentropic[t] eff.fix(eff.value if value(eff) > 0.3 and value(eff) < 1.0 else 0.8) # for outlet pressure try outlet pressure, pressure ratio, delta P, # then if none of those look reasonable use a pressure ratio of 0.8 # to calculate outlet pressure Pout = self.outlet.pressure[t] Pin = self.inlet.pressure[t] prdp = value((self.deltaP[t] - Pin)/Pin) if value(Pout/Pin) > 0.98 or value(Pout/Pin) < 0.3: if value(self.ratioP[t]) < 0.98 and value(self.ratioP[t]) > 0.3: Pout.fix(value(Pin*self.ratioP)) elif prdp < 0.98 and prdp > 0.3: Pout.fix(value(prdp*Pin)) else: Pout.fix(value(Pin*0.8)) else: Pout.fix() self.deltaP[:] = value(Pout - Pin) self.ratioP[:] = value(Pout/Pin) for t in self.flowsheet().config.time: self.properties_isentropic[t].pressure.value = \ value(self.outlet.pressure[t]) self.properties_isentropic[t].flow_mol.value = \ value(self.inlet.flow_mol[t]) self.properties_isentropic[t].enth_mol.value = \ value(self.inlet.enth_mol[t]*0.95) self.outlet.flow_mol[t].value = \ value(self.inlet.flow_mol[t]) self.outlet.enth_mol[t].value = \ value(self.inlet.enth_mol[t]*0.95) # Make sure the initialization problem has no degrees of freedom # This shouldn't happen here unless there is a bug in this dof = degrees_of_freedom(self) try: assert(dof == 0) except: _log.exception("degrees_of_freedom = {}".format(dof)) raise # one bad thing about reusing this is that the log messages aren't # really compatible with being nested inside another initialization super(TurbineInletStageData, self).initialize(state_args=state_args, outlvl=outlvl, solver=solver, optarg=optarg) # Free eff_isen and activate sepcial constarints self.efficiency_isentropic.unfix() self.outlet.pressure.unfix() self.inlet_flow_constraint.activate() self.isentropic_enthalpy.activate() self.efficiency_correlation.activate() slvr = SolverFactory(solver) slvr.options = optarg res = slvr.solve(self, tee=stee) if outlvl > 0: if res.solver.termination_condition == TerminationCondition.optimal: _log.info("{} Initialization Complete.".format(self.name)) else: _log.warning( """{} Initialization Failed. The most likely cause of initialization failure for the Turbine inlet stages model is that the flow coefficient is not compatible with flow rate guess.""".format(self.name)) # reload original spec from_json(self, sd=istate, wts=sp)
def initialize(self, *args, **kwargs): outlvl = kwargs.get("outlvl", idaeslog.NOTSET) init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") config = self.config # shorter ref to config for less line splitting sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # the initialization here isn't straight forward since the heat exchanger # may have 3 stages and they are countercurrent. For simplicity each # stage in initialized with the same cooling water inlet conditions then # the whole feedwater heater is solved together. There are more robust # approaches which can be implimented if the need arises. # initialize desuperheat if include if config.has_desuperheat: if config.has_drain_cooling: _set_port(self.desuperheat.inlet_2, self.cooling.inlet_2) else: _set_port(self.desuperheat.inlet_2, self.condense.inlet_2) self.desuperheat.initialize(*args, **kwargs) self.desuperheat.inlet_1.flow_mol.unfix() if config.has_drain_mixer: _set_port(self.drain_mix.steam, self.desuperheat.outlet_1) else: _set_port(self.condense.inlet_1, self.desuperheat.outlet_1) # fix the steam and fwh inlet for init self.desuperheat.inlet_1.fix() self.desuperheat.inlet_1.flow_mol.unfix() # unfix for extract calc # initialize mixer if included if config.has_drain_mixer: self.drain_mix.steam.fix() self.drain_mix.drain.fix() self.drain_mix.outlet.unfix() self.drain_mix.initialize(*args, **kwargs) _set_port(self.condense.inlet_1, self.drain_mix.outlet) if config.has_desuperheat: self.drain_mix.steam.unfix() else: self.drain_mix.steam.flow_mol.unfix() # Initialize condense section if config.has_drain_cooling: _set_port(self.condense.inlet_2, self.cooling.inlet_2) self.cooling.inlet_2.fix() else: self.condense.inlet_2.fix() if not config.has_drain_mixer and not config.has_desuperheat: self.condense.inlet_1.fix() self.condense.inlet_1.flow_mol.unfix() tempsat = value(self.condense.shell.properties_in[0].temperature_sat) temp = value(self.condense.tube.properties_in[0].temperature) if tempsat - temp < 30: init_log.warning( "The steam sat. temperature ({}) is near the feedwater" " inlet temperature ({})".format(tempsat, temp)) self.condense.initialize(*args, **kwargs) # Initialize drain cooling if included if config.has_drain_cooling: _set_port(self.cooling.inlet_1, self.condense.outlet_1) self.cooling.initialize(*args, **kwargs) # Solve all together opt = SolverFactory(kwargs.get("solver", "ipopt")) opt.options = kwargs.get("oparg", {}) assert degrees_of_freedom(self) == 0 with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(self, tee=slc.tee) init_log.info("Condensing shell inlet delta T = {}".format( value(self.condense.delta_temperature_in[0]))) init_log.info("Condensing Shell outlet delta T = {}".format( value(self.condense.delta_temperature_out[0]))) init_log.info("Steam Flow = {}".format( value(self.condense.inlet_1.flow_mol[0]))) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res))) from_json(self, sd=istate, wts=sp)
def initialize(self, outlvl=idaeslog.NOTSET, solver=None, flow_iterate=2, optarg=None, copy_disconneted_flow=True, copy_disconneted_pressure=True, calculate_outlet_cf=False, calculate_inlet_cf=False): """ Initialize Args: outlvl: logging level default is NOTSET, which inherits from the parent logger solver: the NL solver flow_iterate: If not calculating flow coefficients, this is the number of times to update the flow and repeat initialization (1 to 5 where 1 does not update the flow guess) optarg: solver arguments, default is None copy_disconneted_flow: Copy the flow through the disconnected stages default is True copy_disconneted_pressure: Copy the pressure through the disconnected stages default is True calculate_outlet_cf: Use the flow initial flow guess to calculate the outlet stage flow coefficient, default is False, calculate_inlet_cf: Use the inlet stage ratioP to calculate the flow coefficent for the inlet stage default is False Returns: None """ # Setup loggers init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") # Store initial model specs, restored at the end of initializtion, so # the problem is not altered. This can restore fixed/free vars, # active/inactive constraints, and fixed variable values. sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # Assume the flow into the turbine is a reasonable guess for # initializtion flow_guess = self.inlet_split.inlet.flow_mol[0].value for it_count in range(flow_iterate): self.inlet_split.initialize(outlvl=outlvl, solver=solver, optarg=optarg) # Initialize valves for i in self.inlet_stage_idx: u = self.throttle_valve[i] copy_port(u.inlet, getattr(self.inlet_split, "outlet_{}".format(i))) u.initialize(outlvl=outlvl, solver=solver, optarg=optarg) # Initialize turbine for i in self.inlet_stage_idx: u = self.inlet_stage[i] copy_port(u.inlet, self.throttle_valve[i].outlet) u.initialize(outlvl=outlvl, solver=solver, optarg=optarg, calculate_cf=calculate_inlet_cf) # Initialize Mixer self.inlet_mix.use_minimum_inlet_pressure_constraint() for i in self.inlet_stage_idx: copy_port( getattr(self.inlet_mix, "inlet_{}".format(i)), self.inlet_stage[i].outlet, ) getattr(self.inlet_mix, "inlet_{}".format(i)).fix() self.inlet_mix.initialize(outlvl=outlvl, solver=solver, optarg=optarg) for i in self.inlet_stage_idx: getattr(self.inlet_mix, "inlet_{}".format(i)).unfix() self.inlet_mix.use_equal_pressure_constraint() prev_port = self.inlet_mix.outlet prev_port = self._init_section( self.hp_stages, self.hp_split, self.config.hp_disconnect, prev_port, outlvl, solver, optarg, copy_disconneted_flow=copy_disconneted_flow, copy_disconneted_pressure=copy_disconneted_pressure, ) if len(self.hp_stages) in self.config.hp_disconnect: self.config.ip_disconnect.append(0) prev_port = self._init_section( self.ip_stages, self.ip_split, self.config.ip_disconnect, prev_port, outlvl, solver, optarg, copy_disconneted_flow=copy_disconneted_flow, copy_disconneted_pressure=copy_disconneted_pressure, ) if len(self.ip_stages) in self.config.ip_disconnect: self.config.lp_disconnect.append(0) prev_port = self._init_section( self.lp_stages, self.lp_split, self.config.lp_disconnect, prev_port, outlvl, solver, optarg, copy_disconneted_flow=copy_disconneted_flow, copy_disconneted_pressure=copy_disconneted_pressure, ) copy_port(self.outlet_stage.inlet, prev_port) self.outlet_stage.initialize(outlvl=outlvl, solver=solver, optarg=optarg, calculate_cf=calculate_outlet_cf) if calculate_outlet_cf: break if it_count < flow_iterate - 1: for t in self.inlet_split.inlet.flow_mol: self.inlet_split.inlet.flow_mol[t].value = \ self.outlet_stage.inlet.flow_mol[t].value for s in self.hp_split.values(): for i, o in enumerate(s.outlet_list): if i == 0: continue o = getattr(s, o) self.inlet_split.inlet.flow_mol[t].value += \ o.flow_mol[t].value for s in self.ip_split.values(): for i, o in enumerate(s.outlet_list): if i == 0: continue o = getattr(s, o) self.inlet_split.inlet.flow_mol[t].value += \ o.flow_mol[t].value for s in self.lp_split.values(): for i, o in enumerate(s.outlet_list): if i == 0: continue o = getattr(s, o) self.inlet_split.inlet.flow_mol[t].value += \ o.flow_mol[t].value if calculate_inlet_cf: # cf was probably fixed, so will have to set the value agian here # if you ask for it to be calculated. icf = {} for i in self.inlet_stage: for t in self.inlet_stage[i].flow_coeff: icf[i, t] = pyo.value(self.inlet_stage[i].flow_coeff[t]) if calculate_outlet_cf: ocf = pyo.value(self.outlet_stage.flow_coeff) from_json(self, sd=istate, wts=sp) if calculate_inlet_cf: # cf was probably fixed, so will have to set the value agian here # if you ask for it to be calculated. for t in self.inlet_stage[i].flow_coeff: for i in self.inlet_stage: self.inlet_stage[i].flow_coeff[t] = icf[i, t] if calculate_outlet_cf: self.outlet_stage.flow_coeff = ocf
def initialize( self, state_args_1=None, state_args_2=None, unfix='hot_flow', outlvl=idaeslog.NOTSET, solver=None, optarg=None, ): """ Condenser initialization method. The initialization routine assumes fixed area and heat transfer coefficient and adjusts the cooling water flow to condense steam to saturated water at shell side pressure. Args: state_args_1 : a dict of arguments to be passed to the property initialization for hot side (see documentation of the specific property package) (default = None). state_args_2 : a dict of arguments to be passed to the property initialization for cold side (see documentation of the specific property package) (default = None). optarg : solver options dictionary object (default=None, use default solver options) solver : str indicating which solver to use during initialization (default = None, use default solver) Returns: None """ if unfix not in {"hot_flow", "cold_flow", "pressure"}: raise Exception("Condenser free variable must be in 'hot_flow', " "'cold_flow', or 'pressure'") # Set solver options init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") hot_side = getattr(self, self.config.hot_side_name) cold_side = getattr(self, self.config.cold_side_name) # Store initial model specs, restored at the end of initializtion, so # the problem is not altered. This can restore fixed/free vars, # active/inactive constraints, and fixed variable values. sp = StoreSpec.value_isfixed_isactive(only_fixed=True) istate = to_json(self, return_dict=True, wts=sp) # Create solver opt = get_solver(solver, optarg) flags1 = hot_side.initialize(outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args_1) flags2 = cold_side.initialize(outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args_2) init_log.info_high("Initialization Step 1 Complete.") # Solve with all constraints activated self.saturation_eqn.activate() if unfix == 'pressure': hot_side.properties_in[:].pressure.unfix() elif unfix == 'hot_flow': hot_side.properties_in[:].flow_mol.unfix() elif unfix == 'cold_flow': cold_side.properties_in[:].flow_mol.unfix() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(self, tee=slc.tee) init_log.info_high("Initialization Step 4 {}.".format( idaeslog.condition(res))) # Release Inlet state hot_side.release_state(flags1, outlvl) cold_side.release_state(flags2, outlvl) from_json(self, sd=istate, wts=sp)