def translation_motion(self,x,y,xold,yold): newpos = array((x,y)) oldpos = array((xold,yold)) oldpos_model = self.model_coords(oldpos[0],oldpos[1]) newpos_model = self.model_coords(newpos[0],newpos[1]) dp = oldpos_model - newpos_model up=array(self.get_up()) right=array(self.get_right()) t_up=(dot(dp,up))*up; t_right=(dot(dp,right))*right; self.set_look_at(self.get_look_at()+t_up+t_right); return
def vangle(v1, v2): r1 = length(v1) r2 = length(v2) mag = r1 * r2 dp = dot(v1, v2) / mag dp = max(-0.999999, dp) dp = min(0.999999, dp) return rad2deg * acos(dp)
def simple_bond_finder(atoms,scale=1.2): bonds = [] for i in range(len(atoms)): atomi = atoms[i] for j in range(i): atomj = atoms[j] xyzij = atomi.xyz - atomj.xyz rij = sqrt(dot(xyzij,xyzij)) if rij < scale*(rcov[atomi.atno]+rcov[atomj.atno]): bonds.append(Bond(atomi,atomj)) return bonds
def rotation_motion(self,x,y,xold,yold): newpos = array((x,y)) oldpos = array((xold,yold)) diff_pos=newpos-oldpos r=sqrt(dot(diff_pos,diff_pos)) if r==0: return diff_pos=diff_pos/r angle=r*self.rotate_scale rot_mat=self.rotation_matrix(diff_pos,angle); self.set_up(matrixmultiply(rot_mat,array(self.get_up()))[:]) self.set_right(matrixmultiply(rot_mat,array(self.get_right()))[:]) self.set_position(matrixmultiply(rot_mat, array(self.get_position()))[:]) return
def func(x, y, z): xyz = array((x, y, z)) #xyzl = sqrt(dot(xyz,xyz)) #xyz = xyz/xyzl al = dot(self.axyz, self.axyz) bl = dot(self.bxyz, self.bxyz) cl = dot(self.cxyz, self.cxyz) return dot(xyz, self.axyz) / al, dot(xyz, self.bxyz) / bl, dot( xyz, self.cxyz) / cl
def torsion2(a, b, c, d): b1 = a - b b2 = b - c b3 = c - d c1 = cross(b1, b2) c2 = cross(b2, b3) c3 = cross(c1, c2) if length(c1) * length(c2) < 0.001: tijkl = 0 else: tijkl = vangle(c1, c2) if dot(b2, c3) > 0: tijkl *= -1 return tijkl
def bonds_from_distance_self(self, scale=1.2): bonds = [] for icell in range(self.nbins): atomsi = self.bins[icell] for iat in range(len(atomsi)): atomi = atomsi[iat] xyzi = atomi.get_xyz() atnoi = atomi.get_atno() for jat in range(iat): atomj = atomsi[jat] xyzj = atomj.get_xyz() atnoj = atomj.get_atno() dxyz = xyzi - xyzj r2 = dot(dxyz, dxyz) cut = scale * (rcov[atnoi] + rcov[atnoj]) cut2 = cut * cut if r2 < cut2: bonds.append(Bond(atomi, atomj)) return bonds
def rotation_matrix(self,diffpos,alpha): # diffpos given in model coords #r=dot(diffpos,diffpos); dx,dy=diffpos; up=array(self.get_up()); right=array(self.get_right()); u=-(dy*right)-(dx*up); u=u/sqrt(dot(u,u)); # normalize the vector (a,b,c)=u # # construct the S and M matrices, see # OpenGL Programming Guide, p. 672 # # The M matrix is the rotation matrix # S=array((( 0, -c, b), ( c, 0, -a), (-b, a, 0))); # # u_uT is u times its transpose (to give a 3x3 matrix) # u_uT=matrixmultiply(reshape(u,(3,1)),reshape(u,(1,3))); M=u_uT+cos(alpha)*(identity(3)-u_uT)+sin(alpha)*S return M;
def build_the_slab(material, cleave_dir, depth, vacuum): name = material.get_name() cell = material.get_cell() atomlist = material.get_atom_list() if not cleave_dir: cleave_dir = 'C' axyz = cell.axyz bxyz = cell.bxyz cxyz = cell.cxyz if depth == 1 and vacuum == 0: return material # do nothing newname = "%s_slab" % name newmaterial = Material(newname) # # Replace abc -> uvw (w is the cleave direction) so we can # cleave in more general ways: # if cleave_dir == "C": uxyz = axyz vxyz = bxyz wxyz = cxyz idir = 2 elif cleave_dir == "B": uxyz = cxyz vxyz = axyz wxyz = bxyz idir = 1 elif cleave_dir == "A": uxyz = bxyz vxyz = cxyz wxyz = axyz idir = 0 wlength = sqrt(dot(wxyz, wxyz)) wscale = (wlength * depth + vacuum) / wlength nwxyz = wxyz * wscale for atom in atomlist: atno = atom.get_atno() xyz = atom.get_position() for k in range(depth): xyznew = xyz + k * wxyz xyznew[idir] += vacuum / 2. newmaterial.add_atom(Atom(atno, xyznew)) if abs(xyz[idir]) < 1e-2: # Periodic image of bottom: xyznew = xyz + depth * wxyz xyznew[idir] += vacuum / 2. newmaterial.add_atom(Atom(atno, xyznew)) # I can't tell whether I have to do the cyclic permutations here # i.e. output w,u,v in some cases. newmaterial.set_cell(Cell(uxyz, vxyz, nwxyz)) opts = getattr(material, "seqquest_options", {}) if opts: newmaterial.seqquest_options = opts.copy() opts = getattr(material, "socorro_options", {}) if opts: newmaterial.socorro_options = opts.copy() newmaterial.center() newmaterial.bonds_from_distance() return newmaterial
def normalize(a): return a / sqrt(dot(a, a))
def norm(a): return a/math.sqrt(dot(a,a)) def avg(vals): return sum(vals)/float(len(vals))
def get_position(self): return (self.x,self.y,self.z) def povray(self): return POVRay.Sphere((self.x,self.y,self.z),self.rad, (self.red,self.green,self.blue)) class Cylinder: name = 'Cylinder' def __init__(self,xyz1,xyz2, (red,green,blue)=(0.5,0.5,0.5),rad=CylRad, nsides=20): self.xyz1 = array(xyz1,'d') self.xyz2 = array(xyz2,'d') self.dxyz = self.xyz2-self.xyz1 self.length = math.sqrt(dot(self.dxyz,self.dxyz)) xd,yd,zd = self.dxyz/self.length self.rot = (-yd,xd,0) self.theta = math.acos(zd)*rad2deg self.rad = rad self.nsides = nsides self.red = red self.green = green self.blue = blue return def povray(self): return POVRay.Cylinder(tuple(self.xyz1),tuple(self.xyz2),self.rad, (self.red,self.green,self.blue)) def render(self): "Code that uses GLU"
def length(v): return sqrt(dot(v, v))
def place_atom(self, x, y): atno = self.parent.sketcher_window.atno if atno == -1: d = wx.MessageDialog( self, "Please select an element before attempting to place one", "No element selected", wx.ICON_ERROR) d.ShowModal() d.Destroy() return if self.parent.material.geo.atoms == []: size = self.GetClientSize() y = size.height - y p1 = array(gluUnProject(x, y, 0.0)) p2 = array(gluUnProject(x, y, 1.0)) dp = p2 - p1 u = -p1[2] / dp[2] np = p1 + u * dp sym = symbol[atno] label = sym + str(len(self.parent.material.geo.atoms)) new_atom = Atom(atno, np, sym, label) self.parent.material.add_atom(new_atom) self.parent.render() else: if self.shapes.selections == []: atom_index = self.pick_atom(x, y) if atom_index == -1: return self.placed_atom = self.parent.material.geo.atoms[atom_index] atom = self.shapes.atoms[atom_index] if atom.name == "Sphere": if atom.rad == 0.1: l = 6 * atom.rad else: l = 2 * atom.rad else: l = 0.4 color = (1.0, 1.0, 1.0) weight = 2 wc = WireCube(atom.get_position(), l, color, weight) self.shapes.selections.append(wc) self.InitGL() self.Refresh() else: atom_index = self.pick_atom(x, y) if atom_index == -1: size = self.GetClientSize() y = size.height - y p1 = array(gluUnProject(x, y, 0.0)) p2 = array(gluUnProject(x, y, 1.0)) r = self.camera.get_right() up = self.camera.get_up() Nx = up[1] * r[2] - up[2] * r[1] Ny = up[2] * r[0] - up[0] * r[2] Nz = up[0] * r[1] - up[1] * r[0] N = array((Nx, Ny, Nz)) p3 = array(self.placed_atom.get_position()) u = dot(N, (p3 - p1)) / dot(N, (p2 - p1)) dp = p2 - p1 np = p1 + u * dp atno = self.parent.sketcher_window.atno sym = symbol[atno] label = sym + str(len(self.parent.material.geo.atoms)) new_atom = Atom(atno, np, sym, label) self.parent.material.add_atom(new_atom) new_bond = Bond(self.placed_atom, new_atom) self.parent.material.add_bond(new_bond) else: this_atom = self.parent.material.geo.atoms[atom_index] if this_atom.get_position( ) != self.placed_atom.get_position(): new_bond = Bond(self.placed_atom, this_atom) self.parent.material.add_bond(new_bond) self.parent.render() return