-
Notifications
You must be signed in to change notification settings - Fork 79
mBuild 2.0 polymer and simulation improvements: Introduce Path class, Polymer.build_from_path() and add new HOOMD-Blue simulation methods.
#1261
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.10 → v0.12.11](astral-sh/ruff-pre-commit@v0.12.10...v0.12.11)
…te-config [pre-commit.ci] pre-commit autoupdate
updates: - [github.com/astral-sh/ruff-pre-commit: v0.12.11 → v0.13.0](astral-sh/ruff-pre-commit@v0.12.11...v0.13.0)
…te-config [pre-commit.ci] pre-commit autoupdate
updates: - [github.com/astral-sh/ruff-pre-commit: v0.13.0 → v0.13.1](astral-sh/ruff-pre-commit@v0.13.0...v0.13.1)
…te-config [pre-commit.ci] pre-commit autoupdate
updates: - [github.com/astral-sh/ruff-pre-commit: v0.13.1 → v0.13.2](astral-sh/ruff-pre-commit@v0.13.1...v0.13.2)
updates: - [github.com/astral-sh/ruff-pre-commit: v0.13.2 → v0.13.3](astral-sh/ruff-pre-commit@v0.13.2...v0.13.3) - [github.com/pycqa/isort: 6.0.1 → 6.1.0](PyCQA/isort@6.0.1...6.1.0)
updates: - [github.com/astral-sh/ruff-pre-commit: v0.13.3 → v0.14.0](astral-sh/ruff-pre-commit@v0.13.3...v0.14.0) - [github.com/pycqa/isort: 6.1.0 → 7.0.0](PyCQA/isort@6.1.0...7.0.0)
* Update bond order conversions to handle floats and automate conversions to parmed objects with bond orders * [pre-commit.ci] pre-commit autoupdate updates: - [github.com/astral-sh/ruff-pre-commit: v0.13.3 → v0.14.0](astral-sh/ruff-pre-commit@v0.13.3...v0.14.0) - [github.com/pycqa/isort: 6.1.0 → 7.0.0](PyCQA/isort@6.1.0...7.0.0) * Add back in ability to support string bond orders and convert to the backend float values * remove failing bad bond order test --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.0 → v0.14.1](astral-sh/ruff-pre-commit@v0.14.0...v0.14.1)
…te-config [pre-commit.ci] pre-commit autoupdate
updates: - [github.com/astral-sh/ruff-pre-commit: v0.14.1 → v0.14.2](astral-sh/ruff-pre-commit@v0.14.1...v0.14.2)
…te-config [pre-commit.ci] pre-commit autoupdate
for more information, see https://pre-commit.ci
Contributor
Author
|
Ok, merging this as it has become a very large PR. I'll open issues for some of the unfinished to-dos from here. |
4 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR begins the first efforts towards development of mBuild 2.0 (i.e., we can break things), and focuses mostly on improving the polymer-building experience in mBuild as discussed in #1205 and #1212. There are also quite a few changes that introduce more energy minimization methods that utilize HOOMD-Blue, and can run on GPU for larger systems and/or HPC workflows. I didn't mean for so many changes to be included in this PR, but as I worked on this, more and more needs kept creeping up. This PR isn't necessarily the completed effort on the area of initializing polymer systems and adding more feature-rich energy minimization approaches, but it's close to a good stopping place for now. I'll try to summarize the most notable changes. This won't be merged to the
mainbranch, but instead will be the first commit on thedevelopbranch.Addition of the
mbuild.path.PathclassThis introduces a new data structure for creating "paths" (i.e., molecular configurations). The primary purpose of this class is to generate better starting polymer-chain configurations, as opposed to the wonky ones you often get by default from the
Polymer.build()method.The basic idea is that a path represents a coarse-grained configuration that atomistic polymers can be mapped onto during the build step. Most of the classes include non-random, deterministic paths (3-D lamellar structures, ring polymers, etc.), but there is a
HardSphereRandomWalkpath as well.Here are some examples of the idea and API behind this:
Build a 3D lamellar polymer by specifying parameters such as layer length, separation, number of layers and stacks (3D):
Build a polymer from a random walk:
HardSphereRandomWalkandmbuild.utils.volume.Constraint:Some highlights of this Path class specifically:
mbuild.Compound.volumeis added in this PR, using RDKit)mbuild.utils.volume.Constraint. Right now this PR addsCuboidConstraint,SphereConstraintandCylinderConstraint. These objects can be passed intoHardSphereRandomWalk, making it easy to add to and extend these constraints separately from the random walk logic.mbuild.path.Pathinstance.Lamellarpath, then run a random walk from the last site. The resulting path includes all the coordinates of the first, as well as the results of the random walk. This can be used to start constructing semi-crystalline morphologies.trial_batch_sizeparameter). This should help constrained random walks finish, but possibly at a performance cost. I haven't had a chance to profile this one yet.Here are some examples:
Stitching together a lamellar path and random walk
Including a volume constraint in the random walk
mbuild.simulation module
We already had a pretty great set of simulation methods for performing energy minimization. This PR pulled all of that code out of
compound.pyand added it to asimulation.py. Now, you pass the compound into these methods rather than calling it as a class method (e.g,energy_minimize(compound)instead ofcompound.energy_minimize()). This trims down theCompoundclass quite a bit (~700 lines of code).This PR also adds a few things that allows us to use HOOMD in addition to OpenBabel and OpenMM. The main new addition here is a wrapper class around HOOMD's own simulation class. This makes it easy to design more specific workflows that can go beyond energy minimization. For example, a quick compress simulation is planned for a future PR, which can be ran after the
packing.pymethods. Hopefully, this approach makes it easy for users to make their own quick simulation protocols when needed, and contribute upstream when possible.This PR adds 2 methods that use this HOOMD base class:
hoomd_cap_displacement: This uses the capped displacement method in HOOMD
hoomd_fire: This uses HOOMD's implementation of the FIRE algorithm.
These can both be better options for the energy minimization demands of building larger polymers from paths. They can use the GPU if available, and even on CPU, they are much faster than Openbabel after certain system sizes.
hoomd_cap_displacementwas able to optimize the geometry for a polyethylene 200mer in about the same amount of time it took openbabel to optimize an 80mer (around 12 seconds). They were nearly equally efficient at smaller system sizes.The biggest bottleneck here is the lack of support for universal forcefields (e.g., UFF) that aren't hampered by missing parameters. For now, we are keeping the openbabel stuff in, even though there are some upstream issues with using it as a dependency. Also, we are planning on keeping and expanding the OpenMM energy minimization as well. I might look at making it more modular in the future, similar to the HOOMD implementation.
One important feature of the HOOMD implementation is that all the simulation information is saved, making it faster to call these methods multiple times (e.g., in a for loop or while loop) while skipping repeated calls to the under-the-hood steps of atom typing, applying the forcefield, writing out HOOMD data structures, etc.
For example run
hoomd_cap_displacementin small increments with a condition to stop once all overlaps are removed:Combining Everything:
Here is the result of combining some of the things discussed above. Here, in a while loop, I ran 50 random walks of 25 steps each in a cubic box with 5nm edges. From each random walk, a polyethylene chain was built, and$\approx 0.5 \frac{g}{cm^3}$ . This is significantly better than using PACKMOL to pack a huge box with long, straight 25mers. This took ~3-4 minutes total.
hoomd_cap_displacementwas ran on the system of 50 polymers for 2,000 steps to relax bonds, angles and remove any overlaps. The result is a distribution of initial chain configurations packed at a density ofRemaining To-dos:
Some of these may or may not be included in this PR
General:
Path and Polymer.build_from_path():
Polymer.build_from_pathorPath.apply_backmapping().nx.path_graph()), but everything we need to support things like branching polymers is there, it just needs to be implemented. Cross-linking will require some extra thinking and design. As of 45a6eed, bond graphs are built on the fly, and include ability to track branching paths.from_box()class method forCuboidConstraintso one can be created from a box of another compound. This would be nice when using an existing mBuild compound in a random walk that also has volume constraints.simulation.py:
simulation.pysimulation.pythat uses Hoomd's box updater.Some discussion points
Pretty much everything in
path.py,density.pyandvolumes.pyis completely separate from theCompoundandPolymerdata structures. It kind of makes me wonder if there would be some utility inpath.py,density.pyandvolumes.pybeing in a separate MoSDeF package? It creates some overhead with handling an additional package, but it also keeps mBuild's code-base cleaner and more concise, and opens up more flexibility for further development aroundPathandConstraintthat isn't necessarily limited by mBuild's existing design and data structures. I'm not opposed to it, but also not opposed to keeping all of this in mBuild. Just something to think about.With these additions, there are a lot of workflows that become possible by essentially creating another Monte Carlo like layer of choices (e.g., stringing together multiple random walks, random branching from other random walks, random walks of different lengths to achieve a certain polydispersity, etc..). Once the new features in this PR, and subsequent PRs, become more fleshed-out, it might be worth thinking about adding some recipes/wrappers that implement these at a higher level.