Example #1
0
    def gen_screw_dislocation_quad(self):
        # Easy core
        screw_slab_unit = BodyCenteredCubic(directions = [self.x, self.y, self.z],
                                            size = (1,1,1), symbol='Fe', pbc=(1,1,1),
                                            latticeconstant = alat)
        screw_slab_unit = Atoms(screw_slab_unit)
# set the supercell:
        n_x = int(18.0/screw_slab_unit.get_cell()[0,0])
        n_y = int(18.0/screw_slab_unit.get_cell()[1,1])
        n_z = 2

        ref_slab = screw_slab_unit*(n_x,n_y,n_z)
        ref_slab.write('ref_slab.xyz')
        screw_slab_super = supercell(screw_slab_unit, n_x, n_y, n_z)
        b = screw_slab_unit.get_cell()[2,2]
        brg_vec = b*np.array([0,0,1])
        disloc_l = np.array([0,0,1])
        super_slab = screw_slab_super.copy()
        L_x  = screw_slab_super.lattice[0,0]
        L_y  = screw_slab_super.lattice[1,1]
        L_z  = screw_slab_super.lattice[2,2]
        core = [(np.array([(L_x)/2., (L_y)/2., L_z/2.]), brg_vec),
                 np.array([(L_x)/2., (L_y)/2., L_z/2.]),
                 np.array([(L_x)/2., (L_y)/2., L_z/2.]),
                 np.array([(L_x)/2., (L_y)/2., L_z/2.])]
Example #2
0
def test1_magmom():

    atoms = BodyCenteredCubic(directions=[[1,0,0],
                                          [0,1,0],
                                          [0,0,1]],
                              size=(1,1,1),
                              symbol='Fe')

    for atom in atoms:
        atom.magmom = 2

    with jasp('Fe-magmom',
          xc='PBE',
          encut=300,
          kpts=(4,4,4),
          ispin=2,
          atoms=atoms) as calc:
        calc.prepare_input_files()
        atoms.get_potential_energy()

    with jasp('Fe-magmom') as calc:
        atoms.get_potential_energy()
        
    counter = 0
    with open('Fe-magmom/INCAR') as f:
        for line in f:
            if 'MAGMOM' in line:
                counter += 1

    assert counter == 1
Example #3
0
def make_bcc_100_cell(size=(1, 1, 1), symbols=['Ni'], pbc=(1, 1, 1)):
    direction_x = [1, 0, 0]
    direction_y = [0, 1, 0]
    direction_z = [0, 0, 1]

    directions = [direction_x, direction_y, direction_z]
    atoms = None
    try:
        atoms = BodyCenteredCubic(\
                directions=directions,
                size=size,
                symbol=symbols[0],
                pbc=pbc)
    except ValueError as e:
        if str(
                e
        ) == 'Cannot guess the bcc lattice constant of an element with crystal structure fcc.':
            r = get_atomic_radius(symbol=symbols[0])
            a0 = 4 * r / (3**0.5)
            atoms = BodyCenteredCubic(\
                    directions=directions,
                    size=size,
                    symbol=symbols[0],
                    pbc=pbc,
                    latticeconstant=a0)
        else:
            raise ValueError('cannot create the bcc structure')
    return atoms
Example #4
0
    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()
Example #5
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
Example #6
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
Example #7
0
 def calculate_c(self, pot, size=(1,1,1)):
   """
   Calculate the elastic constants for the underlying crack unit cell.
   """
   if self.symbol=='Si':
     at_bulk = bulk('Si', a=self.a0, cubic=True)
   elif self.symbol=='Fe':
     at_bulk = BodyCenteredCubic(directions=[self.crack_direction, self.cleavage_plane, self.crack_front],
                              size=size, symbol='Fe', pbc=(1,1,1),
                              latticeconstant=self.a0)
   at_bulk.set_calculator(pot)
   self.cij  = pot.get_elastic_constants(at_bulk)
   print((self.cij / units.GPa).round(2))
   return
Example #8
0
    def test_bcc(self):
        """Test that a body centered cubic lattice for copper is characterized
        correctly.
        """
        from ase.lattice.cubic import BodyCenteredCubic
        system = BodyCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [1, 1,
                                                                      1]],
                                   size=(1, 1, 1),
                                   symbol='Cu',
                                   pbc=True,
                                   latticeconstant=4.0)

        # Get the data
        data = self.get_material3d_properties(system)

        # Check that the data is valid
        self.assertEqual(data.space_group_number, 229)
        self.assertEqual(data.space_group_int, "Im-3m")
        self.assertEqual(data.hall_symbol, "-I 4 2 3")
        self.assertEqual(data.hall_number, 529)
        self.assertEqual(data.point_group, "m-3m")
        self.assertEqual(data.crystal_system, "cubic")
        self.assertEqual(data.bravais_lattice, "cI")
        self.assertEqual(data.choice, "")
        self.assertTrue(np.array_equal(data.equivalent_conv, [0, 0]))
        self.assertTrue(np.array_equal(data.wyckoff_conv, ["a", "a"]))
        self.assertTrue(np.array_equal(data.equivalent_original, [0]))
        self.assertTrue(np.array_equal(data.wyckoff_original, ["a"]))
        self.assertTrue(np.array_equal(data.prim_equiv, [0]))
        self.assertTrue(np.array_equal(data.prim_wyckoff, ["a"]))
        self.assertFalse(data.has_free_wyckoff_parameters)
        self.assertWyckoffGroupsOk(data.conv_system, data.wyckoff_sets_conv)
Example #9
0
    def build_surface(self, pot, size=(1, 1, 1)):
        """
    Create an equivalent surface unit cell for the fracture system.
    """
        if self.symbol == 'Si':
            unit_slab = Diamond(directions=[
                self.crack_direction, self.cleavage_plane, self.crack_front
            ],
                                size=size,
                                symbol=self.symbol,
                                pbc=True,
                                latticeconstant=self.a0)
        elif self.symbol == 'Fe':
            unit_slab = BodyCenteredCubic(directions=[
                self.crack_direction, self.cleavage_plane, self.crack_front
            ],
                                          size=size,
                                          symbol='Fe',
                                          pbc=(1, 1, 1),
                                          latticeconstant=self.a0)


# Does this work for more than 2 atoms?
        unit_slab.info['adsorbate_info'] = None
        unit_slab.positions[:, 1] += (unit_slab.positions[1, 1] -
                                      unit_slab.positions[0, 1]) / 2.0
        unit_slab.set_scaled_positions(unit_slab.get_scaled_positions())
        surface = unit_slab.copy()
        surface.center(vacuum=self.vacuum, axis=1)
        surface.set_calculator(pot)
        return surface
Example #10
0
 def build_unit_slab(self, size=(1, 1, 1)):
     """
 Initialize the unit slab for the given crack geometry.
 Currently supports silicon and Fe.
 """
     if self.symbol == 'Si':
         unit_slab = Diamond(directions=[
             self.crack_direction, self.cleavage_plane, self.crack_front
         ],
                             size=size,
                             symbol=self.symbol,
                             pbc=True,
                             latticeconstant=self.a0)
     elif self.symbol == 'Fe':
         unit_slab = BodyCenteredCubic(directions=[
             self.crack_direction, self.cleavage_plane, self.crack_front
         ],
                                       size=size,
                                       symbol='Fe',
                                       pbc=(1, 1, 1),
                                       latticeconstant=self.a0)
     print 'Number atoms in unit slab', len(unit_slab)
     unit_slab.info['adsorbate_info'] = None
     unit_slab.positions[:, 1] += (unit_slab.positions[1, 1] -
                                   unit_slab.positions[0, 1]) / 2.0
     unit_slab.set_scaled_positions(unit_slab.get_scaled_positions())
     pot_dir = os.environ['POTDIR']
     pot_file = os.path.join(pot_dir, self.param_file)
     print pot_file
     print self.mm_init_args
     #pot = Potential(self.mm_init_args, param_filename = pot_file)
     #pot = Potential("IP EAM_ErcolAd do_rescale_r=T r_scale=1.00894848312" , param_filename = "/Users/lambert/pymodules/imeall/imeall/potentials/PotBH.xml")
     #unit_slab.set_calculator(pot)
     return unit_slab
Example #11
0
 def test_strain(self):
     bulk = StructureFactory().ase.bulk('Fe', cubic=True)
     a_0 = bulk.cell[0, 0]
     b = 0.5 * np.sqrt(3) * a_0
     structure = ase_to_pyiron(
         BodyCenteredCubic(symbol='Fe',
                           directions=[[-1, 0, 1], [1, -2, 1], [1, 1, 1]],
                           latticeconstant=a_0))
     L = 100
     structure = structure.repeat(
         (*np.rint(L / structure.cell.diagonal()[:2]).astype(int), 1))
     voro = Voronoi(structure.positions[:, :2])
     center = voro.vertices[np.linalg.norm(
         voro.vertices - structure.cell.diagonal()[:2] * 0.5,
         axis=-1).argmin()]
     structure.positions[:, 2] += b / (2 * np.pi) * np.arctan2(
         *(structure.positions[:, :2] - center).T[::-1])
     structure.center_coordinates_in_unit_cell()
     r_0 = 0.9 * L / 2
     r = np.linalg.norm(structure.positions[:, :2] - center, axis=-1)
     core_region = (r < r_0) * (r > 10)
     strain = structure.analyse.get_strain(bulk, num_neighbors=8)
     strain = strain[core_region]
     positions = structure.positions[core_region, :2]
     x = positions - center
     eps_yz = b / (4 * np.pi) * x[:, 0] / np.linalg.norm(x, axis=-1)**2
     eps_xz = -b / (4 * np.pi) * x[:, 1] / np.linalg.norm(x, axis=-1)**2
     self.assertLess(np.absolute(eps_yz - strain[:, 1, 2]).max(), 0.01)
     self.assertLess(np.absolute(eps_xz - strain[:, 0, 2]).max(), 0.01)
