qsd-group / exposan Goto Github PK
View Code? Open in Web Editor NEWEXPOsition of sanitation and resource recovery systems
Home Page: https://qsdsan.com
License: Other
EXPOsition of sanitation and resource recovery systems
Home Page: https://qsdsan.com
License: Other
See _cmps.py and systems.py in biogenic_refinery (this link leads to EXPOsan-private, you need to sign in to look at it), this will make sure that in the case some bugs are found in one system, other systems will be updated as well
Just want to check with you @haclohman and make sure we aren't missing anything, in the Biogenic Refinery (and also NEWgenerator), we use price_ratio
to adjust material stream price, e.g.,:
But I'm not seeing similar lines in the Reclaimer module, is it because there is no such streams to adjust?
What are these modules for?
https://github.com/QSD-Group/EXPOsan/tree/BR_OmniProcessor/exposan/biogenic_refinery
Not need to recreate a new function if the difference is just:
MCF_decay
and N2O_EF
EXPOsan/exposan/biogenic_refinery/models.py
Line 743 in 8420ffc
Additionally, I think baseline=b
should probably be baseline=2*b
Is it intentional that flowrate in system C is calculated based on a unit in system A?
EXPOsan/exposan/biogenic_refinery/systems.py
Line 1093 in 8420ffc
I think multiple units have this attribute (at least in the BR system, e.g., A8
and A12
), but I didn't see codes that would keep them consistent in simulation
I was trying to run all the systems together for different countries, it worked perfectly for the first country, then failed as it transitioned into the second country.
The error seems to be related to impact items, essentially the impact items for the second system weren't loaded, but I'm not sure why this error could occur, I can think of ways to bypass this (e.g., force reload all impact items), but that'll lead to creation of more objects which will certainly slow the speed.
Looking back at the code - current a new model is create for each system for each country, but transitioning between countries doesn't need a new model, we can just update the model parameter values, so I'd like to update the country_specific.py
module for this, I think the followings should be done:
create_country_specific_model
func should only create a new model when it's not provided, if a model is provided, it can just update the valuesinput_dct
to a centralized place (as a standalone spreadsheet) - I just realized all the input_dct
in different systems are the same (and they should be), moving to one place will make sure that updates can be reflected across modules - users can provide different input_dct
if they wantIf 20 is the lifetime of the system, what is 12? Why is it not 24 (hr per day)?
EXPOsan/exposan/biogenic_refinery/systems.py
Line 689 in 8420ffc
Additionally, this way of calculation won't give the correct answer if there's uncertainty around lifetime
If you want mol, use imol
, don't use imass
then divide by the MW
And here, MW of P is about 31, not 30
EXPOsan/exposan/biogenic_refinery/systems.py
Line 904 in 8420ffc
@lsrowles
Working on updating the POU disinfection module (see pou_disinfection
branch), listing the potential bugs to be confirmed, because your original codes aren't on GitHub, I have to use screenshots here:
>>> def test(turbidity, hardness):
>>> print(f'turbidity is {turbidity}, hardness is {hardness}')
>>> if turbidity <= 10 and hardness <= 60:
>>> print('lifetime is 2')
>>> elif turbidity > 10 or hardness > 60:
>>> print('lifetime is 1.5')
>>> elif turbidity > 10 and hardness > 60:
>>> print('lifetime is 0.5')
>>> test(5, 5)
turbidity is 5, hardness is 5
lifetime is 2
>>> test(15, 5)
turbidity is 15, hardness is 5
lifetime is 1.5
>>> test(15, 65)
turbidity is 15, hardness is 65
lifetime is 1.5
Instead, you should do this:
>>> def test2(turbidity, hardness):
>>> print(f'turbidity is {turbidity}, hardness is {hardness}')
>>> if turbidity <= 10 and hardness <= 60:
>>> print('lifetime is 2')
>>> elif turbidity > 10 and hardness > 60:
>>> print('lifetime is 0.5')
>>> else: print('lifetime is 1.5')
>>> test2(5, 5)
turbidity is 5, hardness is 5
lifetime is 2
>>> test2(15, 5)
turbidity is 15, hardness is 5
lifetime is 1.5
>>> test2(15, 65)
turbidity is 15, hardness is 65
lifetime is 0.5
Right now all the systems in the gates are set up in a similar way, but util functions like batch_setting_unit_params are defined in those systems, some of them have been updated with time, but some not, leading to some bugs. These functions should be consolidated to a central place
I think the codes here (and all other places that use a similar way to calculate N recovery):
EXPOsan/exposan/biogenic_refinery/systems.py
Line 526 in 8420ffc
should be
sysA_N_toilet_fugitive_out = A2.outs[3].imass['N2O'] * (28/44) * time_period
One mol of N2O has two N atoms
Why is this commented out?
EXPOsan/exposan/biogenic_refinery/_cmps.py
Line 152 in 8420ffc
The sysD (baseline system) in systems.py and models.py needs to be updated.
sysD in models.py L833-841 needs to be edited to include the drying bed
EXPOsan/exposan/biogenic_refinery/systems.py
Line 833 in 315338b
The updated code is as follows:
D5 = su.DryingBed('D5', ins=D4-0, outs=('dried_sludge', 'evaporated',
'A8_CH4', 'A8_N2O'),
design_type='unplanted',
decay_k_COD=get_decay_k(tau_deg, log_deg),
decay_k_N=get_decay_k(tau_deg, log_deg),
max_CH4_emission=max_CH4_emission)
D6 = su.Mixer('D6', ins=(D2-2, D4-1, D5-2), outs=streamsD['CH4'])
D6.specification = lambda: add_fugitive_items(D5, 'CH4_item')
D6.line = 'fugitive CH4 mixer'
D7 = su.Mixer('D7', ins=(D2-3, D4-2, D5-3), outs=streamsD['N2O'])
D7.specification = lambda: add_fugitive_items(D6, 'N2O_item')
D7.line = 'fugitive N2O mixer'
sysD = bst.System('sysD', path=(D1, D2, D3, D4, D5, D6, D7))
Also in systems.py, the unit dictionary for sysD needs to be updated.
L876-879 needs include the units for sysD
EXPOsan/exposan/biogenic_refinery/systems.py
Line 876 in 315338b
The following lines should included:
'front_end': dict(sysA=(A2,), sysB=(B2,), sysC=None, sysD=(D2,)),
'transport': dict(sysA=(A3,), sysB=(B3,B4,), sysC=None, sysD=(D3,)),
'pretreatment': dict(sysA=(A6,), sysB=(B10,), sysC=None, sysD=(D4,)),
'liq_treatment': dict(sysA=(A7,), sysB=(B5,B6,B7), sysC=None, sysD=(D7,)),
In models.py, the drying bed needs to be included prior to L878.
EXPOsan/exposan/biogenic_refinery/models.py
Line 878 in 315338b
These additions are as follows:
drying_bed_data = load_data(join_path(su_data_path, '_drying_bed.tsv'))
batch_setting_unit_params(drying_bed_data, modelD, systems.D5)
In models.py, lines 489-505, 537-553, 643, these parameters were commented out, I can understand that they are excluded when country-specific
is True as their values will be updated separately, but in the current that it's coded, they would be excluded from uncertainty analysis, should they be included or not?
EXPOsan/exposan/biogenic_refinery/models.py
Line 489 in 8420ffc
Hi @joyxyz1994 @jiananf2 , can you add a README for your modules (e.g., like this one for BSM1, doesn't have to be that nice, but just at least show others how to create/simulate the system...)
The input_dict
used for each country (e.g., here for BR), are they supposed be have the same values? If so, should put in a central position rather than recreate in each system
I see multiple units (e.g., ScrewPress
) being used across different systems, it'll be more efficient (and easier for debugging) to create functions for this
Why right-hand side of line 942 and 944 are the same?
EXPOsan/exposan/biogenic_refinery/systems.py
Line 942 in 8420ffc
EXPOsan/exposan/biogenic_refinery/systems.py
Line 944 in 8420ffc
Add a module-wise INCLUDE_RESOURCE_RECOVERY
option for biogenic_refinery
, new_generator
, and reclaimer
with default values to False
(or the baseline to the publication, if there's one)
this should adjust the price/CFs in __init__.py
, and make sure the models would be adjust accordingly
See details in the failed test on QSDsan:
https://github.com/QSD-Group/QSDsan/actions/runs/5235788112
Not yet sure what happened, will try to fix it (or wait till it miraculously fixes itself, ๐), temporarily disabled the test for the interface module for now.
The recent changes in requirements.txt
is to address this failed test:
https://github.com/QSD-Group/EXPOsan/actions/runs/4887392720
But the solution isn't ideal, hopefully this is just a glitch and the added requirements can be taken out soon (or maybe QSDsan/BioSTEAM needs to add similar requirements...)
Describe the problem
Trying to add elements of the Bwaise system into a WRRF model but getting errors with implementation (notably, Excretion & PitLatrine).
To Reproduce
Steps to reproduce the behavior, e.g.:
Environment (please complete the following information):
Versions of the following packages:
Operating systems: macOS 11.6
Additional context
'''
QSDsan: Quantitative Sustainable Design for sanitation and resource recovery systems
This module is developed by:
Saumitra Rai <[email protected]>
Joy Zhang <[email protected]>
This module is under the University of Illinois/NCSA Open Source License.
Please refer to https://github.com/QSD-Group/QSDsan/blob/main/LICENSE.txt
for license details.
'''
import os, pickle, numpy as np, qsdsan as qs
from qsdsan import (
processes as pc,
sanunits as su,
WasteStream,
System,
currency,
ImpactItem,
PowerUtility,
Model,
Metric
)
from qsdsan.utils import (
AttrFuncSetter,
AttrSetter,
DictAttrSetter,
data_path,
dct_from_str,
load_data,
ospath,
time_printer,
get_SRT
)
from exposan.bsm1 import data_path
#Bwaise imports
from chaospy import distributions as shape
from thermosteam.functional import V_to_rho, rho_to_V
from exposan.utils import batch_setting_unit_params, add_fugitive_items, run_uncertainty as run
from exposan import bwaise as bw
from exposan.bwaise import (
_load_components,
create_system,
get_alt_salary,
get_biogas_factor,
get_decay_k,
get_LCA_metrics,
get_TEA_metrics,
get_recoveries,
GWP_dct,
price_dct,
results_path,
)
# %%
# =============================================================================
# Parameters and util functions
# =============================================================================
Q = 60000 # influent flowrate [m3/d]
Temp = 273.15+20 # temperature [K]
V_an_1 = 2500 # anoxic zone tank volume [m3] (HRT = 2/2 HRS, M&E)
V_an_2 = 2500 # anoxic zone tank volume [m3] (HRT = 2/2 HRS, M&E)
V_an_3 = 7500 # anoxic zone tank volume [m3] (HRT = 3 HRS, M&E)
V_ae_1 = 20000 # aerated zone tank volume [m3] (HRT = 8 HRS, M&E)
V_ae_2 = 1875 # aerated zone tank volume [m3] (HRT = 0.75 HRS, M&E)
# V_ae_2 = 2521
Q_was = 1700 # Based on trial and error to get SRT between 10-20 days [m3/day]
Q_ras = 45000 # recycle sludge flowrate (75% of influent, M&E) [m3/day]
biomass_IDs = ('X_H', 'X_AUT')
ammonia_ID = ('S_NH4',)
# aer = pc.DiffusedAeration('Fixed_Aeration', 'S_O', KLa_20=240, SOTE=0.3, V=V_ae,
# T_air=Temp, T_water=Temp, d_submergence=4-0.3)
# aer.A = 8.10765
# aer.B = 1750.286
# aer.C = 235.0
# =============================================================================
beijing_inf_kwargs = {
'concentrations': {
'S_F': 152,
'S_A': 15,
'S_I': 30,
'X_S': 25,
'X_I': 0,
'X_AUT': 0,
'X_PAO': 0,
'X_H': 0,
'X_PHA': 10,
'X_PP': 0,
'S_NH4': 38,
'S_PO4': 2.8,
'S_N2': 0,
'S_NO3': 0,
'S_ALK':7*12,
},
'units': ('m3/d', 'mg/L'),
}
default_asm2d_kwargs = dict(iN_SI=0.01, iN_SF=0.03, iN_XI=0.02, iN_XS=0.04, iN_BM=0.07,
iP_SI=0.0, iP_SF=0.01, iP_XI=0.01, iP_XS=0.01, iP_BM=0.02,
iTSS_XI=0.75, iTSS_XS=0.75, iTSS_BM=0.9,
f_SI=0.0, Y_H=0.625, f_XI_H=0.1,
Y_PAO=0.625, Y_PO4=0.4, Y_PHA=0.2, f_XI_PAO=0.1,
Y_A=0.24, f_XI_AUT=0.1,
K_h=3.0, eta_NO3=0.6, eta_fe=0.4, K_O2=0.2, K_NO3=0.5, K_X=0.1,
mu_H=6.0, q_fe=3.0, eta_NO3_H=0.8, b_H=0.4, K_O2_H=0.2, K_F=4.0,
K_fe=4.0, K_A_H=4.0, K_NO3_H=0.5, K_NH4_H=0.05, K_P_H=0.01, K_ALK_H=0.1,
q_PHA=3.0, q_PP=1.5, mu_PAO=1.0, eta_NO3_PAO=0.6, b_PAO=0.2, b_PP=0.2,
b_PHA=0.2, K_O2_PAO=0.2, K_NO3_PAO=0.5, K_A_PAO=4.0, K_NH4_PAO=0.05,
K_PS=0.2, K_P_PAO=0.01, K_ALK_PAO=0.1,
K_PP=0.01, K_MAX=0.34, K_IPP=0.02, K_PHA=0.01,
mu_AUT=1.0, b_AUT=0.15, K_O2_AUT=0.5, K_NH4_AUT=1.0, K_ALK_AUT=0.5, K_P_AUT=0.01,
k_PRE=1.0, k_RED=0.6, K_ALK_PRE=0.5, path=os.path.join(data_path, '_asm2d.tsv'),
)
default_init_conds = {
'S_F':5,
'S_A':2,
'X_I':1000,
'X_S':100,
'X_H':500,
'X_AUT':100,
#'X_P':100,
'S_O2':2,
'S_NO3':20,
'S_NH4':2,
'S_ALK':7*12,
}
def batch_init(sys, path, sheet):
df = load_data(path, sheet)
dct = df.to_dict('index')
u = sys.flowsheet.unit # unit registry
for k in sys.units:
if k.ID.startswith('O'):
k.set_init_conc(**dct['O'])
elif k.ID.startswith('A'):
k.set_init_conc(**dct['A'])
c1s = {k:v for k,v in dct['C1_s'].items() if v>0}
c1x = {k:v for k,v in dct['C1_x'].items() if v>0}
tss = [v for v in dct['C1_tss'].values() if v>0]
u.C1.set_init_solubles(**c1s)
u.C1.set_init_sludge_solids(**c1x)
u.C1.set_init_TSS(tss)
#%%
# =============================================================================
# Data Sheets
# =============================================================================
join_path = lambda prefix, file_name: os.path.join(prefix, file_name)
su_data_path = '/Users/willobrien/QSDsan/qsdsan/data/sanunit_data'
#su_data_path = ospath.join(data_path, 'sanunit_data')
excretion_data = load_data(join_path(su_data_path, '_excretion.tsv'))
toilet_data = load_data(join_path(su_data_path, '_toilet.tsv'))
pit_latrine_data = load_data(join_path(su_data_path, '_pit_latrine.tsv'))
uddt_data = load_data(join_path(su_data_path, '_uddt.tsv'))
drying_bed_data = load_data(join_path(su_data_path, '_drying_bed.tsv'))
liquid_bed_data = load_data(join_path(su_data_path, '_liquid_treatment_bed.tsv'))
sedimentation_tank_data = load_data(join_path(su_data_path, '_sedimentation_tank.tsv'))
anaerobic_lagoon_data = load_data(join_path(su_data_path, '_anaerobic_lagoon.tsv'))
facultative_lagoon_data = load_data(join_path(su_data_path, '_facultative_lagoon.tsv'))
sludge_separator_data = load_data(join_path(su_data_path, '_sludge_separator.tsv'))
abr_data = load_data(join_path(su_data_path, '_anaerobic_baffled_reactor.tsv'))
#%%
# =============================================================================
# Benchmark Simulation Model No. 1
# =============================================================================
#Changed function name to ensure no issues with _components.py
def create_components():
asm2d_cmps = pc.create_asm2d_cmps()
asm2d_cmps.X_S.f_BOD5_COD = 0.54
# CO2 = qs.Component.from_chemical('S_CO2', search_ID='CO2', particle_size='Dissolved gas', degradability='Undegradable', organic=False)
# CH4 = qs.Component.from_chemical('S_CH4', search_ID='CH4', particle_size='Dissolved gas', degradability='Undegradable', organic=False)
# H2 = qs.Component.from_chemical('S_H2', search_ID='H2', particle_size='Dissolved gas', degradability='Undegradable', organic=False)
# cmps1 = qs.Components.load_default()
# ash = cmps1.X_Ig_ISS.copy('ash')
cmps = qs.Components([*asm2d_cmps,
# CO2, CH4, H2, ash
])
cmps.compile()
return cmps
def create_system(flowsheet=None, inf_kwargs={}, asm_kwargs={}, init_conds={},
aeration_processes=()):
flowsheet = flowsheet or qs.Flowsheet('bsm1')
qs.main_flowsheet.set_flowsheet(flowsheet)
# Components and stream
cmps = create_components()
qs.set_thermo(cmps)
wastewater = WasteStream('wastewater', T=Temp)
#inf_kwargs = inf_kwargs or default_inf_kwargs
inf_kwargs = beijing_inf_kwargs
wastewater.set_flow_by_concentration(Q, **inf_kwargs)
effluent = WasteStream('effluent', T=Temp)
WAS = WasteStream('WAS', T=Temp)
RAS = WasteStream('RAS', T=Temp)
flowthrough = WasteStream('flowthrough', T=Temp)
recycle = WasteStream('recycle', T=Temp)
#Add Bwaise System Elements
B1 = su.Excretion('B1', outs=('urine', 'feces'))
B2 = su.PitLatrine('B2', ins=(B1-0, B1-1,
'toilet_paper', 'flushing_water',
'cleansing_water', 'desiccant'),
outs=('mixed_waste', 'leachate', 'A2_CH4', 'A2_N2O'),
OPEX_over_CAPEX=0.05,
decay_k_COD=3,
decay_k_N=3,
max_CH4_emission=0.25
)
B3 = su.Trucking('B3', ins=B2-0, outs=('transported', 'conveyance_loss'),
load_type='mass', distance=5, distance_unit='km',
interval=0.8, interval_unit='yr',
loss_ratio=0.02)
B4 = su.Sedimentation('B4', ins=B3-0,
outs=('liq', 'sol', 'A5_CH4', 'A5_N2O'),
decay_k_COD=3,
decay_k_N=3,
max_CH4_emission=0.25)
B5 = su.DryingBed('B5', ins=B4-1, outs=('dried_sludge', 'evaporated',
'DB1_CH4', 'DB1_N2O'),
design_type='unplanted',
decay_k_COD=3,
decay_k_N=3,
max_CH4_emission=0.25)
M1 = su.Mixer('M1', ins=(B2-2, B4-2, B5-2), outs='CH4')
#A7 = su.Mixer('A7', ins=(A2-1, A4-2, A5-2), outs=streamA.CH4)
M1.add_specification(lambda: add_fugitive_items(M1, 'CH4_item'))
M1.line = 'fugitive CH4 mixer'
M2 = su.Mixer('M2', ins=(B2-3, B4-3, B5-3), outs='N2O')
M2.add_specification(lambda: add_fugitive_items(M2, 'N2O_item'))
M2.line = 'fugitive N2O mixer'
# Process models
# if aeration_processes:
# aer1, aer2, aer3 = aeration_processes
# else:
# aer1 = aer2 = pc.DiffusedAeration('aer1', 'S_O', KLa=240, DOsat=8.0, V=V_ae)
# aer3 = pc.DiffusedAeration('aer3', 'S_O', KLa=84, DOsat=8.0, V=V_ae)
# # asm_kwargs = asm_kwargs or default_asm_kwargs
asm2d = pc.ASM2d(iP_SF=0.005, iP_XS=0.005, iP_XI=0.005, iN_BM=0.1, iTSS_XI=0.72)
A1 = su.CSTR('A1', [wastewater, RAS], V_max=V_an_1,
aeration=None, suspended_growth_model=asm2d)
A2 = su.CSTR('A2', [recycle, A1-0], V_max=V_an_2,
aeration=None, suspended_growth_model=asm2d)
O1 = su.CSTR('O1', A2-0, V_max=V_ae_1, aeration= 2, DO_ID='S_O2',
suspended_growth_model=asm2d)
S1 = qs.sanunits.Splitter('S1', ins=O1-0, outs=(flowthrough, recycle),
split=0.3684, init_with='WasteStream')
A3 = su.CSTR('A3', flowthrough, V_max=V_an_3,
aeration=None, suspended_growth_model=asm2d)
O2 = su.CSTR('O2', A3-0, V_max=V_ae_2, aeration= 2,
DO_ID='S_O2', suspended_growth_model=asm2d)
C1 = su.FlatBottomCircularClarifier('C1', O2-0, [effluent, RAS, WAS],
underflow=Q_ras, wastage=Q_was,
surface_area= 24226, height=6, N_layer=10,
feed_layer=5, X_threshold=3000, v_max=474,
v_max_practical=250, rh=5.76e-4, rp=2.86e-3,
fns=2.28e-3)
sys = qs.System('metro_ASM2d', path=(B1, B2, B3, B4, B5, M1, M2, A1, A2, O1,
S1, A3, O2, C1), recycle = [RAS, recycle])
return sys
#%%
@time_printer
# =============================================================================
# def create_components():
# asm1_cmps = pc.create_asm1_cmps()
# CO2 = qs.Component.from_chemical('S_CO2', search_ID='CO2', particle_size='Dissolved gas', degradability='Undegradable', organic=False)
# CH4 = qs.Component.from_chemical('S_CH4', search_ID='CH4', particle_size='Dissolved gas', degradability='Undegradable', organic=False)
# H2 = qs.Component.from_chemical('S_H2', search_ID='H2', particle_size='Dissolved gas', degradability='Undegradable', organic=False)
# cmps1 = qs.Components.load_default()
# ash = cmps1.X_Ig_ISS.copy('ash')
# cmps = qs.Components([*asm1_cmps, CO2, CH4, H2, ash])
# cmps.compile()
# return cmps
#
# =============================================================================
def run(t, t_step, method=None, **kwargs):
sys = create_system()
# for u in sys.units:
# if u.ID in ('O1', 'A1', 'A2', 'A3', 'O2', 'O3', 'O4', 'O5', 'O6', 'O7', 'O8', 'O9'):
# u.set_init_conc(**default_init_conds)
bw_path = os.path.dirname(__file__)
excel_path = os.path.join(bw_path, "data/initial_conditions_ASM2d.xlsx")
batch_init(sys, excel_path, sheet='t=10')
# RAS = sys.flowsheet.stream.RAS
# C1 = sys.flowsheet.unit.C1
# sys.set_dynamic_tracker(RAS, C1)
sys.set_dynamic_tracker(*sys.products)
sys.simulate(
state_reset_hook='reset_cache',
t_span=(0,t),
t_eval=np.arange(0, t+t_step, t_step),
method=method,
# rtol=1e-2,
# atol=1e-3,
# export_state_to=f'results/sol_{t}d_{method}.xlsx',
**kwargs)
sys.diagram()
return sys
if __name__ == '__main__':
t = 1
t_step = 1
method = 'RK45'
# method = 'RK23'
# method = 'DOP853'
# method = 'Radau'
# method = 'BDF'
# method = 'LSODA'
msg = f'Method {method}'
print(f'\n{msg}\n{"-"*len(msg)}') # long live OCD!
print(f'Time span 0-{t}d \n')
system = run(t, t_step, method=method)
act_units = [u.ID for u in system.units if isinstance(u, (su.CSTR, su.FlatBottomCircularClarifier))]
fs = system.flowsheet.stream
srt = get_SRT(system, biomass_IDs, wastage= [fs.WAS, fs.effluent], active_unit_IDs=act_units)
print(f'Estimated SRT assuming at steady state is {round(srt, 2)} days')
#cmps = qs.get_components()
#cmps = create_components()
f = qs.main_flowsheet
unit = system.flowsheet.unit
fs = system.flowsheet.stream
#fig, axis = fs.RAS.scope.plot_time_series(( 'S_NH'))
# fig, axis = fs.RAS.scope.plot_time_series(('S_S','S_NH'))
fig, axis = fs.effluent.scope.plot_time_series(('S_F', 'S_A', 'S_NH4', 'S_NO3'))
fig
# =============================================================================
# fig, axis = unit.C1.scope.plot_time_series(('S_S', 'S_NH'))
# fig
# =============================================================================
flowsheet = qs.Flowsheet('bsm1')
qs.main_flowsheet.set_flowsheet(flowsheet)
# Components and stream
cmps = create_components()
qs.set_thermo(cmps)
wastewater = WasteStream('wastewater', T=Temp)
#inf_kwargs = inf_kwargs or default_inf_kwargs
inf_kwargs = beijing_inf_kwargs
wastewater.set_flow_by_concentration(Q, **inf_kwargs)
effluent = WasteStream('effluent', T=Temp)
WAS = WasteStream('WAS', T=Temp)
RAS = WasteStream('RAS', T=Temp)
flowthrough = WasteStream('flowthrough', T=Temp)
recycle = WasteStream('recycle', T=Temp)
asm2d = pc.ASM2d(iP_SF=0.005, iP_XS=0.005, iP_XI=0.005, iN_BM=0.1, iTSS_XI=0.72)
__all__ = (
'biomass_IDs',
'create_system',
'default_asm2d_kwargs', 'beijing_inf_kwargs', 'default_init_conds',
'Q', 'Q_ras', 'Q_was', 'Temp', 'V_an_1', 'V_an_2', 'V_an_3', 'V_ae_1', 'V_ae_2',
'wastewater', 'inf_kwargs', 'effluent', 'WAS', 'RAS', 'flowthrough', 'recycle','asm2d'
)
@haclohman @stetsonrowles @lsrowles @lane-to @vlmorgan93 @shionwatabe
See previous issues #12 and #13, I've updated the codes for the BR system in the gates
branch (see models.py, uncertainty.py, and country_specific.py), other systems should update accordingly to make the country-specific analysis feasible
If want to exclude dietary parameters from being auto-added to the model in country-specific analysis,
EXPOsan/exposan/biogenic_refinery/models.py
Line 359 in 8420ffc
why not make sure of the country_specific
argument here?
EXPOsan/exposan/biogenic_refinery/models.py
Line 317 in 8420ffc
Documenting questions related to implementing the BSM2 configuration in EXPOsan: https://github.com/QSD-Group/EXPOsan/tree/bsm2/exposan/bsm2
Tables, etc. below refer to the BSM2 report if not otherwise noted: http://iwa-mia.org/wp-content/uploads/2022/09/TR3_BSM_TG_Tech_Report_no_3_BSM2_General_Description.pdf
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.