Пример #1
0
    def getVolume(self, bname, rtime=40, LF=1 / 2, get_unit=False):
        """Get the volume of decanter depends on the volume flowrate of inlet stream.
        The calculation condition is based on residual time (rtime) of decanter and liquid level fraction (LF)
        in the tank.

        :param bname: Block name.
        :param rtime: Residual time of decanter in minute. The default value is 40 min.
        :param LF: Liquid level fraction in the decanter. The default value is 1/2.
        :param get_unit: "True" to get the unit. "False" is a default value.
        :return: float. a calculated value.
        """
        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")
        if type(rtime) != int and type(rtime) != float:
            raise TypeError("rtime must be a Number!!!")
        if type(LF) != int and type(LF) != float:
            raise TypeError("LF must be a Number!!!")

        ## rtime 不能是負數
        if rtime < 0:
            raise ValueError("rtime should not be a negative number!!")
        ## LF 不能是負數
        if LF < 0:
            raise ValueError("LF should not be a negative number!!")

        ## 檢查bname是否為Decanter
        if self.master.BlockType(bname) != 'Decanter':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a Decanter,' +
                'please check the name you type!!')

        ## 找出Decanter進料物流名稱
        dec_fstream = []
        for e in self.aspen.Tree.Elements("Data").Elements("Blocks").Elements(
                bname).Elements("Connections").Elements:
            streamtype = self.aspen.Tree.Elements("Data").Elements(
                "Blocks").Elements(bname).Elements("Connections").Elements(
                    e.Name).Value
            if streamtype == "F(IN)":
                dec_fstream.append(e.Name)

        ## 檢查Decanter所有進料物流都沒有氣體以避免體積計算誤差
        for fstream in dec_fstream:
            if self.master.Stream.getVaporFrac(fstream) != 0:
                raise UDE.AspenPlus_BlockError(
                    f"The feed stream of decanter '{fstream}' " +
                    "contains gas. The volume-calculation may " +
                    " have a great deviation !!!")

        if get_unit:  # 取得單位
            return "cum"
        else:  # 取得數值
            v = 0
            for fstream in dec_fstream:
                v += self.master.Stream.getVolumeFlow(fstream,
                                                      unit_change_to=20)
            return v * rtime / LF
Пример #2
0
    def getDiameter(self, bname, get_unit=False, unit_change_to=None):
        """Get the Column's diameter. Before using this function. you have to turn on the
                'Sizaing' or 'Rating' function in AspenPlus.
                bname: Block name.
                get_unit: "True" to get the unit. "False" is a default value.
                unit_change_to: unit index in AspenFile for the changing unit. If you don't want to change
                the unit, unit_change_to should be 'None'(Default value is this).
        """
        ## 此功能只能取sizing的結果不是取rating的結果
        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")
        if unit_change_to is not None and type(unit_change_to) != int:
            raise TypeError("unit_change_to must be a 'Integer' or 'None'!!!")

        ## 檢查bname是否為RadFrac
        if self.master.BlockType(bname) != 'RadFrac':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a RadFrac,' +
                'please check the name you type!!')

        ## 檢查是否有開啟Sizing功能
        if self.aspen.Tree.FindNode("\Data\Blocks" + "\\" + bname +
                                    "\Subobjects\Column Internals"
                                    ).AttributeValue(38) == 0:  # 用是否有子代判斷
            raise UDE.AspenPlus_SizingError(
                "'Sizing' function dosen't open!!!")

        ## 確認是否為 Apwn36.0(V10)
        if self.aspen.Name.find('36.0') != -1:  # 第十版的直徑路徑
            path = "\Data\Blocks" + "\\" + bname + "\Subobjects\Column Internals\INT-1\Subobjects\Sections\CS-1\Input\CA_DIAM\INT-1\CS-1"
        else:  # V8.8以前的的直徑路徑
            path = "\Data\Blocks" + "\\" + bname + "\Subobjects\Tray Sizing\\1\Output\DIAM4\\1"

        ## 看看有沒有要改單位
        if unit_change_to is None:  # 沒有要改單位
            ## 是要取得數值還是單位
            if get_unit:  # 取得單位
                return self.master.UnitFind(self.aspen.Tree.FindNode(path),
                                            table=True)
            else:  # 取得數值
                return self.aspen.Tree.FindNode(path).Value
        elif unit_change_to is not None:  # 要改單位的話
            if get_unit:  # 取得單位
                pq = self.aspen.Tree.FindNode(path).AttributeValue(2)
                return self.master.Unit(item=[pq, unit_change_to], table=True)
            else:  # 取得數值
                return self.master.UnitChange(self.aspen.Tree.FindNode(path),
                                              unit_change_to)
