liquid_liquid_extraction#

Abstract Unit Operations#

class LLEUnit(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Abstract class for simulating liquid-liquid equilibrium.

Parameters:
  • ins (Stream], optional) – Inlet fluid.

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

  • top_chemical (str, optional) – Identifier of chemical that will be favored in the low density phase.

  • efficiency=1. (float, optional) – Fraction of feed in liquid-liquid equilibrium. The rest of the feed is divided equally between phases.

  • forced_split_IDs (tuple[str], optional) – IDs of component with a user defined split.

  • forced_split (1d array, optional) – Component-wise split to 0th stream.

Examples

>>> from biorefineries.lipidcane import chemicals
>>> from biosteam import units, settings, Stream
>>> settings.set_thermo(chemicals['Methanol', 'Glycerol', 'Biodiesel', 'TAG'])
>>> feed = Stream('feed', T=333.15,
...               TAG=0.996, Biodiesel=26.9,
...               Methanol=32.9, Glycerol=8.97)
>>> C1 = units.LLEUnit('C1', ins=feed, outs=('light', 'heavy'))
>>> C1.simulate()
>>> C1.outs[0].show()
Stream: light from <LLEUnit: C1>
phase: 'l', T: 333.15 K, P: 101325 Pa
flow (kmol/hr): Methanol   10.2
                Glycerol   0.0239
                Biodiesel  26.9
                TriOlein   0.996
class LiquidsCentrifuge(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Abstract class for liquid centrifuges.

Parameters:
  • ins (Stream], optional) – Inlet fluid.

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

Notes

The f.o.b purchase cost is given by [1]:

\[C_{f.o.b}^{2007} = 28100 Q^{0.574} \ (Q < 100 \frac{m^3}{h})\]
class LiquidsSettler(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Abstract Settler class for liquid-liquid extraction.

Parameters:
  • ins (Stream], optional) – Inlet fluid with two liquid phases.

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

  • steel' (vessel_material='Carbon) – Vessel construction material.

  • vessel_type='Horizontal' ('Horizontal' or 'Vertical', optional) – Vessel type.

  • length_to_diameter=4 (float) – Length to diameter ratio.

  • area_to_feed=0.1 (float) – Diameter * length per gpm of feed [ft2/gpm].

Centrifuges#

class LiquidsSplitCentrifuge(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a liquids centrifuge simulated by component splits.

Parameters:
  • ins (Stream], optional) – Inlet fluid.

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

  • split (Should be one of the following) –

    • [float] The fraction of net feed in the 0th outlet stream.

    • [array_like] Componentwise split of feed to 0th outlet stream.

    • [dict] ID-split pairs of feed to 0th outlet stream.

  • order=None (Iterable[str], defaults to biosteam.settings.chemicals.IDs) – Chemical order of split.

Notes

The f.o.b purchase cost is given by [1]:

\[C_{f.o.b}^{2007} = 28100 Q^{0.574} (Q < 100 \frac{m^3}{h})\]
class LLECentrifuge(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a liquids centrifuge simulated by liquid-liquid equilibrium.

Parameters:
  • ins (Stream], optional) – Inlet fluid.

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

  • top_chemical (str, optional) – Identifier of chemical that will be favored in the low density phase.

  • efficiency (float,) – Fraction of feed in liquid-liquid equilibrium. The rest of the feed is divided equally between phases.

Notes

The f.o.b purchase cost is given by [1]:

\[C_{f.o.b}^{2007} = 28100 Q^{0.574} (Q < 100 \frac{m^3}{h})\]

Examples

>>> from biorefineries.lipidcane import chemicals
>>> from biosteam import units, settings, Stream
>>> settings.set_thermo(chemicals['Methanol', 'Glycerol', 'Biodiesel', 'TAG'])
>>> feed = Stream('feed', T=333.15,
...               TAG=0.996, Biodiesel=26.9,
...               Methanol=32.9, Glycerol=8.97)
>>> C1 = units.LLECentrifuge('C1', ins=feed, outs=('light', 'heavy'))
>>> C1.simulate()
>>> C1.outs[0].show()
Stream: light from <LLECentrifuge: C1>
phase: 'l', T: 333.15 K, P: 101325 Pa
flow (kmol/hr): Methanol   10.2
                Glycerol   0.0239
                Biodiesel  26.9
                TriOlein   0.996
>>> C1.results()
Liquids centrifuge                       Units       C1
Electricity         Power                   kW     17.5
                    Cost                USD/hr     1.37
Design              Flow rate           m^3/hr     12.5
Purchase cost       Liquids centrifuge     USD 1.29e+05
Total purchase cost                        USD 1.29e+05
Utility cost                            USD/hr     1.37
class SLLECentrifuge(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a SLLECentrifuge object that separates the feed into solid, oil, and aqueous phases.

Parameters:
  • ins (Stream], optional) – feed

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

    • [2] Solids.

  • solids_split (dict[str, float]) – Splits to 2nd outlet stream.

  • top_chemical (str, optional) – Identifier of chemical that will be favored in the low density phase.

  • efficiency (float, optional) – Fraction of feed in liquid-liquid equilibrium. The rest of the feed is divided equally between phases. Defaults to 1.0.

  • moisture_content (float, optional) – Moisture content of solids. Defaults to 0.5.

Notes

Cost algorithm is based on a 3-phase decanter centrifuge from a conventional dry-grind corn ethanol plant that separates aqueous, oil, and solid fractions (i.e. DDGS) from the bottoms product of the beer column [2].

Examples

>>> import biosteam as bst
>>> bst.settings.set_thermo(['Water', 'Hexane', bst.Chemical('Solids', search_db=False, default=True, phase='s')], cache=True)
>>> feed = bst.Stream('feed', Water=100, Hexane=100, Solids=10)
>>> C1 = bst.SLLECentrifuge('C1', feed, ['oil', 'aqueous', 'solids'], top_chemical='Hexane', solids_split={'Solids':1.0})
>>> C1.simulate()
>>> C1.show()
SLLECentrifuge: C1
ins...
[0] feed
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kmol/hr): Water   100
                    Hexane  100
                    Solids  10
outs...
[0] oil
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kmol/hr): Water   0.791
                    Hexane  100
[1] aqueous
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kmol/hr): Water   98.7
                    Hexane  0.015
[2] solids
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kmol/hr): Water   0.555
                    Solids  10
>>> C1.results()
3-Phase decanter centrifuge                       Units       C1
Electricity         Power                            kW   0.0101
                    Cost                         USD/hr 0.000792
Design              Flow rate                     L/min      250
Purchase cost       3-Phase decanter centrifuge     USD 2.88e+05
Total purchase cost                                 USD 2.88e+05
Utility cost                                     USD/hr 0.000792
class SolidLiquidsSplitCentrifuge(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a SolidLiquidsSplitCentrifuge object that separates the feed into solid, oil, and aqueous phases.

Parameters:
  • ins (Stream], optional) – feed

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

    • [2] Solids.

  • aqueous_split (dict[str, float]) – Splits to [0] outlet stream.

  • solids_split (dict[str, float]) – Splits to [2] outlet stream.

  • moisture_content (float, optional) – Moisture content of solids. Defaults to 0.5.

Notes

Cost algorithm is based on a 3-phase decanter centrifuge from a conventional dry-grind corn ethanol plant that separates aqueous, oil, and solid fractions (i.e. DDGS) from the bottoms product of the beer column [2].

The unit operation first splits the feed to the light and heavy fractions, then fractionates the solids from the heavy phase.

Examples

>>> import biosteam as bst
>>> bst.settings.set_thermo(['Water', 'Hexane', bst.Chemical('Solids', search_db=False, default=True, phase='s')], cache=True)
>>> feed = bst.Stream('feed', Water=100, Hexane=100, Solids=10)
>>> C1 = bst.SolidLiquidsSplitCentrifuge(
...     'C1', feed, ['oil', 'aqueous', 'solids'],
...     solids_split={'Solids':1.0},
...     aqueous_split={'Water':0.99, 'Hexane':0.01, 'Solids': 0.9}
... )
>>> C1.simulate()
>>> C1.show(flow='kg/hr')
SolidLiquidsSplitCentrifuge: C1
ins...
[0] feed
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kg/hr): Water   1.8e+03
                  Hexane  8.62e+03
                  Solids  10
outs...
[0] oil
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kg/hr): Water   18
                  Hexane  8.53e+03
                  Solids  1
