Skip to content

Commit

Permalink
checkout point to add testing and see if it works on remote (local te…
Browse files Browse the repository at this point in the history
…sting not working)
  • Loading branch information
yalinli2 committed Oct 12, 2023
1 parent 5300f87 commit 96fe35a
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 105 deletions.
37 changes: 37 additions & 0 deletions .github/workflows/build-disinfection.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions

name: build-disinfection

on:
push:
branches: [ disinfection ]
pull_request:
branches: [ disinfection ]

jobs:
build:

runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
python-version: ["3.9", "3.10"]

steps:
- uses: actions/checkout@v3
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
python -m pip install pytest
pip install --no-cache-dir git+https://github.com/BioSTEAMDevelopmentGroup/thermosteam.git@qsdsan
pip install --no-cache-dir git+https://github.com/BioSTEAMDevelopmentGroup/biosteam.git@qsdsan
pip install --no-cache-dir git+https://github.com/QSD-Group/QSDsan.git@beta
pip install --no-cache-dir -r requirements.txt
- name: Test with pytest
run: |
pytest
34 changes: 2 additions & 32 deletions exposan/pou_disinfection/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,26 +37,6 @@
ppl = 1000 # 1k or 500


# %%

# =============================================================================
# Prices and GWP CFs
# =============================================================================

#!!! Might need updating
price_dct = {
'Electricity': 0.17,
'NaClO': 1.96/0.15/1.21/0.125,
'Polyethylene': 0,
}

GWP_dct = {
'Electricity': 0.1135,
'NaClO': 2.6287,
'Polyethylene': 2.7933,
}


# %%

