def hook6(lattice): global nwateratoms lattice.logger.info("Hook6: Output water molecules in Yaplot format.") lattice.logger.info(" Total number of atoms: {0}".format( len(lattice.atoms))) # prepare the reverse dict waters = defaultdict(dict) for atom in lattice.atoms: resno, resname, atomname, position, order = atom if "O" in atomname: waters[order]["O"] = position elif "H" in atomname: if "H0" not in waters[order]: waters[order]["H0"] = position else: waters[order]["H1"] = position s = "" s += yp.Color(3) for order, water in waters.items(): O = water["O"] H0 = water["H0"] H1 = water["H1"] s += yp.Layer(4) s += yp.Color(3) s += yp.Size(0.03) s += yp.Circle(O) s += yp.Line(O, H0) s += yp.Line(O, H1) s += yp.Size(0.01) s += yp.Circle(H0) s += yp.Circle(H1) s += yp.Color(2) s += yp.Layer(1) s += yp.Text(O, "{0}".format(order)) s += yp.Layer(3) s += yp.Color(4) s += yp.ArrowType(1) s += yp.Size(0.03) for i, j in lattice.graph.edges(data=False): if i in waters and j in waters: # edge may connect to the dopant O = waters[j]["O"] H0 = waters[i]["H0"] H1 = waters[i]["H1"] d0 = H0 - O d1 = H1 - O rr0 = np.dot(d0, d0) rr1 = np.dot(d1, d1) if rr0 < rr1 and rr0 < 0.27**2: s += yp.Arrow(H0, O) if rr1 < rr0 and rr1 < 0.245**2: s += yp.Arrow(H1, O) print(s, end="") nwateratoms = len(lattice.atoms) lattice.logger.info("Hook6: end.")
def draw_cell(self): s = yp.Color(2) ex = np.array([1., 0., 0.]) ey = np.array([0., 1., 0.]) ez = np.array([0., 0., 1.]) x = np.dot(ex, self.cell) y = np.dot(ey, self.cell) z = np.dot(ez, self.cell) zero = np.zeros_like(x) for vx in (zero, x): for vy in (zero, y): s += yp.Line(vx + vy, vx + vy + z) for vx in (zero, x): for vz in (zero, z): s += yp.Line(vx + vz, vx + y + vz) for vz in (zero, z): for vy in (zero, y): s += yp.Line(vy + vz, x + vy + vz) return s
def draw_edge(self, i, j): ci = self.coord[i] #0..1 cj = self.coord[j] d = cj - ci d -= np.floor(d + 0.5) xi = np.dot(ci, self.cell) xj = np.dot(ci + d, self.cell) if self.has_edge(i, j): return yp.Color(4) + yp.ArrowType(2) + yp.Arrow(xi, xj) elif self.has_edge(j, i): return yp.Color(5) + yp.ArrowType(2) + yp.Arrow(xj, xi) else: return yp.Color(0) + yp.Line(xi, xj)
def one(self, pair): i, j = pair dij = self.atoms[j] - self.atoms[i] dij -= np.floor(dij + 0.5) dij = np.dot(dij, self.cell) scale = np.linalg.norm(dij) dij /= scale sixpairs = [] for k in self.nei[i]: if k != j: sixpairs.append((k, i)) for k in self.nei[j]: if k != i: sixpairs.append((k, j)) #Regularize the dihedral angles #to point them 6-fold directions. #by adding an offset sixvecs = [] for j, k in sixpairs: vec = self.atoms[j] - self.atoms[k] vec -= np.floor(vec + 0.5) vec = np.dot(vec, self.cell) #orthogonalize shadow = np.dot(dij, vec) vec -= shadow * dij vec /= np.linalg.norm(vec) #print(np.dot(vec,dij)) sixvecs.append(vec) offset = tune_angles(sixvecs, dij) offset += pi / 6 #30 degree x = sixvecs[0].copy() z = dij y = np.cross(z, x) for j in range(6): a = j * pi * 2 / 6 + offset sixvecs[j] = x * cos(a) + y * sin(a) #determine r #assume edge length is 1 #the radius of the outer sphere of the polyhed is sqrt(3/2) L = (3 / 2)**0.5 * 2 + self.Ncyl r = 1 / L #edge len = radius of cyl rp = (3 / 2)**0.5 / L # = radius of polyhed # a = np.dot(self.atoms[i], self.cell) s = "" s += yp.Color(3) s += yp.Line(a, a + dij * scale) for j in range(0, self.Ncyl + 1): vec0 = dij * (rp + j * r) * scale + a for vec in sixvecs: s += yp.Line(vec0, vec0 + vec * r * scale) rpos = vec0 + vec * r * scale pos = np.dot(rpos, np.linalg.inv(self.cell)) self.vertices.append(pos) first = len(self.vertices) - 6 if j % 2 == 0: for k in range(5): self.fixedEdges.append((first + k, first + k + 1)) self.fixedEdges.append((first + 5, first)) else: for k in range(5): self.fixedEdges.append((first + k + 1, first + k)) self.fixedEdges.append((first, first + 5)) if j > 0: for k in range(6): if k % 2 == 0: self.fixedEdges.append((first + k, first + k - 6)) else: self.fixedEdges.append((first + k - 6, first + k)) self.yap += s