Пример #1
0
 def test02b(self):
     """Test with suffixes"""
     model = self.setup_model02b()
     x = model.x
     model.dual[model.g] = 1
     model.ipopt_zL_out[x["1"]] = 0
     model.ipopt_zL_out[x["2"]] = 0
     model.ipopt_zU_out[x["1"]] = 0
     model.ipopt_zU_out[x["2"]] = 0
     to_json(model, fname=self.fname, human_read=True)
     model.x["1"].value = 10
     model.x["2"].value = 10
     model.dual[model.g] = 10
     model.ipopt_zL_out[x["1"]] = 10
     model.ipopt_zL_out[x["2"]] = 10
     model.ipopt_zU_out[x["1"]] = 10
     model.ipopt_zU_out[x["2"]] = 10
     model.p["a"] = 10
     model.p["b"] = 10
     from_json(model, fname=self.fname)
     assert value(model.x["1"]) == pytest.approx(1.5)
     assert value(model.x["2"]) == pytest.approx(2.5)
     assert value(model.p["a"]) == pytest.approx(1)
     assert value(model.p["b"]) == pytest.approx(2)
     assert model.dual[model.g] == pytest.approx(1)
     assert model.ipopt_zL_out[x["1"]] == pytest.approx(0)
     assert model.ipopt_zL_out[x["2"]] == pytest.approx(0)
     assert model.ipopt_zU_out[x["1"]] == pytest.approx(0)
     assert model.ipopt_zU_out[x["2"]] == pytest.approx(0)
Пример #2
0
    def test08(self):
        """Try just saving suffixes"""
        model = self.setup_model02()
        model.x[1].fix(1)

        model.dual[model.g] = 1
        model.ipopt_zL_out[model.x[1]] = 1
        model.ipopt_zL_out[model.x[2]] = 1
        model.ipopt_zU_out[model.x[1]] = 1
        model.ipopt_zU_out[model.x[2]] = 1

        to_json(model, fname=self.fname, wts=StoreSpec.suffix())

        model.dual[model.g] = 10
        model.ipopt_zL_out[model.x[1]] = 10
        model.ipopt_zL_out[model.x[2]] = 10
        model.ipopt_zU_out[model.x[1]] = 10
        model.ipopt_zU_out[model.x[2]] = 10
        model.g.deactivate()
        model.x[1].setlb(-4)
        model.x[1].unfix()
        model.x[2].fix(6)

        from_json(model, fname=self.fname, wts=StoreSpec.suffix())
        assert value(model.x[1]) == 1
        assert value(model.x[2]) == 6
        assert not model.x[1].fixed
        assert model.x[2].fixed
        assert not model.g.active
        assert model.dual[model.g] == 1
        assert model.ipopt_zL_out[model.x[1]] == 1
        assert model.ipopt_zL_out[model.x[2]] == 1
        assert model.ipopt_zU_out[model.x[1]] == 1
        assert model.ipopt_zU_out[model.x[2]] == 1
        assert model.x[1].lb == -4
Пример #3
0
    def test10(self):
        """Try just saving suffixes, and suffix filter only on write"""
        model = self.setup_model02()

        model.dual[model.g] = 1
        model.ipopt_zL_out[model.x[1]] = 1
        model.ipopt_zL_out[model.x[2]] = 1
        model.ipopt_zU_out[model.x[1]] = 1
        model.ipopt_zU_out[model.x[2]] = 1

        wts = StoreSpec.suffix(suffix_filter=("dual", ))
        to_json(model, fname=self.fname, wts=wts)

        model.dual[model.g] = 10
        model.ipopt_zL_out[model.x[1]] = 10
        model.ipopt_zL_out[model.x[2]] = 10
        model.ipopt_zU_out[model.x[1]] = 10
        model.ipopt_zU_out[model.x[2]] = 10

        from_json(model, fname=self.fname, wts=StoreSpec.suffix())
        assert model.dual[model.g] == 1
        assert model.ipopt_zL_out[model.x[1]] == 10
        assert model.ipopt_zL_out[model.x[2]] == 10
        assert model.ipopt_zU_out[model.x[1]] == 10
        assert model.ipopt_zU_out[model.x[2]] == 10
