def add_the_unit_cell(material, buffer): name = material.get_name() cell = material.get_cell() atoms = material.get_atom_list() if cell: return material # Don't do anything for now newname = "%s_cell" % name newmaterial = Material(newname) if not buffer: buffer = 2. # Can still set to a small value like 0.01 xmin, xmax, ymin, ymax, zmin, zmax = bbox_atoms(atoms, buffer) for atom in atoms: atno = atom.get_atno() xyz = atom.get_position() xyznew = array((xyz[0] - xmin, xyz[1] - ymin, xyz[2] - zmin)) newmaterial.add_atom(Atom(atno, xyznew)) newmaterial.set_cell( Cell((xmax - xmin, 0, 0), (0, ymax - ymin, 0), (0, 0, zmax - zmin))) 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.bonds_from_distance() return newmaterial
def build_the_supercell(material, ass, bss, css): if ass == 1 and bss == 1 and css == 1: return material name = material.get_name() cell = material.get_cell() atomlist = material.get_atom_list() axyz = cell.axyz bxyz = cell.bxyz cxyz = cell.cxyz newname = "%s%d%d%d" % (name, ass, bss, css) newmaterial = Material(newname) naxyz = ass * axyz nbxyz = bss * bxyz ncxyz = css * cxyz for atom in atomlist: atno = atom.get_atno() sym = atom.get_symbol() xyz = atom.get_position() for i in range(ass): for j in range(bss): for k in range(css): xyznew = xyz + i * axyz + j * bxyz + k * cxyz newmaterial.add_atom(Atom(atno, xyznew, sym)) newmaterial.set_cell(Cell(naxyz, nbxyz, ncxyz)) 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.bonds_from_distance() return newmaterial
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