def read_shape(shape, shape_atom, layers, atom_dict): import numpy as np import pymatgen as mg import os from objects import atom dir_path = os.path.dirname(os.path.realpath(__file__)) # opening shapes file with open(os.path.join(dir_path, 'shapes/' + shape)) as f: tag = f.readline() try: c = int(tag.split()[1]) except IndexError: c = 0 mg_atom = mg.Element(shape_atom) # adding core layer if specified for j in range(c): coords = np.array(list(map( float, f.readline().split()))) * mg_atom.atomic_radius atom_dict[len(atom_dict)] = atom(mg_atom, coords, num=len(atom_dict), c_tag='b') # adding given layers to global layers list layers.append([atom_dict[i] for i in range(c)]) print('Core layer created, atoms:', len(layers[0])) # adding outer shell (rest of the atoms) for line in f: coords = np.array(list(map(float, line.split()))) * float( mg_atom.atomic_radius) atom_dict[len(atom_dict)] = atom(mg_atom, coords, num=len(atom_dict), c_tag='b') layers.append([atom_dict[i] for i in range(c, len(atom_dict))]) print('Shell layer created, atoms:', len(layers[-1]))
def read_poscar(layers, atom_dict): from pymatgen import Structure, Element from objects import atom name = (input('Enter Name of POSCAR file in the same directory: ')) poscar = Structure.from_file(name) for i in poscar: mg_atom = Element(str(i.specie)) atom_dict[len(atom_dict)] = atom(mg_atom, list(i.coords), num=len(atom_dict), c_tag='b') layers.append([atom_dict[i] for i in atom_dict]) print('Read POSCAR as a single layer') cmd = input('add layer <l> or add adsorbate <a>? ') while cmd == 'l': sym = input("Which atom to deposit? ") add_layer(Element(sym)) cmd = input('add layer <l> or add adsorbate <a>? ') if cmd == 'a': add_ads(layers[-1], Element(sym))
def gen_ads_sites(layer, ads): """ Input: layer: an outer layer (atoms shouldn't be missing, extra is fine) ads: pymatgen atom object Output: list of all atom objects WITH ROOTS """ # T package returns indices of atoms to be considered ttd_indices = DT([i.ic for i in layer.atom_list]) tol_h = 0.01 # float(input('Enter minimum height of a tetrahedral formed on surface (0.01)\n')) tol_d = 3 * layer.atom_list[ 0].radius # float(input('Enter maximum distance between two surface atoms (3*atomic_radius testing)\n')) # dict for all_ttd all_ttd = [] # rc (return coord) returns the coords of concerned index rc = lambda x: layer.atom_list[x].ic # making all ttds in ttd objects for i in ttd_indices: ttd_coord = [rc(j) for j in i] print(ttd_coord) # adding ttd objects to all_ttd all_ttd.append(ttd(i, ttd_coord, tol_d, tol_h)) # faces_indices will have list of lists of relative face indices faces_indices = [] # checking if ttd holds for all requirements of making surface # ttd object KNOWS if it is legit and on surface for i in all_ttd: if i.is_surface(all_ttd): faces_indices.append[i.face] # deleting all_ttd and rc, as not needed now del all_ttd, rc ar = ads.atomic_radius lr = layer.atom_list[0].atomic_radius # a list of sites [atom objects WITH ROOTS] sites = [] # keeps track of previously considered atoms to avoid repitions roots = [] def return_atom(x): # return atom indexed x from the atom_list of layer return layer.atom_list[x] # add ontop adsorbate sites # simply add on all atoms on surface (no repititions) for i in faces_indices: for j in i: root = j if root not in roots: roots.append(root) c = return_atom(j).ic cn = unit(c) d = (ar + lr) * cn new = c + d sites.append(atom(ads, new, root=[return_atom(j)])) # add bridge elements # initializing roots (not necessary) roots = [] comb = [[0, 1], [0, 2], [1, 2]] for F in faces_indices: for i in comb: # root is a set so order doesn't matter root = {F[j] for j in i} if root not in roots: # adding root to roots so that it is not repeated roots.append(root) # getting atoms to add a new bridge atom A = layer.atom_list[faces_indices[i[0]]].ic B = layer.atom_list[faces_indices[i[1]]].ic # midpoint C = (A + B) / 2 c = unit(C) d = ar + lr r = linalg.norm(A - B) # only if atom is too big to sit at midpoint if d > r / 2: new = C + c * pow((pow(d, 2) - pow(r / 2, 2)), 0.5) # else same coordinates are used irrespective of size else: new = C sites.append( atom(ads, new, root=[return_atom(x) for x in root])) # initializing roots (not necessary) roots = [] # func checks if a face is square like (then no hcc/hcp site is added) def is_squarelike(F): C = [return_atom(x).ec for x in F] comb = [[0, 1, 2], [1, 0, 2], [2, 1, 0]] for i in comb: a = unit(C[i[1]] - C[i[0]]) b = unit(C[i[2]] - C[i[0]]) # if angle is more than 75 if abs(dot(a, b)) < 0.258: return 1 # else check other comb else: continue # if all angles less than 75, must be equilateral tri else: return 0 # add fcc/hcp elements for F in faces_indices: root = set(F) if root not in roots: if is_squarelike(F): pass else: A = return_atom(F[0]).ic B = return_atom(F[1]).ic C = return_atom(F[2]).ic D = (A + B + C) / 3 d = unit(D) e = linalg.norm(A - B) new = D + d * (pow(2 / 3, 0.5) * e) sites.append( atom(ads, new, c_tag='i', root=[return_atom(x) for x in root])) return sites
import objects ''' !!!!! VERY IMPORTANT !!!!!!!!! "none" in python does not mean that there is no weight, etc. it means that there is no value to put there. Likley that it is unknown "none" means "unknown" ''' def pack_atom_to_numbers(atom) : return 10000000 + atom.atomic_number * 10000 + atom.column * 100 + atom.row * 10 + atom.valence sulfur = objects.atom(16, 16, 3, 6) print(pack_atom_to_numbers(sulfur))
from objects import Atom, Compound, Variable, atom from rpython.rlib import rfile import machine import parser import os def new_entry_point(config): return main MAIN = atom("main", 0) def main(argv): if len(argv) <= 1: return 1 fd = rfile.create_file(argv[1], 'rb') try: source = fd.read() finally: fd.close() code, next_varno = parser.parse(source) program = machine.load(code) succ = machine.Success() try: program.solve(succ, Compound(MAIN, []), next_varno) except machine.Exiting as exit: return exit.status
from objects import Atom, Compound, Integer, Variable from objects import known_atoms, atom, as_list, wrap from objects import CONS, NIL, AND, OR, TRUE, FALSE, failure, success from objects import Trail, UNIFY_ATTS, BIND_HARD from objects import DepthFirstSearch, OrderedSearch import os CLAUSE = atom("<-", 2) CONSTRAINT_RULE = atom("constraint_rule", 5) SAME = atom("same", 2) UNIFY = atom("=", 2) COND2 = atom("cond", 2) DEF = atom("DEF", 2) def load(code, varno=100, debug=False): defs = {} chrs = [] constraints = {} occurrenceno = 0 for clause in reversed(as_list(code)): assert isinstance(clause, Compound) if clause.fsym is CLAUSE: head = clause.args[0] assert isinstance(head, Compound) if head.fsym in defs: rest = defs[head.fsym] else: rest = Compound(NIL, []) defs[head.fsym] = Compound(CONS, [clause, rest])