Пример #4
0
    def test08(self):
        """Try just saving suffixes"""
        model = self.setup_model02()
        model.x[1].fix(1)

        model.dual[model.g] = 1
        model.ipopt_zL_out[model.x[1]] = 1
        model.ipopt_zL_out[model.x[2]] = 1
        model.ipopt_zU_out[model.x[1]] = 1
        model.ipopt_zU_out[model.x[2]] = 1

        to_json(model, fname=self.fname, wts=StoreSpec.suffix())

        model.dual[model.g] = 10
        model.ipopt_zL_out[model.x[1]] = 10
        model.ipopt_zL_out[model.x[2]] = 10
        model.ipopt_zU_out[model.x[1]] = 10
        model.ipopt_zU_out[model.x[2]] = 10
        model.g.deactivate()
        model.x[1].setlb(-4)
        model.x[1].unfix()
        model.x[2].fix(6)

        from_json(model, fname=self.fname, wts=StoreSpec.suffix())
        assert (abs(value(model.x[1]) - 1) < 1e-5)
        assert (abs(value(model.x[2]) - 6) < 1e-5)
        assert (not model.x[1].fixed)
        assert (model.x[2].fixed)
        assert (not model.g.active)
        assert (abs(model.dual[model.g] - 1) < 1e-5)
        assert (abs(model.ipopt_zL_out[model.x[1]] - 1) < 1e-5)
        assert (abs(model.ipopt_zL_out[model.x[2]] - 1) < 1e-5)
        assert (abs(model.ipopt_zU_out[model.x[1]] - 1) < 1e-5)
        assert (abs(model.ipopt_zU_out[model.x[2]] - 1) < 1e-5)
        assert (abs(model.x[1].lb + 4) < 1e-5)
Пример #5
0
    def test11(self):
        """Try just saving suffixes, and suffix filter only on read"""
        model = self.setup_model02()

        model.dual[model.g] = 1
        model.ipopt_zL_out[model.x[1]] = 1
        model.ipopt_zL_out[model.x[2]] = 1
        model.ipopt_zU_out[model.x[1]] = 1
        model.ipopt_zU_out[model.x[2]] = 1

        to_json(model, fname=self.fname, wts=StoreSpec.suffix())

        model.dual[model.g] = 10
        model.ipopt_zL_out[model.x[1]] = 10
        model.ipopt_zL_out[model.x[2]] = 10
        model.ipopt_zU_out[model.x[1]] = 10
        model.ipopt_zU_out[model.x[2]] = 10

        wts = StoreSpec.suffix(suffix_filter=("dual", ))
        from_json(model, fname=self.fname, wts=wts)
        assert (abs(model.dual[model.g] - 1) < 1e-5)
        assert (abs(model.ipopt_zL_out[model.x[1]] - 10) < 1e-5)
        assert (abs(model.ipopt_zL_out[model.x[2]] - 10) < 1e-5)
        assert (abs(model.ipopt_zU_out[model.x[1]] - 10) < 1e-5)
        assert (abs(model.ipopt_zU_out[model.x[2]] - 10) < 1e-5)
Пример #6
0
 def test02(self):
     """Test with suffixes"""
     model = self.setup_model02()
     x = model.x
     model.dual[model.g] = 1
     model.ipopt_zL_out[x[1]] = 0
     model.ipopt_zL_out[x[2]] = 0
     model.ipopt_zU_out[x[1]] = 0
     model.ipopt_zU_out[x[2]] = 0
     to_json(model, fname=self.fname, human_read=True)
     model.x[1].value = 10
     model.x[2].value = 10
     model.dual[model.g] = 10
     model.ipopt_zL_out[x[1]] = 10
     model.ipopt_zL_out[x[2]] = 10
     model.ipopt_zU_out[x[1]] = 10
     model.ipopt_zU_out[x[2]] = 10
     from_json(model, fname=self.fname)
     assert (abs(value(x[1]) - 1.5) < 1e-5)
     assert (abs(value(x[2]) - 2.5) < 1e-5)
     assert (abs(model.dual[model.g] - 1) < 1e-5)
     assert (abs(model.ipopt_zL_out[x[1]]) < 1e-5)
     assert (abs(model.ipopt_zL_out[x[2]]) < 1e-5)
     assert (abs(model.ipopt_zU_out[x[1]]) < 1e-5)
     assert (abs(model.ipopt_zU_out[x[2]]) < 1e-5)
