Esempio n. 1
0
def bcc_grains(size, perturbation=0.0):
    "Creates a grain layout based on a perturbed BCC lattice."
    graincenters = BodyCenteredCubic(symbol='H', latticeconstant=1.0, size=size)
    graincenters = graincenters.get_positions() + 0.25
    graincenters /= size
    pert = np.random.standard_normal(graincenters.shape) * perturbation
    graincenters += pert
    rotations = [random_rot() for g in graincenters]
    return graincenters, rotations
Esempio n. 2
0
def bcc_grains(size, perturbation=0.0):
    "Creates a grain layout based on a perturbed BCC lattice."
    graincenters = BodyCenteredCubic(symbol='H',
                                     latticeconstant=1.0,
                                     size=size)
    graincenters = graincenters.get_positions() + 0.25
    graincenters /= size
    pert = np.random.standard_normal(graincenters.shape) * perturbation
    graincenters += pert
    rotations = [random_rot() for g in graincenters]
    return graincenters, rotations
Esempio n. 3
0
from ase.lattice.cubic import BodyCenteredCubic
import numpy as np
bulk = BodyCenteredCubic(directions=[[1,0,0],
                                     [0,1,0],
                                     [0,0,1]],
                         size=(2,2,2),
                         latticeconstant=2.87,
                         symbol='Fe')
newbasis = 2.87*np.array([[-0.5, 0.5, 0.5],
                          [0.5, -0.5, 0.5],
                          [0.5, 0.5, -0.5]])
pos = bulk.get_positions()
s = np.dot(np.linalg.inv(newbasis.T), pos.T).T
print('atom positions in primitive basis')
print(s)
# let us see the unit cell in terms of the primitive basis too
print('unit cell in terms of the primitive basis')
print(np.dot(np.linalg.inv(newbasis.T), bulk.get_cell().T).T)
Esempio n. 4
0
from ase.lattice.cubic import BodyCenteredCubic
import numpy as np
bulk = BodyCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                         size=(2, 2, 2),
                         latticeconstant=2.87,
                         symbol='Fe')
newbasis = 2.87 * np.array([[-0.5, 0.5, 0.5], [0.5, -0.5, 0.5],
                            [0.5, 0.5, -0.5]])
