Skip to content

Commit

Permalink
Merge pull request #127 from QSD-Group/beta
Browse files Browse the repository at this point in the history
Merge in recent updates; release new version
  • Loading branch information
yalinli2 authored Dec 10, 2024
2 parents b97d4d1 + d2edfe6 commit af5acab
Show file tree
Hide file tree
Showing 21 changed files with 1,908 additions and 48 deletions.
2 changes: 1 addition & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
# built documents.
#
# The short X.Y version.
version = '1.4.0'
version = '1.4.1'
# The full version, including alpha/beta/rc tags.
release = version

Expand Down
4 changes: 2 additions & 2 deletions qsdsan/_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -1041,8 +1041,8 @@ def load_from_file(cls, path='', components=None, data=None,
stoichio = proc[cmp_IDs]
if data.columns[-1] in cmp_IDs: rate_eq = None
else:
if pd.isna(proc[-1]): rate_eq = None
else: rate_eq = proc[-1]
if pd.isna(proc.iloc[-1]): rate_eq = None
else: rate_eq = proc.iloc[-1]
stoichio = stoichio[-pd.isna(stoichio)].to_dict()
ref = None
for k,v in stoichio.items():
Expand Down
1 change: 1 addition & 0 deletions qsdsan/_sanunit.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ def __init__(self, ID='', ins=None, outs=(), thermo=None, init_with='WasteStream
self._assert_compatible_property_package()

self._utility_cost = None
self._recycle_system = None

##### qsdsan-specific #####
for i in (*construction, *transportation, *equipment):
Expand Down
18 changes: 11 additions & 7 deletions qsdsan/_waste_stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,11 @@ def __init__(self, dct, F_vol, MW, phase, phase_container):
def output(self, index, value):
'''Concentration flows, in mg/L (g/m3).'''
f_mass = value * self.MW[index]
phase = self.phase or self.phase_container.phase
if self.phase:
phase = self.phase
else:
try: phase = self.phase_container._phase
except: phase = self.phase_container
if phase != 'l':
raise AttributeError('Concentration only valid for liquid phase.')
V_sum = self.F_vol
Expand Down Expand Up @@ -186,7 +190,7 @@ def by_conc(self, TP):
check_data=False,
)
return conc
indexer.ChemicalMolarFlowIndexer.by_conc = by_conc
ChemicalMolarFlowIndexer.by_conc = by_conc
del by_conc


Expand Down Expand Up @@ -450,7 +454,7 @@ def _wastestream_info(self, details=True, concentrations=None, N=15):
_ws_info += '\n'
# Only non-zero properties are shown
_ws_info += int(bool(self.pH))*f' pH : {self.pH:.1f}\n'
_ws_info += int(bool(self.SAlk))*f' Alkalinity : {self.SAlk:.1f} mg/L\n'
_ws_info += int(bool(self.SAlk))*f' Alkalinity : {self.SAlk:.1f} mmol/L\n'
if details:
_ws_info += int(bool(self.COD)) *f' COD : {self.COD:.1f} mg/L\n'
_ws_info += int(bool(self.BOD)) *f' BOD : {self.BOD:.1f} mg/L\n'
Expand Down Expand Up @@ -1299,7 +1303,7 @@ def codstates_inf_model(cls, ID='', flow_tot=0., units = ('L/hr', 'mg/L'),
... 9.96e+04
WasteStream-specific properties:
pH : 7.0
Alkalinity : 10.0 mg/L
Alkalinity : 10.0 mmol/L
COD : 430.0 mg/L
BOD : 221.8 mg/L
TC : 265.0 mg/L
Expand Down Expand Up @@ -1522,7 +1526,7 @@ def codbased_inf_model(cls, ID='', flow_tot=0., units = ('L/hr', 'mg/L'),
... 9.96e+04
WasteStream-specific properties:
pH : 7.0
Alkalinity : 10.0 mg/L
Alkalinity : 10.0 mmol/L
COD : 430.0 mg/L
BOD : 249.4 mg/L
TC : 265.0 mg/L
Expand Down Expand Up @@ -1751,7 +1755,7 @@ def bodbased_inf_model(cls, ID='', flow_tot=0., units = ('L/hr', 'mg/L'),
... 9.96e+04
WasteStream-specific properties:
pH : 7.0
Alkalinity : 10.0 mg/L
Alkalinity : 10.0 mmol/L
COD : 431.0 mg/L
BOD : 250.0 mg/L
TC : 264.9 mg/L
Expand Down Expand Up @@ -1983,7 +1987,7 @@ def sludge_inf_model(cls, ID='', flow_tot=0., units = ('L/hr', 'mg/L'),
... 9.88e+04
WasteStream-specific properties:
pH : 7.0
Alkalinity : 10.0 mg/L
Alkalinity : 10.0 mmol/L
COD : 10814.4 mg/L
BOD : 1744.3 mg/L
TC : 4246.5 mg/L
Expand Down
39 changes: 39 additions & 0 deletions qsdsan/data/process_data/_pm2asm2d.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
X_CHL X_ALG X_CH X_LI S_CO2 S_A S_F S_O2 S_NH S_NO S_P X_N_ALG X_P_ALG S_N2 S_ALK S_I X_I X_S X_H X_AUT
photoadaptation 1
ammonium_uptake -1 1
phosphorus_uptake -1 1
growth_pho 1 ? 1 ? ?
carbohydrate_storage_pho 1 ? 1
lipid_storage_pho 1 ? 1
carbohydrate_growth_pho 1 (-Y_CH_PHO/Y_X_ALG_PHO) ? ? ? ?
lipid_growth_pho 1 (-Y_LI_PHO/Y_X_ALG_PHO) ? ? ? ?
carbohydrate_maintenance_pho -1 ? -1
lipid_maintenance_pho -1 ? -1
endogenous_respiration_pho -1 ? -1 ? ?
growth_ace 1 ? (-1)/Y_X_ALG_HET_ACE ? ? ?
carbohydrate_storage_ace 1 ? (-1)/Y_CH_ND_HET_ACE ?
lipid_storage_ace 1 ? (-1)/Y_LI_ND_HET_ACE ?
carbohydrate_growth_ace 1 (-Y_CH_NR_HET_ACE/Y_X_ALG_HET_ACE) ? ? ? ?
lipid_growth_ace 1 (-Y_LI_NR_HET_ACE/Y_X_ALG_HET_ACE) ? ? ? ?
carbohydrate_maintenance_ace -1 ? -1
lipid_maintenance_ace -1 ? -1
endogenous_respiration_ace -1 ? -1 ? ?
growth_glu 1 ? (-1)/Y_X_ALG_HET_GLU ? ? ?
carbohydrate_storage_glu 1 ? (-1)/Y_CH_ND_HET_GLU ?
lipid_storage_glu 1 ? (-1)/Y_LI_ND_HET_GLU ?
carbohydrate_growth_glu 1 (-Y_CH_NR_HET_GLU/Y_X_ALG_HET_GLU) ? ? ? ?
lipid_growth_glu 1 (-Y_LI_NR_HET_GLU/Y_X_ALG_HET_GLU) ? ? ? ?
carbohydrate_maintenance_glu -1 ? -1
lipid_maintenance_glu -1 ? -1
endogenous_respiration_glu -1 ? -1 ? ?
aero_hydrolysis 1-f_SI ? ? ? f_SI -1
anox_hydrolysis 1-f_SI ? ? ? f_SI -1
anae_hydrolysis 1-f_SI ? ? ? f_SI -1
hetero_growth_S_F (-1)/Y_H 1-1/Y_H ? ? ? 1
hetero_growth_S_A (-1)/Y_H 1-1/Y_H ? ? ? 1
denitri_S_F (-1)/Y_H ? (Y_H-1)/(20/7*Y_H) ? (1-Y_H)/(20/7*Y_H) ? 1
denitri_S_A (-1)/Y_H ? (Y_H-1)/(20/7*Y_H) ? (1-Y_H)/(20/7*Y_H) ? 1
ferment 1 -1 ? ? ?
hetero_lysis ? ? ? f_XI_H 1-f_XI_H -1
auto_aero_growth (Y_A-32/7)/Y_A ? 1/Y_A ? ? 1
auto_lysis ? ? ? f_XI_AUT 1-f_XI_AUT -1
28 changes: 28 additions & 0 deletions qsdsan/data/process_data/_pm2asm2d_1.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
X_CHL X_ALG X_CH X_LI S_CO2 S_A S_F S_O2 S_NH S_NO S_P X_N_ALG X_P_ALG S_N2 S_ALK S_I X_I X_S X_H X_AUT
photoadaptation 1
ammonium_uptake -1 1
phosphorus_uptake -1 1
growth_pho 1 ? 1 ? ?
carbohydrate_storage_pho 1 ? 1
lipid_storage_pho 1 ? 1
carbohydrate_growth_pho 1 (-Y_CH_PHO/Y_X_ALG_PHO) ? ? ? ?
lipid_growth_pho 1 (-Y_LI_PHO/Y_X_ALG_PHO) ? ? ? ?
carbohydrate_maintenance_pho -1 ? -1
lipid_maintenance_pho -1 ? -1
endogenous_respiration_pho -1 ? -1 ? ?
growth_ace 1 ? (-1)/Y_X_ALG_HET_ACE ? ? ?
carbohydrate_storage_ace 1 ? (-1)/Y_CH_ND_HET_ACE ?
lipid_storage_ace 1 ? (-1)/Y_LI_ND_HET_ACE ?
carbohydrate_growth_ace 1 (-Y_CH_NR_HET_ACE/Y_X_ALG_HET_ACE) ? ? ? ?
lipid_growth_ace 1 (-Y_LI_NR_HET_ACE/Y_X_ALG_HET_ACE) ? ? ? ?
carbohydrate_maintenance_ace -1 ? -1
lipid_maintenance_ace -1 ? -1
endogenous_respiration_ace -1 ? -1 ? ?
growth_glu 1 ? (-1)/Y_X_ALG_HET_GLU ? ? ?
carbohydrate_storage_glu 1 ? (-1)/Y_CH_ND_HET_GLU ?
lipid_storage_glu 1 ? (-1)/Y_LI_ND_HET_GLU ?
carbohydrate_growth_glu 1 (-Y_CH_NR_HET_GLU/Y_X_ALG_HET_GLU) ? ? ? ?
lipid_growth_glu 1 (-Y_LI_NR_HET_GLU/Y_X_ALG_HET_GLU) ? ? ? ?
carbohydrate_maintenance_glu -1 ? -1
lipid_maintenance_glu -1 ? -1
endogenous_respiration_glu -1 ? -1 ? ?
12 changes: 12 additions & 0 deletions qsdsan/data/process_data/_pm2asm2d_2.tsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
X_CHL X_ALG X_CH X_LI S_CO2 S_A S_F S_O2 S_NH S_NO S_P X_N_ALG X_P_ALG S_N2 S_ALK S_I X_I X_S X_H X_AUT
aero_hydrolysis 1-f_SI ? ? ? f_SI -1
anox_hydrolysis 1-f_SI ? ? ? f_SI -1
anae_hydrolysis 1-f_SI ? ? ? f_SI -1
hetero_growth_S_F (-1)/Y_H 1-1/Y_H ? ? ? 1
hetero_growth_S_A (-1)/Y_H 1-1/Y_H ? ? ? 1
denitri_S_F (-1)/Y_H ? (Y_H-1)/(20/7*Y_H) ? (1-Y_H)/(20/7*Y_H) ? 1
denitri_S_A (-1)/Y_H ? (Y_H-1)/(20/7*Y_H) ? (1-Y_H)/(20/7*Y_H) ? 1
ferment 1 -1 ? ? ?
hetero_lysis ? ? ? f_XI_H 1-f_XI_H -1
auto_aero_growth (Y_A-32/7)/Y_A ? 1/Y_A ? ? 1
auto_lysis ? ? ? f_XI_AUT 1-f_XI_AUT -1
12 changes: 10 additions & 2 deletions qsdsan/processes/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
Joy Zhang <[email protected]>
Ga-Yeong Kim <[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.
Expand Down Expand Up @@ -59,6 +61,7 @@ def __init__(self):

#%%
from ._aeration import *
from ._aerobic_digestion_addon import *
from ._asm1 import *
from ._asm2d import *
from ._adm1 import *
Expand All @@ -67,21 +70,25 @@ def __init__(self):
from ._decay import *
from ._kinetic_reaction import *
from ._pm2 import *
from ._pm2asm2d import *

from . import (
_aeration,
_aerobic_digestion_addon,
_asm1,
_asm2d,
_adm1,
_adm1_p_extension,
# _madm1,
_decay,
_kinetic_reaction,
_pm2
_pm2,
_pm2asm2d,
)

__all__ = (
*_aeration.__all__,
*_aerobic_digestion_addon.__all__,
*_asm1.__all__,
*_asm2d.__all__,
*_adm1.__all__,
Expand All @@ -90,4 +97,5 @@ def __init__(self):
*_decay.__all__,
*_kinetic_reaction.__all__,
*_pm2.__all__,
)
*_pm2asm2d.__all__,
)
19 changes: 11 additions & 8 deletions qsdsan/processes/_adm1_p_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -1037,35 +1037,38 @@ def __new__(cls, components=None, path=None,
#!!! new parameter
KS_IP*P_mw, np.array(k_mmp), Ksp_mass,
np.array(K_dis), K_AlOH, K_FeOH]))
def dydt_Sh2_AD(S_h2, state_arr, h, params, f_stoichio, V_liq, S_h2_in):

def adm1p_dydt_Sh2_AD(S_h2, state_arr, h, params, f_stoichio, V_liq, S_h2_in):
state_arr[7] = S_h2
Q = state_arr[45]
rxn = _rhos_adm1p(state_arr, params, h=h)
stoichio = f_stoichio(state_arr) # should return the stoichiometric coefficients of S_h2 for all processes
return Q/V_liq*(S_h2_in - S_h2) + np.dot(rxn, stoichio)


grad_rhosp = np.zeros(5)
X_biop = np.zeros(5)
def grad_dydt_Sh2_AD(S_h2, state_arr, h, params, f_stoichio, V_liq, S_h2_in):
def adm1p_grad_dydt_Sh2_AD(S_h2, state_arr, h, params, f_stoichio, V_liq, S_h2_in):
state_arr[7] = S_h2
ks = params['rate_constants'][[5,6,7,8,10]]
Ks = params['half_sat_coeffs'][2:6]
K_h2 = params['half_sat_coeffs'][7]
pH_ULs = params['pH_ULs']
pH_LLs = params['pH_LLs']
KS_IN = params['KS_IN']
KS_IP = params['KS_IP']
KIs_h2 = params['KIs_h2']
kLa = params['kLa']

X_biop[:] = state_arr[[18,19,19,20,22]]
substrates = state_arr[2:6]
S_va, S_bu, S_IN = state_arr[[3,4,10]]
S_va, S_bu, S_IN, S_IP = state_arr[[3,4,10,11]]
Iph = Hill_inhibit(h, pH_ULs, pH_LLs)[[2,3,4,5,7]]
Iin = substr_inhibit(S_IN, KS_IN)
Iip = substr_inhibit(S_IP, KS_IP)
grad_Ih2 = grad_non_compet_inhibit(S_h2, KIs_h2)

grad_rhosp[:] = ks * X_biop * Iph * Iin
grad_rhosp[:] = ks * X_biop * Iph * Iin * Iip
grad_rhosp[:-1] *= substr_inhibit(substrates, Ks) * grad_Ih2
if S_va > 0: grad_rhosp[1] *= 1/(1+S_bu/S_va)
if S_bu > 0: grad_rhosp[2] *= 1/(1+S_va/S_bu)
Expand All @@ -1074,12 +1077,12 @@ def grad_dydt_Sh2_AD(S_h2, state_arr, h, params, f_stoichio, V_liq, S_h2_in):
stoichio = f_stoichio(state_arr)

Q = state_arr[45]
return -Q/V_liq + np.dot(grad_rhos, stoichio[[5,6,7,8,10]]) + kLa*stoichio[-3]
return -Q/V_liq + np.dot(grad_rhosp, stoichio[[5,6,7,8,10]]) + kLa*stoichio[-3]

dct['flex_rhos'] = _rhos_adm1p
dct['solve_pH'] = adm1p_solve_pH
dct['dydt_Sh2_AD'] = dydt_Sh2_AD
dct['grad_dydt_Sh2_AD'] = grad_dydt_Sh2_AD
dct['dydt_Sh2_AD'] = adm1p_dydt_Sh2_AD
dct['grad_dydt_Sh2_AD'] = adm1p_grad_dydt_Sh2_AD
return self

def set_half_sat_K(self, K, process):
Expand Down
107 changes: 107 additions & 0 deletions qsdsan/processes/_aerobic_digestion_addon.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# -*- coding: utf-8 -*-
'''
QSDsan: Quantitative Sustainable Design for sanitation and resource recovery systems
This module is developed by:
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 numpy as np
from qsdsan import Process
from thermosteam import settings
_load_components = settings.get_default_chemicals

__all__ = ('ASM_AeDigAddOn',)

class ASM_AeDigAddOn(Process):
'''
Creates a `Process` object representing the degradation of particulate
inert organic materials that typically occur in an aerobic digester.
Stoichiometry is determined by rules of element conservation in corresponding
activated sludge models.
Parameters
----------
k_dig : float, optional
The 1st-order degradation rate constant, in d^(-1). The default is 0.04.
See Also
--------
:class:`qsdsan.processes.ASM1`
:class:`qsdsan.processes.ASM2d`
:class:`qsdsan.processes.mASM2d`
Examples
--------
>>> import qsdsan.processes as pc
>>> cmps_asm1 = pc.create_asm1_cmps()
>>> dig_asm1 = pc.ASM_AeDigAddOn('dig_asm1')
>>> dig_asm1.show()
Process: dig_asm1
[stoichiometry] X_I: -1
X_S: 1
S_NH: 0.06
S_ALK: 0.0514
[reference] X_I
[rate equation] X_I*k_dig
[parameters] k_dig: 0.04
[dynamic parameters]
>>> cmps_masm2d = pc.create_masm2d_cmps(set_thermo=False)
>>> dig_masm2d = pc.ASM_AeDigAddOn('dig_masm2d', components=cmps_masm2d)
>>> dig_masm2d.show()
Process: dig_masm2d
[stoichiometry] S_NH4: 0.0265
S_PO4: 0.0009
S_IC: 0.0433
X_I: -1
X_S: 1
[reference] X_I
[rate equation] X_I*k_dig
[parameters] k_dig: 0.04
[dynamic parameters]
'''

def __init__(self, ID, k_dig=0.04, components=None):
cmps = _load_components(components)
rxn = 'X_I -> X_S'
consrv = []
if 'S_ALK' in cmps.IDs:
consrv.append('charge')
rxn += ' + [?]S_ALK'
elif 'S_IC' in cmps.IDs:
consrv.append('C')
rxn += ' + [?]S_IC'

if 'S_NH' in cmps.IDs:
consrv.append('N')
rxn += ' + [?]S_NH'
elif 'S_NH4' in cmps.IDs:
consrv.append('N')
rxn += ' + [?]S_NH4'

if 'S_PO4' in cmps.IDs:
consrv.append('P')
rxn += ' +[?]S_PO4'

super().__init__(ID=ID, reaction=rxn,
rate_equation='k_dig*X_I',
ref_component='X_I',
components=cmps,
conserved_for=consrv,
parameters=('k_dig',))
self.k_dig=k_dig
self._stoichiometry = np.asarray(self._stoichiometry, dtype=float)

@property
def k_dig(self):
'''[float] Degradation rate constant, in d^(-1).'''
return self._k
@k_dig.setter
def k_dig(self, k):
self._k = k
self.set_parameters(k_dig=k)
Loading

0 comments on commit af5acab

Please sign in to comment.