[1] aqueous
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kg/hr): Water   1.77e+03
                  Hexane  86.2
[2] solids
    phase: 'l', T: 298.15 K, P: 101325 Pa
    flow (kg/hr): Water   9
                  Solids  9
>>> C1.results()
3-Phase decanter centrifuge                       Units       C1
Electricity         Power                            kW   0.0101
                    Cost                         USD/hr 0.000792
Design              Flow rate                     L/min      250
Purchase cost       3-Phase decanter centrifuge     USD 2.88e+05
Total purchase cost                                 USD 2.88e+05
Utility cost                                     USD/hr 0.000792

Mixer-Settlers#

class LiquidsMixingTank(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a LiquidsMixingTank for mixing two liquid phases.

Parameters:
  • ins (Stream], optional) – Inlet fluids to be mixed.

  • outs (Stream], optional) – Mixed outlet fluid.

  • tau=0.022 (float) – Residence time [hr].

  • agitator_kW_per_m3=1.0 (float) – Electricity consumption in kW / m3 of volume.

  • steel' (vessel_material='Carbon) – Vessel construction material.

  • vessel_type='Horizontal' ('Horizontal' or 'Vertical', optional) – Vessel type.

  • length_to_diameter=1 (float) – Length to diameter ratio.

class LLESettler(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a LLESettler object that rigorously simulates liquid-liquid extraction.

Parameters:
  • ins (Stream], optional) – Inlet fluid with two liquid phases.

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

  • steel' (vessel_material='Carbon) – Vessel construction material.

  • vessel_type='Horizontal' ('Horizontal' or 'Vertical', optional) – Vessel type.

  • length_to_diameter=4 (float, optional) – Length to diameter ratio.

  • area_to_feed=0.1 (float, optional) – Diameter * length per gpm of feed [ft2/gpm].

  • top_chemical=None (str, optional) – Identifier of chemical that will be favored in the low density phase.

  • efficiency=1.0 (float) – Fraction of feed in liquid-liquid equilibrium

  • cache_tolerance=1e-6 (float, optional) – Molar tolerance of cached partition coefficients.

class LiquidsSplitSettler(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a LLESettler object that rigorously simulates liquid-liquid extraction.

Parameters:
  • ins (Stream], optional) – Inlet fluid with two liquid phases.

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

  • split (Should be one of the following) –

    • [float] The fraction of net feed in the 0th outlet stream

    • [array_like] Componentwise split of feed to 0th outlet stream

    • [dict] ID-split pairs of feed to 0th outlet stream

  • order=None (Iterable[str], defaults to biosteam.settings.chemicals.IDs) – Chemical order of split.

  • steel' (vessel_material='Carbon) – Vessel construction material.

  • vessel_type='Horizontal' ('Horizontal' or 'Vertical', optional) – Vessel type.

  • length_to_diameter=4 (float, optional) – Length to diameter ratio.

  • area_to_feed=0.1 (float, optional) – Diameter * length per gpm of feed [ft2/gpm].

class LiquidsPartitionSettler(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a LiquidsPartitionSettler object that simulates liquid-liquid extraction by partition coefficients.

Parameters:
  • ins (Stream], optional) – Inlet fluid with two liquid phases.

  • outs (Stream], optional) –

    • [0] Low density fluid.

    • [1] Heavy fluid.

  • steel' (vessel_material='Carbon) – Vessel construction material.

  • vessel_type='Horizontal' ('Horizontal' or 'Vertical', optional) – Vessel type.

  • length_to_diameter=4 (float, optional) – Length to diameter ratio.

  • area_to_feed=0.1 (float, optional) – Diameter * length per gpm of feed [ft2/gpm].

  • partition_coefficients (1d array, optional) – Partition coefficients of chemicals in equilibrium (molar composition ratio of the top fluid over the bottom fluid).

  • partition_IDs (tuple[str], optional) – IDs of chemicals in equilibrium.

class MixerSettler(ID='', ins=None, outs=(), thermo=None, **kwargs)[source]#

Create a MixerSettler object that models liquid-liquid extraction using a mixing tank and a settler tank.

Parameters:
  • ins (Stream], optional) –

    • [0] feed.

    • [1] solvent.

  • outs (Stream], optional) –

    • [0] extract.

    • [1] raffinate.

  • top_chemical (str, optional) – Name of main chemical in the extract phase. Defaults to chemical with highest molar fraction in the solvent.

  • mixer_data (dict, optional) – Arguments to initialize the “mixer” attribute, a LiquidsMixingTank object.

  • settler_data (dict, optional) – Arguments to initialize the “settler” attribute, a LiquidsSettler object.

Examples

Simulate by rigorous LLE:

>>> import biosteam as bst
>>> bst.settings.set_thermo(['Water', 'Methanol', 'Octanol'], cache=True)
>>> feed = bst.Stream('feed', Water=500, Methanol=50)
>>> solvent = bst.Stream('solvent', Octanol=500)
>>> MS1 = bst.MixerSettler('MS1', ins=(feed, solvent), outs=('extract', 'raffinate'))
>>> MS1.simulate()
>>> MS1.extract.imol['Methanol'] / MS1.feed.imol['Methanol']
0.66
>>> MS1.raffinate.imol['Water'] / MS1.feed.imol['Water']
0.82
>>> MS1.extract.imol['Octanol'] / MS1.solvent.imol['Octanol']
0.99
>>> MS1.results() 
Mixer settler                                             Units         MS1
Power               Rate                                     kW        1.98
                    Cost                                 USD/hr       0.155
Design              Mixer - Volume                          m^3        1.98
                    Mixer - Power                            hp        2.65
                    Mixer - Vessel type                            Vertical
                    Mixer - Length                           ft        1.36
                    Mixer - Diameter                         ft        1.36
                    Mixer - Weight                           lb        91.2
                    Mixer - Wall thickness                   in        0.25
                    Settler - Vessel type                        Horizontal
                    Settler - Length                         ft        12.6
                    Settler - Diameter                       ft        3.15
                    Settler - Weight                         lb    1.44e+03
                    Settler - Wall thickness                 in        0.25
Purchase cost       Mixer - Turbine agitator                USD    6.32e+03
                    Mixer - Vertical pressure vessel        USD    4.59e+03
                    Mixer - Platform and ladders            USD         641
                    Settler - Horizontal pressure ve...     USD    9.99e+03
                    Settler - Platform and ladders          USD    2.66e+03
Total purchase cost                                         USD    2.42e+04
Utility cost                                             USD/hr       0.155

Simulate with user defined partition coefficients:

>>> import biosteam as bst
>>> import numpy as np
>>> bst.settings.set_thermo(['Water', 'Methanol', 'Octanol'])
>>> feed = bst.Stream('feed', Water=500, Methanol=50)
>>> solvent = bst.Stream('solvent', Octanol=500)
>>> MS1 = bst.MixerSettler('MS1',
...    ins=(feed, solvent), outs=('extract', 'raffinate'),
...    model='partition coefficients',
...    settler_data={
...        'partition_coefficients': np.array([1.451e-01, 1.380e+00, 2.958e+03]),
...        'partion_IDs': ('Water', 'Methanol', 'Octanol'),
...    },
... )
>>> MS1.simulate()
>>> MS1.extract.imol['Methanol'] / MS1.feed.imol['Methanol']
0.66
>>> MS1.raffinate.imol['Water'] / MS1.feed.imol['Water']
0.82
>>> MS1.extract.imol['Octanol'] / MS1.solvent.imol['Octanol']
0.99
>>> MS1.results() 
Mixer settler                                             Units         MS1
Electricity         Power                                    kW        1.98
                    Cost                                 USD/hr       0.155
Design              Mixer - Volume                          m^3        1.98
                    Mixer - Power                            hp        2.65
                    Mixer - Vessel type                            Vertical
                    Mixer - Length                           ft        1.36
                    Mixer - Diameter                         ft        1.36
                    Mixer - Weight                           lb        91.2
                    Mixer - Wall thickness                   in        0.25
                    Settler - Vessel type                        Horizontal
                    Settler - Length                                   12.6
                    Settler - Diameter                                 3.15
                    Settler - Weight                               1.44e+03
                    Settler - Wall thickness                           0.25
Purchase cost       Mixer - Turbine agitator                USD    6.32e+03
                    Mixer - Vertical pressure vessel        USD    4.91e+03
                    Mixer - Platform and ladders            USD         686
                    Settler - Horizontal pressure ve...     USD    1.16e+04
                    Settler - Platform and ladders          USD    3.08e+03