pos = bulk.get_positions()
s = np.dot(np.linalg.inv(newbasis.T), pos.T).T
print 'atom positions in primitive basis'
print s
#let us see the unit cell in terms of the primitive basis too
print 'unit cell in terms of the primitive basis'
print np.dot(np.linalg.inv(newbasis.T), bulk.get_cell().T).T
Esempio n. 5
0
def build_emitter_from_scratch(element, basis, z_axis, filename="emitter.txt",
                               x_axis="auto", y_axis="auto", emitter_radius=100,
                               emitter_side_height=50, vacuum_radius=25,
                               alloy={}):
    """
    Build an emitter (set of nodes, TAPSim style) based on an
    element, basis, orientation, and dimensions.
    """

    IDS = {element: "10"}

    if x_axis == "auto" and y_axis == "auto":
        if 0.99 < np.dot(z_axis, (1, 0, 0)) < 1.01:
            x_axis = tuple(np.cross(z_axis, (1, 0, 0)))
        else:
            x_axis = tuple(np.cross(z_axis, (0, 1, 0)))
        y_axis = tuple(np.cross(z_axis, x_axis))

    R = emitter_radius + vacuum_radius

    if basis.lower() == "bcc":
        lattice = BodyCenteredCubic(
            size=(1, 1, 1),
            directions=[x_axis, y_axis, z_axis],
            symbol=element
        )
        pts = lattice.get_positions()
        supercell_dimensions = (
            int(math.ceil((2*R)/max([pt[0] for pt in pts])))+1,
            int(math.ceil((2*R)/max([pt[1] for pt in pts])))+1,
            int(math.ceil((emitter_side_height+R)/max([pt[2] for pt in pts])))+1
        )
        lattice = BodyCenteredCubic(
            size=supercell_dimensions,
            directions=[x_axis, y_axis, z_axis],
            symbol=element
        )
    elif basis.lower() == "fcc":
        lattice = FaceCenteredCubic(
            size=(1, 1, 1),
            directions=[x_axis, y_axis, z_axis],
            symbol=element
        )
        pts = lattice.get_positions()
        supercell_dimensions = (
            int(math.ceil((2*R)/max([pt[0] for pt in pts])))+1,
            int(math.ceil((2*R)/max([pt[1] for pt in pts])))+1,
            int(math.ceil((emitter_side_height+R)/max([pt[2] for pt in pts])))+1
        )
        lattice = FaceCenteredCubic(
            size=supercell_dimensions,
            directions=[x_axis, y_axis, z_axis],
            symbol=element
        )
    elif basis.lower() == "sc":
        lattice = SimpleCubic(
            size=(1, 1, 1),
            directions=[x_axis, y_axis, z_axis],
            symbol=element
        )
        pts = lattice.get_positions()
        supercell_dimensions = (
            int(math.ceil((2*R)/max([pt[0] for pt in pts])))+1,
            int(math.ceil((2*R)/max([pt[1] for pt in pts])))+1,
            int(math.ceil((emitter_side_height+R)/max([pt[2] for pt in pts])))+1
        )
        lattice = SimpleCubic(
            size=supercell_dimensions,
            directions=[x_axis, y_axis, z_axis],
            symbol=element
        )

    pts = lattice.get_positions()

    cx = np.mean([pt[0] for pt in pts])
    cy = np.mean([pt[1] for pt in pts])
    min_z = min([pt[2] for pt in pts])

    emitter_points, vacuum_points, bottom_points = [], [], []
    number = 0
    for pt in pts:
        pt = [pt[0], pt[1], pt[2]-min_z]
        if (pt[2] < 1e-5 and (pt[0]-cx)**2+(pt[1]-cy)**2<R**2):
            pt = [pt[0], pt[1], 0.0]
            pt = [i*1e-10 for i in pt]
            pt.append(2)  # bottom ID
            number += 1
            bottom_points.append(pt)
        elif (pt[2]<emitter_side_height and (pt[0]-cx)**2+(pt[1]-cy)**2\
                <emitter_radius**2):
            pt = [i*1e-10 for i in pt]
            pt.append(IDS[element])  # emitter ID
            number += 1
            emitter_points.append(pt)
        elif (pt[0]-cx)**2+(pt[1]-cy)**2+(pt[2]-emitter_side_height)**2\
                <emitter_radius**2:
            pt = [i*1e-10 for i in pt]
            pt.append(IDS[element])  # emitter ID
            number += 1
            emitter_points.append(pt)
        elif (pt[2]<emitter_side_height and (pt[0]-cx)**2+(pt[1]-cy)**2<R**2):
            pt = [i*1e-10 for i in pt]
            pt.append(0)  # vacuum ID
            number += 1
            vacuum_points.append(pt)
        elif (pt[0]-cx)**2+(pt[1]-cy)**2+(pt[2]-emitter_side_height)**2<R**2:
            pt = [i*1e-10 for i in pt]
            pt.append(0)  # vacuum ID
            number += 1
            vacuum_points.append(pt)

    alloy_id = 20
    all_substitution_indices = []
    for elt in alloy:
        substitution_indices = []
        conc = alloy[elt]
        num_atoms = len(emitter_points)
        num_substitution_atoms = math.floor(conc*num_atoms)
        j = 0
        while j < num_substitution_atoms:
            x = randint(0, num_atoms-1)
            if x not in all_substitution_indices:
                substitution_indices.append(x)
                all_substitution_indices.append(x)
                j += 1
        for i in substitution_indices:
            emitter_points[i][3] = alloy_id
        IDS[elt] = str(alloy_id)
        alloy_id += 10

    with open(filename, "w") as e:
        n_nodes = number
        e.write("ASCII {} 0 0\n".format(n_nodes))
        for pt in emitter_points + vacuum_points + bottom_points:
                # It's required that the coordinates be
                # separated by a tab character (^I), not
                # by regular spaces.
                e.write("	".join([str(i) for i in pt]))
                e.write("\n")
        comment = ["#"]
        comment += [" {}={}".format(IDS[elt], elt) for elt in IDS]
        e.write("{}\n".format(" ".join(comment)))