Example #12
0
def test1_magmom():
    '''Make sure magmom is not getting written twice'''
    atoms = BodyCenteredCubic(directions=[[1, 0, 0],
                                          [0, 1, 0],
                                          [0, 0, 1]],
                              size=(1, 1, 1),
                              symbol='Fe')

    for atom in atoms:
        atom.magmom = 2

    with jasp('Fe-magmom',
              xc='PBE',
              encut=300,
              kpts=(4, 4, 4),
              ispin=2,
              atoms=atoms) as calc:
        calc.prepare_input_files()

    counter = 0
    with open('Fe-magmom/INCAR') as f:
        for line in f:
            if 'MAGMOM' in line:
                counter += 1

    assert counter == 1
    shutil.rmtree('Fe-magmom')
Example #13
0
def main():
	for x in fccs+bccs+hcps+diamonds+rocksalts+zincblendes+cscls:
		f = x in fccs
		b = x in bccs
		h = x in hcps
		d = x in diamonds
		r = x in rocksalts
		z = x in zincblendes
		c = x in cscls
		
		try: 
			if   f: a = FaceCenteredCubic(x[0]).get_cell()[0][0]/2
			elif b: a = BodyCenteredCubic(x[0]).get_cell()[0][0]/2
			elif d: a = Diamond(x[0]).get_cell()[0][0]/2
			elif h: 
					cell = HexagonalClosedPacked(x[0]).get_cell()
					a,c = cell[0][0],cell[2][2]

			elif r | z | c: a = dataLookup(x[0])
			else: raise NotImplementedError

		except ValueError: 
			a = sum([radDict[e] for e in elems])/len(elems)
			print "Had to guess lattice constant of "+x[0]

		if   f: name,struc,pos,cell,n = '-fcc',       'fcc',        [[0,0,0]],                  [[0,a,a],[a,0,a],[a,a,0]],   1
		elif b: name,struc,pos,cell,n = '-bcc',       'bcc',        [[0,0,0]],                  [[a,a,-a],[-a,a,a],[a,-a,a]],1
		elif h: name,struc,pos,cell,n = '-hcp',       'hexagonal',  [[0,0,0],[2./3,1./3,1./2]], [a,a,c,90,90,120],           2
		elif d: name,struc,pos,cell,n = '-diamond',   'diamond',    [[0,0,0],[0.25,0.25,0.25]], [[0,a,a],[a,0,a],[a,a,0]],   2
		elif z: name,struc,pos,cell,n = '-zincblende','zincblende', [[0,0,0],[0.25,0.25,0.25]], [[0,a,a],[a,0,a],[a,a,0]],   1
		elif r: name,struc,pos,cell,n = '-rocksalt',  'rocksalt',   [[0,0,0],[0.5,0.5,0.5]],    [[0,a,a],[a,0,a],[a,a,0]],   1
		elif c: name,struc,pos,cell,n = '-cscl',      'cubic',      [[0,0,0],[0.5,0.5,0.5]],    [a,a,a,90,90,90],            1

		mag     = magLookup(x[0])
		elems 	= parseChemicalFormula(x[0]).keys()*n
		magmoms = [magmomInit if e in magElems else 0 for e in elems] 

		atoms = Atoms(elems,scaled_positions=pos,cell=cell,pbc=[1,1,1],magmoms=magmoms,calculator=EMT())
		
		info = 	{'name': 		x[0]+name
				,'relaxed': 	False
				,'emt': 		atoms.get_potential_energy()/len(elems)	#normalized to per-atom basis
				,'comments':	'Autogenerated by createTrajs'
				,'kind': 		'bulk' # vs surface/molecules
				### Stuff for bulk
				,'structure': 	struc
				### Stuff for surfaces
				,'parent': 		None 
				,'sites': 		None
				,'facet': 		None
				,'xy': 			None
				,'layers': 		None
				,'constrained': None
				,'symmetric': 	None
				,'vacuum': 		None
				,'adsorbates':	None}

		db.write(atoms,key_value_pairs=info)
Example #14
0
    def gen_edge_dislocation(self):
        screw_slab_unit = BodyCenteredCubic(directions = [self.x, self.y, self.z],
                                            size = (1,1,1), symbol='Fe', pbc=(1,1,1),
                                            latticeconstant = 2.83)
        screw_slab_unit = Atoms(screw_slab_unit)

        n_x = int(self.l_x/screw_slab_unit.get_cell()[0,0])
        n_y = int(self.l_y/screw_slab_unit.get_cell()[1,1])
        n_z = 1

        screw_slab_super = supercell(screw_slab_unit, n_x, n_y, n_z)
        screw_slab_unit.write('ref_slab.xyz')

        b = screw_slab_unit.get_cell()[0,0]
        brg_vec = b*np.array([1,0,0])

        vacuum = 70.
        screw_slab_super.lattice[1,1] += vacuum

        disloc_l = np.array([0,0,1])
        screw_slab_super.set_lattice(screw_slab_super.get_cell(), scale_positions=False)
        super_slab = screw_slab_super.copy()

        L_x  = screw_slab_super.lattice[0,0]
        L_y  = screw_slab_super.lattice[1,1]
        L_z  = screw_slab_super.lattice[2,2]
#Maintain Periodicity along x and z for an edge dislocation:
        core =  np.array([(L_x)/2., (L_y-vacuum)/2., (L_z)/2.])

        screw_slab_super.set_cutoff(3.0)
        screw_slab_super.calc_connect()
        disloc_noam(screw_slab_super, core, disloc_l, brg_vec)
        screw_slab_super.info['core'] = core
        screw_slab_super.write('e{0}.xyz'.format(self.name))
Example #15
0
def gen_impurity(symbol='H', tetrahedral=True, sup_cell=[5, 5, 5]):
    """
    Add an element of type symbol to a supercell defined by the size sup_cell.
    If tetrahedral is true the element is initially placed in a tetrahedral position
    otherwise it is placed in an octahedral position.
    """
    #Molybdenum is 42!!!
    alat = 2.82893
    atomic_number_dict = {'H': 1, 'B': 5, 'C': 6, 'P': 15, 'Mn': 25, 'Mo': 42}

    tetra_pos = alat * np.array([0.5, 0.0, 0.75])
    octa_pos = alat * np.array([0.5, 0.5, 0.0])
    #Structures
    ats = BodyCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                            size=(sup_cell[0], sup_cell[1], sup_cell[2]),
                            symbol='Fe',
                            pbc=(1, 1, 1),
                            latticeconstant=alat)

    mid_point = 0.5 * (np.diag(ats.get_cell()))
    mid_point = [((sup_cell[0] - 1) / 2.) * alat for sp in sup_cell]

    if tetrahedral:
        tetra_pos += mid_point
        ats.append(Atom(position=tetra_pos, symbol=symbol))
    else:
        octa_pos += mid_point
        ats.append(Atom(position=octa_pos, symbol=symbol))
    return ats
Example #16
0
 def calculate_c(self, pot, size=(1, 1, 1)):
     """
 Calculate the elastic constants for the underlying crack unit cell.
 """
     if self.symbol == 'Si':
         at_bulk = bulk('Si', a=self.a0, cubic=True)
     elif self.symbol == 'Fe':
         at_bulk = BodyCenteredCubic(directions=[
             self.crack_direction, self.cleavage_plane, self.crack_front
         ],
                                     size=size,
                                     symbol='Fe',
                                     pbc=(1, 1, 1),
                                     latticeconstant=self.a0)
     at_bulk.set_calculator(pot)
     self.cij = pot.get_elastic_constants(at_bulk)
     print((self.cij / units.GPa).round(2))
     return
    def EfccEbccCalculator(self, EMT, PARAMETERS):
        # Return 0 is used when the method is not desired to be used
        # return 0
        """ This method uses the given EMT calculator to calculate and return the difference in energy between a system 
            of atoms placed in the BCC and FCC structure. """
        # The atoms objects are created using the input size and element and the energy calculator
        # is set to the EMT calculator
        # The Lattice Constant for the BCC lattice is here given so that the volume pr atom of the system is
        # held fixed for the FCC and BCC lattice, that is Vol_pr_atom_BCC = Vol_pr_atom_FCC.
        atoms1 = FaceCenteredCubic(size=(self.Size, self.Size, self.Size),
                                   symbol=self.Element)
        atoms1.set_calculator(EMT)
        # The Lattice constant which produces the same volume pr atom for an BCC crystal is calculated
        LCBcc = 1. / (2.**(1. / 3.)) * beta * PARAMETERS[
            self.Element][1] * Bohr * numpy.sqrt(2)
        atoms2 = BodyCenteredCubic(size=(self.Size, self.Size, self.Size),
                                   symbol=self.Element,
                                   latticeconstant=LCBcc)
        atoms2.set_calculator(EMT)

        # The energy difference pr atom is calculated and returned
        return atoms2.get_potential_energy() / len(
            atoms2) - atoms1.get_potential_energy() / len(atoms1)
Example #18
0
    def gen_screw_dislocation(self):
        screw_slab_unit = BodyCenteredCubic(directions = [self.x, self.y, self.z],
                                            size = (1,1,1), symbol='Fe', pbc=(1,1,1),
                                            latticeconstant = 2.83)
        screw_slab_unit = Atoms(screw_slab_unit)