Пример #3
0
    def getHeight(self, bname, get_unit=False):
        """Get the Column's height. it is a  calculated value.
                Total number of trays(NT) with 2-ft spacing plus 20% extra length.
                It means  H[ft] = 2.4×(NT-1) which is equal to H[m] = 0.73152×(NT-1).
                Reference: Luyben, W. L.
                                , Comparison of extractive distillation and pressure-swing distillation for acetone/chloroform separation
                                . Comput Chem Eng 2013, 50, 1-7.
        """
        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")

        ## 檢查bname是否為RadFrac
        if self.master.BlockType(bname) != 'RadFrac':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a RadFrac,' +
                'please check the name you type!!')

        ## 取得指定蒸餾塔的總板數
        n = self.getNStage(bname)

        ## 是要取得數值還是單位
        if get_unit:  # 取得單位
            return "meter"
        else:  # 取得數值
            return 0.73152 * (n - 1)
Пример #4
0
    def getHeight(self, bname, AR=0.5, get_unit=False):
        """Get the height of decanter depends on the diameter of decanter.

        :param bname: Block name.
        :param AR: aspect ratio which is the ratio of diameter to height. The default value is 0.5.
        :param get_unit: "True" to get the unit. "False" is a default value.
        :return: float. a calculated value.
        """
        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")
        if type(AR) != int and type(AR) != float:
            raise TypeError("AR must be a Number!!!")

        ## AR 不能是負數
        if AR < 0:
            raise ValueError("AR should not be a negative number!!")

        ## 檢查bname是否為Decanter
        if self.master.BlockType(bname) != 'Decanter':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a Decanter,' +
                'please check the name you type!!')

        d = self.getDiameter(bname)

        if get_unit:  # 取得單位
            return "meter"
        else:  # 取得數值
            return d / AR
Пример #5
0
    def Connections(self, bname, table=False):
        """Show the connected stream of the desired block.

        :param bname: block name in 'Str-Type'.
        :param table: a boolen value. default is False for print the result on the screen. If table=True,
        return result in  list type.
        """
        ## 先檢查輸入的資料型態是否正確
        if type(bname) is not str:
            raise TypeError("bname must be a 'String'!!!")
        if type(table) is not bool:
            raise TypeError("table must be a 'Boolen' value!!!")

        ## 將輸入的字串全部大寫,因為Aspen的單元名稱都是大寫
        bname = bname.upper()

        ## 檢查輸入的單元名稱是否在檔案當中,如無回傳錯誤
        if bname not in self.BlocksList():
            raise UDE.AspenPlus_BlockTypeError("Cannot Find " + bname
                                               + " in the AspenFile. "
                                               + "Please Check the name you type!!")

        ## 在屏幕上輸出指定單元所連接的物流名稱
        if not table:
            print("{0[0]:13s}{0[1]:13s}".format(["Stream_Name","Streams_Type"]))
            print("==========================")
            for e in self.aspen.Tree.Elements("Data").Elements("Blocks").Elements(bname).Elements("Connections").Elements:
                streamtype = self.aspen.Tree.Elements("Data").Elements("Blocks").Elements(bname).Elements("Connections").Elements(e.Name).Value
                print("{0:13s}{1:13s}".format(e.Name,streamtype))
        ## 將結果以列表輸出
        elif table:
            a_list = []
            for e in self.aspen.Tree.Elements("Data").Elements("Blocks").Elements(bname).Elements("Connections").Elements:
                a_list.append(e.Name)
            return a_list
Пример #6
0
    def getNF(self, bname, *, sname=None):
        """Get the number of  feed stage for the specified RadFrac block and feed stream or
        Get the all feed stream for the specified RadFrac block in a list-type.

        :param bname: Block name.
        :param sname: Feed stream name.
        :return: if sname is None, return a feed stream list for specified block.
        if sname is specified, return the NF of specified block and feed stream.
        """
        ## 檢查bname是否為RadFrac
        if self.master.BlockType(bname) != 'RadFrac':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a RadFrac,' +
                'please check the name you type!!')

        ## 對sname進行檢查並處理
        if sname is None:
            pass
        elif type(sname) is str:
            ## 把sname轉換成大寫,因為Aspen裡面的名稱都大寫
            sname = sname.upper()

            ## 檢查輸入的物流名稱是否在檔案當中,如無回傳錯誤
            if sname not in self.master.StreamsList():
                raise UDE.AspenPlus_StreamTypeError(
                    "Cannot Find " + sname + " in the AspenFile. " +
                    "Please Check the name you type!!")
        else:
            raise TypeError("sname must be a 'String'!!!")

        ## 指定塔的進料物流 物件
        obj = self.aspen.Tree.Elements("Data").Elements("Blocks").Elements(
            bname).Elements("Input").Elements("FEED_STAGE")

        ## 列出指定塔的進料物流有哪些
        nlist = []
        for e in obj.Elements:
            nlist.append(e.Name)

        if sname is None:  # 沒輸入sname就回傳進料物流列表
            return nlist
        elif sname is not None:  # 有輸入sname且為特定塔的進料物流的話,輸出進料板
            if sname not in nlist:
                raise UDE.AspenPlus_StreamTypeError(
                    sname + " is not a feed stream" + " for " + bname + ". " +
                    "Please Check the name you type!!")
            return obj.Elements(sname).Value
Пример #7
0
    def setNF(self, bname, sname, set_value):
        """Set the number of  feed stage for the specified RadFrac block and feed stream.

        :param bname: Block name.
        :param sname: Feed stream name.
        :param set_value: feed stage you want to specify.
        :return: None
        """
        ## 檢查輸入的資料型態正確與否
        if type(set_value) != int:
            raise TypeError("set_value must be a 'Integer'!!!")
        ## 檢查set_value 是否為正整數
        if set_value < 0:
            raise ValueError("set_value must be a 'Positive' number!!!")

        ## 對sname進行檢查並處理
        if sname is None:
            pass
        elif type(sname) is str:
            ## 把sname轉換成大寫,因為Aspen裡面的名稱都大寫
            sname = sname.upper()

            ## 檢查輸入的物流名稱是否在檔案當中,如無回傳錯誤
            if sname not in self.master.StreamsList():
                raise UDE.AspenPlus_StreamTypeError(
                    "Cannot Find " + sname + " in the AspenFile. " +
                    "Please Check the name you type!!")
        else:
            raise TypeError("sname must be a 'String'!!!")

        ## 指定塔的進料物流 物件
        obj = self.aspen.Tree.Elements("Data").Elements("Blocks").Elements(
            bname).Elements("Input").Elements("FEED_STAGE")

        ## 列出指定塔的進料物流有哪些
        nlist = []
        for e in obj.Elements:
            nlist.append(e.Name)

        # 有輸入sname且為特定塔的進料物流的話,輸出進料板
        if sname not in nlist:
            raise UDE.AspenPlus_StreamTypeError(
                sname + " is not a feed stream" + " for " + bname + ". " +
                "Please Check the name you type!!")

        obj.Elements(sname).Value = set_value  # 輸入超過總板數會報有用的錯誤
Пример #8
0
        def wrapper(self, *args, **kwargs):
            # Inner function for this decorator
            def name_up_and_arg_change(name, args):
                """將name變大寫並且回傳回args"""

                name = name.upper()
                args = list(args)   # 要把args第一個參數(name)變成大寫
                args[0] = name      # 但是args是tuple不能修改,所以要先
                args = tuple(args)  # 變成list,修改過後再轉回tuple
                return name, args

            if Type == 'stream':
                sname = args[0]

                ## 先檢查輸入的資料型態正確與否
                if type(sname) != str:
                    raise TypeError("sname must be a 'String'!!!")

                # 把sname變大寫並回傳回args
                sname, args = name_up_and_arg_change(sname, args)

                ## 檢查輸入的物流名稱是否在檔案當中,如無回傳錯誤
                if sname not in self.master.StreamsList():
                    raise UDE.AspenPlus_StreamTypeError("Cannot Find " + sname
                                                        + " in the AspenFile. "
                                                        + "Please Check the name you type!!")
            elif Type == 'block':
                bname = args[0]

                ## 先檢查輸入的資料型態正確與否
                if type(bname) != str:
                    raise TypeError("bname must be a 'String'!!!")

                # 把bname變大寫並回傳回args
                bname, args = name_up_and_arg_change(bname, args)

                ## 檢查輸入的物流名稱是否在檔案當中,如無回傳錯誤
                if bname not in self.master.BlocksList():
                    raise UDE.AspenPlus_BlockTypeError("Cannot Find " + bname
                                                        + " in the AspenFile. "
                                                        + "Please Check the name you type!!")
            else:
                raise TypeError('No Match Value for Type, '
                                + 'Please Check the value you type !!!')

            return func(self, *args, **kwargs)
Пример #9
0
    def getCondenserArea(self, bname, get_unit=False, Uc=0.852):
        """Get the condenser area of specified column.
                If it is not condenser, the return value is 'None'.
                bname: Block name.
                get_unit: "True" to get the unit. "False" is a default value.
                Ur: Heat transfer coefficient of reboiler [kW/K-sqrm]. The default value is 0.852.
        """
        # TODO: 不知道需不需要考慮LMTD,需要的話在增加判斷式

        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")
        if type(Uc) != int and type(Uc) != float:
            raise TypeError("unit must be a 'Number'!!!")

        ## Ur不應該小於等於0,那...那是什麼設備??
        if Uc <= 0:
            raise ValueError("Uc shouldn't be equal to  or smaller than 0. " +
                             "Please Check the Value you Type!!!")

        ## 檢查bname是否為RadFrac
        if self.master.BlockType(bname) != 'RadFrac':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a RadFrac,' +
                'please check the name you type!!')

        ## 檢查指定蒸餾塔有沒有condenser
        path = "\Data\Blocks" + "\\" + bname + "\Input\CONDENSER"
        if self.aspen.Tree.FindNode(path).Value == "NONE":
            return

        bottom_name = None
        ## 找出冷凝器的出口物流名稱後取得其溫度
        for e in self.aspen.Tree.Elements("Data").Elements("Blocks").Elements(
                bname).Elements("Connections").Elements:
            streamtype = self.aspen.Tree.Elements("Data").Elements(
                "Blocks").Elements(bname).Elements("Connections").Elements(
                    e.Name).Value
            if streamtype == "LD(OUT)":
                bottom_name = e.Name
        Temp = self.master.Stream.getTemperature(bottom_name, unit_change_to=1)

        utility = self.master.Cost.WaterType(bname)
        DeltaT = Temp - self.master.Cost.Water[utility]['Temperature']['Value']
        Qr = -self.getQC(bname)

        ## 溫差不該小於等於0,那應該就不是condenser了
        if DeltaT <= 0:
            raise ValueError(
                "DeltaT shouldn't be equal to  or smaller than 0. " +
                "Please connect to the programmer!!!")

        ## 是要取得數值還是單位
        if get_unit:  # 取得單位
            return "sqrm"
        else:  # 取得數值
            return Qr / Uc / DeltaT
Пример #10
0
    def getNStage(self, bname):
        """Get the number of stage for the specified RadFrac block.
                bname: Block name.
        """
        ## 檢查bname是否為RadFrac
        if self.master.BlockType(bname) != 'RadFrac':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a RadFrac,' +
                'please check the name you type!!')

        path = "\Data\Blocks" + "\\" + bname + r"\Input\NSTAGE"
        return self.aspen.Tree.FindNode(path).Value