# =============================================================================
Expand Down Expand Up @@ -86,20 +66,10 @@ def _load_lca_data(reload=False):
'''
global _impact_item_loaded
if not _impact_item_loaded or reload:
ImpactIndicator('GWP', unit='kg CO2') # global warming potential
ImpactIndicator('GWP', unit='kg CO2-eq') # global warming potential

item_path = os.path.join(data_path, 'impact_items.xlsx')
qs.ImpactItem.load_from_file(item_path)

# Impacts associated with streams and electricity
def create_stream_impact_item(item_ID):
StreamImpactItem(ID=item_ID,
GWP=GWP_dct[item_ID.rsplit('_item')[0]])

create_stream_impact_item(item_ID='NaClO_item')
create_stream_impact_item(item_ID='Polyethylene_item')
ImpactItem(ID='E_item', functional_unit='kWh', GWP=GWP_dct['Electricity'])

_impact_item_loaded = True

return _impact_item_loaded
Expand All @@ -110,7 +80,7 @@ def create_stream_impact_item(item_ID):
_system_loaded = False
def _load_system():
qs.currency = 'USD'
qs.PowerUtility.price = price_dct['Electricity']
qs.PowerUtility.price = 0.17
global sysA, sysB, sysC, sysD, teaA, teaB, teaC, teaD, lcaA, lcaB, lcaC, lcaD, _system_loaded
sysA = create_system('A')
teaA = sysA.TEA
Expand Down
22 changes: 9 additions & 13 deletions exposan/pou_disinfection/_units.py
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ class POUChlorination(SanUnit):
Parameters
----------
ins : obj
Raw water, chlorine, polyethylene bottle for chlorine.
Raw water, chlorine.
outs : obj
Treated water.
number_of_households : int
Expand Down Expand Up @@ -335,16 +335,11 @@ def _run(self):
Cl_bottle.phase = 's'

# add chlorine to the treated_water
NaClO_dose_total = self.NaClO_dose_total

chlorine.imass['NaClO'] = NaClO_dose_total * treated_water.F_vol / 1000 # kg NaClO/hr
self.chlorine_rate = chlorine.imass['NaClO']
Cl_bottle.imass['Polyethylene'] = chlorine.imass['NaClO'] * self.PE_to_NaClO

NaClO_dose_total = self.NaClO_dose_total
self.chlorine_rate = chlorine.imass['NaClO'] = NaClO_dose_total * treated_water.F_vol / 1000 # kg NaClO/hr

# disinfect bacteria from treated_water

Cl_Concentration = NaClO_dose_total #mg/L

No = raw_water.imass['Ecoli']/raw_water.F_vol * 10**-4 # E coli CFU/ mL ICC/ml (intact cells counts) used by (Cheswick et al., 2020)

#_design will include all the construction or capital impacts
Expand All @@ -353,11 +348,12 @@ def _design(self):

# defining the quantities of materials/items
# note that these items are in the _impacts_items.xlsx data
design['PE'] = Container = self.number_of_households * self.PE_in_container


PE_container = self.number_of_households * self.PE_in_container
PE_bottle = self.ins[1].imass['NaClO'] * self.PE_to_NaClO
design['PE'] = PE_container + PE_bottle

self.construction = (
Construction(item='PE', quantity = Container, quantity_unit = 'kg'),
Construction(item='PE', quantity = design['PE'], quantity_unit = 'kg'),
)
self.add_construction(add_cost=False)

Expand Down
2 changes: 1 addition & 1 deletion exposan/pou_disinfection/data/_AgNP_CWF_2.csv
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Wood_mass,,kg,6.1,4,9.4,triangular,"Ren, D., Colosi, L. M., & Smith, J. A. (2013
propane,,kg,0.9,0.55,1.3,triangular,"Ren, D., Colosi, L. M., & Smith, J. A. (2013). Evaluating the Sustainability of Ceramic Filters for Point-of-Use Drinking Water Treatment. Environmental Science & Technology, 47(19), 11206–11213. https://doi.org/10.1021/es4026087"
PE_in_container,,kg,0.9,0.675,1.125,uniform,https://www.tanksinternational.it/en/category/3/13/PLASTIC-APPROVED-JERRYCAN-20-LITRES-VOLUME/80
AgNP_low_lifetime,,yr,1,0.5,1.5,uniform,"Mittelman, A. M.; Lantagne, D. S.; Rayner, J.; Pennell, K. D. Silver Dissolution and Release from Ceramic Water Filters. Environ. Sci. Technol. 2015, 49 (14), 8515–8522. https://doi.org/10.1021/acs.est.5b01428"
AgNP_lifetime,,yr,3,1.5,4.5,uniform,"Mittelman, A. M.; Lantagne, D. S.; Rayner, J.; Pennell, K. D. Silver Dissolution and Release from Ceramic Water Filters. Environ. Sci. Technol. 2015, 49 (14), 8515–8522. https://doi.org/10.1021/acs.est.5b01429"
AgNP_lifetime_old,,yr,3,1.5,4.5,uniform,"Mittelman, A. M.; Lantagne, D. S.; Rayner, J.; Pennell, K. D. Silver Dissolution and Release from Ceramic Water Filters. Environ. Sci. Technol. 2015, 49 (14), 8515–8522. https://doi.org/10.1021/acs.est.5b01429"
CWF_clay_cost,,USD/filter,0.99,0.7425,1.2375,uniform,
CWF_grog_cost,,USD/filter,0.18,0.135,0.225,uniform,
CWF_sawdust_cost,,USD/filter,0.9,0.675,1.125,uniform,
Expand Down
Binary file modified exposan/pou_disinfection/data/impact_items.xlsx
Binary file not shown.
86 changes: 38 additions & 48 deletions exposan/pou_disinfection/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,10 @@
data_path,
get_LCA_metrics,
get_TEA_metrics,
GWP_dct,
household_size,
ppl,
price_dct,
results_path,
update_number_of_householdsize,
update_water_source,
water_source,
)

Expand Down Expand Up @@ -102,90 +99,83 @@ def add_shared_parameters(model, water):
# Household size
raw_water = sys.path[0]
b = pou.household_size
#!!! Need to update this sigma
# This use of sigma should be correct since we are not multiplying it to get to the
D = shape.Trunc(shape.Normal(mu=b, sigma=1.8), lower=1)
@param(name='Household size', element=raw_water, kind='coupled', units='cap/household',
baseline=b, distribution=D)
def set_household_size(i):
pou.household_size = max(1, i)
update_number_of_householdsize(sys, household_size=i, ppl=ppl)

#!!! Might need to be updated
# # 1.8/((844/4%)^0.5) is for standard error of a mean,
# # standard deviation divided by the square root of the population size,
# # 844 and 4% from Trimmer et al., changed from the distribution used in Trimmer et al.
# D = shape.Trunc(shape.Normal(mu=b, sigma=0.012), lower=1)
# @param(name='Household size', element=Toilet, kind='coupled', units='cap/household',
# baseline=b, distribution=D)
# def set_household_size(i):
# bw.household_size = i

######## General TEA settings ########
# Money discount rate
tea = sys.TEA
b = pou.discount_rate
D = shape.Uniform(lower=0.03, upper=0.06)
@param(name='Discount rate', element='TEA', kind='isolated', units='fraction',
baseline=b, distribution=D)
baseline=b, distribution=D)
def set_discount_rate(i):
pou.discount_rate = tea.discount_rate = i

# Electricity price
b = price_dct['Electricity']
b = PowerUtility.price
D = shape.Triangle(lower=0.08, midpoint=b, upper=0.21)
@param(name='Electricity price', element='TEA', kind='isolated',
units='$/kWh', baseline=b, distribution=D)
def set_electricity_price(i):
PowerUtility.price = i

# NaClO price
b = price_dct['NaClO']
b = sys_stream['NaClO'].price
if b != 1.96/0.15/1.21/0.125: raise ValueError('baseline price of NaClO changed!')
D = shape.Uniform(lower=b*0.75, upper=b*1.25)
@param(name='NaClO price', element='TEA', kind='isolated',
units='$/kg', baseline=b, distribution=D)
def set_NaClO_price(i):
price_dct['NaClO'] = sys_stream['NaClO'].price = i
sys_stream['NaClO'].price = i

######## General LCA settings ########
lca = sys.LCA
#!!! Why not add electricity, etc., through spreadsheet?
b = GWP_dct['Electricity']
D = shape.Uniform(lower=0.106, upper=0.121)
@param(name='Electricity CF', element='LCA', kind='isolated',
units='kg CO2-eq/kWh', baseline=b, distribution=D)
def set_electricity_CF(i):
GWP_dct['Electricity'] = ImpactItem.get_item('E_item').CFs['GlobalWarming'] = i

b = GWP_dct['NaClO']
# Streams uncertainties need to be added separately
# #!!! Probably need to be updated to "GWP"
# b = ImpactItem.get_item('Electricity').CFs['GWP']
# D = shape.Uniform(lower=0.106, upper=0.121)
# @param(name='Electricity CF', element='LCA', kind='isolated',
# units='kg CO2-eq/kWh', baseline=b, distribution=D)
# def set_electricity_CF(i):
# ImpactItem.get_item('E_item').CFs['GlobalWarming'] = i

b = ImpactItem.get_item('NaClO').CFs['GWP']
D = shape.Triangle(lower=2.6287*0.75, midpoint=b, upper=2.6287*1.25)
@param(name='NaClO CF', element='LCA', kind='isolated',
units='kg CO2-eq/kg NaClO', baseline=b, distribution=D)
def set_NaClO_CF(i):
GWP_dct['NaClO'] = ImpactItem.get_item('NaClO_item').CFs['GlobalWarming'] = i

b = GWP_dct['Polyethylene']
D = shape.Triangle(lower=2.7933*0.75, midpoint=b, upper=2.7933*1.25)
@param(name='Polyethylene CF', element='LCA', kind='isolated',
units='kg CO2-eq/kg Polyethylene', baseline=b, distribution=D)
def set_Polyethylene_CF(i):
GWP_dct['Polyethylene'] = ImpactItem.get_item('Polyethylene_item').CFs['GlobalWarming'] = i

# b = GWP_dct['PVC']
# D = shape.Triangle(lower=1.0*0.75, midpoint=b, upper=1.0*1.25)
# @param(name='PVC CF', element='LCA', kind='isolated',
# units='kg CO2-eq/kg PVC', baseline=b, distribution=D)
# def set_PVC_CF(i):
# GWP_dct['PVC'] = ImpactItem.get_item('PVC_item').CFs['GlobalWarming'] = i

# b = GWP_dct['Mecury']
# D = shape.Triangle(lower=1.0*0.75, midpoint=b, upper=1.0*1.25)
# @param(name='Mecury CF', element='LCA', kind='isolated',
# units='kg CO2-eq/kg Mecury', baseline=b, distribution=D)
# def set_Mecury_CF(i):
# GWP_dct['Mecury'] = ImpactItem.get_item('Mecury_item').CFs['GlobalWarming'] = i

# b = GWP_dct['Aluminum']
# D = shape.Triangle(lower=1.0*0.75, midpoint=b, upper=1.0*1.25)
# @param(name='Aluminum CF', element='LCA', kind='isolated',
# units='kg CO2-eq/kg Mecury', baseline=b, distribution=D)
# def set_Aluminum_CF(i):
# GWP_dct['Aluminum'] = ImpactItem.get_item('Aluminum_item').CFs['GlobalWarming'] = i
ImpactItem.get_item('NaClO').CFs['GlobalWarming'] = i

# b = ImpactItem.get_item('Polyethylene_item').CFs['GWP']
# D = shape.Triangle(lower=2.7933*0.75, midpoint=b, upper=2.7933*1.25)
# @param(name='Polyethylene CF', element='LCA', kind='isolated',
# units='kg CO2-eq/kg Polyethylene', baseline=b, distribution=D)
# def set_Polyethylene_CF(i):
# ImpactItem.get_item('Polyethylene_item').CFs['GlobalWarming'] = i


item_path = os.path.join(pou.data_path, 'impact_items.xlsx')
for ind in lca.indicators:
data = load_data(item_path, sheet=ind.ID)
for p in data.index:
item = ImpactItem.get_item(p)
b = item.CFs['GlobalWarming']
b = item.CFs['GWP']
lower = float(data.loc[p]['low'])
upper = float(data.loc[p]['high'])
dist = data.loc[p]['distribution']
Expand All @@ -197,7 +187,7 @@ def set_Polyethylene_CF(i):
else:
raise ValueError(f'Distribution {dist} not recognized.')
model.parameter(name=p+'CF',
setter=DictAttrSetter(item, 'CFs', 'GlobalWarming'),
setter=DictAttrSetter(item, 'CFs', 'GWP'),
element='LCA', kind='isolated',
units=f'kg CO2-eq/{item.functional_unit}',
baseline=b, distribution=D)
Expand Down
18 changes: 7 additions & 11 deletions exposan/pou_disinfection/systems.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@

__all__ = ('create_system',)

# def get_number_of_households(household_size=household_size, ppl=ppl):
# return ppl / household_size


# %%

Expand All @@ -51,17 +48,16 @@
#!!! Seems like only sysA needs NaClO and PE
def create_systemA(flowsheet=None,
water_source=water_source, household_size=household_size, ppl=ppl):
item = ImpactItem.get_item('NaClO_item')
A_naclo = WasteStream('A_naclo', phase='g', stream_impact_item=item)

item = ImpactItem.get_item('Polyethylene_item')
A_polyethylene = WasteStream('A_polyethylene', phase='g', stream_impact_item=item)
item = ImpactItem.get_item('NaClO')
A_naclo = WasteStream('A_naclo', phase='l',
stream_impact_item=item.copy('A_naclo', set_as_source=True),
price=1.96/0.15/1.21/0.125)

number_of_households = ppl / household_size
A1 = u.RawWater('A1', outs=('raw_water'), household_size=household_size,
number_of_households=number_of_households)

A2 = u.POUChlorination('A2', ins=(A1-0, A_naclo, A_polyethylene),
A2 = u.POUChlorination('A2', ins=(A1-0, A_naclo),
outs='treated_water',
number_of_households=number_of_households)

Expand Down Expand Up @@ -123,7 +119,7 @@ def create_systemC(flowsheet=None,
annual_maintenance=0, annual_labor=0)

LCA(system=sysC, lifetime=lifetime, lifetime_unit='yr', uptime_ratio=1,
annualize_construction=True, E_item=lambda: C2.power_utility.rate*(365*12*5))
annualize_construction=True, Electricity=lambda: C2.power_utility.rate*(365*12*5))

return sysC

Expand All @@ -147,7 +143,7 @@ def create_systemD(flowsheet=None,
annual_maintenance=0, annual_labor=0)

LCA(system=sysD, lifetime=lifetime, lifetime_unit='yr', uptime_ratio=1,
annualize_construction=True, E_item=lambda: D2.power_utility.rate*(365*24*5))
annualize_construction=True, Electricity=lambda: D2.power_utility.rate*(365*24*5))

return sysD

Expand Down

0 comments on commit 96fe35a

Please sign in to comment.