Total purchase cost                                         USD    2.65e+04
Utility cost                                             USD/hr       0.155
class MultiStageMixerSettlers(ID='', ins=None, outs=(), thermo=None, stages=None, **kwargs)[source]#

Create a MultiStageMixerSettlers object that models a counter-current system of mixer-settlers for liquid-liquid extraction.

Parameters:
  • ins

    • [0] feed.

    • [1] solvent.

  • outs

    • [0] extract

    • [1] raffinate

  • N_stages (int) – Number of stages.

  • partition_data ({'IDs': tuple[str], 'K': 1d array}, optional) – IDs of chemicals in equilibrium and partition coefficients (molar composition ratio of the extract over the raffinate). If given, The mixer-settlers will be modeled with these constants. Otherwise, partition coefficients are computed based on temperature and composition.

  • top_chemical (str) – Name of main chemical in the top phase (extract phase).

  • mixer_data (dict) – Arguments to initialize the “mixer” attribute, a LiquidsMixingTank object.

  • settler_data (dict) – Arguments to initialize the “settler” attribute, a LiquidsSettler object.

Notes

All mixer settlers are sized equally based on the assumption that the volumetric flow rate of each phase does not change significantly across stages.

Examples

Simulate by rigorous LLE:

>>> import biosteam as bst
>>> bst.settings.set_thermo(['Water', 'Methanol', 'Octanol'])
>>> feed = bst.Stream('feed', Water=500, Methanol=50)
>>> solvent = bst.Stream('solvent', Octanol=500)
>>> MSMS1 = bst.MultiStageMixerSettlers('MSMS1', ins=(feed, solvent), outs=('extract', 'raffinate'), N_stages=2)
>>> MSMS1.simulate()
>>> MSMS1.extract.imol['Methanol'] / MSMS1.feed.imol['Methanol']
0.83
>>> MSMS1.raffinate.imol['Water'] / MSMS1.feed.imol['Water']
0.82
>>> MSMS1.extract.imol['Octanol'] / MSMS1.solvent.imol['Octanol']
0.99
>>> MSMS1.results() 
Multi stage mixer settlers                     Units       MSMS1
Electricity         Power                         kW        3.96
                    Cost                      USD/hr       0.309
Design              Mixer - Volume               m^3        1.98
                    Mixer - Power                 hp        2.65
                    Mixer - Vessel type                 Vertical
                    Mixer - Length                ft        1.36
                    Mixer - Diameter              ft        1.36
                    Mixer - Weight                lb        91.2
                    Mixer - Wall thickness        in        0.25
                    Settler - Vessel type             Horizontal
                    Settler - Length                        12.6
                    Settler - Diameter                      3.15
                    Settler - Weight                    1.44e+03
                    Settler - Wall thickness                0.25
Purchase cost       Mixers and agitators         USD    1.12e+04
                    Settlers                     USD    2.93e+04
Total purchase cost                              USD    4.05e+04
Utility cost                                  USD/hr       0.309

Simulate with user defined partition coefficients:

>>> import biosteam as bst
>>> import numpy as np
>>> bst.settings.set_thermo(['Water', 'Methanol', 'Octanol'])
>>> feed = bst.Stream('feed', Water=5000, Methanol=500)
>>> solvent = bst.Stream('solvent', Octanol=5000)
>>> MSMS1 = bst.MultiStageMixerSettlers('MSMS1', ins=(feed, solvent), outs=('extract', 'raffinate'), N_stages=10,
...     partition_data={
...         'K': np.array([0.1450, 1.380, 2957.]),
...         'IDs': ('Water', 'Methanol', 'Octanol'),
...         'phi': 0.590 # Initial phase fraction guess. This is optional.
...     }
... )
>>> MSMS1.simulate()
>>> MSMS1.extract.imol['Methanol'] / MSMS1.feed.imol['Methanol']
0.99
>>> MSMS1.raffinate.imol['Water'] / MSMS1.feed.imol['Water']
0.82
>>> MSMS1.extract.imol['Octanol'] / MSMS1.solvent.imol['Octanol']
0.99
>>> MSMS1.results() 
Multi stage mixer settlers                     Units       MSMS1
Electricity         Power                         kW         198
                    Cost                      USD/hr        15.5
