├── .clang-format ├── .github ├── dependabot.yml └── workflows │ └── unit-test.yaml ├── .gitignore ├── .mailmap ├── .pre-commit-config.yaml ├── .readthedocs.yaml ├── CHANGELOG.rst ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── doc ├── Makefile ├── _static │ └── .keep ├── _templates │ └── .keep ├── conf.py ├── credits.rst ├── environment.yaml ├── index.rst ├── license.rst ├── make.bat ├── mock_install.py ├── module-azplugins-bond.rst ├── module-azplugins-compute.rst ├── module-azplugins-external.rst ├── module-azplugins-flow.rst ├── module-azplugins-pair.rst └── release.rst ├── ruff.toml └── src ├── AnisoPairEvaluator.h ├── AnisoPairEvaluatorTwoPatchMorse.h ├── AnisoPotentialPairGPUKernel.cu.inc ├── BinningOperation.h ├── BondEvaluator.h ├── BondEvaluatorDoubleWell.h ├── BondEvaluatorQuartic.h ├── CMakeLists.txt ├── CartesianBinningOperation.h ├── ConstantFlow.cc ├── ConstantFlow.h ├── CylindricalBinningOperation.h ├── DPDPairEvaluatorGeneralWeight.h ├── HarmonicBarrier.h ├── HarmonicBarrierGPU.cuh ├── HarmonicBarrierGPU.h ├── HarmonicBarrierGPUKernel.cu.inc ├── PairEvaluator.h ├── PairEvaluatorColloid.h ├── PairEvaluatorExpandedYukawa.h ├── PairEvaluatorHertz.h ├── PairEvaluatorPerturbedLennardJones.h ├── ParabolicFlow.cc ├── ParabolicFlow.h ├── ParticleDataLoader.h ├── ParticleEvaporator.cc ├── ParticleEvaporator.h ├── ParticleEvaporatorGPU.cc ├── ParticleEvaporatorGPU.cu ├── ParticleEvaporatorGPU.cuh ├── ParticleEvaporatorGPU.h ├── PlanarBarrierEvaluator.h ├── PotentialBondGPUKernel.cu.inc ├── PotentialPairDPDThermoGPUKernel.cu.inc ├── PotentialPairGPUKernel.cu.inc ├── RNGIdentifiers.h ├── SphericalBarrierEvaluator.h ├── TwoStepBrownianFlow.h ├── TwoStepBrownianFlowGPU.cu ├── TwoStepBrownianFlowGPU.cuh ├── TwoStepBrownianFlowGPU.h ├── TwoStepLangevinFlow.h ├── TwoStepLangevinFlowGPU.cu ├── TwoStepLangevinFlowGPU.cuh ├── TwoStepLangevinFlowGPU.h ├── TypeUpdater.cc ├── TypeUpdater.h ├── TypeUpdaterGPU.cc ├── TypeUpdaterGPU.cu ├── TypeUpdaterGPU.cuh ├── TypeUpdaterGPU.h ├── VariantSphereArea.cc ├── VariantSphereArea.h ├── VelocityCompute.cc ├── VelocityCompute.h ├── VelocityComputeGPU.cc ├── VelocityComputeGPU.cu ├── VelocityComputeGPU.cuh ├── VelocityComputeGPU.h ├── VelocityFieldCompute.h ├── VelocityFieldComputeGPU.cu ├── VelocityFieldComputeGPU.cuh ├── VelocityFieldComputeGPU.h ├── VelocityFieldComputeGPUKernel.cu.inc ├── WallEvaluatorColloid.h ├── WallEvaluatorLJ93.h ├── WallPotentials.cu ├── WallPotentials.h ├── __init__.py ├── bond.py ├── compute.py ├── conftest.py ├── export_AnisoPotentialPair.cc.inc ├── export_AnisoPotentialPairGPU.cc.inc ├── export_HarmonicBarrier.cc.inc ├── export_HarmonicBarrierGPU.cc.inc ├── export_PotentialBond.cc.inc ├── export_PotentialBondGPU.cc.inc ├── export_PotentialPair.cc.inc ├── export_PotentialPairDPDThermo.cc.inc ├── export_PotentialPairDPDThermoGPU.cc.inc ├── export_PotentialPairGPU.cc.inc ├── export_VelocityFieldCompute.cc.inc ├── export_VelocityFieldComputeGPU.cc.inc ├── external.py ├── flow.py ├── module.cc ├── pair.py └── pytest ├── CMakeLists.txt ├── __init__.py ├── test_bond.py ├── test_compute.py ├── test_external.py ├── test_flow.py ├── test_pair.py ├── test_pair_aniso.py └── test_pair_dpd.py /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: WebKit 3 | AccessModifierOffset: 0 4 | AlignAfterOpenBracket: Align 5 | AlignEscapedNewlines: 'Left' 6 | AlignOperands: 'true' 7 | AlignTrailingComments: 'true' 8 | AllowAllArgumentsOnNextLine: 'false' 9 | AllowAllParametersOfDeclarationOnNextLine: 'false' 10 | AllowShortFunctionsOnASingleLine: Empty 11 | AllowShortIfStatementsOnASingleLine: 'false' 12 | AllowShortLoopsOnASingleLine: 'false' 13 | BinPackArguments: 'false' 14 | BinPackParameters: 'false' 15 | BreakBeforeBraces: Whitesmiths 16 | BreakConstructorInitializers: BeforeColon 17 | ColumnLimit: '100' 18 | CompactNamespaces: 'true' 19 | Cpp11BracedListStyle: 'true' 20 | FixNamespaceComments: 'true' 21 | IndentWidth: '4' 22 | KeepEmptyLinesAtTheStartOfBlocks: false 23 | Language: Cpp 24 | NamespaceIndentation: None 25 | PointerAlignment: Left 26 | SortIncludes: 'true' 27 | SpaceAfterCStyleCast: 'false' 28 | SpaceAfterTemplateKeyword: 'false' 29 | SpaceBeforeParens: ControlStatements 30 | SpacesInAngles: 'false' 31 | SpaceInEmptyParentheses: false 32 | Standard: Cpp11 33 | TabWidth: '4' 34 | UseTab: Never 35 | 36 | ... 37 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | -------------------------------------------------------------------------------- /.github/workflows/unit-test.yaml: -------------------------------------------------------------------------------- 1 | name: Unit test 2 | 3 | env: 4 | COMPONENT_NAME: azplugins 5 | 6 | # Most components should not modify the rest of this file. When needed, merge in updates from 7 | # https://github.com/glotzerlab/hoomd-component-template/ 8 | 9 | ############################################################################################# 10 | # HOOMD-blue version to build. 11 | HOOMD_BLUE_VERSION: v5.0.1 12 | # prevent deadlocked MPI tests from causing the job to cancel 13 | MPIEXEC_TIMEOUT: 3000 14 | # allow mpirun to execute as root in the tests 15 | OMPI_ALLOW_RUN_AS_ROOT: 1 16 | OMPI_ALLOW_RUN_AS_ROOT_CONFIRM: 1 17 | # allow openmpi to oversubscribe cores 18 | PRTE_MCA_rmaps_default_mapping_policy: ":oversubscribe" 19 | OMPI_MCA_rmaps_base_oversubscribe: "true" 20 | # prevent errors from mis-configured openib systems 21 | OMPI_MCA_btl: "vader,self" 22 | 23 | concurrency: 24 | group: ${{ github.workflow }}-${{ github.ref }} 25 | cancel-in-progress: true 26 | 27 | on: 28 | pull_request: 29 | push: 30 | branches: [main] 31 | 32 | workflow_dispatch: 33 | 34 | defaults: 35 | run: 36 | shell: bash 37 | 38 | jobs: 39 | build_test: 40 | name: Build and test [${{ matrix.name }}] 41 | runs-on: ubuntu-24.04 42 | container: 43 | image: nvidia/cuda:12.5.0-devel-ubuntu22.04 44 | strategy: 45 | fail-fast: false 46 | matrix: 47 | include: 48 | - name: "CPU" 49 | enable_gpu: "OFF" 50 | enable_mpi: "OFF" 51 | - name: "CPU, MPI" 52 | enable_gpu: "OFF" 53 | enable_mpi: "ON" 54 | - name: "GPU" 55 | enable_gpu: "ON" 56 | enable_mpi: "OFF" 57 | - name: "GPU, MPI" 58 | enable_gpu: "ON" 59 | enable_mpi: "ON" 60 | 61 | steps: 62 | - name: Restore cached HOOMD-blue build 63 | id: cache 64 | uses: actions/cache/restore@v4 65 | with: 66 | path: install 67 | key: hoomd-blue-${{ env.HOOMD_BLUE_VERSION }}-mpi-${{ matrix.enable_mpi }}-gpu-${{ matrix.enable_gpu }} 68 | - name: Install git 69 | run: | 70 | apt-get update 71 | apt-get install git --yes 72 | - name: Checkout HOOMD-blue 73 | uses: actions/checkout@v4 74 | with: 75 | repository: glotzerlab/hoomd-blue 76 | path: hoomd-blue 77 | submodules: true 78 | ref: ${{ env.HOOMD_BLUE_VERSION }} 79 | - name: Create Python Environment 80 | uses: mamba-org/setup-micromamba@v2 81 | with: 82 | environment-name: test 83 | environment-file: hoomd-blue/.github/workflows/environments/py312-conda-lock.yml 84 | micromamba-root-path: ${{ github.workspace }}/micromamba 85 | 86 | - name: Configure conda environment variables 87 | run: | 88 | echo "PYTHONPATH=$GITHUB_WORKSPACE/install" >> $GITHUB_ENV 89 | echo "CONDA_PREFIX=$MAMBA_ROOT_PREFIX/envs/test" >> $GITHUB_ENV 90 | echo "CMAKE_PREFIX_PATH=$MAMBA_ROOT_PREFIX/envs/test" >> $GITHUB_ENV 91 | echo "$MAMBA_ROOT_PREFIX/envs/test/bin" >> $GITHUB_PATH 92 | 93 | - name: Configure HOOMD-blue 94 | if: steps.cache.outputs.cache-hit != 'true' 95 | run: | 96 | cmake -B build-hoomd-blue -S hoomd-blue \ 97 | -GNinja \ 98 | -DCMAKE_BUILD_TYPE=Release \ 99 | -DENABLE_GPU=${ENABLE_GPU} \ 100 | -DENABLE_MPI=${ENABLE_MPI} \ 101 | -DCUDA_ARCH_LIST="70" \ 102 | -DBUILD_TESTING=OFF \ 103 | -DBUILD_HPMC=OFF \ 104 | -DPLUGINS="" \ 105 | -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/install 106 | env: 107 | ENABLE_GPU: ${{ matrix.enable_gpu }} 108 | ENABLE_MPI: ${{ matrix.enable_mpi }} 109 | - name: Build HOOMD-blue 110 | if: steps.cache.outputs.cache-hit != 'true' 111 | run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) 112 | working-directory: build-hoomd-blue 113 | - name: Cache HOOMD-blue build 114 | if: steps.cache.outputs.cache-hit != 'true' 115 | uses: actions/cache/save@v4 116 | with: 117 | path: install 118 | key: hoomd-blue-${{ env.HOOMD_BLUE_VERSION }}-mpi-${{ matrix.enable_mpi }}-gpu-${{ matrix.enable_gpu }} 119 | 120 | - name: Checkout component 121 | uses: actions/checkout@v4 122 | with: 123 | path: component 124 | - name: Configure component 125 | run: CMAKE_PREFIX_PATH=${GITHUB_WORKSPACE}/install cmake -S component -B build-component -GNinja -DCMAKE_BUILD_TYPE=Release 126 | - name: Build component 127 | run: ninja install -j $(($(getconf _NPROCESSORS_ONLN) + 2)) 128 | working-directory: build-component 129 | 130 | - name: Run pytest (serial) 131 | run: python3 -m pytest --pyargs hoomd.${COMPONENT_NAME} -x -v -ra --durations=0 --durations-min=0.1 132 | - name: Run pytest (MPI) 133 | if: ${{ matrix.enable_mpi == 'ON' }} 134 | run: mpirun -n 2 ${GITHUB_WORKSPACE}/install/hoomd/pytest/pytest-openmpi.sh --pyargs hoomd.${COMPONENT_NAME} -x -v -ra --durations=0 --durations-min=0.1 || (( cat pytest.out.1 && exit 1 )) 135 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.ipynb_checkpoints* 3 | __pycache__ 4 | *.pyc 5 | build* 6 | doc/build 7 | doc/env 8 | **-checkpoint.ipynb 9 | -------------------------------------------------------------------------------- /.mailmap: -------------------------------------------------------------------------------- 1 | Michael Howard Michael Howard 2 | Michael Howard Michael Howard 3 | Antonia Statt Antonia Statt 4 | Antonia Statt Antonia Statt 5 | Antonia Statt Antonia Statt 6 | Antonia Statt azpgroup 7 | Antonia Statt Antonia Statt <49729189+astatt@users.noreply.github.com> 8 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | ci: 2 | autoupdate_schedule: quarterly 3 | autoupdate_branch: 'main' 4 | autofix_prs: false 5 | 6 | repos: 7 | - repo: https://github.com/pre-commit/pre-commit-hooks 8 | rev: 'v5.0.0' 9 | hooks: 10 | - id: end-of-file-fixer 11 | exclude_types: [svg] 12 | - id: trailing-whitespace 13 | exclude_types: [svg] 14 | - id: check-json 15 | - id: check-yaml 16 | - id: check-case-conflict 17 | - id: mixed-line-ending 18 | - repo: https://github.com/glotzerlab/fix-license-header 19 | rev: v0.4.1 20 | hooks: 21 | - id: fix-license-header 22 | name: Fix license headers (Python) 23 | types_or: [python] 24 | args: 25 | - --license-file=LICENSE 26 | - --num=2 27 | - --add=Part of azplugins, released under the BSD 3-Clause License. 28 | - --keep-before=#! 29 | - id: fix-license-header 30 | name: Fix license headers (C) 31 | types_or: [c, c++, cuda, inc] 32 | args: 33 | - --license-file=LICENSE 34 | - --num=2 35 | - --add=Part of azplugins, released under the BSD 3-Clause License. 36 | - --comment-prefix=// 37 | - id: fix-license-header 38 | name: Fix license headers (reStructuredText) 39 | types_or: [rst] 40 | args: 41 | - --license-file=LICENSE 42 | - --num=2 43 | - --add=Part of azplugins, released under the BSD 3-Clause License. 44 | - --keep-after=.. include 45 | - --keep-after=.. automodule 46 | - --comment-prefix=.. 47 | - repo: https://github.com/pre-commit/mirrors-clang-format 48 | rev: v20.1.0 49 | hooks: 50 | - id: clang-format 51 | types_or: [c, c++, cuda, inc] 52 | - repo: https://github.com/astral-sh/ruff-pre-commit 53 | rev: v0.11.4 54 | hooks: 55 | - id: ruff-format 56 | types_or: [python] 57 | - id: ruff 58 | types_or: [python] 59 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | sphinx: 4 | configuration: doc/conf.py 5 | fail_on_warning: true 6 | 7 | build: 8 | os: ubuntu-24.04 9 | tools: 10 | python: "mambaforge-23.11" 11 | jobs: 12 | post_install: 13 | - wget https://github.com/glotzerlab/hoomd-blue/releases/download/v5.0.0/hoomd-5.0.0.tar.gz 14 | - tar -xzvf hoomd-5.0.0.tar.gz 15 | - python doc/mock_install.py hoomd-5.0.0/hoomd src 16 | 17 | conda: 18 | environment: doc/environment.yaml 19 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | CMAKE_MINIMUM_REQUIRED(VERSION 3.9 FATAL_ERROR) 2 | 3 | # Name the plugin project. 4 | # TODO: Set the project title to the name of your Python package. 5 | project(azplugins LANGUAGES C CXX) 6 | 7 | # Find the installed HOOMD. 8 | find_package(HOOMD 5.0.0 REQUIRED) 9 | 10 | message(STATUS "Found HOOMD ${HOOMD_VERSION}: ${HOOMD_INSTALL_PREFIX}/${PYTHON_SITE_INSTALL_DIR}") 11 | 12 | # Force installation to the HOOMD installation location. 13 | set(CMAKE_INSTALL_PREFIX ${HOOMD_INSTALL_PREFIX} CACHE PATH "Installation prefix" FORCE) 14 | 15 | # Enable compiler warnings on gcc and clang. 16 | if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang") 17 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wconversion -Wno-sign-conversion -Wno-unknown-pragmas -Wno-deprecated-declarations -Wno-unused-result") 18 | endif() 19 | 20 | # Add the component's source directory. 21 | add_subdirectory(src) 22 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 2 | # Contributor Covenant Code of Conduct 3 | 4 | ## Our Pledge 5 | 6 | We as members, contributors, and leaders pledge to make participation in our 7 | community a harassment-free experience for everyone, regardless of age, body 8 | size, visible or invisible disability, ethnicity, sex characteristics, gender 9 | identity and expression, level of experience, education, socio-economic status, 10 | nationality, personal appearance, race, caste, color, religion, or sexual 11 | identity and orientation. 12 | 13 | We pledge to act and interact in ways that contribute to an open, welcoming, 14 | diverse, inclusive, and healthy community. 15 | 16 | ## Our Standards 17 | 18 | Examples of behavior that contributes to a positive environment for our 19 | community include: 20 | 21 | * Demonstrating empathy and kindness toward other people 22 | * Being respectful of differing opinions, viewpoints, and experiences 23 | * Giving and gracefully accepting constructive feedback 24 | * Accepting responsibility and apologizing to those affected by our mistakes, 25 | and learning from the experience 26 | * Focusing on what is best not just for us as individuals, but for the overall 27 | community 28 | 29 | Examples of unacceptable behavior include: 30 | 31 | * The use of sexualized language or imagery, and sexual attention or advances of 32 | any kind 33 | * Trolling, insulting or derogatory comments, and personal or political attacks 34 | * Public or private harassment 35 | * Publishing others' private information, such as a physical or email address, 36 | without their explicit permission 37 | * Other conduct which could reasonably be considered inappropriate in a 38 | professional setting 39 | 40 | ## Enforcement Responsibilities 41 | 42 | Community leaders are responsible for clarifying and enforcing our standards of 43 | acceptable behavior and will take appropriate and fair corrective action in 44 | response to any behavior that they deem inappropriate, threatening, offensive, 45 | or harmful. 46 | 47 | Community leaders have the right and responsibility to remove, edit, or reject 48 | comments, commits, code, wiki edits, issues, and other contributions that are 49 | not aligned to this Code of Conduct, and will communicate reasons for moderation 50 | decisions when appropriate. 51 | 52 | ## Scope 53 | 54 | This Code of Conduct applies within all community spaces, and also applies when 55 | an individual is officially representing the community in public spaces. 56 | Examples of representing our community include using an official email address, 57 | posting via an official social media account, or acting as an appointed 58 | representative at an online or offline event. 59 | 60 | ## Enforcement 61 | 62 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 63 | reported to the community leaders responsible for enforcement at 64 | mphoward@auburn.edu. 65 | All complaints will be reviewed and investigated promptly and fairly. 66 | 67 | All community leaders are obligated to respect the privacy and security of the 68 | reporter of any incident. 69 | 70 | ## Enforcement Guidelines 71 | 72 | Community leaders will follow these Community Impact Guidelines in determining 73 | the consequences for any action they deem in violation of this Code of Conduct: 74 | 75 | ### 1. Correction 76 | 77 | **Community Impact**: Use of inappropriate language or other behavior deemed 78 | unprofessional or unwelcome in the community. 79 | 80 | **Consequence**: A private, written warning from community leaders, providing 81 | clarity around the nature of the violation and an explanation of why the 82 | behavior was inappropriate. A public apology may be requested. 83 | 84 | ### 2. Warning 85 | 86 | **Community Impact**: A violation through a single incident or series of 87 | actions. 88 | 89 | **Consequence**: A warning with consequences for continued behavior. No 90 | interaction with the people involved, including unsolicited interaction with 91 | those enforcing the Code of Conduct, for a specified period of time. This 92 | includes avoiding interactions in community spaces as well as external channels 93 | like social media. Violating these terms may lead to a temporary or permanent 94 | ban. 95 | 96 | ### 3. Temporary Ban 97 | 98 | **Community Impact**: A serious violation of community standards, including 99 | sustained inappropriate behavior. 100 | 101 | **Consequence**: A temporary ban from any sort of interaction or public 102 | communication with the community for a specified period of time. No public or 103 | private interaction with the people involved, including unsolicited interaction 104 | with those enforcing the Code of Conduct, is allowed during this period. 105 | Violating these terms may lead to a permanent ban. 106 | 107 | ### 4. Permanent Ban 108 | 109 | **Community Impact**: Demonstrating a pattern of violation of community 110 | standards, including sustained inappropriate behavior, harassment of an 111 | individual, or aggression toward or disparagement of classes of individuals. 112 | 113 | **Consequence**: A permanent ban from any sort of public interaction within the 114 | community. 115 | 116 | ## Attribution 117 | 118 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 119 | version 2.1, available at 120 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 121 | 122 | Community Impact Guidelines were inspired by 123 | [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 124 | 125 | For answers to common questions about this code of conduct, see the FAQ at 126 | [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 127 | [https://www.contributor-covenant.org/translations][translations]. 128 | 129 | [homepage]: https://www.contributor-covenant.org 130 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 131 | [Mozilla CoC]: https://github.com/mozilla/diversity 132 | [FAQ]: https://www.contributor-covenant.org/faq 133 | [translations]: https://www.contributor-covenant.org/translations 134 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018-2020, Michael P. Howard 2 | Copyright (c) 2021-2025, Auburn University 3 | 4 | Redistribution and use in source and binary forms, with or without modification, 5 | are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the copyright holder nor the names of its contributors 15 | may be used to endorse or promote products derived from this software without 16 | specific prior written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # azplugins 2 | 3 | azplugins is a component for [HOOMD-blue][1] which expands its functionality for 4 | tackling a variety of problems in soft matter physics. Currently, azplugins is 5 | tested against v5.0.0 of HOOMD-blue. See [CHANGELOG.rst](CHANGELOG.rst) for a 6 | list of recent development. 7 | 8 | ## Compiling azplugins 9 | 10 | azplugins follows the [standard component template][2]. It has the same 11 | dependencies used to build HOOMD-blue. With HOOMD-blue installed already, adding 12 | azplugins can be as easy as: 13 | 14 | ``` 15 | git clone https://github.com/mphowardlab/azplugins 16 | cmake -B build/azplugins -S azplugins 17 | cmake --build build/azplugins 18 | cmake --install build/azplugins 19 | ``` 20 | 21 | Please refer to the directions in the HOOMD-blue documentation on building an 22 | external component for more information. 23 | 24 | ### Testing 25 | 26 | After building and installing azplugins, you can run our tests with pytest: 27 | 28 | ``` 29 | python -m pytest --pyargs hoomd.azplugins 30 | ``` 31 | 32 | ## Contributing 33 | 34 | Contributions are welcomed and appreciated! Fork and create a pull request on 35 | [GitHub][3]. Be sure to follow the [HOOMD-blue guidelines for developers][4]! We 36 | value the input and experiences all users and contributors bring to `azplugins`. 37 | 38 | ## History 39 | 40 | azplugins began as a collection of code shared between students and postdocs at 41 | Princeton University (2016-2018). It is named for their research advisor, Prof. 42 | Athanassios (Thanos) Z. Panagiotopoulos. 43 | 44 | [1]: http://glotzerlab.engin.umich.edu/hoomd-blue 45 | [2]: https://hoomd-blue.readthedocs.io/en/latest/components.html 46 | [3]: https://github.com/mphowardlab/azplugins 47 | [4]: https://hoomd-blue.readthedocs.io/en/latest/developers.html 48 | -------------------------------------------------------------------------------- /doc/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /doc/_static/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mphowardlab/azplugins/4b30a4bfdab5d7b45e5c6030721f1ff908949bc7/doc/_static/.keep -------------------------------------------------------------------------------- /doc/_templates/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mphowardlab/azplugins/4b30a4bfdab5d7b45e5c6030721f1ff908949bc7/doc/_templates/.keep -------------------------------------------------------------------------------- /doc/conf.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """Sphinx configuration.""" 6 | 7 | # 8 | # For the full list of built-in configuration values, see the documentation: 9 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 10 | 11 | # -- Project information ----------------------------------------------------- 12 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information 13 | 14 | import datetime 15 | import os 16 | 17 | project = "azplugins" 18 | year = datetime.date.today().year 19 | copyright = f"2018-2020, Michael P. Howard. 2021-{year}, Auburn University." 20 | author = "Michael P. Howard" 21 | release = "1.1.0" 22 | 23 | # -- General configuration --------------------------------------------------- 24 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration 25 | 26 | default_role = "any" 27 | 28 | templates_path = ["_templates"] 29 | exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] 30 | 31 | extensions = [ 32 | "sphinx.ext.mathjax", 33 | ] 34 | 35 | extensions += ["sphinx.ext.autodoc", "sphinx.ext.autosummary"] 36 | autodoc_docstring_signature = True 37 | autodoc_typehints_format = "short" 38 | autodoc_mock_imports = ["hoomd.azplugins._azplugins"] 39 | if os.getenv("READTHEDOCS"): 40 | autodoc_mock_imports += [ 41 | "hoomd._hoomd", 42 | "hoomd.version_config", 43 | "hoomd.hpmc._hpmc", 44 | "hoomd.md._md", 45 | "hoomd.mpcd._mpcd", 46 | ] 47 | 48 | extensions += ["sphinx.ext.napoleon"] 49 | napoleon_include_special_with_doc = True 50 | 51 | extensions += ["sphinx.ext.intersphinx"] 52 | intersphinx_mapping = { 53 | "python": ("https://docs.python.org/3", None), 54 | "numpy": ("https://numpy.org/doc/stable", None), 55 | "gsd": ("https://gsd.readthedocs.io/en/stable/", None), 56 | "hoomd": ("https://hoomd-blue.readthedocs.io/en/stable/", None), 57 | } 58 | 59 | extensions += ["sphinx.ext.todo"] 60 | todo_include_todos = False 61 | 62 | extensions += ["sphinx_copybutton"] 63 | copybutton_prompt_text = "$ " 64 | copybutton_remove_prompts = True 65 | copybutton_line_continuation_character = "\\" 66 | 67 | # -- Options for HTML output ------------------------------------------------- 68 | # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output 69 | 70 | html_theme = "furo" 71 | html_static_path = ["_static"] 72 | # html_logo = "hoomdblue-logo-vertical.svg" 73 | html_theme_options = { 74 | # "sidebar_hide_name": True, 75 | "top_of_page_buttons": [], 76 | "navigation_with_keys": True, 77 | "dark_css_variables": { 78 | "color-brand-primary": "#5187b2", 79 | "color-brand-content": "#5187b2", 80 | }, 81 | "light_css_variables": { 82 | "color-brand-primary": "#406a8c", 83 | "color-brand-content": "#406a8c", 84 | }, 85 | } 86 | # html_favicon = "hoomdblue-logo-favicon.svg" 87 | 88 | pygments_style = "friendly" 89 | pygments_dark_style = "native" 90 | -------------------------------------------------------------------------------- /doc/credits.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | Credits 6 | ======= 7 | 8 | Maintainers 9 | ----------- 10 | * Michael P. Howard 11 | * Antonia Statt 12 | 13 | Contributors 14 | ------------ 15 | * Mohammadreza Fakhraei 16 | * Arjun Goswami 17 | * Brandon Jeong 18 | * Sally Jiao 19 | * Ashley Knoerdel 20 | * Kritika 21 | * Mayukh Kundu 22 | * C. Levi Petix 23 | * Wes Reinhart 24 | * Jude Ann Vishnu 25 | 26 | Source code 27 | ----------- 28 | This is a continuation of the ``azplugins`` project begun by members of the 29 | Panagiotopoulos Group at Princeton University. Code from that project is 30 | used under a Modified BSD license: 31 | 32 | .. code-block:: none 33 | 34 | Copyright (c) 2016-2018, Panagiotopoulos Group, Princeton University 35 | 36 | All rights reserved. 37 | 38 | Redistribution and use in source and binary forms, with or without 39 | modification, are permitted provided that the following conditions are met: 40 | 41 | * Redistributions of source code must retain the above copyright notice, 42 | this list of conditions and the following disclaimer. 43 | * Redistributions in binary form must reproduce the above copyright notice, 44 | this list of conditions and the following disclaimer in the documentation 45 | and/or other materials provided with the distribution. 46 | * Neither the name of the copyright holder nor the names of its contributors 47 | may be used to endorse or promote products derived from this software 48 | without specific prior written permission. 49 | 50 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 51 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 52 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 53 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY 54 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 55 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 56 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 57 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 58 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 59 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 60 | 61 | This code is a plugin component for HOOMD-blue. Portions of the code are adapted 62 | under a BSD 3-Clause license: 63 | 64 | .. code-block:: none 65 | 66 | Copyright (c) 2009-2024 The Regents of the University of Michigan. All 67 | rights reserved. 68 | 69 | Redistribution and use in source and binary forms, with or without 70 | modification, are permitted provided that the following conditions are met: 71 | 72 | 1. Redistributions of source code must retain the above copyright notice, 73 | this list of conditions and the following disclaimer. 74 | 75 | 2. Redistributions in binary form must reproduce the above copyright notice, 76 | this list of conditions and the following disclaimer in the documentation 77 | and/or other materials provided with the distribution. 78 | 79 | 3. Neither the name of the copyright holder nor the names of its 80 | contributors 81 | may be used to endorse or promote products derived from this software 82 | without specific prior written permission. 83 | 84 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 85 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 86 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 87 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 88 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 89 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 90 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 91 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 92 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 93 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 94 | POSSIBILITY OF SUCH DAMAGE. 95 | -------------------------------------------------------------------------------- /doc/environment.yaml: -------------------------------------------------------------------------------- 1 | name: rtd 2 | channels: 3 | - conda-forge 4 | - defaults 5 | dependencies: 6 | - python=3.12 7 | - numpy=2.1.3 8 | - sphinx=8.1.3 9 | - furo=2024.8.6 10 | - tornado=6.4.2 11 | - sphinx-copybutton=0.5.2 12 | -------------------------------------------------------------------------------- /doc/index.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | ========= 6 | azplugins 7 | ========= 8 | 9 | azplugins is a component for `HOOMD-blue`_ which expands its functionality for 10 | tackling a variety of problems in soft matter physics. Currently, azplugins is 11 | tested against v5.0.0 of HOOMD-blue. 12 | 13 | Compiling 14 | ========= 15 | 16 | azplugins follows the `component template`_. It has the same dependencies used 17 | to build HOOMD-blue. With HOOMD-blue installed already, adding azplugins can be 18 | as easy as: 19 | 20 | 1. Grab a copy of the code: 21 | 22 | .. code-block:: bash 23 | 24 | git clone https://github.com/mphowardlab/azplugins 25 | 26 | 2. Configure azplugins with CMake: 27 | 28 | .. code-block:: bash 29 | 30 | cmake -B build/azplugins -S azplugins 31 | 32 | 3. Build azplugins: 33 | 34 | .. code-block:: bash 35 | 36 | cmake --build build/azplugins 37 | 38 | 4. Install azplugins alongside HOOMD-blue: 39 | 40 | .. code-block:: bash 41 | 42 | cmake --install build/azplugins 43 | 44 | Please refer to the directions in the HOOMD-blue documentation on building an 45 | external component for more information. 46 | 47 | Contents 48 | ======== 49 | 50 | .. toctree:: 51 | :maxdepth: 1 52 | :caption: API 53 | 54 | module-azplugins-bond 55 | module-azplugins-compute 56 | module-azplugins-external 57 | module-azplugins-flow 58 | module-azplugins-pair 59 | 60 | .. toctree:: 61 | :maxdepth: 1 62 | :caption: Reference 63 | 64 | credits 65 | license 66 | release 67 | 68 | Index 69 | ===== 70 | 71 | * :ref:`genindex` 72 | * :ref:`modindex` 73 | * :ref:`search` 74 | 75 | .. _HOOMD-blue: http://glotzerlab.engin.umich.edu/hoomd-blue 76 | .. _component template: https://hoomd-blue.readthedocs.io/en/latest/components.html 77 | -------------------------------------------------------------------------------- /doc/license.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | License 6 | ======= 7 | 8 | .. literalinclude:: ../LICENSE 9 | :language: none 10 | -------------------------------------------------------------------------------- /doc/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | 13 | %SPHINXBUILD% >NUL 2>NUL 14 | if errorlevel 9009 ( 15 | echo. 16 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 17 | echo.installed, then set the SPHINXBUILD environment variable to point 18 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 19 | echo.may add the Sphinx directory to PATH. 20 | echo. 21 | echo.If you don't have Sphinx installed, grab it from 22 | echo.https://www.sphinx-doc.org/ 23 | exit /b 1 24 | ) 25 | 26 | if "%1" == "" goto help 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /doc/mock_install.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """Mock installation of azplugins into a real hoomd installation.""" 6 | 7 | import os 8 | import shutil 9 | import site 10 | import sys 11 | from pathlib import Path 12 | 13 | install_dir = Path(site.getsitepackages()[0]) 14 | 15 | hoomd_dir = Path(sys.argv[1]) 16 | for file in hoomd_dir.rglob("*.py"): 17 | relative_file = file.relative_to(hoomd_dir.parent) 18 | os.makedirs(install_dir / relative_file.parent, exist_ok=True) 19 | shutil.copy(file, install_dir / relative_file.parent) 20 | 21 | azplugins_dir = Path(sys.argv[2]) 22 | for file in azplugins_dir.rglob("*.py"): 23 | relative_file = Path("hoomd") / "azplugins" / file.relative_to(azplugins_dir) 24 | os.makedirs(install_dir / relative_file.parent, exist_ok=True) 25 | shutil.copy(file, install_dir / relative_file.parent) 26 | -------------------------------------------------------------------------------- /doc/module-azplugins-bond.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | azplugins.bond 6 | -------------- 7 | 8 | .. rubric:: Overview 9 | 10 | .. py:currentmodule:: hoomd.azplugins.bond 11 | 12 | .. autosummary:: 13 | :nosignatures: 14 | 15 | DoubleWell 16 | Quartic 17 | 18 | .. rubric:: Details 19 | 20 | .. automodule:: hoomd.azplugins.bond 21 | :synopsis: Bond potentials. 22 | :members: DoubleWell, 23 | Quartic 24 | :no-inherited-members: 25 | :show-inheritance: 26 | -------------------------------------------------------------------------------- /doc/module-azplugins-compute.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | azplugins.compute 6 | ----------------- 7 | 8 | .. rubric:: Overview 9 | 10 | .. py:currentmodule:: hoomd.azplugins.compute 11 | 12 | .. autosummary:: 13 | :nosignatures: 14 | 15 | CartesianVelocityFieldCompute 16 | CylindricalVelocityFieldCompute 17 | VelocityCompute 18 | VelocityFieldCompute 19 | 20 | .. rubric:: Details 21 | 22 | .. automodule:: hoomd.azplugins.compute 23 | :synopsis: Computes. 24 | :members: CartesianVelocityFieldCompute, 25 | CylindricalVelocityFieldCompute, 26 | VelocityCompute, 27 | VelocityFieldCompute 28 | :no-inherited-members: 29 | :show-inheritance: 30 | -------------------------------------------------------------------------------- /doc/module-azplugins-external.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | azplugins.external 6 | ------------------ 7 | 8 | .. rubric:: Overview 9 | 10 | .. py:currentmodule:: hoomd.azplugins.external 11 | 12 | .. autosummary:: 13 | :nosignatures: 14 | 15 | HarmonicBarrier 16 | PlanarHarmonicBarrier 17 | SphericalHarmonicBarrier 18 | 19 | .. rubric:: Details 20 | 21 | .. automodule:: hoomd.azplugins.external 22 | :synopsis: External potentials. 23 | :members: HarmonicBarrier, 24 | PlanarHarmonicBarrier, 25 | SphericalHarmonicBarrier 26 | :no-inherited-members: 27 | :show-inheritance: 28 | -------------------------------------------------------------------------------- /doc/module-azplugins-flow.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | azplugins.flow 6 | -------------- 7 | 8 | .. rubric:: Overview 9 | 10 | .. py:currentmodule:: hoomd.azplugins.flow 11 | 12 | .. autosummary:: 13 | :nosignatures: 14 | 15 | FlowField 16 | ConstantFlow 17 | ParabolicFlow 18 | 19 | .. rubric:: Details 20 | 21 | .. automodule:: hoomd.azplugins.flow 22 | :synopsis: Flow fields and integrators. 23 | :members: FlowField, 24 | ConstantFlow, 25 | ParabolicFlow 26 | :no-inherited-members: 27 | :show-inheritance: 28 | -------------------------------------------------------------------------------- /doc/module-azplugins-pair.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | azplugins.pair 6 | -------------- 7 | 8 | .. rubric:: Overview 9 | 10 | .. py:currentmodule:: hoomd.azplugins.pair 11 | 12 | .. autosummary:: 13 | :nosignatures: 14 | 15 | Colloid 16 | DPDGeneralWeight 17 | ExpandedYukawa 18 | Hertz 19 | PerturbedLennardJones 20 | TwoPatchMorse 21 | 22 | .. rubric:: Details 23 | 24 | .. automodule:: hoomd.azplugins.pair 25 | :synopsis: Pair potentials. 26 | :members: Colloid, 27 | DPDGeneralWeight, 28 | ExpandedYukawa, 29 | Hertz, 30 | PerturbedLennardJones, 31 | TwoPatchMorse 32 | :no-inherited-members: 33 | :show-inheritance: 34 | -------------------------------------------------------------------------------- /doc/release.rst: -------------------------------------------------------------------------------- 1 | .. Copyright (c) 2018-2020, Michael P. Howard 2 | .. Copyright (c) 2021-2025, Auburn University 3 | .. Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | .. include:: ../CHANGELOG.rst 6 | -------------------------------------------------------------------------------- /ruff.toml: -------------------------------------------------------------------------------- 1 | include = ["*.py"] 2 | extend-exclude = [".git", 3 | "__pycache__", 4 | "build", 5 | ] 6 | line-length = 88 7 | indent-width = 4 8 | 9 | [lint] 10 | select = [ 11 | "E", 12 | "F", 13 | "N", 14 | "W", 15 | "D", 16 | "NPY", 17 | "RUF", 18 | ] 19 | ignore = [ 20 | "D105", # Magic methods don't require documentation 21 | "D107", # do not document __init__ separately from the class 22 | "D301", # Allow backslashes in docstrings 23 | "D205", "D415", # Allow no summary line. The rendered Sphinx documentation is cleaner without them. 24 | "N816", "N806","N803", # allow occasional use of uppercase variable and argument names 25 | "D214", # ignore overindented sections in Trigger - this is Google napoleon formatting 26 | "RUF012", # hoomd does not use typing annotations 27 | "NPY002", # TODO: refactor tests to use modern numpy Generator API. 28 | ] 29 | 30 | [lint.pydocstyle] 31 | convention = "google" 32 | 33 | [lint.per-file-ignores] 34 | # allow unused imports in init files 35 | "__init__.py" = ["F401"] 36 | # do not require docstrings in unit test or documentation example files 37 | "**/pytest/*" = ["D", "F811", "N999"] 38 | 39 | [format] 40 | indent-style = "space" 41 | line-ending = "auto" 42 | docstring-code-line-length = 72 43 | docstring-code-format = true 44 | -------------------------------------------------------------------------------- /src/AnisoPotentialPairGPUKernel.cu.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "hoomd/md/AnisoPotentialPairGPU.cuh" 10 | #include "AnisoPairEvaluator@_evaluator@.h" 11 | 12 | #define EVALUATOR_CLASS AnisoPairEvaluator@_evaluator@ 13 | // clang-format on 14 | 15 | namespace hoomd 16 | { 17 | namespace md 18 | { 19 | namespace kernel 20 | { 21 | template __attribute__((visibility("default"))) hipError_t 22 | gpu_compute_pair_aniso_forces( 23 | const a_pair_args_t& pair_args, 24 | const hoomd::azplugins::detail::EVALUATOR_CLASS::param_type* d_params, 25 | const hoomd::azplugins::detail::EVALUATOR_CLASS::shape_type* d_shape_param); 26 | } // end namespace kernel 27 | } // end namespace md 28 | } // end namespace hoomd 29 | -------------------------------------------------------------------------------- /src/BinningOperation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_BINNING_OPERATION_H_ 6 | #define AZPLUGINS_BINNING_OPERATION_H_ 7 | 8 | #include "hoomd/HOOMDMath.h" 9 | 10 | #ifdef __HIPCC__ 11 | #define HOSTDEVICE __host__ __device__ 12 | #else 13 | #define HOSTDEVICE 14 | #endif // __HIPCC__ 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | 21 | //! Interface for binning operations in different 3D coordinate systems. 22 | class BinningOperation 23 | { 24 | public: 25 | HOSTDEVICE BinningOperation(const uint3& num_bins, 26 | const Scalar3& lower_bounds, 27 | const Scalar3& upper_bounds) 28 | : m_lower_bounds {lower_bounds.x, lower_bounds.y, lower_bounds.z}, 29 | m_upper_bounds {upper_bounds.x, upper_bounds.y, upper_bounds.z}, m_num_bins {1, 1, 1}, 30 | m_should_bin {false, false, false} 31 | { 32 | if (num_bins.x > 0) 33 | { 34 | m_num_bins[0] = num_bins.x; 35 | m_should_bin[0] = true; 36 | } 37 | if (num_bins.y > 0) 38 | { 39 | m_num_bins[1] = num_bins.y; 40 | m_should_bin[1] = true; 41 | } 42 | if (num_bins.z > 0) 43 | { 44 | m_num_bins[2] = num_bins.z; 45 | m_should_bin[2] = true; 46 | } 47 | } 48 | 49 | HOSTDEVICE bool bin(uint3& bin, 50 | Scalar3& transformed_vector, 51 | const Scalar3& coordinates, 52 | const Scalar3& vector) const 53 | { 54 | return false; 55 | } 56 | 57 | HOSTDEVICE size_t getTotalNumBins() const 58 | { 59 | return static_cast(m_num_bins[0]) * m_num_bins[1] * m_num_bins[2]; 60 | } 61 | 62 | HOSTDEVICE size_t ravelBin(const uint3& bin) const 63 | { 64 | return static_cast(bin.z) + m_num_bins[2] * (bin.y + m_num_bins[1] * bin.x); 65 | } 66 | 67 | protected: 68 | Scalar m_lower_bounds[3]; 69 | Scalar m_upper_bounds[3]; 70 | unsigned int m_num_bins[3]; 71 | bool m_should_bin[3]; 72 | 73 | HOSTDEVICE bool bin1D(unsigned int& bin_1d, const Scalar x, unsigned int dim) const 74 | { 75 | int bin_ = static_cast( 76 | slow::floor(((x - m_lower_bounds[dim]) / (m_upper_bounds[dim] - m_lower_bounds[dim])) 77 | * m_num_bins[dim])); 78 | if (bin_ >= 0 && bin_ < static_cast(m_num_bins[dim])) 79 | { 80 | bin_1d = bin_; 81 | return true; 82 | } 83 | else 84 | { 85 | return false; 86 | } 87 | } 88 | }; 89 | 90 | } // end namespace azplugins 91 | } // end namespace hoomd 92 | 93 | #undef HOSTDEVICE 94 | 95 | #endif // AZPLUGINS_BINNING_OPERATION_H_ 96 | -------------------------------------------------------------------------------- /src/BondEvaluator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_BOND_EVALUATOR_H_ 6 | #define AZPLUGINS_BOND_EVALUATOR_H_ 7 | 8 | #ifndef __HIPCC__ 9 | #include 10 | #include 11 | #endif // __HIPCC__ 12 | 13 | #include "hoomd/HOOMDMath.h" 14 | 15 | #ifdef __HIPCC__ 16 | #define DEVICE __device__ 17 | #else 18 | #define DEVICE 19 | #endif // __HIPCC__ 20 | 21 | namespace hoomd 22 | { 23 | namespace azplugins 24 | { 25 | namespace detail 26 | { 27 | 28 | //! Base class for isotropic pair potential parameters 29 | /*! 30 | * This class covers the default case of a simple potential that doesn't do 31 | * anything special loading its parameters. This class can then be used as 32 | * a \a param_type for the evaluator. 33 | * 34 | * Deriving classes \b must implement the constructors below. They should also 35 | * set the aligned attribute based on the size of the object. 36 | */ 37 | struct BondParameters 38 | { 39 | #ifndef __HIPCC__ 40 | BondParameters() { } 41 | 42 | BondParameters(pybind11::dict v) { } 43 | 44 | pybind11::dict asDict() 45 | { 46 | return pybind11::dict(); 47 | } 48 | #endif //__HIPCC__ 49 | }; 50 | 51 | //! Base class for bond potential evaluator 52 | /*! 53 | * This class covers the default case of a simple potential that doesn't require 54 | * additional data. Deriving classes \b must define a \a param_type . They must 55 | * also give the potential a name and implement the evalForceAndEnergy() method. 56 | */ 57 | class BondEvaluator 58 | { 59 | public: 60 | typedef BondParameters param_type; 61 | 62 | DEVICE BondEvaluator(const Scalar _rsq) : rsq(_rsq) { } 63 | 64 | //! Base potential does not need charge 65 | DEVICE static bool needsCharge() 66 | { 67 | return false; 68 | } 69 | 70 | //! Accept the optional charge values 71 | /*! 72 | * \param qi Charge of particle i 73 | * \param qj Charge of particle j 74 | */ 75 | DEVICE void setCharge(Scalar qi, Scalar qj) { } 76 | 77 | //! Evaluate the force and energy 78 | /*! 79 | * \param force_divr Computed force divided by r 80 | * \param bond_eng Computed bond energy 81 | * 82 | * \returns True if the energy calculation occurs 83 | */ 84 | DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& bond_eng) 85 | { 86 | return false; 87 | } 88 | 89 | #ifndef __HIPCC__ 90 | //! Get the name of this potential 91 | /*! 92 | * This method must be overridden by deriving classes. 93 | */ 94 | static std::string getName() 95 | { 96 | throw std::runtime_error("Name not defined for this pair potential."); 97 | } 98 | #endif // __HIPCC__ 99 | 100 | protected: 101 | Scalar rsq; //!< Squared distance between particles 102 | }; 103 | 104 | } // end namespace detail 105 | } // end namespace azplugins 106 | } // end namespace hoomd 107 | 108 | #undef DEVICE 109 | 110 | #endif // AZPLUGINS_BOND_EVALUATOR_H_ 111 | -------------------------------------------------------------------------------- /src/BondEvaluatorDoubleWell.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_BOND_EVALUATOR_DOUBLE_WELL_H_ 6 | #define AZPLUGINS_BOND_EVALUATOR_DOUBLE_WELL_H_ 7 | 8 | #ifndef __HIPCC__ 9 | #include 10 | #endif 11 | 12 | #include "BondEvaluator.h" 13 | 14 | #ifdef __HIPCC__ 15 | #define DEVICE __device__ 16 | #else 17 | #define DEVICE 18 | #endif 19 | 20 | namespace hoomd 21 | { 22 | namespace azplugins 23 | { 24 | namespace detail 25 | { 26 | 27 | //! Parameters of double well bond potential 28 | struct BondParametersDoubleWell : public BondParameters 29 | { 30 | #ifndef __HIPCC__ 31 | BondParametersDoubleWell() : r_1(0), r_diff(1.0), U_1(0), U_tilt(0) { } 32 | 33 | BondParametersDoubleWell(pybind11::dict v) 34 | { 35 | r_1 = v["r_1"].cast(); 36 | r_diff = r_1 - v["r_0"].cast(); 37 | U_1 = v["U_1"].cast(); 38 | U_tilt = v["U_tilt"].cast(); 39 | } 40 | 41 | pybind11::dict asDict() 42 | { 43 | pybind11::dict v; 44 | v["r_0"] = r_1 - r_diff; 45 | v["r_1"] = r_1; 46 | v["U_1"] = U_1; 47 | v["U_tilt"] = U_tilt; 48 | return v; 49 | } 50 | #endif 51 | 52 | Scalar r_1; //!< location of the potential local maximum 53 | Scalar r_diff; //!< difference between r_1 and r_0 (location of first minimum) 54 | Scalar U_1; //!< Potential Potential maximum energy barrier between minima 55 | Scalar U_tilt; //!< tunes the energy offset (tilt) between minima 56 | } 57 | #if HOOMD_LONGREAL_SIZE == 32 58 | __attribute__((aligned(16))); 59 | #else 60 | __attribute__((aligned(32))); 61 | #endif 62 | 63 | //! Class for evaluating the double well bond potential 64 | /*! 65 | * This bond potential follows the functional form 66 | * \f{eqnarray*} 67 | * 68 | * U(r) = U_1\left[\frac{\left((r-r_1)^2-(r_1-r_0)^2\right)^2}{\left(r_1-r_0\right)^4}\right] 69 | * + 70 | * U_{\rm{tilt}}\left[1+\frac{r-r_1}{r_1-r_0}-\frac{\left((r-r_1)^2-(r_1-r_0)^2\right)^2}{\left(r_1-r_0\right)^4}\right] 71 | * 72 | * \f} 73 | * which has two minima at r = r_0 and r = 2 * r_1 - r_0, seperated by a maximum 74 | * at r_1 of height U_1 when U_tilt is set to zero. 75 | * 76 | * The parameter r_1 tunes the location of the maximal value and the parameter r_0 tunes the 77 | * distance of the two minima from each other. This potential is useful to model bonds which can be 78 | * either mechanically or thermally "activated" into a effectively longer state. The value of U_1 79 | * can be used to tune the height of the energy barrier in between the two states. 80 | * 81 | * If U_tilt is non zero, the relative energy of the minima can be tuned, where 2 * U_tilt 82 | * is the energy of the second minima, the first minima value is at zero. This causes a 83 | * small shift in the location of the minima and the maxima, because of the added linear term. 84 | */ 85 | class BondEvaluatorDoubleWell : public BondEvaluator 86 | { 87 | public: 88 | typedef BondParametersDoubleWell param_type; 89 | 90 | DEVICE BondEvaluatorDoubleWell(Scalar _rsq, const param_type& _params) 91 | : BondEvaluator(_rsq), r_1(_params.r_1), r_diff(_params.r_diff), U_1(_params.U_1), 92 | U_tilt(_params.U_tilt) 93 | { 94 | } 95 | 96 | DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& bond_eng) 97 | { 98 | bond_eng = 0; 99 | force_divr = 0; 100 | // check for invalid parameters r0 = r1 101 | if (r_diff == Scalar(0.0)) 102 | return false; 103 | 104 | const Scalar r = fast::sqrt(rsq); 105 | const Scalar x = (r_1 - r) / r_diff; 106 | const Scalar x2 = x * x; 107 | const Scalar y = Scalar(1.0) - x2; 108 | const Scalar y2 = y * y; 109 | 110 | bond_eng = U_1 * y2 + U_tilt * (Scalar(1.0) - x - y2); 111 | force_divr = (Scalar(4.0) * x * y * (U_tilt - U_1) - U_tilt) / (r_diff * r); 112 | return true; 113 | } 114 | 115 | #ifndef __HIPCC__ 116 | static std::string getName() 117 | { 118 | return std::string("DoubleWell"); 119 | } 120 | #endif 121 | 122 | private: 123 | Scalar r_1; //!< r_1 parameter 124 | Scalar r_diff; //!< r_diff parameter 125 | Scalar U_1; //!< U_1 parameter 126 | Scalar U_tilt; //!< U_tilt parameter 127 | }; 128 | 129 | } // end namespace detail 130 | } // end namespace azplugins 131 | } // end namespace hoomd 132 | 133 | #undef DEVICE 134 | 135 | #endif // AZPLUGINS_BOND_EVALUATOR_DOUBLE_WELL_H_ 136 | -------------------------------------------------------------------------------- /src/CartesianBinningOperation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_CARTESIAN_BINNING_OPERATION_H_ 6 | #define AZPLUGINS_CARTESIAN_BINNING_OPERATION_H_ 7 | 8 | #include "BinningOperation.h" 9 | 10 | #ifdef __HIPCC__ 11 | #define HOSTDEVICE __host__ __device__ 12 | #else 13 | #define HOSTDEVICE 14 | #endif // __HIPCC__ 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | 21 | //! Binning operation in Cartesian coordinates 22 | class CartesianBinningOperation : public BinningOperation 23 | { 24 | public: 25 | using BinningOperation::BinningOperation; 26 | 27 | HOSTDEVICE bool bin(uint3& bin, 28 | Scalar3& transformed_vector, 29 | const Scalar3& coordinates, 30 | const Scalar3& vector) const 31 | { 32 | uint3 bin_ = make_uint3(0, 0, 0); 33 | 34 | if (m_should_bin[0] && !bin1D(bin_.x, coordinates.x, 0)) 35 | { 36 | return false; 37 | } 38 | 39 | if (m_should_bin[1] && !bin1D(bin_.y, coordinates.y, 1)) 40 | { 41 | return false; 42 | } 43 | 44 | if (m_should_bin[2] && !bin1D(bin_.z, coordinates.z, 2)) 45 | { 46 | return false; 47 | } 48 | 49 | bin = bin_; 50 | transformed_vector = vector; 51 | 52 | return true; 53 | } 54 | }; 55 | 56 | } // end namespace azplugins 57 | } // end namespace hoomd 58 | 59 | #undef HOSTDEVICE 60 | 61 | #endif // AZPLUGINS_CARTESIAN_BINNING_OPERATION_H_ 62 | -------------------------------------------------------------------------------- /src/ConstantFlow.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #include "ConstantFlow.h" 6 | 7 | namespace hoomd 8 | { 9 | namespace azplugins 10 | { 11 | namespace detail 12 | { 13 | void export_ConstantFlow(pybind11::module& m) 14 | { 15 | namespace py = pybind11; 16 | py::class_>(m, "ConstantFlow") 17 | .def(py::init()) 18 | .def_property( 19 | "velocity", 20 | [](const ConstantFlow& U) 21 | { 22 | const auto field = U.getVelocity(); 23 | return pybind11::make_tuple(field.x, field.y, field.z); 24 | }, 25 | [](ConstantFlow& U, const pybind11::tuple& field) 26 | { 27 | U.setVelocity(make_scalar3(pybind11::cast(field[0]), 28 | pybind11::cast(field[1]), 29 | pybind11::cast(field[2]))); 30 | }); 31 | } 32 | } // end namespace detail 33 | } // end namespace azplugins 34 | } // end namespace hoomd 35 | -------------------------------------------------------------------------------- /src/ConstantFlow.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_CONSTANT_FLOW_H_ 6 | #define AZPLUGINS_CONSTANT_FLOW_H_ 7 | 8 | #ifndef __HIPCC__ 9 | #include 10 | #endif 11 | 12 | #include "hoomd/HOOMDMath.h" 13 | 14 | #ifndef __HIPCC__ 15 | #define HOSTDEVICE __host__ __device__ 16 | #else 17 | #define HOSTDEVICE 18 | #endif // __HIPCC__ 19 | 20 | #ifndef PYBIND11_EXPORT 21 | #define PYBIND11_EXPORT __attribute__((visibility("default"))) 22 | #endif 23 | 24 | namespace hoomd 25 | { 26 | namespace azplugins 27 | { 28 | 29 | //! Position-independent flow along a vector 30 | class PYBIND11_EXPORT ConstantFlow 31 | { 32 | public: 33 | //! Constructor 34 | /*! 35 | *\param U_ Flow field 36 | */ 37 | ConstantFlow(Scalar3 velocity) 38 | { 39 | setVelocity(velocity); 40 | } 41 | 42 | //! Evaluate the flow field 43 | /*! 44 | * \param r position to evaluate flow 45 | * 46 | * This is just a constant, independent of \a r. 47 | */ 48 | HOSTDEVICE Scalar3 operator()(const Scalar3& r) const 49 | { 50 | return U; 51 | } 52 | 53 | HOSTDEVICE Scalar3 getVelocity() const 54 | { 55 | return U; 56 | } 57 | 58 | HOSTDEVICE void setVelocity(const Scalar3& U_) 59 | { 60 | U = U_; 61 | } 62 | 63 | private: 64 | Scalar3 U; //!< Flow field 65 | }; 66 | 67 | } // namespace azplugins 68 | } // namespace hoomd 69 | 70 | #undef HOSTDEVICE 71 | #undef PYBIND11_EXPORT 72 | 73 | #endif // AZPLUGINS_CONSTANT_FLOW_H_ 74 | -------------------------------------------------------------------------------- /src/CylindricalBinningOperation.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_CYLINDRICAL_BINNING_OPERATION_H_ 6 | #define AZPLUGINS_CYLINDRICAL_BINNING_OPERATION_H_ 7 | 8 | #include "BinningOperation.h" 9 | 10 | #ifdef __HIPCC__ 11 | #define HOSTDEVICE __host__ __device__ 12 | #else 13 | #define HOSTDEVICE 14 | #endif // __HIPCC__ 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | 21 | //! Binning operation in cylindrical coordinates 22 | class CylindricalBinningOperation : public BinningOperation 23 | { 24 | public: 25 | using BinningOperation::BinningOperation; 26 | 27 | HOSTDEVICE bool bin(uint3& bin, 28 | Scalar3& transformed_vector, 29 | const Scalar3& coordinates, 30 | const Scalar3& vector) const 31 | { 32 | uint3 bin_ = make_uint3(0, 0, 0); 33 | 34 | // bin with respect to z first because it is cheapest in case of early exit 35 | if (m_should_bin[2] && !bin1D(bin_.z, coordinates.z, 2)) 36 | { 37 | return false; 38 | } 39 | 40 | // bin with respect to theta second because its internals aren't needed later 41 | if (m_should_bin[1]) 42 | { 43 | #if HOOMD_LONGREAL_SIZE == 32 44 | Scalar theta = ::atan2f(coordinates.y, coordinates.x); 45 | #else 46 | Scalar theta = ::atan2(coordinates.y, coordinates.x); 47 | #endif 48 | if (theta < Scalar(0)) 49 | { 50 | theta += Scalar(2) * M_PI; 51 | } 52 | if (!bin1D(bin_.y, theta, 1)) 53 | { 54 | return false; 55 | } 56 | } 57 | 58 | // bin with respect to r last, r will be used for vector transform so always do it 59 | const Scalar r = fast::sqrt(coordinates.x * coordinates.x + coordinates.y * coordinates.y); 60 | if (m_should_bin[0] && !bin1D(bin_.x, r, 0)) 61 | { 62 | return false; 63 | } 64 | 65 | // transform Cartesian vector to cylindrical coordinates, 66 | // defaulting angle to 0 if r == 0 (point is exactly at center) 67 | Scalar cos_theta(1), sin_theta(0); 68 | if (r > Scalar(0)) 69 | { 70 | cos_theta = coordinates.x / r; 71 | sin_theta = coordinates.y / r; 72 | } 73 | transformed_vector = make_scalar3(cos_theta * vector.x + sin_theta * vector.y, 74 | -sin_theta * vector.x + cos_theta * vector.y, 75 | vector.z); 76 | 77 | bin = bin_; 78 | return true; 79 | } 80 | }; 81 | 82 | } // end namespace azplugins 83 | } // end namespace hoomd 84 | 85 | #undef HOSTDEVICE 86 | 87 | #endif // AZPLUGINS_CYLINDRICAL_BINNING_OPERATION_H_ 88 | -------------------------------------------------------------------------------- /src/HarmonicBarrierGPU.cuh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_HARMONIC_BARRIER_GPU_CUH_ 6 | #define AZPLUGINS_HARMONIC_BARRIER_GPU_CUH_ 7 | 8 | #include "hoomd/BoxDim.h" 9 | #include "hoomd/HOOMDMath.h" 10 | #include 11 | 12 | namespace hoomd 13 | { 14 | namespace azplugins 15 | { 16 | namespace gpu 17 | { 18 | 19 | //! Kernel driver to evaluate HarmonicBarrierGPU force 20 | template 21 | cudaError_t compute_harmonic_barrier(Scalar4* d_force, 22 | Scalar* d_virial, 23 | const Scalar4* d_pos, 24 | const Scalar2* d_params, 25 | const BoxDim& global_box, 26 | const BarrierEvaluatorT& evaluator, 27 | const unsigned int N, 28 | const unsigned int ntypes, 29 | const unsigned int block_size); 30 | 31 | #ifdef __HIPCC__ 32 | namespace kernel 33 | { 34 | 35 | /*! 36 | * \param d_force Particle forces 37 | * \param d_pos Particle positions 38 | * \param d_params Per-type parameters 39 | * \param global_box Global simulation box 40 | * \param evaluator Barrier evaluator 41 | * \param N Number of particles 42 | * \param ntypes Number of types 43 | * 44 | * Using one thread per particle, the force of the harmonic potential is computed 45 | * per-particle. The per-particle-type parameters are cached into shared memory. 46 | * This method does not compute the virial. 47 | * 48 | */ 49 | template 50 | __global__ void compute_harmonic_barrier(Scalar4* d_force, 51 | const Scalar4* d_pos, 52 | const Scalar2* d_params, 53 | const BoxDim global_box, 54 | const BarrierEvaluatorT evaluator, 55 | const unsigned int N, 56 | const unsigned int ntypes) 57 | { 58 | // load per-type parameters into shared memory 59 | extern __shared__ Scalar2 s_params[]; 60 | for (unsigned int cur_offset = 0; cur_offset < ntypes; cur_offset += blockDim.x) 61 | { 62 | if (cur_offset + threadIdx.x < ntypes) 63 | { 64 | s_params[cur_offset + threadIdx.x] = d_params[cur_offset + threadIdx.x]; 65 | } 66 | } 67 | __syncthreads(); 68 | 69 | // one thread per particle 70 | unsigned int idx = blockIdx.x * blockDim.x + threadIdx.x; 71 | if (idx >= N) 72 | return; 73 | 74 | const Scalar4 postype = d_pos[idx]; 75 | Scalar3 pos = make_scalar3(postype.x, postype.y, postype.z); 76 | const unsigned int type = __scalar_as_int(postype.w); 77 | const Scalar2 params = s_params[type]; 78 | 79 | // wrap position back into box in case particles have drifted outside 80 | int3 img = make_int3(0, 0, 0); 81 | global_box.wrap(pos, img); 82 | 83 | d_force[idx] = evaluator(pos, params.x, params.y); 84 | } 85 | } // end namespace kernel 86 | 87 | /*! 88 | * \param d_force Particle forces 89 | * \param d_virial Particle virial 90 | * \param d_pos Particle positions 91 | * \param d_params Per-type parameters 92 | * \param global_box Global simulation box 93 | * \param evaluator Barrier evaluator 94 | * \param N Number of particles 95 | * \param ntypes Number of types 96 | * \param block_size Number of threads per block 97 | * 98 | * The virial contribution is set to zero. 99 | */ 100 | template 101 | cudaError_t compute_harmonic_barrier(Scalar4* d_force, 102 | Scalar* d_virial, 103 | const Scalar4* d_pos, 104 | const Scalar2* d_params, 105 | const BoxDim& global_box, 106 | const BarrierEvaluatorT& evaluator, 107 | const unsigned int N, 108 | const unsigned int ntypes, 109 | const unsigned int block_size) 110 | { 111 | unsigned int max_block_size; 112 | cudaFuncAttributes attr; 113 | cudaFuncGetAttributes(&attr, (const void*)kernel::compute_harmonic_barrier); 114 | max_block_size = attr.maxThreadsPerBlock; 115 | 116 | unsigned int run_block_size = min(block_size, max_block_size); 117 | unsigned int shared_size = sizeof(Scalar2) * ntypes; 118 | 119 | dim3 grid(N / run_block_size + 1); 120 | kernel::compute_harmonic_barrier<<>>(d_force, 121 | d_pos, 122 | d_params, 123 | global_box, 124 | evaluator, 125 | N, 126 | ntypes); 127 | 128 | // zero the virial 129 | cudaMemset(d_virial, 0, 6 * sizeof(Scalar) * N); 130 | 131 | return cudaSuccess; 132 | } 133 | 134 | #endif // __HIPCC__ 135 | 136 | } // end namespace gpu 137 | } // end namespace azplugins 138 | } // end namespace hoomd 139 | 140 | #endif // AZPLUGINS_HARMONIC_BARRIER_GPU_CUH_ 141 | -------------------------------------------------------------------------------- /src/HarmonicBarrierGPU.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_HARMONIC_BARRIER_GPU_H_ 6 | #define AZPLUGINS_HARMONIC_BARRIER_GPU_H_ 7 | 8 | #ifdef __HIPCC__ 9 | #error This header cannot be compiled by nvcc 10 | #endif 11 | 12 | #include "HarmonicBarrier.h" 13 | #include "HarmonicBarrierGPU.cuh" 14 | 15 | #include "hoomd/Autotuner.h" 16 | 17 | namespace hoomd 18 | { 19 | 20 | namespace azplugins 21 | { 22 | 23 | //! Harmonic barrier on the GPU 24 | template 25 | class PYBIND11_EXPORT HarmonicBarrierGPU : public HarmonicBarrier 26 | { 27 | public: 28 | //! Constructor 29 | HarmonicBarrierGPU(std::shared_ptr sysdef, std::shared_ptr location) 30 | : HarmonicBarrier(sysdef, location) 31 | { 32 | m_tuner.reset(new Autotuner<1>({AutotunerBase::makeBlockSizeRange(this->m_exec_conf)}, 33 | this->m_exec_conf, 34 | "harmonic_barrier")); 35 | this->m_autotuners.push_back(m_tuner); 36 | } 37 | 38 | protected: 39 | std::shared_ptr> m_tuner; //!< Autotuner for block size 40 | 41 | //! Method to compute the forces 42 | void computeForces(uint64_t timestep) override; 43 | }; 44 | 45 | template 46 | void HarmonicBarrierGPU::computeForces(uint64_t timestep) 47 | { 48 | const BarrierEvaluatorT evaluator = this->makeEvaluator(timestep); 49 | 50 | ArrayHandle d_force(this->m_force, access_location::device, access_mode::overwrite); 51 | ArrayHandle d_virial(this->m_virial, access_location::device, access_mode::overwrite); 52 | 53 | ArrayHandle d_pos(this->m_pdata->getPositions(), 54 | access_location::device, 55 | access_mode::read); 56 | ArrayHandle d_params(this->m_params, access_location::device, access_mode::read); 57 | 58 | m_tuner->begin(); 59 | gpu::compute_harmonic_barrier(d_force.data, 60 | d_virial.data, 61 | d_pos.data, 62 | d_params.data, 63 | this->m_pdata->getGlobalBox(), 64 | evaluator, 65 | this->m_pdata->getN(), 66 | this->m_pdata->getNTypes(), 67 | m_tuner->getParam()[0]); 68 | if (this->m_exec_conf->isCUDAErrorCheckingEnabled()) 69 | CHECK_CUDA_ERROR(); 70 | m_tuner->end(); 71 | 72 | // virial is zeroed by GPU function, warn here 73 | this->warnVirialOnce(); 74 | } 75 | 76 | namespace detail 77 | { 78 | 79 | template 80 | void export_HarmonicBarrierGPU(pybind11::module& m, const std::string& name) 81 | { 82 | namespace py = pybind11; 83 | py::class_, 84 | HarmonicBarrier, 85 | std::shared_ptr>>(m, name.c_str()) 86 | .def(py::init, std::shared_ptr>()); 87 | } 88 | 89 | } // end namespace detail 90 | 91 | } // end namespace azplugins 92 | 93 | } // end namespace hoomd 94 | 95 | #endif // AZPLUGINS_HARMONIC_BARRIER_GPU_H_ 96 | -------------------------------------------------------------------------------- /src/HarmonicBarrierGPUKernel.cu.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "HarmonicBarrierGPU.cuh" 10 | #include "@_geometry@BarrierEvaluator.h" 11 | 12 | #define BARRIER_EVALUATOR @_geometry@BarrierEvaluator 13 | // clang-format on 14 | 15 | namespace hoomd 16 | { 17 | namespace azplugins 18 | { 19 | namespace gpu 20 | { 21 | 22 | template __attribute__((visibility("default"))) cudaError_t 23 | compute_harmonic_barrier(Scalar4* d_force, 24 | Scalar* d_virial, 25 | const Scalar4* d_pos, 26 | const Scalar2* d_params, 27 | const BoxDim& global_box, 28 | const BARRIER_EVALUATOR& evaluator, 29 | const unsigned int N, 30 | const unsigned int ntypes, 31 | const unsigned int block_size); 32 | 33 | } // end namespace gpu 34 | } // namespace azplugins 35 | } // end namespace hoomd 36 | -------------------------------------------------------------------------------- /src/PairEvaluator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_PAIR_EVALUATOR_H_ 6 | #define AZPLUGINS_PAIR_EVALUATOR_H_ 7 | 8 | #ifndef __HIPCC__ 9 | #include 10 | #include 11 | #endif // __HIPCC__ 12 | 13 | #include "hoomd/HOOMDMath.h" 14 | 15 | #ifdef __HIPCC__ 16 | #define DEVICE __device__ 17 | #define HOSTDEVICE __host__ __device__ 18 | #else 19 | #define DEVICE 20 | #define HOSTDEVICE 21 | #endif // __HIPCC__ 22 | 23 | namespace hoomd 24 | { 25 | namespace azplugins 26 | { 27 | namespace detail 28 | { 29 | 30 | //! Base class for isotropic pair potential parameters 31 | /*! 32 | * This class covers the default case of a simple potential that doesn't do 33 | * anything special loading its parameters. This class can then be used as 34 | * a \a param_type for the evaluator. 35 | * 36 | * Deriving classes \b must implement the constructors below. They should also 37 | * set the aligned attribute based on the size of the object. 38 | */ 39 | struct PairParameters 40 | { 41 | #ifndef __HIPCC__ 42 | PairParameters() { } 43 | 44 | PairParameters(pybind11::dict v, bool managed = false) { } 45 | 46 | pybind11::dict asDict() 47 | { 48 | return pybind11::dict(); 49 | } 50 | #endif //__HIPCC__ 51 | 52 | DEVICE void load_shared(char*& ptr, unsigned int& available_bytes) { } 53 | 54 | HOSTDEVICE void allocate_shared(char*& ptr, unsigned int& available_bytes) const { } 55 | 56 | #ifdef ENABLE_HIP 57 | void set_memory_hint() const { } 58 | #endif 59 | }; 60 | 61 | //! Base class for isotropic pair potential evaluator 62 | /*! 63 | * This class covers the default case of a simple potential that doesn't require 64 | * additional data. Deriving classes \b must define a \a param_type . They must 65 | * also give the potential a name and implement the evalForceAndEnergy() method. 66 | */ 67 | class PairEvaluator 68 | { 69 | public: 70 | typedef PairParameters param_type; 71 | 72 | DEVICE PairEvaluator(const Scalar _rsq, const Scalar _rcutsq) : rsq(_rsq), rcutsq(_rcutsq) { } 73 | 74 | //! Base potential does not need charge 75 | DEVICE static bool needsCharge() 76 | { 77 | return false; 78 | } 79 | 80 | //! Accept the optional charge values 81 | /*! 82 | * \param qi Charge of particle i 83 | * \param qj Charge of particle j 84 | */ 85 | DEVICE void setCharge(Scalar qi, Scalar qj) { } 86 | 87 | //! Evaluate the force and energy 88 | /*! 89 | * \param force_divr Holds the computed force divided by r 90 | * \param pair_eng Holds the computed pair energy 91 | * \param energy_shift If true, the potential is shifted to zero at the cutoff 92 | * 93 | * \returns True if the energy calculation occurs 94 | * 95 | * The calculation does not occur if the pair distance is greater than the cutoff 96 | * or if the potential is scaled to zero. 97 | */ 98 | DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& pair_eng, bool energy_shift) 99 | { 100 | return false; 101 | } 102 | 103 | //! Evaluate the long-ranged correction to the pressure. 104 | /*! 105 | * \returns Default value of 0 (no correction). 106 | */ 107 | DEVICE Scalar evalPressureLRCIntegral() 108 | { 109 | return Scalar(0.0); 110 | } 111 | 112 | //! Evaluate the long-ranged correction to the energy. 113 | /*! 114 | * \returns Default value of 0 (no correction). 115 | */ 116 | DEVICE Scalar evalEnergyLRCIntegral() 117 | { 118 | return Scalar(0.0); 119 | } 120 | 121 | #ifndef __HIPCC__ 122 | //! Get the name of this potential 123 | /*! 124 | * This method must be overridden by deriving classes. 125 | */ 126 | static std::string getName() 127 | { 128 | throw std::runtime_error("Name not defined for this pair potential."); 129 | } 130 | 131 | std::string getShapeSpec() const 132 | { 133 | throw std::runtime_error("Shape definition not supported for this pair potential."); 134 | } 135 | #endif // __HIPCC__ 136 | 137 | protected: 138 | Scalar rsq; //!< Squared distance between particles 139 | Scalar rcutsq; //!< Squared cutoff distance 140 | }; 141 | 142 | } // end namespace detail 143 | } // end namespace azplugins 144 | } // end namespace hoomd 145 | 146 | #undef DEVICE 147 | #undef HOSTDEVICE 148 | 149 | #endif // AZPLUGINS_PAIR_EVALUATOR_H_ 150 | -------------------------------------------------------------------------------- /src/PairEvaluatorExpandedYukawa.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_PAIR_EVALUATOR_EXPANDED_YUKAWA_H_ 6 | #define AZPLUGINS_PAIR_EVALUATOR_EXPANDED_YUKAWA_H_ 7 | 8 | #include "PairEvaluator.h" 9 | 10 | #ifdef __HIPCC__ 11 | #define DEVICE __device__ 12 | #else 13 | #define DEVICE 14 | #endif 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | namespace detail 21 | { 22 | 23 | struct PairParametersExpandedYukawa : public PairParameters 24 | { 25 | #ifndef __HIPCC__ 26 | PairParametersExpandedYukawa() : epsilon(0), kappa(0), delta(0) { } 27 | 28 | PairParametersExpandedYukawa(pybind11::dict v, bool managed = false) 29 | { 30 | epsilon = v["epsilon"].cast(); 31 | kappa = v["kappa"].cast(); 32 | delta = v["delta"].cast(); 33 | } 34 | 35 | pybind11::dict asDict() 36 | { 37 | pybind11::dict v; 38 | v["epsilon"] = epsilon; 39 | v["kappa"] = kappa; 40 | v["delta"] = delta; 41 | return v; 42 | } 43 | #endif // __HIPCC__ 44 | 45 | Scalar epsilon; //!< energy parameter [energy] 46 | Scalar kappa; //!< scaling parameter [length]^-1 47 | Scalar delta; //!< shifting parameter [length] 48 | } 49 | #if HOOMD_LONGREAL_SIZE == 32 50 | __attribute__((aligned(16))); 51 | #else 52 | __attribute__((aligned(32))); 53 | #endif 54 | 55 | //! Class for evaluating the expanded yukawa pair potential 56 | /*! 57 | * This is the typical Yukawa potential modified to shift the potential 58 | * to account for different particle diameters. 59 | */ 60 | class PairEvaluatorExpandedYukawa : public PairEvaluator 61 | { 62 | public: 63 | typedef PairParametersExpandedYukawa param_type; 64 | 65 | //! Constructor 66 | /*! 67 | * \param _rsq Squared distance between particles 68 | * \param _rcutsq Cutoff radius squared 69 | * \param _params Pair potential parameters, given by typedef above 70 | * 71 | * The functor initializes its members from \a _params. 72 | */ 73 | DEVICE PairEvaluatorExpandedYukawa(Scalar _rsq, Scalar _rcutsq, const param_type& _params) 74 | : PairEvaluator(_rsq, _rcutsq) 75 | { 76 | epsilon = _params.epsilon; 77 | kappa = _params.kappa; 78 | delta = _params.delta; 79 | } 80 | 81 | //! Evaluate the force and energy 82 | /*! 83 | * \param force_divr Holds the computed force divided by r 84 | * \param pair_eng Holds the computed pair energy 85 | * \param energy_shift If true, the potential is shifted to zero at the cutoff 86 | * 87 | * \returns True if the energy calculation occurs 88 | * 89 | * The calculation does not occur if the pair distance is greater than the cutoff 90 | * or if the potential is scaled to zero. 91 | */ 92 | DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& pair_eng, bool energy_shift) 93 | { 94 | // compute the force divided by r in force_divr 95 | if (rsq < rcutsq && epsilon != Scalar(0)) 96 | { 97 | const Scalar r = fast::sqrt(rsq); 98 | const Scalar r_delta = r - delta; 99 | const Scalar r_delta_inv = Scalar(1.0) / r_delta; 100 | 101 | pair_eng = epsilon * fast::exp(-kappa * r_delta) * r_delta_inv; 102 | force_divr = pair_eng * (kappa + r_delta_inv) / r; 103 | 104 | if (energy_shift) 105 | { 106 | const Scalar rcut = fast::sqrt(rcutsq); 107 | const Scalar rcut_delta = rcut - delta; 108 | pair_eng -= epsilon * fast::exp(-kappa * rcut_delta) / rcut_delta; 109 | } 110 | 111 | return true; 112 | } 113 | else 114 | return false; 115 | } 116 | 117 | #ifndef __HIPCC__ 118 | //! Return the name of this potential 119 | static std::string getName() 120 | { 121 | return std::string("ExpandedYukawa"); 122 | } 123 | #endif 124 | 125 | protected: 126 | Scalar epsilon; //!< Energy parameter 127 | Scalar kappa; //!< Scaling parameter 128 | Scalar delta; //!< Shifting parameter 129 | }; 130 | 131 | } // end namespace detail 132 | } // end namespace azplugins 133 | } // end namespace hoomd 134 | 135 | #undef DEVICE 136 | 137 | #endif // AZPLUGINS_PAIR_EVALUATOR_EXPANDED_YUKAWA_H_ 138 | -------------------------------------------------------------------------------- /src/PairEvaluatorHertz.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_PAIR_EVALUATOR_HERTZ_H_ 6 | #define AZPLUGINS_PAIR_EVALUATOR_HERTZ_H_ 7 | 8 | #include "PairEvaluator.h" 9 | 10 | #ifdef __HIPCC__ 11 | #define DEVICE __device__ 12 | #else 13 | #define DEVICE 14 | #endif 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | namespace detail 21 | { 22 | 23 | struct PairParametersHertz : public PairParameters 24 | { 25 | #ifndef __HIPCC__ 26 | PairParametersHertz() : epsilon(0) { } 27 | 28 | PairParametersHertz(pybind11::dict v, bool managed = false) 29 | { 30 | epsilon = v["epsilon"].cast(); 31 | } 32 | 33 | pybind11::dict asDict() 34 | { 35 | pybind11::dict v; 36 | v["epsilon"] = epsilon; 37 | return v; 38 | } 39 | #endif // __HIPCC__ 40 | 41 | Scalar epsilon; 42 | } 43 | #if HOOMD_LONGREAL_SIZE == 32 44 | __attribute__((aligned(4))); 45 | #else 46 | __attribute__((aligned(8))); 47 | #endif 48 | //! Class for evaluating the Hertz pair potential 49 | /*! 50 | * PairEvaluatorHertz evaluates the function: 51 | * \f{eqnarray*}{ 52 | * V(r) = & \varepsilon (1-\frac{r}{r_{\mathrm{cut}}})^\frac{5}{2} & r < r_{\mathrm{cut}} \\ 53 | * = & 0 r \ge r_{\mathrm{cut}} 54 | * \f} 55 | * 56 | * This potential is implemented as given in 57 | * Pàmies, J. C., Cacciuto, A., & Frenkel, D., Journal 58 | * of Chemical Physics, 131(4) (2009). 59 | * 60 | * The Hertz potential does not need diameter or charge. One parameter is specified and stored in a 61 | * Scalar. 62 | */ 63 | class PairEvaluatorHertz : public PairEvaluator 64 | { 65 | public: 66 | //! Define the parameter type used by this pair potential evaluator 67 | typedef PairParametersHertz param_type; 68 | 69 | //! Constructor 70 | /*! 71 | * \param _rsq Squared distance between particles 72 | * \param _rcutsq Cutoff radius squared 73 | * \param _params Pair potential parameters, given by typedef above 74 | * 75 | * The functor initializes its members from \a _params. 76 | */ 77 | DEVICE PairEvaluatorHertz(Scalar _rsq, Scalar _rcutsq, const param_type& _params) 78 | : PairEvaluator(_rsq, _rcutsq), epsilon(_params.epsilon) 79 | { 80 | } 81 | 82 | //! Evaluate the force and energy 83 | /*! 84 | * \param force_divr Holds the computed force divided by r 85 | * \param pair_eng Holds the computed pair energy 86 | * \param energy_shift If true, the potential is shifted to zero at the cutoff 87 | * 88 | * \returns True if the energy calculation occurs 89 | * 90 | * The calculation does not occur if the pair distance is greater than the cutoff 91 | * or if the potential is scaled to zero. 92 | */ 93 | DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& pair_eng, bool energy_shift) 94 | { 95 | if (rsq < rcutsq && epsilon != Scalar(0)) 96 | { 97 | const Scalar r = fast::sqrt(rsq); 98 | const Scalar rcut = fast::sqrt(rcutsq); 99 | const Scalar x = Scalar(1.0) - (r / rcut); 100 | const Scalar xsqrt = fast::sqrt(x); 101 | const Scalar ex3p2 = epsilon * x * xsqrt; 102 | force_divr = Scalar(2.5) * ex3p2 / (r * rcut); 103 | pair_eng = ex3p2 * x; 104 | return true; 105 | } 106 | else 107 | { 108 | return false; 109 | } 110 | } 111 | 112 | #ifndef __HIPCC__ 113 | //! Return the name of this potential 114 | static std::string getName() 115 | { 116 | return std::string("hertz"); 117 | } 118 | #endif 119 | 120 | protected: 121 | Scalar epsilon; //!< epsilon parameter (energy scale of interaction) 122 | }; 123 | 124 | } // end namespace detail 125 | } // end namespace azplugins 126 | } // end namespace hoomd 127 | 128 | #undef DEVICE 129 | 130 | #endif // AZPLUGINS_PAIR_EVALUATOR_HERTZ_H_ 131 | -------------------------------------------------------------------------------- /src/PairEvaluatorPerturbedLennardJones.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_PAIR_EVALUATOR_PERTURBED_LENNARD_JONES_H_ 6 | #define AZPLUGINS_PAIR_EVALUATOR_PERTURBED_LENNARD_JONES_H_ 7 | 8 | #include "PairEvaluator.h" 9 | 10 | #ifdef __HIPCC__ 11 | #define DEVICE __device__ 12 | #define HOSTDEVICE __host__ __device__ 13 | #else 14 | #define DEVICE 15 | #define HOSTDEVICE 16 | #endif 17 | 18 | namespace hoomd 19 | { 20 | namespace azplugins 21 | { 22 | namespace detail 23 | { 24 | //! Define the parameter type used by this pair potential evaluator 25 | struct PairParametersPerturbedLennardJones : public PairParameters 26 | { 27 | #ifndef __HIPCC__ 28 | PairParametersPerturbedLennardJones() 29 | : sigma_6(0), epsilon_x_4(0), attraction_scale_factor(0), rwcasq(0) 30 | { 31 | } 32 | 33 | PairParametersPerturbedLennardJones(pybind11::dict v, bool managed = false) 34 | { 35 | auto sigma(v["sigma"].cast()); 36 | auto epsilon(v["epsilon"].cast()); 37 | 38 | const Scalar sigma_2 = sigma * sigma; 39 | const Scalar sigma_4 = sigma_2 * sigma_2; 40 | sigma_6 = sigma_2 * sigma_4; 41 | 42 | epsilon_x_4 = Scalar(4.0) * epsilon; 43 | attraction_scale_factor = v["attraction_scale_factor"].cast(); 44 | rwcasq = pow(Scalar(2.), 1. / 3.) * sigma_2; 45 | } 46 | 47 | pybind11::dict asDict() 48 | { 49 | pybind11::dict v; 50 | v["sigma"] = pow(sigma_6, 1. / 6.); 51 | v["epsilon"] = epsilon_x_4 / Scalar(4.); 52 | v["attraction_scale_factor"] = attraction_scale_factor; 53 | return v; 54 | } 55 | #endif // __HIPCC__ 56 | 57 | Scalar sigma_6; //!< The coefficient for 1/r^12 58 | Scalar epsilon_x_4; //!< The coefficient for 1/r^6 59 | Scalar attraction_scale_factor; //!< Controls the attractive tail, between 0 and 1 60 | Scalar rwcasq; //!< The square of the location of the LJ potential minimum 61 | } 62 | #if HOOMD_LONGREAL_SIZE == 32 63 | __attribute__((aligned(16))); 64 | #else 65 | __attribute__((aligned(32))); 66 | #endif 67 | 68 | //! Class for evaluating the perturbed Lennard-Jones pair potential 69 | /*! 70 | * This class evaluates the function: 71 | * \f{eqnarray*}{ 72 | * V(r) = & V_{\mathrm{LJ}}(r, \varepsilon, \sigma) 73 | * + (1-\lambda)\varepsilon & r < 2^{1/6}\sigma \\ 74 | * = & \lambda V_{\mathrm{LJ}}(r, \varepsilon, \sigma) & 75 | * 2^{1/6}\sigma \ge r < r_{\mathrm{cut}} \\ 76 | * = & 0 & r \ge r_{\mathrm{cut}} 77 | * \f} 78 | * 79 | * where \f$V_{\mathrm{LJ}}(r,\varepsilon,\sigma)\f$ is the standard 80 | * Lennard-Jones potential (see EvaluatorPairLJ) with parameters 81 | * \f$\varepsilon\f$ and \f$\sigma\f$. 82 | */ 83 | class PairEvaluatorPerturbedLennardJones : public PairEvaluator 84 | { 85 | public: 86 | typedef PairParametersPerturbedLennardJones param_type; 87 | 88 | //! Constructor 89 | /*! 90 | * \param _rsq Squared distance between particles 91 | * \param _rcutsq Cutoff radius squared 92 | * \param _params Pair potential parameters, given by typedef above 93 | * 94 | * The functor initializes its members from \a _params. 95 | */ 96 | DEVICE 97 | PairEvaluatorPerturbedLennardJones(Scalar _rsq, Scalar _rcutsq, const param_type& _params) 98 | : PairEvaluator(_rsq, _rcutsq), 99 | lj1(_params.epsilon_x_4 * _params.sigma_6 * _params.sigma_6), 100 | lj2(_params.epsilon_x_4 * _params.sigma_6), 101 | attraction_scale_factor(_params.attraction_scale_factor), rwcasq(_params.rwcasq) 102 | { 103 | wca_shift = _params.epsilon_x_4 * (Scalar(1.0) - attraction_scale_factor) / Scalar(4.0); 104 | } 105 | 106 | //! Evaluate the force and energy 107 | /*! 108 | * \param force_divr Holds the computed force divided by r 109 | * \param pair_eng Holds the computed pair energy 110 | * \param energy_shift If true, the potential is shifted to zero at the cutoff 111 | * 112 | * \returns True if the energy calculation occurs 113 | * 114 | * The calculation does not occur if the pair distance is greater than the cutoff 115 | * or if the potential is scaled to zero. 116 | */ 117 | DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& pair_eng, bool energy_shift) 118 | { 119 | if (rsq < rcutsq && lj1 != 0) 120 | { 121 | const Scalar r2inv = Scalar(1.0) / rsq; 122 | const Scalar r6inv = r2inv * r2inv * r2inv; 123 | force_divr = r2inv * r6inv * (Scalar(12.0) * lj1 * r6inv - Scalar(6.0) * lj2); 124 | 125 | pair_eng = r6inv * (lj1 * r6inv - lj2); 126 | if (rsq < rwcasq) 127 | { 128 | pair_eng += wca_shift; 129 | } 130 | else 131 | { 132 | force_divr *= attraction_scale_factor; 133 | pair_eng *= attraction_scale_factor; 134 | } 135 | 136 | if (energy_shift) 137 | { 138 | const Scalar rcut2inv = Scalar(1.0) / rcutsq; 139 | const Scalar rcut6inv = rcut2inv * rcut2inv * rcut2inv; 140 | Scalar pair_eng_shift = rcut6inv * (lj1 * rcut6inv - lj2); 141 | if (rcutsq < rwcasq) 142 | { 143 | pair_eng_shift += wca_shift; 144 | } 145 | else 146 | { 147 | pair_eng_shift *= attraction_scale_factor; 148 | } 149 | pair_eng -= pair_eng_shift; 150 | } 151 | return true; 152 | } 153 | else 154 | return false; 155 | } 156 | 157 | #ifndef __HIPCC__ 158 | //! Return the name of this potential 159 | static std::string getName() 160 | { 161 | return std::string("PerturbedLennardJones"); 162 | } 163 | #endif 164 | 165 | private: 166 | Scalar lj1; //!< lj1 parameter - 4 epsilon sigma^12 167 | Scalar lj2; //!< lj2 parameter - 4 epsilon sigma^6 168 | Scalar attraction_scale_factor; //!< attraction_scale_factor parameter 169 | Scalar rwcasq; //!< WCA cutoff radius squared 170 | Scalar wca_shift; //!< Energy shift for WCA part of the potential 171 | }; 172 | 173 | } // end namespace detail 174 | } // end namespace azplugins 175 | } // end namespace hoomd 176 | 177 | #undef DEVICE 178 | #undef HOSTDEVICE 179 | 180 | #endif // AZPLUGINS_PAIR_EVALUATOR_PERTURBED_LENNARD_JONES_H_ 181 | -------------------------------------------------------------------------------- /src/ParabolicFlow.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #include "ParabolicFlow.h" 6 | 7 | namespace hoomd 8 | { 9 | namespace azplugins 10 | { 11 | namespace detail 12 | { 13 | void export_ParabolicFlow(pybind11::module& m) 14 | { 15 | namespace py = pybind11; 16 | py::class_>(m, "ParabolicFlow") 17 | .def(py::init()) 18 | .def_property("mean_velocity", 19 | &ParabolicFlow::getMeanVelocity, 20 | &ParabolicFlow::setMeanVelocity) 21 | .def_property("separation", &ParabolicFlow::getSeparation, &ParabolicFlow::setSeparation); 22 | } 23 | } // namespace detail 24 | } // namespace azplugins 25 | } // namespace hoomd 26 | -------------------------------------------------------------------------------- /src/ParabolicFlow.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file ParabolicFlow.h 7 | * \brief Declaration of ParabolicFlow 8 | */ 9 | 10 | #ifndef AZPLUGINS_PARABOLIC_FLOW_H_ 11 | #define AZPLUGINS_PARABOLIC_FLOW_H_ 12 | 13 | #ifndef __HIPCC__ 14 | #include 15 | #endif 16 | 17 | #include "hoomd/HOOMDMath.h" 18 | 19 | #ifndef __HIPCC__ 20 | #define HOSTDEVICE __host__ __device__ 21 | #else 22 | #define HOSTDEVICE 23 | #endif // __HIPCC__ 24 | 25 | #ifndef PYBIND11_EXPORT 26 | #define PYBIND11_EXPORT __attribute__((visibility("default"))) 27 | #endif 28 | 29 | namespace hoomd 30 | { 31 | namespace azplugins 32 | { 33 | 34 | //! Unidirectional parabolic flow field 35 | /*! 36 | * 1d flow along the \a x axis. The geometry is a parallel plate channel with 37 | * the plates centered around \f$ y = 0 \f$ and positioned at \f$ \pm L \f$. 38 | * The \a y axis is the vorticity direction and periodic. The flow profile in 39 | * this geometry is then 40 | * 41 | * \f[ 42 | * u_x(y) = \frac{3}{2} U \left[1 - \left(\frac{y}{L}\right)^2 \right] 43 | * \f] 44 | * 45 | * Here, \f$ mean_velocity \f$ is the mean velocity, which is related to the pressure drop 46 | * and viscosity. 47 | * 48 | * \note The user must properly establish no flux of particles through the channel 49 | * walls through an appropriate wall potential. 50 | */ 51 | class PYBIND11_EXPORT ParabolicFlow 52 | { 53 | public: 54 | //! Construct parabolic flow profile 55 | /*! 56 | * \param U_ Mean velocity 57 | * \param L_ Separation 58 | */ 59 | ParabolicFlow(Scalar mean_velocity, Scalar separation) 60 | { 61 | setMeanVelocity(mean_velocity); 62 | setSeparation(separation); 63 | } 64 | 65 | //! Evaluate the flow field 66 | /*! 67 | * \param r position to evaluate flow 68 | */ 69 | HOSTDEVICE Scalar3 operator()(const Scalar3& r) const 70 | { 71 | const Scalar yr = (r.y / L); 72 | return make_scalar3(Umax * (1. - yr * yr), 0.0, 0.0); 73 | } 74 | 75 | HOSTDEVICE Scalar getMeanVelocity() const 76 | { 77 | return Umax / Scalar(1.5); 78 | } 79 | 80 | HOSTDEVICE void setMeanVelocity(const Scalar& U) 81 | { 82 | Umax = Scalar(1.5) * U; 83 | } 84 | 85 | HOSTDEVICE Scalar getSeparation() const 86 | { 87 | return Scalar(2.0) * L; 88 | } 89 | 90 | HOSTDEVICE void setSeparation(const Scalar& L_) 91 | { 92 | L = Scalar(0.5) * L_; 93 | } 94 | 95 | private: 96 | Scalar Umax; // sysdef, unsigned int seed); 49 | 50 | //! Constructor with parameters 51 | ParticleEvaporator(std::shared_ptr sysdef, 52 | unsigned int evap_type, 53 | unsigned int solvent_type, 54 | Scalar z_lo, 55 | Scalar z_hi, 56 | unsigned int seed); 57 | 58 | //! Destructor 59 | virtual ~ParticleEvaporator() { }; 60 | 61 | //! Get the maximum number of particles to evaporate 62 | unsigned int getNEvapMax() const 63 | { 64 | return m_Nevap_max; 65 | } 66 | 67 | //! Set the maximum number of particles to evaporate 68 | void setNEvapMax(unsigned int Nevap_max) 69 | { 70 | m_Nevap_max = Nevap_max; 71 | } 72 | 73 | protected: 74 | unsigned int m_seed; //!< Seed to evaporator pseudo-random number generator 75 | unsigned int m_Nevap_max; //!< Maximum number of particles to evaporate 76 | unsigned int m_Npick; //!< Number of particles picked for evaporation on this rank 77 | GPUVector m_picks; //!< Particles picked for evaporation on this rank 78 | GPUVector m_mark; //!< Indexes of atoms that can be deleted 79 | 80 | //! Changes the particle types according to an update rule on the GPU 81 | virtual void changeTypes(unsigned int timestep); 82 | 83 | //! Mark particles as candidates for evaporation 84 | virtual unsigned int markParticles(); 85 | 86 | //! Apply evaporation to picks 87 | virtual void applyPicks(); 88 | 89 | private: 90 | std::vector m_all_picks; //!< All picked particles 91 | 92 | //! Make a random pick of particles across all ranks 93 | void makeAllPicks(unsigned int timestep, unsigned int N_pick, unsigned N_mark_total); 94 | }; 95 | 96 | namespace detail 97 | { 98 | //! Export ParticleEvaporator to python 99 | void export_ParticleEvaporator(pybind11::module& m); 100 | } // end namespace detail 101 | 102 | } // end namespace azplugins 103 | 104 | #endif // AZPLUGINS_PARTICLE_EVAPORATOR_H_ 105 | -------------------------------------------------------------------------------- /src/ParticleEvaporatorGPU.cuh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file ParticleEvaporatorGPU.cuh 7 | * \brief Declaration of kernel drivers for ParticleEvaporatorGPU 8 | */ 9 | 10 | #ifndef AZPLUGINS_PARTICLE_EVAPORATOR_GPU_CUH_ 11 | #define AZPLUGINS_PARTICLE_EVAPORATOR_GPU_CUH_ 12 | 13 | #include "hoomd/HOOMDMath.h" 14 | #include 15 | 16 | namespace azplugins 17 | { 18 | namespace gpu 19 | { 20 | //! Kernel driver to change particle types in a region on the GPU 21 | cudaError_t evaporate_setup_mark(unsigned char* d_select_flags, 22 | unsigned int* d_mark, 23 | const Scalar4* d_pos, 24 | unsigned int solvent_type, 25 | Scalar z_lo, 26 | Scalar z_hi, 27 | unsigned int N, 28 | unsigned int block_size); 29 | 30 | //! Drives CUB device selection routines for marked particles 31 | cudaError_t evaporate_select_mark(unsigned int* d_mark, 32 | unsigned int* d_num_mark, 33 | void* d_tmp_storage, 34 | size_t& tmp_storage_bytes, 35 | const unsigned char* d_select_flags, 36 | unsigned int N); 37 | 38 | //! Updates particles types according to picks made on cpu 39 | cudaError_t evaporate_apply_picks(Scalar4* d_pos, 40 | const unsigned int* d_picks, 41 | const unsigned int* d_mark, 42 | unsigned int evaporated_type, 43 | unsigned int N_pick, 44 | unsigned int block_size); 45 | } // namespace gpu 46 | } // namespace azplugins 47 | 48 | #endif // AZPLUGINS_PARTICLE_EVAPORATOR_GPU_CUH_ 49 | -------------------------------------------------------------------------------- /src/ParticleEvaporatorGPU.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file ParticleEvaporatorGPU.h 7 | * \brief Declaration of ParticleEvaporatorGPU 8 | */ 9 | 10 | #ifndef AZPLUGINS_PARTICLE_EVAPORATOR_GPU_H_ 11 | #define AZPLUGINS_PARTICLE_EVAPORATOR_GPU_H_ 12 | 13 | #ifdef NVCC 14 | #error This header cannot be compiled by nvcc 15 | #endif 16 | 17 | #include "ParticleEvaporator.h" 18 | #include "hoomd/Autotuner.h" 19 | #include "hoomd/GPUFlags.h" 20 | 21 | namespace azplugins 22 | { 23 | 24 | //! Solvent-particle evaporator on the GPU 25 | /*! 26 | * See ParticleEvaporator for details. This class inherits and minimally implements 27 | * the CPU methods from ParticleEvaporator on the GPU. 28 | */ 29 | class PYBIND11_EXPORT ParticleEvaporatorGPU : public ParticleEvaporator 30 | { 31 | public: 32 | //! Simple constructor 33 | ParticleEvaporatorGPU(std::shared_ptr sysdef, unsigned int seed); 34 | 35 | //! Constructor with parameters 36 | ParticleEvaporatorGPU(std::shared_ptr sysdef, 37 | unsigned int inside_type, 38 | unsigned int outside_type, 39 | Scalar z_lo, 40 | Scalar z_hi, 41 | unsigned int seed); 42 | 43 | //! Destructor 44 | virtual ~ParticleEvaporatorGPU() { }; 45 | 46 | //! Set autotuner parameters 47 | /*! 48 | * \param enable Enable / disable autotuning 49 | * \param period period (approximate) in time steps when retuning occurs 50 | */ 51 | virtual void setAutotunerParams(bool enable, unsigned int period) 52 | { 53 | ParticleEvaporator::setAutotunerParams(enable, period); 54 | 55 | m_mark_tuner->setPeriod(period); 56 | m_mark_tuner->setEnabled(enable); 57 | 58 | m_pick_tuner->setPeriod(period); 59 | m_pick_tuner->setEnabled(enable); 60 | } 61 | 62 | protected: 63 | //! Mark particles as candidates for evaporation on the GPU 64 | virtual unsigned int markParticles(); 65 | 66 | //! Apply evaporation to picks on the GPU 67 | virtual void applyPicks(); 68 | 69 | private: 70 | std::unique_ptr m_mark_tuner; //!< Tuner for marking particles 71 | std::unique_ptr m_pick_tuner; //!< Tuner for applying picks 72 | GPUVector 73 | m_select_flags; //!< Flags (1/0) for device selection of marked particles 74 | GPUFlags m_num_mark; //!< GPU flags for the number of marked particles 75 | }; 76 | 77 | namespace detail 78 | { 79 | //! Export ParticleEvaporatorGPU to python 80 | void export_ParticleEvaporatorGPU(pybind11::module& m); 81 | } // end namespace detail 82 | 83 | } // end namespace azplugins 84 | 85 | #endif // AZPLUGINS_PARTICLE_EVAPORATOR_GPU_H_ 86 | -------------------------------------------------------------------------------- /src/PlanarBarrierEvaluator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_PLANAR_BARRIER_EVALUATOR_H_ 6 | #define AZPLUGINS_PLANAR_BARRIER_EVALUATOR_H_ 7 | 8 | #include "hoomd/BoxDim.h" 9 | #include "hoomd/HOOMDMath.h" 10 | 11 | #ifdef __HIPCC__ 12 | #define HOSTDEVICE __host__ __device__ 13 | #else 14 | #define HOSTDEVICE 15 | #endif // __HIPCC__ 16 | 17 | namespace hoomd 18 | { 19 | namespace azplugins 20 | { 21 | 22 | //! Planar barrier 23 | /*! 24 | * The barrier is a plane with normal in the +y direction. The harmonic potential 25 | * acts to move particles that are above y = H down, with H optionally being 26 | * shifted by an offset. The plane must lie inside the axis-aligned bounding 27 | * box enclosing the global simulation box. The coordinates are assumed to be 28 | * wrapped into the global box. 29 | */ 30 | class PlanarBarrierEvaluator 31 | { 32 | public: 33 | HOSTDEVICE PlanarBarrierEvaluator(Scalar H) : m_H(H) { } 34 | 35 | //! Evaluate the harmonic barrier force and energy 36 | HOSTDEVICE Scalar4 operator()(const Scalar3& pos, Scalar k, Scalar offset) const 37 | { 38 | const Scalar dy = pos.y - (m_H + offset); 39 | // don't compute if below minimum of potential 40 | if (dy <= Scalar(0.0)) 41 | { 42 | return make_scalar4(0, 0, 0, 0); 43 | } 44 | 45 | const Scalar f = -k * dy; // y component of force 46 | const Scalar e = Scalar(-0.5) * f * dy; // U = 0.5 k dx^2 47 | return make_scalar4(0, f, 0, e); 48 | } 49 | 50 | //! Validate the harmonic barrier location is inside the global box 51 | HOSTDEVICE bool valid(const BoxDim& box) const 52 | { 53 | const Scalar3 lo = box.makeCoordinates(make_scalar3(0, 0, 0)); 54 | const Scalar3 hi = box.makeCoordinates(make_scalar3(1, 1, 1)); 55 | return (m_H >= lo.y && m_H < hi.y); 56 | } 57 | 58 | private: 59 | Scalar m_H; //( 27 | const kernel::bond_args_t<2>& bond_args, 28 | const typename hoomd::azplugins::detail::EVALUATOR_CLASS::param_type* d_params, 29 | unsigned int* d_flags); 30 | } // end namespace kernel 31 | } // end namespace md 32 | } // end namespace hoomd 33 | -------------------------------------------------------------------------------- /src/PotentialPairDPDThermoGPUKernel.cu.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "hoomd/md/PotentialPairDPDThermoGPU.cuh" 10 | #include "DPDPairEvaluator@_evaluator@.h" 11 | 12 | #define EVALUATOR_CLASS DPDPairEvaluator@_evaluator@ 13 | // clang-format on 14 | 15 | namespace hoomd 16 | { 17 | namespace md 18 | { 19 | namespace kernel 20 | { 21 | template __attribute__((visibility("default"))) hipError_t 22 | gpu_compute_dpd_forces( 23 | const dpd_pair_args_t& pair_args, 24 | const hoomd::azplugins::detail::EVALUATOR_CLASS::param_type* d_params); 25 | } // end namespace kernel 26 | } // end namespace md 27 | } // end namespace hoomd 28 | -------------------------------------------------------------------------------- /src/PotentialPairGPUKernel.cu.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // Adapted from hoomd/md/export_PotentialPairGPUKernel.cu.inc of HOOMD-blue. 6 | // Copyright (c) 2009-2024 The Regents of the University of Michigan. 7 | // Part of HOOMD-blue, released under the BSD 3-Clause License. 8 | 9 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 10 | // configure_file(). 11 | 12 | // clang-format off 13 | #include "hoomd/md/PotentialPairGPU.cuh" 14 | #include "PairEvaluator@_evaluator@.h" 15 | 16 | #define EVALUATOR_CLASS PairEvaluator@_evaluator@ 17 | // clang-format on 18 | 19 | namespace hoomd 20 | { 21 | namespace md 22 | { 23 | namespace kernel 24 | { 25 | template __attribute__((visibility("default"))) hipError_t 26 | gpu_compute_pair_forces( 27 | const pair_args_t& pair_args, 28 | const hoomd::azplugins::detail::EVALUATOR_CLASS::param_type* d_params); 29 | } // end namespace kernel 30 | } // end namespace md 31 | } // end namespace hoomd 32 | -------------------------------------------------------------------------------- /src/RNGIdentifiers.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file RNGIdentifiers.h 7 | * \brief Identifiers for random123 generator. 8 | */ 9 | 10 | #ifndef AZPLUGINS_RNG_IDENTIFIERS_H_ 11 | #define AZPLUGINS_RNG_IDENTIFIERS_H_ 12 | 13 | namespace hoomd 14 | { 15 | namespace azplugins 16 | { 17 | 18 | namespace detail 19 | { 20 | struct RNGIdentifier 21 | { 22 | // hoomd's identifiers, changed by +/- 1 23 | static const uint8_t DPDEvaluatorGeneralWeight = 200; 24 | static const uint8_t TwoStepBrownianFlow = 201; 25 | static const uint8_t TwoStepLangevinFlow = 202; 26 | static const uint8_t ParticleEvaporator = 203; 27 | }; 28 | 29 | } // end namespace detail 30 | } // end namespace azplugins 31 | } // end namespace hoomd 32 | 33 | #endif // AZPLUGINS_RNG_IDENTIFIERS_H_ 34 | -------------------------------------------------------------------------------- /src/SphericalBarrierEvaluator.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_SPHERICAL_BARRIER_EVALUATOR_H_ 6 | #define AZPLUGINS_SPHERICAL_BARRIER_EVALUATOR_H_ 7 | 8 | #include "hoomd/BoxDim.h" 9 | #include "hoomd/HOOMDMath.h" 10 | 11 | #ifdef __HIPCC__ 12 | #define HOSTDEVICE __host__ __device__ 13 | #else 14 | #define HOSTDEVICE 15 | #endif // __HIPCC__ 16 | 17 | namespace hoomd 18 | { 19 | namespace azplugins 20 | { 21 | 22 | //! Spherical barrier 23 | /*! 24 | * The barrier is a sphere. The harmonic potential 25 | * acts to move particles that are outside the sphere inward, with the radius 26 | * of the sphere being optionally shifted by an offset. The sphere must lie 27 | * inside the global simulation box. The coordinates are assumed to be 28 | * wrapped into the global box. 29 | */ 30 | class SphericalBarrierEvaluator 31 | { 32 | public: 33 | HOSTDEVICE SphericalBarrierEvaluator(Scalar R) : m_R(R) { } 34 | 35 | //! Evaluate the harmonic barrier force and energy 36 | HOSTDEVICE Scalar4 operator()(const Scalar3& pos, Scalar k, Scalar offset) const 37 | { 38 | const Scalar r = fast::sqrt(dot(pos, pos)); 39 | const Scalar dr = r - (m_R + offset); 40 | 41 | // don't compute if below minimum of potential 42 | if (dr <= Scalar(0.0)) 43 | { 44 | return make_scalar4(0, 0, 0, 0); 45 | } 46 | 47 | const Scalar k_dr = k * dr; 48 | const Scalar3 f = -(k_dr / r) * pos; // F = -k dr \hat r 49 | const Scalar e = Scalar(0.5) * k_dr * dr; // U = 0.5 k dr^2 50 | return make_scalar4(f.x, f.y, f.z, e); 51 | } 52 | 53 | //! Validate the harmonic barrier location is inside the global box 54 | HOSTDEVICE bool valid(const BoxDim& box) const 55 | { 56 | const Scalar3 nearest_plane_distance = box.getNearestPlaneDistance(); 57 | const Scalar two_R = Scalar(2.0) * m_R; 58 | return (m_R >= Scalar(0.0) && nearest_plane_distance.x >= two_R 59 | && nearest_plane_distance.y >= two_R && nearest_plane_distance.z >= two_R); 60 | } 61 | 62 | private: 63 | Scalar m_R; //(Scalar4* d_pos, 20 | int3* d_image, 21 | const BoxDim& box, 22 | const Scalar4* d_net_force, 23 | const unsigned int* d_tag, 24 | const unsigned int* d_group, 25 | const Scalar* d_diameter, 26 | const Scalar lambda, 27 | const Scalar* d_gamma, 28 | const unsigned int ntypes, 29 | const azplugins::ConstantFlow& flow_field, 30 | const unsigned int N, 31 | const Scalar dt, 32 | const Scalar T, 33 | const unsigned int timestep, 34 | const unsigned int seed, 35 | bool noiseless, 36 | bool use_lambda, 37 | const unsigned int block_size); 38 | //! Explicit instantiation of ParabolicFlow integrator 39 | template cudaError_t 40 | brownian_flow(Scalar4* d_pos, 41 | int3* d_image, 42 | const BoxDim& box, 43 | const Scalar4* d_net_force, 44 | const unsigned int* d_tag, 45 | const unsigned int* d_group, 46 | const Scalar* d_diameter, 47 | const Scalar lambda, 48 | const Scalar* d_gamma, 49 | const unsigned int ntypes, 50 | const azplugins::ParabolicFlow& flow_field, 51 | const unsigned int N, 52 | const Scalar dt, 53 | const Scalar T, 54 | const unsigned int timestep, 55 | const unsigned int seed, 56 | bool noiseless, 57 | bool use_lambda, 58 | const unsigned int block_size); 59 | //! Explicit instantiation of QuiescentFluid integrator 60 | template cudaError_t 61 | brownian_flow(Scalar4* d_pos, 62 | int3* d_image, 63 | const BoxDim& box, 64 | const Scalar4* d_net_force, 65 | const unsigned int* d_tag, 66 | const unsigned int* d_group, 67 | const Scalar* d_diameter, 68 | const Scalar lambda, 69 | const Scalar* d_gamma, 70 | const unsigned int ntypes, 71 | const azplugins::QuiescentFluid& flow_field, 72 | const unsigned int N, 73 | const Scalar dt, 74 | const Scalar T, 75 | const unsigned int timestep, 76 | const unsigned int seed, 77 | bool noiseless, 78 | bool use_lambda, 79 | const unsigned int block_size); 80 | } // end namespace gpu 81 | } // end namespace azplugins 82 | -------------------------------------------------------------------------------- /src/TypeUpdater.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file TypeUpdater.h 7 | * \brief Declaration of TypeUpdater 8 | */ 9 | 10 | #ifndef AZPLUGINS_TYPE_UPDATER_H_ 11 | #define AZPLUGINS_TYPE_UPDATER_H_ 12 | 13 | #ifdef NVCC 14 | #error This header cannot be compiled by nvcc 15 | #endif 16 | 17 | #include "hoomd/Updater.h" 18 | #include "hoomd/extern/pybind/include/pybind11/pybind11.h" 19 | 20 | namespace azplugins 21 | { 22 | 23 | //! Particle type updater 24 | /*! 25 | * Flips particle types based on their z height. Particles are classified as 26 | * either inside or outside of the region, and can be flipped between these two 27 | * types. Particles that are of neither the inside nor outside type are ignored. 28 | * 29 | * The region is defined by a slab along z. This could be easily extended to 30 | * accommodate a generic region criteria, but for now, the planar slab in z is 31 | * all that is necessary. 32 | */ 33 | class PYBIND11_EXPORT TypeUpdater : public Updater 34 | { 35 | public: 36 | //! Simple constructor 37 | TypeUpdater(std::shared_ptr sysdef); 38 | 39 | //! Constructor with parameters 40 | TypeUpdater(std::shared_ptr sysdef, 41 | unsigned int inside_type, 42 | unsigned int outside_type, 43 | Scalar z_lo, 44 | Scalar z_hi); 45 | 46 | //! Destructor 47 | virtual ~TypeUpdater(); 48 | 49 | //! Evaporate particles 50 | virtual void update(unsigned int timestep); 51 | 52 | //! Get the inside particle type 53 | unsigned int getInsideType() const 54 | { 55 | return m_inside_type; 56 | } 57 | 58 | //! Set the inside particle type 59 | void setInsideType(unsigned int inside_type) 60 | { 61 | m_inside_type = inside_type; 62 | requestCheckTypes(); 63 | } 64 | 65 | //! Get the outside particle type 66 | unsigned int getOutsideType() const 67 | { 68 | return m_outside_type; 69 | } 70 | 71 | //! Set the outside particle type 72 | void setOutsideType(unsigned int outside_type) 73 | { 74 | m_outside_type = outside_type; 75 | requestCheckTypes(); 76 | } 77 | 78 | //! Get region lower bound 79 | Scalar getRegionLo() const 80 | { 81 | return m_z_lo; 82 | } 83 | 84 | //! Get region upper bound 85 | Scalar getRegionHi() const 86 | { 87 | return m_z_hi; 88 | } 89 | 90 | //! Set region lower bound 91 | void setRegionLo(Scalar z_lo) 92 | { 93 | m_z_lo = z_lo; 94 | requestCheckRegion(); 95 | } 96 | 97 | //! Set region upper bound 98 | void setRegionHi(Scalar z_hi) 99 | { 100 | m_z_hi = z_hi; 101 | requestCheckRegion(); 102 | } 103 | 104 | protected: 105 | unsigned int m_inside_type; //!< Type id of particles in region 106 | unsigned int m_outside_type; //!< Type id of particles outside region 107 | 108 | Scalar m_z_lo; //!< Minimum bound of region in z 109 | Scalar m_z_hi; //!< Maximum bound of region in z 110 | 111 | //! Changes the particle types according to an update rule 112 | virtual void changeTypes(unsigned int timestep); 113 | 114 | private: 115 | bool m_check_types; //!< Flag if type check is necessary 116 | //! Request to check types on next update 117 | void requestCheckTypes() 118 | { 119 | m_check_types = true; 120 | } 121 | //! Check that the particle types are valid 122 | void checkTypes() const; 123 | 124 | bool m_check_region; //!< Flag if region check is necessary 125 | //! Request to check region on next update 126 | void requestCheckRegion() 127 | { 128 | m_check_region = true; 129 | } 130 | //! Check that the particle region is valid 131 | void checkRegion() const; 132 | }; 133 | 134 | namespace detail 135 | { 136 | //! Export the Evaporator to python 137 | void export_TypeUpdater(pybind11::module& m); 138 | } // end namespace detail 139 | 140 | } // end namespace azplugins 141 | 142 | #endif // AZPLUGINS_TYPE_UPDATER_H_ 143 | -------------------------------------------------------------------------------- /src/TypeUpdaterGPU.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file TypeUpdaterGPU.cc 7 | * \brief Definition of TypeUpdaterGPU 8 | */ 9 | 10 | #include "TypeUpdaterGPU.h" 11 | #include "TypeUpdaterGPU.cuh" 12 | 13 | namespace azplugins 14 | { 15 | 16 | /*! 17 | * \param sysdef System definition 18 | * 19 | * The system is initialized in a configuration that will be invalid on the 20 | * first check of the types and region. This constructor requires that the user 21 | * properly initialize the system via setters. 22 | */ 23 | TypeUpdaterGPU::TypeUpdaterGPU(std::shared_ptr sysdef) : TypeUpdater(sysdef) 24 | { 25 | m_tuner.reset(new Autotuner(32, 1024, 32, 5, 100000, "type_updater", m_exec_conf)); 26 | } 27 | 28 | /*! 29 | * \param sysdef System definition 30 | * \param inside_type Type id of particles inside region 31 | * \param outside_type Type id of particles outside region 32 | * \param z_lo Lower bound of region in z 33 | * \param z_hi Upper bound of region in z 34 | */ 35 | TypeUpdaterGPU::TypeUpdaterGPU(std::shared_ptr sysdef, 36 | unsigned int inside_type, 37 | unsigned int outside_type, 38 | Scalar z_lo, 39 | Scalar z_hi) 40 | : TypeUpdater(sysdef, inside_type, outside_type, z_lo, z_hi) 41 | { 42 | m_tuner.reset(new Autotuner(32, 1024, 32, 5, 100000, "type_updater", m_exec_conf)); 43 | } 44 | 45 | /*! 46 | * \param timestep Timestep update is called 47 | */ 48 | void TypeUpdaterGPU::changeTypes(unsigned int timestep) 49 | { 50 | if (m_prof) 51 | m_prof->push(m_exec_conf, "type update"); 52 | 53 | ArrayHandle d_pos(m_pdata->getPositions(), 54 | access_location::device, 55 | access_mode::readwrite); 56 | 57 | m_tuner->begin(); 58 | gpu::change_types_region(d_pos.data, 59 | m_inside_type, 60 | m_outside_type, 61 | m_z_lo, 62 | m_z_hi, 63 | m_pdata->getN(), 64 | m_tuner->getParam()); 65 | if (m_exec_conf->isCUDAErrorCheckingEnabled()) 66 | CHECK_CUDA_ERROR(); 67 | m_tuner->end(); 68 | 69 | if (m_prof) 70 | m_prof->pop(); 71 | } 72 | 73 | namespace detail 74 | { 75 | /*! 76 | * \param m Python module to export to 77 | */ 78 | void export_TypeUpdaterGPU(pybind11::module& m) 79 | { 80 | namespace py = pybind11; 81 | py::class_>(m, 82 | "TypeUpdaterGPU", 83 | py::base()) 84 | .def(py::init>()) 85 | .def(py::init, 86 | unsigned int, 87 | unsigned int, 88 | Scalar, 89 | Scalar>()); 90 | } 91 | } // end namespace detail 92 | 93 | } // end namespace azplugins 94 | -------------------------------------------------------------------------------- /src/TypeUpdaterGPU.cu: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file TypeUpdaterGPU.cu 7 | * \brief Definition of kernel drivers and kernels for TypeUpdaterGPU 8 | */ 9 | 10 | #include "TypeUpdaterGPU.cuh" 11 | 12 | namespace azplugins 13 | { 14 | namespace gpu 15 | { 16 | namespace kernel 17 | { 18 | //! Applies the type change in region 19 | /*! 20 | * \param d_pos Particle position array 21 | * \param inside_type Type of particles inside region 22 | * \param outside_type Type of particles outside region 23 | * \param z_lo Lower bound of region in z 24 | * \param z_hi Upper bound of region in z 25 | * \param N Number of particles 26 | * 27 | * One thread per particle is used to flip particles between \a inside_type 28 | * and \a outside_type based on their position in the slab bounded in *z* between 29 | * \a z_lo and \a z_hi. 30 | */ 31 | __global__ void change_types_region(Scalar4* d_pos, 32 | unsigned int inside_type, 33 | unsigned int outside_type, 34 | Scalar z_lo, 35 | Scalar z_hi, 36 | unsigned int N) 37 | { 38 | const unsigned int idx = blockDim.x * blockIdx.x + threadIdx.x; 39 | if (idx >= N) 40 | return; 41 | 42 | const Scalar4 postype = d_pos[idx]; 43 | const Scalar3 pos = make_scalar3(postype.x, postype.y, postype.z); 44 | unsigned int type = __scalar_as_int(postype.w); 45 | 46 | // only check region if type is one that can be flipped 47 | if (type == inside_type || type == outside_type) 48 | { 49 | // test for overlap as for an AABB 50 | bool inside = !(pos.z > z_hi || pos.z < z_lo); 51 | if (inside) 52 | { 53 | type = inside_type; 54 | } 55 | else 56 | { 57 | type = outside_type; 58 | } 59 | } 60 | d_pos[idx] = make_scalar4(pos.x, pos.y, pos.z, __int_as_scalar(type)); 61 | } 62 | } // namespace kernel 63 | 64 | /*! 65 | * \param d_pos Particle position array 66 | * \param inside_type Type of particles inside region 67 | * \param outside_type Type of particles outside region 68 | * \param z_lo Lower bound of region in z 69 | * \param z_hi Upper bound of region in z 70 | * \param N Number of particles 71 | * \param block_size Number of threads per block 72 | */ 73 | cudaError_t change_types_region(Scalar4* d_pos, 74 | unsigned int inside_type, 75 | unsigned int outside_type, 76 | Scalar z_lo, 77 | Scalar z_hi, 78 | unsigned int N, 79 | unsigned int block_size) 80 | { 81 | if (N == 0) 82 | return cudaSuccess; 83 | 84 | static unsigned int max_block_size = UINT_MAX; 85 | if (max_block_size == UINT_MAX) 86 | { 87 | cudaFuncAttributes attr; 88 | cudaFuncGetAttributes(&attr, (const void*)kernel::change_types_region); 89 | max_block_size = attr.maxThreadsPerBlock; 90 | } 91 | 92 | const int run_block_size = min(block_size, max_block_size); 93 | kernel::change_types_region<<>>(d_pos, 94 | inside_type, 95 | outside_type, 96 | z_lo, 97 | z_hi, 98 | N); 99 | 100 | return cudaSuccess; 101 | } 102 | 103 | } // end namespace gpu 104 | } // end namespace azplugins 105 | -------------------------------------------------------------------------------- /src/TypeUpdaterGPU.cuh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file TypeUpdaterGPU.cuh 7 | * \brief Declaration of kernel drivers for TypeUpdaterGPU 8 | */ 9 | 10 | #ifndef AZPLUGINS_TYPE_UPDATER_GPU_CUH_ 11 | #define AZPLUGINS_TYPE_UPDATER_GPU_CUH_ 12 | 13 | #include "hoomd/HOOMDMath.h" 14 | #include 15 | 16 | namespace azplugins 17 | { 18 | namespace gpu 19 | { 20 | //! Kernel driver to change particle types in a region on the GPU 21 | cudaError_t change_types_region(Scalar4* d_pos, 22 | unsigned int inside_type, 23 | unsigned int outside_type, 24 | Scalar z_lo, 25 | Scalar z_hi, 26 | unsigned int N, 27 | unsigned int block_size); 28 | } // namespace gpu 29 | } // namespace azplugins 30 | 31 | #endif // AZPLUGINS_TYPE_UPDATER_GPU_CUH_ 32 | -------------------------------------------------------------------------------- /src/TypeUpdaterGPU.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file TypeUpdaterGPU.h 7 | * \brief Declaration of TypeUpdaterGPU 8 | */ 9 | 10 | #ifndef AZPLUGINS_TYPE_UPDATER_GPU_H_ 11 | #define AZPLUGINS_TYPE_UPDATER_GPU_H_ 12 | 13 | #ifdef NVCC 14 | #error This header cannot be compiled by nvcc 15 | #endif 16 | 17 | #include "TypeUpdater.h" 18 | #include "hoomd/Autotuner.h" 19 | 20 | namespace azplugins 21 | { 22 | 23 | //! Particle type updater on the GPU 24 | /*! 25 | * See TypeUpdater for details. This class inherits and minimally implements 26 | * the CPU methods from TypeUpdater on the GPU. 27 | */ 28 | class PYBIND11_EXPORT TypeUpdaterGPU : public TypeUpdater 29 | { 30 | public: 31 | //! Simple constructor 32 | TypeUpdaterGPU(std::shared_ptr sysdef); 33 | 34 | //! Constructor with parameters 35 | TypeUpdaterGPU(std::shared_ptr sysdef, 36 | unsigned int inside_type, 37 | unsigned int outside_type, 38 | Scalar z_lo, 39 | Scalar z_hi); 40 | 41 | //! Destructor 42 | virtual ~TypeUpdaterGPU() { }; 43 | 44 | //! Set autotuner parameters 45 | /*! 46 | * \param enable Enable / disable autotuning 47 | * \param period period (approximate) in time steps when retuning occurs 48 | */ 49 | virtual void setAutotunerParams(bool enable, unsigned int period) 50 | { 51 | TypeUpdater::setAutotunerParams(enable, period); 52 | m_tuner->setPeriod(period); 53 | m_tuner->setEnabled(enable); 54 | } 55 | 56 | protected: 57 | //! Changes the particle types according to an update rule on the GPU 58 | virtual void changeTypes(unsigned int timestep); 59 | 60 | private: 61 | std::unique_ptr m_tuner; //!< Tuner for changing types 62 | }; 63 | 64 | namespace detail 65 | { 66 | //! Export TypeUpdaterGPU to python 67 | void export_TypeUpdaterGPU(pybind11::module& m); 68 | } // end namespace detail 69 | 70 | } // end namespace azplugins 71 | 72 | #endif // AZPLUGINS_TYPE_UPDATER_GPU_H_ 73 | -------------------------------------------------------------------------------- /src/VariantSphereArea.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file VariantSphereArea.cc 7 | * \brief Defines a variant for a shrinking / growing sphere radius. 8 | */ 9 | 10 | #include "VariantSphereArea.h" 11 | 12 | namespace azplugins 13 | { 14 | /*! 15 | * \param R0 Initial radius. 16 | * \param alpha Rate of surface reduction (units are area per timestep). 17 | */ 18 | VariantSphereArea::VariantSphereArea(double R0, double alpha) 19 | { 20 | m_R0_sq = R0 * R0; 21 | m_k = alpha / (4. * M_PI); 22 | } 23 | 24 | /*! 25 | * \param timestep Current simulation timestep. 26 | * \returns Current radius of sphere. 27 | */ 28 | double VariantSphereArea::getValue(unsigned int timestep) 29 | { 30 | const double drsq = m_k * timestep; 31 | 32 | // droplet cannot shrink smaller than zero 33 | if (drsq >= m_R0_sq) 34 | { 35 | return 0.; 36 | } 37 | else 38 | { 39 | return slow::sqrt(m_R0_sq - drsq); 40 | } 41 | } 42 | 43 | namespace detail 44 | { 45 | /*! 46 | * \param m Python module to export to. 47 | */ 48 | void export_VariantSphereArea(pybind11::module& m) 49 | { 50 | namespace py = pybind11; 51 | py::class_>(m, 52 | "VariantSphereArea", 53 | py::base()) 54 | .def(py::init()); 55 | } 56 | 57 | } // end namespace detail 58 | } // end namespace azplugins 59 | -------------------------------------------------------------------------------- /src/VariantSphereArea.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file VariantSphereArea.h 7 | * \brief Declares a variant for a shrinking / growing sphere radius. 8 | */ 9 | 10 | #ifndef AZPLUGINS_VARIANT_SPHERE_AREA_H_ 11 | #define AZPLUGINS_VARIANT_SPHERE_AREA_H_ 12 | 13 | #ifdef NVCC 14 | #error This header cannot be compiled by nvcc 15 | #endif 16 | 17 | #include "hoomd/HOOMDMath.h" 18 | #include "hoomd/Variant.h" 19 | 20 | #include "hoomd/extern/pybind/include/pybind11/pybind11.h" 21 | 22 | namespace azplugins 23 | { 24 | //! Radius of sphere contracting with a constant rate of surface reduction. 25 | /*! 26 | * The radius of the sphere is reduced according to the following relationship: 27 | * 28 | * \f[ 29 | * R(t) = \sqrt{R(0)^2 - (\alpha/4\pi) t} 30 | * \f] 31 | * 32 | * where \f$\alpha\f$ is the rate of surface area reduction per time. 33 | * 34 | * To be physical, \f$R(t)\f$ is never negative; it is fixed to 0 if \f$t\f$ would make the 35 | * square-root argument negative. 36 | * 37 | * Setting \f$\alpha < 0\f$ will cause the sphere to expand. 38 | */ 39 | class PYBIND11_EXPORT VariantSphereArea : public Variant 40 | { 41 | public: 42 | //! Constructor 43 | VariantSphereArea(double R0, double alpha); 44 | 45 | //! Evaluate sphere radius 46 | virtual double getValue(unsigned int timestep); 47 | 48 | private: 49 | double m_R0_sq; //!< Initial radius (squared) 50 | double m_k; //!< Rate of change (includes 1/4pi prefactor) 51 | }; 52 | 53 | namespace detail 54 | { 55 | 56 | //! Export VariantSphereArea to python 57 | void export_VariantSphereArea(pybind11::module& m); 58 | 59 | } // end namespace detail 60 | } // end namespace azplugins 61 | 62 | #endif // AZPLUGINS_VARIANT_SPHERE_AREA_H_ 63 | -------------------------------------------------------------------------------- /src/VelocityCompute.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #include "VelocityCompute.h" 6 | #include "ParticleDataLoader.h" 7 | 8 | namespace hoomd 9 | { 10 | namespace azplugins 11 | { 12 | 13 | VelocityCompute::VelocityCompute(std::shared_ptr sysdef, 14 | std::shared_ptr group, 15 | bool include_mpcd_particles) 16 | : Compute(sysdef), m_group(group), m_include_mpcd_particles(include_mpcd_particles), 17 | m_velocity(make_scalar3(0, 0, 0)) 18 | { 19 | } 20 | 21 | VelocityCompute::~VelocityCompute() { } 22 | 23 | template 24 | void accumulateParticle(Scalar3& momentum, Scalar& mass, const LoadOpT& load_op, unsigned int idx) 25 | { 26 | Scalar3 v; 27 | Scalar m; 28 | load_op(v, m, idx); 29 | 30 | momentum += m * v; 31 | mass += m; 32 | } 33 | 34 | /*! 35 | * \param timestep Simulation timestep 36 | * 37 | * The center-of-mass velocity of the group is determined by first summing the 38 | * momentum and mass of all particles, then dividing momentum by mass. This 39 | * compute supports MPI decomposition, and the result is available on all ranks. 40 | */ 41 | void VelocityCompute::compute(uint64_t timestep) 42 | { 43 | if (!shouldCompute(timestep)) 44 | return; 45 | 46 | Scalar3 momentum = make_scalar3(0, 0, 0); 47 | Scalar mass(0); 48 | sumMomentumAndMass(momentum, mass); 49 | 50 | #ifdef ENABLE_MPI 51 | if (m_exec_conf->getNRanks() > 1) 52 | { 53 | Scalar buffer[4] = {momentum.x, momentum.y, momentum.z, mass}; 54 | MPI_Allreduce(MPI_IN_PLACE, 55 | &buffer[0], 56 | 4, 57 | MPI_HOOMD_SCALAR, 58 | MPI_SUM, 59 | m_exec_conf->getMPICommunicator()); 60 | momentum = make_scalar3(buffer[0], buffer[1], buffer[2]); 61 | mass = buffer[3]; 62 | } 63 | #endif // ENABLE_MPI 64 | 65 | // reduce total momentum by mass to get center-of-mass velocity 66 | if (mass > 0) 67 | { 68 | m_velocity = momentum / mass; 69 | } 70 | else 71 | { 72 | m_velocity = make_scalar3(0, 0, 0); 73 | } 74 | } 75 | 76 | void VelocityCompute::sumMomentumAndMass(Scalar3& momentum, Scalar& mass) 77 | { 78 | momentum = make_scalar3(0, 0, 0); 79 | mass = Scalar(0); 80 | 81 | if (m_group) 82 | { 83 | const unsigned int N = m_group->getNumMembers(); 84 | ArrayHandle h_index(m_group->getIndexArray(), 85 | access_location::host, 86 | access_mode::read); 87 | ArrayHandle h_vel(m_pdata->getVelocities(), 88 | access_location::host, 89 | access_mode::read); 90 | detail::LoadParticleGroupVelocityMass load_op(h_vel.data, h_index.data); 91 | 92 | for (unsigned int i = 0; i < N; ++i) 93 | { 94 | accumulateParticle(momentum, mass, load_op, i); 95 | } 96 | } 97 | 98 | #ifdef BUILD_MPCD 99 | if (m_include_mpcd_particles) 100 | { 101 | auto mpcd_pdata = m_sysdef->getMPCDParticleData(); 102 | const unsigned int N = mpcd_pdata->getN(); 103 | ArrayHandle h_vel(mpcd_pdata->getVelocities(), 104 | access_location::host, 105 | access_mode::read); 106 | detail::LoadMPCDParticleVelocityMass load_op(h_vel.data, mpcd_pdata->getMass()); 107 | 108 | for (unsigned int i = 0; i < N; ++i) 109 | { 110 | accumulateParticle(momentum, mass, load_op, i); 111 | } 112 | } 113 | #endif // BUILD_MPCD 114 | } 115 | 116 | namespace detail 117 | { 118 | void export_VelocityCompute(pybind11::module& m) 119 | { 120 | pybind11::class_>(m, 121 | "VelocityCompute") 122 | .def(pybind11:: 123 | init, std::shared_ptr, bool>()) 124 | .def_property_readonly("filter", 125 | [](const VelocityCompute& self) 126 | { 127 | auto group = self.getGroup(); 128 | return (group) ? group->getFilter() 129 | : std::shared_ptr(); 130 | }) 131 | .def_property_readonly("include_mpcd_particles", &VelocityCompute::includeMPCDParticles) 132 | .def_property_readonly("velocity", 133 | [](const VelocityCompute& self) 134 | { 135 | const auto v = self.getVelocity(); 136 | return pybind11::make_tuple(v.x, v.y, v.z); 137 | }); 138 | } 139 | } // end namespace detail 140 | } // end namespace azplugins 141 | } // end namespace hoomd 142 | -------------------------------------------------------------------------------- /src/VelocityCompute.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_VELOCITY_COMPUTE_H_ 6 | #define AZPLUGINS_VELOCITY_COMPUTE_H_ 7 | 8 | #ifdef __HIPCC__ 9 | #error This header cannot be compiled by nvcc 10 | #endif 11 | 12 | #include "hoomd/Compute.h" 13 | #include "hoomd/HOOMDMath.h" 14 | #include "hoomd/ParticleGroup.h" 15 | #include "hoomd/SystemDefinition.h" 16 | 17 | #include 18 | 19 | namespace hoomd 20 | { 21 | namespace azplugins 22 | { 23 | //! Compute the center-of-mass velocity of a group of particles 24 | class PYBIND11_EXPORT VelocityCompute : public Compute 25 | { 26 | public: 27 | //! Constructor 28 | VelocityCompute(std::shared_ptr sysdef, 29 | std::shared_ptr group, 30 | bool include_mpcd_particles); 31 | 32 | //! Destructor 33 | virtual ~VelocityCompute(); 34 | 35 | //! Compute center-of-mass velocity of group 36 | void compute(uint64_t timestep) override; 37 | 38 | //! Get particle group 39 | std::shared_ptr getGroup() const 40 | { 41 | return m_group; 42 | } 43 | 44 | bool includeMPCDParticles() const 45 | { 46 | return m_include_mpcd_particles; 47 | } 48 | 49 | //! Get most recently computed velocity 50 | Scalar3 getVelocity() const 51 | { 52 | return m_velocity; 53 | } 54 | 55 | protected: 56 | std::shared_ptr m_group; //!< Particle group 57 | bool m_include_mpcd_particles; //!< Whether to include MPCD particles 58 | Scalar3 m_velocity; //!< Last computed velocity 59 | 60 | virtual void sumMomentumAndMass(Scalar3& momentum, Scalar& mass); 61 | }; 62 | 63 | } // end namespace azplugins 64 | } // end namespace hoomd 65 | 66 | #endif // AZPLUGINS_VELOCITY_COMPUTE_H_ 67 | -------------------------------------------------------------------------------- /src/VelocityComputeGPU.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #include "VelocityComputeGPU.h" 6 | #include "VelocityComputeGPU.cuh" 7 | 8 | namespace hoomd 9 | { 10 | namespace azplugins 11 | { 12 | 13 | void VelocityComputeGPU::sumMomentumAndMass(Scalar3& momentum, Scalar& mass) 14 | { 15 | momentum = make_scalar3(0, 0, 0); 16 | mass = Scalar(0); 17 | 18 | if (m_group) 19 | { 20 | ArrayHandle d_index(m_group->getIndexArray(), 21 | access_location::device, 22 | access_mode::read); 23 | ArrayHandle d_vel(m_pdata->getVelocities(), 24 | access_location::device, 25 | access_mode::read); 26 | detail::LoadParticleGroupVelocityMass load_op(d_vel.data, d_index.data); 27 | 28 | Scalar3 group_momentum = make_scalar3(0, 0, 0); 29 | Scalar group_mass(0); 30 | gpu::sum_momentum_and_mass(group_momentum, group_mass, load_op, m_group->getNumMembers()); 31 | 32 | momentum += group_momentum; 33 | mass += group_mass; 34 | } 35 | 36 | #ifdef BUILD_MPCD 37 | if (m_include_mpcd_particles) 38 | { 39 | auto mpcd_pdata = m_sysdef->getMPCDParticleData(); 40 | ArrayHandle d_vel(mpcd_pdata->getVelocities(), 41 | access_location::device, 42 | access_mode::read); 43 | detail::LoadMPCDParticleVelocityMass load_op(d_vel.data, mpcd_pdata->getMass()); 44 | 45 | Scalar3 mpcd_momentum = make_scalar3(0, 0, 0); 46 | Scalar mpcd_mass(0); 47 | gpu::sum_momentum_and_mass(mpcd_momentum, mpcd_mass, load_op, mpcd_pdata->getN()); 48 | 49 | momentum += mpcd_momentum; 50 | mass += mpcd_mass; 51 | } 52 | #endif // BUILD_MPCD 53 | } 54 | 55 | namespace detail 56 | { 57 | void export_VelocityComputeGPU(pybind11::module& m) 58 | { 59 | pybind11::class_>( 60 | m, 61 | "VelocityComputeGPU") 62 | .def(pybind11:: 63 | init, std::shared_ptr, bool>()); 64 | } 65 | } // end namespace detail 66 | 67 | } // end namespace azplugins 68 | } // end namespace hoomd 69 | -------------------------------------------------------------------------------- /src/VelocityComputeGPU.cu: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #include "VelocityComputeGPU.cuh" 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | namespace hoomd 13 | { 14 | namespace azplugins 15 | { 16 | namespace gpu 17 | { 18 | 19 | //! Transform to go from an index to a momentum+mass Scalar4 using a particle data loader 20 | template class MomentumMassTransform 21 | { 22 | public: 23 | __host__ __device__ MomentumMassTransform(const LoadOpT& load_op) : m_load_op(load_op) { } 24 | 25 | __host__ __device__ Scalar4 operator()(unsigned int idx) const 26 | { 27 | Scalar3 v; 28 | Scalar m; 29 | m_load_op(v, m, idx); 30 | 31 | return make_scalar4(m * v.x, m * v.y, m * v.z, m); 32 | } 33 | 34 | private: 35 | const LoadOpT m_load_op; 36 | }; 37 | 38 | //! Summation for Scalar4s 39 | struct AddScalar4 40 | { 41 | __host__ __device__ Scalar4 operator()(const Scalar4& a, const Scalar4& b) const 42 | { 43 | return make_scalar4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); 44 | } 45 | }; 46 | 47 | //! Thrust implementation of summation for different particle data loaders 48 | template 49 | void thrust_sum_momentum_and_mass(Scalar3& momentum, 50 | Scalar& mass, 51 | const LoadOpT& load_op, 52 | unsigned int N) 53 | { 54 | thrust::transform_iterator momentum_mass_iterator(thrust::counting_iterator(0), 55 | MomentumMassTransform(load_op)); 56 | 57 | const Scalar4 momentum_mass = thrust::reduce(thrust::device, 58 | momentum_mass_iterator, 59 | momentum_mass_iterator + N, 60 | make_scalar4(0, 0, 0, 0), 61 | AddScalar4()); 62 | 63 | momentum = make_scalar3(momentum_mass.x, momentum_mass.y, momentum_mass.z); 64 | mass = momentum_mass.w; 65 | } 66 | 67 | void sum_momentum_and_mass(Scalar3& momentum, 68 | Scalar& mass, 69 | const detail::LoadParticleGroupVelocityMass& load_op, 70 | unsigned int N) 71 | { 72 | thrust_sum_momentum_and_mass(momentum, mass, load_op, N); 73 | } 74 | 75 | void sum_momentum_and_mass(Scalar3& momentum, 76 | Scalar& mass, 77 | const detail::LoadMPCDParticleVelocityMass& load_op, 78 | unsigned int N) 79 | { 80 | thrust_sum_momentum_and_mass(momentum, mass, load_op, N); 81 | } 82 | 83 | } // end namespace gpu 84 | } // end namespace azplugins 85 | } // end namespace hoomd 86 | -------------------------------------------------------------------------------- /src/VelocityComputeGPU.cuh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_VELOCITY_COMPUTE_GPU_CUH_ 6 | #define AZPLUGINS_VELOCITY_COMPUTE_GPU_CUH_ 7 | 8 | #include 9 | 10 | #include "ParticleDataLoader.h" 11 | 12 | #include "hoomd/HOOMDMath.h" 13 | 14 | namespace hoomd 15 | { 16 | namespace azplugins 17 | { 18 | namespace gpu 19 | { 20 | 21 | //! Specialization to HOOMD group 22 | void sum_momentum_and_mass(Scalar3& momentum, 23 | Scalar& mass, 24 | const detail::LoadParticleGroupVelocityMass& load_op, 25 | unsigned int N); 26 | 27 | //! Specialization to MPCD group 28 | void sum_momentum_and_mass(Scalar3& momentum, 29 | Scalar& mass, 30 | const detail::LoadMPCDParticleVelocityMass& load_op, 31 | unsigned int N); 32 | 33 | } // end namespace gpu 34 | } // namespace azplugins 35 | } // end namespace hoomd 36 | 37 | #endif // AZPLUGINS_VELOCITY_COMPUTE_GPU_CUH_ 38 | -------------------------------------------------------------------------------- /src/VelocityComputeGPU.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_VELOCITY_COMPUTE_GPU_H_ 6 | #define AZPLUGINS_VELOCITY_COMPUTE_GPU_H_ 7 | 8 | #ifdef __HIPCC__ 9 | #error This header cannot be compiled by nvcc 10 | #endif 11 | 12 | #include "VelocityCompute.h" 13 | 14 | namespace hoomd 15 | { 16 | namespace azplugins 17 | { 18 | //! Compute the center-of-mass velocity of a group of particles on the GPU 19 | class PYBIND11_EXPORT VelocityComputeGPU : public VelocityCompute 20 | { 21 | public: 22 | using VelocityCompute::VelocityCompute; 23 | 24 | protected: 25 | void sumMomentumAndMass(Scalar3& momentum, Scalar& mass) override; 26 | }; 27 | } // end namespace azplugins 28 | } // end namespace hoomd 29 | 30 | #endif // AZPLUGINS_VELOCITY_COMPUTE_GPU_H_ 31 | -------------------------------------------------------------------------------- /src/VelocityFieldComputeGPU.cu: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #include "VelocityFieldComputeGPU.cuh" 6 | 7 | namespace hoomd 8 | { 9 | namespace azplugins 10 | { 11 | namespace gpu 12 | { 13 | 14 | cudaError_t zeroVelocityFieldArrays(Scalar* d_mass, Scalar3* d_momentum, size_t num_bins) 15 | { 16 | cudaError_t result = cudaMemset(d_mass, 0, sizeof(Scalar) * num_bins); 17 | if (result != cudaSuccess) 18 | { 19 | return result; 20 | } 21 | 22 | result = cudaMemset(d_momentum, 0, sizeof(Scalar3) * num_bins); 23 | if (result != cudaSuccess) 24 | { 25 | return result; 26 | } 27 | 28 | return cudaSuccess; 29 | } 30 | 31 | } // end namespace gpu 32 | } // end namespace azplugins 33 | } // end namespace hoomd 34 | -------------------------------------------------------------------------------- /src/VelocityFieldComputeGPU.cuh: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #ifndef AZPLUGINS_VELOCITY_FIELD_COMPUTE_GPU_CUH_ 6 | #define AZPLUGINS_VELOCITY_FIELD_COMPUTE_GPU_CUH_ 7 | 8 | #include 9 | 10 | #include "hoomd/BoxDim.h" 11 | #include "hoomd/HOOMDMath.h" 12 | 13 | namespace hoomd 14 | { 15 | namespace azplugins 16 | { 17 | namespace gpu 18 | { 19 | 20 | cudaError_t zeroVelocityFieldArrays(Scalar* d_mass, Scalar3* d_momentum, size_t num_bins); 21 | 22 | template 23 | cudaError_t bin_velocity_field(Scalar* d_mass, 24 | Scalar3* d_momentum, 25 | const LoadOpT& load_op, 26 | const BinOpT& bin_op, 27 | const BoxDim& global_box, 28 | const unsigned int N, 29 | const unsigned int block_size); 30 | 31 | #ifdef __HIPCC__ 32 | namespace kernel 33 | { 34 | template 35 | __global__ void bin_velocity_field(Scalar* d_mass, 36 | Scalar3* d_momentum, 37 | const LoadOpT load_op, 38 | const BinOpT bin_op, 39 | const BoxDim global_box, 40 | const unsigned int N) 41 | { 42 | // one thread per particle 43 | const unsigned int idx = blockIdx.x * blockDim.x + threadIdx.x; 44 | if (idx >= N) 45 | return; 46 | 47 | Scalar3 position, momentum; 48 | Scalar mass; 49 | load_op(position, momentum, mass, idx); 50 | momentum *= mass; 51 | 52 | // ensure particle is inside global box 53 | int3 img; 54 | global_box.wrap(position, img); 55 | 56 | uint3 bin = make_uint3(0, 0, 0); 57 | Scalar3 transformed_momentum = make_scalar3(0, 0, 0); 58 | const bool binned = bin_op.bin(bin, transformed_momentum, position, momentum); 59 | if (!binned) 60 | { 61 | return; 62 | } 63 | const auto bin_idx = bin_op.ravelBin(bin); 64 | 65 | atomicAdd(d_mass + bin_idx, mass); 66 | 67 | Scalar3* bin_momentum = d_momentum + bin_idx; 68 | atomicAdd(&(*bin_momentum).x, transformed_momentum.x); 69 | atomicAdd(&(*bin_momentum).y, transformed_momentum.y); 70 | atomicAdd(&(*bin_momentum).z, transformed_momentum.z); 71 | } 72 | 73 | } // namespace kernel 74 | 75 | template 76 | cudaError_t bin_velocity_field(Scalar* d_mass, 77 | Scalar3* d_momentum, 78 | const LoadOpT& load_op, 79 | const BinOpT& bin_op, 80 | const BoxDim& global_box, 81 | const unsigned int N, 82 | const unsigned int block_size) 83 | { 84 | unsigned int max_block_size; 85 | cudaFuncAttributes attr; 86 | cudaFuncGetAttributes(&attr, (const void*)kernel::bin_velocity_field); 87 | max_block_size = attr.maxThreadsPerBlock; 88 | 89 | unsigned int run_block_size = min(block_size, max_block_size); 90 | dim3 grid(N / run_block_size + 1); 91 | 92 | kernel::bin_velocity_field<<>>(d_mass, 93 | d_momentum, 94 | load_op, 95 | bin_op, 96 | global_box, 97 | N); 98 | 99 | return cudaSuccess; 100 | } 101 | #endif // __HIPCC__ 102 | 103 | } // end namespace gpu 104 | } // namespace azplugins 105 | } // end namespace hoomd 106 | #endif // AZPLUGINS_VELOCITY_FIELD_COMPUTE_GPU_H_ 107 | -------------------------------------------------------------------------------- /src/VelocityFieldComputeGPUKernel.cu.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "ParticleDataLoader.h" 10 | #include "VelocityFieldComputeGPU.cuh" 11 | #include "@_geometry@BinningOperation.h" 12 | 13 | #define BINNING_OPERATION @_geometry@BinningOperation 14 | // clang-format on 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | namespace gpu 21 | { 22 | 23 | template __attribute__((visibility("default"))) cudaError_t 24 | bin_velocity_field( 25 | Scalar* d_mass, 26 | Scalar3* d_momentum, 27 | const detail::LoadParticleGroupPositionVelocityMass& load_op, 28 | const BINNING_OPERATION& bin_op, 29 | const BoxDim& global_box, 30 | const unsigned int N, 31 | const unsigned int block_size); 32 | 33 | template __attribute__((visibility("default"))) cudaError_t 34 | bin_velocity_field( 35 | Scalar* d_mass, 36 | Scalar3* d_momentum, 37 | const detail::LoadMPCDParticlePositionVelocityMass& load_op, 38 | const BINNING_OPERATION& bin_op, 39 | const BoxDim& global_box, 40 | const unsigned int N, 41 | const unsigned int block_size); 42 | 43 | } // end namespace gpu 44 | } // namespace azplugins 45 | } // end namespace hoomd 46 | -------------------------------------------------------------------------------- /src/WallEvaluatorLJ93.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file WallEvaluatorLJ93.h 7 | * \brief Defines the wall potential evaluator class for the LJ 9-3 potential 8 | */ 9 | 10 | #ifndef AZPLUGINS_WALL_EVALUATOR_LJ_93_H_ 11 | #define AZPLUGINS_WALL_EVALUATOR_LJ_93_H_ 12 | 13 | #ifndef NVCC 14 | #include 15 | #endif 16 | 17 | #include "hoomd/HOOMDMath.h" 18 | 19 | #ifdef NVCC 20 | #define DEVICE __device__ 21 | #else 22 | #define DEVICE 23 | #endif 24 | 25 | namespace azplugins 26 | { 27 | namespace detail 28 | { 29 | //! Evaluates the Lennard-Jones 9-3 wall force 30 | /*! 31 | * WallEvaluatorLJ93 computes the Lennard-Jones 9-3 wall potential, which is derived from 32 | * integrating the standard Lennard-Jones potential between a point particle and a half plane: 33 | * 34 | * \f[ V(r) = \varepsilon \left( \frac{2}{15}\left(\frac{\sigma}{r}\right)^9 - 35 | * \left(\frac{\sigma}{r}\right)^3 \right) \f] 36 | * 37 | * where \f$\sigma\f$ is the diameter of Lennard-Jones particles in the wall, and \f$ \varepsilon 38 | * \f$ is the effective Hamaker constant \f$ \varepsilon = (2/3) \pi \varepsilon_{\rm LJ} \rho_{\rm 39 | * w} \sigma^3 \f$ with \f$\varepsilon_{\rm LJ}\f$ the energy of interaction and \f$\rho_{\rm w}\f$ 40 | * the density of particles in the wall. Evaluation of this energy is simplified into the following 41 | * parameters: 42 | * 43 | * - \verbatim lj1 = (2.0/15.0) * epsilon * pow(sigma,9.0) \endverbatim 44 | * - \verbatim lj2 = epsilon * pow(sigma,3.0) \endverbatim 45 | * 46 | * The force acting on the particle is then 47 | * \f[ F(r)/r = \frac{\varepsilon}{r^2} \left ( \frac{6}{5}\left(\frac{\sigma}{r}\right)^9 - 3 48 | * \left(\frac{\sigma}{r}\right)^3 \right) \f] 49 | */ 50 | class WallEvaluatorLJ93 51 | { 52 | public: 53 | //! Define the parameter type used by this wall potential evaluator 54 | typedef Scalar2 param_type; 55 | 56 | //! Constructor 57 | /*! 58 | * \param _rsq Squared distance between particles 59 | * \param _rcutsq Cutoff radius squared 60 | * \param _params Pair potential parameters, given by typedef above 61 | * 62 | * The functor initializes its members from \a _params. 63 | */ 64 | DEVICE WallEvaluatorLJ93(Scalar _rsq, Scalar _rcutsq, const param_type& _params) 65 | : rsq(_rsq), rcutsq(_rcutsq), lj1(_params.x), lj2(_params.y) 66 | { 67 | } 68 | 69 | //! LJ 9-3 doesn't use diameter 70 | DEVICE static bool needsDiameter() 71 | { 72 | return false; 73 | } 74 | //! Accept the optional diameter values 75 | /*! 76 | * \param di Diameter of particle 77 | * \param dj Dummy diameter 78 | * 79 | * \note The way HOOMD computes wall forces by recycling evaluators requires that we give 80 | * a second diameter, even though this is meaningless for the potential. 81 | */ 82 | DEVICE void setDiameter(Scalar di, Scalar dj) { } 83 | 84 | //! LJ 9-3 doesn't use charge 85 | DEVICE static bool needsCharge() 86 | { 87 | return false; 88 | } 89 | //! Accept the optional charge values 90 | /*! 91 | * \param qi Charge of particle 92 | * \param qj Dummy charge 93 | * 94 | * \note The way HOOMD computes wall forces by recycling evaluators requires that we give 95 | * a second charge, even though this is meaningless for the potential. 96 | */ 97 | DEVICE void setCharge(Scalar qi, Scalar qj) { } 98 | 99 | //! Evaluate the force and energy 100 | /*! 101 | * \param force_divr Holds the computed force divided by r 102 | * \param energy Holds the computed pair energy 103 | * \param energy_shift If true, the potential is shifted to zero at the cutoff 104 | * 105 | * \returns True if the energy calculation occurs 106 | * 107 | * The calculation does not occur if the pair distance is greater than the cutoff 108 | * or if the potential is scaled to zero. 109 | */ 110 | DEVICE bool evalForceAndEnergy(Scalar& force_divr, Scalar& energy, bool energy_shift) 111 | { 112 | if (rsq < rcutsq && lj1 != 0) 113 | { 114 | Scalar r2inv = Scalar(1.0) / rsq; 115 | Scalar r3inv 116 | = r2inv 117 | * sqrt( 118 | r2inv); // we need to have the odd power to get the energy, so must take sqrt 119 | Scalar r6inv = r3inv * r3inv; 120 | 121 | force_divr = r2inv * r3inv * (Scalar(9.0) * lj1 * r6inv - Scalar(3.0) * lj2); 122 | energy = r3inv * (lj1 * r6inv - lj2); 123 | 124 | if (energy_shift) 125 | { 126 | // this could be cached once per type as a parameter to save flops and a sqrt 127 | Scalar rcut2inv = Scalar(1.0) / rcutsq; 128 | Scalar rcut3inv = rcut2inv * sqrt(rcut2inv); 129 | Scalar rcut6inv = rcut3inv * rcut3inv; 130 | energy -= rcut3inv * (lj1 * rcut6inv - lj2); 131 | } 132 | return true; 133 | } 134 | else 135 | return false; 136 | } 137 | 138 | #ifndef NVCC 139 | //! Return the name of this potential 140 | static std::string getName() 141 | { 142 | return std::string("lj93"); 143 | } 144 | #endif 145 | 146 | protected: 147 | Scalar rsq; //!< Stored rsq from the constructor 148 | Scalar rcutsq; //!< Stored rcutsq from the constructor 149 | Scalar lj1; //!< lj1 parameter extracted from the params passed to the constructor 150 | Scalar lj2; //!< lj2 parameter extracted from the params passed to the constructor 151 | }; 152 | } // end namespace detail 153 | } // end namespace azplugins 154 | 155 | #undef DEVICE 156 | #endif // AZPLUGINS_WALL_EVALUATOR_LJ_93_H_ 157 | -------------------------------------------------------------------------------- /src/WallPotentials.cu: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file WallPotentials.cu 7 | * \brief Defines the driver functions for computing wall forces on the GPU 8 | * 9 | * The driver function must have an explicit template instantiation for each 10 | * evaluator. The template must be in the global namespace that is used by hoomd. 11 | */ 12 | 13 | #include "WallPotentials.h" 14 | #include "hoomd/md/EvaluatorWalls.h" 15 | #include "hoomd/md/PotentialExternalGPU.cuh" 16 | 17 | //! Evaluator for colloid (integrated Lennard-Jones) wall potential 18 | template cudaError_t gpu_cpef>( 19 | const external_potential_args_t& external_potential_args, 20 | const typename EvaluatorWalls::param_type* d_params, 21 | const typename EvaluatorWalls::field_type* d_field); 22 | 23 | //! Evaluator for Lennard-Jones 9-3 wall potential 24 | template cudaError_t gpu_cpef>( 25 | const external_potential_args_t& external_potential_args, 26 | const typename EvaluatorWalls::param_type* d_params, 27 | const typename EvaluatorWalls::field_type* d_field); 28 | -------------------------------------------------------------------------------- /src/WallPotentials.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | /*! 6 | * \file WallPotentials.h 7 | * \brief Convenience inclusion of all wall potential evaluators. 8 | * 9 | * In HOOMD-blue, wall potentials are templated on a base class ForceCompute called 10 | * PotentialExternal (via a templated EvaluatorWall functor). This avoids code duplication of basic 11 | * routines. 12 | * 13 | * To add a new wall potential, take the following steps: 14 | * 1. Create an evaluator functor for your potential, for example WallEvaluatorMyGreatPotential.h. 15 | * This file should be added to the list of includes below. You can follow one of the other 16 | * evaluator functors as an example for the details. 17 | * 18 | * 2. Explicitly instantiate a template for a CUDA driver for your potential in WallPotentials.cu. 19 | * 20 | * 3. Expose the wall potential on the python level in module.cc with export_wall_potential and add 21 | * the mirror python object to wall.py. 22 | * 23 | * 4. Write a unit test for the potential in test-py. Two types of tests should be conducted: one 24 | * that checks that all methods work on the python object, and one that validates the force and 25 | * energy for the particle at a fixed distance from the wall. 26 | */ 27 | 28 | #ifndef AZPLUGINS_WALL_POTENTIALS_H_ 29 | #define AZPLUGINS_WALL_POTENTIALS_H_ 30 | 31 | // All wall potential evaluators should be included here 32 | #include "WallEvaluatorColloid.h" 33 | #include "WallEvaluatorLJ93.h" 34 | 35 | /* 36 | * The code below handles python exports using a templated function, and so should 37 | * not be compiled in NVCC. 38 | */ 39 | #ifndef NVCC 40 | #include "hoomd/extern/pybind/include/pybind11/pybind11.h" 41 | 42 | #include "hoomd/md/EvaluatorWalls.h" 43 | #include "hoomd/md/PotentialExternal.h" 44 | #ifdef ENABLE_CUDA 45 | #include "hoomd/md/PotentialExternalGPU.h" 46 | #endif 47 | 48 | namespace azplugins 49 | { 50 | namespace detail 51 | { 52 | //! Convenience function to export wall potential to python 53 | /*! 54 | * \param m Python module 55 | * \param name Name of CPU class 56 | * \tparam evaluator Wall potential evaluator functor 57 | * 58 | * A CPU object called \a name is exported to python, along with an 59 | * object for the wall parameters (name_params) and convenience method 60 | * for creating the parameters (make_name_params()). If CUDA is enabled, 61 | * a corresponding GPU class called nameGPU is exported. 62 | */ 63 | template void export_wall_potential(pybind11::module& m, const std::string& name) 64 | { 65 | namespace py = pybind11; 66 | typedef ::EvaluatorWalls wall_evaluator; 67 | typedef ::PotentialExternal wall_potential_cpu; 68 | export_PotentialExternal(m, name); 69 | 70 | #ifdef ENABLE_CUDA 71 | typedef ::PotentialExternalGPU wall_potential_gpu; 72 | export_PotentialExternalGPU(m, name + "GPU"); 73 | #endif // ENABLE_CUDA 74 | 75 | py::class_>( 77 | m, 78 | (wall_evaluator::getName() + "_params").c_str()) 79 | .def(py::init<>()) 80 | .def_readwrite("params", &wall_evaluator::param_type::params) 81 | .def_readwrite("rextrap", &wall_evaluator::param_type::rextrap) 82 | .def_readwrite("rcutsq", &wall_evaluator::param_type::rcutsq); 83 | m.def(std::string("make_" + wall_evaluator::getName() + "_params").c_str(), 84 | &make_wall_params); 85 | } 86 | 87 | } // end namespace detail 88 | } // end namespace azplugins 89 | #endif // NVCC 90 | 91 | #endif // AZPLUGINS_WALL_POTENTIALS_H_ 92 | -------------------------------------------------------------------------------- /src/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """azplugins.""" 6 | 7 | from hoomd.azplugins import bond, compute, external, flow, pair 8 | 9 | __version__ = "1.1.0" 10 | -------------------------------------------------------------------------------- /src/bond.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """Bond potentials.""" 6 | 7 | from hoomd.azplugins import _azplugins 8 | from hoomd.data.parameterdicts import TypeParameterDict 9 | from hoomd.data.typeparam import TypeParameter 10 | from hoomd.md import bond 11 | 12 | 13 | class DoubleWell(bond.Bond): 14 | r"""Double-well bond potential. 15 | 16 | `DoubleWell` specifies a double well potential between the two particles in 17 | the simulation state with: 18 | 19 | .. math:: 20 | 21 | U(r) &= U_1 \left[1 - \left(\frac{r_1-r}{r_1-r_0}\right)^2 \right]^2 \\ 22 | &+ U_{\rm{tilt}}\left(1 - \frac{r_1-r}{r_1-r_0} 23 | -\left[1 - \left(\frac{r_1-r}{r_1-r_0}\right)^2 \right]^2 \right) 24 | 25 | Attributes: 26 | params (TypeParameter[``bond type``, dict]): 27 | The parameter of the double-well bonds for each particle type. 28 | The dictionary has the following keys: 29 | 30 | * ``r_0`` (`float`, **required**) - Location of the first potential 31 | minimum :math:`r_0` when :math:`U_{\rm tilt} = 0` 32 | :math:`[\mathrm{length}]` 33 | 34 | * ``r_1`` (`float`, **required**) - Location of the potential local 35 | maximum :math:`r_1` when :math:`U_{\rm tilt} = 0` 36 | :math:`[\mathrm{length}]` 37 | 38 | * ``U_1`` (`float`, **required**) - Potential energy 39 | :math:`U_1 = U(r_1)` 40 | :math:`[\mathrm{energy}]` 41 | 42 | * ``U_tilt`` (`float`, **required**) - Tunes the energy offset 43 | :math:`U_{\rm tilt}` between the two potential minima values, 44 | i.e. it tilts the potential :math:`[\mathrm{energy}]` 45 | 46 | Examples:: 47 | 48 | dw = azplugins.bond.DoubleWell() 49 | dw.params['A-A'] = dict(r_0=0.5, r_1=2.5, U_1=5.0, U_tilt=0.0) 50 | dw.params['A-A'] = dict(r_0=1.0, r_1=2.0, U_1=1.0, U_tilt=0.5) 51 | """ 52 | 53 | _ext_module = _azplugins 54 | _cpp_class_name = "PotentialBondDoubleWell" 55 | 56 | def __init__(self): 57 | super().__init__() 58 | params = TypeParameter( 59 | "params", 60 | "bond_types", 61 | TypeParameterDict( 62 | r_0=float, r_1=float, U_1=float, U_tilt=float, len_keys=1 63 | ), 64 | ) 65 | self._add_typeparam(params) 66 | 67 | 68 | class Quartic(bond.Bond): 69 | r"""Quartic bond potential. 70 | 71 | `Quartic` specifies a quartic potential between the two particles in 72 | the simulation state with: 73 | 74 | .. math:: 75 | 76 | U(r) &= k (r - \Delta - r_0 - b_1)(r - \Delta - r_0 - b_2) 77 | (r - \Delta -r_0)^2 & \\ 78 | &+ U_0 + U_{\rm WCA}(r), & r < r_0 + \Delta \\ 79 | &= U_0 + U_{\rm WCA}(r), & r \ge r_0 + \Delta 80 | 81 | where :math:`r` is the distance from one particle to the other in the 82 | bond. The potential :math:`U_{\rm WCA}(r)` is given by: 83 | 84 | .. math:: 85 | 86 | U_{\rm WCA}(r) &= 4 \varepsilon \left[ 87 | \left( \frac{\sigma}{r-\Delta} \right)^{12} 88 | - \left( \frac{\sigma}{r-\Delta} \right)^{6} 89 | \right] + \varepsilon, & r < 2^{1/6}\sigma + \Delta \\ 90 | &= 0, & r \ge 2^{1/6}\sigma + \Delta 91 | 92 | 93 | Attributes: 94 | params (TypeParameter[``bond type``, dict]): 95 | The parameters of the quartic bonds for each particle type. 96 | The dictionary has the following keys: 97 | 98 | * ``k`` (`float`, **required**) - quartic attractive force strength 99 | :math:`[\mathrm{energy}/\mathrm{length}^4]`. 100 | 101 | * ``r_0`` (`float`, **required**) - Location of the quartic potential 102 | cutoff :math:`r_0`. Intended to be larger than the WCA cutoff, 103 | :math:`2^{1/6}\sigma`. When true, 104 | :math:`U(r_0) = U_{0} + U_{\rm WCA}(r_0)` 105 | :math:`[\mathrm{length}]`. 106 | 107 | * ``b_1`` (`float`, **required**) - First quartic potential fitting 108 | parameter :math:`b_1` :math:`[\mathrm{length}]`. 109 | 110 | * ``b_2`` (`float`, **required**) - Second quartic potential fitting 111 | parameter :math:`b_2` :math:`[\mathrm{length}]`. 112 | 113 | * ``U_0`` (`float`, **required**) - Quartic potential energy barrier height 114 | :math:`U_0` at :math:`r_0` when :math:`r_0 > 2^{1/6}\sigma` 115 | :math:`[\mathrm{energy}]`. 116 | 117 | * ``epsilon`` (`float`, **required**) - Repulsive WCA interaction energy 118 | :math:`\varepsilon` :math:`[\mathrm{energy}]`. 119 | 120 | * ``sigma`` (`float`, **required**) - Repulsive WCA interaction size 121 | :math:`\sigma` :math:`[\mathrm{length}]`. 122 | 123 | * ``delta`` (`float`, **optional**) - Shift :math:`\Delta`, 124 | defaults to zero :math:`[\mathrm{length}]`. 125 | 126 | .. rubric:: Examples: 127 | 128 | `Tsige and Stevens `_ bond potential. 129 | 130 | .. code-block:: python 131 | 132 | quartic = hoomd.azplugins.bond.Quartic() 133 | quartic.params['A-A'] = dict(k=1434.3, r_0=1.5, b_1=-0.7589, b_2=0.0, 134 | U_0=67.2234, sigma=1, epsilon=1, delta=0.0) 135 | """ 136 | 137 | _ext_module = _azplugins 138 | _cpp_class_name = "PotentialBondQuartic" 139 | 140 | def __init__(self): 141 | super().__init__() 142 | params = TypeParameter( 143 | "params", 144 | "bond_types", 145 | TypeParameterDict( 146 | k=float, 147 | r_0=float, 148 | b_1=float, 149 | b_2=float, 150 | U_0=float, 151 | sigma=float, 152 | epsilon=float, 153 | delta=0.0, 154 | len_keys=1, 155 | ), 156 | ) 157 | self._add_typeparam(params) 158 | -------------------------------------------------------------------------------- /src/conftest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """pytest configuration for azplugins.""" 6 | 7 | import pytest 8 | 9 | 10 | @pytest.fixture(scope="session") 11 | def bonded_two_particle_snapshot_factory(two_particle_snapshot_factory): 12 | """Fixture for a single bond.""" 13 | 14 | def make_snapshot(bond_types=None, **kwargs): 15 | if bond_types is None: 16 | bond_types = ["A-A"] 17 | snap = two_particle_snapshot_factory(**kwargs) 18 | if snap.communicator.rank == 0: 19 | snap.bonds.types = bond_types 20 | snap.bonds.N = 1 21 | snap.bonds.group[0] = [0, 1] 22 | return snap 23 | 24 | return make_snapshot 25 | -------------------------------------------------------------------------------- /src/export_AnisoPotentialPair.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "hoomd/md/AnisoPotentialPair.h" 10 | #include "AnisoPairEvaluator@_evaluator@.h" 11 | 12 | #define EVALUATOR_CLASS AnisoPairEvaluator@_evaluator@ 13 | #define EXPORT_FUNCTION export_AnisoPotentialPair@_evaluator@ 14 | // clang-format on 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | namespace detail 21 | { 22 | void EXPORT_FUNCTION(pybind11::module& m) 23 | { 24 | hoomd::md::detail::export_AnisoPotentialPair(m, 25 | "AnisoPotentialPair@_evaluator@"); 26 | } 27 | } // end namespace detail 28 | } // end namespace azplugins 29 | } // end namespace hoomd 30 | -------------------------------------------------------------------------------- /src/export_AnisoPotentialPairGPU.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "hoomd/md/AnisoPotentialPairGPU.h" 10 | #include "AnisoPairEvaluator@_evaluator@.h" 11 | 12 | #define EVALUATOR_CLASS AnisoPairEvaluator@_evaluator@ 13 | #define EXPORT_FUNCTION export_AnisoPotentialPair@_evaluator@GPU 14 | // clang-format on 15 | 16 | namespace hoomd 17 | { 18 | 19 | // Use CPU class from another compilation unit to reduce compile time and compiler memory usage. 20 | extern template class md::AnisoPotentialPair; 21 | 22 | namespace azplugins 23 | { 24 | namespace detail 25 | { 26 | void EXPORT_FUNCTION(pybind11::module& m) 27 | { 28 | hoomd::md::detail::export_AnisoPotentialPairGPU( 29 | m, 30 | "AnisoPotentialPair@_evaluator@GPU"); 31 | } 32 | } // end namespace detail 33 | } // end namespace azplugins 34 | } // end namespace hoomd 35 | -------------------------------------------------------------------------------- /src/export_HarmonicBarrier.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "HarmonicBarrier.h" 10 | #include "@_geometry@BarrierEvaluator.h" 11 | 12 | #define BARRIER_EVALUATOR @_geometry@BarrierEvaluator 13 | #define EXPORT_FUNCTION export_@_geometry@HarmonicBarrier 14 | // clang-format on 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | 21 | template class HarmonicBarrier; 22 | 23 | namespace detail 24 | { 25 | void EXPORT_FUNCTION(pybind11::module& m) 26 | { 27 | export_HarmonicBarrier(m, "@_geometry@HarmonicBarrier"); 28 | } 29 | } // end namespace detail 30 | 31 | } // end namespace azplugins 32 | } // end namespace hoomd 33 | -------------------------------------------------------------------------------- /src/export_HarmonicBarrierGPU.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "HarmonicBarrierGPU.h" 10 | #include "@_geometry@BarrierEvaluator.h" 11 | 12 | #define BARRIER_EVALUATOR @_geometry@BarrierEvaluator 13 | #define EXPORT_FUNCTION export_@_geometry@HarmonicBarrierGPU 14 | // clang-format on 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | 21 | template class HarmonicBarrierGPU; 22 | 23 | namespace detail 24 | { 25 | void EXPORT_FUNCTION(pybind11::module& m) 26 | { 27 | export_HarmonicBarrierGPU(m, "@_geometry@HarmonicBarrierGPU"); 28 | } 29 | } // end namespace detail 30 | 31 | } // end namespace azplugins 32 | } // end namespace hoomd 33 | -------------------------------------------------------------------------------- /src/export_PotentialBond.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // Adapted from hoomd/md/export_PotentialBond.cc.inc of HOOMD-blue. 6 | // Copyright (c) 2009-2024 The Regents of the University of Michigan. 7 | // Part of HOOMD-blue, released under the BSD 3-Clause License. 8 | 9 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 10 | // configure_file(). 11 | 12 | // clang-format off 13 | #include "hoomd/md/PotentialBond.h" 14 | #include "BondEvaluator@_evaluator@.h" 15 | 16 | #define EVALUATOR_CLASS BondEvaluator@_evaluator@ 17 | #define EXPORT_FUNCTION export_PotentialBond@_evaluator@ 18 | // clang-format on 19 | 20 | namespace hoomd 21 | { 22 | namespace azplugins 23 | { 24 | namespace detail 25 | { 26 | 27 | void EXPORT_FUNCTION(pybind11::module& m) 28 | { 29 | hoomd::md::detail::export_PotentialBond(m, "PotentialBond@_evaluator@"); 30 | } 31 | 32 | } // end namespace detail 33 | } // end namespace azplugins 34 | } // end namespace hoomd 35 | -------------------------------------------------------------------------------- /src/export_PotentialBondGPU.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // Adapted from hoomd/md/export_PotentialBondGPU.cc.inc of HOOMD-blue. 6 | // Copyright (c) 2009-2024 The Regents of the University of Michigan. 7 | // Part of HOOMD-blue, released under the BSD 3-Clause License. 8 | 9 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 10 | // configure_file(). 11 | 12 | // clang-format off 13 | #include "hoomd/md/PotentialBondGPU.h" 14 | #include "BondEvaluator@_evaluator@.h" 15 | 16 | #define EVALUATOR_CLASS BondEvaluator@_evaluator@ 17 | #define EXPORT_FUNCTION export_PotentialBond@_evaluator@GPU 18 | // clang-format on 19 | 20 | namespace hoomd 21 | { 22 | 23 | // Use CPU class from another compilation unit to reduce compile time and compiler memory usage. 24 | extern template class md::PotentialBond; 25 | 26 | namespace azplugins 27 | { 28 | namespace detail 29 | { 30 | void EXPORT_FUNCTION(pybind11::module& m) 31 | { 32 | hoomd::md::detail::export_PotentialBondGPU(m, "PotentialBond@_evaluator@GPU"); 33 | } 34 | } // end namespace detail 35 | } // end namespace azplugins 36 | } // end namespace hoomd 37 | -------------------------------------------------------------------------------- /src/export_PotentialPair.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // Adapted from hoomd/md/export_PotentialPair.cc.inc of HOOMD-blue. 6 | // Copyright (c) 2009-2024 The Regents of the University of Michigan. 7 | // Part of HOOMD-blue, released under the BSD 3-Clause License. 8 | 9 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 10 | // configure_file(). 11 | 12 | // clang-format off 13 | #include "hoomd/md/PotentialPair.h" 14 | #include "PairEvaluator@_evaluator@.h" 15 | 16 | #define EVALUATOR_CLASS PairEvaluator@_evaluator@ 17 | #define EXPORT_FUNCTION export_PotentialPair@_evaluator@ 18 | // clang-format on 19 | 20 | namespace hoomd 21 | { 22 | namespace azplugins 23 | { 24 | namespace detail 25 | { 26 | void EXPORT_FUNCTION(pybind11::module& m) 27 | { 28 | hoomd::md::detail::export_PotentialPair(m, "PotentialPair@_evaluator@"); 29 | } 30 | } // end namespace detail 31 | } // end namespace azplugins 32 | } // end namespace hoomd 33 | -------------------------------------------------------------------------------- /src/export_PotentialPairDPDThermo.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // Adapted from hoomd/md/export_PotentialPair.cc.inc of HOOMD-blue. 6 | // Copyright (c) 2009-2024 The Regents of the University of Michigan. 7 | // Part of HOOMD-blue, released under the BSD 3-Clause License. 8 | 9 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 10 | // configure_file(). 11 | 12 | // clang-format off 13 | #include "hoomd/md/PotentialPairDPDThermo.h" 14 | #include "DPDPairEvaluator@_evaluator@.h" 15 | 16 | #define EVALUATOR_CLASS DPDPairEvaluator@_evaluator@ 17 | #define EXPORT_FUNCTION export_PotentialPairDPDThermo@_evaluator@ 18 | // clang-format on 19 | 20 | namespace hoomd 21 | { 22 | 23 | template class hoomd::md::PotentialPair; 24 | template class hoomd::md::PotentialPairDPDThermo; 25 | 26 | namespace azplugins 27 | { 28 | namespace detail 29 | { 30 | 31 | void EXPORT_FUNCTION(pybind11::module& m) 32 | { 33 | hoomd::md::detail::export_PotentialPair( 34 | m, 35 | "PotentialPairConservative@_evaluator@"); 36 | hoomd::md::detail::export_PotentialPairDPDThermo( 37 | m, 38 | "PotentialPairDPDThermo@_evaluator@"); 39 | } 40 | 41 | } // end namespace detail 42 | } // end namespace azplugins 43 | } // end namespace hoomd 44 | -------------------------------------------------------------------------------- /src/export_PotentialPairDPDThermoGPU.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // Adapted from hoomd/md/export_PotentialPairDPDThermoGPU.cc.inc of HOOMD-blue. 6 | // Copyright (c) 2009-2024 The Regents of the University of Michigan. 7 | // Part of HOOMD-blue, released under the BSD 3-Clause License. 8 | 9 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 10 | // configure_file(). 11 | 12 | // clang-format off 13 | #include "hoomd/md/PotentialPairDPDThermoGPU.h" 14 | #include "DPDPairEvaluator@_evaluator@.h" 15 | 16 | #define EVALUATOR_CLASS DPDPairEvaluator@_evaluator@ 17 | #define EXPORT_FUNCTION export_PotentialPairDPDThermo@_evaluator@GPU 18 | // clang-format on 19 | 20 | namespace hoomd 21 | { 22 | 23 | template class md::PotentialPairDPDThermoGPU; 24 | 25 | namespace azplugins 26 | { 27 | namespace detail 28 | { 29 | void EXPORT_FUNCTION(pybind11::module& m) 30 | { 31 | hoomd::md::detail::export_PotentialPairDPDThermoGPU( 32 | m, 33 | "PotentialPairDPDThermo@_evaluator@GPU"); 34 | } 35 | } // end namespace detail 36 | } // end namespace azplugins 37 | } // end namespace hoomd 38 | -------------------------------------------------------------------------------- /src/export_PotentialPairGPU.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // Adapted from hoomd/md/export_PotentialPairGPU.cc.inc of HOOMD-blue. 6 | // Copyright (c) 2009-2024 The Regents of the University of Michigan. 7 | // Part of HOOMD-blue, released under the BSD 3-Clause License. 8 | 9 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 10 | // configure_file(). 11 | 12 | // clang-format off 13 | #include "hoomd/md/PotentialPairGPU.h" 14 | #include "PairEvaluator@_evaluator@.h" 15 | 16 | #define EVALUATOR_CLASS PairEvaluator@_evaluator@ 17 | #define EXPORT_FUNCTION export_PotentialPair@_evaluator@GPU 18 | // clang-format on 19 | 20 | namespace hoomd 21 | { 22 | 23 | // Use CPU class from another compilation unit to reduce compile time and compiler memory usage. 24 | extern template class md::PotentialPair; 25 | 26 | namespace azplugins 27 | { 28 | namespace detail 29 | { 30 | void EXPORT_FUNCTION(pybind11::module& m) 31 | { 32 | hoomd::md::detail::export_PotentialPairGPU(m, "PotentialPair@_evaluator@GPU"); 33 | } 34 | } // end namespace detail 35 | } // end namespace azplugins 36 | } // end namespace hoomd 37 | -------------------------------------------------------------------------------- /src/export_VelocityFieldCompute.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "VelocityFieldCompute.h" 10 | #include "@_geometry@BinningOperation.h" 11 | 12 | #define BINNING_OPERATION @_geometry@BinningOperation 13 | #define EXPORT_FUNCTION export_@_geometry@VelocityFieldCompute 14 | // clang-format on 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | 21 | template class VelocityFieldCompute; 22 | 23 | namespace detail 24 | { 25 | void EXPORT_FUNCTION(pybind11::module& m) 26 | { 27 | export_VelocityFieldCompute(m, "@_geometry@VelocityFieldCompute"); 28 | } 29 | } // end namespace detail 30 | 31 | } // end namespace azplugins 32 | } // end namespace hoomd 33 | -------------------------------------------------------------------------------- /src/export_VelocityFieldComputeGPU.cc.inc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | // See CMakeLists.txt for the source of these variables to be processed by CMake's 6 | // configure_file(). 7 | 8 | // clang-format off 9 | #include "VelocityFieldComputeGPU.h" 10 | #include "@_geometry@BinningOperation.h" 11 | 12 | #define BINNING_OPERATION @_geometry@BinningOperation 13 | #define EXPORT_FUNCTION export_@_geometry@VelocityFieldComputeGPU 14 | // clang-format on 15 | 16 | namespace hoomd 17 | { 18 | namespace azplugins 19 | { 20 | 21 | template class VelocityFieldComputeGPU; 22 | 23 | namespace detail 24 | { 25 | void EXPORT_FUNCTION(pybind11::module& m) 26 | { 27 | export_VelocityFieldComputeGPU(m, "@_geometry@VelocityFieldComputeGPU"); 28 | } 29 | } // end namespace detail 30 | } // end namespace azplugins 31 | } // end namespace hoomd 32 | -------------------------------------------------------------------------------- /src/external.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """External potentials.""" 6 | 7 | import hoomd 8 | 9 | from hoomd.azplugins import _azplugins 10 | from hoomd.data.parameterdicts import ParameterDict, TypeParameterDict 11 | from hoomd.data.typeconverter import OnlyTypes, variant_preprocessing 12 | from hoomd.data.typeparam import TypeParameter 13 | from hoomd.md import force 14 | 15 | 16 | class HarmonicBarrier(force.Force): 17 | r"""Repulsive barrier implemented as a harmonic potential. 18 | 19 | This class should not be instantiated directly. Use a derived type. 20 | 21 | Args: 22 | location (`hoomd.variant.variant_like`): Location of the barrier. 23 | 24 | .. py:attribute:: location 25 | 26 | Location of the barrier. The meaning of this location is interpreted 27 | by derived types. 28 | 29 | Type: `hoomd.variant.variant_like` 30 | 31 | .. py:attribute:: params 32 | 33 | The parameters of the harmonic barrier for each particle type. 34 | The dictionary has the following keys: 35 | 36 | * ``k`` (`float`, **required**) - Spring constant 37 | :math:`[\mathrm{energy} \cdot \mathrm{length}^{-2}]` 38 | * ``offset`` (`float`, **required**) - Amount added to ``location`` 39 | :math:`[\mathrm{length}]` 40 | 41 | 42 | Type: :class:`~hoomd.data.typeparam.TypeParameter` [`tuple` 43 | [``particle_type``], `dict`] 44 | 45 | .. warning:: 46 | 47 | The contribution to the virial is not calculated! 48 | 49 | """ 50 | 51 | def __init__(self, location): 52 | super().__init__() 53 | 54 | param_dict = ParameterDict( 55 | location=OnlyTypes(hoomd.variant.Variant, preprocess=variant_preprocessing), 56 | ) 57 | param_dict["location"] = location 58 | self._param_dict.update(param_dict) 59 | 60 | params = TypeParameter( 61 | "params", 62 | "particle_types", 63 | TypeParameterDict(k=float, offset=float, len_keys=1), 64 | ) 65 | self._add_typeparam(params) 66 | 67 | def _attach_hook(self): 68 | sim = self._simulation 69 | 70 | cpp_class = getattr(_azplugins, self._make_cpp_class_name()) 71 | 72 | self._cpp_obj = cpp_class(sim.state._cpp_sys_def, self.location) 73 | 74 | super()._attach_hook() 75 | 76 | def _make_cpp_class_name(self): 77 | cpp_class_name = self.__class__.__name__ 78 | if isinstance(self._simulation.device, hoomd.device.GPU): 79 | cpp_class_name += "GPU" 80 | return cpp_class_name 81 | 82 | 83 | class PlanarHarmonicBarrier(HarmonicBarrier): 84 | r"""Planar harmonic barrier normal to *y*. 85 | 86 | Args: 87 | location (`hoomd.variant.variant_like`): *y* position of the 88 | barrier. 89 | 90 | `PlanarHarmonicBarrier` applies a purely repulsive harmonic potential 91 | in a planar geometry with a normal in the :math:`y` direction. Particles 92 | are pushed in the :math:`-y` direction when they are above the 93 | ``location``: 94 | 95 | .. math:: 96 | 97 | U(y) = \begin{cases} 98 | 0, & y \le H \\ 99 | \dfrac{\kappa}{2} (y-H)^2, & y > H 100 | \end{cases} 101 | 102 | Here, the barrier is positioned at :math:`y=H`, specified by ``location``, 103 | which may then be modified per-particle-type by adding an ``offset``. 104 | :math:`\kappa` is a spring constant setting the strength of the barrier. 105 | 106 | Example:: 107 | 108 | # moving barrier from H = 50. to H = 25. 109 | barrier = hoomd.variant.Ramp(A=50.0, B=25.0, t_start=100, t_ramp=1e6) 110 | evap = hoomd.azplugins.external.PlanarHarmonicBarrier(location=barrier) 111 | 112 | # small particle has diameter 1.0, offset by -0.5 to keep fully inside 113 | evap.params['S'] = dict(k=50.0, offset=-0.5) 114 | 115 | # big particle is twice as large (diameter 2.0) 116 | # spring constant scales with diameter squared, offset with diameter 117 | evap.params['B'] = dict(k=200.0, offset=-1.0) 118 | 119 | """ 120 | 121 | 122 | class SphericalHarmonicBarrier(HarmonicBarrier): 123 | r"""Spherical harmonic barrier. 124 | 125 | Args: 126 | location (`hoomd.variant.variant_like`): Radius of sphere. 127 | 128 | `SphericalHarmonicBarrier` applies a purely repulsive harmonic potential to 129 | particles outside the radius of a sphere, acting to push them inward: 130 | 131 | .. math:: 132 | 133 | U(r) = \begin{cases} 134 | 0, & r \le R \\ 135 | \dfrac{\kappa}{2} (r-R)^2, & r > R 136 | \end{cases} 137 | 138 | Here, the barrier is positioned at radius *R*, specified by ``location``, 139 | which may then be modified per-particle-type by adding an ``offset``. 140 | :math:`\kappa` is a spring constant setting the strength of the barrier. 141 | 142 | Example:: 143 | 144 | # moving barrier from R = 50 to R = 25 145 | barrier = hoomd.variant.Ramp(A=50.0, B=25.0, t_start=100, t_ramp=1e6) 146 | evap = hoomd.azplugins.external.SphericalHarmonicBarrier(location=barrier) 147 | 148 | # small particle has diameter 1.0, offset by -0.5 to keep fully inside 149 | evap.params['S'] = dict(k=50.0, offset=-0.5) 150 | 151 | # big particle is twice as large (diameter 2.0) 152 | # spring constant scales with diameter squared, offset with diameter 153 | evap.params['B'] = dict(k=200.0, offset=-1.0) 154 | 155 | """ 156 | -------------------------------------------------------------------------------- /src/flow.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """Flow fields.""" 6 | 7 | import hoomd 8 | from hoomd.azplugins import _azplugins 9 | from hoomd.data.parameterdicts import ParameterDict 10 | from hoomd.operation import _HOOMDBaseObject 11 | 12 | 13 | class FlowField(_HOOMDBaseObject): 14 | """Base flow field.""" 15 | 16 | pass 17 | 18 | 19 | # hoomd.azplugins.flow.constant 20 | class ConstantFlow(FlowField): 21 | r"""Constant flow profile. 22 | 23 | Args: 24 | velocity (tuple): Flow field. 25 | 26 | This flow corresponds to a constant vector field, e.g., a constant 27 | backflow in bulk or a plug flow in a channel. The flow field is 28 | independent of the position it is evaluated at. 29 | 30 | Example:: 31 | 32 | u = hoomd.azplugins.flow.ConstantFlow(velocity=(1, 0, 0)) 33 | 34 | """ 35 | 36 | def __init__(self, velocity): 37 | super().__init__() 38 | param_dict = ParameterDict(velocity=(float, float, float)) 39 | param_dict["velocity"] = velocity 40 | self._param_dict.update(param_dict) 41 | 42 | def _attach_hook(self): 43 | self._cpp_obj = _azplugins.ConstantFlow( 44 | hoomd._hoomd.make_scalar3( 45 | self.velocity[0], self.velocity[1], self.velocity[2] 46 | ) 47 | ) 48 | super()._attach_hook() 49 | 50 | 51 | class ParabolicFlow(FlowField): 52 | r"""Parabolic flow profile between parallel plates. 53 | 54 | Args: 55 | mean_velocity (float): Mean velocity. 56 | separation (float): Separation between parallel plates defining the flow field. 57 | 58 | This flow field generates the parabolic flow profile in a slit geomtry: 59 | 60 | .. math:: 61 | 62 | u_x(y) = \frac{3}{2}U \left[1 - \left(\frac{y}{H}\right)^2 \right] 63 | 64 | The flow is along *x* with the gradient in *y*. The ``separation`` between the 65 | two plates is :math:`2H`, and the channel is centered around :math:`y=0`. 66 | The ``mean_velocity`` is :math:`U`. 67 | 68 | Example:: 69 | 70 | u = hoomd.azplugins.flow.ParabolicFlow( 71 | mean_velocity=2.0, separation=0.5 72 | ) 73 | 74 | Note: 75 | Creating a flow profile does **not** imply anything about the simulation 76 | box boundaries. It is the responsibility of the user to construct 77 | appropriate bounding walls commensurate with the flow profile geometry. 78 | 79 | """ 80 | 81 | def __init__(self, mean_velocity, separation): 82 | super().__init__() 83 | 84 | param_dict = ParameterDict( 85 | mean_velocity=float(mean_velocity), separation=float(separation) 86 | ) 87 | 88 | self._param_dict.update(param_dict) 89 | 90 | def _attach_hook(self): 91 | self._cpp_obj = _azplugins.ParabolicFlow(self.mean_velocity, self.separation) 92 | super()._attach_hook() 93 | -------------------------------------------------------------------------------- /src/module.cc: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2018-2020, Michael P. Howard 2 | // Copyright (c) 2021-2025, Auburn University 3 | // Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | #include 6 | 7 | namespace hoomd 8 | { 9 | //! Plugins for soft matter 10 | namespace azplugins 11 | { 12 | 13 | //! azplugins implementation details 14 | /*! 15 | * Classes, functions, and data structures that internally implement parts of the 16 | * plugins. These details are not part of the public interface, and may change at 17 | * any time. 18 | */ 19 | namespace detail 20 | { 21 | } // end namespace detail 22 | 23 | //! azplugins gpu implementations 24 | /*! 25 | * Driver functions for plugin kernels. These driver functions are 26 | * not part of the public interface, and may change at any time. 27 | */ 28 | namespace gpu 29 | { 30 | 31 | //! azplugins gpu kernels 32 | /*! 33 | * CUDA kernels to implement GPU pathways. These kernels are not 34 | * part of the public interface, and may change at any time. 35 | */ 36 | namespace kernel 37 | { 38 | } // end namespace kernel 39 | 40 | } // end namespace gpu 41 | 42 | } // end namespace azplugins 43 | } // end namespace hoomd 44 | 45 | // forward declaration of all export methods 46 | namespace hoomd 47 | { 48 | namespace azplugins 49 | { 50 | namespace detail 51 | { 52 | // bond 53 | void export_PotentialBondDoubleWell(pybind11::module&); 54 | void export_PotentialBondQuartic(pybind11::module&); 55 | 56 | // compute 57 | void export_CartesianVelocityFieldCompute(pybind11::module&); 58 | void export_CylindricalVelocityFieldCompute(pybind11::module&); 59 | void export_VelocityCompute(pybind11::module&); 60 | 61 | // external 62 | void export_PlanarHarmonicBarrier(pybind11::module&); 63 | void export_SphericalHarmonicBarrier(pybind11::module&); 64 | 65 | // flow 66 | void export_ConstantFlow(pybind11::module&); 67 | void export_ParabolicFlow(pybind11::module&); 68 | 69 | // pair 70 | void export_AnisoPotentialPairTwoPatchMorse(pybind11::module&); 71 | void export_PotentialPairColloid(pybind11::module&); 72 | void export_PotentialPairExpandedYukawa(pybind11::module&); 73 | void export_PotentialPairHertz(pybind11::module&); 74 | void export_PotentialPairPerturbedLennardJones(pybind11::module&); 75 | 76 | // dpd 77 | void export_PotentialPairDPDThermoGeneralWeight(pybind11::module&); 78 | 79 | #ifdef ENABLE_HIP 80 | // bond 81 | void export_PotentialBondDoubleWellGPU(pybind11::module&); 82 | void export_PotentialBondQuarticGPU(pybind11::module&); 83 | 84 | // compute 85 | void export_CartesianVelocityFieldComputeGPU(pybind11::module&); 86 | void export_CylindricalVelocityFieldComputeGPU(pybind11::module&); 87 | void export_VelocityComputeGPU(pybind11::module&); 88 | 89 | // external 90 | void export_PlanarHarmonicBarrierGPU(pybind11::module&); 91 | void export_SphericalHarmonicBarrierGPU(pybind11::module&); 92 | 93 | // pair 94 | void export_AnisoPotentialPairTwoPatchMorseGPU(pybind11::module&); 95 | void export_PotentialPairColloidGPU(pybind11::module&); 96 | void export_PotentialPairExpandedYukawaGPU(pybind11::module&); 97 | void export_PotentialPairHertzGPU(pybind11::module&); 98 | void export_PotentialPairPerturbedLennardJonesGPU(pybind11::module&); 99 | 100 | // dpd 101 | void export_PotentialPairDPDThermoGeneralWeightGPU(pybind11::module&); 102 | 103 | #endif // ENABLE_HIP 104 | 105 | } // namespace detail 106 | } // namespace azplugins 107 | } // namespace hoomd 108 | 109 | // python module 110 | PYBIND11_MODULE(_azplugins, m) 111 | { 112 | using namespace hoomd::azplugins::detail; 113 | 114 | // bond 115 | export_PotentialBondDoubleWell(m); 116 | export_PotentialBondQuartic(m); 117 | 118 | // compute 119 | export_CartesianVelocityFieldCompute(m); 120 | export_CylindricalVelocityFieldCompute(m); 121 | export_VelocityCompute(m); 122 | 123 | // external 124 | export_PlanarHarmonicBarrier(m); 125 | export_SphericalHarmonicBarrier(m); 126 | 127 | // flow 128 | export_ConstantFlow(m); 129 | export_ParabolicFlow(m); 130 | 131 | // pair 132 | export_AnisoPotentialPairTwoPatchMorse(m); 133 | export_PotentialPairColloid(m); 134 | export_PotentialPairExpandedYukawa(m); 135 | export_PotentialPairHertz(m); 136 | export_PotentialPairPerturbedLennardJones(m); 137 | 138 | // dpd pair 139 | export_PotentialPairDPDThermoGeneralWeight(m); 140 | 141 | #ifdef ENABLE_HIP 142 | // bond 143 | export_PotentialBondDoubleWellGPU(m); 144 | export_PotentialBondQuarticGPU(m); 145 | 146 | // compute 147 | export_CartesianVelocityFieldComputeGPU(m); 148 | export_CylindricalVelocityFieldComputeGPU(m); 149 | export_VelocityComputeGPU(m); 150 | 151 | // external 152 | export_PlanarHarmonicBarrierGPU(m); 153 | export_SphericalHarmonicBarrierGPU(m); 154 | 155 | // pair 156 | export_AnisoPotentialPairTwoPatchMorseGPU(m); 157 | export_PotentialPairColloidGPU(m); 158 | export_PotentialPairExpandedYukawaGPU(m); 159 | export_PotentialPairHertzGPU(m); 160 | export_PotentialPairPerturbedLennardJonesGPU(m); 161 | 162 | // dpd pair 163 | export_PotentialPairDPDThermoGeneralWeightGPU(m); 164 | 165 | #endif // ENABLE_HIP 166 | } 167 | -------------------------------------------------------------------------------- /src/pytest/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # TODO: List all pytest files in test_files. 2 | set(test_files 3 | __init__.py 4 | test_bond.py 5 | test_compute.py 6 | test_external.py 7 | test_flow.py 8 | test_pair.py 9 | test_pair_aniso.py 10 | test_pair_dpd.py 11 | ) 12 | 13 | # Copy tests to the install directory. 14 | install(FILES ${test_files} 15 | DESTINATION ${PYTHON_SITE_INSTALL_DIR}/${COMPONENT_NAME}/pytest 16 | ) 17 | 18 | # Copy tests to the build directory for testing prior to installation. 19 | copy_files_to_build("${test_files}" "hoomd-component-${COMPONENT_NAME}-pytest" "*.py") 20 | -------------------------------------------------------------------------------- /src/pytest/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """Unit tests.""" 6 | -------------------------------------------------------------------------------- /src/pytest/test_flow.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """Test flow fields.""" 6 | 7 | import hoomd 8 | import numpy 9 | from hoomd.conftest import pickling_check 10 | 11 | 12 | def test_constant_flow_field(simulation_factory): 13 | """Test constant flow field.""" 14 | # make the flow field 15 | U = hoomd.azplugins.flow.ConstantFlow(velocity=(1, 0, 0)) 16 | numpy.testing.assert_array_almost_equal(U.velocity, (1, 0, 0)) 17 | pickling_check(U) 18 | 19 | # set velocity 20 | U.velocity = (1, 2, 3) 21 | numpy.testing.assert_array_almost_equal(U.velocity, (1, 2, 3)) 22 | pickling_check(U) 23 | 24 | # get and set velocity 25 | sim = simulation_factory() 26 | U._attach(sim) 27 | numpy.testing.assert_array_almost_equal(U.velocity, (1, 2, 3)) 28 | pickling_check(U) 29 | 30 | 31 | def test_parabolic_flow_field(simulation_factory): 32 | """Test parabolic flow field.""" 33 | # make the flow field 34 | U = hoomd.azplugins.flow.ParabolicFlow(mean_velocity=4, separation=10) 35 | assert U.mean_velocity == 4 36 | assert U.separation == 10 37 | pickling_check(U) 38 | 39 | # set velocity and separation 40 | U.mean_velocity = 10 41 | U.separation = 20 42 | numpy.testing.assert_array_almost_equal((U.mean_velocity, U.separation), (10, 20)) 43 | pickling_check(U) 44 | 45 | # get and set velocity and separation 46 | sim = simulation_factory() 47 | U._attach(sim) 48 | numpy.testing.assert_array_almost_equal((U.mean_velocity, U.separation), (10, 20)) 49 | pickling_check(U) 50 | -------------------------------------------------------------------------------- /src/pytest/test_pair_aniso.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """Pair potential unit tests.""" 6 | 7 | import collections 8 | 9 | import hoomd 10 | import hoomd.azplugins 11 | import numpy 12 | 13 | import pytest 14 | 15 | PotentialTestCase = collections.namedtuple( 16 | "PotentialTestCase", 17 | ["potential", "params", "r_cut", "shift", "energy", "force", "torque"], 18 | ) 19 | 20 | potential_tests = [] 21 | # Two Patch Morse 22 | potential_tests += [ 23 | # test the calculation of energy, force and torque 24 | # test without potential shifting 25 | PotentialTestCase( 26 | hoomd.azplugins.pair.TwoPatchMorse, 27 | { 28 | "M_d": 1.8341, 29 | "M_r": 0.0302, 30 | "r_eq": 1.0043, 31 | "omega": 5.0, 32 | "alpha": 0.40, 33 | "repulsion": False, 34 | }, 35 | 1.6, 36 | False, 37 | -0.20567 * 2, 38 | (-11.75766, -2.46991, -3.70487), 39 | (-0.000000, -0.08879, 0.05919), 40 | ), 41 | # test that energy shifting works 42 | PotentialTestCase( 43 | hoomd.azplugins.pair.TwoPatchMorse, 44 | { 45 | "M_d": 1.8341, 46 | "M_r": 0.0302, 47 | "r_eq": 1.0043, 48 | "omega": 5.0, 49 | "alpha": 0.40, 50 | "repulsion": False, 51 | }, 52 | 1.10, 53 | True, 54 | -0.14195 * 2, 55 | None, 56 | None, 57 | ), 58 | # test the cases where the potential should be zero 59 | # test without potential shifting, particles are outside cutoff 60 | PotentialTestCase( 61 | hoomd.azplugins.pair.TwoPatchMorse, 62 | { 63 | "M_d": 1.8341, 64 | "M_r": 0.0302, 65 | "r_eq": 1.0043, 66 | "omega": 5.0, 67 | "alpha": 0.40, 68 | "repulsion": False, 69 | }, 70 | 1.0, 71 | True, 72 | 0, 73 | None, 74 | None, 75 | ), 76 | # inside cutoff but Md = 0 77 | PotentialTestCase( 78 | hoomd.azplugins.pair.TwoPatchMorse, 79 | { 80 | "M_d": 0.0, 81 | "M_r": 0.0302, 82 | "r_eq": 1.0043, 83 | "omega": 5.0, 84 | "alpha": 0.40, 85 | "repulsion": False, 86 | }, 87 | 1.6, 88 | True, 89 | 0, 90 | None, 91 | None, 92 | ), 93 | # test no force 94 | PotentialTestCase( 95 | hoomd.azplugins.pair.TwoPatchMorse, 96 | { 97 | "M_d": 1.8341, 98 | "M_r": 0.0302, 99 | "r_eq": 1.1, 100 | "omega": 100.0, 101 | "alpha": 0.40, 102 | "repulsion": False, 103 | }, 104 | 1.6, 105 | False, 106 | -1.8341, 107 | (0, 0, 0), 108 | None, 109 | ), 110 | ] 111 | 112 | 113 | @pytest.mark.parametrize( 114 | "potential_test", potential_tests, ids=lambda x: x.potential.__name__ 115 | ) 116 | def test_energy_force_and_torque( 117 | simulation_factory, two_particle_snapshot_factory, potential_test 118 | ): 119 | """Test energy and force evaluation.""" 120 | # make 2 particle test configuration 121 | snap = two_particle_snapshot_factory() 122 | if snap.communicator.rank == 0: 123 | snap.particles.position[:] = [[-0.5, -0.10, -0.15], [0.5, 0.10, 0.15]] 124 | snap.particles.orientation[:] = [[1, 0, 0, 0], [1, 0, 0, 0]] 125 | snap.particles.moment_inertia[:] = [0.1, 0.1, 0.1] 126 | sim = simulation_factory(snap) 127 | 128 | # setup dummy NVE integrator 129 | integrator = hoomd.md.Integrator(dt=0.001) 130 | nve = hoomd.md.methods.ConstantVolume(hoomd.filter.All()) 131 | integrator.methods = [nve] 132 | 133 | # setup pair potential 134 | potential = potential_test.potential( 135 | nlist=hoomd.md.nlist.Cell(buffer=0.4), 136 | default_r_cut=potential_test.r_cut, 137 | mode="shift" if potential_test.shift else "none", 138 | ) 139 | potential.params[("A", "A")] = potential_test.params 140 | integrator.forces = [potential] 141 | 142 | # calculate energies and forces 143 | sim.operations.integrator = integrator 144 | sim.run(0) 145 | 146 | # test that parameters are still correct after attach runs 147 | ref_values = (list(potential_test.params.values()),) 148 | test_values = [potential.params[("A", "A")][k] for k in potential_test.params] 149 | assert numpy.allclose(test_values, ref_values) 150 | 151 | # test that the energies match reference values, half goes to each particle 152 | energies = potential.energies 153 | e = potential_test.energy 154 | if sim.device.communicator.rank == 0: 155 | numpy.testing.assert_array_almost_equal(energies, [0.5 * e, 0.5 * e], decimal=4) 156 | 157 | # test that the forces match reference values, should be directed along x 158 | forces = potential.forces 159 | f = potential_test.force 160 | if f is not None and sim.device.communicator.rank == 0: 161 | f = numpy.array(f) 162 | numpy.testing.assert_array_almost_equal(forces, [-f, f], decimal=4) 163 | 164 | # test that the torques match reference value 165 | torques = potential.torques 166 | T = potential_test.torque 167 | if T is not None and sim.device.communicator.rank == 0: 168 | numpy.testing.assert_array_almost_equal(torques, [T, T], decimal=4) 169 | -------------------------------------------------------------------------------- /src/pytest/test_pair_dpd.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018-2020, Michael P. Howard 2 | # Copyright (c) 2021-2025, Auburn University 3 | # Part of azplugins, released under the BSD 3-Clause License. 4 | 5 | """Test DPD pair potentials.""" 6 | 7 | import hoomd 8 | import numpy 9 | 10 | import pytest 11 | 12 | 13 | def test_dpd_temperature(simulation_factory, lattice_snapshot_factory): 14 | """Test dpd general weight thermostat.""" 15 | # use lattice snapshot to generate a simulation with N=1000 in a box 6 x 6 x 6 16 | snap = lattice_snapshot_factory(dimensions=3, n=10, a=0.6) 17 | sim = simulation_factory(snap) 18 | all_ = hoomd.filter.All() 19 | sim.state.thermalize_particle_momenta(filter=all_, kT=1.5) 20 | 21 | integrator = hoomd.md.Integrator(dt=0.01) 22 | sim.operations.integrator = integrator 23 | 24 | # create DPD with no repulsion to test random part only 25 | cell = hoomd.md.nlist.Cell(buffer=0.4) 26 | dpd = hoomd.azplugins.pair.DPDGeneralWeight(nlist=cell, kT=1.5, default_r_cut=1.0) 27 | dpd.params[("A", "A")] = dict(A=0.0, gamma=4.5, s=0.5) 28 | integrator.forces.append(dpd) 29 | 30 | # set up NVE integration to test thermostatting part of DPD General Weight 31 | nve = hoomd.md.methods.ConstantVolume(filter=all_) 32 | integrator.methods.append(nve) 33 | 34 | thermo = hoomd.md.compute.ThermodynamicQuantities(filter=all_) 35 | sim.operations.computes.append(thermo) 36 | 37 | sim.run(10) 38 | 39 | num_samples = 100 40 | kT = numpy.zeros(num_samples) 41 | for sample in range(num_samples): 42 | kT[sample] = thermo.kinetic_temperature 43 | sim.run(1) 44 | avg_kT = numpy.mean(kT) 45 | 46 | assert avg_kT == pytest.approx(1.5, 0.1) 47 | --------------------------------------------------------------------------------