diff --git a/AUTHORS.rst b/AUTHORS.rst deleted file mode 100644 index ef5e77db..00000000 --- a/AUTHORS.rst +++ /dev/null @@ -1,45 +0,0 @@ -Authors & Roles -=============== - -Lead Developers ---------------- -- `Yalin Li`_ (current maintainer) -- `Joy Zhang`_ - - -Tutorials and Videos --------------------- -- `Yalin Li`_ -- `Joy Zhang`_ -- `Tori Morgan `_ -- `Hannah Lohman `_ - - -Module Development ------------------- -- `Yalin Li`_ -- `Joy Zhang`_ -- `Stetson Rowles `_ -- Smiti Mittal -- Anna Kogler -- Samuel Aguiar -- Tyler Stephen -- Shion Watabe -- `Other developers `_ that have contributed to the repository. - - -Funding Support ---------------- -- `Jeremy Guest `_ -- `Ro Cusick `_ -- `William Tarpeh `_ - - -Special Acknowledgement ------------------------ -- Yoel Cortés-Peña for helping many of the ``QSDsan`` members get started on Python and package development. - - -.. Links -.. _Yalin Li: https://qsdsan.readthedocs.io/en/beta/authors/Yalin_Li.html -.. _Joy Zhang: https://qsdsan.readthedocs.io/en/beta/authors/Joy_Zhang.html diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index dd3b79b3..38461edc 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1,10 +1,57 @@ -Contributing to ``QSDsan`` -========================== +Contributors and Guidelines +=========================== + +Contributors +------------ +While main developers of ``QSDsan`` are listed below, we thank all `contributors `_ who have supported the development and maintenance of this platform. If you would like to join the effort, please review our guidelines and instructions below. + + +Lead Developers +^^^^^^^^^^^^^^^ + - `Yalin Li`_ (current maintainer) + - `Xinyi (Joy) Zhang`_ (process models & benchmarking) + + +Tutorials and Videos +^^^^^^^^^^^^^^^^^^^^ + - `Yalin Li`_ + - `Xinyi (Joy) Zhang`_ + - `Hannah Lohman`_ + - `Victoria (Tori) Morgan`_ + - `Ga-Yeong Kim`_ + + +System Modules +^^^^^^^^^^^^^^ +Systems constructed using ``QSDsan`` are stored in the `EXPOsan `_ repository. + + - `Jianan Feng `_ + - `Ga-Yeong Kim`_ + - `Yalin Li`_ + - `Hannah Lohman`_ + - `Victoria (Tori) Morgan`_ + - `Saumitra Rai `_ + - `L. Stetson Rowles `_ + - `Shion Watabe `_ + - `Xinyi (Joy) Zhang`_ + + +.. Links +.. _Ga-Yeong Kim: https://www.linkedin.com/in/ga-yeong-kim-8a2b4a141/ +.. _Yalin Li: https://yalinli.group +.. _Hannah Lohman: https://www.linkedin.com/in/hannahlohman/ +.. _Victoria (Tori) Morgan: https://www.linkedin.com/in/victoria-morgan-ph-d-a8493271/ +.. _Xinyi (Joy) Zhang: https://www.linkedin.com/in/xinyi-joy-zhang/ + + + +Contributing Guidelines +----------------------- +Below are some brief instructions on how to contribute to ``QSDsan``. If you find yourself struggle with the installation of QSDsan/setting up the environment, this extended version of `installation instructions `_ might be helpful to you. If you have any questions regarding the process, feel free to `submit an issue on GitHub `_. Thank you in advance for your contribution! -Below are some brief instructions on how to contribute to ``QSDsan``. If you find yourself struggle with the installation of QSDsan/setting up the environment, this extended version of `installation instructions `_ might be helpful to you. If you have any questions regarding the process, feel free to `submit an issue on GitHub `_. Thank you in advance for your contribution! Authorship ----------- +^^^^^^^^^^ The following guideline is adapted from `BioSTEAM `_, we welcome inputs from the community for enhancement. If you feel that your contributions are not acknowledged or adequately acknowledged, please do contact us. #. Contributions must be acknowledged at the module-level with a short description for: @@ -13,19 +60,16 @@ The following guideline is adapted from `BioSTEAM `_. - #. If any code or implementation was copied from a third party, it should be noted in the module-level documentation. #. Any third-party packages copied from ``QSDsan`` must be strictly open-source (not copy-left nor open-access). If license of the third-part package is different from ``QSDsan``, the module should add the third-party license as an option (i.e., dual licensing). Forking and Cloning -------------------- +^^^^^^^^^^^^^^^^^^^ Via command-line interface -^^^^^^^^^^^^^^^^^^^^^^^^^^ - +************************** #. Fork ``QSDsan`` by going to its `GitHub homepage `_ and click the "Fork" button at the top right corner. #. GitHub will open a new page showing your fork, click the green "Code" button on the top and copy the HTTPS address (there's a handy copy button next to the address), it should be something like: @@ -128,8 +172,7 @@ Via command-line interface Via GitHub Desktop -^^^^^^^^^^^^^^^^^^ - +****************** If you are new to command-line interface, `GitHub Desktop `_ can be a good way to get started as it has a graphic interface, though less powerful. To see screenshots of the different interface, visit GitHub's documentations on `Cloning a repository from GitHub to GitHub Desktop `_ @@ -152,14 +195,15 @@ To see screenshots of the different interface, visit GitHub's documentations on Note -^^^^ +**** #. We use fork as the default way for collaboration (i.e., for all first-time contributors). If you are a constant contributor and have independently made at least one successful and meaningful contribution through forking, you will be given the write access to ``QSDsan`` and you can use branch for easier code syncing. We will also invite you to join the ``QSDsan`` team. #. GitHub has really detailed documentation on `forking `_ (and almost everything else). -#. As QSDsan is public, all created forks would be public as well. We would appreciate if you make your work public and contribute back, but we understand it if you would like to create a private fork of QSDsan. To do so, please check our tip on creating the `private fork `_. +#. As QSDsan is public, all created forks would be public as well. We would appreciate if you make your work public and contribute back, but we understand it if you would like to create a private fork of QSDsan. To do so, please check our tip on creating the `private fork `_. #. As we are constantly developing ``QSDsan`` with its core dependencies ``BioSTEAM`` and ``Thermosteam``, it'll be good to clone those two repositories and use the ``qsdsan`` branch of both. + Developing Modules ------------------- +^^^^^^^^^^^^^^^^^^ #. Adding/modifying modules locally. #. `Commit `_ your changes and concisely summarize your changes in the commit message. @@ -180,7 +224,7 @@ Developing Modules Submitting Pull Request ------------------------ +^^^^^^^^^^^^^^^^^^^^^^^ #. Once you are satisfied with your changes and push all commits to your fork, go to you GitHub fork of ``QSDsan``, and submit a `pull request `_. - You can confirm that you have pulled all updates from the root repository if there's a message showing that your branch is X commits ahead of QSD-Group:main (not X commits ahead, Y commits behind). @@ -189,7 +233,7 @@ Submitting Pull Request Documentation -------------- +^^^^^^^^^^^^^ Whenever new modules or functions are added, concise and thorough documents should be added with examples for `doctest`_. Please also include yourself (contact method is optional) to the list of contributors on the top of the module. ``QSDsan`` uses `numpydoc docstring style `_ with some modifications for better rendering. Some important notes: @@ -235,7 +279,7 @@ Tutorials are prepared in `Jupyter Notebook `_ and potenti Testing -------- +^^^^^^^ ``QSDsan`` uses `GitHub Action `_ to test all pushes and pull requests. A pull request will only be accepted when: #. Meaningful contributions have been made. diff --git a/README.rst b/README.rst index fb9f6dd5..17f65f5b 100644 --- a/README.rst +++ b/README.rst @@ -117,7 +117,7 @@ You can also download the package from `PyPI ` Note that development of this package is currently under initial stage with limited backward compatibility, please feel free to `submit an issue `_ for any questions regarding package upgrading. -If you are a developer and want to contribute to ``QSDsan``, please follow the steps in the `Contributing to QSDsan `_ section of the documentation to clone the repository. If you find yourself struggle with the installation of QSDsan/setting up the environment, this extended version of `installation instructions `_ might be helpful to you. +If you want to contribute to ``QSDsan``, please follow the steps in the `Contributing Guidelines `_ section of the documentation to clone the repository. If you find yourself struggle with the installation of QSDsan/setting up the environment, this extended version of `installation instructions `_ might be helpful to you. Documentation @@ -131,33 +131,14 @@ All tutorials are written using Jupyter Notebook, you can run your own Jupyter e For each of these tutorials, we are also recording videos where one of the QSD group members will go through the tutorial step-by-step. We are gradually releasing these videos on our `YouTube channel `_ so subscribe to receive updates! -About the authors +About the Authors ----------------- -Development and maintenance of the package is supported by the Quantitative Sustainable Design Group led by members of the `Guest Group `_ at the `University of Illinois Urbana-Champaign (UIUC) `_. Core contributors are listed below, please refer to the `author page `_ for the full list of authors. - -**Lead developers:** - - `Yalin Li`_ (current maintainer) - - `Joy Zhang`_ - - -**Tutorials and videos:** - - `Yalin Li`_ (current maintainer) - - `Joy Zhang`_ - - `Tori Morgan `_ - - `Hannah Lohman `_ - - -**Project conception & funding support:** - - `Jeremy Guest `_ - - -**Special acknowledgement:** - - Yoel Cortés-Peña for helping many of the ``QSDsan`` members get started on Python and package development. +Please refer to `Contributors `_ section for a list of contributors. Contributing ------------ -Please refer to the `Contributing to QSDsan `_ section of the documentation for instructions and guidelines. +Please refer to the `Contributing Guidelines `_ section of the documentation for instructions and guidelines. Stay Connected @@ -170,7 +151,7 @@ QSDsan Events We will keep this `calendar `_ up-to-date as we organize more events (office hours, workshops, etc.), click on the events in the calendar to see the details (including meeting links). -License information +License Information ------------------- Please refer to the ``LICENSE.txt`` for information on the terms & conditions for usage of this software, and a DISCLAIMER OF ALL WARRANTIES. @@ -181,9 +162,4 @@ References .. [2] Li, Y.; Trimmer, J.T.; Hand, S.; Zhang, X.; Chambers, K.G.; Lohman, H.A.C.; Shi, R.; Byrne, D.M.; Cook, S.M.; Guest, J.S. Quantitative Sustainable Design (QSD): A Methodology for the Prioritization of Research, Development, and Deployment of Technologies. (Tutorial Review) Environ. Sci.: Water Res. Technol. 2022, 8 (11), 2439–2465. https://doi.org/10.1039/D2EW00431C. -.. [3] Cortés-Peña, Y.; Kumar, D.; Singh, V.; Guest, J.S. BioSTEAM: A Fast and Flexible Platform for the Design, Simulation, and Techno-Economic Analysis of Biorefineries under Uncertainty. ACS Sustainable Chem. Eng. 2020, 8 (8), 3302–3310. https://doi.org/10.1021/acssuschemeng.9b07040. - - -.. Links -.. _Yalin Li: https://qsdsan.readthedocs.io/en/beta/authors/Yalin_Li.html -.. _Joy Zhang: https://qsdsan.readthedocs.io/en/beta/authors/Joy_Zhang.html +.. [3] Cortés-Peña, Y.; Kumar, D.; Singh, V.; Guest, J.S. BioSTEAM: A Fast and Flexible Platform for the Design, Simulation, and Techno-Economic Analysis of Biorefineries under Uncertainty. ACS Sustainable Chem. Eng. 2020, 8 (8), 3302–3310. https://doi.org/10.1021/acssuschemeng.9b07040. \ No newline at end of file diff --git a/docs/source/CODE_OF_CONDUCT.rst b/docs/source/CODE_OF_CONDUCT.rst new file mode 100644 index 00000000..11d882be --- /dev/null +++ b/docs/source/CODE_OF_CONDUCT.rst @@ -0,0 +1,140 @@ +Contributor Covenant Code of Conduct +==================================== + +Our Pledge +---------- + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +Our Standards +------------- + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +Enforcement Responsibilities +---------------------------- + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +Scope +----- + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +Enforcement +----------- + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +quantitative.sustainable.design@gmail.com. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +Enforcement Guidelines +---------------------- + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +1. Correction +^^^^^^^^^^^^^ + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +2. Warning +^^^^^^^^^^ + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +3. Temporary Ban +^^^^^^^^^^^^^^^^ + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +4. Permanent Ban +^^^^^^^^^^^^^^^^ + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +Attribution +----------- + +This Code of Conduct is adapted from the Contributor Covenant `homepage`_, +version 2.1, available at +https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. + +Community Impact Guidelines were inspired by `Mozilla's code of conduct +enforcement ladder `_. + +.. _homepage: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/docs/source/Developed_Systems.rst b/docs/source/Developed_Systems.rst deleted file mode 100644 index c40058da..00000000 --- a/docs/source/Developed_Systems.rst +++ /dev/null @@ -1,64 +0,0 @@ -.. _developed_systems: - -Developed Systems -================= - -This page documents the systems that have been/is being developed using ``QSDsan`` with links to the source codes in GitHub and publications. - -+--------------------------+--------------------+--------------------------------+-------------------+ -| System | Source Codes | Publication | Module Status | -+==========================+====================+================================+===================+ -| Biogenic Refinery | - `br_archived`_ | - `Rowles`_ et al., 2022 | Completed | -| | - `br_current`_ | | | -+--------------------------+--------------------+--------------------------------+-------------------+ -| BSM1 (benchmark | - `bsm1_archived`_ | - `Alex`_ et al., 2008 | Completed | -| simulation model no. 1) | - `bsm1_current`_ | - `Li and Zhang`_ et al., 2022 | | -+--------------------------+--------------------+--------------------------------+-------------------+ -| Bwaise | - `bw_archived`_ | - `Trimmer`_ et al., 2020 | Completed | -| | - `bw_current`_ | - `Li and Zhang`_ et al., 2022 | | -+--------------------------+--------------------+--------------------------------+-------------------+ -| CAS (conventional | - `cas`_ | - `Shoener`_ et al., 2016 | Completed | -| activated sludge) | | | | -+--------------------------+--------------------+--------------------------------+-------------------+ -| Eco-San | - `es`_ | NA | Completed | -+--------------------------+--------------------+--------------------------------+-------------------+ -| NEWgenerator | - `ng_archived`_ | - Watabe et al., *In Prep.* | Completed | -| (under NDA) | - `ng_current`_ | | | -+--------------------------+--------------------+--------------------------------+-------------------+ -| Reclaimer | - `re`_ | - `Trotochaud`_ et al., 2020 | Completed | -+--------------------------+--------------------+--------------------------------+-------------------+ -| SCG Zyclonic (under NDA) | - `sz`_ | NA | Completed | -+--------------------------+--------------------+--------------------------------+-------------------+ - -Notes: - - "Under NDA" indicates that the system is under non-disclosure agreement with the technology design team and unfortunately we are not able to share the codes in full at this stage. The source link code will lead to a private repository that only individuals who have signed the NDA can access. - - "Archived" is the version used when the linked literature is published. - - "Current" is the version that has been updated to be compatible with the most up-to-date version of ``QSDsan``. - - -.. Links -.. _br_archived: https://github.com/QSD-Group/EXPOsan/releases/tag/archive%2FBR_OmniProcessor -.. _br_current: https://github.com/QSD-Group/EXPOsan/tree/main/exposan/biogenic_refinery -.. _Rowles: https://doi.org/10.1021/acsenvironau.2c00022 - -.. _bsm1_archived: https://pypi.org/project/exposan/1.1.4 -.. _bsm1_current: https://github.com/QSD-Group/EXPOsan/tree/main/exposan/bsm1 -.. _Alex: http://iwa-mia.org/wp-content/uploads/2019/04/BSM_TG_Tech_Report_no_1_BSM1_General_Description.pdf -.. _Li and Zhang: https://doi.org/10.1039/d2ew00455k - -.. _bw_archived: https://pypi.org/project/exposan/1.1.4 -.. _bw_current: https://github.com/QSD-Group/EXPOsan/tree/main/exposan/bwaise -.. _Trimmer: https://doi.org/10.1021/acs.est.0c03296 - -.. _cas: https://github.com/QSD-Group/EXPOsan/tree/main/exposan/cas -.. _Shoener: https://pubs.rsc.org/en/content/articlelanding/2016/ee/c5ee03715h - -.. _es: https://github.com/QSD-Group/EXPOsan/tree/main/exposan/eco_san - -.. _ng_current: https://github.com/QSD-Group/EXPOsan-private/tree/newgen/exposan/newgen -.. _ng_archived: https://github.com/QSD-Group/EXPOsan-private/tree/main/exposan/new_generator - -.. _re: https://github.com/QSD-Group/EXPOsan/tree/main/exposan/reclaimer -.. _Trotochaud: https://doi.org/10.1021/acs.est.0c02755 - -.. _sz: https://github.com/QSD-Group/EXPOsan-private/tree/main/exposan/scg_zyclonic diff --git a/docs/source/Systems.rst b/docs/source/Systems.rst new file mode 100644 index 00000000..aa5105a0 --- /dev/null +++ b/docs/source/Systems.rst @@ -0,0 +1,76 @@ +.. _systems: + +Systems +======= + +This page documents the systems that have been/is being developed using ``QSDsan`` with links to the source codes in GitHub and publications. + + +Benchmark Simulation Models +--------------------------- +The Modelling and Integrated Assessment (MIA) Specialist Group of the International Water Association has established benchmark simulation models (BSMs) to provide a consistent environment for wastewater treatment plant (WWTP)/water resource recovery facility (WRRF) evaluation (see `BSM webpage `_ and `MATLAB implementation and report `_). + +When publishing the paper that introduces QSDsan (`Li and Zhang`_ et al., 2022), we validated the process modeling and dynamic simulation capacities of QSDsan through BSM1 (`bsm1 EXPOsan module `_, `bsm1 archived codes `_). Work is currently underway to implement BSM2 in ``QSDsan``. + + +Water Resource Recovery Facilities +---------------------------------- +Work is underway to model the 25 distinct Water Resource Recovery Facility (WRRF) configurations identified as “typical” across North America (`Tarallo `_ et al., 2015; Zhang et al., *In Prep*, 2023). + +.. figure:: images/wrrf_configs.png + + +Other Systems +------------- +A variety of other sanitation and resource recovery systems have been developed using QSDsan, including: + +#. Non-sewered sanitation systems (NSSSs) including: + + * Biogenic Refinery + + - Publication: `Rowles `_ et al., 2022 + - `biogenic_refinery EXPOsan module `_ + - `biogenic_refinery archived codes `_ + + * Bwaise + + - Publication: `Trimmer `_ et al., 2020; `Li and Zhang`_ et al., 2022 + - `bwaise EXPOsan module `_ + - `bwaise Trimmer et al archived codes `_; `bwaise Li and Zhang et al archived codes `_ + + * Eco-San: `eco_san EXPOsan module `_ + + * NEWgenerator (under NDA) + + - Publication: `Watabe `_ et al., 2023 + - `new_generator EXPOsan module `_ + - `new_generator archived codes `_ + + * Reclaimer: `reclaimer EXPOsan module `_ + + * SCG Zyclonic (under NDA): `scg_zyclonic EXPOsan module `_ + +#. Conventional activated sludge process + + * Publication: `Shoener `_ et al., 2016 + * `cas EXPOsan module `_ + * `cas archived codes `_ + +#. Hydrothermal systems for fuel and fertilizer production from wet organic wastes + + * Manuscript: Feng et al., Characterizing the Opportunity Space for Sustainable Hydrothermal Valorization of Wet Organic Wastes, Submitted. + * `htl EXPOsan module `_ + +#. Modular encapsulated two-stage anaerobic biological system + + * Manuscript: Zhang et al., Sustainable design of a modular anaerobic system for distributed energy recovery from industrial wastewaters, In Prep. + * `metab EXPOsan module `_ + + +**Notes:** + - "Under NDA" indicates that the system is under non-disclosure agreement with the technology design team and unfortunately we are not able to share the codes in full at this stage. The source link code will lead to a private repository that only individuals who have signed the NDA can access. + - "Archived codes" are the codes used when the linked literature is published. + + +.. Links +.. _Li and Zhang: https://doi.org/10.1039/d2ew00455k \ No newline at end of file diff --git a/docs/source/api/processes/_index.rst b/docs/source/api/processes/_index.rst index eb916efd..e0b43772 100644 --- a/docs/source/api/processes/_index.rst +++ b/docs/source/api/processes/_index.rst @@ -11,9 +11,6 @@ List of Biological Kinetic Models | ADM1 | `adm`_ | `Batstone`_ et al., 2002 | | | | `Rosen and Jeppsson`_, 2006 | +----------+------------------+-----------------------------+ -| Aeration | `bsm1`_ | `EPA design manual`_, 1989 | -| | | `Mueller`_ et al., 2002 | -+----------+------------------+-----------------------------+ | ASM1 | `asm`_ & `bsm1`_ | `Henze`_ et al., 2006 | +----------+------------------+-----------------------------+ | ASM2d | `asm`_ & `bsm1`_ | `Henze`_ et al., 2006 | @@ -23,13 +20,16 @@ List of Biological Kinetic Models List of Other Kinetic Modules ----------------------------- -+-----------------+------------------+-------------------------+ -| Module | Implementation | Reference | -+=================+==================+=========================+ -| Decay | `bwaise`_ | `Trimmer`_ et al., 2020 | -+-----------------+------------------+-------------------------+ -| KineticReaction | N/A | N/A | -+-----------------+------------------+-------------------------+ ++-----------------+------------------+----------------------------+ +| Module | Implementation | Reference | ++=================+==================+============================+ +| Aeration | `bsm1`_ | `EPA design manual`_, 1989 | +| | | `Mueller`_ et al., 2002 | ++-----------------+------------------+----------------------------+ +| Decay | `bwaise`_ | `Trimmer`_ et al., 2020 | ++-----------------+------------------+----------------------------+ +| KineticReaction | N/A | N/A | ++-----------------+------------------+----------------------------+ diff --git a/docs/source/api/sanunits/ActivatedSludgeProcess.rst b/docs/source/api/sanunits/ActivatedSludgeProcess.rst index 67579959..8dbb5d5d 100644 --- a/docs/source/api/sanunits/ActivatedSludgeProcess.rst +++ b/docs/source/api/sanunits/ActivatedSludgeProcess.rst @@ -1,4 +1,4 @@ -ActivatedSludgeProcess -====================== -.. autoclass:: qsdsan.sanunits.ActivatedSludgeProcess - :members: \ No newline at end of file +Activated Sludge Process +======================== +.. automodule:: qsdsan.sanunits._activated_sludge_process + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/CropApplication.rst b/docs/source/api/sanunits/CropApplication.rst index 6d947c65..88ca1fcd 100644 --- a/docs/source/api/sanunits/CropApplication.rst +++ b/docs/source/api/sanunits/CropApplication.rst @@ -1,4 +1,4 @@ -CropApplication -=============== -.. autoclass:: qsdsan.sanunits.CropApplication - :members: \ No newline at end of file +Crop Application +================ +.. automodule:: qsdsan.sanunits._crop_application + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/DynamicInfluent.rst b/docs/source/api/sanunits/DynamicInfluent.rst index 883078fd..b37b39b0 100644 --- a/docs/source/api/sanunits/DynamicInfluent.rst +++ b/docs/source/api/sanunits/DynamicInfluent.rst @@ -1,4 +1,4 @@ -DynamicInfluent -=============== -.. autoclass:: qsdsan.sanunits.DynamicInfluent - :members: \ No newline at end of file +Dynamic Influent +================ +.. automodule:: qsdsan.sanunits._dynamic_influent + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/ElectrochemicalCell.rst b/docs/source/api/sanunits/ElectrochemicalCell.rst index 0396eb46..98fce6a0 100644 --- a/docs/source/api/sanunits/ElectrochemicalCell.rst +++ b/docs/source/api/sanunits/ElectrochemicalCell.rst @@ -1,4 +1,4 @@ -ElectrochemicalCell -=================== -.. autoclass:: qsdsan.sanunits.ElectrochemicalCell - :members: \ No newline at end of file +Electrochemical Cell +==================== +.. automodule:: qsdsan.sanunits._electrochemical_cell + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/Excretion.rst b/docs/source/api/sanunits/Excretion.rst index 6e7c0f35..5105c0c3 100644 --- a/docs/source/api/sanunits/Excretion.rst +++ b/docs/source/api/sanunits/Excretion.rst @@ -1,4 +1,4 @@ Excretion ========= -.. autoclass:: qsdsan.sanunits.Excretion - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._excretion + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/Flash.rst b/docs/source/api/sanunits/Flash.rst new file mode 100644 index 00000000..823ce674 --- /dev/null +++ b/docs/source/api/sanunits/Flash.rst @@ -0,0 +1,4 @@ +Flash +===== +.. automodule:: qsdsan.sanunits._flash + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/InternalCirculationRx.rst b/docs/source/api/sanunits/InternalCirculationRx.rst index aca44d8d..af032ec6 100644 --- a/docs/source/api/sanunits/InternalCirculationRx.rst +++ b/docs/source/api/sanunits/InternalCirculationRx.rst @@ -1,4 +1,4 @@ -InternalCirculationRx -===================== +Internal Circulation Reactor +============================ .. autoclass:: qsdsan.sanunits.InternalCirculationRx :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/Lagoon.rst b/docs/source/api/sanunits/Lagoon.rst index 6b034995..c82b5d0e 100644 --- a/docs/source/api/sanunits/Lagoon.rst +++ b/docs/source/api/sanunits/Lagoon.rst @@ -1,4 +1,4 @@ Lagoon ====== -.. autoclass:: qsdsan.sanunits.Lagoon - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._lagoon + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/MembraneDistillation.rst b/docs/source/api/sanunits/MembraneDistillation.rst new file mode 100644 index 00000000..0e9bb011 --- /dev/null +++ b/docs/source/api/sanunits/MembraneDistillation.rst @@ -0,0 +1,4 @@ +Membrane Distillation +===================== +.. automodule:: qsdsan.sanunits._membrane_distillation + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/PolishingFilter.rst b/docs/source/api/sanunits/PolishingFilter.rst index fc130994..110548f4 100644 --- a/docs/source/api/sanunits/PolishingFilter.rst +++ b/docs/source/api/sanunits/PolishingFilter.rst @@ -1,4 +1,4 @@ -PolishingFilter -=============== -.. autoclass:: qsdsan.sanunits.PolishingFilter - :members: \ No newline at end of file +Polishing Filter +================ +.. automodule:: qsdsan.sanunits._polishing_filter + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/Screening.rst b/docs/source/api/sanunits/Screening.rst index 998563c5..df95c56c 100644 --- a/docs/source/api/sanunits/Screening.rst +++ b/docs/source/api/sanunits/Screening.rst @@ -1,4 +1,4 @@ Screening ========= -.. autoclass:: qsdsan.sanunits.Screening - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._screening + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/Sedimentation.rst b/docs/source/api/sanunits/Sedimentation.rst index 4adf4913..b26f69a1 100644 --- a/docs/source/api/sanunits/Sedimentation.rst +++ b/docs/source/api/sanunits/Sedimentation.rst @@ -1,4 +1,4 @@ Sedimentation ============= -.. autoclass:: qsdsan.sanunits.Sedimentation - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._sedimentation + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/SepticTank.rst b/docs/source/api/sanunits/SepticTank.rst index 6d7dd342..b3ca4a19 100644 --- a/docs/source/api/sanunits/SepticTank.rst +++ b/docs/source/api/sanunits/SepticTank.rst @@ -1,4 +1,4 @@ -SepticTank -========== -.. autoclass:: qsdsan.sanunits.SepticTank - :members: \ No newline at end of file +Septic Tank +=========== +.. automodule:: qsdsan.sanunits._septic_tank + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/SludgePasteurization.rst b/docs/source/api/sanunits/SludgePasteurization.rst index 48921ebf..0a28a782 100644 --- a/docs/source/api/sanunits/SludgePasteurization.rst +++ b/docs/source/api/sanunits/SludgePasteurization.rst @@ -1,4 +1,4 @@ -SludgePasteurization -==================== -.. autoclass:: qsdsan.sanunits.SludgePasteurization - :members: \ No newline at end of file +Sludge Pasteurization +===================== +.. automodule:: qsdsan.sanunits._sludge_pasteurization + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/Trucking.rst b/docs/source/api/sanunits/Trucking.rst index 310dae4e..02c78989 100644 --- a/docs/source/api/sanunits/Trucking.rst +++ b/docs/source/api/sanunits/Trucking.rst @@ -1,4 +1,4 @@ Trucking ======== -.. autoclass:: qsdsan.sanunits.Trucking - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._trucking + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/_index.csv b/docs/source/api/sanunits/_index.csv index 8455cede..4112b1c0 100644 --- a/docs/source/api/sanunits/_index.csv +++ b/docs/source/api/sanunits/_index.csv @@ -37,6 +37,7 @@ InternalCirculationRx,No,No,Completed Lagoon,No,No,Completed LiquidTreatmentBed,No,No,Completed LumpedCost,No,No,Completed +MembraneDistillation,No,No,Completed MixTank,No,No,Completed Mixer,Yes,Yes,Completed MURT (multi-unit reinvented toilet),No,No,Completed diff --git a/docs/source/api/sanunits/_index.rst b/docs/source/api/sanunits/_index.rst index 166a0a14..1c1eab87 100644 --- a/docs/source/api/sanunits/_index.rst +++ b/docs/source/api/sanunits/_index.rst @@ -30,18 +30,24 @@ Individual Unit Operations abstract ActivatedSludgeProcess - anaerobic_reactors - clarifiers + anaerobic_reactor + clarifier combustion + compressor CropApplication DynamicInfluent ElectrochemicalCell + encapsulation_bioreactor Excretion + Flash heat_exchanging - junctions + hydroprocessing + hydrothermal InternalCirculationRx + junction Lagoon - membrane_bioreactors + membrane_bioreactor + MembraneDistillation non_reactive PolishingFilter pumping @@ -50,8 +56,8 @@ Individual Unit Operations SepticTank sludge_thickening SludgePasteurization - suspended_growth_bioreactors - tanks - toilets - treatment_beds + suspended_growth_bioreactor + tank + toilet + treatment_bed Trucking \ No newline at end of file diff --git a/docs/source/api/sanunits/abstract.rst b/docs/source/api/sanunits/abstract.rst index 90594a86..e07b18b0 100644 --- a/docs/source/api/sanunits/abstract.rst +++ b/docs/source/api/sanunits/abstract.rst @@ -1,33 +1,8 @@ -Abstract Units -============== - +Abstract Unit +============= +Note +^^^^ These units are for process simulation only and do not have design and cost algorithms -Mixer ------ -.. autoclass:: qsdsan.sanunits.Mixer - :members: - - -Splitter --------- -.. autoclass:: qsdsan.sanunits.Splitter - :members: - - -FakeSplitter ------------- -.. autoclass:: qsdsan.sanunits.FakeSplitter - :members: - - -ReversedSplitter ----------------- -.. autoclass:: qsdsan.sanunits.ReversedSplitter - :members: - - -ComponentSplitter ------------------ -.. autoclass:: qsdsan.sanunits.ComponentSplitter - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._abstract + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/anaerobic_reactor.rst b/docs/source/api/sanunits/anaerobic_reactor.rst new file mode 100644 index 00000000..397cb143 --- /dev/null +++ b/docs/source/api/sanunits/anaerobic_reactor.rst @@ -0,0 +1,4 @@ +Anaerobic Reactor +================= +.. automodule:: qsdsan.sanunits._anaerobic_reactor + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/anaerobic_reactors.rst b/docs/source/api/sanunits/anaerobic_reactors.rst deleted file mode 100644 index 145c7120..00000000 --- a/docs/source/api/sanunits/anaerobic_reactors.rst +++ /dev/null @@ -1,17 +0,0 @@ -Anaerobic Reactors -================== - -AnaerobicBaffledReactor ------------------------ -.. autoclass:: qsdsan.sanunits.AnaerobicBaffledReactor - :members: - -AnaerobicCSTR -------------- -.. autoclass:: qsdsan.sanunits.AnaerobicCSTR - :members: - -AnaerobicDigestion ------------------- -.. autoclass:: qsdsan.sanunits.AnaerobicDigestion - :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/clarifier.rst b/docs/source/api/sanunits/clarifier.rst new file mode 100644 index 00000000..e99f5a77 --- /dev/null +++ b/docs/source/api/sanunits/clarifier.rst @@ -0,0 +1,4 @@ +Clarifier +========= +.. automodule:: qsdsan.sanunits._clarifier + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/clarifiers.rst b/docs/source/api/sanunits/clarifiers.rst deleted file mode 100644 index 0ca47b51..00000000 --- a/docs/source/api/sanunits/clarifiers.rst +++ /dev/null @@ -1,13 +0,0 @@ -Clarifiers -========== - -Flat bottom circular clarifier ------------------------------- -.. autoclass:: qsdsan.sanunits.FlatBottomCircularClarifier - :members: - - -Ideal clarifier ---------------- -.. autoclass:: qsdsan.sanunits.IdealClarifier - :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/combustion.rst b/docs/source/api/sanunits/combustion.rst index 13990053..1ad8c2d5 100644 --- a/docs/source/api/sanunits/combustion.rst +++ b/docs/source/api/sanunits/combustion.rst @@ -1,13 +1,4 @@ Combustion ========== - -BiogasCombustion ----------------- -.. autoclass:: qsdsan.sanunits.BiogasCombustion - :members: - - -CombinedHeatPower ------------------ -.. autoclass:: qsdsan.sanunits.CombinedHeatPower - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._combustion + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/compressor.rst b/docs/source/api/sanunits/compressor.rst new file mode 100644 index 00000000..2cc5a854 --- /dev/null +++ b/docs/source/api/sanunits/compressor.rst @@ -0,0 +1,4 @@ +Compressor +========== +.. automodule:: qsdsan.sanunits._compressor + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/encapsulation_bioreactor.rst b/docs/source/api/sanunits/encapsulation_bioreactor.rst new file mode 100644 index 00000000..bc4d9476 --- /dev/null +++ b/docs/source/api/sanunits/encapsulation_bioreactor.rst @@ -0,0 +1,4 @@ +Encapsulation Bioreactor +======================== +.. automodule:: qsdsan.sanunits._encapsulation_bioreactor + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/heat_exchanging.rst b/docs/source/api/sanunits/heat_exchanging.rst index a46b88b3..0148947a 100644 --- a/docs/source/api/sanunits/heat_exchanging.rst +++ b/docs/source/api/sanunits/heat_exchanging.rst @@ -1,19 +1,4 @@ -Heat Exchangers +Heat Exchanging =============== - -HeatExchangerNetwork --------------------- -.. autoclass:: qsdsan.sanunits.HeatExchangerNetwork - :members: - - -HXprocess ---------- -.. autoclass:: qsdsan.sanunits.HXprocess - :members: - - -HXutility ---------- -.. autoclass:: qsdsan.sanunits.HXutility - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._heat_exchanging + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/hydroprocessing.rst b/docs/source/api/sanunits/hydroprocessing.rst new file mode 100644 index 00000000..d2f0eeb3 --- /dev/null +++ b/docs/source/api/sanunits/hydroprocessing.rst @@ -0,0 +1,4 @@ +Hydroprocessing +=============== +.. automodule:: qsdsan.sanunits._hydroprocessing + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/hydrothermal.rst b/docs/source/api/sanunits/hydrothermal.rst new file mode 100644 index 00000000..9e1d2b5a --- /dev/null +++ b/docs/source/api/sanunits/hydrothermal.rst @@ -0,0 +1,4 @@ +Hydrothermal +============ +.. automodule:: qsdsan.sanunits._hydrothermal + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/junction.rst b/docs/source/api/sanunits/junction.rst new file mode 100644 index 00000000..a81114d9 --- /dev/null +++ b/docs/source/api/sanunits/junction.rst @@ -0,0 +1,4 @@ +Junction +======== +.. automodule:: qsdsan.sanunits._junction + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/junctions.rst b/docs/source/api/sanunits/junctions.rst deleted file mode 100644 index 7fe09cd5..00000000 --- a/docs/source/api/sanunits/junctions.rst +++ /dev/null @@ -1,19 +0,0 @@ -Junctions -========= - -Junction --------- -.. autoclass:: qsdsan.sanunits.Junction - :members: - - -ADMtoASM --------- -.. autoclass:: qsdsan.sanunits.ADMtoASM - :members: - - -ASMtoADM --------- -.. autoclass:: qsdsan.sanunits.ASMtoADM - :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/membrane_bioreactor.rst b/docs/source/api/sanunits/membrane_bioreactor.rst new file mode 100644 index 00000000..95876797 --- /dev/null +++ b/docs/source/api/sanunits/membrane_bioreactor.rst @@ -0,0 +1,4 @@ +Membrane Bioreactor +=================== +.. automodule:: qsdsan.sanunits._membrane_bioreactor + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/membrane_bioreactors.rst b/docs/source/api/sanunits/membrane_bioreactors.rst deleted file mode 100644 index 7ae8985b..00000000 --- a/docs/source/api/sanunits/membrane_bioreactors.rst +++ /dev/null @@ -1,7 +0,0 @@ -Membrane Bioreactors -==================== - -AnMBR ------ -.. autoclass:: qsdsan.sanunits.AnMBR - :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/non_reactive.rst b/docs/source/api/sanunits/non_reactive.rst index 76bc12af..f78d9830 100644 --- a/docs/source/api/sanunits/non_reactive.rst +++ b/docs/source/api/sanunits/non_reactive.rst @@ -1,13 +1,4 @@ -Non-Reactive Units -================== - -Copier ------- -.. autoclass:: qsdsan.sanunits.Copier - :members: - - -LumpedCost ----------- -.. autoclass:: qsdsan.sanunits.LumpedCost - :members: \ No newline at end of file +Non-Reactive Unit +================= +.. automodule:: qsdsan.sanunits._non_reactive + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/pumping.rst b/docs/source/api/sanunits/pumping.rst index 27067d61..e03d3b1d 100644 --- a/docs/source/api/sanunits/pumping.rst +++ b/docs/source/api/sanunits/pumping.rst @@ -1,28 +1,8 @@ Pumping ======= - -Pump ----- -.. autoclass:: qsdsan.sanunits.Pump - :members: - - -HydraulicDelay --------------- -.. autoclass:: qsdsan.sanunits.HydraulicDelay - :members: - - -WWTpump -------- -.. autoclass:: qsdsan.sanunits.WWTpump - :members: - -wwtpump -------- +.. automodule:: qsdsan.sanunits._pumping + :members: Note ^^^^ -This is a decorator function to add the :class:`WWTpump` to a ``SanUnit``. - -.. autofunction:: qsdsan.sanunits.wwtpump \ No newline at end of file +``wwtpump`` is a decorator function to add the :class:`WWTpump` to a ``SanUnit``. \ No newline at end of file diff --git a/docs/source/api/sanunits/sludge_thickening.rst b/docs/source/api/sanunits/sludge_thickening.rst index 21dfac7c..3d3d9bad 100644 --- a/docs/source/api/sanunits/sludge_thickening.rst +++ b/docs/source/api/sanunits/sludge_thickening.rst @@ -1,25 +1,4 @@ Sludge Thickening ================= - -SludgeThickening ----------------- -.. autoclass:: qsdsan.sanunits.SludgeThickening - :members: - - -BeltThickener -------------- -.. autoclass:: qsdsan.sanunits.BeltThickener - :members: - - -SludgeCentrifuge ----------------- -.. autoclass:: qsdsan.sanunits.SludgeCentrifuge - :members: - - -SludgeSeparator ---------------- -.. autoclass:: qsdsan.sanunits.SludgeSeparator - :members: \ No newline at end of file +.. automodule:: qsdsan.sanunits._sludge_thickening + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/suspended_growth_bioreactors.rst b/docs/source/api/sanunits/suspended_growth_bioreactor.rst similarity index 67% rename from docs/source/api/sanunits/suspended_growth_bioreactors.rst rename to docs/source/api/sanunits/suspended_growth_bioreactor.rst index 36f862b5..624fb8e4 100644 --- a/docs/source/api/sanunits/suspended_growth_bioreactors.rst +++ b/docs/source/api/sanunits/suspended_growth_bioreactor.rst @@ -1,18 +1,11 @@ -Suspended Growth Bioreactors -============================ +Suspended Growth Bioreactor +=========================== +.. automodule:: qsdsan.sanunits._suspended_growth_bioreactor + :members: -CSTR ----- -.. autoclass:: qsdsan.sanunits.CSTR - :members: - -BatchExperiment ---------------- -.. autoclass:: qsdsan.sanunits.BatchExperiment - :members: Example -^^^^^^^ +------- .. code:: python import qsdsan.processes as pc, qsdsan.sanunits as su @@ -28,10 +21,4 @@ Example BE.scope.plot_time_series(('X_BH', 'X_BA', 'X_S')) .. figure:: ../../images/batch_experiment.png - :width: 50% - - -SBR ---- -.. autoclass:: qsdsan.sanunits.SBR - :members: \ No newline at end of file + :width: 50% \ No newline at end of file diff --git a/docs/source/api/sanunits/tank.rst b/docs/source/api/sanunits/tank.rst new file mode 100644 index 00000000..d59f17ae --- /dev/null +++ b/docs/source/api/sanunits/tank.rst @@ -0,0 +1,4 @@ +Tank +==== +.. automodule:: qsdsan.sanunits._tank + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/tanks.rst b/docs/source/api/sanunits/tanks.rst deleted file mode 100644 index 8fe96c1c..00000000 --- a/docs/source/api/sanunits/tanks.rst +++ /dev/null @@ -1,19 +0,0 @@ -Tanks -===== - -Tank ----- -.. autoclass:: qsdsan.sanunits.Tank - :members: - - -MixTank -------- -.. autoclass:: qsdsan.sanunits.MixTank - :members: - - -StorageTank ------------ -.. autoclass:: qsdsan.sanunits.StorageTank - :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/toilet.rst b/docs/source/api/sanunits/toilet.rst new file mode 100644 index 00000000..747a0c31 --- /dev/null +++ b/docs/source/api/sanunits/toilet.rst @@ -0,0 +1,6 @@ +.. _sanunits_toilet: + +Toilet +====== +.. automodule:: qsdsan.sanunits._toilet + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/toilets.rst b/docs/source/api/sanunits/toilets.rst deleted file mode 100644 index 30a3f62b..00000000 --- a/docs/source/api/sanunits/toilets.rst +++ /dev/null @@ -1,27 +0,0 @@ -.. _sanunits_toilets: - -Toilets -======= - -Toilet ------- -.. autoclass:: qsdsan.sanunits.Toilet - :members: - - -MURT ----- -.. autoclass:: qsdsan.sanunits.MURT - :members: - - -Pit latrine ------------ -.. autoclass:: qsdsan.sanunits.PitLatrine - :members: - - -UDDT ----- -.. autoclass:: qsdsan.sanunits.UDDT - :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/treatment_bed.rst b/docs/source/api/sanunits/treatment_bed.rst new file mode 100644 index 00000000..3671e445 --- /dev/null +++ b/docs/source/api/sanunits/treatment_bed.rst @@ -0,0 +1,4 @@ +Treatment Bed +============= +.. automodule:: qsdsan.sanunits._treatment_bed + :members: \ No newline at end of file diff --git a/docs/source/api/sanunits/treatment_beds.rst b/docs/source/api/sanunits/treatment_beds.rst deleted file mode 100644 index 36bd84a6..00000000 --- a/docs/source/api/sanunits/treatment_beds.rst +++ /dev/null @@ -1,13 +0,0 @@ -Treatment Beds -============== - -DryingBed ---------- -.. autoclass:: qsdsan.sanunits.DryingBed - :members: - - -LiquidTreatmentBed ------------------- -.. autoclass:: qsdsan.sanunits.LiquidTreatmentBed - :members: \ No newline at end of file diff --git a/docs/source/api/utils/loading.rst b/docs/source/api/utils/loading.rst index 8bc59d96..52d9854b 100644 --- a/docs/source/api/utils/loading.rst +++ b/docs/source/api/utils/loading.rst @@ -19,9 +19,4 @@ save_pickle load_pickle ^^^^^^^^^^^ -.. autofunction:: qsdsan.utils.load_pickle - - -load_pickled_cmps -^^^^^^^^^^^^^^^^^ -.. autofunction:: qsdsan.utils.load_pickled_cmps \ No newline at end of file +.. autofunction:: qsdsan.utils.load_pickle \ No newline at end of file diff --git a/docs/source/core_developers/Hannah_Lohman.rst b/docs/source/core_developers/Hannah_Lohman.rst deleted file mode 100644 index f1457dd4..00000000 --- a/docs/source/core_developers/Hannah_Lohman.rst +++ /dev/null @@ -1,9 +0,0 @@ -============= -Hannah Lohman -============= - -**Full profile coming soon!** - -Hannah is currently a Ph.D. candidate in the `Guest Group `_ in the Department of Civil and Environmental Engineering at the University of Illinois Urbana-Champaign. - -For more information, please check Hannah's `LinkedIn `_, `Google Scholar `_, or reach out to Hannah through `email `_ and/or `twitter `_. \ No newline at end of file diff --git a/docs/source/core_developers/Joy_Zhang.rst b/docs/source/core_developers/Joy_Zhang.rst deleted file mode 100644 index fc300ec2..00000000 --- a/docs/source/core_developers/Joy_Zhang.rst +++ /dev/null @@ -1,9 +0,0 @@ -=================== -Joy Zhang (co-lead) -=================== - -**Full profile coming soon!** - -Joy is currently a Ph.D. candidate in the `Guest Group `_ in the Department of Civil and Environmental Engineering at the University of Illinois Urbana-Champaign. - -Meanwhile, please check Joy's `LinkedIn `_, `Google Scholar `_, or reach out to Joy through `email `_. diff --git a/docs/source/core_developers/Stetson_Rowles.rst b/docs/source/core_developers/Stetson_Rowles.rst deleted file mode 100644 index f70e42f3..00000000 --- a/docs/source/core_developers/Stetson_Rowles.rst +++ /dev/null @@ -1,9 +0,0 @@ -============== -Stetson Rowles -============== - -**Full profile coming soon!** - -Stetson is currently an Assistant Professor in the Department of Civil Engineering and Construction at the Georgia Southern University, he is also the co-director and founding member of the `Clean Water Science Network (CWSN) `_, which is a nonprofit organization focused on water and sanitation educational and research opportunities for those from under-served communities. - -For more information, please check Stetson's `LinkedIn `_, `Google Scholar `_, or reach out to Stetson through `email `_ and/or `twitter `_. \ No newline at end of file diff --git a/docs/source/core_developers/Tori_Morgan.png b/docs/source/core_developers/Tori_Morgan.png deleted file mode 100644 index 408c78f8..00000000 Binary files a/docs/source/core_developers/Tori_Morgan.png and /dev/null differ diff --git a/docs/source/core_developers/Tori_Morgan.rst b/docs/source/core_developers/Tori_Morgan.rst deleted file mode 100644 index c21f6f9e..00000000 --- a/docs/source/core_developers/Tori_Morgan.rst +++ /dev/null @@ -1,78 +0,0 @@ -=========== -Tori Morgan -=========== - -.. figure:: Tori_Morgan.png - :width: 50% - :align: center - -| - -**Postdoctoral Research Associate** - -vlmorgan@illinois.edu - - -Research Interests -------------------- -• Detection of contaminants in water and wastewater [electrochemical nanosensors and biosensors] -• Data analytic tools [non-linear time series analyses, global sensitivity and uncertainty analyses, and hazard quotient assessment] -• Sustainability Design [tradeoffs across the dimensions of technical, resource recovery, environmental, economic, and social sustainability with techno-economic analysis, life cycle assessment, and multi-criteria decision analysis] - - -Overview -------------------- -Biography: Dr. Victoria Morgan (she/her) was a Postdoctoral Research Associate in the Institute for Sustainability, Energy, and Environment at the University of Illinois Urbana-Champaign. Her core research areas focus on integrating sensor development, wastewater treatment and resource recovery design, and decision-support tools to inform sustainable research, development, and deployment of technologies for key stakeholders. She is currently helping lead a Bill and Melinda Gates Foundation (BMGF) project to assess and improve the design of sanitation technologies for deployment in resource-limited settings under the supervision of Dr. Jeremy Guest and Dr. Ro Cusick. This work leverages quantitative sustainable design techniques (i.e., techno-economic assessment and life cycle assessment) with context specific scenarios to inform investment opportunities of sanitation technologies. In addition the BMGF work, Dr. Morgan is leading the development of a Python package for decision-making among multiple dimensions of sustainability to guide research and development of sanitation systems (`DMsan `_), using data analytic tools coupled with sensors to improve wastewater treatment efficiency in the U.S., and using quantitative sustainable design to identify viable pathways for technologies removing micropollutants from drinking water. Dr. Morgan’s training includes a B.S. in Biology with minors in business, environmental studies, and mathematics from Millsaps College, and a Ph.D. in Agricultural and Biological from the University of Florida with certificates in Engineering Leadership and Biological Systems Modeling. Her dissertation work used data-driven decision support tools by merging nanosensors, public health risk models (i.e., hazard quotient assessment and global sensitivity uncertainty analysis), and multi-criteria decision analysis to mitigate mercury exposure for marginalized communities in Colombia. - -For more information: https://tvlmorgan.wixsite.com/website - - -Education and Training ----------------------- -• Ph.D., Agricultural and Biological Engineering, 2020 -• - Engineering Leadership Certificate -• - Biological Systems Modeling Certificate -• B.S., Biology, Millsaps College, 2016 -• - Mathematics Minor -• - Business Administration Minor -• - Environmental Studies Minor - -Academic Positions -------------------- -• Postdoctoral Research Associate; Institute for Sustainability, Energy, and the Environment; University of Illinois at Urbana-Champaign; 2020 - Present -• Graduate Research Fellow; Department of Agricultural and Biological Engineering; Institute of Food and Agricultural Sciences; University of Florida; 2016 - 2020 -• Research Assistant; Alabama Innovation and Mentoring of Entrepreneurs Center (AIME); University of Alabama; Summer 2014 & Summer 2015 - -Publications -------------------- -• Morgan, V.L., McLamore, E.S., Correll, M., Kiker, G. (2021). Emerging Solutions for Artisanal Small-Scale Gold Mining Communities through a Multi-Criteria Decision Analysis Approach. Environment Systems and Decisions. https://doi.org/10.1007/s10669-021-09808-0 -• Morgan, V.L., Casso-Hartman, L., Vanegas, D., Velez-Torres, I., McLamore, E., Muñoz-Carpena, R., Kiker, G. 2020. Modeling exposure risk and prevention to mercury in drinking water for artisanal-small scale gold mining communities. Human and Ecological Risk Assessment. https://doi.org/10.1080/10807039.2020.1855576 -• Mohapatra, S., Frisina, R., Mohapatra, S., Sneed, K., Markoutsa, E. Wang, T., Dutta, R., Damnjanovic, R., Phan, M., Denmark, D. Biswal, M., McGill, A., Green, R., Howell, M., Ghosh, P., Gonzalez, A., Ahmed, N. Borresen, B., Farmer, M., Gaeta, M., Sharma, K., Bouchard, C., Gamboni, D., Martin, J., Tolve, B., Singh, M., Judy, J., Li, C., Santra, S., Daunert, S., Zeynaloo, E., Gelfanc, R., Lenhert, S., McLamore, E., Xiang, D., Morgan, V., Friedersdorf, L., Lal, R. Webster, T., Hoogerheide, D., Nguyen, T., D’Souza, M., Culha, M., Kondiah, P., Martin., D. 2020. Advances in Translational Nanotechnology: Challenges and Opportunities. Applied Sciences, 10(14), p.4881. https://doi.org/10.3390/app10144881 -• Morgan, V.L., Casso-Hartmann, L., Bahamon-Pinzon, D., McCourt, K., Hjort, R.G., Bahramzadeh, S., Velez-Torres, I., McLamore, E.S., Gomes, C., Alocilja, E.C. and Bhusal, N., 2020. Sensor-as-a-service: convergence of Sensor aNAlytic Point Solutions (SNAPS) and Pay-A-Penny-Per-Use (PAPPU) paradigm as a catalyst for democratization of healthcare in underserved communities. Diagnostics, 10(1), p.22. https://doi.org/10.3390/s19224935 -• McLamore, E.S., Palit Austin Datta, S., Morgan, V.L., Cavallaro, N., Kiker, G., Jenkins, D.M., Rong, Y., Gomes, C., Claussen, J., Vanegas, D. and Alocilja, E.C., 2019. SNAPS: Sensor aNAlytics Point Solutions for detection and decision support systems. Sensors, 19(22), p.4935. https://doi.org/10.3390/s19224935 -• Abdelbasir, S., El-Sheikh, E., Said, Morgan, V.L., Schmidt, H., Casso-Hartmann, L., Vanegas, D., Velez-Torres, I., McLamore, E.S. 2018. Graphene-anchored cuprous oxide nanoparticles from waste electric cables for electrochemical sensing. ACS Sustainable Chemistry & Engineering, 6(9), 12176-12186. https://doi.org/10.1021/acssuschemeng.8b02510 -• Emaminejad, A., Morgan, V.L., Yang, F., Kumar, K., Kavathetkar, A., Ragush, C., Wells, G., Huffaker, R., Cusick, R. 2020. Statistical Analysis of Real Time Carbon Monitoring at Water Resource Recovery Facilities using Bio-electrochemical Sensors. RSC Environmental Science: Water Research and Technology. Submitted. - -Awards -------------------- -• UF ABE Graduate Research Fellow, 2016 - 2020 -• UF Herbert Wertheim College of Engineering Attributes of a Gator Engineering Award in Service to Global Community, Spring 2020 -• NanoFlorida International Conference 1st Place Poster Session Winner in Nanotechnology for Sustainable Environment and Agriculture, Fall 2019 -• UF ABE Graduate Mentoring Award, Summer 2019 -• UF Engineering Leadership Institute (ELI) Woman Engineering Leadership Travel Grant Winner for the Simmons Conference, Spring 2019 -• NanoFlorida Conference Outstanding Student Speaker for Nanotechnology in Agriculture Award, Fall 2018 -• UF ABE 3 Minute-Thesis (3MT) 1st Place Winner, Fall 2018 -• Department of Defense (DoD) National Defense Science & Engineering Graduate Fellowship (NDSEG) Finalist, Spring 2018 -• UF ABE Poster Symposium 1st Place Winner, Spring 2018 -• Institute of Biological Engineering (IBE) 2017 Conference Outstanding Student Oral Presentation Winner, Spring 2017 - -Funding -------------------- -• Agricultural and Biological Engineering Graduate Fellow (2016 - 2020) - -Service -------------------- -• Illinois Water Environment Association Intelligent (IWEA) Water Systems Committee (2021 - Present) -• Illinois Water Environment Association Intelligent (IWEA) Young Professionals Committee (2021 - Present) -• Clean Water Science Network (CWSN) Mentor (2020 - 2021) - diff --git a/docs/source/core_developers/Yalin_Li.jpg b/docs/source/core_developers/Yalin_Li.jpg deleted file mode 100644 index 88db1825..00000000 Binary files a/docs/source/core_developers/Yalin_Li.jpg and /dev/null differ diff --git a/docs/source/core_developers/Yalin_Li.rst b/docs/source/core_developers/Yalin_Li.rst deleted file mode 100644 index 41fc8e8d..00000000 --- a/docs/source/core_developers/Yalin_Li.rst +++ /dev/null @@ -1,71 +0,0 @@ -======================= -Yalin Li (creator/lead) -======================= - -.. figure:: Yalin_Li.jpg - :width: 80% - :align: center - :alt: Yalin at Yosemite - - Oh the mountains and I love them. - -**Email:** `work `_; `personal `_ - -**Webpage:** `professional `_ - -This page is primarily about my aspirations for ``QSDsan``. For information related to my research/teaching interests and other professional activities, please check out my `webpage `_ (and feel free to check out the `source code `_ and build your own one). - -I'm the creator, lead developer, and current maintainer of ``QSDsan``. I am a research scientist at the `University of Illinois Urbana-Champaign (UIUC) `_. I am affiliated with the `Institute of Sustainability, Energy, and Environment (iSEE) `_ and the `Center for Advanced Bioenergy and Bioproducts Innovation (CABBI) `_. - -My background is in experimentation where I investigated multiple thermochemical and catalytic technologies for renewable products from biomass and wastewater (still missing the experiments and my beloved reactors), but I transitioned after graduation as I wanted to look at the big-picture implications through quantitative sustainable design (QSD). Unbeknownst to me, I would go on a fantastic journey as I advance the methodology of QSD and develop tools to for its application in research and education. - - -Education ---------- -- Ph.D., Environmental Engineering, Colorado School of Mines, 2019 (where the mountains are) -- M.S., Environmental Engineering, University of Illinois at Urbana-Champaign, 2015 (where the corns are) -- B.Eng., Environmental Engineering, Tongji University, 2014 (the Magic City) - - -My hope for QSDsan ------------------- -When I finished my Ph.D., all I know about coding was from an entry-level, mandatoroy CS course in the freshman year of my undergraduate and several lines of basic VBA in Excel. I was supposed to design and assess biorefineries with a still-at-the-early-stage `BioSTEAM `_. The idea of learning a programming language (even it was as beginner-friendly as Python) and using it to build tools was daunting, and I could hardly understand anything in Python's official documentation. - -But I struggled through that period (thank you all the good-hearted people on `stackoverflow `_), and I began to see the power of programming language, how it could be used to design systems and perform sustainability analyses in ways that I had never seen before. I wanted something like ``BioSTEAM``, but closer to my experimental background of water/wastewater treatment and resource recovery, and I am lucky enough to have talented friends/colleagues working with me and incredibly supportive advisors, so that was the start of ``QSDsan``. - -At the beginning, ``QSDsan`` was just about research, about how we can leverage QSD to prioritize technology advancement and inform decision-making. But the more I work on ``QSDsan`` and reflect on my experiences and the evolution of research methods and topics (e.g., sustainability analyses were hardly a thing decades ago, but now evidence of advancement on sustainability metrics are required for manuscripts to be considered for top-tier journals), as well as pedagogical approahces (e.g., active learning) and education systems (e.g., MOOC), I see great potential in tools like ``QSDsan`` to be used by people outside of the narrow research circle. It could be used to introduce concepts such as acid-base chemistry, to demonstrate how to design an anaerobic reactor, to illustrate how the deployment location of a technology would affect its sustainability. I am fascinated by these possibilities and I hope I can be a part to make them become reality. - - -Why I enjoy research --------------------- -I quoted this as a closing remark for my Ph.D. defense, still (and I sincerely hope forever) close and dear to my heart: - - | I look up at the starry, starry sky - | which is so deep and vast - | the never-ending truth - | inspires me to follow and quest - - - | -- **Jiabao Wen** - | *For Centennial Anniversary of Tongji University* - - -To ruin everything (and show my peculiar taste of humor), this is a traditional dish of Cornwell, England, called stargazy pie (picture from `Wikipedia `_): - -.. figure:: https://upload.wikimedia.org/wikipedia/commons/thumb/2/23/StargazyPie.jpg/2560px-StargazyPie.jpg - :width: 50% - :align: center - -| - - -What I do for fun ------------------ -- I enjoy every outdoor activities (that do not involving getting >50% of your body wet), but hiking so far is my favorite, I've only done a couple of 14ers during my time in Colorado, but I would put all of them on my bucket list. -- I also like to build things (had quite some fun building the hydrothermal reactors when doing my Ph.D.), probably have spent too much time looking at DIY house videos. -- Coding (not just for research, but for fun as well) is becoming my most liked sedentary activity, learning new programming languages is always frustrating and rewarding. - - -Professional ------------- -If you want to check out my publications, the most up-to-date list is on `Google Scholar `_. For my other repositories, `GitHub `_ would be the go-to place. You can also check out my complete `CV `_ to know about my other professional activities (conference presentations, teaching, service, etc.). \ No newline at end of file diff --git a/docs/source/core_developers/_index.rst b/docs/source/core_developers/_index.rst deleted file mode 100644 index ab0e76ea..00000000 --- a/docs/source/core_developers/_index.rst +++ /dev/null @@ -1,51 +0,0 @@ -Core Developers -=============== -Development and maintenance of the platform is supported by the Quantitative Sustainable Design Group led by members of the `Guest Group `_ at the `University of Illinois Urbana-Champaign (UIUC) `_, as well as `other developers `_ that have contributed to the repository. - - -Lead Developers ---------------- - - `Yalin Li`_ (current maintainer) - - `Joy Zhang`_ - - -Tutorials and Videos --------------------- - - `Yalin Li`_ - - `Joy Zhang`_ - - `Tori Morgan `_ - - `Hannah Lohman `_ - - -Module Development ------------------- -`Developers `_ that have contributed to the repository. - - -Funding Support ---------------- - - `Jeremy Guest `_ - - `Roland Cusick `_ - - `William Tarpeh `_ - - -Special Acknowledgement ------------------------ - - Yoel Cortés-Peña for helping many of the ``QSDsan`` members get started on Python and package development. - - -.. Links -.. _Joy Zhang: https://qsdsan.readthedocs.io/en/latest/authors/Joy_Zhang.html -.. _Yalin Li: https://qsdsan.readthedocs.io/en/latest/authors/Yalin_Li.html - - -.. Hidden TOCs for navigation bar -.. toctree:: - :maxdepth: 1 - :hidden: - - Yalin_Li - Joy_Zhang - Tori_Morgan - Hannah_Lohman - Stetson_Rowles \ No newline at end of file diff --git a/docs/source/images/wrrf_configs.png b/docs/source/images/wrrf_configs.png new file mode 100644 index 00000000..96adfb7d Binary files /dev/null and b/docs/source/images/wrrf_configs.png differ diff --git a/docs/source/index.rst b/docs/source/index.rst index 5bf15059..d6272e4f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -28,7 +28,7 @@ What is ``QSDsan``? .. grid-item-card:: Systems :text-align: center - :link: developed_systems + :link: systems :link-type: ref .. figure:: images/systems_icon.svg @@ -47,6 +47,8 @@ What is ``QSDsan``? Installation ------------ +If you are new to Python, we are developing `beginner tutorials `_ with step-to-step guidance starting from setting up your Python environment. + The easiest way is through ``pip``, in command-line interface (Anaconda prompt, terminal): .. code:: @@ -76,14 +78,12 @@ You can also download the package from `PyPI ` Note that development of this package is currently under initial stage with limited backward compatibility, please feel free to `submit an issue `_ for any questions regarding package upgrading. -If you are a developer and want to contribute to ``QSDsan``, please follow the steps in the `contributing`_ section of the documentation to clone the repository. - Join the Community ------------------ We would like to build an open and welcoming community, you can always post issues on our `GitHub homepage `_ or contact any of the Quantitative Sustainable Design Group members. We are always excited to have new members in our team. -If you would like to contribute, please follow our `contributing`_ guidelines and the `code of conduct `_ (a bonus if you use our `templates `_), thank you for making ``QSDsan`` better! +If you would like to contribute, please follow our `Contributing Guidelines`_ and the `Code of Conduct `_ (a bonus if you use our `templates `_), thank you for making ``QSDsan`` better! ``QSDsan`` is and will stay open source under University of Illinois/NCSA Open Source License. Any third-party packages copied from ``QSDsan`` must be strictly open-source (not copy-left nor open-access). Please refer to the `license `_ page for details. @@ -122,7 +122,7 @@ We will keep the calendar up-to-date as we organize more events (office hours, w :maxdepth: 1 :hidden: - Developed_Systems + Systems .. toctree:: @@ -143,7 +143,7 @@ We will keep the calendar up-to-date as we organize more events (office hours, w :maxdepth: 1 :hidden: - core_developers/_index + CODE_OF_CONDUCT .. toctree:: @@ -170,4 +170,4 @@ References .. Links -.. _contributing: https://qsdsan.readthedocs.io/en/latest/CONTRIBUTING.html +.. _Contributing Guidelines: CONTRIBUTING.html#contributing-guidelines \ No newline at end of file diff --git a/docs/source/tutorials/2_Component.ipynb b/docs/source/tutorials/2_Component.ipynb index 3a767a23..3e667b23 100644 --- a/docs/source/tutorials/2_Component.ipynb +++ b/docs/source/tutorials/2_Component.ipynb @@ -68,7 +68,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "This tutorial was made with qsdsan v1.2.0.\n" + "This tutorial was made with qsdsan v1.3.0.\n" ] } ], @@ -293,18 +293,18 @@ "[Data] MW: 18.015 g/mol\n", " Tm: 273.15 K\n", " Tb: 373.12 K\n", - " Tt: 273.15 K\n", - " Tc: 647.14 K\n", - " Pt: 610 Pa\n", - " Pc: 2.2048e+07 Pa\n", - " Vc: 5.6e-05 m^3/mol\n", + " Tt: 273.16 K\n", + " Tc: 647.1 K\n", + " Pt: 611.65 Pa\n", + " Pc: 2.2064e+07 Pa\n", + " Vc: 5.5948e-05 m^3/mol\n", " Hf: -2.8582e+05 J/mol\n", " S0: 70 J/K/mol\n", " LHV: -44011 J/mol\n", " HHV: -0 J/mol\n", " Hfus: 6010 J/mol\n", " Sfus: None\n", - " omega: 0.344\n", + " omega: 0.3443\n", " dipole: 1.85 Debye\n", " similarity_variable: 0.16653\n", " iscyclic_aliphatic: 0\n", @@ -403,7 +403,7 @@ " i_mass: 1.2878 g mass/g N\n", " i_charge: 0.071394 mol +/g N\n", " i_COD: 0 g COD/g N\n", - " i_NOD: 0 g NOD/g N\n", + " i_NOD: 4.5691 g NOD/g N\n", " f_BOD5_COD: 0\n", " f_uBOD_COD: 0\n", " f_Vmass_Totmass: 0\n", @@ -600,7 +600,7 @@ " i_mass: 1 g mass/g \n", " i_charge: 0.055437 mol +/g \n", " i_COD: 0 g COD/g \n", - " i_NOD: 0 g NOD/g \n", + " i_NOD: 3.5478 g NOD/g \n", " f_BOD5_COD: 0\n", " f_uBOD_COD: 0\n", " f_Vmass_Totmass: 0\n", @@ -637,7 +637,7 @@ " i_mass: 1.2878 g mass/g N\n", " i_charge: 0.071394 mol +/g N\n", " i_COD: 0 g COD/g N\n", - " i_NOD: 0 g NOD/g N\n", + " i_NOD: 4.5691 g NOD/g N\n", " f_BOD5_COD: 0\n", " f_uBOD_COD: 0\n", " f_Vmass_Totmass: 0\n", @@ -1013,27 +1013,6 @@ ">>> cmps" ] }, - { - "cell_type": "code", - "execution_count": 40, - "metadata": {}, - "outputs": [], - "source": [ - "# Note that it's fine to have the \">>>\" or \"...\" (indicates line continuation), in front of the code\n", - "# (indication doesn't matter either) as long as you don't have comments\n", - "# So the previous cell will work but this cell won't\n", - "# >>> import qsdsan as qs\n", - "# >>> chems = qs.Chemicals((qs.Chemical('Water'), qs.Chemical('Ethanol')))\n", - "# >>> data = {'Water': {'particle_size': 'Soluble',\n", - "# ... 'degradability': 'Undegradable',\n", - "# ... 'organic': False},\n", - "# ... 'Ethanol': {'particle_size': 'Soluble',\n", - "# ... 'degradability': 'Readily',\n", - "# ... 'organic': False}}\n", - "# >>> cmps2 = qs.Components.from_chemicals(chems, **data)\n", - "# >>> cmps2" - ] - }, { "cell_type": "markdown", "metadata": {}, @@ -1044,7 +1023,7 @@ }, { "cell_type": "code", - "execution_count": 41, + "execution_count": 40, "metadata": {}, "outputs": [ { @@ -1070,7 +1049,7 @@ }, { "cell_type": "code", - "execution_count": 42, + "execution_count": 41, "metadata": {}, "outputs": [ { @@ -1161,8 +1140,8 @@ " 0.717\n", " 0.863\n", " 1\n", - " 64-19-7\n", - " 176\n", + " 71-50-1\n", + " 175\n", " \n", " \n", " 4\n", @@ -1175,8 +1154,8 @@ " 0.717\n", " 0.863\n", " 1\n", - " 79-09-3\n", - " 1.03e+03\n", + " 72-03-7\n", + " 1.05e+05\n", " \n", " \n", "\n", @@ -1184,24 +1163,17 @@ "" ], "text/plain": [ - " ID description formula particle_size degradability \\\n", - "0 S_H2 Dissolved dihydrogen gas H2 Dissolved gas Readily \n", - "1 S_CH4 Dissolved Methane CH4 Dissolved gas Readily \n", - "2 S_CH3OH Methanol CH3OH Soluble Readily \n", - "3 S_Ac Acetate CH3COO(-) Soluble Readily \n", - "4 S_Prop Propionate C2H5COO- Soluble Readily \n", - "\n", - " ... f_BOD5_COD f_uBOD_COD f_Vmass_Totmass CAS PubChem \n", - "0 ... 0 0 1 1333-74-0 783 \n", - "1 ... 0 0 1 74-82-8 297 \n", - "2 ... 0.717 0.863 1 67-56-1 887 \n", - "3 ... 0.717 0.863 1 64-19-7 176 \n", - "4 ... 0.717 0.863 1 79-09-3 1.03e+03 \n", + " ID description formula particle_size degradability ... f_BOD5_COD f_uBOD_COD f_Vmass_Totmass CAS PubChem\n", + "0 S_H2 Dissolved dihydrogen gas H2 Dissolved gas Readily ... 0 0 1 1333-74-0 783\n", + "1 S_CH4 Dissolved Methane CH4 Dissolved gas Readily ... 0 0 1 74-82-8 297\n", + "2 S_CH3OH Methanol CH3OH Soluble Readily ... 0.717 0.863 1 67-56-1 887\n", + "3 S_Ac Acetate CH3COO(-) Soluble Readily ... 0.717 0.863 1 71-50-1 175\n", + "4 S_Prop Propionate C2H5COO- Soluble Readily ... 0.717 0.863 1 72-03-7 1.05e+05\n", "\n", "[5 rows x 22 columns]" ] }, - "execution_count": 42, + "execution_count": 41, "metadata": {}, "output_type": "execute_result" } @@ -1217,20 +1189,18 @@ }, { "cell_type": "code", - "execution_count": 43, + "execution_count": 42, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "Index(['ID', 'description', 'formula', 'particle_size', 'degradability',\n", - " 'organic', 'measured_as', 'i_C', 'i_N', 'i_P', 'i_K', 'i_Mg', 'i_Ca',\n", - " 'i_mass', 'i_charge', 'i_COD', 'i_NOD', 'f_BOD5_COD', 'f_uBOD_COD',\n", - " 'f_Vmass_Totmass', 'CAS', 'PubChem'],\n", + "Index(['ID', 'description', 'formula', 'particle_size', 'degradability', 'organic', 'measured_as', 'i_C', 'i_N', 'i_P', 'i_K', 'i_Mg', 'i_Ca', 'i_mass',\n", + " 'i_charge', 'i_COD', 'i_NOD', 'f_BOD5_COD', 'f_uBOD_COD', 'f_Vmass_Totmass', 'CAS', 'PubChem'],\n", " dtype='object')" ] }, - "execution_count": 43, + "execution_count": 42, "metadata": {}, "output_type": "execute_result" } @@ -1239,6 +1209,24 @@ "df.columns" ] }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Components([S_H2, S_CH4, S_CH3OH, S_Ac, S_Prop, S_F, S_U_Inf, S_U_E, C_B_Subst, C_B_BAP, C_B_UAP, C_U_Inf, X_B_Subst, X_OHO_PHA, X_GAO_PHA, X_PAO_PHA, X_GAO_Gly, X_PAO_Gly, X_OHO, X_AOO, X_NOO, X_AMO, X_PAO, X_MEOLO, X_FO, X_ACO, X_HMO, X_PRO, X_U_Inf, X_U_OHO_E, X_U_PAO_E, X_Ig_ISS, X_MgCO3, X_CaCO3, X_MAP, X_HAP, X_HDP, X_FePO4, X_AlPO4, X_AlOH, X_FeOH, X_PAO_PP_Lo, X_PAO_PP_Hi, S_NH4, S_NO2, S_NO3, S_PO4, S_K, S_Ca, S_Mg, S_CO3, S_N2, S_O2, S_CAT, S_AN])\n" + ] + } + ], + "source": [ + "cmps2 = qs.Components.load_from_file(df)\n", + "cmps2.show()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -1291,7 +1279,7 @@ " \n", "# Now we can compile\n", "cmps1.compile()\n", - "cmps1" + "cmps1.show()" ] }, { @@ -1308,9 +1296,9 @@ } ], "source": [ - "# For the default `Components` objects, the easy way is let it compile during loading\n", + "# For the default `Components` objects, the easy way is to let it compile during loading\n", "cmps3 = qs.Components.load_default()\n", - "cmps3" + "cmps3.show()" ] }, { @@ -1341,7 +1329,7 @@ "# would be to make a new `Components` containing all the `Component` objects in the `CompiledComponent`\n", "cmps4 = qs.Components(cmps1)\n", "cmps4.append(cmps3.S_H2)\n", - "cmps4" + "cmps4.show()" ] }, { @@ -1362,7 +1350,7 @@ "# you can hand pick the `Component` IDs you want and input it to the \n", "# `.subgroup()` method.\n", "cmps5 = cmps3.subgroup(['S_CH4', 'S_Ac', 'S_F', 'S_NH4'])\n", - "cmps5" + "cmps5.show()" ] }, { @@ -1523,7 +1511,7 @@ { "data": { "text/plain": [ - "140171061956096" + "2332755558272" ] }, "execution_count": 57, @@ -1543,7 +1531,7 @@ { "data": { "text/plain": [ - "140171081327744" + "2332718576768" ] }, "execution_count": 58, diff --git a/docs/source/tutorials/_installation.rst b/docs/source/tutorials/_installation.rst index 5c08485a..af322bcc 100644 --- a/docs/source/tutorials/_installation.rst +++ b/docs/source/tutorials/_installation.rst @@ -1,9 +1,9 @@ Extended Installation Instructions ================================== -If you are new to Python and not even sure how to set up your Python environment, or if you find the pip-installed ``QSDsan`` cannot satisfy your needs but you are not sure how to clone it, then the following instructions might be of help. +If you are new to Python and not even sure how to set up your Python environment, please also refer to our `beginner tutorials `_ (work in progress). -Note that this is just ONE way to set up your environment, not THE way. +Note that this is just ONE way to set up your environment and cloning the latest ``QSDsan``-related packages (not the pip-installed version which are only released periodically), not THE way. #. Download and install `Anaconda `_ diff --git a/qsdsan/_component.py b/qsdsan/_component.py index 1a2d60a9..98f43b0a 100644 --- a/qsdsan/_component.py +++ b/qsdsan/_component.py @@ -233,6 +233,10 @@ def __new__(cls, ID, search_ID=None, formula=None, phase=None, measured_as=None, self._chem_MW = molecular_weight(self.atoms) if phase: lock_phase(self, phase) + self._particle_size = particle_size + self._degradability = degradability + self._organic = organic + self.description = description self._measured_as = measured_as self.i_mass = i_mass self.i_C = i_C @@ -245,10 +249,7 @@ def __new__(cls, ID, search_ID=None, formula=None, phase=None, measured_as=None, self.f_BOD5_COD = f_BOD5_COD self.f_uBOD_COD = f_uBOD_COD self.f_Vmass_Totmass = f_Vmass_Totmass - self._particle_size = particle_size - self._degradability = degradability - self._organic = organic - self.description = description + if not self.MW and not self.formula: self.MW = 1. self.i_COD = i_COD self.i_NOD = i_NOD @@ -340,7 +341,8 @@ def i_mass(self, i): chem_charge = charge_from_formula(self.formula) Cr2O7 = - cod_test_stoichiometry(self.atoms, chem_charge)['Cr2O7-2'] cod = Cr2O7 * 1.5 * molecular_weight({'O':2}) - i = self.chem_MW/cod + try: i = self.chem_MW/cod + except: breakpoint() elif self.measured_as: raise AttributeError(f'Must specify i_mass for component {self.ID} ' f'measured as {self.measured_as}.') @@ -532,7 +534,7 @@ def i_COD(self): def i_COD(self, i): if i is not None: self._i_COD = check_return_property('i_COD', i) else: - if self.organic or self.formula in ('H2', 'O2', 'N2', 'NO2-', 'NO3-'): + if self.organic or self.formula in ('H2', 'O2', 'N2', 'NO2-', 'NO3-', 'H2S', 'S'): if self.measured_as == 'COD': self._i_COD = 1. elif not self.atoms: raise AttributeError(f"Must specify `i_COD` for organic component {self.ID}, " @@ -792,6 +794,10 @@ def from_chemical(cls, ID, chemical=None, formula=None, phase=None, measured_as= new.Tm, new.Tb, new.eos, new.phase_ref, new.S0) TDependentProperty.RAISE_PROPERTY_CALCULATION_ERROR = True + new.description = description + new._particle_size = particle_size + new._degradability = degradability + new._organic = organic new._measured_as = measured_as new.i_mass = i_mass new.i_C = i_C @@ -804,10 +810,7 @@ def from_chemical(cls, ID, chemical=None, formula=None, phase=None, measured_as= new.f_BOD5_COD = f_BOD5_COD new.f_uBOD_COD = f_uBOD_COD new.f_Vmass_Totmass = f_Vmass_Totmass - new.description = description - new._particle_size = particle_size - new._degradability = degradability - new._organic = organic + new.i_COD = i_COD new.i_NOD = i_NOD return new \ No newline at end of file diff --git a/qsdsan/_impact_item.py b/qsdsan/_impact_item.py index c7705908..98fc476a 100644 --- a/qsdsan/_impact_item.py +++ b/qsdsan/_impact_item.py @@ -383,8 +383,12 @@ def get_item(cls, ID): @classmethod def _load_from_df(cls, name, df): if name.lower() == 'info': + if 'kind' not in df.columns: df['kind'] = 'ImpactItem' for num in df.index: - new = cls.__new__(cls) + kind = df.iloc[num].kind.lower() + if kind == 'streamimpactitem': + new = StreamImpactItem.__new__(StreamImpactItem) + else: new = cls.__new__(cls) new.__init__(ID=df.iloc[num].ID, functional_unit=df.iloc[num].functional_unit) else: @@ -409,8 +413,9 @@ def load_from_file(cls, path_or_dict, index_col=None): This Excel should have multiple sheets: - - The "info" sheet should have two columns: "ID" (e.g., Cement) \ - and "functional_unit" (e.g., kg) of different impact items. + - The "info" sheet should have three columns: "ID" (e.g., Cement) \ + "functional_unit" (e.g., kg), and "kind" ("ImpactItem" or "StreamImpactItem") + of different impact items. - The remaining sheets should contain characterization factors of \ impact indicators. diff --git a/qsdsan/_process.py b/qsdsan/_process.py index df1a812b..35ae8ff1 100644 --- a/qsdsan/_process.py +++ b/qsdsan/_process.py @@ -706,8 +706,9 @@ def _normalize_stoichiometry(self, new_ref): self._stoichiometry = [v/factor for v in stoich] def _normalize_rate_eq(self, new_ref): - factor = abs(self._stoichiometry[self._components.index(str(new_ref))]) - self._rate_equation *= factor + if self._rate_equation: + factor = abs(self._stoichiometry[self._components.index(str(new_ref))]) + self._rate_equation *= factor def show(self): info = f"Process: {self.ID}" diff --git a/qsdsan/_waste_stream.py b/qsdsan/_waste_stream.py index 34d7820c..eedf9304 100644 --- a/qsdsan/_waste_stream.py +++ b/qsdsan/_waste_stream.py @@ -40,12 +40,13 @@ _defined_composite_vars = ('COD', 'BOD5', 'BOD', 'uBOD', 'NOD', 'ThOD', 'cnBOD', 'C', 'N', 'P', 'K', 'Mg', 'Ca', 'solids', 'charge') -_common_composite_vars = ('_COD', '_BOD', '_uBOD', '_TC', '_TOC', '_TN', +_common_composite_vars = ('_COD', '_BOD', '_uBOD', '_ThOD', '_cnBOD', + '_TC', '_TOC', '_TN', '_TKN', '_TP', '_TK', '_TMg', '_TCa', - '_dry_mass', '_charge', '_ThOD', '_cnBOD') + '_dry_mass', '_charge',) _ws_specific_slots = (*_common_composite_vars, - '_pH', '_SAlk', '_ratios', + '_pH', '_SAlk', '_ratios', 'additional_properties', # '_stream_impact_item', (pls keep this here, might be useful in debugging) '_state', '_dstate', '_scope') @@ -249,7 +250,9 @@ class WasteStream(SanStream): TO BE IMPLEMENTED stream_impact_item : :class:`StreamImpactItem` The :class:`StreamImpactItem` this stream is linked to. - component_flows : kwargs + additional_properties : dict + Additional properties (e.g., turbidity). + component_flows : dict Component flow data. @@ -271,20 +274,28 @@ def __init__(self, ID='', flow=(), phase='l', T=298.15, P=101325., pH=7., SAlk=2.5, COD=None, BOD=None, uBOD=None, ThOD=None, cnBOD=None, TC=None, TOC=None, TN=None, TKN=None, TP=None, TK=None, - TMg=None, TCa=None, dry_mass=None, charge=None, ratios=None, - stream_impact_item=None, **component_flows): + TMg=None, TCa=None, + dry_mass=None, charge=None, ratios=None, + stream_impact_item=None, additional_properties={}, + **component_flows): SanStream.__init__(self=self, ID=ID, flow=flow, phase=phase, T=T, P=P, units=units, price=price, thermo=thermo, stream_impact_item=stream_impact_item, **component_flows) - self._init_ws(pH, SAlk, COD, BOD, uBOD, TC, TOC, TN, TKN, - TP, TK, TMg, TCa, ThOD, cnBOD, dry_mass, charge, ratios) + self._init_ws(pH=pH, SAlk=SAlk, COD=COD, BOD=BOD, uBOD=uBOD, + ThOD=ThOD, cnBOD=cnBOD, + TC=TC, TOC=TOC, TN=TN, TKN=TKN, + TP=TP, TK=TK, TMg=TMg, TCa=TCa, + dry_mass=dry_mass, charge=charge, ratios=ratios, + additional_properties=additional_properties, + ) def _init_ws(self, pH=7., SAlk=None, COD=None, BOD=None, uBOD=None, ThOD=None, cnBOD=None, TC=None, TOC=None, TN=None, TKN=None, TP=None, TK=None, TMg=None, TCa=None, - dry_mass=None, charge=None, ratios=None): + dry_mass=None, charge=None, ratios=None, + additional_properties={}): self._pH = pH self._SAlk = SAlk @@ -306,6 +317,7 @@ def _init_ws(self, pH=7., SAlk=None, COD=None, BOD=None, self._ratios = ratios self._state = None self._dstate = None + self.additional_properties = {} @staticmethod def from_stream(stream, ID='', **kwargs): @@ -2245,6 +2257,11 @@ def dry_mass(self): def density(self): '''[float] Density of the stream, in mg/L (kg/m3).''' return 0. + + @property + def additional_property(self): + '''[dict] Additional properties (e.g., turbidity).''' + return {} #!!! Keep this up-to-date with WasteStream # @property diff --git a/qsdsan/data/process_data/_madm1.tsv b/qsdsan/data/process_data/_madm1.tsv new file mode 100644 index 00000000..7493add1 --- /dev/null +++ b/qsdsan/data/process_data/_madm1.tsv @@ -0,0 +1,47 @@ + S_su S_aa S_fa S_va S_bu S_pro S_ac S_h2 S_ch4 S_IC S_IN S_IP S_I X_ch X_pr X_li X_su X_aa X_fa X_c4 X_pro X_ac X_h2 X_I X_PHA X_PP X_PAO S_K S_Mg S_SO4 S_IS X_hSRB X_aSRB X_pSRB X_c4SRB S_S0 S_Fe3 S_Fe2 X_HFO_H X_HFO_L X_HFO_old X_HFO_HP X_HFO_LP X_HFO_HP_old X_HFO_LP_old +hydrolysis_carbs 1 ? ? ? -1 +hydrolysis_proteins 1 ? ? ? -1 +hydrolysis_lipids 1-f_fa_li f_fa_li ? ? ? -1 +uptake_sugars -1 (1-Y_su)*f_bu_su (1-Y_su)*f_pro_su (1-Y_su)*f_ac_su (1-Y_su)*f_h2_su ? ? ? Y_su +uptake_amino_acids -1 (1-Y_aa)*f_va_aa (1-Y_aa)*f_bu_aa (1-Y_aa)*f_pro_aa (1-Y_aa)*f_ac_aa (1-Y_aa)*f_h2_aa ? ? ? Y_aa +uptake_LCFA -1 (1-Y_fa)*f_ac_fa (1-Y_fa)*f_h2_fa ? ? ? Y_fa +uptake_valerate -1 (1-Y_c4)*f_pro_va (1-Y_c4)*f_ac_va (1-Y_c4)*f_h2_va ? ? ? Y_c4 +uptake_butyrate -1 (1-Y_c4)*f_ac_bu (1-Y_c4)*f_h2_bu ? ? ? Y_c4 +uptake_propionate -1 (1-Y_pro)*f_ac_pro (1-Y_pro)*f_h2_pro ? ? ? Y_pro +uptake_acetate -1 1-Y_ac ? ? ? Y_ac +uptake_h2 -1 1-Y_h2 ? ? ? Y_h2 +decay_Xsu ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb -1 f_xI_xb +decay_Xaa ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb -1 f_xI_xb +decay_Xfa ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb -1 f_xI_xb +decay_Xc4 ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb -1 f_xI_xb +decay_Xpro ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb -1 f_xI_xb +decay_Xac ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb -1 f_xI_xb +decay_Xh2 ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb -1 f_xI_xb +storage_PHA_valerate -1 ? ? ? 1 -Y_PO4 Y_PO4*K_XPP Y_PO4*Mg_XPP +storage_PHA_butyrate -1 ? ? ? 1 -Y_PO4 Y_PO4*K_XPP Y_PO4*Mg_XPP +storage_PHA_propionate -1 ? ? ? 1 -Y_PO4 Y_PO4*K_XPP Y_PO4*Mg_XPP +storage_PHA_actate -1 ? ? ? 1 -Y_PO4 Y_PO4*K_XPP Y_PO4*Mg_XPP +lysis_XPAO ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb f_xI_xb -1 +lysis_XPP ? ? ? -1 K_XPP Mg_XPP +lysis_XPHA f_va_pha f_bu_pha f_pro_pha f_ac_pha ? ? ? -1 +growth_SRB_h2 -1 ? ? ? -1*(1-Y_hSRB)*i_mass_IS*(MW_S0/MW_IS) 1-Y_hSRB Y_hSRB +decay_XhSRB ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb f_xI_xb -1 +growth_SRB_acetate -1 ? ? ? -1*(1-Y_aSRB)*i_mass_IS*(MW_S0/MW_IS) 1-Y_aSRB Y_aSRB +decay_XaSRB ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb f_xI_xb -1 +growth_SRB_propionate -1 (1-Y_pSRB)*f_ac_pro ? ? ? -1*(1-Y_pSRB)*f_is_pro*i_mass_IS*(MW_S0/MW_IS) (1-Y_pSRB)*f_is_pro Y_pSRB +decay_XpSRB ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb f_xI_xb -1 +growth_SRB_butyrate -1 (1-Y_c4SRB)*f_ac_bu ? ? ? -1*(1-Y_c4SRB)*f_is_bu*i_mass_IS*(MW_S0/MW_IS) (1-Y_c4SRB)*f_is_bu Y_c4SRB +growth_SRB_valerate -1 (1-Y_c4SRB)*f_pro_va (1-Y_c4SRB)*f_ac_va ? ? ? -1*(1-Y_c4SRB)*f_is_va*i_mass_IS*(MW_S0/MW_IS) (1-Y_c4SRB)*f_is_va Y_c4SRB +decay_Xc4SRB ? ? ? f_sI_xb f_ch_xb f_pr_xb f_li_xb f_xI_xb -1 +reduction_HFO_H_h2 -1 1 -1*i_mass_Fe2 +reduction_HFO_L_h2 -1 1 -1*i_mass_Fe2 +reduction_HFO_H_IS -1 (MW_S0/i_mass_S0)/(MW_IS/i_mass_IS) 1-(MW_S0/i_mass_S0)/(MW_IS/i_mass_IS) i_mass_Fe2*((MW_S0/i_mass_S0)/(MW_IS/i_mass_IS)-1) +reduction_HFO_L_IS -1 (MW_S0/i_mass_S0)/(MW_IS/i_mass_IS) 1-(MW_S0/i_mass_S0)/(MW_IS/i_mass_IS) i_mass_Fe2*((MW_S0/i_mass_S0)/(MW_IS/i_mass_IS)-1) +aging_HFO_H -1 1 +aging_HFO_L -1 1 +fast_P_binding ? -1 1 +slow_P_sorption ? -1 1 +aging_HFO_HP -1 1 +aging_HFO_LP -1 1 +dissolution_HFO_HP ? 1 -1 +dissolution_HFO_LP ? 1 -1 diff --git a/qsdsan/processes/__init__.py b/qsdsan/processes/__init__.py index 51e6f0c2..394a97f8 100644 --- a/qsdsan/processes/__init__.py +++ b/qsdsan/processes/__init__.py @@ -18,6 +18,7 @@ from ._asm2d import * from ._adm1 import * from ._adm1_p_extension import * +from ._madm1 import * from ._decay import * from ._kinetic_reaction import * from ._pm2 import * @@ -28,6 +29,7 @@ _asm2d, _adm1, _adm1_p_extension, + _madm1, _decay, _kinetic_reaction, ) @@ -38,6 +40,7 @@ *_asm2d.__all__, *_adm1.__all__, *_adm1_p_extension.__all__, + *_madm1.__all__, *_decay.__all__, *_kinetic_reaction.__all__, *_pm2.__all__, diff --git a/qsdsan/processes/_adm1.py b/qsdsan/processes/_adm1.py index 32d99819..161f9cfb 100644 --- a/qsdsan/processes/_adm1.py +++ b/qsdsan/processes/_adm1.py @@ -190,6 +190,9 @@ def mass2mol_conversion(cmps): # return np.exp(theta * (T2-T1)) def T_correction_factor(T1, T2, delta_H): + """compute temperature correction factor for equilibrium constants based on + the Van't Holf equation.""" + if T1 == T2: return 1 return np.exp(delta_H/(R*100) * (1/T1 - 1/T2)) # R converted to SI # def calc_Kas(pKas, T_base, T_op, theta): @@ -267,10 +270,24 @@ def rhos_adm1(state_arr, params): weak_acids = cmps_in_M[[24, 25, 10, 9, 6, 5, 4, 3]] T_op = state_arr[-1] + if T_op == T_base: + Ka = Kab + KH = KHb / unit_conversion[7:10] + else: + T_temp = params.pop('T_op', None) + if T_op == T_temp: + params['T_op'] = T_op + Ka = params['Ka'] + KH = params['KH'] + else: + params['T_op'] = T_op + Ka = params['Ka'] = Kab * T_correction_factor(T_base, T_op, Ka_dH) + KH = params['KH'] = KHb * T_correction_factor(T_base, T_op, KH_dH) / unit_conversion[7:10] + biogas_S = state_arr[7:10].copy() biogas_p = R * T_op * state_arr[27:30] - Kas = Kab * T_correction_factor(T_base, T_op, Ka_dH) - KH = KHb * T_correction_factor(T_base, T_op, KH_dH) / unit_conversion[7:10] + # Kas = Kab * T_correction_factor(T_base, T_op, Ka_dH) + # KH = KHb * T_correction_factor(T_base, T_op, KH_dH) / unit_conversion[7:10] rhos[:-3] = ks * Cs Monod = substr_inhibit(substrates, Ks) @@ -279,12 +296,12 @@ def rhos_adm1(state_arr, params): if S_bu > 0: rhos[8] *= 1/(1+S_va/S_bu) h = brenth(acid_base_rxn, 1e-14, 1.0, - args=(weak_acids, Kas), + args=(weak_acids, Ka), xtol=1e-12, maxiter=100) # h = 10**(-7.46) - nh3 = Kas[1] * weak_acids[2] / (Kas[1] + h) - co2 = weak_acids[3] - Kas[2] * weak_acids[3] / (Kas[2] + h) + nh3 = Ka[1] * weak_acids[2] / (Ka[1] + h) + co2 = weak_acids[3] - Ka[2] * weak_acids[3] / (Ka[2] + h) biogas_S[-1] = co2 / unit_conversion[9] Iph = Hill_inhibit(h, pH_ULs, pH_LLs) diff --git a/qsdsan/processes/_kinetic_reaction.py b/qsdsan/processes/_kinetic_reaction.py index e37b0886..565d2da2 100644 --- a/qsdsan/processes/_kinetic_reaction.py +++ b/qsdsan/processes/_kinetic_reaction.py @@ -115,7 +115,7 @@ class KineticReaction(Rxn): >>> rxn.rate_equation -2.2e-5*C(t) - Derivative(C(t), t) >>> rxn.integrated_rate_equation.evalf(n=5) # `evalf` is to limit the digits - 0.035543/2.7183**(2.2e-5*t) + 0.037578/2.7183**(2.2e-5*t) >>> round(rxn.half_life, 2) 31506.69 >>> # You can also look at the conversion over time diff --git a/qsdsan/processes/_madm1.py b/qsdsan/processes/_madm1.py new file mode 100644 index 00000000..02ff1b77 --- /dev/null +++ b/qsdsan/processes/_madm1.py @@ -0,0 +1,787 @@ +# -*- coding: utf-8 -*- +''' +QSDsan: Quantitative Sustainable Design for sanitation and resource recovery systems + +This module is developed by: + Joy Zhang + +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. +''' + +from thermosteam.utils import chemicals_user +from thermosteam import settings +from chemicals.elements import molecular_weight as get_mw +from qsdsan import Component, Components, Process, Processes, CompiledProcesses +import numpy as np, qsdsan.processes as pc, qsdsan as qs +from qsdsan.utils import ospath, data_path +from qsdsan.processes._adm1 import ( + R, + create_adm1_cmps, + ADM1, + mass2mol_conversion, + T_correction_factor, + substr_inhibit, + non_compet_inhibit, + Hill_inhibit + ) +# from scipy.optimize import brenth +# from warnings import warn + + +__all__ = ('create_madm1_cmps', 'ModifiedADM1') + +_path = ospath.join(data_path, 'process_data/_madm1.tsv') + +#%% components +# C_mw = get_mw({'C':1}) +N_mw = get_mw({'N':1}) +P_mw = get_mw({'P':1}) +S_mw = get_mw({'S':1}) +Fe_mw = get_mw({'Fe':1}) +O_mw = get_mw({'O':1}) + +def create_madm1_cmps(set_thermo=True, ASF_L=0.31, ASF_H=1.2): + ''' + Create a set of components for the modified ADM1. + + Parameters + ---------- + set_thermo : bool, optional + Whether to set thermo with the returned set of components. The default is True. + ASF_L : float, optional + Active site factor for X_HFO_L [mol P sites/mol Fe]. The default is 0.31. + ASF_H : float, optional + Active site factor for X_HFO_H [mol P sites/mol Fe]. The default is 1.2. + + Returns + ------- + cmps_madm1 : class:`CompiledComponents` + + ''' + + # Components from the original ADM1 + # ********************************* + _cmps = create_adm1_cmps(False) + S_aa = _cmps.S_aa + X_pr = _cmps.X_pr + S_aa.i_C = X_pr.i_C = 0.36890 + S_aa.i_N = X_pr.i_N = 0.11065 + S_aa.i_P = X_pr.i_P = 0. + S_aa.i_mass = X_pr.i_mass = 1/1.35566 + + S_fa = _cmps.S_fa + S_fa.formula = 'C25H52O3' + S_bu = _cmps.S_bu + S_bu.formula = 'C4H8O2' + S_pro = _cmps.S_pro + S_pro.formula = 'C3H6O2' + S_ac = _cmps.S_ac + S_ac.formula = 'C2H4O2' + + S_I = _cmps.S_I + X_I = _cmps.X_I + S_I.i_C = X_I.i_C = 0.36178 + S_I.i_N = X_I.i_N = 0.06003 + S_I.i_P = X_I.i_P = 0.00649 + S_I.i_mass = X_I.i_mass = 1/1.54100 + + X_ch = _cmps.X_ch + X_ch.formula = 'C24H48O24' + # _cmps.X_li.formula = 'C64H119O7.5P' + X_li = X_pr.copy('X_li') + X_li.i_C = 0.26311 + X_li.i_N = 0. + X_li.i_P = 0.01067 + X_li.i_mass = 1/2.81254 + + adm1_biomass = (_cmps.X_su, _cmps.X_aa, _cmps.X_fa, _cmps.X_c4, _cmps.X_pro, _cmps.X_ac, _cmps.X_h2) + for bio in adm1_biomass: + # bio.formula = 'C5H7O2NP0.113' + bio.i_C = 0.36612 + bio.i_N = 0.08615 + bio.i_P = 0.02154 + bio.i_mass = 1/1.39300 + + # P related components from ASM2d + # ******************************* + asm_cmps = pc.create_asm2d_cmps(False) + X_PHA = asm_cmps.X_PHA + X_PHA.formula = '(C2H4O)n' + # X_PHA.i_C = 0.3 + # X_PHA.i_mass = 0.55 + + X_PAO = _cmps.X_su.copy('X_PAO') + X_PAO.description = 'Phosphorus-accumulating organism biomass' + + # Additional components for P, S, Fe extensions + # ********************************************* + S_IP = asm_cmps.S_PO4.copy('S_IP') + + ion_properties = dict( + particle_size='Soluble', + degradability='Undegradable', + organic=False) + S_K = Component.from_chemical('S_K', chemical='K+', description='Potassium ion', + measured_as='K', **ion_properties) + S_Mg = Component.from_chemical('S_Mg', chemical='Mg2+', description='Magnesium ion', + measured_as='Mg',**ion_properties) + S_SO4 = Component.from_chemical('S_SO4', chemical='SO4-2', description='Sulfate', + measured_as='S', **ion_properties) + S_IS = Component.from_chemical('S_IS', chemical='H2S', + description='Hydrogen sulfide', + measured_as='COD', + particle_size='Soluble', + degradability='Undegradable', + organic=False) + + X_hSRB = X_PAO.copy('X_hSRB') + X_hSRB.description = 'sulfate-reducing biomass, utilizing H2' + X_aSRB = X_PAO.copy('X_aSRB') + X_aSRB.description = 'sulfate-reducing biomass, utilizing acetate' + X_pSRB = X_PAO.copy('X_pSRB') + X_pSRB.description = 'sulfate-reducing biomass, utilizing propionate' + X_c4SRB = X_PAO.copy('X_c4SRB') + X_c4SRB.description = 'sulfate-reducing biomass, utilizing butyrate and valerate' + + S_S0 = Component.from_chemical('S_S0', chemical='S', + description='Elemental sulfur', + measured_as='COD', + particle_size='Soluble', + degradability='Undegradable', + organic=False) + S_Fe3 = Component.from_chemical('S_Fe3', chemical='Fe3+', description='Iron (III)', + measured_as='Fe',**ion_properties) + S_Fe2 = Component.from_chemical('S_Fe2', chemical='Fe2+', description='Iron (II)', + measured_as='Fe',**ion_properties) + S_Fe2.i_COD = 0.5*O_mw/Fe_mw + S_Fe2.measured_as = 'COD' + + # Multiple mineral precipitation + # ****************************** + mineral_properties = dict( + particle_size='Particulate', + degradability='Undegradable', + organic=False) + + X_HFO_H = Component('X_HFO_H', formula='FeO(OH)', + description='Hydrous ferric oxide with high number of active sites', + measured_as='Fe',**mineral_properties) + X_HFO_L = X_HFO_H.copy('X_HFO_L') + X_HFO_L.description = 'Hydrous ferric oxide with low number of active sites' + + X_HFO_old = X_HFO_H.copy('X_HFO_old') + X_HFO_old.description = 'Inactive hydrous ferric oxide' + + X_HFO_HP = Component('X_HFO_HP', formula=f'FeO(OH)P{ASF_H}', + description='X_HFO_H with phosphorus-bounded adsorption sites', + measured_as='Fe', **mineral_properties) + X_HFO_HP_old = X_HFO_HP.copy('X_HFO_HP_old') + X_HFO_HP_old.description = 'Old ' + X_HFO_HP.description + + X_HFO_LP = Component('X_HFO_LP', formula=f'FeO(OH)P{ASF_L}', + description='X_HFO_L with phosphorus-bounded adsorption sites', + measured_as='Fe', **mineral_properties) + X_HFO_LP_old = X_HFO_LP.copy('X_HFO_LP_old') + X_HFO_LP_old.description = 'Old ' + X_HFO_LP.description + + X_CCM = Component.from_chemical('X_CCM', chemical='calcite', description='Calcite', **mineral_properties) + X_ACC = Component.from_chemical('X_ACC', chemical='aragonite', description='Aragonite', **mineral_properties) + X_ACP = Component.from_chemical('X_ACP', chemical='Ca3(PO4)2', description='Amorphous calcium phosphate', **mineral_properties) + X_HAP = Component.from_chemical('X_HAP', chemical='hydroxylapatite', description='Hydroxylapatite', **mineral_properties) + X_DCPD = Component.from_chemical('X_DCPD', chemical='CaHPO4', description='Dicalcium phosphate', **mineral_properties) + X_OCP = Component('X_OCP', formula='Ca4HP3O12', description='Octacalcium phosphate', **mineral_properties) + X_struv = Component.from_chemical('X_struv', chemical='MgNH4PO4', description='Struvite', **mineral_properties) + X_newb = Component.from_chemical('X_newb', chemical='MgHPO4', description='Newberyite', **mineral_properties) + X_magn = Component.from_chemical('X_magn', chemical='MgCO3', description='Magnesite', **mineral_properties) + X_kstruv = Component('X_kstruv', formula='MgKPO4', description='K-struvite', **mineral_properties) + X_FeS = Component.from_chemical('X_FeS', chemical='FeS', description='Iron sulfide', **mineral_properties) + X_Fe3PO42 = Component('X_Fe3PO42', formula='Fe3(PO4)2', description='Ferrous phosphate', **mineral_properties) + X_AlPO4 = Component.from_chemical('X_AlPO4', chemical='AlPO4', description='Aluminum phosphate', **mineral_properties) + + S_Ca = Component.from_chemical('S_Ca', chemical='Ca2+', description='Calsium ion', + measured_as='Ca', **ion_properties) + S_Al = Component.from_chemical('S_Al', chemical='Al3+', description='Aluminum ion', + measured_as='Al', **ion_properties) + S_Na = Component.from_chemical('S_Na', chemical='Na+', description='Sodium ion', + measured_as='Na', **ion_properties) + S_Cl = Component.from_chemical('S_Cl', chemical='Cl-', description='Chloride', + measured_as='Cl', **ion_properties) + + cmps_madm1 = Components([_cmps.S_su, S_aa, S_fa, _cmps.S_va, S_bu, + S_pro, S_ac, _cmps.S_h2, _cmps.S_ch4, + _cmps.S_IC, _cmps.S_IN, S_IP, S_I, + X_ch, X_pr, X_li, *adm1_biomass, X_I, + X_PHA, asm_cmps.X_PP, X_PAO, S_K, S_Mg, + S_SO4, S_IS, X_hSRB, X_aSRB, X_pSRB, X_c4SRB, + S_S0, S_Fe3, S_Fe2, X_HFO_H, X_HFO_L, X_HFO_old, + X_HFO_HP, X_HFO_LP, X_HFO_HP_old, X_HFO_LP_old, + S_Ca, S_Al, X_CCM, X_ACC, X_ACP, X_HAP, X_DCPD, + X_OCP, X_struv, X_newb, X_magn, X_kstruv, X_FeS, + X_Fe3PO42, X_AlPO4, + S_Na, S_Cl, _cmps.H2O]) + cmps_madm1.default_compile() + + if set_thermo: qs.set_thermo(cmps_madm1) + return cmps_madm1 + +#%% rate functions + +# https://wiki.dynamita.com/en/biokinetic_process_models#chemical-phosphorus-removal-with-metal-salts-addition-iron-or-aluminium + +# ============================================================================= +# state_variable_indices = { +# 'S_su': 0, 'S_aa': 1, 'S_fa': 2, 'S_va': 3, 'S_bu': 4, 'S_pro': 5, 'S_ac': 6, 'S_h2': 7, +# 'S_ch4': 8, 'S_IC': 9, 'S_IN': 10, 'S_IP': 11, 'S_I': 12, +# 'X_ch': 13, 'X_pr': 14, 'X_li': 15, +# 'X_su': 16, 'X_aa': 17, 'X_fa': 18, 'X_c4': 19, 'X_pro': 20, 'X_ac': 21, 'X_h2': 22, 'X_I': 23, +# 'X_PHA': 24, 'X_PP': 25, 'X_PAO': 26, 'S_K': 27, 'S_Mg': 28, +# 'S_SO4': 29, 'S_IS': 30, 'X_hSRB': 31, 'X_aSRB': 32, 'X_pSRB': 33, 'X_c4SRB': 34, +# 'S_S0': 35, 'S_Fe3': 36, 'S_Fe2': 37, +# 'X_HFO_H': 38, 'X_HFO_L': 39, 'X_HFO_old': 40, 'X_HFO_HP': 41, 'X_HFO_LP': 42, 'X_HFO_HP_old': 43, 'X_HFO_LP_old': 44, +# 'S_Ca': 45, 'S_Al': 46, +# 'X_CCM': 47, 'X_ACC': 48, 'X_ACP': 49, 'X_HAP': 50, 'X_DCPD': 51, 'X_OCP': 52, +# 'X_struv': 53, 'X_newb': 54, 'X_magn': 55, 'X_kstruv': 56, +# 'X_FeS': 57, 'X_Fe3PO42': 58, +# 'X_AlPO4': 59, +# 'S_Na': 60, 'S_Cl': 61, 'H2O': 62 +# } +# ============================================================================= + +def calc_pH(): + pass + +def calc_biogas(): + pass + +def pcm(): + pass + +def saturation_index(): + pass + +rhos = np.zeros(38+8+13+4) # 38 biological + 8 chemical P removal by HFO + 13 MMP + 4 gas transfer +Cs = np.empty(38+8) +sum_stoichios = np.array([2, 2, 5, 9, 3, 8, 3, 3, 2, 3, 2, 2]) + +def rhos_madm1(state_arr, params, T_op): + ks = params['rate_constants'] + Ks = params['half_sat_coeffs'] + K_PP = params['K_PP'] + K_so4 = params['K_so4'] + cmps = params['components'] + # n = len(cmps) + pH_LLs, pH_ULs = params['pH_limits'] + KS_IN = params['KS_IN'] + KS_IP = params['KS_IP'] + KI_nh3 = params['KI_nh3'] + KIs_h2 = params['KIs_h2'] + KIs_h2s = params['KIs_h2s'] + KHb = params['K_H_base'] + Kab = params['Ka_base'] + KH_dH = params['K_H_dH'] + Ka_dH = params['Ka_dH'] + kLa = params['kLa'] + k_cryst = params['k_cryst'] + n_cryst = params['n_cryst'] + Kspb = params['Ksp_base'] + Ksp_dH = params['Ksp_dH'] + T_base = params['T_base'] + + Cs[:7] = state_arr[13:20] # original ADM1 processes + Cs[7:11] = state_arr[19:23] + Cs[11:18] = state_arr[16:23] + Cs[18:23] = X_PAO = state_arr[26] # P extension processes + Cs[23:25] = X_PP, X_PHA = state_arr[[25,24]] + Cs[25:27] = state_arr[31] # S extension processes + Cs[27:29] = state_arr[32] + Cs[29:31] = state_arr[33] + Cs[31:34] = state_arr[34] + Cs[34:36] = Cs[36:38] = Cs[38:40] = Cs[40:42] = state_arr[38:40] # Fe extension processes + HFO module + Cs[42:44] = Cs[44:46] = state_arr[41:43] + + rhos[:46] = ks * Cs + primary_substrates = state_arr[:8] + + rhos[3:11] *= substr_inhibit(primary_substrates, Ks[:8]) + c4 = primary_substrates[[3,4]] + if sum(c4) > 0: rhos[[6,7]] *= c4/sum(c4) + + vfas = primary_substrates[3:7] + rhos[18:22] *= substr_inhibit(vfas, Ks[8]) + if sum(vfas) > 0: rhos[18:22] *= vfas/sum(vfas) + if X_PAO > 0: rhos[18:22] *= substr_inhibit(X_PP/X_PAO, K_PP) + + srb_subs = np.flip(primary_substrates[3:]) + S_SO4, S_IS = state_arr[29:31] + rhos[[25,27,29,31,32]] *= substr_inhibit(srb_subs, Ks[9:13]) * substr_inhibit(S_SO4, K_so4) + if sum(srb_subs[-2:]) > 0: rhos[[31,32]] *= srb_subs[-2:]/sum(srb_subs[-2:]) + + #!!! why divide by 16 or 64? + S_h2 = primary_substrates[-1] + rhos[34:36] *= S_h2 / 16 + rhos[36:38] *= S_IS / 64 + + KPbind, KPdiss = Ks[-2:] + S_IP = state_arr[11] + rhos[40:42] *= substr_inhibit(S_IP, KPbind) + rhos[44:46] *= non_compet_inhibit(S_IP, KPdiss) + + # inhibition factors + # ****************** + unit_conversion = mass2mol_conversion(cmps) + if T_op == T_base: + Ka = Kab + KH = KHb / unit_conversion[[7,8,9,30]] + Ksp = Kspb + else: + T_temp = params.pop('T_op', None) + if T_op == T_temp: + params['T_op'] = T_op + Ka = params['Ka'] + KH = params['KH'] + Ksp = params['Ksp'] + else: + params['T_op'] = T_op + Ka = params['Ka'] = Kab * T_correction_factor(T_base, T_op, Ka_dH) + KH = params['KH'] = KHb * T_correction_factor(T_base, T_op, KH_dH) / unit_conversion[[7,8,9,30]] + Ksp = params['Ksp'] = Kspb * T_correction_factor(T_base, T_op, Ksp_dH) + + S_IN, S_IP = state_arr[[10,11]] + I_nutrients = substr_inhibit(S_IN, KS_IN) * substr_inhibit(S_IP, KS_IP) + rhos[3:11] *= I_nutrients + rhos[[25,27,29,31,32]] *= I_nutrients + +# ============================================================================= +# !!! place holder for PCM (speciation) +# ============================================================================= + pH, nh3, co2, acts = pcm(state_arr, params) + Is_pH = Hill_inhibit(10**(-pH), pH_ULs, pH_LLs) + rhos[3:9] *= Is_pH[0] + rhos[9:11] *= Is_pH[1:3] + rhos[[25,27]] *= Is_pH[3:5] + rhos[[29,31,32]] *= Is_pH[-1] + + Is_h2 = non_compet_inhibit(S_h2, KIs_h2) + rhos[5:9] *= Is_h2 + Inh3 = non_compet_inhibit(nh3, KI_nh3) + rhos[9] *= Inh3 + + Z_h2s = calc_biogas() # should be a function of pH, like co2 and nh3 + Is_h2s = non_compet_inhibit(Z_h2s, KIs_h2s) + rhos[6:11] *= Is_h2s[:5] + rhos[[25,27,29,31,32]] *= Is_h2s[5:] + + # multiple mineral precipitation + # ****************************** + SIs = np.maximum(1.0, saturation_index(acts, Ksp)) # should be an array + rhos[46:59] = k_cryst * state_arr[47:60] * (SIs**(1/sum_stoichios) - 1)**n_cryst + + # gas transfer + # ************ + biogas_S = state_arr[[7,8,9,30]].copy() + biogas_S[2] = co2 / unit_conversion[9] + biogas_S[3] = Z_h2s / unit_conversion[30] + biogas_p = R * T_op * state_arr[63:67] + rhos[-4:] = kLa * (biogas_S - KH * biogas_p) + + return rhos + +#%% modified ADM1 class +_load_components = settings.get_default_chemicals + +def fun(q_aging_H=450.0, q_aging_L=0.1, q_Pcoprec=360, q_Pbinding=0.3, q_diss_H=36.0, q_diss_L=36.0, + K_Pbind=37.2, K_Pdiss=0.93): + ''' + + + Parameters + ---------- + + Returns + ------- + None. + + ''' + pass + +@chemicals_user +class ModifiedADM1(CompiledProcesses): + """ + Modified Anaerobic Digestion Model no.1 [1]_, [2]_, [3]_ + + Parameters + ---------- + f_ch_xb : float, optional + Fraction of carbohydrates as biomass decay product. The default is 0.275. + f_pr_xb : flaot, optional + Fraction of proteins as biomass decay product. The default is 0.275. + f_li_xb : float, optional + Fraction of lipids as biomass decay product. The default is 0.35. + f_xI_xb : float, optional + Fraction of inert particulates as biomass decay product. The default is 0.1. + f_va_pha : float, optional + Fraction of valerate as PHA lysis product. The default is 0.1. + f_bu_pha : float, optional + Fraction of butyrate as PHA lysis product. The default is 0.1. + f_pro_pha : float, optional + Fraction of propionate as PHA lysis product. The default is 0.4. + Y_PO4 : float, optional + Poly-phosphorus (PP) required for PHA storage [kg P/kg COD]. The default is 0.4. + Y_hSRB : float, optional + Sulfide-reducing biomass (SRB) yield of hydrogen uptake [kg COD/kg COD]. + The default is 0.05. + Y_aSRB : float, optional + SRB yield of acetate uptake [kg COD/kg COD]. The default is 0.05. + Y_pSRB : float, optional + SRB yield of propionate uptake [kg COD/kg COD]. The default is 0.04. + Y_c4SRB : float, optional + SRB yield of butyrate or valerate uptake [kg COD/kg COD]. + The default is 0.06. + q_pha : float, optional + Maximum specific rate constant for PHA storage by phosphorus-accumulating + organisms (PAOs) [d^(-1)]. The default is 3.0. + b_pao : float, optional + PAO lysis rate constant [d^(-1)]. The default is 0.2. + b_pp : float, optional + PP lysis rate constant [d^(-1)]. The default is 0.2. + b_pha : float, optional + PHA lysis rate constant [d^(-1)]. The default is 0.2. + K_A : float, optional + Substrate half saturation coefficient for PHA storage [kg COD/m3]. + The default is 4e-3. + K_PP : float, optional + PP half saturation coefficient for PHA storage [kg P (X_PP)/kg COD (X_PHA)]. + The default is 0.01. + k_hSRB : float, optional + Maximum specific growth rate constant of hydrogen-uptaking SRB [d^(-1)]. + The default is 41.125. + k_aSRB : float, optional + Maximum specific growth rate constant of acetate-uptaking SRB [d^(-1)]. + The default is 10.. + k_pSRB : float, optional + Maximum specific growth rate constant of propionate-uptaking SRB [d^(-1)]. + The default is 16.25. + k_c4SRB : float, optional + Maximum specific growth rate constant of butyrate- or valerate-uptaking + SRB [d^(-1)]. The default is 23. + b_hSRB : float, optional + Hydrogen-uptaking SRB decay rate constant [d^(-1)]. The default is 0.02. + b_aSRB : float, optional + Acetate-uptaking SRB decay rate constant [d^(-1)]. The default is 0.02. + b_pSRB : float, optional + Propionate-uptaking SRB decay rate constant [d^(-1)]. The default is 0.02. + b_c4SRB : float, optional + Butyrate- or valerate-uptaking SRB decay rate constant [d^(-1)]. + The default is 0.02. + K_hSRB : float, optional + Substrate half saturation coefficient of hydrogen uptake by SRB + [kg COD/m3]. The default is 5.96e-6. + K_aSRB : float, optional + Substrate half saturation coefficient of acetate uptake by SRB + [kg COD/m3]. The default is 0.176. + K_pSRB : float, optional + Substrate half saturation coefficient of propionate uptake by SRB + [kg COD/m3]. The default is 0.088. + K_c4SRB : float, optional + Substrate half saturation coefficient of butyrate or valerate uptake by + SRB [kg COD/m3]. The default is 0.1739. + K_so4_hSRB : float, optional + Sulfate half saturation coefficient of SRB uptaking hydrogen [kg S/m3]. + The default is 3.335e-3. + K_so4_aSRB : float, optional + Sulfate half saturation coefficient of SRB uptaking acetate [kg S/m3]. + The default is 6.413e-3. + K_so4_pSRB : float, optional + Sulfate half saturation coefficient of SRB uptaking propionate [kg S/m3]. + The default is 6.413e-3. + K_so4_c4SRB : float, optional + Sulfate half saturation coefficient of SRB uptaking butyrate or valerate + [kg S/m3]. The default is 6.413e-3. + k_Fe3t2_h2 : float, optional + Fe(3+) reduction rate constant [m3∙kg^(-1) Fe(III)∙d^(-1)] using hydrogen + as electron donor. The default is 1.79e7. + k_Fe3t2_is : float, optional + Fe(3+) reduction rate constant [m3∙kg^(-1) Fe(III)∙d^(-1)] using sulfide + as electron donor. The default is 1.79e7. + KS_IP : float, optional + Inorganic phosphorus (nutrient) inhibition coefficient for soluble + substrate uptake [M]. The default is 2e-5. + q_aging_H : float, optional + Aging rate constant of X_HFO_H and X_HFO_HP [d^(-1)]. The default is 450.0. + q_aging_L : float, optional + Aging rate constant of X_HFO_L and X_HFO_LP [d^(-1)]. The default is 0.1. + q_Pcoprec : float, optional + Rate constant of P binding and coprecipitation on X_HFO_H [d^(-1)]. + The default is 360. + q_Pbinding : float, optional + Rate constant of P binding on X_HFO_L [d^(-1)]. The default is 0.3. + q_diss_H : float, optional + Dissolution rate constant of X_HFO_HP [d^(-1)]. The default is 36.0. + q_diss_L : float, optional + Dissolution rate constant of X_HFO_HP [d^(-1)]. The default is 36.0. + K_Pbind : float, optional + S_IP half saturation coefficient for binding with X_HFO_H or X_HFO_L + [kg P/m3]. The default is 37.2, i.e., 1.20 kmol P/m3. + K_Pdiss : float, optional + S_IP half inhibition coefficient for dissolution of X_HFO_HP or X_HFO_LP + [kg P/m3]. The default is 0.93, i.e., 0.03 kmol P/m3. + KI_h2s_c4 : float, optional + H2S half inhibition coefficient for butyrate or valerate uptake + [kg COD/m3]. The default is 0.481. + KI_h2s_pro : float, optional + H2S half inhibition coefficient for propionate uptake [kg COD/m3]. + The default is 0.481. + KI_h2s_ac : float, optional + H2S half inhibition coefficient for acetate uptake [kg COD/m3]. + The default is 0.460. + KI_h2s_h2 : float, optional + H2S half inhibition coefficient for hydrogen uptake [kg COD/m3]. + The default is 0.400. + KI_h2s_c4SRB : float, optional + H2S half inhibition coefficient for butyrate or valerate uptake by SRB + [kg COD/m3]. The default is 0.520. + KI_h2s_pSRB : float, optional + H2S half inhibition coefficient for propionate uptake by SRB [kg COD/m3]. + The default is 0.520. + KI_h2s_aSRB : float, optional + H2S half inhibition coefficient for acetate uptake by SRB [kg COD/m3]. + The default is 0.499. + KI_h2s_hSRB : float, optional + H2S half inhibition coefficient for hydrogen uptake by SRB [kg COD/m3]. + The default is 0.499. + pH_limits_aa_SRB : 2-tuple, optional + Lower and upper limits of pH inhibition for acetogenosis by SRB, + unitless. The default is (6,7). + pH_limits_ac_SRB : 2-tuple, optional + Lower and upper limits of pH inhibition for acetate uptake by SRB, + unitless. The default is (6,7). + pH_limits_h2_SRB : 2-tuple, optional + Lower and upper limits of pH inhibition for hydrogen uptake by SRB, + unitless. The default is (5,6). + k_cryst : iterable[float], optional + Mineral precipitation rate constants [h^(-1)], following the order of + `ModifiedADM1._precipitates`. The default is + [0.35, 1e-3, 3.0, 1e-3, 2.0, 0.76, 5.0, 1e-3, 1e-3, 1e-3, 1e2, 1e-3, 1e-3]. + n_cryst : iterable[int], optional + The effect orders of mineral precipitation reactions [unitless], following + the order of `ModifiedADM1._precipitates`. The default is + [2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2]. + + + Examples + -------- + ... + + References + ---------- + .. [1] Flores-Alsina, X., Solon, K., Kazadi Mbamba, C., Tait, S., + Gernaey, K. V., Jeppsson, U., Batstone, D. J. (2016). + Modelling phosphorus (P), sulfur (S) and iron (Fe) interactions + for dynamic simulations of anaerobic digestion processes. + Water Research, 95, 370–382. https://doi.org/10.1016/J.WATRES.2016.03.012 + .. [2] Solon, K., Flores-Alsina, X., Kazadi Mbamba, C., Ikumi, D., + Volcke, E. I. P., Vaneeckhaute, C., Ekama, G., Vanrolleghem, P. A., + Batstone, D. J., Gernaey, K. v., Jeppsson, U. (2017). Plant-wide + modelling of phosphorus transformations in wastewater treatment systems: + Impacts of control and operational strategies. Water Research, + 113, 97–110. https://doi.org/10.1016/J.WATRES.2017.02.007 + .. [3] Hauduc, H., Takács, I., Smith, S., Szabo, A., Murthy, S., Daigger, G. T., + Spérandio, M. (2015). A dynamic physicochemical model for chemical phosphorus + removal. Water Research, 73, 157–170. https://doi.org/10.1016/J.WATRES.2014.12.053 + + See Also + -------- + `qsdsan.processes.ADM1 `_ + + """ + + _cmp_dependent_stoichio = ('K_XPP', 'Mg_XPP', + 'MW_S0', 'MW_IS', + 'i_mass_S0', 'i_mass_IS', 'i_mass_Fe2') + _stoichio_params = (*ADM1._stoichio_params[5:], + 'f_ch_xb', 'f_pr_xb', 'f_li_xb', 'f_xI_xb', 'f_sI_xb', + 'f_va_pha', 'f_bu_pha', 'f_pro_pha', 'f_ac_pha', + 'f_is_pro', 'f_is_bu', 'f_is_va', + 'Y_PO4', 'Y_hSRB', 'Y_aSRB', 'Y_pSRB', 'Y_c4SRB', + *_cmp_dependent_stoichio + ) + _kinetic_params = ('rate_constants', 'half_sat_coeffs', 'K_PP', 'K_so4', + 'pH_limits', 'KS_IN', 'KS_IP', 'KI_nh3', 'KIs_h2', 'KIs_h2s' + 'Ka_base', 'Ka_dH', 'K_H_base', 'K_H_dH', 'kLa', + 'k_cryst', 'n_cryst', 'Ksp_base', 'Ksp_dH', + 'T_base', 'components', + # 'root' + ) + _acid_base_pairs = ADM1._acid_base_pairs + _biogas_IDs = (*ADM1._biogas_IDs, 'S_IS') + _biomass_IDs = (*ADM1._biomass_IDs, 'X_PAO', 'X_hSRB', 'X_aSRB', 'X_pSRB', 'X_c4SRB') + _precipitates = ('X_CCM', 'X_ACC', 'X_ACP', 'X_HAP', 'X_DCPD', 'X_OCP', + 'X_struv', 'X_newb', 'X_magn', 'X_kstruv', + 'X_FeS', 'X_Fe3PO42', 'X_AlPO4') + _T_base = 298.15 + _K_H_base = [7.8e-4, 1.4e-3, 3.5e-2, 0.105] # biogas species Henry's Law constant [M/bar] + _K_H_dH = [-4180, -14240, -19410, -19180] # Heat of reaction of liquid-gas transfer of biogas species [J/mol] + + _pKsp_base = [8.48, 8.3, 28.92, 44.333, 18.995, 47.08, + 13.6, 18.175, 7.46, 11.5508, + 2.95, 37.76, 18.2] + _Ksp_dH = [8000, -12000, 54000, 0, 31000, 0, + -22600, -22600, -20000, -22600, + -11000, 5060, 0] + + def __new__(cls, components=None, path=None, + f_ch_xb=0.275, f_pr_xb=0.275, f_li_xb=0.35, f_xI_xb=0.1, + f_fa_li=0.95, f_bu_su=0.1328, f_pro_su=0.2691, f_ac_su=0.4076, + f_va_aa=0.23, f_bu_aa=0.26, f_pro_aa=0.05, f_ac_aa=0.4, + f_ac_fa=0.7, f_pro_va=0.54, f_ac_va=0.31, f_ac_bu=0.8, f_ac_pro=0.57, + Y_su=0.1, Y_aa=0.08, Y_fa=0.06, Y_c4=0.06, Y_pro=0.04, Y_ac=0.05, Y_h2=0.06, + f_va_pha=0.1, f_bu_pha=0.1, f_pro_pha=0.4, + Y_PO4=0.4, Y_hSRB=0.05, Y_aSRB=0.05, Y_pSRB=0.04, Y_c4SRB=0.06, + q_ch_hyd=10, q_pr_hyd=10, q_li_hyd=10, + k_su=30, k_aa=50, k_fa=6, k_c4=20, k_pro=13, k_ac=8, k_h2=35, + K_su=0.5, K_aa=0.3, K_fa=0.4, K_c4=0.2, K_pro=0.1, K_ac=0.15, K_h2=7e-6, + b_su=0.02, b_aa=0.02, b_fa=0.02, b_c4=0.02, b_pro=0.02, b_ac=0.02, b_h2=0.02, + q_pha=3.0, b_pao=0.2, b_pp=0.2, b_pha=0.2, K_A=4e-3, K_PP=0.01, + k_hSRB=41.125, k_aSRB=10., k_pSRB=16.25, k_c4SRB=23, + b_hSRB=0.02, b_aSRB=0.02, b_pSRB=0.02, b_c4SRB=0.02, + K_hSRB=5.96e-6, K_aSRB=0.176, K_pSRB=0.088, K_c4SRB=0.1739, + K_so4_hSRB=1.04e-4*S_mw, K_so4_aSRB=2e-4*S_mw, K_so4_pSRB=2e-4*S_mw, K_so4_c4SRB=2e-4*S_mw, + k_Fe3t2_h2=1e9/Fe_mw, k_Fe3t2_is=1e9/Fe_mw, + q_aging_H=450.0, q_aging_L=0.1, q_Pcoprec=360, q_Pbinding=0.3, q_diss_H=36.0, q_diss_L=36.0, + K_Pbind=37.2, K_Pdiss=0.93, # 1.20 and 0.03 in MATLAB, assuming in kmol-P/m3 ? + KI_h2_fa=5e-6, KI_h2_c4=1e-5, KI_h2_pro=3.5e-6, KI_nh3=1.8e-3, KS_IN=1e-4, KS_IP=2e-5, + KI_h2s_c4=0.481, KI_h2s_pro=0.481, KI_h2s_ac=0.460, KI_h2s_h2=0.400, + KI_h2s_c4SRB=0.520, KI_h2s_pSRB=0.520, KI_h2s_aSRB=0.499, KI_h2s_hSRB=0.499, + pH_limits_aa=(4,5.5), pH_limits_ac=(6,7), pH_limits_h2=(5,6), + pH_limits_aa_SRB=(6,7), pH_limits_ac_SRB=(6,7), pH_limits_h2_SRB=(5,6), + kLa=200, pKa_base=[14, 9.25, 6.35, 4.76, 4.88, 4.82, 4.86], + Ka_dH=[55900, 51965, 7646, 0, 0, 0, 0], + k_cryst=[0.35, 1e-3, 3.0, 1e-3, 2.0, 0.76, 5.0, 1e-3, 1e-3, 1e-3, 1e2, 1e-3, 1e-3], + n_cryst=[2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2], + **kwargs): + + cmps = _load_components(components) + + if not path: path = _path + self = Processes.load_from_file(path, + components=cmps, + conserved_for=('C', 'N', 'P'), + parameters=cls._stoichio_params, + compile=False) + + for i in ('fast_P_binding', 'slow_P_sorption', 'dissolution_HFO_HP', 'dissolution_HFO_LP'): + p = getattr(self, i) + p.ref_component = 'S_IP' + + precipitation = [] + for i in cls._precipitates[:-3]: + new_p = Process('precipitation_%s' % i.lstrip('X_'), + reaction='[?]S_IC + [?]S_IN + [?]S_IP + [?]S_K + [?]S_Mg + [?]S_Ca -> %s' % i, + ref_component=i, + conserved_for=('C', 'N', 'P', 'K', 'Mg', 'Ca'), + parameters=()) + precipitation.append(new_p) + + i_mass_IS = cmps.S_IS.i_mass + i_mass_Fe2 = cmps.S_Fe2.i_mass + FeS_mw = cmps.X_FeS.chem_MW + new_p = Process('precipitation_FeS', + reaction={'S_Fe2': -Fe_mw/FeS_mw/i_mass_Fe2, + 'S_IS': -S_mw/FeS_mw/i_mass_IS, + 'X_FeS': 1}, + ref_component='X_FeS', + conserved_for=()) + precipitation.append(new_p) + + Fe3PO42_mw = cmps.X_Fe3PO42.chem_MW + new_p = Process('precipitation_Fe3PO42', + reaction={'S_Fe2': -3*Fe_mw/Fe3PO42_mw/i_mass_Fe2, + 'S_IP': '?', + 'X_Fe3PO42': 1}, + ref_component='X_Fe3PO42', + conserved_for=('P',)) + precipitation.append(new_p) + + AlPO4_mw = cmps.X_AlPO4.chem_MW + Al_mw = cmps.S_Al.chem_MW + new_p = Process('precipitation_AlPO4', + reaction={'S_Al': -Al_mw/AlPO4_mw, + 'S_IP': '?', + 'X_AlPO4': 1}, + ref_component='X_AlPO4', + conserved_for=('P',)) + precipitation.append(new_p) + + self.extend(precipitation) + + gas_transfer = [] + for i in cls._biogas_IDs: + new_p = Process('%s_transfer' % i.lstrip('S_'), + reaction={i:-1}, + ref_component=i, + conserved_for=(), + parameters=()) + gas_transfer.append(new_p) + self.extend(gas_transfer) + self.compile(to_class=cls) + + stoichio_vals = (f_fa_li, f_bu_su, f_pro_su, f_ac_su, 1-f_bu_su-f_pro_su-f_ac_su, + f_va_aa, f_bu_aa, f_pro_aa, f_ac_aa, 1-f_va_aa-f_bu_aa-f_pro_aa-f_ac_aa, + f_ac_fa, 1-f_ac_fa, f_pro_va, f_ac_va, 1-f_pro_va-f_ac_va, + f_ac_bu, 1-f_ac_bu, f_ac_pro, 1-f_ac_pro, + Y_su, Y_aa, Y_fa, Y_c4, Y_pro, Y_ac, Y_h2, + f_ch_xb, f_pr_xb, f_li_xb, f_xI_xb, round(1.0-f_ch_xb-f_pr_xb-f_li_xb-f_xI_xb, 4), + f_va_pha, f_bu_pha, f_pro_pha, 1-f_va_pha-f_bu_pha-f_pro_pha, + 1-f_ac_pro, 1-f_ac_bu, 1-f_pro_va-f_ac_va, + Y_PO4, Y_hSRB, Y_aSRB, Y_pSRB, Y_c4SRB, + cmps.X_PP.i_K, cmps.X_PP.i_Mg, + cmps.S_S0.chem_MW, cmps.S_IS.chem_MW, + cmps.S_S0.i_mass, i_mass_IS, i_mass_Fe2) + + pH_limits = np.array([pH_limits_aa, pH_limits_ac, pH_limits_h2, + pH_limits_h2_SRB, pH_limits_ac_SRB, pH_limits_aa_SRB]).T + + ks = np.array((q_ch_hyd, q_pr_hyd, q_li_hyd, + k_su, k_aa, k_fa, k_c4, k_c4, k_pro, k_ac, k_h2, + b_su, b_aa, b_fa, b_c4, b_pro, b_ac, b_h2, # original ADM1 + q_pha, q_pha, q_pha, q_pha, b_pao, b_pp, b_pha, # P extension + k_hSRB, b_hSRB, k_aSRB, b_aSRB, k_pSRB, b_pSRB, k_c4SRB, k_c4SRB, b_c4SRB, # S extension + k_Fe3t2_h2, k_Fe3t2_h2, k_Fe3t2_is, k_Fe3t2_is, # Fe extension + q_aging_H, q_aging_L, q_Pcoprec, q_Pbinding, # HFO module + q_aging_H, q_aging_L, q_diss_H, q_diss_L)) + + Ks = np.array((K_su, K_aa, K_fa, K_c4, K_c4, K_pro, K_ac, K_h2, # original ADM1 + K_A, # P extension + K_hSRB, K_aSRB, K_pSRB, K_c4SRB, # S extension + K_Pbind, K_Pdiss)) # HFO module + K_so4 = np.array((K_so4_hSRB, K_so4_aSRB, K_so4_pSRB, K_so4_c4SRB)) + + KIs_h2 = np.array((KI_h2_fa, KI_h2_c4, KI_h2_c4, KI_h2_pro)) + KIs_h2s = np.array((KI_h2s_c4, KI_h2s_c4, KI_h2s_pro, KI_h2s_ac, KI_h2s_h2, + KI_h2s_hSRB, KI_h2s_aSRB, KI_h2s_pSRB, KI_h2s_c4SRB, KI_h2s_c4SRB)) + K_H_base = np.array(cls._K_H_base) + K_H_dH = np.array(cls._K_H_dH) + Ka_base = np.array([10**(-pKa) for pKa in pKa_base]) + Ka_dH = np.array(Ka_dH) + k_cryst = np.array(k_cryst) * 24 # converted to d^(-1) + n_cryst = np.array(n_cryst) + Ksp_base = np.array([10**(-pK) for pK in cls.pKsp_base]) + Ksp_dH = np.array(cls.Ksp_dH) + # root = TempState() + dct = self.__dict__ + dct.update(kwargs) + + dct['_parameters'] = dict(zip(cls._stoichio_params, stoichio_vals)) + self.set_rate_function(rhos_madm1) + self.rate_function._params = dict(zip(cls._kinetic_params, + [ks, Ks, K_PP, K_so4, + pH_limits, KS_IN*N_mw, KS_IP*P_mw, + KI_nh3, KIs_h2, KIs_h2s, + Ka_base, Ka_dH, K_H_base, K_H_dH, kLa, + k_cryst, n_cryst, Ksp_base, Ksp_dH, + cls.T_base, self._components, + # root, + ])) + return self \ No newline at end of file diff --git a/qsdsan/sanunits/__init__.py b/qsdsan/sanunits/__init__.py index 17367d26..baf71a90 100644 --- a/qsdsan/sanunits/__init__.py +++ b/qsdsan/sanunits/__init__.py @@ -53,7 +53,7 @@ from ._sludge_pasteurization import * from ._sludge_thickening import * from ._suspended_growth_bioreactor import * -from ._tanks import * +from ._tank import * from ._trucking import * # Units that rely on other units @@ -66,14 +66,14 @@ from ._hydrothermal import * from ._internal_circulation_rx import * from ._lagoon import * -from ._membrane_bioreactors import * +from ._membrane_bioreactor import * from ._membrane_distillation import * from ._polishing_filter import * from ._sedimentation import * from ._sludge_treatment import * from ._septic_tank import * -from ._toilets import * -from ._treatment_beds import * +from ._toilet import * +from ._treatment_bed import * # System-specific unit (public) from ._biogenic_refinery import * @@ -84,7 +84,7 @@ from . import ( _abstract, _activated_sludge_process, - _anaerobic_reactors, + _anaerobic_reactor, _clarifier, _combustion, _compressor, @@ -101,8 +101,8 @@ _junction, _lagoon, _membrane_bioreactors, - _membrane_gas_extraction, _membrane_distillation, + _membrane_gas_extraction, _non_reactive, _polishing_filter, _pumping, @@ -113,9 +113,9 @@ _sludge_pasteurization, _sludge_thickening, _suspended_growth_bioreactor, - _tanks, - _toilets, - _treatment_beds, + _tank, + _toilet, + _treatment_bed, _trucking, # System-specific units (public) @@ -129,7 +129,7 @@ __all__ = ( *_abstract.__all__, *_activated_sludge_process.__all__, - *_anaerobic_reactors.__all__, + *_anaerobic_reactor.__all__, *_clarifier.__all__, *_combustion.__all__, *_compressor.__all__, @@ -145,7 +145,7 @@ *_internal_circulation_rx.__all__, *_junction.__all__, *_lagoon.__all__, - *_membrane_bioreactors.__all__, + *_membrane_bioreactor.__all__, *_membrane_distillation.__all__, *_non_reactive.__all__, *_polishing_filter.__all__, @@ -157,9 +157,9 @@ *_sludge_pasteurization.__all__, *_sludge_thickening.__all__, *_suspended_growth_bioreactor.__all__, - *_tanks.__all__, - *_toilets.__all__, - *_treatment_beds.__all__, + *_tank.__all__, + *_toilet.__all__, + *_treatment_bed.__all__, *_trucking.__all__, # System-specific units (public) diff --git a/qsdsan/sanunits/_activated_sludge_process.py b/qsdsan/sanunits/_activated_sludge_process.py index 3278925f..9750ce5d 100644 --- a/qsdsan/sanunits/_activated_sludge_process.py +++ b/qsdsan/sanunits/_activated_sludge_process.py @@ -5,6 +5,7 @@ QSDsan: Quantitative Sustainable Design for sanitation and resource recovery systems This module is developed by: + Yalin Li This module is under the University of Illinois/NCSA Open Source License. diff --git a/qsdsan/sanunits/_anaerobic_reactors.py b/qsdsan/sanunits/_anaerobic_reactor.py similarity index 99% rename from qsdsan/sanunits/_anaerobic_reactors.py rename to qsdsan/sanunits/_anaerobic_reactor.py index a8b8467f..69d086a3 100644 --- a/qsdsan/sanunits/_anaerobic_reactors.py +++ b/qsdsan/sanunits/_anaerobic_reactor.py @@ -6,6 +6,7 @@ This module is developed by: Yalin Li + Joy Zhang This module is under the University of Illinois/NCSA Open Source License. diff --git a/qsdsan/sanunits/_clarifier.py b/qsdsan/sanunits/_clarifier.py index 458c51c9..fd42ee61 100644 --- a/qsdsan/sanunits/_clarifier.py +++ b/qsdsan/sanunits/_clarifier.py @@ -3,8 +3,11 @@ QSDsan: Quantitative Sustainable Design for sanitation and resource recovery systems This module is developed by: + Joy Zhang + Yalin Li + Saumitra Rai This module is under the University of Illinois/NCSA Open Source License. diff --git a/qsdsan/sanunits/_hydroprocessing.py b/qsdsan/sanunits/_hydroprocessing.py index 44ce7ad0..53767d60 100644 --- a/qsdsan/sanunits/_hydroprocessing.py +++ b/qsdsan/sanunits/_hydroprocessing.py @@ -65,7 +65,7 @@ class Hydrocracking(Reactor): References ---------- - .. [1] Jones, S. B.; Zhu, Y.; Anderson, D. B.; Hallen, R. T.; Elliott, D. C.; + [1] Jones, S. B.; Zhu, Y.; Anderson, D. B.; Hallen, R. T.; Elliott, D. C.; Schmidt, A. J.; Albrecht, K. O.; Hart, T. R.; Butcher, M. G.; Drennan, C.; Snowden-Swan, L. J.; Davis, R.; Kinchin, C. Process Design and Economics for the Conversion of Algal Biomass to @@ -274,13 +274,13 @@ class Hydrotreating(Reactor): References ---------- - .. [1] Jones, S. B.; Zhu, Y.; Anderson, D. B.; Hallen, R. T.; Elliott, D. C.; + [1] Jones, S. B.; Zhu, Y.; Anderson, D. B.; Hallen, R. T.; Elliott, D. C.; Schmidt, A. J.; Albrecht, K. O.; Hart, T. R.; Butcher, M. G.; Drennan, C.; Snowden-Swan, L. J.; Davis, R.; Kinchin, C. Process Design and Economics for the Conversion of Algal Biomass to Hydrocarbons: Whole Algae Hydrothermal Liquefaction and Upgrading; PNNL--23227, 1126336; 2014; https://doi.org/10.2172/1126336. - .. [2] Towler, G.; Sinnott, R. Chapter 14 - Design of Pressure Vessels. + [2] Towler, G.; Sinnott, R. Chapter 14 - Design of Pressure Vessels. In Chemical Engineering Design (Second Edition); Towler, G., Sinnott, R., Eds.; Butterworth-Heinemann: Boston, 2013; pp 563–629. https://doi.org/10.1016/B978-0-08-096659-5.00014-6. diff --git a/qsdsan/sanunits/_hydrothermal.py b/qsdsan/sanunits/_hydrothermal.py index 39a02717..3f57a034 100644 --- a/qsdsan/sanunits/_hydrothermal.py +++ b/qsdsan/sanunits/_hydrothermal.py @@ -70,13 +70,13 @@ class CatalyticHydrothermalGasification(Reactor): References ---------- - .. [1] Jones, S. B.; Zhu, Y.; Anderson, D. B.; Hallen, R. T.; Elliott, D. C.; + [1] Jones, S. B.; Zhu, Y.; Anderson, D. B.; Hallen, R. T.; Elliott, D. C.; Schmidt, A. J.; Albrecht, K. O.; Hart, T. R.; Butcher, M. G.; Drennan, C.; Snowden-Swan, L. J.; Davis, R.; Kinchin, C. Process Design and Economics for the Conversion of Algal Biomass to Hydrocarbons: Whole Algae Hydrothermal Liquefaction and Upgrading; PNNL--23227, 1126336; 2014; https://doi.org/10.2172/1126336. - .. [2] Davis, R. E.; Grundl, N. J.; Tao, L.; Biddy, M. J.; Tan, E. C.; + [2] Davis, R. E.; Grundl, N. J.; Tao, L.; Biddy, M. J.; Tan, E. C.; Beckham, G. T.; Humbird, D.; Thompson, D. N.; Roni, M. S. Process Design and Economics for the Conversion of Lignocellulosic Biomass to Hydrocarbon Fuels and Coproducts: 2018 Biochemical Design Case @@ -84,7 +84,7 @@ class CatalyticHydrothermalGasification(Reactor): and Products via Integrated Biorefinery Pathways; NREL/TP--5100-71949, 1483234; 2018; p NREL/TP--5100-71949, 1483234. https://doi.org/10.2172/1483234. - .. [3] Elliott, D. C.; Neuenschwander, G. G.; Hart, T. R.; Rotness, L. J.; + [3] Elliott, D. C.; Neuenschwander, G. G.; Hart, T. R.; Rotness, L. J.; Zacher, A. H.; Santosa, D. M.; Valkenburg, C.; Jones, S. B.; Rahardjo, S. A. T. Catalytic Hydrothermal Gasification of Lignin-Rich Biorefinery Residues and Algae Final Report. 87. @@ -273,7 +273,7 @@ class KnockOutDrum(Reactor): References ---------- - .. [1] Knorr, D.; Lukas, J.; Schoen, P. Production of Advanced Biofuels via + [1] Knorr, D.; Lukas, J.; Schoen, P. Production of Advanced Biofuels via Liquefaction - Hydrothermal Liquefaction Reactor Design: April 5, 2013; NREL/SR-5100-60462, 1111191; 2013; p NREL/SR-5100-60462, 1111191. https://doi.org/10.2172/1111191. @@ -393,30 +393,30 @@ class HydrothermalLiquefaction(Reactor): References ---------- - .. [1] Leow, S.; Witter, J. R.; Vardon, D. R.; Sharma, B. K.; + [1] Leow, S.; Witter, J. R.; Vardon, D. R.; Sharma, B. K.; Guest, J. S.; Strathmann, T. J. Prediction of Microalgae Hydrothermal Liquefaction Products from Feedstock Biochemical Composition. Green Chem. 2015, 17 (6), 3584–3599. https://doi.org/10.1039/C5GC00574D. - .. [2] Li, Y.; Leow, S.; Fedders, A. C.; Sharma, B. K.; Guest, J. S.; + [2] Li, Y.; Leow, S.; Fedders, A. C.; Sharma, B. K.; Guest, J. S.; Strathmann, T. J. Quantitative Multiphase Model for Hydrothermal Liquefaction of Algal Biomass. Green Chem. 2017, 19 (4), 1163–1174. https://doi.org/10.1039/C6GC03294J. - .. [3] Li, Y.; Tarpeh, W. A.; Nelson, K. L.; Strathmann, T. J. + [3] Li, Y.; Tarpeh, W. A.; Nelson, K. L.; Strathmann, T. J. Quantitative Evaluation of an Integrated System for Valorization of Wastewater Algae as Bio-Oil, Fuel Gas, and Fertilizer Products. Environ. Sci. Technol. 2018, 52 (21), 12717–12727. https://doi.org/10.1021/acs.est.8b04035. - .. [4] Jones, S. B.; Zhu, Y.; Anderson, D. B.; Hallen, R. T.; Elliott, D. C.; + [4] Jones, S. B.; Zhu, Y.; Anderson, D. B.; Hallen, R. T.; Elliott, D. C.; Schmidt, A. J.; Albrecht, K. O.; Hart, T. R.; Butcher, M. G.; Drennan, C.; Snowden-Swan, L. J.; Davis, R.; Kinchin, C. Process Design and Economics for the Conversion of Algal Biomass to Hydrocarbons: Whole Algae Hydrothermal Liquefaction and Upgrading; PNNL--23227, 1126336; 2014; https://doi.org/10.2172/1126336. - .. [5] Matayeva, A.; Rasmussen, S. R.; Biller, P. Distribution of Nutrients and + [5] Matayeva, A.; Rasmussen, S. R.; Biller, P. Distribution of Nutrients and Phosphorus Recovery in Hydrothermal Liquefaction of Waste Streams. BiomassBioenergy 2022, 156, 106323. https://doi.org/10.1016/j.biombioe.2021.106323. - .. [6] Knorr, D.; Lukas, J.; Schoen, P. Production of Advanced Biofuels + [6] Knorr, D.; Lukas, J.; Schoen, P. Production of Advanced Biofuels via Liquefaction - Hydrothermal Liquefaction Reactor Design: April 5, 2013; NREL/SR-5100-60462, 1111191; 2013; p NREL/SR-5100-60462, 1111191. https://doi.org/10.2172/1111191. diff --git a/qsdsan/sanunits/_membrane_bioreactors.py b/qsdsan/sanunits/_membrane_bioreactor.py similarity index 100% rename from qsdsan/sanunits/_membrane_bioreactors.py rename to qsdsan/sanunits/_membrane_bioreactor.py diff --git a/qsdsan/sanunits/_membrane_distillation.py b/qsdsan/sanunits/_membrane_distillation.py index 756c225a..57055133 100644 --- a/qsdsan/sanunits/_membrane_distillation.py +++ b/qsdsan/sanunits/_membrane_distillation.py @@ -65,36 +65,36 @@ class MembraneDistillation(SanUnit): References ---------- - .. [1] Li, Y.; Tarpeh, W. A.; Nelson, K. L.; Strathmann, T. J. + [1] Li, Y.; Tarpeh, W. A.; Nelson, K. L.; Strathmann, T. J. Quantitative Evaluation of an Integrated System for Valorization of Wastewater Algae as Bio-Oil, Fuel Gas, and Fertilizer Products. Environ. Sci. Technol. 2018, 52 (21), 12717–12727. https://doi.org/10.1021/acs.est.8b04035. - .. [2] Doran, P. M. Chapter 11 - Unit Operations. In Bioprocess Engineering + [2] Doran, P. M. Chapter 11 - Unit Operations. In Bioprocess Engineering Principles (Second Edition); Doran, P. M., Ed.; Academic Press: London, 2013; pp 445–595. https://doi.org/10.1016/B978-0-12-220851-5.00011-3. - .. [3] Spiller, L. L. Determination of Ammonia/Air Diffusion Coefficient Using + [3] Spiller, L. L. Determination of Ammonia/Air Diffusion Coefficient Using Nafion Lined Tube. Analytical Letters 1989, 22 (11–12), 2561–2573. https://doi.org/10.1080/00032718908052375. - .. [4] Scheepers, D. M.; Tahir, A. J.; Brunner, C.; Guillen-Burrieza, E. + [4] Scheepers, D. M.; Tahir, A. J.; Brunner, C.; Guillen-Burrieza, E. Vacuum Membrane Distillation Multi-Component Numerical Model for Ammonia Recovery from Liquid Streams. Journal of Membrane Science 2020, 614, 118399. https://doi.org/10.1016/j.memsci.2020.118399. - .. [5] Ding, Z.; Liu, L.; Li, Z.; Ma, R.; Yang, Z. Experimental Study of Ammonia + [5] Ding, Z.; Liu, L.; Li, Z.; Ma, R.; Yang, Z. Experimental Study of Ammonia Removal from Water by Membrane Distillation (MD): The Comparison of Three Configurations. Journal of Membrane Science 2006, 286 (1), 93–103. https://doi.org/10.1016/j.memsci.2006.09.015. - .. [6] Al-Obaidani, S.; Curcio, E.; Macedonio, F.; Di Profio, G.; Al-Hinai, H.; + [6] Al-Obaidani, S.; Curcio, E.; Macedonio, F.; Di Profio, G.; Al-Hinai, H.; Drioli, E. Potential of Membrane Distillation in Seawater Desalination: Thermal Efficiency, Sensitivity Study and Cost Estimation. Journal of Membrane Science 2008, 323 (1), 85–98. https://doi.org/10.1016/j.memsci.2008.06.006. - .. [7] Kogler, A.; Farmer, M.; Simon, J. A.; Tilmans, S.; Wells, G. F.; + [7] Kogler, A.; Farmer, M.; Simon, J. A.; Tilmans, S.; Wells, G. F.; Tarpeh, W. A. Systematic Evaluation of Emerging Wastewater Nutrient Removal and Recovery Technologies to Inform Practice and Advance Resource Efficiency. ACS EST Eng. 2021, 1 (4), 662–684. https://doi.org/10.1021/acsestengg.0c00253. - .. [8] Pikaar, I.; Guest, J.; Ganigue, R.; Jensen, P.; Rabaey, K.; Seviour, T.; + [8] Pikaar, I.; Guest, J.; Ganigue, R.; Jensen, P.; Rabaey, K.; Seviour, T.; Trimmer, J.; van der Kolk, O.; Vaneeckhaute, C.; Verstraete, W.; Resource Recovery from Water: Principles and Applicaiton. IWA 2022. ''' diff --git a/qsdsan/sanunits/_pumping.py b/qsdsan/sanunits/_pumping.py index 89d9b1a4..083d3280 100644 --- a/qsdsan/sanunits/_pumping.py +++ b/qsdsan/sanunits/_pumping.py @@ -45,7 +45,7 @@ class Pump(SanUnit, BSTPump): ''' def __init__(self, ID='', ins=None, outs=(), thermo=None, *, P=None, pump_type='Default', material='Cast iron', - dP_design=405300, ignore_NPSH=True, + dP_design=101325, ignore_NPSH=True, init_with='Stream', F_BM_default=None, isdynamic=False): SanUnit.__init__(self, ID, ins, outs, thermo, init_with=init_with, F_BM_default=F_BM_default, @@ -186,7 +186,7 @@ def _cost(self): class WWTpump(SanUnit): ''' - Generic class for pumps used in wastewater treatment, [1]_ + Generic class for pumps used in wastewater treatment, all pumps are assumed be made of stainless steel. This class is intended to be used as a part of other units @@ -247,7 +247,7 @@ class WWTpump(SanUnit): References ---------- - .. [1] Shoener et al., Design of Anaerobic Membrane Bioreactors for the + [1] Shoener et al., Design of Anaerobic Membrane Bioreactors for the Valorization of Dilute Organic Carbon Waste Streams. Energy Environ. Sci. 2016, 9 (3), 1102–1112. https://doi.org/10.1039/C5EE03715H. @@ -932,7 +932,7 @@ class SludgePump(Pump): References ---------- - .. [1] Shoener et al., Design of Anaerobic Membrane Bioreactors for the + [1] Shoener et al., Design of Anaerobic Membrane Bioreactors for the Valorization of Dilute Organic Carbon Waste Streams. Energy Environ. Sci. 2016, 9 (3), 1102–1112. https://doi.org/10.1039/C5EE03715H. @@ -1111,9 +1111,9 @@ def wwtpump(ID, ins=(), prefix='', pump_type='', Q_mgd=None, add_inputs=(), References ---------- [1] Shoener et al., Design of Anaerobic Membrane Bioreactors for the - Valorization of Dilute Organic Carbon Waste Streams. - Energy Environ. Sci. 2016, 9 (3), 1102–1112. - https://doi.org/10.1039/C5EE03715H. + Valorization of Dilute Organic Carbon Waste Streams. + Energy Environ. Sci. 2016, 9 (3), 1102–1112. + https://doi.org/10.1039/C5EE03715H. ''' return lambda cls: add_pump(cls, ID, ins, prefix, pump_type, Q_mgd, add_inputs, capacity_factor, include_pump_cost, include_building_cost, diff --git a/qsdsan/sanunits/_septic_tank.py b/qsdsan/sanunits/_septic_tank.py index 4d5e5891..4da535c6 100644 --- a/qsdsan/sanunits/_septic_tank.py +++ b/qsdsan/sanunits/_septic_tank.py @@ -4,8 +4,11 @@ ''' QSDsan: Quantitative Sustainable Design for sanitation and resource recovery systems This module is developed by: + Yalin Li + Hannah Lohman + Tori Morgan This module is under the University of Illinois/NCSA Open Source License. diff --git a/qsdsan/sanunits/_tanks.py b/qsdsan/sanunits/_tank.py similarity index 100% rename from qsdsan/sanunits/_tanks.py rename to qsdsan/sanunits/_tank.py diff --git a/qsdsan/sanunits/_toilets.py b/qsdsan/sanunits/_toilet.py similarity index 99% rename from qsdsan/sanunits/_toilets.py rename to qsdsan/sanunits/_toilet.py index 223cd1ba..a8a03e06 100644 --- a/qsdsan/sanunits/_toilets.py +++ b/qsdsan/sanunits/_toilet.py @@ -373,7 +373,7 @@ class MURT(Toilet): See Also -------- - :ref:`qsdsan.sanunits.Toilet ` + :ref:`qsdsan.sanunits.Toilet ` ''' _N_outs = 3 _units = { @@ -570,7 +570,7 @@ class PitLatrine(Toilet): See Also -------- - :ref:`qsdsan.sanunits.Toilet ` + :ref:`qsdsan.sanunits.Toilet ` ''' _N_outs = 4 _units = { @@ -883,7 +883,7 @@ class UDDT(Toilet): See Also -------- - :ref:`qsdsan.sanunits.Toilet ` + :ref:`qsdsan.sanunits.Toilet ` ''' _N_outs = 6 _units = { diff --git a/qsdsan/sanunits/_treatment_beds.py b/qsdsan/sanunits/_treatment_bed.py similarity index 100% rename from qsdsan/sanunits/_treatment_beds.py rename to qsdsan/sanunits/_treatment_bed.py diff --git a/qsdsan/stats.py b/qsdsan/stats.py index 3e5613f8..741f4b82 100644 --- a/qsdsan/stats.py +++ b/qsdsan/stats.py @@ -989,8 +989,10 @@ def _plot_corr_bubble(corr_df, ratio, **kwargs): for label in g.ax.get_xticklabels(): label.set_rotation(90) - for artist in g.legend.legendHandles: - artist.set_edgecolor('0.5') + # # Originally `artist.set_edgecolor('0.5')`, but would trigger an error + # # with `seaborn` v0.13.0, and unclear what this is doing, took out + # for artist in g.legend.legendHandles: + # artist.set_markeredgecolor('0.5') for key in g.ax.spines.keys(): g.ax.spines[key].set(color='k', linewidth=0.5, visible=True) diff --git a/qsdsan/utils/cod.py b/qsdsan/utils/cod.py index 7d4b260b..965bbe99 100644 --- a/qsdsan/utils/cod.py +++ b/qsdsan/utils/cod.py @@ -107,10 +107,12 @@ def cod_test_stoichiometry(atoms, charge=0, MW=None, missing_handling='elemental nC, nH, nO, nN, nS, nP = get_CHONSP(atoms) ne = - charge - if nC <= 0 or nH <= 0: - if not (len(atoms) == 1 and nH == 2): # H2 - return {'Cr2O7-2': 0.} - + # if nC <= 0 or nH <= 0: + # if not (len(atoms) == 1 and nH == 2): # H2 + # return {'Cr2O7-2': 0.} + if nC + nH + nS + nP <= 0: + return {'Cr2O7-2': 0.} + nCO2 = nC nNH4 = nN nSO4 = nS diff --git a/qsdsan/utils/doc_examples.py b/qsdsan/utils/doc_examples.py index ba4256bf..31c26873 100644 --- a/qsdsan/utils/doc_examples.py +++ b/qsdsan/utils/doc_examples.py @@ -144,7 +144,7 @@ def create_example_system(components=None): ethanol = SanStream('ethanol', Ethanol=10, units='kg/hr') M1 = su.MixTank('M1', ins=(salt_water, 'recycled_brine', methanol, ethanol)) - P1 = su.Pump('P1', ins=M1-0) + P1 = su.Pump('P1', dP_design=405300,ins=M1-0) H1 = su.HXutility('H1', ins=P1-0, T=350) S1 = su.ComponentSplitter('S1', ins=H1-0, split_keys=('Methanol', 'Ethanol')) M2 = su.Mixer('M2', ins=(S1-0, S1-1), outs='alcohols') diff --git a/qsdsan/utils/loading.py b/qsdsan/utils/loading.py index 92336116..38d228fe 100644 --- a/qsdsan/utils/loading.py +++ b/qsdsan/utils/loading.py @@ -20,7 +20,8 @@ __all__ = ( 'ospath', 'load_data', 'data_path', - 'save_pickle', 'load_pickle', 'load_pickled_cmps', + 'save_pickle', 'load_pickle', + # 'load_pickled_cmps', ) @@ -76,25 +77,28 @@ def load_pickle(path): f.close() return obj - -def load_pickled_cmps(components_creation_f, pickle_path, pickle=None): - ''' - Load components from pickle, update the pickled files if needed. - - Parameters - ---------- - pickle: bool or None. - Whether to pickle the generated components. - If set to None, will pickle when there is no valid pickle file - (either the file is non-existing or it's outdated). - ''' - if pickle == True: # repickle if asked to - return components_creation_f(pickle=True) - if ospath.isfile(pickle_path): # try to load pickled file - try: return load_pickle(pickle_path) - except: # want to repickle if there's no pickled file - pickle = True if pickle==None else False - if pickle is not False: - return components_creation_f(pickle=True) - else: - return components_creation_f(pickle=False) +# # Legacy function no longer in use, DO NOT DELETE for now +# def load_pickled_cmps(components_creation_f, pickle_path, pickle=None): +# ''' +# Load components from pickle, update the pickled files if needed. +# This function is for util testing and + +# Parameters +# ---------- +# pickle: bool or None. +# Whether to pickle the generated components. +# If set to None, will pickle when there is no valid pickle file +# (either the file is non-existing or it's outdated). +# components_creation_f : callable. +# Function used to create the components. +# ''' +# if pickle == True: # repickle if asked to +# return components_creation_f(pickle=True) +# if ospath.isfile(pickle_path): # try to load pickled file +# try: return load_pickle(pickle_path) +# except: # want to repickle if there's no pickled file +# pickle = True if pickle==None else False +# if pickle is not False: +# return components_creation_f(pickle=True) +# else: +# return components_creation_f(pickle=False) diff --git a/tests/test_exposan.py b/tests/test_exposan.py index 50062fcc..b716f8d5 100644 --- a/tests/test_exposan.py +++ b/tests/test_exposan.py @@ -37,15 +37,15 @@ def test_exposan(): bsm1_sys.simulate(t_span=(0,10), method='BDF') print(get_SRT(bsm1_sys, biomass_IDs=biomass_IDs)) # to test the `get_SRT` function + #!!! Will use bsm2 to test the junction models + # from exposan.interface import create_system as create_inter_system + # sys_inter = create_inter_system() + # sys_inter.simulate(method='BDF', t_span=(0, 3)) # the default 'RK45' method can't solve it + from exposan.cas import create_system as create_cas_system cas_sys = create_cas_system() cas_sys.simulate() - from exposan.interface import create_system as create_inter_system - sys_inter = create_inter_system() - #!!! Temporarily disable this test while trying to fix the issue - # sys_inter.simulate(method='BDF', t_span=(0, 3)) # the default 'RK45' method can't solve it - ##### Systems with costs/impacts ##### from qsdsan.utils import clear_lca_registries