Design              Mixer - Volume               m^3        19.8
                    Mixer - Power                 hp        26.5
                    Mixer - Vessel type                 Vertical
                    Mixer - Length                ft        2.93
                    Mixer - Diameter              ft        2.93
                    Mixer - Weight                lb         423
                    Mixer - Wall thickness        in        0.25
                    Settler - Vessel type             Horizontal
                    Settler - Length                        39.8
                    Settler - Diameter                      9.95
                    Settler - Weight                    2.52e+04
                    Settler - Wall thickness               0.438
Purchase cost       Mixers and agitators         USD    1.15e+05
                    Settlers                     USD    6.15e+05
Total purchase cost                              USD     7.3e+05
Utility cost                                  USD/hr        15.5

Because octanol and water do not mix well, it may be a good idea to assume that these solvents do not mix at all:

>>> import biosteam as bst
>>> import numpy as np
>>> bst.settings.set_thermo(['Water', 'Methanol', 'Octanol'])
>>> feed = bst.Stream('feed', Water=5000, Methanol=500)
>>> solvent = bst.Stream('solvent', Octanol=5000)
>>> MSMS1 = bst.MultiStageMixerSettlers('MSMS1', ins=(feed, solvent), outs=('extract', 'raffinate'), N_stages=20,
...     partition_data={
...         'K': np.array([1.38]),
...         'IDs': ('Methanol',),
...         'raffinate_chemicals': ('Water',),
...         'extract_chemicals': ('Octanol',),
...     }
... )
>>> MSMS1.simulate()
>>> MSMS1.extract.imol['Methanol'] / feed.imol['Methanol'] # Recovery
0.99
>>> MSMS1.extract.imol['Octanol'] / solvent.imol['Octanol'] # Solvent stays in extract
1.0
>>> MSMS1.raffinate.imol['Water'] / feed.imol['Water'] # Carrier remains in raffinate
1.0

Simulate with a feed at the 4th stage:

>>> import biosteam as bst
>>> import numpy as np
>>> bst.settings.set_thermo(['Water', 'Methanol', 'Octanol'])
>>> feed = bst.Stream('feed', Water=5000, Methanol=500)
>>> solvent = bst.Stream('solvent', Octanol=5000)
>>> dilute_feed = bst.Stream('dilute_feed', Water=100, Methanol=2)
>>> MSMS1 = bst.MultiStageMixerSettlers('MSMS1', ins=(feed, dilute_feed, solvent), outs=('extract', 'raffinate'), N_stages=5,
...     feed_stages=[0, 3, -1], # Stage at which each inlet enters, respectively
...     partition_data={
...         'K': np.array([1.38]),
...         'IDs': ('Methanol',),
...         'raffinate_chemicals': ('Water',),
...         'extract_chemicals': ('Octanol',),
...     }
... )
>>> MSMS1.simulate()
>>> MSMS1.extract.imol['Methanol'] / (feed.imol['Methanol'] + dilute_feed.imol['Methanol']) # Recovery
0.93

Simulate with a 60% extract side draw at the 2nd stage and 10% raffinate side draw at the 3rd stage:

>>> import biosteam as bst
>>> import numpy as np
>>> bst.settings.set_thermo(['Water', 'Methanol', 'Octanol'])
>>> feed = bst.Stream('feed', Water=5000, Methanol=500)
>>> solvent = bst.Stream('solvent', Octanol=5000)
>>> MSMS1 = bst.MultiStageMixerSettlers('MSMS1', ins=(feed, solvent), N_stages=4,
...     # Extract side draws always come first, then raffinate side draws
...     outs=('extract', 'raffinate', 'extract_side_draw', 'raffinate_side_draw'),
...     extract_side_draws=[(1, 0.6)], # Stage number and split fraction pairs
...     raffinate_side_draws=[(2, 0.10)],
...     partition_data={
...         'K': np.array([1.38]),
...         'IDs': ('Methanol',),
...         'raffinate_chemicals': ('Water',),
...         'extract_chemicals': ('Octanol',),
...     }
... )
>>> MSMS1.simulate()
>>> (MSMS1.extract.imol['Methanol'] + MSMS1.outs[2].imol['Methanol']) / feed.imol['Methanol'] # Recovery
0.87

References