Пример #11
0
    def getMassFlow(self,
                    sname,
                    component='',
                    get_unit=False,
                    unit_change_to=None) -> float:
        """Get the  Massflow of specified stream for Total or component .
                sname: Stream name
                component: If it is no given. the fct will give the total massflow.
                                If you give the component name, the fct will give the component flowrate.
                get_unit: "True" to get the unit. "False" is a default value.
                unit_change_to: unit index in AspenFile for the changing unit. If you don't want to change
                the unit, unit_change_to should be 'None'(Default value is this).
        """
        ## 先檢查輸入的資料型態正確與否
        if type(component) != str:
            raise TypeError("component must be a 'String'!!!")
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")
        if unit_change_to is not None and type(unit_change_to) != int:
            raise TypeError("unit_change_to must be a 'Integer' or 'None'!!!")

        ## 把component轉換成大寫,因為Aspen裡面的名稱都大寫
        component = component.upper()

        ## 辨認是要輸出總流量還是化合物流量
        if component != '':
            ## 辨認化合物有沒有在檔案當中,如無回傳錯誤
            if component not in self.master.ComponentsList():
                raise UDE.AspenPlus_ComponentTypeError(
                    "Cannot Find " + component + " in the AspenFile. " +
                    "Please Check the name you type!!")

            path = '\Data\Streams' + '\\' + sname + '\Output\MASSFLOW3' + '\\' + component
        elif component == '':
            path = "\Data\Streams" + "\\" + sname + "\Output\STR_MAIN\MASSFLMX\MIXED"

        ## 看看有沒有要改單位
        if unit_change_to is None:  # 沒有要改單位
            ## 是要取得數值還是單位
            if get_unit:  # 取得單位
                return self.master.UnitFind(self.aspen.Tree.FindNode(path),
                                            table=True)
            else:  # 取得數值
                return self.aspen.Tree.FindNode(path).Value
        elif unit_change_to is not None:  # 要改單位的話
            if get_unit:  # 取得單位
                pq = self.aspen.Tree.FindNode(path).AttributeValue(2)
                return self.master.Unit(item=[pq, unit_change_to], table=True)
            else:  # 取得數值
                return self.master.UnitChange(self.aspen.Tree.FindNode(path),
                                              unit_change_to)
Пример #12
0
    def getRefluxRatio(self, bname) -> float:
        """Get the reflux ratio of specified column.

        :param bname: Block name.
        :return: float.
        """
        ## 檢查bname是否為RadFrac
        if self.master.BlockType(bname) != 'RadFrac':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a RadFrac,' +
                'please check the name you type!!')

        path = "\Data\Blocks" + "\\" + bname + r"\Output\MOLE_RR"
        return self.aspen.Tree.FindNode(path).Value
Пример #13
0
    def __init__(self, path, version=None):
        import os
        import win32com.client as win32
        if version is not None:
            self.aspen = win32.Dispatch(f'Apwn.Document.{version}.0')
        else:
            self.aspen = win32.Dispatch('Apwn.Document')

        ## 檢查檔案是否存在
        if not os.path.isfile(path):
            raise UDE.FileNotExist(
                "File cannot find at designated dictionary!!" +
                " Please check the dic you  input.")

        self.aspen.InitFromArchive(path)
Пример #14
0
    def FileStatus(self):
        """Determine the status of AspenFile. if the file is

        :return: if file is available, return 'Available'. if file has waring, return 'Warning'.
        if file has error, return 'Error'.
        """
        status_code = self.aspen.Tree.Elements("Data").Elements("Results Summary").Elements("Run-Status").AttributeValue(12)
        if (status_code & 1) == 1:      # 位元運算,1 為 results available
            return 'Available'
        elif (status_code & 4) == 4:    # 位元運算,4 為 results with warning
            return 'Warning'
        elif (status_code & 32) == 32:  # 位元運算,32 為 results with error
            return 'Error'
        else:
            raise UDE.AspenPlus_FileStatusError("File Status recognized error. " +
                                                "Please Connect Programmer !!!")
Пример #15
0
    def getQC(self, bname, get_unit=False, unit_change_to=None):
        """Get the condenser duty of specified column.
                If it is not condenser, the return value is 'None'.
                bname: Block name.
                get_unit: "True" to get the unit. "False" is a default value.
                unit_change_to: unit index in AspenFile for the changing unit. If you don't want to change
                the unit, unit_change_to should be 'None'(Default value is this).
        """
        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")
        if unit_change_to is not None and type(unit_change_to) != int:
            raise TypeError("unit_change_to must be a 'Integer' or 'None'!!!")

        ## 檢查bname是否為RadFrac
        if self.master.BlockType(bname) != 'RadFrac':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a RadFrac,' +
                'please check the name you type!!')

        ## 檢查指定蒸餾塔有沒有condenser
        path = "\Data\Blocks" + "\\" + bname + "\Input\CONDENSER"
        if self.aspen.Tree.FindNode(path).Value == "NONE":
            return

        path = "\Data\Blocks" + "\\" + bname + "\Output\COND_DUTY"

        ## 看看有沒有要改單位
        if unit_change_to is None:  # 沒有要改單位
            ## 是要取得數值還是單位
            if get_unit:  # 取得單位
                return self.master.UnitFind(self.aspen.Tree.FindNode(path),
                                            table=True)
            else:  # 取得數值
                return self.aspen.Tree.FindNode(path).Value
        elif unit_change_to is not None:  # 要改單位的話
            if get_unit:  # 取得單位
                pq = self.aspen.Tree.FindNode(path).AttributeValue(2)
                return self.master.Unit(item=[pq, unit_change_to], table=True)
            else:  # 取得數值
                return self.master.UnitChange(self.aspen.Tree.FindNode(path),
                                              unit_change_to)
Пример #16
0
    def setNStage(self, bname, set_value):
        """Get the number of stage for the specified RadFrac block.
                bname: Block name.
        """
        ## 檢查輸入的資料型態正確與否
        if type(set_value) != int:
            raise TypeError("set_value must be a 'Integer'!!!")
        ## 檢查set_value 是否為正整數
        if set_value < 0:
            raise ValueError("set_value must be a 'Positive' number!!!")

        ## 檢查bname是否為RadFrac
        if self.master.BlockType(bname) != 'RadFrac':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a RadFrac,' +
                'please check the name you type!!')

        path = "\Data\Blocks" + "\\" + bname + r"\Input\NSTAGE"
        self.aspen.Tree.FindNode(path).Value = set_value
        return
Пример #17
0
    def BlockType(self, bname) -> str:
        """Get the block type of the bname in string.

        :param bname: Block name in AspenFile.
        :return: Sting. a string in block type for specified block.
        """
        ## 先檢查輸入的資料型態是否正確
        if type(bname) is not str:
            raise TypeError("bname must be a 'String'!!!")

        ## 將輸入的字串全部大寫,因為Aspen的單元名稱都是大寫
        bname = bname.upper()

        ## 檢查輸入的單元名稱是否在檔案當中,如無回傳錯誤
        if bname not in self.BlocksList():
            raise UDE.AspenPlus_BlockTypeError("Cannot Find " + bname
                                                + " in the AspenFile. "
                                                + "Please Check the name you type!!")

        return self.aspen.Tree.Elements("Data").Elements("Blocks").Elements(bname).AttributeValue(6)
Пример #18
0
    def getMoleFrac(self, sname, component) -> float:
        """Get the  Mole Fraction of specified component of specified stream.
                sname: Stream name
                component: component you want to know.
        """
        ## 先檢查輸入的資料型態正確與否
        if type(component) != str:
            raise TypeError("component must be a 'String'!!!")

        ## 把component轉換成大寫,因為Aspen裡面的名稱都大寫
        component = component.upper()

        ## 檢查輸入的化合物名稱是否在檔案當中,如無回傳錯誤
        if component not in self.master.ComponentsList():
            raise UDE.AspenPlus_ComponentTypeError(
                "Cannot Find " + component + ' in the AspenFile. ' +
                "Please Check the name you type!!")

        # mole fraction這邊用算的
        mt = self.getMoleFlow(sname)
        m = self.getMoleFlow(sname, component=component)
        return m / mt
Пример #19
0
    def getDiameter(self, bname, get_unit=False):
        """Get the diameter of decanter depends on the volume of decanter.

        :param bname: Block name.
        :param get_unit: "True" to get the unit. "False" is a default value.
        :return: float. a calculated value.
        """
        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")

        ## 檢查bname是否為Decanter
        if self.master.BlockType(bname) != 'Decanter':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a Decanter,' +
                'please check the name you type!!')

        v = self.getVolume(bname)

        if get_unit:  # 取得單位
            return "meter"
        else:  # 取得數值
            return (2 * v / 3.1415926)**(1 / 3)
Пример #20
0
    def getQ(self, bname, get_unit=False, unit_change_to=None):
        """Get the duty of Heat exchanger.
                bname: block name.
                get_unit: "True" to get the unit. "False" is a default value.
                unit_change_to: unit index in AspenFile for the changing unit. If you don't want to change
                the unit, unit_change_to should be 'None'(Default value is this).
        """
        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")
        if unit_change_to is not None and type(unit_change_to) != int:
            raise TypeError("unit_change_to must be a 'Integer' or 'None'!!!")

        ## 檢查bname是否為Heater
        if self.master.BlockType(bname) != 'Heater':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a Heater,' +
                'please check the name you type!!')

        path = "\Data\Blocks" + "\\" + bname + "\Output\QNET"

        ## 看看有沒有要改單位
        if unit_change_to is None:  # 沒有要改單位
            ## 是要取得數值還是單位
            if get_unit:  # 取得單位
                return self.master.UnitFind(self.aspen.Tree.FindNode(path),
                                            table=True)
            else:  # 取得數值
                return self.aspen.Tree.FindNode(path).Value
        elif unit_change_to is not None:  # 要改單位的話
            if get_unit:  # 取得單位
                pq = self.aspen.Tree.FindNode(path).AttributeValue(2)
                return self.master.Unit(item=[pq, unit_change_to], table=True)
            else:  # 取得數值
                return self.master.UnitChange(self.aspen.Tree.FindNode(path),
                                              unit_change_to)
