예제 #1
0
def main():
    # set up solver
    solver_dict = {
        'solver_str': 'ipopt',
        'solver_opt': {
            'nlp_scaling_method': 'user-scaling'
        }
    }
    solver_dict['solver'] = SolverFactory(solver_dict['solver_str'])
    solver_dict['solver'].options = solver_dict['solver_opt']

    # build, set, and initialize
    m = build()
    set_operating_conditions(m, solver=solver_dict['solver'])
    initialize_system(m, solver_dict=solver_dict)

    # simulate and display
    solve(m, solver=solver_dict['solver'])
    print('\n***---Simulation results---***')
    display_system(m)
    display_design(m)
    display_state(m)

    # optimize and display
    optimize(m, solver=solver_dict['solver'])
    print('\n***---Optimization results---***')
    display_system(m)
    display_design(m)
    display_state(m)
    def unit_frame(self):
        m = ConcreteModel()
        m.fs = FlowsheetBlock(default={'dynamic': False})
        m.fs.properties = props.SeawaterParameterBlock()
        m.fs.unit = PressureExchanger(
            default={'property_package': m.fs.properties})

        # Specify inlet conditions
        temperature = 25 + 273.15
        flow_vol = 1e-3
        lowP_mass_frac_TDS = 0.035
        lowP_pressure = 101325
        highP_mass_frac_TDS = 0.07
        highP_pressure = 50e5

        m.fs.unit.low_pressure_side.properties_in[0].flow_vol_phase['Liq'].fix(
            flow_vol)
        m.fs.unit.low_pressure_side.properties_in[0].mass_frac_phase_comp[
            'Liq', 'TDS'].fix(lowP_mass_frac_TDS)
        m.fs.unit.low_pressure_side.properties_in[0].pressure.fix(
            lowP_pressure)
        m.fs.unit.low_pressure_side.properties_in[0].temperature.fix(
            temperature)

        m.fs.unit.high_pressure_side.properties_in[0].flow_vol_phase[
            'Liq'].fix(flow_vol)
        m.fs.unit.high_pressure_side.properties_in[0].mass_frac_phase_comp[
            'Liq', 'TDS'].fix(highP_mass_frac_TDS)
        m.fs.unit.high_pressure_side.properties_in[0].pressure.fix(
            highP_pressure)
        m.fs.unit.high_pressure_side.properties_in[0].temperature.fix(
            temperature)

        # solve inlet conditions and only fix state variables (i.e. unfix flow_vol and mass_frac_phase)
        solver = SolverFactory('ipopt')
        solver.options = {'nlp_scaling_method': 'user-scaling'}
        results = solver.solve(m.fs.unit.low_pressure_side.properties_in[0])
        assert results.solver.termination_condition == TerminationCondition.optimal
        m.fs.unit.low_pressure_side.properties_in[0].flow_mass_phase_comp[
            'Liq', 'TDS'].fix()
        m.fs.unit.low_pressure_side.properties_in[0].flow_vol_phase[
            'Liq'].unfix()
        m.fs.unit.low_pressure_side.properties_in[0].mass_frac_phase_comp[
            'Liq', 'TDS'].unfix()

        results = solver.solve(m.fs.unit.high_pressure_side.properties_in[0])
        assert results.solver.termination_condition == TerminationCondition.optimal
        m.fs.unit.high_pressure_side.properties_in[0].flow_mass_phase_comp[
            'Liq', 'H2O'].fix()
        m.fs.unit.high_pressure_side.properties_in[0].flow_mass_phase_comp[
            'Liq', 'TDS'].fix()
        m.fs.unit.high_pressure_side.properties_in[0].flow_vol_phase[
            'Liq'].unfix()
        m.fs.unit.high_pressure_side.properties_in[0].mass_frac_phase_comp[
            'Liq', 'TDS'].unfix()

        # Specify unit
        efficiency = 0.95
        m.fs.unit.efficiency_pressure_exchanger.fix(efficiency)
        return m
예제 #3
0
    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)))
예제 #4
0
    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.")
