|
1 | 1 | import numpy as np
|
2 | 2 | from .pbc import posi_diff
|
3 | 3 |
|
4 |
| -def compute_bonds(box, |
5 |
| - posis, |
6 |
| - atype, |
7 |
| - oh_sel = [0,1], |
8 |
| - max_roh = 1.3, |
9 |
| - uniq_hbond = True): |
| 4 | +def compute_bonds (box, |
| 5 | + posis, |
| 6 | + atype, |
| 7 | + oh_sel = [0,1], |
| 8 | + max_roh = 1.3, |
| 9 | + uniq_hbond = True): |
| 10 | + try : |
| 11 | + import ase |
| 12 | + import ase.neighborlist |
| 13 | + # nlist implemented by ase |
| 14 | + return compute_bonds_ase(box, posis, atype, oh_sel, max_roh, uniq_hbond) |
| 15 | + except ImportError: |
| 16 | + # nlist naivly implemented , scales as O(N^2) |
| 17 | + return compute_bonds_naive(box, posis, atype, oh_sel, max_roh, uniq_hbond) |
| 18 | + |
| 19 | + |
| 20 | +def compute_bonds_ase(box, |
| 21 | + posis, |
| 22 | + atype, |
| 23 | + oh_sel = [0,1], |
| 24 | + max_roh = 1.3, |
| 25 | + uniq_hbond = True): |
| 26 | + natoms = len(posis) |
| 27 | + from ase import Atoms |
| 28 | + import ase.neighborlist |
| 29 | + atoms = Atoms(positions=posis, cell=box, pbc=[1,1,1]) |
| 30 | + nlist = ase.neighborlist.NeighborList(max_roh, self_interaction=False, bothways=True, primitive=ase.neighborlist.NewPrimitiveNeighborList) |
| 31 | + nlist.update(atoms) |
| 32 | + bonds = [] |
| 33 | + o_type = oh_sel[0] |
| 34 | + h_type = oh_sel[1] |
| 35 | + for ii in range(natoms) : |
| 36 | + bonds.append([]) |
| 37 | + for ii in range(natoms) : |
| 38 | + if atype[ii] == o_type : |
| 39 | + nn, ss = nlist.get_neighbors(ii) |
| 40 | + for jj in nn: |
| 41 | + if atype[jj] == h_type : |
| 42 | + dr = posi_diff(box, posis[ii], posis[jj]) |
| 43 | + if np.linalg.norm(dr) < max_roh : |
| 44 | + bonds[ii].append(jj) |
| 45 | + bonds[jj].append(ii) |
| 46 | + if uniq_hbond : |
| 47 | + for jj in range(natoms) : |
| 48 | + if atype[jj] == h_type : |
| 49 | + if len(bonds[jj]) > 1 : |
| 50 | + orig_bonds = bonds[jj] |
| 51 | + min_bd = 1e10 |
| 52 | + min_idx = -1 |
| 53 | + for ii in bonds[jj] : |
| 54 | + dr = posi_diff(box, posis[ii], posis[jj]) |
| 55 | + drr = np.linalg.norm(dr) |
| 56 | + # print(ii,jj, posis[ii], posis[jj], drr) |
| 57 | + if drr < min_bd : |
| 58 | + min_idx = ii |
| 59 | + min_bd = drr |
| 60 | + bonds[jj] = [min_idx] |
| 61 | + orig_bonds.remove(min_idx) |
| 62 | + # print(min_idx, orig_bonds, bonds[jj]) |
| 63 | + for ii in orig_bonds : |
| 64 | + bonds[ii].remove(jj) |
| 65 | + return bonds |
| 66 | + |
| 67 | + |
| 68 | +def compute_bonds_naive(box, |
| 69 | + posis, |
| 70 | + atype, |
| 71 | + oh_sel = [0,1], |
| 72 | + max_roh = 1.3, |
| 73 | + uniq_hbond = True): |
10 | 74 | natoms = len(posis)
|
11 | 75 | bonds = []
|
12 | 76 | o_type = oh_sel[0]
|
|
0 commit comments