Пример #21
0
    def getArea(self, bname, exchanger_type, get_unit=False, U=None):
        """Get the theoretical area of  'Heater'. The available exchanger types are 'Condenser', 'Heater', 'Reboiler', and
        'Cooler'.

        :param bname: block name.
        :param exchanger_type: the type for calculating cost of heater. the available value are 'CONDENSER',
        'HEATER', 'REBOILER', ane 'COOLER'.
        :param get_unit: "True" to get the unit. "False" is a default value.
        :param U: Heat transfer coefficient of exchanger [kW/K-sqrm]. The value will be change to
        match the different condition. You can  specified the value you want.
        :return:
        """
        # 把heater當mixer用還沒有解決辦法

        from math import log
        ## 先檢查輸入的資料型態正確與否
        if type(get_unit) != bool:
            raise TypeError("unit must be a 'Boolean'!!!")

        ## 檢查bname是否為Heater
        if self.master.BlockType(bname) != 'Heater':
            raise UDE.AspenPlus_BlockTypeError(
                bname + ' is not a Heater,' +
                'please check the name you type!!')
        ## 檢查Uc的輸入型態是否正確,如為數字檢查數字範圍是否正確
        if (U is not None) and type(U) != int and type(U) != float:
            raise TypeError("U must be a 'Number'!!!")
        elif U is not None:
            ## Ur不應該小於等於0,那...那是什麼設備??
            if U <= 0:
                raise ValueError(
                    "U shouldn't be equal to  or smaller than 0. " +
                    "Please Check the Value you Type!!! ")

        duty = abs(self.getQ(bname, unit_change_to=14))  # kW

        ## 檢查 exchanger_type是否為三個選項之一,並執行個別的算法,都不是則回報錯誤
        if exchanger_type == 'CONDENSER':
            ## Uc 沒有定義設定值,就用condenser的預設值
            if U is None:
                U = 0.852

            ## 找出Heater出口的物流名稱,並取得其凱式溫度與適合公共流體
            outlet_name = None
            for e in self.aspen.Tree.Elements("Data").Elements(
                    "Blocks").Elements(bname).Elements("Connections").Elements:
                streamtype = self.aspen.Tree.Elements("Data").Elements(
                    "Blocks").Elements(bname).Elements("Connections").Elements(
                        e.Name).Value
                if streamtype == "P(OUT)" and self.master.BlockType(
                        bname) == 'Heater':
                    outlet_name = e.Name
            if outlet_name is None:
                raise UDE.AspenPlus_BlockTypeError(
                    "Please Connect the Developer!!!")
            To = self.master.Stream.getTemperature(outlet_name,
                                                   unit_change_to=1)
            utility = self.master.Cost.WaterType(bname)

            ## 取得 deltaT
            deltaT = To - self.master.Cost.Water[utility]['Temperature'][
                'Value']

        elif (exchanger_type == 'HEATER') or (exchanger_type == 'REBOILER'):
            ## Uc 沒有定義設定值,就用condenser的預設值
            if U is None:
                U = 0.568

            ## 找出Heater出口的物流名稱,並取得其凱式溫度與適合公共流體
            outlet_name = None
            for e in self.aspen.Tree.Elements("Data").Elements(
                    "Blocks").Elements(bname).Elements("Connections").Elements:
                streamtype = self.aspen.Tree.Elements("Data").Elements(
                    "Blocks").Elements(bname).Elements("Connections").Elements(
                        e.Name).Value
                if streamtype == "P(OUT)" and self.master.BlockType(
                        bname) == 'Heater':
                    outlet_name = e.Name
            if outlet_name is None:
                raise UDE.AspenPlus_BlockTypeError(
                    "Please Connect the Developer!!!")
            To = self.master.Stream.getTemperature(outlet_name,
                                                   unit_change_to=1)
            utility = self.master.Cost.SteamType(bname)

            ## 取得 deltaT
            deltaT = self.master.Cost.Steam[utility]['Temperature'][
                'Value'] - To

        elif exchanger_type == 'COOLER':
            if U is None:
                U = 0.852

            ## 找出Heater出口的物流名稱,並取得其凱式溫度與適合公共流體
            outlet_name = None
            inlet_name = None
            for e in self.aspen.Tree.Elements("Data").Elements(
                    "Blocks").Elements(bname).Elements("Connections").Elements:
                streamtype = self.aspen.Tree.Elements("Data").Elements(
                    "Blocks").Elements(bname).Elements("Connections").Elements(
                        e.Name).Value
                if streamtype == "P(OUT)" and self.master.BlockType(
                        bname) == 'Heater':
                    outlet_name = e.Name
                elif streamtype == "F(IN)" and self.master.BlockType(
                        bname) == 'Heater':
                    inlet_name = e.Name
            if (outlet_name is None) or (inlet_name is None):
                raise UDE.AspenPlus_BlockTypeError(
                    "Please Connect the Developer!!!")
            To = self.master.Stream.getTemperature(outlet_name,
                                                   unit_change_to=1)
            Ti = self.master.Stream.getTemperature(inlet_name,
                                                   unit_change_to=1)
            utility = self.master.Cost.WaterType(bname)
            Tu = self.master.Cost.Water[utility]['Temperature']['Value']

            ## 取得 deltaT
            deltaT = (Ti - To) / log((Ti - Tu) / (To - Tu))

        else:
            raise TypeError('exchanger_type must be a String and ' +
                            "one of them that 'CONDENSER', 'HEATER', " +
                            "'REBOILER', and 'COOLER' !!!")

        A = duty / U / deltaT
        if get_unit:
            return 'sqrm'
        else:
            return A