Code Monkey home page Code Monkey logo

qsdsan's People

Contributors

gayeongkim avatar haclohman avatar jiananf2 avatar joyxyz1994 avatar lane-to avatar lsrowles avatar philateawag avatar smitimittal avatar vlmorgan93 avatar yalinli2 avatar yoelcortes avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

qsdsan's Issues

Creating documents

Need a live website to guide users/contributors on how to use the package, how to contribute to this project, etc., probably on readthedocs

`WasteStream._get_property`, `WasteStream.mol` inaccuracy

Need to add WasteStream-specific methods for molar flow and related thermodynamic properties. Generally, Component can be measured as something other than the chemical itself (e.g., COD, N). But this difference is not yet taken into account when getting thermodynamic properties of a WasteStream as a mixture of components.

Question on Grinder

  • Can grinder remove moisture? If so, should include in the description of the class, right now it only says it breaks up the solids
    • Then where does the water go? There's only one influent and one effluent
    • The calculation here is assuming a moisture content of 65%, not 35%
      waste_out.imass['H2O'] = (0.65/0.35) * TS_in # fraction
  • Is price_ratio needed here?

Merging `gates` into `main`

Thanks to everyone (@haclohman in particular for leading and going through the codes for each system), we are close to merging the systems in the gates branchintomain`, just want to document some changes I'd like to make before pulling those in:

  • Consolidate the modules, see #56
  • Make sure references are good, see #58
  • Consistent SanUnit
    • Add in required Component/ImpactItem in unit docs, see #51
    • Remove legacy comments, see #57
    • Update __init__, see #59
  • Make sure the units are included in tests, either through doctest or through testing the corresponding system, see #52

Question on IonExchangeNH3

Check consistency of `price_ratio` usage

The price_ratio attribute should be used for

Anything related to the parts/materials of the system, but no labor

Not sure if this has been used consistently, need to double-check

General `_run` for first order decay

Currently almost all of the subclasses ofDecay have the following module in _run:

    def _run(self):
        waste, salt, HCl_acid = self.ins
        treated, CH4, N2O = self.outs
        treated.copy_like(waste)
        CH4.phase = N2O.phase = 'g'

        # COD decay
        COD_deg = waste.COD*waste.F_vol/1e3*self.COD_removal  # kg/hr
        treated._COD = waste.COD * (1-self.COD_removal)

        CH4_prcd = COD_deg * self.MCF_decay * self.max_CH4_emission
        CH4.imass['CH4'] = CH4_prcd

        # N decay
        N_loss = self.first_order_decay(k=self.decay_k_N, t=self.tau/365, max_decay=self.N_max_decay)
        N_loss_tot = N_loss*waste.TN/1e3*waste.F_vol
        NH3_rmd, NonNH3_rmd = \
            self.allocate_N_removal(N_loss_tot, waste.imass['NH3'])
        treated.imass['NH3'] = waste.imass['NH3'] - NH3_rmd
        treated.imass['NonNH3'] = waste.imass['NonNH3'] - NonNH3_rmd
        N2O.imass['N2O'] = N_loss_tot * self.N2O_EF_decay * 44/28

It'll be good to put this part in Decay so that any future updates can be propagated throughout, would also be good if it can be written to include a sludge effluent with consideration of the sludge moisture content

Task list for v0.2.0

Major features that will be included in this release:

  • Develop Process class @joyxyz1994 bfa51a6
  • Add an Equipment class to account for the different equipment in a SanUnit d80e791
  • Add additional sensitivity analyses and visualization functions
  • (Nice) plotting functions to visualize statistical analyses, with examples:

Do not add attributes that are constant (e.g., MW)

In StruvitePrecipitation (won't b surprising if there are similar situations in other units), there are many attributes that are constant, it'll be better to just hard code those since they won't change, e.g., we know the molecular weight of P, there's no need for an attribute like MW_P (but it'll be good to add a note in the code about what that 30.97 means)

N_recovered = (waste.imass['P'] * self.P_rec_1 / self.MW_P

However, for attributes such as P_rec_1, it still might be better to add them as attributes, as they could change

On this end, why the attribute is called P_rec_1? What does that 1 stand for? Similarly for K_rec_1. Without a reason, it's confusing

Additionally, if want the mol, use imol instead of imass

Running TODO list

Just a list of the things I see QSDsan will benefit from and will be working on:

  • Membrane bioreactor, I've put in the structure and the most promising configurations here.
    • Timeline: Q4 2021
    • Done in 6e1a626, still some missing configurations and haven't been tested, but the next task should take care of it
  • #46
    • Timeline: Q1 2022
    • Done in 8b96dae (EXPOsan commit), the numbers are not checked against anything, but the system runs
  • Add steady-state algorithms so that dynamic units can be simulated at equilibrium conditions (i.e., isdynamic is set to False)
    • Costing not yet added, but can run now
  • Piping units
    • Some of the pipe selection algorithms are here

- Post treatment units including UV, chlorination, and granular activated carbon
- Timeline: Q1 2022
- Initial tutorial is added in 919637a, pending review by Eva and Philipp

QSDsan may move to python 3.8

Currently qsdsan is tested for both python 3.7 and 3.8. However, with biosteam moving to python 3.8 (BioSTEAMDevelopmentGroup/biosteam#56), qsdsan may be only compatible with python 3.8 and higher.

I'm trying to sort this out, but if you are using python 3.7 and lower (like me), the best solution might be to make a new environment and install python 3.8 (conda instruction).

I will follow up if I find out that qsdsan is incompatible with python 3.7 and lower, and I'll post instructions on how to upgrade.

BioSTEAM's QDSsan test not running.

Hi!

Just a heads up, I think the latest qsdsan merge had some name changes that stop BioSTEAM's QDSsan test from running.

To Reproduce
Input:

def test_dyn_sys():
    from qsdsan import processes as pc, sanunits as su, set_thermo, System
    import numpy as np
    from numpy.testing import assert_allclose
    cmps = pc.load_asm1_cmps()
test_dyn_sys()

Output:

AttributeError: module 'qsdsan.processes' has no attribute 'load_asm1_cmps'

Environment
Windows 11, latest github versions of all the following:
- QSDsan
- EXPOsan
- BioSTEAM
- Thermosteam

BM factor

It does not recognize a purchase cost correctly setting the BM factor to one.

Add notes on needed Component/ImpactItem in unit docs

Some units (e.g., PitLatrine) required specific Component and/or ImpactItem to run, such requirements should be added to the class-level docs

E.g., consider adding:

The following components should be included in system thermo object for simulation:
H2O, Polyacrylamide.

The following impact items should be pre-constructed for life cycle assessment:
Steel.

pip install exposan leads to _heat_exchanging.py out of date

I recently installed exposan with the intent to simulate the BSM1 WWTF process. I used pip install exposan --user to avoid needing to uninstall other libraries.

Upon attempting to run from exposan import bsm1 I received the following error:

ModuleNotFoundError                       Traceback (most recent call last)
Cell In[1], line 1
----> 1 from exposan import bsm1

File ~\AppData\Roaming\Python\Python310\site-packages\exposan\__init__.py:25
     22 es_path = os.path.dirname(__file__)
     23 del os, pkg_resources
---> 25 from . import utils

File ~\AppData\Roaming\Python\Python310\site-packages\exposan\utils.py:23
     21 from chaospy import distributions as shape
     22 from thermosteam.functional import rho_to_V
---> 23 from qsdsan import ImpactItem, sanunits as su
     24 from qsdsan.utils import time_printer, AttrSetter
     25 from . import es_path

File ~\AppData\Roaming\Python\Python310\site-packages\qsdsan\__init__.py:72
     68 from ._tea import *
     69 from ._lca import *
---> 72 from . import (
     73     _component,
     74     _components,
     75     _construction,
     76     _equipment,
     77     _impact_indicator,
     78     _impact_item,
     79     _lca,
     80     _process,
     81     _sanstream,
     82     _sanunit,
     83     _tea,
     84     _transportation,
     85     _waste_stream,
     86     equipments,
     87     processes,
     88     sanunits,
     89     stats,
     90     )
     92 utils._secondary_importing()
     93 for _slot in utils.doc_examples.__all__:

File ~\AppData\Roaming\Python\Python310\site-packages\qsdsan\sanunits\__init__.py:44
     42 from ._encapsulation_bioreactor import *
     43 from ._excretion import *
---> 44 from ._heat_exchanging import *
     45 from ._junction import *
     46 from ._non_reactive import *

File ~\AppData\Roaming\Python\Python310\site-packages\qsdsan\sanunits\_heat_exchanging.py:27
     25 from math import ceil, pi
     26 from biosteam.units import HXprocess as HXP, HXutility as HXU
---> 27 from biosteam.units.facilities import HeatExchangerNetwork as HXN
     28 from biosteam.units.design_tools.specification_factors import material_densities_lb_per_ft3
     29 from biosteam.exceptions import bounds_warning, DesignWarning

ModuleNotFoundError: No module named 'biosteam.units.facilities'

Looking at the native _heat_exchanging.py file in QSDsan, it looks like the import lines do not match with the version installed through original pip command.

Native QSDsan File:

from warnings import warn
from math import ceil, pi
from biosteam import HeatExchangerNetwork as HXN, HXprocess as HXP, HXutility as HXU
from biosteam.units.design_tools.specification_factors import material_densities_lb_per_ft3
from biosteam.exceptions import bounds_warning, DesignWarning
from biosteam.units.design_tools import flash_vessel_design
from .. import SanUnit, Construction
from ..utils import auom

Pip download File:

import biosteam as bst
from warnings import warn
from math import ceil, pi
from biosteam.units import HXprocess as HXP, HXutility as HXU
from biosteam.units.facilities import HeatExchangerNetwork as HXN
from biosteam.units.design_tools.specification_factors import material_densities_lb_per_ft3
from biosteam.exceptions import bounds_warning, DesignWarning
from biosteam.units.design_tools import flash_vessel_design
from .. import SanUnit, Construction
from ..utils import auom

Replacing the downloaded block with the native block fixes the error, and I was able to reproduce the dynamic simulation example, though I have not yet tested additional simulations.

Versions of the following packages:
- QSDsan: 1.2.5
- EXPOsan: 1.2.5
- BioSTEAM: 2.37.3
- Thermosteam: 0.35.0

Operating on windows 11

Export components?

Hi QSDSan team! I am wondering if there is any way to export the information from a components object or compiled components into a pandas dataframe or directly into a text file. I ask because I've made a custom set of components using the qs.Components command with the built-in search_ID functionality, and I would like to avoid copying and pasting this large code block between multiple files.

I've seen in the documentation that we can load in components from a file, then compile from there, but I wasn't sure how this text file was made in the first place or if it was possible to do that process in reverse.

Thanks!

Stream has no attribute '_islinked'

Hello,

I was going through this QSDSAN tutorial and am trying to run the following:

`

