Skip to content

Commit

Permalink
improvements to aerated-bioreactor/distillation/plots
Browse files Browse the repository at this point in the history
  • Loading branch information
cortespea committed Jun 17, 2024
1 parent ed48232 commit 25e0a96
Show file tree
Hide file tree
Showing 14 changed files with 615 additions and 243 deletions.
2 changes: 1 addition & 1 deletion Bioindustrial-Park
Submodule Bioindustrial-Park updated 91 files
+14 −34 ...es/TAL/analyses/decarboxylation/analytical_methods/decarboxylation_pH_TALconversion_baseprice_analytical.py
+14 −35 .../decarboxylation/analytical_methods/decarboxylation_pH_TALconversion_baseprice_withoutcitrate_analytical.py
+128 −11 biorefineries/TAL/analyses/fermentation/TRY_analysis_TAL.py
+956 −0 biorefineries/TAL/analyses/full/1_uncertainties_SA_THF_Ethanol_solubility_exploit.py
+931 −0 biorefineries/TAL/analyses/full/1_uncertainties_SA_solubility_exploit.py
+335 −84 biorefineries/TAL/analyses/full/1_uncertainties_TAL_solubility_exploit.py
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_A.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_B.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_C.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_D.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_E.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_F.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_G.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_H.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_Sorbate_THF_Ethanol_A.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_TAL_A.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_TAL_B.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_TAL_C.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/parameter-distributions_TAL_D.xlsx
+ biorefineries/TAL/analyses/full/parameter_distributions/scenarios_key.xlsx
+73 −54 biorefineries/TAL/analyses/production_operation/TALproductioncapacity_operatingdays.py
+882 −0 ...ing/reaction_yields_times/upgrading_dehydration-etherification-hydrolysis_time_conversion_catalyst-price.py
+882 −0 ...ries/TAL/analyses/upgrading/reaction_yields_times/upgrading_hydrogenation_time_conversion_catalyst-price.py
+883 −0 ...TAL/analyses/upgrading/reaction_yields_times/upgrading_ring-opening-hydrolysis_time_conversion_KOH-price.py
+0 −434 biorefineries/TAL/analyses/upgrading/upgrading_YYY_analysis.py
+0 −439 biorefineries/TAL/analyses/upgrading/upgrading_dehydration_YRF_analysis.py
+0 −436 biorefineries/TAL/analyses/upgrading/upgrading_dehydration_YtC_analysis.py
+0 −439 biorefineries/TAL/analyses/upgrading/upgrading_dehydration_YtCprice_analysis.py
+0 −477 biorefineries/TAL/analyses/upgrading/upgrading_hydrogenation_RtCprice_analysis.py
+0 −444 biorefineries/TAL/analyses/upgrading/upgrading_hydrogenation_YtCprice_analysis.py
+7 −7 biorefineries/TAL/chemicals_data.py
+447 −0 biorefineries/TAL/models/models_SA_THF_Ethanol_solubility_exploit.py
+447 −0 biorefineries/TAL/models/models_SA_solubility_exploit.py
+2 −2 biorefineries/TAL/models/models_TAL_solubility_exploit.py
+ biorefineries/TAL/models/solubility/experimental_data_TAL_solubility_in_water.xlsx
+59 −5 biorefineries/TAL/models/solubility/plot_utils.py
+394 −60 biorefineries/TAL/process_areas.py
+81 −21 biorefineries/TAL/process_settings.py
+848 −0 biorefineries/TAL/systems/system_SA_THF_Ethanol_solubility_exploit_ethanol_sugarcane.py
+39 −24 biorefineries/TAL/systems/system_SA_solubility_exploit_ethanol_sugarcane.py
+9 −6 biorefineries/TAL/systems/system_TAL_solubility_exploit_ethanol_sugarcane.py
+90 −88 biorefineries/TAL/units.py
+ biorefineries/cane/results/expenditures.xlsx
+ biorefineries/cane/results/life_cycle.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_7_1566_baseline_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_7_1566_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_7_Ideal_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_7_Target_baseline_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_7_Target_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_7_oilcane_vs_sugarcane.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_9_1566_baseline_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_9_1566_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_9_Ideal_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_9_Target_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_9_WT.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_9_across_lines.xlsx
+ biorefineries/cane/results/oilcane_monte_carlo_9_oilcane_vs_sugarcane.xlsx
+ biorefineries/cane/results/oilcane_spearman_7_1566_baseline_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_7_1566_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_7_Ideal_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_7_Target_baseline_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_7_Target_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_9_1566_baseline_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_9_1566_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_9_Ideal_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_9_Target_target_fermentation_performance.xlsx
+ biorefineries/cane/results/oilcane_spearman_9_WT.xlsx
+48 −0 biorefineries/oxalic/__init__.py
+488 −0 biorefineries/oxalic/_general_utils.py
+ ...neries/oxalic/analyses/fermentation/AOC_animated_contourplot__(60, 60, 1)_steps_TAL_TRY_2024.4.15-19.21.gif
+ ...neries/oxalic/analyses/fermentation/FEC_animated_contourplot__(60, 60, 1)_steps_TAL_TRY_2024.4.15-19.21.gif
+ ...neries/oxalic/analyses/fermentation/GWP_animated_contourplot__(60, 60, 1)_steps_TAL_TRY_2024.4.15-19.21.gif
+ ...eries/oxalic/analyses/fermentation/MPSP_animated_contourplot__(60, 60, 1)_steps_TAL_TRY_2024.4.15-19.21.gif
+ ...ies/oxalic/analyses/fermentation/Purity_animated_contourplot__(60, 60, 1)_steps_TAL_TRY_2024.4.15-19.21.gif
+ ...neries/oxalic/analyses/fermentation/TCI_animated_contourplot__(60, 60, 1)_steps_TAL_TRY_2024.4.15-19.21.gif
+878 −0 biorefineries/oxalic/analyses/fermentation/TRY_analysis.py
+891 −0 biorefineries/oxalic/analyses/full/1_uncertainties_TAL_solubility_exploit.py
+265 −0 biorefineries/oxalic/analyses/full/plot_utils.py
+531 −0 biorefineries/oxalic/chemicals_data.py
+652 −0 biorefineries/oxalic/facilities.py
+238 −0 biorefineries/oxalic/models/_general_process_specification.py
+769 −0 biorefineries/oxalic/models/_process_specification.py
+84 −0 biorefineries/oxalic/models/model_utils.py
+443 −0 biorefineries/oxalic/models/models.py
+232 −0 biorefineries/oxalic/process_areas.py
+430 −0 biorefineries/oxalic/process_settings.py
+15 −0 biorefineries/oxalic/requirements.txt
+829 −0 biorefineries/oxalic/systems/system.py
+19 −0 biorefineries/oxalic/tea.py
+1,286 −0 biorefineries/oxalic/units.py
+282 −0 biorefineries/oxalic/utils.py
178 changes: 178 additions & 0 deletions benchmark/acetic_acid_reactive_purification_system.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
# -*- coding: utf-8 -*-
"""
Created on Sat Mar 16 13:38:11 2024
@author: cortespea
"""
import thermosteam as tmo
import biosteam as bst
import numpy as np
from thermosteam.constants import R
from math import exp
try:
from .profile import register
except:
def register(*args, **kwargs):
return lambda f: f

__all__ = (
'create_system_acetic_acid_reactive_purification',
)

@register(
'acetic_acid_reactive_purification', 'Acetic acid reactive purification',
10, [2, 4, 6, 8, 10], 'AA\nr. sep.'
)
def create_system_acetic_acid_reactive_purification(alg='sequential modular'):
bst.settings.set_thermo(['Water', 'AceticAcid', 'MethylAcetate', 'Methanol'], cache=True)
Gamma = tmo.equilibrium.DortmundActivityCoefficients(bst.settings.chemicals)
class Esterification(bst.KineticReaction):
def volume(self, stream): # kg of catalyst
rho_cat = 770 # kg / m3
liquid_volume = self.liquid_volume
catalyst_volume = 0.5 * liquid_volume
catalyst_mass = catalyst_volume * rho_cat
return catalyst_mass

def rate(self, stream): # kmol/kg-catalyst/hr
K_AcOH = 3.15
K_MeOH = 5.64
K_MeOAc = 4.15
K_H2O = 5.24
K_adsorption = np.array([K_H2O, K_AcOH, K_MeOAc, K_MeOH])
MWs = stream.chemicals.MW
k0f = 8.497e6
EAf = 60.47
k0r = 6.127e5
EAr = 63.73
T = stream.T
mol = stream.mol.to_array()
F_mol = stream.F_mol
if not F_mol: return 0
x = mol / F_mol
gamma = Gamma(x, T)
activity = gamma * x
a = K_adsorption * activity / MWs
H2O, LA, BuLA, BuOH = activity
kf = k0f * exp(-EAf / (R * T))
kr = k0r * exp(-EAr / (R * T))
a_sum = sum(a)
return 3600 * (kf * LA * BuOH - kr * BuLA * H2O) / (a_sum * a_sum) # kmol / kg-catalyst / hr