예제 #5
0
    def initialize(blk,
                   state_args_water_steam={},
                   outlvl=0,
                   solver='ipopt',
                   optarg={'tol': 1e-6}):
        '''
        Drum 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 = SolverFactory(solver)
        opt.options = optarg

        init_log.info_low("Starting initialization...")
        # fix FeedWater Inlet
        flags_fw = fix_state_vars(blk.mixed_state, state_args_water_steam)
        blk.mixed_state.initialize()
        # initialize outlet states
        for t in blk.flowsheet().config.time:
            blk.vap_state[t].flow_mol = value(blk.mixed_state[t].flow_mol *
                                              blk.mixed_state[t].vapor_frac)
            blk.vap_state[t].enth_mol = value(
                blk.mixed_state[t].enth_mol_phase["Vap"])
            blk.vap_state[t].pressure = value(blk.mixed_state[t].pressure)
            blk.vap_state[t].vapor_frac = 1
            blk.liq_state[t].flow_mol = value(
                blk.mixed_state[t].flow_mol *
                (1 - blk.mixed_state[t].vapor_frac))
            blk.liq_state[t].enth_mol = value(
                blk.mixed_state[t].enth_mol_phase["Liq"])
            blk.liq_state[t].pressure = value(blk.mixed_state[t].pressure)
            blk.liq_state[t].vapor_frac = 0
        # unfix variables
        revert_state_vars(blk.mixed_state, flags_fw)
        init_log.info_low("Initialization Complete.")
예제 #6
0
    def initialize(self, outlvl=idaeslog.NOTSET, optarg={}, solver="ipopt"):
        """
        Initialization routine for mixer (default solver ipopt)

        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 = 'ipopt')

        Returns:
            None
        """
        init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit")

        # Set solver options
        opt = SolverFactory(solver)
        opt.options = 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)
예제 #7
0
def get_default_solver():
    """
    Tries to set-up the default solver for testing, and returns None if not
    available
    """
    if SolverFactory('ipopt').available(exception_flag=False):
        solver = SolverFactory('ipopt')
        solver.options = {'tol': 1e-6}
    else:
        solver = None

    return solver
예제 #8
0
    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.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()

        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/ steam flow calc): {}".format(
                idaeslog.condition(res)
            )
        )

        from_json(self, sd=istate, wts=sp)
예제 #9
0
    def initialize(blk,
                   state_args={},
                   outlvl=0,
                   solver='ipopt',
                   optarg={'tol': 1e-6}):
        '''
        This method initializes the StateJunction block by calling the
        initialize method on the property 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 = {}).
            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 which solver to use during
                     initialization (default = 'ipopt')

        Returns:
            None
        '''
        # Set solver options
        opt = SolverFactory(solver)
        opt.options = optarg

        # ---------------------------------------------------------------------
        # Initialize control volume block
        blk.properties.initialize(outlvl=outlvl - 1,
                                  optarg=optarg,
                                  solver=solver,
                                  hold_state=False,
                                  **state_args)

        if outlvl > 0:
            _log.info('{} Initialisation Step Complete.'.format(blk.name))
예제 #10
0
    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 initialize(blk,
                   state_args_1=None,
                   state_args_2=None,
                   state_args_3=None,
                   outlvl=idaeslog.NOTSET,
                   solver='ipopt',
                   optarg={'tol': 1e-6}):
        '''
        General Heat Exchanger initialisation routine.

        Keyword Arguments:
            state_args_1 : a dict of arguments to be passed to the property
                           package(s) for side 1 of the heat exchanger to
                           provide an initial state for initialization
                           (see documentation of the specific property package)
                           (default = None).
            state_args_2 : a dict of arguments to be passed to the property
                           package(s) for side 2 of the heat exchanger to
                           provide an initial state for initialization
                           (see documentation of the specific property package)
                           (default = None).
            state_args_3 : a dict of arguments to be passed to the property
                           package(s) for side 3 of the heat exchanger 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

        # ---------------------------------------------------------------------
        # Initialize inlet property blocks
        flags1 = blk.side_1.initialize(outlvl=outlvl,
                                       optarg=optarg,
                                       solver=solver,
                                       state_args=state_args_1)

        flags2 = blk.side_2.initialize(outlvl=outlvl,
                                       optarg=optarg,
                                       solver=solver,
                                       state_args=state_args_2)

        flags3 = blk.side_3.initialize(outlvl=outlvl,
                                       optarg=optarg,
                                       solver=solver,
                                       state_args=state_args_3)

        init_log.info('Initialisation Step 1 Complete.')

        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(blk, tee=slc.tee)
        init_log.info("Initialization Step 2 Complete: {}".format(
            idaeslog.condition(res)))
        # ---------------------------------------------------------------------
        # Release Inlet state
        blk.side_1.release_state(flags1, outlvl)
        blk.side_2.release_state(flags2, outlvl)
        blk.side_3.release_state(flags3, outlvl)

        init_log.info_low("Initialization Complete: {}".format(
            idaeslog.condition(res)))
예제 #12
0
    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)
예제 #13
0
    def initialize(self, *args, **kwargs):
        config = self.config  # sorter 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 initilization 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()
        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
        outlvl = kwargs.get("outlvl", 0)
        opt = SolverFactory(kwargs.get("solver", "ipopt"))
        opt.options = kwargs.get("oparg", {})
        tee = True if outlvl >= 3 else False
        assert (degrees_of_freedom(self) == 0)
        results = opt.solve(self, tee=tee)
        if results.solver.termination_condition == TerminationCondition.optimal:
            if outlvl >= 2:
                _log.info('{} Initialization Complete.'.format(self.name))
        else:
            _log.warning('{} Initialization Failed.'.format(self.name))

        from_json(self, sd=istate, wts=sp)
