Unit クラスの継承(2)

バイオ・リファイナリー(再生可能資源であるバイオマスを原料にバイオ燃料や樹脂などを製造するプラントや技術)のシミュレーションソフト"BioSTEAM"で、プロセス・パラメータを動的に変更する方法について説明しています。 オリジナルのページはInheriting from Unitです。 ソースコードは以下の実行環境で確認しています。
  • Visual Studio Code バージョン: 1.104.2
  • 拡張機能:Jupyter バージョン 2025.8.0
  • Python 3.12.10
  • biosteam 2.52.13
  • graphviz-14.0.2
<< 目次 >>

Unit クラスの継承

共通の設定

サブクラスの例

シミュレーション テスト

Graphvizで作図

装置のコスト計算

付随設備

参考文献

<< 本文 >>

Unit クラスの継承

装置のコスト計算

各機器の購入価格は、FOB(本船渡し価格)を、基準となるサイズからの指数関数的計算方法をデコレータ構文[1]を使って計算します。各機器の基準となる代表寸法S(例えば物理的な大きさ、流量、消費電力など)の時のコストを基準に、推定したい装置のサイズをSnewとすると、Sからの比率をn乗し、さらに化学工学プラント費用指数(Chemical Engineering Plant Cost Index、CEPCI)を使った年次のコスト上昇を加味して推定します。推定したい装置の購入コストNew costは計算式で表すと以下のようになります。

\begin{align*} \textit{New cost} & = N \cdot \textit{cost} \left( \frac{CE_{new}}{CE} \right) \left( \frac{S_{new}}{N \cdot S} \right) ^n \\ \end{align*} ここで、
  • \( N \) : 装置の個数で、 \begin{align*} N & = ceil \left( \frac{S_{new}}{ub} \right) \\ \end{align*}
  • \( \textit{cost} \) : 基準となるサイズSでの本船渡しの購入価格
  • \( CE_{new} \) : 推定したい年次のCEPCI
  • \( CE \) : 基準となる年次のCEPCI
  • \( S_{new} \) : 推定したい装置のサイズ
  • \( S \) : 基準となるサイズ
  • \( \textit{cost} \) : 基準となるサイズSでの本船渡し価格
  • \( n \) : コスト計算での指数
  • \(ceil \) : 天井関数(切り上げ関数)
  • \(ub \) : 1セットでのサイズの上限
また、消費電力Electricity rateは、 \begin{align*} \textit{Electricity rate} & = kW \left( \frac{S_{new}}{S} \right) \\ \end{align*}
  • \( kW \) : 基準となるサイズSでの消費電力
他に考慮される設定として
  • \( \textit{life time} \) : 設備更新されるまでの操業年数

文献[2]にあるように、最終的な本船渡し(FOB)購入価格は次のよう設計の係数、圧力の係数、材料の係数で補正されます。 \[ C_P = C_{Pb}F_DF_PF_M \] そして、設備設置コストは次のように表されます。 \[ C_{BM} = C_{Pb}(F_{BM} + F_DF_PF_M -1) \] ここで、

  • \( C_{Pb} \) : ベースライン購入価格(baseline purchase cost)
  • \( C_P \) : 購入価格(purchase cost)
  • \( C_{BM} \) : 設備設置コスト(installed_cost)
  • ※ \( C_{BM} \)はinstalled equipment costのこと[3]です。
  • \( F_{BM} \) : 設置に関する係数(Bare module factor)
  • \( F_D \) : 購入費用に対する設計の係数(Design factor)
  • \( F_P \) : 購入費用に対する圧力の係数(Pressure factor)
  • \( F_M \) : 購入費用に対する材料の係数(Material factor)

例(1)

供給されたサトウキビを裁断するシュレッダーを指数関数的にコスト算出する[4]ユニットオブジェクトのサブクラス(Shredderクラス)として作成します。以下のような設定を使用します。

  • 化学工学プラント費用指数(Chemical Engineering Plant Cost Index、CEPCI) : 567.3
  • サイズ : 流量 500,000 kg/hr
  • 購入価格 : $2,500,000
  • 電力消費 : 3,000 kW
  • 指数 : 0.6
  • \( F_{BM} \) : 設置に関する係数(Bare module factor) : 1.39
  • 装置寿命 : 30 年