Пример #7
0
    def initialize(
        self,
        outlvl=idaeslog.NOTSET,
        solver=None,
        optarg={},
    ):
        """
        For simplicity this initialization requires you to set values for the
        efficency, inlet, and one of pressure ratio, pressure change or outlet
        pressure.
        """
        init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit")

        # Create solver
        slvr = get_solver(solver, optarg)

        # Store original specification so initialization doesn't change the model
        # This will only resore the values of varaibles that were originally fixed
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)
        # Check for alternate pressure specs
        for t in self.flowsheet().config.time:
            if self.outlet.pressure[t].fixed:
                self.ratioP[t] = pyo.value(
                    self.outlet.pressure[t]/self.inlet.pressure[t])
            elif self.control_volume.deltaP[t].fixed:
                self.ratioP[t] = pyo.value(
                    (self.control_volume.deltaP[t] + self.inlet.pressure[t])/
                    self.inlet.pressure[t]
                )
        # Fix the variables we base the initializtion on and free the rest.
        # This requires good values to be provided for pressure, efficency,
        # and inlet conditions, but it is simple and reliable.
        self.inlet.fix()
        self.outlet.unfix()
        self.ratioP.fix()
        self.deltaP.unfix()
        self.efficiency_isentropic.fix()
        for t in self.flowsheet().config.time:
            self.outlet.pressure[t] = pyo.value(
                self.inlet.pressure[t]*self.ratioP[t])
            self.deltaP[t] = pyo.value(
                self.outlet.pressure[t] - self.inlet.pressure[t])

            self.outlet.enth_mol[t] = pyo.value(self.h_o[t])
            self.control_volume.work[t] = pyo.value(
                self.inlet.flow_mol[t]*self.inlet.enth_mol[t] -
                self.outlet.flow_mol[t]*self.outlet.enth_mol[t]
            )
            self.outlet.flow_mol[t] = pyo.value(self.inlet.flow_mol[t])
        # Solve the model (should be already solved from above)
        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = slvr.solve(self, tee=slc.tee)
        from_json(self, sd=istate, wts=sp)
Пример #8
0
    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)
Пример #9
0
    def test01_name(self):
        """
        Simple test of load save json with differnt model names
        """
        model = self.setup_model01("m1")
        model2 = self.setup_model01("m2")

        model2.b[1].a = 0.11
        model2.b[1].b = 0.11
        to_json(model, fname=self.fname, human_read=True)
        from_json(model2, fname=self.fname)
        #make sure they are right
        assert pytest.approx(20) == value(model2.b[1].b)
        assert pytest.approx(2) == value(model2.b[1].a)
Пример #10
0
 def test12(self):
     """Test some odd set compoenents"""
     model = self.setup_model03()
     self.assertIs(model.r.ctype, Var)
     model.r[1, 3] = 1
     model.r[2, 3] = 3
     d = to_json(model, return_dict=True, human_read=True)
     model.r[1, 3] = 6
     model.r[2, 3] = 8
     assert value(model.b[1].x[3, 3]) == 6
     assert value(model.b[2].x[3, 3]) == 8
     from_json(model, sd=d)
     assert value(model.b[1].x[3, 3]) == 1
     assert value(model.b[2].x[3, 3]) == 3
Пример #11
0
    def initialize(self, **kwargs):
        # store original state
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        # check for fixed outlet flows and use them to calculate fixed split
        # fractions
        for t in self.flowsheet().config.time:
            for o in self.outlet_list:
                elec_obj = getattr(self, o + "_elec")
                if elec_obj[t].fixed:
                    self.split_fraction[o, t].fix(
                        value(elec_obj[t] / self.electricity[t]))

        # fix or unfix split fractions so n - 1 are fixed
        for t in self.flowsheet().config.time:
            # see how many split fractions are fixed
            n = sum(1 for o in self.outlet_list
                    if self.split_fraction[o, t].fixed)
            # if number of outlets - 1 we're good
            if n == len(self.outlet_list) - 1:
                continue
            # if too many are fixed, unfix the first, generally assume that is
            # the main flow, and is the calculated split fraction
            elif n == len(self.outlet_list):
                self.split_fraction[self.outlet_list[0], t].unfix()
            # if not enough fixed, start fixing from the back until there are
            # are enough
            else:
                for o in reversed(self.outlet_list):
                    if not self.split_fraction[o, t].fixed:
                        self.split_fraction[o, t].fix()
                        n += 1
                    if n == len(self.outlet_list) - 1:
                        break

        self.electricity.fix()
        for o in self.outlet_list:
            getattr(self, o + "_port").unfix()
        assert degrees_of_freedom(self) == 0

        solver = "ipopt"
        if "solver" in kwargs:
            solver = kwargs["solver"]

        opt = SolverFactory(solver)
        opt.solve(self)

        from_json(self, sd=istate, wts=sp)
