パイプ
記法
バイオ・リファイナリー(再生可能資源であるバイオマスを原料にバイオ燃料や樹脂などを製造するプラントや技術)のシミュレーションソフト"BioSTEAM"の機器ユニットどうしを接続する
機器ユニットを接続する時にシンプルな
パイプ記法の使い方を説明しています。 オリジナルのページは-pipe- notationです。 ソースコードは以下の実行環境で確認しています。
- Visual Studio Code バージョン: 1.104.2
- 拡張機能:Jupyter バージョン 2025.8.0
- Python 3.12.10
- biosteam 2.52.13
- graphviz-14.0.2
パイプ
記法
機器ユニットを接続する時にシンプルなパイプ記法が使えます。ここでは、複数の機器ユニットを接続し、一つのプロセスをデモンストレーションとして作成します。パイプ記法では、以下のフォーマットで流出ストリームを取得したり、流入ストリームを設定したりすることが出来ます。
パイプ
記法- 事前準備 例として、流入ストリームが2つ、混合器が2つ、分配器が2つのプロセスを作成します。
- パイプ記法の例 では、機器ユニットを接続し、S2とM1の間にループを作成してみます。
- feed1とS2の流出ストリームの0番目をM1に接続し、その流出ストリームをS1に接続する
- feed2とS1の流出ストリームの0番目をM2に接続し、その流出ストリームをS2に接続する
- 再循環ストリームの接続方法あれこれ(※オリジナルにはない確認事項) まとめて入出力をつなげるのは間違いそうなので、機器ユニットの定義と同時にins、outsを記載することが出来ないか試してみました。が、単に並べるだけでは
- M1の流入ストリームのみ、最後に繋ぐ 折衷案として、M1の流入ストリームのみ、最後に繋ぎます。
- M1の再循環ストリームのみ、最後に繋ぐ M1定義時にinsのfeed1のみ設定しておき、あとから再循環ストリームを繋いでみました。
- 再循環ストリームを最初に設定しておく 他のモデルを見ていて気付きました。こうする方法もありそうです。
# U1-n -> U1.outs[n]
# U1-[0, 1] -> [U1.outs[i] for i in [0, 1]]
# s1-U1 -> U1.ins[:] = [s1]
# s1-n-U1 -> U1.ins[n] = s1
# [s1, s2]-U1 -> U1.ins[:] = [s1, s2]
# U1-n1-n2-U2 -> U2.ins[n2] = U1.outs[n1]
import biosteam as bst
from biosteam.units import Mixer, Splitter
bst.nbtutorial() # Ignore warnings and reset local BioSTEAM preferences
# Set property pacakge
bst.settings.set_thermo(['Water'])
# Set feed stream and units
feed1 = bst.Stream('feed1')
M1 = Mixer('M1', outs='s1')
S1 = Splitter('S1', outs=('s2', 'product1'), split=0.5)
feed2 = bst.Stream('feed2')
M2 = Mixer('M2', outs='s3')
S2 = Splitter('S2', outs=('recycle', 'product2'), split=0.5)
bst.main_flowsheet.diagram()
# In -pipe- notation:
(feed1, S2-0)-M1-S1
(feed2, S1-0)-M2-S2
bst.main_flowsheet.diagram()
パイプ記法を使わない場合は以下のようになります。
M1.ins[:] = (feed1, S2.outs[0])
S1.ins[:] = M1.outs
M2.ins[:] = (feed2, S1.outs[0])
S2.ins[:] = M2.outs
recycleがうまくM1の流入につながらず、2本になってしまいました。
feed1 = bst.Stream('feed1')
M1 = Mixer('M1', ins=(feed1,S2-0), outs='s1')
S1 = Splitter('S1', ins=M1-0, outs=('s2', 'product1'), split=0.5)
feed2 = bst.Stream('feed2')
M2 = Mixer('M2', ins=(feed2,S1-0), outs='s3')
S2 = Splitter('S2', ins=M2-0, outs=('recycle', 'product2'), split=0.5)
bst.main_flowsheet.diagram()
ここで、M1の状況を表示させると、recycle from Splitter-S2となっているので、認識はされているような気はします。繋がっているなら図にも反映されてもよさそうなものですが、Copilot君に聞いても、上手くいきませんでした...。実際にシミュレーションする際に問題ないか、再度検討する必要がありそうです。
M1
Mixer: M1
ins...
[0] feed1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow: 0
[1] recycle from Splitter-S2
phase: 'l', T: 298.15 K, P: 101325 Pa
flow: 0
outs...
[0] s1 to Splitter-S1
phase: 'l', T: 298.15 K, P: 101325 Pa
flow: 0
feed1 = bst.Stream('feed1')
M1 = Mixer('M1')
S1 = Splitter('S1', ins=M1-0, outs=('s2', 'product1'), split=0.5)
feed2 = bst.Stream('feed2')
M2 = Mixer('M2', ins=(feed2,S1-0), outs='s3')
S2 = Splitter('S2', ins=M2-0, outs=('recycle', 'product2'), split=0.5)
M1.ins[:] = (feed1, S2.outs[0])
bst.main_flowsheet.diagram()
これだとうまくrecycleがS2からM1に繋がる図になりました。M1のinsのところは、
M1.ins[0] = feed1
M1.ins[1] = S2-0
でも同じでした。
feed1 = bst.Stream('feed1')
M1 = Mixer('M1',ins=feed1)
S1 = Splitter('S1', ins=M1-0, outs=('s2', 'product1'), split=0.5)
feed2 = bst.Stream('feed2')
M2 = Mixer('M2', ins=(feed2,S1-0), outs='s3')
S2 = Splitter('S2', ins=M2-0, outs=('recycle', 'product2'), split=0.5)
M1.ins[1] = S2-0
これでもいけそうです。後で追加できるんですね。
recycle = bst.Stream('recycle')
feed1 = bst.Stream('feed1')
M1 = Mixer('M1',ins=(feed1,recycle))
S1 = Splitter('S1', ins=M1-0, outs=('s2', 'product1'), split=0.5)
feed2 = bst.Stream('feed2')
M2 = Mixer('M2', ins=(feed2,S1-0), outs='s3')
S2 = Splitter('S2', ins=M2-0, outs=('recycle', 'product2'), split=0.5)
M1.ins[1] = S2-0