예제 #14
0
    def initialize(
        self,
        state_args_1=None,
        state_args_2=None,
        outlvl=idaeslog.NOTSET,
        solver="ipopt",
        optarg={"tol": 1e-6},
        duty=None,
    ):
        """
        Heat exchanger initialization method.

        Args:
            state_args_1 : a dict of arguments to be passed to the property
                initialization for the hot side (see documentation of the specific
                property package) (default = {}).
            state_args_2 : a dict of arguments to be passed to the property
                initialization for the cold side (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')
            duty : an initial guess for the amount of heat transfered. This
                should be a tuple in the form (value, units), (default
                = (1000 J/s))

        Returns:
            None

        """
        # 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)

        opt = SolverFactory(solver)
        opt.options = optarg
        flags1 = hot_side.initialize(outlvl=outlvl,
                                     optarg=optarg,
                                     solver=solver,
                                     state_args=state_args_1)

        init_log.info_high("Initialization Step 1a (hot side) Complete.")

        flags2 = cold_side.initialize(outlvl=outlvl,
                                      optarg=optarg,
                                      solver=solver,
                                      state_args=state_args_2)

        init_log.info_high("Initialization Step 1b (cold side) Complete.")
        # ---------------------------------------------------------------------
        # Solve unit without heat transfer equation
        # if costing block exists, deactivate
        if hasattr(self, "costing"):
            self.costing.deactivate()

        self.heat_transfer_equation.deactivate()

        # Get side 1 and side 2 heat units, and convert duty as needed
        s1_units = hot_side.heat.get_units()
        s2_units = cold_side.heat.get_units()

        if duty is None:
            # Assume 1000 J/s and check for unitless properties
            if s1_units is None and s2_units is None:
                # Backwards compatability for unitless properties
                s1_duty = -1000
                s2_duty = 1000
            else:
                s1_duty = pyunits.convert_value(-1000,
                                                from_units=pyunits.W,
                                                to_units=s1_units)
                s2_duty = pyunits.convert_value(1000,
                                                from_units=pyunits.W,
                                                to_units=s2_units)
        else:
            # Duty provided with explicit units
            s1_duty = -pyunits.convert_value(
                duty[0], from_units=duty[1], to_units=s1_units)
            s2_duty = pyunits.convert_value(duty[0],
                                            from_units=duty[1],
                                            to_units=s2_units)

        cold_side.heat.fix(s2_duty)
        for i in hot_side.heat:
            hot_side.heat[i].value = s1_duty

        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(self, tee=slc.tee)
        init_log.info_high("Initialization Step 2 {}.".format(
            idaeslog.condition(res)))
        cold_side.heat.unfix()
        self.heat_transfer_equation.activate()
        # ---------------------------------------------------------------------
        # Solve unit
        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(self, tee=slc.tee)
        init_log.info_high("Initialization Step 3 {}.".format(
            idaeslog.condition(res)))
        # ---------------------------------------------------------------------
        # Release Inlet state
        hot_side.release_state(flags1, outlvl=outlvl)
        cold_side.release_state(flags2, outlvl=outlvl)

        init_log.info("Initialization Completed, {}".format(
            idaeslog.condition(res)))
        # if costing block exists, activate and initialize
        if hasattr(self, "costing"):
            self.costing.activate()
            costing.initialize(self.costing)