Пример #12
0
 def test05b(self):
     """Try just saving values with fixed filter"""
     model = self.setup_model02()
     model.x[1].fix(1)
     wts = StoreSpec.value(only_not_fixed=True)
     to_json(model, fname=self.fname, human_read=True, wts=wts)
     model.g.deactivate()
     model.x[1].setlb(-4)
     model.x[1].value = 3
     model.x[2].value = 6
     from_json(model, fname=self.fname, wts=wts)
     assert value(model.x[1]) == 3  # should not load since is fixed
     assert model.x[1].lb == -4
     assert value(model.x[2]) == pytest.approx(2.5)
     assert not model.g.active
Пример #13
0
 def test05(self):
     """Try just saving values"""
     model = self.setup_model02()
     model.x[1].value = 1
     wts = StoreSpec.value()
     to_json(model, fname=self.fname, human_read=True, wts=wts)
     model.g.deactivate()
     model.x[1].setlb(-4)
     model.x[1].value = 3
     model.x[2].value = 6
     from_json(model, fname=self.fname, wts=wts)
     assert value(model.x[1]) == 1
     assert model.x[1].lb == -4
     assert value(model.x[2]) == pytest.approx(2.5)
     assert not model.g.active
Пример #14
0
 def test06(self):
     """Try just saving bounds"""
     model = self.setup_model02()
     model.x[1].value = 1
     wts = StoreSpec.bound()
     to_json(model, fname=self.fname, human_read=True, wts=wts)
     model.g.deactivate()
     model.x[1].setlb(-4)
     model.x[1].value = 3
     model.x[2].value = 6
     from_json(model, fname=self.fname, wts=wts)
     assert value(model.x[1]) == 3
     assert model.x[1].lb == -10
     assert value(model.x[2]) == 6
     assert not model.g.active
Пример #15
0
 def test06(self):
     """Try just saving bounds"""
     model = self.setup_model02()
     model.x[1].value = 1
     wts = StoreSpec.bound()
     to_json(model, fname=self.fname, human_read=True, wts=wts)
     model.g.deactivate()
     model.x[1].setlb(-4)
     model.x[1].value = 3
     model.x[2].value = 6
     from_json(model, fname=self.fname, wts=wts)
     assert (abs(value(model.x[1]) - 3) < 1e-5)
     assert (abs(model.x[1].lb + 10) < 1e-5)
     assert (abs(value(model.x[2]) - 6) < 1e-5)
     assert (not model.g.active)
    def initialize(self, *args, **kwargs):
        """
        Use the regular heat exchanger initialization, with the extraction rate
        constraint deactivated; then it activates the constraint and calculates
        a steam inlet flow rate.
        """
        solver = kwargs.get("solver", None)
        optarg = kwargs.get("oparg", {})
        outlvl = kwargs.get("outlvl", idaeslog.NOTSET)
        init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit")

        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        self.area.fix()
        self.overall_heat_transfer_coefficient.fix()
        self.inlet_1.fix()
        self.inlet_2.fix()
        self.outlet_1.unfix()
        self.outlet_2.unfix()

        # Do condenser initialization
        self.inlet_1.flow_mol.unfix()
        # fix volume and pressure drop since
        # the condenser initialization dosen't require them
        self.side_1.volume.fix(10)
        self.side_1.deltaP.fix(0)
        self.shell_volume_eqn.deactivate()
        self.pressure_change_total_eqn.deactivate()
        super().initialize()
        self.side_1.volume.unfix()
        self.side_1.deltaP.unfix()
        self.shell_volume_eqn.activate()
        self.pressure_change_total_eqn.activate()

        # Create solver
        opt = get_solver(solver, optarg)

        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(self, tee=slc.tee)
        init_log.info(
            "Initialization Complete (w/ steam flow calc): {}".format(
                idaeslog.condition(res)
            )
        )

        from_json(self, sd=istate, wts=sp)