# Make three random influents, I'm deliberately using different ways to make these streams
# as a recap previous tutorials

# Method 1: by directly providing the flow rates of select components
ins1 = qs.WasteStream(H2O=100)

# Method 2: using copy and adjust flow rates later
ins2 = ins1.copy()
ins2.imol['X_GAO_Gly'] = ins2.imol['X_GAO_PHA'] = 0.01

# Method 3: using default models
ins3 = qs.WasteStream.codstates_inf_model('', flow_tot=50)

# Use a shorthand to make our lives easier
su = qs.sanunits

# This is the actual line used to initialize the instance,
# and we can pass the influents through the ins argument
M1 = su.Mixer(ins=(ins3))
`

I am getting the following error:

--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) Input In [22], in <cell line: 19>() 15 su = qs.sanunits 17 # This is the actual line used to initialize the instance, 18 # and we can pass the influents through the ins` argument
---> 19 M1 = su.Mixer(ins=(ins3))

File ~/.local/share/virtualenvs/energy_inflows-sTQfUhBs/lib/python3.9/site-packages/qsdsan/sanunits/_abstract.py:48, in Mixer.init(self, ID, ins, outs, thermo, init_with, F_BM_default, isdynamic, rigorous)
45 def init(self, ID='', ins=None, outs=(), thermo=None,
46 init_with='WasteStream', F_BM_default=None, isdynamic=False,
47 rigorous=False):
---> 48 SanUnit.init(self, ID, ins, outs, thermo, init_with,
49 F_BM_default=F_BM_default, isdynamic=isdynamic)
50 self.rigorous = rigorous