# set the supercell:
        n_x = int(self.l_x/screw_slab_unit.get_cell()[0,0])
        n_y = int(self.l_y/screw_slab_unit.get_cell()[1,1])
        n_z = 2

        screw_slab_super = supercell(screw_slab_unit, n_x, n_y, n_z)
        ref_slab = screw_slab_unit*(n_x,n_y,n_z)
        ref_slab.write('ref_slab.xyz')
#Burgers vector modulus:
        b = screw_slab_unit.get_cell()[2,2]
        brg_vec = b*np.array([0,0,1])
        print b

        vacuum = 70.
        screw_slab_super.lattice[0,0] += vacuum
        screw_slab_super.lattice[1,1] += vacuum

        disloc_l   = np.array([0,0,1])
        screw_slab_super.set_lattice(screw_slab_super.get_cell(), scale_positions=False)
        super_slab = screw_slab_super.copy()

        L_x  = screw_slab_super.lattice[0,0]
        L_y  = screw_slab_super.lattice[1,1]
        L_z  = screw_slab_super.lattice[2,2]
        core =  np.array([(L_x-vacuum)/2., (L_y-vacuum)/2., L_z/2.])

        screw_slab_super.set_cutoff(3.0)
        screw_slab_super.calc_connect()
        disloc_noam(screw_slab_super, core, disloc_l, brg_vec)
        screw_slab_super.info['core'] = core
        screw_slab_super.write('s{0}.xyz'.format(self.name))
Example #19
0
 def build_surface(self, bp=[-1,1,12], v=[1,1,0]):
   '''
   Build Surface unit cell
   '''
   bpxv = [(bp[1]*v[2]-v[1]*bp[2]), (bp[2]*v[0]-bp[0]*v[2]), (bp[0]*v[1]- v[0]*bp[1])]
   surf_cell = BodyCenteredCubic(directions = [v, bpxv, bp],
                                 size = (1,1,1), symbol='Fe', pbc=(1,1,1),
                                 latticeconstant = 2.85)
   n = 2
   while(surf_cell.get_cell()[2,2]< 20.0 ):
     surf_cell = BodyCenteredCubic(directions = [v, bpxv, bp],
                   size = (1,1,n), symbol='Fe', pbc=(1,1,1),
                   latticeconstant = 2.85)
     n += 1
   surf_cell.center(vacuum=20.0, axis=2)
   return surf_cell
Example #20
0
def test():
    atoms = BodyCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                              size=(1, 1, 1),
                              symbol='Fe')

    for k in [2, 3, 4]:
        with jasp('kpt-loop',
                  xc='PBE',
                  encut=300,
                  kpts=(k, k, k),
                  ispin=2,
                  atoms=atoms) as calc:
            calc.prepare_input_files()

            with open('KPOINTS') as f:
                lines = f.readlines()

            assert lines[3] == '{0} {0} {0}\n'.format(k)
Example #21
0
  def build_tilt_sym_frac(self, bp=[-1,1,12], v=[1,1,0], c_space=None):
    bpxv = [(bp[1]*v[2]-v[1]*bp[2]),(bp[2]*v[0]-bp[0]*v[2]),(bp[0]*v[1]- v[0]*bp[1])]
    grain_a = BodyCenteredCubic(directions = [bpxv, bp, v],
                              size = (1,1,1), symbol='Fe', pbc=(1,1,1),
                              latticeconstant = 2.85)
    n_grain_unit = len(grain_a)
    n = 2
# Slightly different from slabmaker since in the fracture
# Simulations we want the grainboundary plane to be normal to y.
    while(grain_a.get_cell()[1,1] < 120.0):
      grain_a = BodyCenteredCubic(directions = [bpxv, bp, v],
                           size = (1,n,2), symbol='Fe', pbc=(1,1,1),
                           latticeconstant = 2.85)
      n += 1
    print '\t {0} repeats in z direction'.format(n)
    grain_b = grain_a.copy()
    grain_c = grain_a.copy()
    print '\t', '{0} {1} {2}'.format(v[0],v[1],v[2])
    print '\t', '{0} {1} {2}'.format(bpxv[0],bpxv[1],bpxv[2])
    print '\t', '{0} {1} {2}'.format(bp[0], bp[1], bp[2])
    if c_space==None:
      s1 = surface('Fe', (map(int, bp)), n)
      c_space = s1.get_cell()[2,2]/float(n) #-s1.positions[:,2].max()
      s2 = surface('Fe', (map(int, v)), 1)
      x_space = s2.get_cell()[0,0] #-s1.positions[:,2].max()
      s3 = surface('Fe', (map(int, bpxv)), 1)
      y_space = s3.get_cell()[1,1] #-s1.positions[:,2].max()
    print '\t Interplanar spacing: ', x_space.round(2), y_space.round(2), c_space.round(2), 'A'
	# Reflect grain b in z-axis (across mirror plane):
    print grain_a.get_cell()[1,1]-grain_a.positions[:,1].max()
    grain_b.positions[:,1]  = -1.0*grain_b.positions[:,1]
    grain_c.extend(grain_b)
    grain_c.set_cell([grain_c.get_cell()[0,0], 2*grain_c.get_cell()[1,1], grain_c.get_cell()[2,2]])
    grain_c.positions[:,1] += abs(grain_c.positions[:,1].min())
    pos = [grain.position for grain in grain_c]
    pos = sorted(pos, key= lambda x: x[2])
    dups = get_duplicate_atoms(grain_c)
 #  now center fracture cell with plenty of vacuum
    grain_c.center(vacuum=10.0,axis=1)
    return grain_c
Example #22
0
def test_ldauj():

    atoms = BodyCenteredCubic(directions=[[-1, 1, 1], [1, -1, 1], [1, 1, -1]],
                              size=(2, 2, 2),
                              symbol='Fe')

    with jasp('Fe-base',
              xc='PBE',
              sigma=0.1,
              kpts=(4, 4, 4),
              nbands=44,
              setups={'0': 'Fe'},
              ldau=True,
              ldautype=3,
              ldaul=[2, -1],
              ldauu=[0, 0],
              ldauj=[0, 0],
              ldauprint=2,
              lmaxmix=4,
              lorbit=11,
              debug=logging.DEBUG,
              atoms=atoms) as calc:
        assert not calc.calculation_required(calc.get_atoms(), ['energy'])
Example #23
0
from vasp import Vasp
from ase.lattice.cubic import BodyCenteredCubic
atoms = BodyCenteredCubic(directions=[[1, 0, 0],
                                      [0, 1, 0],
                                      [0, 0, 1]],
                                      size=(1, 1, 1),
                                      symbol='Fe')
calc = Vasp('bulk/Fe-bcc-fixedmagmom-{0:1.2f}'.format(0.0),
            xc='PBE',
            encut=300,
            kpts=[4, 4, 4],
            ispin=2,
            nupdown=0,
            atoms=atoms)
print(atoms.get_potential_energy())
Example #24
0
#Hydrogen interatomic distance 0.73
#Hydrogen formation energy -4.
POT_DIR = os.environ['POTDIR']
eam_pot = os.path.join(POT_DIR, 'PotBH.xml')
r_scale = 1.00894848312
pot = Potential('IP EAM_ErcolAd do_rescale_r=T r_scale={0}'.format(r_scale), param_filename=eam_pot)
#alat = 2.82893
#could just use the proper one as well....
alat = 2.837666

sup_cell = args.supercellsize
tetra_pos = alat*np.array([0.5, 0.0, 0.75])
octa_pos = alat*np.array([0.5, 0.5, 0.0])
#Structures
gb = BodyCenteredCubic(directions = [[1,0,0], [0,1,0], [0,0,1]],
                       size = (sup_cell[0],sup_cell[1],sup_cell[2]), symbol='Fe', pbc=(1,1,1),
                       latticeconstant = alat)
mid_point = 0.5*(np.diag(gb.get_cell()))
mid_point = [((sup_cell[0]-1)/2.)*alat for sp in sup_cell]
gb = Atoms(gb)
if args.tetra:
    print 'Tetrahedral Defect'
    tetra_pos += mid_point
    gb.add_atoms(tetra_pos, 1)
    gb.write('bcc_h.xyz')
elif args.octa:
    print 'Octahedral Defect'
    octa_pos += mid_point
    gb.add_atoms(octa_pos, 1)
    gb.write('bcc_h.xyz')
else:
Example #25
0
from jasp import *
from ase.lattice.cubic import BodyCenteredCubic

atoms = BodyCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]], size=(1, 1, 1), symbol="Fe")
# set magnetic moments on each atom
for atom in atoms:
    atom.magmom = 2.5
with jasp(
    "bulk/Fe-bcc-sp-1",
    xc="PBE",
    encut=300,
    kpts=(4, 4, 4),
    ispin=2,
    lorbit=11,  # you need this for individual magnetic moments
    atoms=atoms,
) as calc:
    try:
        e = atoms.get_potential_energy()
        B = atoms.get_magnetic_moment()
        magmoms = atoms.get_magnetic_moments()
    except (VaspSubmitted, VaspQueued):
        pass
print "Total magnetic moment is {0:1.2f} Bohr-magnetons".format(B)
print "Individual moments are {0} Bohr-magnetons".format(magmoms)
Example #26
0
        at.nye[:, orig_index-1] = alpha[:,:,index].T.reshape(9)
    return core

# Initial Parameters:
input_file = 's111111.xyz'
traj_file  = 's111111_traj.xyz'
timestep   =  2.0*units.fs #Timestep (NB: time base units are not fs!)
print_interval = 100
initial_G      = 0.0*(units.J/units.m**2) #Initial energy flow to crack tip or strain energy of slab
nsteps         = 500  # Total number of timesteps to run for
#Create unit cell with the orientation:

x = [1,1,-2]
y = [-1,1,0]
z = [1,1,1]
screw_slab_unit = BodyCenteredCubic(directions = [x, y, z], size=(1,1,1),
                                    symbol='Fe', pbc=(1,1,1), latticeconstant=2.83)
if __name__=='__main__':
#Parse Arguments:
  parser = argparse.ArgumentParser()
  parser.add_argument("-rd",  "--run_dyn",     help="Performs a relaxation", action='store_true')
  parser.add_argument("-cn",  "--calc_nye",    help="Calculate nye tensor",  action='store_true')
  parser.add_argument("-cv",  "--calc_virial", help="Calculate viral tensor and append to atoms object ",  action='store_true')
  parser.add_argument("-inp", "--input_file", help="name of input file with no suffix", required=True)
  parser.add_argument("-dt",  "--dis_type",   help= "Can be 'edge' or 'screw'", required=True)
  parser.add_argument("-pt",  "--pot_type",   help='Potential associated with dynamics: TB or EAM', default='EAM')
  parser.add_argument("-f",  "--steps", type=int,  help='Number of steps in trajectory to sample for burgers vectors.', default=5)
  parser.add_argument("-st",  "--sim_T",  help='Simulation Temperature in Kelvin. Default is 300 K.', type=float, default=300.0)

  args        = parser.parse_args()
  run_dyn     = args.run_dyn
  calc_nye    = args.calc_nye
Example #27
0
input_file = 's111111.xyz'
traj_file = 's111111_traj.xyz'
timestep = 2.0 * units.fs  #Timestep (NB: time base units are not fs!)
print_interval = 100
initial_G = 0.0 * (
    units.J / units.m**2
)  #Initial energy flow to crack tip or strain energy of slab
nsteps = 500  # Total number of timesteps to run for
#Create unit cell with the orientation:

x = [1, 1, -2]
y = [-1, 1, 0]
z = [1, 1, 1]
screw_slab_unit = BodyCenteredCubic(directions=[x, y, z],
                                    size=(1, 1, 1),
                                    symbol='Fe',
                                    pbc=(1, 1, 1),
                                    latticeconstant=2.83)
if __name__ == '__main__':
    #Parse Arguments:
    parser = argparse.ArgumentParser()
    parser.add_argument("-rd",
                        "--run_dyn",
                        help="Performs a relaxation",
                        action='store_true')
    parser.add_argument("-cn",
                        "--calc_nye",
                        help="Calculate nye tensor",
                        action='store_true')
    parser.add_argument(
        "-cv",
Example #28
0
File: fe-run.py Project: m-yu/MAST
            'forcing': 'Concentration',
            'calc_method': 'LAMMPS',
            'pair_style':'eam/fs',
            'pot_file':'Fe_mm.eam.fs',
            'lammps_thermo_steps':100,
            'keep_Lammps_files': True,
            'ase_min': False,
            'lammps_min': mincomd,
            'lammps_min_style': 'cg\nmin_modify line quadratic',
            'genealogy': True,
            'output_format': 'FormationEnergyPerInt',
            'allenergyfile':True,
            'bestindslist': True,
            'finddefects':True,
            'parallel' : True,
            'algorithm_type' : 'lambda+mu',
            'debug':['None']}
    bsfe = BCC('Fe', size=parameters['supercell'])
	rank = MPI.COMM_WORLD.Get_rank()
	if rank==0:
    	write(parameters['SolidFile'],bsfe)
	cell=numpy.maximum.reduce(bsfe.get_cell())
	parameters['SolidCell']=cell
    A = Optimizer(parameters)
    A.algorithm_parallel()
                                
                                
if __name__ == "__main__":
        main()
                   
Example #29
0
from jasp import *
from ase.lattice.cubic import BodyCenteredCubic
atoms = BodyCenteredCubic(symbol='Fe')
for atom in atoms:
    atom.magmom = 3.0
with jasp('bulk/Fe-bulk',
          xc='PBE',
          kpts=(6, 6, 6),
          encut=350,
          ispin=2,
          isif=3,
          nsw=30,
          ibrion=1,
          atoms=atoms) as calc:
    print atoms.get_potential_energy()
    print atoms.get_stress()
Example #30
0
    dups = get_duplicate_atoms(grain_c)
 #  now center fracture cell with plenty of vacuum
    grain_c.center(vacuum=10.0,axis=1)
    return grain_c

if __name__=='__main__':
  sym_tilt_110 = [[np.pi*(93.37/180.), np.array([-3., 3., 4.])]]
  gbid = '1109337334'
  or_axis = [1,1,0]
  bp      = [-1,1,12]

##########################################
##First calculate surface energetics:   ##
##########################################
  bulk = BodyCenteredCubic(directions = [[1,0,0],[0,1,0], [0,0,1]],
                           size = (1,1,1), symbol='Fe', pbc=(1,1,1),
                           latticeconstant = 2.85)

  eam_pot = './Fe_Mendelev.xml'
  gb_frac = GBFracture()
  surf_cell = gb_frac.build_surface(bp = sym_tilt_110[0][1])
  pot     = Potential('IP EAM_ErcolAd', param_filename=eam_pot)
  bulk.set_calculator(pot)
  ener_per_atom = bulk.get_potential_energy()/len(bulk)
  surf_cell.set_calculator(pot)
  surf_ener = surf_cell.get_potential_energy()
  cell  = surf_cell.get_cell()
  A     = cell[0][0]*cell[1][1]
  gamma = (surf_ener- len(surf_cell)*ener_per_atom)/A

  print '2*gamma ev/A2', gamma
Example #31
0
######

pot2 = pyjulip.pot("StillingerWeber()")

si_at = Diamond("Si", latticeconstant=5.43)
si_big_at = si_at * (2, 2, 2)

print "StillingerWeber()"

test(si_big_at, pot2)

######

pot3 = pyjulip.EAM("../data/w_eam4.fs")

w_at = BodyCenteredCubic("W", latticeconstant=3.16)
w_big_at = w_at * (2, 2, 2)

print "W_EAM"

test(w_big_at, pot3)

######

pot4 = pyjulip.FinnisSinclair("../data/W-pair-Wang-2014.plt",
                              "../data/W-e-dens-Wang-2014.plt")

test(w_big_at, pot4)

try:
    pot = pyjulip.NBodyIPs("Ti_aPIP1_reg.json", fast=True)
Example #32
0
    def get_structure(self, name, elements, a=None, c=None, l=None):
        # Check number of elements
        if name[:3] in ['fcc', 'hcp']:
            if len(elements) != 1:
                raise ValueError("Tuple of elements must be of length one")
        if name[:3] in ['l12', 'l10'] or name[:2] == 'B2':
            if len(elements) != 2:
                raise ValueError("Tuple of elements must be of length two")

        # Get lattice constants
        if a is None:
            if name[:2] == 'B2':
                a = self.get_lattice_constant_a(name[:2], elements)
            elif name[:3] in ['fcc', 'hcp', 'bcc', 'l12', 'l10']:
                a = self.get_lattice_constant_a(name[:3], elements)

        if c is None:
            if name[:3] in ['hcp', 'l10']:
                c = self.get_lattice_constant_c(name[:3], elements)

        # Get size
        if name in ['fcc', 'hcp', 'bcc', 'l12', 'l10', 'B2']:
            size = self.properties[name + '_size']
        elif name in ['fcc100', 'fcc111', 'hcp0001']:
            size = self.properties[name + '_size'][:2] + (l, )

        # Make structure
        if name == 'fcc':
            atoms = FaceCenteredCubic(symbol=elements[0],
                                      size=size,
                                      latticeconstant=a)
        elif name == 'hcp':
            atoms = HexagonalClosedPacked(symbol=elements[0],
                                          size=size,
                                          directions=[[2, -1, -1, 0],
                                                      [0, 1, -1, 0],
                                                      [0, 0, 0, 1]],
                                          latticeconstant=(a, c))
        elif name == 'bcc':
            atoms = BodyCenteredCubic(symbol=elements[0],
                                      size=size,
                                      latticeconstant=a)
        elif name == 'B2':
            atoms = B2(symbol=elements, size=size, latticeconstant=a)
        elif name == 'l12':
            atoms = L1_2(symbol=elements, size=size, latticeconstant=a)
        elif name == 'l10':
            atoms = L1_0(symbol=elements, size=size, latticeconstant=(a, c))
        elif name == 'fcc100':
            atoms = fcc100(symbol=elements[0], size=size, a=a, vacuum=10.0)
        elif name == 'fcc111':
            atoms = fcc111(symbol=elements[0],
                           size=size,
                           a=a,
                           vacuum=10.0,
                           orthogonal=True)
        elif name == 'hcp0001':
            atoms = hcp0001(symbol=elements[0],
                            size=size,
                            a=a,
                            c=c,
                            vacuum=10.0,
                            orthogonal=True)
        elif name == 'hcp1010A':
            raise ValueError("Structure '%s' not supported" % (name, ))
            atoms = None
        elif name == 'hcp1010B':
            raise ValueError("Structure '%s' not supported" % (name, ))
            atoms = None
        elif name == 'l12100':
            n = (l + 1) / 2
            atoms = L1_2(symbol=elements, size=(8, 8, n), latticeconstant=a)
            atoms.set_pbc([True, True, False])
            # Remove layers
            atoms = atoms[atoms.get_positions()[:, 2] > 0.1 * a]
            # Set vacuum
            atoms.center(axis=2, vacuum=10.0)
        elif name == 'l12111':
            if l % 3 == 0:
                n = l / 3
                c = 0
            else:
                n = l / 3 + 1
                c = 3 - l % 3
            atoms = L1_2(
                symbol=elements,
                size=(8, 4, n),
                #directions=[[1,-1,0],[1,0,-1],[1,1,1]], latticeconstant=a)
                directions=[[1, -1, 0], [1, 1, -2], [1, 1, 1]],
                latticeconstant=a)
            atoms.set_pbc([True, True, False])
            # Wrap positions
            scpos = atoms.get_scaled_positions()
            scpos[scpos > (1.0 - 1e-12)] = 0.0
            atoms.set_scaled_positions(scpos)
            # Remove layers
            if c > 0:
                atoms = atoms[atoms.get_positions()[:, 2] > (c - 0.5) * a /
                              np.sqrt(3.0)]
            # Set vacuum
            atoms.center(axis=2, vacuum=10.0)
        else:
            raise ValueError("Structure '%s' not supported" % (name, ))
        return atoms