Пример #17
0
 def test07(self):
     """Try just saving just if fixed"""
     model = self.setup_model02()
     model.x[1].fix(1)
     wts = StoreSpec.isfixed()
     to_json(model, fname=self.fname, human_read=True, wts=wts)
     model.g.deactivate()
     model.x[1].setlb(-4)
     model.x[1].unfix()
     model.x[2].fix(6)
     from_json(model, fname=self.fname, wts=wts)
     assert (abs(value(model.x[1]) - 1) < 1e-5)
     assert (abs(model.x[1].lb + 4) < 1e-5)
     assert (abs(value(model.x[2]) - 6) < 1e-5)
     assert (model.x[1].fixed)
     assert (not model.x[2].fixed)
     assert (not model.g.active)
Пример #18
0
 def test07(self):
     """Try just saving just if fixed"""
     model = self.setup_model02()
     model.x[1].fix(1)
     wts = StoreSpec.isfixed()
     to_json(model, fname=self.fname, human_read=True, wts=wts)
     model.g.deactivate()
     model.x[1].setlb(-4)
     model.x[1].unfix()
     model.x[2].fix(6)
     from_json(model, fname=self.fname, wts=wts)
     assert value(model.x[1]) == 1
     assert model.x[1].lb == -4
     assert value(model.x[2]) == 6
     assert model.x[1].fixed
     assert not model.x[2].fixed
     assert not model.g.active
Пример #19
0
 def test04(self):
     """
     Like test03, but this StoreSpec also saves/loads active/deactivated
     component attribute and parameter values.
     """
     model = self.setup_model02()
     x = model.x
     x[1].fix(1)
     wts = StoreSpec.value_isfixed_isactive(only_fixed=True)
     to_json(model, fname=self.fname, human_read=True, wts=wts)
     x[1].unfix()
     x[1].value = 2
     x[2].value = 10
     model.g.deactivate()
     from_json(model, fname=self.fname, wts=wts)
     assert (x[1].fixed)
     assert (abs(value(x[1]) - 1) < 1e-5)
     assert (abs(value(x[2]) - 10) < 1e-5)
     assert (model.g.active)
Пример #20
0
    def initialize(
        self,
        outlvl=idaeslog.NOTSET,
        solver=None,
        optarg=None,
    ):
        """
        For simplicity this initialization requires you to set values for the
        efficency, inlet, and one of pressure ratio, pressure change or outlet
        pressure.
        """
        init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit")

        # Create solver
        opt = get_solver(solver, optarg)

        # Store original specification so initialization doesn't change the model
        # This will only resore the values of varaibles that were originally fixed
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)
        # Check for alternate pressure specs
        for t in self.flowsheet().time:
            if self.outlet.pressure[t].fixed:
                self.deltaP[t].fix(
                    pyo.value(self.outlet.pressure[t] -
                              self.inlet.pressure[t]))
                self.outlet.pressure[t].unfix()
            elif self.deltaP[t].fixed:
                # No outlet pressure specified guess a small pressure drop
                self.outlet.pressure[t] = pyo.value(self.inlet.pressure[t] +
                                                    self.deltaP[t])

        self.inlet.fix()
        self.outlet.unfix()
        for t, v in self.deltaP.items():
            if v.fixed:
                self.inlet.flow_mol[t].unfix()

        with idaeslog.solver_log(solve_log, idaeslog.DEBUG) as slc:
            res = opt.solve(self, tee=slc.tee)

        from_json(self, sd=istate, wts=sp)
Пример #21
0
 def test03(self):
     """
     This tests a StoreSpec object meant for initialization.  It reloads
     the saved state of variable values and whether they are fixed or
     unfixed but it only loads values for variables that were originally
     fixed. It's use would be in doing initialization that changes which
     variables are fixed and does whatever, but when the original state is
     reloaded only the original values for fixed variables are reloaded.  You
     basically end up with the same problem, just a different initial guess.
     """
     model = self.setup_model02()
     x = model.x
     x[1].fix(1)
     wts = StoreSpec.value_isfixed(only_fixed=True)
     to_json(model, fname=self.fname, human_read=True, wts=wts)
     x[1].unfix()
     x[1].value = 2
     x[2].value = 10
     from_json(model, fname=self.fname, wts=wts)
     assert (x[1].fixed)
     assert (abs(value(x[1]) - 1) < 1e-5)
     assert (abs(value(x[2]) - 10) < 1e-5)
Пример #22
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.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)
Пример #23
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)
Пример #24
0
 def test01(self):
     """
     Simple test of load save json
     """
     model = self.setup_model01()
     a = model.b[1].a
     b = model.b[1].b
     to_json(model, fname=self.fname, human_read=True)
     # change variable values
     a.value = 0.11
     b.value = 0.11
     a.unfix()
     model.b[1].deactivate()
     b.setlb(2)
     b.setub(4)
     # reload values
     from_json(model, fname=self.fname)
     #make sure they are right
     assert (a.fixed)
     assert (model.b[1].active)
     assert (abs(value(b) - 20) < 1e-4)
     assert (abs(value(a) - 2) < 1e-4)
     assert (abs(b.lb - -100) < 1e-4)
     assert (abs(b.ub - 100) < 1e-4)
Пример #25
0
 def test01b(self):
     """
     Simple test of load save json
     """
     model = self.setup_model01b()
     a = model.b["1"].a
     b = model.b["1"].b
     to_json(model, fname=self.fname, human_read=True)
     # change variable values
     a.value = 0.11
     b.value = 0.11
     a.unfix()
     model.b["1"].deactivate()
     b.setlb(2)
     b.setub(4)
     # reload values
     from_json(model, fname=self.fname)
     #make sure they are right
     assert a.fixed
     assert model.b["1"].active
     assert value(b) == 20
     assert value(a) == 2
     assert b.lb == -100
     assert b.ub == 100
Пример #26
0
    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)
