Skip to content

Commit

Permalink
minor enhancements
Browse files Browse the repository at this point in the history
  • Loading branch information
yoelcortes committed May 9, 2024
1 parent a167be9 commit d8964d2
Show file tree
Hide file tree
Showing 9 changed files with 107 additions and 362 deletions.
2 changes: 1 addition & 1 deletion Bioindustrial-Park
Submodule Bioindustrial-Park updated 44 files
+247 −218 biorefineries/HP/TRY_analysis_new.py
+1,039 −0 biorefineries/HP/TY_CO2_analysis.py
+77 −74 biorefineries/HP/analyses/1_full_evaluation.py
+994 −0 biorefineries/HP/analyses/models_2015.py
+5 −6 biorefineries/HP/analyses/models_achieved_improvements.py
+1,005 −0 biorefineries/HP/analyses/models_achieved_improvements_with_CO2.py
+4 −0 biorefineries/HP/chemicals_data.py
+26 −3 biorefineries/HP/process_settings.py
+95 −6 biorefineries/HP/system_light_lle_vacuum_distillation.py
+55 −4 biorefineries/HP/units.py
+4 −1 biorefineries/TAL/_general_utils.py
+881 −0 ...xylation/analytical_methods_new/decarboxylation_TALconversion_PDreq_PDprice_purchasing_PD_analytical_new.py
+3 −2 biorefineries/TAL/analyses/fermentation/TRY_analysis_TAL.py
+1 −1 biorefineries/TAL/analyses/full/1_uncertainties_TAL_solubility_exploit.py
+1 −1 biorefineries/TAL/analyses/full/plot_utils.py
+4 −0 biorefineries/TAL/models/models_TAL_solubility_exploit.py
+87 −57 biorefineries/TAL/systems/system_SA_solubility_exploit_ethanol_sugarcane.py
+2 −1 biorefineries/TAL/systems/system_TAL_adsorption_sugarcane.py
+0 −755 biorefineries/TAL/systems/system_TAL_solubility_exploit_ethanol_sugarcane - Copy.py
+5 −6 biorefineries/TAL/systems/system_TAL_solubility_exploit_ethanol_sugarcane.py
+24 −3 biorefineries/TAL/units.py
+6 −12 biorefineries/lactic/analyses/1_uncertainties.py
+11 −11 biorefineries/lactic/models.py
+ biorefineries/oleochemicals/32576420
+ biorefineries/oleochemicals/675AEE30
+ biorefineries/oleochemicals/Mass_allocation.pdf
+ biorefineries/oleochemicals/O_75.pdf
+ biorefineries/oleochemicals/O_80.pdf
+ biorefineries/oleochemicals/O_85.pdf
+9 −9 biorefineries/oleochemicals/_process_settings.py
+ biorefineries/oleochemicals/box_and_whiskers_plot.pdf
+0 −1 biorefineries/oleochemicals/data_for_contours.py
+18 −0 biorefineries/oleochemicals/model_samples.py
+2,529 −443 biorefineries/oleochemicals/plots.py
+34 −24 biorefineries/oleochemicals/prices_and_GWP_factors.py
+ biorefineries/oleochemicals/stacked_bar_plot.pdf
+125 −9 biorefineries/oleochemicals/system_simulate.py
+14 −16 biorefineries/oleochemicals/systems_baseline.py
+1,453 −0 biorefineries/oleochemicals/systems_baseline_copy1.py
+0 −0 biorefineries/oleochemicals/systems_baseline_copy_orig.py
+377 −471 biorefineries/oleochemicals/uncertainity_analysis.py
+13 −23 biorefineries/oleochemicals/units_baseline.py
+518 −1 biorefineries/oleochemicals/useless info.py
+1 −1 setup.py
29 changes: 21 additions & 8 deletions biosteam/facilities/systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,10 @@ def adjust_plant_air(): plant_air.imass['N2'] = feedstock.F_mass * ADP.plant_air
@FT.add_specification(run=True)
def adjust_fire_water(): fire_water.imass['Water'] = feedstock.F_mass * FT.fire_water_over_feedstock
if CHP:
create_coheat_and_power_system(mockup=True, autopopulate=True, **CHP_kwargs)
if 'autopopulate' not in CHP_kwargs:
CHP_kwargs = CHP_kwargs.copy()
CHP_kwargs['autopopulate'] = True
create_coheat_and_power_system(mockup=True, **CHP_kwargs)
if blowdown_recycle:
units = bst.main_flowsheet.unit.get_context_level(0)
blowdown_to_wastewater = bst.Stream('blowdown_to_wastewater')
Expand Down Expand Up @@ -181,22 +184,32 @@ def create_coheat_and_power_system(
autopopulate=None, **kwargs
):
makeup_water, natural_gas, lime, boiler_chemicals, = ins