このとき、原料の供給量を1,000,000 kg/hrにした時に、2018年の化学工学プラント費用指数(Chemical Engineering Plant Cost Index、CEPCI)603.1での購入価格はいくらか。
  1. 新しい Shredder クラスを作成
  2. import biosteam as bst
    from biosteam.units.decorators import cost
    
    # 使用する成分の化学的特性を設定
    chemicals = bst.Chemicals(['Water', 'Ethanol'])
    SugarCane = bst.Chemical.blank('SugarCane', phase_ref='s')
    SugarCane.default()
    chemicals.append(SugarCane)
    bst.settings.set_thermo(chemicals)
    
    # 2018年相当
    bst.CE = 603.1
    
    # 基準は kg/hr 単位の流量とします
    @cost('Flow rate', units='kg/hr', cost=2.5e6, CE=567.3,
          n=0.6, S=500e3, kW=3000, BM=1.39, lifetime=30)
    class Shredder(bst.Unit): pass
    # `_run` メソッドのない Units サブクラスは流入ストリーム1、出力ストリーム1で、
    # 流出ストリームは流入ストリームがそのまま流出する、となります
    
    ### Shreadder クラスを試します ###
    
    # 画面表示の流量単位を kg/hr にします
    bst.Stream.display_units.flow = 'kg/hr'
    
    feed = bst.Stream(SugarCane=1e6, units='kg/hr')
    shredder = Shredder(ins=feed)
    shredder.simulate()
    
    shredder.show()
    shredder.results()
    Shredder: U1
    ins...
    [0] s1  
        phase: 'l', T: 298.15 K, P: 101325 Pa
        flow (kg/hr): SugarCane  1e+06
    outs...
    [0] s2  
        phase: 'l', T: 298.15 K, P: 101325 Pa
        flow (kg/hr): SugarCane  1e+06
    Shredder Units U1
    Electricity Power kW 6e+03
    Cost USD/hr 469
    Design Flow rate kg/hr 1e+06
    Purchase cost Shredder USD 4.03e+06
    Total purchase cost USD 4.03e+06
    Utility cost USD 469

    基準となる設定は、costデコレータで設定します。costデコレータは定義が cost (basis=None, ID=None, CE, cost=None, S=1.0, lb=None, ub=None, kW=None, BM=1.0, units=None, f=None, annual=None, condition=None, magnituden=None ) で、最初のbasisのところに基準となる物理量が何かを設定します。ここでは'流量'としておきます。後は先程の設定を記述しています。また、今回のクラスは実際の動作は特に何もしない設定ですので、中身はありません。流出ストリームは流入ストリームがそのまま流出する設定です。

    なお、各コスト計算値の関係を確認しておくと、New costにあたる購入価格は、先程の式に当てはめてみると

    2.5e6 * (603.1 / 567.3) * pow((1e+06 / 500e3),0.6)
    4028418.2146237493
    で一致しています。0.6乗になっているので、サイズが2倍になっても価格は2倍にはなりません。また、設置費用は
    shredder.installed_cost
    で確認出来て、
    5599501.318327011
    これは\( C_{BM} = C_{Pb}(F_{BM} + F_DF_PF_M -1) \)より、
    4028418.2146237493 * 1.39
    5599501.318327011
    と一致しています。\(F_DF_PF_M \)の部分ですが、ここでは設定していないので、全て{}です。
    shredder.F_D
    {}
    shredder.F_P
    {}
    shredder.F_M
    {}
    これらは、{}の時には1になるようになっていて、\(F_DF_PF_M = 1 \)になります。従って、ここでは\( C_{BM} = C_{Pb} F_{BM} \) となります。これらの関係から、\( C_{Pb} \)はBioSTEAM上の名前では、baseline_purchase_cost、\( C_{BM} \)installed_cost、さらに本船渡し(FOB)購入価格がpurchase_costに該当すると思われます。
  3. Cost Items
  4. コストの設定は、cost_itemsという名前の辞書型配列に格納されています。

    Shredder.cost_items
    {'Shredder': <CostItem: Flow rate (kg/hr)>}
  5. Cost Itemsの内容
  6. さらに内容を確認すると、
    Shredder.cost_items['Shredder']
    CostItem: Flow rate (kg/hr)
     S     5e+05
     CE    567
     cost  2.5e+06
     n     0.6
     kW    3e+03
    costデコレータで設定した内容を確認できます。
  7. 装置寿命と設置コストの係数
  8. 装置寿命と設置コストの係数はそれぞれ別に記録されています。
    Shredder._default_equipment_lifetime
    {'Shredder': 30}
  9. 設定の変更
  10. 設定は変更できます。例えば、基準の価格を$2,500,000 から $3,000,000 に変更してみましょう。
    Shredder.cost_items['Shredder'].cost = 3e6 # 基準価格の変更
    # 以下でも同じです
    # Shredder.cost_items['Shredder']['cost'] = 3e6
    shredder.simulate()
    shredder.results()
    Shredder Units U1
    Electricity Power kW 6e+03
    Cost USD/hr 469
    Design Flow rate kg/hr 1e+06
    Purchase cost Shredder USD 4.83e+06
    Total purchase cost USD 4.83e+06
    Utility cost USD 469
  11. 上限サイズの変更
  12. 1セットのサイズの上限を変更してみます。
    Shredder.cost_items['Shredder'].ub = 6e5 # 上限サイズの変更
    shredder.simulate()
    shredder.results()
    
    Shredder Units U1
    Electricity Power kW 6e+03
    Cost USD/hr 469
    Design Flow rate kg/hr 1e+06
    Purchase cost Shredder (x2) USD 6.38e+06
    Total purchase cost USD 6.38e+06
    Utility cost USD 469
    流量が上限を超えたので、2個必要という計算になりました。なお、複数のコスト項目を追加するために、Unit のサブクラスに複数回デコレータを適用することも可能です。