예제 #15
0
    def initialize(
        self,
        state_args={},
        outlvl=idaeslog.NOTSET,
        solver="ipopt",
        optarg={
            "tol": 1e-6,
            "max_iter": 30
        },
        calculate_cf=True,
    ):
        """
        Initialize the outlet 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 : sets output level of initialization routine
            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 = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        # 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
        for t in self.flowsheet().config.time:
            if self.outlet.pressure[t].fixed:
                self.ratioP[t] = value(self.outlet.pressure[t] /
                                       self.inlet.pressure[t])
                self.deltaP[t] = value(self.outlet.pressure[t] -
                                       self.inlet.pressure[t])

        # Deactivate special constraints
        self.stodola_equation.deactivate()
        self.efficiency_correlation.deactivate()
        self.efficiency_isentropic.fix()
        self.deltaP.unfix()
        self.ratioP.unfix()
        self.inlet.fix()
        self.outlet.unfix()

        super().initialize(outlvl=outlvl, solver=solver, optarg=optarg)

        for t in self.flowsheet().config.time:
            mw = self.control_volume.properties_in[t].mw
            Tin = self.control_volume.properties_in[t].temperature
            Pin = self.control_volume.properties_in[t].pressure
            Pr = self.ratioP[t]
            if not calculate_cf:
                cf = self.flow_coeff
                self.inlet.flow_mol[t].fix(
                    value(cf * Pin * sqrt(1 - Pr**2) / mw / sqrt(Tin)))

        super().initialize(outlvl=outlvl, solver=solver, optarg=optarg)
        self.control_volume.properties_out[:].pressure.fix()

        # Free eff_isen and activate sepcial constarints
        self.efficiency_isentropic.unfix()
        self.outlet.pressure.fix()
        if calculate_cf:
            self.flow_coeff.unfix()
            self.inlet.flow_mol.unfix()
            self.inlet.flow_mol[0].fix()
            flow = self.control_volume.properties_in[0].flow_mol
            mw = self.control_volume.properties_in[0].mw
            Tin = self.control_volume.properties_in[0].temperature
            Pin = self.control_volume.properties_in[0].pressure
            Pr = self.ratioP[0]
            self.flow_coeff.value = value(flow * mw * sqrt(Tin / (1 - Pr**2)) /
                                          Pin)

        else:
            self.inlet.flow_mol.unfix()

        self.stodola_equation.activate()
        self.efficiency_correlation.activate()
        slvr = SolverFactory(solver)
        slvr.options = optarg
        self.display()
        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = slvr.solve(self, tee=slc.tee)
        init_log.info("Initialization Complete (Outlet Stage): {}".format(
            idaeslog.condition(res)))

        # reload original spec
        if calculate_cf:
            cf = value(self.flow_coeff)
        from_json(self, sd=istate, wts=sp)
        if calculate_cf:
            # cf was probably fixed, so will have to set the value agian here
            # if you ask for it to be calculated.
            self.flow_coeff = cf
예제 #16
0
import pytest

from pyomo.environ import ConcreteModel, SolverFactory, TransformationFactory

from idaes.core import FlowsheetBlock
from idaes.unit_models.power_generation import SteamValve
from idaes.property_models import iapws95
from idaes.core.util.model_statistics import (degrees_of_freedom,
                                              activated_equalities_generator)

prop_available = iapws95.iapws95_available()

# See if ipopt is available and set up solver
if SolverFactory('ipopt').available():
    solver = SolverFactory('ipopt')
    solver.options = {'tol': 1e-6}
else:
    solver = None


@pytest.fixture()
def build_valve_vapor():
    m = ConcreteModel()
    m.fs = FlowsheetBlock(default={"dynamic": False})
    m.fs.properties = iapws95.Iapws95ParameterBlock()
    m.fs.valve = SteamValve(default={"property_package": m.fs.properties})
    return m


@pytest.fixture()
def build_valve_liquid():
예제 #17
0
    def initialize(self,
                   state_args_1=None,
                   state_args_2=None,
                   outlvl=0,
                   solver='ipopt',
                   optarg={'tol': 1e-6},
                   duty=1000):
        """
        Heat exchanger initialization method.

        Args:
            state_args_1 : a dict of arguments to be passed to the property
                initialization for shell (see documentation of the specific
                property package) (default = {}).
            state_args_2 : a dict of arguments to be passed to the property
                initialization for tube (see documentation of the specific
                property package) (default = {}).
            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 which solver to use during
                     initialization (default = 'ipopt')
            duty : an initial guess for the amount of heat transfered
                (default = 10000)

        Returns:
            None

        """
        # Set solver options
        tee = True if outlvl >= 3 else False
        opt = SolverFactory(solver)
        opt.options = optarg
        flags1 = self.shell.initialize(outlvl=outlvl - 1,
                                       optarg=optarg,
                                       solver=solver,
                                       state_args=state_args_1)

        if outlvl > 0:
            _log.info('{} Initialization Step 1a (shell) Complete.'.format(
                self.name))

        flags2 = self.tube.initialize(outlvl=outlvl - 1,
                                      optarg=optarg,
                                      solver=solver,
                                      state_args=state_args_2)

        if outlvl > 0:
            _log.info('{} Initialization Step 1b (tube) Complete.'.format(
                self.name))
        # ---------------------------------------------------------------------
        # Solve unit without heat transfer equation
        self.heat_transfer_equation.deactivate()
        self.tube.heat.fix(duty)
        results = opt.solve(self, tee=tee, symbolic_solver_labels=True)
        if outlvl > 0:
            if results.solver.termination_condition == \
                    TerminationCondition.optimal:
                _log.info('{} Initialization Step 2 Complete.'.format(
                    self.name))
            else:
                _log.warning('{} Initialization Step 2 Failed.'.format(
                    self.name))
        self.tube.heat.unfix()
        self.heat_transfer_equation.activate()
        # ---------------------------------------------------------------------
        # Solve unit
        results = opt.solve(self, tee=tee, symbolic_solver_labels=True)
        if outlvl > 0:
            if results.solver.termination_condition == \
                    TerminationCondition.optimal:
                _log.info('{} Initialization Step 3 Complete.'.format(
                    self.name))
            else:
                _log.warning('{} Initialization Step 3 Failed.'.format(
                    self.name))
        # ---------------------------------------------------------------------
        # Release Inlet state
        self.shell.release_state(flags1, outlvl - 1)
        self.tube.release_state(flags2, outlvl - 1)

        if outlvl > 0:
            _log.info('{} Initialization Complete.'.format(self.name))
예제 #18
0
    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)
예제 #19
0
    def init_isentropic(blk, state_args, outlvl, solver, optarg):
        '''
        Initialisation routine for 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 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
        '''
        # Set solver options
        if outlvl > 3:
            stee = True
        else:
            stee = False

        opt = SolverFactory(solver)
        opt.options = optarg

        # ---------------------------------------------------------------------
        # Initialize Isentropic block
        blk.control_volume.properties_in.initialize(outlvl=outlvl-1,
                                                    optarg=optarg,
                                                    solver=solver,
                                                    state_args=state_args)

        if outlvl > 0:
            logger.info('{} Initialisation Step 1 Complete.'.format(blk.name))

        # ---------------------------------------------------------------------
        # Initialize holdup block
        flags = blk.control_volume.initialize(outlvl=outlvl-1,
                                              optarg=optarg,
                                              solver=solver,
                                              state_args=state_args)

        if outlvl > 0:
            logger.info('{} Initialisation Step 2 Complete.'.format(blk.name))

        # ---------------------------------------------------------------------
        # Solve for isothermal conditions
        if isinstance(
                blk.control_volume.properties_in[
                        blk.flowsheet().config.time[1]].temperature,
                Var):
            for t in blk.flowsheet().config.time:
                blk.control_volume.properties_in[t].temperature.fix()
            blk.isentropic.deactivate()
            results = opt.solve(blk, tee=stee)
            if outlvl > 0:
                if results.solver.termination_condition == \
                        TerminationCondition.optimal:
                    logger.info('{} Initialisation Step 3 Complete.'
                                .format(blk.name))
                else:
                    logger.warning('{} Initialisation Step 3 Failed.'
                                   .format(blk.name))
            for t in blk.flowsheet().config.time:
                blk.control_volume.properties_in[t].temperature.unfix()
                blk.isentropic.activate()
        elif outlvl > 0:
            logger.info('{} Initialisation Step 3 Skipped.'.format(blk.name))

        # ---------------------------------------------------------------------
        # Solve unit
        results = opt.solve(blk, tee=stee)

        if outlvl > 0:
            if results.solver.termination_condition == \
                    TerminationCondition.optimal:
                logger.info('{} Initialisation Step 4 Complete.'
                            .format(blk.name))
            else:
                logger.warning('{} Initialisation Step 4 Failed.'
                               .format(blk.name))

        # ---------------------------------------------------------------------
        # Release Inlet state
        blk.control_volume.release_state(flags, outlvl-1)

        if outlvl > 0:
            logger.info('{} Initialisation Complete.'.format(blk.name))
예제 #20
0
    def initialize(
        self,
        state_args={},
        outlvl=idaeslog.NOTSET,
        solver="ipopt",
        optarg={"tol": 1e-6, "max_iter": 30},
        calculate_cf=False,
    ):
        """
        Initialize the inlet turbine stage model.  This deactivates the
        specialized constraints, then does the isentropic turbine initialization,
        then reactivates the constraints and solves. This initializtion uses a
        flow value guess, so some reasonable flow guess should be sepecified prior
        to initializtion.

        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
            calculate_cf (bool): If True, use the flow and pressure ratio to
                calculate the flow coefficient.
        """
        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
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        # Setup for initializtion step 1
        self.inlet_flow_constraint.deactivate()
        self.efficiency_correlation.deactivate()
        self.eff_nozzle.fix()
        self.blade_reaction.fix()
        self.flow_coeff.fix()
        self.blade_velocity.fix()
        self.inlet.fix()
        self.outlet.unfix()

        for t in self.flowsheet().config.time:
            self.efficiency_isentropic[t] = 0.9
        super().initialize(outlvl=outlvl, solver=solver, optarg=optarg)

        # Free eff_isen and activate sepcial constarints
        self.inlet_flow_constraint.activate()
        self.efficiency_correlation.activate()

        if calculate_cf:
            self.ratioP.fix()
            self.flow_coeff.unfix()

            for t in self.flowsheet().config.time:
                g = self.control_volume.properties_in[t].heat_capacity_ratio
                mw = self.control_volume.properties_in[t].mw
                flow = self.control_volume.properties_in[t].flow_mol
                Tin = self.control_volume.properties_in[t].temperature
                Pin = self.control_volume.properties_in[t].pressure
                Pratio = self.ratioP[t]
                self.flow_coeff[t].value = value(
                    flow * mw * sqrt(
                        Tin/(g/(g - 1) *(Pratio**(2.0/g) - Pratio**((g + 1)/g)))
                    )/Pin
                )

        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
        if calculate_cf:
            cf = {}
            for t in self.flowsheet().config.time:
                cf[t] = value(self.flow_coeff[t])

        from_json(self, sd=istate, wts=sp)
        if calculate_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.flowsheet().config.time:
                self.flow_coeff[t] = cf[t]
예제 #21
0
    def initialize(
        self,
        state_args_1=None,
        state_args_2=None,
        outlvl=idaeslog.NOTSET,
        solver="ipopt",
        optarg={"tol": 1e-6},
        duty=1000,
    ):
        """
        Heat exchanger initialization method.

        Args:
            state_args_1 : a dict of arguments to be passed to the property
                initialization for side_1 (see documentation of the specific
                property package) (default = {}).
            state_args_2 : a dict of arguments to be passed to the property
                initialization for side_2 (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')
            duty : an initial guess for the amount of heat transfered
                (default = 10000)

        Returns:
            None

        """
        # Set solver options
        init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit")

        opt = SolverFactory(solver)
        opt.options = optarg
        flags1 = self.side_1.initialize(outlvl=outlvl,
                                        optarg=optarg,
                                        solver=solver,
                                        state_args=state_args_1)

        init_log.info_high("Initialization Step 1a (side_1) Complete.")

        flags2 = self.side_2.initialize(outlvl=outlvl,
                                        optarg=optarg,
                                        solver=solver,
                                        state_args=state_args_2)

        init_log.info_high("Initialization Step 1b (side_2) Complete.")
        # ---------------------------------------------------------------------
        # Solve unit without heat transfer equation
        self.heat_transfer_equation.deactivate()
        self.side_2.heat.fix(duty)
        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(self, tee=slc.tee)
        init_log.info_high("Initialization Step 2 {}.".format(
            idaeslog.condition(res)))
        self.side_2.heat.unfix()
        self.heat_transfer_equation.activate()
        # ---------------------------------------------------------------------
        # Solve unit
        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(self, tee=slc.tee)
        init_log.info_high("Initialization Step 3 {}.".format(
            idaeslog.condition(res)))
        # ---------------------------------------------------------------------
        # Release Inlet state
        self.side_1.release_state(flags1, outlvl=outlvl)
        self.side_2.release_state(flags2, outlvl=outlvl)

        init_log.info("Initialization Completed, {}".format(
            idaeslog.condition(res)))
예제 #22
0
    def initialize(blk, outlvl=0, optarg={}, solver='ipopt', hold_state=False):
        '''
        Initialisation routine for mixer (default solver ipopt)

        Keyword Arguments:
            outlvl : sets output level of initialisation routine. **Valid
                     values:** **0** - no output (default), **1** - return
                     solver state for each step in routine, **2** - include
                     solver output infomation (tee=True)
            optarg : solver options dictionary object (default={})
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            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.
        '''
        # Set solver options
        if outlvl > 1:
            stee = True
        else:
            stee = False

        opt = SolverFactory(solver)
        opt.options = 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 - 1,
                                          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

        # Calculate initial guesses for mixed stream state
        for t in blk.flowsheet().config.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 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 - 1,
                          optarg=optarg,
                          solver=solver,
                          hold_state=False)

        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().config.time:
                    sys_press = getattr(blk,
                                        blk.create_inlet_list()[0] +
                                        "_state")[t].pressure
                    blk.mixed_state[t].pressure.fix(sys_press.value)

                results = opt.solve(blk, tee=stee)

                blk.pressure_equality_constraints.activate()
                for t in blk.flowsheet().config.time:
                    blk.mixed_state[t].pressure.unfix()

            else:
                results = opt.solve(blk, tee=stee)

            if outlvl > 0:
                if results.solver.termination_condition == \
                        TerminationCondition.optimal:
                    _log.info('{} Initialisation Complete.'.format(blk.name))
                else:
                    _log.warning('{} Initialisation Failed.'.format(blk.name))
        else:
            _log.info('{} Initialisation Complete.'.format(blk.name))

        if hold_state is True:
            return flags
        else:
            blk.release_state(flags, outlvl=outlvl - 1)
Author: Jaffer Ghouse
"""
import pytest
from pyomo.environ import ConcreteModel, SolverFactory, TerminationCondition, \
    SolverStatus, value
from pyomo.util.check_units import assert_units_consistent

from idaes.core import FlowsheetBlock
from idaes.generic_models.properties.activity_coeff_models.BTX_activity_coeff_VLE \
    import BTXParameterBlock
from idaes.core.util.model_statistics import degrees_of_freedom

# See if ipopt is available and set up solver
if SolverFactory('ipopt').available():
    solver = SolverFactory('ipopt')
    solver.options = {'tol': 1e-6, 'mu_init': 1e-8, 'bound_push': 1e-8}
else:
    solver = None
# -----------------------------------------------------------------------------
# Create a flowsheet for test
m = ConcreteModel()
m.fs = FlowsheetBlock(default={"dynamic": False})

# vapor-liquid (ideal) - FTPz
m.fs.properties_ideal_vl_FTPz = BTXParameterBlock(
    default={
        "valid_phase": ('Liq', 'Vap'),
        "activity_coeff_model": "Ideal",
        "state_vars": "FTPz"
    })
m.fs.state_block_ideal_vl_FTPz = m.fs.properties_ideal_vl_FTPz.build_state_block(
예제 #24
0
    def initialize(blk, state_args_PA=None, state_args_SA=None,
                   outlvl=idaeslog.NOTSET, solver='ipopt',
                   optarg={'tol': 1e-6}):
        '''
        Initialization routine.
        1.- initialize state blocks, using an initial guess for inlet
        primary air and secondary air.
        2.- Use PA and SA values to guess flue gas component molar flowrates,
        Temperature, and Pressure. Initialize flue gas state block.
        3.- Then, solve complete model.

        Keyword Arguments:
            state_args_PA : a dict of arguments to be passed to the property
                           package(s) for the primary air state block to
                           provide an initial state for initialization
                           (see documentation of the specific property package)
                           (default = None).
            state_args_SA : a dict of arguments to be passed to the property
                           package(s) for secondary air state block 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

        # ---------------------------------------------------------------------
        # Initialize inlet property blocks
        blk.primary_air.initialize(
            outlvl=outlvl,
            optarg=optarg,
            solver=solver,
            state_args=state_args_PA
        )
        blk.primary_air_moist.initialize(
            outlvl=outlvl,
            optarg=optarg,
            solver=solver,
            state_args=state_args_PA
        )
        blk.secondary_air.initialize(
            outlvl=outlvl,
            optarg=optarg,
            solver=solver,
            state_args=state_args_SA
        )
        init_log.info_high("Initialization Step 1 Complete.")

        state_args = {"flow_mol_comp": {"H2O": (blk.primary_air_inlet.
                                                flow_mol_comp[0, "H2O"].value
                                                + blk.secondary_air_inlet.
                                                flow_mol_comp[0, "H2O"].value),
                                        "CO2": (blk.primary_air_inlet.
                                                flow_mol_comp[0, "CO2"].value
                                                + blk.secondary_air_inlet.
                                                flow_mol_comp[0, "CO2"].value),
                                        "N2": (blk.primary_air_inlet.
                                               flow_mol_comp[0, "N2"].value
                                               + blk.secondary_air_inlet.
                                               flow_mol_comp[0, "N2"].value),
                                        "O2": (blk.primary_air_inlet.
                                               flow_mol_comp[0, "O2"].value
                                               + blk.secondary_air_inlet.
                                               flow_mol_comp[0, "O2"].value),
                                        "SO2": (blk.primary_air_inlet.
                                                flow_mol_comp[0, "SO2"].value
                                                + blk.secondary_air_inlet.
                                                flow_mol_comp[0, "SO2"].value),
                                        "NO": (blk.primary_air_inlet.
                                               flow_mol_comp[0, "NO"].value
                                               + blk.secondary_air_inlet.
                                               flow_mol_comp[0, "NO"].value)},
                      "temperature": 1350.00,
                      "pressure": blk.primary_air_inlet.pressure[0].value}
        # initialize flue gas outlet
        blk.flue_gas.initialize(state_args=state_args,
                                outlvl=outlvl,
                                solver=solver)
        init_log.info_high("Initialization Step 2 Complete.")

        if blk.config.calculate_PA_SA_flows is False:
            # Option 1: given PA and SA component flow rates - fixed inlets
            # fix inlet component molar flow rates
            # unfix ratio_PA2coal, SR, and fluegas_o2_pct_dry
            blk.primary_air_inlet.flow_mol_comp[...].fix()
            blk.secondary_air_inlet.flow_mol_comp[...].fix()
            blk.ratio_PA2coal.unfix()
            blk.SR.unfix()
            blk.fluegas_o2_pct_dry.unfix()
            dof = degrees_of_freedom(blk)

        else:
            # Option 2: SR, ratioPA2_coal to estimate TCA, PA, SA
            # unfix component molar flow rates, but keep T and P fixed.
            blk.primary_air_inlet.flow_mol_comp[:, :].unfix()
            blk.secondary_air_inlet.flow_mol_comp[:, :].unfix()
            dof = degrees_of_freedom(blk)

        if not dof == 0:
            raise ConfigurationError('User needs to check '
                                     'degrees of freedom')

        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))
            )
        init_log.info("Initialization Complete.")
예제 #25
0
    def initialize(blk, outlvl=6, optarg={}, solver="ipopt", hold_state=False):
        """
        Initialization routine for mixer (default solver ipopt)

        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 = 'ipopt')
            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")

        # Set solver options
        opt = SolverFactory(solver)
        opt.options = 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().config.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().config.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().config.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().config.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)
예제 #26
0
    def initialize(
        blk,
        shell_state_args=None,
        tube_state_args=None,
        outlvl=idaeslog.NOTSET,
        solver="ipopt",
        optarg={"tol": 1e-6},
    ):
        """
        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(blk.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(blk.name, outlvl, tag="unit")

        opt = SolverFactory(solver)
        opt.options = optarg

        # ---------------------------------------------------------------------
        # Initialize shell block
        flags_shell = blk.shell.initialize(
            outlvl=outlvl,
            optarg=optarg,
            solver=solver,
            state_args=shell_state_args,
        )

        flags_tube = blk.tube.initialize(
            outlvl=outlvl,
            optarg=optarg,
            solver=solver,
            state_args=tube_state_args,
        )

        init_log.info_high("Initialization Step 1 Complete.")

        # ---------------------------------------------------------------------
        # Solve unit
        # Wall 0D
        if blk.config.has_wall_conduction == WallConductionType.zero_dimensional:
            shell_units = \
                blk.config.shell_side.property_package.get_metadata().get_derived_units
            for t in blk.flowsheet().config.time:
                for z in blk.shell.length_domain:
                    blk.temperature_wall[t, z].fix(
                        value(0.5 *
                              (blk.shell.properties[t, 0].temperature +
                               pyunits.convert(
                                   blk.tube.properties[t, 0].temperature,
                                   to_units=shell_units('temperature')))))

            blk.tube.deactivate()
            blk.tube_heat_transfer_eq.deactivate()
            blk.wall_0D_model.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)))

            blk.tube.activate()
            blk.tube_heat_transfer_eq.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.wall_0D_model.activate()
            blk.temperature_wall.unfix()

            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)))

        blk.shell.release_state(flags_shell)
        blk.tube.release_state(flags_tube)

        init_log.info("Initialization Complete.")
예제 #27
0
        "energy_mixing_type": MixingType.extensive,
        "momentum_mixing_type": MomentumMixingType.none
    })

m.fs.Mixer.feed_1.flow_mass[0].fix(0.5)
m.fs.Mixer.feed_1.mass_frac[0].fix(0.1)
m.fs.Mixer.feed_1.temperature[0].fix(273.15 + 50)
m.fs.Mixer.feed_2.flow_mass[0].fix(0.5)
m.fs.Mixer.feed_2.mass_frac[0].fix(0.035)
m.fs.Mixer.feed_2.temperature[0].fix(273.15 + 25)
# m.fs.Mixer.outlet.temperature[0].fix(273.15 + 40)
# m.fs.Mixer.mixed_state[0].dens_mass
# m.fs.Mixer.mixed_state[0].viscosity
# m.fs.Mixer.mixed_state[0].dens_mass_comp
m.fs.Mixer.mixed_state[0].pressure_osm
# m.fs.Mixer.mixed_state[0].osm_coeff
# m.fs.Mixer.mixed_state[0].enth_mass_liq
m.fs.Mixer.initialize(outlvl=0)
print("Degrees of Freedom =", degrees_of_freedom(m))
assert degrees_of_freedom(m) == 0

solver = SolverFactory('ipopt')
solver.options = {'tol': 1e-6, 'max_iter': 5000}
results = solver.solve(m, tee=False)
assert results.solver.termination_condition == TerminationCondition.optimal
# m.display()
#
m.fs.Mixer.display()
for p in m.fs.Mixer.component_objects(Port, descend_into=True):
    p.display()
# m.fs.Mixer.pprint()
예제 #28
0
from collections import OrderedDict
import random
import time as timemodule
import enum
import pdb

__author__ = "Robert Parker and David Thierry"


# TODO: clean up this file - add license, remove solver_available
# See if ipopt is available and set up solver
solver_available = SolverFactory('ipopt').available()
if solver_available:
    solver = SolverFactory('ipopt')
    solver.options = {'tol': 1e-6,
                      'mu_init': 1e-8,
                      'bound_push': 1e-8,
                      'halt_on_ampl_error': 'yes'}
else:
    solver = None


class CachedVarsContext(object):
    def __init__(self, varlist, nvars, tlist):
        if type(tlist) is not list:
            tlist = [tlist]
        self.n_t = len(tlist)
        self.vars = varlist
        self.nvars = nvars
        self.tlist = tlist
        self.cache = [[None for j in range(self.n_t)] 
                for i in range(self.nvars)]
예제 #29
0
    def initialize(blk, outlvl=0, optarg={}, solver='ipopt', hold_state=False):
        '''
        Initialisation routine for separator (default solver ipopt)

        Keyword Arguments:
            outlvl : sets output level of initialisation routine. **Valid
                     values:** **0** - no output (default), **1** - return
                     solver state for each step in routine, **2** - include
                     solver output infomation (tee=True)
            optarg : solver options dictionary object (default=None)
            solver : str indicating whcih solver to use during
                     initialization (default = 'ipopt')
            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.
        '''
        # Set solver options
        if outlvl > 1:
            stee = True
        else:
            stee = False

        opt = SolverFactory(solver)
        opt.options = optarg

        # Initialize mixed state block
        if blk.config.mixed_state_block is not None:
            mblock = blk.config.mixed_state_block
        else:
            mblock = blk.mixed_state
        flags = mblock.initialize(outlvl=outlvl - 1,
                                  optarg=optarg,
                                  solver=solver,
                                  hold_state=True)

        if blk.config.ideal_separation:
            # If using ideal splitting, initialisation should be complete
            return flags

        # Initialize outlet StateBlocks
        outlet_list = blk.create_outlet_list()

        for o in outlet_list:
            # Get corresponding outlet StateBlock
            o_block = getattr(blk, o + "_state")

            for t in blk.flowsheet().config.time:

                # Calculate values for state variables
                s_vars = o_block[t].define_state_vars()

                for v in s_vars:
                    m_var = getattr(mblock[t], s_vars[v].local_name)

                    if "flow" in v:
                        # If a "flow" variable, is extensive
                        # Apply split fraction
                        try:
                            for k in s_vars[v]:
                                if (k is None or blk.config.split_basis
                                        == SplittingType.totalFlow):
                                    s_vars[v][k].value = value(
                                        m_var[k] * blk.split_fraction[(t, o)])
                                else:
                                    s_vars[v][k].value = value(
                                        m_var[k] *
                                        blk.split_fraction[(t, o) + k])
                        except KeyError:
                            raise KeyError(
                                "{} state variable and split fraction "
                                "indexing sets do not match. The in-built"
                                " initialization routine for Separators "
                                "relies on the split fraction and state "
                                "variable indexing sets matching to "
                                "calculate initial guesses for extensive "
                                "variables. In other cases users will "
                                "need to provide their own initial "
                                "guesses".format(blk.name))
                    else:
                        # Otherwise intensive, equate to mixed stream
                        for k in s_vars[v]:
                            s_vars[v][k].value = m_var[k].value

                # Call initialization routine for outlet StateBlock
                o_block.initialize(outlvl=outlvl - 1,
                                   optarg=optarg,
                                   solver=solver,
                                   hold_state=False)

        if blk.config.mixed_state_block is None:
            results = opt.solve(blk, tee=stee)

            if outlvl > 0:
                if results.solver.termination_condition == \
                        TerminationCondition.optimal:
                    _log.info('{} Initialisation Complete.'.format(blk.name))
                else:
                    _log.warning('{} Initialisation Failed.'.format(blk.name))
        else:
            _log.info('{} Initialisation Complete.'.format(blk.name))

        if hold_state is True:
            return flags
        else:
            blk.release_state(flags, outlvl=outlvl - 1)
예제 #30
0
    def initialize(blk, state_args_feedwater={}, state_args_water_steam={},
                   outlvl=idaeslog.NOTSET, solver='ipopt', optarg={'tol': 1e-6}):
        '''
        Drum 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 = SolverFactory(solver)
        opt.options = optarg

        init_log.info_low("Starting initialization...")
        # fix FeedWater Inlet
        flags_fw = fix_state_vars(blk.mixer.FeedWater_state,
                                  state_args_feedwater)

        # expecting 2 DOF due to pressure driven constraint
        if degrees_of_freedom(blk) != 2:
            raise Exception(degrees_of_freedom(blk))

        blk.flash.initialize(state_args_water_steam=state_args_water_steam,
                             outlvl=outlvl,
                             optarg=optarg,
                             solver=solver)
        init_log.info("Initialization Step 1 Complete.")

        blk.mixer.SaturatedWater.flow_mol[:].fix(blk.flash.liq_outlet.
                                                 flow_mol[0].value)
        blk.mixer.SaturatedWater.pressure[:].fix(blk.flash.liq_outlet.
                                                 pressure[0].value)
        blk.mixer.SaturatedWater.enth_mol[:].fix(blk.flash.liq_outlet.
                                                 enth_mol[0].value)
        blk.mixer.initialize(outlvl=outlvl,
                             optarg=optarg,
                             solver=solver)
        init_log.info("Initialization Step 2 Complete.")

        blk.control_volume.initialize(outlvl=outlvl,
                                      optarg=optarg,
                                      solver=solver,
                                      hold_state=False)
        init_log.info("Initialization Step 3 Complete.")

        # fix flash Inlet
        flags_steam = fix_state_vars(blk.flash.mixed_state,
                                     state_args_water_steam)
        # unfix inlets (connected with arc)
        blk.mixer.SaturatedWater.flow_mol[:].unfix()
        blk.mixer.SaturatedWater.enth_mol[:].unfix()
        blk.mixer.SaturatedWater.pressure[:].unfix()
        blk.mixer.FeedWater.pressure[0].unfix()

        # solve model
        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))
            )
        revert_state_vars(blk.mixer.FeedWater_state, flags_fw)
        revert_state_vars(blk.flash.mixed_state, flags_steam)
        init_log.info("Initialization Complete.")