-
Notifications
You must be signed in to change notification settings - Fork 57
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BSM2 Anoxic CSTR Costing #1186
BSM2 Anoxic CSTR Costing #1186
Changes from 21 commits
1245716
4fe4d9a
a21cb8e
94ec318
e7a9539
6658fa9
dbb3211
e1477bf
816409d
82e719f
fbcc50b
228d8fe
9e18c86
835d9a8
df546bc
fbc092d
b62db8f
7386242
ae15d4a
3bccd1e
65870ff
af96904
390eb5a
9e2b42b
55c4503
fb2a438
b9d2c71
5babe49
fc56ef6
d49433b
c06f4a5
e92f616
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
################################################################################# | ||
# WaterTAP Copyright (c) 2020-2023, The Regents of the University of California, | ||
# through Lawrence Berkeley National Laboratory, Oak Ridge National Laboratory, | ||
# National Renewable Energy Laboratory, and National Energy Technology | ||
# Laboratory (subject to receipt of any required approvals from the U.S. Dept. | ||
# of Energy). All rights reserved. | ||
# | ||
# Please see the files COPYRIGHT.md and LICENSE.md for full copyright and license | ||
# information, respectively. These files are also available online at the URL | ||
# "https://github.com/watertap-org/watertap/" | ||
################################################################################# | ||
|
||
import pyomo.environ as pyo | ||
from ..util import ( | ||
register_costing_parameter_block, | ||
make_capital_cost_var, | ||
) | ||
|
||
|
||
def build_cstr_cost_param_block(blk): | ||
# Source: https://www.fwrj.com/articles/9812.pdf | ||
blk.sizing_cost = pyo.Var( | ||
initialize=0.34, | ||
doc="Reactor sizing cost", | ||
units=pyo.units.USD_1998 / pyo.units.m**3, | ||
) | ||
|
||
|
||
@register_costing_parameter_block( | ||
build_rule=build_cstr_cost_param_block, | ||
parameter_block_name="cstr", | ||
) | ||
def cost_cstr(blk): | ||
""" | ||
CSTR costing method | ||
""" | ||
cost_cstr_capital( | ||
blk, | ||
blk.costing_package.cstr.sizing_cost, | ||
) | ||
|
||
|
||
def cost_cstr_capital(blk, sizing_cost): | ||
""" | ||
Generic function for costing an ElectroNP system. | ||
""" | ||
make_capital_cost_var(blk) | ||
|
||
blk.sizing_cost = pyo.Expression(expr=sizing_cost) | ||
|
||
flow_in = pyo.units.convert( | ||
blk.unit_model.control_volume.properties_in[0].flow_vol, | ||
to_units=pyo.units.m**3 / pyo.units.hr, | ||
) | ||
|
||
HRT = pyo.units.convert( | ||
blk.unit_model.volume[0] | ||
/ blk.unit_model.control_volume.properties_in[0].flow_vol, | ||
to_units=pyo.units.hr, | ||
) | ||
|
||
print(f"base_currency: {blk.costing_package.base_currency}") | ||
blk.capital_cost_constraint = pyo.Constraint( | ||
expr=blk.capital_cost | ||
== pyo.units.convert( | ||
HRT * flow_in * blk.sizing_cost, | ||
to_units=blk.costing_package.base_currency, | ||
) | ||
) | ||
MarcusHolly marked this conversation as resolved.
Show resolved
Hide resolved
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
############################################################################### | ||
# WaterTAP Copyright (c) 2021, The Regents of the University of California, | ||
# through Lawrence Berkeley National Laboratory, Oak Ridge National | ||
# Laboratory, National Renewable Energy Laboratory, and National Energy | ||
# Technology Laboratory (subject to receipt of any required approvals from | ||
# the U.S. Dept. of Energy). All rights reserved. | ||
# | ||
# Please see the files COPYRIGHT.md and LICENSE.md for full copyright and license | ||
# information, respectively. These files are also available online at the URL | ||
# "https://github.com/watertap-org/watertap/" | ||
# | ||
############################################################################### | ||
""" | ||
Anoxic CSTR unit model for BSM2 and plant-wide wastewater treatment modeling. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rename filename to |
||
This unit inherits from the IDAES CSTR unit. | ||
""" | ||
|
||
# Import IDAES cores | ||
from idaes.core import ( | ||
declare_process_block_class, | ||
) | ||
from idaes.models.unit_models.cstr import CSTRData | ||
|
||
import idaes.logger as idaeslog | ||
|
||
from pyomo.environ import ( | ||
Constraint, | ||
NonNegativeReals, | ||
Var, | ||
units as pyunits, | ||
) | ||
|
||
from watertap.costing.unit_models.cstr import cost_cstr | ||
|
||
__author__ = "Marcus Holly" | ||
|
||
|
||
# Set up logger | ||
_log = idaeslog.getLogger(__name__) | ||
|
||
|
||
@declare_process_block_class("AnoxicCSTR") | ||
class AnoxicCSTRData(CSTRData): | ||
""" | ||
Anoxic CSTR unit block for BSM2 | ||
""" | ||
|
||
CONFIG = CSTRData.CONFIG() | ||
|
||
def build(self): | ||
""" | ||
Begin building model. | ||
Args: | ||
None | ||
Returns: | ||
None | ||
""" | ||
|
||
# Call UnitModel.build to set up dynamics | ||
super(AnoxicCSTRData, self).build() | ||
|
||
self.HRT = Var( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know that we used the acronym (HRT) in ZO models previously. I spelled it out in my recent PR and I think @agarciadiego did too. We should be consistent and spell it out here too. |
||
self.flowsheet().time, | ||
initialize=4, | ||
domain=NonNegativeReals, | ||
units=pyunits.s, | ||
doc="Hydraulic retention time", | ||
) | ||
|
||
def CSTR_retention_time_rule(self, t): | ||
return ( | ||
self.HRT[t] | ||
== self.volume[t] / self.control_volume.properties_in[t].flow_vol | ||
) | ||
|
||
self.CSTR_retention_time = Constraint( | ||
self.flowsheet().time, | ||
rule=CSTR_retention_time_rule, | ||
doc="Total CSTR retention time", | ||
) | ||
|
||
@property | ||
def default_costing_method(self): | ||
return cost_cstr |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the unit cost for the largest size shown in the range from the reference. Perhaps we should choose a value like the mean or median.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The reason I chose the largest size is because the flowrate in BSM2 actually goes way beyond the ranges listed in this reference. The largest flow in the reference is 100,000 GPD (378.5 m3/day) whereas the BSM2 feed flowrate is 20648 m3/day. So I didn't think it made sense to choose a mean or median value. Although if we intend on using this CSTR for non-BSM2 purposes, then it would make more sense to use an average value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fair enough!