File ~/.local/share/virtualenvs/energy_inflows-sTQfUhBs/lib/python3.9/site-packages/qsdsan/_sanunit.py:161, in SanUnit.init(self, ID, ins, outs, thermo, init_with, construction, transportation, equipments, add_OPEX, uptime_ratio, lifetime, F_BM_default, isdynamic, **kwargs)
159 self._init_with = init_with
160 self._init_ins(ins, init_with)
--> 161 self._init_outs(outs, init_with)
162 self._init_utils()
163 self._init_results()

File ~/.local/share/virtualenvs/energy_inflows-sTQfUhBs/lib/python3.9/site-packages/qsdsan/_sanunit.py:256, in SanUnit._init_outs(self, outs, init_with)
254 def _init_outs(self, outs, init_with):
255 super()._init_outs(outs)
--> 256 converted, missing = self._convert_stream(outs, self.outs, init_with, 'outs')
257 _outs = self._outs = Outlets(self, self._N_outs, converted, self._thermo,
258 self._outs_size_is_fixed, self._stacklevel)
259 _replace_missing_streams(_outs, missing)

File ~/.local/share/virtualenvs/energy_inflows-sTQfUhBs/lib/python3.9/site-packages/qsdsan/_sanunit.py:217, in SanUnit._convert_stream(self, strm_inputs, streams, init_with, ins_or_outs)
215 converted.append(SanStream.from_stream(SanStream, s))
216 else:
--> 217 converted.append(WasteStream.from_stream(WasteStream, s))
219 diff = len(converted) + len(missing) - len(streams)
220 if diff != 0:

