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

PBC completion super slow #11

Open
fgrunewald opened this issue Jan 6, 2022 · 4 comments
Open

PBC completion super slow #11

fgrunewald opened this issue Jan 6, 2022 · 4 comments

Comments

@fgrunewald
Copy link
Owner

There should be a faster way to do the PBC completion. Subprocess call to GROMACS?

@Tsjerk
Copy link
Collaborator

Tsjerk commented Jan 6, 2022

A subprocess call is quite suboptimal and probably unnecessary. Where is the routine you use now?

@fgrunewald
Copy link
Owner Author

It is the MDAnalysis atomgroup routine. I think can be faster by disabling some checks, running it on the complete position matrix instead of per selection. Stuff like that.

@Tsjerk
Copy link
Collaborator

Tsjerk commented Jan 6, 2022

The fastest will be to have a copy of the coordinates in reciprocal space and then for every selection subtract the first coordinate from the rest and add pi, then floor everything to the 0-2 pi domain and subtract pi, convert to regular coordinates and add the first particle. This will ensure that every group of atoms forming a bead is taken as most compact. You'll have to do it again for bonded terms, but the procedure is quite cheap with numpy and easily implemented. If you want, I can add it. Which file is it?

@fgrunewald
Copy link
Owner Author

If it is cheap, why not. Based on the MDAnalysis it cannot be much slower and people could still do it with GROMACS. So the code that does the mapping is this one:

@njit(parallel=True)
def forward_map_positions(mapped_atoms, bead_idxs, positions, n_frames, mode):
new_trajectory = np.zeros((n_frames, len(mapped_atoms), 3))
for count_lv1 in prange(len(mapped_atoms)):
bead_idx = bead_idxs[count_lv1]
atom_idxs = mapped_atoms[count_lv1]
for fdx in prange(0, n_frames):
new_pos = np.array([0.0, 0.0, 0.0], dtype=np.float32)
for atom_idx in atom_idxs:
vector = positions[fdx, atom_idx, :]
new_pos = new_pos + vector
new_pos = new_pos / len(atom_idxs)
new_trajectory[fdx, bead_idx, :] = new_pos
return new_trajectory

Positions is a n_frames x n_atoms x 3 numpy matrix and the function is accelerated by numba. To get best numba performance it is best to write as simple and plain python as possible and omit numpy magic as much as possible within this function. I leave it up to you if you first want to generate the coordinates in reciprocal space and then run this function or do everything within this function.

@Tsjerk Tsjerk mentioned this issue Jan 8, 2022
Merged
@fgrunewald fgrunewald reopened this Jan 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants