def orientations(coord, graph, cell): """ Does not work when two OHs are colinear """ logger = logging.getLogger() rotmatrices = [] for node in range(graph.number_of_nodes()): if node in graph.ignores: # for dopants; do not rotate rotmat = np.identity(3) else: vsucc = [cell.rel2abs(rel_wrap(coord[x] - coord[node])) for x in graph.successors(node)] if len(vsucc) < 2: #TSL vpred = [cell.rel2abs(rel_wrap(coord[x] - coord[node])) for x in graph.predecessors(node)] vsucc = [x / np.linalg.norm(x) for x in vsucc] vpred = [x / np.linalg.norm(x) for x in vpred] vcomp = complement(vpred+vsucc) logger.debug("Node {0} vcomp {1}".format(node,vcomp)) vsucc = (vsucc+vcomp)[:2] logger.debug("Node {0} vsucc {1}".format(node,vsucc)) assert 2<=len(vsucc), "Probably a wrong ice network." y = vsucc[1] - vsucc[0] y /= np.linalg.norm(y) z = (vsucc[0] + vsucc[1]) / 2 z /= np.linalg.norm(z) x = np.cross(y, z) rotmat = np.vstack([x, y, z]) rotmatrices.append(rotmat) return rotmatrices
def replicate_groups(groups, waters, cagepos, rep): """ This is not that easy. """ logger = logging.getLogger() # Storage for replicated groups newgroups = defaultdict(dict) for root, cages in groups.items(): # Position of root (water) (fractional) root_pos = waters[root] for cage, group_name in cages.items(): # Position of the cage (fractional) cage_pos = cagepos[cage] # Relative position of the cage delta = rel_wrap(cage_pos - root_pos) # (Image) cell that the cage resides gcell = np.floor(root_pos + delta) for x in range(rep[0]): for y in range(rep[1]): for z in range(rep[2]): r = np.array((x, y, z)) # label of the root (water) in the replica newroot = root + len(waters) * \ (x + rep[0] * (y + rep[1] * z)) # replicated cell in which the cage resides. # modulo by positive number is always positive. cr = (r + gcell) % rep newcage = cage + \ len(cagepos) * (cr[0] + rep[0] * (cr[1] + rep[1] * cr[2])) newcage = int(newcage) newgroups[newroot][newcage] = group_name # logger.info(("root",newroot,"newcage", newcage)) return newgroups
def shortest_distance(coord, cell, pairs=None): dmin = 1e99 if pairs is None: iter = it.combinations(coord, 2) else: iter = [(coord[i], coord[j]) for i, j in pairs] for c1, c2 in iter: r = cell.rel2abs(rel_wrap(c1 - c2)) rr = np.dot(r, r) if rr < dmin: dmin = rr return dmin**0.5
def neighbor_cages_of_dopants(dopants, waters, cagepos, cell): """ Just shows the environments of the dopants """ #logger = logging.getLogger() dnei = defaultdict(set) for site, name in dopants.items(): org = waters[site] for i, pos in enumerate(cagepos): #Displacement (relative) a = cell.rel2abs(rel_wrap(pos - org)) sqdistance = np.dot(a, a) if sqdistance < 0.57**2: dnei[site].add(i) # logger.info((i,cagepos[i])) return dnei
def Alkyl(cpos, root, cell, molname, backbone): """ put a normal-alkyl group rooted at root toward cpos. """ logger = logging.getLogger() # logger.info(" Put butyl at {0}".format(molname)) v1abs = cell.rel2abs(rel_wrap(cpos - root)) v1 = v1abs / np.linalg.norm(v1abs) origin = cell.rel2abs(root) CC = 0.154 rawatoms = alkyl.alkyl(v1, v1abs*1.5/CC, backbone) atoms = [] for i, atom in enumerate(rawatoms): atomname, pos = atom atompos = cell.abs_wrapf(pos*CC + origin) atoms.append([i, molname, atomname, atompos, 0]) return atoms