Example #33
0
def make_edge_cyl_001_100(a0, C11, C12, C44,
                          cylinder_r,
                          cutoff=5.5,
                          tol=1e-6,
                          symbol="W"):
    """Function to produce consistent edge dislocation configuration.

    Parameters
    ----------
    alat : float
        Lattice constant of the material.
    C11 : float
        C11 elastic constant of the material.
    C12 : float
        C12 elastic constant of the material.
    C44 : float
        C44 elastic constant of the material.
    cylinder_r : float
        Radius of cylinder of unconstrained atoms around the
        dislocation  in angstrom.
    cutoff : float
        Potential cutoff for determenition of size of
        fixed atoms region (2*cutoff)
    tol : float
        Tolerance for generation of self consistent solution.
    symbol : string
        Symbol of the element to pass to ase.lattuce.cubic.SimpleCubicFactory
        default is "W" for tungsten

    Returns
    -------
    bulk : ase.Atoms object
        Bulk configuration.
    disloc : ase.Atoms object
        Dislocation configuration.
    disp : np.array
        Correstonding displacement.
    """

    # Create a Stroh ojbect with junk data
    stroh = am.defect.Stroh(am.ElasticConstants(C11=141, C12=110, C44=98),
                            np.array([0, 0, 1]))

    axes = np.array([[1, 0, 0],
                     [0, 1, 0],
                     [0, 0, 1]])

    c = am.ElasticConstants(C11=C11, C12=C12, C44=C44)
    burgers = a0 * np.array([1., 0., 0.])

    # Solving a new problem with Stroh.solve
    # Does not work with the new version of atomman
    stroh.solve(c, burgers, axes=axes)

    unit_cell = BodyCenteredCubic(directions=axes.tolist(),
                                  size=(1, 1, 1), symbol=symbol,
                                  pbc=(False, False, True),
                                  latticeconstant=a0)

    bulk = unit_cell.copy()

    # shift to make the zeros of the cell betweem the atomic planes
    # and under the midplane on Y axes
    X_midplane_shift = -0.25*a0
    Y_midplane_shift = -0.25*a0

    bulk_shift = [X_midplane_shift,
                  Y_midplane_shift,
                  0.0]

    bulk.positions += bulk_shift

    tot_r = cylinder_r + 2*cutoff + 0.01

    Lx = int(round(tot_r/a0))
    Ly = int(round(tot_r/a0))

    # factor 2 to make sure odd number of images is translated
    # it is important for the correct centering of the dislocation core
    bulk = bulk * (2*Lx, 2*Ly, 1)

    center_shift = [Lx * a0, Ly * a0, 0.0]

    bulk.positions -= center_shift
    # bulk.write("before.xyz")

    disp1 = stroh.displacement(bulk.positions)
    disloc = bulk.copy()
    res = np.inf
    i = 0
    while res > tol:
        disloc.positions = bulk.positions + disp1
        disp2 = stroh.displacement(disloc.positions)
        res = np.abs(disp1 - disp2).max()
        disp1 = disp2
        print 'disloc SCF', i, '|d1-d2|_inf =', res
        i += 1
        if i > 10:
            raise RuntimeError('Self-consistency did \
                                not converge in 10 cycles')
    disp = disp2

    x, y, z = disloc.positions.T
    radius_x_y_zero = np.sqrt(x**2 + y**2)
    mask = radius_x_y_zero < tot_r
    disloc = disloc[mask]
    bulk = bulk[mask]
    # disloc.write("after_disp.xyz")

    x, y, z = disloc.positions.T
    radius_x_y_zero = np.sqrt(x**2 + y**2)
    mask_zero = radius_x_y_zero > cylinder_r
    fix_atoms = FixAtoms(mask=mask_zero)
    disloc.set_constraint(fix_atoms)

    return bulk, disloc, disp
Example #34
0
from ase.lattice.surface import surface
from ase import Atoms
from ase.visualize import view, write
from ase.calculators.vasp import *
import matplotlib.pyplot as plt
from ase.constraints import FixAtoms
from matplotlib import mlab
from numpy import *
from ase.utils.eos import EquationOfState
from ase.lattice.cubic import BodyCenteredCubic
from ase import Atom

a = 5.7885/2

cell = [[1,0,0],[0,1,0],[0,0,1]]
atoms = BodyCenteredCubic('Fe', directions=cell)
atoms.set_initial_magnetic_moments([5,5])
atoms.set_cell([a, a, a], scale_atoms=True)

carbon = Atom('C', position=(0,0.5*a,0.75*a), charge=0.4)
atoms = atoms*(2,2,2) + carbon

constraint = FixAtoms(indices=[8,10,12,14,16])

atoms.set_constraint(constraint)

atoms[-1].position = [0, 0.5*a, 0.75*a]
init = atoms.copy()
# view(init)

atoms[-1].position = [0, 0.75*a, 0.5*a]
Example #35
0
from ase.lattice.surface import surface
from ase import Atoms
from ase.visualize import view, write
from ase.calculators.vasp import *
import matplotlib.pyplot as plt
from ase.constraints import FixAtoms
from matplotlib import mlab
from numpy import *
from ase.utils.eos import EquationOfState
from ase.lattice.cubic import BodyCenteredCubic
from ase import Atom

a = 2.8920

cell = [[1,0,0],[0,1,0],[0,0,1]]
atoms = BodyCenteredCubic('Fe', directions=cell)
atoms.set_initial_magnetic_moments([5,5])
atoms.set_cell([a,a,a], scale_atoms=True)

carbon = Atom('C', position=(0,0.5*a,0.5*a), charge=0.4)

atoms = atoms*(2,2,2) + carbon
init = atoms.copy()

final = atoms.copy()
final[-1].position = [0, 0.5*a, (0.5+0.25)*a]

for i in range(0,13):
    os.system('mkdir {:02d}'.format(i))
    os.chdir('{:02d}'.format(i))
    atoms[-1].position = [0,0.5*a,(0.5+(0.25/12.*i))*a]
Example #36
0
from ase.lattice.surface import surface
from ase import Atoms
from ase.visualize import view, write
from ase.calculators.vasp import *
import matplotlib.pyplot as plt
from ase.constraints import FixAtoms
from matplotlib import mlab
from numpy import *
from ase.utils.eos import EquationOfState
from ase.lattice.cubic import BodyCenteredCubic
from ase import Atom

a = 2.8920

cell = [[1,0,0],[0,1,0],[0,0,1]]
atoms = BodyCenteredCubic('Fe', directions=cell)
atoms.set_initial_magnetic_moments([5,5])

carbon = Atom('C', position=(0,0.5*a,0.5*a), charge=0.4)

atoms = atoms*(2,2,2) + carbon
init = atoms.copy()

final = atoms.copy()
final[16].position = [0, 0.5*a, (0.5+1.0)*a]

for i in range(11):
    os.system('mkdir {:02d}'.format(i))
    os.chdir('{:02d}'.format(i))
    atoms[16].position = [0,0.5*a,(0.5+(1./10.*i))*a]
 #   view(atoms)
Example #37
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)
Example #38
0
from ase import Atoms
from ase.visualize import view, write
from ase.calculators.vasp import *
import matplotlib.pyplot as plt
from ase.constraints import FixAtoms
from matplotlib import mlab
from numpy import *
from ase.utils.eos import EquationOfState
from ase.lattice.cubic import BodyCenteredCubic
from ase import Atom


a = 2.87

cell = [[1,0,0],[0,1,0],[0,0,1]]
atoms = BodyCenteredCubic('Fe', directions=cell)
atoms.set_initial_magnetic_moments([5,5])

carbon = Atom('C', position=(0,0.5*a,0.75*a), charge=0.4)

atoms = atoms*(2,2,2) + carbon
#atoms = atoms*(2,2,2)

constraint = FixAtoms(indices=[5,7,8,10,12,13,14,15,16])

atoms.set_constraint(constraint)

view(atoms)

def save( filename, arg ):
    f = open(filename, 'a+t')
