├── .coveragerc ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ ├── feature_request.md │ └── question.md ├── labeler.yml └── workflows │ ├── codeql.yml │ ├── cont_int.yml │ ├── docker_build.yml │ ├── gh-pages.yml │ ├── labeler.yml │ └── update-cache.yml ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── CODE_OF_CONDUCT.md ├── Dockerfile ├── LICENSE ├── Makefile ├── README.md ├── T3.code-workspace ├── T3.py ├── codecov.yml ├── data └── libraries.yml ├── devtools ├── ARCHIVED_install_RMS_v032.jl ├── Dockerfile_rmgpy ├── install_all.sh ├── install_arc.sh ├── install_pycall.jl └── install_pyrms.sh ├── docs ├── T3-circle.gif ├── T3-circle.png ├── T3_logo_small.gif ├── cite.md ├── contribute.md ├── credits.md ├── css │ ├── custom.css │ └── termynal.css ├── how_to.md ├── index.md ├── installation.md ├── js │ ├── custom.js │ └── termynal.js ├── licence.md ├── output.md ├── release.md ├── running.md ├── t3-circle.jpg └── tutorials │ ├── 1_no_qm.md │ └── 2_adding_simulate_adapter.md ├── environment.yml ├── examples ├── commented │ └── input.yml ├── liquid_phase │ └── input.yml └── minimal │ └── input.yml ├── grf ├── T3-circle.gif ├── T3_logo.gif ├── T3_logo.jpg ├── T3_logo.psd └── T3_logo_small.gif ├── ipython ├── flux_diagram │ ├── Generate Flux Diagram.ipynb │ └── HOCHO_flux_diagrams │ │ ├── bar_ROPs │ │ ├── H(3)_2.0_s.png │ │ ├── HOCHO(1)_2.0_s.png │ │ └── HOCO(10)_2.0_s.png │ │ └── flux_diagrams │ │ ├── H(3) │ │ ├── flux_diagram_2.0_s.dot │ │ └── flux_diagram_2.0_s.png │ │ ├── HOCHO(1) │ │ ├── flux_diagram_2.0_s.dot │ │ └── flux_diagram_2.0_s.png │ │ └── HOCO(10) │ │ ├── flux_diagram_2.0_s.dot │ │ └── flux_diagram_2.0_s.png └── simulator_adapter_examples │ ├── cantera_simulator.ipynb │ ├── cantera_simulator_data │ ├── input.yml │ └── iteration_0 │ │ └── RMG │ │ ├── cantera │ │ └── chem_annotated.cti │ │ └── input.py │ ├── rmg_simulator.ipynb │ ├── rmg_simulator_data │ ├── input.yml │ └── iteration_0 │ │ └── RMG │ │ ├── chemkin │ │ ├── chem_annotated.inp │ │ └── species_dictionary.txt │ │ └── input.py │ ├── rms_simulator.ipynb │ └── rms_simulator_data │ ├── input.yml │ └── iteration_0 │ └── RMG │ └── rms │ └── chem12.rms ├── mkdocs.yml ├── pytest.ini ├── requirements.txt ├── t3 ├── __init__.py ├── common.py ├── imports.py ├── logger.py ├── main.py ├── runners │ ├── __init__.py │ ├── rmg_incore_script.py │ └── rmg_runner.py ├── schema.py ├── settings │ ├── t3_settings.py │ └── t3_submit.py ├── simulate │ ├── __init__.py │ ├── adapter.py │ ├── cantera_constantHP.py │ ├── cantera_constantTP.py │ ├── cantera_constantUV.py │ ├── factory.py │ └── rmg_constantTP.py └── utils │ ├── __init__.py │ ├── dependencies.py │ ├── fix_cantera.py │ ├── flux.py │ ├── generator.py │ ├── libraries.py │ └── writer.py └── tests ├── __init__.py ├── common.py ├── data ├── backup_rmg_files_before_restart │ └── iteration_1 │ │ └── RMG │ │ ├── RMG.log │ │ ├── chemkin │ │ ├── chem.inp │ │ ├── chem0113.inp │ │ ├── chem_annotated.inp │ │ ├── chem_edge.inp │ │ ├── chem_edge_annotated.inp │ │ ├── species_dictionary.txt │ │ ├── species_edge_dictionary.txt │ │ └── tran.dat │ │ └── pdep │ │ ├── network1_2.py │ │ └── network2_1.py ├── chem_annotated_1.inp ├── collision_rate_violators │ ├── chem_annotated.inp │ ├── collision_rate_violators.log │ └── species_dictionary.txt ├── determine_reactions │ └── iteration_1 │ │ └── RMG │ │ └── chemkin │ │ ├── chem_annotated.inp │ │ └── species_dictionary.txt ├── determine_species │ ├── iteration_1 │ │ └── RMG │ │ │ └── chemkin │ │ │ ├── chem_annotated.inp │ │ │ └── species_dictionary.txt │ ├── iteration_2 │ │ └── RMG │ │ │ └── chemkin │ │ │ ├── chem_annotated.inp │ │ │ └── species_dictionary.txt │ └── iteration_3 │ │ └── RMG │ │ ├── chemkin │ │ ├── chem_annotated.inp │ │ └── species_dictionary.txt │ │ └── collision_rate_violators.log ├── functional_2_thermo │ └── input.yml ├── minimal_data │ └── iteration_1 │ │ └── RMG │ │ ├── chemkin │ │ ├── chem_annotated.inp │ │ └── species_dictionary.txt │ │ └── input.py ├── models │ ├── HOCHO.yaml │ ├── N2H4.yaml │ ├── NH3.yaml │ └── dups │ │ ├── 1.yaml │ │ ├── 2.yaml │ │ └── NH3.yaml ├── pdep_network │ └── iteration_1 │ │ └── RMG │ │ ├── chemkin │ │ ├── chem_annotated.inp │ │ └── species_dictionary.txt │ │ └── pdep │ │ ├── network1_1.py │ │ ├── network4_1.py │ │ └── network4_2.py ├── process_arc │ ├── iteration_2 │ │ └── ARC │ │ │ ├── T3.info │ │ │ ├── T3_info.yml │ │ │ └── output │ │ │ └── RMG libraries │ │ │ └── thermo │ │ │ └── T3.py │ └── reactions.yml ├── restart │ ├── r2 │ │ └── iteration_2 │ │ │ └── RMG │ │ │ └── RMG.log │ ├── r3 │ │ └── iteration_3 │ │ │ └── RMG │ │ │ └── RMG.log │ ├── r4 │ │ └── iteration_4 │ │ │ ├── ARC │ │ │ └── arc.log │ │ │ └── RMG │ │ │ └── RMG.log │ ├── r5 │ │ └── iteration_5 │ │ │ ├── ARC │ │ │ └── arc.log │ │ │ └── RMG │ │ │ └── RMG.log │ ├── r6 │ │ ├── iteration_6 │ │ │ ├── ARC │ │ │ │ ├── T3.info │ │ │ │ ├── T3_info.yml │ │ │ │ ├── arc.log │ │ │ │ ├── restart.yml │ │ │ │ └── test_restart_info.yml │ │ │ └── RMG │ │ │ │ └── RMG.log │ │ └── reactions.yml │ └── r7 │ │ └── iteration_7 │ │ ├── ARC │ │ ├── T3.info │ │ └── arc.log │ │ └── RMG │ │ └── RMG.log └── rmg_convergence │ ├── 1_frag_error │ ├── RMG.log │ └── err.txt │ └── 2_converged │ ├── RMG.log │ └── err.txt ├── test_common.py ├── test_functional.py ├── test_generator.py ├── test_libraries.py ├── test_logger.py ├── test_main.py ├── test_rmg_runner.py ├── test_schema.py ├── test_simulate_adapters ├── data │ ├── cantera_simulator_test │ │ ├── input.yml │ │ └── iteration_0 │ │ │ └── RMG │ │ │ ├── cantera │ │ │ └── chem_annotated.cti │ │ │ ├── chemkin │ │ │ ├── chem_annotated.inp │ │ │ └── species_dictionary.txt │ │ │ └── input.py │ ├── rmg_simulator_test │ │ ├── input.yml │ │ └── iteration_0 │ │ │ └── RMG │ │ │ ├── chemkin │ │ │ ├── chem_annotated.inp │ │ │ └── species_dictionary.txt │ │ │ └── input.py │ ├── rmg_simulator_test_ranges_3c │ │ └── t3.log │ └── rms_simulator_test │ │ ├── input.yml │ │ └── iteration_0 │ │ └── RMG │ │ └── rms │ │ └── chem12.rms └── test_rmg_constantTP.py └── test_writer.py /.coveragerc: -------------------------------------------------------------------------------- 1 | # .coveragerc to control coverage.py 2 | [run] 3 | branch = True 4 | source = t3 5 | omit = 6 | test_*.py 7 | */scripts/* 8 | */testing/* 9 | */tests/* 10 | */docs/* 11 | */examples/* 12 | */ipython/* 13 | */grf/* 14 | */devtools/* 15 | 16 | [report] 17 | show_missing = False 18 | exclude_lines = 19 | if __name__ == .__main__.: 20 | include = 21 | t3/* 22 | omit = 23 | test_*.py 24 | */scripts/* 25 | */testing/* 26 | */tests/* 27 | */docs/* 28 | */examples/* 29 | */ipython/* 30 | */grf/* 31 | */devtools/* 32 | 33 | [html] 34 | directory = testing/coverage 35 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: 'Type: Bug' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **How to reproduce** 14 | Insert code to reproduce this behavior. 15 | 16 | **Expected behavior** 17 | A clear and concise description of what you expected to happen. 18 | 19 | **Additional context** 20 | Add any other context about the problem here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'Type: Feature' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. For example: "I'm always frustrated when [...]" 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/question.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Question 3 | about: Ask a question about how to use T3 4 | title: '' 5 | labels: 'Type: Question' 6 | assignees: '' 7 | 8 | --- 9 | 10 | <-- Thanks for your interest in T3! 11 | Please first check the online documentation at 12 | https://reactionmechanismgenerator.github.io/T3/ to see 13 | if it answers your question. Also, try searching GitHub 14 | issues to see if someone has asked your question before. --> 15 | 16 | **Describe what you are trying to achieve** 17 | A clear and concise description of what you want to achieve. 18 | 19 | **Describe methods you have considered** 20 | Describe alternative methods you've considered. 21 | -------------------------------------------------------------------------------- /.github/labeler.yml: -------------------------------------------------------------------------------- 1 | repo: 2 | - ./* 3 | 4 | examples: 5 | - examples/**/* 6 | 7 | tests: 8 | - tests/**/* 9 | 10 | Module common: 11 | - t3/common.py 12 | 13 | Module docs: 14 | - t3/docs/**/* 15 | 16 | Module logger: 17 | - t3/logger.py 18 | 19 | Module main: 20 | - t3/main.py 21 | 22 | Module schema: 23 | - t3/schema.py 24 | 25 | Module simulate: 26 | - t3/simulate/**/* 27 | 28 | Module writer: 29 | - t3/utils/writer.py 30 | -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ "main" ] 6 | pull_request: 7 | # The branches below must be a subset of the branches above 8 | branches: [ "main" ] 9 | schedule: 10 | - cron: '33 14 * * 5' 11 | 12 | jobs: 13 | analyze: 14 | name: Analyze 15 | runs-on: ubuntu-latest 16 | permissions: 17 | actions: read 18 | contents: read 19 | security-events: write 20 | 21 | strategy: 22 | fail-fast: false 23 | matrix: 24 | language: [ 'python' ] 25 | 26 | steps: 27 | - name: Checkout repository 28 | uses: actions/checkout@v3 29 | 30 | - name: Initialize CodeQL 31 | uses: github/codeql-action/init@v2 32 | with: 33 | languages: ${{ matrix.language }} 34 | queries: security-and-quality 35 | 36 | - name: Autobuild 37 | uses: github/codeql-action/autobuild@v2 38 | 39 | - name: Perform CodeQL Analysis 40 | uses: github/codeql-action/analyze@v2 41 | with: 42 | category: "/language:${{matrix.language}}" 43 | -------------------------------------------------------------------------------- /.github/workflows/docker_build.yml: -------------------------------------------------------------------------------- 1 | name: Docker Image Build and Push 2 | 3 | #Ensure that top-level permissions are not set to write-all 4 | #https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions 5 | 6 | 7 | 8 | on: 9 | schedule: 10 | - cron: "0 0 */7 * *" # every 7 days 11 | push: 12 | branches: 13 | - main 14 | paths: 15 | - "Dockerfile" 16 | - "devtools/Dockerfile_rmgpy" 17 | - ".github/workflows/docker_build.yml" 18 | pull_request: 19 | branches: 20 | - main 21 | paths: 22 | - "Dockerfile" 23 | - "devtools/Dockerfile_rmgpy" 24 | - ".github/workflows/docker_build.yml" 25 | types: [opened, synchronize, reopened, ready_for_review] 26 | #workflow_dispatch: # Add this line to enable manual trigger 27 | 28 | permissions: 29 | contents: read 30 | pull-requests: write 31 | 32 | jobs: 33 | ci-check: 34 | if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref != 'refs/heads/main') 35 | runs-on: ubuntu-latest 36 | steps: 37 | - name: Free Disk Space (Ubuntu) 38 | uses: jlumbroso/free-disk-space@main 39 | with: 40 | # this might remove tools that are actually needed, 41 | # if set to "true" but frees about 6 GB 42 | tool-cache: true 43 | # all of these default to true, but feel free to set to 44 | # "false" if necessary for your workflow 45 | android: true 46 | dotnet: true 47 | haskell: true 48 | large-packages: true 49 | docker-images: false 50 | swap-storage: false 51 | - name: Checkout 52 | uses: actions/checkout@v4.1.1 53 | - name: Set up Docker Buildx 54 | uses: docker/setup-buildx-action@v3.0.0 55 | # Add steps for CI checks of the Dockerfile 56 | - name: Build Docker Image (No Push) 57 | uses: docker/build-push-action@v5.1.0 58 | with: 59 | context: . 60 | file: ./Dockerfile 61 | push: false 62 | 63 | build-and-push: 64 | if: github.event_name == 'push' && github.ref == 'refs/heads/main' 65 | runs-on: ubuntu-latest 66 | steps: 67 | - name: Checkout 68 | uses: actions/checkout@v4.1.1 69 | - name: Free Disk Space (Ubuntu) 70 | uses: jlumbroso/free-disk-space@main 71 | with: 72 | # this might remove tools that are actually needed, 73 | # if set to "true" but frees about 6 GB 74 | tool-cache: true 75 | 76 | # all of these default to true, but feel free to set to 77 | # "false" if necessary for your workflow 78 | android: true 79 | dotnet: true 80 | haskell: true 81 | large-packages: true 82 | docker-images: false 83 | swap-storage: false 84 | - name: Login to Docker Hub 85 | uses: docker/login-action@v3.0.0 86 | with: 87 | username: ${{ secrets.DOCKERHUB_USERNAME }} 88 | password: ${{ secrets.DOCKERHUB_TOKEN }} 89 | - name: Set up Docker Buildx 90 | uses: docker/setup-buildx-action@v3.0.0 91 | - name: Build and push RMG-Py 92 | uses: docker/build-push-action@v5.0.0 93 | with: 94 | context: . 95 | file: ./devtools/Dockerfile_rmgpy 96 | push: true 97 | tags: ${{ secrets.DOCKERHUB_USERNAME }}/rmgpy:latest 98 | - name: Build and push T3 99 | uses: docker/build-push-action@v5.0.0 100 | with: 101 | context: . 102 | file: ./Dockerfile 103 | push: true 104 | tags: ${{ secrets.DOCKERHUB_USERNAME }}/thetandemtool-t3:latest 105 | -------------------------------------------------------------------------------- /.github/workflows/gh-pages.yml: -------------------------------------------------------------------------------- 1 | name: github pages 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | deploy: 10 | runs-on: ubuntu-22.04 11 | steps: 12 | - uses: actions/checkout@v2 13 | 14 | - name: Setup Python 15 | uses: actions/setup-python@v2 16 | with: 17 | python-version: '3.7' 18 | 19 | - name: Upgrade pip 20 | run: | 21 | # install pip=>20.1 to use "pip cache dir" 22 | python3 -m pip install --upgrade pip 23 | 24 | - name: Get pip cache dir 25 | id: pip-cache 26 | run: echo "::set-output name=dir::$(pip cache dir)" 27 | 28 | - name: Cache dependencies 29 | uses: actions/cache@v2 30 | with: 31 | path: ${{ steps.pip-cache.outputs.dir }} 32 | key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt') }} 33 | restore-keys: | 34 | ${{ runner.os }}-pip- 35 | 36 | - name: Install dependencies 37 | run: python3 -m pip install -r ./requirements.txt 38 | 39 | - run: mkdocs build 40 | 41 | - name: Deploy 42 | uses: peaceiris/actions-gh-pages@v3 43 | with: 44 | github_token: ${{ secrets.GITHUB_TOKEN }} 45 | publish_dir: ./site 46 | -------------------------------------------------------------------------------- /.github/workflows/labeler.yml: -------------------------------------------------------------------------------- 1 | # This workflow will triage pull requests and apply a label based on the 2 | # paths that are modified in the pull request. 3 | # See: https://github.com/actions/labeler/blob/main/README.md 4 | 5 | name: Labeler 6 | on: [pull_request] 7 | 8 | jobs: 9 | label: 10 | 11 | runs-on: ubuntu-latest 12 | 13 | steps: 14 | - uses: actions/labeler@v2 15 | with: 16 | repo-token: "${{ secrets.GITHUB_TOKEN }}" 17 | -------------------------------------------------------------------------------- /.github/workflows/update-cache.yml: -------------------------------------------------------------------------------- 1 | name: Update cache 2 | 3 | on: 4 | schedule: 5 | - cron: "0 0 */7 * *" 6 | push: 7 | branches: 8 | - main 9 | 10 | jobs: 11 | update_cache: 12 | runs-on: ubuntu-latest 13 | defaults: 14 | run: 15 | shell: bash -el {0} 16 | steps: 17 | - name: Clean Ubuntu Image 18 | uses: kfir4444/free-disk-space@main 19 | with: 20 | # This may remove tools actually needed - currently does not 21 | tool-cache: true 22 | android: true 23 | dotnet: true 24 | haskell: true 25 | large-packages: true 26 | swap-storage: true 27 | 28 | - name: Checkout T3 29 | uses: actions/checkout@v4.1.1 30 | 31 | - name: Cache RMG 32 | id: cache-rmg 33 | uses: actions/cache@v3.3.2 34 | with: 35 | path: RMG-Py 36 | key: ${{ runner.os }}-rmg-main 37 | 38 | - name: Checkout RMG 39 | uses: actions/checkout@v4.1.1 40 | with: 41 | repository: ReactionMechanismGenerator/RMG-Py 42 | path: RMG-Py 43 | ref: main 44 | fetch-depth: 1 45 | 46 | - name: Cache RMG-database 47 | id: cache-rmg-db 48 | uses: actions/cache@v3.3.2 49 | with: 50 | path: RMG-database 51 | key: ${{ runner.os }}-rmgdb-main 52 | 53 | - name: Checkout RMG-database 54 | uses: actions/checkout@v4.1.1 55 | with: 56 | repository: ReactionMechanismGenerator/RMG-database 57 | path: RMG-database 58 | ref: main 59 | fetch-depth: 1 60 | 61 | - name: Cache ARC 62 | id: cache-arc 63 | uses: actions/cache@v3.3.2 64 | with: 65 | path: ARC 66 | key: ${{ runner.os }}-arc-main 67 | 68 | - name: Checkout ARC 69 | uses: actions/checkout@v4.1.1 70 | with: 71 | repository: ReactionMechanismGenerator/ARC 72 | path: ARC 73 | ref: main 74 | fetch-depth: 1 75 | 76 | - name: Setup RMG-Py Env 77 | uses: conda-incubator/setup-miniconda@v2.2.0 78 | with: 79 | miniforge-variant: Mambaforge 80 | miniforge-version: latest 81 | activate-environment: rmg_env 82 | use-mamba: true 83 | 84 | - name: Cache RMG-Py env 85 | uses: actions/cache@v3.3.2 86 | with: 87 | path: ${{ env.CONDA }}/envs/rmg_env 88 | key: 89 | conda-${{ runner.os }}--${{ runner.arch }}-rmgpyenv-${{ env.CACHE_NUMBER}} 90 | env: 91 | # Increase this value to reset cache if etc/example-environment.yml has not changed 92 | CACHE_NUMBER: 0 93 | id: cache 94 | - name: Update environment 95 | run: mamba env update -n rmg_env -f RMG-Py/environment.yml 96 | 97 | - name: Cythonize RMG-Py 98 | run: | 99 | cd RMG-Py 100 | conda activate rmg_env 101 | make clean 102 | make 103 | echo "PYTHONPATH=$(pwd):$PYTHONPATH" >> $GITHUB_ENV 104 | echo "PATH=$(pwd):$PATH" >> $GITHUB_ENV 105 | echo "export rmgpy_path=$(pwd)" >> $GITHUB_ENV 106 | echo "PYTHONPATH=$(pwd):$PYTHONPATH" >> ~/.bashrc 107 | echo "PATH=$(pwd):$PATH" >> ~/.bashrc 108 | echo "export rmgpy_path=$(pwd)" >> ~/.bashrc 109 | 110 | - name: Install PyCall RMG_ENV 111 | run: python -c "import julia; julia.install(); import diffeqpy; diffeqpy.install()" 112 | 113 | - name: Install RMS Julia 114 | run: julia -e 'using Pkg; Pkg.add(PackageSpec(name="PyCall",rev="master"));Pkg.build("PyCall");Pkg.add(PackageSpec(name="ReactionMechanismSimulator",rev="main")); using ReactionMechanismSimulator;' 115 | 116 | - name: Install PyCall RMG_ENV 117 | run: python -c "import julia; julia.install(); import diffeqpy; diffeqpy.install()" 118 | 119 | - name: Install ARC 120 | run: | 121 | cd ARC 122 | mamba env create -f environment.yml 123 | conda activate arc_env 124 | echo "export arc_path=$(pwd)" >> $GITHUB_ENV 125 | echo "PYTHONPATH=$(pwd):$PYTHONPATH" >> $GITHUB_ENV 126 | echo "PATH=$(pwd):$PATH" >> $GITHUB_ENV 127 | echo "PYTHONPATH=$(pwd):$PYTHONPATH" >> ~/.bashrc 128 | echo "PATH=$(pwd):$PATH" >> ~/.bashrc 129 | echo "export arc_path=$(pwd)" >> ~/.bashrc 130 | cd .. 131 | 132 | - name: Install xtb 133 | run: | 134 | mamba create -n xtb_env python=3.7 -c conda-forge -y 135 | conda activate xtb_env 136 | mamba install -c conda-forge xtb -y 137 | mamba install -c anaconda pyyaml -y 138 | 139 | - name: Cache Conda Packages 140 | uses: actions/cache@v3.3.2 141 | env: 142 | CACHE_NUMBER: 0 143 | with: 144 | path: ~/conda_pkgs_dir 145 | key: 146 | ${{ runner.os }}-conda-${{ env.CACHE_NUMBER }}-${{ hashFiles('environment.yml') }}-t3 147 | 148 | - name: Install T3 149 | run: | 150 | mamba env create -f environment.yml 151 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # Projects 7 | Projects/ 8 | 9 | # C extensions 10 | *.so 11 | 12 | # Distribution / packaging 13 | .Python 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | downloads/ 18 | eggs/ 19 | .eggs/ 20 | lib/ 21 | lib64/ 22 | parts/ 23 | sdist/ 24 | var/ 25 | wheels/ 26 | pip-wheel-metadata/ 27 | share/python-wheels/ 28 | *.egg-info/ 29 | .installed.cfg 30 | *.egg 31 | MANIFEST 32 | 33 | # PyInstaller 34 | # Usually these files are written by a python script from a template 35 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 36 | *.manifest 37 | *.spec 38 | 39 | # Installer logs 40 | pip-log.txt 41 | pip-delete-this-directory.txt 42 | 43 | # Unit test / coverage reports 44 | htmlcov/ 45 | .tox/ 46 | .nox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | *.py,cover 54 | .hypothesis/ 55 | .pytest_cache/ 56 | 57 | # Translations 58 | *.mo 59 | *.pot 60 | 61 | # Django stuff: 62 | *.log 63 | local_settings.py 64 | db.sqlite3 65 | db.sqlite3-journal 66 | 67 | # Flask stuff: 68 | instance/ 69 | .webassets-cache 70 | 71 | # Scrapy stuff: 72 | .scrapy 73 | 74 | # Sphinx documentation 75 | docs/_build/ 76 | 77 | # PyBuilder 78 | target/ 79 | 80 | # Jupyter Notebook 81 | *.ipynb_* 82 | 83 | # IPython 84 | profile_default/ 85 | ipython_config.py 86 | 87 | # pyenv 88 | .python-version 89 | 90 | # pipenv 91 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 92 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 93 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 94 | # install all needed dependencies. 95 | #Pipfile.lock 96 | 97 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 98 | __pypackages__/ 99 | 100 | # Celery stuff 101 | celerybeat-schedule 102 | celerybeat.pid 103 | 104 | # SageMath parsed files 105 | *.sage.py 106 | 107 | # Environments 108 | .env 109 | .venv 110 | env/ 111 | venv/ 112 | ENV/ 113 | env.bak/ 114 | venv.bak/ 115 | 116 | # Spyder project settings 117 | .spyderproject 118 | .spyproject 119 | 120 | # Rope project settings 121 | .ropeproject 122 | 123 | # mkdocs documentation 124 | /site 125 | 126 | # mypy 127 | .mypy_cache/ 128 | .dmypy.json 129 | dmypy.json 130 | 131 | # Pyre type checker 132 | .pyre/ 133 | 134 | # MacOS files 135 | .DS_Store 136 | 137 | # Compiled Python modules 138 | *.pyc 139 | *.so 140 | *.pyd 141 | 142 | # PyCharm project files 143 | .idea/* 144 | 145 | # Unit test files 146 | testing/* 147 | htmlcov/* 148 | 149 | #VSCode files 150 | .vscode/* 151 | .vscode/launch.json 152 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "Python: Current File", 9 | "type": "python", 10 | "request": "launch", 11 | "program": "${file}", 12 | "env": {"PYDEVD_WARN_EVALUATION_TIMEOUT": "500"}, 13 | "console": "integratedTerminal", 14 | "justMyCode": true 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.testing.pytestArgs": [ 3 | "tests" 4 | ], 5 | "python.testing.unittestEnabled": false, 6 | "python.testing.pytestEnabled": true 7 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # The RMG-ARC Tandem Tool (T3) Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to make participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, 8 | body size, disability, ethnicity, sex characteristics, gender identity and 9 | expression, level of experience, education, socio-economic status, nationality, 10 | personal appearance, race, religion, or sexual identity and orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or advances 26 | * Trolling, insulting/derogatory comments, and personal or political attacks 27 | * Public or private harassment 28 | * Publishing others' private information, such as a physical or electronic address, 29 | without explicit permission 30 | * Other conduct which could reasonably be considered inappropriate in a professional setting 31 | 32 | ## Our Responsibilities 33 | 34 | Project maintainers are responsible for clarifying the standards of acceptable 35 | behavior and are expected to take appropriate and fair corrective action in 36 | response to any instances of unacceptable behavior. 37 | 38 | Project maintainers have the right and responsibility to remove, edit, or 39 | reject comments, commits, code, wiki edits, issues, and other contributions 40 | that are not aligned to this Code of Conduct, or to ban temporarily or 41 | permanently any contributor for other behaviors that they deem inappropriate, 42 | threatening, offensive, or harmful. 43 | 44 | ## Scope 45 | 46 | This Code of Conduct applies within all project spaces, and it also applies when 47 | an individual is representing the project or its community in public spaces. 48 | Examples of representing a project or community include using an official 49 | project e-mail address, posting via an official social media account, or acting 50 | as an appointed representative at an online or offline event. Representation of 51 | a project may be further defined and clarified by project maintainers. 52 | 53 | ## Enforcement 54 | 55 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 56 | reported by contacting the project team at . 57 | 58 | All complaints will be reviewed and investigated and will result in a response 59 | that is deemed necessary and appropriate to the circumstances. The project team 60 | is obligated to maintain confidentiality with regard to the reporter of an 61 | incident. Further details of specific enforcement policies may be posted 62 | separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at 72 | 73 | For answers to common questions about this code of conduct, 74 | see 75 | 76 | [homepage]: https://www.contributor-covenant.org 77 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Using the a base image of rmgpy:latest from DockerHub - Not the official version but a custom version that is smaller in size 2 | FROM --platform=linux/amd64 laxzal/arc:latest 3 | 4 | USER rmguser 5 | 6 | # Installing ARC 7 | # Change directory to Code 8 | WORKDIR /home/rmguser/Code 9 | 10 | # Install T3 11 | 12 | # Change directory to Code 13 | WORKDIR /home/rmguser/Code 14 | 15 | # Clone main branch T3 repository from GitHub and set as working directory 16 | RUN git clone -b main https://github.com/ReactionMechanismGenerator/T3.git 17 | WORKDIR /home/rmguser/Code/T3 18 | 19 | # Install T3 Environment 20 | RUN micromamba create -y -f environment.yml && \ 21 | micromamba clean --all -f -y && \ 22 | rm -rf /home/rmguser/.cache/yarn \ 23 | rm -rf /home/rmguser/.cache/pip \ 24 | && find -name '__pycache__' -type d -exec rm -rf '{}' '+' && \ 25 | find /opt/conda/envs/t3_env/lib/python3.7/site-packages/scipy -name 'tests' -type d -exec rm -rf '{}' '+' && \ 26 | find /opt/conda/envs/t3_env/lib/python3.7/site-packages/numpy -name 'tests' -type d -exec rm -rf '{}' '+' && \ 27 | find /opt/conda/envs/t3_env/lib/python3.7/site-packages/pandas -name 'tests' -type d -exec rm -rf '{}' '+' && \ 28 | find /opt/conda/envs/t3_env/lib/python3.7/site-packages -name '*.pyx' -delete \ 29 | && find /opt/conda/ -follow -type f -name '*.a' -delete \ 30 | && find /opt/conda/ -follow -type f -name '*.pyc' -delete \ 31 | && find /opt/conda/ -follow -type f -name '*.js.map' -delete 32 | 33 | # Add alias to bashrc - rmge to activate the environment 34 | # These commands are not necessary for the Docker image to run, but they are useful for the user 35 | RUN echo "export arc_path='/home/rmguser/Code/ARC/'" >> ~/.bashrc \ 36 | && echo "export t3_path='/home/rmguser/Code/T3/'" >> ~/.bashrc \ 37 | && echo "alias t3code='cd \$t3_path'" >> ~/.bashrc \ 38 | && echo "alias t3e='micromamba activate t3_env'" >> ~/.bashrc \ 39 | && echo "alias t3='python /home/rmguser/Code/T3/T3.py input.yml'" >> ~/.bashrc 40 | 41 | # Set the wrapper script as the entrypoint 42 | ENTRYPOINT ["/home/rmguser/entrywrapper.sh"] 43 | 44 | # Activate the T3 environment 45 | WORKDIR /home/rmguser/ 46 | ARG MAMBA_DOCKERFILE_ACTIVATE=1 47 | ENV ENV_NAME=t3_env 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019-2023, Dana Research Group, Technion -- Israel Institute of Technology 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for T3 2 | 3 | install: 4 | bash devtools/install_all.sh 5 | 6 | install-arc: 7 | bash devtools/install_arc.sh 8 | 9 | install-pyrms: 10 | bash devtools/install_pyrms.sh 11 | 12 | test: 13 | pytest tests/ --cov -ra -vv 14 | 15 | test-main: 16 | pytest tests/test_main.py -ra -vv 17 | 18 | test-functional: 19 | pytest tests/test_functional.py -ra -vv 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | T3 3 |

4 | 5 | # The Tandem Tool (T3) for automated chemical kinetic model development 6 | [![Docker Image Build and Push](https://github.com/ReactionMechanismGenerator/T3/actions/workflows/docker_build.yml/badge.svg?branch=main)](https://github.com/ReactionMechanismGenerator/T3/actions/workflows/docker_build.yml) 7 | ![Release](https://img.shields.io/badge/version-0.1.0-blue.svg) 8 | ![Build Status](https://github.com/ReactionMechanismGenerator/T3/actions/workflows/cont_int.yml/badge.svg) 9 | [![codecov](https://codecov.io/gh/ReactionMechanismGenerator/T3/branch/main/graph/badge.svg)](https://codecov.io/gh/ReactionMechanismGenerator/T3) 10 | [![MIT license](http://img.shields.io/badge/license-MIT-brightgreen.svg)](http://opensource.org/licenses/MIT) 11 | ![python](https://img.shields.io/badge/Python-3.7+-blue.svg) 12 | 13 | ### T3 works according to the following general scheme: 14 | 15 | ![T3 scheme][cycle] 16 | 17 | [cycle]: /grf/T3-circle.gif "T3 scheme" 18 | -------------------------------------------------------------------------------- /T3.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | }, 6 | { 7 | "path": "../ARC" 8 | }, 9 | { 10 | "path": "../RMG-Py" 11 | } 12 | ], 13 | "settings": {} 14 | } -------------------------------------------------------------------------------- /T3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | """ 5 | T3 executable module 6 | """ 7 | 8 | import argparse 9 | import os 10 | 11 | from arc.common import read_yaml_file 12 | 13 | from t3 import T3 14 | from t3.utils.dependencies import check_dependencies 15 | 16 | 17 | def parse_command_line_arguments(command_line_args=None): 18 | """ 19 | Parse command-line arguments. 20 | 21 | Args: 22 | command_line_args: The command line arguments. 23 | 24 | Returns: 25 | The parsed command-line arguments by key words. 26 | """ 27 | 28 | parser = argparse.ArgumentParser(description='The Tandem Tool (T3)') 29 | parser.add_argument('file', metavar='FILE', type=str, nargs=1, 30 | help='a file describing the job to execute') 31 | 32 | # Options for controlling the amount of information printed to the console 33 | # By default a moderate level of information is printed; you can either 34 | # ask for less (quiet), more (verbose), or much more (debug) 35 | group = parser.add_mutually_exclusive_group() 36 | group.add_argument('-d', '--debug', action='store_true', help='print debug information') 37 | group.add_argument('-q', '--quiet', action='store_true', help='only print warnings and errors') 38 | 39 | args = parser.parse_args(command_line_args) 40 | args.file = args.file[0] 41 | 42 | return args 43 | 44 | 45 | def main() -> None: 46 | """ 47 | The main T3 executable function. 48 | """ 49 | args = parse_command_line_arguments() 50 | input_file = args.file 51 | project_directory = os.path.abspath(os.path.dirname(args.file)) 52 | input_dict = read_yaml_file(path=input_file) 53 | if 'project' not in list(input_dict.keys()): 54 | raise ValueError('A project name must be provided.') 55 | 56 | verbose = 20 57 | if args.debug: 58 | verbose = 10 59 | elif args.quiet: 60 | verbose = 30 61 | input_dict['verbose'] = input_dict['verbose'] if 'verbose' in input_dict else verbose 62 | if 'project_directory' not in input_dict or not input_dict['project_directory']: 63 | input_dict['project_directory'] = project_directory 64 | 65 | # check that RMG and ARC are available 66 | check_dependencies() 67 | 68 | t3_object = T3(**input_dict) 69 | t3_object.execute() 70 | 71 | 72 | if __name__ == '__main__': 73 | main() 74 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | token: 788d104c-5bc4-4986-8cfd-0d79930d97e1 3 | bot: "codecov-io" 4 | ci: 5 | - "travis.org" 6 | require_ci_to_pass: yes 7 | coverage: 8 | range: 0..100 9 | round: nearest 10 | percision: 2 11 | ignore: 12 | - tests/**/* 13 | comment: 14 | layout: "reach, diff, flags, files" 15 | require_changes: false 16 | branches: main 17 | -------------------------------------------------------------------------------- /data/libraries.yml: -------------------------------------------------------------------------------- 1 | # Recommended RMG libraries per application 2 | 3 | primary: 4 | thermo: 5 | - primaryThermoLibrary 6 | - BurkeH2O2 7 | - Spiekermann_refining_elementary_reactions 8 | - thermo_DFT_CCSDTF12_BAC 9 | - DFT_QCI_thermo 10 | - CBS_QB3_1dHR 11 | kinetics: 12 | - name: primaryH2O2 13 | seed: true 14 | 15 | nitrogen: 16 | thermo: 17 | - NH3 18 | - NitrogenCurran 19 | - CHON_G4 20 | - CN 21 | - NOx2018 22 | - name: primaryNS 23 | credence: low 24 | - name: CHN 25 | credence: low 26 | - name: CHON 27 | credence: low 28 | - name: BurcatNS 29 | credence: low 30 | kinetics: 31 | - primaryNitrogenLibrary 32 | - HydrazinePDep 33 | - Ethylamine 34 | 35 | sulfur: 36 | thermo: 37 | - name: primaryNS 38 | credence: low 39 | - name: SulfurGlarborgH2S 40 | credence: low 41 | - name: SulfurGlarborgBozzeli 42 | credence: low 43 | - name: BurcatNS 44 | credence: low 45 | kinetics: 46 | - primarySulfurLibrary 47 | - Sulfur/DMDS 48 | - Sulfur/DMS 49 | 50 | combustion: 51 | thermo: 52 | - FFCM1(-) 53 | - NOx2018 54 | - name: CHO 55 | credence: low 56 | kinetics: 57 | - FFCM1(-) 58 | - 2006_Joshi_OH_CO 59 | - 2005_Senosiain_OH_C2H2 60 | - NOx2018 61 | 62 | CH_pyrolysis: 63 | thermo: 64 | - NOx2018 65 | - Butadiene_Dimerization 66 | - C10H11 67 | - s3_5_7_ane 68 | - Fulvene_H 69 | - naphthalene_H 70 | - vinylCPD_H 71 | - Lai_Hexylbenzene 72 | - Narayanaswamy 73 | - SABIC_aromatics_1dHR_extended 74 | - SABIC_aromatics_1dHR 75 | - SABIC_aromatics 76 | - heavy_oil_ccsdtf12_1dHR 77 | - bio_oil 78 | - Chernov 79 | - CurranPentane 80 | - Klippenstein_Glarborg2016 81 | - name: CH 82 | credence: low 83 | kinetics: 84 | - 2001_Tokmakov_H_Toluene_to_CH3_Benzene 85 | - 2003_Miller_Propargyl_Recomb_High_P 86 | - 2009_Sharma_C5H5_CH3_highP 87 | - 2015_Buras_C2H3_C4H6_highP 88 | - Butadiene_Dimerization 89 | - C10H11 90 | - C12H11_pdep 91 | - C2H2_init 92 | - C6H5_C4H4_Mebel 93 | - Fulvene_H 94 | - Mebel_Naphthyl 95 | - Mebel_C6H5_C2H2 96 | - biCPD_H_shift 97 | - c-C5H5_CH3_Sharma 98 | - fascella 99 | - kislovB 100 | - naphthalene_H 101 | - vinylCPD_H 102 | - First_to_Second_Aromatic_Ring/2005_Ismail_C6H5_C4H6_highP 103 | - First_to_Second_Aromatic_Ring/2012_Matsugi_C3H3_C7H7_highP 104 | - First_to_Second_Aromatic_Ring/2016_Mebel_C10H9_highP 105 | - First_to_Second_Aromatic_Ring/2016_Mebel_C9H9_highP 106 | - First_to_Second_Aromatic_Ring/2016_Mebel_Indene_CH3_highP 107 | - First_to_Second_Aromatic_Ring/2017_Buras_C6H5_C3H6_highP 108 | - First_to_Second_Aromatic_Ring/2017_Mebel_C6H4C2H_C2H2_highP 109 | - First_to_Second_Aromatic_Ring/2017_Mebel_C6H5C2H2_C2H2_highP 110 | - First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C2H2_highP 111 | - First_to_Second_Aromatic_Ring/2017_Mebel_C6H5_C4H4_highP 112 | - First_to_Second_Aromatic_Ring/phenyl_diacetylene_effective 113 | - Aromatics_high_pressure/C10H10_1 114 | - Aromatics_high_pressure/C10H10_2 115 | - Aromatics_high_pressure/C10H10_H_abstraction 116 | - Aromatics_high_pressure/C10H11_1 117 | - Aromatics_high_pressure/C10H11_2 118 | - Aromatics_high_pressure/C10H11_3 119 | - Aromatics_high_pressure/C10H11_4 120 | - Aromatics_high_pressure/C10H7 121 | - Aromatics_high_pressure/C10H8_H_abstraction_H_recomb 122 | - Aromatics_high_pressure/C10H9_1 123 | - Aromatics_high_pressure/C10H9_2 124 | - Aromatics_high_pressure/C10H9_3 125 | - Aromatics_high_pressure/C10H9_4 126 | - Aromatics_high_pressure/C12H10_1 127 | - Aromatics_high_pressure/C12H10_2 128 | - Aromatics_high_pressure/C12H10_H_abstraction 129 | - Aromatics_high_pressure/C12H11 130 | - Aromatics_high_pressure/C12H8_H_abstraction 131 | - Aromatics_high_pressure/C12H9 132 | - Aromatics_high_pressure/C14H10_H_abstraction_H_recomb 133 | - Aromatics_high_pressure/C14H11_1 134 | - Aromatics_high_pressure/C14H11_2 135 | - Aromatics_high_pressure/C14H11_3 136 | - Aromatics_high_pressure/C14H11_4 137 | - Aromatics_high_pressure/C14H9 138 | - Aromatics_high_pressure/C16H11 139 | - Aromatics_high_pressure/C7H8 140 | - Aromatics_high_pressure/C7H8_H_abstraction 141 | - Aromatics_high_pressure/C7H9 142 | - Aromatics_high_pressure/C8H6_H_abstraction 143 | - Aromatics_high_pressure/C8H7 144 | - Aromatics_high_pressure/C8H8_H_abstraction 145 | - Aromatics_high_pressure/C8H9 146 | - Aromatics_high_pressure/C9H10_H_abstraction 147 | - Aromatics_high_pressure/C9H11 148 | - Aromatics_high_pressure/C9H7 149 | - Aromatics_high_pressure/C9H8_1 150 | - Aromatics_high_pressure/C9H8_2 151 | - Aromatics_high_pressure/C9H8_H_abstraction 152 | - Aromatics_high_pressure/C9H9_1 153 | - Aromatics_high_pressure/C9H9_2 154 | 155 | -------------------------------------------------------------------------------- /devtools/ARCHIVED_install_RMS_v032.jl: -------------------------------------------------------------------------------- 1 | # Install RMS v0.3.2 2 | import Pkg 3 | Pkg.add(Pkg.PackageSpec(url="https://github.com/ReactionMechanismGenerator/ReactionMechanismSimulator.jl", rev="v0.3.2")) 4 | -------------------------------------------------------------------------------- /devtools/Dockerfile_rmgpy: -------------------------------------------------------------------------------- 1 | # RMG Dockerfile 2 | # The parent image is the base image that the Dockerfile builds upon. 3 | # The RMG installation instructions suggest Anaconda for installation by source, however, we use micromamba for the Docker image due to its smaller size and less overhead. 4 | # https://hub.docker.com/layers/mambaorg/micromamba/1.4.3-jammy/images/sha256-0c7c97be938c5522dcb9e1737bfa4499c53f6cf9e32e53897607a57ba8b148d5?context=explore 5 | # We are using the sha256 hash to ensure that the image is not updated without our knowledge. It considered best practice to use the sha256 hash 6 | FROM --platform=linux/amd64 mambaorg/micromamba@sha256:0c7c97be938c5522dcb9e1737bfa4499c53f6cf9e32e53897607a57ba8b148d5 7 | 8 | # Set the user as root 9 | USER root 10 | 11 | # Create a login user named rmguser 12 | ARG NEW_MAMBA_USER=rmguser 13 | ARG NEW_MAMBA_USER_ID=1000 14 | ARG NEW_MAMBA_USER_GID=1000 15 | RUN usermod "--login=${NEW_MAMBA_USER}" "--home=/home/${NEW_MAMBA_USER}" \ 16 | --move-home "-u ${NEW_MAMBA_USER_ID}" "${MAMBA_USER}" && \ 17 | groupmod "--new-name=${NEW_MAMBA_USER}" \ 18 | "-g ${NEW_MAMBA_USER_GID}" "${MAMBA_USER}" && \ 19 | echo "${NEW_MAMBA_USER}" > "/etc/arg_mamba_user" && \ 20 | : 21 | 22 | # Set the environment variables 23 | ARG MAMBA_ROOT_PREFIX=/opt/conda 24 | ENV MAMBA_USER=$NEW_MAMBA_USER 25 | ENV BASE=$MAMBA_ROOT_PREFIX 26 | 27 | # Install system dependencies 28 | # 29 | # List of deps and why they are needed: 30 | # - make, gcc, g++ for building RMG 31 | # - git for downloading RMG respoitories 32 | # - wget for downloading conda install script 33 | # - libxrender1 required by RDKit 34 | # Clean up the apt cache to reduce the size of the image 35 | RUN apt-get update && apt-get install -y \ 36 | git \ 37 | gcc \ 38 | g++ \ 39 | make \ 40 | libgomp1\ 41 | libxrender1 \ 42 | sudo \ 43 | && apt-get clean \ 44 | && apt-get autoclean \ 45 | && apt-get autoremove -y \ 46 | && rm -rf /var/lib/apt/lists/*\ 47 | && echo "${NEW_MAMBA_USER} ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers 48 | # Change user to the non-root user 49 | USER $MAMBA_USER 50 | 51 | # Make directory for RMG-Py and RMG-database 52 | RUN mkdir -p /home/rmguser/Code 53 | 54 | # Change working directory to Code 55 | WORKDIR /home/rmguser/Code 56 | 57 | # Clone the RMG base and database repositories. The pulled branches are only the main branches. 58 | RUN git clone -b main https://github.com/ReactionMechanismGenerator/RMG-Py.git \ 59 | && git clone -b main https://github.com/ReactionMechanismGenerator/RMG-database.git 60 | 61 | # cd into RMG-Py 62 | WORKDIR /home/rmguser/Code/RMG-Py 63 | 64 | # Install RMG-Py and then clean up the micromamba cache 65 | RUN micromamba create -y -f environment.yml && \ 66 | micromamba install -n rmg_env -c conda-forge conda && \ 67 | micromamba clean --all -f -y 68 | 69 | # Activate the RMG environment 70 | ARG MAMBA_DOCKERFILE_ACTIVATE=1 71 | ENV ENV_NAME=rmg_env 72 | 73 | # Set environment variables 74 | # These need to be set in the Dockerfile so that they are available to the build process 75 | ENV PATH /opt/conda/envs/rmg_env/bin:$PATH 76 | ENV PYTHONPATH /home/rmguser/Code/RMG-Py:$PYTHONPATH 77 | ENV PATH /home/rmguser/Code/RMG-Py:$PATH 78 | 79 | # Build RMG 80 | RUN make \ 81 | && echo "export PYTHONPATH=/home/rmguser/Code/RMG-Py" >> ~/.bashrc \ 82 | && echo "export PATH=/home/rmguser/Code/RMG-Py:$PATH" >> ~/.bashrc 83 | 84 | # Create the link between Julia and RMG-Py. A symbolic link is created between Python-JL and Python. 85 | # We do not use the command in Julia 'using ReactionMechanismSimulator' because the command is only for determining if the package is installed. 86 | # The command does not actually install the package but instead increases the build time, therefore not required. 87 | # Install RMS 88 | # The extra arguments are required to install PyCall and RMS in this Dockerfile. Will not work without them. 89 | # Final command is to compile the RMS during Docker build - This will reduce the time it takes to run RMS for the first time 90 | ENV JULIA_CPU_TARGET="x86-64,haswell,skylake,broadwell,znver1,znver2,znver3,cascadelake,icelake-client,cooperlake,generic,native" 91 | RUN touch /opt/conda/envs/rmg_env/condarc-julia.yml 92 | RUN CONDA_JL_CONDA_EXE=/bin/micromamba julia -e 'ENV["CONDA_JL_CONDA_EXE"]="/opt/conda/envs/rmg_env/bin/conda";using Pkg;Pkg.add(PackageSpec(name="PyCall", rev="master")); Pkg.build("PyCall"); Pkg.add(PackageSpec(name="ReactionMechanismSimulator", rev="main"))' \ 93 | && python -c "import julia; julia.install(); import diffeqpy; diffeqpy.install()" \ 94 | && python-jl -c "from pyrms import rms" 95 | 96 | # Add alias to bashrc - rmge to activate the environment 97 | # These commands are not necessary for the Docker image to run, but they are useful for the user 98 | RUN echo "alias rmge='micromamba activate rmg_env'" >> ~/.bashrc \ 99 | && echo "alias rmg='python-jl /home/rmguser/Code/RMG/rmg.py input.py'" >> ~/.bashrc \ 100 | && echo "alias deact='micromamba deactivate'" >> ~/.bashrc \ 101 | && echo "export rmgpy_path='/home/rmguser/Code/RMG-Py/'" >> ~/.bashrc \ 102 | && echo "export rmgdb_path='/home/rmguser/Code/RMG-database/'" >> ~/.bashrc \ 103 | && echo "alias rmgcode='cd \$rmgpy_path'" >> ~/.bashrc \ 104 | && echo "alias rmgdb='cd \$rmgdb_path'" >> ~/.bashrc \ 105 | && echo "alias conda='micromamba'" >> ~/.bashrc \ 106 | && echo "alias mamba='micromamba'" >> ~/.bashrc 107 | 108 | # Set the entrypoint to bash 109 | ENTRYPOINT ["/bin/bash", "--login"] 110 | -------------------------------------------------------------------------------- /devtools/install_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -l 2 | 3 | # Check if Micromamba is installed 4 | if [ -x "$(command -v micromamba)" ]; then 5 | echo "Micromamba is installed." 6 | COMMAND_PKG=micromamba 7 | # Check if Mamba is installed 8 | elif [ -x "$(command -v mamba)" ]; then 9 | echo "Mamba is installed." 10 | COMMAND_PKG=mamba 11 | # Check if Conda is installed 12 | elif [ -x "$(command -v conda)" ]; then 13 | echo "Conda is installed." 14 | COMMAND_PKG=conda 15 | else 16 | echo "Micromamba, Mamba, and Conda are not installed. Please download and install one of them - we strongly recommend Micromamba or Mamba." 17 | exit 1 18 | fi 19 | 20 | # Set up Conda/Micromamba environment 21 | if [ "$COMMAND_PKG" == "micromamba" ]; then 22 | eval "$(micromamba shell hook --shell=bash)" 23 | micromamba activate base 24 | BASE=$MAMBA_ROOT_PREFIX 25 | # shellcheck source=/dev/null 26 | source "$BASE/etc/profile.d/micromamba.sh" 27 | else 28 | BASE=$(conda info --base) 29 | # shellcheck source=/dev/null 30 | source "$BASE/etc/profile.d/conda.sh" 31 | fi 32 | 33 | # Temporarily change directory to $HOME to install software 34 | pushd . 35 | cd .. 36 | 37 | if [ -d "./RMG-database" ]; then 38 | cd RMG-database || exit 39 | git pull https://github.com/ReactionMechanismGenerator/RMG-database 40 | cd .. 41 | else 42 | git clone https://github.com/ReactionMechanismGenerator/RMG-database 43 | fi; 44 | 45 | if [ -d "./RMG-Py" ]; then 46 | cd RMG-Py || exit 47 | git pull https://github.com/ReactionMechanismGenerator/RMG-Py 48 | else 49 | git clone https://github.com/ReactionMechanismGenerator/RMG-Py 50 | cd RMG-Py || exit 51 | fi; 52 | 53 | echo "export PYTHONPATH=$PYTHONPATH:$(pwd)" >> ~/.bashrc 54 | echo "export PATH=$PATH:$(pwd)" >> ~/.bashrc 55 | PYTHONPATH=$PYTHONPATH:$(pwd) 56 | export PYTHONPATH 57 | PATH=$PATH:$(pwd) 58 | export PATH 59 | # shellcheck source=~/.bashrc 60 | source ~/.bashrc 61 | 62 | #Creating rmg_env environment (or updating if it already exists) 63 | if { $COMMAND_PKG env list | grep 'rmg_env'; } >/dev/null 2>&1; then 64 | $COMMAND_PKG env update -n rmg_env -f environment.yml 65 | else 66 | $COMMAND_PKG env create -f environment.yml 67 | fi; 68 | 69 | #Prior to activation of the environment, the LD_LIBRARY_PATH needs to be set as an environmnet variable when rmg_env is activated. 70 | #This exporting and unsetting will solve the RMS installation during the Julia compile and also when the environment is deactivated 71 | #the original LD_LIBRARY_PATH is set. 72 | echo "export OLD_LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >> "$BASE/envs/rmg_env/etc/conda/activate.d/env_vars.sh" 73 | echo "export LD_LIBRARY_PATH=$BASE/envs/rmg_env/lib:$LD_LIBRARY_PATH" >> "$BASE/envs/rmg_env/etc/conda/activate.d/env_vars.sh" 74 | echo "export LD_LIBRARY_PATH=${OLD_LD_LIBRARY_PATH}" >> "$BASE/envs/rmg_env/etc/conda/deactivate.d/env_vars.sh" 75 | echo "unset OLD_LD_LIBRARY_PATH" >> "$BASE/envs/rmg_env/etc/conda/deactivate.d/env_vars.sh" 76 | 77 | #Active rmg_env environment 78 | if [ "$COMMAND_PKG" == "micromamba" ]; then 79 | micromamba activate rmg_env 80 | else 81 | conda activate rmg_env 82 | fi 83 | 84 | #Compile RMG-Py 85 | make 86 | #Update pyjulia to the latest version 87 | $COMMAND_PKG update pyjulia -c conda-forge -y 88 | 89 | #Ensure that added paths etc. are set and then reactivate rmg_env 90 | . ~/.bashrc 91 | if [ "$COMMAND_PKG" == "micromamba" ]; then 92 | micromamba activate rmg_env 93 | else 94 | conda activate rmg_env 95 | fi 96 | 97 | ### Install python + julia connection and compile RMS 98 | # 99 | #This code here is for updating julia if ever required: $(julia -e 'using Pkg; Pkg.add("UpdateJulia"); using UpdateJulia; update_julia()') 100 | python -c "import julia; julia.install(); import diffeqpy; diffeqpy.install()" 101 | julia -e 'using Pkg; Pkg.add(PackageSpec(name="ReactionMechanismSimulator",rev="main"));using ReactionMechanismSimulator' 102 | 103 | # check that Python and Julia are being accessed from the rmg_env 104 | echo checking which python... 105 | which python 106 | echo checking which julia... 107 | which julia 108 | echo linking python-jl to python... 109 | ln -sfn $(which python-jl) $(which python) 110 | 111 | if [ "$COMMAND_PKG" == "micromamba" ]; then 112 | micromamba activate t3_env 113 | else 114 | conda activate t3_env 115 | fi 116 | 117 | cd .. 118 | if [ -d "./ARC" ]; then 119 | cd ARC || exit 120 | git pull https://github.com/ReactionMechanismGenerator/ARC 121 | else 122 | git clone https://github.com/ReactionMechanismGenerator/ARC 123 | cd ARC || exit 124 | fi; 125 | 126 | PYTHONPATH=$PYTHONPATH:$(pwd) 127 | export PYTHONPATH 128 | echo "export PYTHONPATH=$PYTHONPATH:$(pwd)" >> ~/.bashrc 129 | if { $COMMAND_PKG env list | grep 'arc_env'; } >/dev/null 2>&1; then 130 | $COMMAND_PKG env update -n arc_env -f environment.yml 131 | else 132 | $COMMAND_PKG env create -f environment.yml 133 | fi; 134 | 135 | if [ "$COMMAND_PKG" == "micromamba" ]; then 136 | micromamba activate arc_env 137 | else 138 | conda activate arc_env 139 | fi 140 | 141 | make install-all 142 | 143 | conda deactivate 144 | 145 | # Restore original directory 146 | popd || exit 147 | -------------------------------------------------------------------------------- /devtools/install_arc.sh: -------------------------------------------------------------------------------- 1 | # Properly configure the shell to use 'conda activate'. 2 | CONDA_BASE=$(conda info --base) 3 | source $CONDA_BASE/etc/profile.d/conda.sh 4 | ###Check if Mamba is installed#### 5 | echo "Determining whether Mamba is installed..." 6 | if [ $(which mamba) ] >/dev/null 2>&1; then 7 | echo "Mamba found!" 8 | COMMAND_PKG=mamba 9 | else 10 | echo "Reverting to Conda..." 11 | COMMAND_PKG=conda 12 | fi 13 | 14 | 15 | 16 | 17 | 18 | # Temporarily change directory to $HOME to install software 19 | pushd . 20 | 21 | cd .. 22 | if [ -d "./RMG-database" ]; then 23 | cd RMG-database 24 | git pull https://github.com/ReactionMechanismGenerator/RMG-database 25 | cd .. 26 | else 27 | git clone https://github.com/ReactionMechanismGenerator/RMG-database 28 | fi; 29 | 30 | if [ -d "./RMG-Py" ]; then 31 | cd RMG-Py 32 | git pull https://github.com/ReactionMechanismGenerator/RMG-Py 33 | else 34 | git clone https://github.com/ReactionMechanismGenerator/RMG-Py 35 | cd RMG-Py 36 | fi; 37 | 38 | 39 | export PYTHONPATH=$PYTHONPATH:$(pwd) 40 | echo "export PYTHONPATH=$PYTHONPATH:$(pwd)" >> ~/.bashrc 41 | 42 | 43 | $COMMAND_PKG env update -n rmg_env -f environment.yml 44 | conda activate rmg_env 45 | make 46 | python -c "import julia; julia.install(); import diffeqpy; diffeqpy.install()" 47 | julia -e 'using Pkg; Pkg.add(PackageSpec(name="ReactionMechanismSimulator",rev="main")); Pkg.build("ReactionMechanismSimulator");' 48 | conda deactivate 49 | 50 | cd .. 51 | git clone https://github.com/ReactionMechanismGenerator/ARC 52 | cd ARC 53 | export PYTHONPATH=$PYTHONPATH:$(pwd) 54 | echo "export PYTHONPATH=$PYTHONPATH:$(pwd)" >> ~/.bashrc 55 | if { conda env list | grep 'arc_env'; } >/dev/null 2>&1; then 56 | $COMMAND_PKG env update -n arc_env -f environment.yml 57 | else 58 | $COMMAND_PKG env create -f environment.yml 59 | fi; 60 | conda activate arc_env 61 | #make install-all 62 | ###Temp### To be used until ARC repo install is properly updated 63 | $COMMAND_PKG create -n xtb_env python=3.7 -y 64 | conda activate xtb_env 65 | $COMMAND_PKG install -c conda-forge xtb -y 66 | $COMMAND_PKG install -c anaconda pyyaml -y 67 | ########## 68 | 69 | conda deactivate 70 | 71 | # Restore original directory 72 | popd || exit 73 | -------------------------------------------------------------------------------- /devtools/install_pycall.jl: -------------------------------------------------------------------------------- 1 | # Install PyCall 2 | import Pkg 3 | Pkg.add("PyCall") 4 | -------------------------------------------------------------------------------- /devtools/install_pyrms.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -l 2 | 3 | # Check if Micromamba is installed 4 | if [ -x "$(command -v micromamba)" ]; then 5 | echo "Micromamba is installed." 6 | COMMAND_PKG=micromamba 7 | # Check if Mamba is installed 8 | elif [ -x "$(command -v mamba)" ]; then 9 | echo "Mamba is installed." 10 | COMMAND_PKG=mamba 11 | # Check if Conda is installed 12 | elif [ -x "$(command -v conda)" ]; then 13 | echo "Conda is installed." 14 | COMMAND_PKG=conda 15 | else 16 | echo "Micromamba, Mamba, and Conda are not installed. Please download and install one of them - we strongly recommend Micromamba or Mamba." 17 | exit 1 18 | fi 19 | 20 | # Set up Conda/Micromamba environment 21 | if [ "$COMMAND_PKG" == "micromamba" ]; then 22 | eval "$(micromamba shell hook --shell=bash)" 23 | micromamba activate base 24 | BASE=$MAMBA_ROOT_PREFIX 25 | # shellcheck source=/dev/null 26 | source "$BASE/etc/profile.d/micromamba.sh" 27 | else 28 | BASE=$(conda info --base) 29 | # shellcheck source=/dev/null 30 | source "$BASE/etc/profile.d/conda.sh" 31 | fi 32 | 33 | #Prior to activation of the environment, the LD_LIBRARY_PATH needs to be set as an environmnet variable when rmg_env is activated. 34 | #This exporting and unsetting will solve the RMS installation during the Julia compile and also when the environment is deactivated 35 | #the original LD_LIBRARY_PATH is set. 36 | echo "export OLD_LD_LIBRARY_PATH=${LD_LIBRARY_PATH}" >> "$BASE/envs/rmg_env/etc/conda/activate.d/env_vars.sh" 37 | echo "export LD_LIBRARY_PATH=$BASE/envs/rmg_env/lib:$LD_LIBRARY_PATH" >> "$BASE/envs/rmg_env/etc/conda/activate.d/env_vars.sh" 38 | echo "export LD_LIBRARY_PATH=${OLD_LD_LIBRARY_PATH}" >> "$BASE/envs/rmg_env/etc/conda/deactivate.d/env_vars.sh" 39 | echo "unset OLD_LD_LIBRARY_PATH" >> "$BASE/envs/rmg_env/etc/conda/deactivate.d/env_vars.sh" 40 | 41 | #Active rmg_env environment 42 | if [ "$COMMAND_PKG" == "micromamba" ]; then 43 | micromamba activate rmg_env 44 | else 45 | conda activate rmg_env 46 | fi 47 | 48 | #Ensure that added paths etc. are set and then reactivate rmg_env 49 | . ~/.bashrc 50 | if [ "$COMMAND_PKG" == "micromamba" ]; then 51 | micromamba activate rmg_env 52 | else 53 | conda activate rmg_env 54 | fi 55 | 56 | 57 | 58 | ### Install python + julia connection and compile RMS 59 | echo linking python-jl to python... 60 | ln -sfn $(which python-jl) $(which python) 61 | # 62 | #This code here is for updating julia if ever required: $(julia -e 'using Pkg; Pkg.add("UpdateJulia"); using UpdateJulia; update_julia()') 63 | python -c "import julia; julia.install(); import diffeqpy; diffeqpy.install()" 64 | julia -e 'using Pkg; Pkg.add(PackageSpec(name="ReactionMechanismSimulator",rev="main"));using ReactionMechanismSimulator' 65 | -------------------------------------------------------------------------------- /docs/T3-circle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/docs/T3-circle.gif -------------------------------------------------------------------------------- /docs/T3-circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/docs/T3-circle.png -------------------------------------------------------------------------------- /docs/T3_logo_small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/docs/T3_logo_small.gif -------------------------------------------------------------------------------- /docs/cite.md: -------------------------------------------------------------------------------- 1 | # How to cite 2 | 3 | Text form: 4 | 5 | C. Pieters, K. Kaplan, K.A. Spiekermann, W.H. Green, A. Grinberg Dana, 6 | The Tandem Tool (T3) for automated chemical kinetic model development, 7 | version 0.1.0, source code: https://github.com/ReactionMechanismGenerator/T3 8 | 9 | LaTeX form: 10 | 11 | @misc{T3, 12 | author = {C. Pieters, K. Kaplan, K.A. Spiekermann, W.H. Green, A. Grinberg Dana,}, 13 | title = {The Tandem Tool (T3) for automated chemical kinetic model development. https://github.com/ReactionMechanismGenerator/T3, Version 0.1.0}, 14 | year = {2023}, 15 | howpublished = {\url{https://github.com/ReactionMechanismGenerator/T3}}, 16 | } 17 | -------------------------------------------------------------------------------- /docs/contribute.md: -------------------------------------------------------------------------------- 1 | # Contribute 2 | 3 | We use T3 to facilitate our research and have made it available 4 | as a benefit to the community in the hopes that others may find it useful as well. 5 | 6 | We welcome contributions from the community. 7 | Please see the 8 | 9 | contributor guidelines 10 | on T3's GitHub page, as well as the 11 | 12 | Code of Conduct. 13 | 14 | It is recommended to first open an issue on GitHub, 15 | notifying the developers on a bug you are trying to fix 16 | or a feature you plan to implement (see our 17 | road map) 18 | to avoid duplicate work. 19 | -------------------------------------------------------------------------------- /docs/credits.md: -------------------------------------------------------------------------------- 1 | # Credits 2 | 3 | T3 is developed at the 4 | Dana Research Group (Technion) 5 | and at the Green Research Group (MIT). 6 | 7 | T3's contributors are: 8 | 9 | - Dr. Alon Grinberg Dana (leading developer) 10 | - Kevin Spiekermann 11 | -------------------------------------------------------------------------------- /docs/css/custom.css: -------------------------------------------------------------------------------- 1 | a.external-link::after { 2 | /* \00A0 is a non-breaking space 3 | to make the mark be on the same line as the link 4 | */ 5 | content: "\00A0[↪]"; 6 | } 7 | 8 | a.internal-link::after { 9 | /* \00A0 is a non-breaking space 10 | to make the mark be on the same line as the link 11 | */ 12 | content: "\00A0↪"; 13 | } 14 | 15 | /* Give space to lower icons so Gitter chat doesn't get on top of them */ 16 | .md-footer-meta { 17 | padding-bottom: 2em; 18 | } 19 | -------------------------------------------------------------------------------- /docs/css/termynal.css: -------------------------------------------------------------------------------- 1 | /** 2 | * termynal.js 3 | * 4 | * @author Ines Montani 5 | * @version 0.0.1 6 | * @license MIT 7 | */ 8 | 9 | :root { 10 | --color-bg: #252a33; 11 | --color-text: #eee; 12 | --color-text-subtle: #a2a2a2; 13 | } 14 | 15 | [data-termynal] { 16 | width: 750px; 17 | max-width: 100%; 18 | background: var(--color-bg); 19 | color: var(--color-text); 20 | font-size: 18px; 21 | /* font-family: 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; */ 22 | font-family: 'Roboto Mono', 'Fira Mono', Consolas, Menlo, Monaco, 'Courier New', Courier, monospace; 23 | border-radius: 4px; 24 | padding: 75px 45px 35px; 25 | position: relative; 26 | -webkit-box-sizing: border-box; 27 | box-sizing: border-box; 28 | } 29 | 30 | [data-termynal]:before { 31 | content: ''; 32 | position: absolute; 33 | top: 15px; 34 | left: 15px; 35 | display: inline-block; 36 | width: 15px; 37 | height: 15px; 38 | border-radius: 50%; 39 | /* A little hack to display the window buttons in one pseudo element. */ 40 | background: #d9515d; 41 | -webkit-box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; 42 | box-shadow: 25px 0 0 #f4c025, 50px 0 0 #3ec930; 43 | } 44 | 45 | [data-termynal]:after { 46 | content: 'bash'; 47 | position: absolute; 48 | color: var(--color-text-subtle); 49 | top: 5px; 50 | left: 0; 51 | width: 100%; 52 | text-align: center; 53 | } 54 | 55 | a[data-terminal-control] { 56 | text-align: right; 57 | display: block; 58 | color: #aebbff; 59 | } 60 | 61 | [data-ty] { 62 | display: block; 63 | line-height: 2; 64 | } 65 | 66 | [data-ty]:before { 67 | /* Set up defaults and ensure empty lines are displayed. */ 68 | content: ''; 69 | display: inline-block; 70 | vertical-align: middle; 71 | } 72 | 73 | [data-ty="input"]:before, 74 | [data-ty-prompt]:before { 75 | margin-right: 0.75em; 76 | color: var(--color-text-subtle); 77 | } 78 | 79 | [data-ty="input"]:before { 80 | content: '$'; 81 | } 82 | 83 | [data-ty][data-ty-prompt]:before { 84 | content: attr(data-ty-prompt); 85 | } 86 | 87 | [data-ty-cursor]:after { 88 | content: attr(data-ty-cursor); 89 | font-family: monospace; 90 | margin-left: 0.5em; 91 | -webkit-animation: blink 1s infinite; 92 | animation: blink 1s infinite; 93 | } 94 | 95 | 96 | /* Cursor animation */ 97 | 98 | @-webkit-keyframes blink { 99 | 50% { 100 | opacity: 0; 101 | } 102 | } 103 | 104 | @keyframes blink { 105 | 50% { 106 | opacity: 0; 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 |

2 | 3 | T3 4 |

5 |

6 | The Tandem Tool for automated chemical kinetic model development 7 |

8 |

9 | 10 | Release 11 | 12 | Build Status 13 | 14 | Language grade: Python 15 | 16 | 17 | Coverage 18 | 19 | 20 | MIT license 21 | 22 | 23 | Python 24 | 25 |

26 | 27 | --- 28 | 29 | **Documentation**: [T3 Documentation](https://reactionmechanismgenerator.github.io/T3/) 30 | 31 | 32 | **Source Code**: [T3 Source](https://github.com/ReactionMechanismGenerator/T3) 33 | 34 | --- 35 | 36 | > **Note:** 37 | T3 is currently under intense development. 38 | Features described in these documentation pages 39 | which are still not implemented in the code will 40 | be marked with an asterisk (*). 41 | 42 | ## General 43 | 44 | T3 is a tool for automatically generating refined kinetic models. 45 | 46 | The key features are: 47 | 48 | * **Convenient**: A single universal input file with an equivalent API, 49 | controlling all engines. 50 | * **Flexible**: Supports all features of RMG and ARC, while maintaining 51 | reasonable defaults for simplicity. 52 | * **Structured**: All outputs from all iterations are organized in an 53 | intuitive folder tree. 54 | * **Easy**: Designed to be easy to use and learn. 55 | * **Robust**: Captures lower-level exceptions, attempts to troubleshoot. 56 | * **Restartable**: Has a convenient restart feature that's being triggered 57 | by identifying existing iteration outputs. 58 | 59 | ## Principal workflow 60 | 61 |

62 | T3 scheme 63 |

64 | 65 | At it's core, T3 iteratively calls 66 | RMG 67 | and an automated QM tool 68 | (currently supporting only 69 | ARC) 70 | to generate a kinetic model and refine it, respectively. 71 | The maximal number of iterations along with various control parameters 72 | can be determined by the user. 73 | Calculated thermodynamic properties and rate coefficients can optionally 74 | be uploaded to the community cloud, 75 | TCKDB*. 76 | T3 also queries TCKDB before instructing the automated QM tool to perform calculations. 77 | 78 | ## Intended audience 79 | 80 | T3 is intended to be used by individuals with prior knowledge in chemical kinetic modeling, 81 | and some experience in electronic structure (quantum chemical) calculations. 82 | This documentation does not intend to provide advice for which levels of theory 83 | should be used for particular systems although examples with specific levels of theory 84 | are given. 85 | 86 | ## Requirements 87 | 88 | Python 3.7+ 89 | 90 | T3 stands on the shoulders of giants: 91 | 92 | * RMG for model generation. 93 | * ARC 94 | for automating electronic structure calculations. 95 | 96 | ## License 97 | 98 | This project is licensed under the terms of the MIT license. 99 | -------------------------------------------------------------------------------- /docs/installation.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | 3 | T3 was only tested on *Linux (Ubuntu_ 22.04.1 LTS)* and *MacOS*. 4 | We don't expect it to work on Windows. 5 | 6 | It can be installed on a server, as well as on your local desktop / laptop, in order to submit jobs to the server/s. 7 | 8 | ## Package Manager and Cloning from Github 9 | 10 | ### Unix-like platforms 11 | 12 | #### 1. Install `curl` or `wget` 13 | 14 | You can install either package. 15 | 16 | ##### *Option 1* 17 | 18 | ``` bash 19 | sudo apt install curl 20 | ``` 21 | 22 | ##### *Option 2* 23 | 24 | ``` bash 25 | sudo apt install wget 26 | ``` 27 | 28 | #### 2. Install compiler 29 | 30 | - Ubuntu or Debian 31 | 32 | ``` bash 33 | sudo apt install git gcc g++ make 34 | ``` 35 | 36 | - Fedora or Red Hat 37 | 38 | ``` bash 39 | sudo dnf install git gcc gcc-c++ make 40 | ``` 41 | 42 | #### 3. Download Python Package Manager 43 | 44 | ##### *Option 1* 45 | 46 | ``` bash 47 | curl -L -O "https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-$(uname)-$(uname -m).sh" 48 | bash Mambaforge-$(uname)-$(uname -m).sh 49 | ``` 50 | 51 | ##### *Option 2* 52 | 53 | ``` bash 54 | wget "https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-$(uname)-$(uname -m).sh" 55 | bash Mambaforge-$(uname)-$(uname -m).sh 56 | ``` 57 | 58 | #### 4. Clone T3 Repository 59 | 60 | Clone T3's repository by typing the following command in the desired folder (e.g., under ~/Code/): 61 | 62 | ``` bash 63 | git clone https://github.com/ReactionMechanismGenerator/T3.git 64 | ``` 65 | 66 | ## Setting up Path 67 | 68 | - To set up T3 to your local path in .bashrc, you have two options: 69 | 70 | ### Option 1 71 | 72 | Terminal Command (NOTE: Make sure to change "~/Path/to/T3/" accordingly"): 73 | 74 | ``` bash 75 | echo 'PYTHONPATH=$PYTHONPATH:~/Path/to/T3/' >> ~/.bashrc 76 | ``` 77 | 78 | ### Option 2 79 | 80 | Editing .bashrc directly (NOTE: Make sure to change "~/Path/to/T3/" accordingly"): 81 | 82 | - In terminal, enter the command: 83 | 84 | ``` bash 85 | sudo gedit ~/.bashrc 86 | ``` 87 | 88 | - Then in the opened file, on a new line, enter the following: 89 | 90 | ``` text 91 | export PYTHONPATH=$PYTHONPATH:~/Path/to/T3/ 92 | ``` 93 | 94 | ## Install dependencies 95 | 96 | T3 requires RMG-Py, RMG-databse and ARC to function correctly. In order to install the necessary dependencies, you can follow either option below. 97 | 98 | ### Option 1 99 | 100 | - Navigate to the T3 folder, depending on where you cloned it to. 101 | 102 | - Open a terminal in the T3 folder, and type the following: 103 | 104 | ``` bash 105 | make install all 106 | ``` 107 | 108 | > **Note**: This can take some time to finish. 109 | 110 | - You have now installed all the required dependencies. 111 | 112 | ### Option 2 113 | 114 | - Install the latest versions of RMG-Py and the RMG-database on the same machine where T3 is installed. Follow the instructions on [RMG's Documentation](http://reactionmechanismgenerator.github.io/RMG-Py/users/rmg/installation/anacondaDeveloper.html). 115 | - Make sure to install RMG's **developer version** which includes important recent features. Note that the installation instructions suggest Anaconda, but Mambaforge can be used in it's place. 116 | 117 | - Be sure to add RMG-Py to your PATH and PYTHONPATH as explained in the instructions. 118 | 119 | - Install the latest version of ARC on the same machine where T3 is installed. 120 | Follow the instructions on [ARC's documentation](https://reactionmechanismgenerator.github.io/ARC/installation.html) 121 | 122 | - Make sure to add ARC to your PATH and PYTHONPATH, as well as to define your servers as explained in ARC's documentation. 123 | 124 | - Create the Anaconda/Mambaforge environment for T3 by executing the following command in the T3 folder: 125 | 126 | ```bash 127 | $ mamba env create -f environment.yml 128 | 129 | INFO: Collecting package metadata (repodata.json): done 130 | INFO: Solving environment: done 131 | INFO: 132 | INFO: Downloading and Extracting Packages 133 | INFO: ... 134 | INFO: Preparing transaction: done 135 | INFO: Verifying transaction: done 136 | INFO: Executing transaction: done 137 | INFO: # 138 | INFO: # To activate this environment, use 139 | INFO: # 140 | INFO: # $ conda activate t3_env 141 | INFO: # 142 | INFO: # To deactivate an active environment, use 143 | INFO: # 144 | INFO: # $ conda deactivate 145 | ``` 146 | 147 | - Activate the T3 environment every time before running T3: 148 | 149 | ``` bash 150 | conda activate t3_env 151 | ``` 152 | 153 | ## Add T3 aliases to your .bashrc 154 | 155 | Some optional yet convenient aliases are listed below 156 | (make sure to change "/Path/to/T3/" accordingly). 157 | Add these to your ``.bashrc`` file, which can be edited by typing, e.g., ``sudo nano ~/.bashrc``: 158 | 159 | ```bash 160 | export t3_path=$HOME`/Path/to/T3' 161 | alias t3e='conda activate t3_env' 162 | alias t3='python $t3_path/T3.py input.yml' 163 | alias t3code='cd $t3_path' 164 | ``` 165 | 166 | Then, after sourcing ``.bashrc`` or restarting the terminal, 167 | simply typing ``t3e`` will activate the environment, 168 | typing ``t3code`` will change the directory into the T3 repository, 169 | and finally typing ``t3`` from any folder with 170 | a valid T3 input file will execute T3 in that folder. 171 | 172 | ## Updating T3 173 | 174 | The T3 repository is being updated frequently. 175 | Make sure to update your instance of T3 to enjoy new features 176 | and get recent bug fixes. To get the most recent developer version, 177 | execute the following commands (make sure to change ```~/Path/to/T3/``` accordingly: 178 | 179 | ``` bash 180 | cd ~/Path/to/T3/ 181 | git fetch origin 182 | git pull origin main 183 | ``` 184 | 185 | The above will update your **main** branch of T3. 186 | -------------------------------------------------------------------------------- /docs/licence.md: -------------------------------------------------------------------------------- 1 | # Licence 2 | 3 | T3 is distributed free of charge under the MIT license. 4 | 5 | 6 | MIT License 7 | 8 | Copyright (c) 2019-2020 Dana Research Group 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | -------------------------------------------------------------------------------- /docs/output.md: -------------------------------------------------------------------------------- 1 | # Output 2 | 3 | After running a Project, the local Project folder will contain the following directory tree 4 | (**bold** represents folders, *italics* represents files): 5 | 6 | - *t3.log*: Details of all project execution procedures. 7 | - **iteration_x**: 8 | - **RMG**: 9 | - *input.py*: The RMG input file for iteration x (automatically written by T3) 10 | - *RMG.log*: The RMG log file for iteration x. 11 | - Additional RMG files and folders 12 | - **ARC**: 13 | - *restart.yml*: The ARC restart file for iteration x. 14 | - *arc.log*: The ARC log file for iteration x. 15 | - **calcs**: All spawned jobs sorted by species name (including transition states). 16 | - **output**: Additional ARC output files and folders. 17 | -------------------------------------------------------------------------------- /docs/release.md: -------------------------------------------------------------------------------- 1 | # Release notes 2 | 3 | 4 | ## T3 0.1.0 5 | 6 | This is the first version of T3. 7 | 8 | ## Version style 9 | 10 | T3 uses [Semantic Versioning](https://semver.org/) 11 | -------------------------------------------------------------------------------- /docs/running.md: -------------------------------------------------------------------------------- 1 | # Running T3 2 | 3 | ## General 4 | 5 | Executing T3 can be done via two ways: 6 | 7 | - using an input file, or 8 | - using the Python API 9 | 10 | Other than subtle differences described here, 11 | both approaches are equivalent as they can define 12 | the same parameters which will be processed via the same routines. 13 | 14 | > **Note:** 15 | Most examples in these documentation pages are in a **Python API** format rather than a [yaml](https://yaml.org/) 16 | input file** format. 17 | 18 | T3 also has a function for writing a corresponding 19 | YAML input file after defining parameters via the API, 20 | see the [How-to guides](how_to.md#save-an-input-file-from-the-api) 21 | for more details. 22 | 23 | ## Activate the environment 24 | 25 | To use T3, first activate the T3 environment. Type either: 26 | 27 | ``` bash 28 | conda activate t3_env 29 | ``` 30 | 31 | or, if you have set up the recommended aliases, simply type: 32 | 33 | ``` bash 34 | t3e 35 | ``` 36 | 37 | ## Arguments 38 | 39 | T3 has three minor arguments (``project``, ``project_directory``, and ``verbose``) 40 | and three primary arguments (``t3``, ``rmg``, and ``qm``). 41 | 42 | The ``project`` argument is required. It is a string representing the T3 project name. 43 | 44 | The ``project_directory`` argument is optional. It is a string representing the 45 | path to the local project directory where all the project files are stored. 46 | If not specified, it will be set to the folder in which the input file is located 47 | if T3 is being executed using an input file, or to a respective subfolder with the 48 | project's name under the ``Projects`` folder in the T3 repository. 49 | 50 | The ``verbose`` argument is optional. It is an integer representing the logging 51 | level used by T3. Allowed values are: ``10``: debug level (very verbose), 52 | ``20``: info level (default), ``30``: warnings and errors only, ``40``: errors 53 | only. Pass ``None`` to this argument to avoid saving a log file. 54 | 55 | The primary arguments specify various options for the different respective packages 56 | (T3, RMG, and QM which currently only supports 57 | [ARC](https://reactionmechanismgenerator.github.io/ARC/index.html) 58 | Of these three, only the ``rmg`` argument is required. The ``qm`` argument must 59 | be specified if QM-based model refinement is desired 60 | (in most cases it is!). The ``t3`` argument contains optional T3-related 61 | directives and should commonly be specified. 62 | 63 | The RMG arguments in T3 are written in an underscore_lower_case (snake_case) syntax, 64 | while many are in a camelCase syntax in RMG. 65 | A few RMG arguments have different names altogether in T3. These arguments are: 66 | 67 | - `kinetics_libraries`: In the RMG database block, the `kinetics_libraries` argument 68 | replaces the legacy RMG `reactionLibraries` argument. 69 | - `core_tolerance`: In the RMG model block, the `core_tolerance` argument 70 | replaces the legacy RMG `toleranceMoveToCore` argument. See the 71 | [How-to guides](how_to.md#the-rmg-core-tolerances) for more details. 72 | - `conditions_per_iteration`: In the RMG reactors block, the `conditions_per_iteration` argument 73 | replaces the legacy RMG `nSims` argument. 74 | - Species definitions are different than in RMG, see the 75 | [How-to guides](how_to.md#species-properties) for more details. 76 | - Reactors definitions are different than in RMG, see the 77 | [How-to guides](how_to.md#reactors) for more details. 78 | 79 | > **Note:** 80 | Some of the RMG default values have been changed in T3, see the [schema for details](https://github.com/ReactionMechanismGenerator/T3/blob/main/t3/schema.py) 81 | 82 | Use the below **reference guide** to learn more about these arguments. 83 | 84 | ## Reference guide 85 | 86 | T3 has several types of reference guides: 87 | 88 | - The [tutorials](tutorials/1_no_qm.md) are a great place to start with, 89 | and provide an excellent basic reference guide. In T3's tutorials you can find 90 | complete, functioning, and worked-out examples with explanations. 91 | - The [commented input file](https://github.com/ReactionMechanismGenerator/T3/blob/main/examples/commented/input.yml) in T3's examples shows all available input arguments along with a brief explanation. 92 | - A [pydentic schema](https://github.com/ReactionMechanismGenerator/T3/blob/main/t3/schema.py) is used to validate the input file, 93 | and could also be used as a reference for the various allowed arguments. 94 | 95 | ## Where next? 96 | 97 | New users should start learning how to use T3 by reading and executing the [tutorials](tutorials/1_no_qm.md). 98 | 99 | For advanced features and specific examples for solving complex problems, see the [how-to guides](how_to.md). 100 | -------------------------------------------------------------------------------- /docs/t3-circle.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/docs/t3-circle.jpg -------------------------------------------------------------------------------- /environment.yml: -------------------------------------------------------------------------------- 1 | name: t3_env 2 | channels: 3 | - defaults 4 | - rmg 5 | - conda-forge 6 | - cantera 7 | - anaconda 8 | dependencies: 9 | - cairo 10 | - cairocffi 11 | - cantera::cantera=2.6 12 | - conda-forge::cclib >=1.7.0 13 | - rmg::chemprop 14 | - coolprop 15 | - coverage 16 | - cython >=0.25.2 17 | - ffmpeg 18 | - rmg::gprof2dot 19 | - graphviz 20 | - h5py 21 | - jinja2 22 | - jupyter 23 | - rmg::lpsolve55 24 | - markupsafe 25 | - matplotlib >=1.5 26 | - conda-forge::mopac 27 | - mpmath 28 | - rmg::muq2 29 | - networkx 30 | - rmg::numdifftools 31 | - numpy==1.20.1 32 | - conda-forge::openbabel >= 3 33 | - pandas 34 | - psutil 35 | - rmg::pydas >=1.0.2 36 | - pydot 37 | - rmg::pydqed >=1.0.1 38 | - pymongo 39 | - pyparsing 40 | - rmg::pyrdl 41 | - python >=3.7 42 | - pyyaml 43 | - rmg::quantities 44 | - rmg::rdkit >=2020.03.3.0 45 | - scikit-learn 46 | - scipy 47 | - rmg::symmetry 48 | - xlrd 49 | - xlwt 50 | - anaconda::sphinx_rtd_theme 51 | - anaconda::paramiko >=2.6.0 52 | - conda-forge::py3dmol >= 0.8.0 53 | - conda-forge::ase >=3.15.0, <=3.22.1 54 | - anaconda::ipython 55 | - anaconda::sphinx 56 | - anaconda::sphinxcontrib-jsmath 57 | - conda-forge::qcelemental 58 | - mako 59 | - pytables 60 | - anaconda::pytest 61 | - conda-forge::pytest-cov 62 | - mkdocs-material >=5.1.7 63 | - mkdocs-material-extensions 64 | - mock 65 | - pyomo 66 | -------------------------------------------------------------------------------- /examples/liquid_phase/input.yml: -------------------------------------------------------------------------------- 1 | project: T3_liquid_phase_example 2 | 3 | t3: 4 | options: 5 | all_core_species: True 6 | max_T3_iterations: 20 7 | max_rmg_processes: 10 8 | sensitivity: 9 | adapter: RMGConstantTP 10 | SA_threshold: 0.01 # although all core species are selected to be calculated, SA is run for additional information (not used by T3) 11 | 12 | rmg: 13 | database: 14 | kinetics_libraries: ['BurkeH2O2inN2', 'api_soup', 'NOx2018', 'Klippenstein_Glarborg2016'] # showing that lists (and dictionaries) can also be specified in YAML using a Python format 15 | thermo_libraries: 16 | - BurkeH2O2 17 | - thermo_DFT_CCSDTF12_BAC 18 | - DFT_QCI_thermo 19 | - primaryThermoLibrary 20 | - CBS_QB3_1dHR 21 | - CurranPentane 22 | model: 23 | core_tolerance: 24 | - 0.001 25 | options: 26 | save_edge: true 27 | save_html: true 28 | reactors: 29 | - T: # this is a ranged reactor (has a T range) 30 | - 293.0 31 | - 393.0 32 | termination_time: [72, 'hrs'] 33 | type: liquid batch constant T V 34 | species: 35 | - label: AIBN 36 | concentration: 4.9e-06 37 | smiles: CC(C)(C#N)/N=N/C(C)(C)C#N 38 | - label: MeOH 39 | concentration: 0.0124 40 | smiles: CO 41 | - label: water 42 | concentration: 0.0278 43 | smiles: O 44 | solvent: true # defining the solvent used by RMG 45 | - label: O2 46 | concentration: 2.73e-07 47 | smiles: '[O][O]' # if the SMILES begin with a '[' character, the string must be given within quotation marks so the YAML interpreter won't confuse it for a list 48 | - label: OHCH2OO 49 | SA_observable: true 50 | smiles: OCO[O] 51 | - label: cyanoisopropylOO 52 | SA_observable: true 53 | smiles: N#CC(C)(C)O[O] 54 | - label: N2 55 | concentration: 4.819e-07 56 | reactive: false # species can be set as non-reactive 57 | smiles: N#N 58 | species_constraints: 59 | max_C_atoms: 4 60 | max_N_atoms: 2 61 | max_O_atoms: 3 62 | max_S_atoms: 0 63 | max_Si_atoms: 0 64 | max_heavy_atoms: 10 65 | max_radical_electrons: 1 66 | 67 | qm: 68 | adapter: ARC 69 | job_types: 70 | rotors: True 71 | conformers: True 72 | fine: True 73 | freq: True 74 | opt: True 75 | sp: True 76 | level_of_theory: CBS-QB3 77 | -------------------------------------------------------------------------------- /examples/minimal/input.yml: -------------------------------------------------------------------------------- 1 | project: T3_minimal_example 2 | 3 | t3: 4 | options: 5 | max_T3_iterations: 2 6 | max_RMG_walltime: '00:00:05:00' 7 | sensitivity: 8 | adapter: RMGConstantTP # *required* (this is how SA is requested), can use any implemented simulation adapter 9 | top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10 10 | 11 | rmg: 12 | database: 13 | thermo_libraries: ['primaryThermoLibrary'] 14 | kinetics_libraries: [] 15 | species: 16 | - label: H2 17 | smiles: '[H][H]' 18 | concentration: 0.67 19 | - label: O2 20 | smiles: '[O][O]' 21 | concentration: 0.33 22 | - label: H 23 | smiles: '[H]' 24 | SA_observable: true 25 | - label: OH 26 | smiles: '[OH]' 27 | SA_observable: true 28 | reactors: 29 | - type: gas batch constant T P 30 | T: 1000 31 | P: 1 32 | termination_conversion: 33 | 'H2': 0.9 34 | termination_time: [5, 's'] 35 | model: 36 | core_tolerance: [0.01, 0.001] 37 | 38 | qm: 39 | adapter: ARC 40 | level_of_theory: 'b3lyp/6-31g(d,p)' 41 | job_types: 42 | rotors: false 43 | conformers: true 44 | fine: false 45 | freq: true 46 | opt: true 47 | sp: true 48 | -------------------------------------------------------------------------------- /grf/T3-circle.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/grf/T3-circle.gif -------------------------------------------------------------------------------- /grf/T3_logo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/grf/T3_logo.gif -------------------------------------------------------------------------------- /grf/T3_logo.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/grf/T3_logo.jpg -------------------------------------------------------------------------------- /grf/T3_logo.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/grf/T3_logo.psd -------------------------------------------------------------------------------- /grf/T3_logo_small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/grf/T3_logo_small.gif -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/bar_ROPs/H(3)_2.0_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/ipython/flux_diagram/HOCHO_flux_diagrams/bar_ROPs/H(3)_2.0_s.png -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/bar_ROPs/HOCHO(1)_2.0_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/ipython/flux_diagram/HOCHO_flux_diagrams/bar_ROPs/HOCHO(1)_2.0_s.png -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/bar_ROPs/HOCO(10)_2.0_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/ipython/flux_diagram/HOCHO_flux_diagrams/bar_ROPs/HOCO(10)_2.0_s.png -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/H(3)/flux_diagram_2.0_s.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | label="Flux diagram at 2.0 s, ROP range: [8.01e-17, 1.51e-02] mol/cm³/s)"; 3 | "H(3)" [fillcolor="#DCE5F4", fontsize=8, penwidth=1.7530392047540462, style=filled, xlabel="2.80e-11"]; 4 | "CO(8)" [fontsize=8, penwidth=3.999999999999999, xlabel="4.68e-05"]; 5 | "H2(4)" [fontsize=8, penwidth=3.927639860174137, xlabel="2.95e-05"]; 6 | "OH(5)" [fontsize=8, penwidth=1.6100755035270433, xlabel="1.12e-11"]; 7 | "H(3)" -> "CO(8)" [arrowhead=vee, fontsize=8, label="0.9\n+ HOCHO(1)\n- H2(4) - OH(5)", penwidth=3.984676425213845]; 8 | "H(3)" -> "H2(4)" [arrowhead=vee, fontsize=8, label="0.9\n+ HOCHO(1)\n- CO(8) - OH(5)", penwidth=3.984676425213845]; 9 | "H(3)" -> "OH(5)" [arrowhead=vee, fontsize=8, label="0.9\n+ HOCHO(1)\n- CO(8) - H2(4)", penwidth=3.984676425213845]; 10 | "HOCO(10)" [fontsize=8, penwidth=0.5383397186827532, xlabel="1.21e-14"]; 11 | "H(3)" -> "H2(4)" [arrowhead=vee, fontsize=8, label="0.2\n+ HOCHO(1)\n- HOCO(10)", penwidth=3.7536269933534743]; 12 | "H(3)" -> "HOCO(10)" [arrowhead=vee, fontsize=8, label="0.2\n+ HOCHO(1)\n- H2(4)", penwidth=3.7536269933534743]; 13 | "HOCO(10)" -> "CO(8)" [arrowhead=vee, fontsize=8, label="1.0\n- OH(5)", penwidth=3.997757463516357]; 14 | "HOCO(10)" -> "OH(5)" [arrowhead=vee, fontsize=8, label="1.0\n- CO(8)", penwidth=3.997757463516357]; 15 | "CO2(9)" [fontsize=8, penwidth=3.927639907930275, xlabel="2.95e-05"]; 16 | "H2O(17)" [fontsize=8, penwidth=3.9999999645295996, xlabel="4.68e-05"]; 17 | "OH(5)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="1.0\n+ HOCHO(1)\n- H(3) - H2O(17)", penwidth=4.0]; 18 | "OH(5)" -> "H(3)" [arrowhead=vee, fontsize=8, label="1.0\n+ HOCHO(1)\n- CO2(9) - H2O(17)", penwidth=4.0]; 19 | "OH(5)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="1.0\n+ HOCHO(1)\n- CO2(9) - H(3)", penwidth=4.0]; 20 | "OH(5)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="0.8\n+ HOCHO(1)\n- HOCO(10)", penwidth=3.9539926576457947]; 21 | "OH(5)" -> "HOCO(10)" [arrowhead=vee, fontsize=8, label="0.8\n+ HOCHO(1)\n- H2O(17)", penwidth=3.9539926576457947]; 22 | "OCHO(11)" [fontsize=8, penwidth=0.19999999999999937, xlabel="1.40e-15"]; 23 | "OH(5)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="0.1\n+ HOCHO(1)\n- OCHO(11)", penwidth=3.67123391780574]; 24 | "OH(5)" -> "OCHO(11)" [arrowhead=vee, fontsize=8, label="0.1\n+ HOCHO(1)\n- H2O(17)", penwidth=3.67123391780574]; 25 | "OCHO(11)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="0.1\n- H(3)", penwidth=3.676279894902382]; 26 | "OCHO(11)" -> "H(3)" [arrowhead=vee, fontsize=8, label="0.1\n- CO2(9)", penwidth=3.676279894902382]; 27 | "H2O(17)" -> "H(3)" [arrowhead=vee, fontsize=8, label="4.3e-10\n- OH(5)", penwidth=0.43016435137560394]; 28 | "H2O(17)" -> "OH(5)" [arrowhead=vee, fontsize=8, label="4.3e-10\n- H(3)", penwidth=0.43016435137560394]; 29 | "H2O(17)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="1.1e-10\n+ CO(8)\n- H2(4)", penwidth=0.20000000000000034]; 30 | "H2O(17)" -> "H2(4)" [arrowhead=vee, fontsize=8, label="1.1e-10\n+ CO(8)\n- CO2(9)", penwidth=0.20000000000000034]; 31 | "CO2(9)" -> "HOCO(10)" [arrowhead=vee, fontsize=8, label="3.6e-08\n+ HOCHO(1)", penwidth=1.4627966491004998]; 32 | "H2(4)" -> "H(3)" [arrowhead=vee, fontsize=8, label="1.0e-04\n+ OH(5)\n- H2O(17)", penwidth=2.483741242797586]; 33 | "H2(4)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="1.0e-04\n+ OH(5)\n- H(3)", penwidth=2.483741242797586]; 34 | "CO(8)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="2.0e-03\n+ OH(5)\n- H(3)", penwidth=2.9739529963274607]; 35 | "CO(8)" -> "H(3)" [arrowhead=vee, fontsize=8, label="2.0e-03\n+ OH(5)\n- CO2(9)", penwidth=2.9739529963274607]; 36 | } 37 | -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/H(3)/flux_diagram_2.0_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/H(3)/flux_diagram_2.0_s.png -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/HOCHO(1)/flux_diagram_2.0_s.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | label="Flux diagram at 2.0 s, ROP range: [8.01e-17, 1.51e-02] mol/cm³/s)"; 3 | "HOCHO(1)" [fillcolor="#DCE5F4", fontsize=8, penwidth=4.0, style=filled, xlabel="1.69e-01"]; 4 | "CO(8)" [fontsize=8, penwidth=2.6712938924744143, xlabel="4.68e-05"]; 5 | "H2O(17)" [fontsize=8, penwidth=2.671293855796359, xlabel="4.68e-05"]; 6 | "HOCHO(1)" -> "CO(8)" [arrowhead=vee, fontsize=8, label="1.0\n- H2O(17)", penwidth=4.0]; 7 | "HOCHO(1)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="1.0\n- CO(8)", penwidth=4.0]; 8 | "CO2(9)" [fontsize=8, penwidth=2.596470167350586, xlabel="2.95e-05"]; 9 | "H2(4)" [fontsize=8, penwidth=2.5964701179685017, xlabel="2.95e-05"]; 10 | "HOCHO(1)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="0.6\n- H2(4)", penwidth=3.9466405710292745]; 11 | "HOCHO(1)" -> "H2(4)" [arrowhead=vee, fontsize=8, label="0.6\n- CO2(9)", penwidth=3.9466405710292745]; 12 | "H(3)" [fontsize=8, penwidth=0.34783116462852137, xlabel="2.80e-11"]; 13 | "H2(4)" -> "H(3)" [arrowhead=vee, fontsize=8, label="5.2e-09\n+ OH(5)\n- H2O(17)", penwidth=1.7955577099046087]; 14 | "H2(4)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="5.2e-09\n+ OH(5)\n- H(3)", penwidth=1.7955577099046087]; 15 | "HOCO(10)" [fontsize=8, penwidth=0.7324480422152477, xlabel="1.21e-14"]; 16 | "CO2(9)" -> "HOCO(10)" [arrowhead=vee, fontsize=8, label="1.8e-12\n+ HOCHO(1)", penwidth=1.1729774870268643]; 17 | "OH(5)" [fontsize=8, penwidth=0.2000000000000002, xlabel="1.12e-11"]; 18 | "H2O(17)" -> "H(3)" [arrowhead=vee, fontsize=8, label="2.1e-14\n- OH(5)", penwidth=0.3608065303110556]; 19 | "H2O(17)" -> "OH(5)" [arrowhead=vee, fontsize=8, label="2.1e-14\n- H(3)", penwidth=0.3608065303110556]; 20 | "H2O(17)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="5.3e-15\n+ CO(8)\n- H2(4)", penwidth=0.2]; 21 | "H2O(17)" -> "H2(4)" [arrowhead=vee, fontsize=8, label="5.3e-15\n+ CO(8)\n- CO2(9)", penwidth=0.2]; 22 | "CO(8)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="1.0e-07\n+ OH(5)\n- H(3)", penwidth=2.138048850394896]; 23 | "CO(8)" -> "H(3)" [arrowhead=vee, fontsize=8, label="1.0e-07\n+ OH(5)\n- CO2(9)", penwidth=2.138048850394896]; 24 | } 25 | -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/HOCHO(1)/flux_diagram_2.0_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/HOCHO(1)/flux_diagram_2.0_s.png -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/HOCO(10)/flux_diagram_2.0_s.dot: -------------------------------------------------------------------------------- 1 | digraph G { 2 | label="Flux diagram at 2.0 s, ROP range: [8.01e-17, 1.51e-02] mol/cm³/s)"; 3 | "HOCO(10)" [fillcolor="#DCE5F4", fontsize=8, penwidth=0.5383397186827532, style=filled, xlabel="1.21e-14"]; 4 | "CO(8)" [fontsize=8, penwidth=3.999999999999999, xlabel="4.68e-05"]; 5 | "OH(5)" [fontsize=8, penwidth=1.6100755035270433, xlabel="1.12e-11"]; 6 | "HOCO(10)" -> "CO(8)" [arrowhead=vee, fontsize=8, label="1.0\n- OH(5)", penwidth=3.997757463516357]; 7 | "HOCO(10)" -> "OH(5)" [arrowhead=vee, fontsize=8, label="1.0\n- CO(8)", penwidth=3.997757463516357]; 8 | "CO2(9)" [fontsize=8, penwidth=3.927639907930275, xlabel="2.95e-05"]; 9 | "H(3)" [fontsize=8, penwidth=1.7530392047540462, xlabel="2.80e-11"]; 10 | "H2O(17)" [fontsize=8, penwidth=3.9999999645295996, xlabel="4.68e-05"]; 11 | "OH(5)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="1.0\n+ HOCHO(1)\n- H(3) - H2O(17)", penwidth=4.0]; 12 | "OH(5)" -> "H(3)" [arrowhead=vee, fontsize=8, label="1.0\n+ HOCHO(1)\n- CO2(9) - H2O(17)", penwidth=4.0]; 13 | "OH(5)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="1.0\n+ HOCHO(1)\n- CO2(9) - H(3)", penwidth=4.0]; 14 | "OH(5)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="0.8\n+ HOCHO(1)\n- HOCO(10)", penwidth=3.9539926576457947]; 15 | "OH(5)" -> "HOCO(10)" [arrowhead=vee, fontsize=8, label="0.8\n+ HOCHO(1)\n- H2O(17)", penwidth=3.9539926576457947]; 16 | "OCHO(11)" [fontsize=8, penwidth=0.19999999999999937, xlabel="1.40e-15"]; 17 | "OH(5)" -> "H2O(17)" [arrowhead=vee, fontsize=8, label="0.1\n+ HOCHO(1)\n- OCHO(11)", penwidth=3.67123391780574]; 18 | "OH(5)" -> "OCHO(11)" [arrowhead=vee, fontsize=8, label="0.1\n+ HOCHO(1)\n- H2O(17)", penwidth=3.67123391780574]; 19 | "OCHO(11)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="0.1\n- H(3)", penwidth=3.676279894902382]; 20 | "OCHO(11)" -> "H(3)" [arrowhead=vee, fontsize=8, label="0.1\n- CO2(9)", penwidth=3.676279894902382]; 21 | "H2O(17)" -> "H(3)" [arrowhead=vee, fontsize=8, label="4.3e-10\n- OH(5)", penwidth=0.43016435137560394]; 22 | "H2O(17)" -> "OH(5)" [arrowhead=vee, fontsize=8, label="4.3e-10\n- H(3)", penwidth=0.43016435137560394]; 23 | "H2(4)" [fontsize=8, penwidth=3.927639860174137, xlabel="2.95e-05"]; 24 | "H2O(17)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="1.1e-10\n+ CO(8)\n- H2(4)", penwidth=0.20000000000000034]; 25 | "H2O(17)" -> "H2(4)" [arrowhead=vee, fontsize=8, label="1.1e-10\n+ CO(8)\n- CO2(9)", penwidth=0.20000000000000034]; 26 | "H(3)" -> "CO(8)" [arrowhead=vee, fontsize=8, label="0.9\n+ HOCHO(1)\n- H2(4) - OH(5)", penwidth=3.984676425213845]; 27 | "H(3)" -> "H2(4)" [arrowhead=vee, fontsize=8, label="0.9\n+ HOCHO(1)\n- CO(8) - OH(5)", penwidth=3.984676425213845]; 28 | "H(3)" -> "OH(5)" [arrowhead=vee, fontsize=8, label="0.9\n+ HOCHO(1)\n- CO(8) - H2(4)", penwidth=3.984676425213845]; 29 | "H(3)" -> "H2(4)" [arrowhead=vee, fontsize=8, label="0.2\n+ HOCHO(1)\n- HOCO(10)", penwidth=3.7536269933534743]; 30 | "H(3)" -> "HOCO(10)" [arrowhead=vee, fontsize=8, label="0.2\n+ HOCHO(1)\n- H2(4)", penwidth=3.7536269933534743]; 31 | "CO2(9)" -> "HOCO(10)" [arrowhead=vee, fontsize=8, label="3.6e-08\n+ HOCHO(1)", penwidth=1.4627966491004998]; 32 | "CO(8)" -> "CO2(9)" [arrowhead=vee, fontsize=8, label="2.0e-03\n+ OH(5)\n- H(3)", penwidth=2.9739529963274607]; 33 | "CO(8)" -> "H(3)" [arrowhead=vee, fontsize=8, label="2.0e-03\n+ OH(5)\n- CO2(9)", penwidth=2.9739529963274607]; 34 | } 35 | -------------------------------------------------------------------------------- /ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/HOCO(10)/flux_diagram_2.0_s.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ReactionMechanismGenerator/T3/f3dcc84f67d0d373ce5e35d98dd3a4979cd2a782/ipython/flux_diagram/HOCHO_flux_diagrams/flux_diagrams/HOCO(10)/flux_diagram_2.0_s.png -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/cantera_simulator.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "This notebook demonstrates how to use one of the cantera simulator adapters" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": { 14 | "scrolled": false 15 | }, 16 | "outputs": [], 17 | "source": [ 18 | "import os\n", 19 | "import matplotlib.pyplot as plt\n", 20 | "%matplotlib inline\n", 21 | "\n", 22 | "\n", 23 | "from tests.common import run_minimal\n", 24 | "from t3.common import IPYTHON_SIMULATOR_EXAMPLES_PATH\n", 25 | "from t3.main import T3\n", 26 | "from t3.simulate.cantera_constantTP import CanteraConstantTP\n", 27 | "\n", 28 | "from arc.common import read_yaml_file" 29 | ] 30 | }, 31 | { 32 | "cell_type": "code", 33 | "execution_count": null, 34 | "metadata": {}, 35 | "outputs": [], 36 | "source": [ 37 | "# define path that contains the input file and T3 iteration folders\n", 38 | "EXAMPLE_DIR = os.path.join(IPYTHON_SIMULATOR_EXAMPLES_PATH, 'cantera_simulator_data')" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": null, 44 | "metadata": {}, 45 | "outputs": [], 46 | "source": [ 47 | "# read in the input dictionary to use T3 via its API\n", 48 | "minimal_input = os.path.join(EXAMPLE_DIR, 'input.yml')\n", 49 | "input_dict = read_yaml_file(path=minimal_input)\n", 50 | "input_dict['verbose'] = 10\n", 51 | "input_dict['project_directory'] = EXAMPLE_DIR" 52 | ] 53 | }, 54 | { 55 | "cell_type": "code", 56 | "execution_count": null, 57 | "metadata": { 58 | "scrolled": true 59 | }, 60 | "outputs": [], 61 | "source": [ 62 | "# create an instance of T3, which stores information used by the Cantera adapter\n", 63 | "t3 = T3(**input_dict)\n", 64 | "t3.set_paths()" 65 | ] 66 | }, 67 | { 68 | "cell_type": "code", 69 | "execution_count": null, 70 | "metadata": {}, 71 | "outputs": [], 72 | "source": [ 73 | "# simulate ideal gas with constant T and P and perform sensitivity analysis wrt to rate constants and ethalpies\n", 74 | "observable_list = ['OH', 'H']\n", 75 | "cantera_simulator_adapter = CanteraConstantTP(t3=t3.t3,\n", 76 | " rmg=t3.rmg,\n", 77 | " paths=t3.paths,\n", 78 | " logger=t3.logger,\n", 79 | " atol=t3.rmg['model']['atol'],\n", 80 | " rtol=t3.rmg['model']['rtol'],\n", 81 | " observable_list=observable_list,\n", 82 | " sa_atol=t3.t3['sensitivity']['atol'],\n", 83 | " sa_rtol=t3.t3['sensitivity']['rtol'],\n", 84 | " )\n", 85 | "cantera_simulator_adapter.simulate()" 86 | ] 87 | }, 88 | { 89 | "cell_type": "code", 90 | "execution_count": null, 91 | "metadata": {}, 92 | "outputs": [], 93 | "source": [ 94 | "# get the sensitivity analysis coefficients returned in a standard dictionary format\n", 95 | "sa_dict = cantera_simulator_adapter.get_sa_coefficients()" 96 | ] 97 | }, 98 | { 99 | "cell_type": "code", 100 | "execution_count": null, 101 | "metadata": {}, 102 | "outputs": [], 103 | "source": [ 104 | "# plot the results\n", 105 | "species = 'H(3)'\n", 106 | "k = 5\n", 107 | "plt.plot(sa_dict['time'], sa_dict['kinetics'][species][k])\n", 108 | "plt.xlabel('time (s)')\n", 109 | "plt.ylabel(f'dln({species})/dln(k{k})')\n", 110 | "plt.title('Sensitivity over time')" 111 | ] 112 | }, 113 | { 114 | "cell_type": "code", 115 | "execution_count": null, 116 | "metadata": {}, 117 | "outputs": [], 118 | "source": [] 119 | } 120 | ], 121 | "metadata": { 122 | "kernelspec": { 123 | "display_name": "Python 3", 124 | "language": "python", 125 | "name": "python3" 126 | }, 127 | "language_info": { 128 | "codemirror_mode": { 129 | "name": "ipython", 130 | "version": 3 131 | }, 132 | "file_extension": ".py", 133 | "mimetype": "text/x-python", 134 | "name": "python", 135 | "nbconvert_exporter": "python", 136 | "pygments_lexer": "ipython3", 137 | "version": "3.7.7" 138 | } 139 | }, 140 | "nbformat": 4, 141 | "nbformat_minor": 4 142 | } 143 | -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/cantera_simulator_data/input.yml: -------------------------------------------------------------------------------- 1 | project: T3_minimal 2 | 3 | t3: 4 | options: 5 | max_T3_iterations: 2 6 | max_RMG_walltime: '00:00:05:00' 7 | sensitivity: 8 | adapter: CanteraConstantTP # *required* (this is how SA is requested), can use any implemented simulation adapter 9 | top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10 10 | 11 | rmg: 12 | database: 13 | thermo_libraries: ['primaryThermoLibrary'] 14 | kinetics_libraries: [] 15 | species: 16 | - label: H2 17 | smiles: '[H][H]' 18 | concentration: 0.67 19 | - label: O2 20 | smiles: '[O][O]' 21 | concentration: 0.33 22 | - label: H 23 | smiles: '[H]' 24 | SA_observable: true 25 | - label: OH 26 | smiles: '[OH]' 27 | SA_observable: true 28 | reactors: 29 | - type: gas batch constant T P 30 | T: 1000 31 | P: 1 32 | termination_conversion: 33 | 'H2': 0.9 34 | termination_time: [1, 's'] 35 | model: 36 | core_tolerance: [0.01, 0.001] 37 | options: 38 | save_simulation_profiles: true 39 | 40 | qm: 41 | adapter: ARC 42 | level_of_theory: 'b3lyp/6-31g(d,p)' 43 | job_types: 44 | rotors: false 45 | conformers: true 46 | fine: false 47 | freq: true 48 | opt: true 49 | sp: true 50 | -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/cantera_simulator_data/iteration_0/RMG/input.py: -------------------------------------------------------------------------------- 1 | database( 2 | thermoLibraries=['primaryThermoLibrary'], 3 | reactionLibraries=[], 4 | transportLibraries=['OneDMinN2', 'PrimaryTransportLibrary', 'NOx2018', 'GRI-Mech'], 5 | seedMechanisms=[], 6 | kineticsDepositories='default', 7 | kineticsFamilies='default', 8 | kineticsEstimator='rate rules', 9 | ) 10 | 11 | species( 12 | label='H2', 13 | reactive=True, 14 | structure=SMILES('[H][H]'), 15 | ) 16 | 17 | species( 18 | label='O2', 19 | reactive=True, 20 | structure=SMILES('[O][O]'), 21 | ) 22 | 23 | species( 24 | label='H', 25 | reactive=True, 26 | structure=SMILES('[H]'), 27 | ) 28 | 29 | species( 30 | label='OH', 31 | reactive=True, 32 | structure=SMILES('[OH]'), 33 | ) 34 | 35 | simpleReactor( 36 | temperature=(1000.0, 'K'), 37 | pressure=(1.0, 'bar'), 38 | initialMoleFractions={ 39 | 'H2': 0.67, 40 | 'O2': 0.33, 41 | 'H': 0, 42 | 'OH': 0, 43 | }, 44 | terminationConversion={'H2': 0.9}, 45 | terminationTime=(1.0, 's'), 46 | nSims=12, 47 | ) 48 | 49 | model( 50 | toleranceMoveToCore=0.001, 51 | toleranceInterruptSimulation=0.001, 52 | filterReactions=False, 53 | filterThreshold=100000000.0, 54 | maxNumObjsPerIter=1, 55 | terminateAtMaxObjects=False, 56 | ) 57 | 58 | simulator(atol=1e-16, rtol=1e-08) 59 | -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/rmg_simulator.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "This notebook demonstrates how to use the rmg simulator adapter" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import os\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "%matplotlib inline\n", 19 | "\n", 20 | "from tests.common import run_minimal\n", 21 | "from t3.common import IPYTHON_SIMULATOR_EXAMPLES_PATH\n", 22 | "from t3.main import T3\n", 23 | "from t3.simulate.rmg_constantTP import RMGConstantTP\n", 24 | "\n", 25 | "from arc.common import read_yaml_file" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "# define path that contains the input file and T3 iteration folders\n", 35 | "EXAMPLE_DIR = os.path.join(IPYTHON_SIMULATOR_EXAMPLES_PATH, 'rmg_simulator_data')" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "# read in the input dictionary to use T3 via its API\n", 45 | "minimal_input = os.path.join(EXAMPLE_DIR, 'input.yml')\n", 46 | "input_dict = read_yaml_file(path=minimal_input)\n", 47 | "input_dict['verbose'] = 10\n", 48 | "input_dict['project_directory'] = EXAMPLE_DIR" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": { 55 | "scrolled": true 56 | }, 57 | "outputs": [], 58 | "source": [ 59 | "# create an instance of T3, which stores information used by the rmg adapter\n", 60 | "t3 = T3(**input_dict)\n", 61 | "t3.set_paths()" 62 | ] 63 | }, 64 | { 65 | "cell_type": "code", 66 | "execution_count": null, 67 | "metadata": {}, 68 | "outputs": [], 69 | "source": [ 70 | "# simulate ideal gas with constant T and P and perform sensitivity analysis wrt to rate constants and ethalpies\n", 71 | "observable_list = ['OH', 'H']\n", 72 | "rmg_simulator_adapter = RMGConstantTP(t3=t3.t3,\n", 73 | " rmg=t3.rmg,\n", 74 | " paths=t3.paths,\n", 75 | " logger=t3.logger,\n", 76 | " atol=t3.rmg['model']['atol'],\n", 77 | " rtol=t3.rmg['model']['rtol'],\n", 78 | " observable_list=observable_list,\n", 79 | " sa_atol=t3.t3['sensitivity']['atol'],\n", 80 | " sa_rtol=t3.t3['sensitivity']['rtol'],\n", 81 | " )\n", 82 | "rmg_simulator_adapter.simulate()" 83 | ] 84 | }, 85 | { 86 | "cell_type": "code", 87 | "execution_count": null, 88 | "metadata": {}, 89 | "outputs": [], 90 | "source": [ 91 | "# get the sensitivity analysis coefficients returned in a standard dictionary format\n", 92 | "sa_dict = rmg_simulator_adapter.get_sa_coefficients()" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": null, 98 | "metadata": {}, 99 | "outputs": [], 100 | "source": [ 101 | "# plot the results\n", 102 | "species = 'H(3)'\n", 103 | "k = 5\n", 104 | "plt.plot(sa_dict['time'], sa_dict['kinetics'][species][k])\n", 105 | "plt.xlabel('time (s)')\n", 106 | "plt.ylabel(f'dln({species})/dln(k{k})')\n", 107 | "plt.title('Sensitivity over time')" 108 | ] 109 | }, 110 | { 111 | "cell_type": "code", 112 | "execution_count": null, 113 | "metadata": {}, 114 | "outputs": [], 115 | "source": [] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.7.7" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 4 139 | } 140 | -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/rmg_simulator_data/input.yml: -------------------------------------------------------------------------------- 1 | project: T3_minimal 2 | 3 | t3: 4 | options: 5 | max_T3_iterations: 2 6 | max_RMG_walltime: '00:00:05:00' 7 | sensitivity: 8 | adapter: RMGConstantTP # *required* (this is how SA is requested), can use any implemented simulation adapter 9 | top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10 10 | 11 | rmg: 12 | database: 13 | thermo_libraries: ['primaryThermoLibrary'] 14 | kinetics_libraries: [] 15 | species: 16 | - label: H2 17 | smiles: '[H][H]' 18 | concentration: 0.67 19 | - label: O2 20 | smiles: '[O][O]' 21 | concentration: 0.33 22 | - label: H 23 | smiles: '[H]' 24 | SA_observable: true 25 | - label: OH 26 | smiles: '[OH]' 27 | SA_observable: true 28 | reactors: 29 | - type: gas batch constant T P 30 | T: 1000 31 | P: 1 32 | termination_conversion: 33 | 'H2': 0.9 34 | termination_time: [1, 's'] 35 | model: 36 | core_tolerance: [0.01, 0.001] 37 | options: 38 | save_simulation_profiles: true 39 | 40 | qm: 41 | adapter: ARC 42 | level_of_theory: 'b3lyp/6-31g(d,p)' 43 | job_types: 44 | rotors: false 45 | conformers: true 46 | fine: false 47 | freq: true 48 | opt: true 49 | sp: true 50 | -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/rmg_simulator_data/iteration_0/RMG/chemkin/species_dictionary.txt: -------------------------------------------------------------------------------- 1 | Ar 2 | 1 Ar u0 p4 c0 3 | 4 | He 5 | 1 He u0 p1 c0 6 | 7 | Ne 8 | 1 Ne u0 p4 c0 9 | 10 | N2 11 | 1 N u0 p1 c0 {2,T} 12 | 2 N u0 p1 c0 {1,T} 13 | 14 | H2(1) 15 | 1 H u0 p0 c0 {2,S} 16 | 2 H u0 p0 c0 {1,S} 17 | 18 | O2(2) 19 | multiplicity 3 20 | 1 O u1 p2 c0 {2,S} 21 | 2 O u1 p2 c0 {1,S} 22 | 23 | H(3) 24 | multiplicity 2 25 | 1 H u1 p0 c0 26 | 27 | OH(4) 28 | multiplicity 2 29 | 1 O u1 p2 c0 {2,S} 30 | 2 H u0 p0 c0 {1,S} 31 | 32 | HO2(6) 33 | multiplicity 2 34 | 1 O u0 p2 c0 {2,S} {3,S} 35 | 2 O u1 p2 c0 {1,S} 36 | 3 H u0 p0 c0 {1,S} 37 | 38 | OO(9) 39 | 1 O u0 p2 c0 {2,S} {3,S} 40 | 2 O u0 p2 c0 {1,S} {4,S} 41 | 3 H u0 p0 c0 {1,S} 42 | 4 H u0 p0 c0 {2,S} 43 | 44 | H2O(7) 45 | 1 O u0 p2 c0 {2,S} {3,S} 46 | 2 H u0 p0 c0 {1,S} 47 | 3 H u0 p0 c0 {1,S} 48 | 49 | O(T)(5) 50 | multiplicity 3 51 | 1 O u2 p2 c0 52 | 53 | -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/rmg_simulator_data/iteration_0/RMG/input.py: -------------------------------------------------------------------------------- 1 | database( 2 | thermoLibraries=['primaryThermoLibrary'], 3 | reactionLibraries=[], 4 | transportLibraries=['OneDMinN2', 'PrimaryTransportLibrary', 'NOx2018', 'GRI-Mech'], 5 | seedMechanisms=[], 6 | kineticsDepositories='default', 7 | kineticsFamilies='default', 8 | kineticsEstimator='rate rules', 9 | ) 10 | 11 | species( 12 | label='H2', 13 | reactive=True, 14 | structure=SMILES('[H][H]'), 15 | ) 16 | 17 | species( 18 | label='O2', 19 | reactive=True, 20 | structure=SMILES('[O][O]'), 21 | ) 22 | 23 | species( 24 | label='H', 25 | reactive=True, 26 | structure=SMILES('[H]'), 27 | ) 28 | 29 | species( 30 | label='OH', 31 | reactive=True, 32 | structure=SMILES('[OH]'), 33 | ) 34 | 35 | simpleReactor( 36 | temperature=(1000.0, 'K'), 37 | pressure=(1.0, 'bar'), 38 | initialMoleFractions={ 39 | 'H2': 0.67, 40 | 'O2': 0.33, 41 | 'H': 0, 42 | 'OH': 0, 43 | }, 44 | terminationConversion={'H2': 0.9}, 45 | terminationTime=(1, 's'), 46 | nSims=12, 47 | ) 48 | 49 | model( 50 | toleranceMoveToCore=0.001, 51 | toleranceInterruptSimulation=0.001, 52 | filterReactions=False, 53 | filterThreshold=100000000.0, 54 | maxNumObjsPerIter=1, 55 | terminateAtMaxObjects=False, 56 | ) 57 | 58 | simulator(atol=1e-16, rtol=1e-08) 59 | -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/rms_simulator.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "This notebook demonstrates how to use the rms simulator adapter" 8 | ] 9 | }, 10 | { 11 | "cell_type": "code", 12 | "execution_count": null, 13 | "metadata": {}, 14 | "outputs": [], 15 | "source": [ 16 | "import os\n", 17 | "import matplotlib.pyplot as plt\n", 18 | "%matplotlib inline\n", 19 | "\n", 20 | "from tests.common import run_minimal\n", 21 | "from t3.common import IPYTHON_SIMULATOR_EXAMPLES_PATH\n", 22 | "from t3.main import T3\n", 23 | "from t3.simulate.rms_constantTP import RMSConstantTP\n", 24 | "\n", 25 | "from arc.common import read_yaml_file" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": null, 31 | "metadata": {}, 32 | "outputs": [], 33 | "source": [ 34 | "# define path that contains the input file and T3 iteration folders\n", 35 | "EXAMPLE_DIR = os.path.join(IPYTHON_SIMULATOR_EXAMPLES_PATH, 'rms_simulator_data')" 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": null, 41 | "metadata": {}, 42 | "outputs": [], 43 | "source": [ 44 | "# read in the input dictionary to use T3 via its API\n", 45 | "minimal_input = os.path.join(EXAMPLE_DIR, 'input.yml')\n", 46 | "input_dict = read_yaml_file(path=minimal_input)\n", 47 | "input_dict['verbose'] = 10\n", 48 | "input_dict['project_directory'] = EXAMPLE_DIR" 49 | ] 50 | }, 51 | { 52 | "cell_type": "code", 53 | "execution_count": null, 54 | "metadata": {}, 55 | "outputs": [], 56 | "source": [ 57 | "# create an instance of T3, which stores information used by the rms adapter\n", 58 | "t3 = T3(**input_dict)\n", 59 | "t3.set_paths()" 60 | ] 61 | }, 62 | { 63 | "cell_type": "code", 64 | "execution_count": null, 65 | "metadata": {}, 66 | "outputs": [], 67 | "source": [ 68 | "# simulate ideal gas with constant V and perform sensitivity analysis\n", 69 | "rms_simulator_adapter = RMSConstantTP(t3=t3.t3,\n", 70 | " rmg=t3.rmg,\n", 71 | " paths=t3.paths,\n", 72 | " logger=t3.logger,\n", 73 | " atol=t3.rmg['model']['atol'],\n", 74 | " rtol=t3.rmg['model']['rtol'],\n", 75 | " observable_list=observable_list,\n", 76 | " sa_atol=t3.t3['sensitivity']['atol'],\n", 77 | " sa_rtol=t3.t3['sensitivity']['rtol'],\n", 78 | " )\n", 79 | "rms_simulator_adapter.simulate()" 80 | ] 81 | }, 82 | { 83 | "cell_type": "code", 84 | "execution_count": null, 85 | "metadata": {}, 86 | "outputs": [], 87 | "source": [ 88 | "# get the sensitivity analysis coefficients returned in a standard dictionary format\n", 89 | "sa_dict = rms_simulator_adapter.get_sa_coefficients()" 90 | ] 91 | }, 92 | { 93 | "cell_type": "code", 94 | "execution_count": null, 95 | "metadata": {}, 96 | "outputs": [], 97 | "source": [ 98 | "# plot the results\n", 99 | "species = 'H(3)'\n", 100 | "k = 5\n", 101 | "plt.plot(sa_dict['time'], sa_dict['kinetics'][species][k])\n", 102 | "plt.xlabel('time (s)')\n", 103 | "plt.ylabel(f'dln({species})/dln(k{k})')\n", 104 | "plt.title('Sensitivity over time')" 105 | ] 106 | } 107 | ], 108 | "metadata": { 109 | "kernelspec": { 110 | "display_name": "Python 3", 111 | "language": "python", 112 | "name": "python3" 113 | }, 114 | "language_info": { 115 | "codemirror_mode": { 116 | "name": "ipython", 117 | "version": 3 118 | }, 119 | "file_extension": ".py", 120 | "mimetype": "text/x-python", 121 | "name": "python", 122 | "nbconvert_exporter": "python", 123 | "pygments_lexer": "ipython3", 124 | "version": "3.7.7" 125 | } 126 | }, 127 | "nbformat": 4, 128 | "nbformat_minor": 4 129 | } 130 | -------------------------------------------------------------------------------- /ipython/simulator_adapter_examples/rms_simulator_data/input.yml: -------------------------------------------------------------------------------- 1 | project: T3_minimal 2 | 3 | t3: 4 | options: 5 | max_T3_iterations: 2 6 | max_RMG_walltime: '00:00:05:00' 7 | sensitivity: 8 | adapter: RMSConstantTP # *required* (this is how SA is requested), can use any implemented simulation adapter 9 | top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10 10 | 11 | rmg: 12 | database: 13 | thermo_libraries: ['primaryThermoLibrary'] 14 | kinetics_libraries: [] 15 | species: 16 | - label: H2 17 | smiles: '[H][H]' 18 | concentration: 0.67 19 | - label: O2 20 | smiles: '[O][O]' 21 | concentration: 0.33 22 | - label: H 23 | smiles: '[H]' 24 | SA_observable: true 25 | - label: OH 26 | smiles: '[OH]' 27 | SA_observable: true 28 | reactors: 29 | - type: gas batch constant T P 30 | T: 1000 31 | P: 1 32 | termination_conversion: 33 | 'H2': 0.9 34 | termination_time: [0.1, 'ms'] 35 | model: 36 | core_tolerance: [0.01, 0.001] 37 | options: 38 | save_simulation_profiles: true 39 | 40 | qm: 41 | adapter: ARC 42 | level_of_theory: 'b3lyp/6-31g(d,p)' 43 | job_types: 44 | rotors: false 45 | conformers: true 46 | fine: false 47 | freq: true 48 | opt: true 49 | sp: true 50 | -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | # Project information 2 | site_name: T3 3 | site_description: The Tandem Tool for automated chemical kinetic model development 4 | site_author: Alon Grinberg Dana 5 | site_url: https://reactionmechanismgenerator.github.io/T3/ 6 | 7 | # Repository 8 | repo_name: T3 9 | repo_url: https://github.com/ReactionMechanismGenerator/t3 10 | 11 | # Configuration 12 | theme: 13 | name: material 14 | language: en 15 | palette: 16 | primary: indigo 17 | accent: amber 18 | icon: 19 | repo: fontawesome/brands/github-alt 20 | features: 21 | - instant 22 | 23 | # Navigation 24 | nav: 25 | - Home: index.md 26 | - installation.md 27 | - running.md 28 | - Tutorials: 29 | - tutorials/1_no_qm.md 30 | - how_to.md 31 | - output.md 32 | - release.md 33 | - credits.md 34 | - contribute.md 35 | - cite.md 36 | - licence.md 37 | 38 | # Extras 39 | extra: 40 | social: 41 | - icon: fontawesome/brands/github-alt 42 | link: https://github.com/ReactionMechanismGenerator/T3 43 | - icon: fontawesome/brands/linkedin 44 | link: https://www.linkedin.com/in/alongd/ 45 | 46 | # Google Analytics 47 | google_analytics: 48 | - UA-16019208-2 49 | - auto 50 | 51 | # Extensions 52 | markdown_extensions: 53 | - admonition 54 | - codehilite: 55 | guess_lang: false 56 | - toc: 57 | permalink: true 58 | 59 | # Extra 60 | extra_css: 61 | - https://reactionmechanismgenerator.github.io/T3/css/termynal.css 62 | - https://reactionmechanismgenerator.github.io/T3/css/custom.css 63 | extra_javascript: 64 | - https://unpkg.com/mermaid@8.4.6/dist/mermaid.min.js 65 | - https://reactionmechanismgenerator.github.io/T3/js/termynal.js 66 | - https://reactionmechanismgenerator.github.io/T3/js/custom.js 67 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | filterwarnings = 3 | ignore::DeprecationWarning 4 | ignore::PendingDeprecationWarning 5 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Required python packages 2 | 3 | ase >= 3.15.0 4 | cclib >= 1.6 5 | coverage 6 | cython >= 0.25.2 7 | mako 8 | matplotlib >= 2.2.2 9 | mkdocs-material >= 5.1.7 10 | mkdocs-material-extensions 11 | numpy == 1.15.4 12 | paramiko == 3.4.0 13 | pandas 14 | py3Dmol == 0.8.0 15 | pyyaml 16 | pydantic 17 | pydas 18 | pytest 19 | qcelemental 20 | -------------------------------------------------------------------------------- /t3/__init__.py: -------------------------------------------------------------------------------- 1 | import t3.common 2 | import t3.utils 3 | from t3.main import T3 4 | -------------------------------------------------------------------------------- /t3/imports.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains functionality to import user settings and fill in default values from T3's settings. 3 | """ 4 | 5 | import os 6 | import sys 7 | 8 | import t3.settings.t3_settings as t3_settings 9 | from t3.settings.t3_submit import submit_scripts 10 | 11 | 12 | # Common imports where the user can optionally put a modified copy of settings.py or t3_submit.py file under ~/.t3 13 | home = os.getenv("HOME") or os.path.expanduser("~") 14 | local_t3_path = os.path.join(home, '.t3') 15 | 16 | local_t3_settings_path = os.path.join(local_t3_path, 't3_settings.py') 17 | settings = {key: val for key, val in vars(t3_settings).items() if '__' not in key} 18 | if os.path.isfile(local_t3_settings_path): 19 | local_settings = dict() 20 | if local_t3_path not in sys.path: 21 | sys.path.insert(0, local_t3_path) 22 | try: 23 | import t3_settings as local_settings 24 | except ImportError: 25 | print('No local .t3/t3_settings.py file found') 26 | if local_settings: 27 | local_settings_dict = {key: val for key, val in vars(local_settings).items() if '__' not in key} 28 | settings.update(local_settings_dict) 29 | 30 | local_t3_submit_path = os.path.join(local_t3_path, 't3_submit.py') 31 | if os.path.isfile(local_t3_submit_path): 32 | local_submit_scripts = dict() 33 | if local_t3_path != sys.path[0]: 34 | sys.path.insert(0, local_t3_path) 35 | try: 36 | from t3_submit import submit_scripts as local_submit_scripts 37 | except ImportError: 38 | print('No local .t3/t3_submit.py file found') 39 | if local_submit_scripts: 40 | submit_scripts.update(local_submit_scripts) 41 | -------------------------------------------------------------------------------- /t3/runners/__init__.py: -------------------------------------------------------------------------------- 1 | import t3.runners.rmg_runner 2 | -------------------------------------------------------------------------------- /t3/runners/rmg_incore_script.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | """ 5 | A script for running RMG incore using the rmg_env. 6 | 7 | Usage:: 8 | 9 | conda activate rmg_env 10 | 11 | running with no optional args: 12 | python-jl rmg_incore_script.py full/path/to/rmg/input.py > >(tee -a out.txt) 2> >(tee -a err.txt >&2) 13 | 14 | or with optional args: 15 | python-jl rmg_incore_script.py full/path/to/rmg/input.py -v 20 -m 100 > >(tee -a out.txt) 2> >(tee -a err.txt >&2) 16 | """ 17 | 18 | import argparse 19 | import os 20 | import sys 21 | import traceback 22 | 23 | from pydas.daspk import DASPKError 24 | 25 | from rmgpy.exceptions import (ChemicallySignificantEigenvaluesError, 26 | ChemkinError, 27 | CollisionError, 28 | CoreError, 29 | ILPSolutionError, 30 | InputError, 31 | InvalidMicrocanonicalRateError, 32 | KineticsError, 33 | ModifiedStrongCollisionError, 34 | NetworkError, 35 | PressureDependenceError, 36 | ReactionError, 37 | ReservoirStateError, 38 | StatmechError, 39 | StatmechFitError, 40 | ) 41 | from rmgpy.rmg.main import RMG 42 | from rmgpy.rmg.main import initialize_log as initialize_rmg_log 43 | 44 | 45 | def parse_command_line_arguments(command_line_args=None): 46 | """ 47 | Parse command-line arguments. 48 | 49 | Args: 50 | command_line_args: The command line arguments. 51 | 52 | Returns: 53 | The parsed command-line arguments by key words. 54 | """ 55 | 56 | parser = argparse.ArgumentParser(description='The Tandem Tool (T3) RMG incore runner script') 57 | parser.add_argument('file', metavar='FILE', type=str, nargs=1, help='The RMG input file') 58 | parser.add_argument('-v', '--verbose', type=int, nargs=1, default=20, help='the logging level') 59 | parser.add_argument('-m', '--maxiter', type=int, nargs=1, default=0, help='max rmg iterations') 60 | args = parser.parse_args(command_line_args) 61 | args.file = args.file[0] 62 | return args 63 | 64 | 65 | def main() -> None: 66 | """ 67 | Run RMG incore. 68 | """ 69 | args = parse_command_line_arguments() 70 | input_file = args.file 71 | project_directory = os.path.abspath(os.path.dirname(args.file)) 72 | 73 | initialize_rmg_log( 74 | verbose=args.verbose[0], 75 | log_file_name=os.path.join(project_directory, 'RMG.log'), 76 | ) 77 | rmg = RMG(input_file=input_file, output_directory=project_directory) 78 | rmg_kwargs = dict() 79 | if args.maxiter: 80 | rmg_kwargs['max_iterations'] = args.maxiter 81 | 82 | try: 83 | rmg.execute(initialize=True, **rmg_kwargs) 84 | except (ChemicallySignificantEigenvaluesError, 85 | ChemkinError, 86 | CollisionError, 87 | CoreError, 88 | DASPKError, 89 | ILPSolutionError, 90 | InvalidMicrocanonicalRateError, 91 | KineticsError, 92 | ModifiedStrongCollisionError, 93 | NetworkError, 94 | PressureDependenceError, 95 | ReactionError, 96 | ReservoirStateError, 97 | StatmechError, 98 | StatmechFitError, 99 | ) as e: 100 | sys.stderr.write(f'\n\n********\n' 101 | f'RMG threw an exception and did not converge.\n' # Keep this text unchanged. 102 | f'Exception type: {e.__class__}\n' 103 | f'********\n') 104 | print(f'RMG Errored with {e.__class__}. Got the following trace:') 105 | print(traceback.format_exc()) 106 | 107 | except InputError: 108 | # This exception should not be raised. 109 | print('Error: Something seems to be wrong with the RMG input file, please check your input.') 110 | raise 111 | 112 | 113 | if __name__ == '__main__': 114 | main() 115 | -------------------------------------------------------------------------------- /t3/settings/t3_settings.py: -------------------------------------------------------------------------------- 1 | """ 2 | T3's settings 3 | 4 | You may keep a short version of this file in a local ".t3" folder under your home folder. 5 | Any definitions made to the local file will take precedence over this file. 6 | """ 7 | 8 | 9 | # The execution type can be either 'incore', i.e., executed in the same processor, 10 | # or 'local', i.e., to be submitted to the server queue if running on a server. 11 | # If running on a local server, ARC's settings for ``local`` will be used. 12 | execution_type = { 13 | 'rmg': 'local', 14 | 'arc': 'incore', 15 | } 16 | 17 | servers = { 18 | 'local': { 19 | 'cluster_soft': 'PBS', 20 | 'cpus': 16, 21 | 'max mem': 40, # GB 22 | }, 23 | } 24 | 25 | check_status_command = {'OGE': 'export SGE_ROOT=/opt/sge; /opt/sge/bin/lx24-amd64/qstat -u $USER', 26 | 'Slurm': '/usr/bin/squeue -u $USER', 27 | 'PBS': '/usr/local/bin/qstat -u $USER', 28 | 'HTCondor': """condor_q -cons 'Member(Jobstatus,{1,2})' -af:j '{"0","P","R","X","C","H",">","S"}[JobStatus]' RequestCpus RequestMemory JobName '(Time() - EnteredCurrentStatus)'""", 29 | } 30 | 31 | submit_command = {'OGE': 'export SGE_ROOT=/opt/sge; /opt/sge/bin/lx24-amd64/qsub', 32 | 'Slurm': '/usr/bin/sbatch', 33 | 'PBS': '/usr/local/bin/qsub', 34 | 'HTCondor': 'condor_submit', 35 | } 36 | 37 | submit_filenames = {'OGE': 'submit.sh', 38 | 'Slurm': 'submit.sl', 39 | 'PBS': 'submit.sh', 40 | 'HTCondor': 'submit.sub', 41 | } 42 | 43 | rmg_initial_memory = 25 # The initial memory for an RMG job when submitted to the queue, in GB 44 | -------------------------------------------------------------------------------- /t3/settings/t3_submit.py: -------------------------------------------------------------------------------- 1 | """ 2 | Submit scripts 3 | """ 4 | 5 | # Submission scripts stored as a dictionary with software as the primary key. 6 | submit_scripts = { 7 | # 'rmg': """#!/bin/bash -l 8 | # #SBATCH -J {name} 9 | # #SBATCH -t 05-00:00:00 10 | # #SBATCH -o out.txt 11 | # #SBATCH -e err.txt 12 | # #SBATCH --ntasks={cpus} 13 | # #SBATCH --mem-per-cpu={memory / cpus} 14 | # 15 | # 16 | # export PYTHONPATH=$PYTHONPATH:~/Code/RMG-Py/ 17 | # 18 | # conda activate rmg_env 19 | # 20 | # touch initial_time 21 | # 22 | # python-jl ~/Code/RMG-Py/rmg.py -n {cpus} input.py{max_iterations} 23 | # 24 | # touch final_time 25 | # 26 | # """, 27 | # 'rmg': """Universe = vanilla 28 | # 29 | # +JobName = "{name}" 30 | # 31 | # log = job.log 32 | # output = out.txt 33 | # error = err.txt 34 | # 35 | # getenv = True 36 | # 37 | # should_transfer_files = no 38 | # 39 | # executable = job.sh 40 | # 41 | # request_cpus = {cpus} 42 | # request_memory = {memory}MB 43 | # 44 | # queue 45 | # 46 | # """, 47 | # 'rmg_job': """#!/bin/bash -l 48 | # 49 | # touch initial_time 50 | # 51 | # source /srv01/technion/$USER/.bashrc 52 | # 53 | # conda activate rmg_env 54 | # 55 | # python-jl /Local/ce_dana/Code/RMG-Py/rmg.py -n {cpus} input.py{max_iterations} 56 | # 57 | # touch final_time 58 | # 59 | # """, 60 | 'rmg': """#!/bin/bash -l 61 | 62 | #PBS -N {name} 63 | #PBS -q zeus_long_q 64 | #PBS -l walltime=168:00:00 65 | #PBS -l select=1:ncpus={cpus} 66 | #PBS -o out.txt 67 | #PBS -e err.txt 68 | 69 | PBS_O_WORKDIR={workdir} 70 | cd $PBS_O_WORKDIR 71 | 72 | conda activate rmg_env 73 | 74 | touch initial_time 75 | 76 | python-jl $rmgpy_path/rmg.py -n {cpus} input.py{max_iterations} 77 | 78 | touch final_time 79 | 80 | """, 81 | } 82 | -------------------------------------------------------------------------------- /t3/simulate/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Initialize imports for the simulator modules. 3 | """ 4 | 5 | from t3.simulate.adapter import SimulateAdapter 6 | from t3.simulate.factory import simulate_factory, _registered_simulate_adapters 7 | from t3.simulate.cantera_constantTP import CanteraConstantTP 8 | from t3.simulate.cantera_constantHP import CanteraConstantHP 9 | from t3.simulate.cantera_constantUV import CanteraConstantUV 10 | from t3.simulate.rmg_constantTP import RMGConstantTP 11 | -------------------------------------------------------------------------------- /t3/simulate/adapter.py: -------------------------------------------------------------------------------- 1 | """ 2 | A module for the abstract SimulateAdapter class. 3 | This class allows users to easily simulate a mechanism and perform analysis with external packages such as 4 | RMG, RMS, or Cantera. 5 | """ 6 | 7 | from abc import ABC, abstractmethod 8 | 9 | 10 | class SimulateAdapter(ABC): 11 | """ 12 | An abstract Simulate Adapter class 13 | """ 14 | 15 | @abstractmethod 16 | def set_up(self): 17 | """ 18 | Set up the class, possibly by reading an input file, initializing values, and/or setting up the domain. 19 | """ 20 | pass 21 | 22 | @abstractmethod 23 | def simulate(self): 24 | """ 25 | Simulate a job to obtain species profiles. Run sensitivity analysis if requested. 26 | """ 27 | pass 28 | 29 | @abstractmethod 30 | def get_sa_coefficients(self): 31 | """ 32 | Obtain the sensitivity analysis coefficients. 33 | 34 | Returns: 35 | sa_dict (dict): a SA dictionary, whose structure is given in the docstring for T3/t3/main.py 36 | """ 37 | pass 38 | 39 | @abstractmethod 40 | def get_idt_by_T(self): 41 | """ 42 | Finds the ignition point by approximating dT/dt as a first order forward difference 43 | and then finds the point of maximum slope. 44 | 45 | Returns: 46 | idt_dict (dict): Dictionary whose keys include 'idt' and 'idt_index' and whose values are lists of 47 | the ignition delay time in seconds and index at which idt occurs respectively. 48 | """ 49 | pass 50 | -------------------------------------------------------------------------------- /t3/simulate/factory.py: -------------------------------------------------------------------------------- 1 | """ 2 | A module for generating simulate adapters. 3 | """ 4 | 5 | from typing import TYPE_CHECKING, List, Optional, Type 6 | 7 | from t3.simulate.adapter import SimulateAdapter 8 | 9 | if TYPE_CHECKING: 10 | from t3.logger import Logger 11 | 12 | _registered_simulate_adapters = {} 13 | 14 | 15 | def register_simulate_adapter(simulator: str, 16 | simulate_class: Type[SimulateAdapter], 17 | ) -> None: 18 | """ 19 | A register for the simulate adapters. 20 | 21 | Args: 22 | simulator (str): A string representation for a simulate adapter. 23 | simulate_class (Type[SimulateAdapter]): The simulate adapter class. 24 | 25 | Raises: 26 | TypeError: If ``simulate_class`` is not a ``SimulateAdapter`` instance. 27 | """ 28 | if not issubclass(simulate_class, SimulateAdapter): 29 | raise TypeError(f'simulate_class is not a SimulateAdapter, got {simulate_class} which is a {type(simulate_class)}') 30 | _registered_simulate_adapters[simulator] = simulate_class 31 | 32 | 33 | def simulate_factory(simulate_method: str, 34 | t3: dict, 35 | rmg: dict, 36 | paths: dict, 37 | logger: 'Logger', 38 | atol: float, 39 | rtol: float, 40 | observable_list: Optional[list] = None, 41 | sa_atol: float = 1e-6, 42 | sa_rtol: float = 1e-4, 43 | global_observables: Optional[List[str]] = None, 44 | ) -> SimulateAdapter: 45 | """ 46 | A factory generating the simulate adapter corresponding to ``simulate_adapter``. 47 | 48 | Args: 49 | simulate_method (str): The simulate adapter name. Examples: 'RMGConstantTP', 'RMSConstantTP', 50 | or 'CanteraConstantTP'. 51 | t3 (dict): The T3.t3 attribute, which is a dictionary containing the t3 block from the input yaml or API. 52 | rmg (dict): The T3.rmg attribute, which is a dictionary containing the rmg block from the input yaml or API. 53 | paths (dict): The T3.paths attribute, which is a dictionary containing relevant paths. 54 | logger (Type[Logger]): The current T3 Logger instance. 55 | atol (float): The absolute tolerance used when integrating. 56 | rtol (float): The relative tolerance used when integrating. 57 | observable_list (Optional[list]): Species used for SA. Entries are species labels as strings. Example: ['OH'] 58 | sa_atol (float, optional): The absolute tolerance used when performing sensitivity analysis. 59 | sa_rtol (float, optional): The relative tolerance used when performing sensitivity analysis. 60 | global_observables (Optional[List[str]]): List of global observables ['IgD', 'ESR', 'SL'] used by Cantera. 61 | 62 | Raises: 63 | ValueError: If the provided simulate_method is not in the keys for the _registered_simulate_adapters dictionary. 64 | 65 | Returns: 66 | SimulateAdapter: The requested SimulateAdapter child, initialized with the respective arguments. 67 | """ 68 | 69 | if simulate_method not in _registered_simulate_adapters.keys(): 70 | raise ValueError(f'The "simulate_method" argument of {simulate_method} was not present in the keys for the ' 71 | f'_registered_simulate_adapters dictionary: {list(_registered_simulate_adapters.keys())}' 72 | f'\nPlease check that the simulate adapter was registered properly.') 73 | 74 | simulate_adapter_class = _registered_simulate_adapters[simulate_method](t3=t3, 75 | rmg=rmg, 76 | paths=paths, 77 | logger=logger, 78 | atol=atol, 79 | rtol=rtol, 80 | observable_list=observable_list, 81 | sa_atol=sa_atol, 82 | sa_rtol=sa_rtol, 83 | global_observables=global_observables, 84 | ) 85 | return simulate_adapter_class 86 | -------------------------------------------------------------------------------- /t3/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from t3.utils.dependencies import check_dependencies 2 | from t3.utils.generator import generate_radicals 3 | from t3.utils.writer import write_rmg_input_file 4 | -------------------------------------------------------------------------------- /t3/utils/dependencies.py: -------------------------------------------------------------------------------- 1 | """ 2 | t3 utils dependencies module 3 | """ 4 | 5 | 6 | def check_dependencies(): 7 | """ 8 | Check that RMG and ARC are available. 9 | """ 10 | rmg_available, arc_available = True, True 11 | try: 12 | from rmgpy.rmg.main import RMG 13 | except ImportError: 14 | rmg_available = False 15 | try: 16 | from arc import ARC 17 | except ImportError: 18 | arc_available = False 19 | 20 | if not rmg_available or not arc_available: 21 | msg = 'Error: Cannot execute T3. Missing the following critical component(s):\n' 22 | if not rmg_available: 23 | msg += ' - RMG\n' 24 | msg += ' (See https://reactionmechanismgenerator.github.io/RMG-Py/users/rmg/installation/index.html)\n' 25 | if not arc_available: 26 | msg += ' - ARC\n' 27 | msg += ' (See https://reactionmechanismgenerator.github.io/ARC/installation.html)\n' 28 | msg += '\nInstall the missing packages, make sure they were added to the PYTHONPATH, and rerun T3.' 29 | print(msg) 30 | raise ValueError(f'T3 is missing core dependencies, see the above message.') 31 | -------------------------------------------------------------------------------- /t3/utils/fix_cantera.py: -------------------------------------------------------------------------------- 1 | """ 2 | t3 utils fix_cantera module 3 | A module to automatically fix issues with RMG-generated Cantera files, mainly resolving mislabeled duplicate reactions. 4 | """ 5 | import os 6 | 7 | from typing import List, Optional 8 | 9 | import shutil 10 | import time 11 | import traceback 12 | 13 | import cantera as ct 14 | 15 | from arc.common import read_yaml_file, save_yaml_file 16 | 17 | 18 | def get_traceback(model_path: str) -> Optional[str]: 19 | """ 20 | Try loading the Cantera model and return the traceback if it fails. 21 | 22 | Args: 23 | model_path (str): The path to the cantera YAML model file. 24 | 25 | Returns: 26 | Optional[str]: The traceback if the model fails to load. 27 | """ 28 | tb = None 29 | try: 30 | ct.Solution(model_path) 31 | except ct.CanteraError: 32 | tb = traceback.format_exc() 33 | return tb 34 | 35 | 36 | def fix_cantera(model_path: str): 37 | """ 38 | Fix a Cantera model that has incorrectly marked duplicate reactions. 39 | Creates a backup copy of the Cantera model and fixes the content of the original file in place. 40 | 41 | Args: 42 | model_path (str): The path to the cantera YAML model file. 43 | 44 | Returns: 45 | bool: Whether the model was fixed. 46 | """ 47 | shutil.copyfile(model_path, model_path + '.bak') 48 | done, fixed = False, False 49 | counter = 0 50 | while not done and counter < 1000: 51 | counter += 1 52 | tb = get_traceback(model_path) 53 | if tb is None: 54 | done = True 55 | break 56 | else: 57 | if 'Undeclared duplicate reactions detected' in tb: 58 | fix_undeclared_duplicate_reactions(model_path, tb) 59 | fixed = True 60 | elif 'No duplicate found for declared duplicate reaction' in tb: 61 | fix_no_duplicate_found(model_path, tb) 62 | fixed = True 63 | else: 64 | print(f'Could not fix {model_path}:\n\n{tb}') 65 | break 66 | time.sleep(1) 67 | if fixed: 68 | print(f'Fixing Cantera model {model_path} (and creating a backup copy with a .bak extension).') 69 | else: 70 | os.remove(model_path + '.bak') 71 | return done 72 | 73 | 74 | def fix_undeclared_duplicate_reactions(model_path: str, tb: str): 75 | """ 76 | Fix a Cantera model that has undeclared duplicate reactions. 77 | 78 | Args: 79 | model_path (str): The path to the cantera YAML model file. 80 | tb (str): The traceback. 81 | """ 82 | content = read_yaml_file(model_path) 83 | rxns = get_dup_rxn_indices(tb) 84 | print(f'Marking reactions {", ".join([str(r) for r in rxns])} as duplicate.') 85 | for i in rxns: 86 | content['reactions'][i - 1]['duplicate'] = True 87 | save_yaml_file(model_path, content) 88 | 89 | 90 | def fix_no_duplicate_found(model_path: str, tb: str): 91 | """ 92 | Fix a Cantera model that has a reaction marked as duplicate by mistake with no other duplicate reaction. 93 | 94 | Args: 95 | model_path (str): The path to the cantera YAML model file. 96 | tb (str): The traceback. 97 | """ 98 | content = read_yaml_file(model_path) 99 | rxns = get_mistakenly_marked_dup_rxns(tb) 100 | for i in rxns: 101 | if 'duplicate' in content['reactions'][i].keys(): 102 | print(f'Marking reaction {i} as non-duplicate.') 103 | del content['reactions'][i]['duplicate'] 104 | save_yaml_file(model_path, content) 105 | 106 | 107 | def get_dup_rxn_indices(tb: str) -> List[int]: 108 | """ 109 | Get the duplicate reactions from the traceback. 110 | 111 | Args: 112 | tb (str): The traceback. 113 | 114 | Returns: 115 | List[int]: The reactions indices. 116 | """ 117 | rxns = list() 118 | if tb is None: 119 | return rxns 120 | lines = tb.split('\n') 121 | read = False 122 | for line in lines: 123 | if 'Undeclared duplicate reactions detected:' in line: 124 | read = True 125 | if '| Line |' in line: 126 | break 127 | if read and 'Reaction' in line: 128 | rxns.append(int(line.split()[1].split(':')[0])) 129 | return rxns 130 | 131 | 132 | def get_mistakenly_marked_dup_rxns(tb: str) -> List[int]: 133 | """ 134 | Get the duplicate reactions from the traceback. 135 | 136 | Args: 137 | tb (str): The traceback. 138 | 139 | Returns: 140 | List[int]: The reactions indices. 141 | """ 142 | rxns = list() 143 | if tb is None: 144 | return rxns 145 | lines = tb.split('\n') 146 | for line in lines: 147 | if 'No duplicate found for declared duplicate reaction number' in line: 148 | rxns.append(int(line.split()[8])) 149 | return rxns 150 | -------------------------------------------------------------------------------- /t3/utils/generator.py: -------------------------------------------------------------------------------- 1 | """ 2 | t3 utils generator module 3 | 4 | Used to generate specific species and reactions. 5 | """ 6 | 7 | from typing import List 8 | 9 | from rmgpy.molecule.molecule import Atom, Bond 10 | from rmgpy.species import Species 11 | 12 | from arc.common import generate_resonance_structures 13 | from arc.species import ARCSpecies 14 | 15 | 16 | def generate_radicals(species: Species, 17 | types: List[str], 18 | react_aromatic_rings: bool = False, 19 | ): 20 | """ 21 | Generate all radicals for a species by radical type. 22 | 23 | Args: 24 | species (Species): The RMG Species instance to process. 25 | The ``label`` attribute of ``species`` should not be empty. 26 | types (List[str]): Entries are types of radicals to return. 27 | react_aromatic_rings (bool, optional): Whether to also consider hydrogen atoms on aromatic rings. 28 | Default: ``False``. 29 | 30 | Returns: 31 | List[Tuple[str, str]]: Entries are tuples representing the generated radical species, 32 | the first entry in the tuple is a label, 33 | the second entry is the respective SMILES representation. 34 | """ 35 | existing_radical_indices, output, aromatic_rings, output_species = list(), list(), list(), list() 36 | if species is None or len(species.molecule[0].atoms) == 1 \ 37 | or not any(atom.is_hydrogen() for atom in species.molecule[0].atoms): 38 | return output 39 | spc = ARCSpecies(label=species.label, adjlist=species.copy(deep=True).to_adjacency_list(), keep_mol=True) 40 | res_structures = generate_resonance_structures(spc.mol) 41 | spc.mol = res_structures[0] if res_structures is not None else spc.mol 42 | spc.mol.atoms = [a for a in spc.mol.atoms if not a.is_hydrogen()] + [a for a in spc.mol.atoms if a.is_hydrogen()] 43 | spc.final_xyz = spc.get_xyz(generate=True) 44 | spc.bdes = list() 45 | i = 0 46 | for atom_1 in spc.mol.atoms: 47 | if not atom_1.is_hydrogen(): 48 | for atom_2, bond_12 in atom_1.edges.items(): 49 | if atom_2.is_hydrogen() and bond_12.is_single(): 50 | # skipping hydrogen bonds 51 | break 52 | else: 53 | continue 54 | if spc.mol.atoms.index(atom_1) in existing_radical_indices: 55 | continue 56 | if not react_aromatic_rings and any(bond.is_benzene() for bond in atom_1.edges.values()): 57 | continue 58 | existing_radical_indices.append(spc.mol.atoms.index(atom_1)) 59 | i += 1 60 | spc.bdes.append((spc.mol.atoms.index(atom_1) + 1, spc.mol.atoms.index(atom_2) + 1)) 61 | 62 | radicals = [rad for rad in spc.scissors(sort_atom_labels=True) if rad.label != 'H'] 63 | 64 | rad_i, alkoxyl_i, peroxyl_i = 0, 0, 0 65 | for i, rad in enumerate(radicals): 66 | if 'radical' in types: 67 | if not any(rad.is_isomorphic(spc) for spc in output_species): 68 | output_species.append(rad) 69 | output.append((f'{species.label}_radical_{rad_i}', rad.mol.copy(deep=True).to_smiles())) 70 | rad_i += 1 71 | if 'alkoxyl' in types: 72 | alkoxyl = rad.copy() 73 | alkoxyl.mol_list = None 74 | oxygen = Atom(element='O', radical_electrons=1, charge=0, lone_pairs=2) 75 | alkoxyl.mol.add_atom(oxygen) 76 | alkoxyl.mol.atoms[existing_radical_indices[i]].decrement_radical() 77 | new_bond = Bond(atom1=alkoxyl.mol.atoms[existing_radical_indices[i]], atom2=oxygen, order=1) 78 | alkoxyl.mol.add_bond(new_bond) 79 | if not any(alkoxyl.is_isomorphic(spc) for spc in output_species): 80 | output_species.append(alkoxyl) 81 | output.append((f'{species.label}_alkoxyl_{alkoxyl_i}', alkoxyl.mol.to_smiles())) 82 | alkoxyl_i += 1 83 | if 'peroxyl' in types: 84 | peroxyl = rad.copy() 85 | peroxyl.mol_list = None 86 | oxygen_1 = Atom(element='O', radical_electrons=0, charge=0, lone_pairs=2) 87 | oxygen_2 = Atom(element='O', radical_electrons=1, charge=0, lone_pairs=2) 88 | peroxyl.mol.add_atom(oxygen_1) 89 | peroxyl.mol.add_atom(oxygen_2) 90 | peroxyl.mol.atoms[existing_radical_indices[i]].decrement_radical() 91 | new_bond_1 = Bond(atom1=peroxyl.mol.atoms[existing_radical_indices[i]], atom2=oxygen_1, order=1) 92 | new_bond_2 = Bond(atom1=oxygen_1, atom2=oxygen_2, order=1) 93 | peroxyl.mol.add_bond(new_bond_1) 94 | peroxyl.mol.add_bond(new_bond_2) 95 | if not any(peroxyl.is_isomorphic(spc) for spc in output_species): 96 | output_species.append(peroxyl) 97 | output.append((f'{species.label}_peroxyl_{peroxyl_i}', peroxyl.mol.to_smiles())) 98 | peroxyl_i += 1 99 | 100 | return output 101 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Initializing the t3 tests module 3 | """ 4 | -------------------------------------------------------------------------------- /tests/common.py: -------------------------------------------------------------------------------- 1 | """ 2 | t3 tests common module 3 | """ 4 | 5 | from typing import Optional 6 | import os 7 | import shutil 8 | 9 | from rmgpy.molecule import Molecule 10 | 11 | from arc.common import read_yaml_file 12 | 13 | from t3.common import EXAMPLES_BASE_PATH, PROJECTS_BASE_PATH 14 | from t3.main import T3 15 | 16 | 17 | def run_minimal(project: Optional[str] = None, 18 | project_directory: Optional[str] = None, 19 | iteration: Optional[int] = None, 20 | set_paths: bool = False, 21 | ) -> T3: 22 | """ 23 | A helper function for running the minimal example. 24 | 25 | Args: 26 | project (str, optional): The project name. 27 | project_directory (str, optional): The project directory. 28 | iteration (int, optional): The iteration number. 29 | set_paths (bool, optional): Whether to set the paths. 30 | 31 | Returns: 32 | T3: The T3 object. 33 | """ 34 | minimal_input = os.path.join(EXAMPLES_BASE_PATH, 'minimal', 'input.yml') 35 | input_dict = read_yaml_file(path=minimal_input) 36 | input_dict['verbose'] = 10 37 | input_dict['project_directory'] = project_directory \ 38 | or os.path.join(PROJECTS_BASE_PATH, 'test_minimal_delete_after_usage') 39 | if project is not None: 40 | input_dict['project'] = project 41 | t3 = T3(**input_dict) 42 | t3.iteration = iteration or 0 43 | if set_paths: 44 | t3.set_paths() 45 | return t3 46 | 47 | 48 | def isomorphic_smiles(smiles_1: str, 49 | smiles_2: str, 50 | ) -> bool: 51 | """ 52 | Check whether two SMILES strings represent isomorphic molecules. 53 | 54 | Args: 55 | smiles_1: A SMILES string. 56 | smiles_2: A SMILES string. 57 | 58 | Returns: 59 | bool: Whether the two SMILES strings represent isomorphic molecules. 60 | """ 61 | mol_1 = Molecule(smiles=smiles_1) 62 | mol_2 = Molecule(smiles=smiles_2) 63 | return mol_1.is_isomorphic(mol_2) 64 | 65 | 66 | def check_expected_generated_radicals(radicals: list, expected_radicals: list): 67 | """ 68 | A helper function for testing the generator. 69 | """ 70 | assert len(expected_radicals) == len(set([rad[0] for rad in radicals])) 71 | assert len(expected_radicals) == len(set([rad[1] for rad in radicals])) 72 | expected_labels = [expected_rad_tuple[0] for expected_rad_tuple in expected_radicals] 73 | for rad_tuple in radicals: 74 | assert rad_tuple[0] in expected_labels 75 | assert any(isomorphic_smiles(rad_tuple[1], expected_rad_tuple[1]) for expected_rad_tuple in expected_radicals) 76 | 77 | 78 | def almost_equal(a: float, 79 | b: float, 80 | places: int = 4, 81 | ratio: Optional[float] = None, 82 | ) -> bool: 83 | """ 84 | A helper function for testing almost equal assertions. 85 | 86 | Args: 87 | a (float): The first number. 88 | b (float): The second number. 89 | places (int, optional): The number of decimal places to round to. Default is 4. 90 | ratio (float, optional): The ratio between the two numbers. Default is None. 91 | """ 92 | if ratio is not None: 93 | return abs(a - b) / abs(a) < ratio 94 | return round(abs(a - b), places) == 0 95 | 96 | 97 | def copy_model(model_path: str, name: str = '') -> str: 98 | """ 99 | Copy a model to a temporary location. 100 | 101 | Args: 102 | model_path (str): The path to the model to copy. 103 | name (str, optional): A unique name for the copied model in addition to "temp_". 104 | 105 | Returns: 106 | str: The path to the copied model. 107 | """ 108 | model_path = os.path.abspath(model_path) 109 | model_name = os.path.basename(model_path) 110 | model_dir = os.path.dirname(model_path) 111 | name = f'{name}_' if name else '' 112 | new_model_path = os.path.join(model_dir, f'temp_{name}' + model_name) 113 | shutil.copyfile(model_path, new_model_path) 114 | return new_model_path 115 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/RMG.log: -------------------------------------------------------------------------------- 1 | dummy RMG log file 2 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/chemkin/chem.inp: -------------------------------------------------------------------------------- 1 | dummy chem.inp 2 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/chemkin/chem0113.inp: -------------------------------------------------------------------------------- 1 | dummy 2 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/chemkin/chem_annotated.inp: -------------------------------------------------------------------------------- 1 | ELEMENTS 2 | H 3 | D /2.014/ 4 | T /3.016/ 5 | C 6 | CI /13.003/ 7 | O 8 | OI /17.999/ 9 | N 10 | Ne 11 | Ar 12 | He 13 | Si 14 | S 15 | F 16 | Cl 17 | Br 18 | I 19 | X /195.083/ 20 | END 21 | 22 | SPECIES 23 | Ar ! Ar 24 | Ne ! Ne 25 | furfuryl(1) ! furfuryl(1) 26 | END 27 | 28 | 29 | 30 | THERM ALL 31 | 300.000 1000.000 5000.000 32 | 33 | ! Thermo library: primaryThermoLibrary 34 | Ar Ar 1 G 200.000 6000.000 1000.00 1 35 | 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 36 | -7.45375000E+02 4.37967000E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 37 | 0.00000000E+00 0.00000000E+00-7.45375000E+02 4.37967000E+00 4 38 | 39 | ! Thermo library: primaryThermoLibrary 40 | Ne Ne 1 G 200.000 6000.000 1000.00 1 41 | 2.50000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 0.00000000E+00 2 42 | -7.45375000E+02 3.35532000E+00 2.50000000E+00 0.00000000E+00 0.00000000E+00 3 43 | 0.00000000E+00 0.00000000E+00-7.45375000E+02 3.35532000E+00 4 44 | 45 | ! Thermo library: 2FFOH_thermo 46 | furfuryl(1) C 5H 6O 2 G 10.000 3000.000 992.72 1 47 | 6.39130000E+00 3.56842000E-02-1.91804000E-05 4.95507000E-09-4.98206000E-13 2 48 | -3.04566000E+04-4.85274000E+00 3.89525000E+00 2.62426000E-02 2.45489000E-05 3 49 | -4.41978000E-08 1.68630000E-11-2.90002000E+04 1.20103000E+01 4 50 | 51 | END 52 | 53 | 54 | 55 | REACTIONS KCAL/MOLE MOLES 56 | 57 | ! Reaction index: Chemkin #1; RMG #1 58 | ! Library reaction: C2H2_init 59 | ! Flux pairs: acetylene(2), C4H4(17); acetylene(2), C4H4(17); 60 | acetylene(2)+acetylene(2)<=>C4H4(17) 1.000e+00 0.000 0.000 61 | PLOG/ 0.000987 1.280e+54 -12.650 68.650 / 62 | PLOG/ 0.000987 1.770e+88 -24.080 73.900 / 63 | PLOG/ 0.009869 3.090e+36 -7.640 56.790 / 64 | PLOG/ 0.009869 1.490e+62 -14.560 79.730 / 65 | PLOG/ 0.098690 2.690e+52 -11.490 76.010 / 66 | PLOG/ 0.098690 2.480e+41 -9.120 58.940 / 67 | PLOG/ 0.986900 2.640e+44 -8.980 74.000 / 68 | PLOG/ 0.986900 3.000e+33 -6.640 56.150 / 69 | PLOG/ 9.869000 4.300e+23 -3.600 52.310 / 70 | PLOG/ 9.869000 7.660e+33 -5.840 69.450 / 71 | PLOG/ 98.690000 6.500e+26 -3.750 67.720 / 72 | PLOG/ 98.690000 9.560e+11 0.000 47.720 / 73 | 74 | ! Reaction index: Chemkin #1221; RMG #45542 75 | ! PDep reaction: PDepNetwork #226 76 | ! Flux pairs: CHCHO(202), C2H2O(15133); 77 | CHCHO(202)(+M)<=>C2H2O(15133)(+M) 1.000e+00 0.000 0.000 78 | TCHEB/ 300.000 2000.000 / 79 | PCHEB/ 0.005 98.692 / 80 | CHEB/ 6 4/ 81 | CHEB/ -1.944e+00 2.172e+00 7.470e-04 -1.384e-03 / 82 | CHEB/ 7.878e+00 4.088e-02 1.565e-03 -2.606e-03 / 83 | CHEB/ -1.853e-01 3.476e-02 1.717e-03 -2.170e-03 / 84 | CHEB/ -4.447e-02 2.642e-02 1.817e-03 -1.576e-03 / 85 | CHEB/ -2.767e-02 1.779e-02 1.748e-03 -9.650e-04 / 86 | CHEB/ -2.493e-02 1.046e-02 1.480e-03 -4.577e-04 / 87 | 88 | END 89 | 90 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/chemkin/chem_edge.inp: -------------------------------------------------------------------------------- 1 | dummy chem edge file 2 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/chemkin/chem_edge_annotated.inp: -------------------------------------------------------------------------------- 1 | dummy chem edge annotated file 2 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/chemkin/species_dictionary.txt: -------------------------------------------------------------------------------- 1 | Ar 2 | 1 Ar u0 p4 c0 3 | 4 | Ne 5 | 1 Ne u0 p4 c0 6 | 7 | furfuryl(1) 8 | 1 O u0 p2 c0 {4,S} {7,S} 9 | 2 O u0 p2 c0 {3,S} {13,S} 10 | 3 C u0 p0 c0 {2,S} {4,S} {8,S} {9,S} 11 | 4 C u0 p0 c0 {1,S} {3,S} {5,D} 12 | 5 C u0 p0 c0 {4,D} {6,S} {10,S} 13 | 6 C u0 p0 c0 {5,S} {7,D} {11,S} 14 | 7 C u0 p0 c0 {1,S} {6,D} {12,S} 15 | 8 H u0 p0 c0 {3,S} 16 | 9 H u0 p0 c0 {3,S} 17 | 10 H u0 p0 c0 {5,S} 18 | 11 H u0 p0 c0 {6,S} 19 | 12 H u0 p0 c0 {7,S} 20 | 13 H u0 p0 c0 {2,S} 21 | 22 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/chemkin/species_edge_dictionary.txt: -------------------------------------------------------------------------------- 1 | Ar 2 | 1 Ar u0 p4 c0 3 | 4 | Ne 5 | 1 Ne u0 p4 c0 6 | 7 | furfuryl(1) 8 | 1 O u0 p2 c0 {4,S} {7,S} 9 | 2 O u0 p2 c0 {3,S} {13,S} 10 | 3 C u0 p0 c0 {2,S} {4,S} {8,S} {9,S} 11 | 4 C u0 p0 c0 {1,S} {3,S} {5,D} 12 | 5 C u0 p0 c0 {4,D} {6,S} {10,S} 13 | 6 C u0 p0 c0 {5,S} {7,D} {11,S} 14 | 7 C u0 p0 c0 {1,S} {6,D} {12,S} 15 | 8 H u0 p0 c0 {3,S} 16 | 9 H u0 p0 c0 {3,S} 17 | 10 H u0 p0 c0 {5,S} 18 | 11 H u0 p0 c0 {6,S} 19 | 12 H u0 p0 c0 {7,S} 20 | 13 H u0 p0 c0 {2,S} 21 | 22 | C8H11O(18549) 23 | multiplicity 2 24 | 1 O u0 p2 c0 {2,S} {4,S} 25 | 2 C u0 p0 c0 {1,S} {5,S} {6,S} {10,S} 26 | 3 C u0 p0 c0 {5,S} {8,S} {11,S} {12,S} 27 | 4 C u0 p0 c0 {1,S} {7,S} {13,S} {14,S} 28 | 5 C u1 p0 c0 {2,S} {3,S} {15,S} 29 | 6 C u0 p0 c0 {2,S} {7,D} {16,S} 30 | 7 C u0 p0 c0 {4,S} {6,D} {17,S} 31 | 8 C u0 p0 c0 {3,S} {9,D} {18,S} 32 | 9 C u0 p0 c0 {8,D} {19,S} {20,S} 33 | 10 H u0 p0 c0 {2,S} 34 | 11 H u0 p0 c0 {3,S} 35 | 12 H u0 p0 c0 {3,S} 36 | 13 H u0 p0 c0 {4,S} 37 | 14 H u0 p0 c0 {4,S} 38 | 15 H u0 p0 c0 {5,S} 39 | 16 H u0 p0 c0 {6,S} 40 | 17 H u0 p0 c0 {7,S} 41 | 18 H u0 p0 c0 {8,S} 42 | 19 H u0 p0 c0 {9,S} 43 | 20 H u0 p0 c0 {9,S} 44 | 45 | C8H12O2(20177) 46 | 1 O u0 p2 c0 {3,S} {6,S} 47 | 2 O u0 p2 c0 {10,D} 48 | 3 C u0 p0 c0 {1,S} {4,S} {5,S} {8,S} 49 | 4 C u0 p0 c0 {3,S} {7,S} {10,S} {11,S} 50 | 5 C u0 p0 c0 {3,S} {14,S} {15,S} {19,S} 51 | 6 C u0 p0 c0 {1,S} {9,S} {12,S} {13,S} 52 | 7 C u0 p0 c0 {4,S} {16,S} {17,S} {18,S} 53 | 8 C u0 p0 c0 {3,S} {9,D} {21,S} 54 | 9 C u0 p0 c0 {6,S} {8,D} {20,S} 55 | 10 C u0 p0 c0 {2,D} {4,S} {22,S} 56 | 11 H u0 p0 c0 {4,S} 57 | 12 H u0 p0 c0 {6,S} 58 | 13 H u0 p0 c0 {6,S} 59 | 14 H u0 p0 c0 {5,S} 60 | 15 H u0 p0 c0 {5,S} 61 | 16 H u0 p0 c0 {7,S} 62 | 17 H u0 p0 c0 {7,S} 63 | 18 H u0 p0 c0 {7,S} 64 | 19 H u0 p0 c0 {5,S} 65 | 20 H u0 p0 c0 {9,S} 66 | 21 H u0 p0 c0 {8,S} 67 | 22 H u0 p0 c0 {10,S} 68 | 69 | C3H4O2(20308) 70 | multiplicity 3 71 | 1 O u0 p2 c0 {3,S} {9,S} 72 | 2 O u0 p2 c0 {5,D} 73 | 3 C u0 p0 c0 {1,S} {4,S} {5,S} {6,S} 74 | 4 C u1 p0 c0 {3,S} {7,S} {8,S} 75 | 5 C u1 p0 c0 {2,D} {3,S} 76 | 6 H u0 p0 c0 {3,S} 77 | 7 H u0 p0 c0 {4,S} 78 | 8 H u0 p0 c0 {4,S} 79 | 9 H u0 p0 c0 {1,S} 80 | 81 | C4H6O2(20309) 82 | multiplicity 3 83 | 1 O u0 p2 c0 {3,S} {12,S} 84 | 2 O u0 p2 c0 {6,D} 85 | 3 C u0 p0 c0 {1,S} {4,S} {6,S} {7,S} 86 | 4 C u0 p0 c0 {3,S} {5,S} {8,S} {9,S} 87 | 5 C u1 p0 c0 {4,S} {10,S} {11,S} 88 | 6 C u1 p0 c0 {2,D} {3,S} 89 | 7 H u0 p0 c0 {3,S} 90 | 8 H u0 p0 c0 {4,S} 91 | 9 H u0 p0 c0 {4,S} 92 | 10 H u0 p0 c0 {5,S} 93 | 11 H u0 p0 c0 {5,S} 94 | 12 H u0 p0 c0 {1,S} 95 | 96 | C3H7O(20310) 97 | multiplicity 2 98 | 1 O u0 p2 c0 {2,S} {11,S} 99 | 2 C u0 p0 c0 {1,S} {3,S} {4,S} {5,S} 100 | 3 C u0 p0 c0 {2,S} {6,S} {7,S} {8,S} 101 | 4 C u1 p0 c0 {2,S} {9,S} {10,S} 102 | 5 H u0 p0 c0 {2,S} 103 | 6 H u0 p0 c0 {3,S} 104 | 7 H u0 p0 c0 {3,S} 105 | 8 H u0 p0 c0 {3,S} 106 | 9 H u0 p0 c0 {4,S} 107 | 10 H u0 p0 c0 {4,S} 108 | 11 H u0 p0 c0 {1,S} 109 | 110 | [CH]CC-2(20311) 111 | multiplicity 3 112 | 1 C u0 p0 c0 {2,S} {3,S} {4,S} {5,S} 113 | 2 C u0 p0 c0 {1,S} {6,S} {7,S} {8,S} 114 | 3 C u2 p0 c0 {1,S} {9,S} 115 | 4 H u0 p0 c0 {1,S} 116 | 5 H u0 p0 c0 {1,S} 117 | 6 H u0 p0 c0 {2,S} 118 | 7 H u0 p0 c0 {2,S} 119 | 8 H u0 p0 c0 {2,S} 120 | 9 H u0 p0 c0 {3,S} 121 | 122 | -------------------------------------------------------------------------------- /tests/data/backup_rmg_files_before_restart/iteration_1/RMG/chemkin/tran.dat: -------------------------------------------------------------------------------- 1 | ! Species Shape LJ-depth LJ-diam DiplMom Polzblty RotRelaxNum Data 2 | ! Name Index epsilon/k_B sigma mu alpha Zrot Source 3 | Ar 0 136.500 3.330 0.000 0.000 0.000 ! NOx2018 4 | Ne 0 148.600 3.758 0.000 0.000 0.000 ! Epsilon & sigma estimated with fixed Lennard Jones Parameters. This is the fallback method! Try improving transport databases! 5 | furfuryl(1) 2 501.522 6.610 0.000 0.000 0.000 ! Epsilon & sigma estimated with Tc=651.33 K, Pc=32.77 bar (from Joback method) 6 | C2H2O(15133) 2 357.876 4.998 0.000 0.000 0.000 ! Epsilon & sigma estimated with Tc=464.77 K, Pc=54.07 bar (from Joback method) 7 | -------------------------------------------------------------------------------- /tests/data/determine_species/iteration_1/RMG/chemkin/species_dictionary.txt: -------------------------------------------------------------------------------- 1 | Ar 2 | 1 Ar u0 p4 c0 3 | 4 | He 5 | 1 He u0 p1 c0 6 | 7 | Ne 8 | 1 Ne u0 p4 c0 9 | 10 | N2 11 | 1 N u0 p1 c0 {2,T} 12 | 2 N u0 p1 c0 {1,T} 13 | 14 | H2(1) 15 | 1 H u0 p0 c0 {2,S} 16 | 2 H u0 p0 c0 {1,S} 17 | 18 | O2(2) 19 | multiplicity 3 20 | 1 O u1 p2 c0 {2,S} 21 | 2 O u1 p2 c0 {1,S} 22 | 23 | H(3) 24 | multiplicity 2 25 | 1 H u1 p0 c0 26 | 27 | OH(4) 28 | multiplicity 2 29 | 1 O u1 p2 c0 {2,S} 30 | 2 H u0 p0 c0 {1,S} 31 | 32 | HO2(6) 33 | multiplicity 2 34 | 1 O u0 p2 c0 {2,S} {3,S} 35 | 2 O u1 p2 c0 {1,S} 36 | 3 H u0 p0 c0 {1,S} 37 | 38 | H2O2(9) 39 | 1 O u0 p2 c0 {2,S} {3,S} 40 | 2 O u0 p2 c0 {1,S} {4,S} 41 | 3 H u0 p0 c0 {1,S} 42 | 4 H u0 p0 c0 {2,S} 43 | 44 | H2O(7) 45 | 1 O u0 p2 c0 {2,S} {3,S} 46 | 2 H u0 p0 c0 {1,S} 47 | 3 H u0 p0 c0 {1,S} 48 | 49 | O(T)(5) 50 | multiplicity 3 51 | 1 O u2 p2 c0 52 | 53 | -------------------------------------------------------------------------------- /tests/data/determine_species/iteration_2/RMG/chemkin/species_dictionary.txt: -------------------------------------------------------------------------------- 1 | Ar 2 | 1 Ar u0 p4 c0 3 | 4 | He 5 | 1 He u0 p1 c0 6 | 7 | Ne 8 | 1 Ne u0 p4 c0 9 | 10 | N2 11 | 1 N u0 p1 c0 {2,T} 12 | 2 N u0 p1 c0 {1,T} 13 | 14 | H2(1) 15 | 1 H u0 p0 c0 {2,S} 16 | 2 H u0 p0 c0 {1,S} 17 | 18 | O2(2) 19 | multiplicity 3 20 | 1 O u1 p2 c0 {2,S} 21 | 2 O u1 p2 c0 {1,S} 22 | 23 | H(3) 24 | multiplicity 2 25 | 1 H u1 p0 c0 26 | 27 | OH(4) 28 | multiplicity 2 29 | 1 O u1 p2 c0 {2,S} 30 | 2 H u0 p0 c0 {1,S} 31 | 32 | HO2(6) 33 | multiplicity 2 34 | 1 O u0 p2 c0 {2,S} {3,S} 35 | 2 O u1 p2 c0 {1,S} 36 | 3 H u0 p0 c0 {1,S} 37 | 38 | H2O2(9) 39 | 1 O u0 p2 c0 {2,S} {3,S} 40 | 2 O u0 p2 c0 {1,S} {4,S} 41 | 3 H u0 p0 c0 {1,S} 42 | 4 H u0 p0 c0 {2,S} 43 | 44 | H2O(7) 45 | 1 O u0 p2 c0 {2,S} {3,S} 46 | 2 H u0 p0 c0 {1,S} 47 | 3 H u0 p0 c0 {1,S} 48 | 49 | O(T)(5) 50 | multiplicity 3 51 | 1 O u2 p2 c0 52 | 53 | -------------------------------------------------------------------------------- /tests/data/functional_2_thermo/input.yml: -------------------------------------------------------------------------------- 1 | project: functional_1_thermo_1_rate 2 | 3 | t3: 4 | options: 5 | max_T3_iterations: 1 6 | max_RMG_walltime: '00:00:05:00' 7 | sensitivity: 8 | adapter: RMGConstantTP 9 | top_SA_species: 1 10 | top_SA_reactions: 1 11 | 12 | rmg: 13 | rmg_execution_type: incore 14 | database: 15 | thermo_libraries: ['primaryThermoLibrary', 'BurkeH2O2', 'FFCM1(-)'] 16 | kinetics_libraries: ['primaryH2O2', 'FFCM1(-)'] 17 | species: 18 | - label: propane 19 | smiles: 'CCC' 20 | concentration: 0.5 21 | - label: 1-propyl 22 | smiles: '[CH2]CC' 23 | concentration: 0.25 24 | - label: 2-propyl 25 | smiles: 'C[CH]C' 26 | concentration: 0.25 27 | SA_observable: true 28 | reactors: 29 | - type: gas batch constant T P 30 | T: 1000 31 | P: 1 32 | termination_time: [1e-6, 's'] 33 | termination_rate_ratio: 0.1 34 | model: 35 | core_tolerance: 0.1 36 | species_constraints: 37 | allowed: ['input species', 'seed mechanisms', 'reaction libraries'] 38 | max_C_atoms: 3 39 | max_O_atoms: 0 40 | max_N_atoms: 0 41 | max_Si_atoms: 0 42 | max_S_atoms: 0 43 | max_heavy_atoms: 3 44 | max_radical_electrons: 1 45 | max_singlet_carbenes: 0 46 | 47 | qm: 48 | adapter: ARC 49 | level_of_theory: gfn2 50 | conformer_level: gfn2 51 | arkane_level_of_theory: CBS-QB3 52 | freq_scale_factor: 1.0 53 | job_types: 54 | rotors: false 55 | fine: false 56 | 57 | -------------------------------------------------------------------------------- /tests/data/minimal_data/iteration_1/RMG/chemkin/species_dictionary.txt: -------------------------------------------------------------------------------- 1 | Ar 2 | 1 Ar u0 p4 c0 3 | 4 | He 5 | 1 He u0 p1 c0 6 | 7 | Ne 8 | 1 Ne u0 p4 c0 9 | 10 | N2 11 | 1 N u0 p1 c0 {2,T} 12 | 2 N u0 p1 c0 {1,T} 13 | 14 | H2(1) 15 | 1 H u0 p0 c0 {2,S} 16 | 2 H u0 p0 c0 {1,S} 17 | 18 | O2(2) 19 | multiplicity 3 20 | 1 O u1 p2 c0 {2,S} 21 | 2 O u1 p2 c0 {1,S} 22 | 23 | H(3) 24 | multiplicity 2 25 | 1 H u1 p0 c0 26 | 27 | OH(4) 28 | multiplicity 2 29 | 1 O u1 p2 c0 {2,S} 30 | 2 H u0 p0 c0 {1,S} 31 | 32 | HO2(6) 33 | multiplicity 2 34 | 1 O u0 p2 c0 {2,S} {3,S} 35 | 2 O u1 p2 c0 {1,S} 36 | 3 H u0 p0 c0 {1,S} 37 | 38 | OO(9) 39 | 1 O u0 p2 c0 {2,S} {3,S} 40 | 2 O u0 p2 c0 {1,S} {4,S} 41 | 3 H u0 p0 c0 {1,S} 42 | 4 H u0 p0 c0 {2,S} 43 | 44 | H2O(7) 45 | 1 O u0 p2 c0 {2,S} {3,S} 46 | 2 H u0 p0 c0 {1,S} 47 | 3 H u0 p0 c0 {1,S} 48 | 49 | O(T)(5) 50 | multiplicity 3 51 | 1 O u2 p2 c0 52 | 53 | -------------------------------------------------------------------------------- /tests/data/minimal_data/iteration_1/RMG/input.py: -------------------------------------------------------------------------------- 1 | database( 2 | thermoLibraries=['primaryThermoLibrary'], 3 | reactionLibraries=[], 4 | transportLibraries=['OneDMinN2', 'PrimaryTransportLibrary', 'NOx2018', 'GRI-Mech'], 5 | seedMechanisms=[], 6 | kineticsDepositories='default', 7 | kineticsFamilies='default', 8 | kineticsEstimator='rate rules', 9 | ) 10 | 11 | species( 12 | label='H2', 13 | reactive=True, 14 | structure=SMILES('[H][H]'), 15 | ) 16 | 17 | species( 18 | label='O2', 19 | reactive=True, 20 | structure=SMILES('[O][O]'), 21 | ) 22 | 23 | species( 24 | label='H', 25 | reactive=True, 26 | structure=SMILES('[H]'), 27 | ) 28 | 29 | species( 30 | label='OH', 31 | reactive=True, 32 | structure=SMILES('[OH]'), 33 | ) 34 | 35 | simpleReactor( 36 | temperature=(1000.0, 'K'), 37 | pressure=(1.0, 'bar'), 38 | initialMoleFractions={ 39 | 'H2': 0.67, 40 | 'O2': 0.33, 41 | 'H': 0, 42 | 'OH': 0, 43 | }, 44 | terminationConversion={'H2': 0.9}, 45 | terminationTime=(1000000.0, 's'), 46 | nSims=12, 47 | ) 48 | 49 | model( 50 | toleranceMoveToCore=0.001, 51 | toleranceInterruptSimulation=0.001, 52 | filterReactions=False, 53 | filterThreshold=100000000.0, 54 | maxNumObjsPerIter=1, 55 | terminateAtMaxObjects=False, 56 | ) 57 | 58 | simulator(atol=1e-16, rtol=1e-08) 59 | -------------------------------------------------------------------------------- /tests/data/models/dups/1.yaml: -------------------------------------------------------------------------------- 1 | generator: ck2yaml 2 | input-files: [chem_annotated.inp, tran.dat] 3 | cantera-version: 2.6.0 4 | date: Mon, 16 Oct 2023 09:32:11 +0300 5 | 6 | units: {length: cm, time: s, quantity: mol, activation-energy: kcal/mol} 7 | 8 | phases: 9 | - name: gas 10 | thermo: ideal-gas 11 | elements: [H, D, T, C, Ci, O, Oi, N, Ne, Ar, He, Si, S, F, Cl, Br, I, 12 | X] 13 | species: [HNO(63), HNO(T)(117)] 14 | kinetics: gas 15 | transport: mixture-averaged 16 | state: {T: 300.0, P: 1 atm} 17 | 18 | elements: 19 | - symbol: Ci 20 | atomic-weight: 13.003 21 | - symbol: D 22 | atomic-weight: 2.014 23 | - symbol: Oi 24 | atomic-weight: 17.999 25 | - symbol: T 26 | atomic-weight: 3.016 27 | - symbol: X 28 | atomic-weight: 195.083 29 | 30 | species: 31 | - name: HNO(63) 32 | composition: {H: 1, N: 1, O: 1} 33 | thermo: 34 | model: NASA7 35 | temperature-ranges: [298.0, 947.96, 2500.0] 36 | data: 37 | - [4.04892, -2.03371e-03, 9.1381e-06, -7.68952e-09, 2.1349e-12, 1.16828e+04, 38 | 3.72802] 39 | - [2.28668, 5.40271e-03, -2.62961e-06, 5.86811e-10, -4.79003e-14, 1.20169e+04, 40 | 12.1356] 41 | note: 'Thermo library: NH3' 42 | transport: 43 | model: gas 44 | geometry: nonlinear 45 | well-depth: 170.0 46 | diameter: 3.43 47 | dipole: 1.62 48 | rotational-relaxation: 1.0 49 | note: NOx2018 50 | note: HNO(63) 51 | - name: HNO(T)(117) 52 | composition: {H: 1, N: 1, O: 1} 53 | thermo: 54 | model: NASA7 55 | temperature-ranges: [298.0, 797.95, 2500.0] 56 | data: 57 | - [3.9029, -7.20791e-04, 7.98867e-06, -8.20547e-09, 2.72225e-12, 2.13846e+04, 58 | 5.26094] 59 | - [2.76701, 4.97317e-03, -2.71477e-06, 7.36833e-10, -7.93508e-14, 2.15659e+04, 60 | 10.4846] 61 | note: 'Thermo library: NH3' 62 | transport: 63 | model: gas 64 | geometry: nonlinear 65 | well-depth: 419.116 66 | diameter: 5.652 67 | note: Epsilon & sigma estimated with Tc=544.31 K, Pc=43.8 bar (from 68 | Joback method) 69 | note: HNO(T)(117) 70 | 71 | reactions: 72 | - equation: HNO(63) + HNO(63) <=> HNO(T)(117) + HNO(T)(117) # Reaction 515 73 | type: Chebyshev 74 | temperature-range: [500.0, 1600.0] 75 | pressure-range: [0.099 atm, 98.692 atm] 76 | data: 77 | - [-9.899, -2.244e-07, -1.375e-07, -6.452e-08] 78 | - [10.61, -1.791e-08, -1.098e-08, -5.15e-09] 79 | - [0.1084, 5.789e-10, 3.548e-10, 1.665e-10] 80 | - [0.02232, -9.015e-10, -5.526e-10, -2.592e-10] 81 | - [4.458e-03, -6.43e-10, -3.941e-10, -1.849e-10] 82 | - [8.737e-04, -2.09e-10, -1.281e-10, -6.01e-11] 83 | note: |- 84 | Reaction index: Chemkin #515; RMG #1957 85 | PDep reaction: PDepNetwork #87 86 | Flux pairs: HNO(63), HNO(T)(117); HNO(63), HNO(T)(117); 87 | - equation: HNO(T)(117) <=> HNO(63) # Reaction 561 88 | type: Chebyshev 89 | temperature-range: [500.0, 1600.0] 90 | pressure-range: [0.099 atm, 98.692 atm] 91 | data: 92 | - [9.475, 0.7131, -0.2205, 5.328e-03] 93 | - [-0.1518, 0.1572, 4.48e-04, -0.02016] 94 | - [-0.03783, 0.0323, 5.309e-03, -3.914e-03] 95 | - [-6.146e-03, 2.574e-03, 2.342e-03, -1.251e-05] 96 | - [-2.889e-03, 1.998e-03, 2.569e-04, -8.23e-05] 97 | - [4.209e-04, -9.79e-04, 2.049e-04, 1.623e-04] 98 | note: |- 99 | Reaction index: Chemkin #561; RMG #4867 100 | PDep reaction: PDepNetwork #470 101 | Flux pairs: HNO(T)(117), HNO(63); 102 | -------------------------------------------------------------------------------- /tests/data/models/dups/2.yaml: -------------------------------------------------------------------------------- 1 | generator: ck2yaml 2 | input-files: [chem_annotated.inp, tran.dat] 3 | cantera-version: 2.6.0 4 | date: Mon, 16 Oct 2023 09:32:11 +0300 5 | 6 | units: {length: cm, time: s, quantity: mol, activation-energy: kcal/mol} 7 | 8 | phases: 9 | - name: gas 10 | thermo: ideal-gas 11 | elements: [H, D, T, C, Ci, O, Oi, N, Ne, Ar, He, Si, S, F, Cl, Br, I, 12 | X] 13 | species: [N2(2), O2(3), HO2(10), NNH(71), NH2O(93), HNO(T)(117)] 14 | kinetics: gas 15 | transport: mixture-averaged 16 | state: {T: 300.0, P: 1 atm} 17 | 18 | elements: 19 | - symbol: Ci 20 | atomic-weight: 13.003 21 | - symbol: D 22 | atomic-weight: 2.014 23 | - symbol: Oi 24 | atomic-weight: 17.999 25 | - symbol: T 26 | atomic-weight: 3.016 27 | - symbol: X 28 | atomic-weight: 195.083 29 | 30 | species: 31 | - name: N2(2) 32 | composition: {N: 2} 33 | thermo: 34 | model: NASA7 35 | temperature-ranges: [298.0, 1224.73, 2500.0] 36 | data: 37 | - [3.57917, -9.2269e-04, 2.52013e-06, -1.59938e-09, 3.37289e-13, -1044.86, 38 | 2.81354] 39 | - [2.85431, 1.44431e-03, -3.78377e-07, -2.18841e-11, 1.53369e-14, -867.277, 40 | 6.45765] 41 | note: 'Thermo library: NH3' 42 | transport: 43 | model: gas 44 | geometry: linear 45 | well-depth: 97.53 46 | diameter: 3.621 47 | polarizability: 1.76 48 | rotational-relaxation: 4.0 49 | note: PrimaryTransportLibrary 50 | note: N2(2) 51 | - name: O2(3) 52 | composition: {O: 2} 53 | thermo: 54 | model: NASA7 55 | temperature-ranges: [100.0, 1087.71, 5000.0] 56 | data: 57 | - [3.53763631, -1.22826882e-03, 5.36756515e-06, -4.93125523e-09, 1.45954081e-12, 58 | -1037.99023, 4.67180007] 59 | - [3.16427597, 1.69453107e-03, -8.00332239e-07, 1.59029251e-10, -1.14890364e-14, 60 | -1048.44704, 6.08300917] 61 | note: 'Thermo library: BurkeH2O2' 62 | transport: 63 | model: gas 64 | geometry: linear 65 | well-depth: 106.7 66 | diameter: 3.467 67 | note: PrimaryTransportLibrary 68 | note: O2(3) 69 | - name: HO2(10) 70 | composition: {H: 1, O: 2} 71 | thermo: 72 | model: NASA7 73 | temperature-ranges: [100.0, 923.9, 5000.0] 74 | data: 75 | - [4.02957148, -2.63999447e-03, 1.52235621e-05, -1.71678812e-08, 6.26772304e-12, 76 | 322.676787, 4.84423889] 77 | - [4.15129844, 1.91151964e-03, -4.1130909e-07, 6.35040525e-11, -4.86454821e-15, 78 | 83.4346007, 3.0935982] 79 | note: 'Thermo library: BurkeH2O2' 80 | transport: 81 | model: gas 82 | geometry: nonlinear 83 | well-depth: 107.4 84 | diameter: 3.458 85 | rotational-relaxation: 1.0 86 | note: NOx2018 87 | note: HO2(10) 88 | - name: NNH(71) 89 | composition: {H: 1, N: 2} 90 | thermo: 91 | model: NASA7 92 | temperature-ranges: [298.0, 876.56, 2500.0] 93 | data: 94 | - [3.95201, -1.12385e-03, 8.04654e-06, -7.44027e-09, 2.23831e-12, 2.87903e+04, 95 | 4.48518] 96 | - [2.59685, 5.05955e-03, -2.53369e-06, 6.05725e-10, -5.62358e-14, 2.90279e+04, 97 | 10.8447] 98 | note: 'Thermo library: NH3' 99 | transport: 100 | model: gas 101 | geometry: linear 102 | well-depth: 292.088 103 | diameter: 3.459 104 | dipole: 1.858 105 | polarizability: 2.016 106 | rotational-relaxation: 1.0 107 | note: OneDMinN2 108 | note: NNH(71) 109 | - name: NH2O(93) 110 | composition: {H: 2, N: 1, O: 1} 111 | thermo: 112 | model: NASA7 113 | temperature-ranges: [298.0, 914.76, 2500.0] 114 | data: 115 | - [4.07928, 2.27378e-03, 4.54857e-06, -4.93461e-09, 1.48515e-12, 6359.36, 116 | 3.76557] 117 | - [2.98935, 7.03992e-03, -3.26708e-06, 7.61529e-10, -7.16286e-14, 6558.76, 118 | 8.92673] 119 | note: 'Thermo library: NH3' 120 | transport: 121 | model: gas 122 | geometry: nonlinear 123 | well-depth: 116.7 124 | diameter: 3.492 125 | rotational-relaxation: 1.0 126 | note: NOx2018 127 | note: NH2O(93) 128 | - name: HNO(T)(117) 129 | composition: {H: 1, N: 1, O: 1} 130 | thermo: 131 | model: NASA7 132 | temperature-ranges: [298.0, 797.95, 2500.0] 133 | data: 134 | - [3.9029, -7.20791e-04, 7.98867e-06, -8.20547e-09, 2.72225e-12, 2.13846e+04, 135 | 5.26094] 136 | - [2.76701, 4.97317e-03, -2.71477e-06, 7.36833e-10, -7.93508e-14, 2.15659e+04, 137 | 10.4846] 138 | note: 'Thermo library: NH3' 139 | transport: 140 | model: gas 141 | geometry: nonlinear 142 | well-depth: 419.116 143 | diameter: 5.652 144 | note: Epsilon & sigma estimated with Tc=544.31 K, Pc=43.8 bar (from 145 | Joback method) 146 | note: HNO(T)(117) 147 | 148 | reactions: 149 | - equation: O2(3) + NH2O(93) <=> HO2(10) + HNO(T)(117) # Reaction 503 150 | duplicate: true 151 | rate-constant: {A: 4429.0, b: 2.578, Ea: 29.877} 152 | note: |- 153 | Reaction index: Chemkin #503; RMG #340 154 | Library reaction: primaryNitrogenLibrary 155 | Flux pairs: O2(3), HO2(10); NH2O(93), HNO(T)(117); 156 | - equation: HNO(T)(117) + NNH(71) <=> N2(2) + NH2O(93) # Reaction 504 157 | rate-constant: {A: 1.2e+06, b: 2.0, Ea: 0.0} 158 | note: |- 159 | Reaction index: Chemkin #504; RMG #1830 160 | Template reaction: Disproportionation 161 | Flux pairs: HNO(T)(117), NH2O(93); NNH(71), N2(2); 162 | Estimated from node Root_N-4R->H_4CNOS-u1_N-1R!H->O_N-4CNOS->O_Ext-4CNS-R_N-Sp-5R!H#4CCCNNNSSS_N-2R!H->S_5R!H->O_N-1CNS->C 163 | -------------------------------------------------------------------------------- /tests/data/process_arc/iteration_2/ARC/T3.info: -------------------------------------------------------------------------------- 1 | ARC v1.1.0 2 | ARC project T3 3 | 4 | Levels of theory used: 5 | 6 | Conformers: wb97xd/def2svp 7 | TS guesses: wb97xd/def2svp 8 | Optimization: b3lyp/6-311+g(3df,2p) (using a fine grid) 9 | Frequencies: b3lyp/6-311+g(3df,2p) 10 | Single point: b3lyp/6-311+g(3df,2p) 11 | Rotor scans: 12 | Using bond additivity corrections for thermo 13 | 14 | Using the following ESS settings: {'gaussian': ['local'], 'orca': ['local']} 15 | 16 | Considered the following species and TSs: 17 | Species imipramine_ol_2_ket_4_0 (run time: 1 day, 8:24:38) 18 | Species imipramine_ol_2_ket_5_1 (Failed!) (run time: 1 day, 8:24:38) 19 | 20 | Overall time since project initiation: 1.0 days, 08:41:56 21 | -------------------------------------------------------------------------------- /tests/data/process_arc/iteration_2/ARC/T3_info.yml: -------------------------------------------------------------------------------- 1 | reactions: [] 2 | species: 3 | - label: imipramine_ol_2_ket_4 4 | success: true 5 | - label: imipramine_ol_2_ket_5 6 | success: false 7 | -------------------------------------------------------------------------------- /tests/data/process_arc/iteration_2/ARC/output/RMG libraries/thermo/T3.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # encoding: utf-8 3 | 4 | name = "T3" 5 | shortDesc = "" 6 | longDesc = """ 7 | ARC v1.1.0 8 | ARC project T3 9 | 10 | Levels of theory used: 11 | 12 | Conformers: wb97xd/def2svp 13 | TS guesses: wb97xd/def2svp 14 | Optimization: b3lyp/6-311+g(3df,2p) (using a fine grid) 15 | Frequencies: b3lyp/6-311+g(3df,2p) 16 | Single point: b3lyp/6-311+g(3df,2p) 17 | Rotor scans: 18 | Using bond additivity corrections for thermo 19 | 20 | Using the following ESS settings: {'gaussian': ['local'], 'orca': ['local']} 21 | 22 | Considered the following species and TSs: 23 | Species imipramine_ol_2_ket_4 (run time: 1 day, 8:24:38) 24 | 25 | Overall time since project initiation: 1.0 days, 08:41:56 26 | """ 27 | entry( 28 | index = 0, 29 | label = "imipramine_ol_2_ket_4", 30 | molecule = 31 | """ 32 | 1 O u0 p2 c0 {5,S} {45,S} 33 | 2 O u0 p2 c0 {15,D} 34 | 3 N u0 p1 c0 {9,S} {10,S} {15,S} 35 | 4 N u0 p1 c0 {5,S} {13,S} {14,S} 36 | 5 C u0 p0 c0 {1,S} {4,S} {8,S} {24,S} 37 | 6 C u0 p0 c0 {7,S} {11,S} {27,S} {28,S} 38 | 7 C u0 p0 c0 {6,S} {12,S} {29,S} {30,S} 39 | 8 C u0 p0 c0 {5,S} {15,S} {25,S} {26,S} 40 | 9 C u0 p0 c0 {3,S} {31,S} {32,S} {33,S} 41 | 10 C u0 p0 c0 {3,S} {34,S} {35,S} {36,S} 42 | 11 C u0 p0 c0 {6,S} {13,B} {16,B} 43 | 12 C u0 p0 c0 {7,S} {14,B} {17,B} 44 | 13 C u0 p0 c0 {4,S} {11,B} {18,B} 45 | 14 C u0 p0 c0 {4,S} {12,B} {19,B} 46 | 15 C u0 p0 c0 {2,D} {3,S} {8,S} 47 | 16 C u0 p0 c0 {11,B} {21,B} {40,S} 48 | 17 C u0 p0 c0 {12,B} {22,B} {41,S} 49 | 18 C u0 p0 c0 {13,B} {20,B} {37,S} 50 | 19 C u0 p0 c0 {14,B} {23,B} {44,S} 51 | 20 C u0 p0 c0 {18,B} {21,B} {38,S} 52 | 21 C u0 p0 c0 {16,B} {20,B} {39,S} 53 | 22 C u0 p0 c0 {17,B} {23,B} {42,S} 54 | 23 C u0 p0 c0 {19,B} {22,B} {43,S} 55 | 24 H u0 p0 c0 {5,S} 56 | 25 H u0 p0 c0 {8,S} 57 | 26 H u0 p0 c0 {8,S} 58 | 27 H u0 p0 c0 {6,S} 59 | 28 H u0 p0 c0 {6,S} 60 | 29 H u0 p0 c0 {7,S} 61 | 30 H u0 p0 c0 {7,S} 62 | 31 H u0 p0 c0 {9,S} 63 | 32 H u0 p0 c0 {9,S} 64 | 33 H u0 p0 c0 {9,S} 65 | 34 H u0 p0 c0 {10,S} 66 | 35 H u0 p0 c0 {10,S} 67 | 36 H u0 p0 c0 {10,S} 68 | 37 H u0 p0 c0 {18,S} 69 | 38 H u0 p0 c0 {20,S} 70 | 39 H u0 p0 c0 {21,S} 71 | 40 H u0 p0 c0 {16,S} 72 | 41 H u0 p0 c0 {17,S} 73 | 42 H u0 p0 c0 {22,S} 74 | 43 H u0 p0 c0 {23,S} 75 | 44 H u0 p0 c0 {19,S} 76 | 45 H u0 p0 c0 {1,S} 77 | """, 78 | thermo = NASA( 79 | polynomials = [ 80 | NASAPolynomial(coeffs=[3.13652,0.138999,1.99933e-05,-1.03646e-07,4.27784e-11,-20600.7,19.4855], Tmin=(10,'K'), Tmax=(1035.6,'K')), 81 | NASAPolynomial(coeffs=[21.3225,0.1359,-7.27712e-05,1.86781e-08,-1.86505e-12,-27967.9,-86.271], Tmin=(1035.6,'K'), Tmax=(3000,'K')), 82 | ], 83 | Tmin = (10,'K'), 84 | Tmax = (3000,'K'), 85 | E0 = (-171.078,'kJ/mol'), 86 | Cp0 = (33.2579,'J/(mol*K)'), 87 | CpInf = (1105.82,'J/(mol*K)'), 88 | ), 89 | shortDesc = """""", 90 | longDesc = 91 | """ 92 | Bond corrections: {'C-H': 21, 'C=C': 6, 'C-C': 11, 'C-N': 6, 'C=O': 1, 'H-O': 1, 'C-O': 1} 93 | 94 | External symmetry: 1, optical isomers: 2 95 | 96 | Geometry: 97 | C 3.83367400 -0.60223200 -1.79441600 98 | N 3.94392200 0.15580300 -0.56044000 99 | C 3.14521700 -0.34679000 0.54791800 100 | C 4.72137600 1.25845900 -0.38333900 101 | O 4.73931100 1.86456200 0.68748700 102 | C 5.57329900 1.72488000 -1.55920400 103 | C 6.57332400 2.81909100 -1.15153600 104 | O 5.89362200 3.95474600 -0.61959700 105 | N 7.43139100 3.17441000 -2.25579000 106 | C 8.76493100 3.58717600 -1.96528700 107 | C 9.00364600 4.26730900 -0.76066700 108 | C 10.27839600 4.65824400 -0.38702600 109 | C 11.35307000 4.40150700 -1.22805100 110 | C 11.12067300 3.74624500 -2.42585100 111 | C 9.84989800 3.31833000 -2.82291700 112 | C 9.78503700 2.59093800 -4.15610100 113 | C 8.47970600 1.87237500 -4.51433800 114 | C 7.33694300 2.83353300 -4.66243900 115 | C 6.76946200 3.12263000 -5.90145000 116 | C 5.72438500 4.03141400 -6.01797100 117 | C 5.24650400 4.67494300 -4.88319700 118 | C 5.81367700 4.41485600 -3.64110700 119 | C 6.85397200 3.49058300 -3.52378200 120 | H 2.78007400 -0.73612900 -2.04943100 121 | H 4.31422200 -0.09264100 -2.62073700 122 | H 4.28244000 -1.59409500 -1.68629800 123 | H 3.33209000 0.26140000 1.42545600 124 | H 2.08193100 -0.30701900 0.29950500 125 | H 3.40992800 -1.38519200 0.76106800 126 | H 6.13180300 0.88580700 -1.97622800 127 | H 4.92051700 2.10213500 -2.34839200 128 | H 7.22897200 2.40623900 -0.38015600 129 | H 5.37351100 3.60780900 0.12422000 130 | H 8.16181200 4.51175600 -0.13023100 131 | H 10.42379400 5.17941100 0.55017800 132 | H 12.35512900 4.70635900 -0.95781300 133 | H 11.95668100 3.53595200 -3.08320700 134 | H 10.60184600 1.86469100 -4.17660000 135 | H 10.00499200 3.30876100 -4.95302000 136 | H 8.24849900 1.13364400 -3.74271900 137 | H 8.62699200 1.32791600 -5.44846300 138 | H 7.14544700 2.61836100 -6.78369800 139 | H 5.29040600 4.23744300 -6.98752800 140 | H 4.44025300 5.39248200 -4.96257600 141 | H 5.45962700 4.91963200 -2.75508100 142 | """, 143 | ) 144 | 145 | -------------------------------------------------------------------------------- /tests/data/process_arc/reactions.yml: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/data/restart/r2/iteration_2/RMG/RMG.log: -------------------------------------------------------------------------------- 1 | Dummy RMG log file 2 | 3 | -------------------------------------------------------------------------------- /tests/data/restart/r3/iteration_3/RMG/RMG.log: -------------------------------------------------------------------------------- 1 | Dummy RMG log file 2 | 3 | MODEL GENERATION COMPLETED 4 | -------------------------------------------------------------------------------- /tests/data/restart/r4/iteration_4/ARC/arc.log: -------------------------------------------------------------------------------- 1 | Dummy ARC log file 2 | 3 | 4 | -------------------------------------------------------------------------------- /tests/data/restart/r4/iteration_4/RMG/RMG.log: -------------------------------------------------------------------------------- 1 | Dummy RMG log file 2 | 3 | MODEL GENERATION COMPLETED 4 | -------------------------------------------------------------------------------- /tests/data/restart/r5/iteration_5/ARC/arc.log: -------------------------------------------------------------------------------- 1 | Dummy ARC log file 2 | 3 | -------------------------------------------------------------------------------- /tests/data/restart/r5/iteration_5/RMG/RMG.log: -------------------------------------------------------------------------------- 1 | Dummy RMG log file 2 | 3 | MODEL GENERATION COMPLETED 4 | -------------------------------------------------------------------------------- /tests/data/restart/r6/iteration_6/ARC/T3.info: -------------------------------------------------------------------------------- 1 | ARC v1.1.0 2 | ARC project t1072 3 | 4 | Levels of theory used: 5 | 6 | Conformers: wb97xd/def2svp 7 | TS guesses: wb97xd/def2svp 8 | Optimization: b3lyp/6-311+g(3df,2p) (using a fine grid) 9 | Frequencies: b3lyp/6-311+g(3df,2p) 10 | Single point: b3lyp/6-311+g(3df,2p) 11 | Rotor scans: 12 | Using bond additivity corrections for thermo 13 | 14 | Using the following ESS settings: {'gaussian': ['local'], 'orca': ['local']} 15 | 16 | Considered the following species and TSs: 17 | Species Imipramine_1_peroxy_0 (run time: 1 day, 17:28:32) 18 | 19 | Overall time since project initiation: 2.0 days, 18:52:12 20 | -------------------------------------------------------------------------------- /tests/data/restart/r6/iteration_6/ARC/T3_info.yml: -------------------------------------------------------------------------------- 1 | reactions: [] 2 | species: 3 | - label: Imipramine_1_peroxy_0 4 | success: true 5 | -------------------------------------------------------------------------------- /tests/data/restart/r6/iteration_6/ARC/arc.log: -------------------------------------------------------------------------------- 1 | Dummy ARC log file 2 | 3 | Starting project T3_ARC_restart_test 4 | 5 | All jobs terminated. Summary for project T3_ARC_restart_test: 6 | 7 | Total execution time: 00:00:00 8 | 9 | ARC execution terminated on Sun Dec 4 11:50:29 2022 -------------------------------------------------------------------------------- /tests/data/restart/r6/iteration_6/ARC/restart.yml: -------------------------------------------------------------------------------- 1 | project: T3_ARC_restart_test 2 | output: 3 | Imipramine_1_peroxy: 4 | conformers: 'single conformer passed isomorphism check; ' 5 | convergence: true 6 | errors: '' 7 | info: 'T1 = 0.0119504; ' 8 | isomorphism: 'opt passed isomorphism check; ' 9 | job_types: 10 | bde: true 11 | composite: false 12 | conformers: true 13 | fine: true 14 | freq: true 15 | irc: false 16 | onedmin: false 17 | opt: true 18 | orbitals: false 19 | rotors: true 20 | sp: true 21 | paths: 22 | composite: '' 23 | freq: freq_a48877/output.out 24 | geo: freq_a48877/output.out 25 | sp: sp_a48927/output.out 26 | restart: '' 27 | warnings: '' 28 | 29 | species: 30 | - arkane_file: null 31 | charge: 0 32 | compute_thermo: true 33 | conf_is_isomorphic: true 34 | e_elect: -408908.67724884645 35 | final_xyz: |- 36 | C -1.57004500 -0.31383400 -0.10934600 37 | C -0.39847700 0.62165100 0.01284400 38 | C -0.10155000 1.55284600 -0.85131600 39 | C 0.18880300 2.48204900 -1.72036000 40 | H -1.23329100 -1.35203000 -0.13586600 41 | H -2.23679500 -0.21086000 0.74902300 42 | H -2.13910300 -0.11221700 -1.01469400 43 | H 0.24072600 0.50845700 0.88370600 44 | H -0.21315300 3.48367400 -1.62847700 45 | H 0.84327100 2.28232300 -2.56003000 46 | is_ts: false 47 | label: Imipramine_1_peroxy 48 | multiplicity: 1 49 | run_time: 8805.0 50 | t1: 0.0119504 -------------------------------------------------------------------------------- /tests/data/restart/r6/iteration_6/ARC/test_restart_info.yml: -------------------------------------------------------------------------------- 1 | reactions: 2 | - label: Imipramine_1_peroxy_0 <=> IRC_Prod_Opt 3 | success: true 4 | species: 5 | - adj: | 6 | 1 C u0 p0 c0 {2,S} {6,S} {7,S} 7 | 2 C u0 p0 c0 {1,S} {3,S} {8,S} 8 | 3 C u0 p0 c0 {2,S} {4,S} {9,S} 9 | 4 C u0 p0 c0 {3,S} {5,S} {12,S} 10 | 5 C u0 p0 c0 {4,S} {6,S} {10,S} 11 | 6 C u0 p0 c0 {1,S} {5,S} {11,S} 12 | 7 H u0 p0 c0 {1,S} 13 | 8 H u0 p0 c0 {2,S} 14 | 9 H u0 p0 c0 {3,S} 15 | 10 H u0 p0 c0 {5,S} 16 | 11 H u0 p0 c0 {6,S} 17 | 12 C u0 p0 c0 {4,S} {13,S} {26,S} {27,S} 18 | 13 N u0 p0 c0 {12,S} {14,S} {18,S} {22,S} 19 | 14 C u0 p0 c0 {13,S} {15,S} {16,S} {17,S} 20 | 15 H u0 p0 c0 {14,S} 21 | 16 H u0 p0 c0 {14,S} 22 | 17 H u0 p0 c0 {14,S} 23 | 18 C u0 p0 c0 {13,S} {19,S} {20,S} {21,S} 24 | 19 H u0 p0 c0 {18,S} 25 | 20 H u0 p0 c0 {18,S} 26 | 21 H u0 p0 c0 {18,S} 27 | 22 C u0 p0 c0 {13,S} {23,S} {24,S} {25,S} 28 | 23 H u0 p0 c0 {22,S} 29 | 24 H u0 p0 c0 {22,S} 30 | 25 H u0 p0 c0 {22,S} 31 | 26 H u0 p0 c0 {12,S} 32 | 27 H u0 p0 c0 {12,S} 33 | 28 O u0 p2 c0 {29,S} {30,S} 34 | 29 H u0 p0 c0 {28,S} 35 | 30 H u0 p0 c0 {28,S} 36 | 31 O u0 p2 c0 {32,S} 37 | 32 H u0 p0 c0 {31,S} 38 | label: Imipramine_1_peroxy_0 39 | smiles: C[N](C[C]1[CH][CH][CH][CH][CH]1)(C)C.[OH].O 40 | success: true 41 | - adj: | 42 | 1 C u0 p0 c0 {2,D} {6,S} {7,S} 43 | 2 C u0 p0 c0 {1,D} {3,S} {8,S} 44 | 3 C u0 p0 c0 {2,S} {4,D} {9,S} 45 | 4 C u0 p0 c0 {3,D} {5,S} {12,S} 46 | 5 C u0 p0 c0 {4,S} {6,D} {10,S} 47 | 6 C u0 p0 c0 {1,S} {5,D} {11,S} 48 | 7 H u0 p0 c0 {1,S} 49 | 8 H u0 p0 c0 {2,S} 50 | 9 H u0 p0 c0 {3,S} 51 | 10 H u0 p0 c0 {5,S} 52 | 11 H u0 p0 c0 {6,S} 53 | 12 C u0 p0 c0 {4,S} {26,S} {27,S} {28,S} 54 | 13 N u0 p1 c0 {14,S} {18,S} {22,S} 55 | 14 C u0 p0 c0 {13,S} {15,S} {16,S} {17,S} 56 | 15 H u0 p0 c0 {14,S} 57 | 16 H u0 p0 c0 {14,S} 58 | 17 H u0 p0 c0 {14,S} 59 | 18 C u0 p0 c0 {13,S} {19,S} {20,S} {21,S} 60 | 19 H u0 p0 c0 {18,S} 61 | 20 H u0 p0 c0 {18,S} 62 | 21 H u0 p0 c0 {18,S} 63 | 22 C u0 p0 c0 {13,S} {23,S} {24,S} {25,S} 64 | 23 H u0 p0 c0 {22,S} 65 | 24 H u0 p0 c0 {22,S} 66 | 25 H u0 p0 c0 {22,S} 67 | 26 H u0 p0 c0 {12,S} 68 | 27 H u0 p0 c0 {12,S} 69 | 28 O u0 p2 c0 {12,S} {29,S} 70 | 29 H u0 p0 c0 {28,S} 71 | 30 H u0 p0 c0 {31,S} 72 | 31 O u0 p2 c0 {30,S} {32,S} 73 | 32 H u0 p0 c0 {31,S} 74 | label: IRC_Prod_Opt 75 | smiles: CN(C)C.OCc1ccccc1.O 76 | success: true 77 | -------------------------------------------------------------------------------- /tests/data/restart/r6/iteration_6/RMG/RMG.log: -------------------------------------------------------------------------------- 1 | Dummy RMG log file 2 | 3 | MODEL GENERATION COMPLETED 4 | -------------------------------------------------------------------------------- /tests/data/restart/r6/reactions.yml: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /tests/data/restart/r7/iteration_7/ARC/T3.info: -------------------------------------------------------------------------------- 1 | ARC v1.1.0 2 | ARC project restart_test_7 3 | 4 | Levels of theory used: 5 | 6 | Conformers: wb97xd/def2svp 7 | TS guesses: wb97xd/def2svp 8 | Optimization: b3lyp/6-311+g(3df,2p) (using a fine grid) 9 | Frequencies: b3lyp/6-311+g(3df,2p) 10 | Single point: b3lyp/6-311+g(3df,2p) 11 | Rotor scans: 12 | Using bond additivity corrections for thermo 13 | 14 | Using the following ESS settings: {'gaussian': ['local'], 'orca': ['local']} 15 | 16 | Considered the following species and TSs: 17 | Species Imipramine_1_peroxy_0 (run time: 1 day, 17:28:32) 18 | 19 | Overall time since project initiation: 2.0 days, 18:52:12 20 | -------------------------------------------------------------------------------- /tests/data/restart/r7/iteration_7/ARC/arc.log: -------------------------------------------------------------------------------- 1 | Dummy ARC log file 2 | 3 | ARC execution terminated on... some time ago 4 | -------------------------------------------------------------------------------- /tests/data/restart/r7/iteration_7/RMG/RMG.log: -------------------------------------------------------------------------------- 1 | Dummy RMG log file 2 | 3 | MODEL GENERATION COMPLETED 4 | -------------------------------------------------------------------------------- /tests/data/rmg_convergence/1_frag_error/err.txt: -------------------------------------------------------------------------------- 1 | :root:Removing old /home/alon/runs/T3/xsc2101/iteration_2/RMG/RMG_backup.log 2 | :root:Moving /home/alon/runs/T3/xsc2101/iteration_2/RMG/RMG.log to /home/alon/runs/T3/xsc2101/iteration_2/RMG/RMG_backup.log 3 | 4 | /home/alon/anaconda3/envs/rmg_env/lib/python3.7/site-packages/scipy/optimize/optimize.py:1978: LinAlgWarning: Ill-conditioned matrix (rcond=9.79183e-18): result may not be accurate. 5 | fu = func(x, *args) 6 | Traceback (most recent call last): 7 | File "/home/alon/anaconda3/envs/rmg_env/lib/python3.7/site-packages/julia/pseudo_python_cli.py", line 308, in main 8 | python(**vars(ns)) 9 | File "/home/alon/anaconda3/envs/rmg_env/lib/python3.7/site-packages/julia/pseudo_python_cli.py", line 59, in python 10 | scope = runpy.run_path(script, run_name="__main__") 11 | File "/home/alon/anaconda3/envs/rmg_env/lib/python3.7/runpy.py", line 263, in run_path 12 | pkg_name=pkg_name, script_name=fname) 13 | File "/home/alon/anaconda3/envs/rmg_env/lib/python3.7/runpy.py", line 96, in _run_module_code 14 | mod_name, mod_spec, pkg_name, script_name) 15 | File "/home/alon/anaconda3/envs/rmg_env/lib/python3.7/runpy.py", line 85, in _run_code 16 | exec(code, run_globals) 17 | File "/home/alon/Code/RMG-Py/rmg.py", line 118, in 18 | main() 19 | File "/home/alon/Code/RMG-Py/rmg.py", line 112, in main 20 | rmg.execute(**kwargs) 21 | File "/home/alon/Code/RMG-Py/rmgpy/rmg/main.py", line 1026, in execute 22 | trimolecular_react=self.trimolecular_react) 23 | File "/home/alon/Code/RMG-Py/rmgpy/rmg/model.py", line 709, in enlarge 24 | self.update_unimolecular_reaction_networks() 25 | File "/home/alon/Code/RMG-Py/rmgpy/rmg/model.py", line 1918, in update_unimolecular_reaction_networks 26 | network.update(self, self.pressure_dependence) 27 | File "/home/alon/Code/RMG-Py/rmgpy/rmg/pdep.py", line 808, in update 28 | spec.generate_statmech() 29 | File "rmgpy/species.py", line 821, in rmgpy.species.Species.generate_statmech 30 | File "/home/alon/Code/RMG-Py/rmgpy/data/statmech.py", line 679, in get_statmech_data 31 | statmech_model = self.get_statmech_data_from_groups(molecule, thermo_model) 32 | File "/home/alon/Code/RMG-Py/rmgpy/data/statmech.py", line 713, in get_statmech_data_from_groups 33 | return self.groups['groups'].get_statmech_data(molecule, thermo_model) 34 | File "/home/alon/Code/RMG-Py/rmgpy/data/statmech.py", line 384, in get_statmech_data 35 | num_rotors = molecule.count_internal_rotors() 36 | AttributeError: 'Fragment' object has no attribute 'count_internal_rotors' 37 | -------------------------------------------------------------------------------- /tests/data/rmg_convergence/2_converged/err.txt: -------------------------------------------------------------------------------- 1 | /home/alon/anaconda3/envs/rmg_env/lib/python3.7/site-packages/scipy/optimize/optimize.py:1978: LinAlgWarning: Ill-conditioned matrix (rcond=9.79183e-18): result may not be accurate. 2 | fu = func(x, *args) 3 | /home/alon/Code/RMG-Py/rmgpy/rmg/main.py:907: RuntimeWarning: invalid value encountered in true_divide 4 | conditions=self.rmg_memories[index].get_cond() 5 | /home/alon/Code/RMG-Py/rmgpy/rmg/main.py:907: RuntimeWarning: divide by zero encountered in true_divide 6 | conditions=self.rmg_memories[index].get_cond() 7 | -------------------------------------------------------------------------------- /tests/test_logger.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | """ 5 | t3 tests test_logger module 6 | """ 7 | 8 | import datetime 9 | import os 10 | import shutil 11 | from typing import Optional 12 | 13 | from t3.common import TEST_DATA_BASE_PATH 14 | import t3.logger as logger 15 | 16 | 17 | log_project_directory = os.path.join(TEST_DATA_BASE_PATH, 'log_file_testing_dir') 18 | 19 | 20 | def init_logger(project: str = 'project_name', 21 | project_directory: str = log_project_directory, 22 | verbose: Optional[int] = 10, 23 | t0: Optional[datetime.datetime] = None, 24 | ) -> logger.Logger: 25 | """Initialize the logger""" 26 | if t0 is None: 27 | t0 = datetime.datetime.now() 28 | if not os.path.isdir(log_project_directory): 29 | os.mkdir(log_project_directory) 30 | return logger.Logger(project=project, 31 | project_directory=project_directory, 32 | verbose=verbose, 33 | t0=t0, 34 | ) 35 | 36 | 37 | def test_initialize_logger(): 38 | """Test initializing the logger""" 39 | logger_object = init_logger() 40 | assert isinstance(logger_object, logger.Logger) 41 | assert logger_object.project == 'project_name' 42 | assert logger_object.project_directory == log_project_directory 43 | assert logger_object.verbose == 10 44 | assert isinstance(logger_object.t0, datetime.datetime) 45 | shutil.rmtree(log_project_directory, ignore_errors=True) 46 | 47 | 48 | def log_messages(logger_object): 49 | """A helper function for logging dummy messages""" 50 | logger_object.log('message A') 51 | logger_object.log('message B', level='debug') 52 | logger_object.log('message C', level='info') 53 | logger_object.log('message D', level='warning') 54 | logger_object.log('message E', level='error') 55 | logger_object.log('message F', level='always') 56 | logger_object.log('not logging this line to file', level=None) 57 | 58 | 59 | def test_log(): 60 | """Test logging messages""" 61 | logger_object = init_logger(verbose=10) # debug 62 | log_messages(logger_object) 63 | with open(os.path.join(log_project_directory, 't3.log')) as f: 64 | lines = f.readlines() 65 | for line in ['message A\n', 66 | 'message B\n', 67 | 'message C\n', 68 | 'WARNING: message D\n', 69 | 'ERROR: message E\n', 70 | 'message F\n', 71 | ]: 72 | assert line in lines 73 | for line in ['not logging this line to file\n', 74 | ]: 75 | assert line not in lines 76 | shutil.rmtree(log_project_directory, ignore_errors=True) 77 | 78 | logger_object = init_logger(verbose=20) # info 79 | log_messages(logger_object) 80 | with open(os.path.join(log_project_directory, 't3.log')) as f: 81 | lines = f.readlines() 82 | for line in ['message A\n', 83 | 'message C\n', 84 | 'WARNING: message D\n', 85 | 'ERROR: message E\n', 86 | 'message F\n', 87 | ]: 88 | print('*****', line) 89 | assert line in lines 90 | for line in ['message B\n', 91 | 'not logging this line to file\n', 92 | ]: 93 | assert line not in lines 94 | shutil.rmtree(log_project_directory, ignore_errors=True) 95 | 96 | logger_object = init_logger(verbose=30) # warning 97 | log_messages(logger_object) 98 | with open(os.path.join(log_project_directory, 't3.log')) as f: 99 | lines = f.readlines() 100 | for line in [ 101 | 'WARNING: message D\n', 102 | 'ERROR: message E\n', 103 | 'message F\n', 104 | ]: 105 | assert line in lines 106 | for line in ['message A\n', 107 | 'message B\n', 108 | 'message C\n', 109 | 'not logging this line to file\n', 110 | ]: 111 | assert line not in lines 112 | shutil.rmtree(log_project_directory, ignore_errors=True) 113 | 114 | 115 | def test_log_max_time_reached(): 116 | """Test logging reaching the maximum walltime""" 117 | logger_object = init_logger(verbose=30) # warning 118 | logger_object.log_max_time_reached(max_time='01:00:00:00') 119 | with open(os.path.join(log_project_directory, 't3.log')) as f: 120 | lines = f.readlines() 121 | assert 'Terminating T3 due to time limit.\n' in lines 122 | shutil.rmtree(log_project_directory, ignore_errors=True) 123 | -------------------------------------------------------------------------------- /tests/test_rmg_runner.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | """ 5 | t3 tests test_rmg_runner module 6 | """ 7 | 8 | import os 9 | from t3.common import TEST_DATA_BASE_PATH, EXAMPLES_BASE_PATH 10 | from t3.runners.rmg_runner import rmg_job_converged, write_submit_script 11 | 12 | 13 | class TestWriteSubmitScript(object): 14 | 15 | def test_minimal_write_submit_script(self): 16 | """ 17 | Test the write_submit_script() function with minimal input. 18 | write_submit_script params are set as their default values 19 | This test will create a job.sh file in the project directory path and the assertion will check if the file exists 20 | and matches the expected file 21 | """ 22 | project_directory_path = os.path.join(EXAMPLES_BASE_PATH, "minimal") 23 | 24 | write_submit_script(project_directory_path, 25 | cpus=None, 26 | memory=None, 27 | verbose=None, 28 | max_iterations=None, 29 | t3_project_name=None) 30 | 31 | expected = f"""#!/bin/bash -l 32 | 33 | #PBS -N None_RMG 34 | #PBS -q zeus_long_q 35 | #PBS -l walltime=168:00:00 36 | #PBS -l select=1:ncpus=16 37 | #PBS -o out.txt 38 | #PBS -e err.txt 39 | 40 | PBS_O_WORKDIR={project_directory_path} 41 | cd $PBS_O_WORKDIR 42 | 43 | conda activate rmg_env 44 | 45 | touch initial_time 46 | 47 | python-jl $rmgpy_path/rmg.py -n 16 input.pyNone 48 | 49 | touch final_time 50 | 51 | """ 52 | 53 | assert os.path.isfile(os.path.join(project_directory_path, "submit.sh")) 54 | with open(os.path.join(project_directory_path, "submit.sh"), "r") as f: 55 | content = f.read() 56 | assert content == expected 57 | 58 | def test_minimal_project_name_included(self): 59 | """Test that thew minimal project name is included in the PBS submit script.""" 60 | project_directory_path = os.path.join(EXAMPLES_BASE_PATH, "minimal") 61 | t3_proj_name = "T3_test_name" 62 | write_submit_script(project_directory_path, 63 | cpus=None, 64 | memory=None, 65 | verbose=None, 66 | max_iterations=None, 67 | t3_project_name=t3_proj_name) 68 | expected_submit = f"""#!/bin/bash -l 69 | 70 | #PBS -N {t3_proj_name}_RMG 71 | #PBS -q zeus_long_q 72 | #PBS -l walltime=168:00:00 73 | #PBS -l select=1:ncpus=16 74 | #PBS -o out.txt 75 | #PBS -e err.txt 76 | 77 | PBS_O_WORKDIR={project_directory_path} 78 | cd $PBS_O_WORKDIR 79 | 80 | conda activate rmg_env 81 | 82 | touch initial_time 83 | 84 | python-jl $rmgpy_path/rmg.py -n 16 input.pyNone 85 | 86 | touch final_time 87 | 88 | """ 89 | 90 | assert os.path.isfile(os.path.join(project_directory_path, "submit.sh")) 91 | with open(os.path.join(project_directory_path, "submit.sh"), "r") as f: 92 | content_submit = f.read() 93 | assert content_submit == expected_submit 94 | 95 | def test_minimal_parameters_set(self): 96 | """Test creating a submit script for the minimal example.""" 97 | project_directory_path = os.path.join(EXAMPLES_BASE_PATH, "minimal") 98 | 99 | # To be edited by user if required: 100 | t3_proj_name = "T3_test_name" 101 | cpus = 8 102 | max_iter = "-m 100" 103 | mem = 16000 # in MB 104 | ######################################### 105 | write_submit_script(project_directory_path, 106 | cpus=cpus, 107 | memory=mem, # in MB 108 | verbose="-v 20", 109 | max_iterations=max_iter, 110 | t3_project_name=t3_proj_name) 111 | 112 | expected_submit = f"""#!/bin/bash -l 113 | 114 | #PBS -N T3_test_name_RMG 115 | #PBS -q zeus_long_q 116 | #PBS -l walltime=168:00:00 117 | #PBS -l select=1:ncpus=8 118 | #PBS -o out.txt 119 | #PBS -e err.txt 120 | 121 | PBS_O_WORKDIR={project_directory_path} 122 | cd $PBS_O_WORKDIR 123 | 124 | conda activate rmg_env 125 | 126 | touch initial_time 127 | 128 | python-jl $rmgpy_path/rmg.py -n 8 input.py-m 100 129 | 130 | touch final_time 131 | 132 | """ 133 | assert os.path.isfile(os.path.join(project_directory_path, "submit.sh")) 134 | 135 | with open(os.path.join(project_directory_path, "submit.sh"), "r") as submit_file: 136 | content_submit = submit_file.read() 137 | assert content_submit == expected_submit 138 | 139 | def test_rmg_job_converged(self): 140 | """Test correctly identifying whether an RMG job converged ot not, and if not which error was received.""" 141 | rmg_folder_1 = os.path.join(TEST_DATA_BASE_PATH, 'rmg_convergence', '1_frag_error') 142 | converged, error = rmg_job_converged(project_directory=rmg_folder_1) 143 | assert not converged 144 | assert error == "AttributeError: 'Fragment' object has no attribute 'count_internal_rotors'" 145 | 146 | rmg_folder_2 = os.path.join(TEST_DATA_BASE_PATH, 'rmg_convergence', '2_converged') 147 | converged, error = rmg_job_converged(project_directory=rmg_folder_2) 148 | assert converged 149 | assert error is None 150 | 151 | 152 | def teardown_module(): 153 | """teardown any state that was previously setup with a setup_module method.""" 154 | file_paths = [os.path.join(EXAMPLES_BASE_PATH, 'minimal', 'submit.sh')] 155 | for file_path in file_paths: 156 | if os.path.isfile(file_path): 157 | os.remove(file_path) 158 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/data/cantera_simulator_test/input.yml: -------------------------------------------------------------------------------- 1 | project: T3_minimal 2 | 3 | t3: 4 | options: 5 | max_T3_iterations: 2 6 | max_RMG_walltime: '00:00:05:00' 7 | sensitivity: 8 | adapter: CanteraConstantTP # *required* (this is how SA is requested), can use any implemented simulation adapter 9 | top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10 10 | 11 | rmg: 12 | database: 13 | thermo_libraries: ['primaryThermoLibrary'] 14 | kinetics_libraries: [] 15 | species: 16 | - label: H2 17 | smiles: '[H][H]' 18 | concentration: 0.67 19 | - label: O2 20 | smiles: '[O][O]' 21 | concentration: 0.33 22 | - label: H 23 | smiles: '[H]' 24 | SA_observable: true 25 | - label: OH 26 | smiles: '[OH]' 27 | SA_observable: true 28 | reactors: 29 | - type: gas batch constant T P 30 | T: 1000 31 | P: 1 32 | termination_conversion: 33 | 'H2': 0.9 34 | termination_time: [1, 's'] 35 | model: 36 | core_tolerance: [0.01, 0.001] 37 | options: 38 | save_simulation_profiles: true 39 | 40 | qm: 41 | adapter: ARC 42 | level_of_theory: 'b3lyp/6-31g(d,p)' 43 | job_types: 44 | rotors: false 45 | conformers: true 46 | fine: false 47 | freq: true 48 | opt: true 49 | sp: true 50 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/data/cantera_simulator_test/iteration_0/RMG/chemkin/species_dictionary.txt: -------------------------------------------------------------------------------- 1 | Ar 2 | 1 Ar u0 p4 c0 3 | 4 | He 5 | 1 He u0 p1 c0 6 | 7 | Ne 8 | 1 Ne u0 p4 c0 9 | 10 | N2 11 | 1 N u0 p1 c0 {2,T} 12 | 2 N u0 p1 c0 {1,T} 13 | 14 | H2(1) 15 | 1 H u0 p0 c0 {2,S} 16 | 2 H u0 p0 c0 {1,S} 17 | 18 | O2(2) 19 | multiplicity 3 20 | 1 O u1 p2 c0 {2,S} 21 | 2 O u1 p2 c0 {1,S} 22 | 23 | H(3) 24 | multiplicity 2 25 | 1 H u1 p0 c0 26 | 27 | OH(4) 28 | multiplicity 2 29 | 1 O u1 p2 c0 {2,S} 30 | 2 H u0 p0 c0 {1,S} 31 | 32 | HO2(6) 33 | multiplicity 2 34 | 1 O u0 p2 c0 {2,S} {3,S} 35 | 2 O u1 p2 c0 {1,S} 36 | 3 H u0 p0 c0 {1,S} 37 | 38 | OO(9) 39 | 1 O u0 p2 c0 {2,S} {3,S} 40 | 2 O u0 p2 c0 {1,S} {4,S} 41 | 3 H u0 p0 c0 {1,S} 42 | 4 H u0 p0 c0 {2,S} 43 | 44 | H2O(7) 45 | 1 O u0 p2 c0 {2,S} {3,S} 46 | 2 H u0 p0 c0 {1,S} 47 | 3 H u0 p0 c0 {1,S} 48 | 49 | O(T)(5) 50 | multiplicity 3 51 | 1 O u2 p2 c0 52 | 53 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/data/cantera_simulator_test/iteration_0/RMG/input.py: -------------------------------------------------------------------------------- 1 | database( 2 | thermoLibraries=['primaryThermoLibrary'], 3 | reactionLibraries=[], 4 | transportLibraries=['OneDMinN2', 'PrimaryTransportLibrary', 'NOx2018', 'GRI-Mech'], 5 | seedMechanisms=[], 6 | kineticsDepositories='default', 7 | kineticsFamilies='default', 8 | kineticsEstimator='rate rules', 9 | ) 10 | 11 | species( 12 | label='H2', 13 | reactive=True, 14 | structure=SMILES('[H][H]'), 15 | ) 16 | 17 | species( 18 | label='O2', 19 | reactive=True, 20 | structure=SMILES('[O][O]'), 21 | ) 22 | 23 | species( 24 | label='H', 25 | reactive=True, 26 | structure=SMILES('[H]'), 27 | ) 28 | 29 | species( 30 | label='OH', 31 | reactive=True, 32 | structure=SMILES('[OH]'), 33 | ) 34 | 35 | simpleReactor( 36 | temperature=(1000.0, 'K'), 37 | pressure=(1.0, 'bar'), 38 | initialMoleFractions={ 39 | 'H2': 0.67, 40 | 'O2': 0.33, 41 | 'H': 0, 42 | 'OH': 0, 43 | }, 44 | terminationConversion={'H2': 0.9}, 45 | terminationTime=(1.0, 's'), 46 | nSims=12, 47 | ) 48 | 49 | model( 50 | toleranceMoveToCore=0.001, 51 | toleranceInterruptSimulation=0.001, 52 | filterReactions=False, 53 | filterThreshold=100000000.0, 54 | maxNumObjsPerIter=1, 55 | terminateAtMaxObjects=False, 56 | ) 57 | 58 | simulator(atol=1e-16, rtol=1e-08) 59 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/data/rmg_simulator_test/input.yml: -------------------------------------------------------------------------------- 1 | project: T3_minimal 2 | 3 | t3: 4 | options: 5 | max_T3_iterations: 2 6 | max_RMG_walltime: '00:00:05:00' 7 | sensitivity: 8 | adapter: RMGConstantTP # *required* (this is how SA is requested), can use any implemented simulation adapter 9 | top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10 10 | 11 | rmg: 12 | database: 13 | thermo_libraries: ['primaryThermoLibrary'] 14 | kinetics_libraries: [] 15 | species: 16 | - label: H2 17 | smiles: '[H][H]' 18 | concentration: 0.67 19 | - label: O2 20 | smiles: '[O][O]' 21 | concentration: 0.33 22 | - label: H 23 | smiles: '[H]' 24 | SA_observable: true 25 | - label: OH 26 | smiles: '[OH]' 27 | SA_observable: true 28 | reactors: 29 | - type: gas batch constant T P 30 | T: 1000 31 | P: 1 32 | termination_conversion: 33 | 'H2': 0.9 34 | termination_time: [1, 's'] 35 | model: 36 | core_tolerance: [0.01, 0.001] 37 | options: 38 | save_simulation_profiles: true 39 | 40 | qm: 41 | adapter: ARC 42 | level_of_theory: 'b3lyp/6-31g(d,p)' 43 | job_types: 44 | rotors: false 45 | conformers: true 46 | fine: false 47 | freq: true 48 | opt: true 49 | sp: true 50 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/data/rmg_simulator_test/iteration_0/RMG/chemkin/species_dictionary.txt: -------------------------------------------------------------------------------- 1 | Ar 2 | 1 Ar u0 p4 c0 3 | 4 | He 5 | 1 He u0 p1 c0 6 | 7 | Ne 8 | 1 Ne u0 p4 c0 9 | 10 | N2 11 | 1 N u0 p1 c0 {2,T} 12 | 2 N u0 p1 c0 {1,T} 13 | 14 | H2(1) 15 | 1 H u0 p0 c0 {2,S} 16 | 2 H u0 p0 c0 {1,S} 17 | 18 | O2(2) 19 | multiplicity 3 20 | 1 O u1 p2 c0 {2,S} 21 | 2 O u1 p2 c0 {1,S} 22 | 23 | H(3) 24 | multiplicity 2 25 | 1 H u1 p0 c0 26 | 27 | OH(4) 28 | multiplicity 2 29 | 1 O u1 p2 c0 {2,S} 30 | 2 H u0 p0 c0 {1,S} 31 | 32 | HO2(6) 33 | multiplicity 2 34 | 1 O u0 p2 c0 {2,S} {3,S} 35 | 2 O u1 p2 c0 {1,S} 36 | 3 H u0 p0 c0 {1,S} 37 | 38 | OO(9) 39 | 1 O u0 p2 c0 {2,S} {3,S} 40 | 2 O u0 p2 c0 {1,S} {4,S} 41 | 3 H u0 p0 c0 {1,S} 42 | 4 H u0 p0 c0 {2,S} 43 | 44 | H2O(7) 45 | 1 O u0 p2 c0 {2,S} {3,S} 46 | 2 H u0 p0 c0 {1,S} 47 | 3 H u0 p0 c0 {1,S} 48 | 49 | O(T)(5) 50 | multiplicity 3 51 | 1 O u2 p2 c0 52 | 53 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/data/rmg_simulator_test/iteration_0/RMG/input.py: -------------------------------------------------------------------------------- 1 | database( 2 | thermoLibraries=['primaryThermoLibrary'], 3 | reactionLibraries=[], 4 | transportLibraries=['OneDMinN2', 'PrimaryTransportLibrary', 'NOx2018', 'GRI-Mech'], 5 | seedMechanisms=[], 6 | kineticsDepositories='default', 7 | kineticsFamilies='default', 8 | kineticsEstimator='rate rules', 9 | ) 10 | 11 | species( 12 | label='H2', 13 | reactive=True, 14 | structure=SMILES('[H][H]'), 15 | ) 16 | 17 | species( 18 | label='O2', 19 | reactive=True, 20 | structure=SMILES('[O][O]'), 21 | ) 22 | 23 | species( 24 | label='H', 25 | reactive=True, 26 | structure=SMILES('[H]'), 27 | ) 28 | 29 | species( 30 | label='OH', 31 | reactive=True, 32 | structure=SMILES('[OH]'), 33 | ) 34 | 35 | simpleReactor( 36 | temperature=(1000.0, 'K'), 37 | pressure=(1.0, 'bar'), 38 | initialMoleFractions={ 39 | 'H2': 0.67, 40 | 'O2': 0.33, 41 | }, 42 | terminationConversion={'H2': 0.9}, 43 | terminationTime=(5.0, 's'), 44 | nSims=12, 45 | ) 46 | 47 | model( 48 | toleranceMoveToCore=0.01, 49 | toleranceInterruptSimulation=0.01, 50 | filterReactions=True, 51 | filterThreshold=100000000.0, 52 | maxNumObjsPerIter=1, 53 | terminateAtMaxObjects=False, 54 | ) 55 | 56 | simulator(atol=1e-16, rtol=1e-08, sens_atol=1e-06, sens_rtol=0.0001) 57 | 58 | options( 59 | name='Seed', 60 | generateSeedEachIteration=True, 61 | saveSeedToDatabase=False, 62 | units='si', 63 | generateOutputHTML=False, 64 | generatePlots=False, 65 | saveSimulationProfiles=False, 66 | verboseComments=False, 67 | saveEdgeSpecies=True, 68 | keepIrreversible=False, 69 | trimolecularProductReversible=True, 70 | wallTime='00:00:05:00', 71 | saveSeedModulus=-1, 72 | ) 73 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/data/rmg_simulator_test_ranges_3c/t3.log: -------------------------------------------------------------------------------- 1 | T3 execution initiated on Tue Aug 15 16:39:28 2023 2 | 3 | ################################################################ 4 | # # 5 | # The Tandem Tool (T3) # 6 | # for automated chemical kinetic model development # 7 | # # 8 | # Version: 0.1.0 # 9 | # # 10 | ################################################################ 11 | 12 | 13 | The current git HEAD for T3 is: 14 | a29e9884c7ce4b6c99ade2c31c9fba2202947440 15 | Tue Aug 15 16:11:06 2023 +0300 16 | (running on the c_conc_in_sim branch) 17 | 18 | Starting project xfa1014 19 | 20 | 21 | Using the following arguments: 22 | 23 | project: xfa1014 24 | project_directory: /home/alon/Code/T3/tests/test_simulate_adapters/data/rmg_simulator_test_ranges_3c 25 | verbose: info 26 | t3: 27 | options: 28 | all_core_species: True 29 | max_T3_iterations: 5 30 | max_RMG_exceptions_allowed: 5 31 | library_name: FA 32 | sensitivity: 33 | adapter: RMGConstantTP 34 | SA_threshold: 0.01 35 | pdep_SA_threshold: 0.001 36 | ME_methods: ['MSC'] 37 | top_SA_reactions: 0 38 | rmg: 39 | database: 40 | thermo_libraries: ['primaryThermoLibrary', 'BurkeH2O2', 'thermo_DFT_CCSDTF12_BAC', 'DFT_QCI_thermo', 'Spiekermann_refining_elementary_reactions', 'CurranPentane', 'CBS_QB3_1dHR', 'primaryNS'] 41 | kinetics_libraries: ['primaryH2O2', 'NOx2018', '2006_Joshi_OH_CO', 'CurranPentane', 'Klippenstein_Glarborg2016', 'C2H4+O_Klipp2017', 'FFCM1(-)', 'C2H2_init', 'Narayanaswamy', 'Mebel_C6H5_C2H2', 'C10H11', 'C12H11_pdep', 'Lai_Hexylbenzene', '1989_Stewart_2CH3_to_C2H5_H', '2001_Tokmakov_H_Toluene_to_CH3_Benzene', '2003_Miller_Propargyl_Recomb_High_P', '2005_Senosiain_OH_C2H2', 'kislovB', 'c-C5H5_CH3_Sharma', 'fascella', '2006_Joshi_OH_CO', '2009_Sharma_C5H5_CH3_highP', '2015_Buras_C2H3_C4H6_highP', 'C3', 'Methylformate', 'C6H5_C4H4_Mebel', 'vinylCPD_H', 'Mebel_Naphthyl', 'Fulvene_H'] 42 | reactors: [{'type': 'gas batch constant T P', 'T': [500.0, 2000.0], 'P': [1.0, 100.0], 'termination_time': (60.0, 's')}] 43 | species: [{'label': 'FA', 'concentration': (1.0, 4.0), 'smiles': 'OC=O', 'observable': True}, {'label': 'N2', 'concentration': 3.76, 'smiles': 'N#N', 'reactive': False}, {'label': 'O2', 'concentration': 1.0, 'smiles': '[O][O]'}, {'label': 'OH', 'smiles': '[OH]', 'observable': True}, {'label': 'HO2', 'smiles': 'O[O]', 'observable': True}, {'label': 'H', 'smiles': '[H]', 'observable': True}, {'label': 'H2', 'smiles': '[H][H]', 'observable': True}, {'label': 'CH3', 'smiles': '[CH3]', 'observable': True}, {'label': 'CO', 'smiles': '[C-]#[O+]', 'observable': True}, {'label': 'CO2', 'smiles': 'O=C=O', 'observable': True}, {'label': 'HOCO', 'smiles': 'O[C]=O', 'observable': True}, {'label': 'OCHO', 'smiles': '[O]C=O', 'observable': True}, {'label': 'CH2O', 'smiles': 'C=O', 'observable': True}, {'label': 'HCO', 'smiles': '[CH]=O', 'observable': True}] 44 | model: 45 | core_tolerance: [0.2, 0.1, 0.05, 0.01, 0.001] 46 | pdep: 47 | method: MSC 48 | max_grain_size: 2.0 49 | max_number_of_grains: 250 50 | T: [300, 2500, 10] 51 | P: [0.1, 110, 10] 52 | interpolation: Chebyshev 53 | options: 54 | save_edge: False 55 | save_html: True 56 | save_simulation_profiles: True 57 | species_constraints: 58 | allowed: ['input species', 'seed mechanisms', 'reaction libraries'] 59 | max_C_atoms: 2 60 | max_O_atoms: 4 61 | max_N_atoms: 0 62 | max_Si_atoms: 0 63 | max_S_atoms: 0 64 | max_heavy_atoms: 5 65 | max_radical_electrons: 1 66 | max_singlet_carbenes: 1 67 | max_carbene_radicals: 0 68 | qm: 69 | adapter: ARC 70 | job_types: 71 | rotors: False 72 | level_of_theory: CBS-QB3 73 | 74 | Running a simulation using RMGConstantTP... 75 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/data/rms_simulator_test/input.yml: -------------------------------------------------------------------------------- 1 | project: T3_minimal 2 | 3 | t3: 4 | options: 5 | max_T3_iterations: 2 6 | max_RMG_walltime: '00:00:05:00' 7 | sensitivity: 8 | adapter: RMSConstantTP # *required* (this is how SA is requested), can use any implemented simulation adapter 9 | top_SA_species: 10 # optional, used per observable to determine thermo to calculate, default: 10 10 | 11 | rmg: 12 | database: 13 | thermo_libraries: ['primaryThermoLibrary'] 14 | kinetics_libraries: [] 15 | species: 16 | - label: H2 17 | smiles: '[H][H]' 18 | concentration: 0.67 19 | - label: O2 20 | smiles: '[O][O]' 21 | concentration: 0.33 22 | - label: H 23 | smiles: '[H]' 24 | SA_observable: true 25 | - label: OH 26 | smiles: '[OH]' 27 | SA_observable: true 28 | reactors: 29 | - type: gas batch constant T P 30 | T: 1000 31 | P: 1 32 | termination_conversion: 33 | 'H2': 0.9 34 | termination_time: [0.1, 'ms'] 35 | model: 36 | core_tolerance: [0.01, 0.001] 37 | options: 38 | save_simulation_profiles: true 39 | 40 | qm: 41 | adapter: ARC 42 | level_of_theory: 'b3lyp/6-31g(d,p)' 43 | job_types: 44 | rotors: false 45 | conformers: true 46 | fine: false 47 | freq: true 48 | opt: true 49 | sp: true 50 | -------------------------------------------------------------------------------- /tests/test_simulate_adapters/test_rmg_constantTP.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # encoding: utf-8 3 | 4 | """ 5 | t3 tests test_rmg_constantTP module 6 | """ 7 | 8 | import os 9 | import shutil 10 | 11 | from t3.common import SIMULATE_TEST_DATA_BASE_PATH 12 | from tests.common import run_minimal 13 | from t3.simulate.rmg_constantTP import RMGConstantTP 14 | 15 | 16 | TEST_DIR = os.path.join(SIMULATE_TEST_DATA_BASE_PATH, 'rmg_simulator_test') 17 | 18 | 19 | def test_set_up_no_sa(): 20 | """ 21 | Run RMG's minimal example without SA by testing the `set_up` method within the RMGSimulator init method. 22 | By setting observable_list = list(), no SA is run. Instead, RMG is just used to simulate the mechanism. 23 | """ 24 | t3 = run_minimal(project_directory=TEST_DIR) 25 | t3.set_paths() 26 | 27 | rmg_simulator_adapter = RMGConstantTP(t3=t3.t3, 28 | rmg=t3.rmg, 29 | paths=t3.paths, 30 | logger=t3.logger, 31 | atol=t3.rmg['model']['atol'], 32 | rtol=t3.rmg['model']['rtol'], 33 | observable_list=list(), 34 | ) 35 | rmg_simulator_adapter.simulate() 36 | # check that RMG produced the concentration profiles 37 | concentration_profiles = os.path.isfile(os.path.join(t3.paths['RMG'], 'solver', 'simulation_1_12.csv')) 38 | assert concentration_profiles 39 | 40 | 41 | def test_get_sa_coefficients(): 42 | """ 43 | Run RMG's minimal example with SA by testing the `set_up` method within the RMGConstantTP init method. 44 | Then run the `get_sa_coefficients()` method to test that RMGConstantTP correctly parses the SA csv files 45 | to obtain sa_dict. 46 | """ 47 | t3 = run_minimal(project_directory=TEST_DIR) 48 | t3.set_paths() 49 | observable_list = ['OH', 'H'] 50 | rmg_simulator_adapter = RMGConstantTP(t3=t3.t3, 51 | rmg=t3.rmg, 52 | paths=t3.paths, 53 | logger=t3.logger, 54 | atol=t3.rmg['model']['atol'], 55 | rtol=t3.rmg['model']['rtol'], 56 | observable_list=observable_list, 57 | sa_atol=t3.t3['sensitivity']['atol'], 58 | sa_rtol=t3.t3['sensitivity']['rtol'], 59 | ) 60 | rmg_simulator_adapter.simulate() 61 | # check that RMG ran SA 62 | performed_sa = os.path.isdir(t3.paths['SA']) 63 | assert performed_sa 64 | # check that RMG produced the corresponding csv files 65 | files = ['sensitivity_1_SPC_3.csv', 'sensitivity_1_SPC_4.csv', 'simulation_1_12.csv'] 66 | for file in files: 67 | exist = os.path.isfile(os.path.join(t3.paths['SA solver'], file)) 68 | assert exist 69 | # check that RMG can correctly parse the csv files to product the SA dictionary 70 | sa_dict = rmg_simulator_adapter.get_sa_coefficients() 71 | # check that there are over 100 time steps (as an arbitrary number) to indicate that the solver completed 72 | assert len(sa_dict['time']) > 100 73 | # check that there are SA data for the 2 requested species 74 | assert len(sa_dict['kinetics']) == 2 75 | assert len(sa_dict['thermo']) == 2 76 | 77 | 78 | def test_get_idt_by_T(): 79 | """ 80 | Calculate the ignition delay time for RMG's minimal example. 81 | Since this adapter simulates at constant T, this method returns a dictionary whose values are empty lists. 82 | """ 83 | t3 = run_minimal(project_directory=TEST_DIR) 84 | t3.set_paths() 85 | rmg_simulator_adapter = RMGConstantTP(t3=t3.t3, 86 | rmg=t3.rmg, 87 | paths=t3.paths, 88 | logger=t3.logger, 89 | atol=t3.rmg['model']['atol'], 90 | rtol=t3.rmg['model']['rtol'], 91 | observable_list=list(), 92 | ) 93 | rmg_simulator_adapter.simulate() 94 | idt_dict = rmg_simulator_adapter.get_idt_by_T() 95 | assert len(idt_dict['idt']) == 0 96 | assert len(idt_dict['idt_index']) == 0 97 | 98 | 99 | def teardown_module(): 100 | """ 101 | A method that is run after all unit tests in this class. 102 | Delete all project directories created during these unit tests 103 | """ 104 | solver_directory = os.path.join(TEST_DIR, 'iteration_0', 'RMG', 'solver') 105 | species_directory = os.path.join(TEST_DIR, 'iteration_0', 'RMG', 'species') 106 | sa_directory = os.path.join(TEST_DIR, 'iteration_0', 'SA') 107 | log_archive = os.path.join(TEST_DIR, 'log_archive') 108 | dirs = [solver_directory, species_directory, sa_directory, log_archive] 109 | for dir in dirs: 110 | if os.path.isdir(dir): 111 | shutil.rmtree(dir, ignore_errors=True) 112 | files = [os.path.join(TEST_DIR, 't3.log')] 113 | for file in files: 114 | if os.path.isfile(file): 115 | os.remove(file) 116 | --------------------------------------------------------------------------------