Skip to content
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

Add method to Compound that checks for overlapping particles #1225

Open
wants to merge 12 commits into
base: main
Choose a base branch
from

Conversation

chrisjonesBSU
Copy link
Contributor

@chrisjonesBSU chrisjonesBSU commented Feb 20, 2025

PR Summary:

This is a small addition that adds a method to Compound that can check for overlapping particles (given a threshold distance). It uses scipy.spatial.distance.pdist, so it is pretty quick, although I haven't looked into performance with large compounds yet.

Motivation: This would be a useful check to have when building molecules and other structures and checking for problem particles before taking the time to apply a forcefield and start a simulation. It will be helpful in some new polymer-building features we've been talking about.

One thing to consider: It might be useful to have an option to exclude directly bonded neighbors when doing this, since bond distances are often smaller than particle radii.

PR Checklist


  • Includes appropriate unit test(s)
  • Appropriate docstring(s) are added/updated
  • Code is (approximately) PEP8 compliant
  • Issue(s) raised/addressed?

Copy link

codecov bot commented Feb 20, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 85.67%. Comparing base (519dde9) to head (8984135).
Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1225      +/-   ##
==========================================
+ Coverage   84.85%   85.67%   +0.81%     
==========================================
  Files          53       53              
  Lines        4800     4830      +30     
==========================================
+ Hits         4073     4138      +65     
+ Misses        727      692      -35     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@chrisjonesBSU
Copy link
Contributor Author

chrisjonesBSU commented Feb 25, 2025

This includes a refactor of Compound.direct_bonds() where I added a parameter that lets you choose the bond/graph depth used when returning directly bonded particles. A graph_depth of 1 returns all first-neighbor bonded particles (i.e. current behavior), and a graph_depth of 2 returns these as well as their first-neighbor bonded particles, and so on. This will be a useful feature in general, but especially for excluding n-bonded neighbors when checking for overlapping particles.

@chrisjonesBSU
Copy link
Contributor Author

Here is a quick example.

We're making a compound from 2 n-alkane molecules, and we want to make sure there aren't any particles within 0.20 nm of each other (a little less than the size of carbon radius).

chain = mb.load("CCCCCCCC", smiles=True)
chain2 = mb.clone(chain)
chain2.translate(by=np.array([2, 2, 2]))
comp = mb.Compound([chain, chain2])

If we use exclude_bond_depth=0 we'll get a bunch of positives for overlapping particles because the C-H bond is ~0.12 nm

>>> comp.check_for_overlap(excluded_bond_depth=0, minimum_distance=0.20)
[[30, 43], [7, 23], [3, 4], [6, 21], [26, 27], [35, 36], [21, 22], [26, 36], [3, 16], [31, 32], [33, 51], [8, 9], [4, 18], [23, 25], [29, 41], [5, 19], [49, 50], [0, 8], [17, 18], [27, 28], [2, 14], [1, 12], [13, 14], [27, 37], [45, 46], [28, 39], [32, 33], [41, 42], [50, 51], [4, 5], [26, 35], [5, 6], [7, 25], [33, 50], [32, 48], [4, 17], [3, 15], [23, 24], [0, 1], [9, 10], [1, 2], [0, 10], [34, 36], [1, 11], [19, 20], [28, 29], [31, 46], [37, 38], [2, 13], [30, 31], [6, 7], [15, 16], [24, 25], [47, 48], [30, 44], [43, 44], [7, 24], [6, 22], [29, 30], [32, 47], [33, 49], [26, 34], [29, 42], [39, 40], [0, 9], [8, 10], [34, 35], [49, 51], [2, 3], [5, 20], [11, 12], [31, 45], [28, 40], [27, 38]]

If we use excluded_bond_depth=1 that doesn't count particles within 1 direct bond of each other, but we still get particle pairs within the distance cutoff that are separated by 2 direct bonds.

>>> overlap = comp.check_for_overlap(excluded_bond_depth=1, minimum_distance=0.20)
[[35, 36], [21, 22], [8, 9], [23, 25], [49, 50], [17, 18], [13, 14], [45, 46], [41, 42], [50, 51], [23, 24], [9, 10], [34, 36], [19, 20], [37, 38], [15, 16], [24, 25], [47, 48], [43, 44], [39, 40], [8, 10], [34, 35], [49, 51], [11, 12]]

If we use excluded_bond_depth=2 we get zero hits for overlapping particles

>>> overlap = comp.check_for_overlap(excluded_bond_depth=2, minimum_distance=0.20)
[]

This is a simple example where the use case probably isn't that useful, but controlling for excluded_bond_depth will be very useful if we're building up polymers via random walks where the chain can begin to intersect with itself at longer chain lengths (as discussed in #1212 and #1205)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant