-
Notifications
You must be signed in to change notification settings - Fork 17
/
csmod_temp.py
179 lines (153 loc) · 6.92 KB
/
csmod_temp.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# -*- coding: utf-8 -*-
"""
Web-app model for AWS lambda
"""
import biosteam as bst
from chaospy import distributions as shape
import biorefineries.cornstover as cs
sys = cs.cornstover_sys
tea = cs.cornstover_tea
model = bst.Model(sys, exception_hook='raise')
# =============================================================================
# Define metrics
# =============================================================================
metric = model.metric
kg_per_ton = 907.185
ethanol_density_kggal = cs.ethanol_density_kggal
cornstover = cs.cornstover
ethanol = cs.ethanol
pretreatment_conversions = cs.R201.reactions.X
cofermentation_conversions = cs.R303.cofermentation.X
saccharification_conversions = cs.R303.saccharification.X
BT = cs.BT
@metric(name='Minimum ethanol selling price', units='USD/gal')
def get_MESP():
return tea.solve_price(ethanol) * ethanol_density_kggal
# Convert from kg/hr to MM gal/yr
@metric(name='Ethanol production', units='10^6*gal/yr')
def get_ethanol_production():
return ethanol.F_mass / ethanol_density_kggal * tea.operating_hours / 1e6
# Yield in gal/dry-U.S.ton
@metric(name='Ethanol yield', units='gal/dry US ton')
def get_ethanol_yield():
ethanol_galyr = ethanol.F_mass / ethanol_density_kggal
dry_feedstock_tonyr = (cornstover.F_mass - cornstover.imass['H2O']) / kg_per_ton
return ethanol_galyr / dry_feedstock_tonyr
# Total capital investment in MM$
@metric(name='Total capital investment', units='10^6*USD')
def get_TCI():
return tea.TCI / 1e6
# Annual operating cost
@metric(name='Annual operating cost', units='10^6*USD/yr')
def get_AOC():
return tea.AOC / 1e6
@metric(name='Net electricity production', units='MWhr/yr')
def get_net_electricity():
return -sys.power_utility.rate * sys.operating_hours / 1e3
@metric(name='Electricity credit', units='10^6*USD/yr')
def get_electricity_credit():
return -tea.utility_cost / 1e6
# =============================================================================
# Define parameters
# =============================================================================
def param(name, baseline, bounds=None, **kwargs):
lb = 0.9 * baseline
ub = 1.1 * baseline
if bounds is not None:
if lb < bounds[0]:
lb = bounds[0]
if ub > bounds[1]:
ub = bounds[1]
distribution = shape.Uniform(lb, ub)
return model.parameter(name=name, bounds=bounds, distribution=distribution, baseline=baseline, **kwargs)
@param(name='Cornstover price', element=cornstover, kind='isolated',
units='USD/ton', baseline=cornstover.price * kg_per_ton)
def set_cornstover_price(price):
cornstover.price = price / kg_per_ton
@param(name='Enzyme price', element=cs.cellulase, kind='isolated',
description='price of cellulase enzyme mixture containing 50 g of cellulase per 1000g of cocktail',
units='$USD/ton', baseline=cs.cellulase.price * kg_per_ton)
def set_cellulase_price(price):
cs.cellulase.price = price / kg_per_ton
@param(name='Electricity price', element='TEA', kind='isolated', units='USD/kWh',
baseline=bst.PowerUtility.price)
def set_electricity_price(price):
bst.PowerUtility.price = price
@param(name='Income tax rate', element='TEA', kind='isolated', units='%',
baseline=tea.income_tax * 100)
def set_tax_rate(rate):
tea.income_tax = rate / 100
@param(name='Plant capacity', element=cornstover, kind='coupled', units='dry US ton/yr',
baseline=(cornstover.F_mass - cornstover.imass['H2O']) * tea.operating_hours / kg_per_ton,
description="annual feestock processing capacity")
def set_plant_size(flow_rate):
dry_content = 1 - cornstover.imass['H2O'] / cornstover.F_mass
cornstover.F_mass = flow_rate / tea.operating_hours / dry_content * kg_per_ton
@param(name='PT glucan-to-glucose', element=cs.R201, kind='coupled', units='% theoretical',
description='extent of reaction, glucan + water -> glucose, in pretreatment reactor',
baseline=pretreatment_conversions[0] * 100,
bounds=(0, 100))
def set_PT_glucan_to_glucose(X):
X /= 100.
pretreatment_conversions[0] = X
corxns = pretreatment_conversions[1:3]
corxns[:] = 0.003
if pretreatment_conversions[:3].sum() > 1.:
f = corxns / corxns.sum()
corxns[:] = f * (1. - X) * 0.9999999
@param(name='PT xylan-to-xylose', element=cs.R201, kind='coupled', units='% theoretical',
description='extent of reaction, xylan + water -> xylose, in pretreatment reactor',
baseline=pretreatment_conversions[8] * 100,
bounds=(0, 100))
def set_PT_xylan_to_xylose(X):
X /= 100.
pretreatment_conversions[8] = X
corxns = pretreatment_conversions[9:11]
corxns[:] = [0.024, 0.05]
if pretreatment_conversions[8:11].sum() > 1.:
f = corxns / corxns.sum()
corxns[:] = f * (1. - X) * 0.9999999
@param(name='PT xylan-to-furfural', element=cs.R201, kind='coupled', units='% theoretical',
description='extent of reaction, xylan -> furfural + 2 water, in pretreatment reactor',
baseline=pretreatment_conversions[10] * 100,
bounds=(0, 100))
def set_PT_xylan_to_furfural(X):
# To make sure the overall xylan conversion doesn't exceed 100%
lb = 1. - pretreatment_conversions[8] - pretreatment_conversions[9]
pretreatment_conversions[10] = min(lb, X / 100.) * 0.9999999
@param(name='EH cellulose-to-glucose', element=cs.R303, kind='coupled', units='% theoretical',
description='extent of reaction, gluan + water -> glulose, in enzyme hydrolysis',
baseline=saccharification_conversions[2] * 100,
bounds=(0, 100))
def set_EH_glucan_to_glucose(X):
X /= 100.
saccharification_conversions[2] = X
corxns = saccharification_conversions[:2]
corxns[:] = [0.04, 0.0012]
if saccharification_conversions[:3].sum() > 1.:
f = corxns / corxns.sum()
corxns[:] = f * (1. - X) * 0.9999999
@param(name='FERM glucose-to-ethanol', element=cs.R303, kind='coupled', units='% theoretical',
description='extent of reaction, glucose -> 2 ethanol + 2 CO2, in enzyme hydrolysis',
baseline=cofermentation_conversions[0] * 100,
bounds=(0, 100))
def set_FERM_glucose_to_ethanol(X):
X /= 100.
cofermentation_conversions[0] = X
corxns = cofermentation_conversions[1:4]
corxns[:] = [0.02, 0.0004, 0.006]
if cofermentation_conversions[:4].sum() > 1.:
f = corxns / corxns.sum()
corxns[:] = f * (1. - X) * 0.9999999
@param(name='Boiler efficiency', element=BT, kind='coupled', units='%',
description='efficiency of burning fuel to produce steam',
baseline=BT.boiler_efficiency * 100,
bounds=(0, 100))
def set_boiler_efficiency(X):
BT.boiler_efficiency = X / 100.
@param(name='Turbogenerator efficiency', element=BT, kind='coupled', units='%',
description='efficiency of converting steam to power',
baseline=BT.turbogenerator_efficiency * 100,
bounds=(0, 100))
def set_turbogenerator_efficiency(X):
BT.turbogenerator_efficiency = X / 100.