Esempio n. 6
0
class System():
    def __init__(self, setting):
        self.setting = setting

        self.elsProps = []         # elements properties
        self.setting['nAt'] = []   # number of atoms per specie
        
        self.px = self.setting['period'][0]
        self.py = self.setting['period'][1]
        self.pz = self.setting['period'][2]
        self.a0 =  self.setting['a']

        self.box =[[0, self.px*self.a0],\
                [0,self.py*self.a0],\
                [0,self.pz*self.a0]]

        self.setElsProps()

        self.setCrystal()

        if self.setting['positions'] == 'rnd':
                self.setRandomStructure()

        self.setNumbers()
        self.bulk.set_atomic_numbers(self.numbers)


    def setNumbers(self):
        self.numbers = []
        for e in  self.t1_:
            self.numbers.append( self.elsProps[e - 1]['number'])

    def setElsProps(self):
        for e in self.setting['elements']:
            a = ase.Atom(e)
            mass = a.mass / _Nav
            number = a.number

            form = pt.formula(a.symbol)
            e_ = form.structure[0][1]
            crys = e_.crystal_structure['symmetry'] 
            a_ = e_.crystal_structure['a'] 
            self.elsProps.append({'ase':a, 'mass': mass, 'structure': crys,
                'a':a_ , 'number':number})

    def setCrystal(self):
        crys = self.setting['structure']
        if crys == 'rnd':
            print 'rnd implemented'
            self.genRandomPositions()
            d = 1.104  # N2 bondlength
            formula =  'Cu'+str(len(self.pos))
            cell =[(self.px*self.a0,0,0),(0,self.py*self.a0,0),(0,0,self.pz*self.a0)] 
            self.bulk = ase.Atoms(formula, self.pos, pbc=True, cell=cell)

        if crys == 'fcc':
            print 'fcc implemented'
            from ase.lattice.cubic import FaceCenteredCubic
            self.bulk = FaceCenteredCubic(directions=[[1,0,0], [0,1,0], [0,0,1]],
                                        size=(self.px,self.py,self.pz), symbol='Cu',
                    pbc=(1,1,1), latticeconstant=self.a0)

        if crys == 'bcc':
            print 'bcc implemented'
            from ase.lattice.cubic import BodyCenteredCubic
            self.bulk = BodyCenteredCubic(directions=[[1,0,0], [0,1,0], [0,0,1]],
                                        size=(self.px,self.py,self.pz), symbol='Cu',
                    pbc=(1,1,1), latticeconstant=self.a0)

        if self.setting['structure'] == 'hcp':
            print 'hcp no implemented'
            sys.exit(0)


        self.setting['nAtoms'] =  self.bulk.get_number_of_atoms()
        self.calcAtoms2()
        self.genStructure()
        self.pos = self.bulk.get_positions()

    def update (self):
        cell  = self.bulk.get_cell()
        self.box =[[0, cell[0][0]],[0, cell[1][1]],[0, cell[2][2]]]
        self.pos = self.bulk.get_positions()

    def genStructure(self):
        self.t1_ = []
        for i,e in enumerate(self.setting['nAt']):
            [self.t1_.append(i+1) for j in range(e)]

 
    def setRandomStructure(self):
        x = [int(random.random()*len(self.t1_)) for i in range(len(self.t1_))]

        for i in range(len(x) - 1):
            t1 = self.t1_[x[i]]
            t2 = self.t1_[x[i+1]]

            self.t1_[x[i]] = t2
            self.t1_[x[i+1]] = t1
            
        return self.pos, self.t1_, self.box

    def genRandomPositions(self):
        Lx = self.box[0][1]
        Ly = self.box[1][1]
        Lz = self.box[2][1]

        self.pos =[]
        for i in range(self.setting['nAtoms']):
            x = random.random() * Lx
            y = random.random() * Ly
            z = random.random() * Lz
            self.pos.append([x,y,z])


    def getAtoms(self):
        return self.elsProps

    def Interaction (self):
        if self.setting['pot'] == 'lj':
            ljp = ljParameters.LjParameters()
            str_ = ljp.lammpsInteraction(self.elsProps)
        if self.setting['pot'] == 'zhou':
            gz = zhou.calcPotentials(self.setting['elements'])
            gz.createPot()
            str_ = gz.lammpsZhouEam()

        return str_

    def calcAtoms2(self):
        nAt = []

        sum_ = 0
        sumpc = 0.0000001
        len_elements = len(self.setting['elements'])
        len_pca = len(self.setting['pca'])

        print 'calcAtom2', len_pca, len_elements

        if len_elements != len_pca + 1:
            print 'error len'
            sys.exit(0)

        for p in self.setting['pca']:
            sumpc +=p

        if sumpc >= 100 or sumpc <= 0:
            print 'error pc'
            sys.exit(0)

        sumpc = 0

        for i in range(len(self.setting['elements']) - 1):
            p = self.setting['pca'][i]
            sumpc +=p
            t = int(p * self.setting['nAtoms'] / 100.0)
            sum_ +=t
            nAt.append(t)

        nAt.append(self.setting['nAtoms'] - sum_)

        self.setting['nAtoms'] = 0
        for e in nAt: 
            self.setting['nAtoms'] +=e

        print 'pca', self.setting['pca']
        self.setting['nAt'] =  nAt 


    def getMasess(self):
        str_ =''
        i = 1
        for e in self.elsProps:
            str_ += 'mass ' + str(i) + ' ' +str(e['mass']) + '\n'
            i+=1
        return  str_