def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material=Material(fileprefix) file=open(fullfilename, 'r') hatpat = re.compile('HETATM') atpat = re.compile('^ATOM') conpat = re.compile('^CONECT') ordpat = re.compile('^ORDER') endpat = re.compile('^END') ucpat = re.compile('^CRYSTX') bonds = {} orders = {} iat = 0 for line in open(fullfilename): if hatpat.search(line) or atpat.search(line): d1,i,d2,d3,d4,d5,x,y,z,attype,d6,d7,q = read(line,atom_format) xyz = array([x,y,z]) sym = cleansym(attype) atno = sym2no[sym] atom = Atom(atno,xyz,sym,sym+str(iat)) atom.fftype = attype # save just in case material.add_atom(atom) iat += 1 elif conpat.search(line): ats = map(int,line[6:].split()) index = ats[0]-1 bonds[index] = [atj-1 for atj in ats[1:]] orders[index] = [1]*(len(ats)-1) elif ordpat.search(line): ords = map(int,line[6:].split()) index = ords[0]-1 orders[index] = ords[1:] elif ucpat.search(line): words = line.split() a,b,c,alpha,beta,gamma = map(float,words[1:7]) axyz,bxyz,cxyz = abcabg2abc(a,b,c,alpha,beta,gamma) cell = Cell(axyz,bxyz,cxyz) material.set_cell(cell) atoms = material.get_atoms() #print len(atoms)," atoms loaded" for iat in bonds.keys(): bond_partners = bonds[iat] bond_orders = orders[iat] for jat,ij_order in zip(bond_partners,bond_orders): if jat > iat: material.add_bond(Bond(atoms[iat],atoms[jat], ij_order)) return material
def load(fullfilename): #TODO move this splitting to within Material so the extension can #automatically be the default prefix...then move it into structure filedir, fileprefix, fileext = path_split(fullfilename) from vimm.Material import Material from vimm.Atom import Atom from vimm.Cell import Cell material = Material(fileprefix) material.format = fileext pkl_file = open(fullfilename, 'rb') structure = pickle.load(pkl_file) first_run = 1 if first_run: first_run = 0 else: material.new_geo() for structureAtom in structure: material.add_atom(Atom(structureAtom.Z, structureAtom.xyz_cartn)) aVec, bVec, cVec = structure.lattice.base cell = Cell(aVec, bVec, cVec) material.set_cell(cell) material.bonds_from_distance() return material
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material = Material(fileprefix) file = open(fullfilename, 'r') line = file.readline() title = line.strip() line = file.readline() title2 = line.strip() line = file.readline() title3 = line.strip() line = file.readline() natoms = int(line[:3]) nbonds = int(line[3:6]) # Note: I'm skipping the H information here, which is # typically given in fields 5- for i in range(natoms): line = file.readline() words = line.split() xyz = array(map(float, words[:3])) sym = cleansym(words[3]) atno = sym2no[sym] material.add_atom(Atom(atno, xyz, sym, sym + str(i))) atoms = material.get_atoms() for i in range(nbonds): line = file.readline() words = line.split() # bond order is the third field, which I'm ignoring iat, jat, iorder = map(int, words[:3]) material.add_bond(Bond(atoms[iat - 1], atoms[jat - 1], iorder)) return material
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material=Material(fileprefix) file=open(fullfilename, 'r') first_run = 1 while 1: line = file.readline() if not line: break words = line.split() nat = int(words[0]) comment = file.readline() if first_run: first_run = 0 else: material.new_geo() for i in range(nat): line = file.readline() words=line.split() sym=cleansym(words[0]) atno = sym2no[sym] xyz = array(map(float,words[1:4])) material.add_atom(Atom(atno, xyz, sym, sym+str(i))) material.bonds_from_distance() return material
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material = Material(fileprefix) file = open(fullfilename, 'r') nwchem_options = {} geo_pat = re.compile("\s*No\.\s*Tag\s*Charge") molchg_pat = re.compile("\s*Charge\s*:\s*") multip_pat = re.compile("\s*Spin multiplicity:\s*") geos = [] while 1: line = file.readline() if not line: break if geo_pat.search(line): geo = get_geo(file) geos.append(geo) elif molchg_pat.search(line): words = string.split(line) nwchem_options['molchg'] = int(words[2]) elif multip_pat.search(line): words = string.split(line) nwchem_options['multip'] = int(words[2]) # end of main infinite loop file.close() print "Loading %d geometries" % len(geos) for igeo in range(len(geos)): if igeo: material.new_geo() for (atno, xyz) in geos[igeo]: material.add_atom(Atom(atno, xyz)) if len(material.geo.atoms) < 200: material.bonds_from_distance() material.nwchem_options = nwchem_options return material
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material = Material(fileprefix) file = open(fullfilename, 'r') atoms = [] bfs = [] orbs = [] mode = None for line in file.readlines(): if atpat.search(line): mode = 'atoms' elif bfpat.search(line): mode = 'bfs' elif orbpat.search(line): mode = 'orbs' elif mode == 'atoms': atoms.append(line) elif mode == 'bfs': bfs.append(line) elif mode == 'orbs': orbs.append(line) else: print '? ', line, for line in atoms: words = line.split() if len(words) < 6: continue atno = int(words[2]) xyz = map(float, words[3:6]) material.add_atom(Atom(atno, array(xyz))) material.bonds_from_distance() material.geo.basis = parse_basis(bfs) material.geo.orbs = parse_orbs(orbs) return material
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 load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material=Material(fileprefix) file=open(fullfilename, 'r') first_run = 1 while 1: line = file.readline() if not line: break if not geostart.search(line): continue if first_run: first_run = 0 else: material.new_geo() i = 1 while 1: line = file.readline() if geoend.search(line): break match = atpat.match(line) sym = match.group(1) x = float(match.group(2)) y = float(match.group(3)) z = float(match.group(4)) sym=cleansym(sym) atno = sym2no[sym] xyz = array((x,y,z)) material.add_atom(Atom(atno, xyz, sym, sym+str(i))) i += 1 material.bonds_from_distance() return material
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material = Material(fileprefix) file = open(fullfilename, 'r') line = file.readline() title = line.strip() line = file.readline() natoms, nbonds = map(int, line.split()) for i in range(natoms): line = file.readline() words = line.split() xyz = array(map(float, words[:3])) sym = cleansym(words[3]) atno = sym2no[sym] material.add_atom(Atom(atno, xyz, sym, sym + str(i))) atoms = material.get_atoms() for i in range(nbonds): line = file.readline() words = line.split() # I think order is the third one, but I'm not sure iat, jat, iorder = map(int, words[:3]) material.add_bond(Bond(atoms[iat - 1], atoms[jat - 1], iorder)) return material
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material = Material(fileprefix) file = open(fullfilename, 'r') first_run = True while 1: line = file.readline() if not line: break words = line.split() nat = int(words[0]) comment = file.readline() ax, ay, az, bx, by, bz, cx, cy, cz = [ float(i) for i in comment.split() ] cell = Cell((ax, ay, az), (bx, by, bz), (cx, cy, cz)) if first_run: first_run = False else: material.new_geo() material.set_cell(cell) for i in range(nat): line = file.readline() words = line.split() sym = cleansym(words[0]) atno = sym2no[sym] xyz = array(map(float, words[1:4])) material.add_atom(Atom(atno, xyz, sym, sym + str(i))) material.bonds_from_distance() return material
def build_the_alkane(n): atoms = alkanebuilder(n) if not n: n = 1 nc = 2 * n + 2 nh = 2 * nc + 2 material = Material("C%dH%d" % (nc, nh)) for atno, xyz in atoms: material.add_atom(Atom(atno, xyz)) material.bonds_from_distance() return material
def build_the_crystal(crystal_type, sym1, sym2, a, c_a): uc, atoms = builders[crystal_type](a, c_a, sym1, sym2) material = Material(crystal_type.replace(' ', '_')) for sym, (x, y, z) in atoms: atno = sym2no[sym] material.add_atom(Atom(atno, array((x, y, z)))) cell = Cell(uc[0], uc[1], uc[2]) material.set_cell(cell) material.bonds_from_distance() return material
def build_the_crystal_from_db(crystal_type): uc, atoms = crystal_type_dict[crystal_type] material = Material(crystal_type.replace(' ', '_')) for sym, (x, y, z) in atoms: atno = sym2no[sym] material.add_atom(Atom(atno, array((x, y, z)), sym)) cell = Cell(uc[0], uc[1], uc[2]) material.set_cell(cell) material.bonds_from_distance() return material
def parse_cart(lines): material = Material("vimm") for line in lines: words = line.split() if not words: continue sym = str(words[0]) atno = sym2no[sym] xyz = array(map(float, words[1:4])) material.add_atom(Atom(atno, xyz, sym, sym)) material.bonds_from_distance() return material
def get_periodic_images(self): img_cutoff = 0.1 #Angs- distance cutoff for an image to be # near a uc boundary if not self.cell: return axyz = self.cell.axyz bxyz = self.cell.bxyz cxyz = self.cell.cxyz #conv = self.cell.cart2lat_factory() # lattice translations I = [(1,0,0)] J = [(0,1,0)] IJ = [(1,0,0),(0,1,0),(1,1,0)] K = [(0,0,1)] IK = [(1,0,0),(0,0,1),(1,0,1)] JK = [(0,1,0),(0,0,1),(0,1,1)] IJK = [(1,0,0),(0,1,0),(1,1,0),(0,0,1),(1,0,1),(0,1,1),(1,1,1)] atoms = self.atoms nimages = len(atoms)+1 # The 1 really is necessary here! for atom in atoms: atno = atom.get_atno() xyz = atom.get_position() # The right way to do this is to convert to lattice # coords and test those for being near 0 or 1 #xl,yl,zl = conv(x,y,z) x,y,z = xyz if abs(x) < img_cutoff: if abs(y) < img_cutoff: if abs(z) < img_cutoff: directions = IJK else: directions = IJ else: if abs(z) < img_cutoff: directions = IK else: directions = I else: if abs(y) < img_cutoff: if abs(z) < img_cutoff: directions = JK else: directions = J else: if abs(z) < img_cutoff: directions = K else: directions = [] for i,j,k in directions: xyznew = xyz + i*axyz + j*bxyz + k*cxyz self.add_image(Atom(atno,xyznew)) return
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material=Material(fileprefix) try: from matter.Structure import Structure st = Structure() st.read(fullfilename) for i,atom in enumerate(st): Z = atom.Z xyz_cartn = atom.xyz_cartn sym = atom.symbol material.add_atom(Atom(Z, xyz_cartn, sym, sym+str(i))) material.bonds_from_distance() lvs = st.lattice.base cell = Cell(lvs[0],lvs[1],lvs[2]) material.set_cell(cell) return material except: print 'Vimm needs matter package from pypi to open cif files' return
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material = Material(fileprefix) parser = CMLParser() geos = parser.process(fullfilename) molecule = geos[0] atoms = molecule.atoms cell = molecule.cell nat = len(atoms) for i in range(nat): sym, pos = atoms[i] pos = array(pos) atno = sym2no[sym] material.add_atom(Atom(atno, pos, sym, sym + str(i))) if cell: the_cell = Cell(cell[0], cell[1], cell[2]) material.set_cell(the_cell) material.bonds_from_distance() return material
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 load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) material=Material(fileprefix) curresnum = None curres = None locator = None residues = [] for line in open(fullfilename): tag = line[:6].strip() if tag == 'ATOM' or tag == 'HETATM': loctag = line[16:17].strip() resnum = int(line[22:26]) modifyer = line[26].strip() restag = line[18:21].strip() x = float(line[30:38]) y = float(line[38:46]) z = float(line[46:54]) xyz = array([x,y,z]) try: sym = line[13:15].strip() sym = symconv[sym] atno = sym2no[sym] except: sym = line[12:15].strip() atno = sym2no[sym] if loctag: if not locator: locator = loctag if loctag and loctag != locator: continue if modifyer: continue # skip residue #25B if we already have #25 material.add_atom(Atom(atno,xyz)) elif tag == 'CRYST1': words = line.split() a,b,c,alpha,beta,gamma = map(float,words[1:7]) #finish material.bonds_from_distance() return material
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
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) file = open(fullfilename, 'r') # Initialize atom data material = Material(fileprefix) element = [] # Initialize element variable to be appended timestamp = 1 nat = None cell = None lattice_coords = False scale = 1. scalez = 1. conv_to_ang = True while 1: line = file.readline() if not line: break if p_atomtype.search(line): # From the headerfile get the number of atom types line = file.readline() numberoftypes = int(line) elif p_coord_type.search(line): line = file.readline() line = line.strip().lower() if line == 'lattice': lattice_coords = True elif p_to_lattice.search(line): raise "Quest to_lattice flags not currently supported" elif p_scale.search(line): line = file.readline() scale = float(line.strip()) elif p_scalez.search(line): line = file.readline() scalez = float(line.strip()) # Using the atom type number, set the atom names elif p_atomfile.search(line): line = file.readline() words = string.split(line) atomname = cleansym(words[0]).capitalize() #atomname,atomext = path.splitext(words[0]) #atomname = string.capitalize(atomname) # Captitalize the element.append(atomname) # first letter elif p_nat.search(line): line = file.readline() words = string.split(line) nat = int(words[0]) # Read in the initial geometry data elif p_geometry.search(line): for i in range(nat): line = file.readline() words = string.split(line) num = int(words[0]) try: type = element[int(words[1]) - 1] #Set the type atno = sym2no[type] except: # Fallback for when atoms are specified with symbols atno = sym2no[words[1]] x, y, z = [float(i) for i in words[2:5]] #print x,y,z if lattice_coords: converter = cell.lat2cart_factory() x, y, z = converter(x, y, z) #print x,y,z elif conv_to_ang: x, y, z = [bohr2ang * i for i in [x, y, z]] #print x,y,z xyz = array((x, y, z)) material.add_atom(Atom(atno, xyz)) if cell: material.set_cell(cell) elif p_newgeo.search(line): comment = file.readline() material.new_geo() for i in range(nat): line = file.readline() words = string.split(line) num = int(words[0]) try: type = element[int(words[1]) - 1] #Set the type atno = sym2no[type] except: # Fallback for when atoms are specified with symbols atno = sym2no[words[1]] x, y, z = [float(i) for i in words[2:5]] #print x,y,z if lattice_coords: converter = cell.lat2cart_factory() x, y, z = converter(x, y, z) #print x,y,z elif conv_to_ang: x, y, z = [bohr2ang * i for i in [x, y, z]] #print x,y,z xyz = array((x, y, z)) material.add_atom(Atom(atno, xyz)) if cell: material.set_cell(cell) elif p_cell.search(line): line = file.readline() words = string.split(line) ax, ay, az = [float(i) for i in words[:3]] if conv_to_ang: ax, ay, az = [bohr2ang * i for i in [ax, ay, az]] line = file.readline() words = string.split(line) bx, by, bz = [float(i) for i in words[:3]] if conv_to_ang: bx, by, bz = [bohr2ang * i for i in [bx, by, bz]] line = file.readline() words = string.split(line) cx, cy, cz = [float(i) for i in words[:3]] if conv_to_ang: cx, cy, cz = [bohr2ang * i for i in [cx, cy, cz]] cell = Cell((ax, ay, az), (bx, by, bz), (cx, cy, cz), scale=scale, scalez=scalez) file.close() material.bonds_from_distance() return material
def parse_zmat(lines): material = Material("vimm") for line in lines: words = line.split() if len(words) == 0: continue sym = words[0] if len(words) == 1: # Atom at origin x = y = z = 0 elif len(words) == 3: # Atom along z-axis x = y = 0 iat = int(words[1]) - 1 assert iat == 0 r = float(words[2]) z = r elif len(words) == 4: # This line contains a simple list of cartesian coordinates x, y, z = map(float, words[1:]) elif len(words) == 5: # Atom in xy-plane y = 0 iat = int(words[1]) - 1 r = float(words[2]) jat = int(words[3]) - 1 theta = float(words[4]) * deg2rad # Change this to simply use the numpy object: x0, y0, z0 = material.get_atom(iat).get_xyz() x = x0 + r * sin(theta) if iat == 0: z = z0 + r * cos(theta) else: z = z0 - r * cos(theta) else: # General case iat = int(words[1]) - 1 r = float(words[2]) jat = int(words[3]) - 1 theta = float(words[4]) * deg2rad kat = int(words[5]) - 1 phi = float(words[6]) * deg2rad # Change these to simply use the numpy object: xi, yi, zi = material.get_atom(iat).get_xyz() xj, yj, zj = material.get_atom(jat).get_xyz() xk, yk, zk = material.get_atom(kat).get_xyz() # Change these to use numpy math: # Vector from iat -> jat xx = xj - xi yy = yj - yi zz = zj - zi rinv = 1 / sqrt(xx * xx + yy * yy + zz * zz) xa = xx * rinv ya = yy * rinv za = zz * rinv # Vector from iat -> kat xb = xk - xi yb = yk - yi zb = zk - zi # Unit vector from iat -> kat xc = ya * zb - za * yb yc = za * xb - xa * zb zc = xa * yb - ya * xb rinv = 1 / sqrt(xc * xc + yc * yc + zc * zc) xc *= rinv yc *= rinv zc *= rinv xb = yc * za - zc * ya yb = zc * xa - xc * za zb = xc * ya - yc * xa zz = r * cos(theta) xx = r * sin(theta) * cos(phi) yy = r * sin(theta) * sin(phi) x = xi + xa * zz + xb * xx + xc * yy y = yi + ya * zz + yb * xx + yc * yy z = zi + za * zz + zb * xx + zc * yy atno = sym2no[sym] xyz = array([x, y, z]) material.add_atom(Atom(atno, xyz, sym, sym)) material.bonds_from_distance() return material
def load(fullfilename): filedir, fileprefix, fileext = path_split(fullfilename) file = open(fullfilename, 'r') # Initialize atom data material = Material(fileprefix) opts = {} material.seqquest_options = opts line = file.readline() # start reading # Read in the run options while 1: if line[:8] == 'output l': line = file.readline() opts['lvlout'] = int(line.strip()) line = file.readline() elif line[:8] == 'do setup': opts['dosetup'] = True line = file.readline() elif line[:8] == 'no setup': opts['dosetup'] = False line = file.readline() elif line[:8] == 'do iters': opts['doiters'] = True line = file.readline() elif line[:8] == 'no iters': opts['doiters'] = False line = file.readline() elif line[:8] == 'do force': opts['doforce'] = True line = file.readline() elif line[:8] == 'no force': opts['doforce'] = False line = file.readline() elif line[:8] == 'do relax': opts['dorelax'] = True line = file.readline() elif line[:8] == 'no relax': opts['dorelax'] = False line = file.readline() elif line[:7] == 'do cell': opts['docell'] = True line = file.readline() elif line[:7] == 'no cell': opts['docell'] = False line = file.readline() elif line[:6] == 'do neb': opts['doneb'] = True line = file.readline() elif line[:6] == 'no neb': opts['doneb'] = False line = file.readline() elif line[:5] == 'do md': opts['domd'] = True line = file.readline() elif line[:5] == 'no md': opts['domd'] = False line = file.readline() elif line[:7] == 'do post': opts['dopost'] = True line = file.readline() elif line[:7] == 'no post': opts['dopost'] = False line = file.readline() elif line[:7] == 'do blas': opts['doblas3'] = True line = file.readline() elif line[:7] == 'no blas': opts['doblas3'] = False line = file.readline() else: # Comment this out when debugged: print "Unknown line from command section" print line, print "Assuming end of Input Options Section" break # end of run options # Beginning of setup info if line[:6] == 'input ': line = file.readline() # skip line # Title if line[:5] == 'title': opts['title'] = [] try: ntitl = int(line[5]) except: ntitl = 1 for i in range(ntitl): line = file.readline() opts['title'].append(line.strip()) line = file.readline() if line[:5] == 'scale': line = file.readline() opts['scalep'] = float(line.strip()) line = file.readline() # DFT fcnal if line[:6] == 'functi': line = file.readline() opts['dft_func'] = line.strip() line = file.readline() # Spin polarization if line[:6] == 'spin p': line = file.readline() opts['spinpol'] = int(line.strip()) #should put an error condition here if dft requires # spin and no spinpol input line = file.readline() # External electric field if line[:6] == 'efield': line = file.readline() ex, ey, ez = map(float, line.split()) opts['efield'] = (ex, ey, ez) # in Ry/au line = file.readline() # External dielectric constant if line[:6] == 'dielec': line = file.readline() opts['dielec'] = float(line.split()) line = file.readline() # Problem dimension if line[:6] == 'dimens' or line[:6] == 'lattic': line = file.readline() opts['ndim'] = int(line.strip()) line = file.readline() else: print line raise "Dimension must be specified in Quest input" # Coordinates (lattice or cartesian) if line[:6] == 'coordi': line = file.readline() opts['coordi'] = line.strip() line = file.readline() # Problem scaling # RPM: Need to do a better job of this: #if line[:6] == 'scalep' or (line[:5] == 'scale' and len(line) == 5): if line[:6] == 'scalep' or line[:6] == 'scale\n': line = file.readline() opts['scalep'] = float(line.strip()) line = file.readline() if line[:6] == 'scaleu': line = file.readline() opts['scaleu'] = float(line.strip()) line = file.readline() if line[:6] == 'scalex': line = file.readline() opts['scalex'] = float(line.strip()) line = file.readline() if line[:6] == 'scaley': line = file.readline() opts['scaley'] = float(line.strip()) line = file.readline() if line[:6] == 'scalez': line = file.readline() opts['scalez'] = float(line.strip()) line = file.readline() # Strain if line[:6] == 'strain': line = file.readline() xx, xy, xz = map(float, line.split()) line = file.readline() yx, yy, yz = map(float, line.split()) line = file.readline() zx, zy, zz = map(float, line.split()) opts['strain'] = (xx, xy, xz, yx, yy, yz, zx, zy, zz) line = file.readline() if line[:6] == 'strfac': line = file.readline() opts['strfac'] = float(line.strip()) line = file.readline() # Lattice vectors: if line[:6] == 'primit': line = file.readline() ax, ay, az = map(float, line.split()) axyz = ax * bohr2ang, ay * bohr2ang, az * bohr2ang line = file.readline() bx, by, bz = map(float, line.split()) bxyz = bx * bohr2ang, by * bohr2ang, bz * bohr2ang line = file.readline() cx, cy, cz = map(float, line.split()) cxyz = cx * bohr2ang, cy * bohr2ang, cz * bohr2ang cell = Cell(axyz, bxyz, cxyz) line = file.readline() # grid dimensions if line[:6] == 'grid d' or line[:6] == 'points': line = file.readline() opts['griddim'] = map(int, line.split()) line = file.readline() # nearby function if line[:6] == 'nearby': line = file.readline() opts['nearby'] = int(line.strip()) line = file.readline() # number of atom types if line[:6] == 'atom t': line = file.readline() opts['ntyp'] = int(line.strip()) opts['types'] = [] line = file.readline() else: print line, len(line) raise "Number of atom types must be specified" # atom types: for i in range(opts['ntyp']): if line[:6] == 'atom f': line = file.readline() opts['types'].append(line.strip()) line = file.readline() else: raise "Error: expecting another atom file" # number of atoms if line[:6] == 'number': line = file.readline() opts['nat'] = int(line.strip()) line = file.readline() if line[:6] == 'atom, ': for i in range(opts['nat']): line = file.readline() words = line.split() inum = int(words[0]) ityp = int(words[1]) x, y, z = map(float, words[2:5]) xyz = x * bohr2ang, y * bohr2ang, z * bohr2ang xyz = array(xyz) sym = cleansym(opts['types'][ityp - 1]) atno = sym2no[sym] material.add_atom(Atom(atno, xyz)) line = file.readline() material.set_cell(cell) material.bonds_from_distance() else: raise "Error: expected atom listing here" # to lattice/to cartesian if line[:6] == 'to_lat': opts['to_lat'] = True line = file.readline() elif line[:6] == 'to_car': opts['to_car'] = True line = file.readline() # origin offset if line[:6] == 'origin': line = file.readline() opts['dorig'] = map(float, line.split()) line = file.readline() # wigner-seitz origin if line[:6] == 'wigner': line = file.readline() opts['rchrg'] = map(float, line.split()) line = file.readline() # center of symmetry if line[:6] == 'symmet': line = file.readline() opts['rsym'] = map(float, line.split()) line = file.readline() # bloch info if line[:5] == 'kgrid': line = file.readline() opts['kgrid'] = map(int, line.split()) line = file.readline() elif line[:4] == 'khex': line = file.readline() opts['khex'] = map(int, line.split()) line = file.readline() # skipping more detailed bloch info for now if line[:6] == 'n bloc': line = file.readline() opts['nk'] = int(line.strip()) line = file.readline() if line[:6] == 'scalin': line = file.readline() opts['scalin'] = map(float, line.split()) line = file.readline() if line[:6] == 'lattic': line = file.readline() opts['bloch_lattic'] = map(float, line.split()) line = file.readline() elif line[:6] == 'cartes': line = file.readline() opts['bloch_cartes'] = map(float, line.split()) line = file.readline() if line[:6] == 'bloch ': opts['bloch_vecs'] = [] for i in range(opts['nk']): line = file.readline() opts['bloch_vecs'].append(map(float, line.split())) line = file.readline() # symmetry info if line[:6] == 'symops': line = file.readline() opts['nsymi'] = int(line.strip()) line = file.readline() if line[:6] == 'defini': opts['symvecs'] = [] for i in range(opts['nsymi']): line = file.readline() words = line.split() type = int(words[0]) s1, s2, s3, s4, s5, s6 = map(float, words[1:]) opts['symvecs'].append((type, s1, s2, s3, s4, s5, s6)) line = file.readline() if line[:6] == 'end se': line = file.readline() else: raise "Expected end setup phase tag" # End of setup info # Beginning of Run Data if line[:6] == 'run ph': while 1: line = file.readline() if not line: break if line[:6] == 'end ru' or line[:6] == 'end of': break elif line[:6] == 'do fla': opts['doflag'] = True elif line[:6] == 'no fla': opts['doflag'] = False elif line[:6] == 'first ': line = file.readline() opts['itstart'] = int(line.strip()) elif line[:6] == 'last i': line = file.readline() opts['itstop'] = int(line.strip()) elif line[:6] == 'histor': line = file.readline() opts['nhiste'] = int(line.strip()) elif line[:6] == 'restar': line = file.readline() opts['itrst'] = int(line.strip()) elif line[:6] == 'states': line = file.readline() opts['nstate'] = int(line.strip()) elif line[:6] == 'temper': line = file.readline() opts['etemp'] = float(line.strip()) elif line[:6] == 'blend ' or line[:6] == 'percen': line = file.readline() opts['scfblnd'] = float(line.strip()) elif line[:6] == 'scfbl2': line = file.readline() opts['scfbl2'] = float(line.strip()) elif line[:6] == 'conver': line = file.readline() opts['scfconv'] = float(line.strip()) elif line[:6] == 'alfast': line = file.readline() opts['alfast'] = float(line.strip()) elif line[:6] == 'cutii ': line = file.readline() opts['convii'] = float(line.strip()) elif line[:6] == 'cutslo': line = file.readline() opts['convsl'] = float(line.strip()) elif line[:6] == 'cut2s ': line = file.readline() opts['conv2s'] = float(line.strip()) elif line[:6] == 'cutset': line = file.readline() opts['cutset'] = float(line.strip()) elif line[:6] == 'cutfrc': line = file.readline() opts['cutfrc'] = float(line.strip()) elif line[:6] == 'cutgrd': line = file.readline() opts['convgr'] = float(line.strip()) elif line[:6] == 'cut1c ': line = file.readline() opts['conv1c'] = float(line.strip()) elif line[:6] == 'geomet': # Jump into Geometry Data opts['write_geo_sect'] = True while 1: line = file.readline() if line[:4] == 'stop' or line[:3] == 'end': break elif line[:6] == 'relax ': opts['dorelax'] = True opts['geo_dorelax'] = True elif line[:6] == 'grelax': line = file.readline() opts['relax_range'] = map(int, line.split()) elif line[:6] == 'gfixed': line = file.readline() opts['fixed_range'] = map(int, line.split()) elif line[:6] == 'only r': line = file.readline() opts['only_relax'] = int(line.strip()) elif line[:6] == 'frame ': line = file.readline() opts['relax_frame'] = map(int, line.split()) elif line[:6] == 'defect': line = file.readline() opts['defect'] = int(line.strip()) elif line[:6] == 'gblend': line = file.readline() opts['gblend'] = float(line.strip()) elif line[:5] == 'gconv': line = file.readline() opts['gconv'] = float(line.strip()) elif line[:6] == 'gstart': line = file.readline() opts['gstart'] = int(line.strip()) elif line[:6] == 'gsteps': line = file.readline() opts['gsteps'] = int(line.strip()) elif line[:6] == 'ghisto': line = file.readline() opts['nhistg'] = int(line.strip()) elif line[:6] == 'no ges': opts['igges'] = 0 elif line[:6] == 'guess ': line = file.readline() opts['igges'] = int(line.strip()) elif line[:6] == 'gmetho': line = file.readline() opts['gmethod'] = line.strip() elif line[:6] == 'timest': line = file.readline() opts['gtstep'] = float(line.strip()) else: print "Unknown geomdata line:" print line # End of Geometry Data elif line[:5] == 'cell ': # Jump into Cell Data opts['write_cell_sect'] = True while 1: line = file.readline() if line[:6] == 'end ce': break elif line[:6] == 'ucstep': line = file.readline() opts['maxucsteps'] = int(line.strip()) elif line[:6] == 'ucconv': line = file.readline() opts['ucconv'] = float(line.strip()) elif line[:6] == 'pressu': line = file.readline() opts['pressure'] = float(line.strip()) elif line[:6] == 'uniaxi': line = file.readline() opts['uniaxial'] = map(float, line.split()) elif line[:6] == 'stress': opts['stress'] = [] for i in range(opts['ndim']): line = file.readline() opts['stress'].append(map(float, line.split())) elif line[:6] == 'uchist': line = file.readline() opts['nhistuc'] = int(line.strip()) elif line[:6] == 'ucmeth': line = file.readline() opts['ucmeth'] = line.strip() elif line[:6] == 'str_br': line = file.readline() opts['strsbroy'] = float(line.strip()) elif line[:6] == 'max_st': line = file.readline() opts['strnmax'] = float(line.strip()) elif line[:6] == 'cell_f': line = file.readline() opts['cell_f'] = float(line.strip()) elif line[:6] == 'bulk_m': line = file.readline() opts['bmod'] = float(line.strip()) elif line[:6] == 'uc_ble': line = file.readline() opts['ucblend'] = float(line.strip()) else: print "Unknown celldata line:" print line # End of Cell Data else: print "Unknown rundata line:" print line # End of Run Data # Start of MD Data line = file.readline() if line[:6] == 'md dat': while 1: line = file.readline() if line[:3] == 'end': break elif line[:6] == 'temper': line = file.readline() opts['mdtemp'] = float(line.strip()) elif line[:6] == 'time s': line = file.readline() opts['ntstep'] = int(line.strip()) elif line[:6] == 'equil ': line = file.readline() opts['neqsteps'] = int(line.strip()) elif line[:6] == 'step s': line = file.readline() opts['md_dt'] = float(line.strip()) elif line[:6] == 'md typ': line = file.readline() opts['mdtype'] = line.strip() else: print "Unknown md flag" print line return material
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 load(fullfilename,**kwargs): # Keyword args VERBOSE = kwargs.get('VERBOSE',False) filedir, fileprefix, fileext = path_split(fullfilename) material=Material(fileprefix) # Pass 1: check ndtset ndtset = 0 natom = 0 ntypat = 0 dt = 1 iter = abinit_tokenizer(open(fullfilename),**kwargs) while 1: try: word = iter.next() except: break if word == 'ndtset': ndtset = int(iter.next()) if ndtset > 1: print "Multiple data sets found. Reading only the first" # If you want to select a particular data set, pop # up a dialog box here and ask which one you # want to load. # Also need to put code in here so that you don't # get the dialog box twice, such as dt_selected # boolean elif word == 'natom': natom = int(iter.next()) elif word == 'ntypat': ntypat = int(iter.next()) # Pass 2: get remaining info xangst = None xred = None xcart = None znucl = None typat = None rprim = None acell = None angdeg = None iter = abinit_tokenizer(open(fullfilename),**kwargs) while 1: try: word = iter.next() except: break if word == 'xangst' or word == 'xangst%d' % dt: xangst = get_natom3(iter,natom) elif word == 'xred' or word == 'xred%d' % dt: xred = get_natom3(iter,natom) elif word == 'xcart' or word == 'xcart%d' % dt: xcart = get_natom3(iter,natom) elif word == 'znucl': znucl = [int(float(i)) for i in nextn(iter,ntypat)] elif word == 'typat': typat = [int(i) for i in nextn(iter,natom)] elif word == 'acell' or word == 'acell%d' % dt: acell = [float(i) for i in nextn(iter,3)] elif word == 'rprim' or word == 'rprim%d' % dt: rprim = [float(i) for i in nextn(iter,9)] elif word == 'angdeg' or word == 'angdeg%d' % dt: angdeg = [float(i) for i in nextn(iter,3)] # Done parsing if VERBOSE: print "natom = ",natom print "ntypat = ",ntypat print "znucl = ",znucl print "typat = ",typat print "xcart = ",xcart print "xred = ",xred print "xangst = ",xangst print "acel = ",acell print "rprim = ",rprim print "angdeg = ",angdeg # Build the unit cell. Precedence is rprim > angdeg if not acell: acell = [1,1,1] acell = [bohr2ang*i for i in acell] # Convert acell to Angstrom if rprim: ax,ay,az,bx,by,bz,cx,cy,cz = rprim cell = Cell( (acell[0]*ax,acell[0]*ay,acell[0]*az), (acell[1]*bx,acell[1]*by,acell[1]*bz), (acell[2]*cx,acell[2]*cy,acell[2]*cz)) else: if not angdeg: angdeg = [90.,90.,90.] axyz,bxyz,cxyz = abcabg2abc(acell[0],acell[1],acell[2], angdeg[0],angdeg[1],angdeg[2]) cell = Cell(axyz,bxyz,cxyz) material.set_cell(cell) # Build the atom list. Precedence is xred > xangst > xcart if xred: A,B,C = cell.abc() for i in range(natom): atno = znucl[typat[i-1]-1] xr,yr,zr = xred[i] xyz = xr*A + yr*B + zr*C material.add_atom(Atom(atno,xyz)) elif xangst: for i in range(natom): atno = znucl[typat[i-1]-1] material.add_atom(Atom(atno,xangst[i])) elif xcart: for i in range(natom): atno = znucl[typat[i-1]-1] xyz = [bohr2ang*a for a in xcart[i]] material.add_atom(Atom(atno,xyz)) else: raise "Abinit Input: must specify xred, xangst, or xcart" material.bonds_from_distance() return material
def load(fullfilename): gstep = 0 filedir, fileprefix, fileext = path_split(fullfilename) file=open(fullfilename, 'r') # Initialize atom data material = Material(fileprefix) opts = {} material.seqquest_options = opts dconv = 1. # default to Angstroms, which don't need conversion cell = None while 1: line = file.readline() if not line: break line = line.strip() if line == '@=KEYCHAR': continue # ignore other keychars for now elif line == '@DISTANCE UNIT': line = file.readline().strip() if line == 'ANGSTROM': continue elif line == 'BOHR': dconv = bohr2ang else: print "Warning: unknown distance unit ",line elif line == '@DIMENSION': line = file.readline().strip() opts['ndim'] = int(line) elif line == '@NUMBER OF ATOMS': line = file.readline().strip() opts['nat'] = int(line) opts['attypes'] = [] nread = int(ceil(opts['nat']/20.)) for i in range(nread): line = file.readline().strip() opts['attypes'].extend(map(int,line.split())) assert len(opts['attypes']) == opts['nat'] elif line == '@TYPES': line = file.readline().strip() opts['ntyp'] = int(line) opts['types'] = [] for i in range(opts['ntyp']): line = file.readline().strip() opts['types'].append(cleansym(line)) elif line == '@CELL VECTORS': line = file.readline() axyz = map(float,line.split()) line = file.readline() bxyz = map(float,line.split()) line = file.readline() cxyz = map(float,line.split()) if abs(dconv-1) > 1e-4: # careful when comparing floats axyz = axyz[0]*dconv,axyz[1]*dconv,axyz[2]*dconv bxyz = bxyz[0]*dconv,bxyz[1]*dconv,bxyz[2]*dconv cxyz = cxyz[0]*dconv,cxyz[1]*dconv,cxyz[2]*dconv cell = Cell(axyz,bxyz,cxyz) elif line == '@GSTEP': line = file.readline().strip() gstep = int(line) elif line == '@COORDINATES': atoms = [] for i in range(opts['nat']): line = file.readline() xyz = map(float,line.split()) if abs(dconv-1) > 1e-4: # careful when comparing floats xyz = xyz[0]*dconv,xyz[1]*dconv,xyz[2]*dconv isym = opts['attypes'][i] sym = opts['types'][isym-1] atoms.append((sym,xyz)) if gstep > 1: material.new_geo() for i in range(opts['nat']): sym,xyz = atoms[i] atno = sym2no[sym] xyz = array(xyz) material.add_atom(Atom(atno,xyz)) if cell: material.set_cell(cell) elif line == '@ESCF': line = file.readline().strip() escf = float(line) # Consider saving these for plotting elif line == '@FORCES': forces = [] for i in range(opts['nat']): line = file.readline() forces.append(map(float,line.split())) elif line == '@FMAX': line = file.readline().strip() fmax = float(line) elif line == '@FRMS': line = file.readline().strip() frms = float(line) else: print "Unknown line ",line material.bonds_from_distance() return material
def ZMatrix(zatoms): natoms = len(zatoms) atoms = [] # keep a running track of the labels for reference labels = {} for i in range(natoms): zatom = zatoms[i] if type(zatom) == type(''): label = zatom else: label = zatom[0] assert label not in labels sym = cleansym(label) atno = sym2no[sym] if i == 0: x, y, z = 0.0, 0.0, 0.0 elif i == 1: label1 = zatom[1] assert label1 in labels r = zatom[2] x, y, z = r, 0, 0 elif i == 2: label1 = zatom[1] assert label1 in labels atom1 = labels[label1] x1, y1, z1 = atom1.xyz r = zatom[2] label2 = zatom[3] assert label2 in labels atom2 = labels[label2] x2, y2, z2 = atom2.xyz if abs(x2 - x1) < 1e-5: thetap = pi else: thetap = atan((y2 - y1) / (x2 - x1)) if x2 < x1: thetap += pi theta = zatom[4] * deg2rad ang = theta + thetap rc = r * cos(ang) rs = r * sin(ang) x, y, z = x1 + rc, y1 + rs, z1 else: label1 = zatom[1] assert label1 in labels atom1 = labels[label1] r = zatom[2] label2 = zatom[3] assert label2 in labels atom2 = labels[label2] theta = zatom[4] * deg2rad label3 = zatom[5] assert label3 in labels atom3 = labels[label3] phi = zatom[6] * deg2rad v12 = atom1.xyz - atom2.xyz v13 = atom1.xyz - atom3.xyz n = cross(v12, v13) nn = cross(v12, n) n = normalize(n) nn = normalize(nn) n = -n * sin(phi) nn = nn * cos(phi) v3 = normalize(n + nn) v3 = v3 * r * sin(theta) v12 = normalize(v12) v12 = v12 * r * cos(theta) v2 = atom1.xyz + v3 - v12 x, y, z = v2 atom = Atom(atno, array((x, y, z)), label) atoms.append(atom) labels[label] = atom return atoms
def create_nanotube_material(n, m, ncells): bondlength = 1.35 # Angstroms buffer = 2 # Angstroms to pack around nt in uc np, nq, ndr = gen11(n, m) rt3 = sqrt(3) a = rt3 * bondlength r = a * sqrt(np * np + nq * nq + np * nq) c = a * sqrt(n * n + m * m + n * m) t = rt3 * c / ndr rs = c / 2 / pi nn = 2 * (n * n + m * m + n * m) / ndr # hexagons in unit cell N #print 'Nanotube unit cell length ',t #print 'Nanotube radius ',rs #print 'Nanotube unit cell atoms ',nn*2 q1 = atan((rt3 * m) / (2 * n + m)) # Chiral angle for C_h q2 = atan((rt3 * nq) / (2 * np + nq)) # Chiral angle for R q3 = q1 - q2 # Angle btw C_h and R q4 = 2 * pi / nn # Period of angle for A atom q5 = bondlength * cos(pi / 6 - q1) / c * 2 * pi # diff of the angle btw A and B atoms h1 = abs(t) / abs(sin(q3)) h2 = bondlength * sin(pi / 6 - q1) # dz btw A and B atoms xyz = [] for i in range(nn): # A atom k = int(i * abs(r) / h1) x1 = rs * cos(i * q4) y1 = rs * sin(i * q4) z1 = (i * abs(r) - k * h1) * sin(q3) kk2 = abs(int(z1 / t)) + 1 # Insure A in unit cell if z1 > t - 0.02: z1 -= t * kk2 if z1 < -0.02: z1 += t * kk2 xyz.append((x1, y1, z1)) # B atom # Insure B in unit cell z3 = (i * abs(r) - k * h1) * sin(q3) - h2 if z3 > -0.02 and z3 < t - 0.02: x2 = rs * cos(i * q4 + q5) y2 = rs * sin(i * q4 + q5) z2 = (i * abs(r) - k * h1) * sin(q3) - h2 xyz.append((x2, y2, z2)) else: x2 = rs * cos(i * q4 + q5) y2 = rs * sin(i * q4 + q5) z2 = (i * abs(r) - (k + 1) * h1) * sin(q3) - h2 kk = abs(int(z2 / t)) + 1 if z2 > t - 0.01: z2 -= t * kk if z2 < -0.01: z2 += t * kk xyz.append((x2, y2, z2)) xyznew = [] ii = 0 dxy = rs + buffer for j in range(ncells): dz = j * t for i in range(2 * nn): x, y, z = xyz[i] xyznew.append((x + dxy, y + dxy, z + dz)) #for x,y,z in xyznew: print " C %10.4f %10.4f %10.4f" % (x,y,z) material = Material('nanotube%d%d%d' % (ncells, n, m)) for xyz in xyznew: material.add_atom(Atom(6, array(xyz))) material.bonds_from_distance() material.set_cell( Cell((2 * dxy, 0, 0), (0, 2 * dxy, 0), (0, 0, ncells * t))) return material