File ~/.local/share/virtualenvs/energy_inflows-sTQfUhBs/lib/python3.9/site-packages/qsdsan/_waste_stream.py:359, in WasteStream.from_stream(cls, stream, ID, **kwargs)
356 return new
358 # An actual stream
--> 359 new = SanStream.from_stream(cls, stream, ID)
360 for attr, val in kwargs.items():
361 setattr(new, attr, val)

File ~/.local/share/virtualenvs/energy_inflows-sTQfUhBs/lib/python3.9/site-packages/qsdsan/_sanstream.py:344, in SanStream.from_stream(cls, stream, ID, **kwargs)
341 new_ID = ''
342 new.init(ID=new_ID)
--> 344 new._islinked = stream._islinked
346 source = new._source = stream._source
347 if source:

AttributeError: 'Stream' object has no attribute '_islinked'

`

I am using version 1.1.4. Maybe this is a bug in the newest version? Should I use an older version while it is being fixed?

Thank you!

Task list for v0.1.0

Major features that will be included in this release:

  • Develop Process class @joyxyz1994
    • This seems will take longer time, move to version 0.2.0 #25
  • Enable Morris and Sobol sensitivity analysis in QSDsan, either with updates in BioSTEAM or as a standalone module in QSDsan @yalinli2
    • Sobol done in commit 90c71ca
    • Pearson, Spearman, and Morris done in commit 5f5109f
    • Morris plotting function added in commit 59dfef5
  • Add uncertainty models to all three scenarios in the bwaise system, potentially demonstrate how Morris and Sobol can be performed @yalinli2
    • All uncertainty models/parameters added in commit 40512de
    • A demonstrative script for using Morris and Sobol have been added in commit 741342c
    • I noticed this paper on Uncertainpy, which was built on Chaospy and SALib, might consider using this package in the future, but for now, still plan to use SALib
      • Uncertainpy seems to be geared toward neuroscience, Chaospy and SALib are sufficient
  • Replace the get_normalized_impacts method in LCA with something like get_allocated_impacts, and allow users to allocate the impacts based on mass, value, energy, or a ratio/function provided by the user @yalinli2

Clean up legacy comments

Need to to addressed or removed if it's outdated, listed by units in following posts

General ones:

  • breakpoints if you've done debugging, they shouldn't be there

Task list for v0.3.0

Updates to be included in v0.3.0 release

  • Separate developed systems into a standalone repository/package EXPOsan 68f21e2
  • Make it possible to use both Stream and WasteStream 4acc8d7
    • Also added a new SanStream class (tmo.Stream plus with impact_item), now SanUnit can be initialized by any of these three classes, and they can be mixed.
  • Enable LCA data importing
    • This will be done through via brightway2. Kudos to the brightway2 development group for the awesome capacities, the package (with the detailed documentations and tutorials), it's seriously underrated.
    • DONE!!! ๐ŸŽ‰ 73e6d81 with the new package BW2QSD, though will definitely need more testing to make sure it works, and add support for databases other than ecoinvent.
  • Add examples in documentation
    • With df36e50 there are direct examples/links to examples in major classes, will continue to work on this along the way.

Consolidating similar units across systems

There are several similar units in different systems (e.g., IndustrialControlPanel, SystemControls), I'd like to consolidate them into fewer modules with some renaming for consistency and better organization, specifically

The following units will go into qsdsan/sanunits/_ion_exchange.py (see #55):

  • IonExchangeNH3
  • IonExchangeReclaimer
  • IonExchangeNEWgenerator

The following units will go into qsdsan/sanunits/_controlling.py:

  • IndustrialControlPanel (renamed to ControlBoxOP)
  • SystemControls (this one is diff from others, maybe leave this out)
  • SCGZyclonicControlBox
  • RecyclingControls
  • ControlSystem

The following units will go into qsdsan/sanunits/_hxs.py:

  • OilHeatExchanger
  • HydronicHeatExchanger
  • DryerFromHHX (renamed to HHXdryer)

Update QSDsan capacity pages

Open an issue here so I don't forget! Refer to the internal email for details, but the idea is to have a page that shows what is currently in QSDsan. In the past we have a page for the developed processes, unit operations, and systems, but I haven't updated it for quite some time.

Additionally, since we are developing the benchmarking configurations, it'll be great if we can have one page dedicated to it (or add to existing pages).

`SanUnit.__init__`

Many of the the __init__ methods are error-prone, e.g.,

    def __init__(self, ID='', ins=None, outs=(), **kwargs):
        SanUnit.__init__(self, ID, ins, outs, F_BM_default=1)

This won't allow the unit to init with the correct thermo object and stream types, please update those to be

    def __init__(self, ID='', ins=None, outs=(), thermo=None, init_with='WasteStream',
                 **kwargs):
        SanUnit.__init__(self, ID, ins, outs, thermo=thermo, init_with=init_with,
                         F_BM_default=1)

Please DO modify this based on your units - e.g., some units' might other other attributes (e.g., lifetime, CAPEX_over_OPEX that need to be included)

Update from BioSTEAM

Heads up, I just deprecated the _is_linked attribute of Stream objects. I think all what needs to be done for qsdsan is to remove lines where it is copied (e.g., from_stream).

Thanks!

References in units/data sheets

Many of the new units does not have documentation/references, some that stands out:

  • In the data sheet of ScrewPress, not sure what the "Additional Questions" is, and what that "dewatering_energy_demand_old" is doing

Review changes related to Components and WasteStream

Hey @joyxyz1994 , I made the updates as we discussed, can you have a look at the commit b47e36c and make updates as you see fit? I added doc and updated tests accordingly.

Note that commit didn't pass the test because I used functions (aliases) that haven't been released in the existing thermosteam, I reverted it in the next commit 8b61f59 and the all tests are passed now

Thank you!

Add examples to functions

It'll be good to add examples in docs, which would also serve as a test on the functions, listing functions to add docs on (non-exhaustive, just whatever I saw):

Process:

  • class-level doc
    • Could include docs related to Processes and CompiledProcesses there
  • check_conservation done in b0a9a49
  • copy (added this function and doc) done in b0a9a49

Review conc indexer

Hey @joyxyz1994 I think I managed to implemented the concentration indexer through 87aec8f

import qsdsan as qs
qs.set_thermo(qs.Components.load_default())
ws1 = qs.WasteStream.codbased_inf_model(flow_tot=100)
ws1.conc
ws1.iconc['S_F']

Screen Shot 2021-09-14 at 10 13 55 PM

Can you take a look at the changes to _waste_stream.py and see whether it makes sense? I think with it we might not need the get_mass_concentration method (or let it just return self.conc)

Thanks!

TODOs for first release

Items I can think of to release 0.0.1 version in PyPI:

Workflow to merge branches into `gates`

We need to standardize the codes before I'm comfortable with including them into the main branch and on PyPI, I'm doing this myself for the BR_OmniProcessor because it is the closest (i.e., least behind) among all, but I'd really appreciate help, specifically

  • Make sure no error and no warning (i.e., related to F_BM) when running the system

    • Also no warnings/errors from the editor (e.g., no yellow triangles from Spyder)
      Screen Shot 2022-02-25 at 1 25 17 PM
  • Clean up legacy comments, breakpoints, "#!!!", "TODO", etc.

  • If you copy something from another module, make sure you update the variable names, comments, etc. to the existing module

  • If there are codes that you don't understand, try to find who wrote that, if you can't figure it out, open an issue here on GitHub

  • Check the data sheet and make sure they look good, remove legacy data like "XXX_old", see #58

  • Add documentation, at the minimum you should provide description of the unit (including what components and impact items are needed for the unit, see #51) as well as the reference.

  • Rerun the corresponding systems and make sure the results match

Review changes in WasteStream and Components

Hi @joyxyz1994 , I was pulling your changes on processes and found some minor issues, can you review the following and see if they look good to you? If it's good then I'll push to the main branch.

  • In 5350eb0, set_flow_by_concentration in _waste_stream.py, lines 855 and 865
  • In 9905fcf, in _components.py, I'm using ID instead of CAS now, because there might be cases where people want to have two components fixed at different phases of the same chemical (just had a call with Shion and she wanted to have a gas phase CH4 and soluble CH4. If using CAS then the soluble CH4 won't be added in the Components.

Thanks!

Improve test coverage

Currently (Feb 24, 2022) only a bit over 50% of the package is covered by test, let's aim to get it up to ~80%.

See the codecov report for priorities. Adding doc examples would probably be a good solution way to deal with it as it also helps users.

I'll include our tutorial examples in the test after dyn-enabled BioSTEAM is out, hopefully that will also bump up coverage.

Question related to PitLatrine emptying ratio

Open this issue to remind myself about a question from this week's office hour (3/6/23). The question is about why the truck trip increases when increasing PitLatrine.emptying_ratio

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.