with bst.System(algorithm=alg) as sys:
feed = bst.Stream(
'feed',
LacticAcid=4.174,
Water=5.470,
)
feed.vle(V=0.5, P=101325)
makeup_butanol = bst.Stream('makeup_butanol', Butanol=1)
makeup_butanol.T = makeup_butanol.bubble_point_at_P().T
recycle_butanol = bst.Stream('recycle_butanol')
esterification_reflux = bst.Stream('esterification_reflux')
esterification = bst.MESHDistillation(
'esterification',
ins=(feed, makeup_butanol, recycle_butanol, esterification_reflux),
outs=('empty', 'bottoms', 'esterification_distillate'),
N_stages=6,
feed_stages=(3, 3, 3, 0),
stage_specifications={
5: ('Boilup', 1),
0: ('Boilup', 0),
},
liquid_side_draws={
0: 1,
},
stage_reactions={
i: Esterification('LacticAcid + Butanol -> Water + ButylLactate', reactant='LacticAcid')
for i in range(1, 5)
},
maxiter=10,
# LHK=('LacticAcid', 'Butanol'),
LHK=('Butanol', 'ButylLactate'),
P=0.3 * 101325,
)
@esterification.add_specification(run=True)
def adjust_flow():
target = 5.85
makeup_butanol.imol['Butanol'] = max(target - recycle_butanol.imol['Butanol'], 0)

esterification.simulate()
for i in esterification.stages: print(i.Hnet)
esterification.show()
breakpoint()
# esterification.simulate()
# for i in esterification.stages: print(i.Hnet)
# esterification.stage_reactions={
# i: Esterification('LacticAcid + Butanol -> Water + ButylLactate', reactant='LacticAcid')
# for i in range(1, 17)
# }
# esterification.LHK=('Butanol', 'ButylLactate')
# breakpoint()
# esterification.simulate()
esterification_settler = bst.StageEquilibrium(
'esterification_settler',
ins=(esterification-2),
outs=(esterification_reflux, 'water_rich'),
phases=('L', 'l'),
top_chemical='Butanol',
)
water_distiller = bst.BinaryDistillation(
ins=esterification_settler-1, outs=('water_rich_azeotrope', 'water'),
x_bot=0.0001, y_top=0.2, k=1.2, Rmin=0.01,
LHK=('Butanol', 'Water'),
)
splitter = bst.Splitter(ins=water_distiller-1, split=0.5) # TODO: optimize split
hydrolysis_reflux = bst.Stream('hydrolysis_reflux')
hydrolysis = bst.MESHDistillation(
'hydrolysis',
ins=(esterification-1, splitter-0, hydrolysis_reflux),
outs=('empty', 'lactic_acid', 'hydrolysis_distillate'),
N_stages=53,
feed_stages=(27, 50, 0),
stage_specifications={
0: ('Boilup', 0),
52: ('Boilup', 1),
},
liquid_side_draws={
0: 1.0,
},
stage_reactions={
i: Esterification('LacticAcid + Butanol -> Water + ButylLactate', reactant='LacticAcid')
for i in range(1, 52) # It will run in reverse
},
P=101325,
LHK=('Butanol', 'LacticAcid'),
)

# @esterification.add_specification(run=True)
# def adjust_flow():
# target = 5.85
# makeup_butanol.imol['Butanol'] = max(target - recycle_butanol.imol['Butanol'], 0)

# Decanter
butanol_rich_azeotrope = bst.Stream('butanol_rich_azeotrope')
hydrolysis_settler = bst.StageEquilibrium(
'settler',
ins=(hydrolysis-2, water_distiller-0, butanol_rich_azeotrope),
outs=('butanol_rich_extract', hydrolysis_reflux),
phases=('L', 'l'),
top_chemical='Butanol',
T=310,
)

# Butanol purification
butanol_distiller = bst.BinaryDistillation(
ins=(hydrolysis_settler-0),
outs=(butanol_rich_azeotrope, recycle_butanol),
x_bot=0.0001, y_top=0.6, k=1.2, Rmin=0.01,
LHK=('Water', 'Butanol'),
)

return sys

if __name__ == '__main__':
sys = create_system_acetic_acid_reactive_purification()
sys.flatten()
sys.diagram()
sys.simulate()
34 changes: 25 additions & 9 deletions benchmark/lactic_acid_purification_system.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,43 +39,59 @@ def rate(self, stream): # kmol/kg-catalyst/hr
kf = 2.59e4 * exp(-5.340e4 / (R * T))
kr = 3.80e3 * exp(-5.224e4 / (R * T))
H2O, LA, BuLA, BuOH = stream.mol / stream.F_mol
return self.stoichiometry * 3600 * (kf * LA * BuOH - kr * BuLA * H2O) # kmol / kg-catalyst / hr
return 3600 * (kf * LA * BuOH - kr * BuLA * H2O) # kmol / kg-catalyst / hr

with bst.System(algorithm=alg) as sys:
feed = bst.Stream(
'feed',
LacticAcid=4.174,
Water=5.470,
)
makeup_butanol = bst.Stream('makeup_butanol')
feed.vle(V=0.5, P=101325)
makeup_butanol = bst.Stream('makeup_butanol', Butanol=1)
makeup_butanol.T = makeup_butanol.bubble_point_at_P().T
recycle_butanol = bst.Stream('recycle_butanol')
esterification_reflux = bst.Stream('esterification_reflux')
esterification = bst.MESHDistillation(
'esterification',
ins=(feed, makeup_butanol, recycle_butanol, esterification_reflux),
outs=('empty', 'bottoms', 'esterification_distillate'),
N_stages=17,
feed_stages=(1, 16, 16, 0),
N_stages=6,
feed_stages=(3, 3, 3, 0),
stage_specifications={
16: ('Boilup', 1),
5: ('Boilup', 1),
0: ('Boilup', 0),
},
liquid_side_draws={
0: 1.0,
0: 1,
},
stage_reactions={
i: Esterification('LacticAcid + Butanol -> Water + ButylLactate', reactant='LacticAcid')
for i in range(1, 17)
for i in range(1, 5)
},
maxiter=200,
maxiter=10,
# LHK=('LacticAcid', 'Butanol'),
LHK=('Butanol', 'ButylLactate'),
P=0.3 * 101325,
)
@esterification.add_specification(run=True)
def adjust_flow():
target = 5.85
makeup_butanol.imol['Butanol'] = max(target - recycle_butanol.imol['Butanol'], 0)


esterification.simulate()
for i in esterification.stages: print(i.Hnet)
esterification.show()
breakpoint()
# esterification.simulate()
# for i in esterification.stages: print(i.Hnet)
# esterification.stage_reactions={
# i: Esterification('LacticAcid + Butanol -> Water + ButylLactate', reactant='LacticAcid')
# for i in range(1, 17)
# }
# esterification.LHK=('Butanol', 'ButylLactate')
# breakpoint()
# esterification.simulate()
esterification_settler = bst.StageEquilibrium(
'esterification_settler',
ins=(esterification-2),
Expand Down
5 changes: 3 additions & 2 deletions biosteam/_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def {flowmethname}(self):
get_unit_utility_cost_executable = '''
def {costmethname}(self):
"""Return the {docname} cost [USD/hr]."""
return bst.stream_prices[name] * self.{flowmethname}()
return bst.stream_prices[{name}] * self.{flowmethname}()
bst.Unit.{costmethname} = {costmethname}
'''
Expand Down Expand Up @@ -199,7 +199,8 @@ def define_allocation_property(

# %% Register stream utilities

settings.register_utility('Natural gas', 0.218)
settings.register_utility('Fuel', 0.218) # Natural gas
settings.register_utility('Natural gas', 0.218) # Natural gas
settings.register_utility('Ash disposal', -0.0318)
settings.register_utility('Reverse osmosis water', 5.6e-4)
settings.register_utility('Process water', 2.7e-4)
Expand Down
Loading

0 comments on commit 25e0a96

Please sign in to comment.