Пример #27
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)
Пример #28
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)
Пример #29
0
    def initialize(self,
                   outlvl=idaeslog.NOTSET,
                   solver=None,
                   flow_iterate=2,
                   optarg=None,
                   copy_disconneted_flow=True,
                   copy_disconneted_pressure=True,
                   calculate_outlet_cf=False,
                   calculate_inlet_cf=False):
        """
        Initialize

        Args:
            outlvl: logging level default is NOTSET, which inherits from the
                parent logger
            solver: the NL solver
            flow_iterate: If not calculating flow coefficients, this is the
                number of times to update the flow and repeat initialization
                (1 to 5 where 1 does not update the flow guess)
            optarg: solver arguments, default is None
            copy_disconneted_flow: Copy the flow through the disconnected stages
                default is True
            copy_disconneted_pressure: Copy the pressure through the disconnected
                stages default is True
            calculate_outlet_cf: Use the flow initial flow guess to calculate
                the outlet stage flow coefficient, default is False,
            calculate_inlet_cf: Use the inlet stage ratioP to calculate the flow
                coefficent for the inlet stage default is False

        Returns:
            None
        """
        # Setup loggers
        init_log = idaeslog.getInitLogger(self.name, outlvl, tag="unit")
        solve_log = idaeslog.getSolveLogger(self.name, outlvl, tag="unit")
        # Store initial model specs, restored at the end of initializtion, so
        # the problem is not altered.  This can restore fixed/free vars,
        # active/inactive constraints, and fixed variable values.
        sp = StoreSpec.value_isfixed_isactive(only_fixed=True)
        istate = to_json(self, return_dict=True, wts=sp)

        # Assume the flow into the turbine is a reasonable guess for
        # initializtion
        flow_guess = self.inlet_split.inlet.flow_mol[0].value

        for it_count in range(flow_iterate):
            self.inlet_split.initialize(outlvl=outlvl,
                                        solver=solver,
                                        optarg=optarg)

            # Initialize valves
            for i in self.inlet_stage_idx:
                u = self.throttle_valve[i]
                copy_port(u.inlet,
                          getattr(self.inlet_split, "outlet_{}".format(i)))
                u.initialize(outlvl=outlvl, solver=solver, optarg=optarg)

            # Initialize turbine
            for i in self.inlet_stage_idx:
                u = self.inlet_stage[i]
                copy_port(u.inlet, self.throttle_valve[i].outlet)
                u.initialize(outlvl=outlvl,
                             solver=solver,
                             optarg=optarg,
                             calculate_cf=calculate_inlet_cf)

            # Initialize Mixer
            self.inlet_mix.use_minimum_inlet_pressure_constraint()
            for i in self.inlet_stage_idx:
                copy_port(
                    getattr(self.inlet_mix, "inlet_{}".format(i)),
                    self.inlet_stage[i].outlet,
                )
                getattr(self.inlet_mix, "inlet_{}".format(i)).fix()
            self.inlet_mix.initialize(outlvl=outlvl,
                                      solver=solver,
                                      optarg=optarg)
            for i in self.inlet_stage_idx:
                getattr(self.inlet_mix, "inlet_{}".format(i)).unfix()
            self.inlet_mix.use_equal_pressure_constraint()

            prev_port = self.inlet_mix.outlet
            prev_port = self._init_section(
                self.hp_stages,
                self.hp_split,
                self.config.hp_disconnect,
                prev_port,
                outlvl,
                solver,
                optarg,
                copy_disconneted_flow=copy_disconneted_flow,
                copy_disconneted_pressure=copy_disconneted_pressure,
            )
            if len(self.hp_stages) in self.config.hp_disconnect:
                self.config.ip_disconnect.append(0)
            prev_port = self._init_section(
                self.ip_stages,
                self.ip_split,
                self.config.ip_disconnect,
                prev_port,
                outlvl,
                solver,
                optarg,
                copy_disconneted_flow=copy_disconneted_flow,
                copy_disconneted_pressure=copy_disconneted_pressure,
            )
            if len(self.ip_stages) in self.config.ip_disconnect:
                self.config.lp_disconnect.append(0)
            prev_port = self._init_section(
                self.lp_stages,
                self.lp_split,
                self.config.lp_disconnect,
                prev_port,
                outlvl,
                solver,
                optarg,
                copy_disconneted_flow=copy_disconneted_flow,
                copy_disconneted_pressure=copy_disconneted_pressure,
            )

            copy_port(self.outlet_stage.inlet, prev_port)
            self.outlet_stage.initialize(outlvl=outlvl,
                                         solver=solver,
                                         optarg=optarg,
                                         calculate_cf=calculate_outlet_cf)
            if calculate_outlet_cf:
                break
            if it_count < flow_iterate - 1:
                for t in self.inlet_split.inlet.flow_mol:
                    self.inlet_split.inlet.flow_mol[t].value = \
                        self.outlet_stage.inlet.flow_mol[t].value

                    for s in self.hp_split.values():
                        for i, o in enumerate(s.outlet_list):
                            if i == 0:
                                continue
                            o = getattr(s, o)
                            self.inlet_split.inlet.flow_mol[t].value += \
                                o.flow_mol[t].value
                    for s in self.ip_split.values():
                        for i, o in enumerate(s.outlet_list):
                            if i == 0:
                                continue
                            o = getattr(s, o)
                            self.inlet_split.inlet.flow_mol[t].value += \
                                o.flow_mol[t].value
                    for s in self.lp_split.values():
                        for i, o in enumerate(s.outlet_list):
                            if i == 0:
                                continue
                            o = getattr(s, o)
                            self.inlet_split.inlet.flow_mol[t].value += \
                                o.flow_mol[t].value

        if calculate_inlet_cf:
            # cf was probably fixed, so will have to set the value agian here
            # if you ask for it to be calculated.
            icf = {}
            for i in self.inlet_stage:
                for t in self.inlet_stage[i].flow_coeff:
                    icf[i, t] = pyo.value(self.inlet_stage[i].flow_coeff[t])
        if calculate_outlet_cf:
            ocf = pyo.value(self.outlet_stage.flow_coeff)

        from_json(self, sd=istate, wts=sp)

        if calculate_inlet_cf:
            # cf was probably fixed, so will have to set the value agian here
            # if you ask for it to be calculated.
            for t in self.inlet_stage[i].flow_coeff:
                for i in self.inlet_stage:
                    self.inlet_stage[i].flow_coeff[t] = icf[i, t]
        if calculate_outlet_cf:
            self.outlet_stage.flow_coeff = ocf
Пример #30
0
    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)