Example #39
0
def make_screw_cyl(alat, C11, C12, C44,
                   cylinder_r=10, cutoff=5.5,
                   hard_core=False,
                   center=(0., 0., 0.),
                   l_extend=(0., 0., 0.),
                   symbol='W'):

    """Makes screw dislocation using atomman library

    Parameters
    ----------
    alat : float
        Lattice constant of the material.
    C11 : float
        C11 elastic constant of the material.
    C12 : float
        C12 elastic constant of the material.
    C44 : float
        C44 elastic constant of the material.
    cylinder_r : float
        radius of cylinder of unconstrained atoms around the
        dislocation  in angstrom
    cutoff : float
        Potential cutoff for marinica potentials for FS cutoff = 4.4
    hard_core : bool
        Description of parameter `hard_core`.
    center : type
        The position of the dislocation core and the center of the
                 cylinder with FixAtoms condition
    l_extend : float
        extention of the box. used for creation of initial
        dislocation position with box equivalent to the final position
    symbol : string
        Symbol of the element to pass to ase.lattuce.cubic.SimpleCubicFactory
        default is "W" for tungsten

    Returns
    -------
    disloc : ase.Atoms object
        screw dislocation cylinder.
    bulk : ase.Atoms object
        bulk disk used to generate dislocation
    u : np.array
        displacement per atom.
    """
    # Create a Stroh ojbect with junk data
    stroh = am.defect.Stroh(am.ElasticConstants(C11=141, C12=110, C44=98),
                            np.array([0, 0, 1]))

    axes = np.array([[1, 1, -2],
                     [-1, 1, 0],
                     [1, 1, 1]])

    c = am.ElasticConstants(C11=C11, C12=C12, C44=C44)
    burgers = alat * np.array([1., 1., 1.])/2.

    # Solving a new problem with Stroh.solve
    stroh.solve(c, burgers, axes=axes)

    # test the solution that it does not crash
    # pos_test = uc.set_in_units(np.array([12.4, 13.5, -10.6]), 'angstrom')
    # disp = stroh.displacement(pos_test)
    # print("displacement =", uc.get_in_units(disp, 'angstrom'), 'angstrom')

    unit_cell = BodyCenteredCubic(directions=axes.tolist(),
                                  size=(1, 1, 1), symbol=symbol,
                                  pbc=(False, False, True),
                                  latticeconstant=alat)

    # make the dislocation core center of the box
    disloCenterX = alat * np.sqrt(6.)/6.0
    disloCenterY = alat * np.sqrt(2.)/6.0

    unit_cell.positions[:, 0] -= disloCenterX
    unit_cell.positions[:, 1] -= disloCenterY

    # shift to move the fixed atoms boundary condition for the
    # configuration with shifted dislocation core
    shift_x = 2.0 * center[0]
    shift_y = 2.0 * center[1]

    l_shift_x = 2.0 * l_extend[0]
    l_shift_y = 2.0 * l_extend[1]

    # size of the cubic cell as a 112 direction
    Lx = int(round((cylinder_r + 3.*cutoff + shift_x + l_shift_x)
                   / (alat * np.sqrt(6.))))

    # size of the cubic cell as a 110 direction
    Ly = int(round((cylinder_r + 3.*cutoff + shift_y + l_shift_y)
                   / (alat * np.sqrt(2.))))
    # factor 2 to make shure odd number of images is translated
    # it is important for the correct centering of the dislocation core
    bulk = unit_cell * (2*Lx, 2*Ly, 1)
    # make 0, 0, at the center
    bulk.positions[:, 0] -= Lx * alat * np.sqrt(6.)
    bulk.positions[:, 1] -= Ly * alat * np.sqrt(2.)

    # wrap
    # bulk.set_scaled_positions(bulk.get_scaled_positions())
    # apply shear here:
    # bulk.cell *= D
    # bulk.positions *= D

    x, y, z = bulk.positions.T

    radius_x_y_zero = np.sqrt(x**2 + y**2)
    mask_zero = radius_x_y_zero < cylinder_r + 2.*cutoff

    radius_x_y_center = np.sqrt((x - center[0])**2 + (y - center[1])**2)
    mask_center = radius_x_y_center < cylinder_r + 2.*cutoff

    radius_x_y_l_shift = np.sqrt((x - l_extend[0])**2 + (y - l_extend[1])**2)
    mask_l_shift = radius_x_y_l_shift < cylinder_r + 2.*cutoff

    final_mask = mask_center | mask_zero | mask_l_shift
    # leave only atoms inside the cylinder
    bulk = bulk[final_mask]

    disloc = bulk.copy()
    # calculate and apply the displacements for atomic positions
    u = stroh.displacement(bulk.positions - center)
    u = -u if hard_core else u

    disloc.positions += u
    x, y, z = disloc.positions.T

    radius_x_y_zero = np.sqrt(x**2 + y**2)
    mask_zero = radius_x_y_zero > cylinder_r

    radius_x_y_center = np.sqrt((x - center[0])**2 + (y - center[1])**2)
    mask_center = radius_x_y_center > cylinder_r

    radius_x_y_l_shift = np.sqrt((x - l_extend[0])**2 + (y - l_extend[1])**2)
    mask_l_shift = radius_x_y_l_shift > cylinder_r

    fix_mask = mask_center & mask_zero & mask_l_shift
    # leave only atoms inside the cylinder
    fix_atoms = FixAtoms(mask=fix_mask)
    disloc.set_constraint(fix_atoms)

    # make an "region" array to map bulk and fixed atoms
    # all atoms are "MM" by default
    region = np.full_like(disloc, "MM")
    region[fix_mask] = np.full_like(disloc[fix_mask], "fixed")
    disloc.new_array("region", region)

    return disloc, bulk, u
Example #40
0
from jasp import *
from ase.lattice.cubic import BodyCenteredCubic
atoms = BodyCenteredCubic(directions=[[1,0,0],
                                      [0,1,0],
                                      [0,0,1]],
                                      size=(1,1,1),
                                      symbol='Fe')
NUPDOWNS = [0.0, 2.0, 4.0, 5.0, 6.0, 8.0]
energies = []
for B in NUPDOWNS:
    with jasp('bulk/Fe-bcc-fixedmagmom-{0:1.2f}'.format(B),
          xc='PBE',
          encut=300,
          kpts=(4,4,4),
          ispin=2,
          nupdown=B,
          atoms=atoms) as calc:
        try:
            e = atoms.get_potential_energy()
            energies.append(e)
        except (VaspSubmitted, VaspQueued):
            pass
import matplotlib.pyplot as plt
plt.plot(NUPDOWNS, energies)
plt.xlabel('Total Magnetic Moment')
plt.ylabel('Energy (eV)')
plt.savefig('images/Fe-fixedmagmom.png')
Example #41
0
from ase import Atoms
from ase.visualize import view, write
from ase.io import read
from ase.calculators.vasp import *
import matplotlib.pyplot as plt
from ase.constraints import FixAtoms
from matplotlib import mlab
from numpy import *
from ase.utils.eos import EquationOfState
from ase.lattice.cubic import BodyCenteredCubic
from ase import Atom

a = 2.8920

cell = [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
atoms = BodyCenteredCubic('Fe', directions=cell)
atoms.set_initial_magnetic_moments([5, 5])

carbon = Atom('C', position=(0, 0.5 * a, 0.5 * a), charge=0.4)

atoms = atoms * (2, 2, 2) + carbon
init = atoms.copy()

final = atoms.copy()
final[-1].position = [0, 0.5 * a, (0.5 + 1.0) * a]

images = [init]

for i in range(9):
    os.system('mkdir 0{0}'.format(i + 1))
    os.chdir('0{0}'.format(i + 1))
Example #42
0
def make_edge_cyl(alat, C11, C12, C44,
                  cylinder_r=10, cutoff=5.5,
                  symbol='W'):
    '''
    makes edge dislocation using atomman library

    cylinder_r - radius of cylinder of unconstrained atoms around the
                 dislocation  in angstrom

    cutoff - potential cutoff for marinica potentials for FS cutoff = 4.4

    symbol : string
        Symbol of the element to pass to ase.lattuce.cubic.SimpleCubicFactory
        default is "W" for tungsten
    '''

    # Create a Stroh ojbect with junk data
    stroh = am.defect.Stroh(am.ElasticConstants(C11=141, C12=110, C44=98),
                            np.array([0, 0, 1]))

    axes = np.array([[1, 1, 1],
                     [1, -1, 0],
                     [1, 1, -2]])

    c = am.ElasticConstants(C11=C11, C12=C12, C44=C44)
    burgers = alat * np.array([1., 1., 1.])/2.

    # Solving a new problem with Stroh.solve
    # Does not work with the new version of atomman
    stroh.solve(c, burgers, axes=axes)

    unit_cell = BodyCenteredCubic(directions=axes.tolist(),
                                  size=(1, 1, 1), symbol='W',
                                  pbc=(False, False, True),
                                  latticeconstant=alat)

    bulk = unit_cell.copy()

    # shift to make the zeros of the cell betweem the atomic planes
    # and under the midplane on Y axes
    X_midplane_shift = (1.0/3.0)*alat*np.sqrt(3.0)/2.0
    Y_midplane_shift = 0.25*alat*np.sqrt(2.0)

    bulk_shift = [X_midplane_shift,
                  Y_midplane_shift,
                  0.0]

    bulk.positions += bulk_shift

    tot_r = cylinder_r + cutoff + 0.01

    Lx = int(round(tot_r/(alat*np.sqrt(3.0)/2.0)))
    Ly = int(round(tot_r/(alat*np.sqrt(2.))))

    # factor 2 to make shure odd number of images is translated
    # it is important for the correct centering of the dislocation core
    bulk = bulk * (2*Lx, 2*Ly, 1)

    center_shift = [Lx * alat * np.sqrt(3.0)/2.,
                    Ly * alat * np.sqrt(2.),
                    0.0]

    bulk.positions -= center_shift

    ED = bulk.copy()

    disp = stroh.displacement(ED.positions)

    ED.positions += disp

    x, y, z = ED.positions.T
    radius_x_y_zero = np.sqrt(x**2 + y**2)
    mask = radius_x_y_zero < tot_r

    ED = ED[mask]
    bulk = bulk[mask]

    bulk.write("before.xyz")

    ED.write("after_disp.xyz")

    x, y, z = ED.positions.T
    radius_x_y_zero = np.sqrt(x**2 + y**2)
    mask_zero = radius_x_y_zero > cylinder_r
    fix_atoms = FixAtoms(mask=mask_zero)

    ED.set_constraint(fix_atoms)

    x, y, z = bulk.positions.T
    # move lower left segment
    bulk.positions[(y < 0.0) & (x < X_midplane_shift)] -= \
        [alat * np.sqrt(3.0) / 2.0, 0.0, 0.0]
    # make the doslocation extraplane center
    bulk.positions += [(1.0/3.0)*alat*np.sqrt(3.0)/2.0, 0.0, 0.0]

    return ED, bulk
Example #43
0
from vasp import Vasp
from ase.lattice.cubic import BodyCenteredCubic
atoms = BodyCenteredCubic(directions=[[1, 0, 0],
                                      [0, 1, 0],
                                      [0, 0, 1]],
                                      size=(1, 1, 1),
                                      symbol='Fe')
NUPDOWNS = [0.0, 2.0, 4.0, 5.0, 6.0, 8.0]
energies = []
for B in NUPDOWNS:
    calc = Vasp('bulk/Fe-bcc-fixedmagmom-{0:1.2f}'.format(B),
                xc='PBE',
                encut=300,
                kpts=[4, 4, 4],
                ispin=2,
                nupdown=B,
                atoms=atoms)
    energies.append(atoms.get_potential_energy())
if None in energies:
    calc.abort()
import matplotlib.pyplot as plt
plt.plot(NUPDOWNS, energies)
plt.xlabel('Total Magnetic Moment')
plt.ylabel('Energy (eV)')
plt.savefig('images/Fe-fixedmagmom.png')
Example #44
0
def screw_cyl_octahedral(alat, C11, C12, C44,
                         scan_r=15,
                         symbol="W",
                         imp_symbol='H',
                         hard_core=False,
                         center=(0., 0., 0.)):
    """Generates a set of octahedral positions with `scan_r` radius.
       Applies the screw dislocation displacement for creating an initial guess
       for the H positions at dislocation core.

    Parameters
    ----------
    alat : float
        Lattice constant of the material.
    C11 : float
        C11 elastic constant of the material.
    C12 : float
        C12 elastic constant of the material.
    C44 : float
        C44 elastic constant of the material.
    symbol : string
        Symbol of the element to pass to ase.lattuce.cubic.SimpleCubicFactory
        default is "W" for tungsten
    imp_symbol : string
        Symbol of the elemnt to pass creat Atoms object
        default is "H" for hydrogen
    symbol : string
        Symbol of the elemnt to pass creat Atoms object
    hard_core : float
        Type of the dislocatino core if True then -u
        (sign of displacement is flipped) is applied.
        Default is False i.e. soft core is created.
    center : tuple of floats
        Coordinates of dislocation core (center) (x, y, z).
        Default is (0., 0., 0.)

    Returns
    -------
    ase.Atoms object
        Atoms object with predicted tetrahedral
        positions around dislocation core.

    """
    # TODO: Make one function for impurities and pass factory to it:
    # TODO: i.e. octahedral or terahedral

    axes = np.array([[1, 1, -2],
                     [-1, 1, 0],
                     [1, 1, 1]])

    unit_cell = BodyCenteredCubic(directions=axes.tolist(),
                                  size=(1, 1, 1), symbol=symbol,
                                  pbc=(False, False, True),
                                  latticeconstant=alat)

    BCCOctas = BodyCenteredCubicOctahedralFactory()

    impurities = BCCOctas(directions=axes.tolist(),
                          size=(1, 1, 1), symbol=imp_symbol,
                          pbc=(False, False, True),
                          latticeconstant=alat)

    impurities = impurities[impurities.positions.T[2] < alat*1.2]
    impurities.set_cell(unit_cell.get_cell())
    impurities.wrap()

    disloCenterY = alat * np.sqrt(2.)/6.0
    disloCenterX = alat * np.sqrt(6.)/6.0

    impurities.positions[:, 0] -= disloCenterX
    impurities.positions[:, 1] -= disloCenterY

    L = int(round(2.0*scan_r/(alat*np.sqrt(2.)))) + 1

    bulk_octa = impurities * (L, L, 1)

    # make 0, 0, at the center
    bulk_octa.positions[:, 0] -= L * alat * np.sqrt(6.)/2. - center[0]
    bulk_octa.positions[:, 1] -= L * alat * np.sqrt(2.)/2. - center[1]

    x, y, z = bulk_octa.positions.T

    radius_x_y_zero = np.sqrt(x**2 + y**2)
    mask_zero = radius_x_y_zero < scan_r

    radius_x_y_center = np.sqrt((x - center[0])**2 + (y - center[1])**2)
    mask_center = radius_x_y_center < scan_r

    final_mask = mask_center | mask_zero
    # leave only atoms inside the cylinder
    bulk_octa = bulk_octa[final_mask]

    # Create a Stroh ojbect with junk data
    stroh = am.defect.Stroh(am.ElasticConstants(C11=141, C12=110, C44=98),
                            np.array([0, 0, 1]))

    c = am.ElasticConstants(C11=C11, C12=C12, C44=C44)
    burgers = alat * np.array([1., 1., 1.])/2.

    # Solving a new problem with Stroh.solve
    stroh.solve(c, burgers, axes=axes)

    dislo_octa = bulk_octa.copy()

    impurities_u = stroh.displacement(bulk_octa.positions - center)
    impurities_u = -impurities_u if hard_core else impurities_u

    dislo_octa.positions += impurities_u

    return dislo_octa
Example #45
0
from ase.visualize import view, write
from ase.io import read
from ase.calculators.vasp import *
import matplotlib.pyplot as plt
from ase.constraints import FixAtoms
from matplotlib import mlab
from numpy import *
from ase.utils.eos import EquationOfState
from ase.lattice.cubic import BodyCenteredCubic
from ase import Atom


a = 2.8920

cell = [[1,0,0],[0,1,0],[0,0,1]]
atoms = BodyCenteredCubic('Fe', directions=cell)
atoms.set_initial_magnetic_moments([5,5])

carbon = Atom('C', position=(0,0.5*a,0.5*a), charge=0.4)

atoms = atoms*(2,2,2) + carbon
init = atoms.copy()

final = atoms.copy()
final[-1].position = [0, 0.5*a, (0.5+1.0)*a]

images = [init]

for i in range(9):
    os.system('mkdir 0{0}'.format(i+1))
    os.chdir('0{0}'.format(i+1))
Example #46
0
from ase import Atoms
from ase.visualize import view, write
from ase.calculators.vasp import *
import matplotlib.pyplot as plt
from ase.constraints import FixAtoms
from matplotlib import mlab
from numpy import *
from ase.utils.eos import EquationOfState
from ase.lattice.cubic import BodyCenteredCubic
from ase import Atom


a = 2.87

cell = [[1,0,0],[0,1,0],[0,0,1]]
bcc = BodyCenteredCubic('Fe', directions=cell)
bcc.set_initial_magnetic_moments([5,5])

carbon = Atom('C', position=(0,0.5*a,0.5*a), charge=0.4)

bcc = bcc*(2,2,2) + carbon
#atoms = atoms*(2,2,2)
constraint = FixAtoms(indices=[5,7,8,10,12,13,14,15,16])

bcc.set_constraint(constraint)

view(bcc)

def save( filename, arg ):
    f = open(filename, 'a+t')
    f.write('{0} \n'.format(arg))
Example #47
0
 ( r6, dict(el1='Si', el2='Si', A=1.0, r0=1.0, cutoff=5.0),
   [ ( "dia-Si", Diamond("Si", size=[sx,sx,sx]) ) ] ),
 ( Brenner,   Erhart_PRB_71_035211_SiC,
   [ ( "dia-C", Diamond("C", size=[sx,sx,sx]) ),
     ( "dia-Si", Diamond("Si", size=[sx,sx,sx]) ),
     ( "dia-Si-C", B3( [ "Si", "C" ], latticeconstant=4.3596,
                       size=[sx,sx,sx]) ) ] ),
 ( BrennerScr, Erhart_PRB_71_035211_SiC__Scr,
   [ ( "dia-C", Diamond("C", size=[sx,sx,sx]) ),
     ( "dia-Si", Diamond("Si", size=[sx,sx,sx]) ),
     ( "dia-Si-C", B3( [ "Si", "C" ], latticeconstant=4.3596,
                       size=[sx,sx,sx]) ) ] ),
 ( Brenner,   Henriksson_PRB_79_114107_FeC,
   [ dict( name='dia-C', struct=Diamond('C', size=[sx,sx,sx]) ),
     dict( name='bcc-Fe',
           struct=BodyCenteredCubic('Fe', size=[sx,sx,sx]) ),
     dict( name='fcc-Fe',
           struct=FaceCenteredCubic('Fe', size=[sx,sx,sx],
                                    latticeconstant=3.6) ),
     dict( name='sc-Fe',
           struct=SimpleCubic('Fe', size=[sx,sx,sx], latticeconstant=2.4) ),
     dict( name='B1-Fe-C',
           struct=B1( [ 'Fe', 'C' ], size=[sx,sx,sx], latticeconstant=3.9) ),
     dict( name='B3-Fe-C',
           struct=B3( [ 'Fe', 'C' ], size=[sx,sx,sx], latticeconstant=4.0) ),
     ] ),
 ( Kumagai,    Kumagai_CompMaterSci_39_457_Si,
   [ ( "dia-Si", Diamond("Si", size=[sx,sx,sx]) ) ] ),
 ( KumagaiScr, Kumagai_CompMaterSci_39_457_Si__Scr,
   [ ( "dia-Si", Diamond("Si", size=[sx,sx,sx]) ) ] ),
 ( Tersoff,    Tersoff_PRB_39_5566_Si_C,
Example #48
0
def make_screw_quadrupole(alat,
                          left_shift=0,
                          right_shift=0,
                          n1u=5,
                          symbol="W"):
    """Generates a screw dislocation dipole configuration
       for effective quadrupole arrangement. Works for BCC systems.

    Parameters
    ----------
    alat : float
        Lattice parameter of the system in Angstrom.
    left_shift : float, optional
        Shift of the left dislocation core in number of dsitances to next
        equivalent disocation core positions needed for creation for final
        configuration for NEB. Default is 0.
    right_shift : float, optional
        shift of the right dislocation core in number of dsitances to next
        equivalent disocation core positions needed for creation for final
        configuration for NEB. Default is 0.
    n1u : int, odd number
        odd number! length of the cell a doubled distance between core along x.
        Main parameter to calculate cell vectors
    symbol : string
        Symbol of the element to pass to ase.lattuce.cubic.SimpleCubicFactory
        default is "W" for tungsten

    Returns
    -------
    disloc_quadrupole : ase.Atoms
        Resulting quadrupole configuration.
    W_bulk : ase.Atoms
        Perfect system.
    dislo_coord_left : list of float
        Coodrinates of left dislocation core [x, y]
    dislo_coord_right : list of float
        Coodrinates of right dislocation core [x, y]

    Notes
    -----

    Calculation of cell vectors
    +++++++++++++++++++++++++++
    From [1]_ we take:

    - Unit vectors for the cell are:

    .. math::

        u = \frac{1}{3}[1 \bar{2} 1];

    .. math::

        v = \frac{1}{3}[2 \bar{1} \bar{1}];

    .. math::

        z = b = \frac{1}{2}[1 1 1];

    - Cell vectors are:

    .. math::

        C_1 = n^u_1 u + n^v_1 v + C^z_1 z;

    .. math::

        C_2 = n^u_2 u + n^v_2 v + C^z_2 z;

    .. math::

        C_3 = z

    - For quadrupole arrangement n1u needs to be odd number,
      for 135 atoms cell we take n1u=5

    - To have quadrupole as as close as possible to a square one has to take:
    .. math::

        2 n^u_2 + n^v_2 = n^u_1

    .. math::

        n^v_2 \approx \frac{n^u_1}{\sqrt{3}}

    - for n1u = 5:

    .. math::

        n^v_2 \approx \frac{n^u_1}{\sqrt{3}} = 2.89 \approx 3.0

    .. math::

        n^u_2 = \frac{1}{2} (n^u_1 - n^v_2) \approx \frac{1}{2} (5-3)=1

    - Following [2]_ cell geometry is optimized by ading tilt compomemts
    Cz1 and Cz2 for our case of n1u = 3n - 1:

    Easy core

    .. math::

        C^z_1 = + \frac{1}{3}

    .. math::

        C^z_2 = + \frac{1}{6}

    Hard core

    .. math::

        C^z_1 = + \frac{1}{3}

    .. math::

        C^z_2 = + \frac{1}{6}

    may be typo in the paper check the original!

    References:
    +++++++++++

    .. [1] Ventelon, L. & Willaime, F. J 'Core structure and Peierls potential
       of screw dislocations in alpha-Fe from first principles: cluster versus
       dipole approaches' Computer-Aided Mater Des (2007) 14(Suppl 1): 85.
       https://doi.org/10.1007/s10820-007-9064-y

    .. [2] Cai W. (2005) Modeling Dislocations Using a Periodic Cell.
       In: Yip S. (eds) Handbook of Materials Modeling. Springer, Dordrecht
       https://link.springer.com/chapter/10.1007/978-1-4020-3286-8_42

    """

    unit_cell = BodyCenteredCubic(directions=[[1, -2, 1],
                                      [2, -1, -1],
                                      [1, 1, 1]],
                                  symbol=symbol,
                                  pbc=(True, True, True),
                                  latticeconstant=alat, debug=0)

    unit_cell_u, unit_cell_v, unit_cell_z = unit_cell.get_cell()

    # calculate the cell vectors according to the Ventelon paper
    # the real configrution depends on rounding check it here

    n2v = int(np.rint(n1u/np.sqrt(3.0)))
    # when the n1u - n2v difference is odd it is impossible to have
    # perfect arrangemt of translation along x with C2 equal to 0.5*n1u
    # choice of rounding between np.ceil() and np.trunc() makes a different
    # configuration but of same quality of arrangement of quadrupoles (test)
    n2u = np.ceil((n1u - n2v) / 2.)
    n1v = 0

    print("Not rounded values of C2 componets: ")
    print("n2u: %.2f,  n2v: %.2f" % ((n1u - n2v) / 2., n1u/np.sqrt(3.0)))
    print("Calculated cell vectors from n1u = %i" % n1u)
    print("n1v = %i" % n1v)
    print("n2u = %i" % n2u)
    print("n2v = %i" % n2v)

    bulk = unit_cell.copy()*[n1u, n2v, 1]

    # add another periodic shift in x direction to c2 vector
    # for proper periodicity (n^u_2=1) of the effective quadrupole arrangement

    bulk.cell[1] += n2u * unit_cell_u

    C1_quadrupole, C2_quadrupole, C3_quadrupole = bulk.get_cell()

    # calulation of dislocation cores positions
    # distance between centers of triangles along x
    # move to odd/even number -> get to upward/downward triangle
    x_core_dist = alat * np.sqrt(6.)/6.0

    # distance between centers of triangles along y
    y_core_dist = alat * np.sqrt(2.)/6.0

    # separation of the cores in a 1ux1v cell
    nx_left = 2
    nx_right = 5

    if n2v % 2 == 0:  # check if the number of cells in y direction is even
        # Even: then introduce cores between two equal halfes of the cell
        ny_left = -2
        ny_right = -1

    else:  # Odd: introduce cores between two equal halfes of the cell
        ny_left = 4
        ny_right = 5

    nx_left += 2.0 * left_shift
    nx_right += 2.0 * right_shift

    dislo_coord_left = np.array([nx_left * x_core_dist,
                                 ny_left * y_core_dist,
                                0.0])

    dislo_coord_right = np.array([nx_right * x_core_dist,
                                  ny_right * y_core_dist,
                                  0.0])

    # caclulation of the shifts of the inital cores coordinates for the final
    # quadrupole arrangements

    # different x centering preferences for odd and even values
    if n2v % 2 == 0:  # check if the number of cells in y direction is even
        # Even:
        dislo_coord_left += (n2u - 1) * unit_cell_u
        dislo_coord_right += (n2u - 1 + np.trunc(n1u/2.0)) * unit_cell_u

    else:  # Odd:
        dislo_coord_left += n2u * unit_cell_u
        dislo_coord_right += (n2u + np.trunc(n1u/2.0)) * unit_cell_u

    dislo_coord_left += np.trunc(n2v/2.0) * unit_cell_v
    dislo_coord_right += np.trunc(n2v/2.0) * unit_cell_v

    u_quadrupole = dipole_displacement_angle(bulk,
                                             dislo_coord_left,
                                             dislo_coord_right)

    # get the image contribution from the dipoles around
    # (default value of N images to scan n_img=10)
    u_img = get_u_img(bulk,
                      dislo_coord_left,
                      dislo_coord_right)

    u_sum = u_quadrupole + u_img

    # calculate the field of neghbouring cell to estimate
    # linear u_err along C1 and C2 (see. Cai paper)

    # u_err along C2

    n1_shift = 0
    n2_shift = 1

    shift = n1_shift*C1_quadrupole + n2_shift*C2_quadrupole

    u_quadrupole_shifted = dipole_displacement_angle(bulk,
                                                     dislo_coord_left + shift,
                                                     dislo_coord_right + shift,
                                                     shift=shift)

    u_img_shifted = get_u_img(bulk,
                              dislo_coord_left,
                              dislo_coord_right,
                              n1_shift=n1_shift, n2_shift=n2_shift)

    u_sum_shifted = u_quadrupole_shifted + u_img_shifted

    delta_u = u_sum - u_sum_shifted

    delta_u_C2 = delta_u.T[2].mean()
    print("delta u c2: %.2f " % delta_u_C2)

    # u_err along C1

    n1_shift = 1
    n2_shift = 0

    shift = n1_shift*C1_quadrupole + n2_shift*C2_quadrupole

    u_quadrupole_shifted = dipole_displacement_angle(bulk,
                                                     dislo_coord_left + shift,
                                                     dislo_coord_right + shift,
                                                     shift=shift)

    u_img_shifted = get_u_img(bulk,
                              dislo_coord_left,
                              dislo_coord_right,
                              n1_shift=n1_shift, n2_shift=n2_shift)

    u_sum_shifted = u_quadrupole_shifted + u_img_shifted

    delta_u = u_sum - u_sum_shifted

    delta_u_C1 = delta_u.T[2].mean()
    print("delta u c1: %.3f" % delta_u_C1)

    x_scaled, y_scaled, __ = bulk.get_scaled_positions(wrap=False).T

    u_err_C2 = (y_scaled - 0.5)*delta_u_C2

    u_err_C1 = delta_u_C1*(x_scaled - 0.5)

    u_err = u_err_C1 + u_err_C2

    # Calculate the u_tilt to accomodate the stress (see. Cai paper)

    burgers = bulk.cell[2][2]

    u_tilt = 0.5 * burgers * (y_scaled - 0.5)

    final_u = u_sum
    final_u.T[2] += u_err - u_tilt

    disloc_quadrupole = bulk.copy()
    disloc_quadrupole.positions += final_u
    # tilt the cell according to the u_tilt
    disloc_quadrupole.cell[1][2] -= burgers/2.0
    bulk.cell[1][2] -= burgers/2.0

    return disloc_quadrupole, bulk, dislo_coord_left, dislo_coord_right