def initialize(self, solver=None, outlvl=0): # TODO: Fix the inlets to the reboiler to the vapor flow from # the top tray or take it as an argument to this method. init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") # Initialize the inlet and outlet state blocks self.control_volume.initialize(outlvl=outlvl) if solver is not None: with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solver.solve(self, tee=slc.tee) init_log.info("Initialization Complete, {}.".format( idaeslog.condition(res))) else: init_log.warning( "Solver not provided during initialization, proceeding" " with deafult solver in idaes.") solver = get_default_solver() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solver.solve(self, tee=slc.tee) init_log.info("Initialization Complete, {}.".format( idaeslog.condition(res)))
def initialize(blk, state_args=None, outlvl=idaeslog.NOTSET, solver='ipopt', optarg={'tol': 1e-6}): ''' This is a general purpose initialization routine for simple unit models. This method assumes a single ControlVolume block called controlVolume, and first initializes this and then attempts to solve the entire unit. More complex models should overload this method with their own initialization routines, Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}). outlvl : sets output level of initialization routine optarg : solver options dictionary object (default={'tol': 1e-6}) solver : str indicating which solver to use during initialization (default = 'ipopt') Returns: None ''' # Set solver options init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") opt = SolverFactory(solver) opt.options = optarg # --------------------------------------------------------------------- # Initialize control volume block flags = blk.control_volume.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args, ) init_log.info_high('Initialization Step 1 Complete.') # --------------------------------------------------------------------- # Solve unit with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: results = opt.solve(blk, tee=slc.tee) init_log.info_high("Initialization Step 2 {}.".format( idaeslog.condition(results))) # --------------------------------------------------------------------- # Release Inlet state blk.control_volume.release_state(flags, outlvl + 1) init_log.info('Initialization Complete: {}'.format( idaeslog.condition(results)))
def initialize(blk, state_args=None, outlvl=0, solver='ipopt', optarg={'tol': 1e-6}): ''' Downcomer initialization routine. Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) for the control_volume of the model to provide an initial state for initialization (see documentation of the specific property package) (default = None). outlvl : sets output level of initialisation routine optarg : solver options dictionary object (default={'tol': 1e-6}) solver : str indicating whcih solver to use during initialization (default = 'ipopt') Returns: None ''' init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") opt = SolverFactory(solver) opt.options = optarg flags = blk.control_volume.initialize( outlvl=outlvl + 1, optarg=optarg, solver=solver, state_args=state_args, ) init_log.info_high("Initialization Step 1 Complete.") # Fix outlet enthalpy and pressure for t in blk.flowsheet().config.time: blk.control_volume.properties_out[t].pressure.fix( value(blk.control_volume.properties_in[t].pressure)) blk.pressure_change_total_eqn.deactivate() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high("Initialization Step 2 {}.".format( idaeslog.condition(res))) # Unfix outlet enthalpy and pressure for t in blk.flowsheet().config.time: blk.control_volume.properties_out[t].pressure.unfix() blk.pressure_change_total_eqn.activate() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high("Initialization Step 3 {}.".format( idaeslog.condition(res))) blk.control_volume.release_state(flags, outlvl + 1) init_log.info("Initialization Complete.")
def initialize( blk, state_args=None, outlvl=idaeslog.NOTSET, solver=None, optarg=None, hold_state=False, ): """ General wrapper for pressure changer initialization routines Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}). outlvl : sets output level of initialization routine optarg : solver options dictionary object (default=None) solver : str indicating which solver to use during initialization (default = None) hold_state: boolean indicating if the inlet conditions should stay fixed Returns: None """ init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") # Set solver options opt = get_solver(solver, optarg) # --------------------------------------------------------------------- # Initialize control volume flags = blk.control_volume.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args, ) init_log.info_high("Initialization Step 1 Complete.") # # --------------------------------------------------------------------- # Solve unit with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high("Initialization Step 2 {}.".format( idaeslog.condition(res))) # --------------------------------------------------------------------- if hold_state: return flags else: # Release Inlet state blk.control_volume.release_state(flags, outlvl=outlvl) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res)))
def test_solver_condition2(): solver = pyo.SolverFactory('ipopt') model = pyo.ConcreteModel("Solver Result Test Model") model.x = pyo.Var([1, 2]) model.y = pyo.Var(initialize=5) model.x.fix(2) model.y.unfix() model.c = pyo.Constraint(expr=model.x[1] + model.x[2] == model.y) res = solver.solve(model) assert idaeslog.condition(res).startswith("optimal") # better solve model.c2 = pyo.Constraint(expr=model.x[1] == model.y) res = solver.solve(model) assert idaeslog.condition(res).startswith( "other") # too few degrees of freedom
def initialize(self, solver=None, outlvl=idaeslog.NOTSET): # TODO: Fix the inlets to the condenser to the vapor flow from # the top tray or take it as an argument to this method. init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") if self.config.temperature_spec == TemperatureSpec.customTemperature: if degrees_of_freedom(self) != 0: raise ConfigurationError( "Degrees of freedom is not 0 during initialization. " "Check if outlet temperature has been fixed in addition " "to the other inputs required as customTemperature was " "selected for temperature_spec config argument.") if self.config.condenser_type == CondenserType.totalCondenser: self.eq_total_cond_spec.deactivate() # Initialize the inlet and outlet state blocks self.control_volume.initialize(outlvl=outlvl) # Activate the total condenser spec if self.config.condenser_type == CondenserType.totalCondenser: self.eq_total_cond_spec.activate() if solver is not None: with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solver.solve(self, tee=slc.tee) init_log.info("Initialization Complete, {}.".format( idaeslog.condition(res)))
def initialize(self, state_args=None, solver=None, optarg=None, outlvl=idaeslog.NOTSET): # TODO: Fix the inlets to the condenser to the vapor flow from # the top tray or take it as an argument to this method. init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") if self.config.temperature_spec == TemperatureSpec.customTemperature: if degrees_of_freedom(self) != 0: raise ConfigurationError( "Degrees of freedom is not 0 during initialization. " "Check if outlet temperature has been fixed in addition " "to the other inputs required as customTemperature was " "selected for temperature_spec config argument.") solverobj = get_solver(solver, optarg) if state_args is None: state_args = {} state_dict = (self.control_volume.properties_in[ self.flowsheet().time.first()].define_port_members()) for k in state_dict.keys(): if state_dict[k].is_indexed(): state_args[k] = {} for m in state_dict[k].keys(): state_args[k][m] = value(state_dict[k][m]) else: state_args[k] = value(state_dict[k]) if self.config.condenser_type == CondenserType.totalCondenser: self.eq_total_cond_spec.deactivate() # Initialize the inlet and outlet state blocks flags = self.control_volume.initialize(state_args=state_args, solver=solver, optarg=optarg, outlvl=outlvl, hold_state=True) # Activate the total condenser spec if self.config.condenser_type == CondenserType.totalCondenser: self.eq_total_cond_spec.activate() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solverobj.solve(self, tee=slc.tee) init_log.info("Initialization Complete, {}.".format( idaeslog.condition(res))) if not check_optimal_termination(res): raise InitializationError( f"{self.name} failed to initialize successfully. Please check " f"the output logs for more information.") self.control_volume.release_state(flags=flags)
def initialize(blk, state_args={}, outlvl=idaeslog.NOTSET, solver=None, optarg=None): ''' Hydrogen tank model initialization routine. Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) for the control_volume of the model to provide an initial state for initialization (see documentation of the specific property package) (default = None). outlvl : sets output level of initialisation routine * 0 = no output (default) * 1 = return solver state for each step in routine * 2 = return solver state for each step in subroutines * 3 = include solver output infomation (tee=True) optarg : solver options dictionary object (default={'tol': 1e-6}) solver : str indicating whcih solver to use during initialization (default = 'ipopt') Returns: None ''' init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") opt = get_solver(solver, optarg) init_log.info_low("Starting initialization...") flags = blk.control_volume.initialize(state_args=state_args, outlvl=outlvl, optarg=optarg, solver=solver) flag_previous_state = blk.previous_state.initialize( outlvl=outlvl, optarg=optarg, solver=solver, hold_state=True, state_args=state_args, ) init_log.info_high("Initialization Step 1 Complete.") with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high("Initialization Step 2 {}.".format( idaeslog.condition(res))) blk.control_volume.release_state(flags, outlvl) blk.previous_state.release_state(flag_previous_state, outlvl) init_log.info("Initialization Complete.")
def _default_initializer(model, opt=None, init_log=None, solve_log=None, initial_guess=None): with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(model, tee=slc.tee) init_log.info( "Initialization completed using default method {}.".format( idaeslog.condition(res)))
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 initialize(blk, state_args=None, outlvl=idaeslog.NOTSET, solver=None, optarg=None): ''' This method calls the initialization method of the Feed state block. Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = None). 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(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") if optarg is None: optarg = {} opt = get_solver(solver, optarg) if state_args is None: state_args = {} # Initialize state block blk.properties.initialize(outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args) with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info("Initialization complete: {}.".format( idaeslog.condition(res))) if not check_optimal_termination(res): raise InitializationError( f"{blk.name} failed to initialize successfully. Please check " f"the output logs for more information.")
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 initialize(self, state_args_feed=None, state_args_liq=None, state_args_vap=None, solver=None, outlvl=idaeslog.NOTSET): init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") init_log.info("Begin initialization.") if solver is None: init_log.warning("Solver not provided. Default solver(ipopt) " "being used for initialization.") solver = get_default_solver() feed_flags = self.tray[self.config.feed_tray_location].initialize() self.propagate_stream_state( source=self.tray[self.config.feed_tray_location].vap_out, destination=self.condenser.inlet) self.condenser.initialize() self.propagate_stream_state( source=self.tray[self.config.feed_tray_location].liq_out, destination=self.reboiler.inlet) self.reboiler.initialize() for i in self.tray_index: self.propagate_stream_state(source=self.condenser.reflux, destination=self.tray[i].liq_in) self.propagate_stream_state(source=self.reboiler.vapor_reboil, destination=self.tray[i].vap_in) self.tray[i].initialize() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solver.solve(self, tee=slc.tee) init_log.info("Column initialization status {}.".format( idaeslog.condition(res))) # release feed tray state once initialization is complete self.tray[self.config.feed_tray_location].properties_in_feed.\ release_state(flags=feed_flags, outlvl=outlvl)
def initialize(self, state_args=None, outlvl=idaeslog.NOTSET, solver=None, optarg=None): """ Initialization routine for the unit (default solver ipopt). Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}). outlvl : sets output level of initialization routine optarg : solver options dictionary object (default={'tol': 1e-6}) solver : str indicating whcih solver to use during initialization (default = 'ipopt') Returns: None """ init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") solver = get_solver(solver=solver, options=optarg) flags_tube = self.tube.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args, ) init_log.info_high("Initialization Step 1 Complete.") with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solver.solve(self, tee=slc.tee) init_log.info_high("Initialization Step 2 {}.".format( idaeslog.condition(res))) self.tube.release_state(flags_tube) init_log.info("Initialization Complete.")
def initialize(self, state_args=None, solver=None, optarg=None, outlvl=idaeslog.NOTSET): init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solver = get_solver(solver=solver, options=optarg) self.compressor.initialize(state_args=state_args, outlvl=outlvl) propagate_state(self.comp_to_reactor) self.stoic_reactor.initialize(outlvl=outlvl) propagate_state(self.reactor_to_turbine) self.turbine.initialize(outlvl=outlvl) with idaeslog.solver_log(init_log, idaeslog.DEBUG) as slc: res = solver.solve(self, tee=slc.tee) init_log.info("Hydrogen Turbine initialization status {}.".format( idaeslog.condition(res)))
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, 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( blk, state_args_in=None, state_args_out=None, outlvl=idaeslog.NOTSET, solver=None, optarg=None, ): """ This method calls the initialization method of the state blocks. Keyword Arguments: state_args_in : a dict of arguments to be passed to the inlet property package (to provide an initial state for initialization (see documentation of the specific property package) (default = None). state_args_out : a dict of arguments to be passed to the outlet property package (to provide an initial state for initialization (see documentation of the specific property package) (default = None). 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(blk.name, outlvl, tag="unit") # Create solver opt = get_solver(solver, optarg) # --------------------------------------------------------------------- # Initialize state block flags = blk.properties_in.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args_in, hold_state=True, ) blk.properties_out.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args_out, ) if degrees_of_freedom(blk) == 0: with idaeslog.solver_log(init_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info("Initialization Complete {}.".format( idaeslog.condition(res))) else: init_log.warning("Initialization incomplete. Degrees of freedom " "were not zero. Please provide sufficient number " "of constraints linking the state variables " "between the two state blocks.") blk.properties_in.release_state(flags=flags, outlvl=outlvl)
def test_solver_condition(): # test the results that can be tested without a solver assert idaeslog.condition(None) == "Error, no result" assert idaeslog.condition("something else") == "something else"
def initialize( self, state_args={}, outlvl=idaeslog.NOTSET, 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 """ init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit") # 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: init_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().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 with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = slvr.solve(self, tee=slc.tee) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res))) # 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, 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)
def initialize(blk, vapor_phase_state_args=None, liquid_phase_state_args=None, state_vars_fixed=False, outlvl=idaeslog.NOTSET, solver=None, optarg=None): """ Column initialization. Arguments: state_args : a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (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 IDAES default solver) """ # Set up logger for initialization and solve init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") # Set solver options opt = get_solver(solver, optarg) dynamic_constraints = [ "pressure_at_interface", "mass_transfer_vapor", "liquid_phase_mass_transfer_handle", "vapor_phase_mass_transfer_handle", "vapor_phase_volumetric_heat_flux", "vapor_phase_heat_transfer", "liquid_phase_heat_transfer"] # --------------------------------------------------------------------- # Deactivate unit model level constraints (asides geometry constraints) for c in blk.component_objects(Constraint, descend_into=True): if c.local_name in dynamic_constraints: c.deactivate() # Fix variables # Interface pressure blk.pressure_equil.fix() # Molar flux blk.interphase_mass_transfer.fix(0.0) blk.vapor_phase.mass_transfer_term.fix(0.0) blk.liquid_phase.mass_transfer_term.fix(0.0) # Heat transfer rate blk.heat_flux_vap.fix(0.0) blk.vapor_phase.heat.fix(0.0) blk.liquid_phase.heat.fix(0.0) # # --------------------------------------------------------------------- # Provide state arguments for property package initialization init_log.info("Step 1: Property Package initialization") vap_comp = blk.config.vapor_side.property_package.component_list liq_apparent_comp = [c[1] for c in blk.liquid_phase.properties.phase_component_set] if vapor_phase_state_args is None: vapor_phase_state_args = { 'flow_mol': blk.vapor_inlet.flow_mol[0].value, 'temperature': blk.vapor_inlet.temperature[0].value, 'pressure': blk.vapor_inlet.pressure[0].value, 'mole_frac_comp': {j: blk.vapor_inlet.mole_frac_comp[0, j].value for j in vap_comp}} if liquid_phase_state_args is None: liquid_phase_state_args = { 'flow_mol': blk.liquid_inlet.flow_mol[0].value, 'temperature': blk.liquid_inlet.temperature[0].value, 'pressure': blk.vapor_inlet.pressure[0].value, 'mole_frac_comp': {j: blk.liquid_inlet.mole_frac_comp[0, j].value for j in liq_apparent_comp}} # Initialize vapor_phase properties block vflag = blk.vapor_phase.properties.initialize( state_args=vapor_phase_state_args, state_vars_fixed=False, outlvl=outlvl, optarg=optarg, solver=solver, hold_state=True) # Initialize liquid_phase properties block lflag = blk.liquid_phase.properties.initialize( state_args=liquid_phase_state_args, state_vars_fixed=False, outlvl=outlvl, optarg=optarg, solver=solver, hold_state=True) init_log.info("Step 2: Steady-State isothermal mass balance") blk.vapor_phase.properties.release_state(flags=vflag) blk.liquid_phase.properties.release_state(flags=lflag) with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high("Step 2: {}.".format(idaeslog.condition(res))) assert res.solver.termination_condition == \ TerminationCondition.optimal assert res.solver.status == SolverStatus.ok # --------------------------------------------------------------------- init_log.info('Step 3: Interface equilibrium') # Activate interface pressure constraint blk.pressure_equil.unfix() blk.pressure_at_interface.activate() # ---------------------------------------------------------------------- with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high( "Step 3 complete: {}.".format(idaeslog.condition(res))) # --------------------------------------------------------------------- init_log.info('Step 4: Isothermal chemical absoption') init_log.info_high("No mass transfer to mass transfer") # Unfix mass transfer terms blk.interphase_mass_transfer.unfix() # Activate mass transfer equation in vapor phase blk.mass_transfer_vapor.activate() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) blk.vapor_phase.mass_transfer_term.unfix() blk.liquid_phase.mass_transfer_term.unfix() blk.vapor_phase_mass_transfer_handle.activate() blk.liquid_phase_mass_transfer_handle.activate() optarg = { "tol": 1e-8, "max_iter": 150, "bound_push":1e-8} opt.options = optarg with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) if res.solver.status != SolverStatus.warning: print('') init_log.info_high( "Step 4 complete: {}.".format(idaeslog.condition(res))) # --------------------------------------------------------------------- init_log.info('Step 5: Adiabatic chemical absoption') init_log.info_high("Isothermal to Adiabatic ") # Unfix heat transfer terms blk.heat_flux_vap.unfix() blk.vapor_phase.heat.unfix() blk.liquid_phase.heat.unfix() # Activate heat transfer and steady-state energy balance related equations for c in ["vapor_phase_volumetric_heat_flux", "vapor_phase_heat_transfer", "liquid_phase_heat_transfer"]: getattr(blk, c).activate() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high( "Step 5 complete: {}.".format(idaeslog.condition(res))) # --------------------------------------------------------------------- if not blk.config.dynamic: init_log.info('Steady-state initialization complete')
def initialize_build(blk, initialize_guess=None, state_args=None, outlvl=idaeslog.NOTSET, solver=None, optarg=None, fail_on_warning=False, ignore_dof=False): """ Initialization routine for 1D-RO unit. Keyword Arguments: initialize_guess : a dict of guesses for solvent_recovery, solute_recovery, and cp_modulus. These guesses offset the initial values for the retentate, permeate, and membrane interface state blocks from the inlet feed (default = {'deltaP': -1e4, 'solvent_recovery': 0.5, 'solute_recovery': 0.01, 'cp_modulus': 1.1}) state_args : a dict of arguments to be passed to the property package(s) to provide an initial state for the inlet feed side state block (see documentation of the specific property package) (default = None). outlvl : sets output level of initialization routine solver : str indicating which solver to use during initialization (default = None, use default solver) optarg : solver options dictionary object (default=None, use default solver options) fail_on_warning : boolean argument to fail or only produce warning upon unsuccessful solve (default=False) ignore_dof : boolean argument to ignore when DOF != 0 (default=False) Returns: None """ init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") # Create solver opt = get_solver(solver, optarg) source = blk.feed_side.properties[blk.flowsheet().config.time.first(), blk.first_element] state_args = blk._get_state_args(source, blk.mixed_permeate[0], initialize_guess, state_args) # --------------------------------------------------------------------- # Step 1: Initialize feed_side, permeate_side, and mixed_permeate blocks flags_feed_side = blk.feed_side.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args['feed_side'], hold_state=True) init_log.info("Initialization Step 1 Complete") if not ignore_dof: check_dof(blk, fail_flag=fail_on_warning, logger=init_log) # --------------------------------------------------------------------- # Initialize other state blocks # base properties on inlet state block flag_feed_side_properties_interface = blk.feed_side.properties_interface.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args['interface']) flags_permeate_side = blk.permeate_side.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args['permeate']) flags_mixed_permeate = blk.mixed_permeate.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args['permeate']) init_log.info("Initialization Step 2 Complete.") # --------------------------------------------------------------------- # Solve unit with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) # occasionally it might be worth retrying a solve if not check_optimal_termination(res): init_log.warn( "Trouble solving ReverseOsmosis1D unit model, trying one more time" ) res = opt.solve(blk, tee=slc.tee) check_solve(res, logger=init_log, fail_flag=fail_on_warning, checkpoint='Initialization Step 3') # --------------------------------------------------------------------- # Release Inlet state blk.feed_side.release_state(flags_feed_side, outlvl) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res)))
def initialize(m, fileinput=None, outlvl=idaeslog.NOTSET): """ Initialize a mode from create_model(), set model inputs before initializing. Args: m (ConcreteModel): A Pyomo model from create_model() fileinput (str|None): File to load initialized model state from. If a file is supplied skip initialization routine. If None, initialize. Returns: solver: A Pyomo solver object, that can be used to solve the model. """ init_log = idaeslog.getInitLogger(m.name, outlvl, tag="flowsheet") solve_log = idaeslog.getSolveLogger(m.name, outlvl, tag="flowsheet") iscale.calculate_scaling_factors(m) solver = pyo.SolverFactory("ipopt") solver.options = { "tol": 1e-7, "linear_solver": "ma27", "max_iter": 40, } if fileinput is not None: init_log.info("Loading initial values from file: {}".format(fileinput)) ms.from_json(m, fname=fileinput) return solver init_log.info("Starting initialization") ############################################################################ # Initialize turbine # ############################################################################ # Extraction rates are calculated from the feedwater heater models, so to # initialize the turbine fix some initial guesses. They get unfixed after # solving the turbine m.fs.turb.outlet_stage.control_volume.properties_out[:].pressure.fix(3500) m.fs.turb.lp_split[11].split_fraction[:, "outlet_2"].fix(0.04403) m.fs.turb.lp_split[10].split_fraction[:, "outlet_2"].fix(0.04025) m.fs.turb.lp_split[8].split_fraction[:, "outlet_2"].fix(0.04362) m.fs.turb.lp_split[4].split_fraction[:, "outlet_2"].fix(0.08025) m.fs.turb.ip_split[10].split_fraction[:, "outlet_2"].fix(0.045) m.fs.turb.ip_split[10].split_fraction[:, "outlet_3"].fix(0.04) m.fs.turb.ip_split[5].split_fraction[:, "outlet_2"].fix(0.05557) m.fs.turb.hp_split[7].split_fraction[:, "outlet_2"].fix(0.09741) m.fs.turb.hp_split[4].split_fraction[:, "outlet_2"].fix(0.0740) # Put in a rough initial guess for the IP section inlet, since it is # disconnected from the HP section for the reheater. ip1_pin = 5.35e6 ip1_hin = pyo.value( iapws95.htpx(T=866 * pyo.units.K, P=ip1_pin * pyo.units.Pa)) ip1_fin = pyo.value(m.fs.turb.inlet_split.inlet.flow_mol[0]) m.fs.turb.ip_stages[1].inlet.enth_mol[:].value = ip1_hin m.fs.turb.ip_stages[1].inlet.flow_mol[:].value = ip1_fin m.fs.turb.ip_stages[1].inlet.pressure[:].value = ip1_pin # initialize turbine assert degrees_of_freedom(m.fs.turb) == 0 m.fs.turb.initialize(outlvl=outlvl, optarg=solver.options) with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solver.solve(m.fs.turb, tee=slc.tee) init_log.info("Full turbine solve complete: {}".format( idaeslog.condition(res))) # The turbine outlet pressure is determined by the condenser once hooked up m.fs.turb.outlet_stage.control_volume.properties_out[:].pressure.unfix() # Extraction rates are calculated once the feedwater heater models are # added so unfix the splits. m.fs.turb.lp_split[11].split_fraction[:, "outlet_2"].unfix() m.fs.turb.lp_split[10].split_fraction[:, "outlet_2"].unfix() m.fs.turb.lp_split[8].split_fraction[:, "outlet_2"].unfix() m.fs.turb.lp_split[4].split_fraction[:, "outlet_2"].unfix() m.fs.turb.ip_split[10].split_fraction[:, "outlet_3"].unfix() m.fs.turb.ip_split[5].split_fraction[:, "outlet_2"].unfix() m.fs.turb.hp_split[7].split_fraction[:, "outlet_2"].unfix() m.fs.turb.hp_split[4].split_fraction[:, "outlet_2"].unfix() # Initialize the boiler feed pump turbine. _set_port(m.fs.bfpt.inlet, m.fs.turb.ip_split[10].outlet_3) m.fs.bfpt.control_volume.properties_out[:].pressure.fix(10000) m.fs.bfpt.efficiency_isentropic.fix() m.fs.bfpt.initialize(outlvl=idaeslog.DEBUG, optarg=solver.options) m.fs.bfpt.control_volume.properties_out[:].pressure.unfix() m.fs.bfpt.efficiency_isentropic.unfix() ############################################################################ # Condenser section # ############################################################################ # initialize condenser mixer _set_port(m.fs.condenser_mix.main, m.fs.turb.outlet_stage.outlet) _set_port(m.fs.condenser_mix.bfpt, m.fs.bfpt.outlet) m.fs.condenser_mix.initialize(outlvl=outlvl, optarg=solver.options) # initialize condenser hx _set_port(m.fs.condenser.inlet_1, m.fs.condenser_mix.outlet_tpx) _set_port(m.fs.condenser.outlet_2, m.fs.condenser.inlet_2) # This still has the outlet vapor fraction fixed at 0, so if that isn't # true for the initial pressure guess this could fail to initialize m.fs.condenser.inlet_1.fix() m.fs.condenser.inlet_1.pressure.unfix() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solver.solve(m.fs.condenser, tee=slc.tee) init_log.info("Condenser initialized: {}".format(idaeslog.condition(res))) init_log.info_high("Init condenser pressure: {}".format( m.fs.condenser.shell.properties_in[0].pressure.value)) m.fs.condenser.inlet_1.unfix() # initialize hotwell _set_port(m.fs.hotwell.condensate, m.fs.condenser.outlet_1_ph) m.fs.hotwell.initialize(outlvl=outlvl, optarg=solver.options) m.fs.hotwell.condensate.unfix() # initialize condensate pump _set_port(m.fs.cond_pump.inlet, m.fs.hotwell.outlet) m.fs.cond_pump.initialize(outlvl=outlvl, optarg=solver.options) ############################################################################ # Low-pressure FWH section # ############################################################################ # fwh1 m.fs.fwh1.drain_mix.drain.flow_mol[:] = 1000 m.fs.fwh1.drain_mix.drain.pressure[:] = 1e5 m.fs.fwh1.drain_mix.drain.enth_mol[:] = 6117 _set_port(m.fs.fwh1.condense.inlet_2, m.fs.cond_pump.outlet) _set_port(m.fs.fwh1.drain_mix.steam, m.fs.turb.lp_split[11].outlet_2) m.fs.fwh1.initialize(outlvl=outlvl, optarg=solver.options) # initialize fwh1 drain pump _set_port(m.fs.fwh1_pump.inlet, m.fs.fwh1.condense.outlet_1) m.fs.fwh1_pump.initialize(outlvl=5, optarg=solver.options) # initialize mixer to add fwh1 drain to feedwater _set_port(m.fs.fwh1_return.feedwater, m.fs.fwh1.condense.outlet_2) _set_port(m.fs.fwh1_return.fwh1_drain, m.fs.fwh1.condense.outlet_1) m.fs.fwh1_return.initialize(outlvl=outlvl, optarg=solver.options) m.fs.fwh1_return.feedwater.unfix() m.fs.fwh1_return.fwh1_drain.unfix() # fwh2 m.fs.fwh2.drain_mix.drain.flow_mol[:] = 100 m.fs.fwh2.drain_mix.drain.pressure[:] = 1.5e5 m.fs.fwh2.drain_mix.drain.enth_mol[:] = 7000 _set_port(m.fs.fwh2.cooling.inlet_2, m.fs.fwh1_return.outlet) _set_port(m.fs.fwh2.desuperheat.inlet_1, m.fs.turb.lp_split[10].outlet_2) m.fs.fwh2.initialize(outlvl=outlvl, optarg=solver.options) # fwh3 m.fs.fwh3.drain_mix.drain.flow_mol[:] = 100 m.fs.fwh3.drain_mix.drain.pressure[:] = 2.5e5 m.fs.fwh3.drain_mix.drain.enth_mol[:] = 8000 _set_port(m.fs.fwh3.cooling.inlet_2, m.fs.fwh2.desuperheat.outlet_2) _set_port(m.fs.fwh3.desuperheat.inlet_1, m.fs.turb.lp_split[8].outlet_2) m.fs.fwh3.initialize(outlvl=outlvl, optarg=solver.options) # fwh4 _set_port(m.fs.fwh4.cooling.inlet_2, m.fs.fwh3.desuperheat.outlet_2) _set_port(m.fs.fwh4.desuperheat.inlet_1, m.fs.turb.lp_split[4].outlet_2) m.fs.fwh4.initialize(outlvl=outlvl, optarg=solver.options) ############################################################################ # boiler feed pump and deaerator # ############################################################################ _set_port(m.fs.fwh5_da.feedwater, m.fs.fwh4.desuperheat.outlet_2) _set_port(m.fs.fwh5_da.steam, m.fs.turb.ip_split[10].outlet_2) m.fs.fwh5_da.drain.flow_mol[:] = 2000 m.fs.fwh5_da.drain.pressure[:] = 3e6 m.fs.fwh5_da.drain.enth_mol[:] = 9000 m.fs.fwh5_da.initialize(outlvl=outlvl, optarg=solver.options) _set_port(m.fs.bfp.inlet, m.fs.fwh5_da.outlet) m.fs.bfp.control_volume.properties_out[:].pressure.fix() m.fs.bfp.initialize(outlvl=outlvl, optarg=solver.options) m.fs.bfp.control_volume.properties_out[:].pressure.unfix() ############################################################################ # High-pressure feedwater heaters # ############################################################################ # fwh6 m.fs.fwh6.drain_mix.drain.flow_mol[:] = 1000 m.fs.fwh6.drain_mix.drain.pressure[:] = 1e7 m.fs.fwh6.drain_mix.drain.enth_mol[:] = 9500 _set_port(m.fs.fwh6.cooling.inlet_2, m.fs.bfp.outlet) _set_port(m.fs.fwh6.desuperheat.inlet_1, m.fs.turb.ip_split[5].outlet_2) m.fs.fwh6.initialize(outlvl=outlvl, optarg=solver.options) # fwh7 m.fs.fwh7.drain_mix.drain.flow_mol[:] = 2000 m.fs.fwh7.drain_mix.drain.pressure[:] = 1e7 m.fs.fwh7.drain_mix.drain.enth_mol[:] = 9500 _set_port(m.fs.fwh7.cooling.inlet_2, m.fs.fwh6.desuperheat.outlet_2) _set_port(m.fs.fwh7.desuperheat.inlet_1, m.fs.turb.hp_split[7].outlet_2) m.fs.fwh7.initialize(outlvl=outlvl, optarg=solver.options) # fwh8 _set_port(m.fs.fwh8.cooling.inlet_2, m.fs.fwh7.desuperheat.outlet_2) _set_port(m.fs.fwh8.desuperheat.inlet_1, m.fs.turb.hp_split[4].outlet_2) m.fs.fwh8.initialize(outlvl=outlvl, optarg=solver.options) with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solver.solve(m, tee=slc.tee) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res))) return solver
def initialize(blk, state_args=None, outlvl=idaeslog.NOTSET, solver=None, optarg=None): """ General wrapper for pressure changer initialization routines Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) to provide an initial state for initialization (see documentation of the specific property package) (default = {}). outlvl : sets output level of initialization routine optarg : solver options dictionary object (default=None) solver : str indicating which solver to use during initialization (default = None) Returns: None """ init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") # Set solver options opt = get_solver(solver, optarg) # --------------------------------------------------------------------- # Initialize feed side flags_feed = blk.feed_side.properties_feed.initialize(solver=solver, optarg=optarg, hold_state=True) init_log.info_high("Initialization Step 1 Complete.") # # --------------------------------------------------------------------- # # Initialize brine # Set state_args from inlet state if state_args is None: state_args = {} state_dict = blk.feed_side.properties_feed[ blk.flowsheet().config.time.first()].define_port_members() for k in state_dict.keys(): if state_dict[k].is_indexed(): state_args[k] = {} for m in state_dict[k].keys(): state_args[k][m] = state_dict[k][m].value else: state_args[k] = state_dict[k].value blk.feed_side.properties_brine.initialize(outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args) state_args_vapor = {} state_args_vapor["pressure"] = 0.5 * state_args["pressure"] state_args_vapor["temperature"] = state_args["temperature"] state_args_vapor["flow_mass_phase_comp"] = { ("Liq", "H2O"): blk.feed_side.properties_vapor[0].flow_mass_phase_comp["Liq", "H2O"].lb, ("Vap", "H2O"): state_args["flow_mass_phase_comp"][("Liq", "H2O")], } blk.feed_side.properties_vapor.initialize( outlvl=outlvl, optarg=optarg, solver=solver, state_args=state_args_vapor, ) init_log.info_high("Initialization Step 2 Complete.") # intialize condenser state_args_condenser = state_args_vapor state_args_condenser["flow_mass_phase_comp"][("Vap", "H2O")] = ( 0.5 * state_args_condenser["flow_mass_phase_comp"][("Vap", "H2O")]) state_args_condenser["pressure"] = blk.feed_side.properties_brine[ 0].pressure_sat.value state_args_condenser["temperature"] = state_args["temperature"] + 5 blk.condenser.initialize(state_args=state_args_condenser) # assert False # flags_condenser_cv = blk.condenser.initialize(state_args=state_args_condenser,hold_state=True) init_log.info_high("Initialization Step 3 Complete.") # --------------------------------------------------------------------- # Deactivate heat transfer balance # blk.eq_heat_balance.deactivate() # Solve unit with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high("Initialization Step 4 {}.".format( idaeslog.condition(res))) # --------------------------------------------------------------------- # Release feed and condenser inlet states blk.feed_side.properties_feed.release_state(flags_feed, outlvl=outlvl) # blk.condenser.control_volume.release_state(flags_condenser_cv, outlvl=outlvl) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res)))
def initialize( self, state_args=None, state_vars_fixed=False, hold_state=False, outlvl=idaeslog.NOTSET, solver=None, optarg=None, ): """ Initialization routine for property package. Keyword Arguments: state_args : Dictionary with initial guesses for the state vars chosen. Note that if this method is triggered through the control volume, and if initial guesses were not provided at the unit model level, the control volume passes the inlet values as initial guess.The keys for the state_args dictionary are: flow_mass_phase_comp : value at which to initialize phase component flows pressure : value at which to initialize pressure temperature : value at which to initialize temperature outlvl : sets output level of initialization routine (default=idaeslog.NOTSET) optarg : solver options dictionary object (default=None) state_vars_fixed: Flag to denote if state vars have already been fixed. - True - states have already been fixed by the control volume 1D. Control volume 0D does not fix the state vars, so will be False if this state block is used with 0D blocks. - False - states have not been fixed. The state block will deal with fixing/unfixing. solver : Solver object to use during initialization if None is provided it will use the default solver for IDAES (default = None) hold_state : flag indicating whether the initialization routine should unfix any state variables fixed during initialization (default=False). - True - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization. - False - state variables are unfixed after initialization by calling the release_state method Returns: If hold_states is True, returns a dict containing flags for which states were fixed during initialization. """ # Get loggers init_log = idaeslog.getInitLogger(self.name, outlvl, tag="properties") solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="properties") # Set solver and options opt = get_solver(solver, optarg) # Fix state variables flags = fix_state_vars(self, state_args) # Check when the state vars are fixed already result in dof 0 for k in self.keys(): dof = degrees_of_freedom(self[k]) if dof != 0: raise PropertyPackageError( "\nWhile initializing {sb_name}, the degrees of freedom " "are {dof}, when zero is required. \nInitialization assumes " "that the state variables should be fixed and that no other " "variables are fixed. \nIf other properties have a " "predetermined value, use the calculate_state method " "before using initialize to determine the values for " "the state variables and avoid fixing the property variables." "".format(sb_name=self.name, dof=dof)) # --------------------------------------------------------------------- skip_solve = True # skip solve if only state variables are present for k in self.keys(): if number_unfixed_variables(self[k]) != 0: skip_solve = False if not skip_solve: # Initialize properties with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: results = solve_indexed_blocks(opt, [self], tee=slc.tee) init_log.info_high("Property initialization: {}.".format( idaeslog.condition(results))) # --------------------------------------------------------------------- # If input block, return flags, else release state if state_vars_fixed is False: if hold_state is True: return flags else: self.release_state(flags)
def initialize(blk, state_args=None, outlvl=idaeslog.NOTSET, solver=None, optarg=None): ''' Downcomer initialization routine. Keyword Arguments: state_args : a dict of arguments to be passed to the property package(s) for the control_volume of the model to provide an initial state for initialization (see documentation of the specific property package) (default = None). outlvl : sets output level of initialisation 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(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") # Create solver opt = get_solver(solver, optarg) init_log.info_low("Starting initialization...") flags = blk.control_volume.initialize( outlvl=outlvl + 1, optarg=optarg, solver=solver, state_args=state_args, ) init_log.info_high("Initialization Step 1 Complete.") # make sure 0 DoF if degrees_of_freedom(blk) != 0: raise ConfigurationError( "Incorrect degrees of freedom when initializing {}: dof = {}". format(blk.name, degrees_of_freedom(blk))) # Fix outlet pressure for t in blk.flowsheet().time: blk.control_volume.properties_out[t].pressure.fix( value(blk.control_volume.properties_in[t].pressure)) blk.pressure_change_total_eqn.deactivate() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high("Initialization Step 2 {}.".format( idaeslog.condition(res))) # Unfix outlet enthalpy and pressure for t in blk.flowsheet().time: blk.control_volume.properties_out[t].pressure.unfix() blk.pressure_change_total_eqn.activate() with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info_high("Initialization Step 3 {}.".format( idaeslog.condition(res))) blk.control_volume.release_state(flags, outlvl + 1) init_log.info("Initialization Complete.")
def initialize(blk, outlvl=idaeslog.NOTSET, optarg=None, solver=None, hold_state=False): """ 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) hold_state : flag indicating whether the initialization routine should unfix any state variables fixed during initialization, **default** - False. **Valid values:** **True** - states variables are not unfixed, and a dict of returned containing flags for which states were fixed during initialization, **False** - state variables are unfixed after initialization by calling the release_state method. Returns: If hold_states is True, returns a dict containing flags for which states were fixed during initialization. """ init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="unit") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit") # Create solver opt = get_solver(solver, optarg) # Initialize inlet state blocks flags = {} inlet_list = blk.create_inlet_list() i_block_list = [] for i in inlet_list: i_block = getattr(blk, i + "_state") i_block_list.append(i_block) flags[i] = {} flags[i] = i_block.initialize( outlvl=outlvl, optarg=optarg, solver=solver, hold_state=True, ) # Initialize mixed state block if blk.config.mixed_state_block is None: mblock = blk.mixed_state else: mblock = blk.config.mixed_state_block o_flags = {} # Calculate initial guesses for mixed stream state for t in blk.flowsheet().time: # Iterate over state vars as defined by property package s_vars = mblock[t].define_state_vars() for s in s_vars: i_vars = [] for k in s_vars[s]: # Record whether variable was fixed or not o_flags[t, s, k] = s_vars[s][k].fixed # If fixed, use current value # otherwise calculate guess from mixed state if not s_vars[s][k].fixed: for i in range(len(i_block_list)): i_vars.append( getattr(i_block_list[i][t], s_vars[s].local_name)) if s == "pressure": # If pressure, use minimum as initial guess mblock[t].pressure.value = min( i_block_list[i][t].pressure.value for i in range(len(i_block_list))) elif "flow" in s: # If a "flow" variable (i.e. extensive), sum inlets for k in s_vars[s]: s_vars[s][k].value = sum( i_vars[i][k].value for i in range(len(i_block_list))) else: # Otherwise use average of inlets for k in s_vars[s]: s_vars[s][k].value = sum( i_vars[i][k].value for i in range( len(i_block_list))) / len(i_block_list) mblock.initialize( outlvl=outlvl, optarg=optarg, solver=solver, hold_state=False, ) # Revert fixed status of variables to what they were before for t in blk.flowsheet().time: s_vars = mblock[t].define_state_vars() for s in s_vars: for k in s_vars[s]: s_vars[s][k].fixed = o_flags[t, s, k] if blk.config.mixed_state_block is None: if (hasattr(blk, "pressure_equality_constraints") and blk.pressure_equality_constraints.active is True): blk.pressure_equality_constraints.deactivate() for t in blk.flowsheet().time: sys_press = getattr(blk, blk.create_inlet_list()[0] + "_state")[t].pressure blk.mixed_state[t].pressure.fix(sys_press.value) with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) blk.pressure_equality_constraints.activate() for t in blk.flowsheet().time: blk.mixed_state[t].pressure.unfix() else: with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = opt.solve(blk, tee=slc.tee) init_log.info("Initialization Complete: {}".format( idaeslog.condition(res))) else: init_log.info("Initialization Complete.") if hold_state is True: return flags else: blk.release_state(flags, outlvl=outlvl)
def initialize(blk, outlvl=idaeslog.NOTSET, optarg={}, solver=None): ''' Initialisation routine for reaction package. Keyword Arguments: outlvl : sets output level of initialization routine optarg : solver options dictionary object (default={}) solver : str indicating whcih solver to use during initialization (default = None, use default solver) Returns: None ''' init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="reactions") solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="reactions") init_log.info_high('Starting initialization') # TODO - Update in the future as needed # Get a single representative block for getting config arguments for k in blk.keys(): break # Fix state variables if not already fixed # Fix state variables of the primary (solid) state block state_var_flags = fix_state_vars(blk[k].config.solid_state_block) # Fix values of secondary (gas) state block variables if not fixed, # as well as the solid density variable. # This is done to keep the initialization problem square Cflag = {} # Gas concentration flag Dflag = {} # Solid density flag for k in blk.keys(): for j in blk[k]._params.gas_component_list: if blk[k].gas_state_ref.dens_mol_comp[j].fixed is True: Cflag[k, j] = True else: Cflag[k, j] = False blk[k].gas_state_ref.dens_mol_comp[j].fix( blk[k].gas_state_ref.dens_mol_comp[j].value) if blk[k].solid_state_ref.dens_mass_skeletal.fixed is True: Dflag[k] = True else: Dflag[k] = False blk[k].solid_state_ref.dens_mass_skeletal.fix( blk[k].solid_state_ref.dens_mass_skeletal.value) # Create solver opt = get_solver(solver, optarg) # Initialise values for k in blk.keys(): if hasattr(blk[k], "OC_conv_eqn"): calculate_variable_from_constraint(blk[k].OC_conv, blk[k].OC_conv_eqn) if hasattr(blk[k], "OC_conv_temp_eqn"): calculate_variable_from_constraint(blk[k].OC_conv_temp, blk[k].OC_conv_temp_eqn) for j in blk[k]._params.rate_reaction_idx: if hasattr(blk[k], "rate_constant_eqn"): calculate_variable_from_constraint( blk[k].k_rxn[j], blk[k].rate_constant_eqn[j]) if hasattr(blk[k], "gen_rate_expression"): calculate_variable_from_constraint( blk[k].reaction_rate[j], blk[k].gen_rate_expression[j]) # Solve property block if non-empty free_vars = 0 for k in blk.keys(): free_vars += number_unfixed_variables_in_activated_equalities( blk[k]) if free_vars > 0: with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc: res = solve_indexed_blocks(opt, [blk], tee=slc.tee) else: res = "" init_log.info_high("reactions initialization complete {}.".format( idaeslog.condition(res))) # --------------------------------------------------------------------- # Revert state vars and other variables to pre-initialization states # Revert state variables of the primary (solid) state block revert_state_vars(blk[k].config.solid_state_block, state_var_flags) for k in blk.keys(): for j in blk[k]._params.gas_component_list: if Cflag[k, j] is False: blk[k].gas_state_ref.dens_mol_comp[j].unfix() if Dflag[k] is False: blk[k].solid_state_ref.dens_mass_skeletal.unfix() init_log = idaeslog.getInitLogger(blk.name, outlvl, tag="reactions") init_log.info_high('States released.')