例(2)

コストデコレータを使って装置の機能を追加することもできます。次の例では、フラッシュタンクに攪拌機を以下の指数関数的サイズアップの係数[5]で追加しています。

  • 化学工学プラント費用指数 : 522
  • サイズ : 流量 252,891 kg/hr
  • 購入価格 : $90,000
  • 電力消費 : 170 kW
  • 指数 : 0.5
  • \( F_{BM} \) : 1.5
  • 耐用年数:設置されているプラントの操業年数と同じ
  1. 機能追加によるコスト追加
  2. @cost('Flow rate', 'Agitator', units='kg/hr',
          cost=90e3, S=252891, kW=170, CE=522, n=0.5, BM=1.5)
    class FlashWithAgitator(bst.Flash):
    
        def _design(self):
            super()._design()
            self._decorated_design()
    
        def _cost(self):
            # Run flash cost algorithm
            super()._cost()
    
            # Run decorated cost algorithm
            self._decorated_cost()
    
    # Test
    F1 = FlashWithAgitator('F1', bst.Stream('feed', Water=800, Ethanol=500, T=350),
                           V=0.5, P=101325)
    F1.simulate()
    F1.results()
    Flash with agitator Units F1
    Electricity Power kW 25.2
    Cost USD/hr 1.97
    Low pressure steam Duty kJ/hr 2.82e+07
    Flow kmol/hr 728
    Cost USD/hr 173
    Design Vessel type Vertical
    Length ft 12.5
    Diameter ft 8.5
    Weight lbr 8.14e+03
    Wall thickness in 0.438
    Flow rate kg/hr 3.74e+04
    Vessel material kmol/hr Carbon steel
    Purchase cost Vertical pressure vessel USD 4.47e+04
    Platform and ladders USD 1.27e+04
    Agitator USD 4e+04
    Heat exchanger - Floating head USD 3.65e+04
    Total purchase cost USD 1.34e+05
    Utility cost USD 175

付随設備