slurry_mixer = bst.Mixer('slurry_mixer', ins=combustible_slurries or [])
gas_mixer = bst.Mixer('gas_mixer', ins=combustible_gases or [])
if autopopulate or combustible_slurries:
slurry_mixer = bst.Mixer('slurry_mixer', ins=combustible_slurries or [])
slurry = slurry_mixer-0
else:
slurry = None
if autopopulate or combustible_gases:
gas_mixer = bst.Mixer('gas_mixer', ins=combustible_gases or [])
gas = gas_mixer-0
else:
gas = None
BT = bst.BoilerTurbogenerator(
ins=[slurry_mixer-0, gas_mixer-0,
makeup_water, natural_gas, lime, boiler_chemicals],
ins=[slurry, gas,
makeup_water, natural_gas,
lime, boiler_chemicals],
outs=outs,
**kwargs,
)
gas_mixer.autopopulate = slurry_mixer.autopopulate = False if autopopulate is None else autopopulate
BT.autopopulate = False if autopopulate is None else autopopulate

@BT.add_specification(run=True)
def autopopulate_combustibles():
if gas_mixer.autopopulate and not slurry_mixer.ins and not gas_mixer.ins:
if BT.autopopulate and not slurry_mixer.ins and not gas_mixer.ins:
streams = bst.FreeProductStreams(BT.system.streams)
slurry_mixer.ins.extend(streams.combustible_slurries)
gas_mixer.ins.extend(streams.combustible_gases)
slurry_mixer.run_until(BT)
gas_mixer.run_until(BT)
else:
BT.autopopulate = False
26 changes: 25 additions & 1 deletion biosteam/process_tools/process_model.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,28 @@ def load_model(self, model):
for i in model.parameters:
setattr(self, i.setter.__name__, i)
for i in model.metrics:
setattr(self, i.getter.__name__, i)
setattr(self, i.getter.__name__, i)

@property
def parameters(self):
return self.model._parameters

@property
def metrics(self):
return self.model._metrics

def _repr(self, m):
clsname = type(self).__name__
newline = "\n" + " "*(len(clsname)+2)
return f'{clsname}: {newline.join([i.describe() for i in self.metrics])}'

def __repr__(self):
return f'<{type(self).__name__}: {len(self.parameters)}-parameters, {len(self.metrics)}-metrics>'

def _info(self, p, m):
return 'Process' + self.model._info(p, m)

def show(self, p=None, m=None):
"""Return information on p-parameters and m-metrics."""
print(self._info(p, m))
_ipython_display_ = show
59 changes: 5 additions & 54 deletions biosteam/units/_flash.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
#if not (0.1 < V < 70):
# raise DesignError(f"Volume is out of bounds for costing")
#lambda V, CE: CE*13*V**0.62 # V (m3)
__all__ = ('Flash', 'SplitFlash', 'RatioFlash')
__all__ = ('Flash', 'SplitFlash')


# %% Flash
Expand Down Expand Up @@ -521,9 +521,11 @@ def _init(self, split,
vessel_type=None,
holdup_time=15,
surge_time=7.5,
has_mist_eliminator=False
has_mist_eliminator=False,
has_vapor_condenser=False,
):
Splitter._init(self, split=split, order=order)
self.has_vapor_condenser = has_vapor_condenser
self._load_components()

self.T = T #: Operating temperature (K)
Expand Down Expand Up @@ -555,6 +557,7 @@ def _init(self, split,
self.has_mist_eliminator = has_mist_eliminator

self.flash_inlet = False


isplit = Splitter.isplit
split = Splitter.split
Expand All @@ -574,59 +577,7 @@ def _run(self):
def _design(self):
self.heat_exchanger.simulate_as_auxiliary_exchanger(self.ins, self.outs, vle=False)
super()._design()

# TODO: Remove this in favor of partition coefficients
class RatioFlash(Flash):

def _init(self,
K_chemicals, Ks, top_solvents=(), top_split=(),
bot_solvents=(), bot_split=()
):
self._load_components()
self.K_chemicals = K_chemicals
self.Ks = Ks
self.top_solvents = top_solvents
self.top_split = top_split
self.bot_solvents = bot_solvents
self.bot_split = bot_split

def _run(self):
feed = self.ins[0]
top, bot = self.outs
indices = self.chemicals.get_index
def flattend(indices, split):
flat_index = []
flat_split = []
integer = int
isa = isinstance
for i, j in zip(indices, split):
if isa(i, integer):
flat_index.append(i)
flat_split.append(j)
else:
flat_index.extend(i)
flat_split.extend([j] * len(i))
return flat_index, np.array(flat_split)

K_index, Ks = flattend(indices(self.K_chemicals), self.Ks)
top_index, top_split = flattend(indices(self.top_solvents), self.top_split)
bot_index, bot_split = flattend(indices(self.bot_solvents), self.bot_split)
top_mol = top.mol; bot_mol = bot.mol; feed_mol = feed.mol
top_mol[top_index] = feed_mol[top_index] * top_split
bot_mol[top_index] = feed_mol[top_index] - top_mol[top_index]
bot_mol[bot_index] = feed_mol[bot_index] * bot_split
top_mol[bot_index] = feed_mol[bot_index] - bot_mol[bot_index]
topnet = top_mol[top_index].sum()
botnet = bot_mol[bot_index].sum()
molnet = topnet+botnet
top_mol[K_index] = Ks * topnet * feed_mol[K_index] / molnet # solvent * mol ratio
bot_mol[K_index] = feed_mol[K_index] - top_mol[K_index]
top.T, top.P = feed.T, feed.P
bot.T, bot.P = feed.T, feed.P

def _design(self): # pragma: no cover
self.heat_exchanger.simulate_as_auxiliary_exchanger(self.ins, self.outs, vle=False)
super()._design()

# %% Single Component for MultiEffectEvaporator

Expand Down
50 changes: 47 additions & 3 deletions biosteam/units/liquid_liquid_extraction.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
from .phase_equilibrium import MultiStageEquilibrium
from thermosteam._graphics import mixer_settler_graphics
from .. import Unit
from ._flash import RatioFlash
from thermosteam import separations as sep
import numpy as np

__all__ = (
'LLEUnit',
Expand Down Expand Up @@ -181,8 +181,52 @@ class LiquidsCentrifuge(Unit, isabstract=True):
# TODO: Remove this in favor of partition coefficients
class LiquidsRatioCentrifuge(LiquidsCentrifuge):
line = 'Liquids centrifuge'
_init = RatioFlash._init
_run = RatioFlash._run

def _init(self,
K_chemicals, Ks, top_solvents=(), top_split=(),
bot_solvents=(), bot_split=()
):
self._load_components()
self.K_chemicals = K_chemicals
self.Ks = Ks
self.top_solvents = top_solvents
self.top_split = top_split
self.bot_solvents = bot_solvents
self.bot_split = bot_split

def _run(self):
feed = self.ins[0]
top, bot = self.outs
indices = self.chemicals.get_index
def flattend(indices, split):
flat_index = []
flat_split = []
integer = int
isa = isinstance
for i, j in zip(indices, split):
if isa(i, integer):
flat_index.append(i)
flat_split.append(j)
else:
flat_index.extend(i)
flat_split.extend([j] * len(i))
return flat_index, np.array(flat_split)

K_index, Ks = flattend(indices(self.K_chemicals), self.Ks)
top_index, top_split = flattend(indices(self.top_solvents), self.top_split)
bot_index, bot_split = flattend(indices(self.bot_solvents), self.bot_split)
top_mol = top.mol; bot_mol = bot.mol; feed_mol = feed.mol
top_mol[top_index] = feed_mol[top_index] * top_split
bot_mol[top_index] = feed_mol[top_index] - top_mol[top_index]
bot_mol[bot_index] = feed_mol[bot_index] * bot_split
top_mol[bot_index] = feed_mol[bot_index] - bot_mol[bot_index]
topnet = top_mol[top_index].sum()
botnet = bot_mol[bot_index].sum()
molnet = topnet+botnet
top_mol[K_index] = Ks * topnet * feed_mol[K_index] / molnet # solvent * mol ratio
bot_mol[K_index] = feed_mol[K_index] - top_mol[K_index]
top.T, top.P = feed.T, feed.P
bot.T, bot.P = feed.T, feed.P


class LiquidsSplitCentrifuge(LiquidsCentrifuge):
Expand Down
9 changes: 5 additions & 4 deletions biosteam/units/phase_equilibrium.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,7 @@ def __init__(self, ID='', ins=None, outs=(), thermo=None, *,
partition-1, [self.outs[-1], self.outs[1]],
split=bottom_split,
)
self.set_specification(B, Q, T)
self.P = P
self.set_specification(B, Q, T, P)

@property
def Q(self):
Expand Down Expand Up @@ -225,13 +224,15 @@ def add_feed(self, stream):
)
)

def set_specification(self, B, Q, T):
def set_specification(self, B, Q, T, P):
if B is None and Q is None and T is None: Q = 0.
partition = self.partition
partition.B_specification = partition.B = B
partition.T_specification = partition.T = T
if T is not None:
for i in partition.outs: i.T = T
if P is not None:
for i in partition.outs: i.P = P
partition.Q = Q

@property
Expand Down Expand Up @@ -1122,7 +1123,7 @@ def _init(self,
self.stage_specifications = stage_specifications
for i, (name, value) in stage_specifications.items():
B, Q, T = _get_specification(name, value)
stages[i].set_specification(B=B, Q=Q, T=T)
stages[i].set_specification(B=B, Q=Q, T=T, P=P)
else:
self.stage_specifications = stage_specifications
self.stages = stages
Expand Down
Loading

0 comments on commit d8964d2

Please sign in to comment.