一つの装置には複数の付随設備を持つものもあります。付随設備を追加するためには、auxiliary_unit_namesに名前を追加し、auxiliaryメソッドを使ってそれらをインスタンス化します。次の例では、混合槽、ポンプ、熱交換機からなる新しい装置を作ってみます。

  1. 加熱槽
  2. import biosteam as bst
    
    # 使用する成分の化学的特性を設定
    chemicals = bst.Chemicals(['Water'])
    bst.settings.set_thermo(chemicals)
    
    class HeatedTank(bst.Unit):
        # auxiliary unit names に構成要素を記載
        auxiliary_unit_names = ('mix_tank', 'pump', 'heat_exchanger')
    
        def _init(self, T):
            pump = self.auxiliary(
                'pump', # 付随設備の名前
                bst.Pump, # 付随装置の種類
                ins=self.ins, # 付随装置の流入ストリーム(親クラスと同じ)
            )
            heat_exchanger = self.auxiliary(
                'heat_exchanger', # 名前
                bst.HXutility, # 種類
                ins=pump.outlet, # ポンプの流出ストリームを流入させる
                T=T, #: 熱交換器の追加設定 (温度 [K])
            )
            self.auxiliary(
                'mix_tank', # 名前
                bst.MixTank, # 種類
                ins=heat_exchanger.outlet, # 熱交換器の流出ストリームを流入させる
                outs=self.outs, # 流出ストリーム (親クラスと同じ)
            )
    
        def _run(self):
            # 構成要素の _run()メソッドを実行
            self.pump._run()
            self.heat_exchanger._run()
            self.mix_tank._run()
    
        def _design(self):
            # 構成要素の_design()メソッドを実行し、設計緒元を計算
            self.pump._design()
            self.heat_exchanger._design()
            self.mix_tank._design()
    
        def _cost(self):
            # 構成要素の_cost()メソッドを実行し、コストを計算
            self.pump._cost()
            self.heat_exchanger._cost()
            self.mix_tank._cost()
    
    feed = bst.Stream('feed', Water=200)
    HT1 = HeatedTank('HT1', ins=feed, T=310)
    HT1.simulate()
    HT1.diagram(format='png')
    HT1.show()
    HT1.results()
    HeatedTank: HT1
    ins...
    [0] feed  
        phase: 'l', T: 298.15 K, P: 101325 Pa
        flow (kmol/hr): Water  200
    outs...
    [0] s1  
        phase: 'l', T: 310 K, P: 101325 Pa
        flow (kmol/hr): Water  200
    Heated tank Units HT1
    Electricity Power kW 0.736
    Cost USD/hr 0.0575
    Low pressure steam Duty kJ/hr 1.88e+05
    Flow kmol/hr 4.86
    Cost USD/hr 1.15
    Purchase cost Mix tank - Tank USD 2.89e+04
    Pump - Pump USD 4.37e+03
    Pump - Motor USD 273
    Heat exchanger - Double pipe USD 3.61e+03
    Total purchase cost USD 3.71e+04
    Utility cost USD 1.21

    ポンプはポンプ本体とモーターから構成されているので、Purchase costは4つの要素からできています。また、付随設備のユーティリティとコストは自動的に親ユニットに追加されます。

    また、付随設備は図として表示する際に何も指定しないとそれぞれ表示されますが、auxiliaries=0とすることで表示させないようにすることもできます。

  3. 表示の無効化
  4. HT1.diagram(auxiliaries=0, format='png')

参考文献

  • [1]
  • [2]
    Seider, W. D., Lewin, D. R., Seader, J. D., Widagdo, S., Gani, R., & Ng, M. K. (2017). Product and Process Design Principles. Wiley. Cost Accounting and Capital Cost Estimation (Chapter 16)
  • [3]
  • [4]
    Huang, H., Long, S. & Singh, V. Techno-economic analysis of biodiesel and ethanol co-production from lipid-producing sugarcane. Biofuels, Bioprod. Bioref. 10, 299–315 (2016).(https://doi.org/10.1002/bbb.1640)
  • [5]
    Humbird, D., Davis, R., Tao, L., Kinchin, C., Hsu, D., Aden, A., Dudgeon, D. (2011). Process Design and Economics for Biochemical Conversion of Lignocellulosic Biomass to Ethanol: Dilute-Acid Pretreatment and Enzymatic Hydrolysis of Corn Stover (No. NREL/TP-5100-47764, 1013269)

このブログの人気の投稿

さあ、始めよう!

蒸留塔

機器ユニットの計算結果